@tremolo-ui/react 0.7.0 → 0.8.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 +346 -1015
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +76 -221
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +76 -221
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +333 -978
  8. package/dist/index.js.map +1 -1
  9. package/package.json +3 -3
  10. package/src/components/DropZone/index.tsx +2 -1
  11. package/src/components/FileInput/index.tsx +8 -13
  12. package/src/components/Knob/ActiveLine.tsx +5 -3
  13. package/src/components/Knob/InactiveLine.tsx +6 -4
  14. package/src/components/Knob/SVGRoot.tsx +3 -3
  15. package/src/components/Knob/Thumb.tsx +3 -2
  16. package/src/components/Knob/context.tsx +3 -74
  17. package/src/components/Knob/index.tsx +19 -16
  18. package/src/components/NumberInput/InputField.tsx +12 -27
  19. package/src/components/NumberInput/Stepper.tsx +49 -97
  20. package/src/components/NumberInput/StepperButton.tsx +3 -4
  21. package/src/components/NumberInput/context.tsx +2 -1
  22. package/src/components/NumberInput/index.tsx +40 -71
  23. package/src/components/Piano/index.tsx +35 -142
  24. package/src/components/PointsEditor/Container.tsx +15 -26
  25. package/src/components/PointsEditor/Point.tsx +38 -85
  26. package/src/components/PointsEditor/context.tsx +5 -56
  27. package/src/components/PointsEditor/index.tsx +29 -311
  28. package/src/components/Slider/Marks.tsx +3 -5
  29. package/src/components/Slider/MarksOption.tsx +7 -18
  30. package/src/components/Slider/Track.tsx +2 -1
  31. package/src/components/Slider/index.tsx +29 -28
  32. package/src/components/XYPad/Area.tsx +27 -49
  33. package/src/components/XYPad/Thumb.tsx +3 -1
  34. package/src/components/XYPad/context.tsx +1 -3
  35. package/src/components/XYPad/index.tsx +33 -46
  36. package/src/components/_util/VisuallyHiddenRangeInput.tsx +1 -1
  37. package/src/hooks/_internal/useCheckSteps.ts +9 -146
  38. package/src/hooks/useLongPress.ts +35 -51
  39. package/src/hooks/useMIDIAccess.ts +0 -8
  40. package/src/hooks/useMIDIInput.ts +0 -3
  41. package/src/index.ts +2 -27
  42. package/src/components/Piano/keyboard-shortcuts.ts +0 -61
  43. package/src/components/Slider/type.ts +0 -46
  44. package/src/components/_util/css-length.ts +0 -13
  45. package/src/components/_util/decimal-digits.ts +0 -23
  46. package/src/components/_util/visually-hidden.ts +0 -25
  47. package/src/input-event.ts +0 -32
@@ -1,56 +1,34 @@
1
1
  import { ComponentPropsWithoutRef, CSSProperties, forwardRef } from 'react'
2
2
 
3
3
  import { useComposedRefs } from '../../compose-refs'
4
- import { cssLength } from '../_util/css-length'
5
4
  import { Placement } from '../_util/Placement'
6
5
 
7
6
  import { useXYPadContext } from './context'
8
7
 
