@phcdevworks/spectre-ui 0.4.1 → 1.0.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/dist/index.d.cts CHANGED
@@ -8,7 +8,7 @@ declare const spectreStyles: {
8
8
  utilities: string;
9
9
  };
10
10
 
11
- declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger", "success"];
11
+ declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger", "success", "cta", "accent"];
12
12
  declare const buttonSizes: readonly ["sm", "md", "lg"];
13
13
  type ButtonVariant = (typeof buttonVariants)[number];
14
14
  type ButtonSize = (typeof buttonSizes)[number];
@@ -19,6 +19,7 @@ interface ButtonRecipeOptions {
19
19
  loading?: boolean;
20
20
  disabled?: boolean;
21
21
  iconOnly?: boolean;
22
+ pill?: boolean;
22
23
  }
23
24
  declare function getButtonClasses(opts?: ButtonRecipeOptions): string;
24
25
 
@@ -43,13 +44,14 @@ interface InputRecipeOptions {
43
44
  }
44
45
  declare function getInputClasses(opts?: InputRecipeOptions): string;
45
46
 
46
- declare const badgeVariants: readonly ["primary", "success", "warning", "danger"];
47
+ declare const badgeVariants: readonly ["primary", "secondary", "success", "warning", "danger", "neutral", "info"];
47
48
  declare const badgeSizes: readonly ["sm", "md", "lg"];
48
49
  type BadgeVariant = (typeof badgeVariants)[number];
49
50
  type BadgeSize = (typeof badgeSizes)[number];
50
51
  interface BadgeRecipeOptions {
51
52
  variant?: BadgeVariant;
52
53
  size?: BadgeSize;
54
+ interactive?: boolean;
53
55
  }
54
56
  declare function getBadgeClasses(opts?: BadgeRecipeOptions): string;
55
57
 
@@ -63,4 +65,29 @@ interface IconBoxRecipeOptions {
63
65
  }
64
66
  declare function getIconBoxClasses(opts?: IconBoxRecipeOptions): string;
65
67
 
