@flightlesslabs/dodo-ui 0.11.1 → 0.12.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 (44) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +2 -0
  3. package/dist/stories/components/Form/Button/Button.svelte +18 -18
  4. package/dist/stories/components/Form/Button/utils/scss/mixins.scss +3 -3
  5. package/dist/stories/components/Form/NumericInput/Roundness/Roundness.stories.svelte +20 -0
  6. package/dist/stories/components/Form/NumericInput/Roundness/Roundness.stories.svelte.d.ts +26 -0
  7. package/dist/stories/components/Form/NumericInput/Size/Size.stories.svelte +16 -0
  8. package/dist/stories/components/Form/NumericInput/Size/Size.stories.svelte.d.ts +26 -0
  9. package/dist/stories/components/Form/NumericInput/WithIcon/WithIcon.stories.svelte +31 -0
  10. package/dist/stories/components/Form/NumericInput/WithIcon/WithIcon.stories.svelte.d.ts +26 -0
  11. package/dist/stories/components/Form/RangeSlider/Color/Color.stories.svelte +19 -0
  12. package/dist/stories/components/Form/RangeSlider/Color/Color.stories.svelte.d.ts +26 -0
  13. package/dist/stories/components/Form/RangeSlider/Events/Events.stories.svelte +59 -0
  14. package/dist/stories/components/Form/RangeSlider/Events/Events.stories.svelte.d.ts +18 -0
  15. package/dist/stories/components/Form/RangeSlider/RangeSlider.stories.svelte +64 -0
  16. package/dist/stories/components/Form/RangeSlider/RangeSlider.stories.svelte.d.ts +21 -0
  17. package/dist/stories/components/Form/RangeSlider/RangeSlider.svelte +525 -0
  18. package/dist/stories/components/Form/RangeSlider/RangeSlider.svelte.d.ts +48 -0
  19. package/dist/stories/components/Form/RangeSlider/Roundness/Roundness.stories.svelte +30 -0
  20. package/dist/stories/components/Form/RangeSlider/Roundness/Roundness.stories.svelte.d.ts +26 -0
  21. package/dist/stories/components/Form/RangeSlider/Size/Size.stories.svelte +16 -0
  22. package/dist/stories/components/Form/RangeSlider/Size/Size.stories.svelte.d.ts +26 -0
  23. package/dist/stories/components/Form/RangeSlider/WithIcon/WithIcon.stories.svelte +30 -0
  24. package/dist/stories/components/Form/RangeSlider/WithIcon/WithIcon.stories.svelte.d.ts +18 -0
  25. package/dist/stories/components/Form/RangeSlider/utils/scss/mixins.scss +91 -0
  26. package/dist/stories/developer tools/directives/drag/drag.d.ts +3 -0
  27. package/dist/stories/developer tools/directives/drag/drag.js +40 -0
  28. package/dist/styles/_components.css +5 -0
  29. package/package.json +11 -11
  30. package/src/lib/index.ts +4 -0
  31. package/src/lib/stories/components/Form/Button/utils/scss/mixins.scss +3 -3
  32. package/src/lib/stories/components/Form/NumericInput/Roundness/Roundness.stories.svelte +20 -0
  33. package/src/lib/stories/components/Form/NumericInput/Size/Size.stories.svelte +16 -0
  34. package/src/lib/stories/components/Form/NumericInput/WithIcon/WithIcon.stories.svelte +31 -0
  35. package/src/lib/stories/components/Form/RangeSlider/Color/Color.stories.svelte +19 -0
  36. package/src/lib/stories/components/Form/RangeSlider/Events/Events.stories.svelte +63 -0
  37. package/src/lib/stories/components/Form/RangeSlider/RangeSlider.stories.svelte +69 -0
  38. package/src/lib/stories/components/Form/RangeSlider/RangeSlider.svelte +476 -0
  39. package/src/lib/stories/components/Form/RangeSlider/Roundness/Roundness.stories.svelte +30 -0
  40. package/src/lib/stories/components/Form/RangeSlider/Size/Size.stories.svelte +16 -0
  41. package/src/lib/stories/components/Form/RangeSlider/WithIcon/WithIcon.stories.svelte +33 -0
  42. package/src/lib/stories/components/Form/RangeSlider/utils/scss/mixins.scss +91 -0
  43. package/src/lib/stories/developer tools/directives/drag/drag.ts +47 -0
  44. package/src/lib/styles/_components.css +5 -0
