@tremolo-ui/dom 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/index.cjs +343 -595
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +230 -284
  4. package/dist/index.d.cts.map +1 -1
  5. package/dist/index.d.ts +230 -284
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +325 -572
  8. package/dist/index.js.map +1 -1
  9. package/dist/internal.cjs +530 -0
  10. package/dist/internal.cjs.map +1 -0
  11. package/dist/internal.d.cts +365 -0
  12. package/dist/internal.d.cts.map +1 -0
  13. package/dist/internal.d.ts +365 -0
  14. package/dist/internal.d.ts.map +1 -0
  15. package/dist/internal.js +500 -0
  16. package/dist/internal.js.map +1 -0
  17. package/dist/marks-DK7xJmGM.d.cts +305 -0
  18. package/dist/marks-DK7xJmGM.d.cts.map +1 -0
  19. package/dist/marks-DK7xJmGM.d.ts +305 -0
  20. package/dist/marks-DK7xJmGM.d.ts.map +1 -0
  21. package/dist/xy-5Oc6JeJr.cjs +952 -0
  22. package/dist/xy-5Oc6JeJr.cjs.map +1 -0
  23. package/dist/xy-lNFl1CTO.js +827 -0
  24. package/dist/xy-lNFl1CTO.js.map +1 -0
  25. package/package.json +12 -2
  26. package/src/canvas/animation.ts +8 -0
  27. package/src/canvas/context.ts +0 -5
  28. package/src/file/accept.ts +17 -0
  29. package/src/file/drop-zone.ts +8 -10
  30. package/src/index.ts +44 -32
  31. package/src/input/change-gesture.ts +104 -0
  32. package/src/input/check-steps.ts +144 -0
  33. package/src/input/defaults.ts +32 -0
  34. package/src/input/direction.ts +107 -0
  35. package/src/internal.ts +51 -0
  36. package/src/knob/geometry.ts +100 -0
  37. package/src/midi/access.ts +16 -15
  38. package/src/midi/input.ts +2 -9
  39. package/src/number-input/stepper-drag.ts +147 -0
  40. package/src/number-input/text.ts +100 -0
  41. package/src/number-input/value.ts +129 -0
  42. package/src/options/replace.ts +22 -0
  43. package/src/piano/index.ts +128 -2
  44. package/src/piano/layout.ts +19 -0
  45. package/src/piano/shortcuts.ts +86 -0
  46. package/src/pointer/drag-value.ts +3 -1
  47. package/src/pointer/long-press.ts +103 -0
  48. package/src/pointer/wheel.ts +10 -7
  49. package/src/points-editor/index.ts +367 -0
  50. package/src/position.ts +20 -0
  51. package/src/slider/decimal-digits.ts +23 -0
  52. package/src/slider/marks.ts +56 -0
  53. package/src/style.ts +41 -0
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { ValueRange } from "@tremolo-ui/functions";
1
+ import { D as ModifierState, E as ModifierMap, O as ModifierValue, S as notePosition, T as Modifier, _ as NoteRange, c as PointsEditorInstance, f as createPointsEditor, h as XYInput, l as PointsEditorOptions, m as XY, p as SelectionBoxRect, s as PointPosition, t as MarksOptions, u as PointsEditorPoint, v as PianoLayout, w as InputEventOption } from "./marks-DK7xJmGM.js";
2
+ import { Scale, ValueRange } from "@tremolo-ui/functions";
2
3
  //#region src/canvas/animation.d.ts
3
4
  /** What the canvas looked like when a frame was drawn. */
