@phcdevworks/spectre-ui 2.4.0 → 2.6.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/CHANGELOG.md CHANGED
@@ -6,6 +6,56 @@ reflects package releases published to npm.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.6.0] - 2026-06-28
10
+
11
+ Release Title: Semantic Primitives and Form-Field Recipes
12
+
13
+ Contract change type: additive
14
+
15
+ ### Added
16
+
17
+ - **Link utility**: Added a token-backed `.sp-link` class
18
+ (`--sp-link-default` `--sp-link-hover` `--sp-link-active`
19
+ `--sp-link-visited`) for inline text links. Plain CSS, no recipe wrapper —
20
+ there is no variant or size axis to validate.
21
+ - **Interactive surface state utilities**: Added `.sp-surface--hover`,
22
+ `.sp-surface--selected`, and `.sp-surface--active` modifier classes backed
23
+ by `--sp-surface-hover`, `--sp-surface-selected`, and `--sp-surface-active`
24
+ for clickable list items, menu items, table rows, and selectable surfaces.
25
+ - **Divider utility**: Added a token-backed `.sp-divider` class
26
+ (`--sp-surface-divider`) for `<hr>`, section separators, and table borders.
27
+ - **Form-field recipes**: Added `getCheckboxClasses` (`.sp-checkbox-indicator`,
28
+ `--sp-checkbox-*`), `getRadioClasses` (`.sp-radio-indicator`,
29
+ `--sp-radio-*`), `getSelectClasses` (`.sp-select`, `--sp-select-*`),
30
+ `getTextareaClasses` (`.sp-textarea`, `--sp-textarea-*`),
31
+ `getFieldsetClasses`/`getFieldsetLegendClasses` (`.sp-fieldset`,
32
+ `.sp-fieldset__legend`, `--sp-fieldset-*`), and `getLabelClasses`
33
+ (`.sp-form-label`, `--sp-label-*`). These back the previously
34
+ recipe-less `sp-checkbox`, `sp-radio`, `sp-select`, `sp-textarea`,
35
+ `sp-fieldset`, and `sp-label` Lit components in `spectre-components`. New
36
+ class names are distinct from the pre-existing `.sp-label` (input-scoped,
37
+ via `getInputLabelClasses`) to avoid colliding with that existing contract.
38
+
39
+ ## [2.5.0] - 2026-06-25
40
+
41
+ Release Title: Sidebar Navigation Hardening
42
+
43
+ Contract change type: additive
44
+
45
+ ### Added
46
+
47
+ - **Sidebar docked full height**: `.sp-sidebar` now stretches to
48
+ `height: 100%` once docked inline above `breakpoints.md`, so a short link
49
+ list matches the height of a taller sibling content column instead of
50
+ leaving a gap below it.
51
+ - **Sidebar link `level` option**: Added a `level` option (`parent` `child`)
52
+ to `getSidebarLinkClasses`, mapping to a new `.sp-sidebar__link--child`
53
+ modifier that indents nested links. Defaults to `parent` to preserve
54
+ existing call sites.
55
+ - **Sidebar header recipe**: Added `getSidebarHeaderClasses`, wrapping a new
56
+ `.sp-sidebar__header` class styled as a muted eyebrow/section label,
57
+ visually distinct from `.sp-sidebar__link`.
58
+
9
59
  ## [2.4.0] - 2026-06-23
10
60
 
11
61
  Release Title: App Shell Hardening
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  | Project team | `project-design` |
8
8
  | Repository role | Spectre L2 CSS, Tailwind, and recipe contract |
9
9
  | Package/artifact | `@phcdevworks/spectre-ui` |
10
- | Current version/status | 2.4.0 |
10
+ | Current version/status | 2.6.0 |
11
11
 
12
12
  ## Standard Workflow
13
13
 
@@ -280,10 +280,31 @@ All options are optional and fall back to sensible defaults.
280
280
  | Grid | `getGridClasses` | columns: `1` `2` `3` `4` `6` `12` | gap: `sm` `md` `lg` | — |
281
281
  | Sidebar | `getSidebarClasses` | — | — | `bordered` |
282
282
  | Footer | `getFooterClasses` | — | — | `bordered` `fullWidth` |
