@tremolo-ui/svelte 0.7.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 (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/dist/actions/drag-value.d.ts +22 -0
  4. package/dist/actions/drag-value.d.ts.map +1 -0
  5. package/dist/actions/drag-value.js +30 -0
  6. package/dist/actions/drag.d.ts +14 -0
  7. package/dist/actions/drag.d.ts.map +1 -0
  8. package/dist/actions/drag.js +22 -0
  9. package/dist/actions/drop-zone.d.ts +12 -0
  10. package/dist/actions/drop-zone.d.ts.map +1 -0
  11. package/dist/actions/drop-zone.js +20 -0
  12. package/dist/actions/long-press.d.ts +11 -0
  13. package/dist/actions/long-press.d.ts.map +1 -0
  14. package/dist/actions/long-press.js +24 -0
  15. package/dist/actions/wheel.d.ts +15 -0
  16. package/dist/actions/wheel.d.ts.map +1 -0
  17. package/dist/actions/wheel.js +32 -0
  18. package/dist/components/AnimationCanvas/AnimationCanvas.svelte +69 -0
  19. package/dist/components/AnimationCanvas/AnimationCanvas.svelte.d.ts +7 -0
  20. package/dist/components/AnimationCanvas/AnimationCanvas.svelte.d.ts.map +1 -0
  21. package/dist/components/AnimationCanvas/types.d.ts +46 -0
  22. package/dist/components/AnimationCanvas/types.d.ts.map +1 -0
  23. package/dist/components/AnimationCanvas/types.js +1 -0
  24. package/dist/components/DropZone/Root.svelte +47 -0
  25. package/dist/components/DropZone/Root.svelte.d.ts +7 -0
  26. package/dist/components/DropZone/Root.svelte.d.ts.map +1 -0
  27. package/dist/components/DropZone/index.d.ts +2 -0
  28. package/dist/components/DropZone/index.d.ts.map +1 -0
  29. package/dist/components/DropZone/index.js +1 -0
  30. package/dist/components/DropZone/types.d.ts +26 -0
  31. package/dist/components/DropZone/types.d.ts.map +1 -0
  32. package/dist/components/DropZone/types.js +1 -0
  33. package/dist/components/FileInput/Root.svelte +68 -0
  34. package/dist/components/FileInput/Root.svelte.d.ts +7 -0
  35. package/dist/components/FileInput/Root.svelte.d.ts.map +1 -0
  36. package/dist/components/FileInput/Trigger.svelte +28 -0
  37. package/dist/components/FileInput/Trigger.svelte.d.ts +11 -0
  38. package/dist/components/FileInput/Trigger.svelte.d.ts.map +1 -0
  39. package/dist/components/FileInput/context.d.ts +10 -0
  40. package/dist/components/FileInput/context.d.ts.map +1 -0
  41. package/dist/components/FileInput/context.js +5 -0
  42. package/dist/components/FileInput/index.d.ts +3 -0
  43. package/dist/components/FileInput/index.d.ts.map +1 -0
  44. package/dist/components/FileInput/index.js +2 -0
  45. package/dist/components/FileInput/types.d.ts +28 -0
  46. package/dist/components/FileInput/types.d.ts.map +1 -0
  47. package/dist/components/FileInput/types.js +1 -0
  48. package/dist/components/Knob/ActiveLine.svelte +29 -0
  49. package/dist/components/Knob/ActiveLine.svelte.d.ts +6 -0
  50. package/dist/components/Knob/ActiveLine.svelte.d.ts.map +1 -0
  51. package/dist/components/Knob/InactiveLine.svelte +41 -0
  52. package/dist/components/Knob/InactiveLine.svelte.d.ts +6 -0
  53. package/dist/components/Knob/InactiveLine.svelte.d.ts.map +1 -0
  54. package/dist/components/Knob/Root.svelte +189 -0
  55. package/dist/components/Knob/Root.svelte.d.ts +10 -0
  56. package/dist/components/Knob/Root.svelte.d.ts.map +1 -0
  57. package/dist/components/Knob/SVGRoot.svelte +28 -0
  58. package/dist/components/Knob/SVGRoot.svelte.d.ts +13 -0
  59. package/dist/components/Knob/SVGRoot.svelte.d.ts.map +1 -0
  60. package/dist/components/Knob/Thumb.svelte +43 -0
  61. package/dist/components/Knob/Thumb.svelte.d.ts +7 -0
  62. package/dist/components/Knob/Thumb.svelte.d.ts.map +1 -0
  63. package/dist/components/Knob/context.d.ts +22 -0
  64. package/dist/components/Knob/context.d.ts.map +1 -0
  65. package/dist/components/Knob/context.js +5 -0
  66. package/dist/components/Knob/index.d.ts +6 -0
  67. package/dist/components/Knob/index.d.ts.map +1 -0
  68. package/dist/components/Knob/index.js +5 -0
  69. package/dist/components/Knob/types.d.ts +139 -0
  70. package/dist/components/Knob/types.d.ts.map +1 -0
  71. package/dist/components/Knob/types.js +1 -0
  72. package/dist/components/NumberInput/DecrementStepper.svelte +11 -0
  73. package/dist/components/NumberInput/DecrementStepper.svelte.d.ts +9 -0
  74. package/dist/components/NumberInput/DecrementStepper.svelte.d.ts.map +1 -0
  75. package/dist/components/NumberInput/IncrementStepper.svelte +11 -0
  76. package/dist/components/NumberInput/IncrementStepper.svelte.d.ts +9 -0
  77. package/dist/components/NumberInput/IncrementStepper.svelte.d.ts.map +1 -0
  78. package/dist/components/NumberInput/InputField.svelte +134 -0
  79. package/dist/components/NumberInput/InputField.svelte.d.ts +8 -0
  80. package/dist/components/NumberInput/InputField.svelte.d.ts.map +1 -0
  81. package/dist/components/NumberInput/Root.svelte +209 -0
  82. package/dist/components/NumberInput/Root.svelte.d.ts +10 -0
  83. package/dist/components/NumberInput/Root.svelte.d.ts.map +1 -0
  84. package/dist/components/NumberInput/Stepper.svelte +61 -0
  85. package/dist/components/NumberInput/Stepper.svelte.d.ts +10 -0
  86. package/dist/components/NumberInput/Stepper.svelte.d.ts.map +1 -0
  87. package/dist/components/NumberInput/StepperButton.svelte +63 -0
  88. package/dist/components/NumberInput/StepperButton.svelte.d.ts +10 -0
  89. package/dist/components/NumberInput/StepperButton.svelte.d.ts.map +1 -0
  90. package/dist/components/NumberInput/context.d.ts +48 -0
  91. package/dist/components/NumberInput/context.d.ts.map +1 -0
  92. package/dist/components/NumberInput/context.js +8 -0
  93. package/dist/components/NumberInput/index.d.ts +6 -0
  94. package/dist/components/NumberInput/index.d.ts.map +1 -0
  95. package/dist/components/NumberInput/index.js +5 -0
  96. package/dist/components/NumberInput/types.d.ts +104 -0
  97. package/dist/components/NumberInput/types.d.ts.map +1 -0
  98. package/dist/components/NumberInput/types.js +1 -0
  99. package/dist/components/Piano/Root.svelte +177 -0
  100. package/dist/components/Piano/Root.svelte.d.ts +10 -0
  101. package/dist/components/Piano/Root.svelte.d.ts.map +1 -0
  102. package/dist/components/Piano/index.d.ts +2 -0
  103. package/dist/components/Piano/index.d.ts.map +1 -0
  104. package/dist/components/Piano/index.js +1 -0
  105. package/dist/components/Piano/types.d.ts +90 -0
  106. package/dist/components/Piano/types.d.ts.map +1 -0
  107. package/dist/components/Piano/types.js +1 -0
  108. package/dist/components/PointsEditor/Background.svelte +14 -0
  109. package/dist/components/PointsEditor/Background.svelte.d.ts +9 -0
  110. package/dist/components/PointsEditor/Background.svelte.d.ts.map +1 -0
  111. package/dist/components/PointsEditor/Container.svelte +82 -0
  112. package/dist/components/PointsEditor/Container.svelte.d.ts +10 -0
  113. package/dist/components/PointsEditor/Container.svelte.d.ts.map +1 -0
  114. package/dist/components/PointsEditor/Point.svelte +213 -0
  115. package/dist/components/PointsEditor/Point.svelte.d.ts +7 -0
  116. package/dist/components/PointsEditor/Point.svelte.d.ts.map +1 -0
  117. package/dist/components/PointsEditor/Root.svelte +107 -0
  118. package/dist/components/PointsEditor/Root.svelte.d.ts +7 -0
  119. package/dist/components/PointsEditor/Root.svelte.d.ts.map +1 -0
  120. package/dist/components/PointsEditor/SelectionBox.svelte +32 -0
  121. package/dist/components/PointsEditor/SelectionBox.svelte.d.ts +9 -0
  122. package/dist/components/PointsEditor/SelectionBox.svelte.d.ts.map +1 -0
  123. package/dist/components/PointsEditor/context.d.ts +28 -0
  124. package/dist/components/PointsEditor/context.d.ts.map +1 -0
  125. package/dist/components/PointsEditor/context.js +5 -0
  126. package/dist/components/PointsEditor/index.d.ts +6 -0
  127. package/dist/components/PointsEditor/index.d.ts.map +1 -0
  128. package/dist/components/PointsEditor/index.js +5 -0
  129. package/dist/components/PointsEditor/types.d.ts +84 -0
  130. package/dist/components/PointsEditor/types.d.ts.map +1 -0
  131. package/dist/components/PointsEditor/types.js +1 -0
  132. package/dist/components/Slider/Marks.svelte +42 -0
  133. package/dist/components/Slider/Marks.svelte.d.ts +7 -0
  134. package/dist/components/Slider/Marks.svelte.d.ts.map +1 -0
  135. package/dist/components/Slider/MarksOption.svelte +63 -0
  136. package/dist/components/Slider/MarksOption.svelte.d.ts +7 -0
  137. package/dist/components/Slider/MarksOption.svelte.d.ts.map +1 -0
  138. package/dist/components/Slider/Root.svelte +217 -0
  139. package/dist/components/Slider/Root.svelte.d.ts +10 -0
  140. package/dist/components/Slider/Root.svelte.d.ts.map +1 -0
  141. package/dist/components/Slider/Thumb.svelte +84 -0
  142. package/dist/components/Slider/Thumb.svelte.d.ts +10 -0
  143. package/dist/components/Slider/Thumb.svelte.d.ts.map +1 -0
  144. package/dist/components/Slider/Track.svelte +51 -0
  145. package/dist/components/Slider/Track.svelte.d.ts +7 -0
  146. package/dist/components/Slider/Track.svelte.d.ts.map +1 -0
  147. package/dist/components/Slider/context.d.ts +28 -0
  148. package/dist/components/Slider/context.d.ts.map +1 -0
  149. package/dist/components/Slider/context.js +5 -0
  150. package/dist/components/Slider/index.d.ts +6 -0
  151. package/dist/components/Slider/index.d.ts.map +1 -0
  152. package/dist/components/Slider/index.js +5 -0
  153. package/dist/components/Slider/types.d.ts +138 -0
  154. package/dist/components/Slider/types.d.ts.map +1 -0
  155. package/dist/components/Slider/types.js +1 -0
  156. package/dist/components/XYPad/Area.svelte +29 -0
  157. package/dist/components/XYPad/Area.svelte.d.ts +10 -0
  158. package/dist/components/XYPad/Area.svelte.d.ts.map +1 -0
  159. package/dist/components/XYPad/Root.svelte +238 -0
  160. package/dist/components/XYPad/Root.svelte.d.ts +10 -0
  161. package/dist/components/XYPad/Root.svelte.d.ts.map +1 -0
  162. package/dist/components/XYPad/Thumb.svelte +109 -0
  163. package/dist/components/XYPad/Thumb.svelte.d.ts +10 -0
  164. package/dist/components/XYPad/Thumb.svelte.d.ts.map +1 -0
  165. package/dist/components/XYPad/context.d.ts +25 -0
  166. package/dist/components/XYPad/context.d.ts.map +1 -0
  167. package/dist/components/XYPad/context.js +5 -0
  168. package/dist/components/XYPad/index.d.ts +4 -0
  169. package/dist/components/XYPad/index.d.ts.map +1 -0
  170. package/dist/components/XYPad/index.js +3 -0
  171. package/dist/components/XYPad/types.d.ts +80 -0
  172. package/dist/components/XYPad/types.d.ts.map +1 -0
  173. package/dist/components/XYPad/types.js +1 -0
  174. package/dist/components/_util/VisuallyHiddenRangeInput.svelte +17 -0
  175. package/dist/components/_util/VisuallyHiddenRangeInput.svelte.d.ts +8 -0
  176. package/dist/components/_util/VisuallyHiddenRangeInput.svelte.d.ts.map +1 -0
  177. package/dist/components/_util/check-steps.svelte.d.ts +10 -0
  178. package/dist/components/_util/check-steps.svelte.d.ts.map +1 -0
  179. package/dist/components/_util/check-steps.svelte.js +17 -0
  180. package/dist/components/_util/placement.d.ts +15 -0
  181. package/dist/components/_util/placement.d.ts.map +1 -0
  182. package/dist/components/_util/placement.js +30 -0
  183. package/dist/components/_util/style.d.ts +5 -0
  184. package/dist/components/_util/style.d.ts.map +1 -0
  185. package/dist/components/_util/style.js +9 -0
  186. package/dist/hooks/useMIDIAccess.svelte.d.ts +29 -0
  187. package/dist/hooks/useMIDIAccess.svelte.d.ts.map +1 -0
  188. package/dist/hooks/useMIDIAccess.svelte.js +62 -0
  189. package/dist/hooks/useMIDIInput.svelte.d.ts +18 -0
  190. package/dist/hooks/useMIDIInput.svelte.d.ts.map +1 -0
  191. package/dist/hooks/useMIDIInput.svelte.js +31 -0
  192. package/dist/hooks/useMIDIMessage.svelte.d.ts +9 -0
  193. package/dist/hooks/useMIDIMessage.svelte.d.ts.map +1 -0
  194. package/dist/hooks/useMIDIMessage.svelte.js +23 -0
  195. package/dist/index.d.ts +33 -0
  196. package/dist/index.d.ts.map +1 -0
  197. package/dist/index.js +26 -0
  198. package/package.json +72 -0
@@ -0,0 +1,213 @@
1
+ <script lang="ts">
2
+ import {
3
+ arrowKeyMove,
4
+ clampPoint,
5
+ createDragValue,
6
+ elementMapping,
7
+ POINT_AXIS,
8
+ selectModifier,
9
+ type PointPosition,
10
+ type PointsEditorPoint,
11
+ } from '@tremolo-ui/dom'
12
+ import { untrack } from 'svelte'
13
+
14
+ import { checkPlacement } from '../_util/placement.js'
15
+ import VisuallyHiddenRangeInput from '../_util/VisuallyHiddenRangeInput.svelte'
16
+
17
+ import { usePointsEditorContext } from './context.js'
18
+ import type { PointsEditorPointProps } from './types.js'
19
+
20
+ import type { HTMLAttributes } from 'svelte/elements'
21
+
22
+ type Props = PointsEditorPointProps &
23
+ Omit<HTMLAttributes<HTMLDivElement>, keyof PointsEditorPointProps>
24
+
25
+ let {
26
+ value,
27
+ id: idProp,
28
+ min,
29
+ max,
30
+ color,
31
+ disabled: disabledProp,
32
+ readonly: readonlyProp,
33
+ wheel: wheelProp,
34
+ keyboard: keyboardProp,
35
+ 'aria-label': ariaLabel,
36
+ 'aria-valuetext': ariaValuetext,
37
+ onChange,
38
+ onDragStart,
39
+ onDragEnd,
40
+ children,
41
+ style,
42
+ onfocus,
43
+ onkeydown,
44
+ ...rest
45
+ }: Props = $props()
46
+
47
+ const points = usePointsEditorContext()
48
+ checkPlacement('PointsEditor.Point', 'PointsEditor.Container')
49
+
50
+ const generatedId = $props.id()
51
+ const id = $derived(idProp ?? generatedId)
52
+ const disabled = $derived(disabledProp ?? points.disabled)
53
+ const readonly = $derived(readonlyProp ?? points.readonly)
54
+ const inactive = $derived(disabled || readonly)
55
+ // `null` means "no event" and has to survive the fallback, so `??` is not
56
+ // enough: only an omitted prop inherits from the root.
57
+ const wheel = $derived(wheelProp === undefined ? points.wheel : wheelProp)
58
+ const keyboard = $derived(
59
+ keyboardProp === undefined ? points.keyboard : keyboardProp,
60
+ )
61
+ const selected = $derived(points.selection.includes(id))
62
+ const current = $derived(clampPoint(value, min, max))
63
+
64
+ let element: HTMLDivElement | null = $state(null)
65
+ let xInput: HTMLInputElement | null = $state(null)
66
+ let dragging = $state(false)
67
+
68
+ // Read by the editor whenever it moves the selection, so the value can
69
+ // change on every frame of a drag without registering again.
70
+ const read = (): PointsEditorPoint => ({
71
+ value,
72
+ min,
73
+ max,
74
+ readonly: inactive,
75
+ onChange,
76
+ element,
77
+ wheel,
78
+ })
79
+
80
+ $effect(() => points.editor.registerPoint(id, read))
81
+
82
+ /** Where the pointer was when the drag started, to measure the move from. */
83
+ let origin: PointPosition | null = null
84
+
85
+ $effect(() => {
86
+ const node = element
87
+ if (!node) return
88
+ // The value is the position itself: no scaling, and no rounding to a step.
89
+ const drag = createDragValue(node, {
90
+ axis: POINT_AXIS,
91
+ mapping: elementMapping(() => points.container, {
92
+ sensitivity: (state) =>
93
+ selectModifier(points.dragSensitivity, state.event).value,
94
+ }),
95
+ cursor: untrack(() => (inactive ? undefined : points.cursor)),
96
+ shouldStart: () => !disabled,
97
+ // The value is a move rather than a position: the point keeps the
98
+ // offset it was grabbed at, and everything else selected moves with it.
99
+ onChange: ([x, y]) => {
100
+ if (origin)
101
+ points.editor.movePointDrag({ x: x - origin.x, y: y - origin.y })
102
+ },
103
+ onDragStart: ([x, y], state) => {
104
+ points.editor.beginPointDrag(id, state.event)
105
+ origin = { x, y }
106
+ dragging = true
107
+ xInput?.focus()
108
+ if (!inactive) onDragStart?.(clampPoint(value, min, max))
109
+ },
110
+ onDragEnd: () => {
111
+ origin = null
112
+ dragging = false
113
+ if (!inactive) onDragEnd?.(clampPoint(value, min, max))
114
+ },
115
+ })
116
+ $effect(() => {
117
+ drag.update({ cursor: inactive ? undefined : points.cursor })
118
+ })
119
+ return () => drag.destroy()
120
+ })
121
+
122
+ function perAxis(
123
+ setting: string | Partial<Record<'x' | 'y', string>> | undefined,
124
+ axis: 'x' | 'y',
125
+ ) {
126
+ return typeof setting === 'string' ? setting : setting?.[axis]
127
+ }
128
+
129
+ function onInput(axis: 'x' | 'y', target: HTMLInputElement) {
130
+ if (readonly) {
131
+ target.value = String(current[axis])
132
+ return
133
+ }
134
+ const delta = target.valueAsNumber - value[axis]
135
+ points.editor.nudgeSelection(id, {
136
+ x: axis === 'x' ? delta : 0,
137
+ y: axis === 'y' ? delta : 0,
138
+ })
139
+ }
140
+ </script>
141
+
142
+ <!-- The visual point has two values, so its semantics live on the two range
143
+ inputs nested inside it rather than on this drag handle. A press lands on
144
+ the point, which cannot hold focus, and the browser answers that by
145
+ clearing the focus — tabindex -1 keeps it inside. -->
146
+ <div
147
+ bind:this={element}
148
+ tabindex="-1"
149
+ role="presentation"
150
+ data-disabled={disabled ? '' : undefined}
151
+ data-readonly={readonly ? '' : undefined}
152
+ data-dragging={dragging ? '' : undefined}
153
+ data-selected={selected ? '' : undefined}
154
+ {...rest}
155
+ style="position: absolute; translate: var(--translate, -50% -50%); {style ??
156
+ ''}"
157
+ style:--color={color}
158
+ style:left="{value.x * 100}%"
159
+ style:top="{value.y * 100}%"
160
+ onfocus={(event) => {
161
+ // The point itself is not the control: whatever reaches it is handed to
162
+ // the first input.
163
+ if (!disabled && event.target === event.currentTarget) xInput?.focus()
164
+ onfocus?.(event)
165
+ }}
166
+ onkeydown={(event) => {
167
+ // The key picks the axis, whichever of the two inputs holds the focus.
168
+ // y grows downwards, so ArrowUp moves the point towards 0.
169
+ const move = arrowKeyMove(event.key)
170
+ if (move) {
171
+ event.preventDefault()
172
+ if (onChange && !inactive && keyboard) {
173
+ points.editor.nudgePoint(
174
+ id,
175
+ move.axis === 0 ? 'x' : 'y',
176
+ move.direction,
177
+ keyboard,
178
+ event,
179
+ )
180
+ }
181
+ }
182
+ onkeydown?.(event)
183
+ }}
184
+ >
185
+ <VisuallyHiddenRangeInput
186
+ bind:ref={xInput}
187
+ data-axis="x"
188
+ value={current.x}
189
+ min={min?.x ?? 0}
190
+ max={max?.x ?? 1}
191
+ step="any"
192
+ {disabled}
193
+ aria-readonly={readonly}
194
+ aria-orientation="horizontal"
195
+ aria-label={perAxis(ariaLabel, 'x') ?? 'x'}
196
+ aria-valuetext={perAxis(ariaValuetext, 'x')}
197
+ oninput={(event) => onInput('x', event.currentTarget)}
198
+ />
199
+ <VisuallyHiddenRangeInput
200
+ data-axis="y"
201
+ value={current.y}
202
+ min={min?.y ?? 0}
203
+ max={max?.y ?? 1}
204
+ step="any"
205
+ {disabled}
206
+ aria-readonly={readonly}
207
+ aria-orientation="vertical"
208
+ aria-label={perAxis(ariaLabel, 'y') ?? 'y'}
209
+ aria-valuetext={perAxis(ariaValuetext, 'y')}
210
+ oninput={(event) => onInput('y', event.currentTarget)}
211
+ />
212
+ {@render children?.()}
213
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { PointsEditorPointProps } from './types.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = PointsEditorPointProps & Omit<HTMLAttributes<HTMLDivElement>, keyof PointsEditorPointProps>;
4
+ declare const Point: import("svelte").Component<Props, {}, "">;
5
+ type Point = ReturnType<typeof Point>;
6
+ export default Point;
7
+ //# sourceMappingURL=Point.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Point.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/PointsEditor/Point.svelte.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAExD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,sBAAsB,GACjC,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,sBAAsB,CAAC,CAAC;AAmKvE,QAAA,MAAM,KAAK,2CAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -0,0 +1,107 @@
1
+ <script lang="ts">
2
+ import {
3
+ createPointsEditor,
4
+ DEFAULT_DRAG_SENSITIVITY,
5
+ POINTS_EDITOR_DEFAULT_KEYBOARD,
6
+ POINTS_EDITOR_DEFAULT_WHEEL,
7
+ type SelectionBoxRect,
8
+ } from '@tremolo-ui/dom'
9
+
10
+ import { setPointsEditorContext } from './context.js'
11
+ import type { PointsEditorProps } from './types.js'
12
+
13
+ import type { HTMLAttributes } from 'svelte/elements'
14
+
15
+ type Props = PointsEditorProps &
16
+ Omit<HTMLAttributes<HTMLDivElement>, keyof PointsEditorProps>
17
+
18
+ let {
19
+ disabled = false,
20
+ readonly = false,
21
+ externalStyles,
22
+ wheel = POINTS_EDITOR_DEFAULT_WHEEL,
23
+ keyboard = POINTS_EDITOR_DEFAULT_KEYBOARD,
24
+ dragSensitivity = DEFAULT_DRAG_SENSITIVITY,
25
+ selectable = false,
26
+ selection = $bindable([]),
27
+ onSelectionChange,
28
+ ref = $bindable(null),
29
+ children,
30
+ style,
31
+ ...rest
32
+ }: Props = $props()
33
+
34
+ let selectionBox: SelectionBoxRect | null = $state(null)
35
+ let container: HTMLElement | null = $state(null)
36
+
37
+ // Nothing is selected while selection is off, so a drag picks up only the
38
+ // point it started on and `data-selected` never turns on.
39
+ const current = $derived(selectable ? selection : [])
40
+
41
+ // The selection lives here, where Svelte state can hold it; which points a
42
+ // press or a box selects, and how a selection moves, is the core's.
43
+ const editor = createPointsEditor({
44
+ onSelectionBoxChange: (rect) => {
45
+ selectionBox = rect
46
+ },
47
+ onSelectionChange: (next) => {
48
+ selection = next
49
+ onSelectionChange?.(next)
50
+ },
51
+ })
52
+
53
+ // Pushed before the DOM updates, so that the next press already sees it.
54
+ $effect.pre(() => {
55
+ editor.update({ selectable, selection: current })
56
+ })
57
+
58
+ $effect(() => () => editor.destroy())
59
+
60
+ setPointsEditorContext({
61
+ get disabled() {
62
+ return disabled
63
+ },
64
+ get readonly() {
65
+ return readonly
66
+ },
67
+ get wheel() {
68
+ return wheel
69
+ },
70
+ get keyboard() {
71
+ return keyboard
72
+ },
73
+ get dragSensitivity() {
74
+ return dragSensitivity
75
+ },
76
+ get cursor() {
77
+ return externalStyles?.cursor ?? 'grabbing'
78
+ },
79
+ get selectable() {
80
+ return selectable
81
+ },
82
+ get selection() {
83
+ return current
84
+ },
85
+ get selectionBox() {
86
+ return selectionBox
87
+ },
88
+ get container() {
89
+ return container
90
+ },
91
+ editor,
92
+ setContainer: (element) => {
93
+ container = element
94
+ },
95
+ })
96
+ </script>
97
+
98
+ <!-- The layers inside are placed against this box. -->
99
+ <div
100
+ bind:this={ref}
101
+ data-disabled={disabled ? '' : undefined}
102
+ data-readonly={readonly ? '' : undefined}
103
+ style="position: relative; {style ?? ''}"
104
+ {...rest}
105
+ >
106
+ {@render children()}
107
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { PointsEditorProps } from './types.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = PointsEditorProps & Omit<HTMLAttributes<HTMLDivElement>, keyof PointsEditorProps>;
4
+ declare const Root: import("svelte").Component<Props, {}, "ref" | "selection">;
5
+ type Root = ReturnType<typeof Root>;
6
+ export default Root;
7
+ //# sourceMappingURL=Root.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Root.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/PointsEditor/Root.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,iBAAiB,GAC5B,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,iBAAiB,CAAC,CAAC;AAiGlE,QAAA,MAAM,IAAI,4DAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import { checkPlacement } from '../_util/placement.js'
3
+
4
+ import { usePointsEditorContext } from './context.js'
5
+
6
+ import type { Snippet } from 'svelte'
7
+ import type { HTMLAttributes } from 'svelte/elements'
8
+
9
+ type Props = HTMLAttributes<HTMLDivElement> & { children?: Snippet }
10
+
11
+ let { children, style, ...rest }: Props = $props()
12
+
13
+ const points = usePointsEditorContext()
14
+ checkPlacement('PointsEditor.SelectionBox', 'PointsEditor.Container')
15
+ </script>
16
+
17
+ <!-- Drawn over the points while a drag runs, and taking none of the pointer:
18
+ the drag underneath is what it is reporting on. Nothing is rendered while no
19
+ drag is running. -->
20
+ {#if points.selectionBox}
21
+ {@const box = points.selectionBox}
22
+ <div
23
+ {...rest}
24
+ style="position: absolute; z-index: 20; pointer-events: none; {style ?? ''}"
25
+ style:left="{box.x * 100}%"
26
+ style:top="{box.y * 100}%"
27
+ style:width="{box.width * 100}%"
28
+ style:height="{box.height * 100}%"
29
+ >
30
+ {@render children?.()}
31
+ </div>
32
+ {/if}
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = HTMLAttributes<HTMLDivElement> & {
4
+ children?: Snippet;
5
+ };
6
+ declare const SelectionBox: import("svelte").Component<Props, {}, "">;
7
+ type SelectionBox = ReturnType<typeof SelectionBox>;
8
+ export default SelectionBox;
9
+ //# sourceMappingURL=SelectionBox.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionBox.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/PointsEditor/SelectionBox.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA0BvE,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { InputEventOption, ModifierValue, PointsEditorInstance, SelectionBoxRect } from '@tremolo-ui/dom';
2
+ /** What `PointsEditor.Root` shares with its parts. Every field is a getter. */
3
+ export interface PointsEditorContextValue {
4
+ readonly disabled: boolean;
5
+ readonly readonly: boolean;
6
+ readonly wheel: ModifierValue<InputEventOption> | null;
7
+ readonly keyboard: ModifierValue<InputEventOption> | null;
8
+ readonly dragSensitivity: ModifierValue<number>;
9
+ readonly cursor: string;
10
+ readonly selectable: boolean;
11
+ /** Ids of the selected points. Always empty while `selectable` is off. */
12
+ readonly selection: readonly string[];
13
+ /** The selection box, while one is being dragged. */
14
+ readonly selectionBox: SelectionBoxRect | null;
15
+ /** The element points are placed in and measured against. */
16
+ readonly container: HTMLElement | null;
17
+ /**
18
+ * The selection and the moves, from `createPointsEditor` in
19
+ * `@tremolo-ui/dom`: every `Point` registers with it.
20
+ */
21
+ readonly editor: PointsEditorInstance;
22
+ /** @internal `Container` registers its element. */
23
+ setContainer: (element: HTMLElement | null) => void;
24
+ }
25
+ /** The context of the enclosing `PointsEditor.Root`, for a part of your own. */
26
+ export declare const usePointsEditorContext: () => PointsEditorContextValue;
27
+ export declare const setPointsEditorContext: (context: PointsEditorContextValue) => PointsEditorContextValue;
28
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/components/PointsEditor/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,iBAAiB,CAAA;AAExB,+EAA+E;AAC/E,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IACtD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IACzD,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IACrC,qDAAqD;IACrD,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC9C,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IACtC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;IACrC,mDAAmD;IACnD,YAAY,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;CACpD;AAID,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,gCAAM,CAAA;AACzC,eAAO,MAAM,sBAAsB,iEAAM,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { createContext } from 'svelte';
2
+ const [get, set] = createContext();
3
+ /** The context of the enclosing `PointsEditor.Root`, for a part of your own. */
4
+ export const usePointsEditorContext = get;
5
+ export const setPointsEditorContext = set;
@@ -0,0 +1,6 @@
1
+ export { default as Background } from './Background.svelte';
2
+ export { default as Container } from './Container.svelte';
3
+ export { default as Point } from './Point.svelte';
4
+ export { default as Root } from './Root.svelte';
5
+ export { default as SelectionBox } from './SelectionBox.svelte';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PointsEditor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { default as Background } from './Background.svelte';
2
+ export { default as Container } from './Container.svelte';
3
+ export { default as Point } from './Point.svelte';
4
+ export { default as Root } from './Root.svelte';
5
+ export { default as SelectionBox } from './SelectionBox.svelte';
@@ -0,0 +1,84 @@
1
+ import type { InputEventOption, ModifierValue, PointPosition } from '@tremolo-ui/dom';
2
+ import type { Snippet } from 'svelte';
3
+ export interface PointsEditorProps {
4
+ /** Make the points unchangeable and remove them from the tab order. */
5
+ disabled?: boolean;
6
+ /** Make the points unmovable. */
7
+ readonly?: boolean;
8
+ /**
9
+ * The cursor to show while dragging a point.
10
+ * @default { cursor: 'grabbing' }
11
+ */
12
+ externalStyles?: {
13
+ cursor?: string;
14
+ };
15
+ /**
16
+ * How much one notch of the wheel moves the focused `Point`. Scrolling
17
+ * sideways, or with shift held, moves x. A `Point` can override it.
18
+ * @default ['normalized', 0.01]
19
+ */
20
+ wheel?: ModifierValue<InputEventOption> | null;
21
+ /**
22
+ * How much one arrow key press moves a `Point`. A `Point` can override it.
23
+ * @default { default: ['normalized', 0.01], shift: ['normalized', 0.001] }
24
+ */
25
+ keyboard?: ModifierValue<InputEventOption> | null;
26
+ /**
27
+ * How much a drag moves a `Point`, per modifier key.
28
+ * @default { default: 1, shift: 0.1 }
29
+ */
30
+ dragSensitivity?: ModifierValue<number>;
31
+ /**
32
+ * Let points be selected, and a selection be moved as one. A selection
33
+ * calls `onChange` on several points in the same tick.
34
+ * @default false
35
+ */
36
+ selectable?: boolean;
37
+ /**
38
+ * Ids of the selected points. Bind it (`bind:selection`) to hold the
39
+ * selection yourself.
40
+ */
41
+ selection?: string[];
42
+ /** Called whenever the selection changes. */
43
+ onSelectionChange?: (selection: string[]) => void;
44
+ /** The root element, bound with `bind:ref`. */
45
+ ref?: HTMLDivElement | null;
46
+ /** The editor renders exactly what you compose here. */
47
+ children: Snippet;
48
+ }
49
+ export interface PointsEditorPointProps {
50
+ /** Where the point is, as `{ x, y }` from 0 to 1, with `y` growing downwards. */
51
+ value: PointPosition;
52
+ /**
53
+ * How the selection refers to this point. One is generated when it is left
54
+ * out, which lasts as long as the point is mounted.
55
+ */
56
+ id?: string;
57
+ /** The lowest position the point can take, per axis. */
58
+ min?: Partial<PointPosition>;
59
+ /** The highest position the point can take, per axis. */
60
+ max?: Partial<PointPosition>;
61
+ /** Sets `--color`, for the theme to colour the point with. */
62
+ color?: string;
63
+ /** Overrides the `disabled` of `PointsEditor.Root`. */
64
+ disabled?: boolean;
65
+ /** Overrides the `readonly` of `PointsEditor.Root`. */
66
+ readonly?: boolean;
67
+ /** Overrides the `wheel` of `PointsEditor.Root`. */
68
+ wheel?: ModifierValue<InputEventOption> | null;
69
+ /** Overrides the `keyboard` of `PointsEditor.Root`. */
70
+ keyboard?: ModifierValue<InputEventOption> | null;
71
+ /** The accessible name of each axis, or one for both. */
72
+ 'aria-label'?: string | Partial<Record<'x' | 'y', string>>;
73
+ /** What the value of each axis means, or one for both. */
74
+ 'aria-valuetext'?: string | Partial<Record<'x' | 'y', string>>;
75
+ /**
76
+ * Called with the new position when the point is moved, including when it
77
+ * moves along with a selection.
78
+ */
79
+ onChange?: (value: PointPosition) => void;
80
+ onDragStart?: (value: PointPosition) => void;
81
+ onDragEnd?: (value: PointPosition) => void;
82
+ children?: Snippet;
83
+ }
84
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/PointsEditor/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,aAAa,EACd,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAErC,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IAC9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IACjD;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACvC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACjD,+CAA+C;IAC/C,GAAG,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC3B,wDAAwD;IACxD,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,iFAAiF;IACjF,KAAK,EAAE,aAAa,CAAA;IACpB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,wDAAwD;IACxD,GAAG,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAC5B,yDAAyD;IACzD,GAAG,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;IAC5B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,oDAAoD;IACpD,KAAK,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IAC9C,uDAAuD;IACvD,QAAQ,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IACjD,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;IAC1D,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;IAC9D;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IACzC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ import { cssLength, sliderMarks } from '@tremolo-ui/dom'
3
+
4
+ import { setPlacement } from '../_util/placement.js'
5
+
6
+ import { useSliderContext } from './context.js'
7
+ import MarksOption from './MarksOption.svelte'
8
+ import type { SliderMarksProps } from './types.js'
9
+
10
+ import type { HTMLAttributes } from 'svelte/elements'
11
+
12
+ type Props = SliderMarksProps &
13
+ Omit<HTMLAttributes<HTMLDivElement>, keyof SliderMarksProps>
14
+
15
+ let { gap, options, children, style, ...rest }: Props = $props()
16
+
17
+ const slider = useSliderContext()
18
+ setPlacement('Slider.Marks')
19
+
20
+ const marks = $derived.by(() => {
21
+ if (!options) return []
22
+ const list = sliderMarks(options, slider.min, slider.max, slider.step)
23
+ // In the order they are on screen.
24
+ return slider.vertical !== slider.reverse ? list.reverse() : list
25
+ })
26
+ </script>
27
+
28
+ <!-- Each option inside is placed against this box. -->
29
+ <div
30
+ data-orientation={slider.vertical ? 'vertical' : 'horizontal'}
31
+ style="position: relative; {style ?? ''}"
32
+ style:--gap={cssLength(gap)}
33
+ {...rest}
34
+ >
35
+ {#if options}
36
+ {#each marks as { value, mark, label } (value)}
37
+ <MarksOption {value} {mark} label={label ? undefined : null} />
38
+ {/each}
39
+ {:else}
40
+ {@render children?.()}
41
+ {/if}
42
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { SliderMarksProps } from './types.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = SliderMarksProps & Omit<HTMLAttributes<HTMLDivElement>, keyof SliderMarksProps>;
4
+ declare const Marks: import("svelte").Component<Props, {}, "">;
5
+ type Marks = ReturnType<typeof Marks>;
6
+ export default Marks;
7
+ //# sourceMappingURL=Marks.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Marks.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/Slider/Marks.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,gBAAgB,GAC3B,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,gBAAgB,CAAC,CAAC;AAuCjE,QAAA,MAAM,KAAK,2CAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ import { cssLength, valuePercent } from '@tremolo-ui/dom'
3
+
4
+ import { checkPlacement } from '../_util/placement.js'
5
+
6
+ import { useSliderContext } from './context.js'
7
+ import type { SliderMarksOptionProps } from './types.js'
8
+
9
+ import type { HTMLAttributes } from 'svelte/elements'
10
+
11
+ type Props = SliderMarksOptionProps &
12
+ Omit<HTMLAttributes<HTMLDivElement>, keyof SliderMarksOptionProps>
13
+
14
+ let {
15
+ value,
16
+ mark = true,
17
+ label,
18
+ thickness,
19
+ length,
20
+ gap,
21
+ classes,
22
+ styles,
23
+ style,
24
+ ...rest
25
+ }: Props = $props()
26
+
27
+ const slider = useSliderContext()
28
+ checkPlacement('Slider.MarksOption', 'Slider.Marks')
29
+
30
+ // The marks sit on the same curve the thumb runs along.
31
+ const percent = $derived(
32
+ valuePercent(
33
+ value,
34
+ { min: slider.min, max: slider.max, scale: slider.scale },
35
+ slider.vertical !== slider.reverse,
36
+ ),
37
+ )
38
+ const orientation = $derived(slider.vertical ? 'vertical' : 'horizontal')
39
+ </script>
40
+
41
+ <div
42
+ data-orientation={orientation}
43
+ {...rest}
44
+ style="position: absolute; translate: {slider.vertical
45
+ ? 'var(--translate, 0 -50%)'
46
+ : 'var(--translate, -50% 0)'}; z-index: 10; {style ?? ''}"
47
+ style:--thickness={cssLength(thickness)}
48
+ style:--length={cssLength(length)}
49
+ style:--gap={cssLength(gap)}
50
+ style:left={slider.vertical ? undefined : `${percent}%`}
51
+ style:top={slider.vertical ? `${percent}%` : undefined}
52
+ >
53
+ {#if mark}
54
+ <div
55
+ class={classes?.mark}
56
+ style={styles?.mark}
57
+ data-orientation={orientation}
58
+ ></div>
59
+ {/if}
60
+ {#if label !== null}
61
+ <div class={classes?.label} style={styles?.label}>{label ?? value}</div>
62
+ {/if}
63
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { SliderMarksOptionProps } from './types.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = SliderMarksOptionProps & Omit<HTMLAttributes<HTMLDivElement>, keyof SliderMarksOptionProps>;
4
+ declare const MarksOption: import("svelte").Component<Props, {}, "">;
5
+ type MarksOption = ReturnType<typeof MarksOption>;
6
+ export default MarksOption;
7
+ //# sourceMappingURL=MarksOption.svelte.d.ts.map