@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,213 @@
1
+ <script lang="ts">
2
+ import Checkbox from '../forms/Checkbox.svelte';
3
+ import Input from '../forms/Input.svelte';
4
+
5
+ export interface PermissionPickerItem {
6
+ id?: string;
7
+ slug: string;
8
+ name?: string;
9
+ description?: string;
10
+ category?: string;
11
+ }
12
+
13
+ export interface Props {
14
+ /** Permission catalog the host has authorized this actor to assign. */
15
+ permissions: readonly PermissionPickerItem[];
16
+ /** Permission slugs checked on first render or a server-validation retry. */
17
+ selected?: readonly string[];
18
+ /** Repeated native form field name. */
19
+ name?: string;
20
+ /** Visible label for the catalog. */
21
+ label?: string;
22
+ /** Supporting text below the label. */
23
+ description?: string;
24
+ /** Accessible label and placeholder for the progressive search. */
25
+ searchLabel?: string;
26
+ /** Prevents changes and native form submission while retaining readable state. */
27
+ disabled?: boolean;
28
+ }
29
+
30
+ interface PermissionGroup {
31
+ id: string;
32
+ label: string;
33
+ items: readonly PermissionPickerItem[];
34
+ }
35
+
36
+ let {
37
+ permissions,
38
+ selected = [],
39
+ name = 'permission',
40
+ label = 'Permissions',
41
+ description,
42
+ searchLabel = 'Search permissions',
43
+ disabled = false,
44
+ }: Props = $props();
45
+
46
+ let query = $state('');
47
+ let localSelection = $state.raw<{
48
+ source: readonly string[];
49
+ slugs: Set<string>;
50
+ } | null>(null);
51
+ const instanceId = $props.id();
52
+ const labelId = `permission-picker-label-${instanceId}`;
53
+ const selectedSlugs = $derived(new Set(selected));
54
+ const currentSelectedSlugs = $derived(
55
+ localSelection?.source === selected ? localSelection.slugs : selectedSlugs,
56
+ );
57
+ const normalizedQuery = $derived(normalize(query));
58
+ const groups = $derived(groupPermissions(permissions));
59
+ const visibleCount = $derived(
60
+ groups.reduce(
61
+ (count, group) =>
62
+ count +
63
+ group.items.filter((permission) => matches(permission, group.label))
64
+ .length,
65
+ 0,
66
+ ),
67
+ );
68
+
69
+ function updateSelection(slug: string, checked: boolean): void {
70
+ const next = new Set(currentSelectedSlugs);
71
+ if (checked) next.add(slug);
72
+ else next.delete(slug);
73
+ localSelection = { source: selected, slugs: next };
74
+ }
75
+
76
+ function normalize(value: string): string {
77
+ return value.trim().replace(/\s+/g, ' ').toLocaleLowerCase();
78
+ }
79
+
80
+ function words(value: string): string {
81
+ const spaced = value
82
+ .replace(/[._-]+/g, ' ')
83
+ .replace(/([a-z])([A-Z])/g, '$1 $2');
84
+ return spaced
85
+ ? spaced.charAt(0).toLocaleUpperCase() + spaced.slice(1)
86
+ : 'Other';
87
+ }
88
+
89
+ function categoryOf(permission: PermissionPickerItem): string {
90
+ const category = permission.category?.trim();
91
+ if (category) return category;
92
+ return words(permission.slug.split('.')[0] ?? '');
93
+ }
94
+
95
+ function groupPermissions(
96
+ catalog: readonly PermissionPickerItem[],
97
+ ): PermissionGroup[] {
98
+ const byCategory = new Map<string, PermissionPickerItem[]>();
99
+ for (const permission of catalog) {
100
+ const category = categoryOf(permission);
101
+ const group = byCategory.get(category) ?? [];
102
+ group.push(permission);
103
+ byCategory.set(category, group);
104
+ }
105
+ return [...byCategory.entries()]
106
+ .sort(([left], [right]) => left.localeCompare(right))
107
+ .map(([category, items], index) => ({
108
+ id: `permission-group-${index}`,
109
+ label: category,
110
+ items: [...items].sort((left, right) =>
111
+ left.slug.localeCompare(right.slug),
112
+ ),
113
+ }));
114
+ }
115
+
116
+ function displayName(permission: PermissionPickerItem): string {
117
+ return permission.name?.trim() || words(permission.slug);
118
+ }
119
+
120
+ function matches(permission: PermissionPickerItem, category: string): boolean {
121
+ if (!normalizedQuery) return true;
122
+ return normalize(
123
+ [
124
+ displayName(permission),
125
+ permission.slug,
126
+ permission.description ?? '',
127
+ category,
128
+ ].join(' '),
129
+ ).includes(normalizedQuery);
130
+ }
131
+ </script>
132
+
133
+ <section class="permission-picker" aria-labelledby={labelId}>
134
+ <div class="heading">
135
+ <div>
136
+ <h2 id={labelId}>{label}</h2>
137
+ {#if description}<p>{description}</p>{/if}
138
+ </div>
139
+ <label class="search">
140
+ <span>{searchLabel}</span>
141
+ <Input
142
+ type="search"
143
+ value={query}
144
+ oninput={(event) => (query = event.currentTarget.value)}
145
+ placeholder={searchLabel}
146
+ autocomplete="off"
147
+ />
148
+ </label>
149
+ </div>
150
+
151
+ {#key selected}
152
+ <fieldset {disabled}>
153
+ <legend class="visually-hidden">{label}</legend>
154
+ <div class="groups">
155
+ {#each groups as group (group.label)}
156
+ {@const groupVisible = group.items.some((permission) => matches(permission, group.label))}
157
+ {@const selectedCount = group.items.filter((permission) => currentSelectedSlugs.has(permission.slug)).length}
158
+ <details class="group" open={normalizedQuery ? groupVisible : undefined} hidden={!groupVisible}>
159
+ <summary id={group.id}>
160
+ <span>{group.label}</span>
161
+ <span class="selected-count">{selectedCount} selected</span>
162
+ </summary>
163
+ <div class="choices">
164
+ {#each group.items as permission (permission.id ?? permission.slug)}
165
+ <div class="choice" hidden={!matches(permission, group.label)}>
166
+ <Checkbox
167
+ {name}
168
+ value={permission.slug}
169
+ checked={selectedSlugs.has(permission.slug)}
170
+ onchange={(event) => updateSelection(permission.slug, event.currentTarget.checked)}
171
+ label={displayName(permission)}
172
+ {disabled}
173
+ />
174
+ <code>{permission.slug}</code>
175
+ {#if permission.description}<p>{permission.description}</p>{/if}
176
+ </div>
177
+ {/each}
178
+ </div>
179
+ </details>
180
+ {/each}
181
+ </div>
182
+ </fieldset>
183
+ {/key}
184
+
185
+ {#if normalizedQuery && visibleCount === 0}
186
+ <p class="no-results" role="status">No permissions match “{query.trim()}”.</p>
187
+ {/if}
188
+ </section>
189
+
190
+ <style>
191
+ .permission-picker { display: grid; gap: var(--smrt-spacing-4); min-inline-size: 0; }
192
+ .heading { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: var(--smrt-spacing-4); }
193
+ h2, p { margin: 0; }
194
+ h2 { color: var(--smrt-color-on-surface); font: var(--smrt-typography-title-large-font); }
195
+ .heading p, .choice p, code, .no-results { color: var(--smrt-color-on-surface-variant); font: var(--smrt-typography-body-small-font); }
196
+ .heading p { margin-block-start: var(--smrt-spacing-1); }
197
+ .search { display: grid; flex: 1 1 16rem; max-inline-size: 28rem; gap: var(--smrt-spacing-1); color: var(--smrt-color-on-surface); font: var(--smrt-typography-label-medium-font); }
198
+ fieldset { min-inline-size: 0; margin: 0; padding: 0; border: 0; }
199
+ .groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr)); gap: var(--smrt-spacing-4); align-items: start; }
200
+ .group { min-inline-size: 0; border: 1px solid var(--smrt-color-outline-variant); border-radius: var(--smrt-radius-medium); background: var(--smrt-color-surface); }
201
+ summary { display: flex; min-block-size: 2.75rem; align-items: center; justify-content: space-between; gap: var(--smrt-spacing-3); padding: var(--smrt-spacing-3) var(--smrt-spacing-4); color: var(--smrt-color-on-surface); font: var(--smrt-typography-title-medium-font); cursor: pointer; }
202
+ summary:focus-visible { outline: 2px solid var(--smrt-color-primary); outline-offset: 2px; }
203
+ .selected-count { flex: 0 0 auto; color: var(--smrt-color-on-surface-variant); font: var(--smrt-typography-label-medium-font); }
204
+ .choices { display: grid; gap: var(--smrt-spacing-4); padding: 0 var(--smrt-spacing-4) var(--smrt-spacing-4); border-block-start: 1px solid var(--smrt-color-outline-variant); padding-block-start: var(--smrt-spacing-4); }
205
+ .choice { display: grid; min-inline-size: 0; gap: var(--smrt-spacing-1); }
206
+ .choice :global(.checkbox) { min-inline-size: 0; }
207
+ .choice :global(.checkbox__label), code, .choice p { overflow-wrap: anywhere; }
208
+ code { padding-inline-start: calc(1.125rem + var(--smrt-spacing-2)); }
209
+ .choice p { padding-inline-start: calc(1.125rem + var(--smrt-spacing-2)); }
210
+ .no-results { padding: var(--smrt-spacing-4); border-radius: var(--smrt-radius-medium); background: var(--smrt-color-surface-container-low); }
211
+ .visually-hidden { position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
212
+ [hidden] { display: none; }
213
+ </style>
@@ -0,0 +1,27 @@
1
+ export interface PermissionPickerItem {
2
+ id?: string;
3
+ slug: string;
4
+ name?: string;
5
+ description?: string;
6
+ category?: string;
7
+ }
8
+ export interface Props {
9
+ /** Permission catalog the host has authorized this actor to assign. */
10
+ permissions: readonly PermissionPickerItem[];
11
+ /** Permission slugs checked on first render or a server-validation retry. */
12
+ selected?: readonly string[];
13
+ /** Repeated native form field name. */
14
+ name?: string;
15
+ /** Visible label for the catalog. */
16
+ label?: string;
17
+ /** Supporting text below the label. */
18
+ description?: string;
19
+ /** Accessible label and placeholder for the progressive search. */
20
+ searchLabel?: string;
21
+ /** Prevents changes and native form submission while retaining readable state. */
22
+ disabled?: boolean;
23
+ }
24
+ declare const PermissionPicker: import("svelte").Component<Props, {}, "">;
25
+ type PermissionPicker = ReturnType<typeof PermissionPicker>;
26
+ export default PermissionPicker;
27
+ //# sourceMappingURL=PermissionPicker.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionPicker.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/permissions/PermissionPicker.svelte.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,uEAAuE;IACvE,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC7C,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA+JD,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** ISO 4217 currency metadata shared by domain packages and UI components. */
2
+ export { ISO_4217_MINOR_UNITS } from './components/display/currency-metadata.js';
3
+ //# sourceMappingURL=currency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currency.d.ts","sourceRoot":"","sources":["../src/currency.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** ISO 4217 currency metadata shared by domain packages and UI components. */
2
+ export { ISO_4217_MINOR_UNITS } from './components/display/currency-metadata.js';
@@ -44,7 +44,13 @@ export declare const M: {
44
44
  readonly 'ui.form_action_bar.label': "ui.form_action_bar.label";
45
45
  readonly 'ui.dictation.start': "ui.dictation.start";
46
46
  readonly 'ui.dictation.start_hint': "ui.dictation.start_hint";
47
+ readonly 'ui.dictation.start_hands_free': "ui.dictation.start_hands_free";
47
48
  readonly 'ui.dictation.stop': "ui.dictation.stop";
49
+ readonly 'ui.dictation.listening_hands_free': "ui.dictation.listening_hands_free";
50
+ readonly 'ui.dictation.listening_short': "ui.dictation.listening_short";
51
+ readonly 'ui.dictation.hearing': "ui.dictation.hearing";
52
+ readonly 'ui.dictation.sending': "ui.dictation.sending";
53
+ readonly 'ui.dictation.paused_speaking': "ui.dictation.paused_speaking";
48
54
  readonly 'ui.dictation.starting': "ui.dictation.starting";
49
55
  readonly 'ui.dictation.listening': "ui.dictation.listening";
50
56
  readonly 'ui.dictation.unsupported': "ui.dictation.unsupported";
@@ -57,6 +63,7 @@ export declare const M: {
57
63
  readonly 'ui.dictation.too_long': "ui.dictation.too_long";
58
64
  readonly 'ui.dictation.not_transcribed': "ui.dictation.not_transcribed";
59
65
  readonly 'ui.dictation.unavailable': "ui.dictation.unavailable";
66
+ readonly 'ui.dictation.model_missing': "ui.dictation.model_missing";
60
67
  readonly 'ui.dictation.forbidden': "ui.dictation.forbidden";
61
68
  readonly 'ui.progress_bar.label': "ui.progress_bar.label";
62
69
  readonly 'ui.progress_bar.over_by': "ui.progress_bar.over_by";
@@ -1 +1 @@
1
- {"version":3,"file":"strings.ui.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ui.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmKZ,CAAC"}
1
+ {"version":3,"file":"strings.ui.d.ts","sourceRoot":"","sources":["../../src/i18n/strings.ui.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6KZ,CAAC"}
@@ -53,7 +53,13 @@ export const M = defineMessages({
53
53
  // forms/DictationButton.svelte, forms/DictationStatus.svelte
54
54
  'ui.dictation.start': 'Speak instead of typing',
55
55
  'ui.dictation.start_hint': 'Speak instead of typing. You can also press and hold the text box.',
56
+ 'ui.dictation.start_hands_free': 'Speak instead of typing, hands-free. It writes each sentence down when you pause.',
56
57
  'ui.dictation.stop': 'Stop listening',
58
+ 'ui.dictation.listening_hands_free': 'Listening. Just talk; I write it down when you pause. Tap the microphone when you are done.',
59
+ 'ui.dictation.listening_short': 'Listening',
60
+ 'ui.dictation.hearing': 'Hearing you…',
61
+ 'ui.dictation.sending': 'Sending…',
62
+ 'ui.dictation.paused_speaking': 'Paused while the assistant speaks',
57
63
  'ui.dictation.starting': 'Getting the microphone ready…',
58
64
  'ui.dictation.listening': 'Listening. Tap the microphone when you are done.',
59
65
  'ui.dictation.unsupported': "Speech recognition isn't available in this browser. Brave blocks it; try Chrome, Edge or Safari, or type instead.",
@@ -66,6 +72,7 @@ export const M = defineMessages({
66
72
  'ui.dictation.too_long': 'That was too long to write down. Try a shorter message, or type instead.',
67
73
  'ui.dictation.not_transcribed': "Couldn't write that down. Tap the microphone to try again, or type instead.",
68
74
  'ui.dictation.unavailable': "Speaking isn't set up here yet. Please type instead.",
75
+ 'ui.dictation.model_missing': "The speech model isn't downloaded yet. Download it first, or type instead.",
69
76
  'ui.dictation.forbidden': "You can't use speaking here. Please type instead.",
70
77
  // feedback/ProgressBar.svelte
71
78
  'ui.progress_bar.label': 'Progress',
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export { default as MembershipCard } from './components/memberships/MembershipCa
18
18
  export { default as MembershipList } from './components/memberships/MembershipList.svelte';
19
19
  export * from './components/nav/index.js';
20
20
  export { default as PermissionCheck } from './components/permissions/PermissionCheck.svelte';
21
+ export { default as PermissionPicker } from './components/permissions/PermissionPicker.svelte';
21
22
  export { default as RoleBadge } from './components/roles/RoleBadge.svelte';
22
23
  export { default as RoleSelector } from './components/roles/RoleSelector.svelte';
23
24
  export * from './components/ui/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,UAAU,GACX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,cAAc,gCAAgC,CAAC;AAE/C,cAAc,4BAA4B,CAAC;AAE3C,cAAc,+BAA+B,CAAC;AAE9C,cAAc,gCAAgC,CAAC;AAE/C,cAAc,8BAA8B,CAAC;AAE7C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAE3F,cAAc,2BAA2B,CAAC;AAE1C,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAE7F,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAEjF,cAAc,0BAA0B,CAAC;AAEzC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,kBAAkB,CAAC;AAEjC,YAAY,EAAE,WAAW,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAElE,mBAAmB,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,UAAU,GACX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,cAAc,gCAAgC,CAAC;AAE/C,cAAc,4BAA4B,CAAC;AAE3C,cAAc,+BAA+B,CAAC;AAE9C,cAAc,gCAAgC,CAAC;AAE/C,cAAc,8BAA8B,CAAC;AAE7C,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAE3F,cAAc,2BAA2B,CAAC;AAE1C,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AAE/F,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,wCAAwC,CAAC;AAEjF,cAAc,0BAA0B,CAAC;AAEzC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,kBAAkB,CAAC;AAEjC,YAAY,EAAE,WAAW,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAElE,mBAAmB,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ export { default as MembershipList } from './components/memberships/MembershipLi
27
27
  export * from './components/nav/index.js';
28
28
  // Permission components
29
29
  export { default as PermissionCheck } from './components/permissions/PermissionCheck.svelte';
30
+ export { default as PermissionPicker } from './components/permissions/PermissionPicker.svelte';
30
31
  // Role components (domain-agnostic — typed against smrt-types contracts)
31
32
  export { default as RoleBadge } from './components/roles/RoleBadge.svelte';
32
33
  export { default as RoleSelector } from './components/roles/RoleSelector.svelte';
@@ -13,6 +13,7 @@ import MultiSelect from '../../components/forms/MultiSelect.svelte';
13
13
  import Radio from '../../components/forms/Radio.svelte';
14
14
  import RadioGroup from '../../components/forms/RadioGroup.svelte';
15
15
  import RangeSlider from '../../components/forms/RangeSlider.svelte';
16
+ import RelationInput from '../../components/forms/RelationInput.svelte';
16
17
  import SegmentedControl from '../../components/forms/SegmentedControl.svelte';
17
18
  import Slider from '../../components/forms/Slider.svelte';
18
19
  import Switch from '../../components/forms/Switch.svelte';
@@ -27,6 +28,26 @@ const countries = [
27
28
  { value: 'us', label: 'United States' },
28
29
  { value: 'mx', label: 'Mexico' },
29
30
  ];
31
+ // RelationInput demo: a caller-supplied lookup standing in for a REST search.
32
+ const demoCustomers = [
33
+ { id: 'cus_001', label: 'Acme Corp', detail: 'acme@example.com' },
34
+ { id: 'cus_002', label: 'Globex', detail: 'billing@globex.example' },
35
+ { id: 'cus_003', label: 'Initech', detail: 'ap@initech.example' },
36
+ { id: 'cus_004', label: 'Umbrella Ltd' },
37
+ ];
38
+ async function searchCustomers(query: string) {
39
+ await new Promise((resolve) => setTimeout(resolve, 300));
40
+ const q = query.toLowerCase();
41
+ return demoCustomers.filter(
42
+ (c) =>
43
+ c.label.toLowerCase().includes(q) ||
44
+ (c.detail ?? '').toLowerCase().includes(q),
45
+ );
46
+ }
47
+ async function resolveCustomer(id: string) {
48
+ return demoCustomers.find((c) => c.id === id) ?? null;
49
+ }
50
+ let customerId = $state('');
30
51
  let accepted = $state(true);
31
52
  let notifications = $state(true);
32
53
  let pinned = $state(false);
@@ -83,6 +104,7 @@ const identity = (controlId: string) => ({
83
104
 
84
105
  <section><h5>Structured input</h5><div class="grid">
85
106
  <Combobox name="country" label="Country" options={countries} bind:value={country} />
107
+ <RelationInput name="customerId" label="Customer" description="Search by name or email" search={searchCustomers} resolve={resolveCustomer} bind:value={customerId} />
86
108
  <MultiSelect name="channels" label="Channels" options={[{ value: 'email', label: 'Email' }, { value: 'sms', label: 'SMS' }, { value: 'push', label: 'Push' }]} bind:values={channels} />
87
109
  <TagsInput name="topics" label="Topics" bind:values={tags} />
88
110
  <DatePicker name="date" label="Publish date" />
@@ -1 +1 @@
1
- {"version":3,"file":"InteractiveControlsPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/InteractiveControlsPreview.svelte.ts"],"names":[],"mappings":"AAwHA,QAAA,MAAM,0BAA0B,2DAAwC,CAAC;AACzE,KAAK,0BAA0B,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAChF,eAAe,0BAA0B,CAAC"}
1
+ {"version":3,"file":"InteractiveControlsPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/InteractiveControlsPreview.svelte.ts"],"names":[],"mappings":"AA+IA,QAAA,MAAM,0BAA0B,2DAAwC,CAAC;AACzE,KAAK,0BAA0B,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAChF,eAAe,0BAA0B,CAAC"}
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import PermissionPicker from '../../components/permissions/PermissionPicker.svelte';
3
+
4
+ const permissions = [
5
+ { slug: 'projects.read', name: 'View projects', category: 'Projects' },
6
+ { slug: 'projects.update', name: 'Update projects', category: 'Projects' },
7
+ {
8
+ slug: 'tenant.settings.read',
9
+ name: 'View workspace settings',
10
+ description: 'Review the active workspace configuration.',
11
+ category: 'Workspace',
12
+ },
13
+ {
14
+ slug: 'tenant.settings.manage',
15
+ name: 'Manage workspace settings',
16
+ category: 'Workspace',
17
+ },
18
+ ];
19
+ </script>
20
+
21
+ <form>
22
+ <PermissionPicker
23
+ {permissions}
24
+ selected={['projects.read', 'tenant.settings.read']}
25
+ description="Choose the capabilities assigned to this role."
26
+ />
27
+ </form>
@@ -0,0 +1,19 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const PermissionPickerPreview: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type PermissionPickerPreview = InstanceType<typeof PermissionPickerPreview>;
18
+ export default PermissionPickerPreview;
19
+ //# sourceMappingURL=PermissionPickerPreview.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PermissionPickerPreview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/playground/PermissionPickerPreview.svelte.ts"],"names":[],"mappings":"AA+BA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,uBAAuB;;kBAA+E,CAAC;AAC3F,KAAK,uBAAuB,GAAG,YAAY,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC9E,eAAe,uBAAuB,CAAC"}
@@ -2,7 +2,19 @@ declare const _default: {
2
2
  packageName: string;
3
3
  displayName: string;
4
4
  description: string;
5
- entries: {
5
+ entries: ({
6
+ id: string;
7
+ title: string;
8
+ description: string;
9
+ loadComponent: () => Promise<typeof import("./playground/PermissionPickerPreview.svelte")>;
10
+ order: number;
11
+ tags: string[];
12
+ modes: {
13
+ mock: {
14
+ label: string;
15
+ };
16
+ };
17
+ } | {
6
18
  id: string;
7
19
  title: string;
8
20
  description: string;
@@ -14,7 +26,7 @@ declare const _default: {
14
26
  label: string;
15
27
  };
16
28
  };
17
- }[];
29
+ })[];
18
30
  };
19
31
  export default _default;
20
32
  //# sourceMappingURL=playground.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../../src/svelte/playground.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAUA,wBA+FE"}
1
+ {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../../src/svelte/playground.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,wBAyGE"}
@@ -5,11 +5,21 @@ const loadFeedback = () => import('./playground/FeedbackPreview.svelte');
5
5
  const loadCollections = () => import('./playground/CollectionsPreview.svelte');
6
6
  const loadCalendar = () => import('./playground/CalendarPreview.svelte');
7
7
  const loadCapture = () => import('./playground/CapturePreview.svelte');
8
+ const loadPermissionPicker = () => import('./playground/PermissionPickerPreview.svelte');
8
9
  export default {
9
10
  packageName: '@happyvertical/smrt-ui',
10
11
  displayName: 'UI Foundation',
11
12
  description: 'Provider-free controls and data primitives rendered in the active s-m-r-t theme.',
12
13
  entries: [
14
+ {
15
+ id: 'permission-picker',
16
+ title: 'Permission Picker',
17
+ description: 'Grouped, searchable native-form permission grants with retained server retry selections.',
18
+ loadComponent: loadPermissionPicker,
19
+ order: 9,
20
+ tags: ['forms', 'permissions', 'roles', 'search'],
21
+ modes: { mock: { label: 'Interactive' } },
22
+ },
13
23
  {
14
24
  id: 'code-selectors',
15
25
  title: 'Currency, Country & Province',
@@ -55,6 +55,7 @@ export { brandTheme };
55
55
  <!-- +layout.svelte -->
56
56
  <script>
57
57
  import { ThemeProvider } from '@happyvertical/smrt-ui/themes';
58
+ import '@happyvertical/smrt-ui/themes/styles/base.css';
58
59
  import '@happyvertical/smrt-ui/themes/styles/all.css';
59
60
  import '$lib/themes/brand'; // Import to register
60
61
  </script>
@@ -244,6 +245,7 @@ Best for static sites or when you want minimal JavaScript overhead.
244
245
  <!-- +layout.svelte -->
245
246
  <script>
246
247
  // Import only the theme you need
248
+ import '@happyvertical/smrt-ui/themes/styles/base.css';
247
249
  import '@happyvertical/smrt-ui/themes/styles/material.css';
248
250
  </script>
249
251
 
@@ -276,6 +278,9 @@ For maximum performance, use CSS only with media queries:
276
278
  Import the theme styles in your app entry point:
277
279
 
278
280
  ```ts
281
+ // Recommended application sizing, surface, and typography defaults
282
+ import '@happyvertical/smrt-ui/themes/styles/base.css';
283
+
279
284
  // Import all themes (for runtime switching)
280
285
  import '@happyvertical/smrt-ui/themes/styles/all.css';
281
286
 
@@ -21,13 +21,8 @@ export { getThemeContext, hasThemeContext, setThemeContext, tryGetThemeContext,
21
21
  export type { CreateThemeOptions } from './create-theme.js';
22
22
  export { createTheme, createThemeFromColor, getRegisteredTheme, isThemeRegistered, preloadThemeRegistry, registerTheme, } from './create-theme.js';
23
23
  export { generateAllThemesCSS, generateThemeCSS, generateThemeVariables, variablesToStyleString, } from './css-generator.js';
24
- export { glassTheme } from './glass/index.js';
25
- export { happyverticalTheme } from './happyvertical/index.js';
26
- export { materialTheme } from './material/index.js';
27
- export { availablePresets, getAllThemes, getTheme, getThemeName, getThemeOptions, isValidPreset, themes, } from './registry.js';
24
+ export { availablePresets, getAllThemes, getTheme, getThemeName, getThemeOptions, glassTheme, happyverticalTheme, isValidPreset, materialTheme, smrtTheme, studioTheme, type ThemePresetSummary, themePresets, themes, } from './presets.js';
28
25
  export { appleEasing, borderRadiusScale, durationScale, materialEasing, spacingScale, studioEasing, } from './shared.js';
29
- export { smrtTheme } from './smrt/index.js';
30
- export { studioTheme } from './studio/index.js';
31
26
  export { default as ThemeProvider } from './ThemeProvider.svelte';
32
27
  export { type ThemeScriptOptions, themeScript } from './theme-script.js';
33
28
  export type { BorderRadius, BorderRadiusScale, ColorPalette, ColorScheme, CSSVariableOptions, DurationScale, EasingScale, ElevationScale, GlassEffects, ResolvedScheme, SpacingScale, Theme, ThemeConfig, ThemeContext, ThemePreset, ThemeState, TypographyScale, TypographyToken, } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,aAAa,EACb,MAAM,GACP,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,SAAS,EACT,WAAW,EACX,KAAK,kBAAkB,EACvB,YAAY,EACZ,MAAM,GACP,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,KAAK,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
@@ -24,16 +24,10 @@ export { getThemeContext, hasThemeContext, setThemeContext, tryGetThemeContext,
24
24
  export { createTheme, createThemeFromColor, getRegisteredTheme, isThemeRegistered, preloadThemeRegistry, registerTheme, } from './create-theme.js';
25
25
  // CSS generation
26
26
  export { generateAllThemesCSS, generateThemeCSS, generateThemeVariables, variablesToStyleString, } from './css-generator.js';
27
- export { glassTheme } from './glass/index.js';
28
- export { happyverticalTheme } from './happyvertical/index.js';
29
- // Theme definitions
30
- export { materialTheme } from './material/index.js';
31
- // Registry
32
- export { availablePresets, getAllThemes, getTheme, getThemeName, getThemeOptions, isValidPreset, themes, } from './registry.js';
27
+ // Preset data and registry (single source: ./presets.ts, Node-safe)
28
+ export { availablePresets, getAllThemes, getTheme, getThemeName, getThemeOptions, glassTheme, happyverticalTheme, isValidPreset, materialTheme, smrtTheme, studioTheme, themePresets, themes, } from './presets.js';
33
29
  // Shared tokens (if needed for custom themes)
34
30
  export { appleEasing, borderRadiusScale, durationScale, materialEasing, spacingScale, studioEasing, } from './shared.js';
35
- export { smrtTheme } from './smrt/index.js';
36
- export { studioTheme } from './studio/index.js';
37
31
  // Main components
38
32
  export { default as ThemeProvider } from './ThemeProvider.svelte';
39
33
  // Pre-paint bootstrap script
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Theme presets: ids, labels, and palettes only.
3
+ *
4
+ * Node-safe subpath (`@happyvertical/smrt-ui/themes/presets`): it imports no
5
+ * `.svelte` file and no browser global, so a CLI, server, or build script can
6
+ * list the presets without a Svelte toolchain. `@happyvertical/smrt-ui/themes`
7
+ * re-exports everything here, so the preset data has exactly one source.
8
+ */
9
+ export { glassTheme } from './glass/index.js';
10
+ export { happyverticalTheme } from './happyvertical/index.js';
11
+ export { materialTheme } from './material/index.js';
12
+ export { availablePresets, getAllThemes, getTheme, getThemeName, getThemeOptions, isValidPreset, themes, } from './registry.js';
13
+ export { smrtTheme } from './smrt/index.js';
14
+ export { studioTheme } from './studio/index.js';
15
+ export type { ColorPalette, ColorScheme, ResolvedScheme, Theme, ThemePreset, } from './types.js';
16
+ import type { ColorPalette, ThemePreset } from './types.js';
17
+ /** A built-in preset reduced to its identity and palettes. */
18
+ export interface ThemePresetSummary {
19
+ id: ThemePreset;
20
+ label: string;
21
+ light: ColorPalette;
22
+ dark: ColorPalette;
23
+ }
24
+ /** Built-in presets in display order: id, label, and light/dark colors. */
25
+ export declare const themePresets: readonly ThemePresetSummary[];
26
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/themes/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,aAAa,EACb,MAAM,GACP,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EACV,YAAY,EACZ,WAAW,EACX,cAAc,EACd,KAAK,EACL,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,2EAA2E;AAC3E,eAAO,MAAM,YAAY,EAAE,SAAS,kBAAkB,EAOrD,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Theme presets: ids, labels, and palettes only.
3
+ *
4
+ * Node-safe subpath (`@happyvertical/smrt-ui/themes/presets`): it imports no
5
+ * `.svelte` file and no browser global, so a CLI, server, or build script can
6
+ * list the presets without a Svelte toolchain. `@happyvertical/smrt-ui/themes`
7
+ * re-exports everything here, so the preset data has exactly one source.
8
+ */
9
+ export { glassTheme } from './glass/index.js';
10
+ export { happyverticalTheme } from './happyvertical/index.js';
11
+ export { materialTheme } from './material/index.js';
12
+ export { availablePresets, getAllThemes, getTheme, getThemeName, getThemeOptions, isValidPreset, themes, } from './registry.js';
13
+ export { smrtTheme } from './smrt/index.js';
14
+ export { studioTheme } from './studio/index.js';
15
+ import { availablePresets, themes } from './registry.js';
16
+ /** Built-in presets in display order: id, label, and light/dark colors. */
17
+ export const themePresets = availablePresets.map((id) => ({
18
+ id,
19
+ label: themes[id].name,
20
+ light: themes[id].light,
21
+ dark: themes[id].dark,
22
+ }));