283
+ | Checkbox | `getCheckboxClasses` | — | — | `checked` `disabled` |
284
+ | Radio | `getRadioClasses` | — | — | `checked` `disabled` |
285
+ | Select | `getSelectClasses` | — | — | `disabled` `focused` |
286
+ | Textarea | `getTextareaClasses` | — | — | `disabled` `focused` |
287
+ | Fieldset | `getFieldsetClasses` | — | — | `disabled` |
288
+ | Label | `getLabelClasses` | — | — | `disabled` `required` |
283
289
 
284
290
  Each recipe family also exports sub-element helpers for its structural parts
285
291
  (labels, wrappers, sub-containers, text elements). See the full list below.
286
292
 
293
+ ### Semantic utility classes (no recipe wrapper)
294
+
295
+ These primitives are intentionally plain CSS classes in
296
+ `src/styles/utilities.css` with no recipe function — there is no variant or
297
+ size axis to validate, so a recipe wrapper would add indirection without a
298
+ type-safety benefit. Apply the class name directly.
299
+
300
+ | Class | Tokens | Usage |
301
+ | ----------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------- |
302
+ | `.sp-link` | `--sp-link-default` `--sp-link-hover` `--sp-link-active` `--sp-link-visited` | Inline text links (`<a>`). |
303
+ | `.sp-surface--hover` | `--sp-surface-hover` | Clickable list items, menu items, table rows on hover. |
304
+ | `.sp-surface--selected` | `--sp-surface-selected` | Selected list items, menu items, table rows. |
305
+ | `.sp-surface--active` | `--sp-surface-active` | Pressed/active state for clickable surfaces. |
306
+ | `.sp-divider` | `--sp-surface-divider` | `<hr>`, section separators, table borders. |
307
+
287
308
  ### Root package
288
309
 
289
310
  The root package exports CSS path constants plus the recipe functions
@@ -304,22 +325,28 @@ Root recipe functions:
304
325
  - `getBadgeClasses`
305
326
  - `getButtonClasses`
306
327
  - `getCardClasses`
328
+ - `getCheckboxClasses`
307
329
  - `getContainerClasses`
308
330
  - `getDropdownClasses`
331
+ - `getFieldsetClasses`
309
332
  - `getFooterClasses`
310
333
  - `getGridClasses`
311
334
  - `getIconBoxClasses`
312
335
  - `getInputClasses`
336
+ - `getLabelClasses`
313
337
  - `getModalClasses`
314
338
  - `getNavClasses`
315
339
  - `getPricingCardClasses`
340
+ - `getRadioClasses`
316
341
  - `getRatingClasses`
317
342
  - `getSectionClasses`
343
+ - `getSelectClasses`
318
344
  - `getSidebarClasses`
319
345
  - `getSpinnerClasses`
320
346
  - `getStackClasses`
321
347
  - `getTagClasses`
322
348
  - `getTestimonialClasses`
349
+ - `getTextareaClasses`
323
350
  - `getToastClasses`
324
351
  - `getTooltipClasses`
325
352
 
@@ -327,6 +354,7 @@ Root recipe helper functions:
327
354
 
328
355
  - `getDropdownItemClasses`
329
356
  - `getDropdownMenuClasses`
357
+ - `getFieldsetLegendClasses`
330
358
  - `getInputErrorMessageClasses`
331
359
  - `getInputHelperTextClasses`
332
360
  - `getInputLabelClasses`
@@ -342,6 +370,7 @@ Root recipe helper functions:
342
370
  - `getRatingStarsClasses`
343
371
  - `getRatingTextClasses`
344
372
  - `getSidebarBackdropClasses`
373
+ - `getSidebarHeaderClasses`
345
374
  - `getSidebarLinkClasses`
346
375
  - `getSidebarToggleClasses`
347
376
  - `getTestimonialAuthorClasses`
@@ -413,6 +442,16 @@ clicks meant for the toggle once the sidebar is open.
413
442
  Adapters own the hamburger/toggle control, click handling, and SSR-safe
414
443
  initial closed state.
415
444
 
