Merge develop

This commit is contained in:
Pontus Dreij
2024-10-08 10:56:02 +02:00
82 changed files with 1432 additions and 519 deletions

View File

@@ -14,7 +14,7 @@ export default function CardImage({
return (
<article className={`${styles.container} ${className}`}>
<div className={styles.imageContainer}>
{imageCards.map(
{imageCards?.map(
({ backgroundImage }) =>
backgroundImage && (
<Image

View File

@@ -2,6 +2,7 @@ import { cardVariants } from "./variants"
import type { VariantProps } from "class-variance-authority"
import type { ApiImage } from "@/types/components/image"
import type { ImageVaultAsset } from "@/types/components/imageVault"
export interface CardProps
@@ -22,9 +23,10 @@ export interface CardProps
scriptedTopTitle?: string | null
heading?: string | null
bodyText?: string | null
backgroundImage?: ImageVaultAsset
imageHeight?: number
imageWidth?: number
imageGradient?: boolean
onPrimaryButtonClick?: () => void
onSecondaryButtonClick?: () => void
backgroundImage?: ImageVaultAsset | ApiImage
}

View File

@@ -24,15 +24,17 @@ export default function Card({
backgroundImage,
imageHeight,
imageWidth,
imageGradient,
onPrimaryButtonClick,
onSecondaryButtonClick,
}: CardProps) {
const buttonTheme = getTheme(theme)
imageHeight = imageHeight || 320
imageWidth =
imageWidth ||
(backgroundImage
(backgroundImage && "dimensions" in backgroundImage
? backgroundImage.dimensions.aspectRatio * imageHeight
: 420)
@@ -44,7 +46,7 @@ export default function Card({
})}
>
{backgroundImage && (
<div className={styles.imageWrapper}>
<div className={imageGradient ? styles.imageWrapper : ""}>
<Image
src={backgroundImage.url}
className={styles.image}

View File

@@ -0,0 +1,7 @@
import Card from "."
import type { CheckboxProps } from "./card"
export default function CheckboxCard(props: CheckboxProps) {
return <Card {...props} type="checkbox" />
}

View File

@@ -0,0 +1,7 @@
import Card from "."
import type { RadioProps } from "./card"
export default function RadioCard(props: RadioProps) {
return <Card {...props} type="radio" />
}

View File

@@ -1,70 +1,72 @@
.checkbox {
.label {
align-self: flex-start;
background-color: var(--Base-Surface-Primary-light-Normal);
border: 1px solid var(--Base-Border-Subtle);
border-radius: var(--Corner-radius-Large);
cursor: pointer;
display: flex;
flex-direction: column;
gap: var(--Spacing-x1);
display: grid;
grid-template-columns: 1fr auto;
padding: var(--Spacing-x-one-and-half) var(--Spacing-x2);
transition: all 200ms ease;
width: min(100%, 600px);
}
.checkbox:hover {
.label:hover {
background-color: var(--Base-Surface-Secondary-light-Hover);
}
.checkbox:has(:checked) {
.label:has(:checked) {
background-color: var(--Primary-Light-Surface-Normal);
border-color: var(--Base-Border-Hover);
}
.header {
align-items: center;
display: grid;
gap: 0px var(--Spacing-x1);
grid-template-areas:
"title icon"
"subtitle icon";
}
.icon {
grid-area: icon;
align-self: center;
grid-column: 2/3;
grid-row: 1/3;
justify-self: flex-end;
transition: fill 200ms ease;
}
.checkbox:hover .icon,
.checkbox:hover .icon *,
.checkbox:has(:checked) .icon,
.checkbox:has(:checked) .icon * {
.label:hover .icon,
.label:hover .icon *,
.label:has(:checked) .icon,
.label:has(:checked) .icon * {
fill: var(--Base-Text-Medium-contrast);
}
.checkbox[data-declined="true"]:hover .icon,
.checkbox[data-declined="true"]:hover .icon *,
.checkbox[data-declined="true"]:has(:checked) .icon,
.checkbox[data-declined="true"]:has(:checked) .icon * {
.label[data-declined="true"]:hover .icon,
.label[data-declined="true"]:hover .icon *,
.label[data-declined="true"]:has(:checked) .icon,
.label[data-declined="true"]:has(:checked) .icon * {
fill: var(--Base-Text-Disabled);
}
.subtitle {
grid-area: subtitle;
grid-column: 1 / 2;
grid-row: 2;
}
.title {
grid-area: title;
grid-column: 1 / 2;
}
.list {
list-style: none;
margin: 0;
padding: 0;
.label .text {
margin-top: var(--Spacing-x1);
grid-column: 1/-1;
}
.listItem {
align-items: center;
display: flex;
gap: var(--Spacing-x-quarter);
grid-column: 1/-1;
}
.listItem:first-of-type {
margin-top: var(--Spacing-x1);
}
.listItem:nth-of-type(n + 2) {
margin-top: var(--Spacing-x-quarter);
}

View File

@@ -0,0 +1,35 @@
import type { IconProps } from "@/types/components/icon"
interface BaseCardProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
Icon?: (props: IconProps) => JSX.Element
declined?: boolean
iconHeight?: number
iconWidth?: number
name?: string
saving?: boolean
subtitle?: string
title: string
type: "checkbox" | "radio"
value?: string
}
interface ListCardProps extends BaseCardProps {
list: {
title: string
}[]
text?: never
}
interface TextCardProps extends BaseCardProps {
list?: never
text: string
}
export type CardProps = ListCardProps | TextCardProps
export type CheckboxProps =
| Omit<ListCardProps, "type">
| Omit<TextCardProps, "type">
export type RadioProps =
| Omit<ListCardProps, "type">
| Omit<TextCardProps, "type">

View File

@@ -0,0 +1,77 @@
"use client"
import { CheckIcon, CloseIcon, HeartIcon } from "@/components/Icons"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import styles from "./card.module.css"
import type { CardProps } from "./card"
export default function Card({
Icon = HeartIcon,
iconHeight = 32,
iconWidth = 32,
declined = false,
id,
list,
name = "join",
saving = false,
subtitle,
text,
title,
type,
value,
}: CardProps) {
return (
<label className={styles.label} data-declined={declined}>
<Caption className={styles.title} textTransform="bold" uppercase>
{title}
</Caption>
{subtitle ? (
<Caption
className={styles.subtitle}
color={saving ? "baseTextAccent" : "uiTextHighContrast"}
textTransform="bold"
>
{subtitle}
</Caption>
) : null}
<Icon
className={styles.icon}
color="uiTextHighContrast"
height={iconHeight}
width={iconWidth}
/>
{list
? list.map((listItem) => (
<span key={listItem.title} className={styles.listItem}>
{declined ? (
<CloseIcon
color="uiTextMediumContrast"
height={20}
width={20}
/>
) : (
<CheckIcon color="baseIconLowContrast" height={20} width={20} />
)}
<Footnote color="uiTextMediumContrast">{listItem.title}</Footnote>
</span>
))
: null}
{text ? (
<Footnote className={styles.text} color="uiTextMediumContrast">
{text}
</Footnote>
) : null}
<input
aria-hidden
id={id || name}
hidden
name={name}
type={type}
value={value}
/>
</label>
)
}

View File

@@ -1,14 +0,0 @@
import type { IconProps } from "@/types/components/icon"
export interface CheckboxCardProps {
Icon?: (props: IconProps) => JSX.Element
declined?: boolean
list?: {
title: string
}[]
name?: string
saving?: boolean
subtitle?: string
text?: string
title: string
}

View File

@@ -1,65 +0,0 @@
"use client"
import { CheckIcon, CloseIcon, HeartIcon } from "@/components/Icons"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import styles from "./card.module.css"
import type { CheckboxCardProps } from "./card"
export default function CheckboxCard({
Icon = HeartIcon,
declined = false,
list,
name = "join",
saving = false,
subtitle,
text,
title,
}: CheckboxCardProps) {
return (
<label className={styles.checkbox} data-declined={declined} htmlFor={name}>
<header className={styles.header}>
<Caption className={styles.title} textTransform="bold" uppercase>
{title}
</Caption>
{subtitle ? (
<Caption
className={styles.subtitle}
color={saving ? "baseTextAccent" : "uiTextHighContrast"}
textTransform="bold"
>
{subtitle}
</Caption>
) : null}
<Icon
className={styles.icon}
color="uiTextHighContrast"
height={32}
width={32}
/>
</header>
{list ? (
<ul className={styles.list}>
{list.map((listItem) => (
<li key={listItem.title} className={styles.listItem}>
{declined ? (
<CloseIcon
color="uiTextMediumContrast"
height={20}
width={20}
/>
) : (
<CheckIcon color="baseIconLowContrast" height={20} width={20} />
)}
<Footnote color="uiTextMediumContrast">{listItem.title}</Footnote>
</li>
))}
</ul>
) : null}
{text ? <Footnote color="uiTextMediumContrast">{text}</Footnote> : null}
<input aria-hidden id={name} hidden name={name} type="checkbox" />
</label>
)
}