@tremolo-ui/vue 0.7.0 → 0.9.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 (47) hide show
  1. package/dist/index.cjs +865 -611
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +934 -169
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +934 -169
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +339 -128
  8. package/dist/index.js.map +1 -1
  9. package/package.json +8 -8
  10. package/src/components/AnimationCanvas/AnimationCanvas.ts +27 -30
  11. package/src/components/AnimationCanvas/index.ts +1 -5
  12. package/src/components/DropZone/DropZone.ts +19 -9
  13. package/src/components/DropZone/index.ts +1 -1
  14. package/src/components/FileInput/FileInput.ts +28 -14
  15. package/src/components/FileInput/index.ts +1 -1
  16. package/src/components/Knob/Knob.ts +107 -57
  17. package/src/components/Knob/KnobThumb.ts +32 -22
  18. package/src/components/Knob/index.ts +2 -2
  19. package/src/components/NumberInput/NumberInput.ts +136 -53
  20. package/src/components/NumberInput/NumberInputField.ts +5 -2
  21. package/src/components/NumberInput/NumberInputStepper.ts +25 -4
  22. package/src/components/NumberInput/context.ts +12 -0
  23. package/src/components/NumberInput/index.ts +1 -1
  24. package/src/components/NumberInput/stepper-button.ts +8 -1
  25. package/src/components/Piano/Piano.ts +51 -43
  26. package/src/components/Piano/index.ts +6 -1
  27. package/src/components/PointsEditor/PointsEditor.ts +43 -35
  28. package/src/components/PointsEditor/PointsEditorContainer.ts +2 -6
  29. package/src/components/PointsEditor/PointsEditorPoint.ts +82 -42
  30. package/src/components/PointsEditor/context.ts +1 -1
  31. package/src/components/PointsEditor/index.ts +5 -2
  32. package/src/components/Slider/Slider.ts +92 -49
  33. package/src/components/Slider/SliderMarks.ts +28 -14
  34. package/src/components/Slider/SliderMarksOption.ts +54 -33
  35. package/src/components/Slider/SliderThumb.ts +26 -8
  36. package/src/components/Slider/SliderTrack.ts +31 -16
  37. package/src/components/Slider/context.ts +1 -1
  38. package/src/components/Slider/index.ts +8 -5
  39. package/src/components/XYPad/XYPad.ts +94 -56
  40. package/src/components/XYPad/XYPadThumb.ts +21 -14
  41. package/src/components/XYPad/index.ts +2 -2
  42. package/src/components/_util/change-gesture.ts +44 -0
  43. package/src/components/_util/useCheckSteps.ts +1 -1
  44. package/src/components/_util/visually-hidden-range-input.ts +1 -1
  45. package/src/composables/useInstance.ts +1 -1
  46. package/src/composables/useWheel.ts +5 -2
  47. package/src/index.ts +21 -4
@@ -1,10 +1,25 @@
1
- import { defineComponent, h, onBeforeUnmount, ref, watchEffect } from 'vue'
1
+ import {
2
+ type ComponentObjectPropsOptions,
3
+ defineComponent,
4
+ type ExtractPublicPropTypes,
5
+ h,
6
+ onBeforeUnmount,
7
+ ref,
8
+ watchEffect,
9
+ } from 'vue'
2
10
 
3
11
  import { checkPlacement } from '../_util/placement'
4
12
  import { visuallyHiddenRangeInput } from '../_util/visually-hidden-range-input'
5
13
 
6
14
  import { useSliderContext } from './context'
7
15
 