445
+ Above `breakpoints.md`, `.sp-sidebar` stretches to `height: 100%` so a short
446
+ link list matches the height of a taller sibling content column when docked
447
+ inline in a `Stack` row (see `align: 'stretch'` on `getStackClasses`).
448
+
449
+ `getSidebarLinkClasses` accepts a `level` option (`'parent' | 'child'`,
450
+ default `'parent'`) for nested link indentation — e.g. a package name with
451
+ "Overview" / "Reference" links beneath it. `getSidebarHeaderClasses` styles a
452
+ section label (e.g. "Tokens", "UI", "Guides") as a muted eyebrow, visually
453
+ distinct from `.sp-sidebar__link`.
454
+
416
455
  ## Downstream boundaries
417
456
 
418
457
  Downstream packages should never redefine locally:
package/dist/base.css CHANGED
@@ -76,6 +76,39 @@
76
76
  --sp-dropdown-item-hover: #eef1f6;
77
77
  --sp-dropdown-item-active: #f0f9ff;
78
78
  --sp-dropdown-item-text: #141b24;
79
+ --sp-checkbox-bg: #ffffff;
80
+ --sp-checkbox-border: #b7c1d4;
81
+ --sp-checkbox-checked-bg: #0369a1;
82
+ --sp-checkbox-checked-border: #0369a1;
83
+ --sp-checkbox-text: #ffffff;
84
+ --sp-checkbox-disabled-bg: #f7f8fb;
85
+ --sp-checkbox-disabled-border: #d9dfeb;
86
+ --sp-radio-bg: #ffffff;
87
+ --sp-radio-border: #b7c1d4;
88
+ --sp-radio-checked-bg: #0369a1;
89
+ --sp-radio-checked-border: #0369a1;
90
+ --sp-radio-text: #ffffff;
91
+ --sp-radio-disabled-bg: #f7f8fb;
92
+ --sp-radio-disabled-border: #d9dfeb;
93
+ --sp-select-bg: #ffffff;
94
+ --sp-select-border: #b7c1d4;
95
+ --sp-select-text: #141b24;
96
+ --sp-select-placeholder-text: #657287;
97
+ --sp-select-disabled-bg: #f7f8fb;
98
+ --sp-select-disabled-border: #d9dfeb;
99
+ --sp-select-focus-border: #0ea5e9;
100
+ --sp-textarea-bg: #ffffff;
101
+ --sp-textarea-border: #b7c1d4;
102
+ --sp-textarea-text: #141b24;
103
+ --sp-textarea-placeholder: #657287;
104
+ --sp-textarea-disabled-bg: #f7f8fb;
105
+ --sp-textarea-disabled-border: #d9dfeb;
106
+ --sp-textarea-focus-border: #0ea5e9;
107
+ --sp-fieldset-border: #d9dfeb;
108
+ --sp-fieldset-legend-text: #141b24;
109
+ --sp-label-text: #141b24;
110
+ --sp-label-disabled-text: #8a96ad;
111
+ --sp-label-required-indicator-text: #dc2626;
79
112
  --sp-link-default: #1f57db;
80
113
  --sp-link-hover: #1946b4;
81
114
  --sp-link-active: #173b8f;
@@ -505,6 +538,39 @@
505
538
  --sp-dropdown-item-hover: #374253;
506
539
  --sp-dropdown-item-active: #082f49;
507
540
  --sp-dropdown-item-text: #eef1f6;
541
+ --sp-checkbox-bg: #222b38;
542
+ --sp-checkbox-border: #4b576a;
543
+ --sp-checkbox-checked-bg: #0369a1;
544
+ --sp-checkbox-checked-border: #0369a1;
545
+ --sp-checkbox-text: #ffffff;
546
+ --sp-checkbox-disabled-bg: #141b24;
547
+ --sp-checkbox-disabled-border: #374253;
548
+ --sp-radio-bg: #222b38;
549
+ --sp-radio-border: #4b576a;
550
+ --sp-radio-checked-bg: #0369a1;
551
+ --sp-radio-checked-border: #0369a1;
552
+ --sp-radio-text: #ffffff;
553
+ --sp-radio-disabled-bg: #141b24;
554
+ --sp-radio-disabled-border: #374253;
555
+ --sp-select-bg: #222b38;
556
+ --sp-select-border: #4b576a;
557
+ --sp-select-text: #f7f8fb;
558
+ --sp-select-placeholder-text: #8a96ad;
559
+ --sp-select-disabled-bg: #141b24;
560
+ --sp-select-disabled-border: #374253;
561
+ --sp-select-focus-border: #38bdf8;
562
+ --sp-textarea-bg: #222b38;
563
+ --sp-textarea-border: #4b576a;
564
+ --sp-textarea-text: #f7f8fb;
565
+ --sp-textarea-placeholder: #8a96ad;
566
+ --sp-textarea-disabled-bg: #141b24;
567
+ --sp-textarea-disabled-border: #374253;
568
+ --sp-textarea-focus-border: #38bdf8;
569
+ --sp-fieldset-border: #374253;
570
+ --sp-fieldset-legend-text: #f7f8fb;
571
+ --sp-label-text: #f7f8fb;
572
+ --sp-label-disabled-text: #4b576a;
573
+ --sp-label-required-indicator-text: #f87171;
508
574
  --sp-link-default: #1f57db;
