diff --git a/src/index.ts b/src/index.ts index d2048d8..a9bfb2c 100644 --- a/src/index.ts +++ b/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' + } + } } }) } diff --git a/src/keyframes/fade.ts b/src/keyframes/fade.ts new file mode 100644 index 0000000..6916126 --- /dev/null +++ b/src/keyframes/fade.ts @@ -0,0 +1,10 @@ +import { defineKeyframes } from '@pandacss/dev' + +const fadeKeyframes = defineKeyframes({ + fade: { + '0%': { opacity: '0' }, + '100%': { opacity: '1' } + } +}) + +export default fadeKeyframes diff --git a/src/recipes/alert.ts b/src/recipes/alert.ts new file mode 100644 index 0000000..c36eb4d --- /dev/null +++ b/src/recipes/alert.ts @@ -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 diff --git a/src/recipes/mark.ts b/src/recipes/mark.ts index e10eb14..1fccb1b 100644 --- a/src/recipes/mark.ts +++ b/src/recipes/mark.ts @@ -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' } })