16
+ const sliderThumbProps = {
17
+ /** Sets `--color`, for the theme to colour the thumb with. */
18
+ color: String,
19
+ } satisfies ComponentObjectPropsOptions
20
+
21
+ export type SliderThumbProps = ExtractPublicPropTypes<typeof sliderThumbProps>
22
+
8
23
  /**
9
24
  * The thumb, placed at the value. The ARIA (`aria-label` and friends) lands
10
25
  * on the range input inside it, which is the control and takes the focus.
@@ -12,10 +27,7 @@ import { useSliderContext } from './context'
12
27
  export const SliderThumb = /* @__PURE__ */ defineComponent({
13
28
  name: 'SliderThumb',
14
29
  inheritAttrs: false,
15
- props: {
16
- /** Sets `--color`, for the theme to colour the thumb with. */
17
- color: String,
18
- },
30
+ props: sliderThumbProps,
19
31
  setup(props, { slots, attrs, expose }) {
20
32
  const slider = useSliderContext()
21
33
  checkPlacement('SliderThumb', 'SliderTrack')
@@ -56,8 +68,14 @@ export const SliderThumb = /* @__PURE__ */ defineComponent({
56
68
  },
57
69
  style,
58
70
  {
59
- top: slider.vertical ? `${slider.percent}%` : '50%',
60
- left: slider.vertical ? '50%' : `${slider.percent}%`,
71
+ top:
72
+ slider.orientation === 'vertical'
73
+ ? `${slider.percent}%`
74
+ : '50%',
75
+ left:
76
+ slider.orientation === 'vertical'
77
+ ? '50%'
78
+ : `${slider.percent}%`,
61
79
  },
62
80
  ],
63
81
  },
@@ -70,7 +88,7 @@ export const SliderThumb = /* @__PURE__ */ defineComponent({
70
88
  step: slider.step,
71
89
  disabled: slider.disabled,
72
90
  'aria-readonly': slider.readonly,
73
- 'aria-orientation': slider.vertical ? 'vertical' : 'horizontal',
91
+ 'aria-orientation': slider.orientation,
74
92
  'aria-label': ariaLabel,
75
93
  'aria-labelledby': ariaLabelledby,
76
94
  'aria-describedby': ariaDescribedby,
@@ -1,24 +1,36 @@
1
- import { defineComponent, h, onBeforeUnmount, ref, watchEffect } from 'vue'
1
+ import {
2
+ type ComponentObjectPropsOptions,
3
+ defineComponent,
4
+ type ExtractPublicPropTypes,
5
+ h,
6
+ onBeforeUnmount,
7
+ ref,
8
+ watchEffect,
9
+ } from 'vue'
2
10
 
3
- import { cssLength } from '@tremolo-ui/dom'
11
+ import { cssLength } from '@tremolo-ui/dom/internal'
4
12
 
5
13
  import { providePlacement } from '../_util/placement'
6
14
 
7
15
  import { useSliderContext } from './context'
8
16
 
17
+ const sliderTrackProps = {
18
+ /** How long the track is along the axis the slider runs. Sets `--length`. */
19
+ length: [Number, String],
20
+ /** How thick the track is across that axis. Sets `--thickness`. */
21
+ thickness: [Number, String],
22
+ /** Colour of the part from `min` to the value. Sets `--active-color`. */
23
+ activeColor: String,
24
+ /** Colour of the rest of the track. Sets `--inactive-color`. */
25
+ inactiveColor: String,
26
+ } satisfies ComponentObjectPropsOptions
27
+
28
+ export type SliderTrackProps = ExtractPublicPropTypes<typeof sliderTrackProps>
29
+
9
30
  /** The track the thumb runs along, and what the pointer is measured against. */
10
31
  export const SliderTrack = /* @__PURE__ */ defineComponent({
11
32
  name: 'SliderTrack',
12
- props: {
13
- /** How long the track is along the axis the slider runs. Sets `--length`. */
14
- length: [Number, String],
15
- /** How thick the track is across that axis. Sets `--thickness`. */
16
- thickness: [Number, String],
17
- /** Colour of the part from `min` to the value. Sets `--active`. */
18
- active: String,
19
- /** Colour of the rest of the track. Sets `--inactive`. */
20
- inactive: String,
21
- },
33
+ props: sliderTrackProps,
22
34
  setup(props, { slots }) {
23
35
  const slider = useSliderContext()
24
36
  providePlacement('SliderTrack')
@@ -33,11 +45,14 @@ export const SliderTrack = /* @__PURE__ */ defineComponent({
33
45
  {
34
46
  ref: el,
35
47
  'data-disabled': slider.disabled ? '' : undefined,
36
- 'data-orientation': slider.vertical ? 'vertical' : 'horizontal',
37
- 'data-flipped': slider.vertical !== slider.reverse ? '' : undefined,
48
+ 'data-orientation': slider.orientation,
49
+ 'data-flipped':
50
+ (slider.orientation === 'vertical') !== slider.reverse
51
+ ? ''
52
+ : undefined,
38
53
  style: {
39
- '--active': props.active,
40
- '--inactive': props.inactive,
54
+ '--active-color': props.activeColor,
55
+ '--inactive-color': props.inactiveColor,
41
56
  '--length': cssLength(props.length),
42
57
  '--thickness': cssLength(props.thickness),
43
58
  '--percent': `${slider.percent}%`,
@@ -11,7 +11,7 @@ export interface SliderContextValue {
11
11
  readonly max: number
12
12
  readonly step: number
13
13
  readonly scale: Scale
14
- readonly vertical: boolean
14
+ readonly orientation: 'horizontal' | 'vertical'
15
15
  readonly reverse: boolean
16
16
  readonly disabled: boolean
17
17
  readonly readonly: boolean
@@ -1,6 +1,9 @@
1
1
  export { useSliderContext, type SliderContextValue } from './context'
2
- export { Slider } from './Slider'
3
- export { SliderMarks } from './SliderMarks'
4
- export { SliderMarksOption } from './SliderMarksOption'
5
- export { SliderThumb } from './SliderThumb'
6
- export { SliderTrack } from './SliderTrack'
2
+ export { Slider, type SliderProps } from './Slider'
3
+ export { SliderMarks, type SliderMarksProps } from './SliderMarks'
4
+ export {
5
+ SliderMarksOption,
6
+ type SliderMarksOptionProps,
7
+ } from './SliderMarksOption'
8
+ export { SliderThumb, type SliderThumbProps } from './SliderThumb'
9
+ export { SliderTrack, type SliderTrackProps } from './SliderTrack'
@@ -1,78 +1,108 @@
1
- import { computed, defineComponent, h, provide, ref, type PropType } from 'vue'
1
+ import {
2
+ type ComponentObjectPropsOptions,
3
+ computed,
4
+ defineComponent,
5
+ type ExtractPublicPropTypes,
6
+ h,
7
+ type PropType,
8
+ provide,
9
+ ref,
10
+ } from 'vue'
2
11
 
3
12
  import {
4
- applyDelta,
5
- arrowKeyMove,
6
13
  elementMapping,
7
- selectModifier,
8
- toXY,
9
14
  valuePercent,
10
- wheelMove,
11
- type AxisMove,
12
15
  type AxisOptions,
16
+ type ChangeSource,
13
17
  type InputEventOption,
14
18
  type ModifierState,
15
19
  type ModifierValue,
16
20
  type XY,
17
21
  type XYInput,
18
22
  } from '@tremolo-ui/dom'
23
+ import {
24
+ applyDelta,
25
+ arrowKeyMove,
26
+ selectModifier,
27
+ toXY,
28
+ wheelMove,
29
+ type AxisMove,
30
+ } from '@tremolo-ui/dom/internal'
19
31
  import { linearScale, type Scale } from '@tremolo-ui/functions'
20
32
 
21
33
  import { useDragValue } from '../../composables/useDragValue'
22
34
  import { useWheel } from '../../composables/useWheel'
35
+ import { useChangeGesture } from '../_util/change-gesture'
23
36
  import { dragSensitivityProp, keyboardProp, wheelProp } from '../_util/props'
24
37
  import { useCheckSteps } from '../_util/useCheckSteps'
25
38
 
26
39
  import { XYPadKey } from './context'
27
40
 
41
+ const xyPadProps = {
42
+ /** The current value as `[x, y]`. Bind it with `v-model`. */
43
+ modelValue: {
44
+ type: Array as unknown as PropType<XY<number>>,
45
+ required: true,
46
+ },
47
+ /** The value at the start of the travel, per axis. */
48
+ min: {
49
+ type: [Number, Array] as PropType<XYInput<number>>,
50
+ required: true,
51
+ },
52
+ /** The value at the end of the travel, per axis. */
53
+ max: {
54
+ type: [Number, Array] as PropType<XYInput<number>>,
55
+ required: true,
56
+ },
57
+ /** Granularity of the value, per axis. @default 1 */
58
+ step: { type: [Number, Array] as PropType<XYInput<number>>, default: 1 },
59
+ /** How the value is distributed, per axis. @default linearScale */
60
+ scale: {
61
+ type: [Object, Array] as PropType<XYInput<Scale>>,
62
+ default: () => linearScale,
63
+ },
64
+ /** Grow the value the other way, per axis. `y` grows downwards unless reversed. */
65
+ reverse: {
66
+ type: [Boolean, Array] as PropType<XYInput<boolean>>,
67
+ default: false,
68
+ },
69
+ /** The cursor to show while dragging. @default 'pointer' */
70
+ dragCursor: { type: String, default: 'pointer' },
71
+ wheel: wheelProp,
72
+ keyboard: keyboardProp,
73
+ dragSensitivity: dragSensitivityProp,
74
+ /** Make the pad unchangeable and remove it from the tab order. */
75
+ disabled: Boolean,
76
+ /** Make the value unchangeable. */
77
+ readonly: Boolean,
78
+ /**
79
+ * How long after the last wheel notch or arrow key a change counts as over,
80
+ * in milliseconds, for `change-end`.
81
+ * @default 500
82
+ */
83
+ changeEndDelay: { type: Number, default: 500 },
84
+ } satisfies ComponentObjectPropsOptions
85
+
86
+ export type XYPadProps = ExtractPublicPropTypes<typeof xyPadProps>
87
+
28
88
  /**
29
89
  * Two-dimensional slider. The per-axis settings are `[x, y]` tuples, and a
30
90
  * plain value applies to both axes. Bind the value with `v-model`.
31
91
  */
32
92
  export const XYPad = /* @__PURE__ */ defineComponent({
33
93
  name: 'XYPad',
34
- props: {
35
- /** The current value as `[x, y]`. Bind it with `v-model`. */
36
- modelValue: {
37
- type: Array as unknown as PropType<XY<number>>,
38
- required: true,
39
- },
40
- /** The value at the start of the travel, per axis. */
41
- min: {
42
- type: [Number, Array] as PropType<XYInput<number>>,
43
- required: true,
44
- },
45
- /** The value at the end of the travel, per axis. */
46
- max: {
47
- type: [Number, Array] as PropType<XYInput<number>>,
48
- required: true,
49
- },
50
- /** Granularity of the value, per axis. @default 1 */
51
- step: { type: [Number, Array] as PropType<XYInput<number>>, default: 1 },
52
- /** How the value is distributed, per axis. @default linearScale */
53
- scale: {
54
- type: [Object, Array] as PropType<XYInput<Scale>>,
55
- default: () => linearScale,
56
- },
57
- /** Grow the value the other way, per axis. `y` grows downwards unless reversed. */
58
- reverse: {
59
- type: [Boolean, Array] as PropType<XYInput<boolean>>,
60
- default: false,
61
- },
62
- /** The cursor to show while dragging. @default { cursor: 'pointer' } */
63
- externalStyles: Object as PropType<{ cursor?: string }>,
64
- wheel: wheelProp,
65
- keyboard: keyboardProp,
66
- dragSensitivity: dragSensitivityProp,
67
- /** Make the pad unchangeable and remove it from the tab order. */
68
- disabled: Boolean,
69
- /** Make the value unchangeable. */
70
- readonly: Boolean,
71
- },
94
+ props: xyPadProps,
72
95
  emits: {
73
96
  'update:modelValue': (value: XY<number>) => Array.isArray(value),
74
- dragStart: (value: XY<number>) => Array.isArray(value),
75
- dragEnd: (value: XY<number>) => Array.isArray(value),
97
+ /**
98
+ * A change of the value started, with the value before it and what it is
99
+ * made with.
100
+ */
101
+ changeStart: (value: XY<number>, _source: ChangeSource) =>
102
+ Array.isArray(value),
103
+ /** The change ended, with the value it ended on. */
104
+ changeEnd: (value: XY<number>, _source: ChangeSource) =>
105
+ Array.isArray(value),
76
106
  },
77
107
  setup(props, { slots, emit, expose }) {
78
108
  const root = ref<HTMLDivElement | null>(null)
@@ -121,7 +151,17 @@ export const XYPad = /* @__PURE__ */ defineComponent({
121
151
  }))
122
152
  }
123
153
 
124
- const change = (next: XY<number>) => emit('update:modelValue', next)
154
+ const gesture = useChangeGesture({
155
+ value: () => props.modelValue,
156
+ inactive: () => inactive.value,
157
+ endDelay: () => props.changeEndDelay,
158
+ onStart: (value, source) => emit('changeStart', value, source),
159
+ onEnd: (value, source) => emit('changeEnd', value, source),
160
+ })
161
+ const change = (next: XY<number>) => {
162
+ gesture.changed(next)
163
+ emit('update:modelValue', next)
164
+ }
125
165
 
126
166
  /** Move one axis by one press of `option`, in screen coordinates. */
127
167
  function nudge(
@@ -184,21 +224,17 @@ export const XYPad = /* @__PURE__ */ defineComponent({
184
224
  selectModifier(props.dragSensitivity, state.event).value,
185
225
  }),
186
226
  updateOnPointerDown: true,
187
- cursor: inactive.value
188
- ? undefined
189
- : (props.externalStyles?.cursor ?? 'pointer'),
227
+ cursor: inactive.value ? undefined : props.dragCursor,
190
228
  shouldStart: () => !inactive.value,
191
229
  onChange: (v) => {
192
230
  if (!inactive.value) change(v)
193
231
  },
194
- onDragStart: (v) => {
232
+ onDragStart: () => {
195
233
  if (inactive.value) return
234
+ gesture.hold('pointer')
196
235
  thumb?.focus()
197
- emit('dragStart', v)
198
- },
199
- onDragEnd: (v) => {
200
- if (!inactive.value) emit('dragEnd', v)
201
236
  },
237
+ onDragEnd: () => gesture.end(),
202
238
  }))
203
239
 
204
240
  useWheel(
@@ -208,6 +244,7 @@ export const XYPad = /* @__PURE__ */ defineComponent({
208
244
  const move = wheelMove(event)
209
245
  if (!move) return
210
246
  event.preventDefault()
247
+ gesture.pulse('wheel')
211
248
  nudge(move, props.wheel, event)
212
249
  },
213
250
  { requireFocus: true },
@@ -236,6 +273,7 @@ export const XYPad = /* @__PURE__ */ defineComponent({
236
273
  if (!move) return
237
274
  event.preventDefault()
238
275
  if (props.keyboard && !inactive.value) {
276
+ gesture.pulse('keyboard')
239
277
  nudge(move, props.keyboard, event)
240
278
  }
241
279
  },
@@ -1,13 +1,16 @@
1
1
  import {
2
+ type ComponentObjectPropsOptions,
2
3
  defineComponent,
4
+ type ExtractPublicPropTypes,
3
5
  h,
4
6
  onBeforeUnmount,
7
+ type PropType,
5
8
  ref,
6
9
  watchEffect,
7
- type PropType,
8
10
  } from 'vue'
9
11
 
10
- import { toXY, type XYInput } from '@tremolo-ui/dom'
12
+ import { type XYInput } from '@tremolo-ui/dom'
13
+ import { toXY } from '@tremolo-ui/dom/internal'
11
14
 
12
15
  import { checkPlacement } from '../_util/placement'
13
16
  import { visuallyHiddenRangeInput } from '../_util/visually-hidden-range-input'
@@ -16,22 +19,26 @@ import { useXYPadContext } from './context'
16
19
 
17
20
  type PerAxis = XYInput<string | undefined>
18
21
 
22
+ const xyPadThumbProps = {
23
+ /** Sets `--color`, for the theme to colour the thumb with. */
24
+ color: String,
25
+ /** The accessible name of each axis, as `[x, y]`. */
26
+ ariaLabel: [String, Array] as PropType<PerAxis>,
27
+ /** The ids of what labels each axis, as `[x, y]` or one for both. */
28
+ ariaLabelledby: [String, Array] as PropType<PerAxis>,
29
+ /** The ids of what describes each axis, as `[x, y]` or one for both. */
30
+ ariaDescribedby: [String, Array] as PropType<PerAxis>,
31
+ /** What the value of each axis means, as `[x, y]` or one for both. */
32
+ ariaValuetext: [String, Array] as PropType<PerAxis>,
33
+ } satisfies ComponentObjectPropsOptions
34
+
35
+ export type XYPadThumbProps = ExtractPublicPropTypes<typeof xyPadThumbProps>
36
+
19
37
  /** The thumb, placed at the value, with one range input per axis inside. */
20
38
  export const XYPadThumb = /* @__PURE__ */ defineComponent({
21
39
  name: 'XYPadThumb',
22
40
  inheritAttrs: false,
23
- props: {
24
- /** Sets `--color`, for the theme to colour the thumb with. */
25
- color: String,
26
- /** The accessible name of each axis, as `[x, y]`. */
27
- ariaLabel: [String, Array] as PropType<PerAxis>,
28
- /** The ids of what labels each axis, as `[x, y]` or one for both. */
29
- ariaLabelledby: [String, Array] as PropType<PerAxis>,
30
- /** The ids of what describes each axis, as `[x, y]` or one for both. */
31
- ariaDescribedby: [String, Array] as PropType<PerAxis>,
32
- /** What the value of each axis means, as `[x, y]` or one for both. */
33
- ariaValuetext: [String, Array] as PropType<PerAxis>,
34
- },
41
+ props: xyPadThumbProps,
35
42
  setup(props, { slots, attrs, expose }) {
36
43
  const pad = useXYPadContext()
37
44
  checkPlacement('XYPadThumb', 'XYPadArea')
@@ -1,4 +1,4 @@
1
1
  export { useXYPadContext, type XYPadContextValue } from './context'
2
- export { XYPad } from './XYPad'
2
+ export { XYPad, type XYPadProps } from './XYPad'
3
3
  export { XYPadArea } from './XYPadArea'
4
- export { XYPadThumb } from './XYPadThumb'
4
+ export { XYPadThumb, type XYPadThumbProps } from './XYPadThumb'
@@ -0,0 +1,44 @@
1
+ import { onScopeDispose, watch, watchEffect } from 'vue'
2
+
3
+ import { createChangeGesture, type ChangeSource } from '@tremolo-ui/dom'
4
+
5
+ export interface ChangeGestureOptions<V> {
6
+ /** The value now, read when a gesture starts. */
7
+ value: () => V
8
+ inactive: () => boolean
9
+ endDelay: () => number | undefined
10
+ onStart: (value: V, source: ChangeSource) => void
11
+ onEnd: (value: V, source: ChangeSource) => void
12
+ }
13
+
14
+ /**
15
+ * The core's change gesture, reporting the control's value: the start gets
16
+ * the value before the change, the end the last one the control emitted.
17
+ * `modelValue` lags behind until the parent renders, and a drag ends in the
18
+ * same event as its last change, so the component reports each value it
19
+ * emits through `changed`.
20
+ */
21
+ export function useChangeGesture<V>(options: ChangeGestureOptions<V>) {
22
+ let last = options.value()
23
+ const gesture = createChangeGesture({
24
+ onStart: (source) => {
25
+ last = options.value()
26
+ options.onStart(last, source)
27
+ },
28
+ onEnd: (source) => options.onEnd(last, source),
29
+ })
30
+
31
+ watchEffect(() => gesture.update({ endDelay: options.endDelay() }))
32
+ // A control that turns inactive mid-gesture, or goes away, should not leave
33
+ // a host thinking it is still being touched.
34
+ watch(options.inactive, (inactive) => {
35
+ if (inactive) gesture.end()
36
+ })
37
+ onScopeDispose(() => gesture.end())
38
+
39
+ return Object.assign(gesture, {
40
+ changed: (value: V) => {
41
+ last = value
42
+ },
43
+ })
44
+ }
@@ -1,6 +1,6 @@
1
1
  import { watchEffect } from 'vue'
2
2
 
3
- import { checkSteps, type CheckStepsOptions } from '@tremolo-ui/dom'
3
+ import { checkSteps, type CheckStepsOptions } from '@tremolo-ui/dom/internal'
4
4
 
5
5
  /**
6
6
  * Warn, in development only, when a key press or a wheel notch cannot produce
@@ -1,6 +1,6 @@
1
1
  import { h, type VNodeProps } from 'vue'
2
2
 
3
- import { visuallyHiddenStyle } from '@tremolo-ui/dom'
3
+ import { visuallyHiddenStyle } from '@tremolo-ui/dom/internal'
4
4
 
5
5
  /**
6
6
  * The control underneath a headless part: out of sight, but in the
@@ -1,6 +1,6 @@
1
1
  import { toValue, watch, type MaybeRefOrGetter } from 'vue'
2
2
 
3
- import { replaceOptions } from '@tremolo-ui/dom'
3
+ import { replaceOptions } from '@tremolo-ui/dom/internal'
4
4
 
5
5
  /**
6
6
  * Create an instance for the element `target` holds, and destroy it when the
@@ -12,12 +12,15 @@ import { useInstance } from './useInstance'
12
12
  export function useWheel(
13
13
  target: MaybeRefOrGetter<Element | null | undefined>,
14
14
  onWheel: (event: WheelEvent) => void,
15
- options: MaybeRefOrGetter<WheelOptions> = {},
15
+ // `onWheel` is left out: the handler is the second argument, and an option
16
+ // of the same name would replace it on the first update.
17
+ options: MaybeRefOrGetter<Omit<WheelOptions, 'onWheel'>> = {},
16
18
  ) {
17
19
  useInstance(
18
20
  target,
19
21
  options,
20
- (element, opts) => createWheel(element, (event) => onWheel(event), opts),
22
+ (element, opts) =>
23
+ createWheel(element, { ...opts, onWheel: (event) => onWheel(event) }),
21
24
  (instance, next) => instance.update(next),
22
25
  )
23
26
  }
package/src/index.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  // components
2
2
  export {
3
3
  AnimationCanvas,
4
- type DrawFunction,
5
- type InitFunction,
4
+ type AnimationCanvasProps,
6
5
  } from './components/AnimationCanvas'
7
- export { DropZone } from './components/DropZone'
6
+ export { DropZone, type DropZoneProps } from './components/DropZone'
8
7
  export {
9
8
  FileInput,
10
9
  FileInputTrigger,
11
10
  useFileInputContext,
12
11
  type FileInputContextValue,
12
+ type FileInputProps,
13
13
  } from './components/FileInput'
14
14
  export {
15
15
  Knob,
@@ -19,6 +19,8 @@ export {
19
19
  KnobThumb,
20
20
  useKnobContext,
21
21
  type KnobContextValue,
22
+ type KnobProps,
23
+ type KnobThumbProps,
22
24
  } from './components/Knob'
23
25
  export {
24
26
  NumberInput,
@@ -28,8 +30,14 @@ export {
28
30
  NumberInputStepper,
29
31
  useNumberInputContext,
30
32
  type NumberInputContextValue,
33
+ type NumberInputProps,
31
34
  } from './components/NumberInput'
32
- export { Piano, type KeyAttributes, type KeyState } from './components/Piano'
35
+ export {
36
+ Piano,
37
+ type KeyAttributes,
38
+ type KeyState,
39
+ type PianoProps,
40
+ } from './components/Piano'
33
41
  export {
34
42
  PointsEditor,
35
43
  PointsEditorBackground,
@@ -38,6 +46,8 @@ export {
38
46
  PointsEditorSelectionBox,
39
47
  usePointsEditorContext,
40
48
  type PointsEditorContextValue,
49
+ type PointsEditorPointProps,
50
+ type PointsEditorProps,
41
51
  } from './components/PointsEditor'
42
52
  export {
43
53
  Slider,
@@ -47,6 +57,11 @@ export {
47
57
  SliderTrack,
48
58
  useSliderContext,
49
59
  type SliderContextValue,
60
+ type SliderMarksOptionProps,
61
+ type SliderMarksProps,
62
+ type SliderProps,
63
+ type SliderThumbProps,
64
+ type SliderTrackProps,
50
65
  } from './components/Slider'
51
66
  export {
52
67
  XYPad,
@@ -54,6 +69,8 @@ export {
54
69
  XYPadThumb,
55
70
  useXYPadContext,
56
71
  type XYPadContextValue,
72
+ type XYPadProps,
73
+ type XYPadThumbProps,
57
74
  } from './components/XYPad'
58
75
 
59
76
  // composables