@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,238 @@
1
+ <script lang="ts">
2
+ import {
3
+ applyDelta,
4
+ arrowKeyMove,
5
+ DEFAULT_DRAG_SENSITIVITY,
6
+ DEFAULT_KEYBOARD_OPTIONS,
7
+ DEFAULT_WHEEL_OPTIONS,
8
+ elementMapping,
9
+ selectModifier,
10
+ toXY,
11
+ valuePercent,
12
+ wheelMove,
13
+ type AxisMove,
14
+ type AxisOptions,
15
+ type InputEventOption,
16
+ type ModifierState,
17
+ type ModifierValue,
18
+ type XY,
19
+ } from '@tremolo-ui/dom'
20
+ import { linearScale } from '@tremolo-ui/functions'
21
+
22
+ import { dragValue } from '../../actions/drag-value.js'
23
+ import { wheel as wheelAction } from '../../actions/wheel.js'
24
+ import { useCheckSteps } from '../_util/check-steps.svelte.js'
25
+
26
+ import { setXYPadContext } from './context.js'
27
+ import type { XYPadProps } from './types.js'
28
+
29
+ import type { HTMLAttributes } from 'svelte/elements'
30
+
31
+ type Props = XYPadProps &
32
+ Omit<HTMLAttributes<HTMLDivElement>, keyof XYPadProps>
33
+
34
+ let {
35
+ value = $bindable(),
36
+ min: minProp,
37
+ max: maxProp,
38
+ step: stepProp = 1,
39
+ scale: scaleProp = linearScale,
40
+ reverse: reverseProp = false,
41
+ wheel = DEFAULT_WHEEL_OPTIONS,
42
+ keyboard = DEFAULT_KEYBOARD_OPTIONS,
43
+ dragSensitivity = DEFAULT_DRAG_SENSITIVITY,
44
+ externalStyles,
45
+ disabled = false,
46
+ readonly = false,
47
+ onChange,
48
+ onDragStart,
49
+ onDragEnd,
50
+ ref = $bindable(null),
51
+ children,
52
+ onkeydown,
53
+ onfocus,
54
+ onblur,
55
+ ...rest
56
+ }: Props = $props()
57
+
58
+ const inactive = $derived(disabled || readonly)
59
+ const min = $derived(toXY(minProp))
60
+ const max = $derived(toXY(maxProp))
61
+ const step = $derived(toXY(stepProp))
62
+ const scale = $derived(toXY(scaleProp))
63
+ const reverse = $derived(toXY(reverseProp))
64
+
65
+ const percent = $derived(
66
+ [0, 1].map((i) =>
67
+ valuePercent(
68
+ value[i],
69
+ { min: min[i], max: max[i], scale: scale[i] },
70
+ reverse[i],
71
+ ),
72
+ ) as XY<number>,
73
+ )
74
+ // `reverse` only concerns the drag, where positions follow the screen; the
75
+ // key and wheel handlers below flip the direction themselves.
76
+ const axis = $derived(
77
+ [0, 1].map((i) => ({
78
+ min: min[i],
79
+ max: max[i],
80
+ step: step[i],
81
+ scale: scale[i],
82
+ reverse: reverse[i],
83
+ })) as XY<AxisOptions>,
84
+ )
85
+
86
+ let area: HTMLElement | null = null
87
+ let thumb: HTMLInputElement | null = null
88
+
89
+ useCheckSteps(() => ({
90
+ component: 'XYPad',
91
+ axis: 'x',
92
+ range: axis[0],
93
+ keyboard,
94
+ wheel,
95
+ }))
96
+ useCheckSteps(() => ({
97
+ component: 'XYPad',
98
+ axis: 'y',
99
+ range: axis[1],
100
+ keyboard,
101
+ wheel,
102
+ }))
103
+
104
+ function change(next: XY<number>) {
105
+ value = next
106
+ onChange?.(next)
107
+ }
108
+
109
+ /** Move one axis by one press of `option`, in screen coordinates. */
110
+ function nudge(
111
+ { axis: i, direction }: AxisMove,
112
+ option: ModifierValue<InputEventOption>,
113
+ modifiers: ModifierState,
114
+ ) {
115
+ const next = applyDelta(
116
+ value[i],
117
+ reverse[i] ? -direction : direction,
118
+ option,
119
+ axis[i],
120
+ modifiers,
121
+ )
122
+ change(i === 0 ? [next, value[1]] : [value[0], next])
123
+ }
124
+
125
+ setXYPadContext({
126
+ get value() {
127
+ return value
128
+ },
129
+ get min() {
130
+ return min
131
+ },
132
+ get max() {
133
+ return max
134
+ },
135
+ get step() {
136
+ return step
137
+ },
138
+ get scale() {
139
+ return scale
140
+ },
141
+ get reverse() {
142
+ return reverse
143
+ },
144
+ get disabled() {
145
+ return disabled
146
+ },
147
+ get readonly() {
148
+ return readonly
149
+ },
150
+ get percent() {
151
+ return percent
152
+ },
153
+ change,
154
+ setArea: (element) => {
155
+ area = element
156
+ },
157
+ setThumb: (input) => {
158
+ thumb = input
159
+ },
160
+ })
161
+
162
+ const dragOptions = $derived({
163
+ axis,
164
+ mapping: elementMapping(() => area, {
165
+ sensitivity: (state) =>
166
+ selectModifier(dragSensitivity, state.event).value,
167
+ }),
168
+ updateOnPointerDown: true,
169
+ cursor: inactive ? undefined : (externalStyles?.cursor ?? 'pointer'),
170
+ shouldStart: () => !inactive,
171
+ onChange: (v: XY<number>) => {
172
+ if (!inactive) change(v)
173
+ },
174
+ onDragStart: (v: XY<number>) => {
175
+ if (inactive) return
176
+ thumb?.focus()
177
+ onDragStart?.(v)
178
+ },
179
+ onDragEnd: (v: XY<number>) => {
180
+ if (!inactive) onDragEnd?.(v)
181
+ },
182
+ })
183
+
184
+ const wheelOptions = $derived({
185
+ requireFocus: true,
186
+ onWheel: (event: WheelEvent) => {
187
+ if (!wheel || inactive) return
188
+ const move = wheelMove(event)
189
+ if (!move) return
190
+ event.preventDefault()
191
+ nudge(move, wheel, event)
192
+ },
193
+ })
194
+
195
+ /** Move the focus to the thumb. */
196
+ export function focus() {
197
+ if (!disabled) thumb?.focus()
198
+ }
199
+
200
+ /** Take the focus away from the thumb. */
201
+ export function blur() {
202
+ thumb?.blur()
203
+ }
204
+ </script>
205
+
206
+ <!-- The group handles the pointer and keyboard input shared by its two range
207
+ controls. -->
208
+ <div
209
+ bind:this={ref}
210
+ role="group"
211
+ tabindex="-1"
212
+ data-disabled={disabled ? '' : undefined}
213
+ data-readonly={readonly ? '' : undefined}
214
+ use:dragValue={dragOptions}
215
+ use:wheelAction={wheelOptions}
216
+ onkeydown={(event) => {
217
+ // The key picks the axis, whichever of the two inputs holds the focus:
218
+ // the focus lands on the x input, so reading the axis off the input would
219
+ // leave the y axis with no keys at all.
220
+ const move = arrowKeyMove(event.key)
221
+ if (move) {
222
+ event.preventDefault()
223
+ if (keyboard && !inactive) nudge(move, keyboard, event)
224
+ }
225
+ onkeydown?.(event)
226
+ }}
227
+ onfocus={(event) => {
228
+ if (!disabled) thumb?.focus()
229
+ onfocus?.(event)
230
+ }}
231
+ onblur={(event) => {
232
+ thumb?.blur()
233
+ onblur?.(event)
234
+ }}
235
+ {...rest}
236
+ >
237
+ {@render children()}
238
+ </div>
@@ -0,0 +1,10 @@
1
+ import type { XYPadProps } from './types.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = XYPadProps & Omit<HTMLAttributes<HTMLDivElement>, keyof XYPadProps>;
4
+ declare const Root: import("svelte").Component<Props, {
5
+ focus: () => void;
6
+ blur: () => void;
7
+ }, "ref" | "value">;
8
+ type Root = ReturnType<typeof Root>;
9
+ export default Root;
10
+ //# sourceMappingURL=Root.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Root.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/XYPad/Root.svelte.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,UAAU,GACrB,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,UAAU,CAAC,CAAC;AAkN3D,QAAA,MAAM,IAAI;;;mBAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
@@ -0,0 +1,109 @@
1
+ <script lang="ts">
2
+ import { toXY } from '@tremolo-ui/dom'
3
+
4
+ import { checkPlacement } from '../_util/placement.js'
5
+ import VisuallyHiddenRangeInput from '../_util/VisuallyHiddenRangeInput.svelte'
6
+
7
+ import { useXYPadContext } from './context.js'
8
+ import type { XYPadThumbProps } from './types.js'
9
+
10
+ import type { HTMLAttributes } from 'svelte/elements'
11
+
12
+ type Props = XYPadThumbProps &
13
+ Omit<HTMLAttributes<HTMLDivElement>, keyof XYPadThumbProps>
14
+
15
+ let {
16
+ color,
17
+ children,
18
+ style,
19
+ 'aria-label': ariaLabel,
20
+ 'aria-labelledby': ariaLabelledby,
21
+ 'aria-describedby': ariaDescribedby,
22
+ 'aria-valuetext': ariaValuetext,
23
+ ...rest
24
+ }: Props = $props()
25
+
26
+ const pad = useXYPadContext()
27
+ checkPlacement('XYPad.Thumb', 'XYPad.Area')
28
+
29
+ // Per axis, since the thumb holds one input for each.
30
+ const labels = $derived(toXY(ariaLabel))
31
+ const labelledby = $derived(toXY(ariaLabelledby))
32
+ const describedby = $derived(toXY(ariaDescribedby))
33
+ const valueText = $derived(toXY(ariaValuetext))
34
+
35
+ let x: HTMLInputElement | null = $state(null)
36
+ let y: HTMLInputElement | null = $state(null)
37
+
38
+ // Root focuses the thumb when a drag starts, wherever it was placed.
39
+ $effect(() => {
40
+ pad.setThumb(x)
41
+ return () => pad.setThumb(null)
42
+ })
43
+
44
+ function onInput(axis: 0 | 1, target: HTMLInputElement) {
45
+ if (pad.readonly) {
46
+ target.value = String(pad.value[axis])
47
+ return
48
+ }
49
+ const next = [...pad.value] as [number, number]
50
+ next[axis] = target.valueAsNumber
51
+ pad.change(next)
52
+ }
53
+
54
+ /** Move the focus to the x input. */
55
+ export function focus() {
56
+ if (!pad.disabled) x?.focus()
57
+ }
58
+
59
+ /** Take the focus away from both inputs. */
60
+ export function blur() {
61
+ x?.blur()
62
+ y?.blur()
63
+ }
64
+ </script>
65
+
66
+ <div
67
+ data-disabled={pad.disabled ? '' : undefined}
68
+ data-readonly={pad.readonly ? '' : undefined}
69
+ {...rest}
70
+ style="position: absolute; translate: var(--translate, -50% -50%); z-index: 100; {style ??
71
+ ''}"
72
+ style:--color={color}
73
+ style:left="{pad.percent[0]}%"
74
+ style:top="{pad.percent[1]}%"
75
+ >
76
+ <VisuallyHiddenRangeInput
77
+ bind:ref={x}
78
+ data-axis="x"
79
+ value={pad.value[0]}
80
+ min={pad.min[0]}
81
+ max={pad.max[0]}
82
+ step={pad.step[0]}
83
+ disabled={pad.disabled}
84
+ aria-readonly={pad.readonly}
85
+ aria-orientation="horizontal"
86
+ aria-label={labels[0] ?? 'x'}
87
+ aria-labelledby={labelledby[0]}
88
+ aria-describedby={describedby[0]}
89
+ aria-valuetext={valueText[0]}
90
+ oninput={(event) => onInput(0, event.currentTarget)}
91
+ />
92
+ <VisuallyHiddenRangeInput
93
+ bind:ref={y}
94
+ data-axis="y"
95
+ value={pad.value[1]}
96
+ min={pad.min[1]}
97
+ max={pad.max[1]}
98
+ step={pad.step[1]}
99
+ disabled={pad.disabled}
100
+ aria-readonly={pad.readonly}
101
+ aria-orientation="vertical"
102
+ aria-label={labels[1] ?? 'y'}
103
+ aria-labelledby={labelledby[1]}
104
+ aria-describedby={describedby[1]}
105
+ aria-valuetext={valueText[1]}
106
+ oninput={(event) => onInput(1, event.currentTarget)}
107
+ />
108
+ {@render children?.()}
109
+ </div>
@@ -0,0 +1,10 @@
1
+ import type { XYPadThumbProps } from './types.js';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = XYPadThumbProps & Omit<HTMLAttributes<HTMLDivElement>, keyof XYPadThumbProps>;
4
+ declare const Thumb: import("svelte").Component<Props, {
5
+ focus: () => void;
6
+ blur: () => void;
7
+ }, "">;
8
+ type Thumb = ReturnType<typeof Thumb>;
9
+ export default Thumb;
10
+ //# sourceMappingURL=Thumb.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Thumb.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/XYPad/Thumb.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGpD,KAAK,KAAK,GAAG,eAAe,GAC1B,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,eAAe,CAAC,CAAC;AAyEhE,QAAA,MAAM,KAAK;;;MAAwC,CAAC;AACpD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACtC,eAAe,KAAK,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { XY } from '@tremolo-ui/dom';
2
+ import type { Scale } from '@tremolo-ui/functions';
3
+ /** What `XYPad.Root` shares with its parts. Every field is a getter. */
4
+ export interface XYPadContextValue {
5
+ readonly value: XY<number>;
6
+ readonly min: XY<number>;
7
+ readonly max: XY<number>;
8
+ readonly step: XY<number>;
9
+ readonly scale: XY<Scale>;
10
+ readonly reverse: XY<boolean>;
11
+ readonly disabled: boolean;
12
+ readonly readonly: boolean;
13
+ /** Where the value sits in the area, as percentages from the left and top. */
14
+ readonly percent: XY<number>;
15
+ /** Set the value, as an input on the pad would. */
16
+ change: (value: XY<number>) => void;
17
+ /** @internal `XYPad.Area` registers the element the pointer is measured against. */
18
+ setArea: (element: HTMLElement | null) => void;
19
+ /** @internal `XYPad.Thumb` registers the input the focus goes to. */
20
+ setThumb: (input: HTMLInputElement | null) => void;
21
+ }
22
+ /** The context of the enclosing `XYPad.Root`, for a part of your own. */
23
+ export declare const useXYPadContext: () => XYPadContextValue;
24
+ export declare const setXYPadContext: (context: XYPadContextValue) => XYPadContextValue;
25
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/components/XYPad/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAElD,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IAC1B,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IACxB,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IAC5B,mDAAmD;IACnD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;IACnC,oFAAoF;IACpF,OAAO,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAC9C,qEAAqE;IACrE,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,CAAA;CACnD;AAID,yEAAyE;AACzE,eAAO,MAAM,eAAe,yBAAM,CAAA;AAClC,eAAO,MAAM,eAAe,mDAAM,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { createContext } from 'svelte';
2
+ const [get, set] = createContext();
3
+ /** The context of the enclosing `XYPad.Root`, for a part of your own. */
4
+ export const useXYPadContext = get;
5
+ export const setXYPadContext = set;
@@ -0,0 +1,4 @@
1
+ export { default as Area } from './Area.svelte';
2
+ export { default as Root } from './Root.svelte';
3
+ export { default as Thumb } from './Thumb.svelte';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/XYPad/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { default as Area } from './Area.svelte';
2
+ export { default as Root } from './Root.svelte';
3
+ export { default as Thumb } from './Thumb.svelte';
@@ -0,0 +1,80 @@
1
+ import type { InputEventOption, ModifierValue, XY, XYInput } from '@tremolo-ui/dom';
2
+ import type { Scale } from '@tremolo-ui/functions';
3
+ import type { Snippet } from 'svelte';
4
+ /**
5
+ * The per-axis settings mirror `Slider`, given as `[x, y]` tuples. A plain
6
+ * value applies to both axes.
7
+ */
8
+ export interface XYPadProps {
9
+ /** The current value as `[x, y]`. Bind it or update it from `onChange`. */
10
+ value: XY<number>;
11
+ /** The value at the start of the travel, per axis. */
12
+ min: XYInput<number>;
13
+ /** The value at the end of the travel, per axis. */
14
+ max: XYInput<number>;
15
+ /**
16
+ * Granularity of the value, per axis.
17
+ * @default 1
18
+ */
19
+ step?: XYInput<number>;
20
+ /**
21
+ * How the value is distributed across the travel, per axis.
22
+ * @default linearScale
23
+ */
24
+ scale?: XYInput<Scale>;
25
+ /**
26
+ * Grow the value the other way, per axis. `y` grows downwards unless
27
+ * reversed.
28
+ * @default false
29
+ */
30
+ reverse?: XYInput<boolean>;
31
+ /**
32
+ * How much one notch of the wheel moves the value, while the focus is
33
+ * inside. Scrolling sideways, or with shift held, moves x.
34
+ * @default ['raw', 1]
35
+ */
36
+ wheel?: ModifierValue<InputEventOption> | null;
37
+ /**
38
+ * How much a drag moves the value, per modifier key.
39
+ * @default { default: 1, shift: 0.1 }
40
+ */
41
+ dragSensitivity?: ModifierValue<number>;
42
+ /**
43
+ * How much one arrow key press moves the value. Left and right move x, up
44
+ * and down move y.
45
+ * @default { default: ['raw', 1], shift: ['raw', 0.1] }
46
+ */
47
+ keyboard?: ModifierValue<InputEventOption> | null;
48
+ /**
49
+ * The cursor to show while dragging.
50
+ * @default { cursor: 'pointer' }
51
+ */
52
+ externalStyles?: {
53
+ cursor?: string;
54
+ };
55
+ /** Make the pad unchangeable and remove it from the tab order. */
56
+ disabled?: boolean;
57
+ /** Make the value unchangeable. */
58
+ readonly?: boolean;
59
+ onChange?: (value: XY<number>) => void;
60
+ onDragStart?: (value: XY<number>) => void;
61
+ onDragEnd?: (value: XY<number>) => void;
62
+ /** The root element, bound with `bind:ref`. */
63
+ ref?: HTMLDivElement | null;
64
+ /** The pad renders exactly what you compose here. */
65
+ children: Snippet;
66
+ }
67
+ export interface XYPadThumbProps {
68
+ /** Sets `--color`, for the theme to colour the thumb with. */
69
+ color?: string;
70
+ /** The accessible name of each axis, as `[x, y]`. */
71
+ 'aria-label'?: XYInput<string | undefined | null>;
72
+ /** The ids of what labels each axis, as `[x, y]` or one for both. */
73
+ 'aria-labelledby'?: XYInput<string | undefined | null>;
74
+ /** The ids of what describes each axis, as `[x, y]` or one for both. */
75
+ 'aria-describedby'?: XYInput<string | undefined | null>;
76
+ /** What the value of each axis means, as `[x, y]` or one for both. */
77
+ 'aria-valuetext'?: XYInput<string | undefined | null>;
78
+ children?: Snippet;
79
+ }
80
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/XYPad/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,EAAE,EACF,OAAO,EACR,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAElD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAErC;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IACjB,sDAAsD;IACtD,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACpB,oDAAoD;IACpD,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IAC9C;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACvC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAA;IACjD;;;OAGG;IACH,cAAc,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;IACtC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;IACzC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;IACvC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC3B,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;IACjD,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;IACtD,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;IACvD,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;IACrD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { visuallyHidden } from './style.js'
3
+
4
+ import type { HTMLInputAttributes } from 'svelte/elements'
5
+
6
+ type Props = Omit<HTMLInputAttributes, 'type' | 'style'> & {
7
+ ref?: HTMLInputElement | null
8
+ }
9
+
10
+ let { ref = $bindable(null), ...rest }: Props = $props()
11
+ </script>
12
+
13
+ <!--
14
+ The control underneath a headless part: out of sight, but in the
15
+ accessibility tree and the tab order, carrying the ARIA and the keyboard.
16
+ -->
17
+ <input bind:this={ref} {...rest} type="range" style={visuallyHidden} />
@@ -0,0 +1,8 @@
1
+ import type { HTMLInputAttributes } from 'svelte/elements';
2
+ type Props = Omit<HTMLInputAttributes, 'type' | 'style'> & {
3
+ ref?: HTMLInputElement | null;
4
+ };
5
+ declare const VisuallyHiddenRangeInput: import("svelte").Component<Props, {}, "ref">;
6
+ type VisuallyHiddenRangeInput = ReturnType<typeof VisuallyHiddenRangeInput>;
7
+ export default VisuallyHiddenRangeInput;
8
+ //# sourceMappingURL=VisuallyHiddenRangeInput.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisuallyHiddenRangeInput.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/_util/VisuallyHiddenRangeInput.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGzD,KAAK,KAAK,GAAG,IAAI,CAAC,mBAAmB,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG;IACzD,GAAG,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAC9B,CAAC;AAeJ,QAAA,MAAM,wBAAwB,8CAAwC,CAAC;AACvE,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC5E,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type CheckStepsOptions } from '@tremolo-ui/dom';
2
+ /**
3
+ * Warn, in development only, when a key press or a wheel notch cannot produce
4
+ * a change the user can see. The probing is `checkSteps` in the core; `DEV`
5
+ * is a constant the bundler folds, so production builds drop the call.
6
+ *
7
+ * Takes a getter, so that the check runs again when the settings change.
8
+ */
9
+ export declare function useCheckSteps(options: () => CheckStepsOptions): void;
10
+ //# sourceMappingURL=check-steps.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-steps.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/_util/check-steps.svelte.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEpE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,iBAAiB,QAK7D"}
@@ -0,0 +1,17 @@
1
+ import { DEV } from 'esm-env';
2
+ import { checkSteps } from '@tremolo-ui/dom';
3
+ /**
4
+ * Warn, in development only, when a key press or a wheel notch cannot produce
5
+ * a change the user can see. The probing is `checkSteps` in the core; `DEV`
6
+ * is a constant the bundler folds, so production builds drop the call.
7
+ *
8
+ * Takes a getter, so that the check runs again when the settings change.
9
+ */
10
+ export function useCheckSteps(options) {
11
+ if (!DEV)
12
+ return;
13
+ $effect(() => {
14
+ for (const warning of checkSteps(options()))
15
+ console.warn(warning);
16
+ });
17
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Mark the children of this component as being inside `name`, for
3
+ * {@link checkPlacement}. Call it while the component initialises.
4
+ */
5
+ export declare function setPlacement(name: string): void;
6
+ /**
7
+ * Warn, in development only, when `child` is rendered outside `parent`.
8
+ *
9
+ * A part positioned against its parent still renders anywhere else, so
10
+ * nothing fails when it is misplaced — its position just comes out wrong.
11
+ * The names are the ones written in markup (`'Knob.Thumb'`), since they are
12
+ * what the warning shows. Call it while the component initialises.
13
+ */
14
+ export declare function checkPlacement(child: string, parent: string): void;
15
+ //# sourceMappingURL=placement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placement.d.ts","sourceRoot":"","sources":["../../../src/components/_util/placement.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,QAExC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAU3D"}
@@ -0,0 +1,30 @@
1
+ import { DEV } from 'esm-env';
2
+ import { getContext, setContext } from 'svelte';
3
+ const PLACEMENT = Symbol('tremolo-ui placement');
4
+ /**
5
+ * Mark the children of this component as being inside `name`, for
6
+ * {@link checkPlacement}. Call it while the component initialises.
7
+ */
8
+ export function setPlacement(name) {
9
+ setContext(PLACEMENT, name);
10
+ }
11
+ /**
12
+ * Warn, in development only, when `child` is rendered outside `parent`.
13
+ *
14
+ * A part positioned against its parent still renders anywhere else, so
15
+ * nothing fails when it is misplaced — its position just comes out wrong.
16
+ * The names are the ones written in markup (`'Knob.Thumb'`), since they are
17
+ * what the warning shows. Call it while the component initialises.
18
+ */
19
+ export function checkPlacement(child, parent) {
20
+ var _a;
21
+ if (!DEV)
22
+ return;
23
+ const found = (_a = getContext(PLACEMENT)) !== null && _a !== void 0 ? _a : null;
24
+ if (found === parent)
25
+ return;
26
+ console.warn(`[tremolo-ui] ${child} has to be rendered inside ${parent}` +
27
+ (found === null ? '.' : `, but it is inside ${found}.`) +
28
+ ' It renders either way, so nothing fails — its position just' +
29
+ ' comes out wrong.');
30
+ }
@@ -0,0 +1,5 @@
1
+ /** A style object as the text of a `style` attribute. */
2
+ export declare function styleText(style: Record<string, string>): string;
3
+ /** `visuallyHiddenStyle` from the core, as a `style` attribute. */
4
+ export declare const visuallyHidden: string;
5
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../src/components/_util/style.ts"],"names":[],"mappings":"AAEA,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAO/D;AAED,mEAAmE;AACnE,eAAO,MAAM,cAAc,QAAiD,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { visuallyHiddenStyle } from '@tremolo-ui/dom';
2
+ /** A style object as the text of a `style` attribute. */
3
+ export function styleText(style) {
4
+ return Object.entries(style)
5
+ .map(([key, value]) => `${key.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)}: ${value}`)
6
+ .join('; ');
7
+ }
8
+ /** `visuallyHiddenStyle` from the core, as a `style` attribute. */
9
+ export const visuallyHidden = /* @__PURE__ */ styleText(visuallyHiddenStyle);