@happyvertical/smrt-ui 0.55.0 → 0.55.16

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 (84) hide show
  1. package/AGENTS.md +3 -1
  2. package/README.md +113 -5
  3. package/dist/components/forms/CodeSelect.svelte +12 -2
  4. package/dist/components/forms/CodeSelect.svelte.d.ts.map +1 -1
  5. package/dist/components/forms/Combobox.svelte +50 -7
  6. package/dist/components/forms/Combobox.svelte.d.ts +26 -0
  7. package/dist/components/forms/Combobox.svelte.d.ts.map +1 -1
  8. package/dist/components/forms/DictationButton.svelte +110 -3
  9. package/dist/components/forms/DictationButton.svelte.d.ts.map +1 -1
  10. package/dist/components/forms/DictationStatus.svelte +33 -5
  11. package/dist/components/forms/DictationStatus.svelte.d.ts +2 -0
  12. package/dist/components/forms/DictationStatus.svelte.d.ts.map +1 -1
  13. package/dist/components/forms/FieldLabel.svelte +44 -0
  14. package/dist/components/forms/FieldLabel.svelte.d.ts +20 -0
  15. package/dist/components/forms/FieldLabel.svelte.d.ts.map +1 -0
  16. package/dist/components/forms/FormGroup.svelte +2 -17
  17. package/dist/components/forms/FormGroup.svelte.d.ts.map +1 -1
  18. package/dist/components/forms/RelationInput.svelte +378 -0
  19. package/dist/components/forms/RelationInput.svelte.d.ts +75 -0
  20. package/dist/components/forms/RelationInput.svelte.d.ts.map +1 -0
  21. package/dist/components/forms/code-select-options.d.ts +8 -1
  22. package/dist/components/forms/code-select-options.d.ts.map +1 -1
  23. package/dist/components/forms/code-select-options.js +46 -5
  24. package/dist/components/forms/code-select-types.d.ts +4 -0
  25. package/dist/components/forms/code-select-types.d.ts.map +1 -1
  26. package/dist/components/forms/dictation.svelte.d.ts +84 -2
  27. package/dist/components/forms/dictation.svelte.d.ts.map +1 -1
  28. package/dist/components/forms/dictation.svelte.js +236 -2
  29. package/dist/components/forms/hands-free-capture.d.ts +70 -0
  30. package/dist/components/forms/hands-free-capture.d.ts.map +1 -0
  31. package/dist/components/forms/hands-free-capture.js +19 -0
  32. package/dist/components/forms/hands-free-vad.d.ts +5 -0
  33. package/dist/components/forms/hands-free-vad.d.ts.map +1 -0
  34. package/dist/components/forms/hands-free-vad.js +80 -0
  35. package/dist/components/forms/index.d.ts +4 -1
  36. package/dist/components/forms/index.d.ts.map +1 -1
  37. package/dist/components/forms/index.js +3 -0
  38. package/dist/components/forms/types.d.ts +9 -0
  39. package/dist/components/forms/types.d.ts.map +1 -1
  40. package/dist/components/layout/ActionGroup.svelte +55 -0
  41. package/dist/components/layout/ActionGroup.svelte.d.ts +18 -0
  42. package/dist/components/layout/ActionGroup.svelte.d.ts.map +1 -0
  43. package/dist/components/layout/Container.svelte +1 -0
  44. package/dist/components/layout/Grid.svelte +2 -1
  45. package/dist/components/layout/PageHeader.svelte +3 -3
  46. package/dist/components/layout/PageHeader.svelte.d.ts +3 -3
  47. package/dist/components/layout/PageLayout.svelte +61 -0
  48. package/dist/components/layout/PageLayout.svelte.d.ts +18 -0
  49. package/dist/components/layout/PageLayout.svelte.d.ts.map +1 -0
  50. package/dist/components/layout/index.d.ts +2 -0
  51. package/dist/components/layout/index.d.ts.map +1 -1
  52. package/dist/components/layout/index.js +2 -0
  53. package/dist/components/permissions/PermissionPicker.svelte +213 -0
  54. package/dist/components/permissions/PermissionPicker.svelte.d.ts +27 -0
  55. package/dist/components/permissions/PermissionPicker.svelte.d.ts.map +1 -0
  56. package/dist/currency.d.ts +3 -0
  57. package/dist/currency.d.ts.map +1 -0
  58. package/dist/currency.js +2 -0
  59. package/dist/i18n/strings.ui.d.ts +7 -0
  60. package/dist/i18n/strings.ui.d.ts.map +1 -1
  61. package/dist/i18n/strings.ui.js +7 -0
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +1 -0
  65. package/dist/svelte/playground/InteractiveControlsPreview.svelte +22 -0
  66. package/dist/svelte/playground/InteractiveControlsPreview.svelte.d.ts.map +1 -1
  67. package/dist/svelte/playground/PermissionPickerPreview.svelte +27 -0
  68. package/dist/svelte/playground/PermissionPickerPreview.svelte.d.ts +19 -0
  69. package/dist/svelte/playground/PermissionPickerPreview.svelte.d.ts.map +1 -0
  70. package/dist/svelte/playground.d.ts +14 -2
  71. package/dist/svelte/playground.d.ts.map +1 -1
  72. package/dist/svelte/playground.js +10 -0
  73. package/dist/themes/README.md +5 -0
  74. package/dist/themes/index.d.ts +1 -6
  75. package/dist/themes/index.d.ts.map +1 -1
  76. package/dist/themes/index.js +2 -8
  77. package/dist/themes/presets.d.ts +26 -0
  78. package/dist/themes/presets.d.ts.map +1 -0
  79. package/dist/themes/presets.js +22 -0
  80. package/dist/themes/styles/base.css +31 -0
  81. package/dist/themes/styles/index.d.ts +2 -0
  82. package/dist/themes/styles/index.d.ts.map +1 -1
  83. package/dist/themes/styles/index.js +2 -0
  84. package/package.json +22 -2
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The microphone side of hands-free dictation, as an interface.
3
+ *
4
+ * `Dictation` in `mode: 'hands-free'` opens the microphone once and cuts it
5
+ * into utterances on the device (voice activity detection, no audio leaves
6
+ * the page): each pause hands over one 16 kHz mono utterance, which the speech
7
+ * source writes down while the next is still being spoken. A
8
+ * `HandsFreeCaptureFactory` supplies that microphone. The one that ships is
9
+ * `createHandsFreeCapture` in `@happyvertical/smrt-ui/forms/hands-free`, built
10
+ * on `@happyvertical/speech/browser`'s `createVadCapture`; it lives in its own
11
+ * entry so only apps that opt in bundle the optional peer.
12
+ */
13
+ /** Whether this browser can open a microphone and tap it with Web Audio. */
14
+ export function canCaptureHandsFree() {
15
+ return (typeof navigator !== 'undefined' &&
16
+ typeof navigator.mediaDevices?.getUserMedia === 'function' &&
17
+ typeof AudioContext !== 'undefined' &&
18
+ typeof AudioWorkletNode !== 'undefined');
19
+ }
@@ -0,0 +1,5 @@
1
+ import type { HandsFreeCaptureFactory } from './hands-free-capture.js';
2
+ export type { HandsFreeCapture, HandsFreeCaptureFactory, HandsFreeCaptureOptions, HandsFreeUtterance, HandsFreeVadOptions, } from './hands-free-capture.js';
3
+ /** Hands-free capture on the speech package's `createVadCapture`. */
4
+ export declare const createHandsFreeCapture: HandsFreeCaptureFactory;
5
+ //# sourceMappingURL=hands-free-vad.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hands-free-vad.d.ts","sourceRoot":"","sources":["../../../src/components/forms/hands-free-vad.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAEV,uBAAuB,EAExB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AAEjC,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,EAAE,uBAiEpC,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Hands-free microphone capture on `@happyvertical/speech/browser`.
3
+ *
4
+ * `createHandsFreeCapture` opens the microphone and runs it through the
5
+ * speech package's on-device voice activity detector (`createVadCapture`):
6
+ * an adaptive noise floor, a pause that ends each utterance, a pre-roll so
7
+ * the first syllable is not clipped, and a length cap that splits long
8
+ * speech. Each utterance arrives as 16 kHz mono PCM. The audio stays in
9
+ * memory; `stop()` / `cancel()` release the microphone.
10
+ *
11
+ * This is the one module in smrt-ui that imports the optional peer
12
+ * `@happyvertical/speech`, so it has its own entry
13
+ * (`@happyvertical/smrt-ui/forms/hands-free`) and only apps that import it
14
+ * bundle the peer:
15
+ *
16
+ * ```ts
17
+ * import { createHandsFreeCapture } from '@happyvertical/smrt-ui/forms/hands-free';
18
+ * new Dictation({ source, mode: 'hands-free', handsFreeCapture: createHandsFreeCapture, onText });
19
+ * ```
20
+ */
21
+ import { createVadCapture, } from '@happyvertical/speech/browser';
22
+ /** Hands-free capture on the speech package's `createVadCapture`. */
23
+ export const createHandsFreeCapture = (options) => {
24
+ let vad = null;
25
+ let cancelled = false;
26
+ let stopped = false;
27
+ // Wanted before the microphone finished opening.
28
+ let suspendWanted = false;
29
+ return {
30
+ async start() {
31
+ const opened = await createVadCapture({
32
+ ...options.vad,
33
+ ...(options.constraints ? { constraints: options.constraints } : {}),
34
+ });
35
+ if (cancelled || stopped) {
36
+ opened.cancel();
37
+ return;
38
+ }
39
+ vad = opened;
40
+ if (suspendWanted)
41
+ opened.suspend();
42
+ opened.on('speechstart', () => options.onSpeaking?.(true));
43
+ opened.on('level', ({ level }) => options.onLevel?.(level));
44
+ opened.on('speechend', (event) => {
45
+ options.onSpeaking?.(false);
46
+ options.onUtterance({
47
+ pcm: event.samples,
48
+ sampleRate: event.sampleRate,
49
+ durationMs: event.durationMs,
50
+ reason: event.reason,
51
+ });
52
+ });
53
+ },
54
+ suspend() {
55
+ suspendWanted = true;
56
+ vad?.suspend();
57
+ // A discarded utterance never ends with a `speechend`.
58
+ options.onSpeaking?.(false);
59
+ },
60
+ resume() {
61
+ suspendWanted = false;
62
+ vad?.resume();
63
+ },
64
+ stop() {
65
+ stopped = true;
66
+ const current = vad;
67
+ vad = null;
68
+ // `stop()` delivers the utterance in progress synchronously, then
69
+ // releases the microphone.
70
+ void current?.stop().catch((error) => {
71
+ options.onError?.(error instanceof Error ? error : new Error(String(error)));
72
+ });
73
+ },
74
+ cancel() {
75
+ cancelled = true;
76
+ vad?.cancel();
77
+ vad = null;
78
+ },
79
+ };
80
+ };
@@ -29,6 +29,7 @@ export { default as DictationStatus } from './DictationStatus.svelte';
29
29
  export { classifyDictationError, Dictation, type DictationErrorKind, type DictationLogEvent, type DictationOptions, type DictationSourceProvider, type DictationSpeechResult, type DictationSpeechSource, type DictationStartOptions, type DictationState, dictationErrorCode, } from './dictation.svelte.js';
