@placeholderco/placeholder-ui 1.0.11 → 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 (289) 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 +270 -137
  99. package/dist/form/Autocomplete.svelte.d.ts +58 -10
  100. package/dist/form/AutocompleteMulti.svelte +385 -227
  101. package/dist/form/AutocompleteMulti.svelte.d.ts +59 -10
  102. package/dist/form/Checkbox.svelte +124 -43
  103. package/dist/form/Checkbox.svelte.d.ts +26 -2
  104. package/dist/form/Chips.svelte +47 -17
  105. package/dist/form/Chips.svelte.d.ts +24 -3
  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 +177 -191
  115. package/dist/form/DatePicker.svelte.d.ts +17 -2
  116. package/dist/form/DateRangePicker.svelte +775 -0
  117. package/dist/form/DateRangePicker.svelte.d.ts +23 -0
  118. package/dist/form/DateTimePicker.svelte +168 -209
  119. package/dist/form/DateTimePicker.svelte.d.ts +10 -2
  120. package/dist/form/FormGroup.svelte +33 -10
  121. package/dist/form/FormGroup.svelte.d.ts +12 -2
  122. package/dist/form/Number.svelte +71 -29
  123. package/dist/form/Number.svelte.d.ts +39 -6
  124. package/dist/form/Radio.svelte +174 -0
  125. package/dist/form/Radio.svelte.d.ts +21 -0
  126. package/dist/form/RadioGroup.svelte +52 -138
  127. package/dist/form/RadioGroup.svelte.d.ts +19 -2
  128. package/dist/form/SegmentedControl.svelte +103 -57
  129. package/dist/form/SegmentedControl.svelte.d.ts +12 -2
  130. package/dist/form/Select.svelte +160 -229
  131. package/dist/form/Select.svelte.d.ts +35 -6
  132. package/dist/form/SelectMulti.svelte +166 -277
  133. package/dist/form/SelectMulti.svelte.d.ts +37 -6
  134. package/dist/form/Slider.svelte +185 -268
  135. package/dist/form/Slider.svelte.d.ts +33 -16
  136. package/dist/form/StringArrayBuilder.svelte +249 -0
  137. package/dist/form/StringArrayBuilder.svelte.d.ts +15 -0
  138. package/dist/form/Switch.svelte +164 -106
  139. package/dist/form/Switch.svelte.d.ts +22 -3
  140. package/dist/form/TextArea.svelte +80 -45
  141. package/dist/form/TextArea.svelte.d.ts +35 -10
  142. package/dist/form/Textbox.svelte +80 -47
  143. package/dist/form/Textbox.svelte.d.ts +41 -8
  144. package/dist/form/TimePicker.svelte +42 -47
  145. package/dist/form/TimePicker.svelte.d.ts +12 -2
  146. package/dist/form/comboBoxCore.svelte.d.ts +99 -0
  147. package/dist/form/comboBoxCore.svelte.js +243 -0
  148. package/dist/icon/Icon.svelte +8 -3
  149. package/dist/icon/Icon.svelte.d.ts +8 -3
  150. package/dist/icon/cube-send.svg +1 -0
  151. package/dist/icon/file-type-bmp.svg +1 -0
  152. package/dist/icon/file-type-csv.svg +1 -0
  153. package/dist/icon/file-type-doc.svg +1 -0
  154. package/dist/icon/file-type-docx.svg +1 -0
  155. package/dist/icon/file-type-jpg.svg +1 -0
  156. package/dist/icon/file-type-pdf.svg +1 -0
  157. package/dist/icon/file-type-png.svg +1 -0
  158. package/dist/icon/file-type-ppt.svg +1 -0
  159. package/dist/icon/file-type-svg.svg +1 -0
  160. package/dist/icon/file-type-txt.svg +1 -0
  161. package/dist/icon/file-type-xls.svg +1 -0
  162. package/dist/icon/file-type-zip.svg +1 -0
  163. package/dist/icon/index.d.ts +166 -145
  164. package/dist/icon/index.js +166 -146
  165. package/dist/icon/layout-sidebar-left-collapse.svg +1 -0
  166. package/dist/icon/layout-sidebar-left-expand.svg +1 -0
  167. package/dist/icon/logo-placeholder.svg +6 -0
  168. package/dist/icon/paperclip.svg +1 -0
  169. package/dist/icon/source-code.svg +1 -0
  170. package/dist/icon/sun-moon.svg +1 -0
  171. package/dist/icon/table.svg +6 -0
  172. package/dist/icon/thumb-down.svg +1 -0
  173. package/dist/icon/thumb-up.svg +1 -0
  174. package/dist/index.d.ts +93 -22
  175. package/dist/index.js +28 -27
  176. package/dist/layout/AppShell.svelte +12 -162
  177. package/dist/layout/AppShell.svelte.d.ts +6 -27
  178. package/dist/layout/CustomNavbar.svelte +9 -7
  179. package/dist/layout/CustomNavbar.svelte.d.ts +4 -2
  180. package/dist/layout/Navbar.svelte +158 -110
  181. package/dist/layout/Navbar.svelte.d.ts +26 -12
  182. package/dist/layout/NavbarItemDisplay.svelte +2 -2
  183. package/dist/layout/NavbarItemView.svelte +182 -0
  184. package/dist/layout/NavbarItemView.svelte.d.ts +10 -0
  185. package/dist/layout/Sidenav.svelte +280 -341
  186. package/dist/layout/Sidenav.svelte.d.ts +36 -4
  187. package/dist/models/ComboBoxItem.d.ts +2 -0
  188. package/dist/models/Employee.d.ts +53 -0
  189. package/dist/models/Employee.js +23 -0
  190. package/dist/models/Hyperlink.d.ts +3 -1
  191. package/dist/models/LinkCollectionItem.d.ts +3 -1
  192. package/dist/models/NavbarItem.d.ts +6 -2
  193. package/dist/theme.svelte.d.ts +0 -1
  194. package/dist/theme.svelte.js +46 -58
  195. package/dist/ui/Accordion.svelte +81 -242
  196. package/dist/ui/Accordion.svelte.d.ts +37 -14
  197. package/dist/ui/AccordionItem.svelte +303 -0
  198. package/dist/ui/AccordionItem.svelte.d.ts +21 -0
  199. package/dist/ui/ActionIcon.svelte +25 -21
  200. package/dist/ui/ActionIcon.svelte.d.ts +15 -2
  201. package/dist/ui/Badge.svelte +170 -161
  202. package/dist/ui/Badge.svelte.d.ts +16 -4
  203. package/dist/ui/Button.svelte +178 -205
  204. package/dist/ui/Button.svelte.d.ts +19 -2
  205. package/dist/ui/ButtonVariant.d.ts +15 -1
  206. package/dist/ui/ContextMenu.svelte +146 -0
  207. package/dist/ui/ContextMenu.svelte.d.ts +37 -0
  208. package/dist/ui/ContextMenuList.svelte +188 -0
  209. package/dist/ui/ContextMenuList.svelte.d.ts +12 -0
  210. package/dist/ui/Dialog.svelte +183 -104
  211. package/dist/ui/Dialog.svelte.d.ts +21 -2
  212. package/dist/ui/Drawer.svelte +237 -184
  213. package/dist/ui/Drawer.svelte.d.ts +20 -2
  214. package/dist/ui/Dropdown.svelte +24 -14
  215. package/dist/ui/Dropdown.svelte.d.ts +11 -2
  216. package/dist/ui/Dropzone.svelte +159 -57
  217. package/dist/ui/Dropzone.svelte.d.ts +29 -2
  218. package/dist/ui/Link.svelte +12 -4
  219. package/dist/ui/Link.svelte.d.ts +8 -2
  220. package/dist/ui/Loader.svelte +23 -18
  221. package/dist/ui/Loader.svelte.d.ts +5 -2
  222. package/dist/ui/Logo.svelte +37 -0
  223. package/dist/ui/Logo.svelte.d.ts +16 -0
  224. package/dist/ui/MultiSortable.svelte +287 -0
  225. package/dist/ui/MultiSortable.svelte.d.ts +50 -0
  226. package/dist/ui/Pagination.svelte +12 -6
  227. package/dist/ui/Pagination.svelte.d.ts +6 -2
  228. package/dist/ui/Popover.svelte +43 -65
  229. package/dist/ui/Popover.svelte.d.ts +14 -5
  230. package/dist/ui/ProgressBar.svelte +169 -0
  231. package/dist/ui/ProgressBar.svelte.d.ts +30 -0
  232. package/dist/ui/ProgressBarVariant.d.ts +7 -0
  233. package/dist/ui/ProgressBarVariant.js +1 -0
  234. package/dist/ui/SegmentedControl.svelte +0 -0
  235. package/dist/ui/SegmentedControl.svelte.d.ts +26 -0
  236. package/dist/ui/Sortable.svelte +163 -0
  237. package/dist/ui/Sortable.svelte.d.ts +47 -0
  238. package/dist/ui/Table.svelte +497 -56
  239. package/dist/ui/Table.svelte.d.ts +64 -2
  240. package/dist/ui/Tabs.svelte +22 -18
  241. package/dist/ui/Tabs.svelte.d.ts +6 -2
  242. package/dist/ui/ThemeSwitcher.svelte +26 -7
  243. package/dist/ui/ThemeSwitcher.svelte.d.ts +4 -2
  244. package/dist/ui/Tooltip.svelte +312 -180
  245. package/dist/ui/Tooltip.svelte.d.ts +4 -3
  246. package/dist/uiTheme.svelte.d.ts +86 -0
  247. package/dist/uiTheme.svelte.js +214 -0
  248. package/dist/util/DateFunctions.js +1 -1
  249. package/dist/util/DragDrop.d.ts +50 -0
  250. package/dist/util/DragDrop.js +154 -0
  251. package/dist/util/NavigateTo.js +2 -2
  252. package/dist/util/dayjs.d.ts +4 -0
  253. package/dist/util/dayjs.js +15 -0
  254. package/dist/util/interceptLinkClick.d.ts +13 -0
  255. package/dist/util/interceptLinkClick.js +33 -0
  256. package/package.json +66 -26
  257. package/dist/display/Alert.svelte +0 -179
  258. package/dist/display/Alert.svelte.d.ts +0 -13
  259. package/dist/form/FileInput.svelte +0 -235
  260. package/dist/form/FileInput.svelte.d.ts +0 -23
  261. package/dist/form/PasswordInput.svelte +0 -252
  262. package/dist/form/PasswordInput.svelte.d.ts +0 -33
  263. package/dist/form/Rating.svelte +0 -235
  264. package/dist/form/Rating.svelte.d.ts +0 -21
  265. package/dist/styles/components.css +0 -199
  266. package/dist/styles/dark.css +0 -146
  267. package/dist/styles/index.css +0 -116
  268. package/dist/styles/reset.css +0 -110
  269. package/dist/styles/semantic.css +0 -86
  270. package/dist/styles/tokens.css +0 -203
  271. package/dist/styles/utilities.css +0 -523
  272. package/dist/ui/Breadcrumbs.svelte +0 -131
  273. package/dist/ui/Breadcrumbs.svelte.d.ts +0 -16
  274. package/dist/ui/LoadingOverlay.svelte +0 -53
  275. package/dist/ui/LoadingOverlay.svelte.d.ts +0 -11
  276. package/dist/ui/Progress.svelte +0 -191
  277. package/dist/ui/Progress.svelte.d.ts +0 -15
  278. package/dist/ui/RingProgress.svelte +0 -141
  279. package/dist/ui/RingProgress.svelte.d.ts +0 -18
  280. package/dist/ui/Skeleton.svelte +0 -85
  281. package/dist/ui/Skeleton.svelte.d.ts +0 -12
  282. package/dist/ui/Stepper.svelte +0 -355
  283. package/dist/ui/Stepper.svelte.d.ts +0 -24
  284. package/dist/ui/Timeline.svelte +0 -225
  285. package/dist/ui/Timeline.svelte.d.ts +0 -23
  286. /package/dist/{actions → util}/ClickOutside.d.ts +0 -0
  287. /package/dist/{actions → util}/ClickOutside.js +0 -0
  288. /package/dist/{transitions → util}/Transitions.d.ts +0 -0
  289. /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;