@tremolo-ui/react 0.5.0 → 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 (86) hide show
  1. package/dist/compose-refs.cjs +72 -0
  2. package/dist/compose-refs.cjs.map +1 -0
  3. package/dist/compose-refs.d.cts +43 -0
  4. package/dist/compose-refs.d.cts.map +1 -0
  5. package/dist/compose-refs.d.ts +43 -0
  6. package/dist/compose-refs.d.ts.map +1 -0
  7. package/dist/compose-refs.js +70 -0
  8. package/dist/compose-refs.js.map +1 -0
  9. package/dist/index.cjs +1669 -541
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +1571 -486
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.ts +1571 -486
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +1640 -538
  16. package/dist/index.js.map +1 -1
  17. package/package.json +29 -27
  18. package/src/components/AnimationCanvas/index.tsx +115 -76
  19. package/src/components/DropZone/index.tsx +100 -0
  20. package/src/components/FileInput/Trigger.tsx +39 -0
  21. package/src/components/FileInput/context.tsx +24 -0
  22. package/src/components/FileInput/index.tsx +144 -0
  23. package/src/components/Knob/ActiveLine.tsx +7 -6
  24. package/src/components/Knob/InactiveLine.tsx +9 -10
  25. package/src/components/Knob/SVGRoot.tsx +5 -3
  26. package/src/components/Knob/Thumb.tsx +33 -11
  27. package/src/components/Knob/context.tsx +17 -1
  28. package/src/components/Knob/index.tsx +156 -60
  29. package/src/components/NumberInput/DecrementStepper.tsx +3 -10
  30. package/src/components/NumberInput/IncrementStepper.tsx +3 -10
  31. package/src/components/NumberInput/InputField.tsx +185 -108
  32. package/src/components/NumberInput/Stepper.tsx +120 -84
  33. package/src/components/NumberInput/StepperButton.tsx +100 -0
  34. package/src/components/NumberInput/context.tsx +34 -8
  35. package/src/components/NumberInput/index.tsx +270 -82
  36. package/src/components/Piano/index.tsx +363 -200
  37. package/src/components/PointsEditor/Background.tsx +13 -10
  38. package/src/components/PointsEditor/Container.tsx +83 -29
  39. package/src/components/PointsEditor/Point.tsx +241 -79
  40. package/src/components/PointsEditor/SelectionBox.tsx +48 -0
  41. package/src/components/PointsEditor/context.tsx +78 -10
  42. package/src/components/PointsEditor/index.tsx +440 -41
  43. package/src/components/Slider/Marks.tsx +48 -19
  44. package/src/components/Slider/MarksOption.tsx +64 -45
  45. package/src/components/Slider/Thumb.tsx +107 -55
  46. package/src/components/Slider/Track.tsx +66 -62
  47. package/src/components/Slider/context.tsx +4 -2
  48. package/src/components/Slider/index.tsx +136 -77
  49. package/src/components/Slider/type.ts +29 -9
  50. package/src/components/XYPad/Area.tsx +46 -41
  51. package/src/components/XYPad/Thumb.tsx +131 -64
  52. package/src/components/XYPad/context.tsx +4 -1
  53. package/src/components/XYPad/index.tsx +183 -53
  54. package/src/components/_util/Placement.tsx +68 -0
  55. package/src/components/_util/VisuallyHiddenRangeInput.tsx +12 -0
  56. package/src/components/_util/css-length.ts +13 -0
  57. package/src/components/_util/decimal-digits.ts +23 -0
  58. package/src/components/_util/visually-hidden.ts +25 -0
  59. package/src/{components/_util/composeRefs.tsx → compose-refs/index.tsx} +33 -5
  60. package/src/css-variables.ts +23 -0
  61. package/src/hooks/_internal/useCallbackRef.ts +3 -1
  62. package/src/hooks/_internal/useCheckSteps.ts +169 -0
  63. package/src/hooks/useAnimationFrame.ts +17 -7
  64. package/src/hooks/useDrag.ts +51 -12
  65. package/src/hooks/useDragValue.ts +71 -11
  66. package/src/hooks/useDropZone.ts +78 -0
  67. package/src/hooks/useEventListener.ts +10 -6
  68. package/src/hooks/useLongPress.ts +42 -8
  69. package/src/hooks/useMIDIAccess.ts +82 -11
  70. package/src/hooks/useMIDIInput.ts +45 -13
  71. package/src/hooks/useMIDIMessage.ts +23 -5
  72. package/src/hooks/useWheel.ts +4 -1
  73. package/src/index.ts +45 -25
  74. package/src/input-event.ts +32 -0
  75. package/dist/index.css +0 -501
  76. package/src/Globals.d.ts +0 -3
  77. package/src/components/Knob/index.css +0 -81
  78. package/src/components/NumberInput/index.css +0 -121
  79. package/src/components/NumberInput/stepperButton.tsx +0 -90
  80. package/src/components/Piano/index.css +0 -90
  81. package/src/components/PointsEditor/index.css +0 -35
  82. package/src/components/Slider/index.css +0 -125
  83. package/src/components/XYPad/index.css +0 -60
  84. package/src/components/_util/index.ts +0 -28
  85. package/src/styles/global.css +0 -19
  86. /package/src/components/Piano/{keyboardShortcuts.ts → keyboard-shortcuts.ts} +0 -0
package/dist/index.d.cts CHANGED
@@ -1,18 +1,35 @@
1
- import * as _$react from "react";
2
- import React, { CSSProperties, ComponentPropsWithoutRef, DependencyList, ReactElement, ReactNode, Ref, RefObject, SVGProps } from "react";
3
- import * as _$_tremolo_ui_dom0 from "@tremolo-ui/dom";
4
- import { AnimationFrame, AxisOptions, MIDIAccessError, NOT_SUPPORTED, PERMISSION_DENIED, WheelOptions, XY, XY as XY$1, XYInput, XYInput as XYInput$1 } from "@tremolo-ui/dom";
5
- import { InputEventOption, NoteRange, Scale, Units, ValueRange } from "@tremolo-ui/functions";
6
-
1
+ import React, { AriaAttributes, CSSProperties, ComponentPropsWithoutRef, DependencyList, ReactNode, Ref, RefObject, SVGProps } from "react";
2
+ import { AnimationFrame, AxisOptions, DragState, DropZoneOptions, InputEventOption, MIDIAccessError, MIDIAccessOptions, MIDIAccessOptions as MIDIAccessOptions$1, MIDIInputHandlers, ModifierState, ModifierValue, NOT_SUPPORTED, NoteRange, PERMISSION_DENIED, PITCH_BEND_CENTER, SelectionBoxRect, UNAVAILABLE, WheelOptions, XY, XY as XY$1, XYInput, XYInput as XYInput$1 } from "@tremolo-ui/dom";
3
+ import { Scale, ValueRange } from "@tremolo-ui/functions";
7
4
  //#region src/components/AnimationCanvas/index.d.ts
8
5
  type InitFunction = (context: CanvasRenderingContext2D, option: {
9
- /** current canvas width */width: number; /** current canvas height */
6
+ /** current canvas width */
7
+ width: number;
8
+ /** current canvas height */
10
9
  height: number;
11
10
  }) => void;
12
11
  type DrawFunction = (context: CanvasRenderingContext2D, option: AnimationFrame) => void;