66
- export { type BadgeRecipeOptions, type BadgeSize, type BadgeVariant, type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type IconBoxRecipeOptions, type IconBoxSize, type IconBoxVariant, type InputRecipeOptions, type InputSize, type InputState, getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
68
+ interface TestimonialRecipeOptions {
69
+ }
70
+ declare function getTestimonialClasses(_opts?: TestimonialRecipeOptions): string;
71
+ declare function getTestimonialQuoteClasses(): string;
72
+ declare function getTestimonialAuthorClasses(): string;
73
+ declare function getTestimonialAuthorInfoClasses(): string;
74
+ declare function getTestimonialAuthorNameClasses(): string;
75
+ declare function getTestimonialAuthorTitleClasses(): string;
76
+
77
+ interface PricingCardRecipeOptions {
78
+ featured?: boolean;
79
+ }
80
+ declare function getPricingCardClasses(opts?: PricingCardRecipeOptions): string;
81
+ declare function getPricingCardBadgeClasses(): string;
82
+ declare function getPricingCardPriceContainerClasses(): string;
83
+ declare function getPricingCardPriceClasses(): string;
84
+ declare function getPricingCardDescriptionClasses(): string;
85
+
86
+ interface RatingRecipeOptions {
87
+ }
88
+ declare function getRatingClasses(_opts?: RatingRecipeOptions): string;
89
+ declare function getRatingStarsClasses(): string;
90
+ declare function getRatingStarClasses(isFilled?: boolean): string;
91
+ declare function getRatingTextClasses(): string;
92
+
93
+ export { type BadgeRecipeOptions, type BadgeSize, type BadgeVariant, type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type IconBoxRecipeOptions, type IconBoxSize, type IconBoxVariant, type InputRecipeOptions, type InputSize, type InputState, type PricingCardRecipeOptions, type RatingRecipeOptions, type TestimonialRecipeOptions, getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, getPricingCardBadgeClasses, getPricingCardClasses, getPricingCardDescriptionClasses, getPricingCardPriceClasses, getPricingCardPriceContainerClasses, getRatingClasses, getRatingStarClasses, getRatingStarsClasses, getRatingTextClasses, getTestimonialAuthorClasses, getTestimonialAuthorInfoClasses, getTestimonialAuthorNameClasses, getTestimonialAuthorTitleClasses, getTestimonialClasses, getTestimonialQuoteClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ declare const spectreStyles: {
8
8
  utilities: string;
9
9
  };
10
10
 
11
- declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger", "success"];
11
+ declare const buttonVariants: readonly ["primary", "secondary", "ghost", "danger", "success", "cta", "accent"];
12
12
  declare const buttonSizes: readonly ["sm", "md", "lg"];
13
13
  type ButtonVariant = (typeof buttonVariants)[number];
14
14
  type ButtonSize = (typeof buttonSizes)[number];
@@ -19,6 +19,7 @@ interface ButtonRecipeOptions {
19
19
  loading?: boolean;
20
20
  disabled?: boolean;
21
21
  iconOnly?: boolean;
22
+ pill?: boolean;
22
23
  }
23
24
  declare function getButtonClasses(opts?: ButtonRecipeOptions): string;
24
25
 
@@ -43,13 +44,14 @@ interface InputRecipeOptions {
43
44
  }
44
45
  declare function getInputClasses(opts?: InputRecipeOptions): string;
45
46
 
46
- declare const badgeVariants: readonly ["primary", "success", "warning", "danger"];
47
+ declare const badgeVariants: readonly ["primary", "secondary", "success", "warning", "danger", "neutral", "info"];
47
48
  declare const badgeSizes: readonly ["sm", "md", "lg"];
48
49
  type BadgeVariant = (typeof badgeVariants)[number];
49
50
  type BadgeSize = (typeof badgeSizes)[number];
50
51
  interface BadgeRecipeOptions {
51
52
  variant?: BadgeVariant;
52
53
  size?: BadgeSize;
54
+ interactive?: boolean;
53
55
  }
54
56
  declare function getBadgeClasses(opts?: BadgeRecipeOptions): string;
55
57
 
@@ -63,4 +65,29 @@ interface IconBoxRecipeOptions {
63
65
  }
64
66
  declare function getIconBoxClasses(opts?: IconBoxRecipeOptions): string;
65
67
 
66
- export { type BadgeRecipeOptions, type BadgeSize, type BadgeVariant, type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type IconBoxRecipeOptions, type IconBoxSize, type IconBoxVariant, type InputRecipeOptions, type InputSize, type InputState, getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
68
+ interface TestimonialRecipeOptions {
69
+ }
70
+ declare function getTestimonialClasses(_opts?: TestimonialRecipeOptions): string;
71
+ declare function getTestimonialQuoteClasses(): string;
72
+ declare function getTestimonialAuthorClasses(): string;
73
+ declare function getTestimonialAuthorInfoClasses(): string;
74
+ declare function getTestimonialAuthorNameClasses(): string;
75
+ declare function getTestimonialAuthorTitleClasses(): string;
76
+
77
+ interface PricingCardRecipeOptions {
78
+ featured?: boolean;
79
+ }
80
+ declare function getPricingCardClasses(opts?: PricingCardRecipeOptions): string;
81
+ declare function getPricingCardBadgeClasses(): string;
82
+ declare function getPricingCardPriceContainerClasses(): string;
83
+ declare function getPricingCardPriceClasses(): string;
84
+ declare function getPricingCardDescriptionClasses(): string;
85
+
86
+ interface RatingRecipeOptions {
87
+ }
88
+ declare function getRatingClasses(_opts?: RatingRecipeOptions): string;
89
+ declare function getRatingStarsClasses(): string;
90
+ declare function getRatingStarClasses(isFilled?: boolean): string;
91
+ declare function getRatingTextClasses(): string;
92
+
93
+ export { type BadgeRecipeOptions, type BadgeSize, type BadgeVariant, type ButtonRecipeOptions, type ButtonSize, type ButtonVariant, type CardRecipeOptions, type CardVariant, type IconBoxRecipeOptions, type IconBoxSize, type IconBoxVariant, type InputRecipeOptions, type InputSize, type InputState, type PricingCardRecipeOptions, type RatingRecipeOptions, type TestimonialRecipeOptions, getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, getPricingCardBadgeClasses, getPricingCardClasses, getPricingCardDescriptionClasses, getPricingCardPriceClasses, getPricingCardPriceContainerClasses, getRatingClasses, getRatingStarClasses, getRatingStarsClasses, getRatingTextClasses, getTestimonialAuthorClasses, getTestimonialAuthorInfoClasses, getTestimonialAuthorNameClasses, getTestimonialAuthorTitleClasses, getTestimonialClasses, getTestimonialQuoteClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
package/dist/index.js CHANGED
@@ -53,7 +53,9 @@ var BUTTON_VARIANTS = {
53
53
  secondary: true,
54
54
  ghost: true,
55
55
  danger: true,
56
- success: true
56
+ success: true,
57
+ cta: true,
58
+ accent: true
57
59
  };
58
60
  var BUTTON_SIZES = {
59
61
  sm: true,
@@ -67,7 +69,8 @@ function getButtonClasses(opts = {}) {
67
69
  fullWidth = false,
68
70
  loading = false,
69
71
  disabled = false,
70
- iconOnly = false
72
+ iconOnly = false,
73
+ pill = false
71
74
  } = opts;
72
75
  const variant = resolveOption({
73
76
  name: "button variant",
@@ -86,7 +89,9 @@ function getButtonClasses(opts = {}) {
86
89
  secondary: "sp-btn--secondary",
87
90
  ghost: "sp-btn--ghost",
88
91
  danger: "sp-btn--danger",
89
- success: "sp-btn--success"
92
+ success: "sp-btn--success",
93
+ cta: "sp-btn--cta",
94
+ accent: "sp-btn--accent"
90
95
  };
91
96
  const variantClass = variantMap[variant];
92
97
  const sizeMap = {
@@ -102,7 +107,8 @@ function getButtonClasses(opts = {}) {
102
107
  fullWidth && "sp-btn--full",
103
108
  loading && "sp-btn--loading",
104
109
  disabled && "sp-btn--disabled",
105
- iconOnly && "sp-btn--icon"
110
+ iconOnly && "sp-btn--icon",
111
+ pill && "sp-btn--pill"
106
112
  );
107
113
  }
108
114
 
@@ -188,9 +194,12 @@ function getInputClasses(opts = {}) {
188
194
  // src/recipes/badge.ts
189
195
  var BADGE_VARIANTS = {
190
196
  primary: true,
197
+ secondary: true,
191
198
  success: true,
192
199
  warning: true,
193
- danger: true
200
+ danger: true,
201
+ neutral: true,
202
+ info: true
194
203
  };
195
204
  var BADGE_SIZES = {
196
205
  sm: true,
@@ -198,7 +207,7 @@ var BADGE_SIZES = {
198
207
  lg: true
199
208
  };
200
209
  function getBadgeClasses(opts = {}) {
201
- const { variant: variantInput, size: sizeInput } = opts;
210
+ const { variant: variantInput, size: sizeInput, interactive } = opts;
202
211
  const variant = resolveOption({
203
212
  name: "badge variant",
204
213
  value: variantInput,
@@ -213,9 +222,12 @@ function getBadgeClasses(opts = {}) {
213
222
  });
214
223
  const variantMap = {
215
224
  primary: "sp-badge--primary",
225
+ secondary: "sp-badge--secondary",
216
226
  success: "sp-badge--success",
217
227
  warning: "sp-badge--warning",
218
- danger: "sp-badge--danger"
228
+ danger: "sp-badge--danger",
229
+ neutral: "sp-badge--neutral",
230
+ info: "sp-badge--info"
219
231
  };
220
232
  const variantClass = variantMap[variant];
221
233
  const sizeMap = {
@@ -224,7 +236,12 @@ function getBadgeClasses(opts = {}) {
224
236
  lg: "sp-badge--lg"
225
237
  };
226
238
  const sizeClass = sizeMap[size];
227
- return cx("sp-badge", variantClass, sizeClass);
239
+ return cx(
240
+ "sp-badge",
241
+ variantClass,
242
+ sizeClass,
243
+ interactive && "sp-badge--interactive"
244
+ );
228
245
  }
229
246
 
230
247
  // src/recipes/iconbox.ts
@@ -271,6 +288,64 @@ function getIconBoxClasses(opts = {}) {
271
288
  return cx("sp-iconbox", variantClass, sizeClass);
272
289
  }
273
290
 
274
- export { getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
291
+ // src/recipes/testimonial.ts
292
+ function getTestimonialClasses(_opts = {}) {
293
+ return cx("sp-testimonial");
294
+ }
295
+ function getTestimonialQuoteClasses() {
296
+ return cx("sp-testimonial-quote");
297
+ }
298
+ function getTestimonialAuthorClasses() {
299
+ return cx("sp-testimonial-author");
300
+ }
301
+ function getTestimonialAuthorInfoClasses() {
302
+ return cx("sp-testimonial-author-info");
303
+ }
304
+ function getTestimonialAuthorNameClasses() {
305
+ return cx("sp-testimonial-author-name");
306
+ }
307
+ function getTestimonialAuthorTitleClasses() {
308
+ return cx("sp-testimonial-author-title");
309
+ }
310
+
311
+ // src/recipes/pricing-card.ts
312
+ function getPricingCardClasses(opts = {}) {
313
+ const { featured = false } = opts;
314
+ return cx(
315
+ "sp-pricing-card",
316
+ featured && "sp-pricing-card--featured"
317
+ );
318
+ }
319
+ function getPricingCardBadgeClasses() {
320
+ return cx("sp-pricing-card-badge");
321
+ }
322
+ function getPricingCardPriceContainerClasses() {
323
+ return cx("sp-pricing-card-price-container");
324
+ }
325
+ function getPricingCardPriceClasses() {
326
+ return cx("sp-pricing-card-price");
327
+ }
328
+ function getPricingCardDescriptionClasses() {
329
+ return cx("sp-pricing-card-description");
330
+ }
331
+
332
+ // src/recipes/rating.ts
333
+ function getRatingClasses(_opts = {}) {
334
+ return cx("sp-rating");
335
+ }
336
+ function getRatingStarsClasses() {
337
+ return cx("sp-rating-stars");
338
+ }
339
+ function getRatingStarClasses(isFilled = false) {
340
+ return cx(
341
+ "sp-rating-star",
342
+ isFilled && "sp-rating-star--filled"
343
+ );
344
+ }
345
+ function getRatingTextClasses() {
346
+ return cx("sp-rating-text");
347
+ }
348
+
349
+ export { getBadgeClasses, getButtonClasses, getCardClasses, getIconBoxClasses, getInputClasses, getPricingCardBadgeClasses, getPricingCardClasses, getPricingCardDescriptionClasses, getPricingCardPriceClasses, getPricingCardPriceContainerClasses, getRatingClasses, getRatingStarClasses, getRatingStarsClasses, getRatingTextClasses, getTestimonialAuthorClasses, getTestimonialAuthorInfoClasses, getTestimonialAuthorNameClasses, getTestimonialAuthorTitleClasses, getTestimonialClasses, getTestimonialQuoteClasses, spectreBaseStylesPath, spectreComponentsStylesPath, spectreStyles, spectreUtilitiesStylesPath };
275
350
  //# sourceMappingURL=index.js.map
276
351
  //# sourceMappingURL=index.js.map
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"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const spectreBaseStylesPath = \"@phcdevworks/spectre-ui/base.css\";\nexport const spectreComponentsStylesPath = \"@phcdevworks/spectre-ui/components.css\";\nexport const spectreUtilitiesStylesPath = \"@phcdevworks/spectre-ui/utilities.css\";\nexport const spectreIndexStylesPath = \"@phcdevworks/spectre-ui/index.css\";\n\nexport const spectreStyles = {\n index: spectreIndexStylesPath,\n base: spectreBaseStylesPath,\n components: spectreComponentsStylesPath,\n utilities: spectreUtilitiesStylesPath,\n};\n","export function cx(...parts: Array<string | false | null | undefined>): string {\n const seen = new Set<string>();\n const classes: string[] = [];\n\n for (const part of parts) {\n if (!part) continue;\n const trimmed = part.trim();\n if (!trimmed) continue;\n\n if (!/\\s/.test(trimmed)) {\n if (!seen.has(trimmed)) {\n seen.add(trimmed);\n classes.push(trimmed);\n }\n continue;\n }\n\n for (const token of trimmed.split(/\\s+/)) {\n if (!token || seen.has(token)) continue;\n seen.add(token);\n classes.push(token);\n }\n }\n\n return classes.join(\" \");\n}\n","type AllowedValues<T extends string> = readonly T[] | Record<T, unknown>;\n\nconst hasOwn = (value: object, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\nconst isAllowedValue = <T extends string>(value: T, allowed: AllowedValues<T>): boolean =>\n Array.isArray(allowed) ? allowed.includes(value) : hasOwn(allowed, value);\n\nexport function resolveOption<T extends string>(config: {\n name: string;\n value: T | undefined;\n allowed: AllowedValues<T>;\n fallback: T;\n}): T {\n const { name, value, allowed, fallback } = config;\n\n if (value === undefined) return fallback;\n if (isAllowedValue(value, allowed)) return value;\n\n if (process.env.NODE_ENV !== \"production\") {\n throw new Error(`[spectre-ui] Unknown ${name}: ${value}`);\n }\n\n return fallback;\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst buttonVariants = [\"primary\", \"secondary\", \"ghost\", \"danger\", \"success\"] as const;\nconst buttonSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type ButtonVariant = (typeof buttonVariants)[number];\nexport type ButtonSize = (typeof buttonSizes)[number];\n\nconst BUTTON_VARIANTS = {\n primary: true,\n secondary: true,\n ghost: true,\n danger: true,\n success: true,\n} as const;\n\nconst BUTTON_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface ButtonRecipeOptions {\n variant?: ButtonVariant;\n size?: ButtonSize;\n fullWidth?: boolean;\n loading?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n}\n\nexport function getButtonClasses(opts: ButtonRecipeOptions = {}): string {\n const {\n variant: variantInput,\n size: sizeInput,\n fullWidth = false,\n loading = false,\n disabled = false,\n iconOnly = false,\n } = opts;\n\n const variant = resolveOption({\n name: \"button variant\",\n value: variantInput,\n allowed: BUTTON_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"button size\",\n value: sizeInput,\n allowed: BUTTON_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<ButtonVariant, string> = {\n primary: \"sp-btn--primary\",\n secondary: \"sp-btn--secondary\",\n ghost: \"sp-btn--ghost\",\n danger: \"sp-btn--danger\",\n success: \"sp-btn--success\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<ButtonSize, string> = {\n sm: \"sp-btn--sm\",\n md: \"sp-btn--md\",\n lg: \"sp-btn--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\n \"sp-btn\",\n variantClass,\n sizeClass,\n fullWidth && \"sp-btn--full\",\n loading && \"sp-btn--loading\",\n disabled && \"sp-btn--disabled\",\n iconOnly && \"sp-btn--icon\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst cardVariants = [\"elevated\", \"flat\", \"outline\", \"ghost\"] as const;\n\nexport type CardVariant = (typeof cardVariants)[number];\n\nconst CARD_VARIANTS = {\n elevated: true,\n flat: true,\n outline: true,\n ghost: true,\n} as const;\n\nexport interface CardRecipeOptions {\n variant?: CardVariant;\n interactive?: boolean; // hover/focus styles\n padded?: boolean; // apply default padding\n fullHeight?: boolean;\n}\n\nexport function getCardClasses(opts: CardRecipeOptions = {}): string {\n const {\n variant: variantInput,\n interactive = false,\n padded = false,\n fullHeight = false,\n } = opts;\n\n const variant = resolveOption({\n name: \"card variant\",\n value: variantInput,\n allowed: CARD_VARIANTS,\n fallback: \"elevated\",\n });\n\n const variantMap: Record<CardVariant, string> = {\n elevated: \"sp-card--elevated\",\n flat: \"sp-card--flat\",\n outline: \"sp-card--outline\",\n ghost: \"sp-card--ghost\",\n };\n const variantClass = variantMap[variant];\n\n return cx(\n \"sp-card\",\n variantClass,\n interactive && \"sp-card--interactive\",\n padded && \"sp-card--padded\",\n fullHeight && \"sp-card--full\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst inputStates = [\"default\", \"error\", \"success\", \"disabled\"] as const;\nconst inputSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type InputState = (typeof inputStates)[number];\nexport type InputSize = (typeof inputSizes)[number];\n\nconst INPUT_STATES = {\n default: true,\n error: true,\n success: true,\n disabled: true,\n} as const;\n\nconst INPUT_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface InputRecipeOptions {\n state?: InputState;\n size?: InputSize;\n fullWidth?: boolean;\n}\n\nexport function getInputClasses(opts: InputRecipeOptions = {}): string {\n const { state: stateInput, size: sizeInput, fullWidth = false } = opts;\n\n const state = resolveOption({\n name: \"input state\",\n value: stateInput,\n allowed: INPUT_STATES,\n fallback: \"default\",\n });\n const size = resolveOption({\n name: \"input size\",\n value: sizeInput,\n allowed: INPUT_SIZES,\n fallback: \"md\",\n });\n\n const sizeMap: Record<InputSize, string> = {\n sm: \"sp-input--sm\",\n md: \"sp-input--md\",\n lg: \"sp-input--lg\",\n };\n const sizeClass = sizeMap[size];\n\n // State\n return cx(\n \"sp-input\",\n sizeClass,\n state === \"error\" && \"sp-input--error\",\n state === \"success\" && \"sp-input--success\",\n // Visual state only; actual disabled attribute is handled by adapters.\n state === \"disabled\" && \"sp-input--disabled\",\n fullWidth && \"sp-input--full\",\n );\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst badgeVariants = [\"primary\", \"success\", \"warning\", \"danger\"] as const;\nconst badgeSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type BadgeVariant = (typeof badgeVariants)[number];\nexport type BadgeSize = (typeof badgeSizes)[number];\n\nconst BADGE_VARIANTS = {\n primary: true,\n success: true,\n warning: true,\n danger: true,\n} as const;\n\nconst BADGE_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface BadgeRecipeOptions {\n variant?: BadgeVariant;\n size?: BadgeSize;\n}\n\nexport function getBadgeClasses(opts: BadgeRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput } = opts;\n\n const variant = resolveOption({\n name: \"badge variant\",\n value: variantInput,\n allowed: BADGE_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"badge size\",\n value: sizeInput,\n allowed: BADGE_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<BadgeVariant, string> = {\n primary: \"sp-badge--primary\",\n success: \"sp-badge--success\",\n warning: \"sp-badge--warning\",\n danger: \"sp-badge--danger\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<BadgeSize, string> = {\n sm: \"sp-badge--sm\",\n md: \"sp-badge--md\",\n lg: \"sp-badge--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\"sp-badge\", variantClass, sizeClass);\n}\n","import { cx } from \"../internal/cx\";\nimport { resolveOption } from \"../internal/resolve-option\";\n\nconst iconBoxVariants = [\"primary\", \"success\", \"warning\", \"danger\", \"info\"] as const;\nconst iconBoxSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nexport type IconBoxVariant = (typeof iconBoxVariants)[number];\nexport type IconBoxSize = (typeof iconBoxSizes)[number];\n\nconst ICONBOX_VARIANTS = {\n primary: true,\n success: true,\n warning: true,\n danger: true,\n info: true,\n} as const;\n\nconst ICONBOX_SIZES = {\n sm: true,\n md: true,\n lg: true,\n} as const;\n\nexport interface IconBoxRecipeOptions {\n variant?: IconBoxVariant;\n size?: IconBoxSize;\n}\n\nexport function getIconBoxClasses(opts: IconBoxRecipeOptions = {}): string {\n const { variant: variantInput, size: sizeInput } = opts;\n\n const variant = resolveOption({\n name: \"icon box variant\",\n value: variantInput,\n allowed: ICONBOX_VARIANTS,\n fallback: \"primary\",\n });\n const size = resolveOption({\n name: \"icon box size\",\n value: sizeInput,\n allowed: ICONBOX_SIZES,\n fallback: \"md\",\n });\n\n const variantMap: Record<IconBoxVariant, string> = {\n primary: \"sp-iconbox--primary\",\n success: \"sp-iconbox--success\",\n warning: \"sp-iconbox--warning\",\n danger: \"sp-iconbox--danger\",\n info: \"sp-iconbox--info\",\n };\n const variantClass = variantMap[variant];\n\n const sizeMap: Record<IconBoxSize, string> = {\n sm: \"sp-iconbox--sm\",\n md: \"sp-iconbox--md\",\n lg: \"sp-iconbox--lg\",\n };\n const sizeClass = sizeMap[size];\n\n return cx(\"sp-iconbox\", variantClass, sizeClass);\n}\n"]}
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"]}
@@ -7,7 +7,14 @@ function createSpectreTailwindTheme(options) {
7
7
  ...options.overrides ?? {}
8
8
  };
9
9
  const t = mergedTokens;
10
- const colors = t.colors ?? t.color ?? t.palette ?? {};
10
+ const colors = {
11
+ ...t.colors ?? t.color ?? t.palette ?? {},
12
+ surface: t.surface ?? {},
13
+ text: t.text ?? {},
14
+ buttons: t.buttons ?? {},
15
+ forms: t.forms ?? {},
16
+ component: t.component ?? {}
17
+ };
11
18
  const spacing = t.spacing ?? t.space ?? {};
12
19
  const borderRadius = t.radii ?? t.radius ?? {};
13
20
  const boxShadow = t.shadows ?? t.shadow ?? {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":";;;AAkBO,SAAS,2BACd,OAAA,EACsB;AACtB,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,GAAI,OAAA,CAAQ,MAAA,IAAW,EAAC;AAAA,IACxB,GAAI,OAAA,CAAQ,SAAA,IAAa;AAAC,GAC5B;AAIA,EAAA,MAAM,CAAA,GAAS,YAAA;AAEf,EAAA,MAAM,SAAU,CAAA,CAAE,MAAA,IAAU,EAAE,KAAA,IAAS,CAAA,CAAE,WAAW,EAAC;AACrD,EAAA,MAAM,OAAA,GAAW,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,SAAS,EAAC;AAC1C,EAAA,MAAM,YAAA,GAAgB,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,UAAU,EAAC;AAC9C,EAAA,MAAM,SAAA,GAAa,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,UAAU,EAAC;AAC7C,EAAA,MAAM,aAAc,CAAA,CAAE,UAAA,EAAY,QAAA,IAAY,CAAA,CAAE,SAAS,EAAC;AAC1D,EAAA,MAAM,WAAY,CAAA,CAAE,UAAA,EAAY,KAAA,IAAS,CAAA,CAAE,YAAY,EAAC;AAExD,EAAA,MAAM,KAAA,GAAuB;AAAA,IAC3B,MAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;;;ACnCA,IAAM,aAAA,GAAgB,CAAC,KAAA,KACrB,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAGrE,IAAM,SAAA,GAAY,CAChB,IAAA,EACA,SAAA,KACM;AACN,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AAEvB,EAAA,MAAM,MAAA,GAAkC,EAAE,GAAG,IAAA,EAAK;AAElD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,aAAa,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC5D,IAAA,MAAM,SAAA,GAAY,OAAO,GAAG,CAAA;AAC5B,IAAA,IAAI,aAAA,CAAc,SAAS,CAAA,IAAK,aAAA,CAAc,aAAa,CAAA,EAAG;AAC5D,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,SAAA,CAAU,SAAA,EAAW,aAAa,CAAA;AAAA,IAClD,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,aAAA;AAAA,IAChB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT,CAAA;AAEO,IAAM,2BAAA,GAA8B,CACzC,OAAA,KACmB;AACnB,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,MAAM,EAAE,QAAO,GAAI,OAAA;AACnB,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,0BAAA,CAA2B,EAAE,QAAQ,CAAA;AACvD,EAAA,MAAM,WAAA,GAAc,SAAA;AAAA,IAClB,KAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV;AAEA,EAAA,MAAM,UAAA,GAA6B;AAAA,IACjC,SAAS,EAAC;AAAA,IACV,KAAA,EAAO;AAAA;AAAA,GACT;AAEA,EAAA,OAAO,SAAA;AAAA,IACL,UAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV;AACF","file":"index.cjs","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = (t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>;\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends Record<string, unknown>>(\n base: T,\n overrides?: Record<string, unknown>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(\n theme as Record<string, unknown>,\n options.themeOverrides as Record<string, unknown> | undefined\n );\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme, // theme is guaranteed non-undefined now\n };\n\n return deepMerge(\n basePreset as Record<string, unknown>,\n options.presetOverrides as Record<string, unknown> | undefined\n ) as TailwindConfig;\n};\n"]}
1
+ {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = {\n ...((t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>),\n surface: t.surface ?? {},\n text: t.text ?? {},\n buttons: t.buttons ?? {},\n forms: t.forms ?? {},\n component: t.component ?? {},\n };\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends Record<string, unknown>>(\n base: T,\n overrides?: Record<string, unknown>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(\n theme as Record<string, unknown>,\n options.themeOverrides as Record<string, unknown> | undefined\n );\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme, // theme is guaranteed non-undefined now\n };\n\n return deepMerge(\n basePreset as Record<string, unknown>,\n options.presetOverrides as Record<string, unknown> | undefined\n ) as TailwindConfig;\n};\n"]}
@@ -5,7 +5,14 @@ function createSpectreTailwindTheme(options) {
5
5
  ...options.overrides ?? {}
6
6
  };
7
7
  const t = mergedTokens;
8
- const colors = t.colors ?? t.color ?? t.palette ?? {};
8
+ const colors = {
9
+ ...t.colors ?? t.color ?? t.palette ?? {},
10
+ surface: t.surface ?? {},
11
+ text: t.text ?? {},
12
+ buttons: t.buttons ?? {},
13
+ forms: t.forms ?? {},
14
+ component: t.component ?? {}
15
+ };
9
16
  const spacing = t.spacing ?? t.space ?? {};
10
17
  const borderRadius = t.radii ?? t.radius ?? {};
11
18
  const boxShadow = t.shadows ?? t.shadow ?? {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":";AAkBO,SAAS,2BACd,OAAA,EACsB;AACtB,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,GAAI,OAAA,CAAQ,MAAA,IAAW,EAAC;AAAA,IACxB,GAAI,OAAA,CAAQ,SAAA,IAAa;AAAC,GAC5B;AAIA,EAAA,MAAM,CAAA,GAAS,YAAA;AAEf,EAAA,MAAM,SAAU,CAAA,CAAE,MAAA,IAAU,EAAE,KAAA,IAAS,CAAA,CAAE,WAAW,EAAC;AACrD,EAAA,MAAM,OAAA,GAAW,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,SAAS,EAAC;AAC1C,EAAA,MAAM,YAAA,GAAgB,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,UAAU,EAAC;AAC9C,EAAA,MAAM,SAAA,GAAa,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,UAAU,EAAC;AAC7C,EAAA,MAAM,aAAc,CAAA,CAAE,UAAA,EAAY,QAAA,IAAY,CAAA,CAAE,SAAS,EAAC;AAC1D,EAAA,MAAM,WAAY,CAAA,CAAE,UAAA,EAAY,KAAA,IAAS,CAAA,CAAE,YAAY,EAAC;AAExD,EAAA,MAAM,KAAA,GAAuB;AAAA,IAC3B,MAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,EAAE,KAAA,EAAM;AACjB;;;ACnCA,IAAM,aAAA,GAAgB,CAAC,KAAA,KACrB,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA;AAGrE,IAAM,SAAA,GAAY,CAChB,IAAA,EACA,SAAA,KACM;AACN,EAAA,IAAI,CAAC,WAAW,OAAO,IAAA;AAEvB,EAAA,MAAM,MAAA,GAAkC,EAAE,GAAG,IAAA,EAAK;AAElD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,aAAa,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC5D,IAAA,MAAM,SAAA,GAAY,OAAO,GAAG,CAAA;AAC5B,IAAA,IAAI,aAAA,CAAc,SAAS,CAAA,IAAK,aAAA,CAAc,aAAa,CAAA,EAAG;AAC5D,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,SAAA,CAAU,SAAA,EAAW,aAAa,CAAA;AAAA,IAClD,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,aAAA;AAAA,IAChB;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT,CAAA;AAEO,IAAM,2BAAA,GAA8B,CACzC,OAAA,KACmB;AACnB,EAAA,IAAI,CAAC,QAAQ,MAAA,EAAQ;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,MAAM,EAAE,QAAO,GAAI,OAAA;AACnB,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,0BAAA,CAA2B,EAAE,QAAQ,CAAA;AACvD,EAAA,MAAM,WAAA,GAAc,SAAA;AAAA,IAClB,KAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV;AAEA,EAAA,MAAM,UAAA,GAA6B;AAAA,IACjC,SAAS,EAAC;AAAA,IACV,KAAA,EAAO;AAAA;AAAA,GACT;AAEA,EAAA,OAAO,SAAA;AAAA,IACL,UAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV;AACF","file":"index.js","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = (t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>;\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends Record<string, unknown>>(\n base: T,\n overrides?: Record<string, unknown>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(\n theme as Record<string, unknown>,\n options.themeOverrides as Record<string, unknown> | undefined\n );\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme, // theme is guaranteed non-undefined now\n };\n\n return deepMerge(\n basePreset as Record<string, unknown>,\n options.presetOverrides as Record<string, unknown> | undefined\n ) as TailwindConfig;\n};\n"]}
1
+ {"version":3,"sources":["../../src/tailwind/theme.ts","../../src/tailwind/preset.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface SpectreTailwindTheme {\n theme: TailwindTheme;\n}\n\nexport interface CreateSpectreTailwindThemeOptions {\n tokens: SpectreTokens;\n overrides?: Partial<SpectreTokens>;\n}\n\n/**\n * Minimal, type-safe theme mapper.\n * Important: theme is NEVER undefined (fixes exactOptionalPropertyTypes + DTS).\n */\nexport function createSpectreTailwindTheme(\n options: CreateSpectreTailwindThemeOptions\n): SpectreTailwindTheme {\n const mergedTokens = {\n ...(options.tokens ?? ({} as SpectreTokens)),\n ...(options.overrides ?? {}),\n } as SpectreTokens;\n\n // We keep mapping shallow + permissive because token shapes will evolve.\n // Tailwind accepts nested objects of strings for colors.\n const t: any = mergedTokens;\n\n const colors = {\n ...((t.colors ?? t.color ?? t.palette ?? {}) as Record<string, any>),\n surface: t.surface ?? {},\n text: t.text ?? {},\n buttons: t.buttons ?? {},\n forms: t.forms ?? {},\n component: t.component ?? {},\n };\n const spacing = (t.spacing ?? t.space ?? {}) as Record<string, any>;\n const borderRadius = (t.radii ?? t.radius ?? {}) as Record<string, any>;\n const boxShadow = (t.shadows ?? t.shadow ?? {}) as Record<string, any>;\n const fontFamily = (t.typography?.families ?? t.fonts ?? {}) as Record<string, any>;\n const fontSize = (t.typography?.scale ?? t.fontSize ?? {}) as Record<string, any>;\n\n const theme: TailwindTheme = {\n colors: colors as any,\n spacing: spacing as any,\n borderRadius: borderRadius as any,\n boxShadow: boxShadow as any,\n fontFamily: fontFamily as any,\n fontSize: fontSize as any,\n };\n\n return { theme };\n}\n","import type { Config as TailwindConfig } from \"tailwindcss\";\nimport type { SpectreTokens } from \"../tokens\";\nimport { createSpectreTailwindTheme } from \"./theme\";\n\ntype TailwindTheme = NonNullable<TailwindConfig[\"theme\"]>;\n\nexport interface CreateSpectreTailwindPresetOptions {\n tokens: SpectreTokens;\n themeOverrides?: TailwindTheme;\n presetOverrides?: TailwindConfig;\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n// Deep-merge plain objects only; arrays and primitives replace by override.\nconst deepMerge = <T extends Record<string, unknown>>(\n base: T,\n overrides?: Record<string, unknown>\n): T => {\n if (!overrides) return base;\n\n const result: Record<string, unknown> = { ...base };\n\n for (const [key, overrideValue] of Object.entries(overrides)) {\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue);\n } else {\n result[key] = overrideValue;\n }\n }\n\n return result as T;\n};\n\nexport const createSpectreTailwindPreset = (\n options: CreateSpectreTailwindPresetOptions\n): TailwindConfig => {\n if (!options.tokens) {\n throw new Error(\n \"[spectre-ui] createSpectreTailwindPreset requires tokens; pass { tokens } explicitly.\"\n );\n }\n const { tokens } = options;\n const { theme } = createSpectreTailwindTheme({ tokens });\n const mergedTheme = deepMerge(\n theme as Record<string, unknown>,\n options.themeOverrides as Record<string, unknown> | undefined\n );\n\n const basePreset: TailwindConfig = {\n content: [],\n theme: mergedTheme, // theme is guaranteed non-undefined now\n };\n\n return deepMerge(\n basePreset as Record<string, unknown>,\n options.presetOverrides as Record<string, unknown> | undefined\n ) as TailwindConfig;\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: 72rem;
21
+ max-width: calc(var(--sp-space-96) * 12);
22
22
  }
23
23
 
24
24
  .sp-section {
@@ -67,50 +67,42 @@
67
67
  }
68
68
 
69
69
  .sp-animate-fade-in {
70
- animation: var(--sp-animation-fadein-keyframes)
71
- var(--sp-animation-fadein-duration) var(--sp-animation-fadein-easing);
70
+ animation: var(--sp-animation-fadein-keyframes) var(--sp-animation-fadein-duration) var(--sp-animation-fadein-easing);
72
71
  }
73
72
 
74
73
  .sp-animate-fade-out {
75
- animation: var(--sp-animation-fadeout-keyframes)
76
- var(--sp-animation-fadeout-duration) var(--sp-animation-fadeout-easing);
74
+ animation: var(--sp-animation-fadeout-keyframes) var(--sp-animation-fadeout-duration) var(--sp-animation-fadeout-easing);
77
75
  }
78
76
 
79
77
  .sp-animate-slide-up {
80
- animation: var(--sp-animation-slideup-keyframes)
81
- var(--sp-animation-slideup-duration) var(--sp-animation-slideup-easing);
78
+ animation: var(--sp-animation-slideup-keyframes) var(--sp-animation-slideup-duration) var(--sp-animation-slideup-easing);
82
79
  }
83
80
 
84
81
  .sp-animate-slide-down {
85
- animation: var(--sp-animation-slidedown-keyframes)
86
- var(--sp-animation-slidedown-duration)
87
- var(--sp-animation-slidedown-easing);
82
+ animation: var(--sp-animation-slidedown-keyframes) var(--sp-animation-slidedown-duration) var(--sp-animation-slidedown-easing);
88
83
  }
89
84
 
90
85
  .sp-animate-scale-in {
91
- animation: var(--sp-animation-scalein-keyframes)
92
- var(--sp-animation-scalein-duration) var(--sp-animation-scalein-easing);
86
+ animation: var(--sp-animation-scalein-keyframes) var(--sp-animation-scalein-duration) var(--sp-animation-scalein-easing);
93
87
  }
94
88
 
95
89
  .sp-animate-bounce {
96
- animation: var(--sp-animation-bounce-keyframes)
97
- var(--sp-animation-bounce-duration) var(--sp-animation-bounce-easing);
90
+ animation: var(--sp-animation-bounce-keyframes) var(--sp-animation-bounce-duration) var(--sp-animation-bounce-easing);
98
91
  }
99
92
 
100
93
  .sp-animate-shake {
101
- animation: var(--sp-animation-shake-keyframes)
102
- var(--sp-animation-shake-duration) var(--sp-animation-shake-easing);
94
+ animation: var(--sp-animation-shake-keyframes) var(--sp-animation-shake-duration) var(--sp-animation-shake-easing);
103
95
  }
104
96
 
105
97
  .sp-animate-pulse {
106
- animation: var(--sp-animation-pulse-keyframes)
107
- var(--sp-animation-pulse-duration) var(--sp-animation-pulse-easing);
98
+ animation: var(--sp-animation-pulse-keyframes) var(--sp-animation-pulse-duration) var(--sp-animation-pulse-easing);
108
99
  }
109
100
 
110
101
  @keyframes fade-in {
111
102
  from {
112
103
  opacity: 0;
113
104
  }
105
+
114
106
  to {
115
107
  opacity: 1;
116
108
  }
@@ -120,6 +112,7 @@
120
112
  from {
121
113
  opacity: 1;
122
114
  }
115
+
123
116
  to {
124
117
  opacity: 0;
125
118
  }
@@ -128,8 +121,9 @@
128
121
  @keyframes slide-up {
129
122
  from {
130
123
  opacity: 0;
131
- transform: translateY(0.5rem);
124
+ transform: translateY(var(--sp-space-8));
132
125
  }
126
+
133
127
  to {
134
128
  opacity: 1;
135
129
  transform: translateY(0);
@@ -139,8 +133,9 @@
139
133
  @keyframes slide-down {
140
134
  from {
141
135
  opacity: 0;
142
- transform: translateY(-0.5rem);
136
+ transform: translateY(calc(var(--sp-space-8) * -1));
143
137
  }
138
+
144
139
  to {
145
140
  opacity: 1;
146
141
  transform: translateY(0);
@@ -152,6 +147,7 @@
152
147
  opacity: 0;
153
148
  transform: scale(0.95);
154
149
  }
150
+
155
151
  to {
156
152
  opacity: 1;
157
153
  transform: scale(1);
@@ -159,35 +155,42 @@
159
155
  }
160
156
 
161
157
  @keyframes bounce {
158
+
162
159
  0%,
163
160
  100% {
164
161
  transform: translateY(0);
165
162
  }
163
+
166
164
  50% {
167
- transform: translateY(-0.375rem);
165
+ transform: translateY(calc(var(--sp-space-4) * -1.5));
168
166
  }
169
167
  }
170
168
 
171
169
  @keyframes shake {
170
+
172
171
  0%,
173
172
  100% {
174
173
  transform: translateX(0);
175
174
  }
175
+
176
176
  20%,
177
177
  60% {
178
- transform: translateX(-0.375rem);
178
+ transform: translateX(calc(var(--sp-space-4) * -1.5));
179
179
  }
180
+
180
181
  40%,
181
182
  80% {
182
- transform: translateX(0.375rem);
183
+ transform: translateX(calc(var(--sp-space-4) * 1.5));
183
184
  }
184
185
  }
185
186
 
186
187
  @keyframes pulse {
188
+
187
189
  0%,
188
190
  100% {
189
191
  transform: scale(1);
190
192
  }
193
+
191
194
  50% {
192
195
  transform: scale(1.04);
193
196
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phcdevworks/spectre-ui",
3
- "version": "0.4.1",
3
+ "version": "1.0.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",
@@ -77,9 +77,10 @@
77
77
  "tailwindcss": "^3.4.0 || ^4.0.0"
78
78
  },
79
79
  "dependencies": {
80
- "@phcdevworks/spectre-tokens": "^0.2.1"
80
+ "@phcdevworks/spectre-tokens": "^2.0.0"
81
81
  },
82
82
  "devDependencies": {
83
+ "@types/node": "^25.5.0",
83
84
  "autoprefixer": "^10.4.20",
84
85
  "postcss": "^8.4.35",
85
86
  "postcss-cli": "^11.0.1",