@placeholderco/placeholder-ui 1.0.12 → 2.0.0

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 (276) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +134 -130
  3. package/dist/app.css +178 -0
  4. package/dist/bootstrap.min.css +3600 -0
  5. package/dist/cards/GitCard.svelte +115 -0
  6. package/dist/cards/GitCard.svelte.d.ts +22 -0
  7. package/dist/display/Avatar.svelte +29 -17
  8. package/dist/display/Avatar.svelte.d.ts +12 -2
  9. package/dist/display/LinkCollection.svelte +40 -18
  10. package/dist/display/LinkCollection.svelte.d.ts +9 -2
  11. package/dist/display/Paper.svelte +31 -19
  12. package/dist/display/Paper.svelte.d.ts +12 -3
  13. package/dist/display/alert/Alert.svelte +129 -0
  14. package/dist/display/alert/Alert.svelte.d.ts +15 -0
  15. package/dist/display/alert/AlertVariant.d.ts +1 -0
  16. package/dist/display/alert/AlertVariant.js +1 -0
  17. package/dist/display/filetree/FileTree.svelte +259 -0
  18. package/dist/display/filetree/FileTree.svelte.d.ts +76 -0
  19. package/dist/display/filetree/FileTreeItem.svelte +396 -0
  20. package/dist/display/filetree/FileTreeItem.svelte.d.ts +40 -0
  21. package/dist/display/filetree/FileTreeNode.d.ts +46 -0
  22. package/dist/display/filetree/FileTreeNode.js +115 -0
  23. package/dist/display/filetree/index.d.ts +5 -0
  24. package/dist/display/filetree/index.js +3 -0
  25. package/dist/editors/CodeMirror.svelte +306 -0
  26. package/dist/editors/CodeMirror.svelte.d.ts +31 -0
  27. package/dist/editors/tiptap/LinkActionMenu.svelte +307 -0
  28. package/dist/editors/tiptap/LinkActionMenu.svelte.d.ts +8 -0
  29. package/dist/editors/tiptap/TipTap.svelte +856 -0
  30. package/dist/editors/tiptap/TipTap.svelte.d.ts +54 -0
  31. package/dist/editors/tiptap/TipTapBubble.svelte +790 -0
  32. package/dist/editors/tiptap/TipTapBubble.svelte.d.ts +44 -0
  33. package/dist/editors/tiptap/collaboration.d.ts +55 -0
  34. package/dist/editors/tiptap/collaboration.js +1 -0
  35. package/dist/editors/tiptap/extensions/Alert.d.ts +18 -0
  36. package/dist/editors/tiptap/extensions/Alert.js +72 -0
  37. package/dist/editors/tiptap/extensions/CodeBlockEditor.d.ts +21 -0
  38. package/dist/editors/tiptap/extensions/CodeBlockEditor.js +326 -0
  39. package/dist/editors/tiptap/extensions/Div.d.ts +19 -0
  40. package/dist/editors/tiptap/extensions/Div.js +89 -0
  41. package/dist/editors/tiptap/extensions/Span.d.ts +5 -0
  42. package/dist/editors/tiptap/extensions/Span.js +56 -0
  43. package/dist/editors/tiptap/extensions/codeBlockEditor.css +236 -0
  44. package/dist/editors/tiptap/extensions/codeBlockLanguages.d.ts +17 -0
  45. package/dist/editors/tiptap/extensions/codeBlockLanguages.js +124 -0
  46. package/dist/editors/tiptap/extensions/index.d.ts +7 -0
  47. package/dist/editors/tiptap/extensions/index.js +5 -0
  48. package/dist/editors/tiptap/toolbar/AlertButton.svelte +261 -0
  49. package/dist/editors/tiptap/toolbar/AlertButton.svelte.d.ts +7 -0
  50. package/dist/editors/tiptap/toolbar/AlignCenterButton.svelte +18 -0
  51. package/dist/editors/tiptap/toolbar/AlignCenterButton.svelte.d.ts +7 -0
  52. package/dist/editors/tiptap/toolbar/AlignJustifyButton.svelte +18 -0
  53. package/dist/editors/tiptap/toolbar/AlignJustifyButton.svelte.d.ts +7 -0
  54. package/dist/editors/tiptap/toolbar/AlignLeftButton.svelte +18 -0
  55. package/dist/editors/tiptap/toolbar/AlignLeftButton.svelte.d.ts +7 -0
  56. package/dist/editors/tiptap/toolbar/AlignRightButton.svelte +18 -0
  57. package/dist/editors/tiptap/toolbar/AlignRightButton.svelte.d.ts +7 -0
  58. package/dist/editors/tiptap/toolbar/BoldButton.svelte +18 -0
  59. package/dist/editors/tiptap/toolbar/BoldButton.svelte.d.ts +7 -0
  60. package/dist/editors/tiptap/toolbar/BulletListButton.svelte +18 -0
  61. package/dist/editors/tiptap/toolbar/BulletListButton.svelte.d.ts +7 -0
  62. package/dist/editors/tiptap/toolbar/CodeBlockButton.svelte +18 -0
  63. package/dist/editors/tiptap/toolbar/CodeBlockButton.svelte.d.ts +7 -0
  64. package/dist/editors/tiptap/toolbar/CodeButton.svelte +18 -0
  65. package/dist/editors/tiptap/toolbar/CodeButton.svelte.d.ts +7 -0
  66. package/dist/editors/tiptap/toolbar/ColorButton.svelte +299 -0
  67. package/dist/editors/tiptap/toolbar/ColorButton.svelte.d.ts +20 -0
  68. package/dist/editors/tiptap/toolbar/DocumentButton.svelte +58 -0
  69. package/dist/editors/tiptap/toolbar/DocumentButton.svelte.d.ts +9 -0
  70. package/dist/editors/tiptap/toolbar/HeadingButton.svelte +30 -0
  71. package/dist/editors/tiptap/toolbar/HeadingButton.svelte.d.ts +8 -0
  72. package/dist/editors/tiptap/toolbar/HtmlButton.svelte +68 -0
  73. package/dist/editors/tiptap/toolbar/HtmlButton.svelte.d.ts +7 -0
  74. package/dist/editors/tiptap/toolbar/ImageButton.svelte +54 -0
  75. package/dist/editors/tiptap/toolbar/ImageButton.svelte.d.ts +8 -0
  76. package/dist/editors/tiptap/toolbar/ItalicButton.svelte +18 -0
  77. package/dist/editors/tiptap/toolbar/ItalicButton.svelte.d.ts +7 -0
  78. package/dist/editors/tiptap/toolbar/LinkButton.svelte +257 -0
  79. package/dist/editors/tiptap/toolbar/LinkButton.svelte.d.ts +7 -0
  80. package/dist/editors/tiptap/toolbar/OrderedListButton.svelte +18 -0
  81. package/dist/editors/tiptap/toolbar/OrderedListButton.svelte.d.ts +7 -0
  82. package/dist/editors/tiptap/toolbar/RedoButton.svelte +18 -0
  83. package/dist/editors/tiptap/toolbar/RedoButton.svelte.d.ts +7 -0
  84. package/dist/editors/tiptap/toolbar/StrikethroughButton.svelte +18 -0
  85. package/dist/editors/tiptap/toolbar/StrikethroughButton.svelte.d.ts +7 -0
  86. package/dist/editors/tiptap/toolbar/SubscriptButton.svelte +18 -0
  87. package/dist/editors/tiptap/toolbar/SubscriptButton.svelte.d.ts +7 -0
  88. package/dist/editors/tiptap/toolbar/SuperscriptButton.svelte +18 -0
  89. package/dist/editors/tiptap/toolbar/SuperscriptButton.svelte.d.ts +7 -0
  90. package/dist/editors/tiptap/toolbar/TableButton.svelte +258 -0
  91. package/dist/editors/tiptap/toolbar/TableButton.svelte.d.ts +7 -0
  92. package/dist/editors/tiptap/toolbar/ToolbarButton.svelte +84 -0
  93. package/dist/editors/tiptap/toolbar/ToolbarButton.svelte.d.ts +10 -0
  94. package/dist/editors/tiptap/toolbar/UnderlineButton.svelte +18 -0
  95. package/dist/editors/tiptap/toolbar/UnderlineButton.svelte.d.ts +7 -0
  96. package/dist/editors/tiptap/toolbar/UndoButton.svelte +18 -0
  97. package/dist/editors/tiptap/toolbar/UndoButton.svelte.d.ts +7 -0
  98. package/dist/form/Autocomplete.svelte +86 -135
  99. package/dist/form/Autocomplete.svelte.d.ts +6 -8
  100. package/dist/form/AutocompleteMulti.svelte +385 -227
  101. package/dist/form/AutocompleteMulti.svelte.d.ts +59 -10
  102. package/dist/form/Checkbox.svelte +59 -54
  103. package/dist/form/Checkbox.svelte.d.ts +14 -5
  104. package/dist/form/Chips.svelte +29 -13
  105. package/dist/form/Chips.svelte.d.ts +16 -2
  106. package/dist/form/ComboBox.svelte +30 -20
  107. package/dist/form/ComboBox.svelte.d.ts +1 -1
  108. package/dist/form/ComboBoxItemBuilder.svelte +161 -188
  109. package/dist/form/ComboBoxItemBuilder.svelte.d.ts +19 -2
  110. package/dist/form/ComboBoxMulti.svelte +38 -24
  111. package/dist/form/ComboBoxMulti.svelte.d.ts +1 -1
  112. package/dist/form/CronBuilder.svelte +84 -67
  113. package/dist/form/CronBuilder.svelte.d.ts +16 -3
  114. package/dist/form/DatePicker.svelte +148 -195
  115. package/dist/form/DateRangePicker.svelte +101 -98
  116. package/dist/form/DateTimePicker.svelte +167 -208
  117. package/dist/form/DateTimePicker.svelte.d.ts +10 -2
  118. package/dist/form/FormGroup.svelte +33 -10
  119. package/dist/form/FormGroup.svelte.d.ts +12 -2
  120. package/dist/form/Number.svelte +70 -47
  121. package/dist/form/Number.svelte.d.ts +36 -6
  122. package/dist/form/Radio.svelte +18 -18
  123. package/dist/form/RadioGroup.svelte +23 -12
  124. package/dist/form/RadioGroup.svelte.d.ts +13 -2
  125. package/dist/form/SegmentedControl.svelte +76 -56
  126. package/dist/form/SegmentedControl.svelte.d.ts +9 -4
  127. package/dist/form/Select.svelte +150 -233
  128. package/dist/form/Select.svelte.d.ts +29 -5
  129. package/dist/form/SelectMulti.svelte +163 -277
  130. package/dist/form/SelectMulti.svelte.d.ts +36 -7
  131. package/dist/form/Slider.svelte +183 -269
  132. package/dist/form/Slider.svelte.d.ts +32 -17
  133. package/dist/form/StringArrayBuilder.svelte +249 -0
  134. package/dist/form/StringArrayBuilder.svelte.d.ts +15 -0
  135. package/dist/form/Switch.svelte +164 -106
  136. package/dist/form/Switch.svelte.d.ts +22 -3
  137. package/dist/form/TextArea.svelte +49 -29
  138. package/dist/form/TextArea.svelte.d.ts +23 -3
  139. package/dist/form/Textbox.svelte +69 -68
  140. package/dist/form/Textbox.svelte.d.ts +32 -4
  141. package/dist/form/TimePicker.svelte +42 -47
  142. package/dist/form/TimePicker.svelte.d.ts +12 -2
  143. package/dist/form/comboBoxCore.svelte.d.ts +99 -0
  144. package/dist/form/comboBoxCore.svelte.js +243 -0
  145. package/dist/icon/Icon.svelte +8 -3
  146. package/dist/icon/Icon.svelte.d.ts +8 -3
  147. package/dist/icon/file-type-bmp.svg +1 -0
  148. package/dist/icon/file-type-csv.svg +1 -0
  149. package/dist/icon/file-type-doc.svg +1 -0
  150. package/dist/icon/file-type-docx.svg +1 -0
  151. package/dist/icon/file-type-jpg.svg +1 -0
  152. package/dist/icon/file-type-pdf.svg +1 -0
  153. package/dist/icon/file-type-png.svg +1 -0
  154. package/dist/icon/file-type-ppt.svg +1 -0
  155. package/dist/icon/file-type-svg.svg +1 -0
  156. package/dist/icon/file-type-txt.svg +1 -0
  157. package/dist/icon/file-type-xls.svg +1 -0
  158. package/dist/icon/file-type-zip.svg +1 -0
  159. package/dist/icon/index.d.ts +166 -151
  160. package/dist/icon/index.js +166 -152
  161. package/dist/icon/logo-placeholder.svg +6 -0
  162. package/dist/icon/source-code.svg +1 -0
  163. package/dist/icon/sun-moon.svg +1 -0
  164. package/dist/icon/table.svg +6 -0
  165. package/dist/index.d.ts +87 -26
  166. package/dist/index.js +25 -28
  167. package/dist/layout/AppShell.svelte +12 -162
  168. package/dist/layout/AppShell.svelte.d.ts +6 -27
  169. package/dist/layout/CustomNavbar.svelte +9 -7
  170. package/dist/layout/CustomNavbar.svelte.d.ts +4 -2
  171. package/dist/layout/Navbar.svelte +161 -129
  172. package/dist/layout/Navbar.svelte.d.ts +29 -15
  173. package/dist/layout/NavbarItemDisplay.svelte +2 -2
  174. package/dist/layout/NavbarItemView.svelte +182 -0
  175. package/dist/layout/NavbarItemView.svelte.d.ts +10 -0
  176. package/dist/layout/Sidenav.svelte +280 -341
  177. package/dist/layout/Sidenav.svelte.d.ts +36 -4
  178. package/dist/models/ComboBoxItem.d.ts +2 -0
  179. package/dist/models/Employee.d.ts +53 -0
  180. package/dist/models/Employee.js +23 -0
  181. package/dist/models/Hyperlink.d.ts +3 -1
  182. package/dist/models/LinkCollectionItem.d.ts +3 -1
  183. package/dist/models/NavbarItem.d.ts +6 -2
  184. package/dist/theme.svelte.d.ts +0 -1
  185. package/dist/theme.svelte.js +46 -58
  186. package/dist/ui/Accordion.svelte +81 -242
  187. package/dist/ui/Accordion.svelte.d.ts +37 -14
  188. package/dist/ui/AccordionItem.svelte +303 -0
  189. package/dist/ui/AccordionItem.svelte.d.ts +21 -0
  190. package/dist/ui/ActionIcon.svelte +25 -21
  191. package/dist/ui/ActionIcon.svelte.d.ts +15 -2
  192. package/dist/ui/Badge.svelte +163 -171
  193. package/dist/ui/Badge.svelte.d.ts +13 -5
  194. package/dist/ui/Button.svelte +178 -205
  195. package/dist/ui/Button.svelte.d.ts +19 -2
  196. package/dist/ui/ButtonVariant.d.ts +15 -1
  197. package/dist/ui/ContextMenu.svelte +146 -0
  198. package/dist/ui/ContextMenu.svelte.d.ts +37 -0
  199. package/dist/ui/ContextMenuList.svelte +188 -0
  200. package/dist/ui/ContextMenuList.svelte.d.ts +12 -0
  201. package/dist/ui/Dialog.svelte +183 -111
  202. package/dist/ui/Dialog.svelte.d.ts +21 -4
  203. package/dist/ui/Drawer.svelte +237 -184
  204. package/dist/ui/Drawer.svelte.d.ts +20 -2
  205. package/dist/ui/Dropdown.svelte +24 -14
  206. package/dist/ui/Dropdown.svelte.d.ts +11 -2
  207. package/dist/ui/Dropzone.svelte +159 -57
  208. package/dist/ui/Dropzone.svelte.d.ts +29 -2
  209. package/dist/ui/Link.svelte +12 -4
  210. package/dist/ui/Link.svelte.d.ts +8 -2
  211. package/dist/ui/Loader.svelte +23 -18
  212. package/dist/ui/Loader.svelte.d.ts +5 -2
  213. package/dist/ui/Logo.svelte +37 -0
  214. package/dist/ui/Logo.svelte.d.ts +16 -0
  215. package/dist/ui/MultiSortable.svelte +287 -0
  216. package/dist/ui/MultiSortable.svelte.d.ts +50 -0
  217. package/dist/ui/Pagination.svelte +15 -9
  218. package/dist/ui/Pagination.svelte.d.ts +6 -2
  219. package/dist/ui/Popover.svelte +43 -65
  220. package/dist/ui/Popover.svelte.d.ts +14 -5
  221. package/dist/ui/ProgressBar.svelte +28 -30
  222. package/dist/ui/ProgressBarVariant.d.ts +7 -1
  223. package/dist/ui/SegmentedControl.svelte +0 -0
  224. package/dist/ui/SegmentedControl.svelte.d.ts +26 -0
  225. package/dist/ui/Sortable.svelte +163 -0
  226. package/dist/ui/Sortable.svelte.d.ts +47 -0
  227. package/dist/ui/Table.svelte +383 -80
  228. package/dist/ui/Table.svelte.d.ts +43 -2
  229. package/dist/ui/Tabs.svelte +22 -18
  230. package/dist/ui/Tabs.svelte.d.ts +6 -2
  231. package/dist/ui/ThemeSwitcher.svelte +26 -7
  232. package/dist/ui/ThemeSwitcher.svelte.d.ts +4 -2
  233. package/dist/ui/Tooltip.svelte +312 -180
  234. package/dist/ui/Tooltip.svelte.d.ts +4 -3
  235. package/dist/uiTheme.svelte.d.ts +86 -0
  236. package/dist/uiTheme.svelte.js +214 -0
  237. package/dist/util/DateFunctions.js +1 -1
  238. package/dist/util/DragDrop.d.ts +50 -0
  239. package/dist/util/DragDrop.js +154 -0
  240. package/dist/util/NavigateTo.js +2 -2
  241. package/dist/util/dayjs.d.ts +4 -0
  242. package/dist/util/dayjs.js +15 -0
  243. package/package.json +66 -26
  244. package/dist/display/Alert.svelte +0 -179
  245. package/dist/display/Alert.svelte.d.ts +0 -13
  246. package/dist/form/FileInput.svelte +0 -235
  247. package/dist/form/FileInput.svelte.d.ts +0 -23
  248. package/dist/form/PasswordInput.svelte +0 -253
  249. package/dist/form/PasswordInput.svelte.d.ts +0 -34
  250. package/dist/form/Rating.svelte +0 -235
  251. package/dist/form/Rating.svelte.d.ts +0 -21
  252. package/dist/styles/components.css +0 -199
  253. package/dist/styles/dark.css +0 -146
  254. package/dist/styles/index.css +0 -116
  255. package/dist/styles/reset.css +0 -110
  256. package/dist/styles/semantic.css +0 -86
  257. package/dist/styles/tokens.css +0 -203
  258. package/dist/styles/utilities.css +0 -523
  259. package/dist/ui/Breadcrumbs.svelte +0 -131
  260. package/dist/ui/Breadcrumbs.svelte.d.ts +0 -16
  261. package/dist/ui/LoadingOverlay.svelte +0 -53
  262. package/dist/ui/LoadingOverlay.svelte.d.ts +0 -11
  263. package/dist/ui/Progress.svelte +0 -191
  264. package/dist/ui/Progress.svelte.d.ts +0 -15
  265. package/dist/ui/RingProgress.svelte +0 -141
  266. package/dist/ui/RingProgress.svelte.d.ts +0 -18
  267. package/dist/ui/Skeleton.svelte +0 -85
  268. package/dist/ui/Skeleton.svelte.d.ts +0 -12
  269. package/dist/ui/Stepper.svelte +0 -355
  270. package/dist/ui/Stepper.svelte.d.ts +0 -24
  271. package/dist/ui/Timeline.svelte +0 -225
  272. package/dist/ui/Timeline.svelte.d.ts +0 -23
  273. /package/dist/{actions → util}/ClickOutside.d.ts +0 -0
  274. /package/dist/{actions → util}/ClickOutside.js +0 -0
  275. /package/dist/{transitions → util}/Transitions.d.ts +0 -0
  276. /package/dist/{transitions → util}/Transitions.js +0 -0