509
575
  --sp-link-hover: #1946b4;
510
576
  --sp-link-active: #173b8f;
@@ -76,6 +76,39 @@
76
76
  --sp-dropdown-item-hover: #eef1f6;
77
77
  --sp-dropdown-item-active: #f0f9ff;
78
78
  --sp-dropdown-item-text: #141b24;
79
+ --sp-checkbox-bg: #ffffff;
80
+ --sp-checkbox-border: #b7c1d4;
81
+ --sp-checkbox-checked-bg: #0369a1;
82
+ --sp-checkbox-checked-border: #0369a1;
83
+ --sp-checkbox-text: #ffffff;
84
+ --sp-checkbox-disabled-bg: #f7f8fb;
85
+ --sp-checkbox-disabled-border: #d9dfeb;
86
+ --sp-radio-bg: #ffffff;
87
+ --sp-radio-border: #b7c1d4;
88
+ --sp-radio-checked-bg: #0369a1;
89
+ --sp-radio-checked-border: #0369a1;
90
+ --sp-radio-text: #ffffff;
91
+ --sp-radio-disabled-bg: #f7f8fb;
92
+ --sp-radio-disabled-border: #d9dfeb;
93
+ --sp-select-bg: #ffffff;
94
+ --sp-select-border: #b7c1d4;
95
+ --sp-select-text: #141b24;
96
+ --sp-select-placeholder-text: #657287;
97
+ --sp-select-disabled-bg: #f7f8fb;
98
+ --sp-select-disabled-border: #d9dfeb;
99
+ --sp-select-focus-border: #0ea5e9;
100
+ --sp-textarea-bg: #ffffff;
101
+ --sp-textarea-border: #b7c1d4;
102
+ --sp-textarea-text: #141b24;
103
+ --sp-textarea-placeholder: #657287;
104
+ --sp-textarea-disabled-bg: #f7f8fb;
105
+ --sp-textarea-disabled-border: #d9dfeb;
106
+ --sp-textarea-focus-border: #0ea5e9;
107
+ --sp-fieldset-border: #d9dfeb;
108
+ --sp-fieldset-legend-text: #141b24;
109
+ --sp-label-text: #141b24;
110
+ --sp-label-disabled-text: #8a96ad;
111
+ --sp-label-required-indicator-text: #dc2626;
79
112
  --sp-link-default: #1f57db;
80
113
  --sp-link-hover: #1946b4;
81
114
  --sp-link-active: #173b8f;
@@ -505,6 +538,39 @@
505
538
  --sp-dropdown-item-hover: #374253;
506
539
  --sp-dropdown-item-active: #082f49;
507
540
  --sp-dropdown-item-text: #eef1f6;
