ui-svelte 0.2.11 → 0.2.13

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 (225) hide show
  1. package/README.md +2 -2
  2. package/dist/charts/ArcChart.svelte +9 -14
  3. package/dist/charts/ArcChart.svelte.d.ts +3 -3
  4. package/dist/charts/AreaChart.svelte +347 -118
  5. package/dist/charts/AreaChart.svelte.d.ts +33 -4
  6. package/dist/charts/BarChart.svelte +288 -66
  7. package/dist/charts/BarChart.svelte.d.ts +26 -1
  8. package/dist/charts/Candlestick.svelte +53 -50
  9. package/dist/charts/Candlestick.svelte.d.ts +8 -8
  10. package/dist/charts/LineChart.svelte +391 -91
  11. package/dist/charts/LineChart.svelte.d.ts +26 -3
  12. package/dist/charts/PieChart.svelte +333 -92
  13. package/dist/charts/PieChart.svelte.d.ts +33 -5
  14. package/dist/charts/css/arc-chart.css +3 -3
  15. package/dist/charts/css/area-chart.css +127 -29
  16. package/dist/charts/css/bar-chart.css +114 -8
  17. package/dist/charts/css/candlestick.css +2 -0
  18. package/dist/charts/css/line-chart.css +111 -13
  19. package/dist/charts/css/pie-chart.css +92 -20
  20. package/dist/control/Audio.svelte +86 -44
  21. package/dist/control/Audio.svelte.d.ts +4 -1
  22. package/dist/control/Button.svelte +18 -27
  23. package/dist/control/Button.svelte.d.ts +3 -2
  24. package/dist/control/Fab.svelte +103 -0
  25. package/dist/control/Fab.svelte.d.ts +25 -0
  26. package/dist/control/IconButton.svelte +17 -27
  27. package/dist/control/IconButton.svelte.d.ts +3 -3
  28. package/dist/control/Image.svelte +123 -0
  29. package/dist/control/Image.svelte.d.ts +13 -0
  30. package/dist/control/Record.svelte +141 -98
  31. package/dist/control/Record.svelte.d.ts +2 -1
  32. package/dist/control/ToggleGroup.svelte +22 -8
  33. package/dist/control/ToggleGroup.svelte.d.ts +2 -1
  34. package/dist/control/ToggleTheme.svelte +13 -11
  35. package/dist/control/ToggleTheme.svelte.d.ts +3 -2
  36. package/dist/control/Video.svelte +57 -29
  37. package/dist/control/Video.svelte.d.ts +1 -0
  38. package/dist/control/css/btn.css +200 -152
  39. package/dist/control/css/fab.css +84 -0
  40. package/dist/control/css/image.css +56 -0
  41. package/dist/control/css/media.css +95 -30
  42. package/dist/control/css/toggle-group.css +253 -84
  43. package/dist/control/css/video.css +1 -14
  44. package/dist/css/animations.css +5 -9
  45. package/dist/css/base.css +13 -347
  46. package/dist/css/decorations.css +561 -0
  47. package/dist/css/rich-text.css +485 -0
  48. package/dist/css/transitions.css +158 -0
  49. package/dist/css/typography.css +291 -0
  50. package/dist/css/utilities.css +0 -4
  51. package/dist/display/Accordion.svelte +28 -4
  52. package/dist/display/Accordion.svelte.d.ts +2 -1
  53. package/dist/display/Alert.svelte +32 -12
  54. package/dist/display/Alert.svelte.d.ts +2 -3
  55. package/dist/display/Avatar.svelte +23 -18
  56. package/dist/display/Avatar.svelte.d.ts +4 -1
  57. package/dist/display/AvatarGroup.svelte +20 -18
  58. package/dist/display/AvatarGroup.svelte.d.ts +6 -3
  59. package/dist/display/Badge.svelte +11 -4
  60. package/dist/display/Badge.svelte.d.ts +2 -1
  61. package/dist/display/Card.svelte +15 -14
  62. package/dist/display/Card.svelte.d.ts +2 -3
  63. package/dist/display/Carousel.svelte +130 -99
  64. package/dist/display/Carousel.svelte.d.ts +6 -4
  65. package/dist/display/ChatBox.svelte +245 -106
  66. package/dist/display/ChatBox.svelte.d.ts +32 -5
  67. package/dist/display/Chip.svelte +31 -17
  68. package/dist/display/Chip.svelte.d.ts +3 -2
  69. package/dist/display/Code.svelte +7 -4
  70. package/dist/display/Code.svelte.d.ts +1 -0
  71. package/dist/display/Collapsible.svelte +30 -4
  72. package/dist/display/Collapsible.svelte.d.ts +2 -1
  73. package/dist/display/Countdown.svelte +169 -0
  74. package/dist/display/Countdown.svelte.d.ts +21 -0
  75. package/dist/display/Empty.svelte +37 -3
  76. package/dist/display/Empty.svelte.d.ts +3 -0
  77. package/dist/display/Item.svelte +42 -11
  78. package/dist/display/Item.svelte.d.ts +4 -2
  79. package/dist/display/Map.svelte +488 -0
  80. package/dist/display/Map.svelte.d.ts +44 -0
  81. package/dist/display/Marquee.svelte +0 -2
  82. package/dist/display/Section.svelte +14 -12
  83. package/dist/display/Section.svelte.d.ts +2 -3
  84. package/dist/display/Skeleton.svelte +32 -0
  85. package/dist/display/Skeleton.svelte.d.ts +10 -0
  86. package/dist/display/Table.svelte +94 -132
  87. package/dist/display/Table.svelte.d.ts +10 -1
  88. package/dist/display/css/accordion.css +349 -52
  89. package/dist/display/css/alert.css +38 -18
  90. package/dist/display/css/avatar-group.css +38 -75
  91. package/dist/display/css/avatar.css +139 -121
  92. package/dist/display/css/badge.css +50 -27
  93. package/dist/display/css/card.css +123 -71
  94. package/dist/display/css/carousel.css +25 -5
  95. package/dist/display/css/chat-box.css +158 -26
  96. package/dist/display/css/chip.css +142 -68
  97. package/dist/display/css/code.css +2 -6
  98. package/dist/display/css/collapsible.css +349 -45
  99. package/dist/display/css/countdown.css +206 -0
  100. package/dist/display/css/divider.css +8 -6
  101. package/dist/display/css/empty.css +7 -0
  102. package/dist/display/css/item.css +330 -84
  103. package/dist/display/css/map.css +164 -0
  104. package/dist/display/css/marquee.css +0 -3
  105. package/dist/display/css/section.css +89 -65
  106. package/dist/display/css/skeleton.css +58 -0
  107. package/dist/display/css/table.css +309 -193
  108. package/dist/form/Checkbox.svelte +11 -5
  109. package/dist/form/Checkbox.svelte.d.ts +2 -1
  110. package/dist/form/ColorField.svelte +601 -0
  111. package/dist/form/ColorField.svelte.d.ts +29 -0
  112. package/dist/form/ComboBox.svelte +24 -9
  113. package/dist/form/ComboBox.svelte.d.ts +2 -2
  114. package/dist/form/CsvField.svelte +62 -136
  115. package/dist/form/CsvField.svelte.d.ts +2 -2
  116. package/dist/form/DateField.svelte +33 -15
  117. package/dist/form/DateField.svelte.d.ts +2 -1
  118. package/dist/form/DateRange.svelte +436 -0
  119. package/dist/form/DateRange.svelte.d.ts +24 -0
  120. package/dist/form/DragDrop.svelte +578 -0
  121. package/dist/form/DragDrop.svelte.d.ts +33 -0
  122. package/dist/form/Dropzone.svelte +28 -8
  123. package/dist/form/Dropzone.svelte.d.ts +2 -2
  124. package/dist/form/Editor.svelte +626 -0
  125. package/dist/form/Editor.svelte.d.ts +50 -0
  126. package/dist/form/ImageCropper.svelte +422 -61
  127. package/dist/form/ImageCropper.svelte.d.ts +15 -1
  128. package/dist/form/{PasswordStrength.svelte → PasswordField.svelte} +58 -24
  129. package/dist/form/{PasswordStrength.svelte.d.ts → PasswordField.svelte.d.ts} +6 -5
  130. package/dist/form/PhoneField.svelte +26 -14
  131. package/dist/form/PhoneField.svelte.d.ts +4 -3
  132. package/dist/form/PinField.svelte +39 -31
  133. package/dist/form/PinField.svelte.d.ts +3 -3
  134. package/dist/form/RadioGroup.svelte +9 -5
  135. package/dist/form/RadioGroup.svelte.d.ts +1 -1
  136. package/dist/form/Select.svelte +20 -19
  137. package/dist/form/Select.svelte.d.ts +2 -2
  138. package/dist/form/Slider.svelte +10 -4
  139. package/dist/form/Slider.svelte.d.ts +2 -1
  140. package/dist/form/TextField.svelte +29 -11
  141. package/dist/form/TextField.svelte.d.ts +5 -4
  142. package/dist/form/Textarea.svelte +15 -6
  143. package/dist/form/Textarea.svelte.d.ts +2 -2
  144. package/dist/form/Toggle.svelte +7 -3
  145. package/dist/form/Toggle.svelte.d.ts +1 -1
  146. package/dist/form/css/checkbox.css +18 -2
  147. package/dist/form/css/color-field.css +141 -0
  148. package/dist/form/css/control.css +193 -82
  149. package/dist/form/css/csv-field.css +221 -0
  150. package/dist/form/css/date-range.css +122 -0
  151. package/dist/form/css/date.css +24 -2
  152. package/dist/form/css/drag-drop.css +234 -0
  153. package/dist/form/css/dropzone.css +153 -34
  154. package/dist/form/css/editor.css +367 -0
  155. package/dist/form/css/field.css +4 -0
  156. package/dist/form/css/image-cropper.css +242 -20
  157. package/dist/form/css/radio-group.css +26 -1
  158. package/dist/form/css/select.css +2 -2
  159. package/dist/form/css/slider.css +37 -0
  160. package/dist/form/css/textarea.css +178 -75
  161. package/dist/form/css/toggle.css +15 -3
  162. package/dist/hooks/use-chat.svelte.js +1 -1
  163. package/dist/hooks/use-form.svelte.js +3 -3
  164. package/dist/hooks/use-search.svelte.js +0 -3
  165. package/dist/hooks/use-table.svelte.d.ts +1 -0
  166. package/dist/hooks/use-table.svelte.js +6 -0
  167. package/dist/icons/index.d.ts +34 -2
  168. package/dist/icons/index.js +36 -4
  169. package/dist/index.css +44 -49
  170. package/dist/index.d.ts +14 -4
  171. package/dist/index.js +13 -3
  172. package/dist/layout/AppBar.svelte +22 -14
  173. package/dist/layout/AppBar.svelte.d.ts +2 -1
  174. package/dist/layout/Footer.svelte +19 -11
  175. package/dist/layout/Footer.svelte.d.ts +2 -1
  176. package/dist/layout/Provider.svelte +32 -9
  177. package/dist/layout/Provider.svelte.d.ts +3 -1
  178. package/dist/layout/Sidebar.svelte +17 -8
  179. package/dist/layout/Sidebar.svelte.d.ts +2 -1
  180. package/dist/layout/css/app-bar.css +63 -66
  181. package/dist/layout/css/footer.css +62 -65
  182. package/dist/layout/css/sidebar.css +120 -59
  183. package/dist/navigation/BottomNav.svelte +51 -14
  184. package/dist/navigation/FooterGroup.svelte +1 -1
  185. package/dist/navigation/NavMenu.svelte +47 -23
  186. package/dist/navigation/NavMenu.svelte.d.ts +29 -0
  187. package/dist/navigation/Pagination.svelte +158 -0
  188. package/dist/navigation/Pagination.svelte.d.ts +18 -0
  189. package/dist/navigation/SideNav.svelte +30 -25
  190. package/dist/navigation/SideNav.svelte.d.ts +2 -3
  191. package/dist/navigation/Tabs.svelte +17 -7
  192. package/dist/navigation/Tabs.svelte.d.ts +2 -2
  193. package/dist/navigation/css/bottom-nav.css +319 -257
  194. package/dist/navigation/css/footer-group.css +1 -1
  195. package/dist/navigation/css/footer-nav.css +1 -1
  196. package/dist/navigation/css/nav-menu.css +331 -106
  197. package/dist/navigation/css/pagination.css +74 -0
  198. package/dist/navigation/css/side-nav.css +514 -75
  199. package/dist/navigation/css/tabs.css +246 -52
  200. package/dist/overlay/AlertDialog.svelte +58 -0
  201. package/dist/overlay/AlertDialog.svelte.d.ts +14 -25
  202. package/dist/overlay/Command.svelte +347 -0
  203. package/dist/overlay/Command.svelte.d.ts +33 -25
  204. package/dist/overlay/Drawer.svelte +49 -21
  205. package/dist/overlay/Drawer.svelte.d.ts +2 -2
  206. package/dist/overlay/Dropdown.svelte +3 -3
  207. package/dist/overlay/Modal.svelte +51 -16
  208. package/dist/overlay/Modal.svelte.d.ts +3 -3
  209. package/dist/overlay/Toast.svelte +41 -17
  210. package/dist/overlay/Toast.svelte.d.ts +1 -1
  211. package/dist/overlay/Tooltip.svelte +36 -27
  212. package/dist/overlay/Tooltip.svelte.d.ts +2 -2
  213. package/dist/overlay/css/command.css +68 -0
  214. package/dist/overlay/css/drawer.css +63 -24
  215. package/dist/overlay/css/dropdown.css +1 -1
  216. package/dist/overlay/css/hovercard.css +1 -1
  217. package/dist/overlay/css/modal.css +79 -27
  218. package/dist/overlay/css/toast.css +40 -24
  219. package/dist/overlay/css/tooltip.css +110 -67
  220. package/dist/stores/theme.svelte.js +44 -12
  221. package/dist/stores/toast.svelte.d.ts +4 -4
  222. package/dist/stores/toast.svelte.js +2 -2
  223. package/package.json +1 -1
  224. package/dist/utils/charts.d.ts +0 -27
  225. package/dist/utils/charts.js +0 -140