13
- interface CommonProps {
12
+ interface AnimationCanvasCommonProps {
13
+ /**
14
+ * Draw one frame. It is given the 2D context and the frame: the size in CSS
15
+ * pixels, `count`, `deltaTime`, `elapsedTime` and `fps`.
16
+ *
17
+ * A new function replaces the old one in place, so writing it inline does
18
+ * not restart anything.
19
+ */
14
20
  draw: DrawFunction;
21
+ /**
22
+ * Called once before the first frame, with the context and the size in CSS
23
+ * pixels. Set up what every frame shares here.
24
+ */
15
25
  init?: InitFunction;
26
+ /**
27
+ * Redraw on every animation frame. Turn it off to draw only when there is a
28
+ * reason to: when the canvas mounts, when it is resized, and when the
29
+ * component re-renders.
30
+ *
31
+ * @default true
32
+ */
16
33
  animate?: boolean;
17
34
  /**
18
35
  * Read once, when the 2D context is created, so changing it later has no
@@ -21,95 +38,282 @@ interface CommonProps {
21
38
  * @see https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/getContext#contextattributes
22
39
  */
23
40
  options?: CanvasRenderingContext2DSettings;
41
+ /**
42
+ * Carry the drawing across a resize, so that the canvas does not blank for a
43
+ * frame while the new size is drawn. A fixed canvas is resized too, when its
44
+ * `width` or `height` changes.
45
+ *
46
+ * @default true
47
+ */
48
+ reduceFlickering?: boolean;
24
49
  }
25
- interface AbsoluteSizingProps {
50
+ /** A canvas of the size given in CSS pixels. This is the default. */
51
+ interface AnimationCanvasFixedProps {
52
+ /** Leave it out, or pass `false`, for a canvas of the size below. */
53
+ resizable?: false;
54
+ /**
55
+ * Width of the canvas in CSS pixels.
56
+ * @default 100
57
+ */
26
58
  width?: number;
59
+ /**
60
+ * Height of the canvas in CSS pixels.
61
+ * @default 100
62
+ */
27
63
  height?: number;
28
64
  }
29
- interface RelativeSizingProps {
30
- relativeSize?: boolean;
31
- reduceFlickering?: boolean;
65
+ /**
66
+ * A canvas that follows the size of its parent element, so the parent needs a
67
+ * size of its own.
68
+ */
69
+ interface AnimationCanvasResizableProps {
70
+ /**
71
+ * Follow the size of the parent element instead of `width` and `height`.
72
+ * Switching it rebuilds the canvas.
73
+ */
74
+ resizable: true;
75
+ /** Not accepted: the size comes from the parent element. */
76
+ width?: never;
77
+ /** Not accepted: the size comes from the parent element. */
78
+ height?: never;
32
79
  }
33
- type AnimationCanvasProps = CommonProps & AbsoluteSizingProps & RelativeSizingProps;
80
+ type AnimationCanvasProps = AnimationCanvasCommonProps & (AnimationCanvasFixedProps | AnimationCanvasResizableProps);
81
+ type Props = AnimationCanvasProps & Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasCommonProps | 'resizable' | 'width' | 'height'>;
34
82
  /**
35
83
  * A simple animatable canvas with requestAnimationFrame()
36
84
  */
37
- declare function AnimationCanvas(props: CommonProps & AbsoluteSizingProps & Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>): ReactElement;
38
- declare function AnimationCanvas(pros: CommonProps & RelativeSizingProps & Omit<ComponentPropsWithoutRef<'canvas'>, keyof AnimationCanvasProps>): ReactElement;
85
+ export declare const AnimationCanvas: import("react").ForwardRefExoticComponent<Props & import("react").RefAttributes<HTMLCanvasElement>>;
39
86
  //#endregion
40
- //#region src/components/_util/index.d.ts
41
- declare const cursorStyles: {
42
- grabbing: string;
43
- grab: string;
44
- pointer: string;
45
- move: string;
46
- none: string;
87
+ //#region src/components/DropZone/index.d.ts
88
+ interface DropZoneProps {
89
+ /**
90
+ * Which files to take, written the way the `accept` attribute of a file
91
+ * input is: a comma separated list of extensions (`.wav`), MIME types
92
+ * (`audio/wav`) and type groups (`audio/*`).
93
+ *
94
+ * What does not match goes to `onReject` rather than `onDrop`. While the
95
+ * drag is still in the air the element is marked `[data-invalid]`, as far as
96
+ * the browser lets it be told apart — a rule written as an extension cannot
97
+ * be decided until the drop.
98
+ */
99
+ accept?: string;
100
+ /**
101
+ * Take more than one file from a single drop. With it off, only the first
102
+ * accepted file is reported, as a file input without `multiple` does.
103
+ *
104
+ * @default false
105
+ */
106
+ multiple?: boolean;
107
+ /**
108
+ * Refuse the drop. The drag is still swallowed rather than let through: an
109
+ * unhandled drop makes the browser leave the page and open the file.
110
+ *
111
+ * @default false
112
+ */
113
+ disabled?: boolean;
114
+ /**
115
+ * Called with the dropped files that match `accept`.
116
+ *
117
+ * @param event the drop, for anything the files leave out — where on the
118
+ * element it landed, most of all.
119
+ */
120
+ onDrop?: (files: File[], event: DragEvent) => void;
121
+ /**
122
+ * Called with the dropped files that do not match `accept`, so that the
123
+ * reason can be shown.
124
+ */
125
+ onReject?: (files: File[], event: DragEvent) => void;
126
+ /** What the zone shows. */
127
+ children: ReactNode;
128
+ }
129
+ /**
130
+ * An area that takes files dropped onto it.
131
+ */
132
+ export declare const DropZone: {
133
+ Root: import("react").ForwardRefExoticComponent<DropZoneProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof DropZoneProps> & import("react").RefAttributes<HTMLDivElement>>;
134
+ };
135
+ //#endregion
136
+ //#region src/components/FileInput/Trigger.d.ts
137
+ interface FileInputTriggerProps {
138
+ /** What the trigger reads. It is the accessible name of the file input. */
139
+ children: ReactNode;
140
+ }
141
+ //#endregion
142
+ //#region src/components/FileInput/context.d.ts
143
+ type FileInputContextValue = {
144
+ /** The id of the hidden `<input type="file">`, for `Trigger`'s `htmlFor`. */
145
+ inputId: string;
146
+ disabled: boolean;
147
+ };
148
+ export declare function useFileInputContext(): FileInputContextValue;
149
+ export declare function useFileInputContext<T>(selector: (state: FileInputContextValue) => T): T;
150
+ //#endregion
151
+ //#region src/components/FileInput/index.d.ts
152
+ interface FileInputProps {
153
+ /**
154
+ * Which files to take, written the way the HTML attribute is: a comma
155
+ * separated list of extensions (`.wav`), MIME types (`audio/wav`) and type
156
+ * groups (`audio/*`).
157
+ *
158
+ * **The browser treats it as a hint to the picker, not a rule.** A person
159
+ * can switch the picker to "All Files", so what arrives is checked again
160
+ * here, and anything that does not match goes to `onReject` instead.
161
+ */
162
+ accept?: string;
163
+ /**
164
+ * Let more than one file be picked at a time.
165
+ * @default false
166
+ */
167
+ multiple?: boolean;
168
+ /**
169
+ * Refuse to open the picker, and mark every part with `[data-disabled]`.
170
+ * @default false
171
+ */
172
+ disabled?: boolean;
173
+ /**
174
+ * Called with the files that were picked and match `accept`.
175
+ *
176
+ * It is not called at all when the picker is dismissed, or when every file
177
+ * picked was rejected — an empty array never arrives, so there is no need to
178
+ * tell "nothing was chosen" from "the choice was cleared".
179
+ */
180
+ onChange?: (files: File[]) => void;
181
+ /**
182
+ * Called with the files that were picked and do not match `accept`, so that
183
+ * the reason can be shown. Given alongside `onChange` when a selection held
184
+ * both.
185
+ */
186
+ onReject?: (files: File[]) => void;
187
+ /** Normally a `FileInput.Trigger`, and whatever shows what was picked. */
188
+ children: ReactNode;
189
+ }
190
+ /**
191
+ * Picks files, and hands them over as `File`s.
192
+ */
193
+ export declare const FileInput: {
194
+ Root: import("react").ForwardRefExoticComponent<FileInputProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof FileInputProps> & import("react").RefAttributes<HTMLDivElement>>;
195
+ Trigger: import("react").ForwardRefExoticComponent<FileInputTriggerProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref">, "children" | "htmlFor"> & import("react").RefAttributes<HTMLLabelElement>>;
47
196
  };
48
- type Cursor = keyof typeof cursorStyles;
49
197
  //#endregion
50
198
  //#region src/components/Knob/ActiveLine.d.ts
51
- declare function ActiveLine({
52
- stroke,
53
- strokeWidth,
54
- className,
55
- ...props
56
- }: Omit<SVGProps<SVGPathElement>, 'd'>): _$react.JSX.Element;
199
+ declare function ActiveLine({ stroke, strokeWidth, className, ...props }: Omit<SVGProps<SVGPathElement>, 'd'>): import("react").JSX.Element;
57
200
  //#endregion
58
201
  //#region src/components/Knob/InactiveLine.d.ts
59
- declare function InactiveLine({
60
- stroke,
61
- strokeWidth,
62
- className,
63
- ...props
64
- }: Omit<SVGProps<SVGPathElement>, 'd'>): _$react.JSX.Element;
202
+ declare function InactiveLine({ stroke, strokeWidth, className, ...props }: Omit<SVGProps<SVGPathElement>, 'd'>): import("react").JSX.Element;
65
203
  //#endregion
66
204
  //#region src/components/Knob/SVGRoot.d.ts
67
- interface SVGRootProps {
205
+ interface KnobSVGRootProps {
68
206
  /**
69
207
  * `<Knob.InactiveLine />`, `<Knob.ActiveLine />` and `<Knob.Thumb />` go
70
208
  * here, in the order you want them painted.
71
209
  */
72
210
  children: ReactNode;
73
211
  }
74
- declare function SVGRoot({
75
- children,
76
- style,
77
- ...props
78
- }: SVGRootProps & Omit<SVGProps<SVGSVGElement>, keyof SVGRootProps>): _$react.JSX.Element;
212
+ declare function SVGRoot({ children, style, ...props }: KnobSVGRootProps & Omit<SVGProps<SVGSVGElement>, keyof KnobSVGRootProps>): import("react").JSX.Element;
79
213
  //#endregion
80
214
  //#region src/components/Knob/Thumb.d.ts
81
- interface Props$1 {
82
- /** color */
215
+ interface KnobThumbProps {
216
+ /**
217
+ * Fill colour of the circle.
218
+ * @default 'currentColor'
219
+ */
83
220
  thumb?: string;
84
- /** color */
221
+ /**
222
+ * Colour of the line that points at the value.
223
+ * @default 'currentColor'
224
+ */
85
225
  thumbLine?: string;
86
- /** percent (0-100) */
226
+ /**
227
+ * Diameter of the circle, as a percentage of the knob.
228
+ * @default 84
229
+ */
87
230
  thumbSize?: number;
88
- /** percent (0-100) */
231
+ /**
232
+ * Thickness of the line, as a percentage of the knob.
233
+ * @default 6
234
+ */
89
235
  thumbLineWeight?: number;
90
- /** percent (0-100) */
236
+ /**
237
+ * How far down the line reaches, as a percentage of the knob from its top.
238
+ * The line starts at the edge of the circle.
239
+ * @default 35
240
+ */
91
241
  thumbLineLength?: number;
242
+ /**
243
+ * Classes for what the thumb draws inside itself: `thumbLine` is the line
244
+ * that points at the value.
245
+ */
92
246
  classes?: {
93
- thumb?: string;
94
247
  thumbLine?: string;
95
248
  };
96
249
  }
97
- declare function Thumb$2({
98
- className,
99
- thumb,
100
- thumbLine,
101
- thumbSize,
102
- thumbLineWeight,
103
- thumbLineLength,
104
- classes,
105
- ...props
106
- }: Props$1 & Omit<SVGProps<SVGSVGElement>, 'd' | keyof Props$1>): _$react.JSX.Element;
250
+ declare function Thumb({ className, thumb, thumbLine, thumbSize, thumbLineWeight, thumbLineLength, classes, ...props }: KnobThumbProps & Omit<SVGProps<SVGSVGElement>, 'd' | keyof KnobThumbProps>): import("react").JSX.Element;
251
+ //#endregion
252
+ //#region src/css-variables.d.ts
253
+ /**
254
+ * CSS custom properties, for a `style` object.
255
+ *
256
+ * React's `CSSProperties` has no key starting with `--`, so
257
+ * `style={{ '--color': 'red' }}` is refused as an unknown property even though
258
+ * the browser takes it. Every part accepts this alongside `CSSProperties`,
259
+ * which is how a variable the component or a theme reads is set inline.
260
+ *
261
+ * `T` names the custom properties the part itself writes or reads, without the
262
+ * leading `--`, so that an editor can suggest them. Any other `--` name is
263
+ * still accepted — a theme reads variables of its own, such as the colours of
264
+ * each kind of key.
265
+ *
266
+ * @example
267
+ * CSSVariables<'thickness' | 'length'>
268
+ * // { '--thickness'?: string | number, '--length'?: string | number,
269
+ * // [name: `--${string}`]: string | number | undefined }
270
+ */
271
+ type CSSVariables<T extends string = never> = { [K in T as `--${K}`]?: string | number; } & { [K in `--${string}`]?: string | number; };
272
+ //#endregion
273
+ //#region src/components/Knob/context.d.ts
274
+ type KnobConfig = {
275
+ value: number;
276
+ min: number;
277
+ max: number;
278
+ step: number;
279
+ scale: Scale;
280
+ startValue: number;
281
+ /** angle range [degree] */
282
+ angleRange: number;
283
+ };
284
+ type KnobContextValue = KnobConfig & {
285
+ /** normalized value */
286
+ p: number;
287
+ /** ロータリー開始位置 */
288
+ r1: number;
289
+ /** activeLine の開始位置 */
290
+ r2: number;
291
+ /** activeLine の終了位置 */
292
+ r3: number;
293
+ /** ロータリー終了位置 */
294
+ r4: number;
295
+ };
296
+ /**
297
+ * Everything here is derived during render, so there is no state to keep in
298
+ * sync: `value` comes from the props of `Root` and the rest follows from it.
299
+ */
300
+ export declare function useKnobContext(): KnobContextValue;
301
+ export declare function useKnobContext<T>(selector: (state: KnobContextValue) => T): T;
107
302
  //#endregion
108
303
  //#region src/components/Knob/index.d.ts
109
304
  interface KnobProps {
305
+ /** The current value. The knob shows only this, so update it from `onChange`. */
110
306
  value: number;
307
+ /** The value with the knob turned all the way down. */
111
308
  min: number;
309
+ /** The value with the knob turned all the way up. */
112
310
  max: number;
311
+ /**
312
+ * Granularity of the value. A drag, the wheel and the arrow keys snap it to
313
+ * multiples of `step`.
314
+ *
315
+ * @default 1
316
+ */
113
317
  step?: number;
114
318
  /**
115
319
  * How the value is distributed across the travel.
@@ -122,46 +326,115 @@ interface KnobProps {
122
326
  */
123
327
  scale?: Scale;
124
328
  /**
125
- * value set when double-clicking
126
- * restriction: enableDoubleClickDefault = true
329
+ * The value a double click restores, while `enableDoubleClickDefault` is on.
127
330
  * @default min
128
- * @see enableDoubleClickDefault
129
331
  */
130
332
  defaultValue?: number;
131
333
  /**
132
- * Value to be used as the starting point of the line when drawing.
334
+ * Where the active arc starts. Put it at the centre of a bipolar control,
335
+ * such as a pan knob, so that the arc grows from there either way.
133
336
  * @default min
134
337
  */
135
338
  startValue?: number;
136
- /** width and height */
137
339
  /**
138
- * Width and height of the knob.
139
- * Defaults to the `--knob-size` CSS variable (50px).
340
+ * Width and height of the knob. Sets `--knob-size`; the size the theme
341
+ * gives it stands when this is omitted.
140
342
  */
141
343
  size?: number | string;
142
344
  /**
143
- * Global style to apply when dragged
144
- * @default defaultExternalStyles
345
+ * The cursor to show while dragging. It is set on the dragged element, so it
346
+ * stays while the pointer is outside the knob.
347
+ *
348
+ * @default { cursor: 'grabbing' }
145
349
  */
146
350
  externalStyles?: {
147
- userSelectNone?: boolean;
148
- cursor?: Cursor;
351
+ cursor?: CSSProperties['cursor'];
149
352
  };
150
353
  /**
151
- * wheel control option
152
- * If null, no event will be triggered
354
+ * How much one notch of the wheel moves the value. It only acts while the
355
+ * focus is inside, so that scrolling the page past the knob leaves it alone.
356
+ *
357
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
358
+ * range between `min` and `max`. The result is snapped to `step`, except for
359
+ * an amount set on a modifier key (`{ default: …, shift: … }`). `null` turns
360
+ * the wheel off.
361
+ *
362
+ * @default ['raw', 1]
363
+ */
364
+ wheel?: ModifierValue<InputEventOption> | null;
365
+ /**
366
+ * How much a drag moves the value, per modifier key.
367
+ *
368
+ * `1` is the normal travel of 100px for the whole range; `0.1` makes the
369
+ * same movement cover a tenth of it. Shift is bound to `0.1` by default, to
370
+ * match what it does on the arrow keys.
371
+ *
372
+ * Pressing or releasing the key mid-drag does not disturb the value: the
373
+ * travel so far is kept and the new sensitivity applies from there. It takes
374
+ * effect on the next movement, since a key on its own produces no pointer
375
+ * event.
376
+ *
377
+ * @default { default: 1, shift: 0.1 }
378
+ */
379
+ dragSensitivity?: ModifierValue<number>;
380
+ /**
381
+ * Hide the cursor while dragging and read the pointer movement directly,
382
+ * rather than letting it wander off across the screen.
383
+ *
384
+ * A knob does not care where the pointer is, only how far it moved, and
385
+ * letting it wander costs twice: the cursor ends up far from the knob it is
386
+ * holding, and **the drag stops at the edge of the screen**, where the
387
+ * operating system pins the pointer and the coordinates stop changing. A
388
+ * `dragSensitivity` below 1 reaches that edge quickly.
389
+ *
390
+ * Off by default because it is not free: the browser shows its own notice,
391
+ * Esc takes the lock back, and the request needs a user gesture and can be
392
+ * refused. A refused request is not an error — the drag simply carries on as
393
+ * an ordinary one.
394
+ *
395
+ * @default false
153
396
  */
154
- wheel?: InputEventOption | null;
397
+ pointerLock?: boolean;
155
398
  /**
156
- * keyboard control option
157
- * If null, no event will be triggered
399
+ * How much one arrow key press moves the value.
400
+ *
401
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
402
+ * range between `min` and `max`. The result is snapped to `step`, except for
403
+ * an amount set on a modifier key, which is what lets shift move off the
404
+ * grid. `null` turns the arrow keys off.
405
+ *
406
+ * The default moves by 1, and by 0.1 with shift. With a `step` above 1, raise
407
+ * the amount to match: 1 would round straight back to where it started, and
408
+ * a development build warns about it.
409
+ *
410
+ * @default { default: ['raw', 1], shift: ['raw', 0.1] }
411
+ */
412
+ keyboard?: ModifierValue<InputEventOption> | null;
413
+ /**
414
+ * Restore `defaultValue` on a double click.
415
+ * @default true
158
416
  */
159
- keyboard?: InputEventOption | null;
160
417
  enableDoubleClickDefault?: boolean;
418
+ /**
419
+ * Make the knob unchangeable and remove it from the tab order.
420
+ * The parts carry `data-disabled` while it is set.
421
+ */
161
422
  disabled?: boolean;
423
+ /**
424
+ * Make the knob unchangeable while leaving it focusable.
425
+ * The parts carry `data-readonly` while it is set.
426
+ */
162
427
  readonly?: boolean;
163
- /** angle range [degree] */
428
+ /**
429
+ * How far the knob turns from `min` to `max`, in degrees, centred on the
430
+ * top.
431
+ * @default 270
432
+ */
164
433
  angleRange?: number;
434
+ /**
435
+ * Called with the new value when a drag, the wheel, an arrow key or a double
436
+ * click moves it.
437
+ */
165
438
  onChange?: (value: number) => void;
166
439
  /**
167
440
  * The knob renders exactly what you compose here; there is no default
@@ -177,6 +450,7 @@ interface KnobProps {
177
450
  * </Knob.Root>
178
451
  */
179
452
  children: ReactNode;
453
+ style?: CSSProperties & CSSVariables<'knob-size'>;
180
454
  }
181
455
  interface KnobMethods {
182
456
  focus: () => void;
@@ -185,89 +459,30 @@ interface KnobMethods {
185
459
  /**
186
460
  * Interactive rotary knob component implemented in SVG.
187
461
  */
188
- declare const Knob: {
189
- Root: _$react.ForwardRefExoticComponent<KnobProps & Omit<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof KnobProps> & _$react.RefAttributes<KnobMethods>>;
462
+ export declare const Knob: {
463
+ Root: import("react").ForwardRefExoticComponent<KnobProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof KnobProps> & import("react").RefAttributes<KnobMethods>>;
190
464
  SVGRoot: typeof SVGRoot;
191
465
  InactiveLine: typeof InactiveLine;
192
466
  ActiveLine: typeof ActiveLine;
193
- Thumb: typeof Thumb$2;
467
+ Thumb: typeof Thumb;
194
468
  };
195
469
  //#endregion
196
- //#region src/components/NumberInput/stepperButton.d.ts
197
- interface StepperButtonProps {
198
- className?: string;
199
- style?: CSSProperties;
200
- /** Replaces the default arrow. Size it with the `--stepper-icon-size` variable. */
201
- children?: ReactNode;
202
- }
470
+ //#region src/components/NumberInput/StepperButton.d.ts
471
+ /**
472
+ * `--stepper-icon-size` is read by the default arrow inside, and set on the
473
+ * button so that it inherits there.
474
+ */
475
+ type StepperButtonProps = Omit<ComponentPropsWithoutRef<'div'>, 'style'> & {
476
+ style?: CSSProperties & CSSVariables<'stepper-icon-size'>;
477
+ };
203
478
  //#endregion
204
479
  //#region src/components/NumberInput/DecrementStepper.d.ts
205
- type DecrementStepperProps = StepperButtonProps;
206
480
  /** Lowers the value by one `step`, repeating while held. */
207
- declare function DecrementStepper(props: DecrementStepperProps & Omit<ComponentPropsWithoutRef<'div'>, keyof DecrementStepperProps>): _$react.JSX.Element;
481
+ declare function DecrementStepper(props: StepperButtonProps): import("react").JSX.Element;
208
482
  //#endregion
209
483
  //#region src/components/NumberInput/IncrementStepper.d.ts
210
- type IncrementStepperProps = StepperButtonProps;
211
484
  /** Raises the value by one `step`, repeating while held. */
212
- declare function IncrementStepper(props: IncrementStepperProps & Omit<ComponentPropsWithoutRef<'div'>, keyof IncrementStepperProps>): _$react.JSX.Element;
213
- //#endregion
214
- //#region src/components/NumberInput/InputField.d.ts
215
- interface NumberInputFieldProps {
216
- /**
217
- * Select the text when the input takes focus. `'number'` selects the leading
218
- * number, leaving whatever the format appended to it.
219
- * @default 'none'
220
- */
221
- selectOnFocus?: 'all' | 'number' | 'none';
222
- /**
223
- * Commit and leave the input when Enter is pressed. Enter commits either way.
224
- * @default true
225
- */
226
- blurOnEnter?: boolean;
227
- className?: string;
228
- style?: CSSProperties;
229
- ref?: Ref<HTMLInputElement>;
230
- }
231
- /**
232
- * The text field of a `NumberInput`, and the only place the value can be typed.
233
- *
234
- * While the user types, their own text stands rather than `format(value)`, so
235
- * that a half-finished entry is not rewritten under the caret.
236
- */
237
- declare function InputField({
238
- selectOnFocus,
239
- blurOnEnter,
240
- className,
241
- style,
242
- ref,
243
- onFocus,
244
- onBlur,
245
- onKeyDown,
246
- ...props
247
- }: NumberInputFieldProps & Omit<ComponentPropsWithoutRef<'input'>, keyof NumberInputFieldProps | 'type' | 'value' | 'defaultValue'>): _$react.JSX.Element;
248
- //#endregion
249
- //#region src/components/NumberInput/Stepper.d.ts
250
- interface StepperProps {
251
- className?: string;
252
- style?: CSSProperties;
253
- /** `<NumberInput.IncrementStepper />` and `<NumberInput.DecrementStepper />` go here. */
254
- children?: ReactNode;
255
- ref?: Ref<HTMLDivElement>;
256
- }
257
- /**
258
- * The area the steppers sit in, and a drag handle in its own right: dragging it
259
- * up and down moves the value one `step` every `drag` pixels.
260
- *
261
- * The drag lives here rather than on `InputField` because `createDrag` turns
262
- * off text selection on whatever element it is attached to.
263
- */
264
- declare function Stepper({
265
- className,
266
- style,
267
- children,
268
- ref,
269
- ...props
270
- }: StepperProps & Omit<ComponentPropsWithoutRef<'div'>, keyof StepperProps>): _$react.JSX.Element;
485
+ declare function IncrementStepper(props: StepperButtonProps): import("react").JSX.Element;
271
486
  //#endregion
272
487
  //#region src/components/NumberInput/context.d.ts
273
488
  type NumberInputContextValue = {
@@ -279,37 +494,61 @@ type NumberInputContextValue = {
279
494
  */
280
495
  min?: number;
281
496
  max?: number;
282
- step: number; /** How the value is distributed across the travel. */
497
+ step: number;
498
+ /** How the value is distributed across the travel. */
283
499
  scale: Scale;
284
500
  disabled: boolean;
285
501
  readonly: boolean;
286
502
  clampValue: boolean;
287
503
  /**
288
- * The effective scaling for `applyDelta` and for clamping on commit, with the
289
- * unbounded ends filled in. Ignores `min` / `max` when `clampValue` is off.
504
+ * The effective scaling for `applyDelta`, with unbounded ends filled in.
505
+ * Ignores `min` / `max` when `clampValue` is off.
290
506
  */
291
507
  range: ValueRange;
292
- keyboard: InputEventOption | null; /** Pixels of vertical drag on `Stepper` that move the value by one `step`. */
293
- drag: number | null; /** What the input shows: the draft while editing, the formatted value otherwise. */
508
+ /** The effective range for raw input, whose open ends cover finite numbers. */
509
+ rawRange: ValueRange;
510
+ keyboard: ModifierValue<InputEventOption> | null;
511
+ /** Pixels of vertical drag on `Stepper` that move the value by one `step`. */
512
+ drag: number | null;
513
+ /** How much a `Stepper` drag counts, per modifier key. */
514
+ dragSensitivity: ModifierValue<number>;
515
+ /** Whether a `Stepper` drag hides the pointer and reads its movement. */
516
+ pointerLock: boolean;
517
+ /** What `InputField` selects when it takes focus. */
518
+ selectOnFocus: 'all' | 'number' | 'none';
519
+ /** Whether `InputField` shows the plain value while it has focus. */
520
+ unformatOnFocus: boolean;
521
+ /** Whether `InputField` puts the caret back after an arrow key steps the value. */
522
+ keepCaretOnStep: boolean;
523
+ /** Whether Enter leaves `InputField` as well as committing. */
524
+ blurOnEnter: boolean;
525
+ /** What the input shows: the draft while editing, the formatted value otherwise. */
294
526
  text: string;
295
- editing: boolean; /** Whether the value sits outside `min` / `max`. Not judged while editing. */
296
- outOfRange: boolean; /** Whether a stepper would have no effect, for `aria-disabled`. */
527
+ editing: boolean;
528
+ /** Whether the value sits outside `min` / `max`. Not judged while editing. */
529
+ outOfRange: boolean;
530
+ /** Whether a stepper would have no effect, for `aria-disabled`. */
297
531
  atMin: boolean;
298
532
  atMax: boolean;
299
533
  format: (value: number) => string;
300
- parse: (text: string) => number; /** Typing. Replaces the draft and reports the parsed value, unclamped. */
301
- setDraft: (text: string) => void; /** Blur or Enter. Clamps the draft, reports it, and drops the draft. */
302
- commitDraft: () => void; /** Drops the draft and replaces the value: steppers, wheel, keyboard, drag. */
303
- changeValue: (next: number) => void; /** Moves the value by one `option` in `direction`, normally +1 or -1. */
304
- nudge: (direction: number, option: InputEventOption) => void; /** `InputField` registers itself here; `Root` focuses it through its methods. */
534
+ parse: (text: string) => number;
535
+ /** Typing. Replaces the draft and reports the parsed value, unclamped. */
536
+ setDraft: (text: string) => void;
537
+ /** Blur or Enter. Optionally clamps the draft, reports it, and drops it. */
538
+ commitDraft: () => void;
539
+ /** Drops the draft and replaces the value: steppers, wheel, keyboard, drag. */
540
+ changeValue: (next: number) => void;
541
+ /** Moves the value by one `option` in `direction`, normally +1 or -1. */
542
+ nudge: (direction: number, option: ModifierValue<InputEventOption>, modifiers?: ModifierState) => void;
543
+ /** `InputField` registers itself here; `Root` focuses it through its methods. */
305
544
  inputRef: RefObject<HTMLInputElement | null>;
306
545
  };
307
546
  /**
308
547
  * The only state behind this is the editing draft; `value` comes from the props
309
548
  * of `Root` and everything else is derived during render.
310
549
  */
311
- declare function useNumberInputContext(): NumberInputContextValue;
312
- declare function useNumberInputContext<T>(selector: (state: NumberInputContextValue) => T): T;
550
+ export declare function useNumberInputContext(): NumberInputContextValue;
551
+ export declare function useNumberInputContext<T>(selector: (state: NumberInputContextValue) => T): T;
313
552
  //#endregion
314
553
  //#region src/components/NumberInput/index.d.ts
315
554
  interface NumberInputProps {
@@ -318,8 +557,27 @@ interface NumberInputProps {
318
557
  * is typing, when their own text stands until it is committed.
319
558
  */
320
559
  value: number;
560
+ /**
561
+ * Lowest value. Leave it out for no lower bound.
562
+ *
563
+ * It is enforced when a value is committed or stepped, while `clampValue` is
564
+ * on. A value below it carries `data-out-of-range` on `InputField`.
565
+ */
321
566
  min?: number;
567
+ /**
568
+ * Highest value. Leave it out for no upper bound.
569
+ *
570
+ * It is enforced when a value is committed or stepped, while `clampValue` is
571
+ * on. A value above it carries `data-out-of-range` on `InputField`.
572
+ */
322
573
  max?: number;
574
+ /**
575
+ * Granularity of the value. The steppers, a drag on `Stepper`, the wheel and
576
+ * the arrow keys snap it to multiples of `step`; a typed value is left as it
577
+ * is.
578
+ *
579
+ * @default 1
580
+ */
323
581
  step?: number;
324
582
  /**
325
583
  * How the value is distributed across the travel of a drag or a
@@ -329,26 +587,20 @@ interface NumberInputProps {
329
587
  */
330
588
  scale?: Scale;
331
589
  /**
332
- * Unit to display the value in, or a list to pick from by magnitude.
333
- * Builds the default `format` and `parse`.
590
+ * Render the value as text. Plain digits by default.
591
+ *
592
+ * `unitFormat` from `@tremolo-ui/functions` builds this and `parse` together
593
+ * for a unit, as a pair to spread into the root.
334
594
  *
335
595
  * @example
336
- * units='Hz'
337
- * units={[['Hz', 1], ['kHz', 1000]]}
338
- * units={[['ms', 1], ['s', 1000]]}
596
+ * <NumberInput.Root {...unitFormat('Hz', { digits: 2 })} value={v} />
339
597
  */
340
- units?: string | Units;
598
+ format?: (value: number) => string;
341
599
  /**
342
- * Digits after the decimal point, for the default `format`.
600
+ * Read a value back out of the text. Has to undo `format`.
343
601
  *
344
- * @example
345
- * // units={[['Hz', 1], ['kHz', 1000]]} digit={2}
346
- * // 100 -> 100.00Hz, 1600 -> 1.60kHz
602
+ * Text with no number in it reads as `NaN`, which leaves the value alone.
347
603
  */
348
- digit?: number;
349
- /** Render the value as text. Takes precedence over `units` / `digit`. */
350
- format?: (value: number) => string;
351
- /** Read a value back out of the text. Takes precedence over `units`. */
352
604
  parse?: (text: string) => number;
353
605
  /**
354
606
  * Keep the value within `min` and `max` when it is committed or stepped.
@@ -357,35 +609,128 @@ interface NumberInputProps {
357
609
  */
358
610
  clampValue?: boolean;
359
611
  /**
360
- * Wheel control option. Only applies while the focus is inside, so that
361
- * scrolling past the input does not change it.
362
- * If null, no event will be triggered
612
+ * How much one notch of the wheel moves the value. It only acts while the
613
+ * focus is inside, so that scrolling the page past the input leaves it
614
+ * alone.
615
+ *
616
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
617
+ * range between `min` and `max`. The result is snapped to `step`, except for
618
+ * an amount set on a modifier key (`{ default: …, shift: … }`). `null` turns
619
+ * the wheel off.
620
+ *
621
+ * @default ['raw', 1]
363
622
  */
364
- wheel?: InputEventOption | null;
623
+ wheel?: ModifierValue<InputEventOption> | null;
365
624
  /**
366
- * keyboard control option
367
- * If null, no event will be triggered
625
+ * How much one arrow key press moves the value.
626
+ *
627
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
628
+ * range between `min` and `max`. The result is snapped to `step`, except for
629
+ * an amount set on a modifier key, which is what lets shift move off the
630
+ * grid. `null` turns the arrow keys off.
631
+ *
632
+ * The default moves by 1, and by 0.1 with shift. With a `step` above 1, raise
633
+ * the amount to match: 1 would round straight back to where it started, and
634
+ * a development build warns about it.
635
+ *
636
+ * @default { default: ['raw', 1], shift: ['raw', 0.1] }
368
637
  */
369
- keyboard?: InputEventOption | null;
638
+ keyboard?: ModifierValue<InputEventOption> | null;
370
639
  /**
371
640
  * Pixels of vertical drag on `Stepper` that move the value by one `step`.
372
- * If null, no event will be triggered
641
+ * `null` turns the drag off.
373
642
  * @default 1
374
643
  */
375
644
  drag?: number | null;
376
645
  /**
377
- * Only the appearance will change.
378
- * Please consider using with readonly.
379
- * aria-disabled property is also applied.
646
+ * How much a `Stepper` drag counts, per modifier key.
647
+ *
648
+ * `1` is `drag` pixels per `step`; `0.1` makes the same movement cover a
649
+ * tenth of that. Shift is bound to `0.1` by default, to match what it does
650
+ * on the arrow keys.
651
+ *
652
+ * A modifier entry is not snapped to `step`, which is what lets a finer
653
+ * amount move at all.
654
+ *
655
+ * @default { default: 1, shift: 0.1 }
656
+ */
657
+ dragSensitivity?: ModifierValue<number>;
658
+ /**
659
+ * Hide the cursor while dragging a `Stepper` and read the pointer movement
660
+ * directly, rather than letting it wander off across the screen.
661
+ *
662
+ * The drag is already relative, so the pointer position carries nothing —
663
+ * but it still runs into the edge of the screen, where the operating system
664
+ * pins it and the coordinates stop changing.
665
+ *
666
+ * Off by default: the browser shows its own notice, Esc takes the lock back,
667
+ * and the request can be refused. A refused request is not an error, and the
668
+ * drag carries on as an ordinary one.
669
+ *
670
+ * @default false
671
+ */
672
+ pointerLock?: boolean;
673
+ /**
674
+ * Select the text when `InputField` takes focus: `'all'` selects all of it,
675
+ * `'number'` only the leading number, leaving whatever the format appended,
676
+ * and `'none'` leaves the caret where the click put it.
677
+ * @default 'none'
678
+ */
679
+ selectOnFocus?: 'all' | 'number' | 'none';
680
+ /**
681
+ * Show the plain value while `InputField` has focus, dropping whatever
682
+ * `format` put around it: an input reading `1.23kHz` shows `1230` to be
683
+ * typed over.
684
+ *
685
+ * The number shown is the value itself, not the number inside the formatted
686
+ * text. Those differ whenever the format scales — `1.23` out of `1.23kHz`
687
+ * would read back as 1.23 and lose a factor of a thousand — and it is also
688
+ * why a rounded display no longer becomes the value: `1.6` shown as `2Hz`
689
+ * offers `1.6` for editing, not `2`.
690
+ *
691
+ * @default false
692
+ */
693
+ unformatOnFocus?: boolean;
694
+ /**
695
+ * Put the caret in `InputField` back where it was after an arrow key steps
696
+ * the value.
697
+ *
698
+ * A controlled input whose `value` is replaced drops the caret at the end,
699
+ * so without this the second press of a repeated step always acts on the
700
+ * last digit. With it, the digit under the caret stays under the caret and
701
+ * a column can be held while stepping.
702
+ *
703
+ * The position is measured from the decimal point rather than from either
704
+ * end, so it survives the number growing or shrinking: the caret between
705
+ * `9` and `.9` is still between `10` and `.0`.
706
+ *
707
+ * It only restores the caret. Which digit it sits on does not change the
708
+ * size of the step — that is `keyboard`'s to say.
709
+ *
710
+ * @default false
711
+ */
712
+ keepCaretOnStep?: boolean;
713
+ /**
714
+ * Commit and leave `InputField` when Enter is pressed. Enter commits either
715
+ * way.
716
+ * @default true
717
+ */
718
+ blurOnEnter?: boolean;
719
+ /**
720
+ * Make the input unchangeable and remove it from the tab order.
721
+ * The parts carry `data-disabled` while it is set.
380
722
  */
381
723
  disabled?: boolean;
382
724
  /**
383
725
  * Make the value unchangeable.
384
- * aria-readonly property is also applied.
726
+ * The parts carry `data-readonly` while it is set.
385
727
  */
386
728
  readonly?: boolean;
387
- className?: string;
388
- style?: CSSProperties;
729
+ /**
730
+ * Called with the new value. While the user types, it is called for every
731
+ * entry that reads as a number, unclamped; committing the entry calls it
732
+ * again if clamping changes the value.
733
+ */
389
734
  onChange?: (value: number) => void;
390
735
  /**
391
736
  * The input renders exactly what you compose here; there is no default
@@ -409,15 +754,324 @@ interface NumberInputMethods {
409
754
  /**
410
755
  * Input with some useful functions for entering numerical values.
411
756
  */
412
- declare const NumberInput: {
413
- Root: _$react.ForwardRefExoticComponent<NumberInputProps & Omit<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof NumberInputProps> & _$react.RefAttributes<NumberInputMethods>>;
414
- InputField: typeof InputField;
415
- Stepper: typeof Stepper;
757
+ export declare const NumberInput: {
758
+ Root: import("react").ForwardRefExoticComponent<NumberInputProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof NumberInputProps> & import("react").RefAttributes<NumberInputMethods>>;
759
+ InputField: import("react").ForwardRefExoticComponent<{
760
+ form?: string | undefined | undefined;
761
+ slot?: string | undefined | undefined;
762
+ style?: import("react").CSSProperties | undefined;
763
+ title?: string | undefined | undefined;
764
+ pattern?: string | undefined | undefined;
765
+ key?: import("react").Key | null | undefined;
766
+ height?: number | string | undefined | undefined;
767
+ width?: number | string | undefined | undefined;
768
+ defaultChecked?: boolean | undefined | undefined;
769
+ suppressContentEditableWarning?: boolean | undefined | undefined;
770
+ suppressHydrationWarning?: boolean | undefined | undefined;
771
+ accessKey?: string | undefined | undefined;
772
+ autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
773
+ autoFocus?: boolean | undefined | undefined;
774
+ className?: string | undefined | undefined;
775
+ contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
776
+ contextMenu?: string | undefined | undefined;
777
+ dir?: string | undefined | undefined;
778
+ draggable?: (boolean | "true" | "false") | undefined;
779
+ enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
780
+ hidden?: boolean | undefined | undefined;
781
+ id?: string | undefined | undefined;
782
+ lang?: string | undefined | undefined;
783
+ nonce?: string | undefined | undefined;
784
+ spellCheck?: (boolean | "true" | "false") | undefined;
785
+ tabIndex?: number | undefined | undefined;
786
+ translate?: "yes" | "no" | undefined | undefined;
787
+ radioGroup?: string | undefined | undefined;
788
+ role?: import("react").AriaRole | undefined;
789
+ about?: string | undefined | undefined;
790
+ content?: string | undefined | undefined;
791
+ datatype?: string | undefined | undefined;
792
+ inlist?: any;
793
+ prefix?: string | undefined | undefined;
794
+ property?: string | undefined | undefined;
795
+ rel?: string | undefined | undefined;
796
+ resource?: string | undefined | undefined;
797
+ rev?: string | undefined | undefined;
798
+ typeof?: string | undefined | undefined;
799
+ vocab?: string | undefined | undefined;
800
+ autoCorrect?: string | undefined | undefined;
801
+ autoSave?: string | undefined | undefined;
802
+ color?: string | undefined | undefined;
803
+ itemProp?: string | undefined | undefined;
804
+ itemScope?: boolean | undefined | undefined;
805
+ itemType?: string | undefined | undefined;
806
+ itemID?: string | undefined | undefined;
807
+ itemRef?: string | undefined | undefined;
808
+ results?: number | undefined | undefined;
809
+ security?: string | undefined | undefined;
810
+ unselectable?: "on" | "off" | undefined | undefined;
811
+ popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
812
+ popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
813
+ popoverTarget?: string | undefined | undefined;
814
+ inert?: boolean | undefined | undefined;
815
+ inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
816
+ is?: string | undefined | undefined;
817
+ exportparts?: string | undefined | undefined;
818
+ part?: string | undefined | undefined;
819
+ "aria-activedescendant"?: string | undefined | undefined;
820
+ "aria-atomic"?: (boolean | "true" | "false") | undefined;
821
+ "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
822
+ "aria-braillelabel"?: string | undefined | undefined;
823
+ "aria-brailleroledescription"?: string | undefined | undefined;
824
+ "aria-busy"?: (boolean | "true" | "false") | undefined;
825
+ "aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
826
+ "aria-colcount"?: number | undefined | undefined;
827
+ "aria-colindex"?: number | undefined | undefined;
828
+ "aria-colindextext"?: string | undefined | undefined;
829
+ "aria-colspan"?: number | undefined | undefined;
830
+ "aria-controls"?: string | undefined | undefined;
831
+ "aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
832
+ "aria-describedby"?: string | undefined | undefined;
833
+ "aria-description"?: string | undefined | undefined;
834
+ "aria-details"?: string | undefined | undefined;
835
+ "aria-disabled"?: (boolean | "true" | "false") | undefined;
836
+ "aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
837
+ "aria-errormessage"?: string | undefined | undefined;
838
+ "aria-expanded"?: (boolean | "true" | "false") | undefined;
839
+ "aria-flowto"?: string | undefined | undefined;
840
+ "aria-grabbed"?: (boolean | "true" | "false") | undefined;
841
+ "aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
842
+ "aria-hidden"?: (boolean | "true" | "false") | undefined;
843
+ "aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
844
+ "aria-keyshortcuts"?: string | undefined | undefined;
845
+ "aria-label"?: string | undefined | undefined;
846
+ "aria-labelledby"?: string | undefined | undefined;
847
+ "aria-level"?: number | undefined | undefined;
848
+ "aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
849
+ "aria-modal"?: (boolean | "true" | "false") | undefined;
850
+ "aria-multiline"?: (boolean | "true" | "false") | undefined;
851
+ "aria-multiselectable"?: (boolean | "true" | "false") | undefined;
852
+ "aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
853
+ "aria-owns"?: string | undefined | undefined;
854
+ "aria-placeholder"?: string | undefined | undefined;
855
+ "aria-posinset"?: number | undefined | undefined;
856
+ "aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
857
+ "aria-readonly"?: (boolean | "true" | "false") | undefined;
858
+ "aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
859
+ "aria-required"?: (boolean | "true" | "false") | undefined;
860
+ "aria-roledescription"?: string | undefined | undefined;
861
+ "aria-rowcount"?: number | undefined | undefined;
862
+ "aria-rowindex"?: number | undefined | undefined;
863
+ "aria-rowindextext"?: string | undefined | undefined;
864
+ "aria-rowspan"?: number | undefined | undefined;
865
+ "aria-selected"?: (boolean | "true" | "false") | undefined;
866
+ "aria-setsize"?: number | undefined | undefined;
867
+ "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
868
+ "aria-valuemax"?: number | undefined | undefined;
869
+ "aria-valuemin"?: number | undefined | undefined;
870
+ "aria-valuenow"?: number | undefined | undefined;
871
+ "aria-valuetext"?: string | undefined | undefined;
872
+ children?: ReactNode;
873
+ dangerouslySetInnerHTML?: {
874
+ __html: string | TrustedHTML;
875
+ } | undefined | undefined;
876
+ onCopy?: import("react").ClipboardEventHandler<HTMLInputElement> | undefined;
877
+ onCopyCapture?: import("react").ClipboardEventHandler<HTMLInputElement> | undefined;
878
+ onCut?: import("react").ClipboardEventHandler<HTMLInputElement> | undefined;
879
+ onCutCapture?: import("react").ClipboardEventHandler<HTMLInputElement> | undefined;
880
+ onPaste?: import("react").ClipboardEventHandler<HTMLInputElement> | undefined;
881
+ onPasteCapture?: import("react").ClipboardEventHandler<HTMLInputElement> | undefined;
882
+ onCompositionEnd?: import("react").CompositionEventHandler<HTMLInputElement> | undefined;
883
+ onCompositionEndCapture?: import("react").CompositionEventHandler<HTMLInputElement> | undefined;
884
+ onCompositionStart?: import("react").CompositionEventHandler<HTMLInputElement> | undefined;
885
+ onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLInputElement> | undefined;
886
+ onCompositionUpdate?: import("react").CompositionEventHandler<HTMLInputElement> | undefined;
887
+ onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLInputElement> | undefined;
888
+ onFocus?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
889
+ onFocusCapture?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
890
+ onBlur?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
891
+ onBlurCapture?: import("react").FocusEventHandler<HTMLInputElement> | undefined;
892
+ onChange?: import("react").ChangeEventHandler<HTMLInputElement, HTMLInputElement> | undefined;
893
+ onChangeCapture?: import("react").ChangeEventHandler<HTMLInputElement, Element> | undefined;
894
+ onBeforeInput?: import("react").InputEventHandler<HTMLInputElement> | undefined;
895
+ onBeforeInputCapture?: import("react").InputEventHandler<HTMLInputElement> | undefined;
896
+ onInput?: import("react").InputEventHandler<HTMLInputElement> | undefined;
897
+ onInputCapture?: import("react").InputEventHandler<HTMLInputElement> | undefined;
898
+ onReset?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
899
+ onResetCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
900
+ onSubmit?: import("react").SubmitEventHandler<HTMLInputElement> | undefined;
901
+ onSubmitCapture?: import("react").SubmitEventHandler<HTMLInputElement> | undefined;
902
+ onInvalid?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
903
+ onInvalidCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
904
+ onLoad?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
905
+ onLoadCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
906
+ onError?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
907
+ onErrorCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
908
+ onKeyDown?: import("react").KeyboardEventHandler<HTMLInputElement> | undefined;
909
+ onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLInputElement> | undefined;
910
+ onKeyPress?: import("react").KeyboardEventHandler<HTMLInputElement> | undefined;
911
+ onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLInputElement> | undefined;
912
+ onKeyUp?: import("react").KeyboardEventHandler<HTMLInputElement> | undefined;
913
+ onKeyUpCapture?: import("react").KeyboardEventHandler<HTMLInputElement> | undefined;
914
+ onAbort?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
915
+ onAbortCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
916
+ onCanPlay?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
917
+ onCanPlayCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
918
+ onCanPlayThrough?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
919
+ onCanPlayThroughCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
920
+ onDurationChange?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
921
+ onDurationChangeCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
922
+ onEmptied?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
923
+ onEmptiedCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
924
+ onEncrypted?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
925
+ onEncryptedCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
926
+ onEnded?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
927
+ onEndedCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
928
+ onLoadedData?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
929
+ onLoadedDataCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
930
+ onLoadedMetadata?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
931
+ onLoadedMetadataCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
932
+ onLoadStart?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
933
+ onLoadStartCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
934
+ onPause?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
935
+ onPauseCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
936
+ onPlay?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
937
+ onPlayCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
938
+ onPlaying?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
939
+ onPlayingCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
940
+ onProgress?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
941
+ onProgressCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
942
+ onRateChange?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
943
+ onRateChangeCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
944
+ onSeeked?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
945
+ onSeekedCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
946
+ onSeeking?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
947
+ onSeekingCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
948
+ onStalled?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
949
+ onStalledCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
950
+ onSuspend?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
951
+ onSuspendCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
952
+ onTimeUpdate?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
953
+ onTimeUpdateCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
954
+ onVolumeChange?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
955
+ onVolumeChangeCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
956
+ onWaiting?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
957
+ onWaitingCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
958
+ onAuxClick?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
959
+ onAuxClickCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
960
+ onClick?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
961
+ onClickCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
962
+ onContextMenu?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
963
+ onContextMenuCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
964
+ onDoubleClick?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
965
+ onDoubleClickCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
966
+ onDrag?: import("react").DragEventHandler<HTMLInputElement> | undefined;
967
+ onDragCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
968
+ onDragEnd?: import("react").DragEventHandler<HTMLInputElement> | undefined;
969
+ onDragEndCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
970
+ onDragEnter?: import("react").DragEventHandler<HTMLInputElement> | undefined;
971
+ onDragEnterCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
972
+ onDragExit?: import("react").DragEventHandler<HTMLInputElement> | undefined;
973
+ onDragExitCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
974
+ onDragLeave?: import("react").DragEventHandler<HTMLInputElement> | undefined;
975
+ onDragLeaveCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
976
+ onDragOver?: import("react").DragEventHandler<HTMLInputElement> | undefined;
977
+ onDragOverCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
978
+ onDragStart?: import("react").DragEventHandler<HTMLInputElement> | undefined;
979
+ onDragStartCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
980
+ onDrop?: import("react").DragEventHandler<HTMLInputElement> | undefined;
981
+ onDropCapture?: import("react").DragEventHandler<HTMLInputElement> | undefined;
982
+ onMouseDown?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
983
+ onMouseDownCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
984
+ onMouseEnter?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
985
+ onMouseLeave?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
986
+ onMouseMove?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
987
+ onMouseMoveCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
988
+ onMouseOut?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
989
+ onMouseOutCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
990
+ onMouseOver?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
991
+ onMouseOverCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
992
+ onMouseUp?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
993
+ onMouseUpCapture?: import("react").MouseEventHandler<HTMLInputElement> | undefined;
994
+ onSelect?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
995
+ onSelectCapture?: import("react").ReactEventHandler<HTMLInputElement> | undefined;
996
+ onTouchCancel?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
997
+ onTouchCancelCapture?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
998
+ onTouchEnd?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
999
+ onTouchEndCapture?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
1000
+ onTouchMove?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
1001
+ onTouchMoveCapture?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
1002
+ onTouchStart?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
1003
+ onTouchStartCapture?: import("react").TouchEventHandler<HTMLInputElement> | undefined;
1004
+ onPointerDown?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1005
+ onPointerDownCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1006
+ onPointerMove?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1007
+ onPointerMoveCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1008
+ onPointerUp?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1009
+ onPointerUpCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1010
+ onPointerCancel?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1011
+ onPointerCancelCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1012
+ onPointerEnter?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1013
+ onPointerLeave?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1014
+ onPointerOver?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1015
+ onPointerOverCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1016
+ onPointerOut?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1017
+ onPointerOutCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1018
+ onGotPointerCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1019
+ onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1020
+ onLostPointerCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1021
+ onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLInputElement> | undefined;
1022
+ onScroll?: import("react").UIEventHandler<HTMLInputElement> | undefined;
1023
+ onScrollCapture?: import("react").UIEventHandler<HTMLInputElement> | undefined;
1024
+ onScrollEnd?: import("react").UIEventHandler<HTMLInputElement> | undefined;
1025
+ onScrollEndCapture?: import("react").UIEventHandler<HTMLInputElement> | undefined;
1026
+ onWheel?: import("react").WheelEventHandler<HTMLInputElement> | undefined;
1027
+ onWheelCapture?: import("react").WheelEventHandler<HTMLInputElement> | undefined;
1028
+ onAnimationStart?: import("react").AnimationEventHandler<HTMLInputElement> | undefined;
1029
+ onAnimationStartCapture?: import("react").AnimationEventHandler<HTMLInputElement> | undefined;
1030
+ onAnimationEnd?: import("react").AnimationEventHandler<HTMLInputElement> | undefined;
1031
+ onAnimationEndCapture?: import("react").AnimationEventHandler<HTMLInputElement> | undefined;
1032
+ onAnimationIteration?: import("react").AnimationEventHandler<HTMLInputElement> | undefined;
1033
+ onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLInputElement> | undefined;
1034
+ onToggle?: import("react").ToggleEventHandler<HTMLInputElement> | undefined;
1035
+ onBeforeToggle?: import("react").ToggleEventHandler<HTMLInputElement> | undefined;
1036
+ onTransitionCancel?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1037
+ onTransitionCancelCapture?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1038
+ onTransitionEnd?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1039
+ onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1040
+ onTransitionRun?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1041
+ onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1042
+ onTransitionStart?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1043
+ onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLInputElement> | undefined;
1044
+ min?: number | string | undefined | undefined;
1045
+ max?: number | string | undefined | undefined;
1046
+ step?: number | string | undefined | undefined;
1047
+ disabled?: boolean | undefined | undefined;
1048
+ alt?: string | undefined | undefined;
1049
+ accept?: string | undefined | undefined;
1050
+ multiple?: boolean | undefined | undefined;
1051
+ size?: number | undefined | undefined;
1052
+ autoComplete?: import("react").HTMLInputAutoCompleteAttribute | undefined;
1053
+ capture?: boolean | "user" | "environment" | undefined | undefined;
1054
+ checked?: boolean | undefined | undefined;
1055
+ formAction?: string | ((formData: FormData) => void | Promise<void>) | undefined;
1056
+ formEncType?: string | undefined | undefined;
1057
+ formMethod?: string | undefined | undefined;
1058
+ formNoValidate?: boolean | undefined | undefined;
1059
+ formTarget?: string | undefined | undefined;
1060
+ list?: string | undefined | undefined;
1061
+ maxLength?: number | undefined | undefined;
1062
+ minLength?: number | undefined | undefined;
1063
+ name?: string | undefined | undefined;
1064
+ placeholder?: string | undefined | undefined;
1065
+ readOnly?: boolean | undefined | undefined;
1066
+ required?: boolean | undefined | undefined;
1067
+ src?: string | undefined | undefined;
1068
+ } & import("react").RefAttributes<HTMLInputElement>>;
1069
+ Stepper: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
416
1070
  IncrementStepper: typeof IncrementStepper;
417
1071
  DecrementStepper: typeof DecrementStepper;
418
1072
  };
419
1073
  //#endregion
420
- //#region src/components/Piano/keyboardShortcuts.d.ts
1074
+ //#region src/components/Piano/keyboard-shortcuts.d.ts
421
1075
  type KeyboardShortcuts = {
422
1076
  /**
423
1077
  * Keys laid out from `noteRange.first`, one entry per semitone.
@@ -432,21 +1086,19 @@ type KeyboardShortcuts = {
432
1086
  /**
433
1087
  * Ready-made keyboard layouts. Both assume `noteRange.first` is a C.
434
1088
  */
435
- declare const SHORTCUTS: {
436
- /** Every semitone from C, over the two rows of a QWERTY keyboard. */HOME_ROW: {
1089
+ export declare const SHORTCUTS: {
1090
+ /** Every semitone from C, over the two rows of a QWERTY keyboard. */
1091
+ HOME_ROW: {
437
1092
  keys: string[];
438
- }; /** The white keys only, on the home row. Black keys have no shortcut. */
1093
+ };
1094
+ /** The white keys only, on the home row. Black keys have no shortcut. */
439
1095
  HOME_ROW_NATURAL: {
440
1096
  keys: string[];
441
1097
  };
442
1098
  };
443
1099
  //#endregion
444
1100
  //#region src/components/Piano/index.d.ts
445
- /**
446
- * `style` that also takes CSS custom properties, which is how a key's colours
447
- * are set: see `index.css` for the ones each key type reads.
448
- */
449
- type CSSVariables = Record<`--${string}`, string | number | undefined>;
1101
+ type KeyboardShortcutsScope = 'root' | 'window';
450
1102
  /**
451
1103
  * What {@link PianoProps.keyProps} may return for one key.
452
1104
  *
@@ -455,7 +1107,7 @@ type CSSVariables = Record<`--${string}`, string | number | undefined>;
455
1107
  * mark a key out.
456
1108
  */
457
1109
  type KeyAttributes = Omit<ComponentPropsWithoutRef<'div'>, 'style'> & {
458
- style?: CSSProperties & CSSVariables;
1110
+ style?: CSSProperties & CSSVariables<'color' | 'bg' | 'active-color' | 'active-bg'>;
459
1111
  } & Record<`data-${string}`, string | number | boolean | undefined>;
460
1112
  /** What a key is, when {@link PianoProps.label} or `keyProps` is asked about it. */
461
1113
  interface KeyState {
@@ -468,31 +1120,62 @@ interface KeyState {
468
1120
  disabled: boolean;
469
1121
  }
470
1122
  interface PianoProps {
1123
+ /**
1124
+ * Classes for what a key draws inside itself: `keyLabelWrapper`, and
1125
+ * `keyLabel` around what `label` returns. The key itself takes a class
1126
+ * through `keyProps`, which is also where the note and its state are.
1127
+ */
1128
+ classes?: {
1129
+ keyLabelWrapper?: string;
1130
+ keyLabel?: string;
1131
+ };
1132
+ /**
1133
+ * The notes to draw keys for, as MIDI note numbers from `first` to `last`,
1134
+ * both included.
1135
+ */
471
1136
  noteRange: NoteRange;
472
1137
  /**
473
- * Let a pointer slide from one key to the next while it is down.
1138
+ * Let a pointer slide from one key to the next while it is down. With it
1139
+ * off, the key that was pressed sounds until the pointer is released.
474
1140
  *
475
1141
  * @default true
476
1142
  */
477
1143
  glissando?: boolean;
478
1144
  /**
479
- * Highest note that can sound. Keys above it are drawn `aria-disabled`.
1145
+ * Highest note that can sound. Keys above it carry `data-disabled`.
480
1146
  *
481
1147
  * @default 127
482
1148
  */
483
1149
  midiMax?: number;
1150
+ /**
1151
+ * Play notes from the computer keyboard: `keys[i]` plays
1152
+ * `noteRange.first + i`. `SHORTCUTS` has ready-made layouts, which assume
1153
+ * `noteRange.first` is a C. Where they listen is `keyboardShortcutsScope`.
1154
+ */
484
1155
  keyboardShortcuts?: KeyboardShortcuts;
485
1156
  /**
486
- * Fill the parent element, deriving the width of a white key from it.
487
- * {@link PianoProps.whiteKeyWidth} is ignored.
1157
+ * Where keyboard shortcuts listen. `root` handles keys only while the Piano
1158
+ * root or one of its descendants has focus; `window` handles them anywhere
1159
+ * on the page except in editable elements.
1160
+ *
1161
+ * @default 'root'
1162
+ */
1163
+ keyboardShortcutsScope?: KeyboardShortcutsScope;
1164
+ /**
1165
+ * Follow the width of the parent element, deriving the width of a white key
1166
+ * from it. {@link PianoProps.whiteKeyWidth} is ignored.
488
1167
  *
489
1168
  * @default false
490
1169
  */
491
- fill?: boolean;
492
- /** @default 40 */
1170
+ resizable?: boolean;
1171
+ /**
1172
+ * Width of a white key in pixels, not counting `keyGap`. Ignored while
1173
+ * `resizable` is on.
1174
+ * @default 40
1175
+ */
493
1176
  whiteKeyWidth?: number;
494
1177
  /**
495
- * Space between two white keys.
1178
+ * Space between two white keys, in pixels.
496
1179
  * @default 1
497
1180
  */
498
1181
  keyGap?: number;
@@ -506,9 +1189,12 @@ interface PianoProps {
506
1189
  * @default 0.6
507
1190
  */
508
1191
  blackKeyHeightRatio?: number;
509
- /** @default `fill ? '100%' : 160` */
1192
+ /**
1193
+ * Height of the keyboard. Sets `--height`; when it is omitted, the height
1194
+ * the theme gives stands, and the theme can tell `resizable` apart through
1195
+ * `data-resizable`.
1196
+ */
510
1197
  height?: number | string;
511
- style?: CSSProperties & CSSVariables;
512
1198
  /**
513
1199
  * What to draw inside a key. `''`, `null` and `undefined` leave it bare, so
514
1200
  * a layout with gaps — {@link SHORTCUTS.HOME_ROW_NATURAL}, say — needs no
@@ -525,12 +1211,20 @@ interface PianoProps {
525
1211
  *
526
1212
  * @example highlight the notes of a scale
527
1213
  * ```tsx
528
- * keyProps={(note) => ({ 'data-in-scale': inScale(note, root, 'major') })}
1214
+ * keyProps={(note) => ({ 'data-in-scale': inScale(note, root, 'major') ? '' : undefined })}
529
1215
  * ```
530
1216
  */
531
1217
  keyProps?: (note: number, state: KeyState) => KeyAttributes;
1218
+ /**
1219
+ * Called when a note starts sounding, whether a pointer, a keyboard shortcut
1220
+ * or `playNote` asked for it. A note held by several of them at once is
1221
+ * reported once. `velocity` is what `playNote` was given, and `undefined`
1222
+ * otherwise.
1223
+ */
532
1224
  onPlayNote?: (note: number, velocity?: number) => void;
1225
+ /** Called once everything holding a note has let go of it. */
533
1226
  onStopNote?: (note: number) => void;
1227
+ style?: CSSProperties & CSSVariables<'height'>;
534
1228
  }
535
1229
  interface PianoMethods {
536
1230
  playNote: (note: number, velocity?: number) => void;
@@ -539,141 +1233,263 @@ interface PianoMethods {
539
1233
  /**
540
1234
  * Customizable piano component.
541
1235
  */
542
- declare const Piano: {
543
- Root: _$react.ForwardRefExoticComponent<PianoProps & Omit<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof PianoProps> & _$react.RefAttributes<PianoMethods>>;
1236
+ export declare const Piano: {
1237
+ Root: import("react").ForwardRefExoticComponent<PianoProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof PianoProps> & import("react").RefAttributes<PianoMethods>>;
544
1238
  };
545
1239
  //#endregion
546
1240
  //#region src/components/PointsEditor/Background.d.ts
547
- interface PointsEditorBackgroundProps {
548
- /** Whatever the points are placed over: a graph, a canvas, an image. */
549
- children?: ReactNode;
550
- }
551
- declare function Background({
552
- className,
553
- children,
554
- ...props
555
- }: PointsEditorBackgroundProps & Omit<ComponentPropsWithoutRef<'div'>, keyof PointsEditorBackgroundProps>): _$react.JSX.Element;
556
- //#endregion
557
- //#region src/components/PointsEditor/Container.d.ts
558
- interface PointsEditorContainerProps {
559
- /** `<PointsEditor.Point />` goes here. */
560
- children?: ReactNode;
561
- ref?: Ref<HTMLDivElement>;
562
- }
563
- declare function Container({
564
- children,
565
- className,
566
- ref,
567
- ...props
568
- }: PointsEditorContainerProps & Omit<ComponentPropsWithoutRef<'div'>, keyof PointsEditorContainerProps>): _$react.JSX.Element;
1241
+ declare function Background({ className, children, style, ...props }: ComponentPropsWithoutRef<'div'>): import("react").JSX.Element;
569
1242
  //#endregion
570
1243
  //#region src/components/PointsEditor/Point.d.ts
571
1244
  type PointBaseType = {
572
1245
  x: number;
573
1246
  y: number;
574
1247
  };
575
- declare function clampPoint(point: PointBaseType, min?: Partial<PointBaseType>, max?: Partial<PointBaseType>): {
1248
+ export declare function clampPoint(point: PointBaseType, min?: Partial<PointBaseType>, max?: Partial<PointBaseType>): {
576
1249
  x: number;
577
1250
  y: number;
578
1251
  };
579
- interface PointProps<T extends PointBaseType> {
1252
+ interface PointsEditorPointProps<T extends PointBaseType> {
1253
+ /**
1254
+ * Where the point is, as `{ x, y }` from 0 to 1 on each axis, with `y`
1255
+ * growing downwards.
1256
+ */
580
1257
  value: T;
1258
+ /**
1259
+ * How the selection refers to this point. One is generated when it is left
1260
+ * out, which lasts as long as the point is mounted — give your own if the
1261
+ * selection has to survive a remount, or be recognised in your own state.
1262
+ */
1263
+ id?: string;
1264
+ /** The lowest position the point can take, per axis. An axis left out is 0. */
581
1265
  min?: Partial<PointBaseType>;
1266
+ /** The highest position the point can take, per axis. An axis left out is 1. */
582
1267
  max?: Partial<PointBaseType>;
1268
+ /** Width and height at once. Sets both `--width` and `--height`. */
583
1269
  size?: number | string;
1270
+ /** Sets `--width`; the size the theme gives it stands when omitted. */
584
1271
  width?: number | string;
1272
+ /** Sets `--height`; the size the theme gives it stands when omitted. */
585
1273
  height?: number | string;
1274
+ /** Sets `--color`, for the theme to colour the point with. */
586
1275
  color?: string;
587
1276
  /** Overrides the `disabled` of `PointsEditor.Root`. */
588
1277
  disabled?: boolean;
589
1278
  /** Overrides the `readonly` of `PointsEditor.Root`. */
590
1279
  readonly?: boolean;
591
1280
  /** Overrides the `wheel` of `PointsEditor.Root`. */
592
- wheel?: InputEventOption | null;
1281
+ wheel?: ModifierValue<InputEventOption> | null;
593
1282
  /** Overrides the `keyboard` of `PointsEditor.Root`. */
594
- keyboard?: InputEventOption | null;
1283
+ keyboard?: ModifierValue<InputEventOption> | null;
1284
+ /**
1285
+ * The accessible name of each axis. There are two range inputs inside the
1286
+ * point, so this takes one name per axis; a single string names them both.
1287
+ */
1288
+ 'aria-label'?: string | Partial<Record<'x' | 'y', string>>;
1289
+ /** What the value of each axis means, when the number does not say it. */
1290
+ 'aria-valuetext'?: string | Partial<Record<'x' | 'y', string>>;
1291
+ /**
1292
+ * Called with the new position when the point is dragged or moved by the
1293
+ * arrow keys or the wheel, including when it moves along with a selection.
1294
+ */
595
1295
  onChange?: (value: PointBaseType) => void;
1296
+ /** Called when a drag on this point starts, with where the point is. */
596
1297
  onDragStart?: (value: PointBaseType) => void;
1298
+ /** Called when that drag ends, with where the point is. */
597
1299
  onDragEnd?: (value: PointBaseType) => void;
1300
+ style?: CSSProperties & CSSVariables<'width' | 'height' | 'color' | 'translate'>;
598
1301
  }
599
- declare function Point<T extends PointBaseType>({
600
- value,
601
- min,
602
- max,
603
- size,
604
- width,
605
- height,
606
- color,
607
- disabled: _disabled,
608
- readonly: _readonly,
609
- wheel: _wheel,
610
- keyboard: _keyboard,
611
- onChange,
612
- onDragStart,
613
- onDragEnd,
614
- className,
615
- style,
616
- onPointerDown,
617
- onKeyDown,
618
- ...props
619
- }: PointProps<T> & Omit<ComponentPropsWithoutRef<'div'>, keyof PointProps<T>>): _$react.JSX.Element;
1302
+ declare function Point<T extends PointBaseType>({ value, children, id: idProp, min, max, size, width, height, color, disabled: _disabled, readonly: _readonly, wheel: _wheel, keyboard: _keyboard, 'aria-label': ariaLabel, 'aria-valuetext': ariaValuetext, onChange, onDragStart, onDragEnd, className, style, onPointerDown, onKeyDown, onFocus, ...props }: PointsEditorPointProps<T> & Omit<ComponentPropsWithoutRef<'div'>, keyof PointsEditorPointProps<T>>): import("react").JSX.Element;
1303
+ //#endregion
1304
+ //#region src/components/PointsEditor/SelectionBox.d.ts
1305
+ /**
1306
+ * The box a drag on empty space draws, and what it covers is selected.
1307
+ *
1308
+ * Nothing is rendered while no drag is running, and leaving it out leaves the
1309
+ * editor without one — the selection still works, it just cannot be seen.
1310
+ */
1311
+ declare function SelectionBox({ children, className, style, ...props }: ComponentPropsWithoutRef<'div'>): import("react").JSX.Element | null;
620
1312
  //#endregion
621
1313
  //#region src/components/PointsEditor/context.d.ts
1314
+ /**
1315
+ * What a `Point` tells the editor about itself, so that a selection can be
1316
+ * moved without the editor knowing how the points are stored.
1317
+ *
1318
+ * Held behind a ref and rewritten on every render: the value changes on every
1319
+ * frame of a drag, and a registry keyed on it would be rebuilt just as often.
1320
+ */
1321
+ interface PointRegistration {
1322
+ value: PointBaseType;
1323
+ min?: Partial<PointBaseType>;
1324
+ max?: Partial<PointBaseType>;
1325
+ readonly: boolean;
1326
+ onChange?: (value: PointBaseType) => void;
1327
+ /** The point's own element, to match the focus against. */
1328
+ element: HTMLElement | null;
1329
+ /** The wheel option this point resolved, root inheritance applied. */
1330
+ wheel: ModifierValue<InputEventOption> | null;
1331
+ }
622
1332
  type PointsEditorContextValue = {
623
1333
  disabled: boolean;
624
- readonly: boolean; /** Inherited by every `Point`; `null` turns the wheel off. */
625
- wheel: InputEventOption | null; /** Inherited by every `Point`; `null` turns the keyboard off. */
626
- keyboard: InputEventOption | null;
1334
+ readonly: boolean;
1335
+ /** Inherited by every `Point`; `null` turns the wheel off. */
1336
+ wheel: ModifierValue<InputEventOption> | null;
1337
+ /** Inherited by every `Point`; `null` turns the keyboard off. */
1338
+ keyboard: ModifierValue<InputEventOption> | null;
1339
+ /** Inherited by every `Point`. See `PointsEditorProps.dragSensitivity`. */
1340
+ dragSensitivity: ModifierValue<number>;
627
1341
  externalStyles: {
628
- userSelectNone?: boolean;
629
- cursor?: Cursor;
1342
+ cursor?: CSSProperties['cursor'];
630
1343
  };
631
1344
  /**
632
1345
  * `Container` registers its element here; `Point` normalizes the pointer
633
1346
  * against it, so a point is placed by its position within the container.
634
1347
  */
635
1348
  containerRef: RefObject<HTMLDivElement | null>;
1349
+ /** Whether points can be selected at all. See `PointsEditorProps.selectable`. */
1350
+ selectable: boolean;
1351
+ /** Ids of the points currently selected. Always empty while `selectable` is off. */
1352
+ selection: readonly string[];
1353
+ /** Register a point so that a selection can move it with the rest. */
1354
+ registerPoint: (id: string, entry: RefObject<PointRegistration>) => () => void;
1355
+ /**
1356
+ * Whether the element is a point, or inside one. The registry knows which
1357
+ * elements the points are, so nothing has to be recognised by a class name.
1358
+ */
1359
+ isPointElement: (element: Element | null | undefined) => boolean;
1360
+ /**
1361
+ * A pointer went down on a point: works out the new selection and takes the
1362
+ * snapshot the move will be measured against.
1363
+ */
1364
+ beginPointDrag: (id: string, modifiers: ModifierState) => void;
1365
+ /** Move everything the drag picked up, by one amount, clamped as one. */
1366
+ movePointDrag: (delta: PointBaseType) => void;
1367
+ /**
1368
+ * Move the selection by an amount that did not come from a drag — an arrow
1369
+ * key or a wheel notch. The current values are the starting point.
1370
+ */
1371
+ nudgeSelection: (id: string, delta: PointBaseType) => void;
1372
+ /**
1373
+ * Move the point that currently holds focus by one notch. The wheel listener
1374
+ * belongs to `Container` rather than to every `Point`, so the lookup of who
1375
+ * has focus happens here, where the registry is. Returns whether a point
1376
+ * took it, so the caller knows whether to consume the event.
1377
+ */
1378
+ nudgeFocusedPoint: (axis: 'x' | 'y', direction: number, modifiers: ModifierState) => boolean;
1379
+ /** The selection box, while one is being dragged. */
1380
+ selectionBox: SelectionBoxRect | null;
1381
+ beginSelectionBox: (at: PointBaseType, modifiers: ModifierState) => void;
1382
+ moveSelectionBox: (to: PointBaseType) => void;
1383
+ endSelectionBox: () => void;
636
1384
  };
637
1385
  /**
638
- * The settings `Root` was given, for the subcomponents to read. There is no
639
- * state to keep in sync: a point's value belongs to the `Point` that draws it.
1386
+ * The settings `Root` was given, for the subcomponents to read. A point's
1387
+ * value still belongs to the `Point` that draws it; what the root keeps is
1388
+ * which points are selected, and a registry of who they are.
640
1389
  */
641
- declare function usePointsEditorContext(): PointsEditorContextValue;
642
- declare function usePointsEditorContext<T>(selector: (state: PointsEditorContextValue) => T): T;
1390
+ export declare function usePointsEditorContext(): PointsEditorContextValue;
1391
+ export declare function usePointsEditorContext<T>(selector: (state: PointsEditorContextValue) => T): T;
643
1392
  //#endregion
644
1393
  //#region src/components/PointsEditor/index.d.ts
645
1394
  interface PointsEditorProps {
1395
+ /** Sets `--width`; the size the theme gives it stands when omitted. */
646
1396
  width?: number | string;
1397
+ /** Sets `--height`; the size the theme gives it stands when omitted. */
647
1398
  height?: number | string;
648
1399
  /**
649
- * Only the appearance will change.
650
- * Please consider using with readonly.
651
- * aria-disabled property is also applied.
1400
+ * Make the points unchangeable and remove them from the tab order.
1401
+ * The parts carry `data-disabled` while it is set.
652
1402
  */
653
1403
  disabled?: boolean;
654
1404
  /**
655
1405
  * Make the points unmovable.
656
- * aria-readonly property is also applied.
1406
+ * The parts carry `data-readonly` while it is set.
657
1407
  */
658
1408
  readonly?: boolean;
1409
+ /**
1410
+ * The cursor to show while dragging a point. It is set on the dragged
1411
+ * point, so it stays while the pointer is outside it.
1412
+ *
1413
+ * @default { cursor: 'grabbing' }
1414
+ */
659
1415
  externalStyles?: {
660
- userSelectNone?: boolean;
661
- cursor?: Cursor;
1416
+ cursor?: CSSProperties['cursor'];
662
1417
  };
663
1418
  /**
664
- * wheel control option for every `Point`. Shift selects the x axis.
665
- * If null, no event will be triggered
1419
+ * How much one notch of the wheel moves the focused `Point`. Scrolling
1420
+ * sideways, or with shift held, moves x; otherwise it moves y.
666
1421
  *
667
- * A `Point` can override it with a `wheel` of its own.
1422
+ * A position runs from 0 to 1, so `['normalized', n]` and `['raw', n]` both
1423
+ * move it by `n` of the editor. `null` turns the wheel off, and a `Point`
1424
+ * can override it with a `wheel` of its own.
1425
+ *
1426
+ * @default ['normalized', 0.01]
668
1427
  */
669
- wheel?: InputEventOption | null;
1428
+ wheel?: ModifierValue<InputEventOption> | null;
670
1429
  /**
671
- * keyboard control option for every `Point`, on the arrow keys.
672
- * If null, no event will be triggered
1430
+ * How much one arrow key press moves a `Point`. Left and right move x, up
1431
+ * and down move y.
1432
+ *
1433
+ * A position runs from 0 to 1, so `['normalized', n]` and `['raw', n]` both
1434
+ * move it by `n` of the editor; give a map to set an amount per modifier
1435
+ * key. `null` turns the arrow keys off, and a `Point` can override it with a
1436
+ * `keyboard` of its own.
673
1437
  *
674
- * A `Point` can override it with a `keyboard` of its own.
1438
+ * @default { default: ['normalized', 0.01], shift: ['normalized', 0.001] }
675
1439
  */
676
- keyboard?: InputEventOption | null;
1440
+ keyboard?: ModifierValue<InputEventOption> | null;
1441
+ /**
1442
+ * How much a drag moves a `Point`, per modifier key.
1443
+ *
1444
+ * `1` is the pointer position itself, which is what dragging a point
1445
+ * normally is. **Anything else turns the drag relative**: `0.1` makes the
1446
+ * same movement cover a tenth of the editor, so the point stops following
1447
+ * the pointer and starts moving a tenth as fast. Shift is bound to `0.1` by
1448
+ * default, to match what it does on the arrow keys.
1449
+ *
1450
+ * Pressing or releasing the key mid-drag does not disturb the point: the
1451
+ * travel so far is kept and the new sensitivity applies from there. **The
1452
+ * pointer and the point stay apart for the rest of the drag** — snapping
1453
+ * them back together on release would move the point nobody asked to move.
1454
+ *
1455
+ * @default { default: 1, shift: 0.1 }
1456
+ */
1457
+ dragSensitivity?: ModifierValue<number>;
1458
+ /**
1459
+ * Let points be selected, and a selection be moved as one.
1460
+ *
1461
+ * Off by default, because it changes what a press and a drag mean: a press
1462
+ * on empty space starts a selection box rather than doing nothing, and a drag
1463
+ * on a point moves everything else that is selected. An editor whose points
1464
+ * each mean something different — the four handles of an ADSR envelope, say
1465
+ * — has nothing to gain from moving them together.
1466
+ *
1467
+ * **A selection calls `onChange` on several points in the same tick**, so
1468
+ * each of them has to update from the previous state rather than from a
1469
+ * value captured in the render:
1470
+ *
1471
+ * ```jsx
1472
+ * onChange={(v) => setPoints((prev) => ({ ...prev, [id]: v }))}
1473
+ * ```
1474
+ *
1475
+ * Written the other way round — `setPoints({ ...points, [id]: v })` — every
1476
+ * call but the last is thrown away, and only one point appears to move.
1477
+ *
1478
+ * @default false
1479
+ */
1480
+ selectable?: boolean;
1481
+ /**
1482
+ * Ids of the selected points, to hold the selection yourself. Leave it out
1483
+ * and the editor keeps its own.
1484
+ *
1485
+ * A `Point` takes its id from its `id` prop, or generates one that lasts as
1486
+ * long as it is mounted.
1487
+ */
1488
+ selection?: string[];
1489
+ /** The selection to start with, when the editor keeps its own. */
1490
+ defaultSelection?: string[];
1491
+ /** Called whenever the selection changes, controlled or not. */
1492
+ onSelectionChange?: (selection: string[]) => void;
677
1493
  /**
678
1494
  * The editor renders exactly what you compose here; there is no default
679
1495
  * markup to fall back to.
@@ -691,154 +1507,163 @@ interface PointsEditorProps {
691
1507
  * </PointsEditor.Root>
692
1508
  */
693
1509
  children: ReactNode;
1510
+ style?: CSSProperties & CSSVariables<'width' | 'height'>;
694
1511
  }
695
1512
  /**
696
1513
  * Multiple Point Controller
697
1514
  */
698
- declare const PointsEditor: {
699
- Root: _$react.ForwardRefExoticComponent<PointsEditorProps & Omit<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof PointsEditorProps> & _$react.RefAttributes<HTMLDivElement>>;
1515
+ export declare const PointsEditor: {
1516
+ Root: import("react").ForwardRefExoticComponent<PointsEditorProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof PointsEditorProps> & import("react").RefAttributes<HTMLDivElement>>;
700
1517
  Background: typeof Background;
701
- Container: typeof Container;
1518
+ Container: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
702
1519
  Point: typeof Point;
1520
+ SelectionBox: typeof SelectionBox;
703
1521
  };
704
1522
  //#endregion
1523
+ //#region src/components/Slider/Thumb.d.ts
1524
+ interface SliderThumbProps {
1525
+ /**
1526
+ * Sets `--color`, for the theme to colour the thumb with. The size is not
1527
+ * set here but by `--thumb-size` on `Slider.Root`, so that the root can
1528
+ * leave the matching room around the track.
1529
+ */
1530
+ color?: string;
1531
+ style?: CSSProperties & CSSVariables<'color' | 'translate'>;
1532
+ }
1533
+ interface SliderThumbMethods {
1534
+ focus: () => void;
1535
+ blur: () => void;
1536
+ }
1537
+ //#endregion
1538
+ //#region src/components/Slider/Track.d.ts
1539
+ interface SliderTrackProps {
1540
+ /**
1541
+ * How long the track is along the axis the slider runs. Sets `--length`;
1542
+ * the size the theme gives it stands when this is omitted.
1543
+ */
1544
+ length?: number | string;
1545
+ /** How thick the track is across that axis. Sets `--thickness`. */
1546
+ thickness?: number | string;
1547
+ /** Colour of the part from `min` to the value. Sets `--active`. */
1548
+ active?: string;
1549
+ /** Colour of the rest of the track. Sets `--inactive`. */
1550
+ inactive?: string;
1551
+ style?: CSSProperties & CSSVariables<'length' | 'thickness' | 'active' | 'inactive' | 'percent'>;
1552
+ }
1553
+ //#endregion
705
1554
  //#region src/components/Slider/type.d.ts
706
- type MarksType = 'mark' | 'mark-number' | 'number';
707
- type MarksOptions = ['step', MarksType] | [number, MarksType];
1555
+ /**
1556
+ * How `Slider.Marks` fills itself in when it is given no children: one option
1557
+ * every `per`, or every `step` of the slider. The object form turns off the
1558
+ * mark or the label for the whole set; a single option is customized by
1559
+ * writing `Slider.MarksOption` out instead.
1560
+ */
1561
+ type MarksOptions = 'step' | number | {
1562
+ per: 'step' | number;
1563
+ mark?: boolean;
1564
+ label?: boolean;
1565
+ };
708
1566
  //#endregion
709
1567
  //#region src/components/Slider/Marks.d.ts
710
- interface MarksProps {
1568
+ interface SliderMarksProps {
1569
+ /**
1570
+ * Space between the marks and the track. Sets `--gap`; the theme's own
1571
+ * spacing stands when this is omitted.
1572
+ */
711
1573
  gap?: number | string;
1574
+ /**
1575
+ * Build the marks instead of writing `Slider.MarksOption` out: a number puts
1576
+ * one every that many, `'step'` one every `step`, and `{ per, mark, label }`
1577
+ * also turns the mark or the label off for all of them. `children` is
1578
+ * ignored while it is set.
1579
+ *
1580
+ * `'step'` makes one per step, which is a great many for a fine `step`.
1581
+ */
712
1582
  options?: MarksOptions;
713
- children?: ReactNode;
1583
+ style?: CSSProperties & CSSVariables<'gap'>;
714
1584
  }
715
- declare function Marks({
716
- gap,
717
- options,
718
- children,
719
- className,
720
- style,
721
- ...props
722
- }: MarksProps & Omit<ComponentPropsWithoutRef<'div'>, keyof MarksProps>): _$react.JSX.Element;
1585
+ declare function Marks({ gap, options, children, className, style, ...props }: SliderMarksProps & Omit<ComponentPropsWithoutRef<'div'>, keyof SliderMarksProps>): import("react").JSX.Element;
723
1586
  //#endregion
724
1587
  //#region src/components/Slider/MarksOption.d.ts
725
- interface MarksOptionProps {
1588
+ interface SliderMarksOptionProps {
1589
+ /** Where the mark sits, on the same scale as the thumb. */
726
1590
  value: number;
727
- type?: MarksType;
728
- /** Display text instead of value. */
729
- label?: string;
730
- /** mark thickness */
1591
+ /**
1592
+ * Draw the mark itself. Turn it off to show the label alone.
1593
+ * @default true
1594
+ */
1595
+ mark?: boolean;
1596
+ /**
1597
+ * Text shown next to the mark. Leave it out to show the value; `null` leaves
1598
+ * the label out, and an empty string draws an empty one.
1599
+ */
1600
+ label?: number | string | null;
1601
+ /** Thickness of the mark. Sets `--thickness`. */
731
1602
  thickness?: number | string;
732
- /** mark length */
1603
+ /** Length of the mark. Sets `--length`. */
733
1604
  length?: number | string;
734
- /** Gap between mark and label. */
1605
+ /** Space between the mark and the label. Sets `--gap`. */
735
1606
  gap?: number | string;
1607
+ /** Width of the label. Sets `--label-width`. */
736
1608
  labelWidth?: number | string;
1609
+ /** Classes for the mark and the label inside the option. */
737
1610
  classes?: {
738
1611
  mark?: string;
739
1612
  label?: string;
740
1613
  };
1614
+ /** Styles for the mark and the label inside the option. */
741
1615
  styles?: {
742
1616
  mark?: CSSProperties;
743
1617
  label?: CSSProperties;
744
1618
  };
1619
+ style?: CSSProperties & CSSVariables<'thickness' | 'length' | 'gap' | 'label-width' | 'translate'>;
745
1620
  }
746
- declare function MarksOption({
747
- value,
748
- type,
749
- label,
750
- thickness,
751
- length,
752
- gap,
753
- labelWidth,
754
- classes,
755
- styles,
756
- className,
757
- style,
758
- ...props
759
- }: MarksOptionProps & Omit<ComponentPropsWithoutRef<'div'>, keyof MarksOptionProps>): _$react.JSX.Element;
760
- //#endregion
761
- //#region src/components/Slider/Thumb.d.ts
762
- interface SliderThumbProps {
763
- /**
764
- * Size comes from the `--thumb-size` CSS variable on `Slider.Root`, so that
765
- * the root can reserve the matching amount of space around the track.
766
- */
767
- color?: string;
768
- className?: string;
769
- style?: CSSProperties;
770
- children?: ReactNode;
771
- ref?: Ref<SliderThumbMethods>;
772
- }
773
- interface SliderThumbMethods {
774
- focus: () => void;
775
- blur: () => void;
776
- }
777
- declare function Thumb$1({
778
- color,
779
- children,
780
- className,
781
- style,
782
- ref
783
- }: SliderThumbProps): _$react.JSX.Element;
784
- //#endregion
785
- //#region src/components/Slider/Track.d.ts
786
- interface SliderTrackProps {
787
- length?: number | string;
788
- thickness?: number | string;
789
- active?: string;
790
- inactive?: string;
791
- defaultStyle?: boolean;
792
- className?: string;
793
- style?: CSSProperties;
794
- /** `<Slider.Thumb />` goes here. */
795
- children?: ReactNode;
796
- ref?: Ref<HTMLDivElement>;
797
- }
798
- declare function Track({
799
- length,
800
- thickness,
801
- active,
802
- inactive,
803
- children,
804
- className,
805
- style,
806
- defaultStyle,
807
- ref,
808
- ...props
809
- }: SliderTrackProps & Omit<ComponentPropsWithoutRef<'div'>, keyof SliderTrackProps>): _$react.JSX.Element;
1621
+ declare function MarksOption({ value, mark, label, thickness, length, gap, labelWidth, classes, styles, className, style, ...props }: SliderMarksOptionProps & Omit<ComponentPropsWithoutRef<'div'>, keyof SliderMarksOptionProps>): import("react").JSX.Element;
810
1622
  //#endregion
811
1623
  //#region src/components/Slider/context.d.ts
812
1624
  type SliderContextValue = {
813
1625
  value: number;
814
1626
  min: number;
815
1627
  max: number;
816
- step: number; /** How the value is distributed across the travel. */
1628
+ step: number;
1629
+ /** How the value is distributed across the travel. */
817
1630
  scale: Scale;
818
1631
  vertical: boolean;
819
1632
  reverse: boolean;
820
1633
  disabled: boolean;
821
1634
  readonly: boolean;
1635
+ onChange?: (value: number) => void;
822
1636
  /**
823
1637
  * Position of the thumb, 0-100, already accounting for the display direction
824
1638
  * implied by `vertical` and `reverse`.
825
1639
  */
826
- percent: number; /** `Track` registers its element here; `Root` normalizes the pointer against it. */
827
- trackRef: RefObject<HTMLDivElement | null>; /** `Thumb` registers itself here; `Root` focuses it when a drag starts. */
1640
+ percent: number;
1641
+ /** `Track` registers its element here; `Root` normalizes the pointer against it. */
1642
+ trackRef: RefObject<HTMLDivElement | null>;
1643
+ /** `Thumb` registers itself here; `Root` focuses it when a drag starts. */
828
1644
  thumbRef: RefObject<SliderThumbMethods | null>;
829
1645
  };
830
1646
  /**
831
1647
  * Everything here is derived during render, so there is no state to keep in
832
1648
  * sync: `value` comes from the props of `Root` and the rest follows from it.
833
1649
  */
834
- declare function useSliderContext(): SliderContextValue;
835
- declare function useSliderContext<T>(selector: (state: SliderContextValue) => T): T;
1650
+ export declare function useSliderContext(): SliderContextValue;
1651
+ export declare function useSliderContext<T>(selector: (state: SliderContextValue) => T): T;
836
1652
  //#endregion
837
1653
  //#region src/components/Slider/index.d.ts
838
1654
  interface SliderProps {
1655
+ /** The current value. The slider shows only this, so update it from `onChange`. */
839
1656
  value: number;
1657
+ /** The value at the start of the travel. */
840
1658
  min: number;
1659
+ /** The value at the end of the travel. */
841
1660
  max: number;
1661
+ /**
1662
+ * Granularity of the value. A drag, the wheel and the arrow keys snap it to
1663
+ * multiples of `step`.
1664
+ *
1665
+ * @default 1
1666
+ */
842
1667
  step?: number;
843
1668
  /**
844
1669
  * How the value is distributed across the travel.
@@ -851,41 +1676,88 @@ interface SliderProps {
851
1676
  */
852
1677
  scale?: Scale;
853
1678
  /**
854
- * slider orientation
855
- * aria-orientation property is also applied.
1679
+ * Run the slider vertically, with the value growing upwards. The range input
1680
+ * inside the thumb takes its `aria-orientation` from this.
1681
+ *
1682
+ * @default false
856
1683
  */
857
1684
  vertical?: boolean;
1685
+ /**
1686
+ * Grow the value the other way: leftwards, or downwards when `vertical`.
1687
+ * The arrow keys follow the direction on screen.
1688
+ *
1689
+ * @default false
1690
+ */
858
1691
  reverse?: boolean;
859
- /** Global style to apply when dragged */
1692
+ /**
1693
+ * The cursor to show while dragging. It is set on the dragged element, so it
1694
+ * stays while the pointer is outside the slider.
1695
+ *
1696
+ * @default { cursor: 'pointer' }
1697
+ */
860
1698
  externalStyles?: {
861
- userSelectNone?: boolean;
862
- cursor?: Cursor;
1699
+ cursor?: CSSProperties['cursor'];
863
1700
  };
864
1701
  /**
865
- * wheel control option
866
- * If null, no event will be triggered
1702
+ * How much one notch of the wheel moves the value. It only acts while the
1703
+ * focus is inside, so that scrolling the page past the slider leaves it
1704
+ * alone.
1705
+ *
1706
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
1707
+ * range between `min` and `max`. The result is snapped to `step`, except for
1708
+ * an amount set on a modifier key (`{ default: …, shift: … }`). `null` turns
1709
+ * the wheel off.
1710
+ *
1711
+ * @default ['raw', 1]
867
1712
  */
868
- wheel?: InputEventOption | null;
1713
+ wheel?: ModifierValue<InputEventOption> | null;
869
1714
  /**
870
- * keyboard control option
871
- * If null, no event will be triggered
1715
+ * How much a drag moves the value, per modifier key.
1716
+ *
1717
+ * `1` is the pointer position itself, which is what a drag normally is here.
1718
+ * **Anything else turns the drag relative**: `0.1` makes the same movement
1719
+ * cover a tenth of the travel, so the value stops following the pointer and
1720
+ * starts moving a tenth as fast. Shift is bound to `0.1` by default, to
1721
+ * match what it does on the arrow keys.
1722
+ *
1723
+ * Pressing or releasing the key mid-drag does not disturb the value: the
1724
+ * travel so far is kept and the new sensitivity applies from there. **The
1725
+ * pointer and the value stay apart for the rest of the drag** — snapping
1726
+ * them back together on release would move the value nobody asked to move.
1727
+ *
1728
+ * @default { default: 1, shift: 0.1 }
872
1729
  */
873
- keyboard?: InputEventOption | null;
1730
+ dragSensitivity?: ModifierValue<number>;
874
1731
  /**
875
- * Only the appearance will change.
876
- * Please consider using with readonly.
877
- * aria-disabled property is also applied.
1732
+ * How much one arrow key press moves the value.
1733
+ *
1734
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
1735
+ * range between `min` and `max`. The result is snapped to `step`, except for
1736
+ * an amount set on a modifier key, which is what lets shift move off the
1737
+ * grid. `null` turns the arrow keys off.
1738
+ *
1739
+ * The default moves by 1, and by 0.1 with shift. With a `step` above 1, raise
1740
+ * the amount to match: 1 would round straight back to where it started, and
1741
+ * a development build warns about it.
1742
+ *
1743
+ * @default { default: ['raw', 1], shift: ['raw', 0.1] }
1744
+ */
1745
+ keyboard?: ModifierValue<InputEventOption> | null;
1746
+ /**
1747
+ * Make the slider unchangeable and remove it from the tab order.
1748
+ * The parts carry `data-disabled` while it is set.
878
1749
  */
879
1750
  disabled?: boolean;
880
1751
  /**
881
1752
  * Make the value unchangeable.
882
- * aria-readonly property is also applied.
1753
+ * The parts carry `data-readonly` while it is set.
883
1754
  */
884
1755
  readonly?: boolean;
885
- className?: string;
886
- style?: CSSProperties;
1756
+ /** Called with the new value when a drag, the wheel or an arrow key moves it. */
887
1757
  onChange?: (value: number) => void;
1758
+ /** Called when a drag starts, with the value where the track was pressed. */
888
1759
  onDragStart?: (value: number) => void;
1760
+ /** Called when the drag ends, with the value it ended on. */
889
1761
  onDragEnd?: (value: number) => void;
890
1762
  /**
891
1763
  * The slider renders exactly what you compose here; there is no default
@@ -894,7 +1766,7 @@ interface SliderProps {
894
1766
  * @example
895
1767
  * <Slider.Root value={value} min={0} max={100} onChange={setValue}>
896
1768
  * <Slider.Track>
897
- * <Slider.Thumb />
1769
+ * <Slider.Thumb aria-label="Level" />
898
1770
  * </Slider.Track>
899
1771
  * </Slider.Root>
900
1772
  */
@@ -907,63 +1779,82 @@ interface SliderMethods {
907
1779
  /**
908
1780
  * Customizable slider
909
1781
  */
910
- declare const Slider: {
1782
+ export declare const Slider: {
911
1783
  Root: React.ForwardRefExoticComponent<SliderProps & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof SliderProps> & React.RefAttributes<SliderMethods>>;
912
- Thumb: typeof Thumb$1;
913
- Track: typeof Track;
1784
+ Thumb: React.ForwardRefExoticComponent<SliderThumbProps & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof SliderThumbProps> & React.RefAttributes<SliderThumbMethods>>;
1785
+ Track: React.ForwardRefExoticComponent<SliderTrackProps & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof SliderTrackProps> & React.RefAttributes<HTMLDivElement>>;
914
1786
  Marks: typeof Marks;
915
1787
  MarksOption: typeof MarksOption;
916
1788
  };
917
1789
  //#endregion
918
- //#region src/components/XYPad/Area.d.ts
919
- interface XYPadAreaProps {
920
- width?: number | string;
921
- height?: number | string;
922
- color?: string;
923
- className?: string;
924
- style?: CSSProperties;
925
- /** `<XYPad.Thumb />` goes here. */
926
- children?: ReactNode;
927
- ref?: Ref<HTMLDivElement>;
928
- }
929
- declare function Area({
930
- width,
931
- height,
932
- color,
933
- children,
934
- className,
935
- style,
936
- ref,
937
- ...props
938
- }: XYPadAreaProps & Omit<ComponentPropsWithoutRef<'div'>, keyof XYPadAreaProps>): _$react.JSX.Element;
1790
+ //#region src/components/XYPad/context.d.ts
1791
+ type XYPadContextValue = {
1792
+ value: XY<number>;
1793
+ min: XY<number>;
1794
+ max: XY<number>;
1795
+ step: XY<number>;
1796
+ /** How the value of each axis is distributed across the travel. */
1797
+ scale: XY<Scale>;
1798
+ reverse: XY<boolean>;
1799
+ disabled: boolean;
1800
+ readonly: boolean;
1801
+ onChange?: (value: XY<number>) => void;
1802
+ /**
1803
+ * Position of the thumb, 0-100 per axis, already accounting for `reverse`.
1804
+ */
1805
+ percent: XY<number>;
1806
+ /** `Area` registers its element here; `Root` normalizes the pointer against it. */
1807
+ areaRef: RefObject<HTMLDivElement | null>;
1808
+ /** `Thumb` registers itself here; `Root` focuses it when a drag starts. */
1809
+ thumbRef: RefObject<XYPadThumbMethods | null>;
1810
+ };
1811
+ /**
1812
+ * Everything here is derived during render, so there is no state to keep in
1813
+ * sync: `value` comes from the props of `Root` and the rest follows from it.
1814
+ */
1815
+ export declare function useXYPadContext(): XYPadContextValue;
1816
+ export declare function useXYPadContext<T>(selector: (state: XYPadContextValue) => T): T;
939
1817
  //#endregion
940
1818
  //#region src/components/XYPad/Thumb.d.ts
941
1819
  interface XYPadThumbProps {
942
1820
  /**
943
- * Size comes from the `--thumb-size` CSS variable on `XYPad.Root`, so that
944
- * the root can reserve the matching amount of space around the area.
1821
+ * Sets `--color`, for the theme to colour the thumb with. The size is not
1822
+ * set here but by `--thumb-size` on `XYPad.Root`, so that the root can leave
1823
+ * the matching room around the area.
945
1824
  */
946
1825
  color?: string;
947
- wrapperClassName?: string;
948
- wrapperStyle?: CSSProperties;
949
- children?: ReactNode;
950
- ref?: Ref<XYPadThumbMethods>;
1826
+ /**
1827
+ * The accessible name of each axis, as `[x, y]`. There are two range inputs
1828
+ * inside the thumb, so each takes a name of its own; a single string names
1829
+ * them both, which is rarely what you want.
1830
+ */
1831
+ 'aria-label'?: XYInput<AriaAttributes['aria-label']>;
1832
+ /** The ids of what labels each axis, as `[x, y]` or one for both. */
1833
+ 'aria-labelledby'?: XYInput<AriaAttributes['aria-labelledby']>;
1834
+ /** The ids of what describes each axis, as `[x, y]` or one for both. */
1835
+ 'aria-describedby'?: XYInput<AriaAttributes['aria-describedby']>;
1836
+ /**
1837
+ * What the value of each axis means, when the number does not say it, as
1838
+ * `[x, y]` or one for both.
1839
+ */
1840
+ 'aria-valuetext'?: XYInput<AriaAttributes['aria-valuetext']>;
1841
+ style?: CSSProperties & CSSVariables<'color' | 'translate'>;
951
1842
  }
952
1843
  interface XYPadThumbMethods {
953
1844
  focus: () => void;
954
1845
  blur: () => void;
955
1846
  }
956
- type Props = XYPadThumbProps & Omit<ComponentPropsWithoutRef<'div'>, keyof XYPadThumbProps>;
957
- declare function Thumb({
958
- color,
959
- children,
960
- wrapperClassName,
961
- wrapperStyle,
962
- className,
963
- style,
964
- ref,
965
- ...props
966
- }: Props): _$react.JSX.Element;
1847
+ //#endregion
1848
+ //#region src/components/XYPad/Area.d.ts
1849
+ interface XYPadAreaProps {
1850
+ /** Sets `--width`; the size the theme gives it stands when omitted. */
1851
+ width?: number | string;
1852
+ /** Sets `--height`; the size the theme gives it stands when omitted. */
1853
+ height?: number | string;
1854
+ /** Sets `--color`, for the theme to colour the area with. */
1855
+ color?: string;
1856
+ style?: CSSProperties & CSSVariables<'width' | 'height' | 'color'>;
1857
+ }
967
1858
  //#endregion
968
1859
  //#region src/components/XYPad/index.d.ts
969
1860
  /**
@@ -973,12 +1864,22 @@ declare function Thumb({
973
1864
  * value applies to both axes.
974
1865
  */
975
1866
  interface XYPadProps {
1867
+ /** The current value as `[x, y]`. The pad shows only this, so update it from `onChange`. */
976
1868
  value: XY<number>;
1869
+ /** The value at the start of each axis, as `[x, y]` or one number for both. */
977
1870
  min: XYInput<number>;
1871
+ /** The value at the end of each axis, as `[x, y]` or one number for both. */
978
1872
  max: XYInput<number>;
1873
+ /**
1874
+ * Granularity of each axis, as `[x, y]` or one number for both. A drag, the
1875
+ * wheel and the arrow keys snap the value to multiples of it.
1876
+ *
1877
+ * @default 1
1878
+ */
979
1879
  step?: XYInput<number>;
980
1880
  /**
981
- * How the value of each axis is distributed across the travel.
1881
+ * How the value of each axis is distributed across the travel, as `[x, y]`
1882
+ * or one scale for both.
982
1883
  *
983
1884
  * Pick one of the scales from `@tremolo-ui/functions`: `linearScale`,
984
1885
  * `exponentialScale`, `curveScale(n)`, `symmetricSkewScale(n)`, or
@@ -987,25 +1888,83 @@ interface XYPadProps {
987
1888
  * @default linearScale
988
1889
  */
989
1890
  scale?: XYInput<Scale>;
1891
+ /**
1892
+ * Grow an axis the other way, as `[x, y]` or one for both. By default x grows
1893
+ * rightwards and y downwards. The arrow keys follow the direction on screen.
1894
+ *
1895
+ * @default false
1896
+ */
990
1897
  reverse?: XYInput<boolean>;
991
1898
  /**
992
- * wheel control option. Shift selects the x axis.
993
- * If null, no event will be triggered
1899
+ * How much one notch of the wheel moves the value. It only acts while the
1900
+ * focus is inside, so that scrolling the page past the pad leaves it alone.
1901
+ * Scrolling sideways, or with shift held, moves x; otherwise it moves y.
1902
+ *
1903
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
1904
+ * range of that axis. The result is snapped to `step`, except for an amount
1905
+ * set on a modifier key (`{ default: …, alt: … }`). `null` turns the wheel
1906
+ * off.
1907
+ *
1908
+ * @default ['raw', 1]
1909
+ */
1910
+ wheel?: ModifierValue<InputEventOption> | null;
1911
+ /**
1912
+ * How much a drag moves the value, per modifier key.
1913
+ *
1914
+ * `1` is the pointer position itself, which is what a drag normally is here.
1915
+ * **Anything else turns the drag relative**: `0.1` makes the same movement
1916
+ * cover a tenth of the travel, so the value stops following the pointer and
1917
+ * starts moving a tenth as fast. Shift is bound to `0.1` by default, to
1918
+ * match what it does on the arrow keys.
1919
+ *
1920
+ * Pressing or releasing the key mid-drag does not disturb the value: the
1921
+ * travel so far is kept and the new sensitivity applies from there. **The
1922
+ * pointer and the value stay apart for the rest of the drag** — snapping
1923
+ * them back together on release would move the value nobody asked to move.
1924
+ *
1925
+ * @default { default: 1, shift: 0.1 }
1926
+ */
1927
+ dragSensitivity?: ModifierValue<number>;
1928
+ /**
1929
+ * How much one arrow key press moves the value. Left and right move x, up
1930
+ * and down move y.
1931
+ *
1932
+ * `['raw', n]` moves the value by `n`, and `['normalized', n]` by `n` of the
1933
+ * range of that axis. The result is snapped to `step`, except for an amount
1934
+ * set on a modifier key, which is what lets shift move off the grid. `null`
1935
+ * turns the arrow keys off.
1936
+ *
1937
+ * The default moves by 1, and by 0.1 with shift. With a `step` above 1, raise
1938
+ * the amount to match: 1 would round straight back to where it started, and
1939
+ * a development build warns about it.
1940
+ *
1941
+ * @default { default: ['raw', 1], shift: ['raw', 0.1] }
994
1942
  */
995
- wheel?: InputEventOption | null;
1943
+ keyboard?: ModifierValue<InputEventOption> | null;
996
1944
  /**
997
- * keyboard control option
998
- * If null, no event will be triggered
1945
+ * The cursor to show while dragging. It is set on the dragged element, so it
1946
+ * stays while the pointer is outside the pad.
1947
+ *
1948
+ * @default { cursor: 'pointer' }
999
1949
  */
1000
- keyboard?: InputEventOption | null;
1001
1950
  externalStyles?: {
1002
- userSelectNone?: boolean;
1003
- cursor?: Cursor;
1951
+ cursor?: CSSProperties['cursor'];
1004
1952
  };
1953
+ /**
1954
+ * Make the pad unchangeable and remove its thumb from the tab order.
1955
+ * The parts carry `data-disabled` while it is set.
1956
+ */
1005
1957
  disabled?: boolean;
1958
+ /**
1959
+ * Make the pad unchangeable while leaving its thumb focusable.
1960
+ * The parts carry `data-readonly` while it is set.
1961
+ */
1006
1962
  readonly?: boolean;
1963
+ /** Called with the new value when a drag, the wheel or an arrow key moves it. */
1007
1964
  onChange?: (value: XY<number>) => void;
1965
+ /** Called when a drag starts, with the value where the area was pressed. */
1008
1966
  onDragStart?: (value: XY<number>) => void;
1967
+ /** Called when the drag ends, with the value it ended on. */
1009
1968
  onDragEnd?: (value: XY<number>) => void;
1010
1969
  /**
1011
1970
  * The pad renders exactly what you compose here; there is no default
@@ -1028,40 +1987,55 @@ interface XYPadMethods {
1028
1987
  /**
1029
1988
  * Simple XYPad
1030
1989
  */
1031
- declare const XYPad: {
1032
- Root: _$react.ForwardRefExoticComponent<XYPadProps & Omit<Omit<_$react.DetailedHTMLProps<_$react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof XYPadProps> & _$react.RefAttributes<XYPadMethods>>;
1033
- Thumb: typeof Thumb;
1034
- Area: typeof Area;
1990
+ export declare const XYPad: {
1991
+ Root: import("react").ForwardRefExoticComponent<XYPadProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof XYPadProps> & import("react").RefAttributes<XYPadMethods>>;
1992
+ Thumb: import("react").ForwardRefExoticComponent<XYPadThumbProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof XYPadThumbProps> & import("react").RefAttributes<XYPadThumbMethods>>;
1993
+ Area: import("react").ForwardRefExoticComponent<XYPadAreaProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, keyof XYPadAreaProps> & import("react").RefAttributes<HTMLDivElement>>;
1035
1994
  };
1036
1995
  //#endregion
1037
1996
  //#region src/hooks/useAnimationFrame.d.ts
1038
- declare function useAnimationFrame(callback?: () => void, deps?: DependencyList): void;
1997
+ export declare function useAnimationFrame(callback?: () => void, deps?: DependencyList): void;
1039
1998
  //#endregion
1040
1999
  //#region src/hooks/useDrag.d.ts
1041
- interface UseDragProps {
2000
+ interface UseDragOptions {
1042
2001
  /**
1043
- * Threshold at which the onDrag event fires.
1044
- * Prevents onDrag events from firing, for example, when double-clicking.
2002
+ * Pixels the pointer has to travel before the drag counts as one.
2003
+ *
2004
+ * A click moves the pointer by a pixel or two, so without a threshold a
2005
+ * double click reports a drag between the two presses.
2006
+ *
2007
+ * @default 1
1045
2008
  */
1046
2009
  threshold?: number;
1047
2010
  /** CSS cursor to show while dragging. Applied to the element itself. */
1048
2011
  cursor?: string;
1049
- onDrag?: (x: number, y: number, deltaX: number, deltaY: number) => void;
1050
- onDragStart?: () => void;
1051
- onDragEnd?: () => void;
2012
+ /**
2013
+ * Hide the pointer and read its movement directly, instead of following it
2014
+ * around the screen.
2015
+ *
2016
+ * @see DragOptions.pointerLock
2017
+ * @default false
2018
+ */
2019
+ pointerLock?: boolean;
2020
+ /**
2021
+ * Called on every move once the drag has started, with the pointer position
2022
+ * relative to the element and how far it moved since the last call.
2023
+ *
2024
+ * @param state the whole drag, for anything the four numbers leave out —
2025
+ * the pointer event and its modifier keys, most of all.
2026
+ */
2027
+ onDrag?: (x: number, y: number, deltaX: number, deltaY: number, state: DragState) => void;
2028
+ /** Called once the pointer has moved past `threshold`, not on pointerdown. */
2029
+ onDragStart?: (state: DragState) => void;
2030
+ /** Called when the pointer is released, only if the drag ever started. */
2031
+ onDragEnd?: (state: DragState) => void;
1052
2032
  }
1053
2033
  /**
1054
2034
  * Track a pointer drag on an element.
1055
2035
  *
1056
2036
  * @returns a ref callback to attach to the element being dragged
1057
2037
  */
1058
- declare function useDrag<T extends Element>({
1059
- threshold,
1060
- cursor,
1061
- onDrag,
1062
- onDragStart,
1063
- onDragEnd
1064
- }: UseDragProps): (node: T | null) => void;
2038
+ export declare function useDrag<T extends Element>({ threshold, cursor, pointerLock, onDrag, onDragStart, onDragEnd }: UseDragOptions): (node: T | null) => void;
1065
2039
  //#endregion
1066
2040
  //#region src/hooks/useDragValue.d.ts
1067
2041
  interface UseDragValueOptions {
@@ -1086,63 +2060,153 @@ interface UseDragValueOptions {
1086
2060
  * @default 100
1087
2061
  */
1088
2062
  pixelRange?: XYInput$1<number>;
1089
- /** @see DragValueOptions.updateOnPointerDown */
2063
+ /**
2064
+ * How much the movement counts, read on every move. `0.1` makes the same
2065
+ * movement cover a tenth of the range, which is what a fine-adjustment
2066
+ * modifier wants.
2067
+ *
2068
+ * With `baseElementRef` the value is normally the position pointed at, so
2069
+ * anything but `1` turns the mapping relative and leaves the pointer and the
2070
+ * value apart for the rest of the drag.
2071
+ *
2072
+ * @see relativeMapping
2073
+ * @see elementMapping
2074
+ */
2075
+ sensitivity?: (state: DragState) => number;
2076
+ /**
2077
+ * Move the value on pointerdown, before the pointer has moved at all. With
2078
+ * `baseElementRef` that makes a press jump the value to where it landed.
2079
+ *
2080
+ * @see DragValueOptions.updateOnPointerDown
2081
+ */
1090
2082
  updateOnPointerDown?: boolean;
1091
- /** @default 0 */
2083
+ /**
2084
+ * Pixels the pointer has to travel before the drag counts as one. The
2085
+ * default is 0, so the value follows the very first move.
2086
+ *
2087
+ * @default 0
2088
+ */
1092
2089
  threshold?: number;
1093
2090
  /** CSS cursor to show while dragging. Applied to the element itself. */
1094
2091
  cursor?: string;
1095
- onChange?: (value: XY$1<number>) => void;
1096
- onDragStart?: (value: XY$1<number>) => void;
1097
- onDragEnd?: (value: XY$1<number>) => void;
2092
+ /**
2093
+ * Hide the pointer and read its movement directly, instead of following it
2094
+ * around the screen. Only with `getValue`: there is no pointer position to
2095
+ * normalize against a `baseElementRef` while the pointer is locked.
2096
+ *
2097
+ * @see DragOptions.pointerLock
2098
+ * @default false
2099
+ */
2100
+ pointerLock?: boolean;
2101
+ /**
2102
+ * Decide whether a pointerdown starts a drag at all, before the pointer is
2103
+ * captured.
2104
+ *
2105
+ * @see DragOptions.shouldStart
2106
+ */
2107
+ shouldStart?: (event: PointerEvent) => boolean;
2108
+ /**
2109
+ * Called with the new value whenever the drag moves it. The hook holds no
2110
+ * value of its own, so this is where it is stored.
2111
+ *
2112
+ * @param state the whole drag, for anything the value leaves out — the
2113
+ * pointer event and its modifier keys, most of all.
2114
+ */
2115
+ onChange?: (value: XY$1<number>, state: DragState) => void;
2116
+ /** Called once the drag starts, with the value it starts from. */
2117
+ onDragStart?: (value: XY$1<number>, state: DragState) => void;
2118
+ /** Called when the pointer is released, with the value it ends on. */
2119
+ onDragEnd?: (value: XY$1<number>, state: DragState) => void;
1098
2120
  }
1099
2121
  /**
1100
2122
  * Drive a value with a pointer drag.
1101
2123
  *
1102
2124
  * @returns a ref callback for the element that starts the drag, and whether a drag is in progress
1103
2125
  */
1104
- declare function useDragValue<T extends Element>(options: UseDragValueOptions): {
2126
+ export declare function useDragValue<T extends Element>(options: UseDragValueOptions): {
1105
2127
  refCallback: (node: T | null) => void;
1106
2128
  dragging: boolean;
1107
2129
  };
1108
2130
  //#endregion
2131
+ //#region src/hooks/useDropZone.d.ts
2132
+ interface UseDropZoneOptions extends Omit<DropZoneOptions, 'onStateChange'> {}
2133
+ /**
2134
+ * Take files dropped onto an element.
2135
+ *
2136
+ * Any element can become a drop target this way — a waveform display, a track
2137
+ * lane, a canvas — without wrapping it in anything.
2138
+ *
2139
+ * @returns a ref callback for the element, and whether a drag is over it
2140
+ */
2141
+ export declare function useDropZone<T extends Element>({ accept, multiple, disabled, onDrop, onReject }?: UseDropZoneOptions): {
2142
+ refCallback: (node: T | null) => void;
2143
+ over: boolean;
2144
+ invalid: boolean;
2145
+ };
2146
+ //#endregion
1109
2147
  //#region src/hooks/useEventListener.d.ts
1110
2148
  type Target = EventTarget | null | (() => EventTarget | null);
1111
2149
  type Options = boolean | AddEventListenerOptions;
1112
- declare function useEventListener<K extends keyof DocumentEventMap>(target: Target, event: K, handler: (event: DocumentEventMap[K]) => void, options?: Options): VoidFunction;
1113
- declare function useEventListener<K extends keyof WindowEventMap>(target: Target, event: K, handler: (event: WindowEventMap[K]) => void, options?: Options): VoidFunction;
1114
- declare function useEventListener<K extends keyof GlobalEventHandlersEventMap>(target: Target, event: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, options?: Options): VoidFunction;
2150
+ export declare function useEventListener<K extends keyof DocumentEventMap>(target: Target, event: K, handler: (event: DocumentEventMap[K]) => void, options?: Options): VoidFunction;
2151
+ export declare function useEventListener<K extends keyof WindowEventMap>(target: Target, event: K, handler: (event: WindowEventMap[K]) => void, options?: Options): VoidFunction;
2152
+ export declare function useEventListener<K extends keyof GlobalEventHandlersEventMap>(target: Target, event: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, options?: Options): VoidFunction;
1115
2153
  //#endregion
1116
2154
  //#region src/hooks/useInterval.d.ts
1117
- declare function useInterval(callback: () => void, delay: number | null): void;
2155
+ export declare function useInterval(callback: () => void, delay: number | null): void;
1118
2156
  //#endregion
1119
2157
  //#region src/hooks/useLongPress.d.ts
1120
- declare function useLongPress(callback: () => void, initialDelay?: number, interval?: number): () => void;
2158
+ export declare function useLongPress(callback: () => void, initialDelay?: number, interval?: number): (event?: Pick<PointerEvent, "button" | "pointerId">) => void;
1121
2159
  //#endregion
1122
2160
  //#region src/hooks/useMIDIAccess.d.ts
1123
2161
  /**
1124
2162
  * Hooks for requesting MIDI access in the browser. The first argument allows you to choose whether to request access on mount.
2163
+ *
2164
+ * `inputs` follows the devices: it changes as one is plugged in or unplugged,
2165
+ * so a list of devices needs no `statechange` listener of its own.
2166
+ *
2167
+ * `request` takes `{ sysex: true }` when the app needs system exclusive
2168
+ * messages. Browsers treat that as a separate, more sensitive permission, so
2169
+ * ask for it only when it is actually used.
1125
2170
  */
1126
- declare function useMIDIAccess(requestOnMount?: boolean): {
1127
- request: () => void;
2171
+ export declare function useMIDIAccess(requestOnMount?: boolean): {
2172
+ request: (options?: MIDIAccessOptions$1) => void;
1128
2173
  midiAccess: MIDIAccess | null;
1129
- error: _$_tremolo_ui_dom0.MIDIAccessError | null;
2174
+ error: import("@tremolo-ui/dom").MIDIAccessError | null;
2175
+ inputs: readonly MIDIInput[];
1130
2176
  };
1131
2177
  //#endregion
1132
2178
  //#region src/hooks/useMIDIInput.d.ts
1133
2179
  /**
1134
- * Hooks for handling note on/off events. To be used with useMIDIAccess. Internally uses useMIDIMessage.
2180
+ * Handle MIDI input events. To be used with {@link useMIDIAccess}.
2181
+ *
2182
+ * The handlers are read fresh on every event, so writing them inline is fine:
2183
+ * the listeners are attached once per `midiAccess` and stay attached. Devices
2184
+ * plugged in later are picked up without anything having to be rebuilt.
2185
+ *
2186
+ * @example
2187
+ * const { midiAccess } = useMIDIAccess()
2188
+ * useMIDIInput(midiAccess, {
2189
+ * onNoteOnEvent: (note, velocity) => play(note, velocity / 127),
2190
+ * onNoteOffEvent: (note) => stop(note),
2191
+ * onControlChangeEvent: (controller, value) => {
2192
+ * if (controller === 1) setModulation(value / 127)
2193
+ * },
2194
+ * })
1135
2195
  */
1136
- declare function useMIDIInput(midiAccess: MIDIAccess | null, onNoteOnEvent?: (note: number, velocity: number) => void, onNoteOffEvent?: (note: number) => void, onPitchBendEvent?: (msb: number, lsb: number) => void): void;
2196
+ export declare function useMIDIInput(midiAccess: MIDIAccess | null, handlers: MIDIInputHandlers): void;
1137
2197
  //#endregion
1138
2198
  //#region src/hooks/useMIDIMessage.d.ts
1139
2199
  /**
1140
2200
  * Hooks for when you want to process MIDI events in more detail than useMIDIInput.
2201
+ *
2202
+ * The handler is read fresh on every event, so writing it inline is fine: the
2203
+ * listeners are attached once per `midiAccess` and stay attached, and devices
2204
+ * plugged in later are picked up.
1141
2205
  */
1142
- declare function useMIDIMessage(midiAccess: MIDIAccess | null, onMIDIMessage: (event: MIDIMessageEvent) => void): void;
2206
+ export declare function useMIDIMessage(midiAccess: MIDIAccess | null, onMIDIMessage: (event: MIDIMessageEvent) => void): void;
1143
2207
  //#endregion
1144
2208
  //#region src/hooks/useWheel.d.ts
1145
- interface UseWheelOptions extends WheelOptions {
2209
+ interface UseWheelOptions extends Omit<WheelOptions, 'onWheel'> {
1146
2210
  /**
1147
2211
  * Listen on this element rather than on the one the returned ref callback is
1148
2212
  * attached to, and ignore that callback.
@@ -1164,10 +2228,31 @@ interface UseWheelOptions extends WheelOptions {
1164
2228
  *
1165
2229
  * @returns a ref callback to attach to the element, unused when `target` is given
1166
2230
  */
1167
- declare function useWheel<T extends Element>(onWheel: (event: WheelEvent) => void, {
1168
- requireFocus,
1169
- target
1170
- }?: UseWheelOptions): (node: T | null) => void;
2231
+ export declare function useWheel<T extends Element>(onWheel: (event: WheelEvent) => void, { requireFocus, target }?: UseWheelOptions): (node: T | null) => void;
2232
+ //#endregion
2233
+ //#region src/input-event.d.ts
2234
+ /**
2235
+ * The keyboard amount used by Knob, NumberInput, Slider, and XYPad by default:
2236
+ * 1 per press in the units of the value, and 0.1 with shift held. That is one
2237
+ * `step` only while `step` is 1; a coarser `step` rounds 1 straight back, which
2238
+ * `useCheckSteps` warns about.
2239
+ *
2240
+ * A modifier entry is not snapped to `step`, which is what lets the finer
2241
+ * amount move at all — see `applyDelta` in `@tremolo-ui/dom`.
2242
+ */
2243
+ export declare const DEFAULT_KEYBOARD_OPTIONS: ModifierValue<InputEventOption>;
2244
+ /**
2245
+ * The wheel amount used by Knob, NumberInput, Slider, and XYPad by default.
2246
+ *
2247
+ * Browsers turn shift+wheel into horizontal scrolling, which empties `deltaY`
2248
+ * and fills `deltaX`, so no modifier is bound here.
2249
+ */
2250
+ export declare const DEFAULT_WHEEL_OPTIONS: ModifierValue<InputEventOption>;
2251
+ /**
2252
+ * The drag sensitivity used by value controls by default. Shift makes the
2253
+ * same movement cover a tenth of the range, matching the arrow keys.
2254
+ */
2255
+ export declare const DEFAULT_DRAG_SENSITIVITY: ModifierValue<number>;
1171
2256
  //#endregion
1172
- export { type AbsoluteSizingProps, AnimationCanvas, type AnimationCanvasProps, type CSSVariables, type CommonProps, type DecrementStepperProps, type DrawFunction, type IncrementStepperProps, type InitFunction, type KeyAttributes, type KeyState, type KeyboardShortcuts, Knob, type KnobMethods, type KnobProps, type MIDIAccessError, type MarksOptionProps, type MarksProps, NOT_SUPPORTED, NumberInput, type NumberInputFieldProps, type NumberInputMethods, type NumberInputProps, PERMISSION_DENIED, Piano, type PianoMethods, type PianoProps, type PointBaseType, type PointProps, PointsEditor, type PointsEditorBackgroundProps, type PointsEditorContainerProps, type PointsEditorContextValue, type PointsEditorProps, type RelativeSizingProps, SHORTCUTS, Slider, type SliderMethods, type SliderProps, type SliderThumbMethods, type SliderThumbProps, type SliderTrackProps, type StepperProps, type UseDragValueOptions, type UseWheelOptions, type XY, type XYInput, XYPad, type XYPadAreaProps, type XYPadMethods, type XYPadProps, type XYPadThumbMethods, type XYPadThumbProps, clampPoint, useAnimationFrame, useDrag, useDragValue, useEventListener, useInterval, useLongPress, useMIDIAccess, useMIDIInput, useMIDIMessage, useNumberInputContext, usePointsEditorContext, useSliderContext, useWheel };
2257
+ export { type AnimationCanvasCommonProps, type AnimationCanvasFixedProps, type AnimationCanvasProps, type AnimationCanvasResizableProps, type CSSVariables, type DrawFunction, type DropZoneProps, type FileInputContextValue, type FileInputProps, type FileInputTriggerProps, type InitFunction, type KeyAttributes, type KeyState, type KeyboardShortcuts, type KnobContextValue, type KnobMethods, type KnobProps, type KnobSVGRootProps, type KnobThumbProps, type MIDIAccessError, type MIDIAccessOptions, type MIDIInputHandlers, type MarksOptions, NOT_SUPPORTED, type NumberInputContextValue, type NumberInputMethods, type NumberInputProps, PERMISSION_DENIED, PITCH_BEND_CENTER, type PianoMethods, type PianoProps, type PointBaseType, type PointsEditorContextValue, type PointsEditorPointProps, type PointsEditorProps, type SliderContextValue, type SliderMarksOptionProps, type SliderMarksProps, type SliderMethods, type SliderProps, type SliderThumbMethods, type SliderThumbProps, type SliderTrackProps, UNAVAILABLE, type UseDragOptions, type UseDragValueOptions, type UseDropZoneOptions, type UseWheelOptions, type XY, type XYInput, type XYPadAreaProps, type XYPadContextValue, type XYPadMethods, type XYPadProps, type XYPadThumbMethods, type XYPadThumbProps };
1173
2258
  //# sourceMappingURL=index.d.cts.map