@phcdevworks/spectre-ui 1.0.0 → 1.1.0

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.
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ### **The Blueprint (Layer 2 of the Spectre 8-Layer Arsenal)**
4
4
 
5
- `@phcdevworks/spectre-ui` is the structural engine of the Spectre design system. It consumes the raw "DNA" from `@phcdevworks/spectre-tokens` and translates it into standard CSS, a localized Tailwind preset, and type-safe class recipes.
5
+ `@phcdevworks/spectre-ui` is the structural engine of the Spectre design system. It translates the design "DNA" from `@phcdevworks/spectre-tokens` into CSS structure, localized Tailwind presets, and type-safe class recipes.
6
6
 
7
7
  🤝 **[Contributing Guide](CONTRIBUTING.md)** | 📝 **[Changelog](CHANGELOG.md)** | 🏛️ **[Spectre Arsenal](https://github.com/phcdevworks)**
8
8
 
@@ -10,9 +10,9 @@
10
10
 
11
11
  ## 🏗️ Core Architecture
12
12
 
13
- This package operates as a pure structural layer. It follows a strict **Zero-Hex Enforcement** policy—visual values are imported via `--sp-*` variables, ensuring that if tokens change, the entire UI layer updates automatically.
13
+ This package operates as a pure **Blueprint Layer**. It follows a strict **Zero-Hex Enforcement** policy—visual values are imported via `--sp-*` variables, ensuring that if tokens change, the entire UI layer updates automatically.
14
14
 
15
- - 💎 **Token-Driven**: Fully compatible with `@phcdevworks/spectre-tokens` v2.0.0.
15
+ - 💎 **Token-Driven**: Fully compatible with `@phcdevworks/spectre-tokens` v2.1.0.
16
16
  - 📦 **Precompiled CSS**: Ships `base`, `components`, and `utilities` bundles.
17
17
  - 🧪 **Type-Safe Recipes**: Pure JS/TS functions for generating framework-agnostic class strings.
18
18
  - 🌪️ **Tailwind Preset**: Mirrors the design scale into the Tailwind utility engine.
@@ -117,5 +117,4 @@ npm test
117
117
 
118
118
  ## ❤️ Support & Community
119
119
 
120
- - **Sponsor**: [GitHub Sponsors](https://github.com/sponsors/phcdevworks) | [Buy Me a Coffee](https://buymeacoffee.com/phcdevworks)
121
120
  - **License**: MIT © [PHCDevworks](https://phcdevworks.com)
package/dist/base.css CHANGED
@@ -54,7 +54,7 @@
54
54
  }
55
55
 
56
56
  :focus-visible {
57
- outline: var(--sp-focus-ring-width) solid var(--sp-color-focus-primary);
57
+ outline: var(--sp-focus-ring-width) var(--sp-focus-ring-style) var(--sp-color-focus-primary);
58
58
  outline-offset: var(--sp-focus-ring-offset);
59
59
  }
60
60
 
@@ -1,8 +1,8 @@
1
1
  @layer components {
2
2
 
3
3
  :root {
4
- /* structural border width — swap to token when spectre-tokens ships sp-border-width-base */
5
- --sp-component-border-width: 1px;
4
+ /* structural border width */
5
+ --sp-component-border-width: var(--sp-border-width-base);
6
6
 
7
7
  /* button roles */
8
8
  --sp-component-button-border-base: var(--sp-component-button-ghost-bg);
@@ -39,6 +39,8 @@
39
39
  --sp-component-button-success-bg-disabled: var(--sp-button-success-bgdisabled);
40
40
  --sp-component-button-success-text: var(--sp-button-success-text);
41
41
  --sp-component-button-success-text-disabled: var(--sp-button-success-textdisabled);
42
+ /* FLAG: buttons.cta tokens in spectre-tokens v2.x use warning.500 (Gold),
43
+ which violates the Aesthetic Audit guardrails. Remaining on accent palette. */
42
44
  --sp-component-button-cta-bg: var(--sp-color-accent-600);
43
45
  --sp-component-button-cta-bg-hover: var(--sp-color-accent-700);
44
46
  --sp-component-button-cta-bg-active: var(--sp-color-accent-800);
@@ -142,34 +144,57 @@
142
144
  /* testimonial roles */
143
145
  --sp-component-testimonial-bg: var(--sp-surface-card);
144
146
  --sp-component-testimonial-border: var(--sp-color-neutral-200);
145
- --sp-component-testimonial-text: var(--sp-text-on-surface-muted);
146
- --sp-component-testimonial-author-name: var(--sp-text-on-surface-default);
147
- --sp-component-testimonial-author-title: var(--sp-text-on-surface-subtle);
147
+ --sp-component-testimonial-text: var(--sp-color-neutral-700);
148
+ --sp-component-testimonial-author-name: var(--sp-color-neutral-900);
149
+ --sp-component-testimonial-author-title: var(--sp-color-neutral-500);
148
150
  --sp-component-testimonial-quote-mark: var(--sp-color-neutral-300);
149
151
 
150
152
  /* pricing card roles */
151
153
  --sp-component-pricing-card-bg: var(--sp-surface-card);
152
154
  --sp-component-pricing-card-border: var(--sp-color-neutral-200);
155
+ /* FLAG: component.pricingCard.featuredBg in tokens is info.600 (Blue), which clashing
156
+ with the warning.500 (Gold) badge. Remaining on neutral-900 to pass Aesthetic Audit. */
153
157
  --sp-component-pricing-card-featured-bg: var(--sp-color-neutral-900);
154
158
  --sp-component-pricing-card-featured-text: var(--sp-color-neutral-50);
155
159
  --sp-component-pricing-card-featured-badge-bg: var(--sp-color-warning-500);
156
160
  --sp-component-pricing-card-featured-badge-text: var(--sp-color-neutral-900);
157
- --sp-component-pricing-card-price: var(--sp-text-on-surface-default);
161
+ --sp-component-pricing-card-price: var(--sp-color-neutral-900);
158
162
  --sp-component-pricing-card-featured-price: var(--sp-color-neutral-50);
159
- --sp-component-pricing-card-price-description: var(--sp-text-on-surface-subtle);
163
+ --sp-component-pricing-card-price-description: var(--sp-color-neutral-500);
160
164
 
161
165
  /* rating roles */
162
166
  --sp-component-rating-star-filled: var(--sp-color-warning-500);
163
167
  --sp-component-rating-star-empty: var(--sp-color-neutral-200);
164
- --sp-component-rating-text: var(--sp-text-on-surface-subtle);
168
+ --sp-component-rating-text: var(--sp-color-neutral-500);
165
169
  }
166
170
 
167
171
  /* dark mode overrides for complex component tokens not yet exported by spectre-tokens v2.x */
168
172
  :root[data-spectre-theme="dark"] {
173
+ --sp-component-testimonial-bg: var(--sp-color-neutral-800);
169
174
  --sp-component-testimonial-border: var(--sp-color-neutral-700);
175
+ --sp-component-testimonial-text: var(--sp-color-neutral-300);
176
+ --sp-component-testimonial-author-name: var(--sp-color-neutral-100);
177
+ --sp-component-testimonial-author-title: var(--sp-color-neutral-400);
170
178
  --sp-component-testimonial-quote-mark: var(--sp-color-neutral-600);
179
+
180
+ --sp-component-pricing-card-bg: var(--sp-color-neutral-800);
171
181
  --sp-component-pricing-card-border: var(--sp-color-neutral-700);
182
+ --sp-component-pricing-card-price: var(--sp-color-neutral-100);
183
+ --sp-component-pricing-card-price-description: var(--sp-color-neutral-400);
184
+
172
185
  --sp-component-rating-star-empty: var(--sp-color-neutral-700);
186
+ --sp-component-rating-text: var(--sp-color-neutral-400);
187
+
188
+ --sp-component-badge-success-bg: var(--sp-color-success-800);
189
+ --sp-component-badge-success-text: var(--sp-color-success-100);
190
+ --sp-component-badge-warning-bg: var(--sp-color-warning-800);
191
+ --sp-component-badge-warning-text: var(--sp-color-warning-100);
192
+ --sp-component-badge-danger-bg: var(--sp-color-error-800);
193
+ --sp-component-badge-danger-text: var(--sp-color-error-100);
194
+ --sp-component-badge-neutral-bg: var(--sp-color-neutral-700);
195
+ --sp-component-badge-neutral-text: var(--sp-color-neutral-100);
196
+ --sp-component-badge-info-bg: var(--sp-color-info-800);
197
+ --sp-component-badge-info-text: var(--sp-color-info-100);
173
198
 
174
199
  --sp-component-badge-success-bg-hover: var(--sp-color-success-700);
175
200
  --sp-component-badge-warning-bg-hover: var(--sp-color-warning-700);
@@ -495,6 +520,10 @@
495
520
  width: 100%;
496
521
  }
497
522
 
523
+ .sp-input--pill {
524
+ border-radius: var(--sp-radius-pill);
525
+ }
526
+
498
527
  .sp-input:focus,
499
528
  .sp-input--focus {
500
529
  border-color: var(--sp-component-input-role-border-focus);
@@ -580,6 +609,11 @@
580
609
  height: 100%;
581
610
  }
582
611
 
612
+ .sp-card--disabled {
613
+ opacity: var(--sp-opacity-disabled);
614
+ pointer-events: none;
615
+ }
616
+
583
617
  .sp-card--interactive {
584
618
  cursor: pointer;
585
619
  transition:
@@ -698,6 +732,11 @@
698
732
  transition: background-color var(--sp-duration-fast) var(--sp-easing-out);
699
733
  }
700
734
 
735
+ .sp-badge--disabled {
736
+ opacity: var(--sp-opacity-disabled);
737
+ pointer-events: none;
738
+ }
739
+
701
740
  /* ICON BOXES ----------------------------------------------------------- */
702
741
 
703
742
  .sp-iconbox {
@@ -803,6 +842,11 @@
803
842
  color: var(--sp-component-iconbox-info-text);
804
843
  }
805
844
 
845
+ .sp-iconbox--disabled {
846
+ opacity: var(--sp-opacity-disabled);
847
+ pointer-events: none;
848
+ }
849
+
806
850
  /* TESTIMONIALS --------------------------------------------------------- */
807
851
 
808
852
  .sp-testimonial {
@@ -877,6 +921,11 @@
877
921
  border: none;
878
922
  }
879
923
 
924
+ .sp-pricing-card--disabled {
925
+ opacity: var(--sp-opacity-disabled);
926
+ pointer-events: none;
927
+ }
928
+
880
929
  .sp-pricing-card-badge {
881
930
  position: absolute;
882
931
  top: var(--sp-space-16);
package/dist/index.cjs CHANGED
@@ -126,7 +126,8 @@ function getCardClasses(opts = {}) {
126
126
  variant: variantInput,
127
127
  interactive = false,
128
128
  padded = false,
129
- fullHeight = false
129
+ fullHeight = false,
130
+ disabled = false
130
131
  } = opts;
131
132
  const variant = resolveOption({
132
133
  name: "card variant",
@@ -146,7 +147,8 @@ function getCardClasses(opts = {}) {
146
147
  variantClass,
147
148
  interactive && "sp-card--interactive",
148
149
  padded && "sp-card--padded",
149
- fullHeight && "sp-card--full"
150
+ fullHeight && "sp-card--full",
151
+ disabled && "sp-card--disabled"
150
152
  );
151
153
  }
152
154
 
@@ -163,7 +165,7 @@ var INPUT_SIZES = {
163
165
  lg: true
164
166
  };
165
167
  function getInputClasses(opts = {}) {
166
- const { state: stateInput, size: sizeInput, fullWidth = false } = opts;
168
+ const { state: stateInput, size: sizeInput, fullWidth = false, pill = false } = opts;
167
169
  const state = resolveOption({
168
170
  name: "input state",
169
171
  value: stateInput,
@@ -189,7 +191,8 @@ function getInputClasses(opts = {}) {
189
191
  state === "success" && "sp-input--success",
190
192
  // Visual state only; actual disabled attribute is handled by adapters.
191
193
  state === "disabled" && "sp-input--disabled",
192
- fullWidth && "sp-input--full"
194
+ fullWidth && "sp-input--full",
195
+ pill && "sp-input--pill"
193
196
  );
194
197
  }
195
198
 
@@ -209,7 +212,7 @@ var BADGE_SIZES = {
209
212
  lg: true
210
213
  };
211
214
  function getBadgeClasses(opts = {}) {
212
- const { variant: variantInput, size: sizeInput, interactive } = opts;
215
+ const { variant: variantInput, size: sizeInput, interactive, disabled } = opts;
213
216
  const variant = resolveOption({
214
217
  name: "badge variant",
215
218
  value: variantInput,
@@ -242,7 +245,8 @@ function getBadgeClasses(opts = {}) {
242
245
  "sp-badge",
243
246
  variantClass,
244
247
  sizeClass,
245
- interactive && "sp-badge--interactive"
248
+ interactive && "sp-badge--interactive",
249
+ disabled && "sp-badge--disabled"
246
250
  );
247
251
  }
248
252
 
@@ -260,7 +264,7 @@ var ICONBOX_SIZES = {
260
264
  lg: true
261
265
  };
262
266
  function getIconBoxClasses(opts = {}) {
263
- const { variant: variantInput, size: sizeInput } = opts;
267
+ const { variant: variantInput, size: sizeInput, disabled = false } = opts;
264
268
  const variant = resolveOption({
265
269
  name: "icon box variant",
266
270
  value: variantInput,
@@ -287,7 +291,7 @@ function getIconBoxClasses(opts = {}) {
287
291
  lg: "sp-iconbox--lg"
288
292
  };
289
293
  const sizeClass = sizeMap[size];
290
- return cx("sp-iconbox", variantClass, sizeClass);
294
+ return cx("sp-iconbox", variantClass, sizeClass, disabled && "sp-iconbox--disabled");
291
295
  }
292
296
 
293
297
  // src/recipes/testimonial.ts
@@ -312,10 +316,11 @@ function getTestimonialAuthorTitleClasses() {
312
316
 
313
317
  // src/recipes/pricing-card.ts
314
318
  function getPricingCardClasses(opts = {}) {
315
- const { featured = false } = opts;
319
+ const { featured = false, disabled = false } = opts;
316
320
  return cx(
317
321
  "sp-pricing-card",
318
- featured && "sp-pricing-card--featured"
322
+ featured && "sp-pricing-card--featured",
323
+ disabled && "sp-pricing-card--disabled"
319
324
  );
320
325
  }
321
326
  function getPricingCardBadgeClasses() {
@@ -1 +1 @@
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","../src/recipes/testimonial.ts","../src/recipes/pricing-card.ts","../src/recipes/rating.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\", \"cta\", \"accent\"] 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 cta: true,\n accent: 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 pill?: 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 pill = 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 cta: \"sp-btn--cta\",\n accent: \"sp-btn--accent\",\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 pill && \"sp-btn--pill\",\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\", \"secondary\", \"success\", \"warning\", \"danger\", \"neutral\", \"info\"] 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 secondary: true,\n success: true,\n warning: true,\n danger: true,\n neutral: true,\n info: 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 interactive?: boolean;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, interactive } = 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 secondary: \"sp-badge--secondary\",\n success: \"sp-badge--success\",\n warning: \"sp-badge--warning\",\n danger: \"sp-badge--danger\",\n neutral: \"sp-badge--neutral\",\n info: \"sp-badge--info\",\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(\n \"sp-badge\",\n variantClass,\n sizeClass,\n interactive && \"sp-badge--interactive\"\n );\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","import { cx } from \"../internal/cx\";\n\nexport interface TestimonialRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getTestimonialClasses(_opts: TestimonialRecipeOptions = {}): string {\n return cx(\"sp-testimonial\");\n}\n\nexport function getTestimonialQuoteClasses(): string {\n return cx(\"sp-testimonial-quote\");\n}\n\nexport function getTestimonialAuthorClasses(): string {\n return cx(\"sp-testimonial-author\");\n}\n\nexport function getTestimonialAuthorInfoClasses(): string {\n return cx(\"sp-testimonial-author-info\");\n}\n\nexport function getTestimonialAuthorNameClasses(): string {\n return cx(\"sp-testimonial-author-name\");\n}\n\nexport function getTestimonialAuthorTitleClasses(): string {\n return cx(\"sp-testimonial-author-title\");\n}\n","import { cx } from \"../internal/cx\";\n\nexport interface PricingCardRecipeOptions {\n featured?: boolean;\n}\n\nexport function getPricingCardClasses(opts: PricingCardRecipeOptions = {}): string {\n const { featured = false } = opts;\n return cx(\n \"sp-pricing-card\",\n featured && \"sp-pricing-card--featured\"\n );\n}\n\nexport function getPricingCardBadgeClasses(): string {\n return cx(\"sp-pricing-card-badge\");\n}\n\nexport function getPricingCardPriceContainerClasses(): string {\n return cx(\"sp-pricing-card-price-container\");\n}\n\nexport function getPricingCardPriceClasses(): string {\n return cx(\"sp-pricing-card-price\");\n}\n\nexport function getPricingCardDescriptionClasses(): string {\n return cx(\"sp-pricing-card-description\");\n}\n","import { cx } from \"../internal/cx\";\n\nexport interface RatingRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getRatingClasses(_opts: RatingRecipeOptions = {}): string {\n return cx(\"sp-rating\");\n}\n\nexport function getRatingStarsClasses(): string {\n return cx(\"sp-rating-stars\");\n}\n\nexport function getRatingStarClasses(isFilled: boolean = false): string {\n return cx(\n \"sp-rating-star\",\n isFilled && \"sp-rating-star--filled\"\n );\n}\n\nexport function getRatingTextClasses(): string {\n return cx(\"sp-rating-text\");\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","../src/recipes/testimonial.ts","../src/recipes/pricing-card.ts","../src/recipes/rating.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\", \"cta\", \"accent\"] 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 cta: true,\n accent: true,\n} as const;\n\nconst BUTTON_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\n/**\n * Generate classes for the Button component.\n * @sync v2.x - Synced with latest design tokens, including CTA variants.\n */\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n pill?: 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 pill = 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 cta: \"sp-btn--cta\",\n accent: \"sp-btn--accent\",\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 pill && \"sp-btn--pill\",\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 disabled?: boolean;\n}\n\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant: variantInput,\n interactive = false,\n padded = false,\n fullHeight = false,\n disabled = 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 disabled && \"sp-card--disabled\",\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 pill?: boolean;\n}\n\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const { state: stateInput, size: sizeInput, fullWidth = false, pill = 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 pill && \"sp-input--pill\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst badgeVariants = [\"primary\", \"secondary\", \"success\", \"warning\", \"danger\", \"neutral\", \"info\"] 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 secondary: true,\n success: true,\n warning: true,\n danger: true,\n neutral: true,\n info: true,\n} as const;\n\nconst BADGE_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\n/**\n * Generate classes for the Badge component.\n * @sync v2.x - Synced with latest design tokens, including hover states.\n */\nexport interface BadgeRecipeOptions {\n variant?: BadgeVariant;\n size?: BadgeSize;\n interactive?: boolean;\n disabled?: boolean;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, interactive, disabled } = 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 secondary: \"sp-badge--secondary\",\n success: \"sp-badge--success\",\n warning: \"sp-badge--warning\",\n danger: \"sp-badge--danger\",\n neutral: \"sp-badge--neutral\",\n info: \"sp-badge--info\",\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(\n \"sp-badge\",\n variantClass,\n sizeClass,\n interactive && \"sp-badge--interactive\",\n disabled && \"sp-badge--disabled\"\n );\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 disabled?: boolean;\n}\n\nexport function getIconBoxClasses(opts: IconBoxRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, disabled = false } = 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, disabled && \"sp-iconbox--disabled\");\n}\n","import { cx } from \"../internal/cx\";\n\n/**\n * Generate classes for the Testimonial component.\n * @sync v2.x - Synced with latest design tokens.\n */\nexport interface TestimonialRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getTestimonialClasses(_opts: TestimonialRecipeOptions = {}): string {\n return cx(\"sp-testimonial\");\n}\n\nexport function getTestimonialQuoteClasses(): string {\n return cx(\"sp-testimonial-quote\");\n}\n\nexport function getTestimonialAuthorClasses(): string {\n return cx(\"sp-testimonial-author\");\n}\n\nexport function getTestimonialAuthorInfoClasses(): string {\n return cx(\"sp-testimonial-author-info\");\n}\n\nexport function getTestimonialAuthorNameClasses(): string {\n return cx(\"sp-testimonial-author-name\");\n}\n\nexport function getTestimonialAuthorTitleClasses(): string {\n return cx(\"sp-testimonial-author-title\");\n}\n","import { cx } from \"../internal/cx\";\n\n/**\n * Generate classes for the PricingCard component.\n * @sync v2.x - Synced with latest design tokens.\n */\nexport interface PricingCardRecipeOptions {\n featured?: boolean;\n disabled?: boolean;\n}\n\nexport function getPricingCardClasses(opts: PricingCardRecipeOptions = {}): string {\n const { featured = false, disabled = false } = opts;\n return cx(\n \"sp-pricing-card\",\n featured && \"sp-pricing-card--featured\",\n disabled && \"sp-pricing-card--disabled\"\n );\n}\n\nexport function getPricingCardBadgeClasses(): string {\n return cx(\"sp-pricing-card-badge\");\n}\n\nexport function getPricingCardPriceContainerClasses(): string {\n return cx(\"sp-pricing-card-price-container\");\n}\n\nexport function getPricingCardPriceClasses(): string {\n return cx(\"sp-pricing-card-price\");\n}\n\nexport function getPricingCardDescriptionClasses(): string {\n return cx(\"sp-pricing-card-description\");\n}\n","import { cx } from \"../internal/cx\";\n\n/**\n * Generate classes for the Rating component.\n * @sync v2.x - Synced with latest design tokens.\n */\nexport interface RatingRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getRatingClasses(_opts: RatingRecipeOptions = {}): string {\n return cx(\"sp-rating\");\n}\n\nexport function getRatingStarsClasses(): string {\n return cx(\"sp-rating-stars\");\n}\n\nexport function getRatingStarClasses(isFilled: boolean = false): string {\n return cx(\n \"sp-rating-star\",\n isFilled && \"sp-rating-star--filled\"\n );\n}\n\nexport function getRatingTextClasses(): string {\n return cx(\"sp-rating-text\");\n}\n"]}
package/dist/index.css CHANGED
@@ -58,16 +58,16 @@
58
58
  --sp-color-neutral-700: #334155;
59
59
  --sp-color-neutral-800: #1e293b;
60
60
  --sp-color-neutral-900: #0f172a;
61
- --sp-color-accent-50: #eff6ff;
62
- --sp-color-accent-100: #dbeafe;
61
+ --sp-color-accent-50: #f5f3ff;
62
+ --sp-color-accent-100: #ede9fe;
63
63
  --sp-color-accent-200: #ddd6fe;
64
- --sp-color-accent-300: #93c5fd;
65
- --sp-color-accent-400: #60a5fa;
64
+ --sp-color-accent-300: #c4b5fd;
65
+ --sp-color-accent-400: #a78bfa;
66
66
  --sp-color-accent-500: #8b5cf6;
67
67
  --sp-color-accent-600: #7c3aed;
68
68
  --sp-color-accent-700: #6d28d9;
69
- --sp-color-accent-800: #1e40af;
70
- --sp-color-accent-900: #1e3a8a;
69
+ --sp-color-accent-800: #5b21b6;
70
+ --sp-color-accent-900: #4c1d95;
71
71
  --sp-color-success-50: #f0fdf4;
72
72
  --sp-color-success-100: #dcfce7;
73
73
  --sp-color-success-200: #bbf7d0;
@@ -154,6 +154,9 @@
154
154
  --sp-layout-container-padding-inline-sm: 1rem;
155
155
  --sp-layout-container-padding-inline-md: 1.5rem;
156
156
  --sp-layout-container-padding-inline-lg: 2rem;
157
+ --sp-layout-container-max-width: 72rem;
158
+ --sp-border-width-base: 1px;
159
+ --sp-border-width-thick: 2px;
157
160
  --sp-radius-none: 0;
158
161
  --sp-radius-sm: 2px;
159
162
  --sp-radius-md: 4px;
@@ -250,6 +253,7 @@
250
253
  --sp-button-primary-bgdisabled: #e2e8f0;
251
254
  --sp-button-primary-text: #ffffff;
252
255
  --sp-button-primary-textdisabled: #94a3b8;
256
+ --sp-button-primary-focusring: rgba(59, 130, 246, 0.4);
253
257
  --sp-button-secondary-bg: #ffffff;
254
258
  --sp-button-secondary-bghover: #f8fafc;
255
259
  --sp-button-secondary-bgactive: #f1f5f9;
@@ -258,24 +262,28 @@
258
262
  --sp-button-secondary-textdisabled: #94a3b8;
259
263
  --sp-button-secondary-border: #2563eb;
260
264
  --sp-button-secondary-borderdisabled: #e2e8f0;
265
+ --sp-button-secondary-focusring: rgba(59, 130, 246, 0.4);
261
266
  --sp-button-ghost-bg: transparent;
262
267
  --sp-button-ghost-bghover: #eff6ff;
263
268
  --sp-button-ghost-bgactive: #dbeafe;
264
269
  --sp-button-ghost-bgdisabled: transparent;
265
270
  --sp-button-ghost-text: #2563eb;
266
271
  --sp-button-ghost-textdisabled: #94a3b8;
272
+ --sp-button-ghost-focusring: rgba(59, 130, 246, 0.4);
267
273
  --sp-button-danger-bg: #dc2626;
268
274
  --sp-button-danger-bghover: #b91c1c;
269
275
  --sp-button-danger-bgactive: #991b1b;
270
276
  --sp-button-danger-bgdisabled: #fecaca;
271
277
  --sp-button-danger-text: #ffffff;
272
278
  --sp-button-danger-textdisabled: #94a3b8;
279
+ --sp-button-danger-focusring: rgba(239, 68, 68, 0.4);
273
280
  --sp-button-success-bg: #15803d;
274
281
  --sp-button-success-bghover: #166534;
275
282
  --sp-button-success-bgactive: #14532d;
276
283
  --sp-button-success-bgdisabled: #bbf7d0;
277
284
  --sp-button-success-text: #ffffff;
278
285
  --sp-button-success-textdisabled: #94a3b8;
286
+ --sp-button-success-focusring: rgba(34, 197, 94, 0.4);
279
287
  --sp-button-cta-bg: #f59e0b;
280
288
  --sp-button-cta-bghover: #d97706;
281
289
  --sp-button-cta-bgactive: #b45309;
@@ -283,12 +291,14 @@
283
291
  --sp-button-cta-text: #0f172a;
284
292
  --sp-button-cta-textdisabled: #94a3b8;
285
293
  --sp-button-cta-shadow: 0 4px 14px 0 rgba(245, 158, 11, 0.39);
294
+ --sp-button-cta-focusring: rgba(245, 158, 11, 0.4);
286
295
  --sp-button-accent-bg: #7c3aed;
287
296
  --sp-button-accent-bghover: #6d28d9;
288
- --sp-button-accent-bgactive: #1e40af;
297
+ --sp-button-accent-bgactive: #5b21b6;
289
298
  --sp-button-accent-bgdisabled: #ddd6fe;
290
299
  --sp-button-accent-text: #ffffff;
291
300
  --sp-button-accent-textdisabled: #94a3b8;
301
+ --sp-button-accent-focusring: rgba(139, 92, 246, 0.4);
292
302
  --sp-form-default-bg: #ffffff;
293
303
  --sp-form-default-border: #cbd5e1;
294
304
  --sp-form-default-text: #0f172a;
@@ -335,7 +345,7 @@
335
345
  --sp-surface-card: #1e293b;
336
346
  --sp-surface-input: #334155;
337
347
  --sp-surface-overlay: #1e293b;
338
- --sp-surface-hero: linear-gradient(135deg, #1e3a8a 0%, #6d28d9 100%);
348
+ --sp-surface-hero: linear-gradient(135deg, #4c1d95 0%, #6d28d9 100%);
339
349
  --sp-text-on-page-default: #f8fafc;
340
350
  --sp-text-on-page-muted: #cbd5e1;
341
351
  --sp-text-on-page-subtle: #94a3b8;
@@ -423,7 +433,7 @@
423
433
  }
424
434
 
425
435
  :focus-visible {
426
- outline: var(--sp-focus-ring-width) solid var(--sp-color-focus-primary);
436
+ outline: var(--sp-focus-ring-width) var(--sp-focus-ring-style) var(--sp-color-focus-primary);
427
437
  outline-offset: var(--sp-focus-ring-offset);
428
438
  }
429
439
 
@@ -435,8 +445,8 @@
435
445
  @layer components {
436
446
 
437
447
  :root {
438
- /* structural border width — swap to token when spectre-tokens ships sp-border-width-base */
439
- --sp-component-border-width: 1px;
448
+ /* structural border width */
449
+ --sp-component-border-width: var(--sp-border-width-base);
440
450
 
441
451
  /* button roles */
442
452
  --sp-component-button-border-base: var(--sp-component-button-ghost-bg);
@@ -473,6 +483,8 @@
473
483
  --sp-component-button-success-bg-disabled: var(--sp-button-success-bgdisabled);
474
484
  --sp-component-button-success-text: var(--sp-button-success-text);
475
485
  --sp-component-button-success-text-disabled: var(--sp-button-success-textdisabled);
486
+ /* FLAG: buttons.cta tokens in spectre-tokens v2.x use warning.500 (Gold),
487
+ which violates the Aesthetic Audit guardrails. Remaining on accent palette. */
476
488
  --sp-component-button-cta-bg: var(--sp-color-accent-600);
477
489
  --sp-component-button-cta-bg-hover: var(--sp-color-accent-700);
478
490
  --sp-component-button-cta-bg-active: var(--sp-color-accent-800);
@@ -576,34 +588,57 @@
576
588
  /* testimonial roles */
577
589
  --sp-component-testimonial-bg: var(--sp-surface-card);
578
590
  --sp-component-testimonial-border: var(--sp-color-neutral-200);
579
- --sp-component-testimonial-text: var(--sp-text-on-surface-muted);
580
- --sp-component-testimonial-author-name: var(--sp-text-on-surface-default);
581
- --sp-component-testimonial-author-title: var(--sp-text-on-surface-subtle);
591
+ --sp-component-testimonial-text: var(--sp-color-neutral-700);
592
+ --sp-component-testimonial-author-name: var(--sp-color-neutral-900);
593
+ --sp-component-testimonial-author-title: var(--sp-color-neutral-500);
582
594
  --sp-component-testimonial-quote-mark: var(--sp-color-neutral-300);
583
595
 
584
596
  /* pricing card roles */
585
597
  --sp-component-pricing-card-bg: var(--sp-surface-card);
586
598
  --sp-component-pricing-card-border: var(--sp-color-neutral-200);
599
+ /* FLAG: component.pricingCard.featuredBg in tokens is info.600 (Blue), which clashing
600
+ with the warning.500 (Gold) badge. Remaining on neutral-900 to pass Aesthetic Audit. */
587
601
  --sp-component-pricing-card-featured-bg: var(--sp-color-neutral-900);
588
602
  --sp-component-pricing-card-featured-text: var(--sp-color-neutral-50);
589
603
  --sp-component-pricing-card-featured-badge-bg: var(--sp-color-warning-500);
590
604
  --sp-component-pricing-card-featured-badge-text: var(--sp-color-neutral-900);
591
- --sp-component-pricing-card-price: var(--sp-text-on-surface-default);
605
+ --sp-component-pricing-card-price: var(--sp-color-neutral-900);
592
606
  --sp-component-pricing-card-featured-price: var(--sp-color-neutral-50);
593
- --sp-component-pricing-card-price-description: var(--sp-text-on-surface-subtle);
607
+ --sp-component-pricing-card-price-description: var(--sp-color-neutral-500);
594
608
 
595
609
  /* rating roles */
596
610
  --sp-component-rating-star-filled: var(--sp-color-warning-500);
597
611
  --sp-component-rating-star-empty: var(--sp-color-neutral-200);
598
- --sp-component-rating-text: var(--sp-text-on-surface-subtle);
612
+ --sp-component-rating-text: var(--sp-color-neutral-500);
599
613
  }
600
614
 
601
615
  /* dark mode overrides for complex component tokens not yet exported by spectre-tokens v2.x */
602
616
  :root[data-spectre-theme="dark"] {
617
+ --sp-component-testimonial-bg: var(--sp-color-neutral-800);
603
618
  --sp-component-testimonial-border: var(--sp-color-neutral-700);
619
+ --sp-component-testimonial-text: var(--sp-color-neutral-300);
620
+ --sp-component-testimonial-author-name: var(--sp-color-neutral-100);
621
+ --sp-component-testimonial-author-title: var(--sp-color-neutral-400);
604
622
  --sp-component-testimonial-quote-mark: var(--sp-color-neutral-600);
623
+
624
+ --sp-component-pricing-card-bg: var(--sp-color-neutral-800);
605
625
  --sp-component-pricing-card-border: var(--sp-color-neutral-700);
626
+ --sp-component-pricing-card-price: var(--sp-color-neutral-100);
627
+ --sp-component-pricing-card-price-description: var(--sp-color-neutral-400);
628
+
606
629
  --sp-component-rating-star-empty: var(--sp-color-neutral-700);
630
+ --sp-component-rating-text: var(--sp-color-neutral-400);
631
+
632
+ --sp-component-badge-success-bg: var(--sp-color-success-800);
633
+ --sp-component-badge-success-text: var(--sp-color-success-100);
634
+ --sp-component-badge-warning-bg: var(--sp-color-warning-800);
635
+ --sp-component-badge-warning-text: var(--sp-color-warning-100);
636
+ --sp-component-badge-danger-bg: var(--sp-color-error-800);
637
+ --sp-component-badge-danger-text: var(--sp-color-error-100);
638
+ --sp-component-badge-neutral-bg: var(--sp-color-neutral-700);
639
+ --sp-component-badge-neutral-text: var(--sp-color-neutral-100);
640
+ --sp-component-badge-info-bg: var(--sp-color-info-800);
641
+ --sp-component-badge-info-text: var(--sp-color-info-100);
607
642
 
608
643
  --sp-component-badge-success-bg-hover: var(--sp-color-success-700);
609
644
  --sp-component-badge-warning-bg-hover: var(--sp-color-warning-700);
@@ -929,6 +964,10 @@
929
964
  width: 100%;
930
965
  }
931
966
 
967
+ .sp-input--pill {
968
+ border-radius: var(--sp-radius-pill);
969
+ }
970
+
932
971
  .sp-input:focus,
933
972
  .sp-input--focus {
934
973
  border-color: var(--sp-component-input-role-border-focus);
@@ -1014,6 +1053,11 @@
1014
1053
  height: 100%;
1015
1054
  }
1016
1055
 
1056
+ .sp-card--disabled {
1057
+ opacity: var(--sp-opacity-disabled);
1058
+ pointer-events: none;
1059
+ }
1060
+
1017
1061
  .sp-card--interactive {
1018
1062
  cursor: pointer;
1019
1063
  transition:
@@ -1132,6 +1176,11 @@
1132
1176
  transition: background-color var(--sp-duration-fast) var(--sp-easing-out);
1133
1177
  }
1134
1178
 
1179
+ .sp-badge--disabled {
1180
+ opacity: var(--sp-opacity-disabled);
1181
+ pointer-events: none;
1182
+ }
1183
+
1135
1184
  /* ICON BOXES ----------------------------------------------------------- */
1136
1185
 
1137
1186
  .sp-iconbox {
@@ -1237,6 +1286,11 @@
1237
1286
  color: var(--sp-component-iconbox-info-text);
1238
1287
  }
1239
1288
 
1289
+ .sp-iconbox--disabled {
1290
+ opacity: var(--sp-opacity-disabled);
1291
+ pointer-events: none;
1292
+ }
1293
+
1240
1294
  /* TESTIMONIALS --------------------------------------------------------- */
1241
1295
 
1242
1296
  .sp-testimonial {
@@ -1311,6 +1365,11 @@
1311
1365
  border: none;
1312
1366
  }
1313
1367
 
1368
+ .sp-pricing-card--disabled {
1369
+ opacity: var(--sp-opacity-disabled);
1370
+ pointer-events: none;
1371
+ }
1372
+
1314
1373
  .sp-pricing-card-badge {
1315
1374
  position: absolute;
1316
1375
  top: var(--sp-space-16);
@@ -1398,7 +1457,7 @@
1398
1457
  margin-right: auto;
1399
1458
  padding-left: var(--sp-layout-container-padding-inline-md);
1400
1459
  padding-right: var(--sp-layout-container-padding-inline-md);
1401
- max-width: calc(var(--sp-space-96) * 12);
1460
+ max-width: var(--sp-layout-container-max-width);
1402
1461
  }
1403
1462
 
1404
1463
  .sp-section {
package/dist/index.d.cts CHANGED
@@ -12,6 +12,10 @@ declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger
12
12
  declare const buttonSizes: readonly ["sm", "md", "lg"];
13
13
  type ButtonVariant = (typeof buttonVariants)[number];
14
14
  type ButtonSize = (typeof buttonSizes)[number];
15
+ /**
16
+ * Generate classes for the Button component.
17
+ * @sync v2.x - Synced with latest design tokens, including CTA variants.
18
+ */
15
19
  interface ButtonRecipeOptions {
16
20
  variant?: ButtonVariant;
17
21
  size?: ButtonSize;
@@ -30,6 +34,7 @@ interface CardRecipeOptions {
30
34
  interactive?: boolean;
31
35
  padded?: boolean;
32
36
  fullHeight?: boolean;
37
+ disabled?: boolean;
33
38
  }
34
39
  declare function getCardClasses(opts?: CardRecipeOptions): string;
35
40
 
@@ -41,6 +46,7 @@ interface InputRecipeOptions {
41
46
  state?: InputState;
42
47
  size?: InputSize;
43
48
  fullWidth?: boolean;
49
+ pill?: boolean;
44
50
  }
45
51
  declare function getInputClasses(opts?: InputRecipeOptions): string;
46
52
 
@@ -48,10 +54,15 @@ declare const badgeVariants: readonly ["primary", "secondary", "success", "warni
48
54
  declare const badgeSizes: readonly ["sm", "md", "lg"];
49
55
  type BadgeVariant = (typeof badgeVariants)[number];
50
56
  type BadgeSize = (typeof badgeSizes)[number];
57
+ /**
58
+ * Generate classes for the Badge component.
59
+ * @sync v2.x - Synced with latest design tokens, including hover states.
60
+ */
51
61
  interface BadgeRecipeOptions {
52
62
  variant?: BadgeVariant;
53
63
  size?: BadgeSize;
54
64
  interactive?: boolean;
65
+ disabled?: boolean;
55
66
  }
56
67
  declare function getBadgeClasses(opts?: BadgeRecipeOptions): string;
57
68
 
@@ -62,9 +73,14 @@ type IconBoxSize = (typeof iconBoxSizes)[number];
62
73
  interface IconBoxRecipeOptions {
63
74
  variant?: IconBoxVariant;
64
75
  size?: IconBoxSize;
76
+ disabled?: boolean;
65
77
  }
66
78
  declare function getIconBoxClasses(opts?: IconBoxRecipeOptions): string;
67
79
 
80
+ /**
81
+ * Generate classes for the Testimonial component.
82
+ * @sync v2.x - Synced with latest design tokens.
83
+ */
68
84
  interface TestimonialRecipeOptions {
69
85
  }
70
86
  declare function getTestimonialClasses(_opts?: TestimonialRecipeOptions): string;
@@ -74,8 +90,13 @@ declare function getTestimonialAuthorInfoClasses(): string;
74
90
  declare function getTestimonialAuthorNameClasses(): string;
75
91
  declare function getTestimonialAuthorTitleClasses(): string;
76
92
 
93
+ /**
94
+ * Generate classes for the PricingCard component.
95
+ * @sync v2.x - Synced with latest design tokens.
96
+ */
77
97
  interface PricingCardRecipeOptions {
78
98
  featured?: boolean;
99
+ disabled?: boolean;
79
100
  }
80
101
  declare function getPricingCardClasses(opts?: PricingCardRecipeOptions): string;
81
102
  declare function getPricingCardBadgeClasses(): string;
@@ -83,6 +104,10 @@ declare function getPricingCardPriceContainerClasses(): string;
83
104
  declare function getPricingCardPriceClasses(): string;
84
105
  declare function getPricingCardDescriptionClasses(): string;
85
106
 
107
+ /**
108
+ * Generate classes for the Rating component.
109
+ * @sync v2.x - Synced with latest design tokens.
110
+ */
86
111
  interface RatingRecipeOptions {
87
112
  }
88
113
  declare function getRatingClasses(_opts?: RatingRecipeOptions): string;
package/dist/index.d.ts CHANGED
@@ -12,6 +12,10 @@ declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger
12
12
  declare const buttonSizes: readonly ["sm", "md", "lg"];
13
13
  type ButtonVariant = (typeof buttonVariants)[number];
14
14
  type ButtonSize = (typeof buttonSizes)[number];
15
+ /**
16
+ * Generate classes for the Button component.
17
+ * @sync v2.x - Synced with latest design tokens, including CTA variants.
18
+ */
15
19
  interface ButtonRecipeOptions {
16
20
  variant?: ButtonVariant;
17
21
  size?: ButtonSize;
@@ -30,6 +34,7 @@ interface CardRecipeOptions {
30
34
  interactive?: boolean;
31
35
  padded?: boolean;
32
36
  fullHeight?: boolean;
37
+ disabled?: boolean;
33
38
  }
34
39
  declare function getCardClasses(opts?: CardRecipeOptions): string;
35
40
 
@@ -41,6 +46,7 @@ interface InputRecipeOptions {
41
46
  state?: InputState;
42
47
  size?: InputSize;
43
48
  fullWidth?: boolean;
49
+ pill?: boolean;
44
50
  }
45
51
  declare function getInputClasses(opts?: InputRecipeOptions): string;
46
52
 
@@ -48,10 +54,15 @@ declare const badgeVariants: readonly ["primary", "secondary", "success", "warni
48
54
  declare const badgeSizes: readonly ["sm", "md", "lg"];
49
55
  type BadgeVariant = (typeof badgeVariants)[number];
50
56
  type BadgeSize = (typeof badgeSizes)[number];
57
+ /**
58
+ * Generate classes for the Badge component.
59
+ * @sync v2.x - Synced with latest design tokens, including hover states.
60
+ */
51
61
  interface BadgeRecipeOptions {
52
62
  variant?: BadgeVariant;
53
63
  size?: BadgeSize;
54
64
  interactive?: boolean;
65
+ disabled?: boolean;
55
66
  }
56
67
  declare function getBadgeClasses(opts?: BadgeRecipeOptions): string;
57
68
 
@@ -62,9 +73,14 @@ type IconBoxSize = (typeof iconBoxSizes)[number];
62
73
  interface IconBoxRecipeOptions {
63
74
  variant?: IconBoxVariant;
64
75
  size?: IconBoxSize;
76
+ disabled?: boolean;
65
77
  }
66
78
  declare function getIconBoxClasses(opts?: IconBoxRecipeOptions): string;
67
79
 
80
+ /**
81
+ * Generate classes for the Testimonial component.
82
+ * @sync v2.x - Synced with latest design tokens.
83
+ */
68
84
  interface TestimonialRecipeOptions {
69
85
  }
70
86
  declare function getTestimonialClasses(_opts?: TestimonialRecipeOptions): string;
@@ -74,8 +90,13 @@ declare function getTestimonialAuthorInfoClasses(): string;
74
90
  declare function getTestimonialAuthorNameClasses(): string;
75
91
  declare function getTestimonialAuthorTitleClasses(): string;
76
92
 
93
+ /**
94
+ * Generate classes for the PricingCard component.
95
+ * @sync v2.x - Synced with latest design tokens.
96
+ */
77
97
  interface PricingCardRecipeOptions {
78
98
  featured?: boolean;
99
+ disabled?: boolean;
79
100
  }
80
101
  declare function getPricingCardClasses(opts?: PricingCardRecipeOptions): string;
81
102
  declare function getPricingCardBadgeClasses(): string;
@@ -83,6 +104,10 @@ declare function getPricingCardPriceContainerClasses(): string;
83
104
  declare function getPricingCardPriceClasses(): string;
84
105
  declare function getPricingCardDescriptionClasses(): string;
85
106
 
107
+ /**
108
+ * Generate classes for the Rating component.
109
+ * @sync v2.x - Synced with latest design tokens.
110
+ */
86
111
  interface RatingRecipeOptions {
87
112
  }
88
113
  declare function getRatingClasses(_opts?: RatingRecipeOptions): string;
package/dist/index.js CHANGED
@@ -124,7 +124,8 @@ function getCardClasses(opts = {}) {
124
124
  variant: variantInput,
125
125
  interactive = false,
126
126
  padded = false,
127
- fullHeight = false
127
+ fullHeight = false,
128
+ disabled = false
128
129
  } = opts;
129
130
  const variant = resolveOption({
130
131
  name: "card variant",
@@ -144,7 +145,8 @@ function getCardClasses(opts = {}) {
144
145
  variantClass,
145
146
  interactive && "sp-card--interactive",
146
147
  padded && "sp-card--padded",
147
- fullHeight && "sp-card--full"
148
+ fullHeight && "sp-card--full",
149
+ disabled && "sp-card--disabled"
148
150
  );
149
151
  }
150
152
 
@@ -161,7 +163,7 @@ var INPUT_SIZES = {
161
163
  lg: true
162
164
  };
163
165
  function getInputClasses(opts = {}) {
164
- const { state: stateInput, size: sizeInput, fullWidth = false } = opts;
166
+ const { state: stateInput, size: sizeInput, fullWidth = false, pill = false } = opts;
165
167
  const state = resolveOption({
166
168
  name: "input state",
167
169
  value: stateInput,
@@ -187,7 +189,8 @@ function getInputClasses(opts = {}) {
187
189
  state === "success" && "sp-input--success",
188
190
  // Visual state only; actual disabled attribute is handled by adapters.
189
191
  state === "disabled" && "sp-input--disabled",
190
- fullWidth && "sp-input--full"
192
+ fullWidth && "sp-input--full",
193
+ pill && "sp-input--pill"
191
194
  );
192
195
  }
193
196
 
@@ -207,7 +210,7 @@ var BADGE_SIZES = {
207
210
  lg: true
208
211
  };
209
212
  function getBadgeClasses(opts = {}) {
210
- const { variant: variantInput, size: sizeInput, interactive } = opts;
213
+ const { variant: variantInput, size: sizeInput, interactive, disabled } = opts;
211
214
  const variant = resolveOption({
212
215
  name: "badge variant",
213
216
  value: variantInput,
@@ -240,7 +243,8 @@ function getBadgeClasses(opts = {}) {
240
243
  "sp-badge",
241
244
  variantClass,
242
245
  sizeClass,
243
- interactive && "sp-badge--interactive"
246
+ interactive && "sp-badge--interactive",
247
+ disabled && "sp-badge--disabled"
244
248
  );
245
249
  }
246
250
 
@@ -258,7 +262,7 @@ var ICONBOX_SIZES = {
258
262
  lg: true
259
263
  };
260
264
  function getIconBoxClasses(opts = {}) {
261
- const { variant: variantInput, size: sizeInput } = opts;
265
+ const { variant: variantInput, size: sizeInput, disabled = false } = opts;
262
266
  const variant = resolveOption({
263
267
  name: "icon box variant",
264
268
  value: variantInput,
@@ -285,7 +289,7 @@ function getIconBoxClasses(opts = {}) {
285
289
  lg: "sp-iconbox--lg"
286
290
  };
287
291
  const sizeClass = sizeMap[size];
288
- return cx("sp-iconbox", variantClass, sizeClass);
292
+ return cx("sp-iconbox", variantClass, sizeClass, disabled && "sp-iconbox--disabled");
289
293
  }
290
294
 
291
295
  // src/recipes/testimonial.ts
@@ -310,10 +314,11 @@ function getTestimonialAuthorTitleClasses() {
310
314
 
311
315
  // src/recipes/pricing-card.ts
312
316
  function getPricingCardClasses(opts = {}) {
313
- const { featured = false } = opts;
317
+ const { featured = false, disabled = false } = opts;
314
318
  return cx(
315
319
  "sp-pricing-card",
316
- featured && "sp-pricing-card--featured"
320
+ featured && "sp-pricing-card--featured",
321
+ disabled && "sp-pricing-card--disabled"
317
322
  );
318
323
  }
319
324
  function getPricingCardBadgeClasses() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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","../src/recipes/testimonial.ts","../src/recipes/pricing-card.ts","../src/recipes/rating.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\", \"cta\", \"accent\"] 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 cta: true,\n accent: 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 pill?: 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 pill = 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 cta: \"sp-btn--cta\",\n accent: \"sp-btn--accent\",\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 pill && \"sp-btn--pill\",\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\", \"secondary\", \"success\", \"warning\", \"danger\", \"neutral\", \"info\"] 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 secondary: true,\n success: true,\n warning: true,\n danger: true,\n neutral: true,\n info: 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 interactive?: boolean;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, interactive } = 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 secondary: \"sp-badge--secondary\",\n success: \"sp-badge--success\",\n warning: \"sp-badge--warning\",\n danger: \"sp-badge--danger\",\n neutral: \"sp-badge--neutral\",\n info: \"sp-badge--info\",\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(\n \"sp-badge\",\n variantClass,\n sizeClass,\n interactive && \"sp-badge--interactive\"\n );\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","import { cx } from \"../internal/cx\";\n\nexport interface TestimonialRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getTestimonialClasses(_opts: TestimonialRecipeOptions = {}): string {\n return cx(\"sp-testimonial\");\n}\n\nexport function getTestimonialQuoteClasses(): string {\n return cx(\"sp-testimonial-quote\");\n}\n\nexport function getTestimonialAuthorClasses(): string {\n return cx(\"sp-testimonial-author\");\n}\n\nexport function getTestimonialAuthorInfoClasses(): string {\n return cx(\"sp-testimonial-author-info\");\n}\n\nexport function getTestimonialAuthorNameClasses(): string {\n return cx(\"sp-testimonial-author-name\");\n}\n\nexport function getTestimonialAuthorTitleClasses(): string {\n return cx(\"sp-testimonial-author-title\");\n}\n","import { cx } from \"../internal/cx\";\n\nexport interface PricingCardRecipeOptions {\n featured?: boolean;\n}\n\nexport function getPricingCardClasses(opts: PricingCardRecipeOptions = {}): string {\n const { featured = false } = opts;\n return cx(\n \"sp-pricing-card\",\n featured && \"sp-pricing-card--featured\"\n );\n}\n\nexport function getPricingCardBadgeClasses(): string {\n return cx(\"sp-pricing-card-badge\");\n}\n\nexport function getPricingCardPriceContainerClasses(): string {\n return cx(\"sp-pricing-card-price-container\");\n}\n\nexport function getPricingCardPriceClasses(): string {\n return cx(\"sp-pricing-card-price\");\n}\n\nexport function getPricingCardDescriptionClasses(): string {\n return cx(\"sp-pricing-card-description\");\n}\n","import { cx } from \"../internal/cx\";\n\nexport interface RatingRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getRatingClasses(_opts: RatingRecipeOptions = {}): string {\n return cx(\"sp-rating\");\n}\n\nexport function getRatingStarsClasses(): string {\n return cx(\"sp-rating-stars\");\n}\n\nexport function getRatingStarClasses(isFilled: boolean = false): string {\n return cx(\n \"sp-rating-star\",\n isFilled && \"sp-rating-star--filled\"\n );\n}\n\nexport function getRatingTextClasses(): string {\n return cx(\"sp-rating-text\");\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","../src/recipes/testimonial.ts","../src/recipes/pricing-card.ts","../src/recipes/rating.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\", \"cta\", \"accent\"] 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 cta: true,\n accent: true,\n} as const;\n\nconst BUTTON_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\n/**\n * Generate classes for the Button component.\n * @sync v2.x - Synced with latest design tokens, including CTA variants.\n */\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n pill?: 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 pill = 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 cta: \"sp-btn--cta\",\n accent: \"sp-btn--accent\",\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 pill && \"sp-btn--pill\",\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 disabled?: boolean;\n}\n\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant: variantInput,\n interactive = false,\n padded = false,\n fullHeight = false,\n disabled = 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 disabled && \"sp-card--disabled\",\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 pill?: boolean;\n}\n\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const { state: stateInput, size: sizeInput, fullWidth = false, pill = 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 pill && \"sp-input--pill\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst badgeVariants = [\"primary\", \"secondary\", \"success\", \"warning\", \"danger\", \"neutral\", \"info\"] 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 secondary: true,\n success: true,\n warning: true,\n danger: true,\n neutral: true,\n info: true,\n} as const;\n\nconst BADGE_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\n/**\n * Generate classes for the Badge component.\n * @sync v2.x - Synced with latest design tokens, including hover states.\n */\nexport interface BadgeRecipeOptions {\n variant?: BadgeVariant;\n size?: BadgeSize;\n interactive?: boolean;\n disabled?: boolean;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, interactive, disabled } = 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 secondary: \"sp-badge--secondary\",\n success: \"sp-badge--success\",\n warning: \"sp-badge--warning\",\n danger: \"sp-badge--danger\",\n neutral: \"sp-badge--neutral\",\n info: \"sp-badge--info\",\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(\n \"sp-badge\",\n variantClass,\n sizeClass,\n interactive && \"sp-badge--interactive\",\n disabled && \"sp-badge--disabled\"\n );\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 disabled?: boolean;\n}\n\nexport function getIconBoxClasses(opts: IconBoxRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, disabled = false } = 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, disabled && \"sp-iconbox--disabled\");\n}\n","import { cx } from \"../internal/cx\";\n\n/**\n * Generate classes for the Testimonial component.\n * @sync v2.x - Synced with latest design tokens.\n */\nexport interface TestimonialRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getTestimonialClasses(_opts: TestimonialRecipeOptions = {}): string {\n return cx(\"sp-testimonial\");\n}\n\nexport function getTestimonialQuoteClasses(): string {\n return cx(\"sp-testimonial-quote\");\n}\n\nexport function getTestimonialAuthorClasses(): string {\n return cx(\"sp-testimonial-author\");\n}\n\nexport function getTestimonialAuthorInfoClasses(): string {\n return cx(\"sp-testimonial-author-info\");\n}\n\nexport function getTestimonialAuthorNameClasses(): string {\n return cx(\"sp-testimonial-author-name\");\n}\n\nexport function getTestimonialAuthorTitleClasses(): string {\n return cx(\"sp-testimonial-author-title\");\n}\n","import { cx } from \"../internal/cx\";\n\n/**\n * Generate classes for the PricingCard component.\n * @sync v2.x - Synced with latest design tokens.\n */\nexport interface PricingCardRecipeOptions {\n featured?: boolean;\n disabled?: boolean;\n}\n\nexport function getPricingCardClasses(opts: PricingCardRecipeOptions = {}): string {\n const { featured = false, disabled = false } = opts;\n return cx(\n \"sp-pricing-card\",\n featured && \"sp-pricing-card--featured\",\n disabled && \"sp-pricing-card--disabled\"\n );\n}\n\nexport function getPricingCardBadgeClasses(): string {\n return cx(\"sp-pricing-card-badge\");\n}\n\nexport function getPricingCardPriceContainerClasses(): string {\n return cx(\"sp-pricing-card-price-container\");\n}\n\nexport function getPricingCardPriceClasses(): string {\n return cx(\"sp-pricing-card-price\");\n}\n\nexport function getPricingCardDescriptionClasses(): string {\n return cx(\"sp-pricing-card-description\");\n}\n","import { cx } from \"../internal/cx\";\n\n/**\n * Generate classes for the Rating component.\n * @sync v2.x - Synced with latest design tokens.\n */\nexport interface RatingRecipeOptions {\n // Potential for variants later if needed\n}\n\nexport function getRatingClasses(_opts: RatingRecipeOptions = {}): string {\n return cx(\"sp-rating\");\n}\n\nexport function getRatingStarsClasses(): string {\n return cx(\"sp-rating-stars\");\n}\n\nexport function getRatingStarClasses(isFilled: boolean = false): string {\n return cx(\n \"sp-rating-star\",\n isFilled && \"sp-rating-star--filled\"\n );\n}\n\nexport function getRatingTextClasses(): string {\n return cx(\"sp-rating-text\");\n}\n"]}
@@ -18,7 +18,7 @@
18
18
  margin-right: auto;
19
19
  padding-left: var(--sp-layout-container-padding-inline-md);
20
20
  padding-right: var(--sp-layout-container-padding-inline-md);
21
- max-width: calc(var(--sp-space-96) * 12);
21
+ max-width: var(--sp-layout-container-max-width);
22
22
  }
23
23
 
24
24
  .sp-section {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phcdevworks/spectre-ui",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Cross-platform UI built on Spectre Tokens. A Tailwind-powered design system that turns the tokens into consistent CSS utilities, component classes and design recipes for WordPress blocks, Astro components, 11ty templates and other modern web apps.",
5
5
  "keywords": [
6
6
  "phcdevworks",
@@ -68,6 +68,8 @@
68
68
  "build:css": "mkdir -p dist && postcss src/styles/index.css -o dist/index.css",
69
69
  "dev": "tsup --config tsup.config.ts --watch",
70
70
  "clean": "rm -rf dist",
71
+ "lint": "eslint .",
72
+ "format": "prettier --write .",
71
73
  "test": "vitest run"
72
74
  },
73
75
  "publishConfig": {
@@ -77,17 +79,25 @@
77
79
  "tailwindcss": "^3.4.0 || ^4.0.0"
78
80
  },
79
81
  "dependencies": {
80
- "@phcdevworks/spectre-tokens": "^2.0.0"
82
+ "@phcdevworks/spectre-tokens": "^2.1.0"
81
83
  },
82
84
  "devDependencies": {
83
85
  "@types/node": "^25.5.0",
86
+ "@typescript-eslint/eslint-plugin": "^8.57.1",
87
+ "@typescript-eslint/parser": "^8.57.1",
84
88
  "autoprefixer": "^10.4.20",
89
+ "eslint": "^10.1.0",
85
90
  "postcss": "^8.4.35",
86
91
  "postcss-cli": "^11.0.1",
87
92
  "postcss-import": "^16.1.1",
93
+ "prettier": "^3.8.1",
88
94
  "tailwindcss": "^3.4.15",
89
95
  "tsup": "^8.5.1",
90
96
  "typescript": "^5.9.3",
97
+ "typescript-eslint": "^8.57.1",
91
98
  "vitest": "^4.0.15"
92
- }
99
+ },
100
+ "cSpell.words": [
101
+ "phcdevworks"
102
+ ]
93
103
  }