@happyvertical/smrt-ui 0.55.16 → 0.55.18

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.
Files changed (166) hide show
  1. package/AGENTS.md +14 -0
  2. package/README.md +75 -0
  3. package/dist/components/calendar/Calendar.svelte +59 -56
  4. package/dist/components/calendar/CalendarView.svelte +80 -77
  5. package/dist/components/calendar/DayView.svelte +39 -36
  6. package/dist/components/chat/MessageBubble.svelte +26 -23
  7. package/dist/components/chat/ReactionPicker.svelte +12 -9
  8. package/dist/components/chat/TypingIndicator.svelte +12 -9
  9. package/dist/components/data/CollectionList.svelte +11 -8
  10. package/dist/components/data/CollectionToolbar.svelte +5 -2
  11. package/dist/components/data/DataTable.svelte +74 -59
  12. package/dist/components/data/ListSortSelect.svelte +8 -5
  13. package/dist/components/data/SortableHeader.svelte +10 -7
  14. package/dist/components/display/ConfidenceBadge.svelte +11 -8
  15. package/dist/components/display/CurrencyDisplay.svelte +7 -4
  16. package/dist/components/display/DateDisplay.svelte +6 -3
  17. package/dist/components/display/Icon.svelte +4 -1
  18. package/dist/components/display/StatusBadge.svelte +9 -6
  19. package/dist/components/feedback/Alert.svelte +12 -8
  20. package/dist/components/feedback/ConfirmDialog.svelte +13 -10
  21. package/dist/components/feedback/LoadingOverlay.svelte +37 -34
  22. package/dist/components/feedback/Meter.svelte +4 -1
  23. package/dist/components/feedback/Modal.svelte +26 -21
  24. package/dist/components/feedback/PhoneSheet.svelte +6 -3
  25. package/dist/components/feedback/Progress.svelte +8 -5
  26. package/dist/components/feedback/ProgressBar.svelte +13 -10
  27. package/dist/components/feedback/Spinner.svelte +4 -1
  28. package/dist/components/feedback/ToastViewport.svelte +18 -15
  29. package/dist/components/feedback/WorkingStrip.svelte +6 -3
  30. package/dist/components/forms/CameraCapture.svelte +8 -5
  31. package/dist/components/forms/Checkbox.svelte +11 -8
  32. package/dist/components/forms/Combobox.svelte +5 -2
  33. package/dist/components/forms/DatePicker.svelte +7 -2
  34. package/dist/components/forms/DictationButton.svelte +17 -14
  35. package/dist/components/forms/DictationStatus.svelte +12 -9
  36. package/dist/components/forms/ErrorSummary.svelte +4 -1
  37. package/dist/components/forms/FieldLabel.svelte +9 -6
  38. package/dist/components/forms/Fieldset.svelte +4 -1
  39. package/dist/components/forms/FilePicker.svelte +5 -2
  40. package/dist/components/forms/Form.svelte +1 -1
  41. package/dist/components/forms/FormActionBar.svelte +4 -1
  42. package/dist/components/forms/FormGroup.svelte +6 -3
  43. package/dist/components/forms/Input.svelte +22 -15
  44. package/dist/components/forms/InputGroup.svelte +6 -3
  45. package/dist/components/forms/Listbox.svelte +5 -2
  46. package/dist/components/forms/MultiSelect.svelte +4 -1
  47. package/dist/components/forms/Radio.svelte +9 -6
  48. package/dist/components/forms/RadioGroup.svelte +5 -2
  49. package/dist/components/forms/RangeSlider.svelte +5 -2
  50. package/dist/components/forms/RelationInput.svelte +7 -4
  51. package/dist/components/forms/SearchInput.svelte +7 -4
  52. package/dist/components/forms/SegmentedControl.svelte +6 -3
  53. package/dist/components/forms/Select.svelte +20 -13
  54. package/dist/components/forms/SignaturePad.svelte +8 -5
  55. package/dist/components/forms/Slider.svelte +5 -2
  56. package/dist/components/forms/StagedControlReview.svelte +15 -12
  57. package/dist/components/forms/Switch.svelte +8 -5
  58. package/dist/components/forms/TagsInput.svelte +5 -2
  59. package/dist/components/forms/Textarea.svelte +20 -13
  60. package/dist/components/forms/TimePicker.svelte +7 -2
  61. package/dist/components/forms/Toggle.svelte +14 -11
  62. package/dist/components/forms/ToggleButton.svelte +5 -2
  63. package/dist/components/layout/ActionGroup.svelte +4 -1
  64. package/dist/components/layout/Container.svelte +4 -1
  65. package/dist/components/layout/EmptyState.svelte +11 -8
  66. package/dist/components/layout/Footer.svelte +4 -1
  67. package/dist/components/layout/Grid.svelte +13 -10
  68. package/dist/components/layout/Header.svelte +4 -1
  69. package/dist/components/layout/Masthead.svelte +4 -1
  70. package/dist/components/layout/PageHeader.svelte +12 -9
  71. package/dist/components/layout/PageLayout.svelte +3 -0
  72. package/dist/components/layout/SummaryCard.svelte +9 -6
  73. package/dist/components/memberships/MembershipCard.svelte +5 -2
  74. package/dist/components/memberships/MembershipList.svelte +5 -2
  75. package/dist/components/nav/FilterChips.svelte +13 -10
  76. package/dist/components/nav/Tabs.svelte +75 -41
  77. package/dist/components/permissions/PermissionPicker.svelte +5 -2
  78. package/dist/components/roles/RoleBadge.svelte +8 -5
  79. package/dist/components/roles/RoleSelector.svelte +22 -19
  80. package/dist/components/theme/ThemeProvider.svelte +7 -4
  81. package/dist/components/ui/Accordion.svelte +4 -1
  82. package/dist/components/ui/AccordionItem.svelte +5 -2
  83. package/dist/components/ui/Avatar.svelte +10 -7
  84. package/dist/components/ui/Badge.svelte +6 -2
  85. package/dist/components/ui/Button.svelte +49 -37
  86. package/dist/components/ui/Card.svelte +18 -14
  87. package/dist/components/ui/Chip.svelte +41 -14
  88. package/dist/components/ui/Disclosure.svelte +5 -2
  89. package/dist/components/ui/Dropdown.svelte +33 -25
  90. package/dist/components/ui/IconToggle.svelte +12 -9
  91. package/dist/components/ui/IconToggle.svelte.d.ts +1 -1
  92. package/dist/components/ui/IconToggle.svelte.d.ts.map +1 -1
  93. package/dist/components/ui/IconToggleGroup.svelte +8 -5
  94. package/dist/components/ui/Pagination.svelte +11 -8
  95. package/dist/components/ui/Popover.svelte +9 -6
  96. package/dist/components/ui/Skeleton.svelte +10 -7
  97. package/dist/components/ui/Tooltip.svelte +13 -9
  98. package/dist/components/ui/Tree.svelte +12 -9
  99. package/dist/styles/layers.css +8 -0
  100. package/dist/styles/layers.d.ts +9 -0
  101. package/dist/styles/layers.d.ts.map +1 -0
  102. package/dist/styles/layers.js +8 -0
  103. package/dist/styles/tokens.css +27 -69
  104. package/dist/styles/unstyled.css +65 -0
  105. package/dist/svelte/playground/BaseControlsPreview.svelte +3 -0
  106. package/dist/svelte/playground/CalendarPreview.svelte +5 -2
  107. package/dist/svelte/playground/CapturePreview.svelte +3 -0
  108. package/dist/svelte/playground/CodeSelectorsPreview.svelte +3 -0
  109. package/dist/svelte/playground/CollectionsPreview.svelte +3 -0
  110. package/dist/svelte/playground/DataTablePreview.svelte +3 -0
  111. package/dist/svelte/playground/FeedbackPreview.svelte +3 -0
  112. package/dist/svelte/playground/InteractiveControlsPreview.svelte +3 -0
  113. package/dist/svelte/playground/StylelessPreview.svelte +110 -0
  114. package/dist/svelte/playground/StylelessPreview.svelte.d.ts +4 -0
  115. package/dist/svelte/playground/StylelessPreview.svelte.d.ts.map +1 -0
  116. package/dist/svelte/playground.d.ts.map +1 -1
  117. package/dist/svelte/playground.js +10 -0
  118. package/dist/test-support/setup.js +9 -0
  119. package/dist/theme/ThemeProvider.svelte +3 -0
  120. package/dist/themes/CUSTOM_THEME_GUIDE.md +40 -0
  121. package/dist/themes/README.md +151 -0
  122. package/dist/themes/ThemeProvider.svelte +181 -12
  123. package/dist/themes/ThemeProvider.svelte.d.ts +7 -2
  124. package/dist/themes/ThemeProvider.svelte.d.ts.map +1 -1
  125. package/dist/themes/components/ColorSchemeToggle.svelte +17 -14
  126. package/dist/themes/components/ThemeSwitcher.svelte +14 -11
  127. package/dist/themes/create-theme.d.ts +22 -1
  128. package/dist/themes/create-theme.d.ts.map +1 -1
  129. package/dist/themes/create-theme.js +100 -9
  130. package/dist/themes/css-generator.d.ts.map +1 -1
  131. package/dist/themes/css-generator.js +20 -20
  132. package/dist/themes/derive.d.ts +31 -0
  133. package/dist/themes/derive.d.ts.map +1 -0
  134. package/dist/themes/derive.js +183 -0
  135. package/dist/themes/glass/index.d.ts.map +1 -1
  136. package/dist/themes/glass/index.js +127 -14
  137. package/dist/themes/happyvertical/index.d.ts.map +1 -1
  138. package/dist/themes/happyvertical/index.js +101 -20
  139. package/dist/themes/index.d.ts +2 -2
  140. package/dist/themes/index.d.ts.map +1 -1
  141. package/dist/themes/index.js +1 -1
  142. package/dist/themes/material/index.d.ts.map +1 -1
  143. package/dist/themes/material/index.js +129 -28
  144. package/dist/themes/required-tokens.generated.json +201 -0
  145. package/dist/themes/shared.d.ts +35 -0
  146. package/dist/themes/shared.d.ts.map +1 -1
  147. package/dist/themes/shared.js +32 -0
  148. package/dist/themes/smrt/index.d.ts +3 -0
  149. package/dist/themes/smrt/index.d.ts.map +1 -1
  150. package/dist/themes/smrt/index.js +108 -26
  151. package/dist/themes/studio/index.d.ts.map +1 -1
  152. package/dist/themes/studio/index.js +116 -40
  153. package/dist/themes/styles/base.css +229 -1
  154. package/dist/themes/styles/glass.css +107 -20
  155. package/dist/themes/styles/happyvertical.css +111 -15
  156. package/dist/themes/styles/material.css +127 -35
  157. package/dist/themes/styles/smrt.css +126 -31
  158. package/dist/themes/styles/studio.css +132 -37
  159. package/dist/themes/theme-script.d.ts +3 -1
  160. package/dist/themes/theme-script.d.ts.map +1 -1
  161. package/dist/themes/theme-script.js +7 -2
  162. package/dist/themes/types.d.ts +118 -6
  163. package/dist/themes/types.d.ts.map +1 -1
  164. package/dist/utils/theme/typography.d.ts +21 -21
  165. package/dist/utils/theme/typography.js +21 -21
  166. package/package.json +8 -2
