twintrinsic 0.0.1

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 (212) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +150 -0
  3. package/dist/App/App.svelte +54 -0
  4. package/dist/App/App.svelte.d.ts +65 -0
  5. package/dist/Section.svelte +25 -0
  6. package/dist/Section.svelte.d.ts +34 -0
  7. package/dist/actions/clickOutside.d.ts +9 -0
  8. package/dist/actions/clickOutside.js +19 -0
  9. package/dist/actions/index.d.ts +1 -0
  10. package/dist/actions/index.js +1 -0
  11. package/dist/components/Accordion/Accordion.svelte +75 -0
  12. package/dist/components/Accordion/Accordion.svelte.d.ts +39 -0
  13. package/dist/components/Accordion/AccordionItem.svelte +150 -0
  14. package/dist/components/Accordion/AccordionItem.svelte.d.ts +30 -0
  15. package/dist/components/App/App.story.md +8 -0
  16. package/dist/components/App/App.story.svelte +170 -0
  17. package/dist/components/App/App.story.svelte.d.ts +22 -0
  18. package/dist/components/App/App.svelte +77 -0
  19. package/dist/components/App/App.svelte.d.ts +66 -0
  20. package/dist/components/App/Split.svelte +346 -0
  21. package/dist/components/App/Split.svelte.d.ts +54 -0
  22. package/dist/components/App/index.d.ts +2 -0
  23. package/dist/components/App/index.js +3 -0
  24. package/dist/components/AppHeader/AppHeader.svelte +439 -0
  25. package/dist/components/AppHeader/AppHeader.svelte.d.ts +24 -0
  26. package/dist/components/Avatar/Avatar.svelte +300 -0
  27. package/dist/components/Avatar/Avatar.svelte.d.ts +48 -0
  28. package/dist/components/Avatar/AvatarGroup.svelte +185 -0
  29. package/dist/components/Avatar/AvatarGroup.svelte.d.ts +46 -0
  30. package/dist/components/Badge/Badge.svelte +186 -0
  31. package/dist/components/Badge/Badge.svelte.d.ts +51 -0
  32. package/dist/components/BottomBar/BottomBar.svelte +146 -0
  33. package/dist/components/BottomBar/BottomBar.svelte.d.ts +38 -0
  34. package/dist/components/Breadcrumb/Breadcrumb.svelte +77 -0
  35. package/dist/components/Breadcrumb/Breadcrumb.svelte.d.ts +42 -0
  36. package/dist/components/Breadcrumb/BreadcrumbItem.svelte +171 -0
  37. package/dist/components/Breadcrumb/BreadcrumbItem.svelte.d.ts +38 -0
  38. package/dist/components/Button/Button.svelte +252 -0
  39. package/dist/components/Button/Button.svelte.d.ts +80 -0
  40. package/dist/components/Button/ButtonGroup.svelte +127 -0
  41. package/dist/components/Button/ButtonGroup.svelte.d.ts +44 -0
  42. package/dist/components/Card/Card.svelte +152 -0
  43. package/dist/components/Card/Card.svelte.d.ts +55 -0
  44. package/dist/components/Carousel/Carousel.svelte +461 -0
  45. package/dist/components/Carousel/Carousel.svelte.d.ts +79 -0
  46. package/dist/components/Carousel/CarouselItem.svelte +149 -0
  47. package/dist/components/Carousel/CarouselItem.svelte.d.ts +35 -0
  48. package/dist/components/Chip/Chip.svelte +288 -0
  49. package/dist/components/Chip/Chip.svelte.d.ts +71 -0
  50. package/dist/components/Chip/ChipGroup.svelte +190 -0
  51. package/dist/components/Chip/ChipGroup.svelte.d.ts +71 -0
  52. package/dist/components/CodeBlock/CodeBlock.svelte +356 -0
  53. package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +44 -0
  54. package/dist/components/CodeBlock/index.d.ts +1 -0
  55. package/dist/components/CodeBlock/index.js +1 -0
  56. package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte +145 -0
  57. package/dist/components/CodeBlockSpeed/CodeBlockSpeed.svelte.d.ts +44 -0
  58. package/dist/components/CodeEditor/CodeEditor.svelte +229 -0
  59. package/dist/components/CodeEditor/CodeEditor.svelte.d.ts +23 -0
  60. package/dist/components/Combobox/Combobox.svelte +279 -0
  61. package/dist/components/Combobox/Combobox.svelte.d.ts +34 -0
  62. package/dist/components/Container/Container.svelte +45 -0
  63. package/dist/components/Container/Container.svelte.d.ts +36 -0
  64. package/dist/components/DataTable/DataTable.svelte +879 -0
  65. package/dist/components/DataTable/DataTable.svelte.d.ts +102 -0
  66. package/dist/components/Form/AutoComplete.svelte +357 -0
  67. package/dist/components/Form/AutoComplete.svelte.d.ts +73 -0
  68. package/dist/components/Form/Calendar.svelte +429 -0
  69. package/dist/components/Form/Calendar.svelte.d.ts +53 -0
  70. package/dist/components/Form/Checkbox.svelte +196 -0
  71. package/dist/components/Form/Checkbox.svelte.d.ts +50 -0
  72. package/dist/components/Form/ColorPicker.svelte +396 -0
  73. package/dist/components/Form/ColorPicker.svelte.d.ts +43 -0
  74. package/dist/components/Form/Combobox.svelte +645 -0
  75. package/dist/components/Form/Combobox.svelte.d.ts +93 -0
  76. package/dist/components/Form/Dropdown.svelte +773 -0
  77. package/dist/components/Form/Dropdown.svelte.d.ts +81 -0
  78. package/dist/components/Form/FileUpload.svelte +796 -0
  79. package/dist/components/Form/FileUpload.svelte.d.ts +78 -0
  80. package/dist/components/Form/FloatLabel.svelte +245 -0
  81. package/dist/components/Form/FloatLabel.svelte.d.ts +44 -0
  82. package/dist/components/Form/Form.svelte +281 -0
  83. package/dist/components/Form/Form.svelte.d.ts +54 -0
  84. package/dist/components/Form/FormField.svelte +218 -0
  85. package/dist/components/Form/FormField.svelte.d.ts +47 -0
  86. package/dist/components/Form/Input.svelte +340 -0
  87. package/dist/components/Form/Input.svelte.d.ts +79 -0
  88. package/dist/components/Form/InputSwitch.svelte +189 -0
  89. package/dist/components/Form/InputSwitch.svelte.d.ts +46 -0
  90. package/dist/components/Form/InvalidState.svelte +97 -0
  91. package/dist/components/Form/InvalidState.svelte.d.ts +37 -0
  92. package/dist/components/Form/Knob.svelte +537 -0
  93. package/dist/components/Form/Knob.svelte.d.ts +78 -0
  94. package/dist/components/Form/ListInput.svelte +469 -0
  95. package/dist/components/Form/ListInput.svelte.d.ts +70 -0
  96. package/dist/components/Form/Listbox.svelte +513 -0
  97. package/dist/components/Form/Listbox.svelte.d.ts +74 -0
  98. package/dist/components/Form/NumberInput.svelte +452 -0
  99. package/dist/components/Form/NumberInput.svelte.d.ts +82 -0
  100. package/dist/components/Form/Radio.svelte +192 -0
  101. package/dist/components/Form/Radio.svelte.d.ts +53 -0
  102. package/dist/components/Form/RadioGroup.svelte +155 -0
  103. package/dist/components/Form/RadioGroup.svelte.d.ts +48 -0
  104. package/dist/components/Form/Rating.svelte +380 -0
  105. package/dist/components/Form/Rating.svelte.d.ts +64 -0
  106. package/dist/components/Form/Select.svelte +436 -0
  107. package/dist/components/Form/Select.svelte.d.ts +49 -0
  108. package/dist/components/Form/SelectGroup.svelte +34 -0
  109. package/dist/components/Form/SelectGroup.svelte.d.ts +33 -0
  110. package/dist/components/Form/Slider.svelte +622 -0
  111. package/dist/components/Form/Slider.svelte.d.ts +73 -0
  112. package/dist/components/Form/Switch.svelte +192 -0
  113. package/dist/components/Form/Switch.svelte.d.ts +46 -0
  114. package/dist/components/Form/TextInput.svelte +274 -0
  115. package/dist/components/Form/TextInput.svelte.d.ts +74 -0
  116. package/dist/components/Form/Textarea.svelte +207 -0
  117. package/dist/components/Form/Textarea.svelte.d.ts +62 -0
  118. package/dist/components/Icon/Icon.svelte +140 -0
  119. package/dist/components/Icon/Icon.svelte.d.ts +25 -0
  120. package/dist/components/Icon/index.d.ts +1 -0
  121. package/dist/components/Icon/index.js +1 -0
  122. package/dist/components/Lazy/Lazy.svelte +158 -0
  123. package/dist/components/Lazy/Lazy.svelte.d.ts +42 -0
  124. package/dist/components/Masonry/Masonry.svelte +299 -0
  125. package/dist/components/Masonry/Masonry.svelte.d.ts +55 -0
  126. package/dist/components/Menu/Menu/Menu.svelte +65 -0
  127. package/dist/components/Menu/Menu/Menu.svelte.d.ts +17 -0
  128. package/dist/components/Menu/Menu/MenuItem.svelte +90 -0
  129. package/dist/components/Menu/Menu/MenuItem.svelte.d.ts +27 -0
  130. package/dist/components/Modal/Modal.svelte +334 -0
  131. package/dist/components/Modal/Modal.svelte.d.ts +55 -0
  132. package/dist/components/Panel/Card.svelte +141 -0
  133. package/dist/components/Panel/Card.svelte.d.ts +52 -0
  134. package/dist/components/Panel/Hero/Hero.story.md +9 -0
  135. package/dist/components/Panel/Hero/Hero.story.svelte +49 -0
  136. package/dist/components/Panel/Hero/Hero.story.svelte.d.ts +21 -0
  137. package/dist/components/Panel/Hero/Hero.svelte +24 -0
  138. package/dist/components/Panel/Hero/Hero.svelte.d.ts +32 -0
  139. package/dist/components/Panel/LazyPanel.svelte +110 -0
  140. package/dist/components/Panel/LazyPanel.svelte.d.ts +46 -0
  141. package/dist/components/Panel/Panel.svelte +205 -0
  142. package/dist/components/Panel/Panel.svelte.d.ts +23 -0
  143. package/dist/components/Progress/Progress.svelte +220 -0
  144. package/dist/components/Progress/Progress.svelte.d.ts +61 -0
  145. package/dist/components/Separator/Separator.svelte +109 -0
  146. package/dist/components/Separator/Separator.svelte.d.ts +35 -0
  147. package/dist/components/Sidebar/Sidebar.svelte +213 -0
  148. package/dist/components/Sidebar/Sidebar.svelte.d.ts +60 -0
  149. package/dist/components/Skeleton/Skeleton.svelte +170 -0
  150. package/dist/components/Skeleton/Skeleton.svelte.d.ts +48 -0
  151. package/dist/components/Stepper/Stepper.svelte +111 -0
  152. package/dist/components/Stepper/Stepper.svelte.d.ts +54 -0
  153. package/dist/components/Stepper/StepperStep.svelte +369 -0
  154. package/dist/components/Stepper/StepperStep.svelte.d.ts +63 -0
  155. package/dist/components/Table/Table.svelte +167 -0
  156. package/dist/components/Table/Table.svelte.d.ts +56 -0
  157. package/dist/components/Table/TableBody.svelte +41 -0
  158. package/dist/components/Table/TableBody.svelte.d.ts +33 -0
  159. package/dist/components/Table/TableCell.svelte +76 -0
  160. package/dist/components/Table/TableCell.svelte.d.ts +36 -0
  161. package/dist/components/Table/TableHead.svelte +41 -0
  162. package/dist/components/Table/TableHead.svelte.d.ts +32 -0
  163. package/dist/components/Table/TableHeader.svelte +148 -0
  164. package/dist/components/Table/TableHeader.svelte.d.ts +42 -0
  165. package/dist/components/Table/TableRow.svelte +99 -0
  166. package/dist/components/Table/TableRow.svelte.d.ts +40 -0
  167. package/dist/components/Tabs/Tab.svelte +145 -0
  168. package/dist/components/Tabs/Tab.svelte.d.ts +36 -0
  169. package/dist/components/Tabs/TabList.svelte +60 -0
  170. package/dist/components/Tabs/TabList.svelte.d.ts +32 -0
  171. package/dist/components/Tabs/TabPanel.svelte +118 -0
  172. package/dist/components/Tabs/TabPanel.svelte.d.ts +38 -0
  173. package/dist/components/Tabs/Tabs.svelte +287 -0
  174. package/dist/components/Tabs/Tabs.svelte.d.ts +50 -0
  175. package/dist/components/Tag/Tag.svelte +260 -0
  176. package/dist/components/Tag/Tag.svelte.d.ts +54 -0
  177. package/dist/components/Tag/TagGroup.svelte +147 -0
  178. package/dist/components/Tag/TagGroup.svelte.d.ts +62 -0
  179. package/dist/components/ThemeToggle/ThemeToggle.svelte +93 -0
  180. package/dist/components/ThemeToggle/ThemeToggle.svelte.d.ts +12 -0
  181. package/dist/components/Timeline/Timeline.svelte +144 -0
  182. package/dist/components/Timeline/Timeline.svelte.d.ts +48 -0
  183. package/dist/components/Timeline/TimelineItem.svelte +391 -0
  184. package/dist/components/Timeline/TimelineItem.svelte.d.ts +63 -0
  185. package/dist/components/Toast/Toast.svelte +313 -0
  186. package/dist/components/Toast/Toast.svelte.d.ts +44 -0
  187. package/dist/components/Toast/toastStore.d.ts +40 -0
  188. package/dist/components/Toast/toastStore.js +293 -0
  189. package/dist/components/Tooltip/Tooltip.svelte +282 -0
  190. package/dist/components/Tooltip/Tooltip.svelte.d.ts +55 -0
  191. package/dist/components/Tree/Tree.svelte +129 -0
  192. package/dist/components/Tree/Tree.svelte.d.ts +61 -0
  193. package/dist/components/Tree/TreeNode.svelte +332 -0
  194. package/dist/components/Tree/TreeNode.svelte.d.ts +55 -0
  195. package/dist/components/icons/TwintrinsicLogo.svelte +73 -0
  196. package/dist/components/icons/TwintrinsicLogo.svelte.d.ts +17 -0
  197. package/dist/components/icons/twintrinsic-source.svg +73 -0
  198. package/dist/components/icons/twintrinsic.svg +38 -0
  199. package/dist/docs/EventsTable.svelte +86 -0
  200. package/dist/docs/EventsTable.svelte.d.ts +27 -0
  201. package/dist/docs/PropsTable.svelte +103 -0
  202. package/dist/docs/PropsTable.svelte.d.ts +28 -0
  203. package/dist/docs/index.d.ts +2 -0
  204. package/dist/docs/index.js +2 -0
  205. package/dist/helpers/detectLanguage.d.ts +6 -0
  206. package/dist/helpers/detectLanguage.js +60 -0
  207. package/dist/helpers/index.d.ts +1 -0
  208. package/dist/helpers/index.js +1 -0
  209. package/dist/index.d.ts +86 -0
  210. package/dist/index.js +94 -0
  211. package/dist/twintrinsic.css +347 -0
  212. package/package.json +98 -0
