161 lines
5.7 KiB
TypeScript
161 lines
5.7 KiB
TypeScript
import { defineSlotRecipe, type SystemStyleObject } from '@pandacss/dev'
|
|
|
|
export const cardSlots = ['root', 'header', 'body', 'footer', 'media', 'actions'] as const
|
|
|
|
export type CardRecipeArg = {
|
|
semanticColorNames: string[]
|
|
}
|
|
|
|
const cardRecipe = ({ semanticColorNames }: CardRecipeArg) => {
|
|
const colors = ['neutral', ...semanticColorNames]
|
|
return defineSlotRecipe({
|
|
className: 'card',
|
|
slots: cardSlots,
|
|
base: {
|
|
root: {
|
|
border: '1px solid',
|
|
borderColor: 'var(--card-border-color)',
|
|
borderRadius: 'md',
|
|
backgroundColor: 'var(--card-background-color)',
|
|
color: 'var(--card-color-text)',
|
|
overflow: 'hidden',
|
|
'&:is(button, a, [role="button"], [role="link"])': {
|
|
all: 'unset',
|
|
border: '1px solid',
|
|
borderColor: 'var(--card-border-color)',
|
|
borderRadius: 'md',
|
|
backgroundColor: 'var(--card-background-color)',
|
|
color: 'var(--card-color-text)',
|
|
overflow: 'hidden',
|
|
cursor: 'pointer',
|
|
transitionProperty: 'color, background-color, border-color',
|
|
transitionDuration: 'normal',
|
|
transitionTimingFunction: 'easeOut',
|
|
focusRingColor: 'var(--card-border-color-hover)',
|
|
_hover: {
|
|
borderColor: 'var(--card-border-color-hover)',
|
|
backgroundColor: 'var(--card-background-color-hover)',
|
|
'& .card__header': {
|
|
backgroundColor: 'var(--card-background-color-variant-hover)'
|
|
}
|
|
},
|
|
_active: {
|
|
borderColor: 'var(--card-border-color-active)',
|
|
backgroundColor: 'var(--card-background-color-active)'
|
|
},
|
|
_focus: {
|
|
focusRing: 'outside',
|
|
focusRingWidth: '2px',
|
|
borderColor: 'var(--card-border-color-hover)',
|
|
backgroundColor: 'var(--card-background-color-hover)',
|
|
'& .card__header': {
|
|
backgroundColor: 'var(--card-background-color-variant-hover)'
|
|
}
|
|
},
|
|
_disabled: {
|
|
borderColor: 'color-mix(in srgb, var(--card-border-color) 40%, transparent)',
|
|
backgroundColor: 'color-mix(in srgb, var(--card-background-color) 40%, transparent)',
|
|
color: 'color-mix(in srgb, var(--card-color-text) 40%, transparent)',
|
|
cursor: 'not-allowed',
|
|
_hover: {
|
|
borderColor: 'color-mix(in srgb, var(--card-border-color) 40%, transparent)',
|
|
backgroundColor: 'color-mix(in srgb, var(--card-background-color) 40%, transparent)'
|
|
},
|
|
_active: {
|
|
borderColor: 'color-mix(in srgb, var(--card-border-color) 40%, transparent)',
|
|
backgroundColor: 'color-mix(in srgb, var(--card-background-color) 40%, transparent)'
|
|
},
|
|
'& .card__header': {
|
|
backgroundColor: 'color-mix(in srgb, var(--card-background-color-variant) 40%, transparent)'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
header: {
|
|
width: '100%',
|
|
paddingInline: 'calc({spacing.xs} * 1.25)',
|
|
paddingBlock: 'calc({spacing.xs} * 0.75)',
|
|
backgroundColor: 'var(--card-background-color-variant)',
|
|
transitionProperty: 'color, background-color, border-color',
|
|
fontWeight: 'semibold',
|
|
fontSize: 'lg',
|
|
textOverflow: 'ellipsis',
|
|
textWrap: 'stable',
|
|
wordBreak: 'break-word',
|
|
overflow: 'hidden',
|
|
whiteSpace: 'nowrap'
|
|
},
|
|
body: {
|
|
paddingInline: 'calc({spacing.xs} * 1.25)',
|
|
paddingBlock: 'calc({spacing.xs} * 0.75)',
|
|
textWrap: 'balance',
|
|
'@supports (text-wrap: pretty)': {
|
|
textWrap: 'pretty'
|
|
}
|
|
},
|
|
footer: {
|
|
paddingInline: 'calc({spacing.xs} * 1.25)',
|
|
paddingBlock: 'calc({spacing.xs} * 0.75)',
|
|
color: 'var(--card-color-text-subtle)',
|
|
fontSize: 'sm',
|
|
textWrap: 'balance',
|
|
'@supports (text-wrap: pretty)': {
|
|
textWrap: 'pretty'
|
|
}
|
|
},
|
|
media: {
|
|
width: '100%',
|
|
height: 'auto',
|
|
objectFit: 'cover',
|
|
objectPosition: 'center'
|
|
},
|
|
actions: {
|
|
display: 'flex',
|
|
justifyContent: 'space-evenly',
|
|
|
|
paddingInline: 'calc({spacing.xs} * 1.25)',
|
|
paddingBlock: 'calc({spacing.xs} * 0.75)'
|
|
}
|
|
},
|
|
variants: {
|
|
color: {
|
|
...Object.fromEntries(
|
|
colors.map((color) => [
|
|
color,
|
|
Object.fromEntries(
|
|
cardSlots.map((slot) => {
|
|
switch (slot) {
|
|
case 'root':
|
|
return [
|
|
slot,
|
|
{
|
|
'--card-background-color': `{colors.${color}.2}`,
|
|
'--card-background-color-variant': `{colors.${color}.3}`,
|
|
'--card-background-color-hover': `{colors.${color}.4}`,
|
|
'--card-background-color-active': `{colors.${color}.5}`,
|
|
'--card-border-color': `{colors.${color}.6}`,
|
|
'--card-border-color-hover': `{colors.${color}.7}`,
|
|
'--card-border-color-active': `{colors.${color}.8}`,
|
|
'--card-color': `{colors.${color}.9}`,
|
|
'--card-color-hover': `{colors.${color}.10}`,
|
|
'--card-color-text-subtle': `{colors.${color}.11}`,
|
|
'--card-color-text': `{colors.${color}.12}`
|
|
} as SystemStyleObject
|
|
]
|
|
default:
|
|
return [slot, {} as SystemStyleObject]
|
|
}
|
|
})
|
|
)
|
|
])
|
|
)
|
|
}
|
|
},
|
|
defaultVariants: {
|
|
color: 'neutral'
|
|
}
|
|
})
|
|
}
|
|
|
|
export default cardRecipe
|