feat: add new components and improve styling utilities
- Add chip, mark, and iconButton recipes with semantic color support - Introduce skeleton pattern and shimmer gradient for loading states - Enhance button and details recipes with refined transition properties - Update border radius tokens to include 'full' and negative spacing values - Refactor details recipe export and semantic color key handling - Bump package version to 0.0.6
This commit is contained in:
@@ -3,11 +3,11 @@ import { defineRecipe } from '@pandacss/dev'
|
||||
export const buttonVariants = ['solid', 'outline', 'ghost'] as const
|
||||
|
||||
interface ButtonRecipeArg {
|
||||
semanticColors: string[]
|
||||
semanticColorNames: string[]
|
||||
}
|
||||
|
||||
const buttonRecipe = ({ semanticColors }: ButtonRecipeArg) => {
|
||||
const colorVariants = ['neutral', ...semanticColors]
|
||||
const buttonRecipe = ({ semanticColorNames }: ButtonRecipeArg) => {
|
||||
const colorVariants = ['neutral', ...semanticColorNames]
|
||||
|
||||
return defineRecipe({
|
||||
className: 'button',
|
||||
@@ -15,13 +15,15 @@ const buttonRecipe = ({ semanticColors }: ButtonRecipeArg) => {
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '0.5em',
|
||||
gap: 'xs',
|
||||
width: 'fit-content',
|
||||
borderRadius: '4px',
|
||||
paddingBlock: '0.25em',
|
||||
paddingInline: '0.5em',
|
||||
borderRadius: 'sm',
|
||||
paddingBlock: 'xs',
|
||||
paddingInline: 'sm',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 200ms ease-in-out'
|
||||
transition: 'all',
|
||||
transitionDuration: 'normal',
|
||||
transitionTimingFunction: 'easeOut'
|
||||
},
|
||||
variants: {
|
||||
color: {
|
||||
@@ -29,13 +31,19 @@ const buttonRecipe = ({ semanticColors }: ButtonRecipeArg) => {
|
||||
},
|
||||
size: {
|
||||
small: {
|
||||
fontSize: '0.875em'
|
||||
paddingBlock: 'calc({spacing.xs} * 0.5)',
|
||||
paddingInline: 'calc({spacing.xs} * 1)',
|
||||
fontSize: 'sm'
|
||||
},
|
||||
medium: {
|
||||
fontSize: '1em'
|
||||
paddingBlock: 'calc({spacing.xs} * 0.75)',
|
||||
paddingInline: 'calc({spacing.xs} * 1.25)',
|
||||
fontSize: 'base'
|
||||
},
|
||||
large: {
|
||||
fontSize: '1.125em'
|
||||
paddingBlock: 'calc({spacing.xs} * 1)',
|
||||
paddingInline: 'calc({spacing.xs} * 1.5)',
|
||||
fontSize: 'lg'
|
||||
}
|
||||
},
|
||||
variant: {
|
||||
|
||||
97
src/recipes/chip.ts
Normal file
97
src/recipes/chip.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { defineRecipe } from '@pandacss/dev'
|
||||
|
||||
export const chipVariants = ['solid', 'outline', 'ghost'] as const
|
||||
|
||||
interface ChipRecipeArg {
|
||||
semanticColorNames: string[]
|
||||
}
|
||||
|
||||
const chipRecipe = ({ semanticColorNames }: ChipRecipeArg) => {
|
||||
const colors = ['neutral', ...semanticColorNames]
|
||||
return defineRecipe({
|
||||
className: 'chip',
|
||||
base: {
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 'xs',
|
||||
lineHeight: '1',
|
||||
borderRadius: 'sm',
|
||||
fontWeight: 'semibold',
|
||||
lineHeightStep: 'none',
|
||||
userSelect: 'none'
|
||||
},
|
||||
variants: {
|
||||
color: {
|
||||
...Object.fromEntries(colors.map((color) => [color, {}]))
|
||||
},
|
||||
variant: {
|
||||
...Object.fromEntries(chipVariants.map((variant) => [variant, {}]))
|
||||
},
|
||||
size: {
|
||||
small: {
|
||||
paddingBlock: 'calc({spacing.sm} * 0.5)',
|
||||
paddingInline: 'calc({spacing.sm} * 0.75)',
|
||||
fontSize: 'xs'
|
||||
},
|
||||
medium: {
|
||||
paddingBlock: 'calc({spacing.sm} * 0.75)',
|
||||
paddingInline: 'calc({spacing.sm})',
|
||||
fontSize: 'sm'
|
||||
},
|
||||
large: {
|
||||
paddingBlock: 'calc({spacing.sm})',
|
||||
paddingInline: 'calc({spacing.sm} * 1.25)',
|
||||
fontSize: 'base'
|
||||
}
|
||||
}
|
||||
},
|
||||
compoundVariants: colors.flatMap((color) => {
|
||||
return chipVariants.map((variant) => {
|
||||
switch (variant) {
|
||||
case 'solid':
|
||||
return {
|
||||
color,
|
||||
variant,
|
||||
css: {
|
||||
backgroundColor: `{colors.${color}.9}`,
|
||||
color: `{colors.${color}.foreground}`
|
||||
}
|
||||
}
|
||||
case 'outline':
|
||||
return {
|
||||
color,
|
||||
variant,
|
||||
css: {
|
||||
border: '1px solid',
|
||||
borderColor: `{colors.${color}.6}`,
|
||||
color: `{colors.${color}.9}`
|
||||
}
|
||||
}
|
||||
case 'ghost':
|
||||
return {
|
||||
color,
|
||||
variant,
|
||||
css: {
|
||||
backgroundColor: `{colors.${color}.2}`,
|
||||
color: `{colors.${color}.9}`
|
||||
}
|
||||
}
|
||||
default:
|
||||
return {
|
||||
color,
|
||||
variant,
|
||||
css: {}
|
||||
}
|
||||
}
|
||||
})
|
||||
}),
|
||||
defaultVariants: {
|
||||
color: 'neutral',
|
||||
size: 'medium',
|
||||
variant: 'solid'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default chipRecipe
|
||||
@@ -1,11 +1,11 @@
|
||||
import { defineSlotRecipe } from '@pandacss/dev'
|
||||
|
||||
export interface DetailsRecipeArg {
|
||||
semanticColors: string[]
|
||||
semanticColorNames: string[]
|
||||
}
|
||||
|
||||
export const detailsRecipe = ({ semanticColors }: DetailsRecipeArg) => {
|
||||
const colorVariants = ['neutral', ...semanticColors]
|
||||
const detailsRecipe = ({ semanticColorNames }: DetailsRecipeArg) => {
|
||||
const colorVariants = ['neutral', ...semanticColorNames]
|
||||
const recipe = defineSlotRecipe({
|
||||
className: 'details',
|
||||
slots: ['summary', 'details'],
|
||||
@@ -13,16 +13,20 @@ export const detailsRecipe = ({ semanticColors }: DetailsRecipeArg) => {
|
||||
details: {
|
||||
display: 'block',
|
||||
overflow: 'hidden',
|
||||
borderRadius: '0.25em',
|
||||
transition: 'all 300ms ease-in-out'
|
||||
borderRadius: 'sm',
|
||||
transition: 'all',
|
||||
transitionTimingFunction: 'easeOut',
|
||||
transitionDuration: 'normal'
|
||||
},
|
||||
summary: {
|
||||
display: 'block',
|
||||
overflow: 'hidden',
|
||||
borderRadius: '0.25em',
|
||||
padding: '0.25em',
|
||||
borderRadius: 'sm',
|
||||
padding: 'xs',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 300ms ease-in-out'
|
||||
transition: 'all',
|
||||
transitionTimingFunction: 'easeOut',
|
||||
transitionDuration: 'normal'
|
||||
}
|
||||
},
|
||||
variants: {
|
||||
@@ -57,3 +61,5 @@ export const detailsRecipe = ({ semanticColors }: DetailsRecipeArg) => {
|
||||
|
||||
return recipe
|
||||
}
|
||||
|
||||
export default detailsRecipe
|
||||
|
||||
176
src/recipes/iconButton.ts
Normal file
176
src/recipes/iconButton.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import { defineRecipe, type SystemStyleObject } from '@pandacss/dev'
|
||||
|
||||
export const iconButtonVariants = ['solid', 'outline', 'ghost'] as const
|
||||
export const iconButtonShapes = ['circle', 'square'] 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',
|
||||
_disabled: {
|
||||
cursor: 'not-allowed'
|
||||
}
|
||||
},
|
||||
variants: {
|
||||
shape: {
|
||||
...Object.fromEntries(
|
||||
iconButtonShapes.map((shape) => {
|
||||
switch (shape) {
|
||||
case 'circle':
|
||||
return [
|
||||
shape,
|
||||
{
|
||||
borderRadius: 'full'
|
||||
}
|
||||
]
|
||||
case 'square':
|
||||
return [
|
||||
shape,
|
||||
{
|
||||
borderRadius: 'none'
|
||||
}
|
||||
]
|
||||
default:
|
||||
return [shape, {}]
|
||||
}
|
||||
})
|
||||
)
|
||||
},
|
||||
color: {
|
||||
...Object.fromEntries(colors.map((color) => [color, {}]))
|
||||
},
|
||||
variant: {
|
||||
...Object.fromEntries(iconButtonVariants.map((variant) => [variant, {}]))
|
||||
},
|
||||
size: {
|
||||
small: {
|
||||
padding: 'calc({spacing.xs} * 0.75) '
|
||||
},
|
||||
medium: {
|
||||
padding: 'xs'
|
||||
},
|
||||
large: {
|
||||
padding: 'calc({spacing.xs} * 1.25)'
|
||||
}
|
||||
}
|
||||
},
|
||||
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`
|
||||
},
|
||||
_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)`,
|
||||
cursor: 'not-allowed',
|
||||
pointerEvents: 'none',
|
||||
_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`
|
||||
},
|
||||
_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)`,
|
||||
cursor: 'not-allowed',
|
||||
pointerEvents: 'none',
|
||||
_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`
|
||||
},
|
||||
_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)`,
|
||||
cursor: 'not-allowed',
|
||||
pointerEvents: 'none',
|
||||
_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
|
||||
@@ -1,36 +1,69 @@
|
||||
import { defineRecipe } from '@pandacss/dev'
|
||||
|
||||
export const inputRecipe = defineRecipe({
|
||||
className: 'input',
|
||||
base: {
|
||||
display: 'inline-flex',
|
||||
borderRadius: '4px',
|
||||
cursor: 'pointer',
|
||||
paddingBlock: '0.25em',
|
||||
paddingInline: '0.5em',
|
||||
border: '1px solid',
|
||||
borderColor: 'neutral.7',
|
||||
backgroundColor: 'neutral.3',
|
||||
color: 'neutral.12',
|
||||
outline: 'none',
|
||||
transition: 'all 200ms ease-in-out',
|
||||
_hover: {
|
||||
backgroundColor: 'neutral.4'
|
||||
},
|
||||
_disabled: {
|
||||
backgroundColor: 'neutral.3/50',
|
||||
color: 'neutral.11/50',
|
||||
borderColor: 'neutral.6/50',
|
||||
cursor: 'not-allowed',
|
||||
_hover: {
|
||||
backgroundColor: 'neutral.6/50',
|
||||
color: 'neutral.11/50'
|
||||
export interface InputRecipeArg {
|
||||
semanticColorNames: string[]
|
||||
}
|
||||
|
||||
export const inputRecipe = ({ semanticColorNames }: InputRecipeArg) => {
|
||||
const colorVariants = ['neutral', ...semanticColorNames]
|
||||
|
||||
return defineRecipe({
|
||||
className: 'input',
|
||||
base: {
|
||||
display: 'inline-flex',
|
||||
borderRadius: 'sm',
|
||||
paddingBlock: 'xs',
|
||||
paddingInline: 'sm',
|
||||
border: '1px solid',
|
||||
outline: 'none',
|
||||
transitionProperty: 'color, background-color, border-color',
|
||||
transitionDuration: 'normal',
|
||||
transitionTimingFunction: 'easeOut',
|
||||
cursor: 'text',
|
||||
_disabled: {
|
||||
cursor: 'not-allowed'
|
||||
}
|
||||
},
|
||||
_active: {
|
||||
backgroundColor: 'neutral.8'
|
||||
variants: {
|
||||
color: {
|
||||
...Object.fromEntries(
|
||||
colorVariants.map((color) => [
|
||||
color,
|
||||
{
|
||||
borderColor: `${color}.6`,
|
||||
backgroundColor: `${color}.2`,
|
||||
color: `${color}.12`,
|
||||
_hover: {
|
||||
backgroundColor: `${color}.3`
|
||||
},
|
||||
_focus: {
|
||||
backgroundColor: `${color}.3`,
|
||||
borderColor: `${color}.7`
|
||||
},
|
||||
_disabled: {
|
||||
backgroundColor: `color-mix(in srgb, {colors.${color}.2} 30%, transparent)`,
|
||||
color: `color-mix(in srgb, {colors.${color}.11} 30%, transparent)`,
|
||||
borderColor: `color-mix(in srgb, {colors.${color}.6} 30%, transparent)`,
|
||||
_hover: {
|
||||
backgroundColor: `color-mix(in srgb, {colors.${color}.2} 30%, transparent)`,
|
||||
borderColor: `color-mix(in srgb, {colors.${color}.6} 30%, transparent)`,
|
||||
color: `color-mix(in srgb, {colors.${color}.11} 30%, transparent)`
|
||||
},
|
||||
_focus: {
|
||||
backgroundColor: `color-mix(in srgb, {colors.${color}.2} 30%, transparent)`,
|
||||
borderColor: `color-mix(in srgb, {colors.${color}.6} 30%, transparent)`,
|
||||
color: `color-mix(in srgb, {colors.${color}.11} 30%, transparent)`
|
||||
}
|
||||
}
|
||||
}
|
||||
])
|
||||
)
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
color: 'neutral'
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default inputRecipe
|
||||
|
||||
80
src/recipes/mark.ts
Normal file
80
src/recipes/mark.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { defineRecipe, type SystemStyleObject } from '@pandacss/dev'
|
||||
|
||||
const markVariants = ['highlight', 'bold', 'underline'] as const
|
||||
|
||||
interface MarkRecipeArg {
|
||||
semanticColorNames: string[]
|
||||
}
|
||||
|
||||
const markRecipe = ({ semanticColorNames }: MarkRecipeArg) => {
|
||||
const colors = ['neutral', ...semanticColorNames] as const
|
||||
return defineRecipe({
|
||||
className: 'mark',
|
||||
base: {
|
||||
backgroundColor: 'transparent',
|
||||
display: 'inline-block',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: 'inherit',
|
||||
gap: 'xs'
|
||||
},
|
||||
variants: {
|
||||
color: {
|
||||
...Object.fromEntries(colors.map((color) => [color, {}]))
|
||||
},
|
||||
variant: {
|
||||
...Object.fromEntries(markVariants.map((variant) => [variant, {}]))
|
||||
}
|
||||
},
|
||||
compoundVariants: markVariants.flatMap((variant) =>
|
||||
colors.map((color) => {
|
||||
switch (variant) {
|
||||
case 'highlight':
|
||||
return {
|
||||
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',
|
||||
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}`
|
||||
} as SystemStyleObject
|
||||
}
|
||||
case 'bold':
|
||||
return {
|
||||
color,
|
||||
variant,
|
||||
css: {
|
||||
fontWeight: 'bold',
|
||||
color: `{colors.${color}.9}`
|
||||
} as SystemStyleObject
|
||||
}
|
||||
case 'underline':
|
||||
return {
|
||||
color,
|
||||
variant,
|
||||
css: {
|
||||
textDecorationLine: 'underline',
|
||||
textDecorationThickness: '2px',
|
||||
textDecorationColor: `{colors.${color}.9}`
|
||||
} as SystemStyleObject
|
||||
}
|
||||
default:
|
||||
return { color, variant, css: {} }
|
||||
}
|
||||
})
|
||||
),
|
||||
defaultVariants: {
|
||||
color: 'neutral',
|
||||
variant: 'highlight'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default markRecipe
|
||||
export { markVariants }
|
||||
Reference in New Issue
Block a user