@happyvertical/smrt-svelte 0.34.5 → 0.34.6

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 (39) hide show
  1. package/AGENTS.md +22 -9
  2. package/dist/browser-ai/svelte/components/STTTest.svelte +7 -42
  3. package/dist/browser-ai/svelte/components/STTTest.svelte.d.ts.map +1 -1
  4. package/dist/browser-ai/svelte/components/VoiceInput.svelte +1 -0
  5. package/dist/browser-ai/svelte/components/VoiceInput.svelte.d.ts.map +1 -1
  6. package/dist/components/forms/index.d.ts +9 -6
  7. package/dist/components/forms/index.d.ts.map +1 -1
  8. package/dist/components/forms/index.js +10 -7
  9. package/dist/components/workspace/WorkspaceShell.svelte +27 -34
  10. package/dist/components/workspace/WorkspaceShell.svelte.d.ts.map +1 -1
  11. package/dist/components/workspace/tools-dock/ToolsDock.svelte +11 -7
  12. package/dist/components/workspace/tools-dock/ToolsDock.svelte.d.ts.map +1 -1
  13. package/package.json +5 -4
  14. package/dist/components/forms/FormGroup.svelte +0 -86
  15. package/dist/components/forms/FormGroup.svelte.d.ts +0 -13
  16. package/dist/components/forms/FormGroup.svelte.d.ts.map +0 -1
  17. package/dist/components/forms/Input.svelte +0 -83
  18. package/dist/components/forms/Input.svelte.d.ts +0 -9
  19. package/dist/components/forms/Input.svelte.d.ts.map +0 -1
  20. package/dist/components/forms/Select.svelte +0 -83
  21. package/dist/components/forms/Select.svelte.d.ts +0 -11
  22. package/dist/components/forms/Select.svelte.d.ts.map +0 -1
  23. package/dist/components/forms/Textarea.svelte +0 -85
  24. package/dist/components/forms/Textarea.svelte.d.ts +0 -10
  25. package/dist/components/forms/Textarea.svelte.d.ts.map +0 -1
  26. package/dist/components/forms/Toggle.svelte +0 -217
  27. package/dist/components/forms/Toggle.svelte.d.ts +0 -37
  28. package/dist/components/forms/Toggle.svelte.d.ts.map +0 -1
  29. package/dist/components/forms/__tests__/FormGroup.test.js +0 -48
  30. package/dist/components/forms/__tests__/Input.test.js +0 -49
  31. package/dist/components/forms/__tests__/Select.test.js +0 -37
  32. package/dist/components/forms/__tests__/Textarea.test.js +0 -39
  33. package/dist/components/forms/__tests__/Toggle.test.js +0 -87
  34. package/dist/components/forms/__tests__/form-group-input.fixture.svelte +0 -16
  35. package/dist/components/forms/__tests__/form-group-input.fixture.svelte.d.ts +0 -9
  36. package/dist/components/forms/__tests__/form-group-input.fixture.svelte.d.ts.map +0 -1
  37. package/dist/state/form-group-context.d.ts +0 -13
  38. package/dist/state/form-group-context.d.ts.map +0 -1
  39. package/dist/state/form-group-context.js +0 -28
package/AGENTS.md CHANGED
@@ -6,19 +6,30 @@ Top-of-stack Svelte 5 integration layer for SMRT: the app `Provider`, auth / AI
6
6
 
7
7
  SMRT's shared UI primitives are split by concern: **`smrt-ui` owns the
8
8
  domain-agnostic VISUAL primitives** (`Button`, `Card`, `Modal`, `Badge`,
9
- `Avatar`, `Chip`, `Dropdown`, …) and **`smrt-svelte` (here) owns the FORM
10
- primitives** (`Input`, `Textarea`, `Select`, `Checkbox`/`Toggle`, `Form`, and the
11
- specialized date/measurement/address/file inputs they carry i18n + spoken-input
12
- logic that keeps them above the leaf).
9
+ `Avatar`, `Chip`, `Dropdown`, …) **plus the Provider-free base FORM primitives**
10
+ (`Form`, `Input`, `Select`, `Textarea`, `Toggle`, `FormGroup` under
11
+ `@happyvertical/smrt-ui/forms`relocated there in #1589's deferred-forms phase
12
+ so domain packages can adopt them without the Provider or a build-graph cycle),
13
+ and **`smrt-svelte` (here) owns the Provider-REQUIRED form primitives**
14
+ (`CheckboxInput`, the rich `Form`, `TextInput`, `MoneyInput`, and the specialized
15
+ date/measurement/address/file inputs — they call `useAppState` / the AI hooks and
16
+ carry i18n + spoken-input logic that keeps them above the leaf). This package
17
+ re-exports the base **input** primitives (`Input`, `Select`, `Textarea`,
18
+ `Toggle`, `FormGroup`) from smrt-ui so `@happyvertical/smrt-svelte/forms` stays
19
+ the full barrel — but **not** `Form`: this barrel's `Form` is the rich
20
+ Provider-backed one, so import the Provider-free `Form` from
21
+ `@happyvertical/smrt-ui/forms` directly.
13
22
 