@@ -0,0 +1,249 @@
1
+ <script module lang="ts">
2
+ export interface StringArrayBuilderProps {
3
+ /** Label text displayed above the builder */
4
+ label?: string;
5
+ /** Array of string values (bindable) */
6
+ items?: string[];
7
+ /** Placeholder for value input field */
8
+ placeholder?: string;
9
+ /** Additional CSS classes */
10
+ class?: string;
11
+ /** Callback when items change */
12
+ onchange?: (items: string[]) => void;
13
+ }
14
+ </script>
15
+
16
+ <script lang="ts">
17
+ import ActionIcon from '../ui/ActionIcon.svelte';
18
+ import Button from '../ui/Button.svelte';
19
+ import { iconPlus, iconTrash } from '../icon/index.js';
20
+ import FormGroup from './FormGroup.svelte';
21
+
22
+ let {
23
+ label = '',
24
+ items = $bindable([]),
25
+ placeholder = 'Value',
26
+ class: classes = '',
27
+ onchange
28
+ }: StringArrayBuilderProps = $props();
29
+
30
+ let newValue = $state('');
31
+ let valueInputEl: HTMLInputElement | undefined = $state(undefined);
32
+
33
+ function valueExists(value: string, excludeIndex: number | undefined = undefined): boolean {
34
+ return items.some((item, i) => item === value && i !== excludeIndex);
35
+ }
36
+
37
+ let isDuplicateNewValue = $derived(
38
+ newValue.trim() !== '' && valueExists(newValue.trim())
39
+ );
40
+
41
+ function addItem() {
42
+ const trimmed = newValue.trim();
43
+ if (!trimmed) return;
44
+ if (isDuplicateNewValue) return;
45
+
46
+ items = [...items, trimmed];
47
+ newValue = '';
48
+
49
+ notifyChange();
50
+
51
+ valueInputEl?.focus();
52
+ }
53
+
54
+ function removeItem(index: number) {
55
+ items = items.filter((_, i) => i !== index);
56
+ notifyChange();
57
+ }
58
+
59
+ function updateItem(index: number, newVal: string) {
60
+ if (valueExists(newVal, index)) return;
61
+
62
+ items = items.map((item, i) => (i === index ? newVal : item));
63
+ notifyChange();
64
+ }
65
+
66
+ function notifyChange() {
67
+ onchange?.(items);
68
+ }
69
+
70
+ function handleKeyDown(e: KeyboardEvent) {
71
+ if (e.key === 'Enter') {
72
+ e.preventDefault();
73
+ addItem();
74
+ }
75
+ }
76
+ </script>
77
+
78
+ <div class="string-array-builder {classes}">
79
+ {#if label}
80
+ <FormGroup {label}>
81
+ <div></div>
82
+ </FormGroup>
83
+ {/if}
84
+
85
+ <div class="builder-content">
86
+ <!-- Existing items -->
87
+ {#each items as item, index (index)}
88
+ <div class="item-row">
89
+ <div class="col-value">
90
+ <input
91
+ type="text"
92
+ class="item-input"
93
+ value={item}
94
+ oninput={(e) => updateItem(index, e.currentTarget.value)}
95
+ {placeholder}
96
+ />
97
+ </div>
98
+ <div class="col-actions">
99
+ <ActionIcon
100
+ variant="danger-subtle"
101
+ svg={iconTrash}
102
+ size="1rem"
103
+ onclick={() => removeItem(index)}
104
+ tooltip="Remove item"
105
+ />
106
+ </div>
107
+ </div>
108
+ {/each}
109
+
110
+ <!-- Add new item row -->
111
+ <div class="add-row">
112
+ <div class="col-value">
113
+ <input
114
+ bind:this={valueInputEl}
115
+ type="text"
116
+ class="item-input new-input"
117
+ class:error={isDuplicateNewValue}
118
+ value={newValue}
119
+ oninput={(e) => (newValue = e.currentTarget.value)}
120
+ {placeholder}
121
+ onkeydown={handleKeyDown}
122
+ />
123
+ </div>
124
+ <div class="col-actions">
125
+ <ActionIcon
126
+ variant="auto-subtle"
127
+ svg={iconPlus}
128
+ size="1rem"
129
+ onclick={addItem}
130
+ disabled={!newValue.trim() || isDuplicateNewValue}
131
+ tooltip="Add item"
132
+ />
133
+ </div>
134
+ </div>
135
+
136
+ {#if isDuplicateNewValue}
137
+ <div class="error-message">
138
+ Value "{newValue}" already exists
139
+ </div>
140
+ {/if}
141
+
142
+ <!-- Quick add button for mobile/convenience -->
143
+ {#if newValue.trim() && !isDuplicateNewValue}
144
+ <div class="quick-add">
145
+ <Button variant="auto-subtle" onclick={addItem}>
146
+ Add "{newValue}"
147
+ </Button>
148
+ </div>
149
+ {/if}
150
+ </div>
151
+
152
+ <!-- Summary -->
153
+ {#if items.length > 0}
154
+ <div class="summary">
155
+ <span class="summary-count">{items.length} item{items.length !== 1 ? 's' : ''}</span>
156
+ </div>
157
+ {/if}
158
+ </div>
159
+
160
+ <style>
161
+ .string-array-builder {
162
+ width: 100%;
163
+ }
164
+
165
+ .item-row,
166
+ .add-row {
167
+ display: grid;
168
+ grid-template-columns: 1fr 2.5rem;
169
+ gap: 0.5rem;
170
+ padding: 0.25rem 0;
171
+ align-items: center;
172
+ }
173
+
174
+ .col-actions {
175
+ display: flex;
176
+ justify-content: center;
177
+ align-items: center;
178
+ }
179
+
180
+ .item-input {
181
+ width: 100%;
182
+ padding: 0.375rem 0.5rem;
183
+ border: 1px solid var(--border-color);
184
+ border-radius: 0.25rem;
185
+ background-color: var(--input-bg-color);
186
+ color: var(--text-color);
187
+ font-size: 0.875rem;
188
+ transition: border-color 0.15s;
189
+ }
190
+
191
+ .item-input:focus {
192
+ outline: none;
193
+ border-color: var(--accent-color);
194
+ }
195
+
196
+ .item-input::placeholder {
197
+ color: var(--placeholder-color);
198
+ }
199
+
200
+ .new-input {
201
+ background-color: transparent;
202
+ }
203
+
204
+ .item-input.error {
205
+ border-color: var(--danger-text);
206
+ }
207
+
208
+ .item-input.error:focus {
209
+ border-color: var(--danger-text);
210
+ }
211
+
212
+ .error-message {
213
+ padding: 0.375rem 0;
214
+ font-size: 0.75rem;
215
+ color: var(--danger-text);
216
+ }
217
+
218
+ .quick-add {
219
+ padding: 0.5rem 0;
220
+ display: flex;
221
+ justify-content: flex-end;
222
+ }
223
+
224
+ .summary {
225
+ display: flex;
226
+ gap: 1rem;
227
+ padding: 0.5rem 0;
228
+ font-size: 0.875rem;
229
+ color: var(--text-muted);
230
+ margin-top: 0.5rem;
231
+ }
232
+
233
+ .summary-count {
234
+ font-weight: 500;
235
+ }
236
+
237
+ @media (max-width: 480px) {
238
+ .item-row,
239
+ .add-row {
240
+ grid-template-columns: 1fr 2rem;
241
+ gap: 0.25rem;
242
+ }
243
+
244
+ .item-input {
245
+ padding: 0.25rem 0.375rem;
246
+ font-size: 0.8125rem;
247
+ }
248
+ }
249
+ </style>
@@ -0,0 +1,15 @@
1
+ export interface StringArrayBuilderProps {
2
+ /** Label text displayed above the builder */
3
+ label?: string;
4
+ /** Array of string values (bindable) */
5
+ items?: string[];
6
+ /** Placeholder for value input field */
7
+ placeholder?: string;
8
+ /** Additional CSS classes */
9
+ class?: string;
10
+ /** Callback when items change */
11
+ onchange?: (items: string[]) => void;
12
+ }
13
+ declare const StringArrayBuilder: import("svelte").Component<StringArrayBuilderProps, {}, "items">;
14
+ type StringArrayBuilder = ReturnType<typeof StringArrayBuilder>;
15
+ export default StringArrayBuilder;
@@ -1,113 +1,171 @@
1
+ <script module lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ export interface SwitchProps {
5
+ /** Label text displayed above the switch */
6
+ label?: string;
7
+ /** Mark field as required (shows asterisk) */
8
+ required?: boolean;
9
+ /** Whether the switch is on (bindable) */
10
+ checked: boolean;
11
+ /** Disable the switch */
12
+ disabled?: boolean;
13
+ /** CSS classes for the container element */
14
+ containerClass?: string;
15
+ /** CSS classes for the switch element */
16
+ switchClass?: string;
17
+ /** Custom ID for the switch element */
18
+ inputId?: string;
19
+ /** Callback when switch state changes */
20
+ onchange?: (value: boolean) => void;
21
+ /** Show error state styling */
22
+ showError?: boolean;
23
+ /** Error message to display */
24
+ errorText?: string;
25
+ /** Simple tooltip text */
26
+ tooltipText?: string;
27
+ /** Position of the tooltip */
28
+ tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
29
+ /** Rich tooltip content using a Svelte snippet */
30
+ tooltipContent?: Snippet;
31
+ }
32
+ </script>
33
+
1
34
  <script lang="ts">
2
- import FormGroup from "./FormGroup.svelte";
3
-
4
- interface Props {
5
- label: string;
6
- required?: boolean;
7
- checked: boolean;
8
- disabled?: boolean;
9
- containerClass?: string;
10
- switchClass?: string;
11
- onchange?: (value: boolean) => void;
12
- showError?: boolean;
13
- }
14
-
15
- let {
16
- label,
17
- required = false,
18
- checked = $bindable(),
19
- disabled = false,
20
- containerClass,
21
- switchClass,
22
- onchange,
23
- showError,
24
- }: Props = $props();
25
-
26
- function handleClick(event: Event) {
27
- const target = event.target as HTMLElement;
28
- const state = target.getAttribute("aria-checked");
29
- checked = !(state === "true");
30
- onchange?.(checked);
31
- }
35
+ import { Icon, iconInfoCircle } from '../icon/index.js';
36
+ import Tooltip from '../ui/Tooltip.svelte';
37
+
38
+ let {
39
+ label,
40
+ required = false,
41
+ checked = $bindable(),
42
+ disabled = false,
43
+ containerClass = '',
44
+ switchClass = '',
45
+ inputId = undefined,
46
+ onchange,
47
+ showError = false,
48
+ errorText = '',
49
+ tooltipText = undefined,
50
+ tooltipLocation = 'top',
51
+ tooltipContent = undefined
52
+ }: SwitchProps = $props();
53
+
54
+ const nonce = Math.random().toString(36).substring(2, 15);
55
+
56
+ const id = $derived(inputId ? inputId : label ? `switch-${label}` : `switch-${nonce}`);
57
+
58
+ function handleClick() {
59
+ if (disabled) return;
60
+ checked = !checked;
61
+ onchange?.(checked);
62
+ }
32
63
  </script>
33
64
 
34
- <div class="switch-container {containerClass}">
35
- <FormGroup {required} {label}>
36
- <div
37
- class="switch-track {switchClass}"
38
- class:error={showError}
39
- class:disabled
40
- >
41
- <button
42
- role="switch"
43
- aria-checked={checked}
44
- aria-labelledby="form-{label}"
45
- onclick={handleClick}
46
- {disabled}
47
- ></button>
48
- </div>
49
- </FormGroup>
65
+ <div class="switch-container {containerClass} {disabled ? 'disabled' : ''}">
66
+ <label for={id}>
67
+ <span class="label-text"
68
+ >{label}
69
+ {#if required}
70
+ <span class="required">*</span>
71
+ {/if}
72
+ {#if tooltipContent || tooltipText}
73
+ <Tooltip {tooltipContent} location={tooltipLocation} text={tooltipText}>
74
+ <Icon svg={iconInfoCircle} size="1em" stroke="var(--accent-color)" />
75
+ </Tooltip>
76
+ {/if}</span
77
+ >
78
+ <button
79
+ {id}
80
+ role="switch"
81
+ type="button"
82
+ aria-checked={checked}
83
+ aria-label={label || 'Toggle switch'}
84
+ onclick={handleClick}
85
+ class="switch {switchClass} {showError ? 'error' : ''} {disabled ? 'disabled' : ''}"
86
+ {disabled}
87
+ >
88
+ </button>
89
+ </label>
90
+ {#if showError && errorText}
91
+ <div class="error-text">{errorText}</div>
92
+ {/if}
50
93
  </div>
51
94
 
52
95
  <style>
53
- .switch-container {
54
- --switch-track-color: var(--pui-border-disabled);
55
- }
56
-
57
- :global(.dark) .switch-container {
58
- --switch-track-color: var(--pui-color-gray-600);
59
- }
60
-
61
- .switch-track {
62
- display: flex;
63
- align-items: center;
64
- }
65
-
66
- button {
67
- width: 3em;
68
- height: 1.6em;
69
- position: relative;
70
- margin: 0 0 0 var(--pui-spacing-2);
71
- padding: 0;
72
- background: var(--switch-track-color);
73
- border: none;
74
- border-radius: var(--pui-radius-3xl);
75
- cursor: pointer;
76
- transition: background-color var(--pui-transition-fast)
77
- var(--pui-ease-in-out);
78
- }
79
-
80
- button::before {
81
- content: "";
82
- position: absolute;
83
- width: 1.3em;
84
- height: 1.3em;
85
- top: 0.15em;
86
- right: 1.5em;
87
- background: var(--pui-color-white);
88
- border-radius: var(--pui-radius-full);
89
- transition: transform var(--pui-transition-slow) var(--pui-ease-in-out);
90
- }
91
-
92
- button[aria-checked="true"] {
93
- background-color: var(--pui-color-primary);
94
- }
95
-
96
- button[aria-checked="true"]::before {
97
- transform: translateX(1.3em);
98
- }
99
-
100
- button:focus-visible {
101
- outline: 2px solid var(--pui-color-primary);
102
- outline-offset: var(--pui-focus-ring-offset);
103
- }
104
-
105
- .disabled button {
106
- opacity: 0.5;
107
- cursor: not-allowed;
108
- }
109
-
110
- .error button {
111
- outline: 1px solid var(--pui-text-danger);
112
- }
96
+ :root .switch-container {
97
+ --accent-color: var(--ui-primary);
98
+ --gray: #ccc;
99
+ }
100
+
101
+ :global(.dark) .switch-container {
102
+ --accent-color: var(--ui-primary);
103
+ --gray: #444;
104
+ }
105
+
106
+ label {
107
+ display: flex;
108
+ flex-direction: column;
109
+ align-items: flex-start;
110
+ user-select: none;
111
+ cursor: pointer;
112
+ }
113
+
114
+ .disabled label {
115
+ cursor: not-allowed;
116
+ }
117
+
118
+ .switch {
119
+ width: 3em;
120
+ height: 1.6em;
121
+ position: relative;
122
+ margin: 4px 0 0 0;
123
+ background: var(--gray);
124
+ border: none;
125
+ border-radius: 1.5em;
126
+ cursor: pointer;
127
+ }
128
+
129
+ .switch::before {
130
+ content: '';
131
+ position: absolute;
132
+ width: 1.3em;
133
+ height: 1.3em;
134
+ background: #fff;
135
+ top: 0.13em;
136
+ right: 1.5em;
137
+ border-radius: 100%;
138
+ transition: transform 0.3s;
139
+ }
140
+
141
+ .switch[aria-checked='true'] {
142
+ background-color: var(--ui-primary);
143
+ }
144
+
145
+ .switch[aria-checked='true']::before {
146
+ transform: translateX(1.3em);
147
+ transition: transform 0.3s;
148
+ }
149
+
150
+ .switch:focus {
151
+ outline: 1px solid var(--ui-primary);
152
+ outline-offset: 2px;
153
+ }
154
+
155
+ .switch.disabled {
156
+ cursor: not-allowed;
157
+ opacity: 0.5;
158
+ }
159
+
160
+ .switch.error {
161
+ outline: 1px solid var(--danger-text);
162
+ }
163
+
164
+ .required {
165
+ color: var(--danger-text);
166
+ }
167
+
168
+ .error-text {
169
+ color: var(--danger-text);
170
+ }
113
171
  </style>
@@ -1,13 +1,32 @@
1
- interface Props {
2
- label: string;
1
+ import type { Snippet } from 'svelte';
2
+ export interface SwitchProps {
3
+ /** Label text displayed above the switch */
4
+ label?: string;
5
+ /** Mark field as required (shows asterisk) */
3
6
  required?: boolean;
7
+ /** Whether the switch is on (bindable) */
4
8
  checked: boolean;
9
+ /** Disable the switch */
5
10
  disabled?: boolean;
11
+ /** CSS classes for the container element */
6
12
  containerClass?: string;
13
+ /** CSS classes for the switch element */
7
14
  switchClass?: string;
15
+ /** Custom ID for the switch element */
16
+ inputId?: string;
17
+ /** Callback when switch state changes */
8
18
  onchange?: (value: boolean) => void;
19
+ /** Show error state styling */
9
20
  showError?: boolean;
21
+ /** Error message to display */
22
+ errorText?: string;
23
+ /** Simple tooltip text */
24
+ tooltipText?: string;
25
+ /** Position of the tooltip */
26
+ tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
27
+ /** Rich tooltip content using a Svelte snippet */
28
+ tooltipContent?: Snippet;
10
29
  }
11
- declare const Switch: import("svelte").Component<Props, {}, "checked">;
30
+ declare const Switch: import("svelte").Component<SwitchProps, {}, "checked">;
12
31
  type Switch = ReturnType<typeof Switch>;
13
32
  export default Switch;