9
- import type { CSSVariables } from '../../css-variables'
10
-
11
- export interface XYPadAreaProps {
12
- /** Sets `--width`; the size the theme gives it stands when omitted. */
13
- width?: number | string
14
- /** Sets `--height`; the size the theme gives it stands when omitted. */
15
- height?: number | string
16
- /** Sets `--color`, for the theme to colour the area with. */
17
- color?: string
18
-
19
- style?: CSSProperties & CSSVariables<'width' | 'height' | 'color'>
20
- }
21
-
22
- type Props = XYPadAreaProps &
23
- Omit<ComponentPropsWithoutRef<'div'>, keyof XYPadAreaProps>
24
-
25
- export const Area = /* @__PURE__ */ forwardRef<HTMLDivElement, Props>(
26
- function Area(
27
- { width, height, color, children, className, style, ...props },
28
- forwardedRef,
29
- ) {
30
- const { areaRef } = useXYPadContext()
31
-
32
- // The area is what the pointer position is normalized against, so the
33
- // context ref is composed with any ref the caller passed.
34
- const composedRef = useComposedRefs<HTMLDivElement>(forwardedRef, areaRef)
35
-
36
- return (
37
- <div
38
- ref={composedRef}
39
- className={className}
40
- style={
41
- {
42
- '--color': color,
43
- '--width': cssLength(width),
44
- '--height': cssLength(height),
45
- // The thumb inside is placed against this box.
46
- position: 'relative',
47
- ...style,
48
- } as CSSProperties
49
- }
50
- {...props}
51
- >
52
- <Placement name="XYPad.Area">{children}</Placement>
53
- </div>
54
- )
55
- },
56
- )
8
+ export const Area = /* @__PURE__ */ forwardRef<
9
+ HTMLDivElement,
10
+ ComponentPropsWithoutRef<'div'>
11
+ >(function Area({ children, className, style, ...props }, forwardedRef) {
12
+ const { areaRef } = useXYPadContext()
13
+
14
+ // The area is what the pointer position is normalized against, so the
15
+ // context ref is composed with any ref the caller passed.
16
+ const composedRef = useComposedRefs<HTMLDivElement>(forwardedRef, areaRef)
17
+
18
+ return (
19
+ <div
20
+ ref={composedRef}
21
+ className={className}
22
+ style={
23
+ {
24
+ // The thumb inside is placed against this box.
25
+ position: 'relative',
26
+ ...style,
27
+ } as CSSProperties
28
+ }
29
+ {...props}
30
+ >
31
+ <Placement name="XYPad.Area">{children}</Placement>
32
+ </div>
33
+ )
34
+ })
@@ -7,10 +7,12 @@ import {
7
7
  CSSProperties,
8
8
  } from 'react'
9
9
 
10
+ import { toXY, type XYInput } from '@tremolo-ui/dom'
11
+
10
12
  import { useCheckPlacement } from '../_util/Placement'
11
13
  import { VisuallyHiddenRangeInput } from '../_util/VisuallyHiddenRangeInput'
12
14
 
13
- import { toXY, useXYPadContext, type XYInput } from './context'
15
+ import { useXYPadContext } from './context'
14
16
 
15
17
  import type { CSSVariables } from '../../css-variables'
16
18
 
@@ -1,12 +1,10 @@
1
1
  import { createContext, RefObject, useContext } from 'react'
2
2
 
3
- import { toXY, type XY, type XYInput } from '@tremolo-ui/dom'
3
+ import { type XY } from '@tremolo-ui/dom'
4
4
  import type { Scale } from '@tremolo-ui/functions'
5
5
 
6
6
  import type { XYPadThumbMethods } from './Thumb'
7
7
 