@@ -0,0 +1,622 @@
1
+ <!--
2
+ @component
3
+ Slider - A component for selecting values from a range.
4
+ Provides consistent styling, accessibility features, and interactive options.
5
+
6
+ Usage:
7
+ ```svelte
8
+ <Slider value={50} min={0} max={100} />
9
+
10
+ <Slider
11
+ value={[20, 80]}
12
+ min={0}
13
+ max={100}
14
+ step={5}
15
+ showTicks
16
+ showValue
17
+ onchange={(e) => console.log(e.detail.value)}
18
+ />
19
+
20
+ <Slider
21
+ value={25}
22
+ min={0}
23
+ max={100}
24
+ disabled={false}
25
+ variant="primary"
26
+ orientation="horizontal"
27
+ />
28
+ ```
29
+ -->
30
+ <script>
31
+ import { onDestroy } from "svelte"
32
+
33
+ const {
34
+ /** @type {string} - Additional CSS classes */
35
+ class: className = "",
36
+
37
+ /** @type {string} - HTML id for accessibility */
38
+ id = crypto.randomUUID(),
39
+
40
+ /** @type {number|Array} - Current value or range [min, max] */
41
+ value = 0,
42
+
43
+ /** @type {number} - Minimum value */
44
+ min = 0,
45
+
46
+ /** @type {number} - Maximum value */
47
+ max = 100,
48
+
49
+ /** @type {number} - Step size */
50
+ step = 1,
51
+
52
+ /** @type {string} - Visual style variant */
53
+ variant = "primary",
54
+
55
+ /** @type {string} - Orientation (horizontal, vertical) */
56
+ orientation = "horizontal",
57
+
58
+ /** @type {boolean} - Whether the slider is disabled */
59
+ disabled = false,
60
+
61
+ /** @type {boolean} - Whether to show tick marks */
62
+ showTicks = false,
63
+
64
+ /** @type {Array} - Custom tick values */
65
+ tickValues = [],
66
+
67
+ /** @type {boolean} - Whether to show the current value */
68
+ showValue = false,
69
+
70
+ /** @type {string} - Format for displayed value */
71
+ valueFormat = "{value}",
72
+
73
+ /** @type {boolean} - Whether to show tooltips on hover/drag */
74
+ showTooltip = false,
75
+
76
+ /** @type {string} - Name attribute for form submission */
77
+ name,
78
+
79
+ /** @type {string} - ARIA label for accessibility */
80
+ ariaLabel,
81
+
82
+ /** @type {(event: CustomEvent) => void} - Change event handler */
83
+ onchange,
84
+ /** @type {(event: CustomEvent) => void} - Input event handler */
85
+ oninput,
86
+ } = $props()
87
+
88
+ // Component state
89
+ let sliderValues = $state([])
90
+ let isDragging = $state(false)
91
+ let dragIndex = $state(-1)
92
+ let hoverIndex = $state(-1)
93
+ let trackElement = $state()
94
+ let thumbElements = $state([])
95
+
96
+ // Update internal value when prop changes
97
+ $effect(() => {
98
+ sliderValues = Array.isArray(value) ? [...value] : [value]
99
+ })
100
+
101
+ // Computed values
102
+ const isRange = $derived(sliderValues.length > 1)
103
+ const range = $derived(max - min)
104
+
105
+ // Determine variant classes
106
+ const variantClasses = $derived(
107
+ {
108
+ default: "bg-muted dark:bg-muted",
109
+ primary: "bg-primary-500 dark:bg-primary-500",
110
+ secondary: "bg-secondary-500 dark:bg-secondary-500",
111
+ success: "bg-success-500 dark:bg-success-500",
112
+ warning: "bg-warning-500 dark:bg-warning-500",
113
+ error: "bg-error-500 dark:bg-error-500",
114
+ info: "bg-info-500 dark:bg-info-500",
115
+ }[variant] || "bg-primary-500 dark:bg-primary-500"
116
+ )
117
+
118
+ // Generate tick values if not provided
119
+ const ticks = $derived.by(() => {
120
+ if (!showTicks) return []
121
+
122
+ if (tickValues.length > 0) {
123
+ return tickValues
124
+ }
125
+
126
+ // Generate ticks based on step
127
+ const count = Math.floor(range / step) + 1
128
+ // Limit to a reasonable number of ticks
129
+ const stride = count > 20 ? Math.ceil(count / 20) : 1
130
+
131
+ return Array.from({ length: Math.ceil(count / stride) }, (_, i) => min + i * stride * step)
132
+ })
133
+
134
+ /**
135
+ * Calculates the percentage position for a value
136
+ * @param {number} val - Value to calculate position for
137
+ * @returns {number} - Percentage (0-100)
138
+ */
139
+ function getPercentage(val) {
140
+ return ((val - min) / range) * 100
141
+ }
142
+
143
+ /**
144
+ * Calculates the value from a percentage position
145
+ * @param {number} percentage - Percentage position (0-100)
146
+ * @returns {number} - Value
147
+ */
148
+ function getValueFromPercentage(percentage) {
149
+ const rawValue = min + (percentage / 100) * range
150
+
151
+ // Round to nearest step
152
+ const steppedValue = Math.round(rawValue / step) * step
153
+
154
+ // Ensure value is within bounds
155
+ return Math.max(min, Math.min(max, steppedValue))
156
+ }
157
+
158
+ /**
159
+ * Formats the displayed value
160
+ * @param {number} val - Value to format
161
+ * @returns {string} - Formatted value
162
+ */
163
+ function formatValue(val) {
164
+ return valueFormat.replace("{value}", val)
165
+ }
166
+
167
+ /**
168
+ * Updates the value based on pointer position
169
+ * @param {MouseEvent|TouchEvent} event - Pointer event
170
+ */
171
+ function updateValue(event) {
172
+ if (disabled || !trackElement) return
173
+
174
+ const rect = trackElement.getBoundingClientRect()
175
+ const clientPos = event.type.startsWith("touch") ? event.touches[0].clientX : event.clientX
176
+
177
+ // Calculate percentage
178
+ let percentage
179
+ if (orientation === "horizontal") {
180
+ percentage = ((clientPos - rect.left) / rect.width) * 100
181
+ } else {
182
+ percentage = ((rect.bottom - clientPos) / rect.height) * 100
183
+ }
184
+
185
+ // Clamp percentage
186
+ percentage = Math.max(0, Math.min(100, percentage))
187
+
188
+ // Get value from percentage
189
+ const newValue = getValueFromPercentage(percentage)
190
+
191
+ // Update the appropriate thumb
192
+ if (isRange) {
193
+ if (dragIndex >= 0) {
194
+ // Update the dragging thumb
195
+ sliderValues[dragIndex] = newValue
196
+
197
+ // Ensure values remain in order
198
+ if (dragIndex === 0 && newValue > sliderValues[1]) {
199
+ sliderValues[0] = sliderValues[1]
200
+ } else if (dragIndex === 1 && newValue < sliderValues[0]) {
201
+ sliderValues[1] = sliderValues[0]
202
+ }
203
+ } else {
204
+ // Determine which thumb to update based on proximity
205
+ const dist0 = Math.abs(percentage - getPercentage(sliderValues[0]))
206
+ const dist1 = Math.abs(percentage - getPercentage(sliderValues[1]))
207
+
208
+ if (dist0 < dist1) {
209
+ sliderValues[0] = newValue
210
+ dragIndex = 0
211
+ } else {
212
+ sliderValues[1] = newValue
213
+ dragIndex = 1
214
+ }
215
+ }
216
+ } else {
217
+ sliderValues[0] = newValue
218
+ }
219
+
220
+ // Dispatch change event
221
+ dispatchChange()
222
+ }
223
+
224
+ /**
225
+ * Handles pointer down event
226
+ * @param {MouseEvent|TouchEvent} event - Pointer event
227
+ * @param {number} index - Thumb index
228
+ */
229
+ function handlePointerDown(event, index) {
230
+ if (disabled) return
231
+
232
+ isDragging = true
233
+ dragIndex = index
234
+
235
+ // Update value immediately
236
+ updateValue(event)
237
+
238
+ // Add document event listeners
239
+ if (event.type === "mousedown") {
240
+ document.addEventListener("mousemove", handlePointerMove)
241
+ document.addEventListener("mouseup", handlePointerUp)
242
+ } else if (event.type === "touchstart") {
243
+ document.addEventListener("touchmove", handlePointerMove, { passive: false })
244
+ document.addEventListener("touchend", handlePointerUp)
245
+ }
246
+
247
+ // Prevent default to avoid text selection
248
+ event.preventDefault()
249
+ }
250
+
251
+ /**
252
+ * Handles pointer move event
253
+ * @param {MouseEvent|TouchEvent} event - Pointer event
254
+ */
255
+ function handlePointerMove(event) {
256
+ if (!isDragging) return
257
+
258
+ updateValue(event)
259
+
260
+ // Prevent scrolling on touch devices
261
+ if (event.type === "touchmove") {
262
+ event.preventDefault()
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Handles pointer up event
268
+ */
269
+ function handlePointerUp() {
270
+ isDragging = false
271
+ dragIndex = -1
272
+
273
+ // Remove document event listeners
274
+ document.removeEventListener("mousemove", handlePointerMove)
275
+ document.removeEventListener("mouseup", handlePointerUp)
276
+ document.removeEventListener("touchmove", handlePointerMove)
277
+ document.removeEventListener("touchend", handlePointerUp)
278
+
279
+ // Dispatch final change event
280
+ dispatchChange()
281
+ }
282
+
283
+ /**
284
+ * Handles track click
285
+ * @param {MouseEvent} event - Click event
286
+ */
287
+ function handleTrackClick(event) {
288
+ if (disabled) return
289
+
290
+ // Only handle direct track clicks
291
+ if (event.target === trackElement) {
292
+ updateValue(event)
293
+ }
294
+ }
295
+
296
+ /**
297
+ * Handles thumb hover
298
+ * @param {number} index - Thumb index
299
+ */
300
+ function handleThumbHover(index) {
301
+ hoverIndex = index
302
+ }
303
+
304
+ /**
305
+ * Handles thumb leave
306
+ */
307
+ function handleThumbLeave() {
308
+ hoverIndex = -1
309
+ }
310
+
311
+ /**
312
+ * Handles keyboard navigation
313
+ * @param {KeyboardEvent} event - Keydown event
314
+ * @param {number} index - Thumb index
315
+ */
316
+ function handleKeydown(event, index) {
317
+ if (disabled) return
318
+
319
+ let newValue = sliderValues[index]
320
+ const stepSize = event.shiftKey ? step * 10 : step
321
+
322
+ switch (event.key) {
323
+ case "ArrowRight":
324
+ case "ArrowUp":
325
+ newValue = Math.min(max, newValue + stepSize)
326
+ break
327
+ case "ArrowLeft":
328
+ case "ArrowDown":
329
+ newValue = Math.max(min, newValue - stepSize)
330
+ break
331
+ case "Home":
332
+ newValue = min
333
+ break
334
+ case "End":
335
+ newValue = max
336
+ break
337
+ default:
338
+ return
339
+ }
340
+
341
+ // Ensure range values remain in order
342
+ if (isRange) {
343
+ if (index === 0 && newValue > sliderValues[1]) {
344
+ newValue = sliderValues[1]
345
+ } else if (index === 1 && newValue < sliderValues[0]) {
346
+ newValue = sliderValues[0]
347
+ }
348
+ }
349
+
350
+ if (newValue !== sliderValues[index]) {
351
+ sliderValues[index] = newValue
352
+ dispatchChange()
353
+ event.preventDefault()
354
+ }
355
+ }
356
+
357
+ /**
358
+ * Dispatches change event
359
+ */
360
+ function dispatchChange() {
361
+ const eventValue = isRange ? [...sliderValues] : sliderValues[0]
362
+ onchange?.(new CustomEvent("change", { detail: { value: eventValue } }))
363
+ oninput?.(new CustomEvent("input", { detail: { value: eventValue } }))
364
+ }
365
+
366
+ // Clean up event listeners on destroy
367
+ onDestroy(() => {
368
+ document.removeEventListener("mousemove", handlePointerMove)
369
+ document.removeEventListener("mouseup", handlePointerUp)
370
+ document.removeEventListener("touchmove", handlePointerMove)
371
+ document.removeEventListener("touchend", handlePointerUp)
372
+ })
373
+ </script>
374
+
375
+ <div
376
+ {id}
377
+ class="
378
+ slider
379
+ slider-{orientation}
380
+ {disabled ? 'slider-disabled' : ''}
381
+ {className}
382
+ "
383
+ aria-disabled={disabled}
384
+ >
385
+ {#if name}
386
+ <input
387
+ type="hidden"
388
+ {name}
389
+ value={isRange ? sliderValues.join(',') : sliderValues[0]}
390
+ />
391
+ {/if}
392
+
393
+ <div
394
+ class="slider-container"
395
+ onclick={handleTrackClick}
396
+ >
397
+ <div
398
+ class="slider-track"
399
+ bind:this={trackElement}
400
+ >
401
+ <div
402
+ class="slider-track-background"
403
+ ></div>
404
+
405
+ <div
406
+ class="slider-track-fill {variantClasses}"
407
+ style="
408
+ {orientation === 'horizontal'
409
+ ? `left: ${getPercentage(isRange ? sliderValues[0] : min)}%; right: ${100 - getPercentage(isRange ? sliderValues[1] : sliderValues[0])}%`
410
+ : `bottom: ${getPercentage(isRange ? sliderValues[0] : min)}%; top: ${100 - getPercentage(isRange ? sliderValues[1] : sliderValues[0])}%`}
411
+ "
412
+ ></div>
413
+
414
+ {#if showTicks}
415
+ <div class="slider-ticks">
416
+ {#each ticks as tick}
417
+ <div
418
+ class="slider-tick"
419
+ style="
420
+ {orientation === 'horizontal'
421
+ ? `left: ${getPercentage(tick)}%`
422
+ : `bottom: ${getPercentage(tick)}%`}
423
+ "
424
+ ></div>
425
+ {/each}
426
+ </div>
427
+ {/if}
428
+
429
+ {#each sliderValues as value, i}
430
+ <div
431
+ class="
432
+ slider-thumb
433
+ {isDragging && dragIndex === i ? 'slider-thumb-active' : ''}
434
+ {variantClasses}
435
+ "
436
+ style="
437
+ {orientation === 'horizontal'
438
+ ? `left: ${getPercentage(value)}%`
439
+ : `bottom: ${getPercentage(value)}%`}
440
+ "
441
+ role="slider"
442
+ aria-valuemin={min}
443
+ aria-valuemax={max}
444
+ aria-valuenow={value}
445
+ aria-orientation={orientation}
446
+ aria-label={ariaLabel || `Slider ${isRange ? i + 1 : ''}`}
447
+ tabindex={disabled ? undefined : 0}
448
+ onmousedown={(e) => handlePointerDown(e, i)}
449
+ ontouchstart={(e) => handlePointerDown(e, i)}
450
+ onkeydown={(e) => handleKeydown(e, i)}
451
+ onmouseenter={() => handleThumbHover(i)}
452
+ onmouseleave={handleThumbLeave}
453
+ bind:this={thumbElements[i]}
454
+ >
455
+ {#if showTooltip && (isDragging && dragIndex === i || hoverIndex === i)}
456
+ <div class="slider-tooltip">
457
+ {formatValue(value)}
458
+ </div>
459
+ {/if}
460
+ </div>
461
+ {/each}
462
+ </div>
463
+
464
+ {#if showValue}
465
+ <div class="slider-values">
466
+ {#if isRange}
467
+ <div class="slider-value">{formatValue(sliderValues[0])}</div>
468
+ <div class="slider-value">{formatValue(sliderValues[1])}</div>
469
+ {:else}
470
+ <div class="slider-value">{formatValue(sliderValues[0])}</div>
471
+ {/if}
472
+ </div>
473
+ {/if}
474
+ </div>
475
+ </div>
476
+
477
+ <style>
478
+ @reference "../../twintrinsic.css";
479
+
480
+ .slider {
481
+ @apply w-full;
482
+ }
483
+
484
+ .slider-horizontal {
485
+ @apply h-12;
486
+ }
487
+
488
+ .slider-vertical {
489
+ @apply h-48 w-12;
490
+ }
491
+
492
+ .slider-disabled {
493
+ @apply opacity-50 cursor-not-allowed;
494
+ @apply pointer-events-none;
495
+ }
496
+
497
+ .slider-container {
498
+ @apply relative;
499
+ @apply h-full;
500
+ }
501
+
502
+ .slider-track {
503
+ @apply absolute;
504
+ @apply cursor-pointer;
505
+ }
506
+
507
+ .slider-horizontal .slider-track {
508
+ @apply left-0 right-0 top-1/2 -translate-y-1/2;
509
+ @apply h-1.5;
510
+ }
511
+
512
+ .slider-vertical .slider-track {
513
+ @apply bottom-0 top-0 left-1/2 -translate-x-1/2;
514
+ @apply w-1.5;
515
+ }
516
+
517
+ .slider-track-background {
518
+ @apply absolute inset-0;
519
+ @apply bg-muted/20 dark:bg-muted/20;
520
+ @apply rounded-full;
521
+ }
522
+
523
+ .slider-track-fill {
524
+ @apply absolute;
525
+ @apply rounded-full;
526
+ }
527
+
528
+ .slider-horizontal .slider-track-fill {
529
+ @apply h-full;
530
+ }
531
+
532
+ .slider-vertical .slider-track-fill {
533
+ @apply w-full;
534
+ }
535
+
536
+ .slider-ticks {
537
+ @apply absolute;
538
+ @apply pointer-events-none;
539
+ }
540
+
541
+ .slider-horizontal .slider-ticks {
542
+ @apply left-0 right-0 top-1/2;
543
+ @apply h-0;
544
+ }
545
+
546
+ .slider-vertical .slider-ticks {
547
+ @apply bottom-0 top-0 left-1/2;
548
+ @apply w-0;
549
+ }
550
+
551
+ .slider-tick {
552
+ @apply absolute;
553
+ @apply w-1 h-3;
554
+ @apply bg-muted/40 dark:bg-muted/40;
555
+ @apply rounded-sm;
556
+ }
557
+
558
+ .slider-horizontal .slider-tick {
559
+ @apply -translate-x-1/2 -translate-y-1/2;
560
+ }
561
+
562
+ .slider-vertical .slider-tick {
563
+ @apply -translate-x-1/2 translate-y-1/2;
564
+ @apply h-1 w-3;
565
+ }
566
+
567
+ .slider-thumb {
568
+ @apply absolute;
569
+ @apply w-5 h-5 rounded-full;
570
+ @apply shadow-md;
571
+ @apply cursor-grab;
572
+ @apply focus:outline-none focus:ring-2 focus:ring-primary-500 dark:focus:ring-primary-400 focus:ring-offset-2;
573
+ @apply transition-transform duration-150;
574
+ @apply z-10;
575
+ }
576
+
577
+ .slider-horizontal .slider-thumb {
578
+ @apply -translate-x-1/2 -translate-y-1/2;
579
+ }
580
+
581
+ .slider-vertical .slider-thumb {
582
+ @apply -translate-x-1/2 translate-y-1/2;
583
+ }
584
+
585
+ .slider-thumb-active {
586
+ @apply cursor-grabbing;
587
+ @apply scale-110;
588
+ }
589
+
590
+ .slider-tooltip {
591
+ @apply absolute;
592
+ @apply px-2 py-1;
593
+ @apply bg-background dark:bg-background;
594
+ @apply border border-border dark:border-border;
595
+ @apply rounded;
596
+ @apply text-xs font-medium;
597
+ @apply shadow-md;
598
+ @apply whitespace-nowrap;
599
+ @apply z-20;
600
+ }
601
+
602
+ .slider-horizontal .slider-tooltip {
603
+ @apply bottom-full mb-1.5;
604
+ @apply left-1/2 -translate-x-1/2;
605
+ }
606
+
607
+ .slider-vertical .slider-tooltip {
608
+ @apply left-full ml-1.5;
609
+ @apply top-1/2 -translate-y-1/2;
610
+ }
611
+
612
+ .slider-values {
613
+ @apply flex justify-between;
614
+ @apply mt-2;
615
+ @apply text-sm text-muted dark:text-muted;
616
+ }
617
+
618
+ .slider-vertical .slider-values {
619
+ @apply flex-col h-full justify-between;
620
+ @apply ml-6 mt-0;
621
+ }
622
+ </style>
@@ -0,0 +1,73 @@
1
+ export default Slider;
2
+ type Slider = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ /**
7
+ * Slider - A component for selecting values from a range.
8
+ * Provides consistent styling, accessibility features, and interactive options.
9
+ *
10
+ * Usage:
11
+ * ```svelte
12
+ * <Slider value={50} min={0} max={100} />
13
+ *
14
+ * <Slider
15
+ * value={[20, 80]}
16
+ * min={0}
17
+ * max={100}
18
+ * step={5}
19
+ * showTicks
20
+ * showValue
21
+ * onchange={(e) => console.log(e.detail.value)}
22
+ * />
23
+ *
24
+ * <Slider
25
+ * value={25}
26
+ * min={0}
27
+ * max={100}
28
+ * disabled={false}
29
+ * variant="primary"
30
+ * orientation="horizontal"
31
+ * />
32
+ * ```
33
+ */
34
+ declare const Slider: import("svelte").Component<{
35
+ class?: string;
36
+ id?: any;
37
+ value?: number;
38
+ min?: number;
39
+ max?: number;
40
+ step?: number;
41
+ variant?: string;
42
+ orientation?: string;
43
+ disabled?: boolean;
44
+ showTicks?: boolean;
45
+ tickValues?: any[];
46
+ showValue?: boolean;
47
+ valueFormat?: string;
48
+ showTooltip?: boolean;
49
+ name: any;
50
+ ariaLabel: any;
51
+ onchange: any;
52
+ oninput: any;
53
+ }, {}, "">;
54
+ type $$ComponentProps = {
55
+ class?: string;
56
+ id?: any;
57
+ value?: number;
58
+ min?: number;
59
+ max?: number;
60
+ step?: number;
61
+ variant?: string;
62
+ orientation?: string;
63
+ disabled?: boolean;
64
+ showTicks?: boolean;
65
+ tickValues?: any[];
66
+ showValue?: boolean;
67
+ valueFormat?: string;
68
+ showTooltip?: boolean;
69
+ name: any;
70
+ ariaLabel: any;
71
+ onchange: any;
72
+ oninput: any;
73
+ };