@placeholderco/placeholder-ui 1.0.12 → 2.1.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 (278) 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/ColorPicker.svelte +957 -0
  107. package/dist/form/ColorPicker.svelte.d.ts +78 -0
  108. package/dist/form/ComboBox.svelte +30 -20
  109. package/dist/form/ComboBox.svelte.d.ts +1 -1
  110. package/dist/form/ComboBoxItemBuilder.svelte +161 -188
  111. package/dist/form/ComboBoxItemBuilder.svelte.d.ts +19 -2
  112. package/dist/form/ComboBoxMulti.svelte +38 -24
  113. package/dist/form/ComboBoxMulti.svelte.d.ts +1 -1
  114. package/dist/form/CronBuilder.svelte +84 -67
  115. package/dist/form/CronBuilder.svelte.d.ts +16 -3
  116. package/dist/form/DatePicker.svelte +148 -195
  117. package/dist/form/DateRangePicker.svelte +101 -98
  118. package/dist/form/DateTimePicker.svelte +167 -208
  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 +70 -47
  123. package/dist/form/Number.svelte.d.ts +36 -6
  124. package/dist/form/Radio.svelte +18 -18
  125. package/dist/form/RadioGroup.svelte +23 -12
  126. package/dist/form/RadioGroup.svelte.d.ts +13 -2
  127. package/dist/form/SegmentedControl.svelte +76 -56
  128. package/dist/form/SegmentedControl.svelte.d.ts +9 -4
  129. package/dist/form/Select.svelte +150 -233
  130. package/dist/form/Select.svelte.d.ts +29 -5
  131. package/dist/form/SelectMulti.svelte +163 -277
  132. package/dist/form/SelectMulti.svelte.d.ts +36 -7
  133. package/dist/form/Slider.svelte +183 -269
  134. package/dist/form/Slider.svelte.d.ts +32 -17
  135. package/dist/form/StringArrayBuilder.svelte +249 -0
  136. package/dist/form/StringArrayBuilder.svelte.d.ts +15 -0
  137. package/dist/form/Switch.svelte +164 -106
  138. package/dist/form/Switch.svelte.d.ts +22 -3
  139. package/dist/form/TextArea.svelte +49 -29
  140. package/dist/form/TextArea.svelte.d.ts +23 -3
  141. package/dist/form/Textbox.svelte +69 -68
  142. package/dist/form/Textbox.svelte.d.ts +32 -4
  143. package/dist/form/TimePicker.svelte +42 -47
  144. package/dist/form/TimePicker.svelte.d.ts +12 -2
  145. package/dist/form/comboBoxCore.svelte.d.ts +99 -0
  146. package/dist/form/comboBoxCore.svelte.js +243 -0
  147. package/dist/icon/Icon.svelte +8 -3
  148. package/dist/icon/Icon.svelte.d.ts +8 -3
  149. package/dist/icon/file-type-bmp.svg +1 -0
  150. package/dist/icon/file-type-csv.svg +1 -0
  151. package/dist/icon/file-type-doc.svg +1 -0
  152. package/dist/icon/file-type-docx.svg +1 -0
  153. package/dist/icon/file-type-jpg.svg +1 -0
  154. package/dist/icon/file-type-pdf.svg +1 -0
  155. package/dist/icon/file-type-png.svg +1 -0
  156. package/dist/icon/file-type-ppt.svg +1 -0
  157. package/dist/icon/file-type-svg.svg +1 -0
  158. package/dist/icon/file-type-txt.svg +1 -0
  159. package/dist/icon/file-type-xls.svg +1 -0
  160. package/dist/icon/file-type-zip.svg +1 -0
  161. package/dist/icon/index.d.ts +166 -151
  162. package/dist/icon/index.js +166 -152
  163. package/dist/icon/logo-placeholder.svg +6 -0
  164. package/dist/icon/source-code.svg +1 -0
  165. package/dist/icon/sun-moon.svg +1 -0
  166. package/dist/icon/table.svg +6 -0
  167. package/dist/index.d.ts +146 -82
  168. package/dist/index.js +77 -78
  169. package/dist/layout/AppShell.svelte +12 -162
  170. package/dist/layout/AppShell.svelte.d.ts +6 -27
  171. package/dist/layout/CustomNavbar.svelte +9 -7
  172. package/dist/layout/CustomNavbar.svelte.d.ts +4 -2
  173. package/dist/layout/Navbar.svelte +161 -129
  174. package/dist/layout/Navbar.svelte.d.ts +29 -15
  175. package/dist/layout/NavbarItemDisplay.svelte +2 -2
  176. package/dist/layout/NavbarItemView.svelte +182 -0
  177. package/dist/layout/NavbarItemView.svelte.d.ts +10 -0
  178. package/dist/layout/Sidenav.svelte +280 -341
  179. package/dist/layout/Sidenav.svelte.d.ts +36 -4
  180. package/dist/models/ComboBoxItem.d.ts +2 -0
  181. package/dist/models/Employee.d.ts +53 -0
  182. package/dist/models/Employee.js +23 -0
  183. package/dist/models/Hyperlink.d.ts +3 -1
  184. package/dist/models/LinkCollectionItem.d.ts +3 -1
  185. package/dist/models/NavbarItem.d.ts +6 -2
  186. package/dist/theme.svelte.d.ts +0 -1
  187. package/dist/theme.svelte.js +46 -58
  188. package/dist/ui/Accordion.svelte +81 -242
  189. package/dist/ui/Accordion.svelte.d.ts +37 -14
  190. package/dist/ui/AccordionItem.svelte +303 -0
  191. package/dist/ui/AccordionItem.svelte.d.ts +21 -0
  192. package/dist/ui/ActionIcon.svelte +25 -21
  193. package/dist/ui/ActionIcon.svelte.d.ts +15 -2
  194. package/dist/ui/Badge.svelte +163 -171
  195. package/dist/ui/Badge.svelte.d.ts +13 -5
  196. package/dist/ui/Button.svelte +178 -205
  197. package/dist/ui/Button.svelte.d.ts +19 -2
  198. package/dist/ui/ButtonVariant.d.ts +15 -1
  199. package/dist/ui/ContextMenu.svelte +146 -0
  200. package/dist/ui/ContextMenu.svelte.d.ts +37 -0
  201. package/dist/ui/ContextMenuList.svelte +188 -0
  202. package/dist/ui/ContextMenuList.svelte.d.ts +12 -0
  203. package/dist/ui/Dialog.svelte +183 -111
  204. package/dist/ui/Dialog.svelte.d.ts +21 -4
  205. package/dist/ui/Drawer.svelte +237 -184
  206. package/dist/ui/Drawer.svelte.d.ts +20 -2
  207. package/dist/ui/Dropdown.svelte +24 -14
  208. package/dist/ui/Dropdown.svelte.d.ts +11 -2
  209. package/dist/ui/Dropzone.svelte +159 -57
  210. package/dist/ui/Dropzone.svelte.d.ts +29 -2
  211. package/dist/ui/Link.svelte +12 -4
  212. package/dist/ui/Link.svelte.d.ts +8 -2
  213. package/dist/ui/Loader.svelte +23 -18
  214. package/dist/ui/Loader.svelte.d.ts +5 -2
  215. package/dist/ui/Logo.svelte +37 -0
  216. package/dist/ui/Logo.svelte.d.ts +16 -0
  217. package/dist/ui/MultiSortable.svelte +287 -0
  218. package/dist/ui/MultiSortable.svelte.d.ts +50 -0
  219. package/dist/ui/Pagination.svelte +15 -9
  220. package/dist/ui/Pagination.svelte.d.ts +6 -2
  221. package/dist/ui/Popover.svelte +43 -65
  222. package/dist/ui/Popover.svelte.d.ts +14 -5
  223. package/dist/ui/ProgressBar.svelte +28 -30
  224. package/dist/ui/ProgressBarVariant.d.ts +7 -1
  225. package/dist/ui/SegmentedControl.svelte +0 -0
  226. package/dist/ui/SegmentedControl.svelte.d.ts +26 -0
  227. package/dist/ui/Sortable.svelte +163 -0
  228. package/dist/ui/Sortable.svelte.d.ts +47 -0
  229. package/dist/ui/Table.svelte +383 -80
  230. package/dist/ui/Table.svelte.d.ts +43 -2
  231. package/dist/ui/Tabs.svelte +22 -18
  232. package/dist/ui/Tabs.svelte.d.ts +6 -2
  233. package/dist/ui/ThemeSwitcher.svelte +26 -7
  234. package/dist/ui/ThemeSwitcher.svelte.d.ts +4 -2
  235. package/dist/ui/Tooltip.svelte +312 -180
  236. package/dist/ui/Tooltip.svelte.d.ts +4 -3
  237. package/dist/uiTheme.svelte.d.ts +86 -0
  238. package/dist/uiTheme.svelte.js +214 -0
  239. package/dist/util/DateFunctions.js +1 -1
  240. package/dist/util/DragDrop.d.ts +50 -0
  241. package/dist/util/DragDrop.js +154 -0
  242. package/dist/util/NavigateTo.js +2 -2
  243. package/dist/util/dayjs.d.ts +4 -0
  244. package/dist/util/dayjs.js +15 -0
  245. package/package.json +66 -26
  246. package/dist/display/Alert.svelte +0 -179
  247. package/dist/display/Alert.svelte.d.ts +0 -13
  248. package/dist/form/FileInput.svelte +0 -235
  249. package/dist/form/FileInput.svelte.d.ts +0 -23
  250. package/dist/form/PasswordInput.svelte +0 -253
  251. package/dist/form/PasswordInput.svelte.d.ts +0 -34
  252. package/dist/form/Rating.svelte +0 -235
  253. package/dist/form/Rating.svelte.d.ts +0 -21
  254. package/dist/styles/components.css +0 -199
  255. package/dist/styles/dark.css +0 -146
  256. package/dist/styles/index.css +0 -116
  257. package/dist/styles/reset.css +0 -110
  258. package/dist/styles/semantic.css +0 -86
  259. package/dist/styles/tokens.css +0 -203
  260. package/dist/styles/utilities.css +0 -523
  261. package/dist/ui/Breadcrumbs.svelte +0 -131
  262. package/dist/ui/Breadcrumbs.svelte.d.ts +0 -16
  263. package/dist/ui/LoadingOverlay.svelte +0 -53
  264. package/dist/ui/LoadingOverlay.svelte.d.ts +0 -11
  265. package/dist/ui/Progress.svelte +0 -191
  266. package/dist/ui/Progress.svelte.d.ts +0 -15
  267. package/dist/ui/RingProgress.svelte +0 -141
  268. package/dist/ui/RingProgress.svelte.d.ts +0 -18
  269. package/dist/ui/Skeleton.svelte +0 -85
  270. package/dist/ui/Skeleton.svelte.d.ts +0 -12
  271. package/dist/ui/Stepper.svelte +0 -355
  272. package/dist/ui/Stepper.svelte.d.ts +0 -24
  273. package/dist/ui/Timeline.svelte +0 -225
  274. package/dist/ui/Timeline.svelte.d.ts +0 -23
  275. /package/dist/{actions → util}/ClickOutside.d.ts +0 -0
  276. /package/dist/{actions → util}/ClickOutside.js +0 -0
  277. /package/dist/{transitions → util}/Transitions.d.ts +0 -0
  278. /package/dist/{transitions → util}/Transitions.js +0 -0