541
+ --sp-checkbox-bg: #222b38;
542
+ --sp-checkbox-border: #4b576a;
543
+ --sp-checkbox-checked-bg: #0369a1;
544
+ --sp-checkbox-checked-border: #0369a1;
545
+ --sp-checkbox-text: #ffffff;
546
+ --sp-checkbox-disabled-bg: #141b24;
547
+ --sp-checkbox-disabled-border: #374253;
548
+ --sp-radio-bg: #222b38;
549
+ --sp-radio-border: #4b576a;
550
+ --sp-radio-checked-bg: #0369a1;
551
+ --sp-radio-checked-border: #0369a1;
552
+ --sp-radio-text: #ffffff;
553
+ --sp-radio-disabled-bg: #141b24;
554
+ --sp-radio-disabled-border: #374253;
555
+ --sp-select-bg: #222b38;
556
+ --sp-select-border: #4b576a;
557
+ --sp-select-text: #f7f8fb;
558
+ --sp-select-placeholder-text: #8a96ad;
559
+ --sp-select-disabled-bg: #141b24;
560
+ --sp-select-disabled-border: #374253;
561
+ --sp-select-focus-border: #38bdf8;
562
+ --sp-textarea-bg: #222b38;
563
+ --sp-textarea-border: #4b576a;
564
+ --sp-textarea-text: #f7f8fb;
565
+ --sp-textarea-placeholder: #8a96ad;
566
+ --sp-textarea-disabled-bg: #141b24;
567
+ --sp-textarea-disabled-border: #374253;
568
+ --sp-textarea-focus-border: #38bdf8;
569
+ --sp-fieldset-border: #374253;
570
+ --sp-fieldset-legend-text: #f7f8fb;
571
+ --sp-label-text: #f7f8fb;
572
+ --sp-label-disabled-text: #4b576a;
573
+ --sp-label-required-indicator-text: #f87171;
508
574
  --sp-link-default: #1f57db;
509
575
  --sp-link-hover: #1946b4;
510
576
  --sp-link-active: #173b8f;
@@ -2818,6 +2884,19 @@
2818
2884
  opacity: var(--sp-opacity-disabled);
2819
2885
  }
2820
2886
 