30
30
  export { createHttpTranscriber, type DictationTranscribe, type DictationTranscribeOptions, type HttpTranscriberOptions, } from './dictation-transcribe.js';
31
31
  export { default as ErrorSummary } from './ErrorSummary.svelte';
32
+ export { default as FieldLabel } from './FieldLabel.svelte';
32
33
  export { default as Fieldset } from './Fieldset.svelte';
33
34
  export { default as FilePicker } from './FilePicker.svelte';
34
35
  export { default as Form } from './Form.svelte';
@@ -36,6 +37,7 @@ export { default as FormActionBar } from './FormActionBar.svelte';
36
37
  export { default as Field, default as FormGroup } from './FormGroup.svelte';
37
38
  export { type FormGroupContextValue, nextFieldId, setFormGroupContext, tryGetFormGroupContext, } from './form-group-context.js';
38
39
  export * from './form-retry/index.js';
40
+ export { canCaptureHandsFree, type HandsFreeCapture, type HandsFreeCaptureFactory, type HandsFreeCaptureOptions, type HandsFreeUtterance, type HandsFreeVadOptions, } from './hands-free-capture.js';
39
41
  export { default as Input } from './Input.svelte';
40
42
  export { default as InputGroup } from './InputGroup.svelte';
41
43
  export { insertTextAtCursor } from './insert-text.js';