@@ -1,35 +1,64 @@
1
- import type { ComboBoxGroup, ComboBoxItem, FetchFunctionType, RetrieveLabelFunctionType, SearchFunctionType } from "../models/ComboBoxItem.js";
2
- import { type Snippet } from "svelte";
3
- interface Props {
4
- /** HTML name attribute for the select */
1
+ import type { ComboBoxGroup, ComboBoxItem, FetchFunctionType, RetrieveLabelFunctionType, SearchFunctionType } from '../models/ComboBoxItem.js';
2
+ import { type Snippet } from 'svelte';
3
+ export interface SelectMultiProps {
4
+ /** HTML name attribute for the select (falls back to label, then auto-generated) */
5
5
  name?: string;
6
+ /** Label text displayed above the select */
6
7
  label?: string;
8
+ /** Array of selected values (bindable) */
7
9
  values?: string[];
10
+ /**
11
+ * Array of full selected item objects (bindable). Can be passed initially to preset
12
+ * the selection with known labels — no `values` or retrieveLabelFunction needed.
13
+ */
8
14
  rawValues?: ComboBoxItem[];
15
+ /** Placeholder text when no values are selected */
9
16
  placeholder?: string;
17
+ /** CSS classes for the select element */
10
18
  class?: string;
19
+ /** CSS classes for the container element */
11
20
  containerClass?: string;
21
+ /** Disable the select */
12
22
  disabled?: boolean;
23
+ /** Mark field as required (shows asterisk) */
13
24
  required?: boolean;
25
+ /** Show error state styling */
14
26
  showError?: boolean;
27
+ /** Error message to display */
15
28
  errorText?: string;
29
+ /** Auto-focus on mount (first dialog open only) */
16
30
  autofocus?: boolean;
31
+ /** Auto-focus on every dialog open */
17
32
  autofocusDialog?: boolean;
33
+ /** Enable search/filter within options */
18
34
  allowSearch?: boolean;
19
- showNoResultsMessage?: boolean;
35
+ /** Hide "no results" message when search finds nothing */
36
+ hideNoResults?: boolean;
37
+ /** Close dropdown after selecting an option */
20
38
  closeOnSelection?: boolean;
39
+ /** Text shown while loading options */
21
40
  loadingText?: string;
41
+ /** Flat list of selectable options */
22
42
  options?: ComboBoxItem[];
43
+ /** Options organized into groups */
23
44
  groupedOptions?: ComboBoxGroup[];
24
- tooltipLocation?: "top" | "bottom" | "left" | "right";
45
+ /** Position of the tooltip */
46
+ tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
47
+ /** Async function to fetch options */
25
48
  fetchFunction?: FetchFunctionType | null;
49
+ /** Async function to search/filter options */
26
50
  searchFunction?: SearchFunctionType | null;
51
+ /** Async function to retrieve labels for values */
27
52
  retrieveLabelFunction?: RetrieveLabelFunctionType | null;
53
+ /** Rich tooltip content using a Svelte snippet */
28
54
  tooltipContent?: Snippet;
55
+ /** Simple tooltip text */
29
56
  tooltipText?: string;
57
+ /** Callback when selection changes (returns value strings) */
30
58
  onchange?: (e: string[]) => void;
59
+ /** Callback when selection changes (returns full item objects) */
31
60
  onchangeRaw?: (e: ComboBoxItem[]) => void;
32
61
  }
33
- declare const SelectMulti: import("svelte").Component<Props, {}, "values" | "rawValues">;
62
+ declare const SelectMulti: import("svelte").Component<SelectMultiProps, {}, "values" | "rawValues">;
34
63
  type SelectMulti = ReturnType<typeof SelectMulti>;
35
64
  export default SelectMulti;
@@ -1,150 +1,137 @@
1
1
  <script lang="ts">
2
- import FormGroup from './FormGroup.svelte';
2
+ import Tooltip from '../ui/Tooltip.svelte';
3
+ import { Icon, iconInfoCircle } from '../icon/index.js';
3
4
 
4
- interface Mark {
5
- value: number;
6
- label?: string;
7
- }
5
+ const autoName = `slider-${crypto.randomUUID()}`;
8
6
 
9
- interface Props {
10
- /** HTML name attribute for the slider */
7
+ export interface SliderProps {
8
+ /** HTML name attribute for the slider (falls back to label, then auto-generated) */
11
9
  name?: string;
10
+ /** Label text displayed above the slider */
12
11
  label?: string;
12
+ /** Custom ID for the slider element */
13
+ inputId?: string;
14
+ /** Mark field as required (shows asterisk) */
15
+ required?: boolean;
16
+ /** Disable the slider */
17
+ disabled?: boolean;
18
+ /** CSS classes for the slider element */
19
+ class?: string;
20
+ /** CSS classes for the container element */
21
+ containerClass?: string;
22
+ /** Slider value (bindable) */
13
23
  value?: number;
24
+ /** Minimum allowed value */
14
25
  min?: number;
26
+ /** Maximum allowed value */
15
27
  max?: number;
28
+ /** Increment/decrement step value */
16
29
  step?: number;
17
- marks?: Mark[] | boolean;
18
- showValue?: boolean;
19
- labelAlwaysOn?: boolean;
20
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
21
- color?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'danger';
22
- radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
23
- disabled?: boolean;
24
- class?: string;
25
- containerClass?: string;
26
- required?: boolean;
30
+ /** Show error state styling */
27
31
  showError?: boolean;
32
+ /** Error message to display */
28
33
  errorText?: string;
34
+ /** Position of the tooltip */
29
35
  tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
36
+ /** Simple tooltip text */
30
37
  tooltipText?: string;
38
+ /** Hide the current value next to the label */
39
+ hideValue?: boolean;
40
+ /** Format function for displaying the value */
41
+ formatValue?: (value: number) => string;
42
+ /** Callback when value changes (after interaction ends) */
31
43
  onchange?: (value: number) => void;
44
+ /** Callback on input event (during dragging) */
32
45
  oninput?: (value: number) => void;
46
+ /** Callback when slider gains focus */
47
+ onfocus?: (e: FocusEvent) => void;
48
+ /** Callback when slider loses focus */
49
+ onblur?: (e: FocusEvent) => void;
33
50
  }
34
51
 
35
52
  let {
36
53
  name,
37
54
  label = '',
38
- value = $bindable(0),
39
- min = 0,
40
- max = 100,
41
- step = 1,
42
- marks = false,
43
- showValue = false,
44
- labelAlwaysOn = false,
45
- size = 'md',
46
- color = 'primary',
47
- radius = 'full',
55
+ inputId = undefined,
56
+ required = false,
48
57
  disabled = false,
49
58
  class: classes = '',
50
59
  containerClass = '',
51
- required = false,
60
+ value = $bindable(50),
61
+ min = 0,
62
+ max = 100,
63
+ step = 1,
52
64
  showError = false,
53
65
  errorText = '',
54
66
  tooltipLocation = 'top',
55
67
  tooltipText = undefined,
56
- onchange,
57
- oninput
58
- }: Props = $props();
59
-
60
- let isDragging = $state(false);
61
-
62
- const percentage = $derived(((value - min) / (max - min)) * 100);
63
-
64
- // Generate marks if boolean true
65
- const computedMarks = $derived.by(() => {
66
- if (marks === false) return [];
67
- if (marks === true) {
68
- // Generate marks at 0%, 25%, 50%, 75%, 100%
69
- const range = max - min;
70
- return [
71
- { value: min, label: String(min) },
72
- { value: min + range * 0.25, label: String(min + range * 0.25) },
73
- { value: min + range * 0.5, label: String(min + range * 0.5) },
74
- { value: min + range * 0.75, label: String(min + range * 0.75) },
75
- { value: max, label: String(max) }
76
- ];
77
- }
78
- return marks;
68
+ hideValue = false,
69
+ formatValue = (v: number) => v.toString(),
70
+ onchange = undefined,
71
+ oninput = undefined,
72
+ onfocus = undefined,
73
+ onblur = undefined
74
+ }: SliderProps = $props();
75
+
76
+ let resolvedName = $derived((name || label || autoName).replace(/[^a-zA-Z0-9_\-:.]/g, '_'));
77
+
78
+ let id = $derived.by(() => {
79
+ if (inputId) return inputId;
80
+ if (label) return `slider-${label.toLowerCase().replace(/ /g, '-')}`;
81
+ return Math.random().toString(36).substring(2, 8);
79
82
  });
80
83
 
81
- function handleInput(e: Event) {
82
- const target = e.target as HTMLInputElement;
83
- value = Number(target.value);
84
- oninput?.(value);
85
- }
84
+ const extraClasses: string[] = $derived.by(() => {
85
+ const result = [];
86
+ if (disabled) result.push('disabled');
87
+ if (showError) result.push('show-error');
88
+ return result;
89
+ });
86
90
 
87
- function handleChange(e: Event) {
88
- const target = e.target as HTMLInputElement;
89
- value = Number(target.value);
90
- onchange?.(value);
91
- }
91
+ // Calculate fill percentage for the track
92
+ const fillPercent = $derived(((value - min) / (max - min)) * 100);
92
93
  </script>
93
94
 
94
95
  <div class="slider-container {containerClass}">
95
- <FormGroup
96
- {label}
97
- {required}
98
- class={classes}
99
- {tooltipLocation}
100
- {tooltipText}
101
- {showError}
102
- {errorText}
103
- >
104
- <div class="slider-wrapper size-{size}">
105
- {#if showValue}
106
- <div class="slider-value-display">
107
- <span>{value}</span>
108
- </div>
109
- {/if}
110
- <div class="slider-track-wrapper">
111
- <input
112
- type="range"
113
- class="slider color-{color} radius-{radius}"
114
- {min}
115
- {max}
116
- {step}
117
- {disabled}
118
- bind:value
119
- oninput={handleInput}
120
- onchange={handleChange}
121
- onmousedown={() => (isDragging = true)}
122
- onmouseup={() => (isDragging = false)}
123
- ontouchstart={() => (isDragging = true)}
124
- ontouchend={() => (isDragging = false)}
125
- style="--slider-percentage: {percentage}%;"
126
- />
127
- {#if labelAlwaysOn || isDragging}
128
- <div class="slider-thumb-label" style="left: {percentage}%;">
129
- {value}
130
- </div>
96
+ {#if label}
97
+ <div class="label-row">
98
+ <label class="label" for={id}>
99
+ {label}
100
+ {#if required}
101
+ <span class="text-required">*</span>
131
102
  {/if}
132
- </div>
133
- {#if computedMarks.length > 0}
134
- <div class="slider-marks">
135
- {#each computedMarks as mark}
136
- {@const markPercentage = ((mark.value - min) / (max - min)) * 100}
137
- <div class="slider-mark" style="left: {markPercentage}%;">
138
- <div class="mark-dot" class:active={value >= mark.value}></div>
139
- {#if mark.label}
140
- <div class="mark-label">{mark.label}</div>
141
- {/if}
142
- </div>
143
- {/each}
144
- </div>
103
+ {#if tooltipText}
104
+ <Tooltip location={tooltipLocation} text={tooltipText}>
105
+ <Icon svg={iconInfoCircle} size="1em" stroke="var(--accent-color)" />
106
+ </Tooltip>
107
+ {/if}
108
+ </label>
109
+ {#if !hideValue}
110
+ <span class="label-value">{formatValue(value)}</span>
145
111
  {/if}
146
112
  </div>
147
- </FormGroup>
113
+ {/if}
114
+ <div class="slider-wrapper">
115
+ <input
116
+ type="range"
117
+ class="slider {classes} {extraClasses.join(' ')}"
118
+ {id}
119
+ name={resolvedName}
120
+ {min}
121
+ {max}
122
+ {step}
123
+ {disabled}
124
+ bind:value
125
+ style="--fill-percent: {fillPercent}%"
126
+ onchange={() => onchange?.(value)}
127
+ oninput={() => oninput?.(value)}
128
+ {onfocus}
129
+ {onblur}
130
+ />
131
+ </div>
132
+ {#if showError && errorText}
133
+ <div class="error-text">{errorText}</div>
134
+ {/if}
148
135
  </div>
149
136
 
150
137
  <style>
@@ -152,210 +139,137 @@
152
139
  width: 100%;
153
140
  }
154
141
 
155
- .slider-wrapper {
156
- width: 100%;
157
- padding-top: var(--pui-spacing-1);
142
+ .label-row {
143
+ display: flex;
144
+ justify-content: space-between;
145
+ align-items: center;
146
+ margin-bottom: 0.25rem;
158
147
  }
159
148
 
160
- .slider-value-display {
161
- text-align: right;
162
- font-size: var(--pui-font-size-sm);
163
- font-weight: var(--pui-font-weight-medium);
164
- color: var(--pui-text-secondary);
165
- margin-bottom: var(--pui-spacing-1);
149
+ .label {
150
+ font-size: 1rem;
151
+ line-height: 1.5rem;
152
+ color: var(--text-color);
166
153
  }
167
154
 
168
- :global(.dark) .slider-value-display {
169
- color: var(--pui-color-gray-300);
155
+ .text-required {
156
+ color: var(--danger-text);
170
157
  }
171
158
 
172
- .slider-track-wrapper {
173
- position: relative;
174
- width: 100%;
159
+ .label-value {
160
+ font-size: 0.875rem;
161
+ color: var(--text-muted);
162
+ font-variant-numeric: tabular-nums;
163
+ }
164
+
165
+ .slider-wrapper {
166
+ display: flex;
167
+ align-items: center;
168
+ gap: 0.75rem;
169
+ padding: 4px 0 4px 0;
175
170
  }
176
171
 
177
172
  .slider {
178
173
  -webkit-appearance: none;
179
174
  appearance: none;
180
175
  width: 100%;
181
- background: transparent;
182
- cursor: pointer;
183
- }
184
-
185
- .slider:disabled {
186
- opacity: 0.5;
187
- cursor: not-allowed;
188
- }
189
-
190
- /* Track */
191
- .slider::-webkit-slider-runnable-track {
192
- height: var(--track-height, 6px);
193
- background: linear-gradient(
194
- to right,
195
- var(--slider-color, var(--pui-color-primary)) 0%,
196
- var(--slider-color, var(--pui-color-primary)) var(--slider-percentage),
197
- var(--pui-color-gray-300) var(--slider-percentage),
198
- var(--pui-color-gray-300) 100%
199
- );
200
- border-radius: var(--track-radius, var(--pui-radius-full));
201
- }
202
-
203
- :global(.dark) .slider::-webkit-slider-runnable-track {
176
+ height: 6px;
177
+ border-radius: 3px;
204
178
  background: linear-gradient(
205
179
  to right,
206
- var(--slider-color, var(--pui-color-primary)) 0%,
207
- var(--slider-color, var(--pui-color-primary)) var(--slider-percentage),
208
- var(--pui-color-dark-border) var(--slider-percentage),
209
- var(--pui-color-dark-border) 100%
180
+ var(--accent-color) 0%,
181
+ var(--accent-color) var(--fill-percent),
182
+ var(--border-color) var(--fill-percent),
183
+ var(--border-color) 100%
210
184
  );
185
+ outline: none;
186
+ cursor: pointer;
211
187
  }
212
188
 
213
- .slider::-moz-range-track {
214
- height: var(--track-height, 6px);
215
- background: var(--pui-color-gray-300);
216
- border-radius: var(--track-radius, var(--pui-radius-full));
217
- }
218
-
219
- .slider::-moz-range-progress {
220
- background: var(--slider-color, var(--pui-color-primary));
221
- height: var(--track-height, 6px);
222
- border-radius: var(--track-radius, var(--pui-radius-full));
223
- }
224
-
225
- /* Thumb */
226
189
  .slider::-webkit-slider-thumb {
227
190
  -webkit-appearance: none;
228
191
  appearance: none;
229
- width: var(--thumb-size, 16px);
230
- height: var(--thumb-size, 16px);
231
- background: var(--pui-color-white);
232
- border: 2px solid var(--slider-color, var(--pui-color-primary));
192
+ width: 16px;
193
+ height: 16px;
233
194
  border-radius: 50%;
234
- margin-top: calc((var(--track-height, 6px) - var(--thumb-size, 16px)) / 2);
235
- box-shadow: var(--pui-shadow-sm);
236
- transition: transform var(--pui-transition-fast) var(--pui-ease-out);
237
- }
238
-
239
- .slider::-webkit-slider-thumb:hover {
240
- transform: scale(1.1);
195
+ background: var(--accent-color);
196
+ cursor: pointer;
197
+ border: 2px solid var(--bg-color);
198
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
199
+ transition:
200
+ transform 0.15s ease,
201
+ box-shadow 0.15s ease;
241
202
  }
242
203
 
243
204
  .slider::-moz-range-thumb {
244
- width: var(--thumb-size, 16px);
245
- height: var(--thumb-size, 16px);
246
- background: var(--pui-color-white);
247
- border: 2px solid var(--slider-color, var(--pui-color-primary));
205
+ width: 16px;
206
+ height: 16px;
248
207
  border-radius: 50%;
249
- box-shadow: var(--pui-shadow-sm);
208
+ background: var(--accent-color);
209
+ cursor: pointer;
210
+ border: 2px solid var(--bg-color);
211
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
212
+ transition:
213
+ transform 0.15s ease,
214
+ box-shadow 0.15s ease;
250
215
  }
251
216
 
252
- /* Sizes */
253
- .size-xs {
254
- --track-height: 4px;
255
- --thumb-size: 12px;
256
- }
257
- .size-sm {
258
- --track-height: 5px;
259
- --thumb-size: 14px;
260
- }
261
- .size-md {
262
- --track-height: 6px;
263
- --thumb-size: 16px;
264
- }
265
- .size-lg {
266
- --track-height: 8px;
267
- --thumb-size: 20px;
268
- }
269
- .size-xl {
270
- --track-height: 10px;
271
- --thumb-size: 24px;
217
+ .slider::-webkit-slider-thumb:hover {
218
+ transform: scale(1.1);
219
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
272
220
  }
273
221
 
274
- /* Colors */
275
- .color-primary {
276
- --slider-color: var(--pui-color-primary);
277
- }
278
- .color-secondary {
279
- --slider-color: var(--pui-color-secondary);
280
- }
281
- .color-accent {
282
- --slider-color: var(--pui-color-accent);
283
- }
284
- .color-success {
285
- --slider-color: var(--pui-color-success);
286
- }
287
- .color-warning {
288
- --slider-color: var(--pui-color-warning);
289
- }
290
- .color-danger {
291
- --slider-color: var(--pui-color-danger);
222
+ .slider::-moz-range-thumb:hover {
223
+ transform: scale(1.1);
224
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
292
225
  }
293
226
 
294
- /* Radius */
295
- .radius-none {
296
- --track-radius: 0;
227
+ .slider:focus {
228
+ outline: none;
297
229
  }
298
- .radius-sm {
299
- --track-radius: var(--pui-radius-sm);
300
- }
301
- .radius-md {
302
- --track-radius: var(--pui-radius-md);
303
- }
304
- .radius-lg {
305
- --track-radius: var(--pui-radius-lg);
230
+
231
+ .slider:focus::-webkit-slider-thumb {
232
+ box-shadow: 0 0 0 3px rgba(var(--accent-color-rgb, 59, 130, 246), 0.3);
306
233
  }
307
- .radius-full {
308
- --track-radius: var(--pui-radius-full);
234
+
235
+ .slider:focus::-moz-range-thumb {
236
+ box-shadow: 0 0 0 3px rgba(var(--accent-color-rgb, 59, 130, 246), 0.3);
309
237
  }
310
238
 
311
- /* Thumb label */
312
- .slider-thumb-label {
313
- position: absolute;
314
- top: -28px;
315
- transform: translateX(-50%);
316
- background: var(--pui-color-gray-800);
317
- color: var(--pui-color-white);
318
- font-size: var(--pui-font-size-xs);
319
- padding: 2px 6px;
320
- border-radius: var(--pui-radius-sm);
321
- white-space: nowrap;
322
- pointer-events: none;
239
+ .slider.disabled {
240
+ opacity: 0.5;
241
+ cursor: not-allowed;
323
242
  }
324
243
 
325
- /* Marks */
326
- .slider-marks {
327
- position: relative;
328
- width: 100%;
329
- height: 20px;
330
- margin-top: var(--pui-spacing-1);
244
+ .slider.disabled::-webkit-slider-thumb {
245
+ cursor: not-allowed;
331
246
  }
332
247
 
333
- .slider-mark {
334
- position: absolute;
335
- transform: translateX(-50%);
336
- display: flex;
337
- flex-direction: column;
338
- align-items: center;
248
+ .slider.disabled::-moz-range-thumb {
249
+ cursor: not-allowed;
339
250
  }
340
251
 
341
- .mark-dot {
342
- width: 6px;
343
- height: 6px;
344
- border-radius: 50%;
345
- background: var(--pui-color-gray-400);
346
- margin-bottom: var(--pui-spacing-1);
252
+ .slider.show-error {
253
+ background: linear-gradient(
254
+ to right,
255
+ var(--danger-text) 0%,
256
+ var(--danger-text) var(--fill-percent),
257
+ var(--border-color) var(--fill-percent),
258
+ var(--border-color) 100%
259
+ );
347
260
  }
348
261
 
349
- .mark-dot.active {
350
- background: var(--slider-color, var(--pui-color-primary));
262
+ .slider.show-error::-webkit-slider-thumb {
263
+ background: var(--danger-text);
351
264
  }
352
265
 
353
- .mark-label {
354
- font-size: var(--pui-font-size-xs);
355
- color: var(--pui-color-gray-600);
266
+ .slider.show-error::-moz-range-thumb {
267
+ background: var(--danger-text);
356
268
  }
357
269
 
358
- :global(.dark) .mark-label {
359
- color: var(--pui-color-gray-400);
270
+ .error-text {
271
+ color: var(--danger-text);
272
+ font-size: 0.875rem;
273
+ margin-top: 0.25rem;
360
274
  }
361
275
  </style>
@@ -1,32 +1,47 @@
1
- interface Mark {
2
- value: number;
3
- label?: string;
4
- }
5
- interface Props {
6
- /** HTML name attribute for the slider */
1
+ export interface SliderProps {
2
+ /** HTML name attribute for the slider (falls back to label, then auto-generated) */
7
3
  name?: string;
4
+ /** Label text displayed above the slider */
8
5
  label?: string;
6
+ /** Custom ID for the slider element */
7
+ inputId?: string;
8
+ /** Mark field as required (shows asterisk) */
9
+ required?: boolean;
10
+ /** Disable the slider */
11
+ disabled?: boolean;
12
+ /** CSS classes for the slider element */
13
+ class?: string;
14
+ /** CSS classes for the container element */
15
+ containerClass?: string;
16
+ /** Slider value (bindable) */
9
17
  value?: number;
18
+ /** Minimum allowed value */
10
19
  min?: number;
20
+ /** Maximum allowed value */
11
21
  max?: number;
22
+ /** Increment/decrement step value */
12
23
  step?: number;
13
- marks?: Mark[] | boolean;
14
- showValue?: boolean;
15
- labelAlwaysOn?: boolean;
16
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
17
- color?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'danger';
18
- radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
19
- disabled?: boolean;
20
- class?: string;
21
- containerClass?: string;
22
- required?: boolean;
24
+ /** Show error state styling */
23
25
  showError?: boolean;
26
+ /** Error message to display */
24
27
  errorText?: string;
28
+ /** Position of the tooltip */
25
29
  tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
30
+ /** Simple tooltip text */
26
31
  tooltipText?: string;
32
+ /** Hide the current value next to the label */
33
+ hideValue?: boolean;
34
+ /** Format function for displaying the value */
35
+ formatValue?: (value: number) => string;
36
+ /** Callback when value changes (after interaction ends) */
27
37
  onchange?: (value: number) => void;
38
+ /** Callback on input event (during dragging) */
28
39
  oninput?: (value: number) => void;
40
+ /** Callback when slider gains focus */
41
+ onfocus?: (e: FocusEvent) => void;
42
+ /** Callback when slider loses focus */
43
+ onblur?: (e: FocusEvent) => void;
29
44
  }
30
- declare const Slider: import("svelte").Component<Props, {}, "value">;
45
+ declare const Slider: import("svelte").Component<SliderProps, {}, "value">;
31
46
  type Slider = ReturnType<typeof Slider>;
32
47
  export default Slider;