feat: add alert recipe and fade keyframes, update font sizes and global styles
This commit is contained in:
96
src/index.ts
96
src/index.ts
@@ -6,9 +6,11 @@ import detailsRecipe from '@/recipes/details.js'
|
||||
import inputRecipe from '@/recipes/input.js'
|
||||
import { type BrandColor, type Color, type ColorVariation, color, type NeutralColor } from '@/types.js'
|
||||
import generateSemanticColors from './colors/generateSemanticColors.js'
|
||||
import fadeKeyframes from './keyframes/fade.js'
|
||||
import pulseKeyframes from './keyframes/pulse.js'
|
||||
import shimmerKeyframes from './keyframes/shimmer.js'
|
||||
import skeletonPattern from './patterns/skeleton.js'
|
||||
import alertRecipe from './recipes/alert.js'
|
||||
import chipRecipe from './recipes/chip.js'
|
||||
import iconButtonRecipe from './recipes/iconButton.js'
|
||||
import markRecipe from './recipes/mark.js'
|
||||
@@ -40,6 +42,7 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => {
|
||||
},
|
||||
theme: {
|
||||
recipes: {
|
||||
alert: alertRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||
button: buttonRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||
chip: chipRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||
details: detailsRecipe({ semanticColorNames: semanticColorKeysArray }),
|
||||
@@ -84,24 +87,24 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => {
|
||||
sm: { value: '0.875em' },
|
||||
base: { value: '1em' },
|
||||
lg: { value: '1.125em' },
|
||||
xl: { value: '1.5em' },
|
||||
h1: { value: '3em' },
|
||||
h2: { value: '2.5em' },
|
||||
h3: { value: '2.25em' },
|
||||
h4: { value: '2em' },
|
||||
h5: { value: '1.75em' },
|
||||
xl: { value: '1.375em' },
|
||||
h6: { value: '1.5em' },
|
||||
h5: { value: '1.625em' },
|
||||
h4: { value: '1.75em' },
|
||||
h3: { value: '1.875em' },
|
||||
h2: { value: '2em' },
|
||||
h1: { value: '2.25em' },
|
||||
rxs: { value: '0.75rem' },
|
||||
rsm: { value: '0.875rem' },
|
||||
rbase: { value: '1rem' },
|
||||
rlg: { value: '1.25rem' },
|
||||
rxl: { value: '1.5rem' },
|
||||
rh1: { value: '3rem' },
|
||||
rh2: { value: '2.5rem' },
|
||||
rh3: { value: '2.25rem' },
|
||||
rh4: { value: '2rem' },
|
||||
rh5: { value: '1.75rem' },
|
||||
rh6: { value: '1.5rem' }
|
||||
rxl: { value: '1.375rem' },
|
||||
rh6: { value: '1.5rem' },
|
||||
rh5: { value: '1.625rem' },
|
||||
rh4: { value: '1.75rem' },
|
||||
rh3: { value: '1.875rem' },
|
||||
rh2: { value: '2rem' },
|
||||
rh1: { value: '2.25rem' }
|
||||
},
|
||||
fontWeights: {
|
||||
thin: { value: '100' },
|
||||
@@ -173,7 +176,8 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => {
|
||||
animationStyles: {},
|
||||
keyframes: {
|
||||
...shimmerKeyframes,
|
||||
...pulseKeyframes
|
||||
...pulseKeyframes,
|
||||
...fadeKeyframes
|
||||
},
|
||||
semanticTokens: {
|
||||
colors: {
|
||||
@@ -181,6 +185,70 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => {
|
||||
...semanticColors
|
||||
}
|
||||
}
|
||||
},
|
||||
globalCss: {
|
||||
'*, *:before, *:after': {
|
||||
boxSizing: 'border-box',
|
||||
margin: 0,
|
||||
padding: 0
|
||||
},
|
||||
body: {
|
||||
backgroundColor: 'neutral.1',
|
||||
color: 'neutral.12'
|
||||
},
|
||||
'img, picture, video, canvas, svg ': {
|
||||
display: 'block',
|
||||
maxWidth: '100%'
|
||||
},
|
||||
'input, button, textarea, select': {
|
||||
font: 'inherit'
|
||||
},
|
||||
button: {
|
||||
cursor: 'pointer'
|
||||
},
|
||||
'h1, h2, h3, h4, h5, h6': {
|
||||
fontWeight: 'bold',
|
||||
lineHeight: 'tight'
|
||||
},
|
||||
h1: {
|
||||
fontSize: 'h1'
|
||||
},
|
||||
h2: {
|
||||
fontSize: 'h2'
|
||||
},
|
||||
h3: {
|
||||
fontSize: 'h3'
|
||||
},
|
||||
h4: {
|
||||
fontSize: 'h4'
|
||||
},
|
||||
h5: {
|
||||
fontSize: 'h5'
|
||||
},
|
||||
h6: {
|
||||
fontSize: 'h6'
|
||||
},
|
||||
p: {
|
||||
fontSize: 'base',
|
||||
lineHeight: 'normal',
|
||||
textWrap: 'pretty'
|
||||
},
|
||||
small: {
|
||||
fontSize: 'xs'
|
||||
},
|
||||
a: {
|
||||
color: 'inherit',
|
||||
textDecoration: 'none',
|
||||
fontWeight: 'semibold',
|
||||
_hover: {
|
||||
color: 'primary.9'
|
||||
}
|
||||
},
|
||||
'@media (prefers-reduced-motion: no-preference)': {
|
||||
html: {
|
||||
interpolateSize: 'allow-keywords'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
10
src/keyframes/fade.ts
Normal file
10
src/keyframes/fade.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { defineKeyframes } from '@pandacss/dev'
|
||||
|
||||
const fadeKeyframes = defineKeyframes({
|
||||
fade: {
|
||||
'0%': { opacity: '0' },
|
||||
'100%': { opacity: '1' }
|
||||
}
|
||||
})
|
||||
|
||||
export default fadeKeyframes
|
||||
106
src/recipes/alert.ts
Normal file
106
src/recipes/alert.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { defineSlotRecipe, type SystemStyleObject } from '@pandacss/dev'
|
||||
|
||||
export const alertSlots = ['root', 'title', 'description', 'closeButton', 'actionsContainer'] as const
|
||||
|
||||
interface AlertRecipeArg {
|
||||
semanticColorNames: string[]
|
||||
}
|
||||
|
||||
const alertRecipe = ({ semanticColorNames }: AlertRecipeArg) => {
|
||||
const colors = ['neutral', ...semanticColorNames]
|
||||
return defineSlotRecipe({
|
||||
className: 'alert',
|
||||
slots: alertSlots,
|
||||
base: {
|
||||
root: {
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: 'xs',
|
||||
padding: 'sm',
|
||||
borderRadius: 'md',
|
||||
backgroundColor: 'var(--alert-background-color)',
|
||||
color: 'var(--alert-color)'
|
||||
},
|
||||
title: {
|
||||
color: 'var(--alert-color)',
|
||||
fontWeight: 'semibold',
|
||||
lineHeight: 'tight',
|
||||
'&[aria-level="1"]': {
|
||||
fontSize: 'h1'
|
||||
},
|
||||
'&[aria-level="2"]': {
|
||||
fontSize: 'h2'
|
||||
},
|
||||
'&[aria-level="3"]': {
|
||||
fontSize: 'h3'
|
||||
},
|
||||
'&[aria-level="4"]': {
|
||||
fontSize: 'h4'
|
||||
},
|
||||
'&[aria-level="5"]': {
|
||||
fontSize: 'h5'
|
||||
},
|
||||
'&[aria-level="6"]': {
|
||||
fontSize: 'h6'
|
||||
}
|
||||
},
|
||||
description: {
|
||||
color: 'var(--alert-color)'
|
||||
},
|
||||
closeButton: {
|
||||
all: 'unset',
|
||||
position: 'absolute',
|
||||
top: 'sm',
|
||||
right: 'sm',
|
||||
cursor: 'pointer',
|
||||
color: 'var(--alert-color)'
|
||||
},
|
||||
actionsContainer: {
|
||||
display: 'flex',
|
||||
gap: 'xs',
|
||||
justifyContent: 'flex-end'
|
||||
}
|
||||
},
|
||||
variants: {
|
||||
color: {
|
||||
...Object.fromEntries(
|
||||
colors.map((color) => [
|
||||
color,
|
||||
{
|
||||
...Object.fromEntries(
|
||||
alertSlots.map((slot) => {
|
||||
switch (slot) {
|
||||
case 'root':
|
||||
return [
|
||||
slot,
|
||||
{
|
||||
'--alert-background-color': `{colors.${color}.3}`,
|
||||
'--alert-color': `{colors.${color}.12}`
|
||||
} as SystemStyleObject
|
||||
]
|
||||
case 'title':
|
||||
return [slot, {} as SystemStyleObject]
|
||||
case 'closeButton':
|
||||
return [slot, {} as SystemStyleObject]
|
||||
case 'description':
|
||||
return [slot, {} as SystemStyleObject]
|
||||
case 'actionsContainer':
|
||||
return [slot, {} as SystemStyleObject]
|
||||
default:
|
||||
return [slot, {} as SystemStyleObject]
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
])
|
||||
)
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
color: 'neutral'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default alertRecipe
|
||||
@@ -20,7 +20,17 @@ const markRecipe = ({ semanticColorNames }: MarkRecipeArg) => {
|
||||
},
|
||||
variants: {
|
||||
color: {
|
||||
...Object.fromEntries(colors.map((color) => [color, {}]))
|
||||
...Object.fromEntries(
|
||||
colors.map((color) => [
|
||||
color,
|
||||
{
|
||||
'&::selection': {
|
||||
backgroundColor: `{colors.${color}.2}`,
|
||||
color: `{colors.${color}.9}`
|
||||
}
|
||||
}
|
||||
])
|
||||
)
|
||||
},
|
||||
variant: {
|
||||
...Object.fromEntries(markVariants.map((variant) => [variant, {}]))
|
||||
@@ -34,15 +44,34 @@ const markRecipe = ({ semanticColorNames }: MarkRecipeArg) => {
|
||||
color,
|
||||
variant,
|
||||
css: {
|
||||
margin: '0 -0.4em',
|
||||
padding: '0.1em 0.4em 0.1em 0.4em',
|
||||
borderRadius: '0.8em 0.3em',
|
||||
boxDecorationBreak: 'clone',
|
||||
WebkitBoxDecorationBreak: 'clone',
|
||||
position: 'relative',
|
||||
marginBlock: '0',
|
||||
marginInline: '-0.4ch',
|
||||
paddingBlock: '0.2ch',
|
||||
paddingInline: '0.6ch',
|
||||
borderTopLeftRadius: '0.5em 40%',
|
||||
borderTopRightRadius: '0.3em 15%',
|
||||
borderBottomLeftRadius: '0.45em 80%',
|
||||
borderBottomRightRadius: '0.75em 60%',
|
||||
backgroundClip: 'padding-box',
|
||||
fontWeight: 'semibold',
|
||||
backgroundImage: `linear-gradient(to right, color-mix(in srgb, {colors.${color}.9} 10%,transparent) 0%, color-mix(in srgb, {colors.${color}.9} 73%, transparent) 12%, color-mix(in srgb, {colors.${color}.9} 25%, transparent) 100%)`,
|
||||
color: `{colors.${color}.foreground}`
|
||||
color: `{colors.${color}.foreground}`,
|
||||
_before: {
|
||||
content: '""',
|
||||
position: 'absolute',
|
||||
inset: '0',
|
||||
width: '100%',
|
||||
height: '80%',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
boxDecorationBreak: 'clone',
|
||||
WebkitBoxDecorationBreak: 'clone',
|
||||
borderRadius: 'inherit',
|
||||
background: 'inherit',
|
||||
backgroundImage: `linear-gradient(to right,color-mix(in srgb, {colors.${color}.9} 15%,transparent) 0%,color-mix(in srgb, {colors.${color}.9} 65%, transparent) 12%, color-mix(in srgb, {colors.${color}.9} 20%, transparent 80%))`,
|
||||
transform: 'translate(-50%, -50%) skewX(-15deg)',
|
||||
zIndex: '-1'
|
||||
}
|
||||
} as SystemStyleObject
|
||||
}
|
||||
case 'bold':
|
||||
@@ -70,7 +99,7 @@ const markRecipe = ({ semanticColorNames }: MarkRecipeArg) => {
|
||||
})
|
||||
),
|
||||
defaultVariants: {
|
||||
color: 'neutral',
|
||||
color: 'primary',
|
||||
variant: 'highlight'
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user