117 lines
2.7 KiB
TypeScript
117 lines
2.7 KiB
TypeScript
"use client"
|
|
|
|
import { useFormContext } from "react-hook-form"
|
|
|
|
import { CheckIcon, CloseIcon } 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, ListProps, SubtitleProps, TextProps } from "./card"
|
|
|
|
export default function Card({
|
|
Icon,
|
|
iconHeight = 32,
|
|
iconWidth = 32,
|
|
declined = false,
|
|
highlightSubtitle = false,
|
|
id,
|
|
list,
|
|
name,
|
|
subtitle,
|
|
text,
|
|
title,
|
|
type,
|
|
value,
|
|
handleSelectedOnClick,
|
|
}: CardProps) {
|
|
const { register } = useFormContext()
|
|
|
|
function onLabelClick(event: React.MouseEvent) {
|
|
// Preventing click event on label elements firing twice: https://github.com/facebook/react/issues/14295
|
|
event.preventDefault()
|
|
handleSelectedOnClick?.()
|
|
}
|
|
return (
|
|
<label
|
|
className={styles.label}
|
|
data-declined={declined}
|
|
tabIndex={0}
|
|
onClick={handleSelectedOnClick ? onLabelClick : undefined}
|
|
>
|
|
<Caption className={styles.title} color="burgundy" type="label" uppercase>
|
|
{title}
|
|
</Caption>
|
|
<Subtitle highlightSubtitle={highlightSubtitle} subtitle={subtitle} />
|
|
{Icon ? (
|
|
<Icon
|
|
className={styles.icon}
|
|
color="uiTextHighContrast"
|
|
height={iconHeight}
|
|
width={iconWidth}
|
|
/>
|
|
) : null}
|
|
<List declined={declined} list={list} />
|
|
<Text text={text} />
|
|
<input
|
|
{...register(name)}
|
|
aria-hidden
|
|
id={id || name}
|
|
hidden
|
|
type={type}
|
|
value={value}
|
|
/>
|
|
</label>
|
|
)
|
|
}
|
|
|
|
function List({ declined, list }: ListProps) {
|
|
if (!list) {
|
|
return null
|
|
}
|
|
|
|
return 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>
|
|
))
|
|
}
|
|
|
|
function Subtitle({ highlightSubtitle, subtitle }: SubtitleProps) {
|
|
if (!subtitle) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<Caption
|
|
className={styles.subtitle}
|
|
color={highlightSubtitle ? "baseTextAccent" : "uiTextMediumContrast"}
|
|
type="label"
|
|
uppercase
|
|
>
|
|
{subtitle}
|
|
</Caption>
|
|
)
|
|
}
|
|
|
|
function Text({ text }: TextProps) {
|
|
if (!text) {
|
|
return null
|
|
}
|
|
return (
|
|
<Footnote className={styles.text} color="uiTextMediumContrast">
|
|
{text}
|
|
</Footnote>
|
|
)
|
|
}
|
|
|
|
export function Highlight({ children }: React.PropsWithChildren) {
|
|
return <span className={styles.highlight}>{children}</span>
|
|
}
|