fluentui-svelte 0.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 (283) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +201 -0
  3. package/dist/components/auto-suggest-box/auto-suggest-box.d.ts +2 -0
  4. package/dist/components/auto-suggest-box/auto-suggest-box.js +2 -0
  5. package/dist/components/auto-suggest-box/auto-suggest-box.svelte +457 -0
  6. package/dist/components/auto-suggest-box/auto-suggest-box.svelte.d.ts +4 -0
  7. package/dist/components/auto-suggest-box/docs/llms.md +73 -0
  8. package/dist/components/auto-suggest-box/option.svelte +82 -0
  9. package/dist/components/auto-suggest-box/option.svelte.d.ts +4 -0
  10. package/dist/components/auto-suggest-box/types.d.ts +140 -0
  11. package/dist/components/auto-suggest-box/types.js +1 -0
  12. package/dist/components/avatar/avatar.svelte +269 -0
  13. package/dist/components/avatar/avatar.svelte.d.ts +20 -0
  14. package/dist/components/avatar/docs/llms.md +92 -0
  15. package/dist/components/avatar/type.d.ts +63 -0
  16. package/dist/components/avatar/type.js +1 -0
  17. package/dist/components/badge/badge-icon.svelte +103 -0
  18. package/dist/components/badge/badge-icon.svelte.d.ts +25 -0
  19. package/dist/components/badge/badge.svelte +163 -0
  20. package/dist/components/badge/badge.svelte.d.ts +20 -0
  21. package/dist/components/badge/docs/llms.md +133 -0
  22. package/dist/components/badge/types.d.ts +70 -0
  23. package/dist/components/badge/types.js +1 -0
  24. package/dist/components/badge/utils.svelte.d.ts +16 -0
  25. package/dist/components/badge/utils.svelte.js +35 -0
  26. package/dist/components/button/button.svelte +203 -0
  27. package/dist/components/button/button.svelte.d.ts +38 -0
  28. package/dist/components/button/docs/llms.md +102 -0
  29. package/dist/components/button/split-button.svelte +66 -0
  30. package/dist/components/button/split-button.svelte.d.ts +4 -0
  31. package/dist/components/button/types.d.ts +84 -0
  32. package/dist/components/button/types.js +1 -0
  33. package/dist/components/calendar-date-picker/calendar-date-picker.svelte +119 -0
  34. package/dist/components/calendar-date-picker/calendar-date-picker.svelte.d.ts +4 -0
  35. package/dist/components/calendar-date-picker/docs/llms.md +33 -0
  36. package/dist/components/calendar-date-picker/types.d.ts +36 -0
  37. package/dist/components/calendar-date-picker/types.js +1 -0
  38. package/dist/components/calendar-view/calendar-view-controls.svelte +115 -0
  39. package/dist/components/calendar-view/calendar-view-controls.svelte.d.ts +3 -0
  40. package/dist/components/calendar-view/calendar-view-days.svelte +210 -0
  41. package/dist/components/calendar-view/calendar-view-days.svelte.d.ts +3 -0
  42. package/dist/components/calendar-view/calendar-view-grid.d.ts +38 -0
  43. package/dist/components/calendar-view/calendar-view-grid.js +140 -0
  44. package/dist/components/calendar-view/calendar-view-header.svelte +66 -0
  45. package/dist/components/calendar-view/calendar-view-header.svelte.d.ts +18 -0
  46. package/dist/components/calendar-view/calendar-view-item.svelte +181 -0
  47. package/dist/components/calendar-view/calendar-view-item.svelte.d.ts +4 -0
  48. package/dist/components/calendar-view/calendar-view-months.svelte +165 -0
  49. package/dist/components/calendar-view/calendar-view-months.svelte.d.ts +3 -0
  50. package/dist/components/calendar-view/calendar-view-years.svelte +161 -0
  51. package/dist/components/calendar-view/calendar-view-years.svelte.d.ts +3 -0
  52. package/dist/components/calendar-view/calendar-view.svelte +451 -0
  53. package/dist/components/calendar-view/calendar-view.svelte.d.ts +9 -0
  54. package/dist/components/calendar-view/calendar-view.svelte.js +196 -0
  55. package/dist/components/calendar-view/docs/llms.md +121 -0
  56. package/dist/components/calendar-view/index.d.ts +1 -0
  57. package/dist/components/calendar-view/index.js +1 -0
  58. package/dist/components/calendar-view/types.d.ts +174 -0
  59. package/dist/components/calendar-view/types.js +1 -0
  60. package/dist/components/checkbox/checkbox.svelte +171 -0
  61. package/dist/components/checkbox/checkbox.svelte.d.ts +40 -0
  62. package/dist/components/checkbox/docs/llms.md +78 -0
  63. package/dist/components/checkbox/types.d.ts +50 -0
  64. package/dist/components/checkbox/types.js +1 -0
  65. package/dist/components/date-picker/date-picker.svelte +381 -0
  66. package/dist/components/date-picker/date-picker.svelte.d.ts +4 -0
  67. package/dist/components/date-picker/docs/llms.md +52 -0
  68. package/dist/components/date-picker/index.d.ts +1 -0
  69. package/dist/components/date-picker/index.js +1 -0
  70. package/dist/components/date-picker/types.d.ts +74 -0
  71. package/dist/components/date-picker/types.js +1 -0
  72. package/dist/components/dialog/dialog-actions.svelte +37 -0
  73. package/dist/components/dialog/dialog-actions.svelte.d.ts +4 -0
  74. package/dist/components/dialog/dialog-content.svelte +17 -0
  75. package/dist/components/dialog/dialog-content.svelte.d.ts +4 -0
  76. package/dist/components/dialog/dialog-surface.svelte +95 -0
  77. package/dist/components/dialog/dialog-surface.svelte.d.ts +4 -0
  78. package/dist/components/dialog/dialog-title.svelte +33 -0
  79. package/dist/components/dialog/dialog-title.svelte.d.ts +25 -0
  80. package/dist/components/dialog/dialog-trigger.svelte +23 -0
  81. package/dist/components/dialog/dialog-trigger.svelte.d.ts +4 -0
  82. package/dist/components/dialog/dialog.svelte +64 -0
  83. package/dist/components/dialog/dialog.svelte.d.ts +7 -0
  84. package/dist/components/dialog/dialog.svelte.js +2 -0
  85. package/dist/components/dialog/docs/llms.md +131 -0
  86. package/dist/components/dialog/types.d.ts +92 -0
  87. package/dist/components/dialog/types.js +1 -0
  88. package/dist/components/divider/divider.svelte +120 -0
  89. package/dist/components/divider/divider.svelte.d.ts +39 -0
  90. package/dist/components/divider/docs/llms.md +83 -0
  91. package/dist/components/divider/types.d.ts +32 -0
  92. package/dist/components/divider/types.js +1 -0
  93. package/dist/components/dropdown/docs/llms.md +70 -0
  94. package/dist/components/dropdown/dropdown-context.d.ts +2 -0
  95. package/dist/components/dropdown/dropdown-context.js +2 -0
  96. package/dist/components/dropdown/dropdown-option.svelte +31 -0
  97. package/dist/components/dropdown/dropdown-option.svelte.d.ts +4 -0
  98. package/dist/components/dropdown/dropdown.svelte +309 -0
  99. package/dist/components/dropdown/dropdown.svelte.d.ts +4 -0
  100. package/dist/components/dropdown/types.d.ts +82 -0
  101. package/dist/components/dropdown/types.js +1 -0
  102. package/dist/components/dropdown-select/docs/llms.md +72 -0
  103. package/dist/components/dropdown-select/dropdown-select-option.svelte +87 -0
  104. package/dist/components/dropdown-select/dropdown-select-option.svelte.d.ts +4 -0
  105. package/dist/components/dropdown-select/dropdown-select.svelte +165 -0
  106. package/dist/components/dropdown-select/dropdown-select.svelte.d.ts +4 -0
  107. package/dist/components/dropdown-select/dropdown-select.svelte.js +48 -0
  108. package/dist/components/dropdown-select/index.d.ts +2 -0
  109. package/dist/components/dropdown-select/index.js +2 -0
  110. package/dist/components/dropdown-select/types.d.ts +46 -0
  111. package/dist/components/dropdown-select/types.js +1 -0
  112. package/dist/components/expander/docs/llms.md +88 -0
  113. package/dist/components/expander/expander.svelte +249 -0
  114. package/dist/components/expander/expander.svelte.d.ts +21 -0
  115. package/dist/components/expander/types.d.ts +47 -0
  116. package/dist/components/expander/types.js +1 -0
  117. package/dist/components/flyout/docs/llms.md +31 -0
  118. package/dist/components/flyout/flyout.svelte +148 -0
  119. package/dist/components/flyout/flyout.svelte.d.ts +19 -0
  120. package/dist/components/flyout/types.d.ts +36 -0
  121. package/dist/components/flyout/types.js +1 -0
  122. package/dist/components/hyperlink/docs/llms.md +33 -0
  123. package/dist/components/hyperlink/hyperlink.svelte +66 -0
  124. package/dist/components/hyperlink/hyperlink.svelte.d.ts +16 -0
  125. package/dist/components/hyperlink/types.d.ts +14 -0
  126. package/dist/components/hyperlink/types.js +1 -0
  127. package/dist/components/info-bar/docs/llms.md +81 -0
  128. package/dist/components/info-bar/info-bar.svelte +140 -0
  129. package/dist/components/info-bar/info-bar.svelte.d.ts +19 -0
  130. package/dist/components/info-bar/types.d.ts +27 -0
  131. package/dist/components/info-bar/types.js +1 -0
  132. package/dist/components/label/docs/llms.md +67 -0
  133. package/dist/components/label/label.svelte +95 -0
  134. package/dist/components/label/label.svelte.d.ts +4 -0
  135. package/dist/components/label/types.d.ts +32 -0
  136. package/dist/components/label/types.js +1 -0
  137. package/dist/components/list-view/docs/llms.md +110 -0
  138. package/dist/components/list-view/list-view-item.svelte +168 -0
  139. package/dist/components/list-view/list-view-item.svelte.d.ts +25 -0
  140. package/dist/components/list-view/list-view.svelte +137 -0
  141. package/dist/components/list-view/list-view.svelte.d.ts +25 -0
  142. package/dist/components/list-view/types.d.ts +95 -0
  143. package/dist/components/list-view/types.js +1 -0
  144. package/dist/components/list-view/utils.d.ts +6 -0
  145. package/dist/components/list-view/utils.js +12 -0
  146. package/dist/components/menu/context-menu-trigger.svelte +84 -0
  147. package/dist/components/menu/context-menu-trigger.svelte.d.ts +9 -0
  148. package/dist/components/menu/docs/llms.md +169 -0
  149. package/dist/components/menu/menu-divider.svelte +9 -0
  150. package/dist/components/menu/menu-divider.svelte.d.ts +26 -0
  151. package/dist/components/menu/menu-group.svelte +31 -0
  152. package/dist/components/menu/menu-group.svelte.d.ts +4 -0
  153. package/dist/components/menu/menu-item-checkbox.svelte +143 -0
  154. package/dist/components/menu/menu-item-checkbox.svelte.d.ts +15 -0
  155. package/dist/components/menu/menu-item-radio.svelte +147 -0
  156. package/dist/components/menu/menu-item-radio.svelte.d.ts +15 -0
  157. package/dist/components/menu/menu-item-switch.svelte +194 -0
  158. package/dist/components/menu/menu-item-switch.svelte.d.ts +15 -0
  159. package/dist/components/menu/menu-item.svelte +124 -0
  160. package/dist/components/menu/menu-item.svelte.d.ts +18 -0
  161. package/dist/components/menu/menu-list.svelte +38 -0
  162. package/dist/components/menu/menu-list.svelte.d.ts +5 -0
  163. package/dist/components/menu/menu-popover.svelte +125 -0
  164. package/dist/components/menu/menu-popover.svelte.d.ts +12 -0
  165. package/dist/components/menu/menu-trigger.svelte +121 -0
  166. package/dist/components/menu/menu-trigger.svelte.d.ts +4 -0
  167. package/dist/components/menu/menu.svelte +124 -0
  168. package/dist/components/menu/menu.svelte.d.ts +4 -0
  169. package/dist/components/menu/menu.svelte.js +77 -0
  170. package/dist/components/menu/types.d.ts +127 -0
  171. package/dist/components/menu/types.js +1 -0
  172. package/dist/components/number-box/docs/llms.md +37 -0
  173. package/dist/components/number-box/number-box.svelte +115 -0
  174. package/dist/components/number-box/number-box.svelte.d.ts +15 -0
  175. package/dist/components/number-box/types.d.ts +16 -0
  176. package/dist/components/number-box/types.js +1 -0
  177. package/dist/components/persona/docs/llms.md +107 -0
  178. package/dist/components/persona/persona.svelte +79 -0
  179. package/dist/components/persona/persona.svelte.d.ts +4 -0
  180. package/dist/components/persona/types.d.ts +42 -0
  181. package/dist/components/persona/types.js +1 -0
  182. package/dist/components/progress-bar/docs/llms.md +67 -0
  183. package/dist/components/progress-bar/progress-bar.svelte +167 -0
  184. package/dist/components/progress-bar/progress-bar.svelte.d.ts +15 -0
  185. package/dist/components/progress-bar/types.d.ts +39 -0
  186. package/dist/components/progress-bar/types.js +1 -0
  187. package/dist/components/progress-ring/docs/llms.md +76 -0
  188. package/dist/components/progress-ring/progress-ring.svelte +145 -0
  189. package/dist/components/progress-ring/progress-ring.svelte.d.ts +15 -0
  190. package/dist/components/progress-ring/types.d.ts +42 -0
  191. package/dist/components/progress-ring/types.js +1 -0
  192. package/dist/components/radio-button/docs/llms.md +64 -0
  193. package/dist/components/radio-button/radio-button.svelte +129 -0
  194. package/dist/components/radio-button/radio-button.svelte.d.ts +19 -0
  195. package/dist/components/radio-button/types.d.ts +24 -0
  196. package/dist/components/radio-button/types.js +1 -0
  197. package/dist/components/skeleton/docs/llms.md +67 -0
  198. package/dist/components/skeleton/skeleton.svelte +106 -0
  199. package/dist/components/skeleton/skeleton.svelte.d.ts +39 -0
  200. package/dist/components/skeleton/types.d.ts +24 -0
  201. package/dist/components/skeleton/types.js +1 -0
  202. package/dist/components/slider/docs/llms.md +75 -0
  203. package/dist/components/slider/slider.svelte +486 -0
  204. package/dist/components/slider/slider.svelte.d.ts +19 -0
  205. package/dist/components/slider/types.d.ts +102 -0
  206. package/dist/components/slider/types.js +1 -0
  207. package/dist/components/text-box/docs/llms.md +86 -0
  208. package/dist/components/text-box/text-box-button.svelte +65 -0
  209. package/dist/components/text-box/text-box-button.svelte.d.ts +9 -0
  210. package/dist/components/text-box/text-box.svelte +299 -0
  211. package/dist/components/text-box/text-box.svelte.d.ts +16 -0
  212. package/dist/components/text-box/types.d.ts +60 -0
  213. package/dist/components/text-box/types.js +1 -0
  214. package/dist/components/textarea/docs/llms.md +55 -0
  215. package/dist/components/textarea/textarea.svelte +151 -0
  216. package/dist/components/textarea/textarea.svelte.d.ts +17 -0
  217. package/dist/components/textarea/types.d.ts +33 -0
  218. package/dist/components/textarea/types.js +1 -0
  219. package/dist/components/time-picker/docs/llms.md +47 -0
  220. package/dist/components/time-picker/index.d.ts +1 -0
  221. package/dist/components/time-picker/index.js +1 -0
  222. package/dist/components/time-picker/time-picker.svelte +336 -0
  223. package/dist/components/time-picker/time-picker.svelte.d.ts +4 -0
  224. package/dist/components/time-picker/types.d.ts +54 -0
  225. package/dist/components/time-picker/types.js +1 -0
  226. package/dist/components/toggle-switch/docs/llms.md +39 -0
  227. package/dist/components/toggle-switch/toggle-switch.svelte +151 -0
  228. package/dist/components/toggle-switch/toggle-switch.svelte.d.ts +17 -0
  229. package/dist/components/toggle-switch/types.d.ts +20 -0
  230. package/dist/components/toggle-switch/types.js +1 -0
  231. package/dist/components/tooltip/docs/llms.md +74 -0
  232. package/dist/components/tooltip/tooltip.svelte +246 -0
  233. package/dist/components/tooltip/tooltip.svelte.d.ts +18 -0
  234. package/dist/components/tooltip/types.d.ts +67 -0
  235. package/dist/components/tooltip/types.js +1 -0
  236. package/dist/components/tree-view/docs/llms.md +117 -0
  237. package/dist/components/tree-view/tree-view-item-content.svelte +158 -0
  238. package/dist/components/tree-view/tree-view-item-content.svelte.d.ts +4 -0
  239. package/dist/components/tree-view/tree-view-item.svelte +197 -0
  240. package/dist/components/tree-view/tree-view-item.svelte.d.ts +4 -0
  241. package/dist/components/tree-view/tree-view.svelte +220 -0
  242. package/dist/components/tree-view/tree-view.svelte.d.ts +4 -0
  243. package/dist/components/tree-view/tree-view.svelte.js +111 -0
  244. package/dist/components/tree-view/types.d.ts +185 -0
  245. package/dist/components/tree-view/types.js +1 -0
  246. package/dist/css/class-darkmode.css +186 -0
  247. package/dist/css/media-darkmode.css +189 -0
  248. package/dist/css/reset.css +53 -0
  249. package/dist/css/theme.css +276 -0
  250. package/dist/css/typography.css +67 -0
  251. package/dist/css/utils.d.ts +1 -0
  252. package/dist/css/utils.js +153 -0
  253. package/dist/index.d.ts +63 -0
  254. package/dist/index.js +129 -0
  255. package/dist/internal/components/dynamic-carousel/dynamic-carousel.svelte +449 -0
  256. package/dist/internal/components/dynamic-carousel/dynamic-carousel.svelte.d.ts +22 -0
  257. package/dist/internal/components/render-soc/render-soc.svelte +29 -0
  258. package/dist/internal/components/render-soc/render-soc.svelte.d.ts +30 -0
  259. package/dist/internal/constants.d.ts +26 -0
  260. package/dist/internal/constants.js +4036 -0
  261. package/dist/internal/context.d.ts +14 -0
  262. package/dist/internal/context.js +13 -0
  263. package/dist/internal/dom-utils.svelte.d.ts +6 -0
  264. package/dist/internal/dom-utils.svelte.js +46 -0
  265. package/dist/internal/floating-ui/floating.svelte.d.ts +15 -0
  266. package/dist/internal/floating-ui/floating.svelte.js +26 -0
  267. package/dist/internal/floating-ui/utils.d.ts +3 -0
  268. package/dist/internal/floating-ui/utils.js +30 -0
  269. package/dist/internal/index.d.ts +9 -0
  270. package/dist/internal/index.js +9 -0
  271. package/dist/internal/polyfills/expander.svelte.d.ts +21 -0
  272. package/dist/internal/polyfills/expander.svelte.js +96 -0
  273. package/dist/internal/transitions.d.ts +32 -0
  274. package/dist/internal/transitions.js +37 -0
  275. package/dist/internal/utils.d.ts +22 -0
  276. package/dist/internal/utils.js +63 -0
  277. package/dist/providers/fluentui-svelte/fluentui-svelte.d.ts +19 -0
  278. package/dist/providers/fluentui-svelte/fluentui-svelte.js +11 -0
  279. package/dist/providers/fluentui-svelte/fluentui-svelte.svelte +68 -0
  280. package/dist/providers/fluentui-svelte/fluentui-svelte.svelte.d.ts +9 -0
  281. package/dist/types/index.d.ts +117 -0
  282. package/dist/types/index.js +1 -0
  283. package/package.json +142 -0
