Merge develop
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
7
components/TempDesignSystem/Form/Card/Checkbox.tsx
Normal file
7
components/TempDesignSystem/Form/Card/Checkbox.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import Card from "."
|
||||
|
||||
import type { CheckboxProps } from "./card"
|
||||
|
||||
export default function CheckboxCard(props: CheckboxProps) {
|
||||
return <Card {...props} type="checkbox" />
|
||||
}
|
||||
7
components/TempDesignSystem/Form/Card/Radio.tsx
Normal file
7
components/TempDesignSystem/Form/Card/Radio.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import Card from "."
|
||||
|
||||
import type { RadioProps } from "./card"
|
||||
|
||||
export default function RadioCard(props: RadioProps) {
|
||||
return <Card {...props} type="radio" />
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
35
components/TempDesignSystem/Form/Card/card.ts
Normal file
35
components/TempDesignSystem/Form/Card/card.ts
Normal 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">
|
||||
77
components/TempDesignSystem/Form/Card/index.tsx
Normal file
77
components/TempDesignSystem/Form/Card/index.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user