@@ -0,0 +1,476 @@
1
+ <script lang="ts" module>
2
+ import type { ComponentSize } from '$lib/types/size.js';
3
+ import type { ComponentRoundness } from '$lib/types/roundness.js';
4
+ import type { ChangeEventHandler, FocusEventHandler, FormEventHandler } from 'svelte/elements';
5
+ import type { ComponentColor } from '$lib/types/colors.js';
6
+ import type { Snippet } from 'svelte';
7
+
8
+ export interface RangeSliderProps {
9
+ /** How large should the button be? */
10
+ size?: ComponentSize;
11
+ /** What color to use? */
12
+ color?: ComponentColor;
13
+ /** RangeSlider ref */
14
+ ref?: HTMLInputElement;
15
+ /** How round should the border radius be? */
16
+ roundness?: ComponentRoundness;
17
+ /** How round should the thumb border radius be? */
18
+ thumbRoundness?: ComponentRoundness;
19
+ /** RangeSlider value */
20
+ value: number;
21
+ /** disabled state */
22
+ disabled?: boolean;
23
+ /** Id */
24
+ id?: string;
25
+ /** name */
26
+ name?: string;
27
+ /** Icon before button content */
28
+ before?: Snippet;
29
+ /** Icon after button content */
30
+ after?: Snippet;
31
+ /** Custom css class*/
32
+ class?: string;
33
+ /** oninput event handler */
34
+ oninput?: FormEventHandler<HTMLInputElement>;
35
+ /** onchange event handler */
36
+ onchange?: ChangeEventHandler<HTMLInputElement>;
37
+ /** onblur event handler */
38
+ onblur?: FocusEventHandler<HTMLInputElement>;
39
+ /** onfocus event handler */
40
+ onfocus?: FocusEventHandler<HTMLInputElement>;
41
+ /** Min Value */
42
+ min?: number;
43
+ /** Max Value */
44
+ max?: number;
45
+ /** Value Increment step */
46
+ step?: number;
47
+ }
48
+ </script>
49
+
50
+ <script lang="ts">
51
+ let {
52
+ color = 'primary',
53
+ size = 'normal',
54
+ roundness = 1,
55
+ thumbRoundness = 'full',
56
+ class: className = '',
57
+ ref = $bindable<HTMLInputElement>(),
58
+ value = $bindable<number>(),
59
+ disabled = false,
60
+ id,
61
+ min = 0,
62
+ max = 100,
63
+ step = 0,
64
+ name,
65
+ oninput,
66
+ onchange,
67
+ onblur,
68
+ onfocus,
69
+ before,
70
+ after,
71
+ }: RangeSliderProps = $props();
72
+
73
+ const percentageValue = $derived(((value - min) / (max - min)) * 100);
74
+ </script>
75
+
76
+ <div
77
+ class:disabled
78
+ class={[
79
+ 'dodo-ui-RangeSlider',
80
+ `size--${size}`,
81
+ `roundness--${roundness}`,
82
+ `thumbRoundness--${thumbRoundness}`,
83
+ `color--${color}`,
84
+ className,
85
+ ].join(' ')}
86
+ style={`--dodo-ui-RangeSlider-value-percent: ${percentageValue};`}
87
+ >
88
+ {#if before}
89
+ <span class="content--before">
90
+ {@render before()}
91
+ </span>
92
+ {/if}
93
+
94
+ <input
95
+ type="range"
96
+ class="NativeRangeSlider"
97
+ {min}
98
+ {max}
99
+ {step}
100
+ {oninput}
101
+ {onchange}
102
+ {onblur}
103
+ {onfocus}
104
+ {id}
105
+ {name}
106
+ {disabled}
107
+ bind:this={ref}
108
+ bind:value
109
+ />
110
+
111
+ {#if after}
112
+ <span class="content--after">
113
+ {@render after()}
114
+ </span>
115
+ {/if}
116
+ </div>
117
+
118
+ <style lang="scss">
119
+ @use 'utils/scss/mixins.scss' as *;
120
+
121
+ :global(:root) {
122
+ --dodo-ui-RangeSlider-track-bg: var(--dodo-color-neutral-200);
123
+ --dodo-ui-RangeSlider-track-filled-disabled-bg: var(--dodo-color-neutral-300);
124
+ --dodo-ui-RangeSlider-thumb-disabled-bg: var(--dodo-color-neutral-300);
125
+
126
+ @include generate-dodo-ui-range-slider-colors(neutral);
127
+ @include generate-dodo-ui-range-slider-colors(primary);
128
+ @include generate-dodo-ui-range-slider-colors(secondary);
129
+ @include generate-dodo-ui-range-slider-colors(safe);
130
+ @include generate-dodo-ui-range-slider-colors(warning);
131
+ @include generate-dodo-ui-range-slider-colors(danger);
132
+ }
133
+
134
+ :global(.dodo-theme--dark) {
135
+ --dodo-ui-RangeSlider-track-bg: var(--dodo-color-neutral-400);
136
+ --dodo-ui-RangeSlider-track-filled-disabled-bg: var(--dodo-color-neutral-500);
137
+ --dodo-ui-RangeSlider-thumb-disabled-bg: var(--dodo-color-neutral-500);
138
+
139
+ @include generate-dodo-ui-range-slider-colors-dark(neutral);
140
+ @include generate-dodo-ui-range-slider-colors-dark(primary);
141
+ @include generate-dodo-ui-range-slider-colors-dark(secondary);
142
+ @include generate-dodo-ui-range-slider-colors-dark(safe);
143
+ @include generate-dodo-ui-range-slider-colors-dark(warning);
144
+ @include generate-dodo-ui-range-slider-colors-dark(danger);
145
+ }
146
+
147
+ .dodo-ui-RangeSlider {
148
+ display: flex;
149
+
150
+ .NativeRangeSlider {
151
+ height: 100%;
152
+ -webkit-appearance: none;
153
+ appearance: none;
154
+ background: transparent;
155
+ cursor: pointer;
156
+ width: 100%;
157
+ margin: 0;
158
+ padding: 0;
159
+ overflow: hidden;
160
+ display: flex;
161
+ align-items: center;
162
+ flex: 1;
163
+
164
+ &:focus {
165
+ outline: none;
166
+ }
167
+
168
+ &::-webkit-slider-thumb {
169
+ -webkit-appearance: none; /* Override default look */
170
+ appearance: none;
171
+ border: 0;
172
+ transition: all 150ms;
173
+ }
174
+
175
+ &::-moz-range-thumb {
176
+ border: 0;
177
+ transition: all 150ms;
178
+ }
179
+ }
180
+
181
+ .content {
182
+ &--before {
183
+ display: flex;
184
+ align-items: center;
185
+ justify-content: center;
186
+ }
187
+
188
+ &--after {
189
+ display: flex;
190
+ align-items: center;
191
+ justify-content: center;
192
+ }
193
+ }
194
+
195
+ &.size {
196
+ &--normal {
197
+ height: var(--dodo-ui-element-height-normal);
198
+ .NativeRangeSlider {
199
+ &::-webkit-slider-runnable-track {
200
+ height: var(--dodo-ui-track-element-height-normal);
201
+ }
202
+
203
+ &::-moz-range-track {
204
+ height: var(--dodo-ui-track-element-height-normal);
205
+ }
206
+
207
+ &::-moz-range-progress {
208
+ height: var(--dodo-ui-track-element-height-normal);
209
+ }
210
+
211
+ // Thumb
212
+ &::-webkit-slider-thumb {
213
+ margin-top: -0.5em;
214
+ height: calc(var(--dodo-ui-element-height-normal) / 2);
215
+ width: calc(var(--dodo-ui-element-height-normal) / 2);
216
+ }
217
+
218
+ &::-moz-range-thumb {
219
+ height: calc(var(--dodo-ui-element-height-normal) / 2);
220
+ width: calc(var(--dodo-ui-element-height-normal) / 2);
221
+ }
222
+ }
223
+
224
+ .content {
225
+ &--before {
226
+ margin-right: 12px;
227
+ }
228
+
229
+ &--after {
230
+ margin-left: 12px;
231
+ }
232
+ }
233
+ }
234
+
235
+ &--small {
236
+ height: var(--dodo-ui-element-height-small);
237
+
238
+ .NativeRangeSlider {
239
+ &::-webkit-slider-runnable-track {
240
+ height: var(--dodo-ui-track-element-height-small);
241
+ }
242
+
243
+ &::-moz-range-track {
244
+ height: var(--dodo-ui-track-element-height-small);
245
+ }
246
+
247
+ &::-moz-range-progress {
248
+ height: var(--dodo-ui-track-element-height-small);
249
+ }
250
+
251
+ // Thumb
252
+ &::-webkit-slider-thumb {
253
+ margin-top: -0.45em;
254
+ height: calc(var(--dodo-ui-element-height-small) / 2);
255
+ width: calc(var(--dodo-ui-element-height-small) / 2);
256
+ }
257
+
258
+ &::-moz-range-thumb {
259
+ height: calc(var(--dodo-ui-element-height-small) / 2);
260
+ width: calc(var(--dodo-ui-element-height-small) / 2);
261
+ }
262
+ }
263
+
264
+ .content {
265
+ &--before {
266
+ margin-right: 8px;
267
+ }
268
+
269
+ &--after {
270
+ margin-left: 8px;
271
+ }
272
+ }
273
+ }
274
+
275
+ &--large {
276
+ height: var(--dodo-ui-element-height-large);
277
+
278
+ .NativeRangeSlider {
279
+ &::-webkit-slider-runnable-track {
280
+ height: var(--dodo-ui-track-element-height-large);
281
+ }
282
+
283
+ &::-moz-range-track {
284
+ height: var(--dodo-ui-track-element-height-large);
285
+ }
286
+
287
+ &::-moz-range-progress {
288
+ height: var(--dodo-ui-track-element-height-large);
289
+ }
290
+
291
+ // Thumb
292
+ &::-webkit-slider-thumb {
293
+ margin-top: -0.6em;
294
+ height: calc(var(--dodo-ui-element-height-large) / 2);
295
+ width: calc(var(--dodo-ui-element-height-large) / 2);
296
+ }
297
+
298
+ &::-moz-range-thumb {
299
+ height: calc(var(--dodo-ui-element-height-large) / 2);
300
+ width: calc(var(--dodo-ui-element-height-large) / 2);
301
+ }
302
+ }
303
+
304
+ .content {
305
+ &--before {
306
+ margin-right: 14px;
307
+ }
308
+
309
+ &--after {
310
+ margin-left: 14px;
311
+ }
312
+ }
313
+ }
314
+ }
315
+
316
+ &.color {
317
+ @include generate-dodo-ui-range-slider-color(neutral);
318
+ @include generate-dodo-ui-range-slider-color(primary);
319
+ @include generate-dodo-ui-range-slider-color(secondary);
320
+ @include generate-dodo-ui-range-slider-color(safe);
321
+ @include generate-dodo-ui-range-slider-color(warning);
322
+ @include generate-dodo-ui-range-slider-color(danger);
323
+ }
324
+
325
+ &.roundness {
326
+ &--1 {
327
+ .NativeRangeSlider {
328
+ &::-webkit-slider-runnable-track {
329
+ border-radius: var(--dodo-ui-element-roundness-1);
330
+ }
331
+
332
+ &::-moz-range-track {
333
+ border-radius: var(--dodo-ui-element-roundness-1);
334
+ }
335
+
336
+ &::-moz-range-progress {
337
+ border-radius: var(--dodo-ui-element-roundness-1);
338
+ }
339
+ }
340
+ }
341
+
342
+ &--2 {
343
+ .NativeRangeSlider {
344
+ &::-webkit-slider-runnable-track {
345
+ border-radius: var(--dodo-ui-element-roundness-2);
346
+ }
347
+
348
+ &::-moz-range-track {
349
+ border-radius: var(--dodo-ui-element-roundness-2);
350
+ }
351
+
352
+ &::-moz-range-progress {
353
+ border-radius: var(--dodo-ui-element-roundness-2);
354
+ }
355
+ }
356
+ }
357
+
358
+ &--3 {
359
+ .NativeRangeSlider {
360
+ &::-webkit-slider-runnable-track {
361
+ border-radius: var(--dodo-ui-element-roundness-3);
362
+ }
363
+
364
+ &::-moz-range-track {
365
+ border-radius: var(--dodo-ui-element-roundness-3);
366
+ }
367
+
368
+ &::-moz-range-progress {
369
+ border-radius: var(--dodo-ui-element-roundness-3);
370
+ }
371
+ }
372
+ }
373
+ }
374
+
375
+ &.thumbRoundness {
376
+ &--1 {
377
+ .NativeRangeSlider {
378
+ // Thumb
379
+ &::-webkit-slider-thumb {
380
+ border-radius: var(--dodo-ui-element-roundness-1);
381
+ }
382
+
383
+ &::-moz-range-thumb {
384
+ border-radius: var(--dodo-ui-element-roundness-1);
385
+ }
386
+ }
387
+ }
388
+
389
+ &--2 {
390
+ .NativeRangeSlider {
391
+ // Thumb
392
+ &::-webkit-slider-thumb {
393
+ border-radius: var(--dodo-ui-element-roundness-2);
394
+ }
395
+
396
+ &::-moz-range-thumb {
397
+ border-radius: var(--dodo-ui-element-roundness-2);
398
+ }
399
+ }
400
+ }
401
+
402
+ &--3 {
403
+ .NativeRangeSlider {
404
+ // Thumb
405
+ &::-webkit-slider-thumb {
406
+ border-radius: var(--dodo-ui-element-roundness-3);
407
+ }
408
+
409
+ &::-moz-range-thumb {
410
+ border-radius: var(--dodo-ui-element-roundness-3);
411
+ }
412
+ }
413
+ }
414
+
415
+ &--full {
416
+ .NativeRangeSlider {
417
+ // Thumb
418
+ &::-webkit-slider-thumb {
419
+ border-radius: 50%;
420
+ }
421
+
422
+ // Thumb
423
+ &::-moz-range-thumb {
424
+ border-radius: 50%;
425
+ }
426
+ }
427
+ }
428
+ }
429
+
430
+ .NativeRangeSlider {
431
+ &[disabled] {
432
+ cursor: initial;
433
+
434
+ &::-webkit-slider-runnable-track {
435
+ background: linear-gradient(
436
+ to right,
437
+ var(--dodo-ui-RangeSlider-track-filled-disabled-bg) 0%,
438
+ var(--dodo-ui-RangeSlider-track-filled-disabled-bg)
439
+ calc(var(--dodo-ui-RangeSlider-value-percent, 50%) * 1%),
440
+ var(--dodo-ui-RangeSlider-track-bg)
441
+ calc(var(--dodo-ui-RangeSlider-value-percent, 50%) * 1%),
442
+ var(--dodo-ui-RangeSlider-track-bg) 100%
443
+ );
444
+ }
445
+
446
+ &::-moz-range-progress {
447
+ background: var(--dodo-ui-RangeSlider-track-filled-disabled-bg);
448
+ }
449
+
450
+ &::-webkit-slider-thumb {
451
+ background: var(--dodo-ui-RangeSlider-thumb-disabled-bg);
452
+
453
+ &:hover {
454
+ background: var(--dodo-ui-RangeSlider-thumb-disabled-bg);
455
+ }
456
+
457
+ &:focus-visible {
458
+ background: var(--dodo-ui-RangeSlider-thumb-disabled-bg);
459
+ }
460
+
461
+ &:active {
462
+ background: var(--dodo-ui-RangeSlider-thumb-disabled-bg);
463
+ }
464
+ }
465
+
466
+ &::-moz-range-thumb {
467
+ background: var(--dodo-ui-RangeSlider-thumb-disabled-bg);
468
+
469
+ &:active {
470
+ background: var(--dodo-ui-RangeSlider-thumb-disabled-bg);
471
+ }
472
+ }
473
+ }
474
+ }
475
+ }
476
+ </style>
@@ -0,0 +1,30 @@
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import RangeSlider from '../RangeSlider.svelte';
4
+ import { storyRangeSliderArgTypes } from '../RangeSlider.stories.svelte';
5
+
6
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
+ const { Story } = defineMeta({
8
+ component: RangeSlider,
9
+ tags: ['autodocs'],
10
+ argTypes: storyRangeSliderArgTypes,
11
+ });
12
+ </script>
13
+
14
+ <Story name="Roundness 1" />
15
+
16
+ <Story name="Roundness 2" args={{ roundness: 2 }} />
17
+
18
+ <Story name="Roundness 3" args={{ roundness: 3 }} />
19
+
20
+ <Story name="Roundness 0" args={{ roundness: 0 }} />
21
+
22
+ <Story name="Thumb Roundness Full" />
23
+
24
+ <Story name="Thumb Roundness 0" args={{ thumbRoundness: 0 }} />
25
+
26
+ <Story name="Thumb Roundness 1" args={{ thumbRoundness: 1 }} />
27
+
28
+ <Story name="Thumb Roundness 2" args={{ thumbRoundness: 2 }} />
29
+
30
+ <Story name="Thumb Roundness 3" args={{ thumbRoundness: 3 }} />
@@ -0,0 +1,16 @@
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import RangeSlider from '../RangeSlider.svelte';
4
+ import { storyRangeSliderArgTypes } from '../RangeSlider.stories.svelte';
5
+
6
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
+ const { Story } = defineMeta({
8
+ component: RangeSlider,
9
+ tags: ['autodocs'],
10
+ argTypes: storyRangeSliderArgTypes,
11
+ });
12
+ </script>
13
+
14
+ <Story name="Normal" />
15
+ <Story name="Small" args={{ size: 'small' }} />
16
+ <Story name="Large" args={{ size: 'large' }} />
@@ -0,0 +1,33 @@
1
+ <script module lang="ts">
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import RangeSlider from '../RangeSlider.svelte';
4
+ import { storyRangeSliderArgTypes } from '../RangeSlider.stories.svelte';
5
+ import Icon from '@iconify/svelte';
6
+
7
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
8
+ const { Story } = defineMeta({
9
+ component: RangeSlider,
10
+ tags: ['autodocs'],
11
+ argTypes: storyRangeSliderArgTypes,
12
+ });
13
+
14
+ let value = $state<number>(30);
15
+ </script>
16
+
17
+ <!-- RangeSlider icon in front. -->
18
+ <Story name="Icon Before" asChild>
19
+ <RangeSlider {value}>
20
+ {#snippet before()}
21
+ <Icon icon="material-symbols:content-copy" />
22
+ {/snippet}
23
+ </RangeSlider>
24
+ </Story>
25
+
26
+ <!-- RangeSlider icon in front. -->
27
+ <Story name="Icon After" asChild>
28
+ <RangeSlider {value}>
29
+ {#snippet after()}
30
+ <Icon icon="material-symbols:download-2" />
31
+ {/snippet}
32
+ </RangeSlider>
33
+ </Story>
@@ -0,0 +1,91 @@
1
+ /// Mixin: generate-dodo-ui-range-slider-colors
2
+ /// Generates CSS custom properties for Dodo UI range-slider styles (text & solid)
3
+ /// across different interaction states (default, hover, active).
4
+ /// @param {String} $color-name - The theme color name (e.g., "primary", "safe", etc.)
5
+ @mixin generate-dodo-ui-range-slider-colors($color-name) {
6
+ --dodo-ui-RangeSlider-thumb-#{$color-name}-bg: var(--dodo-color-#{$color-name}-500);
7
+ --dodo-ui-RangeSlider-thumb-#{$color-name}-hover-bg: var(--dodo-color-#{$color-name}-600);
8
+ --dodo-ui-RangeSlider-thumb-#{$color-name}-active-bg: var(--dodo-color-#{$color-name}-700);
9
+
10
+ --dodo-ui-RangeSlider-track-filled-#{$color-name}-bg: var(--dodo-color-#{$color-name}-500);
11
+ }
12
+
13
+ /// Mixin: generate-dodo-ui-range-slider-colors
14
+ /// Generates CSS custom properties for Dodo UI range-slider styles (text & solid)
15
+ /// across different interaction states (default, hover, active).
16
+ /// @param {String} $color-name - The theme color name (e.g., "primary", "safe", etc.)
17
+ @mixin generate-dodo-ui-range-slider-colors-dark($color-name) {
18
+ --dodo-ui-RangeSlider-thumb-#{$color-name}-bg: var(--dodo-color-#{$color-name}-500);
19
+ --dodo-ui-RangeSlider-thumb-#{$color-name}-hover-bg: var(--dodo-color-#{$color-name}-400);
20
+ --dodo-ui-RangeSlider-thumb-#{$color-name}-active-bg: var(--dodo-color-#{$color-name}-300);
21
+
22
+ --dodo-ui-RangeSlider-track-filled-#{$color-name}-bg: var(--dodo-color-#{$color-name}-500);
23
+ }
24
+
25
+ /// Mixin: generate-dodo-ui-range-slider-color
26
+ /// Auto-generates .color--[theme] > .variant--text & .variant--solid styles
27
+ /// @param {String} $theme - e.g., default, safe, danger, etc.
28
+ @mixin generate-dodo-ui-range-slider-color($theme) {
29
+ &--#{$theme} {
30
+ .NativeRangeSlider {
31
+ &::-webkit-slider-runnable-track {
32
+ background-color: var(--dodo-ui-RangeSlider-track-#{$theme}-bg);
33
+ }
34
+
35
+ &::-moz-range-track {
36
+ background-color: var(--dodo-ui-RangeSlider-track-#{$theme}-bg);
37
+ }
38
+
39
+ &:focus-visible {
40
+ &::-webkit-slider-thumb {
41
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-active-bg);
42
+ }
43
+
44
+ &::-moz-range-thumb {
45
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-active-bg);
46
+ }
47
+ }
48
+
49
+ &::-webkit-slider-runnable-track {
50
+ background: linear-gradient(
51
+ to right,
52
+ var(--dodo-ui-RangeSlider-track-filled-#{$theme}-bg) 0%,
53
+ var(--dodo-ui-RangeSlider-track-filled-#{$theme}-bg)
54
+ calc(var(--dodo-ui-RangeSlider-value-percent, 50%) * 1%),
55
+ var(--dodo-ui-RangeSlider-track-bg)
56
+ calc(var(--dodo-ui-RangeSlider-value-percent, 50%) * 1%),
57
+ var(--dodo-ui-RangeSlider-track-bg) 100%
58
+ );
59
+ }
60
+
61
+ &::-moz-range-progress {
62
+ background: var(--dodo-ui-RangeSlider-track-filled-#{$theme}-bg);
63
+ }
64
+
65
+ // Thumb
66
+ &::-webkit-slider-thumb {
67
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-bg);
68
+
69
+ &:hover {
70
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-hover-bg);
71
+ }
72
+
73
+ &:active {
74
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-active-bg);
75
+ }
76
+ }
77
+
78
+ &::-moz-range-thumb {
79
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-bg);
80
+
81
+ &:hover {
82
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-hover-bg);
83
+ }
84
+
85
+ &:active {
86
+ background: var(--dodo-ui-RangeSlider-thumb-#{$theme}-active-bg);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,47 @@
1
+ export function drag(node: HTMLElement) {
2
+ let dragging = false;
3
+
4
+ function getX(e: MouseEvent | TouchEvent): number {
5
+ return 'touches' in e ? e.touches[0].clientX : e.clientX;
6
+ }
7
+
8
+ function handleStart(e: MouseEvent | TouchEvent) {
9
+ dragging = true;
10
+ const x = getX(e);
11
+ node.dispatchEvent(new CustomEvent('dragstart', { detail: { x } }));
12
+
13
+ window.addEventListener('mousemove', handleMove);
14
+ window.addEventListener('mouseup', handleEnd);
15
+ window.addEventListener('touchmove', handleMove);
16
+ window.addEventListener('touchend', handleEnd);
17
+ }
18
+
19
+ function handleMove(e: MouseEvent | TouchEvent) {
20
+ if (!dragging) return;
21
+ const x = getX(e);
22
+
23
+ node.dispatchEvent(new CustomEvent('dragging', { detail: { x } }));
24
+ }
25
+
26
+ function handleEnd(e: MouseEvent | TouchEvent) {
27
+ if (!dragging) return;
28
+ dragging = false;
29
+ const x = getX(e);
30
+ node.dispatchEvent(new CustomEvent('dragend', { detail: { x } }));
31
+
32
+ window.removeEventListener('mousemove', handleMove);
33
+ window.removeEventListener('mouseup', handleEnd);
34
+ window.removeEventListener('touchmove', handleMove);
35
+ window.removeEventListener('touchend', handleEnd);
36
+ }
37
+
38
+ node.addEventListener('mousedown', handleStart);
39
+ node.addEventListener('touchstart', handleStart, { passive: true });
40
+
41
+ return {
42
+ destroy() {
43
+ node.removeEventListener('mousedown', handleStart);
44
+ node.removeEventListener('touchstart', handleStart);
45
+ },
46
+ };
47
+ }
@@ -4,6 +4,11 @@
4
4
  --dodo-ui-element-height-normal: 40px;
5
5
  --dodo-ui-element-height-large: 50px;
6
6
 
7
+ /* Size Thin elements */
8
+ --dodo-ui-track-element-height-small: 6px;
9
+ --dodo-ui-track-element-height-normal: 8px;
10
+ --dodo-ui-track-element-height-large: 10px;
11
+
7
12
  /* Roundness */
8
13
  --dodo-ui-element-roundness-1: 0.4375em;
9
14
  --dodo-ui-element-roundness-2: 0.8125em;