@@ -47,6 +49,7 @@ export { default as ProvinceSelect } from './ProvinceSelect.svelte';
47
49
  export { default as Radio } from './Radio.svelte';
48
50
  export { default as RadioGroup } from './RadioGroup.svelte';
49
51
  export { default as RangeSlider } from './RangeSlider.svelte';
52
+ export { default as RelationInput } from './RelationInput.svelte';
50
53
  export { playReadyBeep, primeReadyBeep, type ReadyBeepOptions, } from './ready-beep.js';
51
54
  export { default as SearchInput } from './SearchInput.svelte';
52
55
  export { default as SegmentedControl } from './SegmentedControl.svelte';
@@ -62,6 +65,6 @@ export { default as Textarea } from './Textarea.svelte';
62
65
  export { default as TimePicker } from './TimePicker.svelte';
63
66
  export { default as Toggle } from './Toggle.svelte';
64
67
  export { default as ToggleButton } from './ToggleButton.svelte';
65
- export type { CameraCaptureLabels, CameraCaptureState, CaptureResult, FormError, RangeSliderValue, SegmentedControlOption, SignaturePadLabels, SignaturePadState, } from './types.js';
68
+ export type { CameraCaptureLabels, CameraCaptureState, CaptureResult, FormError, RangeSliderValue, RelationOption, SegmentedControlOption, SignaturePadLabels, SignaturePadState, } from './types.js';
66
69
  export { type ControlRegistrationDescriptor, useControlRegistration, } from './use-control-registration.svelte.js';