14
23
  Two consequences:
15
24
 
16
25
  - **This package is the canonical consumer.** smrt-svelte's own composites and
17
26
  workspace shell must adopt smrt-ui visual primitives — use `Button`, not a raw
18
- `<button>`. Only `src/components/forms/` (the form primitives themselves)
19
- legitimately holds raw `<input>`/`<select>`/`<textarea>`.
20
- - **Domain packages import visual primitives from `smrt-ui` and form primitives
21
- from `smrt-svelte`**, and must not hand-roll raw interactive markup.
27
+ `<button>`. Only `src/components/forms/` (the Provider-required form primitives
28
+ themselves) legitimately holds raw `<input>`/`<select>`/`<textarea>`; the base
29
+ primitives now define those raw elements in `smrt-ui/src/components/forms/`.
30
+ - **Domain packages import visual + base form primitives from `smrt-ui` and the
31
+ Provider-required form primitives from `smrt-svelte`**, and must not hand-roll
32
+ raw interactive markup.
22
33
 
23
34
  Enforced by `scripts/check-raw-primitives.mjs` (report-only during the #1589
24
35
  migration; flips strict per package as it adopts the primitives).
@@ -102,7 +113,9 @@ library. Which barrel for what:
102
113
  | Need | Import from |
103
114
  |------|-------------|
104
115
  | Buttons, cards, badges, avatars, chips, skeletons, tooltips, dropdowns, trees, pagination | `@happyvertical/smrt-svelte/ui` (or the package root) |
105
- | Text/select/number/date/money/address inputs, toggles, file upload, `Form`, `FormGroup` | `@happyvertical/smrt-svelte/forms` |
116
+ | Provider-free base inputs `Input`, `Select`, `Textarea`, `Toggle`, `FormGroup` | `@happyvertical/smrt-ui/forms` (also re-exported from `@happyvertical/smrt-svelte/forms`) |
117
+ | Provider-free `Form` (plain `<form>` wrapper) | `@happyvertical/smrt-ui/forms` **only** — `@happyvertical/smrt-svelte/forms` exports the *rich* Provider-backed `Form` under that name, so import the plain one straight from smrt-ui |
118
+ | Provider-backed inputs — `TextInput`, `NumberInput`, `MoneyInput`, date/measurement/address inputs, `CheckboxInput`, file upload, the rich `Form` | `@happyvertical/smrt-svelte/forms` |
106
119
  | `Modal`, `ConfirmDialog`, `LoadingOverlay`, `ProgressBar` | `@happyvertical/smrt-svelte/feedback` |
107
120
  | `Container`, `Grid`, `Header`, `Footer`, `PageHeader`, `EmptyState` | `@happyvertical/smrt-svelte/layout` |
108
121
  | Chat message bubble, reaction picker, typing indicator | `@happyvertical/smrt-svelte/chat` |
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
+ import { Button } from '@happyvertical/smrt-ui/ui';
3
4
  import { useAppState } from '../../../hooks/useAppState.svelte.js';
4
5
  import { M } from '../../../i18n/strings.workspace.js';
5
6
  import type { GetSTTOptions } from '../../index.js';
