Files
srjuggernaut-panda-preset/src/recipes/iconButton.ts
T

201 lines
6.3 KiB
TypeScript

import { defineRecipe, type SystemStyleObject } from '@pandacss/dev'
export const iconButtonVariants = ['solid', 'outline', 'ghost'] as const
export const iconButtonShapes = ['circle', 'square'] as const
export const iconButtonSizes = ['small', 'medium', 'large'] as const
interface IconButtonRecipeArg {
semanticColorNames: string[]
}
const iconButtonRecipe = ({ semanticColorNames }: IconButtonRecipeArg) => {
const colors = ['neutral', ...semanticColorNames]
return defineRecipe({
className: 'iconButton',
base: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
width: 'calc(max-content)',
height: 'auto',
aspectRatio: '1/1',
cursor: 'pointer',
transitionProperty: 'color, background-color, border-color',
transitionDuration: 'normal',
transitionTimingFunction: 'easeOut',
focusVisibleRing: 'outside',
focusRingWidth: '2px',
focusRingOffset: '0px',
_disabled: {
cursor: 'not-allowed',
_hover: {
cursor: 'not-allowed'
}
}
},
variants: {
shape: {
...Object.fromEntries(
iconButtonShapes.map((shape) => {
switch (shape) {
case 'circle':
return [
shape,
{
borderRadius: 'full'
}
]
case 'square':
return [
shape,
{
borderRadius: 'sm'
}
]
default:
return [shape, {}]
}
})
)
},
color: {
...Object.fromEntries(
colors.map((color) => [
color,
{
focusRingColor: `{colors.${color}.6}`
}
])
)
},
variant: {
...Object.fromEntries(iconButtonVariants.map((variant) => [variant, {}]))
},
size: {
...Object.fromEntries(
iconButtonSizes.map((size) => {
switch (size) {
case 'small':
return [size, { padding: 'calc({spacing.sm} * 0.5)' }]
case 'medium':
return [size, { padding: 'calc({spacing.sm} * 0.75)' }]
case 'large':
return [size, { padding: 'calc({spacing.sm})' }]
default:
return [size, {}]
}
})
)
}
},
compoundVariants: colors.flatMap((color) =>
iconButtonVariants.map((variant) => {
switch (variant) {
case 'solid':
return {
color,
variant,
css: {
border: 'none',
backgroundColor: `${color}.9`,
color: `${color}.foreground`,
_hover: {
backgroundColor: `${color}.10`
},
_focusVisible: {
backgroundColor: `${color}.10`
},
_active: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 80%, {colors.${color}.1})`
},
_disabled: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 40%, transparent)`,
color: `color-mix(in srgb, {colors.${color}.foreground} 40%, transparent)`,
_hover: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 40%, transparent)`,
color: `color-mix(in srgb, {colors.${color}.foreground} 40%, transparent)`
}
}
} as SystemStyleObject
}
case 'outline':
return {
color,
variant,
css: {
border: '1px solid',
borderColor: `${color}.9`,
backgroundColor: 'transparent',
color: `${color}.9`,
_hover: {
backgroundColor: `${color}.10`,
color: `${color}.foreground`
},
_focusVisible: {
backgroundColor: `${color}.10`,
color: `${color}.foreground`
},
_active: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 80%, {colors.${color}.1})`,
color: `${color}.foreground`
},
_disabled: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 10%, transparent)`,
color: `color-mix(in srgb, {colors.${color}.foreground} 40%, transparent)`,
borderColor: `color-mix(in srgb, {colors.${color}.9} 10%, transparent)`,
_hover: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 10%, transparent)`,
color: `${color}.4/50`
}
}
}
}
case 'ghost':
return {
color,
variant,
css: {
border: 'none',
backgroundColor: 'transparent',
color: `${color}.9`,
_hover: {
backgroundColor: `${color}.10`,
color: `${color}.foreground`
},
_focusVisible: {
backgroundColor: `${color}.10`,
color: `${color}.foreground`
},
_active: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 80%, {colors.${color}.1})`,
color: `${color}.foreground`
},
_disabled: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 10%, transparent)`,
color: `color-mix(in srgb, {colors.${color}.foreground} 40%, transparent)`,
_hover: {
backgroundColor: `color-mix(in srgb, {colors.${color}.9} 10%, transparent)`
}
}
}
}
default:
return {
color,
variant,
css: {}
}
}
})
),
defaultVariants: {
shape: 'circle',
color: 'neutral',
variant: 'solid',
size: 'medium'
}
})
}
export default iconButtonRecipe