@phcdevworks/spectre-ui 1.1.0 β†’ 1.1.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.
package/LICENSE CHANGED
@@ -1,21 +1,20 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 PHCDevworks
3
+ Copyright (c) 2026 PHCDevworks
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
11
 
12
12
  The above copyright notice and this permission notice shall be included in all
13
13
  copies or substantial portions of the Software.
14
14
 
15
15
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,120 +1,186 @@
1
1
  # @phcdevworks/spectre-ui
2
2
 
3
- ### **The Blueprint (Layer 2 of the Spectre 8-Layer Arsenal)**
3
+ [![GitHub issues](https://img.shields.io/github/issues/phcdevworks/spectre-ui)](https://github.com/phcdevworks/spectre-ui/issues)
4
+ [![GitHub pull requests](https://img.shields.io/github/issues-pr/phcdevworks/spectre-ui)](https://github.com/phcdevworks/spectre-ui/pulls)
5
+ [![License](https://img.shields.io/github/license/phcdevworks/spectre-ui)](LICENSE)
4
6
 
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.
7
+ `@phcdevworks/spectre-ui` is the implementation layer between
8
+ [`@phcdevworks/spectre-tokens`](https://github.com/phcdevworks/spectre-tokens)
9
+ and downstream adapters or apps.
6
10
 
7
- 🀝 **[Contributing Guide](CONTRIBUTING.md)** | πŸ“ **[Changelog](CHANGELOG.md)** | πŸ›οΈ **[Spectre Arsenal](https://github.com/phcdevworks)**
11
+ Maintained by PHCDevworks, it turns Spectre tokens into reusable CSS bundles,
12
+ Tailwind tooling, and type-safe class recipes. It is framework-agnostic,
13
+ token-driven, and follows a strict zero-hex policy so visual values do not drift
14
+ locally.
8
15
 
9
- ---
16
+ [Contributing](CONTRIBUTING.md) | [Changelog](CHANGELOG.md) |
17
+ [Security Policy](SECURITY.md)
10
18
 
11
- ## πŸ—οΈ Core Architecture
19
+ ## Key capabilities
12
20
 
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.
21
+ - Ships precompiled CSS: `index.css`, `base.css`, `components.css`, and
22
+ `utilities.css`
23
+ - Provides Tailwind theme and preset helpers built from Spectre tokens
24
+ - Exports type-safe class recipes for shared UI patterns
25
+ - Keeps CSS classes and recipe APIs aligned
26
+ - Gives adapters and apps a stable styling contract instead of re-implementing
27
+ classes
28
+ - Enforces a zero-hex approach so visual values stay tied to
29
+ `@phcdevworks/spectre-tokens`
14
30
 
15
- - πŸ’Ž **Token-Driven**: Fully compatible with `@phcdevworks/spectre-tokens` v2.1.0.
16
- - πŸ“¦ **Precompiled CSS**: Ships `base`, `components`, and `utilities` bundles.
17
- - πŸ§ͺ **Type-Safe Recipes**: Pure JS/TS functions for generating framework-agnostic class strings.
18
- - πŸŒͺ️ **Tailwind Preset**: Mirrors the design scale into the Tailwind utility engine.
31
+ ## Installation
19
32
 
20
- ---
33
+ ```bash
34
+ npm install @phcdevworks/spectre-ui
35
+ ```
21
36
 
22
- ## πŸš€ Quick Start
37
+ ## Quick start
23
38
 
24
- ### Installation
39
+ ### CSS import
25
40
 
26
- ```bash
27
- npm install @phcdevworks/spectre-ui
41
+ Import the full stylesheet:
42
+
43
+ ```ts
44
+ import '@phcdevworks/spectre-ui/index.css'
28
45
  ```
29
46
 
30
- ### 1. Import CSS
31
- For most applications, importing the unified `index.css` is recommended.
47
+ Or import the bundles separately:
32
48
 
33
49
  ```ts
34
- import "@phcdevworks/spectre-ui/index.css";
50
+ import '@phcdevworks/spectre-ui/base.css'
51
+ import '@phcdevworks/spectre-ui/components.css'
52
+ import '@phcdevworks/spectre-ui/utilities.css'
35
53
  ```
36
54
 
37
- ### 2. Tailwind Integration
38
- Synchronize your Tailwind theme with the Spectre token scale.
55
+ ### Tailwind preset usage
56
+
57
+ Use Spectre tokens as the source of truth for your Tailwind theme:
39
58
 
40
59
  ```ts
41
60
  // tailwind.config.ts
42
- import { createSpectreTailwindPreset } from "@phcdevworks/spectre-ui/tailwind";
43
- import { spectreTokens } from "@phcdevworks/spectre-tokens";
61
+ import type { Config } from 'tailwindcss'
62
+ import { createSpectreTailwindPreset } from '@phcdevworks/spectre-ui/tailwind'
63
+ import { spectreTokens } from '@phcdevworks/spectre-tokens'
44
64
 
45
- const spectrePreset = createSpectreTailwindPreset({ tokens: spectreTokens });
65
+ const config: Config = {
66
+ content: ['./src/**/*.{ts,tsx,js,jsx,html}'],
67
+ presets: [createSpectreTailwindPreset({ tokens: spectreTokens })]
68
+ }
46
69
 
47
- export default {
48
- content: ["./src/**/*.{js,ts,jsx,tsx}"],
49
- presets: [spectrePreset],
50
- };
70
+ export default config
51
71
  ```
52
72
 
53
- ---
73
+ ### Class recipe usage
54
74
 
55
- ## 🧩 Class Recipes
75
+ Class recipes are the stable styling API for adapters and apps. They return
76
+ predictable class strings and keep behavior consistent across frameworks.
56
77
 
57
- Recipes are the API contract for all Spectre framework adapters. They ensure `.sp-btn--primary` always behaves identical whether used in React, Astro, or WordPress.
78
+ ```ts
79
+ import {
80
+ getBadgeClasses,
81
+ getButtonClasses,
82
+ getPricingCardClasses
83
+ } from '@phcdevworks/spectre-ui'
84
+
85
+ const cta = getButtonClasses({ variant: 'primary', size: 'lg' })
86
+ const badge = getBadgeClasses({ variant: 'success', size: 'sm' })
87
+ const pricingCard = getPricingCardClasses({ featured: true })
88
+ ```
58
89
 
59
- ### Core Components
60
- | Recipe | Primary Variants | Sizes |
61
- | :--- | :--- | :--- |
62
- | `getButtonClasses` | `primary`, `secondary`, `ghost`, `danger`, `success` | `sm`, `md`, `lg` |
63
- | `getBadgeClasses` | `primary`, `success`, `warning`, `danger` | `sm`, `md`, `lg` |
64
- | `getCardClasses` | `elevated`, `outline`, `ghost` | `padded` |
65
- | `getInputClasses` | `default`, `error`, `success` | `sm`, `md`, `lg` |
66
- | `getIconBoxClasses` | `primary`, `success`, `warning`, `danger`, `info` | `sm`, `md`, `lg` |
90
+ ## What this package owns
67
91
 
68
- ### Specialized Components
69
- | Recipe | Description |
70
- | :--- | :--- |
71
- | `getPricingCardClasses` | Semantic structure for pricing tables and plans. |
72
- | `getTestimonialClasses` | Compound classes for quotes, authors, and roles. |
73
- | `getRatingClasses` | Layout recipes for star ratings and count labels. |
92
+ - Token-driven CSS implementation
93
+ - Precompiled CSS bundles and utility classes
94
+ - Tailwind helpers and preset generation
95
+ - Type-safe class recipes for shared UI contracts
96
+ - Stable styling behavior consumed by downstream adapters and apps
74
97
 
75
- ```ts
76
- import { getButtonClasses, getPricingCardClasses } from "@phcdevworks/spectre-ui";
98
+ Golden rule: consume tokens, do not redefine them.
77
99
 
78
- // Generate a primary CTA class string
79
- const cta = getButtonClasses({ variant: "primary", size: "lg" });
80
- // Result: "sp-btn sp-btn--primary sp-btn--lg"
100
+ ## What this package does not own
81
101
 
82
- // Generate pricing card layout
83
- const pricing = getPricingCardClasses({ featured: true });
84
- ```
102
+ - Design values or semantic meaning That belongs to
103
+ `@phcdevworks/spectre-tokens`.
104
+ - Framework-specific component delivery Adapters and apps consume
105
+ `@phcdevworks/spectre-ui`; they do not recreate its styling logic.
106
+ - Local visual values outside the token contract Hardcoded hex, spacing, or
107
+ shadow values are drift unless clearly intentional and documented.
85
108
 
86
- ---
109
+ ## Package exports / API surface
87
110
 
88
- ## πŸ›οΈ The Spectre Suite Hierarchy
111
+ ### Root package
89
112
 
90
- Spectre is built on a non-negotiable hierarchy to prevent style leakage and duplication:
113
+ Exports CSS path constants and class recipes, including:
91
114
 
92
- 1. **Layer 1: Tokens** ([@phcdevworks/spectre-tokens](https://github.com/phcdevworks/spectre-tokens)) – The source of truth for all design values.
93
- 2. **Layer 2: UI (This Package)** – Translates tokens into CSS structure and recipes.
94
- 3. **Layer 3: Adapters** (WordPress, Astro, etc.) – Thin bridges that map Layer 2 to specific frameworks.
115
+ - `spectreStyles`
116
+ - `getButtonClasses`
117
+ - `getBadgeClasses`
118
+ - `getCardClasses`
119
+ - `getInputClasses`
120
+ - `getIconBoxClasses`
121
+ - `getPricingCardClasses`
122
+ - `getTestimonialClasses`
123
+ - `getRatingClasses`
95
124
 
96
- > **The Golden Rule**: Tokens define *meaning*. UI defines *structure*. Adapters define *delivery*.
125
+ Recipes also export their related TypeScript option and variant types.
97
126
 
98
- ---
127
+ ### Tailwind entry point
99
128
 
100
- ## πŸ› οΈ Development
129
+ `@phcdevworks/spectre-ui/tailwind` exports:
101
130
 
102
- ### Build Pipeline
103
- Compiles TypeScript, processes PostCSS, and bundles artifacts into `dist/`.
131
+ - `createSpectreTailwindPreset`
132
+ - `createSpectreTailwindTheme`
104
133
 
105
- ```bash
106
- npm run build
107
- ```
134
+ ### CSS entry points
135
+
136
+ - `@phcdevworks/spectre-ui/index.css`
137
+ - `@phcdevworks/spectre-ui/base.css`
138
+ - `@phcdevworks/spectre-ui/components.css`
139
+ - `@phcdevworks/spectre-ui/utilities.css`
140
+
141
+ ## Relationship to the rest of Spectre
142
+
143
+ Spectre keeps responsibilities separate:
144
+
145
+ - [`@phcdevworks/spectre-tokens`](https://github.com/phcdevworks/spectre-tokens)
146
+ defines design values and semantic meaning
147
+ - `@phcdevworks/spectre-ui` turns those tokens into reusable CSS, Tailwind
148
+ tooling, and type-safe class recipes
149
+ - Adapters and apps consume `@phcdevworks/spectre-ui` instead of re-implementing
150
+ its styling layer
151
+
152
+ That separation keeps recipe behavior consistent across frameworks and reduces
153
+ implementation drift.
154
+
155
+ ## Development
108
156
 
109
- ### Testing
110
- Run the Vitest suite to verify recipe outputs and token-first compliance.
157
+ Install dependencies, then run the package checks:
111
158
 
112
159
  ```bash
160
+ npm run build
113
161
  npm test
114
162
  ```
115
163
 
116
- ---
164
+ Key source areas:
165
+
166
+ - `src/styles/` for source CSS
167
+ - `src/recipes/` for class recipes
168
+ - `src/tailwind/` for Tailwind helpers
169
+ - `tests/` for contract and regression coverage
170
+
171
+ ## Contributing
172
+
173
+ PHCDevworks maintains this package as part of the Spectre suite.
174
+
175
+ When contributing:
176
+
177
+ - keep styling token-driven
178
+ - keep recipe APIs and CSS classes in sync
179
+ - avoid local visual values unless clearly intentional
180
+ - run `npm run build` and `npm test` before opening a pull request
181
+
182
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow.
117
183
 
118
- ## ❀️ Support & Community
184
+ ## License
119
185
 
120
- - **License**: MIT Β© [PHCDevworks](https://phcdevworks.com)
186
+ MIT Β© PHCDevworks. See [LICENSE](LICENSE).
@@ -560,6 +560,11 @@
560
560
  box-shadow: none;
561
561
  }
562
562
 
563
+ .sp-input--loading {
564
+ pointer-events: none;
565
+ opacity: var(--sp-opacity-active);
566
+ }
567
+
563
568
  /* CARDS ---------------------------------------------------------------- */
564
569
 
565
570
  .sp-card {
@@ -737,6 +742,11 @@
737
742
  pointer-events: none;
738
743
  }
739
744
 
745
+ .sp-badge--loading {
746
+ opacity: var(--sp-opacity-active);
747
+ pointer-events: none;
748
+ }
749
+
740
750
  /* ICON BOXES ----------------------------------------------------------- */
741
751
 
742
752
  .sp-iconbox {
@@ -847,6 +857,11 @@
847
857
  pointer-events: none;
848
858
  }
849
859
 
860
+ .sp-iconbox--loading {
861
+ opacity: var(--sp-opacity-active);
862
+ pointer-events: none;
863
+ }
864
+
850
865
  /* TESTIMONIALS --------------------------------------------------------- */
851
866
 
852
867
  .sp-testimonial {
@@ -859,6 +874,16 @@
859
874
  gap: var(--sp-space-24);
860
875
  }
861
876
 
877
+ .sp-testimonial--disabled {
878
+ opacity: var(--sp-opacity-disabled);
879
+ pointer-events: none;
880
+ }
881
+
882
+ .sp-testimonial--loading {
883
+ opacity: var(--sp-opacity-active);
884
+ pointer-events: none;
885
+ }
886
+
862
887
  .sp-testimonial-quote {
863
888
  color: var(--sp-component-testimonial-text);
864
889
  font-size: var(--sp-font-lg-size);
@@ -972,6 +997,16 @@
972
997
  gap: var(--sp-space-8);
973
998
  }
974
999
 
1000
+ .sp-rating--disabled {
1001
+ opacity: var(--sp-opacity-disabled);
1002
+ pointer-events: none;
1003
+ }
1004
+
1005
+ .sp-rating--loading {
1006
+ opacity: var(--sp-opacity-active);
1007
+ pointer-events: none;
1008
+ }
1009
+
975
1010
  .sp-rating-stars {
976
1011
  display: flex;
977
1012
  gap: var(--sp-space-4);
@@ -983,7 +1018,7 @@
983
1018
  align-items: center;
984
1019
  justify-content: center;
985
1020
  }
986
-
1021
+
987
1022
  .sp-rating-star--filled {
988
1023
  color: var(--sp-component-rating-star-filled);
989
1024
  }
package/dist/index.cjs CHANGED
@@ -157,7 +157,8 @@ var INPUT_STATES = {
157
157
  default: true,
158
158
  error: true,
159
159
  success: true,
160
- disabled: true
160
+ disabled: true,
161
+ loading: true
161
162
  };
162
163
  var INPUT_SIZES = {
163
164
  sm: true,
@@ -191,6 +192,7 @@ function getInputClasses(opts = {}) {
191
192
  state === "success" && "sp-input--success",
192
193
  // Visual state only; actual disabled attribute is handled by adapters.
193
194
  state === "disabled" && "sp-input--disabled",
195
+ state === "loading" && "sp-input--loading",
194
196
  fullWidth && "sp-input--full",
195
197
  pill && "sp-input--pill"
196
198
  );
@@ -212,7 +214,7 @@ var BADGE_SIZES = {
212
214
  lg: true
213
215
  };
214
216
  function getBadgeClasses(opts = {}) {
215
- const { variant: variantInput, size: sizeInput, interactive, disabled } = opts;
217
+ const { variant: variantInput, size: sizeInput, interactive, disabled, loading } = opts;
216
218
  const variant = resolveOption({
217
219
  name: "badge variant",
218
220
  value: variantInput,
@@ -246,7 +248,8 @@ function getBadgeClasses(opts = {}) {
246
248
  variantClass,
247
249
  sizeClass,
248
250
  interactive && "sp-badge--interactive",
249
- disabled && "sp-badge--disabled"
251
+ disabled && "sp-badge--disabled",
252
+ loading && "sp-badge--loading"
250
253
  );
251
254
  }
252
255
 
@@ -264,7 +267,7 @@ var ICONBOX_SIZES = {
264
267
  lg: true
265
268
  };
266
269
  function getIconBoxClasses(opts = {}) {
267
- const { variant: variantInput, size: sizeInput, disabled = false } = opts;
270
+ const { variant: variantInput, size: sizeInput, disabled = false, loading = false } = opts;
268
271
  const variant = resolveOption({
269
272
  name: "icon box variant",
270
273
  value: variantInput,
@@ -291,12 +294,23 @@ function getIconBoxClasses(opts = {}) {
291
294
  lg: "sp-iconbox--lg"
292
295
  };
293
296
  const sizeClass = sizeMap[size];
294
- return cx("sp-iconbox", variantClass, sizeClass, disabled && "sp-iconbox--disabled");
297
+ return cx(
298
+ "sp-iconbox",
299
+ variantClass,
300
+ sizeClass,
301
+ disabled && "sp-iconbox--disabled",
302
+ loading && "sp-iconbox--loading"
303
+ );
295
304
  }
296
305
 
297
306
  // src/recipes/testimonial.ts
298
- function getTestimonialClasses(_opts = {}) {
299
- return cx("sp-testimonial");
307
+ function getTestimonialClasses(opts = {}) {
308
+ const { disabled = false, loading = false } = opts;
309
+ return cx(
310
+ "sp-testimonial",
311
+ disabled && "sp-testimonial--disabled",
312
+ loading && "sp-testimonial--loading"
313
+ );
300
314
  }
301
315
  function getTestimonialQuoteClasses() {
302
316
  return cx("sp-testimonial-quote");
@@ -337,8 +351,13 @@ function getPricingCardDescriptionClasses() {
337
351
  }
338
352
 
339
353
  // src/recipes/rating.ts
340
- function getRatingClasses(_opts = {}) {
341
- return cx("sp-rating");
354
+ function getRatingClasses(opts = {}) {
355
+ const { disabled = false, loading = false } = opts;
356
+ return cx(
357
+ "sp-rating",
358
+ disabled && "sp-rating--disabled",
359
+ loading && "sp-rating--loading"
360
+ );
342
361
  }
343
362
  function getRatingStarsClasses() {
344
363
  return cx("sp-rating-stars");
@@ -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\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"]}
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":";;;AAAO,IAAM,qBAAA,GAAwB;AAC9B,IAAM,2BAAA,GAA8B;AACpC,IAAM,0BAAA,GAA6B;AACnC,IAAM,sBAAA,GAAyB,mCAAA;AAE/B,IAAM,aAAA,GAAgB;AAAA,EAC3B,KAAA,EAAO,sBAAA;AAAA,EACP,IAAA,EAAM,qBAAA;AAAA,EACN,UAAA,EAAY,2BAAA;AAAA,EACZ,SAAA,EAAW;AACb;;;ACVO,SAAS,MAAM,KAAA,EAAyD;AAC7E,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,MAAM,UAAoB,EAAC;AAE3B,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,IAAI,CAAC,IAAA,CAAK,IAAA,CAAK,OAAO,CAAA,EAAG;AACvB,MAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,EAAG;AACtB,QAAA,IAAA,CAAK,IAAI,OAAO,CAAA;AAChB,QAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,MACtB;AACA,MAAA;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,KAAA,IAAS,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AACxC,MAAA,IAAI,CAAC,KAAA,IAAS,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG;AAC/B,MAAA,IAAA,CAAK,IAAI,KAAK,CAAA;AACd,MAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAEA,EAAA,OAAO,OAAA,CAAQ,KAAK,GAAG,CAAA;AACzB;;;ACvBA,IAAM,MAAA,GAAS,CAAC,KAAA,EAAe,GAAA,KAC7B,OAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAK,KAAA,EAAO,GAAG,CAAA;AAEjD,IAAM,cAAA,GAAiB,CAAmB,KAAA,EAAU,OAAA,KAClD,MAAM,OAAA,CAAQ,OAAO,CAAA,GAAI,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,GAAI,MAAA,CAAO,SAAS,KAAK,CAAA;AAEnE,SAAS,cAAgC,MAAA,EAK1C;AACJ,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,UAAS,GAAI,MAAA;AAE3C,EAAA,IAAI,KAAA,KAAU,QAAW,OAAO,QAAA;AAChC,EAAA,IAAI,cAAA,CAAe,KAAA,EAAO,OAAO,CAAA,EAAG,OAAO,KAAA;AAE3C,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,YAAA,EAAc;AACzC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAA;AAAA,EAC1D;AAEA,EAAA,OAAO,QAAA;AACT;;;ACfA,IAAM,eAAA,GAAkB;AAAA,EACtB,OAAA,EAAS,IAAA;AAAA,EACT,SAAA,EAAW,IAAA;AAAA,EACX,KAAA,EAAO,IAAA;AAAA,EACP,MAAA,EAAQ,IAAA;AAAA,EACR,OAAA,EAAS,IAAA;AAAA,EACT,GAAA,EAAK,IAAA;AAAA,EACL,MAAA,EAAQ;AACV,CAAA;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAgBO,SAAS,gBAAA,CAAiB,IAAA,GAA4B,EAAC,EAAW;AACvE,EAAA,MAAM;AAAA,IACJ,OAAA,EAAS,YAAA;AAAA,IACT,IAAA,EAAM,SAAA;AAAA,IACN,SAAA,GAAY,KAAA;AAAA,IACZ,OAAA,GAAU,KAAA;AAAA,IACV,QAAA,GAAW,KAAA;AAAA,IACX,QAAA,GAAW,KAAA;AAAA,IACX,IAAA,GAAO;AAAA,GACT,GAAI,IAAA;AAEJ,EAAA,MAAM,UAAU,aAAA,CAAc;AAAA,IAC5B,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,EAAO,YAAA;AAAA,IACP,OAAA,EAAS,eAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AACD,EAAA,MAAM,OAAO,aAAA,CAAc;AAAA,IACzB,IAAA,EAAM,aAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,OAAA,EAAS,YAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,MAAM,UAAA,GAA4C;AAAA,IAChD,OAAA,EAAS,iBAAA;AAAA,IACT,SAAA,EAAW,mBAAA;AAAA,IACX,KAAA,EAAO,eAAA;AAAA,IACP,MAAA,EAAQ,gBAAA;AAAA,IACR,OAAA,EAAS,iBAAA;AAAA,IACT,GAAA,EAAK,aAAA;AAAA,IACL,MAAA,EAAQ;AAAA,GACV;AACA,EAAA,MAAM,YAAA,GAAe,WAAW,OAAO,CAAA;AAEvC,EAAA,MAAM,OAAA,GAAsC;AAAA,IAC1C,EAAA,EAAI,YAAA;AAAA,IACJ,EAAA,EAAI,YAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACN;AACA,EAAA,MAAM,SAAA,GAAY,QAAQ,IAAI,CAAA;AAE9B,EAAA,OAAO,EAAA;AAAA,IACL,QAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA,IAAa,cAAA;AAAA,IACb,OAAA,IAAW,iBAAA;AAAA,IACX,QAAA,IAAY,kBAAA;AAAA,IACZ,QAAA,IAAY,cAAA;AAAA,IACZ,IAAA,IAAQ;AAAA,GACV;AACF;;;ACpFA,IAAM,aAAA,GAAgB;AAAA,EACpB,QAAA,EAAU,IAAA;AAAA,EACV,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,EAAS,IAAA;AAAA,EACT,KAAA,EAAO;AACT,CAAA;AAUO,SAAS,cAAA,CAAe,IAAA,GAA0B,EAAC,EAAW;AACnE,EAAA,MAAM;AAAA,IACJ,OAAA,EAAS,YAAA;AAAA,IACT,WAAA,GAAc,KAAA;AAAA,IACd,MAAA,GAAS,KAAA;AAAA,IACT,UAAA,GAAa,KAAA;AAAA,IACb,QAAA,GAAW;AAAA,GACb,GAAI,IAAA;AAEJ,EAAA,MAAM,UAAU,aAAA,CAAc;AAAA,IAC5B,IAAA,EAAM,cAAA;AAAA,IACN,KAAA,EAAO,YAAA;AAAA,IACP,OAAA,EAAS,aAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,MAAM,UAAA,GAA0C;AAAA,IAC9C,QAAA,EAAU,mBAAA;AAAA,IACV,IAAA,EAAM,eAAA;AAAA,IACN,OAAA,EAAS,kBAAA;AAAA,IACT,KAAA,EAAO;AAAA,GACT;AACA,EAAA,MAAM,YAAA,GAAe,WAAW,OAAO,CAAA;AAEvC,EAAA,OAAO,EAAA;AAAA,IACL,SAAA;AAAA,IACA,YAAA;AAAA,IACA,WAAA,IAAe,sBAAA;AAAA,IACf,MAAA,IAAU,iBAAA;AAAA,IACV,UAAA,IAAc,eAAA;AAAA,IACd,QAAA,IAAY;AAAA,GACd;AACF;;;AC7CA,IAAM,YAAA,GAAe;AAAA,EACnB,OAAA,EAAS,IAAA;AAAA,EACT,KAAA,EAAO,IAAA;AAAA,EACP,OAAA,EAAS,IAAA;AAAA,EACT,QAAA,EAAU,IAAA;AAAA,EACV,OAAA,EAAS;AACX,CAAA;AAEA,IAAM,WAAA,GAAc;AAAA,EAClB,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AASO,SAAS,eAAA,CAAgB,IAAA,GAA2B,EAAC,EAAW;AACrE,EAAA,MAAM,EAAE,OAAO,UAAA,EAAY,IAAA,EAAM,WAAW,SAAA,GAAY,KAAA,EAAO,IAAA,GAAO,KAAA,EAAM,GAAI,IAAA;AAEhF,EAAA,MAAM,QAAQ,aAAA,CAAc;AAAA,IAC1B,IAAA,EAAM,aAAA;AAAA,IACN,KAAA,EAAO,UAAA;AAAA,IACP,OAAA,EAAS,YAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AACD,EAAA,MAAM,OAAO,aAAA,CAAc;AAAA,IACzB,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,OAAA,EAAS,WAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,MAAM,OAAA,GAAqC;AAAA,IACzC,EAAA,EAAI,cAAA;AAAA,IACJ,EAAA,EAAI,cAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACN;AACA,EAAA,MAAM,SAAA,GAAY,QAAQ,IAAI,CAAA;AAG9B,EAAA,OAAO,EAAA;AAAA,IACL,UAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAU,OAAA,IAAW,iBAAA;AAAA,IACrB,UAAU,SAAA,IAAa,mBAAA;AAAA;AAAA,IAEvB,UAAU,UAAA,IAAc,oBAAA;AAAA,IACxB,UAAU,SAAA,IAAa,mBAAA;AAAA,IACvB,SAAA,IAAa,gBAAA;AAAA,IACb,IAAA,IAAQ;AAAA,GACV;AACF;;;ACxDA,IAAM,cAAA,GAAiB;AAAA,EACrB,OAAA,EAAS,IAAA;AAAA,EACT,SAAA,EAAW,IAAA;AAAA,EACX,OAAA,EAAS,IAAA;AAAA,EACT,OAAA,EAAS,IAAA;AAAA,EACT,MAAA,EAAQ,IAAA;AAAA,EACR,OAAA,EAAS,IAAA;AAAA,EACT,IAAA,EAAM;AACR,CAAA;AAEA,IAAM,WAAA,GAAc;AAAA,EAClB,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAcO,SAAS,eAAA,CAAgB,IAAA,GAA2B,EAAC,EAAW;AACrE,EAAA,MAAM,EAAE,SAAS,YAAA,EAAc,IAAA,EAAM,WAAW,WAAA,EAAa,QAAA,EAAU,SAAQ,GAAI,IAAA;AAEnF,EAAA,MAAM,UAAU,aAAA,CAAc;AAAA,IAC5B,IAAA,EAAM,eAAA;AAAA,IACN,KAAA,EAAO,YAAA;AAAA,IACP,OAAA,EAAS,cAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AACD,EAAA,MAAM,OAAO,aAAA,CAAc;AAAA,IACzB,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,OAAA,EAAS,WAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,MAAM,UAAA,GAA2C;AAAA,IAC/C,OAAA,EAAS,mBAAA;AAAA,IACT,SAAA,EAAW,qBAAA;AAAA,IACX,OAAA,EAAS,mBAAA;AAAA,IACT,OAAA,EAAS,mBAAA;AAAA,IACT,MAAA,EAAQ,kBAAA;AAAA,IACR,OAAA,EAAS,mBAAA;AAAA,IACT,IAAA,EAAM;AAAA,GACR;AACA,EAAA,MAAM,YAAA,GAAe,WAAW,OAAO,CAAA;AAEvC,EAAA,MAAM,OAAA,GAAqC;AAAA,IACzC,EAAA,EAAI,cAAA;AAAA,IACJ,EAAA,EAAI,cAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACN;AACA,EAAA,MAAM,SAAA,GAAY,QAAQ,IAAI,CAAA;AAE9B,EAAA,OAAO,EAAA;AAAA,IACL,UAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA,IAAe,uBAAA;AAAA,IACf,QAAA,IAAY,oBAAA;AAAA,IACZ,OAAA,IAAW;AAAA,GACb;AACF;;;ACtEA,IAAM,gBAAA,GAAmB;AAAA,EACvB,OAAA,EAAS,IAAA;AAAA,EACT,OAAA,EAAS,IAAA;AAAA,EACT,OAAA,EAAS,IAAA;AAAA,EACT,MAAA,EAAQ,IAAA;AAAA,EACR,IAAA,EAAM;AACR,CAAA;AAEA,IAAM,aAAA,GAAgB;AAAA,EACpB,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AASO,SAAS,iBAAA,CAAkB,IAAA,GAA6B,EAAC,EAAW;AACzE,EAAA,MAAM,EAAE,SAAS,YAAA,EAAc,IAAA,EAAM,WAAW,QAAA,GAAW,KAAA,EAAO,OAAA,GAAU,KAAA,EAAM,GAAI,IAAA;AAEtF,EAAA,MAAM,UAAU,aAAA,CAAc;AAAA,IAC5B,IAAA,EAAM,kBAAA;AAAA,IACN,KAAA,EAAO,YAAA;AAAA,IACP,OAAA,EAAS,gBAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AACD,EAAA,MAAM,OAAO,aAAA,CAAc;AAAA,IACzB,IAAA,EAAM,eAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,OAAA,EAAS,aAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AAED,EAAA,MAAM,UAAA,GAA6C;AAAA,IACjD,OAAA,EAAS,qBAAA;AAAA,IACT,OAAA,EAAS,qBAAA;AAAA,IACT,OAAA,EAAS,qBAAA;AAAA,IACT,MAAA,EAAQ,oBAAA;AAAA,IACR,IAAA,EAAM;AAAA,GACR;AACA,EAAA,MAAM,YAAA,GAAe,WAAW,OAAO,CAAA;AAEvC,EAAA,MAAM,OAAA,GAAuC;AAAA,IAC3C,EAAA,EAAI,gBAAA;AAAA,IACJ,EAAA,EAAI,gBAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACN;AACA,EAAA,MAAM,SAAA,GAAY,QAAQ,IAAI,CAAA;AAE9B,EAAA,OAAO,EAAA;AAAA,IACL,YAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA,IAAY,sBAAA;AAAA,IACZ,OAAA,IAAW;AAAA,GACb;AACF;;;AC1DO,SAAS,qBAAA,CAAsB,IAAA,GAAiC,EAAC,EAAW;AACjF,EAAA,MAAM,EAAE,QAAA,GAAW,KAAA,EAAO,OAAA,GAAU,OAAM,GAAI,IAAA;AAC9C,EAAA,OAAO,EAAA;AAAA,IACL,gBAAA;AAAA,IACA,QAAA,IAAY,0BAAA;AAAA,IACZ,OAAA,IAAW;AAAA,GACb;AACF;AAEO,SAAS,0BAAA,GAAqC;AACnD,EAAA,OAAO,GAAG,sBAAsB,CAAA;AAClC;AAEO,SAAS,2BAAA,GAAsC;AACpD,EAAA,OAAO,GAAG,uBAAuB,CAAA;AACnC;AAEO,SAAS,+BAAA,GAA0C;AACxD,EAAA,OAAO,GAAG,4BAA4B,CAAA;AACxC;AAEO,SAAS,+BAAA,GAA0C;AACxD,EAAA,OAAO,GAAG,4BAA4B,CAAA;AACxC;AAEO,SAAS,gCAAA,GAA2C;AACzD,EAAA,OAAO,GAAG,6BAA6B,CAAA;AACzC;;;AC3BO,SAAS,qBAAA,CAAsB,IAAA,GAAiC,EAAC,EAAW;AACjF,EAAA,MAAM,EAAE,QAAA,GAAW,KAAA,EAAO,QAAA,GAAW,OAAM,GAAI,IAAA;AAC/C,EAAA,OAAO,EAAA;AAAA,IACL,iBAAA;AAAA,IACA,QAAA,IAAY,2BAAA;AAAA,IACZ,QAAA,IAAY;AAAA,GACd;AACF;AAEO,SAAS,0BAAA,GAAqC;AACnD,EAAA,OAAO,GAAG,uBAAuB,CAAA;AACnC;AAEO,SAAS,mCAAA,GAA8C;AAC5D,EAAA,OAAO,GAAG,iCAAiC,CAAA;AAC7C;AAEO,SAAS,0BAAA,GAAqC;AACnD,EAAA,OAAO,GAAG,uBAAuB,CAAA;AACnC;AAEO,SAAS,gCAAA,GAA2C;AACzD,EAAA,OAAO,GAAG,6BAA6B,CAAA;AACzC;;;ACvBO,SAAS,gBAAA,CAAiB,IAAA,GAA4B,EAAC,EAAW;AACvE,EAAA,MAAM,EAAE,QAAA,GAAW,KAAA,EAAO,OAAA,GAAU,OAAM,GAAI,IAAA;AAC9C,EAAA,OAAO,EAAA;AAAA,IACL,WAAA;AAAA,IACA,QAAA,IAAY,qBAAA;AAAA,IACZ,OAAA,IAAW;AAAA,GACb;AACF;AAEO,SAAS,qBAAA,GAAgC;AAC9C,EAAA,OAAO,GAAG,iBAAiB,CAAA;AAC7B;AAEO,SAAS,oBAAA,CAAqB,WAAoB,KAAA,EAAe;AACtE,EAAA,OAAO,EAAA;AAAA,IACL,gBAAA;AAAA,IACA,QAAA,IAAY;AAAA,GACd;AACF;AAEO,SAAS,oBAAA,GAA+B;AAC7C,EAAA,OAAO,GAAG,gBAAgB,CAAA;AAC5B","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\", \"loading\"] 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 loading: 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 state === \"loading\" && \"sp-input--loading\",\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 loading?: boolean;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, interactive, disabled, loading } = 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 loading && \"sp-badge--loading\"\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 loading?: boolean;\n}\n\nexport function getIconBoxClasses(opts: IconBoxRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput, disabled = false, loading = 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(\n \"sp-iconbox\",\n variantClass,\n sizeClass,\n disabled && \"sp-iconbox--disabled\",\n loading && \"sp-iconbox--loading\",\n );\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 disabled?: boolean;\n loading?: boolean;\n}\n\nexport function getTestimonialClasses(opts: TestimonialRecipeOptions = {}): string {\n const { disabled = false, loading = false } = opts;\n return cx(\n \"sp-testimonial\",\n disabled && \"sp-testimonial--disabled\",\n loading && \"sp-testimonial--loading\"\n );\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 disabled?: boolean;\n loading?: boolean;\n}\n\nexport function getRatingClasses(opts: RatingRecipeOptions = {}): string {\n const { disabled = false, loading = false } = opts;\n return cx(\n \"sp-rating\",\n disabled && \"sp-rating--disabled\",\n loading && \"sp-rating--loading\"\n );\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"]}