Compare commits

...

3 Commits

Author SHA1 Message Date
0252fc04d3 refactor: update details recipe 2025-09-29 18:26:32 -06:00
557301d59a fix: button font-weight 2025-09-29 14:28:02 -06:00
c085bc8014 feat: add progress bar recipe 2025-09-29 14:27:37 -06:00
4 changed files with 132 additions and 44 deletions

View File

@@ -1,20 +1,21 @@
import { definePreset } from '@pandacss/dev' import { definePreset } from '@pandacss/dev'
import generateColors from '@/colors/generateColors.js' import generateColors from '@/colors/generateColors'
import generateNeutralColor from '@/colors/generateNeutralColor.js' import generateNeutralColor from '@/colors/generateNeutralColor'
import buttonRecipe from '@/recipes/button.js' import generateSemanticColors from '@/colors/generateSemanticColors'
import detailsRecipe from '@/recipes/details.js' import fadeKeyframes from '@/keyframes/fade'
import inputRecipe from '@/recipes/input.js' import pulseKeyframes from '@/keyframes/pulse'
import { type BrandColor, type Color, type ColorVariation, color, type NeutralColor } from '@/types.js' import shimmerKeyframes from '@/keyframes/shimmer'
import generateSemanticColors from './colors/generateSemanticColors.js' import skeletonPattern from '@/patterns/skeleton'
import fadeKeyframes from './keyframes/fade.js' import alertRecipe from '@/recipes/alert'
import pulseKeyframes from './keyframes/pulse.js' import buttonRecipe from '@/recipes/button'
import shimmerKeyframes from './keyframes/shimmer.js' import chipRecipe from '@/recipes/chip'
import skeletonPattern from './patterns/skeleton.js' import detailsRecipe from '@/recipes/details'
import alertRecipe from './recipes/alert.js' import iconButtonRecipe from '@/recipes/iconButton'
import chipRecipe from './recipes/chip.js' import inputRecipe from '@/recipes/input'
import iconButtonRecipe from './recipes/iconButton.js' import markRecipe from '@/recipes/mark'
import markRecipe from './recipes/mark.js' import progressBarRecipe from '@/recipes/progressBar'
import selectRecipe from './recipes/select.js' import selectRecipe from '@/recipes/select'
import { type BrandColor, type Color, type ColorVariation, color, type NeutralColor } from '@/types'
export type ThemeConfig = { export type ThemeConfig = {
neutral?: NeutralColor neutral?: NeutralColor
@@ -50,6 +51,7 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => {
mark: markRecipe({ semanticColorNames: semanticColorKeysArray }), mark: markRecipe({ semanticColorNames: semanticColorKeysArray }),
input: inputRecipe({ semanticColorNames: semanticColorKeysArray }), input: inputRecipe({ semanticColorNames: semanticColorKeysArray }),
iconButton: iconButtonRecipe({ semanticColorNames: semanticColorKeysArray }), iconButton: iconButtonRecipe({ semanticColorNames: semanticColorKeysArray }),
progressBar: progressBarRecipe({ semanticColorNames: semanticColorKeysArray }),
select: selectRecipe({ semanticColorNames: semanticColorKeysArray }) select: selectRecipe({ semanticColorNames: semanticColorKeysArray })
}, },
tokens: { tokens: {
@@ -191,9 +193,10 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => {
conditions: { conditions: {
extend: { extend: {
active: '&:is(:active, [data-active], [data-state="active"], [data-state="open"])', active: '&:is(:active, [data-active], [data-state="active"], [data-state="open"])',
open: '&:is(:open, [open], [data-open], [data-state="open"])',
checked: '&:is(:checked, [data-checked], [data-state="checked"])', checked: '&:is(:checked, [data-checked], [data-state="checked"])',
disabled: '&:is(:disabled, [data-disabled], [data-state="disabled"])' disabled: '&:is(:disabled, [data-disabled], [data-state="disabled"])',
indeterminate: '&:is(:indeterminate, [data-indeterminate], [aria-checked=mixed], [data-state="indeterminate"])',
open: '&:is(:open, [open], [data-open], [data-state="open"])'
} }
}, },
globalCss: { globalCss: {

View File

@@ -26,6 +26,7 @@ const buttonRecipe = ({ semanticColorNames }: ButtonRecipeArg) => {
transitionProperty: 'color, background-color, border-color', transitionProperty: 'color, background-color, border-color',
transitionDuration: 'normal', transitionDuration: 'normal',
transitionTimingFunction: 'easeOut', transitionTimingFunction: 'easeOut',
fontWeight: 'semibold',
_disabled: { _disabled: {
cursor: 'not-allowed', cursor: 'not-allowed',
_hover: { _hover: {

View File

@@ -1,6 +1,6 @@
import { defineSlotRecipe } from '@pandacss/dev' import { defineSlotRecipe, type SystemStyleObject } from '@pandacss/dev'
export const detailsSlots = ['summary', 'details'] as const export const detailsSlots = ['summary', 'details', 'content'] as const
export interface DetailsRecipeArg { export interface DetailsRecipeArg {
semanticColorNames: string[] semanticColorNames: string[]
@@ -14,43 +14,68 @@ const detailsRecipe = ({ semanticColorNames }: DetailsRecipeArg) => {
base: { base: {
details: { details: {
display: 'block', display: 'block',
overflow: 'hidden',
borderRadius: 'sm', borderRadius: 'sm',
transition: 'all', backgroundColor: 'var(--details-background-color)',
transitionTimingFunction: 'easeOut', color: 'var(--details-color)',
transitionDuration: 'normal' border: '1px solid',
borderColor: 'var(--details-background-widget)',
_open: {
'& .details__summary': {
backgroundColor: 'var(--details-background-widget-active)',
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0
}
}
}, },
summary: { summary: {
display: 'block', display: 'block',
overflow: 'hidden',
borderRadius: 'sm', borderRadius: 'sm',
padding: 'xs', backgroundColor: 'var(--details-background-widget)',
color: 'var(--details-color)',
cursor: 'pointer', cursor: 'pointer',
transition: 'all', paddingBlock: 'calc({spacing.xs} * 0.75)',
transitionTimingFunction: 'easeOut', paddingInline: 'calc({spacing.xs} * 1.25)',
transitionDuration: 'normal' transitionProperty: 'color, background-color',
transitionDuration: 'normal',
transitionTimingFunction: 'easeIn',
_hover: {
backgroundColor: 'var(--details-background-widget-hover)'
}
},
content: {
padding: 'sm'
} }
}, },
variants: { variants: {
color: { color: {
...Object.fromEntries( ...Object.fromEntries(
colorVariants.map((color) => [ colorVariants.map((color) => [
color as keyof typeof colorVariants, color,
{ {
summary: { ...Object.fromEntries(
backgroundColor: `{colors.${color}.3}`, detailsSlots.map((slot) => {
color: `{colors.${color}.12}`, // return [slot, {}]
_hover: { switch (slot) {
backgroundColor: `{colors.${color}.4}` case 'details':
}, return [
'[open] &': { slot,
backgroundColor: `{colors.${color}.4}` {
} '--details-background-color': `colors.${color}.2`,
}, '--details-background-widget': `colors.${color}.3`,
details: { '--details-background-widget-hover': `colors.${color}.4`,
backgroundColor: `{colors.${color}.2}`, '--details-background-widget-active': `colors.${color}.5`,
color: `{colors.${color}.12}` '--details-color': `colors.${color}.12`
} as SystemStyleObject
]
case 'summary':
return [slot, {} as SystemStyleObject]
case 'content':
return [slot, {} as SystemStyleObject]
default:
return [slot, {}]
} }
})
)
} }
]) ])
) )

View File

@@ -0,0 +1,59 @@
import { defineRecipe, type SystemStyleObject } from '@pandacss/dev'
interface ProgressBarRecipeArg {
semanticColorNames: string[]
}
const progressBarRecipe = ({ semanticColorNames }: ProgressBarRecipeArg) => {
const colors = ['neutral', ...semanticColorNames]
return defineRecipe({
className: 'progress-bar',
base: {
'-webkit-appearance': 'none',
appearance: 'none',
height: '1em',
borderRadius: 'sm',
border: '1px solid',
overflow: 'hidden',
'&::-webkit-progress-value, &::-moz-progress-bar': {
borderRadius: 'sm'
}
},
variants: {
color: {
...Object.fromEntries(
colors.map((color) => [
color,
{
backgroundColor: `${color}.2`,
borderColor: `${color}.7`,
'&::-webkit-progress-bar': {
backgroundColor: `${color}.2`
},
'&::-webkit-progress-value, &::-moz-progress-bar': {
backgroundColor: `${color}.9`
},
_indeterminate: {
'&::-webkit-progress-value, &::-moz-progress-bar': {
animationName: 'shimmer',
animationIterationCount: 'infinite',
animationDuration: '1s'
}
}
} as SystemStyleObject
])
)
},
fullWidth: {
true: {
width: '100%'
}
}
},
defaultVariants: {
color: 'neutral'
}
})
}
export default progressBarRecipe