@@ -0,0 +1,75 @@
1
+ # Slider
2
+
3
+ A slider lets users select a value from a continuous or discrete range by dragging a thumb along a track. It supports horizontal and vertical orientations, tick marks, a value tooltip and reverse direction.
4
+
5
+ ## Usage
6
+
7
+ ```svelte
8
+ <script>
9
+ import { Slider } from 'fluentui-svelte';
10
+ </script>
11
+
12
+ <Slider value={50} min={0} max={100} />
13
+ ```
14
+
15
+ ## Component API
16
+
17
+ A slider allows users to select a value from a continuous or discrete range by moving a thumb along a track. It supports horizontal and vertical orientations, ticks, tooltips, and reverse direction.
18
+
19
+ ## Examples
20
+
21
+ ### Range and Step
22
+
23
+ Use the `min`, `max`, and `step` props to control the range of values and the increment between them.
24
+
25
+ ```svelte
26
+ <Slider value={20} min={0} max={50} step={5} />
27
+ ```
28
+
29
+ ### Ticks
30
+
31
+ Provide an array of values to the `ticks` prop to render tick marks along the track. Use `tickPlacement` to position them `around`, `before`, or `after` the rail.
32
+
33
+ ```svelte
34
+ <Slider value={50} step={25} ticks={[0, 25, 50, 75, 100]} />
35
+ ```
36
+
37
+ ### Vertical Orientation
38
+
39
+ Set `orientation="vertical"` to lay the slider out vertically.
40
+
41
+ ```svelte
42
+ <Slider value={40} orientation="vertical" />
43
+ ```
44
+
45
+ ### Disabled
46
+
47
+ Set the `disabled` prop to prevent interaction with the slider.
48
+
49
+ ```svelte
50
+ <Slider value={30} disabled />
51
+ ```
52
+
53
+ ## Component Props
54
+
55
+ | Name | Type | Description |
56
+ | ------------------ | --------------------------------- | -------------------------------------------------------------------------- |
57
+ | `value` | `number` | The current value of the slider. Bindable. Default: `0`. |
58
+ | `min` | `number` | The minimum value of the range. Default: `0`. |
59
+ | `max` | `number` | The maximum value of the range. Default: `100`. |
60
+ | `step` | `number` | The increment between selectable values. Default: `1`. |
61
+ | `ticks` | `number[]` | An array of values at which to render tick marks. Default: `[]`. |
62
+ | `tickPlacement` | `'around' \| 'before' \| 'after'` | Where tick marks are placed relative to the rail. Default: `around`. |
63
+ | `prefix` | `string` | Text prepended to the value shown in the tooltip. Default: `''`. |
64
+ | `suffix` | `string` | Text appended to the value shown in the tooltip. Default: `''`. |
65
+ | `track` | `boolean` | Whether the filled track is shown. Default: `true`. |
66
+ | `orientation` | `'horizontal' \| 'vertical'` | The layout direction of the slider. Default: `horizontal`. |
67
+ | `reverse` | `boolean` | Reverses the direction of the slider. Default: `false`. |
68
+ | `disabled` | `boolean` | Whether the slider is disabled. Default: `false`. |
69
+ | `sync` | `boolean` | Snaps the initial value to the nearest step on initialization. |
70
+ | `tooltip` | `boolean` | Whether the value tooltip is shown while interacting. Default: `true`. |
71
+ | `tooltipPlacement` | `Placement` | The placement of the tooltip relative to the thumb. Default: `top`. |
72
+ | `tooltipContent` | `string \| Snippet \| Component` | Custom content for the tooltip. Defaults to `prefix` + `value` + `suffix`. |
73
+ | `onChange` | `(value: number) => void` | Callback fired when the value changes. |
74
+ | `class` | `string` | Additional CSS classes applied to the slider. |
75
+ | `ref` | `HTMLElement` | The DOM reference of the slider element. Bindable. |
@@ -0,0 +1,486 @@
1
+ <script module>
2
+ </script>
3
+
4
+ <script lang="ts">
5
+ import { untrack } from 'svelte';
6
+ import { watch } from 'runed';
7
+ import { Tooltip } from '../../index.js';
8
+ import { preventDefault } from '../../internal/index.js';
9
+ import type { Attachment } from 'svelte/attachments';
10
+ import type { MouseOrTouchEvent, SliderProps } from './types.js';
11
+
12
+ let {
13
+ value = $bindable(0),
14
+ min = 0,
15
+ max = 100,
16
+ step = 1,
17
+ ticks = [],
18
+ tickPlacement = 'around',
19
+ prefix = '',
20
+ suffix = '',
21
+ track = true,
22
+ orientation = 'horizontal',
23
+ reverse = false,
24
+ sync,
25
+ disabled = false,
26
+ tooltip = true,
27
+ tooltipPlacement = 'top',
28
+ tooltipContent,
29
+ onChange,
30
+ class: classes,
31
+ ref = $bindable(),
32
+ inputRef = $bindable(),
33
+ thumbRef = $bindable(),
34
+ tooltipRef = $bindable(),
35
+ railRef = $bindable(),
36
+ trackRef = $bindable(),
37
+ tickBarRef = $bindable(),
38
+ 'aria-label': ariaLabel = 'Slider',
39
+ ...attributes
40
+ }: SliderProps = $props();
41
+
42
+ watch(
43
+ () => step,
44
+ () => {
45
+ if (step > max - min) {
46
+ throw new Error('Step must be less than or equal to the difference between max and min');
47
+ } else if (min >= max) {
48
+ throw new Error('Min must be less than max');
49
+ }
50
+ }
51
+ );
52
+
53
+ watch(
54
+ () => value,
55
+ () => {
56
+ const clamped = Math.min(Math.max(value, min), max);
57
+ if (clamped !== value) {
58
+ value = clamped;
59
+ onChange?.(value);
60
+ }
61
+ }
62
+ );
63
+
64
+ let dragging = $state(false);
65
+ let holding = $state(false);
66
+ let thumbClientWidth = $state(20);
67
+ let percentage = $derived(valueToPercentage(value));
68
+ let directionAwareReverse = $derived(
69
+ ref && window
70
+ ? window.getComputedStyle(ref)?.direction === 'ltr' && orientation === 'horizontal'
71
+ ? reverse
72
+ : !reverse
73
+ : reverse
74
+ );
75
+
76
+ function valueToPercentage(v: number) {
77
+ return ((v - min) / (max - min)) * 100;
78
+ }
79
+
80
+ function cancelMove() {
81
+ holding = false;
82
+ dragging = false;
83
+ }
84
+
85
+ function handleMove(event: MouseOrTouchEvent) {
86
+ if (holding) {
87
+ dragging = true;
88
+ calculateValue(event);
89
+ }
90
+ }
91
+
92
+ function calculateValue(event: MouseOrTouchEvent) {
93
+ if (disabled || !railRef) return;
94
+ const { top, bottom, left, right, width, height } = railRef.getBoundingClientRect();
95
+ const percentageX = (event as TouchEvent).touches
96
+ ? (event as TouchEvent).touches[0].clientX
97
+ : (event as MouseEvent).clientX;
98
+ const percentageY = (event as TouchEvent).touches
99
+ ? (event as TouchEvent).touches[0].clientY
100
+ : (event as MouseEvent).clientY;
101
+
102
+ const position = orientation === 'horizontal' ? percentageX : percentageY;
103
+ const startingPos =
104
+ orientation === 'horizontal' ? (directionAwareReverse ? right : left) : directionAwareReverse ? top : bottom;
105
+ const length = orientation === 'horizontal' ? width : height;
106
+
107
+ let nextStep =
108
+ min +
109
+ Math.round(
110
+ ((max - min) *
111
+ ((position - startingPos) / length) *
112
+ (directionAwareReverse ? -1 : 1) *
113
+ (orientation === 'vertical' ? -1 : 1)) /
114
+ step
115
+ ) *
116
+ step;
117
+
118
+ value = nextStep;
119
+ }
120
+
121
+ function handleArrowKeys(event: KeyboardEvent) {
122
+ const { key } = event;
123
+
124
+ if (key === 'ArrowDown' || key === 'ArrowUp') event.preventDefault();
125
+ if (key === 'ArrowLeft' || (key === 'ArrowDown' && !disabled)) {
126
+ if (reverse) {
127
+ stepUp();
128
+ } else {
129
+ stepDown();
130
+ }
131
+ } else if (key === 'ArrowRight' || (key === 'ArrowUp' && !disabled)) {
132
+ if (reverse) {
133
+ stepDown();
134
+ } else {
135
+ stepUp();
136
+ }
137
+ }
138
+ }
139
+
140
+ function handleTouchStart(event: TouchEvent) {
141
+ if (event.cancelable) event.preventDefault();
142
+ holding = true;
143
+ }
144
+
145
+ function linearScale(input: readonly [number, number], output: readonly [number, number]) {
146
+ return (value: number) => {
147
+ if (input[0] === input[1] || output[0] === output[1]) return output[0];
148
+ const ratio = (output[1] - output[0]) / (input[1] - input[0]);
149
+ return output[0] + ratio * (value - input[0]);
150
+ };
151
+ }
152
+
153
+ function stepUp() {
154
+ value += step;
155
+ if (value > max) {
156
+ value = max;
157
+ }
158
+ }
159
+
160
+ function stepDown() {
161
+ value -= step;
162
+ if (value < min) {
163
+ value = min;
164
+ }
165
+ }
166
+
167
+ $effect.pre(() => {
168
+ if (!sync) return;
169
+
170
+ untrack(() => {
171
+ // set the nearest step value on initialization (if the provided value is not exactly on a step)
172
+ const nearestStepValue = Math.round((value - min) / step) * step + min;
173
+ if (nearestStepValue !== value) {
174
+ value = nearestStepValue;
175
+ }
176
+ });
177
+ });
178
+ </script>
179
+
180
+ <!--
181
+ @component
182
+ A slider allows users to select a value from a continuous or discrete range by moving a thumb along a track. It supports horizontal and vertical orientations, ticks, tooltips, and reverse direction.
183
+
184
+ - Usage:
185
+ ```tsx
186
+ <script>
187
+ import { Slider } from 'fluentui-svelte';
188
+ </script>
189
+
190
+ <Slider value={50} min={0} max={100} />
191
+ <Slider orientation="vertical" step={10} ticks={[0, 25, 50, 75, 100]} />
192
+ ```
193
+
194
+ @status WIP
195
+ -->
196
+ <svelte:window
197
+ onmousemove={handleMove}
198
+ ontouchmove={handleMove}
199
+ onmouseup={cancelMove}
200
+ ontouchend={cancelMove}
201
+ ontouchcancel={cancelMove}
202
+ />
203
+
204
+ <div
205
+ class={['fs-slider', `orientation-${orientation}`, classes, { disabled }, directionAwareReverse && 'reverse']}
206
+ bind:this={ref}
207
+ tabindex={disabled ? -1 : 0}
208
+ role="slider"
209
+ aria-label={ariaLabel}
210
+ aria-orientation={orientation}
211
+ aria-valuemin={min}
212
+ aria-valuemax={max}
213
+ aria-valuenow={value}
214
+ aria-valuetext={prefix || suffix ? `${prefix}${value}${suffix}` : undefined}
215
+ aria-disabled={disabled || undefined}
216
+ ontouchstart={handleTouchStart}
217
+ onkeydown={handleArrowKeys}
218
+ onmousedown={preventDefault(() => {
219
+ holding = true;
220
+ dragging = true;
221
+ })}
222
+ style="--slider-percentage: {percentage}%; --slider-thumb-offset: {thumbClientWidth / 2 -
223
+ linearScale([0, 50], [6, thumbClientWidth / 2])(percentage)}px;"
224
+ {...attributes}
225
+ >
226
+ {#if tooltip && !disabled}
227
+ <Tooltip
228
+ content={tooltipContent ?? `${prefix}${value}${suffix}`}
229
+ placement={tooltipPlacement}
230
+ relationship="description"
231
+ bind:preventClose={dragging}
232
+ bind:ref={tooltipRef}
233
+ withArrow
234
+ class="slider-tooltip"
235
+ animationFrame
236
+ >
237
+ {#snippet children(args, ref)}
238
+ {@render sliderThumb(args, ref)}
239
+ {/snippet}
240
+ </Tooltip>
241
+ {:else}
242
+ {@render sliderThumb()}
243
+ {/if}
244
+
245
+ <div class="slider-rail" bind:this={railRef}>
246
+ {#if track}
247
+ <div class="slider-track" bind:this={trackRef}></div>
248
+ {/if}
249
+ </div>
250
+
251
+ {#if ticks}
252
+ <div class="slider-tick-bar placement-{tickPlacement}" bind:this={tickBarRef}>
253
+ {#each ticks as tick (tick)}
254
+ <div class="slider-tick" style="--slider-tick-percentage: {valueToPercentage(tick)}%"></div>
255
+ {/each}
256
+ </div>
257
+ {/if}
258
+ <input type="range" hidden {min} {max} {step} {disabled} {value} bind:this={inputRef} />
259
+ </div>
260
+
261
+ {#snippet sliderThumb(attrs: Record<string, unknown> | undefined = undefined, ref: Attachment | undefined = undefined)}
262
+ <div
263
+ class="slider-thumb"
264
+ {...attrs}
265
+ {@attach ref ? ref : undefined}
266
+ bind:this={thumbRef}
267
+ bind:clientWidth={thumbClientWidth}
268
+ ></div>
269
+ {/snippet}
270
+
271
+ <style>
272
+ .fs-slider {
273
+ display: flex;
274
+ justify-content: center;
275
+ align-items: center;
276
+ position: relative;
277
+ border-radius: var(--fs-control-border-radius);
278
+ min-inline-size: 32px;
279
+ min-block-size: 32px;
280
+
281
+ & :focus-visible {
282
+ outline: none;
283
+ box-shadow: var(--fs-focus-stroke-outer);
284
+ }
285
+
286
+ &.orientation-horizontal {
287
+ block-size: 32px;
288
+ inline-size: 100%;
289
+
290
+ & .slider-rail {
291
+ inline-size: 100%;
292
+ block-size: 4px;
293
+ }
294
+
295
+ & .slider-track {
296
+ inline-size: var(--slider-percentage);
297
+ block-size: 100%;
298
+ }
299
+
300
+ & .slider-thumb {
301
+ inset-inline-start: calc(var(--slider-percentage) + var(--slider-thumb-offset));
302
+ transform: translateX(-50%);
303
+ }
304
+
305
+ & .slider-tick {
306
+ flex-direction: column;
307
+ height: 100%;
308
+ padding: 2px 0;
309
+ inset-inline-start: var(--slider-tick-percentage);
310
+
311
+ &::before,
312
+ &::after {
313
+ width: 1px;
314
+ height: 6px;
315
+ border-inline-start: 1px solid var(--fs-control-strong-stroke-default);
316
+ }
317
+ }
318
+
319
+ &.reverse {
320
+ & .slider-rail {
321
+ justify-content: flex-end;
322
+ }
323
+
324
+ & .slider-thumb {
325
+ inset-inline-start: unset;
326
+ inset-inline-end: calc(var(--slider-percentage) + var(--slider-thumb-offset));
327
+ transform: translateX(50%);
328
+ }
329
+
330
+ & .slider-tick {
331
+ inset-inline-start: unset;
332
+ inset-inline-end: var(--slider-tick-percentage);
333
+ }
334
+ }
335
+ }
336
+
337
+ &.orientation-vertical {
338
+ block-size: 100%;
339
+ inline-size: 32px;
340
+
341
+ & .slider-rail {
342
+ align-items: flex-end;
343
+ block-size: 100%;
344
+ inline-size: 4px;
345
+ }
346
+
347
+ & .slider-track {
348
+ inline-size: 100%;
349
+ block-size: var(--slider-percentage);
350
+ }
351
+
352
+ & .slider-thumb {
353
+ inset-block-end: calc(var(--slider-percentage) + var(--slider-thumb-offset));
354
+ transform: translateY(50%);
355
+ }
356
+
357
+ & .slider-tick {
358
+ width: 100%;
359
+ padding: 0 6px;
360
+ inset-block-end: var(--slider-tick-percentage);
361
+
362
+ &::before,
363
+ &::after {
364
+ width: 4px;
365
+ height: 1px;
366
+ border-block-start: 1px solid var(--fs-control-strong-default);
367
+ }
368
+ }
369
+
370
+ &.reverse {
371
+ & .slider-rail {
372
+ align-items: flex-start;
373
+ }
374
+
375
+ & .slider-thumb {
376
+ inset-block-end: unset;
377
+ inset-block-start: calc(var(--slider-percentage) + var(--slider-thumb-offset));
378
+ transform: translateY(-50%);
379
+ }
380
+
381
+ & .slider-tick {
382
+ inset-block-end: unset;
383
+ inset-block-start: var(--slider-tick-percentage);
384
+ }
385
+ }
386
+ }
387
+
388
+ &.disabled {
389
+ & .slider-rail {
390
+ background-color: var(--fs-accent-fill-disabled);
391
+ }
392
+
393
+ & .slider-track {
394
+ background-color: var(--fs-accent-fill-disabled);
395
+ }
396
+
397
+ & .slider-thumb::before {
398
+ background-color: var(--fs-accent-fill-disabled);
399
+ transform: none;
400
+ }
401
+
402
+ & .slider-tick::before,
403
+ & .slider-tick::after {
404
+ border-color: var(--fs-control-strong-disabled);
405
+ }
406
+ }
407
+ }
408
+
409
+ .slider-rail {
410
+ display: flex;
411
+ align-items: center;
412
+ overflow: hidden;
413
+ border-radius: 50px;
414
+ background-color: var(--fs-control-strong-default);
415
+ }
416
+
417
+ .slider-track {
418
+ background-color: var(--fs-accent-fill-default);
419
+ }
420
+
421
+ .slider-tick-bar {
422
+ position: absolute;
423
+ z-index: -1;
424
+ width: 100%;
425
+ height: 100%;
426
+ inset-block-start: 0;
427
+ inset-inline-start: 0;
428
+
429
+ &.placement-before .slider-tick::after {
430
+ visibility: hidden;
431
+ }
432
+
433
+ &.placement-after .slider-tick::before {
434
+ visibility: hidden;
435
+ }
436
+ }
437
+
438
+ .slider-tick {
439
+ display: flex;
440
+ justify-content: space-between;
441
+ align-items: center;
442
+ position: absolute;
443
+ box-sizing: border-box;
444
+
445
+ &::before,
446
+ &::after {
447
+ content: '';
448
+ }
449
+ }
450
+
451
+ .slider-thumb {
452
+ display: flex;
453
+ justify-content: center;
454
+ align-items: center;
455
+ position: absolute;
456
+ z-index: 10;
457
+ border-radius: 100%;
458
+ background-color: var(--fs-control-solid);
459
+ box-shadow: 0 0 0 1px var(--fs-control-stroke-default);
460
+ inline-size: 20px;
461
+ block-size: 20px;
462
+
463
+ &::before {
464
+ content: '';
465
+ position: absolute;
466
+ border-radius: 100%;
467
+ background-color: var(--fs-accent-fill-default);
468
+ transition: var(--fs-fast-duration) var(--fs-control-fast-out-slow-in-easing) transform;
469
+ inline-size: 12px;
470
+ block-size: 12px;
471
+ }
472
+
473
+ &:hover {
474
+ &::before {
475
+ transform: scale(1.167);
476
+ }
477
+ }
478
+
479
+ &:active {
480
+ &::before {
481
+ background-color: var(--fs-accent-fill-tertiary);
482
+ transform: scale(0.833);
483
+ }
484
+ }
485
+ }
486
+ </style>
@@ -0,0 +1,19 @@
1
+ import type { SliderProps } from './types.ts';
2
+ /**
3
+ * A slider allows users to select a value from a continuous or discrete range by moving a thumb along a track. It supports horizontal and vertical orientations, ticks, tooltips, and reverse direction.
4
+ *
5
+ * - Usage:
6
+ * ```tsx
7
+ * <script>
8
+ * import { Slider } from 'fluentui-svelte';
9
+ * </script>
10
+ *
11
+ * <Slider value={50} min={0} max={100} />
12
+ * <Slider orientation="vertical" step={10} ticks={[0, 25, 50, 75, 100]} />
13
+ * ```
14
+ *
15
+ * @status WIP
16
+ */
17
+ declare const Slider: import("svelte").Component<SliderProps, {}, "ref" | "value" | "inputRef" | "thumbRef" | "tooltipRef" | "railRef" | "trackRef" | "tickBarRef">;
18
+ type Slider = ReturnType<typeof Slider>;
19
+ export default Slider;
@@ -0,0 +1,102 @@
1
+ import type { Placement } from '@floating-ui/dom';
2
+ import type { Component, Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ /** @propsmith SliderProps */
5
+ export type SliderProps = {
6
+ /** The current value of the slider.
7
+ * @default 0
8
+ * @bindable
9
+ */
10
+ value?: number;
11
+ /** The minimum value of the slider.
12
+ * @default 0
13
+ */
14
+ min?: number;
15
+ /** The maximum value of the slider.
16
+ * @default 100
17
+ */
18
+ max?: number;
19
+ /** How much the value moves on every step.
20
+ * @default 1
21
+ */
22
+ step?: number;
23
+ /** The values the tick marks are drawn at.
24
+ * @default []
25
+ */
26
+ ticks?: number[];
27
+ /** Where the tick marks sit relative to the rail.
28
+ * @default 'around'
29
+ */
30
+ tickPlacement?: 'around' | 'before' | 'after';
31
+ /** Text prepended to the value in the tooltip.
32
+ * @default ''
33
+ */
34
+ prefix?: string;
35
+ /** Text appended to the value in the tooltip.
36
+ * @default ''
37
+ */
38
+ suffix?: string;
39
+ /** Whether to fill the rail up to the current value.
40
+ * @default true
41
+ */
42
+ track?: boolean;
43
+ /** The direction the slider runs in.
44
+ * @default 'horizontal'
45
+ */
46
+ orientation?: 'horizontal' | 'vertical';
47
+ /** Runs the slider from the maximum to the minimum instead.
48
+ * @default false
49
+ */
50
+ reverse?: boolean;
51
+ /** Disables the user interaction.
52
+ * @default false
53
+ */
54
+ disabled?: boolean;
55
+ /** Snaps the thumb to the pointer as soon as it is pressed, instead of stepping towards it. */
56
+ sync?: boolean;
57
+ /** Whether to show the value in a tooltip while dragging.
58
+ * @default true
59
+ */
60
+ tooltip?: boolean;
61
+ /** Where the tooltip is placed relative to the thumb.
62
+ * @default 'top'
63
+ */
64
+ tooltipPlacement?: Placement;
65
+ /** Custom content for the tooltip, replacing the plain value.
66
+ * @type string | Snippet | Component
67
+ */
68
+ tooltipContent?: string | Snippet | Component;
69
+ /** Called whenever the value changes. */
70
+ onChange?: (value: number) => void;
71
+ /** The class to apply to the slider. */
72
+ class?: string;
73
+ /** The DOM reference of the slider element.
74
+ * @bindable
75
+ */
76
+ ref?: HTMLElement;
77
+ /** The DOM reference of the underlying input element.
78
+ * @bindable
79
+ */
80
+ inputRef?: HTMLInputElement;
81
+ /** The DOM reference of the thumb element.
82
+ * @bindable
83
+ */
84
+ thumbRef?: HTMLElement;
85
+ /** The DOM reference of the tooltip element.
86
+ * @bindable
87
+ */
88
+ tooltipRef?: HTMLElement;
89
+ /** The DOM reference of the rail element.
90
+ * @bindable
91
+ */
92
+ railRef?: HTMLElement;
93
+ /** The DOM reference of the track element.
94
+ * @bindable
95
+ */
96
+ trackRef?: HTMLElement;
97
+ /** The DOM reference of the tick bar element.
98
+ * @bindable
99
+ */
100
+ tickBarRef?: HTMLElement;
101
+ } & HTMLAttributes<HTMLDivElement>;
102
+ export type MouseOrTouchEvent = MouseEvent | TouchEvent;
@@ -0,0 +1 @@
1
+ export {};