67
70
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/forms/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/forms/index.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,7 @@ export { default as DictationStatus } from './DictationStatus.svelte';
29
29
  export { classifyDictationError, Dictation, dictationErrorCode, } from './dictation.svelte.js';
30
30
  export { createHttpTranscriber, } from './dictation-transcribe.js';
31
31
  export { default as ErrorSummary } from './ErrorSummary.svelte';
32
+ export { default as FieldLabel } from './FieldLabel.svelte';
32
33
  export { default as Fieldset } from './Fieldset.svelte';
33
34
  export { default as FilePicker } from './FilePicker.svelte';
34
35
  export { default as Form } from './Form.svelte';
@@ -37,6 +38,7 @@ export { default as Field, default as FormGroup } from './FormGroup.svelte';
37
38
  export { nextFieldId, setFormGroupContext, tryGetFormGroupContext, } from './form-group-context.js';
38
39
  // Form retry (#3291): also published Svelte-free at `@happyvertical/smrt-ui/form-retry`.
39
40
  export * from './form-retry/index.js';
41
+ export { canCaptureHandsFree, } from './hands-free-capture.js';
40
42
  export { default as Input } from './Input.svelte';
41
43
  export { default as InputGroup } from './InputGroup.svelte';
42
44
  export { insertTextAtCursor } from './insert-text.js';
@@ -48,6 +50,7 @@ export { default as ProvinceSelect } from './ProvinceSelect.svelte';
48
50
  export { default as Radio } from './Radio.svelte';