8
- export { toXY, type XY, type XYInput }
9
-
10
8
  export type XYPadContextValue = {
11
9
  value: XY<number>
12
10
  min: XY<number>
@@ -12,26 +12,30 @@ import {
12
12
 
13
13
  import {
14
14
  applyDelta,
15
+ arrowKeyMove,
15
16
  type AxisOptions,
17
+ DEFAULT_DRAG_SENSITIVITY,
18
+ DEFAULT_KEYBOARD_OPTIONS,
19
+ DEFAULT_WHEEL_OPTIONS,
16
20
  InputEventOption,
17
21
  ModifierState,
18
22
  type ModifierValue,
19
23
  selectModifier,
24
+ toXY,
25
+ valuePercent,
26
+ wheelMove,
27
+ type XY,
28
+ type XYInput,
20
29
  } from '@tremolo-ui/dom'
21
- import { linearScale, type Scale, toFixed } from '@tremolo-ui/functions'
30
+ import { linearScale, type Scale } from '@tremolo-ui/functions'
22
31
 
23
32
  import { useComposedRefs } from '../../compose-refs'
24
33
  import { useCheckSteps } from '../../hooks/_internal/useCheckSteps'
25
34
  import { useDragValue } from '../../hooks/useDragValue'
26
35
  import { useWheel } from '../../hooks/useWheel'
27
- import {
28
- DEFAULT_DRAG_SENSITIVITY,
29
- DEFAULT_KEYBOARD_OPTIONS,
30
- DEFAULT_WHEEL_OPTIONS,
31
- } from '../../input-event'
32
36
 
33
37
  import { Area } from './Area'
34
- import { toXY, XY, XYInput, XYPadProvider } from './context'
38
+ import { XYPadProvider } from './context'
35
39
  import { Thumb, XYPadThumbMethods } from './Thumb'
36
40
 
37
41
  const defaultExternalStyles: XYPadProps['externalStyles'] = {
@@ -227,14 +231,17 @@ export const Root = /* @__PURE__ */ forwardRef<XYPadMethods, Props>(
227
231
  const scale = useMemo(() => toXY(_scale), [_scale])
228
232
  const reverse = useMemo(() => toXY(_reverse), [_reverse])
229
233
 
230
- const percent = useMemo((): XY<number> => {
231
- const normalized = [0, 1].map((i) =>
232
- scale[i].normalize(value[i], min[i], max[i]),
233
- )
234
- return [0, 1].map((i) =>
235
- toFixed((reverse[i] ? 1 - normalized[i] : normalized[i]) * 100),
236
- ) as XY<number>
237
- }, [value, min, max, scale, reverse])
234
+ const percent = useMemo(
235
+ (): XY<number> =>
236
+ [0, 1].map((i) =>
237
+ valuePercent(
238
+ value[i],
239
+ { min: min[i], max: max[i], scale: scale[i] },
240
+ reverse[i],
241
+ ),
242
+ ) as XY<number>,
243
+ [value, min, max, scale, reverse],
244
+ )
238
245
 
239
246
  // --- internal functions ---
240
247
  // `AxisOptions` extends `ValueRange`, so the same pair also describes the
@@ -291,21 +298,15 @@ export const Root = /* @__PURE__ */ forwardRef<XYPadMethods, Props>(
291
298
 
292
299
  const handleKeyDown = useCallback(
293
300
  (event: React.KeyboardEvent<HTMLDivElement>) => {
294
- const key = event.key
295
- if (!['ArrowRight', 'ArrowLeft', 'ArrowUp', 'ArrowDown'].includes(key))
296
- return
297
-
298
301
  // The key picks the axis, whichever of the two inputs holds the
299
- // focus: the pad is one control to the person moving it, and the focus
300
- // lands on the x input, so reading the axis off the input would leave
301
- // the y axis with no keys at all.
302
- const i: 0 | 1 = key === 'ArrowRight' || key === 'ArrowLeft' ? 0 : 1
302
+ // focus: the focus lands on the x input, so reading the axis off the
303
+ // input would leave the y axis with no keys at all.
304
+ const move = arrowKeyMove(event.key)
305
+ if (!move) return
303
306
  event.preventDefault()
304
307
  if (!onChange || inactive || !keyboard) return
305
- let direction = 1
306
- if (key === 'ArrowLeft' || key === 'ArrowUp') direction *= -1
307
- if (reverse[i]) direction *= -1
308
- onChange(nudge(i, direction, keyboard, event))
308
+ const { axis: i, direction } = move
309
+ onChange(nudge(i, reverse[i] ? -direction : direction, keyboard, event))
309
310
  },
310
311
  [onChange, inactive, keyboard, reverse, nudge],
311
312
  )
@@ -337,19 +338,11 @@ export const Root = /* @__PURE__ */ forwardRef<XYPadMethods, Props>(
337
338
 
338
339
  const wheelRefCallback = useWheel<HTMLDivElement>((event) => {
339
340
  if (!onChange || inactive || !wheel) return
340
- // Browsers turn shift+wheel into horizontal scrolling: `deltaY` comes
341
- // out empty and `deltaX` carries the movement. Reading whichever axis
342
- // moved keeps shift working as the x-axis modifier — and picks up a
343
- // trackpad's own horizontal gesture, which never had a modifier.
344
- const horizontal = event.deltaX !== 0
345
- const delta = horizontal ? event.deltaX : event.deltaY
346
- if (delta === 0) return
347
- const i: 0 | 1 = horizontal || event.shiftKey ? 0 : 1
341
+ const move = wheelMove(event)
342
+ if (!move) return
348
343
  event.preventDefault()
349
- let direction = 1
350
- if (delta < 0) direction *= -1
351
- if (reverse[i]) direction *= -1
352
- onChange(nudge(i, direction, wheel, event))
344
+ const { axis: i, direction } = move
345
+ onChange(nudge(i, reverse[i] ? -direction : direction, wheel, event))
353
346
  }, WHEEL_OPTIONS)
354
347
 
355
348
  // Composed once, so React attaches the refs a single time instead of
@@ -444,10 +437,4 @@ export const XYPad = {
444
437
  }
445
438
 
446
439
  export { type XYPadThumbProps, type XYPadThumbMethods } from './Thumb'
447
- export { type XYPadAreaProps } from './Area'
448
- export {
449
- useXYPadContext,
450
- type XYPadContextValue,
451
- type XY,
452
- type XYInput,
453
- } from './context'
440
+ export { useXYPadContext, type XYPadContextValue } from './context'
@@ -1,6 +1,6 @@
1
1
  import { ComponentPropsWithoutRef, forwardRef } from 'react'
2
2
 
3
- import { visuallyHiddenStyle } from './visually-hidden'
3
+ import { visuallyHiddenStyle } from '@tremolo-ui/dom'
4
4
 
5
5
  type Props = Omit<ComponentPropsWithoutRef<'input'>, 'type' | 'style'>
6
6
 
@@ -1,162 +1,25 @@
1
1
  import { useEffect } from 'react'
2
2
 
3
- import {
4
- applyDelta,
5
- type InputEventOption,
6
- type ModifierState,
7
- type ModifierValue,
8
- } from '@tremolo-ui/dom'
9
- import { linearScale, type ValueRange } from '@tremolo-ui/functions'
10
-
11
- /** Positions probed across the travel. The ends are left out so that the
12
- * clamp at `min` and `max` cannot be mistaken for a press that does nothing. */
13
- const PROBES = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
14
-
15
- const NONE: ModifierState = {
16
- shiftKey: false,
17
- altKey: false,
18
- ctrlKey: false,
19
- metaKey: false,
20
- }
21
-
22
- const MODIFIER_STATE: Record<string, ModifierState> = {
23
- shift: { ...NONE, shiftKey: true },
24
- alt: { ...NONE, altKey: true },
25
- ctrl: { ...NONE, ctrlKey: true },
26
- meta: { ...NONE, metaKey: true },
27
- }
28
-
29
- /** Each entry of a modifier-aware input option, as a name and held keys. */
30
- function entries(
31
- options: ModifierValue<InputEventOption>,
32
- ): { name: string; modifiers: ModifierState }[] {
33
- if (Array.isArray(options)) return [{ name: '', modifiers: NONE }]
34
- return Object.keys(options).map((key) => ({
35
- name: key === 'default' ? '' : key,
36
- modifiers: MODIFIER_STATE[key] ?? NONE,
37
- }))
38
- }
39
-
40
- interface Outcome {
41
- /** The press changed the value at least once across the travel. */
42
- moved: boolean
43
- /** The change reached the displayed text at least once. */
44
- visible: boolean
45
- }
46
-
47
- /**
48
- * Press every entry of `options` at nine points along the travel and report
49
- * whether anything came of it.
50
- *
51
- * Run against `applyDelta` itself rather than against a reading of `step`:
52
- * the whole point is that the amount, the step and the scale interact, and
53
- * the pipeline is the only thing that knows how.
54
- */
55
- function probe(
56
- options: ModifierValue<InputEventOption>,
57
- range: ValueRange,
58
- format?: (value: number) => string,
59
- ): Outcome {
60
- const { min, max, scale = linearScale } = range
61
- const outcome: Outcome = { moved: false, visible: false }
62
-
63
- for (const { modifiers } of entries(options)) {
64
- for (const position of PROBES) {
65
- const value = scale.denormalize(position, min, max)
66
- const up = applyDelta(value, 1, options, range, modifiers)
67
- const down = applyDelta(value, -1, options, range, modifiers)
68
- if (up !== value || down !== value) outcome.moved = true
69
- if (!format) continue
70
- const shown = format(value)
71
- if (format(up) !== shown || format(down) !== shown) outcome.visible = true
72
- }
73
- }
74
-
75
- return outcome
76
- }
77
-
78
- export interface CheckStepsOptions {
79
- /** The component, for the message. */
80
- component: string
81
- /** The axis, for a component that has more than one. */
82
- axis?: string
83
- /**
84
- * The range to probe, or `null` to check nothing. An unbounded input has no
85
- * travel to sample, so `NumberInput` passes `null` when `min` and `max` are
86
- * not both there.
87
- */
88
- range: ValueRange | null
89
- keyboard?: ModifierValue<InputEventOption> | null
90
- wheel?: ModifierValue<InputEventOption> | null
91
- /**
92
- * How the value is displayed, where the component shows one. Called with
93
- * probe values only, and only in development.
94
- */
95
- format?: (value: number) => string
96
- }
3
+ import { checkSteps, type CheckStepsOptions } from '@tremolo-ui/dom'
97
4
 
98
5
  /**
99
6
  * Warn, in development only, when a key press or a wheel notch cannot produce
100
- * a change the user can see.
101
- *
102
- * Two settings that are each fine on their own can cancel out, and nothing
103
- * fails when they do — the control simply sits there:
104
- *
105
- * - **`step` coarser than the amount.** `keyboard={['raw', 0.1]}` with
106
- * `step={1}` rounds every press straight back to where it started
107
- * - **the display coarser than the amount.** A `format` showing two decimals
108
- * of a kHz value cannot show a press worth 1 Hz
109
- *
110
- * The second is only reported when the press is invisible at *every* point
111
- * along the travel. A display that rounds is a deliberate choice and is
112
- * normally right — it is being too coarse everywhere that makes it a mistake.
7
+ * a change the user can see. The probing is `checkSteps` in the core.
113
8
  *
114
9
  * @internal
115
10
  */
116
- export function useCheckSteps({
117
- component,
118
- axis,
119
- range,
120
- keyboard,
121
- wheel,
122
- format,
123
- }: CheckStepsOptions) {
11
+ export function useCheckSteps(options: CheckStepsOptions) {
12
+ const { component, axis, range, keyboard, wheel } = options
124
13
  const { min, max, step, scale } = range ?? {}
125
- const where = axis ? `${component} (${axis})` : component
126
14
 
127
15
  useEffect(() => {
128
16
  try {
129
17
  // Inline and first, so a bundler folds the comparison and drops the
130
- // whole block — the probing and the message strings with it. See
131
- // `useCheckPlacement` for why it cannot go through a helper, and why
132
- // it is wrapped.
18
+ // whole block — and with it the only call to `checkSteps`, which then
19
+ // falls out of the bundle too. See `useCheckPlacement` for why it
20
+ // cannot go through a helper, and why it is wrapped.
133
21
  if (process.env.NODE_ENV === 'production') return
134
- if (!range || min === undefined || max === undefined || !(min < max)) {
135
- return
136
- }
137
-
138
- for (const [name, options] of [
139
- ['keyboard', keyboard],
140
- ['wheel', wheel],
141
- ] as const) {
142
- if (!options) continue
143
- const { moved, visible } = probe(options, range, format)
144
- if (!moved) {
145
- console.warn(
146
- `[tremolo-ui] ${where}: \`${name}\` cannot move the value.` +
147
- (step !== undefined
148
- ? ` Each press is smaller than \`step\` (${step}), so it rounds`
149
- : ' Each press rounds') +
150
- ' straight back to where it started.',
151
- )
152
- } else if (format && !visible) {
153
- console.warn(
154
- `[tremolo-ui] ${where}: \`${name}\` moves the value, but \`format\`` +
155
- ' shows the same text before and after, everywhere in the range.' +
156
- ' The display is too coarse for it to be seen.',
157
- )
158
- }
159
- }
22
+ for (const warning of checkSteps(options)) console.warn(warning)
160
23
  } catch {
161
24
  // No bundler substituted NODE_ENV, so a production build cannot be told
162
25
  // from a development one. Say nothing rather than break.
@@ -165,5 +28,5 @@ export function useCheckSteps({
165
28
  // on what actually decides the outcome. `format` is left out on purpose:
166
29
  // an inline arrow function would make this run every render.
167
30
  // oxlint-disable-next-line react-hooks/exhaustive-deps
168
- }, [where, min, max, step, scale, keyboard, wheel])
31
+ }, [component, axis, min, max, step, scale, keyboard, wheel])
169
32
  }
@@ -1,65 +1,49 @@
1
- import { useCallback, useRef, useState } from 'react'
1
+ import { useCallback, useEffect, useRef } from 'react'
2
2
 
3
- import { useEventListener } from './useEventListener'
4
- import { useInterval } from './useInterval'
3
+ import { createLongPress, type LongPressInstance } from '@tremolo-ui/dom'
5
4
 
5
+ import { useCallbackRef } from './_internal/useCallbackRef'
6
+
7
+ /**
8
+ * Repeat `callback` while a pointer is held down: once on the press, then
9
+ * every `interval` after `initialDelay`. The repeat itself is
10
+ * `createLongPress` in `@tremolo-ui/dom`.
11
+ *
12
+ * Returns the function that starts a press, for an `onPointerDown`.
13
+ */
6
14
  export function useLongPress(
7
15
  callback: () => void,
8
16
  initialDelay = 500,
9
17
  interval = 40,
10
18
  ) {
11
- const [pressed, setPressed] = useState(false)
12
- const [delay, setDelay] = useState(initialDelay)
13
- const activePointerId = useRef<number | null>(null)
14
- const isPressed = useRef(false)
15
-
16
- useInterval(
17
- () => {
18
- callback()
19
- setDelay(interval)
20
- },
21
- pressed ? delay : null,
22
- )
23
-
24
- const stop = useCallback(
25
- (pointerId?: number) => {
26
- if (!isPressed.current) return
27
- if (
28
- pointerId !== undefined &&
29
- activePointerId.current !== null &&
30
- activePointerId.current !== pointerId
31
- )
32
- return
33
-
34
- isPressed.current = false
35
- activePointerId.current = null
36
- setPressed(false)
37
- setDelay(initialDelay)
38
- },
39
- [initialDelay],
40
- )
19
+ // Updated before layout effects run, so that a press started from one
20
+ // right after a re-render already calls the new callback.
21
+ const onPress = useCallbackRef(callback)
22
+ const instanceRef = useRef<LongPressInstance | null>(null)
41
23
 
42
- useEventListener(globalThis.window, 'pointerup', (event) => {
43
- stop(event.pointerId)
24
+ useEffect(() => {
25
+ instanceRef.current?.update({ delay: initialDelay, interval })
44
26
  })
45
27
 
46
- useEventListener(globalThis.window, 'pointercancel', (event) => {
47
- stop(event.pointerId)
48
- })
49
-
50
- useEventListener(globalThis.window, 'blur', () => {
51
- stop()
52
- })
28
+ useEffect(() => {
29
+ const instance = createLongPress({
30
+ onPress: () => onPress(),
31
+ delay: initialDelay,
32
+ interval,
33
+ })
34
+ instanceRef.current = instance
35
+ return () => {
36
+ instanceRef.current = null
37
+ instance.destroy()
38
+ }
39
+ // Created once: the options are pushed with update() above, so that a new
40
+ // delay does not end a press in progress.
41
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
42
+ }, [])
53
43
 
54
44
  return useCallback(
55
- (event?: Pick<PointerEvent, 'button' | 'pointerId'>) => {
56
- if (isPressed.current || (event && event.button !== 0)) return
57
-
58
- isPressed.current = true
59
- activePointerId.current = event?.pointerId ?? null
60
- callback()
61
- setPressed(true)
62
- },
63
- [callback],
45
+ (event?: Pick<PointerEvent, 'button' | 'pointerId'>) =>
46
+ instanceRef.current?.start(event),
47
+ [],
64
48
  )
65
49
  }
@@ -7,14 +7,6 @@ import {
7
7
  type MIDIAccessState,
8
8
  } from '@tremolo-ui/dom'
9
9
 
10
- export {
11
- NOT_SUPPORTED,
12
- PERMISSION_DENIED,
13
- UNAVAILABLE,
14
- type MIDIAccessError,
15
- type MIDIAccessOptions,
16
- } from '@tremolo-ui/dom'
17
-
18
10
  const INITIAL_STATE: MIDIAccessState = {
19
11
  midiAccess: null,
20
12
  error: null,
@@ -2,13 +2,10 @@ import { useEffect, useRef } from 'react'
2
2
 
3
3
  import {
4
4
  createMIDIInput,
5
- PITCH_BEND_CENTER,
6
5
  type MIDIInputHandlers,
7
6
  type MIDIInputInstance,
8
7
  } from '@tremolo-ui/dom'
9
8
 
10
- export { PITCH_BEND_CENTER, type MIDIInputHandlers }
11
-
12
9
  /**
13
10
  * Handle MIDI input events. To be used with {@link useMIDIAccess}.
14
11
  *
package/src/index.ts CHANGED
@@ -33,28 +33,23 @@ export {
33
33
  } from './components/NumberInput'
34
34
  export {
35
35
  Piano,
36
- SHORTCUTS,
37
36
  type PianoProps,
38
37
  type PianoMethods,
39
38
  type KeyState,
40
39
  type KeyAttributes,
41
- type KeyboardShortcuts,
42
40
  } from './components/Piano'
43
41
  export {
44
42
  PointsEditor,
45
43
  usePointsEditorContext,
46
- clampPoint,
47
44
  type PointsEditorProps,
48
45
  type PointsEditorContextValue,
49
46
  type PointsEditorPointProps,
50
- type PointBaseType,
51
47
  } from './components/PointsEditor'
52
48
  export {
53
49
  Slider,
54
50
  useSliderContext,
55
51
  type SliderContextValue,
56
52
  type SliderMarksOptionProps,
57
- type MarksOptions,
58
53
  type SliderMarksProps,
59
54
  type SliderMethods,
60
55
  type SliderProps,
@@ -68,11 +63,8 @@ export {
68
63
  type XYPadContextValue,
69
64
  type XYPadProps,
70
65
  type XYPadMethods,
71
- type XYPadAreaProps,
72
66
  type XYPadThumbProps,
73
67
  type XYPadThumbMethods,
74
- type XY,
75
- type XYInput,
76
68
  } from './components/XYPad'
77
69
 
78
70
  export { type CSSVariables } from './css-variables'
@@ -85,24 +77,7 @@ export { useDropZone, type UseDropZoneOptions } from './hooks/useDropZone'
85
77
  export { useEventListener } from './hooks/useEventListener'
86
78
  export { useInterval } from './hooks/useInterval'
87
79
  export { useLongPress } from './hooks/useLongPress'
88
- export {
89
- useMIDIAccess,
90
- NOT_SUPPORTED,
91
- PERMISSION_DENIED,
92
- UNAVAILABLE,
93
- type MIDIAccessError,
94
- type MIDIAccessOptions,
95
- } from './hooks/useMIDIAccess'
96
- export {
97
- useMIDIInput,
98
- PITCH_BEND_CENTER,
99
- type MIDIInputHandlers,
100
- } from './hooks/useMIDIInput'
80
+ export { useMIDIAccess } from './hooks/useMIDIAccess'
81
+ export { useMIDIInput } from './hooks/useMIDIInput'
101
82
  export { useMIDIMessage } from './hooks/useMIDIMessage'
102
83
  export { useWheel, type UseWheelOptions } from './hooks/useWheel'
103
-
104
- export {
105
- DEFAULT_DRAG_SENSITIVITY,
106
- DEFAULT_KEYBOARD_OPTIONS,
107
- DEFAULT_WHEEL_OPTIONS,
108
- } from './input-event'