@@ -117,13 +118,13 @@ function clearLogs() {
117
118
  </select>
118
119
  </div>
119
120
 
120
- <button
121
- type="button"
121
+ <Button
122
+ variant="primary"
122
123
  onclick={initializeAdapter}
123
124
  disabled={isRecording || isInitializing}
124
125
  >
125
126
  Initialize
126
- </button>
127
+ </Button>
127
128
  </div>
128
129
 
129
130
  <div class="status">
@@ -153,6 +154,7 @@ function clearLogs() {
153
154
  {/if}
154
155
 
155
156
  <div class="record-controls">
157
+ <!-- raw-primitive-allow: press-and-hold record control driven by mousedown/up/leave + touchstart/end (push-to-talk), not a click action; Button has no press-and-hold model so this stays a native button -->
156
158
  <button
157
159
  type="button"
158
160
  class="record-btn"
@@ -180,7 +182,7 @@ function clearLogs() {
180
182
  <div class="logs">
181
183
  <div class="logs-header">
182
184
  <strong>Logs:</strong>
183
- <button type="button" onclick={clearLogs}>Clear</button>
185
+ <Button variant="ghost" size="sm" onclick={clearLogs}>Clear</Button>
184
186
  </div>
185
187
  <div class="log-list">
186
188
  {#each logs as logEntry}
@@ -229,27 +231,6 @@ function clearLogs() {
229
231
  font: var(--smrt-typography-body-medium-font, 0.875rem / 1.25 sans-serif);
230
232
  }
231
233
 
232
- .controls button {
233
- padding: var(--smrt-spacing-sm, 8px) var(--smrt-spacing-md, 16px);
234
- background: var(--smrt-color-primary, #005ac1);
235
- color: var(--smrt-color-on-primary, #ffffff);
236
- border: none;
237
- border-radius: var(--smrt-radius-small, 6px);
238
- cursor: pointer;
239
- font: var(--smrt-typography-label-large-font, 0.875rem / 1.25 sans-serif);
240
- transition: all var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
241
- }
242
-
243
- .controls button:hover:not(:disabled) {
244
- background: var(--smrt-color-primary-container, #005ac1);
245
- opacity: 0.9;
246
- }
247
-
248
- .controls button:disabled {
249
- opacity: 0.5;
250
- cursor: not-allowed;
251
- }
252
-
253
234
  .status {
254
235
  display: flex;
255
236
  gap: var(--smrt-spacing-md, 16px);
@@ -337,20 +318,6 @@ function clearLogs() {
337
318
  margin-bottom: var(--smrt-spacing-sm, 8px);
338
319
  }
339
320
 
340
- .logs-header button {
341
- padding: var(--smrt-spacing-1, 4px) var(--smrt-spacing-sm, 8px);
342
- font: var(--smrt-typography-label-small-font, 0.75rem / 1 sans-serif);
343
- background: var(--smrt-color-surface-container, #e5e7eb);
344
- border: none;
345
- border-radius: var(--smrt-radius-small, 4px);
346
- cursor: pointer;
347
- transition: background-color var(--smrt-duration-short2, 150ms) var(--smrt-easing-standard, ease);
348
- }
349
-
350
- .logs-header button:hover {
351
- background: var(--smrt-color-surface-container-high, #d1d5db);
352
- }
353
-
354
321
  .log-list {
355
322
  background: var(--smrt-color-inverse-surface, #1f2937);
356
323
  color: var(--smrt-color-inverse-on-surface, #d1d5db);
@@ -366,9 +333,7 @@ function clearLogs() {
366
333
  }
367
334
 
368
335
  @media (prefers-reduced-motion: reduce) {
369
- .controls button,
370
- .record-btn,
371
- .logs-header button {
336
+ .record-btn {
372
337
  transition: none;
373
338
  }
374
339
 
@@ -1 +1 @@
1
- {"version":3,"file":"STTTest.svelte.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/svelte/components/STTTest.svelte.ts"],"names":[],"mappings":"AAUA,kCAAkC;AAClC,MAAM,WAAW,KAAK;IACpB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgLD,QAAA,MAAM,OAAO,2CAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"STTTest.svelte.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/svelte/components/STTTest.svelte.ts"],"names":[],"mappings":"AAWA,kCAAkC;AAClC,MAAM,WAAW,KAAK;IACpB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkLD,QAAA,MAAM,OAAO,2CAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -66,6 +66,7 @@ async function handleToggle() {
66
66
  <span>{stt.error.message}</span>
67
67
  </div>
68
68
  {:else}
69
+ <!-- raw-primitive-allow: bespoke circular mic toggle with a listening-state pulse animation, the core voice-input control; not a standard action button -->
69
70
  <button
70
71
  type="button"
71
72
  class="mic-button"
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceInput.svelte.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/svelte/components/VoiceInput.svelte.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,KAAK;IACpB,qCAAqC;IACrC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yBAAyB;IACzB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmED,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"VoiceInput.svelte.d.ts","sourceRoot":"","sources":["../../../../src/browser-ai/svelte/components/VoiceInput.svelte.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,KAAK;IACpB,qCAAqC;IACrC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yBAAyB;IACzB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoED,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -1,25 +1,28 @@
1
1
  /**
2
- * SMRT Form components with voice input capabilities
2
+ * SMRT Form components with voice input capabilities.
3
+ *
4
+ * The Provider-FREE base primitives (`Input`, `Select`, `Textarea`, `Toggle`,
5
+ * `FormGroup`) were relocated to `@happyvertical/smrt-ui/forms` (#1589
6
+ * deferred-forms phase) so domain packages can adopt them without the Provider
7
+ * or a build-graph cycle. They are re-exported here so this subpath stays the
8
+ * one-stop barrel for form primitives. The Provider-REQUIRED inputs (the rich
9
+ * `Form`, `CheckboxInput`, `TextInput`, …) still live in this package.
3
10
  */
11
+ export { FormGroup, Input, Select, Textarea, Toggle, } from '@happyvertical/smrt-ui/forms';
4
12
  export { default as AddressInput } from './AddressInput.svelte';
5
13
  export { default as CheckboxInput } from './CheckboxInput.svelte';
6
14
  export { default as DateRangeInput } from './DateRangeInput.svelte';
7
15
  export { default as DateTimeInput } from './DateTimeInput.svelte';
8
16
  export { default as FileUpload } from './FileUpload.svelte';
9
17
  export { default as Form } from './Form.svelte';
10
- export { default as FormGroup } from './FormGroup.svelte';
11
18
  export { default as FormMicButton } from './FormMicButton.svelte';
12
- export { default as Input } from './Input.svelte';
13
19
  export { default as MeasurementInput } from './MeasurementInput.svelte';
14
20
  export { default as MoneyInput } from './MoneyInput.svelte';
15
21
  export { default as NumberInput } from './NumberInput.svelte';
16
22
  export { default as PhoneInput } from './PhoneInput.svelte';
17
23
  export { default as SearchInput } from './SearchInput.svelte';
18
- export { default as Select } from './Select.svelte';
19
24
  export { default as SelectInput } from './SelectInput.svelte';
20
- export { default as Textarea } from './Textarea.svelte';
21
25
  export { default as TextareaInput } from './TextareaInput.svelte';
22
26
  export { default as TextInput } from './TextInput.svelte';
23
- export { default as Toggle } from './Toggle.svelte';
24
27
  export type { AddressValue, DateRangeValue, LLMModelId, MeasurementUnit, MeasurementValue, SelectOption, STTAdapterType, } from './types.js';
25
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/forms/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGpD,YAAY,EACV,YAAY,EACZ,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/forms/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACL,SAAS,EACT,KAAK,EACL,MAAM,EACN,QAAQ,EACR,MAAM,GACP,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG1D,YAAY,EACV,YAAY,EACZ,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -1,6 +1,15 @@
1
1
  /**
2
- * SMRT Form components with voice input capabilities
2
+ * SMRT Form components with voice input capabilities.
3
+ *
4
+ * The Provider-FREE base primitives (`Input`, `Select`, `Textarea`, `Toggle`,
5
+ * `FormGroup`) were relocated to `@happyvertical/smrt-ui/forms` (#1589
6
+ * deferred-forms phase) so domain packages can adopt them without the Provider
7
+ * or a build-graph cycle. They are re-exported here so this subpath stays the
8
+ * one-stop barrel for form primitives. The Provider-REQUIRED inputs (the rich
9
+ * `Form`, `CheckboxInput`, `TextInput`, …) still live in this package.
3
10
  */
11
+ // Provider-free base primitives — relocated to the smrt-ui leaf (#1589).
12
+ export { FormGroup, Input, Select, Textarea, Toggle, } from '@happyvertical/smrt-ui/forms';
4
13
  // SMRT-enhanced form components with voice support (v2.0 naming)
5
14
  export { default as AddressInput } from './AddressInput.svelte';
6
15
  export { default as CheckboxInput } from './CheckboxInput.svelte';
@@ -8,18 +17,12 @@ export { default as DateRangeInput } from './DateRangeInput.svelte';
8
17
  export { default as DateTimeInput } from './DateTimeInput.svelte';
9
18
  export { default as FileUpload } from './FileUpload.svelte';
10
19
  export { default as Form } from './Form.svelte';
11
- // Generic form components (migrated from @happyvertical/svelte)
12
- export { default as FormGroup } from './FormGroup.svelte';
13
20
  export { default as FormMicButton } from './FormMicButton.svelte';
14
- export { default as Input } from './Input.svelte';
15
21
  export { default as MeasurementInput } from './MeasurementInput.svelte';
16
22
  export { default as MoneyInput } from './MoneyInput.svelte';
17
23
  export { default as NumberInput } from './NumberInput.svelte';
18
24
  export { default as PhoneInput } from './PhoneInput.svelte';
19
25
  export { default as SearchInput } from './SearchInput.svelte';
20
- export { default as Select } from './Select.svelte';
21
26
  export { default as SelectInput } from './SelectInput.svelte';
22
- export { default as Textarea } from './Textarea.svelte';
23
27
  export { default as TextareaInput } from './TextareaInput.svelte';
24
28
  export { default as TextInput } from './TextInput.svelte';
25
- export { default as Toggle } from './Toggle.svelte';
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
3
+ import { Button } from '@happyvertical/smrt-ui/ui';
3
4
  import type { Snippet } from 'svelte';
4
5
  import { M } from '../../i18n/strings.workspace.js';
5
6
 
@@ -261,6 +262,7 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
261
262
  class:has-inspector-rail={hasInspectorRail}
262
263
  >
263
264
  <!-- Mobile sidebar backdrop -->
265
+ <!-- raw-primitive-allow: full-bleed click-catching navigation backdrop/scrim; a structural overlay surface, not a styled action button -->
264
266
  <button
265
267
  class="mobile-backdrop"
266
268
  type="button"
@@ -277,6 +279,7 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
277
279
  -->
278
280
  {#if hasInspector}
279
281
  {#if onCloseInspector}
282
+ <!-- raw-primitive-allow: full-bleed click-catching inspector backdrop/scrim; a structural overlay surface, not a styled action button -->
280
283
  <button
281
284
  class="inspector-backdrop"
282
285
  type="button"
@@ -311,9 +314,10 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
311
314
  </div>
312
315
 
313
316
  {#if collapsible && onToggleCollapsed}
314
- <button
317
+ <Button
318
+ variant="ghost"
319
+ size="sm"
315
320
  class="shell-toggle"
316
- type="button"
317
321
  onclick={handleCollapseToggle}
318
322
  aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
319
323
  aria-expanded={!collapsed}
@@ -321,7 +325,7 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
321
325
  <span class="shell-toggle-glyph" aria-hidden="true">
322
326
  {collapsed ? '›' : '‹'}
323
327
  </span>
324
- </button>
328
+ </Button>
325
329
  {/if}
326
330
  </div>
327
331
 
@@ -341,15 +345,16 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
341
345
  <div class="smrt-workspace-main">
342
346
  <header class="smrt-workspace-topbar">
343
347
  <div class="topbar-left">
344
- <button
348
+ <Button
349
+ variant="ghost"
350
+ size="sm"
345
351
  class="mobile-menu"
346
- type="button"
347
352
  onclick={toggleMobileNav}
348
353
  aria-label={mobileNavOpen ? 'Close navigation' : 'Open navigation'}
349
354
  aria-expanded={mobileNavOpen}
350
355
  >
351
356
  <span aria-hidden="true">≡</span>
352
- </button>
357
+ </Button>
353
358
  <div class="topbar-brand">
354
359
  {#if eyebrow}
355
360
  <div class="eyebrow topbar-eyebrow">{eyebrow}</div>
@@ -396,14 +401,15 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
396
401
  <div class="inspector-header">
397
402
  <span class="inspector-title">{inspectorTitle}</span>
398
403
  {#if onCloseInspector}
399
- <button
404
+ <Button
405
+ variant="ghost"
406
+ size="sm"
400
407
  class="inspector-close"
401
- type="button"
402
408
  onclick={handleInspectorClose}
403
409
  aria-label={t(M['ui.workspace_shell.close_inspector'])}
404
410
  >
405
411
  <span aria-hidden="true">×</span>
406
- </button>
412
+ </Button>
407
413
  {/if}
408
414
  </div>
409
415
  <div class="inspector-body">
@@ -518,8 +524,11 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
518
524
  color: var(--smrt-color-on-surface-variant, #6b7280);
519
525
  }
520
526
 
521
- .shell-toggle {
522
- appearance: none;
527
+ /* These shell-chrome controls now render through smrt-ui <Button>; pierce
528
+ Svelte scoping into the child <button> with `.smrt-workspace-shell
529
+ :global(.class)` (#1589). Button owns focus-visible, so those rules are
530
+ dropped. The responsive `display` toggles below are preserved. */
531
+ .smrt-workspace-shell :global(.shell-toggle) {
523
532
  border: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
524
533
  background: var(--smrt-color-surface-container, #f3f4f6);
525
534
  color: var(--smrt-color-on-surface, #111827);
@@ -529,22 +538,16 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
529
538
  display: inline-flex;
530
539
  align-items: center;
531
540
  justify-content: center;
532
- cursor: pointer;
533
541
  flex-shrink: 0;
534
542
  transition:
535
543
  background-color 150ms ease,
536
544
  color 150ms ease;
537
545
  }
538
546
 
539
- .shell-toggle:hover {
547
+ .smrt-workspace-shell :global(.shell-toggle):hover {
540
548
  background: var(--smrt-color-surface-container-high, #e5e7eb);
541
549
  }
542
550
 
543
- .shell-toggle:focus-visible {
544
- outline: 2px solid var(--smrt-color-primary, #2563eb);
545
- outline-offset: 2px;
546
- }
547
-
548
551
  .shell-toggle-glyph {
549
552
  font-size: var(--smrt-typography-body-large-size, 1rem);
550
553
  line-height: 1;
@@ -680,9 +683,8 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
680
683
  background: var(--smrt-color-warning, #f59e0b);
681
684
  }
682
685
 
683
- .mobile-menu {
686
+ .smrt-workspace-shell :global(.mobile-menu) {
684
687
  display: none;
685
- appearance: none;
686
688
  border: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
687
689
  background: var(--smrt-color-surface, #ffffff);
688
690
  color: var(--smrt-color-on-surface, #111827);
@@ -691,17 +693,10 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
691
693
  height: 2.35rem;
692
694
  align-items: center;
693
695
  justify-content: center;
694
- cursor: pointer;
695
696
  font-size: var(--smrt-typography-body-large-size, 1.1rem);
696
697
  line-height: 1;
697
698
  }
698
699
 
699
- .mobile-menu:focus-visible,
700
- .inspector-close:focus-visible {
701
- outline: 2px solid var(--smrt-color-primary, #2563eb);
702
- outline-offset: 2px;
703
- }
704
-
705
700
  /* ─── Stage / content / inspector ─────────────────────── */
706
701
 
707
702
  .smrt-workspace-stage {
@@ -743,8 +738,7 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
743
738
  font-size: var(--smrt-typography-title-medium-size, 0.95rem);
744
739
  }
745
740
 
746
- .inspector-close {
747
- appearance: none;
741
+ .smrt-workspace-shell :global(.inspector-close) {
748
742
  border: 1px solid transparent;
749
743
  background: transparent;
750
744
  color: var(--smrt-color-on-surface-variant, #6b7280);
@@ -756,13 +750,12 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
756
750
  justify-content: center;
757
751
  font-size: var(--smrt-typography-title-large-size, 1.25rem);
758
752
  line-height: 1;
759
- cursor: pointer;
760
753
  transition:
761
754
  background-color 150ms ease,
762
755
  color 150ms ease;
763
756
  }
764
757
 
765
- .inspector-close:hover {
758
+ .smrt-workspace-shell :global(.inspector-close):hover {
766
759
  background: var(--smrt-color-surface-container-high, #e5e7eb);
767
760
  color: var(--smrt-color-on-surface, #111827);
768
761
  }
@@ -851,7 +844,7 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
851
844
  justify-content: center;
852
845
  }
853
846
 
854
- .smrt-workspace-shell .shell-toggle {
847
+ .smrt-workspace-shell :global(.shell-toggle) {
855
848
  display: none;
856
849
  }
857
850
 
@@ -869,11 +862,11 @@ const sidebarInert = $derived(isMobileViewport && !mobileNavOpen);
869
862
  grid-template-columns: 1fr;
870
863
  }
871
864
 
872
- .mobile-menu {
865
+ .smrt-workspace-shell :global(.mobile-menu) {
873
866
  display: inline-flex;
874
867
  }
875
868
 
876
- .shell-toggle {
869
+ .smrt-workspace-shell :global(.shell-toggle) {
877
870
  display: none;
878
871
  }
879
872
 
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/WorkspaceShell.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,KAAK;IACpB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,UAAU,CAAC,EACP,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,WAAW,GACX,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAClB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,mEAAmE;IACnE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iDAAiD;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sCAAsC;IACtC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iCAAiC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wDAAwD;IACxD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAwQD,QAAA,MAAM,cAAc,wDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"WorkspaceShell.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/workspace/WorkspaceShell.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,MAAM,WAAW,KAAK;IACpB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,UAAU,CAAC,EACP,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,WAAW,GACX,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAClB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,mEAAmE;IACnE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iDAAiD;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sCAAsC;IACtC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iCAAiC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wDAAwD;IACxD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA2QD,QAAA,MAAM,cAAc,wDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -31,6 +31,7 @@
31
31
  import { onDestroy, onMount, tick } from 'svelte';
32
32
  import { M } from '../../../i18n/strings.workspace.js';
33
33
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
34
+ import { Button } from '@happyvertical/smrt-ui/ui';
34
35
  import type { ToolsDockContext } from '../types.js';
35
36
  import type { ToolsDockInstance } from './define-tools-dock.svelte.js';
36
37
 
@@ -159,6 +160,7 @@
159
160
  {@const def = toolDefById(tool.id)}
160
161
  {@const IconComponent = def?.iconComponent}
161
162
  {@const iconString = def?.icon}
163
+ <!-- raw-primitive-allow: dock tool-selector toggle (aria-pressed) with variant-dependent rail/topbar styling, part of the ToolsDock segmented control; not a standard action button -->
162
164
  <button
163
165
  type="button"
164
166
  class:active={isActive}
@@ -209,15 +211,16 @@
209
211
  >
210
212
  <header class="tools-dock__panel-header">
211
213
  <h3>{dock.activeTool ? labelFor(dock.activeTool) : 'Tools'}</h3>
212
- <button
213
- type="button"
214
+ <Button
215
+ variant="ghost"
216
+ size="sm"
214
217
  class="tools-dock__close"
215
218
  onclick={handleClose}
216
219
  aria-label={closeLabel}
217
220
  title={closeLabel}
218
221
  >
219
222
  ×
220
- </button>
223
+ </Button>
221
224
  </header>
222
225
 
223
226
  <div class="tools-dock__panel-body">
@@ -254,6 +257,7 @@
254
257
  {:else}
255
258
  <aside class="tools-dock tools-dock--rail" class:tools-dock--open={dock.isOpen}>
256
259
  {#if dock.isOpen}
260
+ <!-- raw-primitive-allow: click-catching overlay/backdrop that closes the dock; a structural full-bleed surface, not a styled action button -->
257
261
  <button
258
262
  type="button"
259
263
  class="tools-dock__overlay"
@@ -326,8 +330,7 @@
326
330
  }
327
331
 
328
332
  .tools-dock__rail-button:focus-visible,
329
- .tools-dock__topbar-button:focus-visible,
330
- .tools-dock__close:focus-visible {
333
+ .tools-dock__topbar-button:focus-visible {
331
334
  outline: 2px solid var(--smrt-color-primary, #7dd3fc);
332
335
  outline-offset: 2px;
333
336
  }
@@ -411,7 +414,9 @@
411
414
  overflow-y: auto;
412
415
  }
413
416
 
414
- .tools-dock__close {
417
+ /* The close control now renders through smrt-ui <Button>; pierce Svelte
418
+ scoping into the child-rendered <button> with `:global` (#1589). */
419
+ .tools-dock__panel-header :global(.tools-dock__close) {
415
420
  width: 2rem;
416
421
  height: 2rem;
417
422
  display: inline-grid;
@@ -420,7 +425,6 @@
420
425
  border-radius: 0.5rem;
421
426
  background: var(--smrt-color-surface-container-high, #1d2228);
422
427
  color: inherit;
423
- cursor: pointer;
424
428
  font-size: var(--smrt-typography-title-large-size, 1.2rem);
425
429
  line-height: 1;
426
430
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ToolsDock.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/tools-dock/ToolsDock.svelte.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGrE,UAAU,KAAK;IACb,mDAAmD;IACnD,IAAI,EAAE,iBAAiB,CAAC;IACxB,qFAAqF;IACrF,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuNH,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"ToolsDock.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/tools-dock/ToolsDock.svelte.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGrE,UAAU,KAAK;IACb,mDAAmD;IACnD,IAAI,EAAE,iBAAiB,CAAC;IACxB,qFAAqF;IACrF,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA0NH,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-svelte",
3
- "version": "0.34.5",
3
+ "version": "0.34.6",
4
4
  "description": "Svelte 5 components for SMRT user management - auth, users, tenants, roles, permissions, groups",
5
5
  "type": "module",
6
+ "smrtRawPrimitives": "strict-buttons",
6
7
  "main": "./dist/index.js",
7
8
  "types": "./dist/index.d.ts",
8
9
  "svelte": "./dist/index.js",
@@ -77,9 +78,9 @@
77
78
  "dependencies": {
78
79
  "@happyvertical/logger": "^0.74.7",
79
80
  "esm-env": "^1.2.2",
80
- "@happyvertical/smrt-languages": "0.34.5",
81
- "@happyvertical/smrt-types": "0.34.5",
82
- "@happyvertical/smrt-ui": "0.34.5"
81
+ "@happyvertical/smrt-languages": "0.34.6",
82
+ "@happyvertical/smrt-types": "0.34.6",
83
+ "@happyvertical/smrt-ui": "0.34.6"
83
84
  },
84
85
  "peerDependencies": {
85
86
  "@huggingface/transformers": ">=3.0.0",
@@ -1,86 +0,0 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
- import {
4
- type FormGroupContextValue,
5
- nextFieldId,
6
- setFormGroupContext,
7
- } from '../../state/form-group-context.js';
8
-
9
- export interface Props {
10
- label: string;
11
- id?: string;
12
- error?: string;
13
- hint?: string;
14
- required?: boolean;
15
- children: Snippet;
16
- }
17
-
18
- const { label, id, error, hint, required = false, children }: Props = $props();
19
-
20
- // Stable id so the label's `for` and the wrapped input's `id` agree even when
21
- // the consumer doesn't pass one.
22
- const fallbackId = nextFieldId();
23
- const fieldId = $derived(id ?? fallbackId);
24
- const hintId = $derived(hint && !error ? `${fieldId}-hint` : undefined);
25
- const errorId = $derived(error ? `${fieldId}-error` : undefined);
26
- const describedBy = $derived(
27
- [hintId, errorId].filter(Boolean).join(' ') || undefined,
28
- );
29
-
30
- // Publish the wiring a base input auto-applies (getter stays reactive as
31
- // hint/error change).
32
- setFormGroupContext(
33
- (): FormGroupContextValue => ({
34
- inputId: fieldId,
35
- describedBy,
36
- invalid: !!error,
37
- }),
38
- );
39
- </script>
40
-
41
- <div class="form-group">
42
- <label for={fieldId} class="form-label">
43
- {label}
44
- {#if required}
45
- <span class="required" aria-hidden="true">*</span>
46
- {/if}
47
- </label>
48
- {@render children()}
49
- {#if hintId}
50
- <p id={hintId} class="form-hint">{hint}</p>
51
- {/if}
52
- {#if errorId}
53
- <p id={errorId} class="form-error" role="alert">{error}</p>
54
- {/if}
55
- </div>
56
-
57
- <style>
58
- .form-group {
59
- margin-bottom: 1rem;
60
- }
61
-
62
- .form-label {
63
- display: block;
64
- font-size: var(--smrt-typography-label-large-size, 0.875rem);
65
- font-weight: var(--smrt-typography-weight-medium, 500);
66
- color: var(--smrt-color-on-surface, #374151);
67
- margin-bottom: 0.375rem;
68
- }
69
-
70
- .required {
71
- color: var(--smrt-color-error, #ba1a1a);
72
- margin-left: 0.125rem;
73
- }
74
-
75
- .form-hint {
76
- margin: 0.25rem 0 0;
77
- font-size: var(--smrt-typography-body-small-size, 0.75rem);
78
- color: var(--smrt-color-on-surface-variant, #6b7280);
79
- }
80
-
81
- .form-error {
82
- margin: 0.25rem 0 0;
83
- font-size: var(--smrt-typography-body-small-size, 0.75rem);
84
- color: var(--smrt-color-error, #ba1a1a);
85
- }
86
- </style>
@@ -1,13 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- export interface Props {
3
- label: string;
4
- id?: string;
5
- error?: string;
6
- hint?: string;
7
- required?: boolean;
8
- children: Snippet;
9
- }
10
- declare const FormGroup: import("svelte").Component<Props, {}, "">;
11
- type FormGroup = ReturnType<typeof FormGroup>;
12
- export default FormGroup;
13
- //# sourceMappingURL=FormGroup.svelte.d.ts.map