49
51
  export { default as RadioGroup } from './RadioGroup.svelte';
50
52
  export { default as RangeSlider } from './RangeSlider.svelte';
53
+ export { default as RelationInput } from './RelationInput.svelte';
51
54
  export { playReadyBeep, primeReadyBeep, } from './ready-beep.js';
52
55
  export { default as SearchInput } from './SearchInput.svelte';
53
56
  export { default as SegmentedControl } from './SegmentedControl.svelte';
@@ -52,4 +52,13 @@ export interface SignaturePadLabels {
52
52
  useSignature: string;
53
53
  committed: string;
54
54
  }
55
+ /** A searchable relation target for the RelationInput component */
56
+ export interface RelationOption {
57
+ /** Record id; this is the value the form posts. */
58
+ id: string;
59
+ /** Human-readable name shown in the field and the list. */
60
+ label: string;
61
+ /** Secondary text shown under the label in the list. */
62
+ detail?: string;
63
+ }
55
64
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/forms/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,IAAI,EAAE,IAAI,CAAC;IACX,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,iFAAiF;AACjF,MAAM,MAAM,kBAAkB,GAC1B,KAAK,GACL,UAAU,GACV,WAAW,GACX,WAAW,GACX,WAAW,GACX,mBAAmB,GACnB,WAAW,GACX,aAAa,GACb,OAAO,GACP,UAAU,CAAC;AAEf,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/forms/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mEAAmE;AACnE,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,IAAI,EAAE,IAAI,CAAC;IACX,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,iFAAiF;AACjF,MAAM,MAAM,kBAAkB,GAC1B,KAAK,GACL,UAAU,GACV,WAAW,GACX,WAAW,GACX,WAAW,GACX,mBAAmB,GACnB,WAAW,GACX,aAAa,GACb,OAAO,GACP,UAAU,CAAC;AAEf,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,mEAAmE;AACnE,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+
5
+ type Gap = 'sm' | 'md';
6
+ type Justify = 'start' | 'end';
7
+
8
+ export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'class'> {
9
+ /** Space between actions. */
10
+ gap?: Gap;
11
+ /** Horizontal alignment when the row has spare space. */
12
+ justify?: Justify;
13
+ /** CSS classes appended to the action group. */
14
+ class?: string;
15
+ /** Buttons, button links, or other compact actions. */
16
+ children: Snippet;
17
+ }
18
+
19
+ const {
20
+ gap = 'sm',
21
+ justify = 'start',
22
+ class: className = '',
23
+ children,
24
+ ...rest
25
+ }: Props = $props();
26
+ </script>
27
+
28
+ <div class="action-group gap-{gap} justify-{justify} {className}" {...rest}>
29
+ {@render children()}
30
+ </div>
31
+
32
+ <style>
33
+ .action-group {
34
+ display: flex;
35
+ flex-wrap: wrap;
36
+ align-items: center;
37
+ min-inline-size: 0;
38
+ }
39
+
40
+ .gap-sm {
41
+ gap: var(--smrt-spacing-2);
42
+ }
43
+
44
+ .gap-md {
45
+ gap: var(--smrt-spacing-3);
46
+ }
47
+
48
+ .justify-start {
49
+ justify-content: flex-start;
50
+ }
51
+
52
+ .justify-end {
53
+ justify-content: flex-end;
54
+ }
55
+ </style>
@@ -0,0 +1,18 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Gap = 'sm' | 'md';
4
+ type Justify = 'start' | 'end';
5
+ export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'class'> {
6
+ /** Space between actions. */
7
+ gap?: Gap;
8
+ /** Horizontal alignment when the row has spare space. */
9
+ justify?: Justify;
10
+ /** CSS classes appended to the action group. */
11
+ class?: string;
12
+ /** Buttons, button links, or other compact actions. */
13
+ children: Snippet;
14
+ }
15
+ declare const ActionGroup: import("svelte").Component<Props, {}, "">;
16
+ type ActionGroup = ReturnType<typeof ActionGroup>;
17
+ export default ActionGroup;
18
+ //# sourceMappingURL=ActionGroup.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionGroup.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/layout/ActionGroup.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,KAAK,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AACvB,KAAK,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAE/B,MAAM,WAAW,KAAM,SAAQ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAC1E,6BAA6B;IAC7B,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAyBD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -20,6 +20,7 @@ const { maxWidth = 'lg', children, ...rest }: Props = $props();
20
20
 