@@ -84,7 +84,7 @@ function handleChange(event: Event) {
84
84
  }
85
85
  </script>
86
86
 
87
- <div class={`list-sort-select ${className}`}>
87
+ <div class={`list-sort-select ${className}`} data-smrt-component="ListSortSelect">
88
88
  <label class="list-sort-select__label" for={id}>{label}</label>
89
89
  <select
90
90
  {id}
@@ -99,6 +99,8 @@ function handleChange(event: Event) {
99
99
  </div>
100
100
 
101
101
  <style>
102
+ @layer smrt.reset, smrt.structure, smrt.theme;
103
+ @layer smrt.theme {
102
104
  .list-sort-select {
103
105
  display: inline-flex;
104
106
  align-items: center;
@@ -106,16 +108,17 @@ function handleChange(event: Event) {
106
108
  }
107
109
  .list-sort-select__label {
108
110
  font-size: 0.875rem;
109
- color: var(--color-text-secondary, inherit);
111
+ color: var(--smrt-color-on-surface-variant, inherit);
110
112
  white-space: nowrap;
111
113
  }
112
114
  .list-sort-select__control {
113
115
  min-height: 2.75rem;
114
116
  padding: 0.25rem 0.5rem;
115
- border: 1px solid var(--color-border, currentColor);
116
- border-radius: var(--radius-md, 0.375rem);
117
- background: var(--color-surface, transparent);
117
+ border: 1px solid var(--smrt-color-outline-variant, currentColor);
118
+ border-radius: var(--smrt-radius-md, 0.375rem);
119
+ background: var(--smrt-color-surface, transparent);
118
120
  color: inherit;
119
121
  font: inherit;
120
122
  }
123
+ }
121
124
  </style>
@@ -13,8 +13,8 @@
13
13
  Use `as="div"` with `role="columnheader"` semantics for grid layouts that
14
14
  are not a `<table>`.
15
15
 
16
- Style hooks (set on the header or an ancestor): `--sortable-header-padding`
17
- (the control's padding) and `--sortable-header-font-weight` (default 600;
16
+ Style hooks (set on the header or an ancestor): `--smrt-sortable-header-padding`
17
+ (the control's padding) and `--smrt-sortable-header-font-weight` (default 600;
18
18
  `inherit` takes the surrounding head row's weight).
19
19
  -->
20
20
  <script lang="ts">
@@ -92,7 +92,7 @@ const actionLabel = $derived(listSortActionLabel(sort, columnId, label, spec));
92
92
  scope={as === 'th' ? 'col' : undefined}
93
93
  role={as === 'div' ? 'columnheader' : undefined}
94
94
  aria-sort={aria}
95
- data-sort-column={columnId}
95
+ data-sort-column={columnId} data-smrt-component="SortableHeader"
96
96
  >
97
97
  {#if href}
98
98
  <a
@@ -119,6 +119,8 @@ const actionLabel = $derived(listSortActionLabel(sort, columnId, label, spec));
119
119
  </svelte:element>
120
120
 
121
121
  <style>
122
+ @layer smrt.reset, smrt.structure, smrt.theme;
123
+ @layer smrt.theme {
122
124
  .sortable-header {
123
125
  padding: 0;
124
126
  font-weight: inherit;
@@ -136,12 +138,12 @@ const actionLabel = $derived(listSortActionLabel(sort, columnId, label, spec));
136
138
  gap: 0.25rem;
137
139
  min-height: 2.75rem;
138
140
  width: 100%;
139
- padding: var(--sortable-header-padding, 0.5rem 0.75rem);
141
+ padding: var(--smrt-sortable-header-padding, 0.5rem 0.75rem);
140
142
  border: 0;
141
143
  background: transparent;
142
144
  color: inherit;
143
145
  font: inherit;
144
- font-weight: var(--sortable-header-font-weight, 600);
146
+ font-weight: var(--smrt-sortable-header-font-weight, 600);
145
147
  text-align: inherit;
146
148
  text-decoration: none;
147
149
  cursor: pointer;
@@ -156,8 +158,8 @@ const actionLabel = $derived(listSortActionLabel(sort, columnId, label, spec));
156
158
  text-decoration: underline;
157
159
  }
158
160
  .sortable-header__control:focus-visible {
159
- outline: 2px solid var(--color-focus, var(--color-primary, currentColor));
160
- outline-offset: -2px;
161
+ outline: var(--smrt-focus-ring-width) solid var(--smrt-focus-ring-color);
162
+ outline-offset: calc(var(--smrt-focus-ring-width) * -1);
161
163
  }
162
164
  .sortable-header__icon {
163
165
  opacity: 0.35;
@@ -166,4 +168,5 @@ const actionLabel = $derived(listSortActionLabel(sort, columnId, label, spec));
166
168
  .sortable-header__icon.is-active {
167
169
  opacity: 1;
168
170
  }
171
+ }
169
172
  </style>
@@ -84,15 +84,15 @@ const valueText = $derived(
84
84
  class="confidence-badge {className}"
85
85
  class:sm={size === 'sm'}
86
86
  class:lg={size === 'lg'}
87
- style:--badge-bg={colors.bg}
88
- style:--badge-text={colors.text}
89
- style:--bar-color={colors.bar}
87
+ style:--smrt-badge-bg={colors.bg}
88
+ style:--smrt-badge-text={colors.text}
89
+ style:--smrt-confidence-badge-bar-color={colors.bar}
90
90
  role="meter"
91
91
  aria-valuenow={clampedConfidence}
92
92
  aria-valuemin={0}
93
93
  aria-valuemax={100}
94
94
  aria-valuetext={valueText}
95
- aria-label={ariaLabel ?? defaultLabel}
95
+ aria-label={ariaLabel ?? defaultLabel} data-smrt-component="ConfidenceBadge"
96
96
  >
97
97
  <span class="confidence-bar" style:width="{clampedConfidence}%"></span>
98
98
  {#if showPercent}
@@ -101,6 +101,8 @@ const valueText = $derived(
101
101
  </span>
102
102
 
103
103
  <style>
104
+ @layer smrt.reset, smrt.structure, smrt.theme;
105
+ @layer smrt.theme {
104
106
  .confidence-badge {
105
107
  display: inline-flex;
106
108
  align-items: center;
@@ -108,9 +110,9 @@ const valueText = $derived(
108
110
  padding: 0.25rem 0.5rem;
109
111
  font-size: var(--smrt-typography-label-medium-size, 0.75rem);
110
112
  font-weight: var(--smrt-typography-weight-medium, 500);
111
- border-radius: var(--smrt-radius-sm, 4px);
112
- background-color: var(--badge-bg);
113
- color: var(--badge-text);
113
+ border-radius: var(--smrt-radius-sm);
114
+ background-color: var(--smrt-badge-bg);
115
+ color: var(--smrt-badge-text);
114
116
  position: relative;
115
117
  overflow: hidden;
116
118
  min-width: 60px;
@@ -133,7 +135,7 @@ const valueText = $derived(
133
135
  left: 0;
134
136
  top: 0;
135
137
  bottom: 0;
136
- background-color: var(--bar-color);
138
+ background-color: var(--smrt-confidence-badge-bar-color);
137
139
  opacity: 0.3;
138
140
  transition: width var(--smrt-duration-short4, 300ms) var(--smrt-easing-standard, ease);
139
141
  }
@@ -143,4 +145,5 @@ const valueText = $derived(
143
145
  z-index: 1;
144
146
  font-variant-numeric: tabular-nums;
145
147
  }
148
+ }
146
149
  </style>
@@ -203,12 +203,14 @@ const colorClass = $derived.by(() => {
203
203
  class:lg={size === 'lg'}
204
204
  class:negative={colorClass === 'negative'}
205
205
  class:positive={colorClass === 'positive'}
206
- class:invalid={formatted.invalidCode !== null}
206
+ class:invalid={formatted.invalidCode !== null} data-smrt-component="CurrencyDisplay"
207
207
  >
208
208
  {formatted.text}
209
209
  </span>
210
210
 
211
211
  <style>
212
+ @layer smrt.reset, smrt.structure, smrt.theme;
213
+ @layer smrt.theme {
212
214
  .currency-display {
213
215
  font-variant-numeric: tabular-nums;
214
216
  white-space: nowrap;
@@ -224,14 +226,15 @@ const colorClass = $derived.by(() => {
224
226
  }
225
227
 
226
228
  .currency-display.negative {
227
- color: var(--smrt-color-error, #dc2626);
229
+ color: var(--smrt-color-error);
228
230
  }
229
231
 
230
232
  .currency-display.positive {
231
- color: var(--smrt-color-tertiary, #16a34a);
233
+ color: var(--smrt-color-tertiary);
232
234
  }
233
235
 
234
236
  .currency-display.invalid {
235
- color: var(--smrt-color-error, #dc2626);
237
+ color: var(--smrt-color-error);
236
238
  }
239
+ }
237
240
  </style>
@@ -163,22 +163,25 @@ const isoString = $derived(
163
163
  </script>
164
164
 
165
165
  {#if parsedDate}
166
- <time class="date-display {className}" datetime={isoString}>
166
+ <time class="date-display {className}" datetime={isoString} data-smrt-component="DateDisplay">
167
167
  {formatted}
168
168
  </time>
169
169
  {:else}
170
- <span class="date-display date-fallback {className}">
170
+ <span class="date-display date-fallback {className}" data-smrt-component="DateDisplay">
171
171
  {fallback}
172
172
  </span>
173
173
  {/if}
174
174
 
175
175
  <style>
176
+ @layer smrt.reset, smrt.structure, smrt.theme;
177
+ @layer smrt.theme {
176
178
  .date-display {
177
179
  white-space: nowrap;
178
180
  }
179
181
 
180
182
  .date-fallback {
181
- color: var(--smrt-color-on-surface-variant, #9ca3af);
183
+ color: var(--smrt-color-on-surface-variant);
182
184
  font-style: italic;
183
185
  }
186
+ }
184
187
  </style>
@@ -50,15 +50,18 @@ const pxSize = $derived(typeof size === 'number' ? `${size}px` : size);
50
50
  fill={color}
51
51
  aria-hidden={!isInformative}
52
52
  aria-label={ariaLabel}
53
- role={isInformative ? 'img' : undefined}
53
+ role={isInformative ? 'img' : undefined} data-smrt-component="Icon"
54
54
  >
55
55
  <path d={finalPath} />
56
56
  </svg>
57
57
 
58
58
  <style>
59
+ @layer smrt.reset, smrt.structure, smrt.theme;
60
+ @layer smrt.theme {
59
61
  svg {
60
62
  display: inline-block;
61
63
  flex-shrink: 0;
62
64
  vertical-align: middle;
63
65
  }
66
+ }
64
67
  </style>
@@ -251,24 +251,26 @@ const displayLabel = $derived(label ?? status.replace(/_/g, ' '));
251
251
  class:sm={size === 'sm'}
252
252
  class:lg={size === 'lg'}
253
253
  class:outline={variant === 'outline'}
254
- style:--badge-bg={colors.bg}
255
- style:--badge-text={colors.text}
254
+ style:--smrt-badge-bg={colors.bg}
255
+ style:--smrt-badge-text={colors.text} data-smrt-component="StatusBadge"
256
256
  >
257
257
  {displayLabel}
258
258
  </span>
259
259
 
260
260
  <style>
261
+ @layer smrt.reset, smrt.structure, smrt.theme;
262
+ @layer smrt.theme {
261
263
  .status-badge {
262
264
  display: inline-flex;
263
265
  align-items: center;
264
266
  padding: 0.25rem 0.75rem;
265
267
  font-size: var(--smrt-typography-label-medium-size, 0.75rem);
266
268
  font-weight: var(--smrt-typography-label-medium-weight, 500);
267
- border-radius: var(--smrt-radius-full, 9999px);
269
+ border-radius: var(--smrt-radius-full);
268
270
  white-space: nowrap;
269
271
  text-transform: capitalize;
270
- background-color: var(--badge-bg);
271
- color: var(--badge-text);
272
+ background-color: var(--smrt-badge-bg);
273
+ color: var(--smrt-badge-text);
272
274
  line-height: 1.25;
273
275
  }
274
276
 
@@ -284,6 +286,7 @@ const displayLabel = $derived(label ?? status.replace(/_/g, ' '));
284
286
 
285
287
  .status-badge.outline {
286
288
  background-color: transparent;
287
- border: 1px solid var(--badge-text);
289
+ border: 1px solid var(--smrt-badge-text);
288
290
  }
291
+ }
289
292
  </style>
@@ -32,7 +32,7 @@ const role = $derived(
32
32
  );
33
33
  </script>
34
34
 
35
- <div class="alert alert--{variant} {className}" {role}>
35
+ <div class="alert alert--{variant} {className}" {role} data-smrt-component="Alert">
36
36
  <span class="marker" aria-hidden="true"></span>
37
37
  <div class="content">
38
38
  {#if title}<strong>{title}</strong>{/if}
@@ -45,16 +45,20 @@ const role = $derived(
45
45
  </div>
46
46
 
47
47
  <style>
48
- .alert { --alert-color: var(--smrt-color-primary); display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: start; gap: var(--smrt-spacing-3); padding: var(--smrt-spacing-3) var(--smrt-spacing-4); border: 1px solid color-mix(in srgb, var(--alert-color) 35%, var(--smrt-color-outline-variant)); border-radius: var(--smrt-radius-medium); background: color-mix(in srgb, var(--alert-color) 8%, var(--smrt-color-surface)); color: var(--smrt-color-on-surface); }
49
- .alert--success { --alert-color: var(--smrt-color-success, #2e7d32); }
50
- .alert--warning { --alert-color: var(--smrt-color-warning, #a45b00); }
51
- .alert--error { --alert-color: var(--smrt-color-error); }
52
- .marker { width: .65rem; height: .65rem; margin-top: .4rem; border-radius: 50%; background: var(--alert-color); }
48
+ @layer smrt.reset, smrt.structure, smrt.theme;
49
+ @layer smrt.theme {
50
+ .alert { --smrt-alert-color: var(--smrt-color-primary); display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: start; gap: var(--smrt-spacing-3); padding: var(--smrt-spacing-3) var(--smrt-spacing-4); border: var(--smrt-hairline); border-color: color-mix(in srgb, var(--smrt-alert-color) 35%, var(--smrt-hairline-color)); box-shadow: var(--smrt-inset-highlight); border-radius: var(--smrt-radius-medium); background: color-mix(in srgb, var(--smrt-alert-color) 8%, var(--smrt-surface-panel)); color: var(--smrt-color-on-surface); }
51
+ .alert--info { --smrt-alert-color: var(--smrt-color-info); }
52
+ .alert--success { --smrt-alert-color: var(--smrt-color-success); }
53
+ .alert--warning { --smrt-alert-color: var(--smrt-color-warning); }
54
+ .alert--error { --smrt-alert-color: var(--smrt-color-error); }
55
+ .marker { width: .65rem; height: .65rem; margin-top: .4rem; border-radius: 50%; background: var(--smrt-alert-color); }
53
56
  .content { min-width: 0; }
54
57
  strong { display: block; font: var(--smrt-typography-title-small-font); }
55
58
  .message { color: var(--smrt-color-on-surface-variant); }
56
59
  .action { align-self: center; }
57
60
  .dismiss { width: 2rem; height: 2rem; margin: -.35rem; border: 0; border-radius: var(--smrt-radius-full); background: transparent; color: inherit; font-size: 1.25rem; cursor: pointer; }
58
- .dismiss:hover { background: color-mix(in srgb, currentColor 10%, transparent); }
59
- .dismiss:focus-visible { outline: 2px solid var(--smrt-color-primary); }
61
+ .dismiss:hover { background: color-mix(in srgb, currentColor calc(var(--smrt-state-hover) * 100%), transparent); }
62
+ .dismiss:focus-visible { outline: var(--smrt-focus-ring-width) solid var(--smrt-focus-ring-color); outline-offset: var(--smrt-focus-ring-offset); }
63
+ }
60
64
  </style>
@@ -134,7 +134,7 @@ function handleKeydown(e: KeyboardEvent) {
134
134
  tabindex="-1"
135
135
  onclick={handleBackdropClick}
136
136
  onkeydown={handleKeydown}
137
- oncancel={handleCancel}
137
+ oncancel={handleCancel} data-smrt-component="ConfirmDialog"
138
138
  >
139
139
  <div class="dialog-content">
140
140
  <h2 id={`${instanceId}-title`} class="dialog-title">{title}</h2>
@@ -176,6 +176,8 @@ function handleKeydown(e: KeyboardEvent) {
176
176
  {/if}
177
177
 
178
178
  <style>
179
+ @layer smrt.reset, smrt.structure, smrt.theme;
180
+ @layer smrt.theme {
179
181
  .dialog-backdrop {
180
182
  position: fixed;
181
183
  inset: 0;
@@ -201,7 +203,7 @@ function handleKeydown(e: KeyboardEvent) {
201
203
  .dialog-content {
202
204
  background-color: var(--smrt-color-surface-container-high);
203
205
  border-radius: var(--smrt-radius-3xl, 32px);
204
- padding: var(--smrt-spacing-6, 24px);
206
+ padding: var(--smrt-spacing-6);
205
207
  max-width: 400px;
206
208
  width: 100%;
207
209
  box-shadow: var(--smrt-elevation-3);
@@ -224,32 +226,32 @@ function handleKeydown(e: KeyboardEvent) {
224
226
  .dialog-title {
225
227
  font: var(--smrt-typography-headline-small-font);
226
228
  color: var(--smrt-color-on-surface);
227
- margin: 0 0 var(--smrt-spacing-4, 16px);
229
+ margin: 0 0 var(--smrt-spacing-4);
228
230
  }
229
231
 
230
232
  .dialog-message {
231
233
  font: var(--smrt-typography-body-medium-font);
232
234
  color: var(--smrt-color-on-surface-variant);
233
- margin: 0 0 var(--smrt-spacing-6, 24px);
235
+ margin: 0 0 var(--smrt-spacing-6);
234
236
  line-height: 1.5;
235
237
  }
236
238
 
237
239
  .dialog-actions {
238
240
  display: flex;
239
241
  justify-content: flex-end;
240
- gap: var(--smrt-spacing-2, 8px);
242
+ gap: var(--smrt-spacing-2);
241
243
  }
242
244
 
243
245
  .btn {
244
246
  display: inline-flex;
245
247
  align-items: center;
246
248
  justify-content: center;
247
- gap: var(--smrt-spacing-2, 8px);
249
+ gap: var(--smrt-spacing-2);
248
250
  height: 40px;
249
- padding: 0 var(--smrt-spacing-6, 24px);
251
+ padding: 0 var(--smrt-spacing-6);
250
252
  font: var(--smrt-typography-label-large-font);
251
253
  font-weight: var(--smrt-typography-weight-medium, 500);
252
- border-radius: var(--smrt-radius-2xl, 24px);
254
+ border-radius: var(--smrt-radius-2xl);
253
255
  cursor: pointer;
254
256
  transition: all var(--smrt-duration-short3, 200ms) var(--smrt-easing-standard, ease);
255
257
  border: none;
@@ -265,7 +267,7 @@ function handleKeydown(e: KeyboardEvent) {
265
267
  .btn-text {
266
268
  background: transparent;
267
269
  color: var(--smrt-color-primary);
268
- padding: 0 var(--smrt-spacing-3, 12px);
270
+ padding: 0 var(--smrt-spacing-3);
269
271
  }
270
272
 
271
273
  .btn-text:hover:not(:disabled) {
@@ -292,7 +294,7 @@ function handleKeydown(e: KeyboardEvent) {
292
294
  height: 18px;
293
295
  border: 2px solid transparent;
294
296
  border-top-color: currentColor;
295
- border-radius: var(--smrt-radius-full, 9999px);
297
+ border-radius: var(--smrt-radius-full);
296
298
  animation: spin 0.8s linear infinite;
297
299
  }
298
300
 
@@ -310,4 +312,5 @@ function handleKeydown(e: KeyboardEvent) {
310
312
  animation: none;
311
313
  }
312
314
  }
315
+ }
313
316
  </style>
@@ -70,7 +70,7 @@ function handleKeydown(e: KeyboardEvent) {
70
70
  aria-modal="true"
71
71
  aria-labelledby="loading-title"
72
72
  aria-describedby={items.length > 0 ? 'loading-items' : undefined}
73
- aria-busy={!error}
73
+ aria-busy={!error} data-smrt-component="LoadingOverlay"
74
74
  >
75
75
  <div class="overlay-backdrop"></div>
76
76
 
@@ -132,6 +132,8 @@ function handleKeydown(e: KeyboardEvent) {
132
132
  {/if}
133
133
 
134
134
  <style>
135
+ @layer smrt.reset, smrt.structure, smrt.theme;
136
+ @layer smrt.theme {
135
137
  .loading-overlay {
136
138
  position: fixed;
137
139
  inset: 0;
@@ -151,8 +153,8 @@ function handleKeydown(e: KeyboardEvent) {
151
153
  .overlay-content {
152
154
  position: relative;
153
155
  background: var(--smrt-color-surface-container-high, white);
154
- border-radius: var(--smrt-radius-xl, 16px);
155
- padding: var(--smrt-spacing-8, 32px) var(--smrt-spacing-10, 40px);
156
+ border-radius: var(--smrt-radius-xl);
157
+ padding: var(--smrt-spacing-8) var(--smrt-spacing-10);
156
158
  max-width: 400px;
157
159
  width: 90%;
158
160
  text-align: center;
@@ -162,7 +164,7 @@ function handleKeydown(e: KeyboardEvent) {
162
164
  .loading-icon {
163
165
  width: 48px;
164
166
  height: 48px;
165
- margin: 0 auto var(--smrt-spacing-4, 16px);
167
+ margin: 0 auto var(--smrt-spacing-4);
166
168
  }
167
169
 
168
170
  .icon {
@@ -171,12 +173,12 @@ function handleKeydown(e: KeyboardEvent) {
171
173
  }
172
174
 
173
175
  .icon.spinner {
174
- color: var(--smrt-color-primary, #3b82f6);
176
+ color: var(--smrt-color-primary);
175
177
  animation: spin 1s linear infinite;
176
178
  }
177
179
 
178
180
  .icon.error {
179
- color: var(--smrt-color-error, #ef4444);
181
+ color: var(--smrt-color-error);
180
182
  }
181
183
 
182
184
  @keyframes spin {
@@ -191,22 +193,22 @@ function handleKeydown(e: KeyboardEvent) {
191
193
  .title {
192
194
  font-size: var(--smrt-typography-title-large-size, 1.25rem);
193
195
  font-weight: var(--smrt-typography-weight-semibold, 600);
194
- color: var(--smrt-color-on-surface, #1f2937);
195
- margin: 0 0 var(--smrt-spacing-4, 16px);
196
+ color: var(--smrt-color-on-surface);
197
+ margin: 0 0 var(--smrt-spacing-4);
196
198
  }
197
199
 
198
200
  .progress-container {
199
201
  display: flex;
200
202
  align-items: center;
201
- gap: var(--smrt-spacing-3, 12px);
202
- margin: var(--smrt-spacing-4, 16px) 0;
203
+ gap: var(--smrt-spacing-3);
204
+ margin: var(--smrt-spacing-4) 0;
203
205
  }
204
206
 
205
207
  .progress-bar {
206
208
  flex: 1;
207
209
  height: 8px;
208
- background: var(--smrt-color-surface-container-highest, #e5e7eb);
209
- border-radius: var(--smrt-radius-sm, 4px);
210
+ background: var(--smrt-color-surface-container-highest);
211
+ border-radius: var(--smrt-radius-sm);
210
212
  overflow: hidden;
211
213
  }
212
214
 
@@ -217,62 +219,62 @@ function handleKeydown(e: KeyboardEvent) {
217
219
  var(--smrt-color-primary),
218
220
  color-mix(in srgb, var(--smrt-color-primary) 70%, white)
219
221
  );
220
- border-radius: var(--smrt-radius-sm, 4px);
222
+ border-radius: var(--smrt-radius-sm);
221
223
  transition: width var(--smrt-duration-short4, 300ms) var(--smrt-easing-standard, ease);
222
224
  }
223
225
 
224
226
  .progress-text {
225
227
  font-size: var(--smrt-typography-label-large-size, 0.875rem);
226
228
  font-weight: var(--smrt-typography-weight-semibold, 600);
227
- color: var(--smrt-color-primary, #3b82f6);
229
+ color: var(--smrt-color-primary);
228
230
  min-width: 40px;
229
231
  }
230
232
 
231
233
  .items-container {
232
234
  display: flex;
233
235
  flex-wrap: wrap;
234
- gap: var(--smrt-spacing-2, 8px);
236
+ gap: var(--smrt-spacing-2);
235
237
  justify-content: center;
236
- margin-top: var(--smrt-spacing-4, 16px);
238
+ margin-top: var(--smrt-spacing-4);
237
239
  }
238
240
 
239
241
  .item-badge {
240
242
  font-size: var(--smrt-typography-label-medium-size, 0.75rem);
241
- padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-3, 12px);
242
- border-radius: var(--smrt-radius-full, 9999px);
243
- background: var(--smrt-color-primary-container, #dcfce7);
244
- color: var(--smrt-color-on-primary-container, #166534);
243
+ padding: var(--smrt-spacing-1) var(--smrt-spacing-3);
244
+ border-radius: var(--smrt-radius-full);
245
+ background: var(--smrt-color-primary-container);
246
+ color: var(--smrt-color-on-primary-container);
245
247
  }
246
248
 
247
249
  .error-message {
248
250
  font-size: var(--smrt-typography-body-medium-size, 0.875rem);
249
- color: var(--smrt-color-error, #ef4444);
250
- margin: var(--smrt-spacing-4, 16px) 0 0;
251
- padding: var(--smrt-spacing-3, 12px);
252
- background: var(--smrt-color-error-container, #fef2f2);
253
- border-radius: var(--smrt-radius-md, 8px);
251
+ color: var(--smrt-color-error);
252
+ margin: var(--smrt-spacing-4) 0 0;
253
+ padding: var(--smrt-spacing-3);
254
+ background: var(--smrt-color-error-container);
255
+ border-radius: var(--smrt-radius-md);
254
256
  }
255
257
 
256
258
  .dismiss-btn {
257
- margin-top: var(--smrt-spacing-5, 20px);
258
- padding: var(--smrt-spacing-3, 12px) var(--smrt-spacing-5, 20px);
259
+ margin-top: var(--smrt-spacing-5);
260
+ padding: var(--smrt-spacing-3) var(--smrt-spacing-5);
259
261
  font-size: var(--smrt-typography-label-large-size, 0.875rem);
260
- color: var(--smrt-color-on-surface-variant, #6b7280);
262
+ color: var(--smrt-color-on-surface-variant);
261
263
  background: transparent;
262
- border: 1px solid var(--smrt-color-outline, #9ca3af);
263
- border-radius: var(--smrt-radius-md, 8px);
264
+ border: 1px solid var(--smrt-color-outline);
265
+ border-radius: var(--smrt-radius-md);
264
266
  cursor: pointer;
265
267
  transition: all var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
266
268
  }
267
269
 
268
270
  .dismiss-btn:hover {
269
- background: var(--smrt-color-surface-container-highest, #f3f4f6);
270
- border-color: var(--smrt-color-outline, #9ca3af);
271
+ background: var(--smrt-color-surface-container-highest);
272
+ border-color: var(--smrt-color-outline);
271
273
  }
272
274
 
273
275
  .dismiss-btn:focus-visible {
274
- outline: 2px solid var(--smrt-color-primary);
275
- outline-offset: 2px;
276
+ outline: var(--smrt-focus-ring-width) solid var(--smrt-focus-ring-color);
277
+ outline-offset: var(--smrt-focus-ring-offset);
276
278
  }
277
279
 
278
280
  @media (prefers-reduced-motion: reduce) {
@@ -283,4 +285,5 @@ function handleKeydown(e: KeyboardEvent) {
283
285
  transition: none;
284
286
  }
285
287
  }
288
+ }
286
289
  </style>
@@ -34,10 +34,13 @@ let {
34
34
  class: className = '',
35
35
  }: Props = $props();
36
36
  </script>
37
- <div class="meter {className}"><div class="meter__header"><span>{label}</span>{#if showValue}<span>{formatValue(value)}</span>{/if}</div>
37
+ <div class="meter {className}" data-smrt-component="Meter"><div class="meter__header"><span>{label}</span>{#if showValue}<span>{formatValue(value)}</span>{/if}</div>
38
38
  <meter {value} {min} {max} {low} {high} {optimum}>{formatValue(value)}</meter></div>
39
39
  <style>
40
+ @layer smrt.reset, smrt.structure, smrt.theme;
41
+ @layer smrt.theme {
40
42
  .meter { display: grid; gap: var(--smrt-spacing-2); color: var(--smrt-color-on-surface); }
41
43
  .meter__header { display: flex; justify-content: space-between; font: var(--smrt-typography-label-large-font); }
42
44
  meter { width: 100%; height: .75rem; accent-color: var(--smrt-color-primary); }
45
+ }
43
46
  </style>