4
5
  interface AnimationFrame {
@@ -15,7 +16,15 @@ interface AnimationFrame {
15
16
  /** Frames per second implied by `deltaTime`, or 0 when no time elapsed. */
16
17
  fps: number;
17
18
  }
19
+ /**
20
+ * Draws one frame, given the 2D context and the frame: the size in CSS pixels,
21
+ * `count`, `deltaTime`, `elapsedTime` and `fps`.
22
+ */
18
23
  type CanvasDrawFunction = (context: CanvasRenderingContext2D, frame: AnimationFrame) => void;
24
+ /**
25
+ * Sets up what every frame shares. Called once, with the context and the size
26
+ * in CSS pixels, before the first frame; not again on a resize.
27
+ */
19
28
  type CanvasInitFunction = (context: CanvasRenderingContext2D, size: {
20
29
  width: number;
21
30
  height: number;
@@ -91,59 +100,6 @@ interface AnimationCanvasInstance {
91
100
  */
92
101
  export declare function createAnimationCanvas(canvas: HTMLCanvasElement, options: AnimationCanvasOptions): AnimationCanvasInstance;
93
102
  //#endregion
94
- //#region src/canvas/context.d.ts
95
- /**
96
- * The assignable parts of a 2D context's drawing state. They have to be
97
- * carried across a resize by hand because setting `canvas.width` resets the
98
- * context to its defaults. The transform and line dash are handled separately
99
- * by {@link DrawingContext} because they are exposed through methods.
100
- *
101
- * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save
102
- */
103
- export declare const drawingState: readonly ["strokeStyle", "fillStyle", "globalAlpha", "lineWidth", "lineCap", "lineJoin", "miterLimit", "lineDashOffset", "shadowOffsetX", "shadowOffsetY", "shadowBlur", "shadowColor", "globalCompositeOperation", "filter", "font", "fontKerning", "fontStretch", "fontVariantCaps", "textAlign", "textBaseline", "direction", "letterSpacing", "textRendering", "wordSpacing", "imageSmoothingEnabled", "imageSmoothingQuality"];
104
- type DrawingState = (typeof drawingState)[number];
105
- type DrawingStateValue = CanvasRenderingContext2D[DrawingState];
106
- type DrawingContext = Pick<CanvasRenderingContext2D, DrawingState> & {
107
- /** The current line dash sequence. */
108
- lineDash: number[];
109
- /** The current transformation matrix. */
110
- transform: DOMMatrix;
111
- };
112
- export declare function isDrawingState(value: unknown): value is DrawingState;
113
- //#endregion
114
- //#region src/file/accept.d.ts
115
- /**
116
- * What an `accept` rule is matched against.
117
- *
118
- * `File` satisfies it, and so does `DataTransferItem` — which matters while a
119
- * drag is still in the air, since the browser reports the type of what is
120
- * being dragged but withholds the name.
121
- */
122
- interface AcceptCandidate {
123
- /** The file name, when it is known. */
124
- name?: string;
125
- /** The MIME type, or `''` when the browser has no type for it. */
126
- type: string;
127
- }
128
- /**
129
- * Does a file satisfy an `accept` attribute?
130
- *
131
- * `accept` is written the way the HTML attribute is: a comma separated list of
132
- * extensions (`.wav`), MIME types (`audio/wav`) and type groups (`audio/*`).
133
- * Anything that matches one entry is accepted, and an empty or missing
134
- * `accept` takes everything.
135
- *
136
- * **The browser's own `accept` is only a hint to the file picker.** A person
137
- * can switch it to "All Files", drag a file in, or pick one the picker was
138
- * never asked about, so what arrives still has to be checked.
139
- *
140
- * A rule that cannot be decided is not treated as a rejection: with no `name`,
141
- * an extension rule says nothing either way, and `accept=".wav"` reports a
142
- * match rather than refusing a file it has not seen the name of. The name is
143
- * there by the time the file is dropped, which is when the answer counts.
144
- */
145
- export declare function matchesAccept(candidate: AcceptCandidate, accept?: string): boolean;
146
- //#endregion
147
103
  //#region src/file/drop-zone.d.ts
148
104
  /** What is in the air over the element. */
149
105
  interface DropZoneState {
@@ -184,7 +140,8 @@ interface DropZoneOptions {
184
140
  onDrop?: (files: File[], event: DragEvent) => void;
185
141
  /**
186
142
  * Called with the dropped files that do not match `accept`, so that the
187
- * reason can be shown.
143
+ * reason can be shown. It comes after `onDrop` for the same drop, so a list
144
+ * of rejected files can be cleared in `onDrop` and filled here.
188
145
  */
189
146
  onReject?: (files: File[], event: DragEvent) => void;
190
147
  /** Called whenever {@link DropZoneInstance.state} would change. */
@@ -212,98 +169,134 @@ interface DropZoneInstance {
212
169
  */
213
170
  export declare function createDropZone(element: Element, options?: DropZoneOptions): DropZoneInstance;
214
171
  //#endregion
215
- //#region src/input/modifiers.d.ts
172
+ //#region src/input/change-gesture.d.ts
173
+ /** What a change of value was made with. */
174
+ type ChangeSource = 'pointer' | 'wheel' | 'keyboard' | 'doubleClick';
175
+ interface ChangeGestureOptions {
176
+ /** Called before the first change of a gesture. */
177
+ onStart?: (source: ChangeSource) => void;
178
+ /** Called after the last change of a gesture. */
179
+ onEnd?: (source: ChangeSource) => void;
180
+ /**
181
+ * How long after the last wheel notch or key press a gesture counts as
182
+ * over, in milliseconds. Neither has an event that says it is done, so the
183
+ * gesture ends when nothing more arrives for this long.
184
+ *
185
+ * @default 500
186
+ */
187
+ endDelay?: number;
188
+ }
189
+ interface ChangeGestureInstance {
190
+ /**
191
+ * Start a gesture that lasts until {@link end}, such as a drag. A gesture of
192
+ * another kind in progress ends first.
193
+ */
194
+ hold: (source: ChangeSource) => void;
195
+ /**
196
+ * One step of a gesture with no end of its own, such as a wheel notch:
197
+ * starts one if none is in progress, and ends it `endDelay` after the last
198
+ * step. While a held gesture is in progress the step belongs to it.
199
+ */
200
+ pulse: (source: ChangeSource) => void;
201
+ /**
202
+ * A gesture that starts and ends around a single change, such as a reset:
203
+ * `change` runs between the two.
204
+ */
205
+ instant: (source: ChangeSource, change: () => void) => void;
206
+ /** End the gesture in progress, if any. */
207
+ end: () => void;
208
+ /** Whether a gesture is in progress. */
209
+ active: () => boolean;
210
+ /** Replace the given options. A gesture in progress picks them up. */
211
+ update: (options: Partial<ChangeGestureOptions>) => void;
212
+ /** End a gesture in progress, so that nothing is left touched. */
213
+ destroy: () => void;
214
+ }
216
215
  /**
217
- * Options for setting the amount of keyboard and mouse wheel changes.
216
+ * Track when a change of value starts and ends, whatever made it: a drag, the
217
+ * wheel, the keys or a reset. A host that records automation needs both ends
218
+ * to know when the control is touched.
218
219
  */
219
- type InputEventOption = readonly ['normalized' | 'raw', number];
220
+ export declare function createChangeGesture(options?: ChangeGestureOptions): ChangeGestureInstance;
221
+ //#endregion
222
+ //#region src/input/defaults.d.ts
220
223
  /**
221
- * A modifier key that can carry an amount of its own.
224
+ * The keyboard amount used by Knob, NumberInput, Slider, and XYPad by default:
225
+ * 1 per press in the units of the value, and 0.1 with shift held. That is one
226
+ * `step` only while `step` is 1; a coarser `step` rounds 1 straight back, which
227
+ * `checkSteps` warns about.
222
228
  *
223
- * `ctrl` and `meta` are kept apart rather than folded into one "command" key:
224
- * a plugin UI that mirrors a desktop host usually wants the same physical key
225
- * on every platform, not the platform's own convention.
229
+ * A modifier entry is not snapped to `step`, which is what lets the finer
230
+ * amount move at all — see `applyDelta`.
226
231
  */
227
- type Modifier = 'shift' | 'alt' | 'ctrl' | 'meta';
228
- /** The modifier flags of a `WheelEvent` or a `KeyboardEvent`. */
229
- interface ModifierState {
230
- shiftKey: boolean;
231
- altKey: boolean;
232
- ctrlKey: boolean;
233
- metaKey: boolean;
234
- }
235
- /** One setting per modifier key, with `default` for none of them. */
236
- type ModifierSetting = number | InputEventOption;
237
- type ModifierMap<T extends ModifierSetting> = {
238
- default: T;
239
- } & Partial<Record<Modifier, T>>;
232
+ export declare const DEFAULT_KEYBOARD_OPTIONS: ModifierValue<InputEventOption>;
240
233
  /**
241
- * A single setting, or one per modifier key.
234
+ * The wheel amount used by Knob, NumberInput, Slider, and XYPad by default.
242
235
  *
243
- * @example
244
- * ['raw', 1]
245
- * { default: ['raw', 1], shift: ['raw', 0.1] }
236
+ * Browsers turn shift+wheel into horizontal scrolling, which empties `deltaY`
237
+ * and fills `deltaX`, so no modifier is bound here.
246
238
  */
247
- type ModifierValue<T extends ModifierSetting> = T | ModifierMap<T>;
239
+ export declare const DEFAULT_WHEEL_OPTIONS: ModifierValue<InputEventOption>;
248
240
  /**
249
- * Pick the setting that applies, given the modifier keys being held.
250
- *
251
- * @example
252
- * selectModifier({ default: 1, shift: 0.1 }, event)
241
+ * The drag sensitivity used by value controls by default. Shift makes the
242
+ * same movement cover a tenth of the range, matching the arrow keys.
253
243
  */
254
- export declare function selectModifier<T extends ModifierSetting>(options: ModifierValue<T>, modifiers?: ModifierState): {
255
- value: T;
256
- modifier: Modifier | null;
257
- };
244
+ export declare const DEFAULT_DRAG_SENSITIVITY: ModifierValue<number>;
245
+ //#endregion
246
+ //#region src/knob/geometry.d.ts
247
+ /**
248
+ * Width and height of the viewBox a knob is drawn in. The arcs and the thumb
249
+ * are laid out in these units, and the SVG scales them to the knob's size.
250
+ */
251
+ export declare const KNOB_VIEWBOX_SIZE = 100;
252
+ interface KnobAngleOptions {
253
+ value: number;
254
+ min: number;
255
+ max: number;
256
+ scale: Scale;
257
+ /** Where the active arc starts from, so that it can grow from the middle. */
258
+ startValue: number;
259
+ /** How far the knob turns from `min` to `max`, in degrees. */
260
+ angleRange: number;
261
+ }
258
262
  /**
259
- * Turn every entry of a setting into another kind of setting, keeping which
260
- * modifier each belongs to.
261
- *
262
- * A drag sensitivity is a number and a keyboard amount is a tuple, but the two
263
- * describe the same thing from the caller's side. This carries one over to the
264
- * other so that a component can hand a sensitivity to {@link applyDelta}
265
- * without unpicking the modifier map itself — which matters, since naming a
266
- * modifier is also what takes `step` out of the pipeline.
267
- *
268
- * @example
269
- * mapModifier({ default: 1, shift: 0.1 }, (f) => ['raw', step * f])
270
- * // { default: ['raw', 1], shift: ['raw', 0.1] }
263
+ * The angles a knob is drawn with, in degrees clockwise from the top.
264
+ *
265
+ * The travel is centred on the top, so `angleRange` of 270 runs from -135 to
266
+ * 135. Derived from the value alone, so a wrapper can call it while rendering.
267
+ */
268
+ interface KnobAngles {
269
+ /** The value, normalized to 0..1 along the scale. */
270
+ p: number;
271
+ /** Where the travel starts. */
272
+ r1: number;
273
+ /** Where the active arc starts: the lower of the value and `startValue`. */
274
+ r2: number;
275
+ /** Where the active arc ends: the higher of the value and `startValue`. */
276
+ r3: number;
277
+ /** Where the travel ends. */
278
+ r4: number;
279
+ }
280
+ export declare function knobAngles({ value, min, max, scale, startValue, angleRange }: KnobAngleOptions): KnobAngles;
281
+ /**
282
+ * The radius that keeps a stroke of `strokeWidth` inside the viewBox: half of
283
+ * the stroke falls outside the path it is drawn along.
271
284
  */
272
- export declare function mapModifier<T extends ModifierSetting, U extends ModifierSetting>(options: ModifierValue<T>, fn: (value: T) => U): ModifierValue<U>;
285
+ export declare function knobArcRadius(strokeWidth: number | string | undefined): number;
286
+ /** Build an SVG path for an arc, splitting full turns into drawable segments. */
287
+ export declare function knobArcPath(startAngle: number, endAngle: number, radius: number): string;
273
288
  //#endregion
274
- //#region src/input/apply-delta.d.ts
289
+ //#region src/midi/access.d.ts
275
290
  /**
276
- * Move a value by an amount of input, as reported by a wheel or an arrow key.
277
- *
278
- * The pipeline matches {@link createDragValue}: scale, then step, then clamp.
279
- * Which key or which sign of `deltaY` counts as which direction is left to the
280
- * caller, since it differs per component.
281
- *
282
- * @param direction which way, and how many times, to apply the option. The
283
- * size of one step is `option[1]`, so this is normally `1` or `-1`.
284
- *
285
- * @param modifiers the event, for `options` that name a modifier key. See
286
- * {@link selectModifier}.
287
- *
288
- * @example
289
- * // ArrowDown on a slider whose keyboard option is ['raw', 1]
290
- * applyDelta(value, -1, keyboard, { min, max, step, scale })
291
+ * Why MIDI access could not be had.
291
292
  *
292
- * @example
293
- * // Shift+ArrowDown, where `keyboard` is { default: …, shift: ['raw', 0.1] }
294
- * applyDelta(value, -1, keyboard, range, event)
293
+ * - `'NOT_SUPPORTED'`: the browser has no Web MIDI API, and asking again will
294
+ * not change that
295
+ * - `'PERMISSION_DENIED'`: the user or the browser said no. Asking again is
296
+ * worthwhile
297
+ * - `'UNAVAILABLE'`: anything else
295
298
  */
296
- export declare function applyDelta(value: number, direction: number, options: ModifierValue<InputEventOption>, { min, max, step, scale }: ValueRange, modifiers?: ModifierState): number;
297
- //#endregion
298
- //#region src/midi/access.d.ts
299
- /** @private */
300
- export declare const PERMISSION_DENIED = "PERMISSION_DENIED";
301
- /** @private */
302
- export declare const NOT_SUPPORTED = "NOT_SUPPORTED";
303
- /** @private */
304
- export declare const UNAVAILABLE = "UNAVAILABLE";
305
- /** @private */
306
- type MIDIAccessError = typeof PERMISSION_DENIED | typeof NOT_SUPPORTED | typeof UNAVAILABLE;
299
+ type MIDIAccessError = 'NOT_SUPPORTED' | 'PERMISSION_DENIED' | 'UNAVAILABLE';
307
300
  type MIDIAccessOptions = {
308
301
  /**
309
302
  * Ask for system exclusive messages as well.
@@ -345,13 +338,6 @@ interface MIDIAccessInstance {
345
338
  export declare function createMIDIAccess(): MIDIAccessInstance;
346
339
  //#endregion
347
340
  //#region src/midi/input.d.ts
348
- /**
349
- * Centre of the 14-bit pitch bend range: no bend.
350
- *
351
- * The range is not symmetric — 0 is 8192 below centre and 16383 is 8191 above
352
- * — so a wheel at rest reports exactly this rather than half of the maximum.
353
- */
354
- export declare const PITCH_BEND_CENTER = 8192;
355
341
  /**
356
342
  * Every handler is given the channel last, as 0-15. MIDI channels are written
357
343
  * 1-16 on hardware, so add one before showing it to anyone.
@@ -360,7 +346,8 @@ type MIDIInputHandlers = {
360
346
  onNoteOnEvent?: (note: number, velocity: number, channel: number) => void;
361
347
  onNoteOffEvent?: (note: number, channel: number) => void;
362
348
  /**
363
- * The 14-bit bend, 0-16383, centred at {@link PITCH_BEND_CENTER}.
349
+ * The 14-bit bend, 0-16383, centred at 8192. `normalizePitchBend` in
350
+ * `@tremolo-ui/functions` turns it into -1 to 1.
364
351
  *
365
352
  * The two data bytes are little-endian — the first carries the low 7 bits —
366
353
  * which is the other way round from every other message.
@@ -407,69 +394,37 @@ interface MIDIMessageInstance {
407
394
  */
408
395
  export declare function createMIDIMessage(midiAccess: MIDIAccess | null, onMIDIMessage: (event: MIDIMessageEvent) => void): MIDIMessageInstance;
409
396
  //#endregion
410
- //#region src/piano/layout.d.ts
411
- type NoteRange = {
412
- first: number;
413
- last: number;
414
- };
415
- /**
416
- * `[noteRange.first, noteRange.first + 1, ..., noteRange.last]`
417
- */
418
- export declare function getNoteRangeArray(noteRange: NoteRange): number[];
419
- /**
420
- * The geometry of a drawn keyboard.
421
- *
422
- * One description is shared by the drawing and the hit testing, so a key cannot
423
- * be drawn somewhere other than where it responds.
424
- */
425
- interface PianoLayout {
426
- noteRange: NoteRange;
427
- /** Width of a white key, excluding {@link PianoLayout.keyGap}. */
428
- whiteKeyWidth: number;
429
- /**
430
- * Space between two white keys. Part of the slot a white key occupies, so it
431
- * still belongs to one of the keys for the purpose of hit testing.
432
- *
433
- * @default 1
434
- */
435
- keyGap?: number;
397
+ //#region src/piano/shortcuts.d.ts
398
+ type KeyboardShortcuts = {
436
399
  /**
437
- * Width of a black key, as a fraction of {@link PianoLayout.whiteKeyWidth}.
400
+ * Keys laid out from `noteRange.first`, one entry per semitone.
438
401
  *
439
- * @default 0.65
402
+ * An empty string leaves that note without a shortcut: `KeyboardEvent.key` is
403
+ * never empty, so the entry can never match. Use it to skip the black keys
404
+ * (see {@link SHORTCUTS.HOME_ROW_NATURAL}) and keep the remaining entries
405
+ * lined up with the notes.
440
406
  */
441
- blackKeyWidthRatio?: number;
442
- /**
443
- * Height of a black key, as a fraction of the height of the keyboard.
444
- *
445
- * @default 0.6
446
- */
447
- blackKeyHeightRatio?: number;
448
- }
449
- /** Width of a black key in pixels. */
450
- export declare function blackKeyWidth(layout: PianoLayout): number;
451
- /** Width of the whole keyboard in pixels. */
452
- export declare function pianoWidth(layout: PianoLayout): number;
407
+ keys: string[];
408
+ };
453
409
  /**
454
- * Offset of the left edge of a key from the left edge of the keyboard, in
455
- * pixels.
456
- *
457
- * Notes outside `noteRange` are placed too, so the value is negative below
458
- * `noteRange.first`.
410
+ * Ready-made keyboard layouts. Both assume `noteRange.first` is a C.
459
411
  */
460
- export declare function notePosition(note: number, layout: PianoLayout): number;
412
+ export declare const SHORTCUTS: {
413
+ /** Every semitone from C, over the two rows of a QWERTY keyboard. */
414
+ HOME_ROW: {
415
+ keys: string[];
416
+ };
417
+ /** The white keys only, on the home row. Black keys have no shortcut. */
418
+ HOME_ROW_NATURAL: {
419
+ keys: string[];
420
+ };
421
+ };
461
422
  /**
462
- * The note drawn at a point, or null where there is none.
463
- *
464
- * Black keys are tested first, so they win where they overlap a white one. A
465
- * white key covers its gap as well as its width, so the whole width of the
466
- * keyboard belongs to some key and a click cannot fall between two.
467
- *
468
- * @param x offset from the left edge of the keyboard, in pixels
469
- * @param y offset from its top edge, in pixels
470
- * @param height height of the keyboard, in pixels
423
+ * Where keyboard shortcuts listen. `root` handles keys only while the piano
424
+ * or one of its descendants has focus; `window` handles them anywhere on the
425
+ * page except in editable elements.
471
426
  */
472
- export declare function noteAt(x: number, y: number, height: number, layout: PianoLayout): number | null;
427
+ type KeyboardShortcutsScope = 'root' | 'window';
473
428
  //#endregion
474
429
  //#region src/piano/index.d.ts
475
430
  /**
@@ -499,6 +454,24 @@ interface PianoInputOptions {
499
454
  * @default 127
500
455
  */
501
456
  midiMax?: number;
457
+ /**
458
+ * Play notes from the computer keyboard: `keys[i]` plays
459
+ * `layout.noteRange.first + i`. `SHORTCUTS` has ready-made layouts.
460
+ *
461
+ * A held key keeps its note until it is released, the focus leaves (with
462
+ * `root`), or the window loses focus. Changing the keys, the scope or the
463
+ * note range releases every note a key is holding, since the key would
464
+ * mean something else on release.
465
+ */
466
+ keyboardShortcuts?: KeyboardShortcuts;
467
+ /**
468
+ * Where keyboard shortcuts listen: on the element (`root`), which has to
469
+ * be focusable, or anywhere on the page (`window`). Keys typed into an
470
+ * editable element are ignored either way.
471
+ *
472
+ * @default 'root'
473
+ */
474
+ keyboardShortcutsScope?: KeyboardShortcutsScope;
502
475
  /** Called when a note starts sounding, not for each source that asks. */
503
476
  onPlayNote?: (note: number, velocity?: number) => void;
504
477
  /** Called once the last source holding a note has let go. */
@@ -513,8 +486,8 @@ interface PianoInputInstance {
513
486
  */
514
487
  update: (options: Partial<PianoInputOptions>) => void;
515
488
  /**
516
- * Start a note from something other than a pointer: a keyboard shortcut, a
517
- * MIDI message, an imperative call.
489
+ * Start a note from something other than a pointer or a shortcut: a MIDI
490
+ * message, an imperative call.
518
491
  */
519
492
  noteOn: (note: number, options?: {
520
493
  source?: NoteSource;
@@ -656,32 +629,6 @@ interface DragInstance {
656
629
  */
657
630
  export declare function createDrag(element: Element, options?: DragOptions): DragInstance;
658
631
  //#endregion
659
- //#region src/xy.d.ts
660
- /**
661
- * A pair of per-axis values. The tuple elements are labelled, so editors show
662
- * `[x: number, y: number]` rather than a bare pair.
663
- */
664
- type XY<T> = [x: T, y: T];
665
- /**
666
- * A setting that may be given once for both axes, or per axis.
667
- *
668
- * A single value is told from a pair with `Array.isArray`, so the single form
669
- * is only offered while `T` cannot itself be an array. Where it can, the pair
670
- * is the only way to write it, since a lone array would be read as a pair.
671
- */
672
- type XYInput<T> = [T] extends [readonly unknown[]] ? readonly [x: T, y: T] : T | readonly [x: T, y: T];
673
- /**
674
- * Spread a setting that may have been given as a single value.
675
- *
676
- * The parameter is written out rather than taken as `XYInput<T>`: a
677
- * conditional type cannot be narrowed, so the constraint stays where it is
678
- * declared and this takes both forms.
679
- *
680
- * The pair is copied rather than passed along, so that the result is a tuple
681
- * the caller owns even when a readonly one was given.
682
- */
683
- export declare function toXY<T>(value: T | readonly [x: T, y: T]): XY<T>;
684
- //#endregion
685
632
  //#region src/pointer/drag-value.d.ts
686
633
  /**
687
634
  * How the 0-1 travel of one axis maps onto a value.
@@ -821,10 +768,58 @@ interface DragValueInstance {
821
768
  */
822
769
  export declare function createDragValue(element: Element, options: DragValueOptions): DragValueInstance;
823
770
  //#endregion
771
+ //#region src/pointer/long-press.d.ts
772
+ interface LongPressOptions {
773
+ /** Called once on the press, then again every `interval` after `delay`. */
774
+ onPress: () => void;
775
+ /**
776
+ * How long the press has to be held before it starts repeating, in
777
+ * milliseconds.
778
+ *
779
+ * @default 500
780
+ */
781
+ delay?: number;
782
+ /**
783
+ * How often it repeats once it has started, in milliseconds.
784
+ *
785
+ * @default 40
786
+ */
787
+ interval?: number;
788
+ }
789
+ interface LongPressInstance {
790
+ /**
791
+ * Start a press, from a `pointerdown` or with no event at all. Only the
792
+ * primary button starts one, and a press already in progress is left alone.
793
+ */
794
+ start: (event?: Pick<PointerEvent, 'button' | 'pointerId'>) => void;
795
+ /** End the press, as releasing the pointer would. */
796
+ stop: () => void;
797
+ /** Replace the given options. The press in progress picks them up. */
798
+ update: (options: Partial<LongPressOptions>) => void;
799
+ /** Whether a press is in progress. */
800
+ pressed: () => boolean;
801
+ destroy: () => void;
802
+ }
803
+ /**
804
+ * Repeat an action while a pointer is held down: once on the press, then
805
+ * again every `interval` after `delay` — the way a stepper button or a
806
+ * key held on a keyboard behaves.
807
+ *
808
+ * The release is listened for on the window, not on the element: the
809
+ * pointer may be let go anywhere. Only the pointer that started the press
810
+ * ends it, so a second finger lifting elsewhere does not. The window losing
811
+ * focus ends it too, since the release would never arrive.
812
+ */
813
+ export declare function createLongPress(options: LongPressOptions): LongPressInstance;
814
+ //#endregion
824
815
  //#region src/pointer/wheel.d.ts
825
816
  interface WheelOptions {
826
- /** Replace the callback through {@link WheelInstance.update}. */
827
- onWheel?: (event: WheelEvent) => void;
817
+ /**
818
+ * Called for every wheel event that `requireFocus` lets through. The
819
+ * listener is not passive, so this may call `preventDefault()` to keep the
820
+ * page from scrolling.
821
+ */
822
+ onWheel: (event: WheelEvent) => void;
828
823
  /**
829
824
  * Only report events while the focus is inside the element.
830
825
  *
@@ -842,7 +837,7 @@ interface WheelOptions {
842
837
  }
843
838
  interface WheelInstance {
844
839
  /** Replace the given options, keeping the listener in place. */
845
- update: (options: WheelOptions) => void;
840
+ update: (options: Partial<WheelOptions>) => void;
846
841
  destroy: () => void;
847
842
  }
848
843
  /**
@@ -851,67 +846,18 @@ interface WheelInstance {
851
846
  * The listener is registered with `passive: false` so that the handler can call
852
847
  * `preventDefault()` to stop the page from scrolling.
853
848
  */
854
- export declare function createWheel(element: Element, onWheel: (event: WheelEvent) => void, options?: WheelOptions): WheelInstance;
849
+ export declare function createWheel(element: Element, options: WheelOptions): WheelInstance;
855
850
  //#endregion
856
- //#region src/selection/box.d.ts
857
- /**
858
- * A rectangle in the 0..1 space of whatever the box is drawn over, with `y`
859
- * growing downwards — the same space the items are given in.
860
- */
861
- interface SelectionBoxRect {
862
- x: number;
863
- y: number;
864
- width: number;
865
- height: number;
866
- }
867
- interface SelectionBoxOptions<Id> {
868
- /**
869
- * Everything the box can pick up, read on every move rather than taken as a
870
- * snapshot: what is under the box changes while it is dragged, and an item
871
- * may have moved since the last one.
872
- */
873
- items: () => Iterable<readonly [Id, XY<number>]>;
874
- /** The box as it is dragged, and `null` once it is gone. */
875
- onBoxChange?: (box: SelectionBoxRect | null) => void;
876
- /** What the box covers, added to whatever it started from. */
877
- onSelectionChange?: (ids: Id[]) => void;
878
- }
879
- interface SelectionBoxBeginOptions<Id> {
880
- /**
881
- * Add to `selection` rather than replacing it. Ctrl / meta rather than
882
- * shift, for the controls where shift is the fine-adjustment key.
883
- */
884
- additive?: boolean;
885
- /** What was selected before the box started. Only read when `additive`. */
886
- selection?: readonly Id[];
887
- }
888
- interface SelectionBoxInstance<Id> {
889
- /** Replace the given options, without interrupting a box in progress. */
890
- update: (options: Partial<SelectionBoxOptions<Id>>) => void;
891
- /** Start a box at `at`, which is one of its corners. */
892
- begin: (at: XY<number>, options?: SelectionBoxBeginOptions<Id>) => void;
893
- /** Drag the opposite corner to `to`. */
894
- move: (to: XY<number>) => void;
895
- /**
896
- * Finish the box. The selection stays as it is.
897
- *
898
- * @returns whether a box was running, so that a caller can tell a drag from
899
- * a press that selected nothing.
900
- */
901
- end: () => boolean;
902
- /** The box being dragged, or `null` when there is none. */
903
- box: () => SelectionBoxRect | null;
904
- destroy: () => void;
905
- }
906
- /** Whether the box covers the point, edges included. */
907
- export declare function selectionBoxCovers(box: SelectionBoxRect, [x, y]: XY<number>): boolean;
851
+ //#region src/position.d.ts
908
852
  /**
909
- * Selecting by dragging a box over a set of items.
853
+ * Where a value sits along a track, as a whole percentage from its start.
910
854
  *
911
- * The drag itself is not here: the caller owns the pointer, and reports where
912
- * it went in the same 0..1 space the items are given in.
855
+ * Normalized along the scale, so a thumb, the fill behind it and the marks
856
+ * all sit on the curve the drag follows. `reversed` measures from the other
857
+ * end — for a track that grows upwards or leftwards on screen, since CSS
858
+ * places things from the top and the left.
913
859
  */
914
- export declare function createSelectionBox<Id>(options: SelectionBoxOptions<Id>): SelectionBoxInstance<Id>;
860
+ export declare function valuePercent(value: number, { min, max, scale }: Pick<ValueRange, 'min' | 'max' | 'scale'>, reversed?: boolean): number;
915
861
  //#endregion
916
- export type { AcceptCandidate, AnimationCanvasInstance, AnimationCanvasOptions, AnimationFrame, AxisOptions, CanvasDrawFunction, CanvasInitFunction, DragInstance, DragOptions, DragState, DragValueInstance, DragValueMapping, DragValueOptions, DrawingContext, DrawingState, DrawingStateValue, DropZoneInstance, DropZoneOptions, DropZoneState, InputEventOption, MIDIAccessError, MIDIAccessInstance, MIDIAccessOptions, MIDIAccessState, MIDIInputHandlers, MIDIInputInstance, MIDIMessageInstance, MappingContext, Modifier, ModifierMap, ModifierState, ModifierValue, NoteRange, NoteSource, PianoInputInstance, PianoInputOptions, PianoLayout, SelectionBoxBeginOptions, SelectionBoxInstance, SelectionBoxOptions, SelectionBoxRect, WheelInstance, WheelOptions, XY, XYInput };
862
+ export { type AnimationCanvasInstance, type AnimationCanvasOptions, type AnimationFrame, type AxisOptions, type CanvasDrawFunction, type CanvasInitFunction, type ChangeGestureInstance, type ChangeGestureOptions, type ChangeSource, type DragInstance, type DragOptions, type DragState, type DragValueInstance, type DragValueMapping, type DragValueOptions, type DropZoneInstance, type DropZoneOptions, type DropZoneState, type InputEventOption, type KeyboardShortcuts, type KeyboardShortcutsScope, type KnobAngleOptions, type KnobAngles, type LongPressInstance, type LongPressOptions, type MIDIAccessError, type MIDIAccessInstance, type MIDIAccessOptions, type MIDIAccessState, type MIDIInputHandlers, type MIDIInputInstance, type MIDIMessageInstance, type MappingContext, type MarksOptions, type Modifier, type ModifierMap, type ModifierState, type ModifierValue, type NoteRange, type NoteSource, type PianoInputInstance, type PianoInputOptions, type PianoLayout, type PointPosition, type PointsEditorInstance, type PointsEditorOptions, type PointsEditorPoint, type SelectionBoxRect, type WheelInstance, type WheelOptions, type XY, type XYInput, createPointsEditor, notePosition };
917
863
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/canvas/animation.ts","../src/canvas/context.ts","../src/file/accept.ts","../src/file/drop-zone.ts","../src/input/modifiers.ts","../src/input/apply-delta.ts","../src/midi/access.ts","../src/midi/input.ts","../src/midi/message.ts","../src/piano/layout.ts","../src/piano/index.ts","../src/pointer/drag.ts","../src/xy.ts","../src/pointer/drag-value.ts","../src/pointer/wheel.ts","../src/selection/box.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/canvas/animation.ts","../src/file/drop-zone.ts","../src/input/change-gesture.ts","../src/input/defaults.ts","../src/knob/geometry.ts","../src/midi/access.ts","../src/midi/input.ts","../src/midi/message.ts","../src/piano/shortcuts.ts","../src/piano/index.ts","../src/pointer/drag.ts","../src/pointer/drag-value.ts","../src/pointer/long-press.ts","../src/pointer/wheel.ts","../src/position.ts"],"mappings":"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"}