21
21
  <style>
22
22
  .container {
23
+ box-sizing: border-box;
23
24
  width: 100%;
24
25
  margin: 0 auto;
25
26
  padding-left: var(--smrt-spacing-4);
@@ -74,7 +74,7 @@ const isResponsive = $derived(
74
74
  const _gridColumns = $derived.by(() => {
75
75
  if (isResponsive) return undefined;
76
76
  if (columns === 'auto') {
77
- return 'repeat(auto-fill, minmax(300px, 1fr))';
77
+ return 'repeat(auto-fill, minmax(min(300px, 100%), 1fr))';
78
78
  }
79
79
  return `repeat(${columns}, 1fr)`;
80
80
  });
@@ -158,6 +158,7 @@ const gridClasses = $derived.by(() => {
158
158
  <style>
159
159
  .grid {
160
160
  display: grid;
161
+ min-width: 0;
161
162
  }
162
163
 
163
164
  .grid-header {
@@ -11,9 +11,9 @@
11
11
  * title (for its phone top bar). smrt-svelte's `shellPageTrailFor()`
12
12
  * computes such a trail from a nav.
13
13
  * - The crumb row carries `data-shell-breadcrumbs` and the title
14
- * `data-shell-page-title`: on phones AdminShell hides the crumbs and
15
- * visually hides the title, because its phone top bar shows the back arrow
16
- * and the title instead.
14
+ * `data-shell-page-title`: on phones AdminShell hides crumbs only when its
15
+ * top bar declares `data-shell-page-navigation-replacement`, and visually
16
+ * hides the title only with `data-shell-page-title-replacement`.
17
17
  * - No in-page back link: the crumbs (and the phone top bar) are the way
18
18
  * back. `backHref` is kept only for pages outside such a shell.
19
19
  * - An editable title (`titleField`, e.g. an article's headline) renders
@@ -10,9 +10,9 @@
10
10
  * title (for its phone top bar). smrt-svelte's `shellPageTrailFor()`
11
11
  * computes such a trail from a nav.
12
12
  * - The crumb row carries `data-shell-breadcrumbs` and the title
13
- * `data-shell-page-title`: on phones AdminShell hides the crumbs and
14
- * visually hides the title, because its phone top bar shows the back arrow
15
- * and the title instead.
13
+ * `data-shell-page-title`: on phones AdminShell hides crumbs only when its
14
+ * top bar declares `data-shell-page-navigation-replacement`, and visually
15
+ * hides the title only with `data-shell-page-title-replacement`.
16
16
  * - No in-page back link: the crumbs (and the phone top bar) are the way
17
17
  * back. `backHref` is kept only for pages outside such a shell.
18
18
  * - An editable title (`titleField`, e.g. an article's headline) renders
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import Container from './Container.svelte';
5
+
6
+ type MaxWidth = 'sm' | 'md' | 'lg' | 'xl' | 'full';
7
+ type Gap = 'sm' | 'md' | 'lg';
8
+
9
+ export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'class'> {
10
+ /** Maximum width of the page content. */
11
+ maxWidth?: MaxWidth;
12
+ /** Vertical space between the page's direct children. */
13
+ gap?: Gap;
14
+ /** CSS classes appended to the page content element. */
15
+ class?: string;
16
+ /** Page content. */
17
+ children: Snippet;
18
+ }
19
+
20
+ const {
21
+ maxWidth = 'lg',
22
+ gap = 'md',
23
+ class: className = '',
24
+ children,
25
+ ...rest
26
+ }: Props = $props();
27
+ </script>
28
+
29
+ <Container {maxWidth} data-page-layout-container>
30
+ <div class="page-layout gap-{gap} {className}" data-page-layout {...rest}>
31
+ {@render children()}
32
+ </div>
33
+ </Container>
34
+
35
+ <style>
36
+ .page-layout {
37
+ display: grid;
38
+ grid-template-columns: minmax(0, 1fr);
39
+ min-inline-size: 0;
40
+ padding-block: var(--smrt-spacing-5) var(--smrt-spacing-8);
41
+ overflow-wrap: anywhere;
42
+ }
43
+
44
+ .gap-sm {
45
+ gap: var(--smrt-spacing-3);
46
+ }
47
+
48
+ .gap-md {
49
+ gap: var(--smrt-spacing-5);
50
+ }
51
+
52
+ .gap-lg {
53
+ gap: var(--smrt-spacing-8);
54
+ }
55
+
56
+ @media (min-width: 640px) {
57
+ .page-layout {
58
+ padding-block: var(--smrt-spacing-6) var(--smrt-spacing-10);
59
+ }
60
+ }
61
+ </style>
@@ -0,0 +1,18 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type MaxWidth = 'sm' | 'md' | 'lg' | 'xl' | 'full';
4
+ type Gap = 'sm' | 'md' | 'lg';
5
+ export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'class'> {
6
+ /** Maximum width of the page content. */
7
+ maxWidth?: MaxWidth;
8
+ /** Vertical space between the page's direct children. */
9
+ gap?: Gap;
10
+ /** CSS classes appended to the page content element. */
11
+ class?: string;
12
+ /** Page content. */
13
+ children: Snippet;
14
+ }
15
+ declare const PageLayout: import("svelte").Component<Props, {}, "">;
16
+ type PageLayout = ReturnType<typeof PageLayout>;
17
+ export default PageLayout;
18
+ //# sourceMappingURL=PageLayout.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageLayout.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/layout/PageLayout.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAItD,KAAK,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AACnD,KAAK,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE9B,MAAM,WAAW,KAAM,SAAQ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAC1E,yCAAyC;IACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,yDAAyD;IACzD,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AA4BD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Layout components - Page structure and containers
3
3
  */
4
+ export { default as ActionGroup } from './ActionGroup.svelte';
4
5
  export { default as Container } from './Container.svelte';
5
6
  export { default as EmptyState } from './EmptyState.svelte';
6
7
  export { default as Footer } from './Footer.svelte';
@@ -8,6 +9,7 @@ export { default as Grid } from './Grid.svelte';
8
9
  export { default as Header } from './Header.svelte';
9
10
  export { default as Masthead } from './Masthead.svelte';
10
11
  export { default as PageHeader } from './PageHeader.svelte';
12
+ export { default as PageLayout } from './PageLayout.svelte';
11
13
  export { getPageHeaderContext, type PageHeaderContext, type PageHeaderCrumb, type PageHeaderReport, setPageHeaderContext, } from './page-header-context.js';
12
14
  export { default as SummaryCard } from './SummaryCard.svelte';
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layout/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/layout/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,oBAAoB,GACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Layout components - Page structure and containers
3
3
  */
4
+ export { default as ActionGroup } from './ActionGroup.svelte';
4
5
  export { default as Container } from './Container.svelte';
5
6
  export { default as EmptyState } from './EmptyState.svelte';
6
7
  export { default as Footer } from './Footer.svelte';
@@ -8,5 +9,6 @@ export { default as Grid } from './Grid.svelte';
8
9
  export { default as Header } from './Header.svelte';
9
10
  export { default as Masthead } from './Masthead.svelte';
10
11
  export { default as PageHeader } from './PageHeader.svelte';
12
+ export { default as PageLayout } from './PageLayout.svelte';
11
13
  export { getPageHeaderContext, setPageHeaderContext, } from './page-header-context.js';
12
14
  export { default as SummaryCard } from './SummaryCard.svelte';