@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
@@ -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;