@@ -0,0 +1,347 @@
1
+ <script lang="ts">
2
+ import type { SearchState, SearchOption } from '../hooks/use-search.svelte.js';
3
+ import { Search24RegularIcon, DotsMoveIcon } from '../icons/index.js';
4
+ import { Icon, Item, Modal, TextField, type IconData } from '../index.js';
5
+ import { cn } from '../utils/class-names.js';
6
+ import { tick } from 'svelte';
7
+ import { afterNavigate } from '$app/navigation';
8
+
9
+ type CommandGroup = {
10
+ label: string;
11
+ icon?: IconData;
12
+ options: SearchOption[];
13
+ };
14
+
15
+ type CommandLabels = {
16
+ placeholder?: string;
17
+ emptyText?: string;
18
+ loadingText?: string;
19
+ loadingMoreText?: string;
20
+ closeText?: string;
21
+ navigateText?: string;
22
+ selectText?: string;
23
+ toggleText?: string;
24
+ };
25
+
26
+ type Props = {
27
+ search: SearchState;
28
+ open?: boolean;
29
+ labels?: CommandLabels;
30
+ color?: 'primary' | 'secondary' | 'muted' | 'success' | 'info' | 'warning' | 'danger';
31
+ disableOverlayClose?: boolean;
32
+ disableGlobalShortcut?: boolean;
33
+ shortcut?: string;
34
+ showFooter?: boolean;
35
+ groups?: CommandGroup[];
36
+ onselect?: (item: SearchOption) => void;
37
+ onclose?: () => void;
38
+ class?: string;
39
+ };
40
+
41
+ let {
42
+ search,
43
+ open = $bindable(false),
44
+ labels = {},
45
+ color = 'muted',
46
+ disableOverlayClose = false,
47
+ disableGlobalShortcut = false,
48
+ shortcut = 'k',
49
+ showFooter = true,
50
+ groups,
51
+ onselect,
52
+ onclose,
53
+ class: className
54
+ }: Props = $props();
55
+
56
+ const defaultLabels: Required<CommandLabels> = {
57
+ placeholder: 'Search...',
58
+ emptyText: 'No results found',
59
+ loadingText: 'Loading...',
60
+ loadingMoreText: 'Loading more...',
61
+ closeText: 'to close',
62
+ navigateText: 'Navigate',
63
+ selectText: 'Select',
64
+ toggleText: 'Toggle'
65
+ };
66
+
67
+ const t = $derived({ ...defaultLabels, ...labels });
68
+
69
+ let optionsEl = $state<HTMLElement>();
70
+ let searchInputEl = $state<HTMLInputElement>();
71
+ let focusedIndex = $state(-1);
72
+ let hasSearched = $state(false);
73
+ let modifierKey = $state('Ctrl');
74
+
75
+ const filteredGroups = $derived(() => {
76
+ if (!groups || groups.length === 0) return [];
77
+ const query = search.search?.toLowerCase() ?? '';
78
+ if (!query) return groups;
79
+
80
+ return groups
81
+ .map((group) => ({
82
+ ...group,
83
+ options: group.options.filter((opt) => opt.label.toLowerCase().includes(query))
84
+ }))
85
+ .filter((group) => group.options.length > 0);
86
+ });
87
+
88
+ const flatOptions = $derived(() => {
89
+ const filtered = filteredGroups();
90
+ if (filtered.length > 0) {
91
+ return filtered.flatMap((g) => g.options);
92
+ }
93
+ return search.options;
94
+ });
95
+
96
+ const scrollToItem = (index: number) => {
97
+ if (!optionsEl) return;
98
+ const items = Array.from(optionsEl.querySelectorAll('.item'));
99
+ const target = items[index] as HTMLElement;
100
+ if (!target) return;
101
+
102
+ target.scrollIntoView({ block: 'nearest' });
103
+ };
104
+
105
+ const handleKeyDown = (event: KeyboardEvent) => {
106
+ const items = flatOptions();
107
+ if (!items.length && event.key !== 'Escape') return;
108
+
109
+ switch (event.key) {
110
+ case 'ArrowDown':
111
+ event.preventDefault();
112
+ focusedIndex = (focusedIndex + 1) % items.length;
113
+ scrollToItem(focusedIndex);
114
+ break;
115
+ case 'ArrowUp':
116
+ event.preventDefault();
117
+ focusedIndex = (focusedIndex - 1 + items.length) % items.length;
118
+ scrollToItem(focusedIndex);
119
+ break;
120
+ case 'Enter': {
121
+ event.preventDefault();
122
+ if (focusedIndex >= 0 && focusedIndex < items.length) {
123
+ handleSelect(items[focusedIndex]);
124
+ }
125
+ break;
126
+ }
127
+ case 'Escape':
128
+ event.preventDefault();
129
+ handleClose();
130
+ break;
131
+ }
132
+ };
133
+
134
+ const handleGlobalKeyDown = (event: KeyboardEvent) => {
135
+ if (disableGlobalShortcut) return;
136
+ if (typeof navigator === 'undefined') return;
137
+
138
+ const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
139
+ const modifier = isMac ? event.metaKey : event.ctrlKey;
140
+
141
+ if (modifier && event.key.toLowerCase() === shortcut.toLowerCase()) {
142
+ event.preventDefault();
143
+ open = !open;
144
+ }
145
+ };
146
+
147
+ const handleScroll = async () => {
148
+ if (!optionsEl || !search.hasMore || search.isLoadingMore) return;
149
+
150
+ const { scrollTop, scrollHeight, clientHeight } = optionsEl;
151
+ const scrollPercentage = (scrollTop + clientHeight) / scrollHeight;
152
+
153
+ if (scrollPercentage >= 0.8) {
154
+ await search.loadMore();
155
+ }
156
+ };
157
+
158
+ const handleSelect = (item: SearchOption) => {
159
+ onselect?.(item);
160
+ open = false;
161
+ search.setSearch('');
162
+ };
163
+
164
+ const handleClose = () => {
165
+ open = false;
166
+ focusedIndex = -1;
167
+ hasSearched = false;
168
+ search.setSearch('');
169
+ onclose?.();
170
+ };
171
+
172
+ const handleModalClose = () => {
173
+ handleClose();
174
+ };
175
+
176
+ $effect(() => {
177
+ if (search.search && search.search.length > 0) {
178
+ hasSearched = true;
179
+ }
180
+ });
181
+
182
+ $effect(() => {
183
+ afterNavigate(() => {
184
+ if (open) {
185
+ open = false;
186
+ focusedIndex = -1;
187
+ hasSearched = false;
188
+ search.setSearch('');
189
+ }
190
+ });
191
+ });
192
+
193
+ $effect(() => {
194
+ if (open) {
195
+ document.addEventListener('keydown', handleKeyDown);
196
+ } else {
197
+ document.removeEventListener('keydown', handleKeyDown);
198
+ }
199
+
200
+ return () => {
201
+ document.removeEventListener('keydown', handleKeyDown);
202
+ };
203
+ });
204
+
205
+ $effect(() => {
206
+ if (open && searchInputEl) {
207
+ tick().then(() => {
208
+ searchInputEl?.focus();
209
+ focusedIndex = -1;
210
+ hasSearched = false;
211
+ });
212
+ }
213
+ });
214
+
215
+ $effect(() => {
216
+ if (typeof document === 'undefined') return;
217
+
218
+ if (!disableGlobalShortcut) {
219
+ document.addEventListener('keydown', handleGlobalKeyDown);
220
+ }
221
+
222
+ if (typeof navigator !== 'undefined') {
223
+ const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
224
+ modifierKey = isMac ? '⌘' : 'Ctrl';
225
+ }
226
+
227
+ return () => {
228
+ document.removeEventListener('keydown', handleGlobalKeyDown);
229
+ };
230
+ });
231
+ </script>
232
+
233
+ {#snippet commandKbd()}
234
+ <div class="command-kbd">
235
+ <kbd>Esc</kbd>
236
+ <span>{t.closeText}</span>
237
+ </div>
238
+ {/snippet}
239
+
240
+ {#snippet renderItem(item: SearchOption, index: number)}
241
+ {@const hasVisualElement = !!item.icon || !!item.src}
242
+ <Item
243
+ id={item.id}
244
+ label={item.label}
245
+ icon={item.icon as IconData}
246
+ src={item.src}
247
+ description={item.description}
248
+ href={item.href as string | undefined}
249
+ isFocused={focusedIndex === index}
250
+ isDisabled={item.disabled}
251
+ hasBullet={!hasVisualElement}
252
+ {color}
253
+ size="sm"
254
+ isCompact
255
+ onclick={() => handleSelect(item)}
256
+ />
257
+ {/snippet}
258
+
259
+ <Modal
260
+ bind:open
261
+ onclose={handleModalClose}
262
+ rootClass={cn(className)}
263
+ color="background"
264
+ {disableOverlayClose}
265
+ hideCloseButton
266
+ >
267
+ {#snippet header()}
268
+ <TextField
269
+ bind:el={searchInputEl}
270
+ bind:value={search.search}
271
+ placeholder={t.placeholder}
272
+ startIcon={Search24RegularIcon}
273
+ variant="line"
274
+ {color}
275
+ size="md"
276
+ endText={commandKbd}
277
+ />
278
+ {/snippet}
279
+
280
+ <div class="command-results" bind:this={optionsEl} onscroll={handleScroll}>
281
+ {#if search.isLoading}
282
+ <div class="command-loading">
283
+ <Icon icon={DotsMoveIcon} class="command-loading-spinner" />
284
+ <span>{t.loadingText}</span>
285
+ </div>
286
+ {:else if flatOptions().length === 0 && hasSearched}
287
+ <div class="command-empty">{t.emptyText}</div>
288
+ {:else if filteredGroups().length > 0}
289
+ {#each filteredGroups() as group}
290
+ <div class="command-group">
291
+ <div class="command-group-label">
292
+ {#if group.icon}
293
+ <Icon icon={group.icon} class="command-group-icon" />
294
+ {/if}
295
+ {group.label}
296
+ </div>
297
+ <div class="command-group-items">
298
+ {#each group.options as item}
299
+ {@render renderItem(item, flatOptions().indexOf(item))}
300
+ {/each}
301
+ </div>
302
+ </div>
303
+ {/each}
304
+
305
+ {#if search.isLoadingMore}
306
+ <div class="command-loading">
307
+ <Icon icon={DotsMoveIcon} class="command-loading-spinner" />
308
+ <span>{t.loadingMoreText}</span>
309
+ </div>
310
+ {/if}
311
+ {:else if search.options.length > 0}
312
+ <div class="command-group-items">
313
+ {#each search.options as item, index}
314
+ {@render renderItem(item, index)}
315
+ {/each}
316
+ </div>
317
+
318
+ {#if search.isLoadingMore}
319
+ <div class="command-loading">
320
+ <Icon icon={DotsMoveIcon} class="command-loading-spinner" />
321
+ <span>{t.loadingMoreText}</span>
322
+ </div>
323
+ {/if}
324
+ {/if}
325
+ </div>
326
+
327
+ {#snippet footer()}
328
+ {#if showFooter}
329
+ <div class="command-shortcuts">
330
+ <div class="command-shortcut">
331
+ <div class="command-shortcut-item">
332
+ <kbd>↑</kbd><kbd>↓</kbd>
333
+ <span>{t.navigateText}</span>
334
+ </div>
335
+ <div class="command-shortcut-item">
336
+ <kbd>↵</kbd>
337
+ <span>{t.selectText}</span>
338
+ </div>
339
+ </div>
340
+ <div class="command-shortcut-item">
341
+ <kbd>{modifierKey}</kbd><kbd>{shortcut.toUpperCase()}</kbd>
342
+ <span>{t.toggleText}</span>
343
+ </div>
344
+ </div>
345
+ {/if}
346
+ {/snippet}
347
+ </Modal>
@@ -1,26 +1,34 @@
1
- export default Command;
2
- type Command = SvelteComponent<{
3
- [x: string]: never;
4
- }, {
5
- [evt: string]: CustomEvent<any>;
6
- }, {}> & {
7
- $$bindings?: string | undefined;
1
+ import type { SearchState, SearchOption } from '../hooks/use-search.svelte.js';
2
+ import { type IconData } from '../index.js';
3
+ type CommandGroup = {
4
+ label: string;
5
+ icon?: IconData;
6
+ options: SearchOption[];
7
+ };
8
+ type CommandLabels = {
9
+ placeholder?: string;
10
+ emptyText?: string;
11
+ loadingText?: string;
12
+ loadingMoreText?: string;
13
+ closeText?: string;
14
+ navigateText?: string;
15
+ selectText?: string;
16
+ toggleText?: string;
8
17
  };
9
- declare const Command: $$__sveltets_2_IsomorphicComponent<{
10
- [x: string]: never;
11
- }, {
12
- [evt: string]: CustomEvent<any>;
13
- }, {}, {}, string>;
14
- 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> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
16
- $$bindings?: Bindings;
17
- } & Exports;
18
- (internal: unknown, props: {
19
- $$events?: Events;
20
- $$slots?: Slots;
21
- }): Exports & {
22
- $set?: any;
23
- $on?: any;
24
- };
25
- z_$$bindings?: Bindings;
26
- }
18
+ type Props = {
19
+ search: SearchState;
20
+ open?: boolean;
21
+ labels?: CommandLabels;
22
+ color?: 'primary' | 'secondary' | 'muted' | 'success' | 'info' | 'warning' | 'danger';
23
+ disableOverlayClose?: boolean;
24
+ disableGlobalShortcut?: boolean;
25
+ shortcut?: string;
26
+ showFooter?: boolean;
27
+ groups?: CommandGroup[];
28
+ onselect?: (item: SearchOption) => void;
29
+ onclose?: () => void;
30
+ class?: string;
31
+ };
32
+ declare const Command: import("svelte").Component<Props, {}, "open">;
33
+ type Command = ReturnType<typeof Command>;
34
+ export default Command;
@@ -5,7 +5,7 @@
5
5
  import { fade } from 'svelte/transition';
6
6
  import { afterNavigate } from '$app/navigation';
7
7
  import { Dismiss24RegularIcon } from '../icons/index.js';
8
- import { Icon } from '../index.js';
8
+ import { IconButton } from '../index.js';
9
9
 
10
10
  type Props = {
11
11
  open: boolean;
@@ -18,10 +18,19 @@
18
18
  headerClass?: string;
19
19
  footerClass?: string;
20
20
  bodyClass?: string;
21
- variant?: 'ghost' | 'surface' | 'primary' | 'secondary' | 'muted';
21
+ color?:
22
+ | 'primary'
23
+ | 'secondary'
24
+ | 'muted'
25
+ | 'success'
26
+ | 'info'
27
+ | 'warning'
28
+ | 'danger'
29
+ | 'surface'
30
+ | 'background';
31
+ variant?: 'solid' | 'soft';
22
32
  disableOverlayClose?: boolean;
23
33
  hideCloseButton?: boolean;
24
- isSolid?: boolean;
25
34
  };
26
35
 
27
36
  let {
@@ -35,10 +44,10 @@
35
44
  headerClass,
36
45
  bodyClass,
37
46
  footerClass,
38
- variant = 'ghost',
47
+ color = 'background',
48
+ variant = 'solid',
39
49
  disableOverlayClose,
40
- hideCloseButton,
41
- isSolid
50
+ hideCloseButton
42
51
  }: Props = $props();
43
52
 
44
53
  const positionClasses = {
@@ -48,12 +57,33 @@
48
57
  bottom: 'is-bottom'
49
58
  };
50
59
 
51
- const variants = {
52
- ghost: 'is-ghost',
53
- surface: 'is-surface',
60
+ const colors = {
54
61
  primary: 'is-primary',
55
62
  secondary: 'is-secondary',
56
- muted: 'is-muted'
63
+ muted: 'is-muted',
64
+ success: 'is-success',
65
+ info: 'is-info',
66
+ danger: 'is-danger',
67
+ warning: 'is-warning',
68
+ surface: 'is-surface',
69
+ background: 'is-background'
70
+ };
71
+
72
+ const variants = {
73
+ solid: 'is-solid',
74
+ soft: 'is-soft'
75
+ };
76
+
77
+ const closeColors = {
78
+ primary: 'primary',
79
+ secondary: 'secondary',
80
+ muted: 'muted',
81
+ success: 'success',
82
+ info: 'info',
83
+ warning: 'warning',
84
+ danger: 'danger',
85
+ surface: 'muted',
86
+ background: 'muted'
57
87
  };
58
88
 
59
89
  let openDrawer = $state(false);
@@ -95,13 +125,7 @@
95
125
  <!-- svelte-ignore a11y_no_static_element_interactions -->
96
126
  <div class="drawer-overlay" onclick={handleOverlayClick}></div>
97
127
  <div
98
- class={cn(
99
- 'drawer',
100
- positionClasses[position],
101
- variants[variant],
102
- isSolid && 'is-solid',
103
- className
104
- )}
128
+ class={cn('drawer', positionClasses[position], variants[variant], colors[color], className)}
105
129
  class:is-active={openContent}
106
130
  >
107
131
  {#if header}
@@ -118,10 +142,14 @@
118
142
  </div>
119
143
  {/if}
120
144
  {#if !hideCloseButton}
121
- <div class="btn-close">
122
- <button onclick={() => (open = false)}>
123
- <Icon icon={Dismiss24RegularIcon} class="btn-close-icon" />
124
- </button>
145
+ <div class="drawer-btn-close">
146
+ <IconButton
147
+ icon={Dismiss24RegularIcon}
148
+ variant={variant === 'solid' ? 'soft' : 'solid'}
149
+ color={closeColors[color] as any}
150
+ size="xs"
151
+ onclick={() => (open = false)}
152
+ />
125
153
  </div>
126
154
  {/if}
127
155
  </div>
@@ -10,10 +10,10 @@ type Props = {
10
10
  headerClass?: string;
11
11
  footerClass?: string;
12
12
  bodyClass?: string;
13
- variant?: 'ghost' | 'surface' | 'primary' | 'secondary' | 'muted';
13
+ color?: 'primary' | 'secondary' | 'muted' | 'success' | 'info' | 'warning' | 'danger' | 'surface' | 'background';
14
+ variant?: 'solid' | 'soft';
14
15
  disableOverlayClose?: boolean;
15
16
  hideCloseButton?: boolean;
16
- isSolid?: boolean;
17
17
  };
18
18
  declare const Drawer: import("svelte").Component<Props, {}, "open">;
19
19
  type Drawer = ReturnType<typeof Drawer>;
@@ -14,13 +14,13 @@
14
14
 
15
15
  type Props = {
16
16
  options: Option[];
17
- variant?: 'primary' | 'secondary' | 'muted';
17
+ color?: 'primary' | 'secondary' | 'muted' | 'success' | 'danger' | 'warning' | 'info';
18
18
  children: Snippet;
19
19
  header?: Snippet;
20
20
  footer?: Snippet;
21
21
  };
22
22
 
23
- const { children, header, footer, options, variant = 'primary' }: Props = $props();
23
+ const { children, header, footer, options, color = 'primary' }: Props = $props();
24
24
 
25
25
  let isOpen = $state(false);
26
26
  let controlElement = $state<HTMLElement>();
@@ -131,7 +131,7 @@
131
131
  id={item.id}
132
132
  href={item.href}
133
133
  onclick={() => item.onclick?.(item)}
134
- {variant}
134
+ {color}
135
135
  size="sm"
136
136
  isCompact
137
137
  />
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import IconButton from '../control/IconButton.svelte';
2
3
  import { Dismiss24RegularIcon } from '../icons/index.js';
3
4
  import { Icon } from '../index.js';
4
5
  import { cn } from '../utils/class-names.js';
@@ -12,14 +13,23 @@
12
13
  children: Snippet;
13
14
  header?: Snippet;
14
15
  footer?: Snippet;
15
- class?: string;
16
+ rootClass?: string;
16
17
  headerClass?: string;
17
18
  footerClass?: string;
18
19
  contentClass?: string;
19
- variant?: 'ghost' | 'surface' | 'primary' | 'secondary' | 'muted';
20
+ color?:
21
+ | 'primary'
22
+ | 'secondary'
23
+ | 'muted'
24
+ | 'success'
25
+ | 'info'
26
+ | 'warning'
27
+ | 'danger'
28
+ | 'surface'
29
+ | 'background';
30
+ variant?: 'solid' | 'soft';
20
31
  disableOverlayClose?: boolean;
21
32
  hideCloseButton?: boolean;
22
- isSolid?: boolean;
23
33
  };
24
34
 
25
35
  let {
@@ -28,24 +38,45 @@
28
38
  header,
29
39
  footer,
30
40
  children,
31
- class: className,
41
+ rootClass,
32
42
  headerClass,
33
43
  contentClass,
34
44
  footerClass,
35
- variant = 'ghost',
45
+ color = 'background',
46
+ variant = 'solid',
36
47
  disableOverlayClose,
37
- hideCloseButton,
38
- isSolid
48
+ hideCloseButton
39
49
  }: Props = $props();
40
50
 
41
51
  let openContent = $state(false);
42
52
 
43
- const variants = {
44
- ghost: 'is-ghost',
45
- surface: 'is-surface',
53
+ const colors = {
46
54
  primary: 'is-primary',
47
55
  secondary: 'is-secondary',
48
- muted: 'is-muted'
56
+ muted: 'is-muted',
57
+ success: 'is-success',
58
+ info: 'is-info',
59
+ danger: 'is-danger',
60
+ warning: 'is-warning',
61
+ surface: 'is-surface',
62
+ background: 'is-background'
63
+ };
64
+
65
+ const variants = {
66
+ solid: 'is-solid',
67
+ soft: 'is-soft'
68
+ };
69
+
70
+ const closeColors = {
71
+ primary: 'primary',
72
+ secondary: 'secondary',
73
+ muted: 'muted',
74
+ success: 'success',
75
+ info: 'info',
76
+ warning: 'warning',
77
+ danger: 'danger',
78
+ surface: 'muted',
79
+ background: 'muted'
49
80
  };
50
81
 
51
82
  const handleOverlayClick = () => {
@@ -74,14 +105,14 @@
74
105
  {#if openContent}
75
106
  <div
76
107
  in:scale={{ duration: 100 }}
77
- class={cn('modal', variants[variant], isSolid && 'is-solid', className)}
108
+ class={cn('modal', variants[variant], colors[color], rootClass)}
78
109
  >
79
110
  {#if header}
80
111
  <div class={cn('modal-header', headerClass)}>
81
112
  {@render header()}
82
113
  </div>
83
114
  {/if}
84
- <div class={cn('modal-content', contentClass)}>
115
+ <div class={cn('modal-body', contentClass)}>
85
116
  {@render children()}
86
117
  </div>
87
118
  {#if footer}
@@ -91,9 +122,13 @@
91
122
  {/if}
92
123
  {#if !hideCloseButton}
93
124
  <div class="btn-close">
94
- <button onclick={() => (open = false)}>
95
- <Icon icon={Dismiss24RegularIcon} class="btn-close-icon" />
96
- </button>
125
+ <IconButton
126
+ icon={Dismiss24RegularIcon}
127
+ variant={variant === 'solid' ? 'soft' : 'solid'}
128
+ color={closeColors[color] as any}
129
+ size="xs"
130
+ onclick={() => (open = false)}
131
+ />
97
132
  </div>
98
133
  {/if}
99
134
  </div>
@@ -5,14 +5,14 @@ type Props = {
5
5
  children: Snippet;
6
6
  header?: Snippet;
7
7
  footer?: Snippet;
8
- class?: string;
8
+ rootClass?: string;
9
9
  headerClass?: string;
10
10
  footerClass?: string;
11
11
  contentClass?: string;
12
- variant?: 'ghost' | 'surface' | 'primary' | 'secondary' | 'muted';
12
+ color?: 'primary' | 'secondary' | 'muted' | 'success' | 'info' | 'warning' | 'danger' | 'surface' | 'background';
13
+ variant?: 'solid' | 'soft';
13
14
  disableOverlayClose?: boolean;
14
15
  hideCloseButton?: boolean;
15
- isSolid?: boolean;
16
16
  };
17
17
  declare const Modal: import("svelte").Component<Props, {}, "open">;
18
18
  type Modal = ReturnType<typeof Modal>;