@phcdevworks/spectre-ui 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/css-constants.ts","../src/tailwind/theme.ts","../src/tailwind/preset.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts"],"names":["theme","spectreTokens"],"mappings":"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","file":"index.cjs","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/utilities.css\";\nexport const spectreIndexStylesPath = \"@phcdevworks/spectre-ui/index.css\";\n\nexport const spectreStyles = {\n index: spectreIndexStylesPath,\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = (t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>;\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport { spectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\nconst { theme } = createSpectreTailwindTheme({ tokens: spectreTokens });\n\nexport const spectrePreset: TailwindConfig = {\n content: [],\n theme, // theme is guaranteed non-undefined now\n};\n\nexport const spectreTailwindPreset: TailwindConfig = spectrePreset;\n","export type ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\" | \"success\";\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant = \"primary\",\n size = \"md\",\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const classes: string[] = [\"sp-btn\"];\n\n const variantMap: Record<ButtonVariant, string> = {\n primary: \"sp-btn--primary\",\n secondary: \"sp-btn--secondary\",\n ghost: \"sp-btn--ghost\",\n danger: \"sp-btn--danger\",\n success: \"sp-btn--success\",\n };\n classes.push(variantMap[variant]);\n\n const sizeMap: Record<ButtonSize, string> = {\n sm: \"sp-btn--sm\",\n md: \"sp-btn--md\",\n lg: \"sp-btn--lg\",\n };\n classes.push(sizeMap[size]);\n\n if (fullWidth) classes.push(\"sp-btn--full\");\n if (loading) classes.push(\"sp-btn--loading\");\n if (disabled) classes.push(\"sp-btn--disabled\");\n if (iconOnly) classes.push(\"sp-btn--icon\");\n\n return classes.join(\" \").trim();\n}\n","export type CardVariant = \"elevated\" | \"flat\" | \"outline\" | \"ghost\";\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant = \"elevated\",\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const classes: string[] = [\"sp-card\"];\n\n const variantMap: Record<CardVariant, string> = {\n elevated: \"sp-card--elevated\",\n flat: \"sp-card--flat\",\n outline: \"sp-card--outline\",\n ghost: \"sp-card--ghost\",\n };\n classes.push(variantMap[variant]);\n\n if (interactive) classes.push(\"sp-card--interactive\");\n if (padded) classes.push(\"sp-card--padded\");\n if (fullHeight) classes.push(\"sp-card--full\");\n\n return classes.join(\" \").trim();\n}\n","export type InputState = \"default\" | \"error\" | \"success\" | \"disabled\";\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const { state = \"default\", size = \"md\", fullWidth = false } = opts;\n\n const classes: string[] = [\"sp-input\"];\n\n const sizeMap: Record<InputSize, string> = {\n sm: \"sp-input--sm\",\n md: \"sp-input--md\",\n lg: \"sp-input--lg\",\n };\n classes.push(sizeMap[size]);\n\n // State\n if (state === \"error\") classes.push(\"sp-input--error\");\n if (state === \"success\") classes.push(\"sp-input--success\");\n if (state === \"disabled\") classes.push(\"sp-input--disabled\");\n\n if (fullWidth) classes.push(\"sp-input--full\");\n\n return classes.join(\" \").trim();\n}\n"]}
1
+ {"version":3,"sources":["../src/css-constants.ts","../src/internal/cx.ts","../src/internal/resolve-option.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts","../src/recipes/badge.ts","../src/recipes/iconbox.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/utilities.css\";\nexport const spectreIndexStylesPath = \"@phcdevworks/spectre-ui/index.css\";\n\nexport const spectreStyles = {\n index: spectreIndexStylesPath,\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","export function cx(...parts: Array<string | false | null | undefined>): string {\n const seen = new Set<string>();\n const classes: string[] = [];\n\n for (const part of parts) {\n if (!part) continue;\n const trimmed = part.trim();\n if (!trimmed) continue;\n\n if (!/\\s/.test(trimmed)) {\n if (!seen.has(trimmed)) {\n seen.add(trimmed);\n classes.push(trimmed);\n }\n continue;\n }\n\n for (const token of trimmed.split(/\\s+/)) {\n if (!token || seen.has(token)) continue;\n seen.add(token);\n classes.push(token);\n }\n }\n\n return classes.join(\" \");\n}\n","type AllowedValues<T extends string> = readonly T[] | Record<T, unknown>;\n\nconst hasOwn = (value: object, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\nconst isAllowedValue = <T extends string>(value: T, allowed: AllowedValues<T>): boolean =>\n Array.isArray(allowed) ? allowed.includes(value) : hasOwn(allowed, value);\n\nexport function resolveOption<T extends string>(config: {\n name: string;\n value: T | undefined;\n allowed: AllowedValues<T>;\n fallback: T;\n}): T {\n const { name, value, allowed, fallback } = config;\n\n if (value === undefined) return fallback;\n if (isAllowedValue(value, allowed)) return value;\n\n if (process.env.NODE_ENV !== \"production\") {\n throw new Error(`[spectre-ui] Unknown ${name}: ${value}`);\n }\n\n return fallback;\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst buttonVariants = [\"primary\", \"secondary\", \"ghost\", \"danger\", \"success\"] as const;\nconst buttonSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type ButtonVariant = (typeof buttonVariants)[number];\nexport type ButtonSize = (typeof buttonSizes)[number];\n\nconst BUTTON_VARIANTS = {\n primary: true,\n secondary: true,\n ghost: true,\n danger: true,\n success: true,\n} as const;\n\nconst BUTTON_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant: variantInput,\n size: sizeInput,\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const variant = resolveOption({\n name: \"button variant\",\n value: variantInput,\n allowed: BUTTON_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"button size\",\n value: sizeInput,\n allowed: BUTTON_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<ButtonVariant, string> = {\n primary: \"sp-btn--primary\",\n secondary: \"sp-btn--secondary\",\n ghost: \"sp-btn--ghost\",\n danger: \"sp-btn--danger\",\n success: \"sp-btn--success\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<ButtonSize, string> = {\n sm: \"sp-btn--sm\",\n md: \"sp-btn--md\",\n lg: \"sp-btn--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\n \"sp-btn\",\n variantClass,\n sizeClass,\n fullWidth && \"sp-btn--full\",\n loading && \"sp-btn--loading\",\n disabled && \"sp-btn--disabled\",\n iconOnly && \"sp-btn--icon\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst cardVariants = [\"elevated\", \"flat\", \"outline\", \"ghost\"] as const;\n\nexport type CardVariant = (typeof cardVariants)[number];\n\nconst CARD_VARIANTS = {\n elevated: true,\n flat: true,\n outline: true,\n ghost: true,\n} as const;\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant: variantInput,\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const variant = resolveOption({\n name: \"card variant\",\n value: variantInput,\n allowed: CARD_VARIANTS,\n fallback: \"elevated\",\n });\n\n const variantMap: Record<CardVariant, string> = {\n elevated: \"sp-card--elevated\",\n flat: \"sp-card--flat\",\n outline: \"sp-card--outline\",\n ghost: \"sp-card--ghost\",\n };\n const variantClass = variantMap[variant];\n\n return cx(\n \"sp-card\",\n variantClass,\n interactive && \"sp-card--interactive\",\n padded && \"sp-card--padded\",\n fullHeight && \"sp-card--full\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst inputStates = [\"default\", \"error\", \"success\", \"disabled\"] as const;\nconst inputSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type InputState = (typeof inputStates)[number];\nexport type InputSize = (typeof inputSizes)[number];\n\nconst INPUT_STATES = {\n default: true,\n error: true,\n success: true,\n disabled: true,\n} as const;\n\nconst INPUT_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const { state: stateInput, size: sizeInput, fullWidth = false } = opts;\n\n const state = resolveOption({\n name: \"input state\",\n value: stateInput,\n allowed: INPUT_STATES,\n fallback: \"default\",\n });\n const size = resolveOption({\n name: \"input size\",\n value: sizeInput,\n allowed: INPUT_SIZES,\n fallback: \"md\",\n });\n\n const sizeMap: Record<InputSize, string> = {\n sm: \"sp-input--sm\",\n md: \"sp-input--md\",\n lg: \"sp-input--lg\",\n };\n const sizeClass = sizeMap[size];\n\n // State\n return cx(\n \"sp-input\",\n sizeClass,\n state === \"error\" && \"sp-input--error\",\n state === \"success\" && \"sp-input--success\",\n // Visual state only; actual disabled attribute is handled by adapters.\n state === \"disabled\" && \"sp-input--disabled\",\n fullWidth && \"sp-input--full\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst badgeVariants = [\"primary\", \"success\", \"warning\", \"danger\"] as const;\nconst badgeSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type BadgeVariant = (typeof badgeVariants)[number];\nexport type BadgeSize = (typeof badgeSizes)[number];\n\nconst BADGE_VARIANTS = {\n primary: true,\n success: true,\n warning: true,\n danger: true,\n} as const;\n\nconst BADGE_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface BadgeRecipeOptions {\n variant?: BadgeVariant;\n size?: BadgeSize;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput } = opts;\n\n const variant = resolveOption({\n name: \"badge variant\",\n value: variantInput,\n allowed: BADGE_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"badge size\",\n value: sizeInput,\n allowed: BADGE_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<BadgeVariant, string> = {\n primary: \"sp-badge--primary\",\n success: \"sp-badge--success\",\n warning: \"sp-badge--warning\",\n danger: \"sp-badge--danger\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<BadgeSize, string> = {\n sm: \"sp-badge--sm\",\n md: \"sp-badge--md\",\n lg: \"sp-badge--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\"sp-badge\", variantClass, sizeClass);\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst iconBoxVariants = [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] as const;\nconst iconBoxSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type IconBoxVariant = (typeof iconBoxVariants)[number];\nexport type IconBoxSize = (typeof iconBoxSizes)[number];\n\nconst ICONBOX_VARIANTS = {\n primary: true,\n success: true,\n warning: true,\n danger: true,\n info: true,\n} as const;\n\nconst ICONBOX_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface IconBoxRecipeOptions {\n variant?: IconBoxVariant;\n size?: IconBoxSize;\n}\n\nexport function getIconBoxClasses(opts: IconBoxRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput } = opts;\n\n const variant = resolveOption({\n name: \"icon box variant\",\n value: variantInput,\n allowed: ICONBOX_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"icon box size\",\n value: sizeInput,\n allowed: ICONBOX_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<IconBoxVariant, string> = {\n primary: \"sp-iconbox--primary\",\n success: \"sp-iconbox--success\",\n warning: \"sp-iconbox--warning\",\n danger: \"sp-iconbox--danger\",\n info: \"sp-iconbox--info\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<IconBoxSize, string> = {\n sm: \"sp-iconbox--sm\",\n md: \"sp-iconbox--md\",\n lg: \"sp-iconbox--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\"sp-iconbox\", variantClass, sizeClass);\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,3 @@
1
- import { Config } from 'tailwindcss';
2
- import { SpectreTokens } from '@phcdevworks/spectre-tokens';
3
1
  export { SpectreTokens, default as spectreTokens } from '@phcdevworks/spectre-tokens';
4
2
 
5
3
  declare const spectreBaseStylesPath = "@phcdevworks/spectre-ui/base.css";
@@ -12,24 +10,10 @@ declare const spectreStyles: {
12
10
  utilities: string;
13
11
  };
14
12
 
15
- type TailwindTheme = NonNullable<Config["theme"]>;
16
- interface SpectreTailwindTheme {
17
- theme: TailwindTheme;
18
- }
19
- interface CreateSpectreTailwindThemeOptions {
20
- tokens: SpectreTokens;
21
- overrides?: Partial<SpectreTokens>;
22
- }
23
- /**
24
- * Minimal, type-safe theme mapper.
25
- * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).
26
- */
27
- declare function createSpectreTailwindTheme(options: CreateSpectreTailwindThemeOptions): SpectreTailwindTheme;
28
-
29
- declare const spectrePreset: Config;
30
-
31
- type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "success";
32
- type ButtonSize = "sm" | "md" | "lg";
13
+ declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger", "success"];
14
+ declare const buttonSizes: readonly ["sm", "md", "lg"];
15
+ type ButtonVariant = (typeof buttonVariants)[number];
16
+ type ButtonSize = (typeof buttonSizes)[number];
33
17
  interface ButtonRecipeOptions {
34
18
  variant?: ButtonVariant;
35
19
  size?: ButtonSize;
@@ -40,7 +24,8 @@ interface ButtonRecipeOptions {
40
24
  }
41
25
  declare function getButtonClasses(opts?: ButtonRecipeOptions): string;
42
26
 
43
- type CardVariant = "elevated" | "flat" | "outline" | "ghost";
27
+ declare const cardVariants: readonly ["elevated", "flat", "outline", "ghost"];
28
+ type CardVariant = (typeof cardVariants)[number];
44
29
  interface CardRecipeOptions {
45
30
  variant?: CardVariant;
46
31
  interactive?: boolean;
@@ -49,8 +34,10 @@ interface CardRecipeOptions {
49
34
  }
50
35
  declare function getCardClasses(opts?: CardRecipeOptions): string;
51
36
 
52
- type InputState = "default" | "error" | "success" | "disabled";
53
- type InputSize = "sm" | "md" | "lg";
37
+ declare const inputStates: readonly ["default", "error", "success", "disabled"];
38
+ declare const inputSizes: readonly ["sm", "md", "lg"];
39
+ type InputState = (typeof inputStates)[number];
40
+ type InputSize = (typeof inputSizes)[number];
54
41
  interface InputRecipeOptions {
55
42
  state?: InputState;
56
43
  size?: InputSize;
@@ -58,4 +45,24 @@ interface InputRecipeOptions {
58
45
  }
59
46
  declare function getInputClasses(opts?: InputRecipeOptions): string;
60
47
 
61
- export { type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type CreateSpectreTailwindThemeOptions, type InputRecipeOptions, type InputSize, type InputState, type SpectreTailwindTheme, createSpectreTailwindTheme, getButtonClasses, getCardClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectrePreset, spectreStyles, spectreUtilitiesStylesPath };
48
+ declare const badgeVariants: readonly ["primary", "success", "warning", "danger"];
49
+ declare const badgeSizes: readonly ["sm", "md", "lg"];
50
+ type BadgeVariant = (typeof badgeVariants)[number];
51
+ type BadgeSize = (typeof badgeSizes)[number];
52
+ interface BadgeRecipeOptions {
53
+ variant?: BadgeVariant;
54
+ size?: BadgeSize;
55
+ }
56
+ declare function getBadgeClasses(opts?: BadgeRecipeOptions): string;
57
+
58
+ declare const iconBoxVariants: readonly ["primary", "success", "warning", "danger", "info"];
59
+ declare const iconBoxSizes: readonly ["sm", "md", "lg"];
60
+ type IconBoxVariant = (typeof iconBoxVariants)[number];
61
+ type IconBoxSize = (typeof iconBoxSizes)[number];
62
+ interface IconBoxRecipeOptions {
63
+ variant?: IconBoxVariant;
64
+ size?: IconBoxSize;
65
+ }
66
+ declare function getIconBoxClasses(opts?: IconBoxRecipeOptions): string;
67
+
68
+ export { type BadgeRecipeOptions, type BadgeSize, type BadgeVariant, type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type IconBoxRecipeOptions, type IconBoxSize, type IconBoxVariant, type InputRecipeOptions, type InputSize, type InputState, getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { Config } from 'tailwindcss';
2
- import { SpectreTokens } from '@phcdevworks/spectre-tokens';
3
1
  export { SpectreTokens, default as spectreTokens } from '@phcdevworks/spectre-tokens';
4
2
 
5
3
  declare const spectreBaseStylesPath = "@phcdevworks/spectre-ui/base.css";
@@ -12,24 +10,10 @@ declare const spectreStyles: {
12
10
  utilities: string;
13
11
  };
14
12
 
15
- type TailwindTheme = NonNullable<Config["theme"]>;
16
- interface SpectreTailwindTheme {
17
- theme: TailwindTheme;
18
- }
19
- interface CreateSpectreTailwindThemeOptions {
20
- tokens: SpectreTokens;
21
- overrides?: Partial<SpectreTokens>;
22
- }
23
- /**
24
- * Minimal, type-safe theme mapper.
25
- * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).
26
- */
27
- declare function createSpectreTailwindTheme(options: CreateSpectreTailwindThemeOptions): SpectreTailwindTheme;
28
-
29
- declare const spectrePreset: Config;
30
-
31
- type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "success";
32
- type ButtonSize = "sm" | "md" | "lg";
13
+ declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger", "success"];
14
+ declare const buttonSizes: readonly ["sm", "md", "lg"];
15
+ type ButtonVariant = (typeof buttonVariants)[number];
16
+ type ButtonSize = (typeof buttonSizes)[number];
33
17
  interface ButtonRecipeOptions {
34
18
  variant?: ButtonVariant;
35
19
  size?: ButtonSize;
@@ -40,7 +24,8 @@ interface ButtonRecipeOptions {
40
24
  }
41
25
  declare function getButtonClasses(opts?: ButtonRecipeOptions): string;
42
26
 
43
- type CardVariant = "elevated" | "flat" | "outline" | "ghost";
27
+ declare const cardVariants: readonly ["elevated", "flat", "outline", "ghost"];
28
+ type CardVariant = (typeof cardVariants)[number];
44
29
  interface CardRecipeOptions {
45
30
  variant?: CardVariant;
46
31
  interactive?: boolean;
@@ -49,8 +34,10 @@ interface CardRecipeOptions {
49
34
  }
50
35
  declare function getCardClasses(opts?: CardRecipeOptions): string;
51
36
 
52
- type InputState = "default" | "error" | "success" | "disabled";
53
- type InputSize = "sm" | "md" | "lg";
37
+ declare const inputStates: readonly ["default", "error", "success", "disabled"];
38
+ declare const inputSizes: readonly ["sm", "md", "lg"];
39
+ type InputState = (typeof inputStates)[number];
40
+ type InputSize = (typeof inputSizes)[number];
54
41
  interface InputRecipeOptions {
55
42
  state?: InputState;
56
43
  size?: InputSize;
@@ -58,4 +45,24 @@ interface InputRecipeOptions {
58
45
  }
59
46
  declare function getInputClasses(opts?: InputRecipeOptions): string;
60
47
 
61
- export { type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type CreateSpectreTailwindThemeOptions, type InputRecipeOptions, type InputSize, type InputState, type SpectreTailwindTheme, createSpectreTailwindTheme, getButtonClasses, getCardClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectrePreset, spectreStyles, spectreUtilitiesStylesPath };
48
+ declare const badgeVariants: readonly ["primary", "success", "warning", "danger"];
49
+ declare const badgeSizes: readonly ["sm", "md", "lg"];
50
+ type BadgeVariant = (typeof badgeVariants)[number];
51
+ type BadgeSize = (typeof badgeSizes)[number];
52
+ interface BadgeRecipeOptions {
53
+ variant?: BadgeVariant;
54
+ size?: BadgeSize;
55
+ }
56
+ declare function getBadgeClasses(opts?: BadgeRecipeOptions): string;
57
+
58
+ declare const iconBoxVariants: readonly ["primary", "success", "warning", "danger", "info"];
59
+ declare const iconBoxSizes: readonly ["sm", "md", "lg"];
60
+ type IconBoxVariant = (typeof iconBoxVariants)[number];
61
+ type IconBoxSize = (typeof iconBoxSizes)[number];
62
+ interface IconBoxRecipeOptions {
63
+ variant?: IconBoxVariant;
64
+ size?: IconBoxSize;
65
+ }
66
+ declare function getIconBoxClasses(opts?: IconBoxRecipeOptions): string;
67
+
68
+ export { type BadgeRecipeOptions, type BadgeSize, type BadgeVariant, type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type IconBoxRecipeOptions, type IconBoxSize, type IconBoxVariant, type InputRecipeOptions, type InputSize, type InputState, getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import spectreTokens from '@phcdevworks/spectre-tokens';
2
1
  export { default as spectreTokens } from '@phcdevworks/spectre-tokens';
3
2
 
4
3
  // src/css-constants.ts
@@ -13,49 +12,77 @@ var spectreStyles = {
13
12
  utilities: spectreUtilitiesStylesPath
14
13
  };
15
14
 
16
- // src/tailwind/theme.ts
17
- function createSpectreTailwindTheme(options) {
18
- const mergedTokens = {
19
- ...options.tokens ?? {},
20
- ...options.overrides ?? {}
21
- };
22
- const t = mergedTokens;
23
- const colors = t.colors ?? t.color ?? t.palette ?? {};
24
- const spacing = t.spacing ?? t.space ?? {};
25
- const borderRadius = t.radii ?? t.radius ?? {};
26
- const boxShadow = t.shadows ?? t.shadow ?? {};
27
- const fontFamily = t.typography?.families ?? t.fonts ?? {};
28
- const fontSize = t.typography?.scale ?? t.fontSize ?? {};
29
- const theme2 = {
30
- colors,
31
- spacing,
32
- borderRadius,
33
- boxShadow,
34
- fontFamily,
35
- fontSize
36
- };
37
- return { theme: theme2 };
15
+ // src/internal/cx.ts
16
+ function cx(...parts) {
17
+ const seen = /* @__PURE__ */ new Set();
18
+ const classes = [];
19
+ for (const part of parts) {
20
+ if (!part) continue;
21
+ const trimmed = part.trim();
22
+ if (!trimmed) continue;
23
+ if (!/\s/.test(trimmed)) {
24
+ if (!seen.has(trimmed)) {
25
+ seen.add(trimmed);
26
+ classes.push(trimmed);
27
+ }
28
+ continue;
29
+ }
30
+ for (const token of trimmed.split(/\s+/)) {
31
+ if (!token || seen.has(token)) continue;
32
+ seen.add(token);
33
+ classes.push(token);
34
+ }
35
+ }
36
+ return classes.join(" ");
38
37
  }
39
38
 
40
- // src/tailwind/preset.ts
41
- var { theme } = createSpectreTailwindTheme({ tokens: spectreTokens });
42
- var spectrePreset = {
43
- content: [],
44
- theme
45
- // theme is guaranteed non-undefined now
46
- };
39
+ // src/internal/resolve-option.ts
40
+ var hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
41
+ var isAllowedValue = (value, allowed) => Array.isArray(allowed) ? allowed.includes(value) : hasOwn(allowed, value);
42
+ function resolveOption(config) {
43
+ const { name, value, allowed, fallback } = config;
44
+ if (value === void 0) return fallback;
45
+ if (isAllowedValue(value, allowed)) return value;
46
+ if (process.env.NODE_ENV !== "production") {
47
+ throw new Error(`[spectre-ui] Unknown ${name}: ${value}`);
48
+ }
49
+ return fallback;
50
+ }
47
51
 
48
52
  // src/recipes/button.ts
53
+ var BUTTON_VARIANTS = {
54
+ primary: true,
55
+ secondary: true,
56
+ ghost: true,
57
+ danger: true,
58
+ success: true
59
+ };
60
+ var BUTTON_SIZES = {
61
+ sm: true,
62
+ md: true,
63
+ lg: true
64
+ };
49
65
  function getButtonClasses(opts = {}) {
50
66
  const {
51
- variant = "primary",
52
- size = "md",
67
+ variant: variantInput,
68
+ size: sizeInput,
53
69
  fullWidth = false,
54
70
  loading = false,
55
71
  disabled = false,
56
72
  iconOnly = false
57
73
  } = opts;
58
- const classes = ["sp-btn"];
74
+ const variant = resolveOption({
75
+ name: "button variant",
76
+ value: variantInput,
77
+ allowed: BUTTON_VARIANTS,
78
+ fallback: "primary"
79
+ });
80
+ const size = resolveOption({
81
+ name: "button size",
82
+ value: sizeInput,
83
+ allowed: BUTTON_SIZES,
84
+ fallback: "md"
85
+ });
59
86
  const variantMap = {
60
87
  primary: "sp-btn--primary",
61
88
  secondary: "sp-btn--secondary",
@@ -63,59 +90,189 @@ function getButtonClasses(opts = {}) {
63
90
  danger: "sp-btn--danger",
64
91
  success: "sp-btn--success"
65
92
  };
66
- classes.push(variantMap[variant]);
93
+ const variantClass = variantMap[variant];
67
94
  const sizeMap = {
68
95
  sm: "sp-btn--sm",
69
96
  md: "sp-btn--md",
70
97
  lg: "sp-btn--lg"
71
98
  };
72
- classes.push(sizeMap[size]);
73
- if (fullWidth) classes.push("sp-btn--full");
74
- if (loading) classes.push("sp-btn--loading");
75
- if (disabled) classes.push("sp-btn--disabled");
76
- if (iconOnly) classes.push("sp-btn--icon");
77
- return classes.join(" ").trim();
99
+ const sizeClass = sizeMap[size];
100
+ return cx(
101
+ "sp-btn",
102
+ variantClass,
103
+ sizeClass,
104
+ fullWidth && "sp-btn--full",
105
+ loading && "sp-btn--loading",
106
+ disabled && "sp-btn--disabled",
107
+ iconOnly && "sp-btn--icon"
108
+ );
78
109
  }
79
110
 
80
111
  // src/recipes/card.ts
112
+ var CARD_VARIANTS = {
113
+ elevated: true,
114
+ flat: true,
115
+ outline: true,
116
+ ghost: true
117
+ };
81
118
  function getCardClasses(opts = {}) {
82
119
  const {
83
- variant = "elevated",
120
+ variant: variantInput,
84
121
  interactive = false,
85
122
  padded = false,
86
123
  fullHeight = false
87
124
  } = opts;
88
- const classes = ["sp-card"];
125
+ const variant = resolveOption({
126
+ name: "card variant",
127
+ value: variantInput,
128
+ allowed: CARD_VARIANTS,
129
+ fallback: "elevated"
130
+ });
89
131
  const variantMap = {
90
132
  elevated: "sp-card--elevated",
91
133
  flat: "sp-card--flat",
92
134
  outline: "sp-card--outline",
93
135
  ghost: "sp-card--ghost"
94
136
  };
95
- classes.push(variantMap[variant]);
96
- if (interactive) classes.push("sp-card--interactive");
97
- if (padded) classes.push("sp-card--padded");
98
- if (fullHeight) classes.push("sp-card--full");
99
- return classes.join(" ").trim();
137
+ const variantClass = variantMap[variant];
138
+ return cx(
139
+ "sp-card",
140
+ variantClass,
141
+ interactive && "sp-card--interactive",
142
+ padded && "sp-card--padded",
143
+ fullHeight && "sp-card--full"
144
+ );
100
145
  }
101
146
 
102
147
  // src/recipes/input.ts
148
+ var INPUT_STATES = {
149
+ default: true,
150
+ error: true,
151
+ success: true,
152
+ disabled: true
153
+ };
154
+ var INPUT_SIZES = {
155
+ sm: true,
156
+ md: true,
157
+ lg: true
158
+ };
103
159
  function getInputClasses(opts = {}) {
104
- const { state = "default", size = "md", fullWidth = false } = opts;
105
- const classes = ["sp-input"];
160
+ const { state: stateInput, size: sizeInput, fullWidth = false } = opts;
161
+ const state = resolveOption({
162
+ name: "input state",
163
+ value: stateInput,
164
+ allowed: INPUT_STATES,
165
+ fallback: "default"
166
+ });
167
+ const size = resolveOption({
168
+ name: "input size",
169
+ value: sizeInput,
170
+ allowed: INPUT_SIZES,
171
+ fallback: "md"
172
+ });
106
173
  const sizeMap = {
107
174
  sm: "sp-input--sm",
108
175
  md: "sp-input--md",
109
176
  lg: "sp-input--lg"
110
177
  };
111
- classes.push(sizeMap[size]);
112
- if (state === "error") classes.push("sp-input--error");
113
- if (state === "success") classes.push("sp-input--success");
114
- if (state === "disabled") classes.push("sp-input--disabled");
115
- if (fullWidth) classes.push("sp-input--full");
116
- return classes.join(" ").trim();
178
+ const sizeClass = sizeMap[size];
179
+ return cx(
180
+ "sp-input",
181
+ sizeClass,
182
+ state === "error" && "sp-input--error",
183
+ state === "success" && "sp-input--success",
184
+ // Visual state only; actual disabled attribute is handled by adapters.
185
+ state === "disabled" && "sp-input--disabled",
186
+ fullWidth && "sp-input--full"
187
+ );
188
+ }
189
+
190
+ // src/recipes/badge.ts
191
+ var BADGE_VARIANTS = {
192
+ primary: true,
193
+ success: true,
194
+ warning: true,
195
+ danger: true
196
+ };
197
+ var BADGE_SIZES = {
198
+ sm: true,
199
+ md: true,
200
+ lg: true
201
+ };
202
+ function getBadgeClasses(opts = {}) {
203
+ const { variant: variantInput, size: sizeInput } = opts;
204
+ const variant = resolveOption({
205
+ name: "badge variant",
206
+ value: variantInput,
207
+ allowed: BADGE_VARIANTS,
208
+ fallback: "primary"
209
+ });
210
+ const size = resolveOption({
211
+ name: "badge size",
212
+ value: sizeInput,
213
+ allowed: BADGE_SIZES,
214
+ fallback: "md"
215
+ });
216
+ const variantMap = {
217
+ primary: "sp-badge--primary",
218
+ success: "sp-badge--success",
219
+ warning: "sp-badge--warning",
220
+ danger: "sp-badge--danger"
221
+ };
222
+ const variantClass = variantMap[variant];
223
+ const sizeMap = {
224
+ sm: "sp-badge--sm",
225
+ md: "sp-badge--md",
226
+ lg: "sp-badge--lg"
227
+ };
228
+ const sizeClass = sizeMap[size];
229
+ return cx("sp-badge", variantClass, sizeClass);
230
+ }
231
+
232
+ // src/recipes/iconbox.ts
233
+ var ICONBOX_VARIANTS = {
234
+ primary: true,
235
+ success: true,
236
+ warning: true,
237
+ danger: true,
238
+ info: true
239
+ };
240
+ var ICONBOX_SIZES = {
241
+ sm: true,
242
+ md: true,
243
+ lg: true
244
+ };
245
+ function getIconBoxClasses(opts = {}) {
246
+ const { variant: variantInput, size: sizeInput } = opts;
247
+ const variant = resolveOption({
248
+ name: "icon box variant",
249
+ value: variantInput,
250
+ allowed: ICONBOX_VARIANTS,
251
+ fallback: "primary"
252
+ });
253
+ const size = resolveOption({
254
+ name: "icon box size",
255
+ value: sizeInput,
256
+ allowed: ICONBOX_SIZES,
257
+ fallback: "md"
258
+ });
259
+ const variantMap = {
260
+ primary: "sp-iconbox--primary",
261
+ success: "sp-iconbox--success",
262
+ warning: "sp-iconbox--warning",
263
+ danger: "sp-iconbox--danger",
264
+ info: "sp-iconbox--info"
265
+ };
266
+ const variantClass = variantMap[variant];
267
+ const sizeMap = {
268
+ sm: "sp-iconbox--sm",
269
+ md: "sp-iconbox--md",
270
+ lg: "sp-iconbox--lg"
271
+ };
272
+ const sizeClass = sizeMap[size];
273
+ return cx("sp-iconbox", variantClass, sizeClass);
117
274
  }
118
275
 
119
- export { createSpectreTailwindTheme, getButtonClasses, getCardClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectrePreset, spectreStyles, spectreUtilitiesStylesPath };
276
+ export { getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
120
277
  //# sourceMappingURL=index.js.map
121
278
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/css-constants.ts","../src/tailwind/theme.ts","../src/tailwind/preset.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts"],"names":["theme"],"mappings":"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","file":"index.js","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/utilities.css\";\nexport const spectreIndexStylesPath = \"@phcdevworks/spectre-ui/index.css\";\n\nexport const spectreStyles = {\n index: spectreIndexStylesPath,\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = (t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>;\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport { spectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\nconst { theme } = createSpectreTailwindTheme({ tokens: spectreTokens });\n\nexport const spectrePreset: TailwindConfig = {\n content: [],\n theme, // theme is guaranteed non-undefined now\n};\n\nexport const spectreTailwindPreset: TailwindConfig = spectrePreset;\n","export type ButtonVariant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\" | \"success\";\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant = \"primary\",\n size = \"md\",\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const classes: string[] = [\"sp-btn\"];\n\n const variantMap: Record<ButtonVariant, string> = {\n primary: \"sp-btn--primary\",\n secondary: \"sp-btn--secondary\",\n ghost: \"sp-btn--ghost\",\n danger: \"sp-btn--danger\",\n success: \"sp-btn--success\",\n };\n classes.push(variantMap[variant]);\n\n const sizeMap: Record<ButtonSize, string> = {\n sm: \"sp-btn--sm\",\n md: \"sp-btn--md\",\n lg: \"sp-btn--lg\",\n };\n classes.push(sizeMap[size]);\n\n if (fullWidth) classes.push(\"sp-btn--full\");\n if (loading) classes.push(\"sp-btn--loading\");\n if (disabled) classes.push(\"sp-btn--disabled\");\n if (iconOnly) classes.push(\"sp-btn--icon\");\n\n return classes.join(\" \").trim();\n}\n","export type CardVariant = \"elevated\" | \"flat\" | \"outline\" | \"ghost\";\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant = \"elevated\",\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const classes: string[] = [\"sp-card\"];\n\n const variantMap: Record<CardVariant, string> = {\n elevated: \"sp-card--elevated\",\n flat: \"sp-card--flat\",\n outline: \"sp-card--outline\",\n ghost: \"sp-card--ghost\",\n };\n classes.push(variantMap[variant]);\n\n if (interactive) classes.push(\"sp-card--interactive\");\n if (padded) classes.push(\"sp-card--padded\");\n if (fullHeight) classes.push(\"sp-card--full\");\n\n return classes.join(\" \").trim();\n}\n","export type InputState = \"default\" | \"error\" | \"success\" | \"disabled\";\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const { state = \"default\", size = \"md\", fullWidth = false } = opts;\n\n const classes: string[] = [\"sp-input\"];\n\n const sizeMap: Record<InputSize, string> = {\n sm: \"sp-input--sm\",\n md: \"sp-input--md\",\n lg: \"sp-input--lg\",\n };\n classes.push(sizeMap[size]);\n\n // State\n if (state === \"error\") classes.push(\"sp-input--error\");\n if (state === \"success\") classes.push(\"sp-input--success\");\n if (state === \"disabled\") classes.push(\"sp-input--disabled\");\n\n if (fullWidth) classes.push(\"sp-input--full\");\n\n return classes.join(\" \").trim();\n}\n"]}
1
+ {"version":3,"sources":["../src/css-constants.ts","../src/internal/cx.ts","../src/internal/resolve-option.ts","../src/recipes/button.ts","../src/recipes/card.ts","../src/recipes/input.ts","../src/recipes/badge.ts","../src/recipes/iconbox.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/utilities.css\";\nexport const spectreIndexStylesPath = \"@phcdevworks/spectre-ui/index.css\";\n\nexport const spectreStyles = {\n index: spectreIndexStylesPath,\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","export function cx(...parts: Array<string | false | null | undefined>): string {\n const seen = new Set<string>();\n const classes: string[] = [];\n\n for (const part of parts) {\n if (!part) continue;\n const trimmed = part.trim();\n if (!trimmed) continue;\n\n if (!/\\s/.test(trimmed)) {\n if (!seen.has(trimmed)) {\n seen.add(trimmed);\n classes.push(trimmed);\n }\n continue;\n }\n\n for (const token of trimmed.split(/\\s+/)) {\n if (!token || seen.has(token)) continue;\n seen.add(token);\n classes.push(token);\n }\n }\n\n return classes.join(\" \");\n}\n","type AllowedValues<T extends string> = readonly T[] | Record<T, unknown>;\n\nconst hasOwn = (value: object, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\nconst isAllowedValue = <T extends string>(value: T, allowed: AllowedValues<T>): boolean =>\n Array.isArray(allowed) ? allowed.includes(value) : hasOwn(allowed, value);\n\nexport function resolveOption<T extends string>(config: {\n name: string;\n value: T | undefined;\n allowed: AllowedValues<T>;\n fallback: T;\n}): T {\n const { name, value, allowed, fallback } = config;\n\n if (value === undefined) return fallback;\n if (isAllowedValue(value, allowed)) return value;\n\n if (process.env.NODE_ENV !== \"production\") {\n throw new Error(`[spectre-ui] Unknown ${name}: ${value}`);\n }\n\n return fallback;\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst buttonVariants = [\"primary\", \"secondary\", \"ghost\", \"danger\", \"success\"] as const;\nconst buttonSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type ButtonVariant = (typeof buttonVariants)[number];\nexport type ButtonSize = (typeof buttonSizes)[number];\n\nconst BUTTON_VARIANTS = {\n primary: true,\n secondary: true,\n ghost: true,\n danger: true,\n success: true,\n} as const;\n\nconst BUTTON_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant: variantInput,\n size: sizeInput,\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const variant = resolveOption({\n name: \"button variant\",\n value: variantInput,\n allowed: BUTTON_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"button size\",\n value: sizeInput,\n allowed: BUTTON_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<ButtonVariant, string> = {\n primary: \"sp-btn--primary\",\n secondary: \"sp-btn--secondary\",\n ghost: \"sp-btn--ghost\",\n danger: \"sp-btn--danger\",\n success: \"sp-btn--success\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<ButtonSize, string> = {\n sm: \"sp-btn--sm\",\n md: \"sp-btn--md\",\n lg: \"sp-btn--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\n \"sp-btn\",\n variantClass,\n sizeClass,\n fullWidth && \"sp-btn--full\",\n loading && \"sp-btn--loading\",\n disabled && \"sp-btn--disabled\",\n iconOnly && \"sp-btn--icon\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst cardVariants = [\"elevated\", \"flat\", \"outline\", \"ghost\"] as const;\n\nexport type CardVariant = (typeof cardVariants)[number];\n\nconst CARD_VARIANTS = {\n elevated: true,\n flat: true,\n outline: true,\n ghost: true,\n} as const;\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant: variantInput,\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const variant = resolveOption({\n name: \"card variant\",\n value: variantInput,\n allowed: CARD_VARIANTS,\n fallback: \"elevated\",\n });\n\n const variantMap: Record<CardVariant, string> = {\n elevated: \"sp-card--elevated\",\n flat: \"sp-card--flat\",\n outline: \"sp-card--outline\",\n ghost: \"sp-card--ghost\",\n };\n const variantClass = variantMap[variant];\n\n return cx(\n \"sp-card\",\n variantClass,\n interactive && \"sp-card--interactive\",\n padded && \"sp-card--padded\",\n fullHeight && \"sp-card--full\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst inputStates = [\"default\", \"error\", \"success\", \"disabled\"] as const;\nconst inputSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type InputState = (typeof inputStates)[number];\nexport type InputSize = (typeof inputSizes)[number];\n\nconst INPUT_STATES = {\n default: true,\n error: true,\n success: true,\n disabled: true,\n} as const;\n\nconst INPUT_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const { state: stateInput, size: sizeInput, fullWidth = false } = opts;\n\n const state = resolveOption({\n name: \"input state\",\n value: stateInput,\n allowed: INPUT_STATES,\n fallback: \"default\",\n });\n const size = resolveOption({\n name: \"input size\",\n value: sizeInput,\n allowed: INPUT_SIZES,\n fallback: \"md\",\n });\n\n const sizeMap: Record<InputSize, string> = {\n sm: \"sp-input--sm\",\n md: \"sp-input--md\",\n lg: \"sp-input--lg\",\n };\n const sizeClass = sizeMap[size];\n\n // State\n return cx(\n \"sp-input\",\n sizeClass,\n state === \"error\" && \"sp-input--error\",\n state === \"success\" && \"sp-input--success\",\n // Visual state only; actual disabled attribute is handled by adapters.\n state === \"disabled\" && \"sp-input--disabled\",\n fullWidth && \"sp-input--full\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst badgeVariants = [\"primary\", \"success\", \"warning\", \"danger\"] as const;\nconst badgeSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type BadgeVariant = (typeof badgeVariants)[number];\nexport type BadgeSize = (typeof badgeSizes)[number];\n\nconst BADGE_VARIANTS = {\n primary: true,\n success: true,\n warning: true,\n danger: true,\n} as const;\n\nconst BADGE_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface BadgeRecipeOptions {\n variant?: BadgeVariant;\n size?: BadgeSize;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput } = opts;\n\n const variant = resolveOption({\n name: \"badge variant\",\n value: variantInput,\n allowed: BADGE_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"badge size\",\n value: sizeInput,\n allowed: BADGE_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<BadgeVariant, string> = {\n primary: \"sp-badge--primary\",\n success: \"sp-badge--success\",\n warning: \"sp-badge--warning\",\n danger: \"sp-badge--danger\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<BadgeSize, string> = {\n sm: \"sp-badge--sm\",\n md: \"sp-badge--md\",\n lg: \"sp-badge--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\"sp-badge\", variantClass, sizeClass);\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst iconBoxVariants = [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] as const;\nconst iconBoxSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type IconBoxVariant = (typeof iconBoxVariants)[number];\nexport type IconBoxSize = (typeof iconBoxSizes)[number];\n\nconst ICONBOX_VARIANTS = {\n primary: true,\n success: true,\n warning: true,\n danger: true,\n info: true,\n} as const;\n\nconst ICONBOX_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface IconBoxRecipeOptions {\n variant?: IconBoxVariant;\n size?: IconBoxSize;\n}\n\nexport function getIconBoxClasses(opts: IconBoxRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput } = opts;\n\n const variant = resolveOption({\n name: \"icon box variant\",\n value: variantInput,\n allowed: ICONBOX_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"icon box size\",\n value: sizeInput,\n allowed: ICONBOX_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<IconBoxVariant, string> = {\n primary: \"sp-iconbox--primary\",\n success: \"sp-iconbox--success\",\n warning: \"sp-iconbox--warning\",\n danger: \"sp-iconbox--danger\",\n info: \"sp-iconbox--info\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<IconBoxSize, string> = {\n sm: \"sp-iconbox--sm\",\n md: \"sp-iconbox--md\",\n lg: \"sp-iconbox--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\"sp-iconbox\", variantClass, sizeClass);\n}\n"]}