From cb3f7fb70164f34c33df814cc809ce29a9b989b2 Mon Sep 17 00:00:00 2001 From: SrJuggernaut Date: Mon, 29 Sep 2025 12:31:59 -0600 Subject: [PATCH] feat: enhance UI components and update build configuration --- package.json | 6 ++-- src/index.ts | 18 ++++++----- src/recipes/button.ts | 67 ++++++++++++++++++++++++++------------- src/recipes/chip.ts | 53 +++++++++++++++++++++---------- src/recipes/details.ts | 4 ++- src/recipes/iconButton.ts | 35 ++++++++++---------- src/recipes/mark.ts | 2 +- tsconfig.json | 10 ++++-- 8 files changed, 125 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index 7d63a6b..b9b4ab0 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,11 @@ { "name": "@srjuggernaut-dev/srjuggernaut-panda-preset", - "module": "dist/index.js", + "main": "dist/index.js", "type": "module", "files": [ "dist/**/*", "README.md" ], - "main": "dist/index.js", "version": "0.0.10", "scripts": { "prepare": "ts-patch install -s && bun .husky/install.ts", @@ -26,7 +25,8 @@ "lint-staged": "^16.1.5", "ts-patch": "^3.3.0", "typescript": "^5", - "typescript-transform-paths": "^3.5.5" + "typescript-transform-paths": "^3.5.5", + "vite": "^7.1.7" }, "peerDependencies": { "@pandacss/dev": "^1.2.0", diff --git a/src/index.ts b/src/index.ts index 8505d58..b416851 100644 --- a/src/index.ts +++ b/src/index.ts @@ -191,7 +191,9 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => { conditions: { extend: { active: '&:is(:active, [data-active], [data-state="active"], [data-state="open"])', - open: '&:is(:open, [open], [data-open], [data-state="open"])' + open: '&:is(:open, [open], [data-open], [data-state="open"])', + checked: '&:is(:checked, [data-checked], [data-state="checked"])', + disabled: '&:is(:disabled, [data-disabled], [data-state="disabled"])' } }, globalCss: { @@ -245,11 +247,11 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => { fontSize: 'xs' }, a: { - color: 'inherit', + color: 'primary.9', textDecoration: 'none', fontWeight: 'semibold', _hover: { - color: 'primary.9' + color: 'primary.10' } }, '@media (prefers-reduced-motion: no-preference)': { @@ -263,9 +265,9 @@ const srJuggernautPandaPreset = (config?: ThemeConfig) => { export default srJuggernautPandaPreset -export { buttonVariants } from '@/recipes/button.js' -export { chipVariants } from '@/recipes/chip.js' -export { iconButtonShapes, iconButtonVariants } from '@/recipes/iconButton.js' -export { markVariants } from '@/recipes/mark.js' +export { buttonVariants } from '@/recipes/button' +export { chipVariants } from '@/recipes/chip' +export { iconButtonShapes, iconButtonVariants } from '@/recipes/iconButton' +export { markVariants } from '@/recipes/mark' -export { BrandColor, ColorVariation, NeutralColor } from '@/types.js' +export { BrandColor, ColorVariation, NeutralColor } from '@/types' diff --git a/src/recipes/button.ts b/src/recipes/button.ts index d269ffa..92b2c31 100644 --- a/src/recipes/button.ts +++ b/src/recipes/button.ts @@ -1,6 +1,7 @@ import { defineRecipe } from '@pandacss/dev' export const buttonVariants = ['solid', 'outline', 'ghost'] as const +export const buttonSizes = ['small', 'medium', 'large'] as const interface ButtonRecipeArg { semanticColorNames: string[] @@ -12,6 +13,7 @@ const buttonRecipe = ({ semanticColorNames }: ButtonRecipeArg) => { return defineRecipe({ className: 'button', base: { + all: 'unset', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', @@ -23,28 +25,54 @@ const buttonRecipe = ({ semanticColorNames }: ButtonRecipeArg) => { cursor: 'pointer', transitionProperty: 'color, background-color, border-color', transitionDuration: 'normal', - transitionTimingFunction: 'easeOut' + transitionTimingFunction: 'easeOut', + _disabled: { + cursor: 'not-allowed', + _hover: { + cursor: 'not-allowed' + } + } }, variants: { color: { ...Object.fromEntries(colorVariants.map((color) => [color, {}])) }, size: { - small: { - paddingBlock: 'calc({spacing.xs} * 0.5)', - paddingInline: 'calc({spacing.xs} * 1)', - fontSize: 'sm' - }, - medium: { - paddingBlock: 'calc({spacing.xs} * 0.75)', - paddingInline: 'calc({spacing.xs} * 1.25)', - fontSize: 'base' - }, - large: { - paddingBlock: 'calc({spacing.xs} * 1)', - paddingInline: 'calc({spacing.xs} * 1.5)', - fontSize: 'lg' - } + ...Object.fromEntries( + buttonSizes.map((size) => { + switch (size) { + case 'small': + return [ + size, + { + paddingBlock: 'calc({spacing.xs} * 0.5)', + paddingInline: 'calc({spacing.xs} * 1)', + fontSize: 'sm' + } + ] + case 'medium': + return [ + size, + { + paddingBlock: 'calc({spacing.xs} * 0.75)', + paddingInline: 'calc({spacing.xs} * 1.25)', + fontSize: 'base' + } + ] + case 'large': + return [ + size, + { + paddingBlock: 'calc({spacing.xs} * 1)', + paddingInline: 'calc({spacing.xs} * 1.5)', + fontSize: 'lg' + } + ] + default: + return [size, {}] + } + }) + ) }, variant: { ...Object.fromEntries(buttonVariants.map((variant) => [variant, {}])) @@ -74,8 +102,6 @@ const buttonRecipe = ({ semanticColorNames }: ButtonRecipeArg) => { 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` @@ -102,14 +128,13 @@ const buttonRecipe = ({ semanticColorNames }: ButtonRecipeArg) => { _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)` } } } } + // case 'solid' or unmatched: default: return { color, @@ -129,8 +154,6 @@ const buttonRecipe = ({ semanticColorNames }: ButtonRecipeArg) => { _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)` diff --git a/src/recipes/chip.ts b/src/recipes/chip.ts index c0186b6..49203f9 100644 --- a/src/recipes/chip.ts +++ b/src/recipes/chip.ts @@ -1,6 +1,7 @@ -import { defineRecipe } from '@pandacss/dev' +import { defineRecipe, type SystemStyleObject } from '@pandacss/dev' export const chipVariants = ['solid', 'outline', 'ghost'] as const +export const chipSizes = ['small', 'medium', 'large'] as const interface ChipRecipeArg { semanticColorNames: string[] @@ -29,21 +30,41 @@ const chipRecipe = ({ semanticColorNames }: ChipRecipeArg) => { ...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' - } + ...Object.fromEntries( + chipSizes.map((size) => { + switch (size) { + case 'small': + return [ + size, + { + paddingBlock: 'calc({spacing.sm} * 0.5)', + paddingInline: 'calc({spacing.sm} * 0.75)', + fontSize: 'xs' + } as SystemStyleObject + ] + case 'medium': + return [ + size, + { + paddingBlock: 'calc({spacing.sm} * 0.75)', + paddingInline: 'calc({spacing.sm})', + fontSize: 'sm' + } as SystemStyleObject + ] + case 'large': + return [ + size, + { + paddingBlock: 'calc({spacing.sm})', + paddingInline: 'calc({spacing.sm} * 1.25)', + fontSize: 'base' + } as SystemStyleObject + ] + default: + return [size, {}] + } + }) + ) } }, compoundVariants: colors.flatMap((color) => { diff --git a/src/recipes/details.ts b/src/recipes/details.ts index bcb54e1..81f9f99 100644 --- a/src/recipes/details.ts +++ b/src/recipes/details.ts @@ -1,5 +1,7 @@ import { defineSlotRecipe } from '@pandacss/dev' +export const detailsSlots = ['summary', 'details'] as const + export interface DetailsRecipeArg { semanticColorNames: string[] } @@ -8,7 +10,7 @@ const detailsRecipe = ({ semanticColorNames }: DetailsRecipeArg) => { const colorVariants = ['neutral', ...semanticColorNames] const recipe = defineSlotRecipe({ className: 'details', - slots: ['summary', 'details'], + slots: detailsSlots, base: { details: { display: 'block', diff --git a/src/recipes/iconButton.ts b/src/recipes/iconButton.ts index 99c0695..b1303eb 100644 --- a/src/recipes/iconButton.ts +++ b/src/recipes/iconButton.ts @@ -2,6 +2,7 @@ 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[] @@ -23,7 +24,10 @@ const iconButtonRecipe = ({ semanticColorNames }: IconButtonRecipeArg) => { transitionDuration: 'normal', transitionTimingFunction: 'easeOut', _disabled: { - cursor: 'not-allowed' + cursor: 'not-allowed', + _hover: { + cursor: 'not-allowed' + } } }, variants: { @@ -58,15 +62,20 @@ const iconButtonRecipe = ({ semanticColorNames }: IconButtonRecipeArg) => { ...Object.fromEntries(iconButtonVariants.map((variant) => [variant, {}])) }, size: { - small: { - padding: 'calc({spacing.sm} * 0.5)' - }, - medium: { - padding: 'calc({spacing.sm} * 0.75)' - }, - large: { - padding: 'calc({spacing.sm})' - } + ...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) => @@ -89,8 +98,6 @@ const iconButtonRecipe = ({ semanticColorNames }: IconButtonRecipeArg) => { _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)` @@ -119,8 +126,6 @@ const iconButtonRecipe = ({ semanticColorNames }: IconButtonRecipeArg) => { 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` @@ -147,8 +152,6 @@ const iconButtonRecipe = ({ semanticColorNames }: IconButtonRecipeArg) => { _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)` } diff --git a/src/recipes/mark.ts b/src/recipes/mark.ts index 1fccb1b..2331b3a 100644 --- a/src/recipes/mark.ts +++ b/src/recipes/mark.ts @@ -100,7 +100,7 @@ const markRecipe = ({ semanticColorNames }: MarkRecipeArg) => { ), defaultVariants: { color: 'primary', - variant: 'highlight' + variant: 'bold' } }) } diff --git a/tsconfig.json b/tsconfig.json index 813d9e6..25799bd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,15 +4,19 @@ // Environment setup & latest features "lib": ["esnext"], "target": "es2024", - "module": "NodeNext", + "module": "ESNext", "moduleDetection": "auto", "allowJs": false, // Bundler mode "outDir": "./dist/", - "moduleResolution": "NodeNext", - // "verbatimModuleSyntax": true, + "rootDir": "./src", + "moduleResolution": "bundler", "declaration": true, + "declarationMap": true, + "sourceMap": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, // Best practices "strict": true,