feat: add card recipe
This commit is contained in:
@@ -8,6 +8,7 @@ import shimmerKeyframes from '@/keyframes/shimmer'
|
|||||||
import skeletonPattern from '@/patterns/skeleton'
|
import skeletonPattern from '@/patterns/skeleton'
|
||||||
import alertRecipe from '@/recipes/alert'
|
import alertRecipe from '@/recipes/alert'
|
||||||
import buttonRecipe from '@/recipes/button'
|
import buttonRecipe from '@/recipes/button'
|
||||||
|
import cardRecipe from '@/recipes/card'
|
||||||
import chipRecipe from '@/recipes/chip'
|
import chipRecipe from '@/recipes/chip'
|
||||||
import detailsRecipe from '@/recipes/details'
|
import detailsRecipe from '@/recipes/details'
|
||||||
import iconButtonRecipe from '@/recipes/iconButton'
|
import iconButtonRecipe from '@/recipes/iconButton'
|
||||||
@@ -46,6 +47,7 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => {
|
|||||||
recipes: {
|
recipes: {
|
||||||
alert: alertRecipe({ semanticColorNames: semanticColorKeysArray }),
|
alert: alertRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||||
button: buttonRecipe({ semanticColorNames: semanticColorKeysArray }),
|
button: buttonRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||||
|
card: cardRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||||
chip: chipRecipe({ semanticColorNames: semanticColorKeysArray }),
|
chip: chipRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||||
details: detailsRecipe({ semanticColorNames: semanticColorKeysArray }),
|
details: detailsRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||||
mark: markRecipe({ semanticColorNames: semanticColorKeysArray }),
|
mark: markRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||||
|
|||||||
160
src/recipes/card.ts
Normal file
160
src/recipes/card.ts
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
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
|
||||||
Reference in New Issue
Block a user