2887
+ .sp-sidebar__link--child {
2888
+ padding-left: calc(var(--sp-space-24) + var(--sp-space-16));
2889
+ }
2890
+
2891
+ .sp-sidebar__header {
2892
+ font-size: var(--sp-font-xs-size);
2893
+ line-height: var(--sp-font-xs-line-height);
2894
+ font-weight: var(--sp-font-xs-weight);
2895
+ letter-spacing: var(--sp-font-xs-letter-spacing);
2896
+ color: var(--sp-text-on-surface-muted);
2897
+ text-transform: uppercase;
2898
+ }
2899
+
2821
2900
  .sp-sidebar-backdrop {
2822
2901
  display: none;
2823
2902
  position: fixed;
@@ -2844,7 +2923,7 @@
2844
2923
  @media (min-width: 768px) {
2845
2924
  .sp-sidebar {
2846
2925
  position: static;
2847
- height: auto;
2926
+ height: 100%;
2848
2927
  transform: none;
2849
2928
  }
2850
2929
 
@@ -3138,4 +3217,143 @@
3138
3217
  .sp-modal--full {
3139
3218
  width: 100%;
3140
3219
  }
3220
+
3221
+ .sp-checkbox-indicator {
3222
+ display: inline-block;
3223
+ width: var(--sp-space-16);
3224
+ height: var(--sp-space-16);
3225
+ border-radius: var(--sp-radius-sm);
3226
+ border: var(--sp-component-border-width) solid var(--sp-checkbox-border);
3227
+ background-color: var(--sp-checkbox-bg);
3228
+ transition:
3229
+ background-color var(--sp-duration-fast) var(--sp-easing-out),
3230
+ border-color var(--sp-duration-fast) var(--sp-easing-out);
3231
+ }
3232
+
3233
+ .sp-checkbox-indicator--checked {
3234
+ background-color: var(--sp-checkbox-checked-bg);
3235
+ border-color: var(--sp-checkbox-checked-border);
3236
+ }
3237
+
3238
+ .sp-checkbox-indicator--disabled {
3239
+ background-color: var(--sp-checkbox-disabled-bg);
3240
+ border-color: var(--sp-checkbox-disabled-border);
3241
+ }
3242
+
3243
+ .sp-radio-indicator {
3244
+ display: inline-block;
3245
+ width: var(--sp-space-16);
3246
+ height: var(--sp-space-16);
3247
+ border-radius: var(--sp-radius-pill);
3248
+ border: var(--sp-component-border-width) solid var(--sp-radio-border);
3249
+ background-color: var(--sp-radio-bg);
3250
+ transition:
3251
+ background-color var(--sp-duration-fast) var(--sp-easing-out),
3252
+ border-color var(--sp-duration-fast) var(--sp-easing-out);
3253
+ }
3254
+
3255
+ .sp-radio-indicator--checked {
3256
+ background-color: var(--sp-radio-checked-bg);
3257
+ border-color: var(--sp-radio-checked-border);
3258
+ }
3259
+
3260
+ .sp-radio-indicator--disabled {
3261
+ background-color: var(--sp-radio-disabled-bg);
3262
+ border-color: var(--sp-radio-disabled-border);
3263
+ }
3264
+
3265
+ .sp-select {
3266
+ width: 100%;
3267
+ display: block;
3268
+ appearance: none;
3269
+ padding: var(--sp-space-4) var(--sp-space-16);
3270
+ border-radius: var(--sp-radius-md);
3271
+ border: var(--sp-component-border-width) solid var(--sp-select-border);
3272
+ background-color: var(--sp-select-bg);
3273
+ color: var(--sp-select-text);
3274
+ font-family: var(--sp-font-family-sans);
3275
+ font-size: var(--sp-font-md-size);
3276
+ line-height: var(--sp-font-md-line-height);
3277
+ transition:
3278
+ border-color var(--sp-duration-fast) var(--sp-easing-out),
3279
+ background-color var(--sp-duration-fast) var(--sp-easing-out);
3280
+ }
3281
+
3282
+ .sp-select::placeholder {
3283
+ color: var(--sp-select-placeholder-text);
3284
+ }
3285
+
3286
+ .sp-select:focus,
3287
+ .sp-select--focus,
3288
+ .sp-select.is-focus {
3289
+ border-color: var(--sp-select-focus-border);
3290
+ }
3291
+
3292
+ .sp-select--disabled,
3293
+ .sp-select:disabled {
3294
+ background-color: var(--sp-select-disabled-bg);
3295
+ border-color: var(--sp-select-disabled-border);
3296
+ }
3297
+
3298
+ .sp-textarea {
3299
+ width: 100%;
3300
+ display: block;
3301
+ appearance: none;
3302
+ padding: var(--sp-space-4) var(--sp-space-16);
3303
+ border-radius: var(--sp-radius-md);
3304
+ border: var(--sp-component-border-width) solid var(--sp-textarea-border);
3305
+ background-color: var(--sp-textarea-bg);
3306
+ color: var(--sp-textarea-text);
3307
+ font-family: var(--sp-font-family-sans);
3308
+ font-size: var(--sp-font-md-size);
3309
+ line-height: var(--sp-font-md-line-height);
3310
+ transition:
3311
+ border-color var(--sp-duration-fast) var(--sp-easing-out),
3312
+ background-color var(--sp-duration-fast) var(--sp-easing-out);
3313
+ }
3314
+
3315
+ .sp-textarea::placeholder {
3316
+ color: var(--sp-textarea-placeholder);
3317
+ }
3318
+
3319
+ .sp-textarea:focus,
3320
+ .sp-textarea--focus,
3321
+ .sp-textarea.is-focus {
3322
+ border-color: var(--sp-textarea-focus-border);
3323
+ }
3324
+
3325
+ .sp-textarea--disabled,
3326
+ .sp-textarea:disabled {
3327
+ background-color: var(--sp-textarea-disabled-bg);
3328
+ border-color: var(--sp-textarea-disabled-border);
3329
+ }
3330
+
3331
+ .sp-fieldset {
3332
+ border: var(--sp-component-border-width) solid var(--sp-fieldset-border);
3333
+ border-radius: var(--sp-radius-md);
3334
+ padding: var(--sp-space-16);
3335
+ }
3336
+
3337
+ .sp-fieldset__legend {
3338
+ color: var(--sp-fieldset-legend-text);
3339
+ font-size: var(--sp-font-sm-size);
3340
+ font-weight: var(--sp-font-sm-weight);
3341
+ line-height: var(--sp-font-sm-line-height);
3342
+ }
3343
+
3344
+ .sp-form-label {
3345
+ color: var(--sp-label-text);
3346
+ font-size: var(--sp-font-sm-size);
3347
+ font-weight: var(--sp-font-sm-weight);
3348
+ line-height: var(--sp-font-sm-line-height);
3349
+ }
3350
+
3351
+ .sp-form-label--disabled {
3352
+ color: var(--sp-label-disabled-text);
3353
+ }
3354
+
3355
+ .sp-form-label--required::after {
3356
+ content: "*";
3357
+ color: var(--sp-label-required-indicator-text);
3358
+ }
3141
3359
  }
package/dist/index.cjs CHANGED
@@ -793,21 +793,36 @@ function getSidebarClasses(opts = {}) {
793
793
  const { bordered = false } = opts;
794
794
  return cx("sp-sidebar", bordered && "sp-sidebar--bordered");
795
795
  }
796
+ var SIDEBAR_LINK_LEVELS = {
797
+ parent: true,
798
+ child: true
799
+ };
796
800
  function getSidebarLinkClasses(opts = {}) {
797
801
  const {
798
802
  active = false,
799
803
  disabled = false,
800
804
  hovered = false,
801
- focused = false
805
+ focused = false,
806
+ level: levelInput
802
807
  } = opts;
808
+ const level = resolveOption({
809
+ name: "sidebar link level",
810
+ value: levelInput,
811
+ allowed: SIDEBAR_LINK_LEVELS,
812
+ fallback: "parent"
813
+ });
803
814
  return cx(
804
815
  "sp-sidebar__link",
805
816
  active && "sp-sidebar__link--active",
806
817
  disabled && "sp-sidebar__link--disabled",
807
818
  hovered && "sp-sidebar__link--hover is-hover",
808
- focused && "sp-sidebar__link--focus is-focus"
819
+ focused && "sp-sidebar__link--focus is-focus",
820
+ level === "child" && "sp-sidebar__link--child"
809
821
  );
810
822
  }
823
+ function getSidebarHeaderClasses() {
824
+ return cx("sp-sidebar__header");
825
+ }
811
826
  function getSidebarBackdropClasses() {
812
827
  return cx("sp-sidebar-backdrop");
813
828
  }
@@ -1023,15 +1038,77 @@ function getGridClasses(opts = {}) {
1023
1038
  return cx("sp-grid", `sp-grid--gap-${gap}`, `sp-grid-cols-${columns}`);
1024
1039
  }
1025
1040
 
1041
+ // src/recipes/checkbox.ts
1042
+ function getCheckboxClasses(opts = {}) {
1043
+ const { checked = false, disabled = false } = opts;
1044
+ return cx(
1045
+ "sp-checkbox-indicator",
1046
+ checked && "sp-checkbox-indicator--checked",
1047
+ disabled && "sp-checkbox-indicator--disabled"
1048
+ );
1049
+ }
1050
+
1051
+ // src/recipes/radio.ts
1052
+ function getRadioClasses(opts = {}) {
1053
+ const { checked = false, disabled = false } = opts;
1054
+ return cx(
1055
+ "sp-radio-indicator",
1056
+ checked && "sp-radio-indicator--checked",
1057
+ disabled && "sp-radio-indicator--disabled"
1058
+ );
1059
+ }
1060
+
1061
+ // src/recipes/select.ts
1062
+ function getSelectClasses(opts = {}) {
1063
+ const { disabled = false, focused = false } = opts;
1064
+ return cx(
1065
+ "sp-select",
1066
+ disabled && "sp-select--disabled",
1067
+ focused && "sp-select--focus is-focus"
1068
+ );
1069
+ }
1070
+
1071
+ // src/recipes/textarea.ts
1072
+ function getTextareaClasses(opts = {}) {
1073
+ const { disabled = false, focused = false } = opts;
1074
+ return cx(
1075
+ "sp-textarea",
1076
+ disabled && "sp-textarea--disabled",
1077
+ focused && "sp-textarea--focus is-focus"
1078
+ );
1079
+ }
1080
+
1081
+ // src/recipes/fieldset.ts
1082
+ function getFieldsetClasses(opts = {}) {
1083
+ const { disabled = false } = opts;
1084
+ return cx("sp-fieldset", disabled && "sp-fieldset--disabled");
1085
+ }
1086
+ function getFieldsetLegendClasses() {
1087
+ return cx("sp-fieldset__legend");
1088
+ }
1089
+
1090
+ // src/recipes/label.ts
1091
+ function getLabelClasses(opts = {}) {
1092
+ const { disabled = false, required = false } = opts;
1093
+ return cx(
1094
+ "sp-form-label",
1095
+ disabled && "sp-form-label--disabled",
1096
+ required && "sp-form-label--required"
1097
+ );
1098
+ }
1099
+
1026
1100
  exports.getAlertClasses = getAlertClasses;
1027
1101
  exports.getAvatarClasses = getAvatarClasses;
1028
1102
  exports.getBadgeClasses = getBadgeClasses;
1029
1103
  exports.getButtonClasses = getButtonClasses;
1030
1104
  exports.getCardClasses = getCardClasses;
1105
+ exports.getCheckboxClasses = getCheckboxClasses;
1031
1106
  exports.getContainerClasses = getContainerClasses;
1032
1107
  exports.getDropdownClasses = getDropdownClasses;
1033
1108
  exports.getDropdownItemClasses = getDropdownItemClasses;
1034
1109
  exports.getDropdownMenuClasses = getDropdownMenuClasses;
1110
+ exports.getFieldsetClasses = getFieldsetClasses;
1111
+ exports.getFieldsetLegendClasses = getFieldsetLegendClasses;
1035
1112
  exports.getFooterClasses = getFooterClasses;
1036
1113
  exports.getGridClasses = getGridClasses;
1037
1114
  exports.getIconBoxClasses = getIconBoxClasses;
@@ -1040,6 +1117,7 @@ exports.getInputErrorMessageClasses = getInputErrorMessageClasses;
1040
1117
  exports.getInputHelperTextClasses = getInputHelperTextClasses;
1041
1118
  exports.getInputLabelClasses = getInputLabelClasses;
1042
1119
  exports.getInputWrapperClasses = getInputWrapperClasses;
1120
+ exports.getLabelClasses = getLabelClasses;
1043
1121
  exports.getModalClasses = getModalClasses;
1044
1122
  exports.getModalOverlayClasses = getModalOverlayClasses;
1045
1123
  exports.getNavClasses = getNavClasses;
@@ -1050,13 +1128,16 @@ exports.getPricingCardClasses = getPricingCardClasses;
1050
1128
  exports.getPricingCardDescriptionClasses = getPricingCardDescriptionClasses;
1051
1129
  exports.getPricingCardPriceClasses = getPricingCardPriceClasses;
1052
1130
  exports.getPricingCardPriceContainerClasses = getPricingCardPriceContainerClasses;
1131
+ exports.getRadioClasses = getRadioClasses;
1053
1132
  exports.getRatingClasses = getRatingClasses;
1054
1133
  exports.getRatingStarClasses = getRatingStarClasses;
1055
1134
  exports.getRatingStarsClasses = getRatingStarsClasses;
1056
1135
  exports.getRatingTextClasses = getRatingTextClasses;
1057
1136
  exports.getSectionClasses = getSectionClasses;
1137
+ exports.getSelectClasses = getSelectClasses;
1058
1138
  exports.getSidebarBackdropClasses = getSidebarBackdropClasses;
1059
1139
  exports.getSidebarClasses = getSidebarClasses;
1140
+ exports.getSidebarHeaderClasses = getSidebarHeaderClasses;
1060
1141
  exports.getSidebarLinkClasses = getSidebarLinkClasses;
1061
1142
  exports.getSidebarToggleClasses = getSidebarToggleClasses;
1062
1143
  exports.getSpinnerClasses = getSpinnerClasses;
@@ -1068,6 +1149,7 @@ exports.getTestimonialAuthorNameClasses = getTestimonialAuthorNameClasses;
1068
1149
  exports.getTestimonialAuthorTitleClasses = getTestimonialAuthorTitleClasses;
1069
1150
  exports.getTestimonialClasses = getTestimonialClasses;
1070
1151
  exports.getTestimonialQuoteClasses = getTestimonialQuoteClasses;
1152
+ exports.getTextareaClasses = getTextareaClasses;
1071
1153
  exports.getToastClasses = getToastClasses;
1072
1154
  exports.getToastIconClasses = getToastIconClasses;
1073
1155
  exports.getTooltipClasses = getTooltipClasses;