@cutoff/audio-ui-core 1.0.0-preview.20260123.1125

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 (48) hide show
  1. package/LICENSE.md +690 -0
  2. package/dist/constants/cssVars.d.ts +42 -0
  3. package/dist/constants/cssVars.d.ts.map +1 -0
  4. package/dist/constants/cursors.d.ts +2 -0
  5. package/dist/constants/cursors.d.ts.map +1 -0
  6. package/dist/constants/interaction.d.ts +24 -0
  7. package/dist/constants/interaction.d.ts.map +1 -0
  8. package/dist/constants/styles.d.ts +17 -0
  9. package/dist/constants/styles.d.ts.map +1 -0
  10. package/dist/constants/theme.d.ts +66 -0
  11. package/dist/constants/theme.d.ts.map +1 -0
  12. package/dist/constants/themeDefaults.d.ts +16 -0
  13. package/dist/constants/themeDefaults.d.ts.map +1 -0
  14. package/dist/controller/BooleanInteractionController.d.ts +141 -0
  15. package/dist/controller/BooleanInteractionController.d.ts.map +1 -0
  16. package/dist/controller/ContinuousInteractionController.d.ts +114 -0
  17. package/dist/controller/ContinuousInteractionController.d.ts.map +1 -0
  18. package/dist/controller/DiscreteInteractionController.d.ts +51 -0
  19. package/dist/controller/DiscreteInteractionController.d.ts.map +1 -0
  20. package/dist/controller/NoteInteractionController.d.ts +88 -0
  21. package/dist/controller/NoteInteractionController.d.ts.map +1 -0
  22. package/dist/index.d.ts +21 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +1404 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/model/AudioParameter.d.ts +437 -0
  27. package/dist/model/AudioParameter.d.ts.map +1 -0
  28. package/dist/styles/styles.css +256 -0
  29. package/dist/styles/themes.css +193 -0
  30. package/dist/types.d.ts +18 -0
  31. package/dist/types.d.ts.map +1 -0
  32. package/dist/utils/colorUtils.d.ts +102 -0
  33. package/dist/utils/colorUtils.d.ts.map +1 -0
  34. package/dist/utils/math.d.ts +108 -0
  35. package/dist/utils/math.d.ts.map +1 -0
  36. package/dist/utils/normalizedProps.d.ts +22 -0
  37. package/dist/utils/normalizedProps.d.ts.map +1 -0
  38. package/dist/utils/noteUtils.d.ts +71 -0
  39. package/dist/utils/noteUtils.d.ts.map +1 -0
  40. package/dist/utils/propCompare.d.ts +22 -0
  41. package/dist/utils/propCompare.d.ts.map +1 -0
  42. package/dist/utils/sizing.d.ts +39 -0
  43. package/dist/utils/sizing.d.ts.map +1 -0
  44. package/dist/utils/svg.d.ts +27 -0
  45. package/dist/utils/svg.d.ts.map +1 -0
  46. package/dist/utils/valueFormatters.d.ts +167 -0
  47. package/dist/utils/valueFormatters.d.ts.map +1 -0
  48. package/package.json +48 -0
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared constants for CSS custom property names used throughout the library.
3
+ * Using string constants makes it easier to update prefixes in the future and
4
+ * keeps TypeScript aware of the possible values.
5
+ */
6
+ export declare const CSS_VARS: {
7
+ readonly roundnessBase: "--audioui-roundness-base";
8
+ readonly primaryColor: "--audioui-primary-color";
9
+ readonly adaptiveDefaultColor: "--audioui-adaptive-default-color";
10
+ readonly adaptive50: "--audioui-adaptive-50";
11
+ readonly adaptive20: "--audioui-adaptive-20";
12
+ readonly adaptiveLight: "--audioui-adaptive-light";
13
+ readonly adaptiveDark: "--audioui-adaptive-dark";
14
+ readonly primary50: "--audioui-primary-50";
15
+ readonly primary20: "--audioui-primary-20";
16
+ readonly primaryLight: "--audioui-primary-light";
17
+ readonly primaryDark: "--audioui-primary-dark";
18
+ readonly textColor: "--audioui-text-color";
19
+ readonly defaultFontSize: "--audioui-default-font-size";
20
+ readonly highlightEffect: "--audioui-highlight-effect";
21
+ readonly highlightTransitionDuration: "--audioui-highlight-transition-duration";
22
+ readonly cursorClickable: "--audioui-cursor-clickable";
23
+ readonly cursorBidirectional: "--audioui-cursor-bidirectional";
24
+ readonly cursorHorizontal: "--audioui-cursor-horizontal";
25
+ readonly cursorVertical: "--audioui-cursor-vertical";
26
+ readonly cursorCircular: "--audioui-cursor-circular";
27
+ readonly cursorNoneditable: "--audioui-cursor-noneditable";
28
+ readonly cursorDisabled: "--audioui-cursor-disabled";
29
+ readonly keysIvory: "--audioui-keys-ivory";
30
+ readonly keysIvoryStroke: "--audioui-keys-ivory-stroke";
31
+ readonly keysEbony: "--audioui-keys-ebony";
32
+ readonly keysEbonyStroke: "--audioui-keys-ebony-stroke";
33
+ readonly knobCapFill: "--audioui-knob-cap-fill";
34
+ readonly buttonStrokeWidth: "--audioui-button-stroke-width";
35
+ readonly sliderTrackColor: "--audioui-slider-track-color";
36
+ readonly sliderStripColor: "--audioui-slider-strip-color";
37
+ readonly sliderCursorColor: "--audioui-slider-cursor-color";
38
+ readonly sliderCursorBorderColor: "--audioui-slider-cursor-border-color";
39
+ readonly sliderCursorBorderWidth: "--audioui-slider-cursor-border-width";
40
+ };
41
+ export type AudioUiCssVar = (typeof CSS_VARS)[keyof typeof CSS_VARS];
42
+ //# sourceMappingURL=cssVars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cssVars.d.ts","sourceRoot":"","sources":["../../src/constants/cssVars.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CX,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const CIRCULAR_CURSOR = "url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxMCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSI0Ii8+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTAiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==') 16 16, move";
2
+ //# sourceMappingURL=cursors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursors.d.ts","sourceRoot":"","sources":["../../src/constants/cursors.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,eAAe,sWAC2U,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Standard sensitivity for continuous controls.
3
+ * Represents normalized value change per pixel of drag.
4
+ * 0.005 means 200 pixels for a full 0-1 sweep.
5
+ * This aligns with standard "virtual throw" in audio software.
6
+ */
7
+ export declare const DEFAULT_CONTINUOUS_SENSITIVITY = 0.005;
8
+ /**
9
+ * Standard sensitivity for wheel interactions.
10
+ * Represents normalized value change per unit of wheel delta.
11
+ */
12
+ export declare const DEFAULT_WHEEL_SENSITIVITY = 0.005;
13
+ /**
14
+ * Target pixels per discrete step.
15
+ * Used for adaptive sensitivity: if a step exists, we ensure
16
+ * it doesn't take more than this many pixels to traverse it.
17
+ * This prevents "dead zones" in low-resolution parameters.
18
+ */
19
+ export declare const TARGET_PIXELS_PER_STEP = 30;
20
+ /**
21
+ * Default step size for keyboard interaction (normalized 0..1).
22
+ */
23
+ export declare const DEFAULT_KEYBOARD_STEP = 0.05;
24
+ //# sourceMappingURL=interaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../../src/constants/interaction.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Centralized collection of CSS class names used across AudioUI components.
3
+ * Keeping them in one place makes it easier to enforce prefixing conventions
4
+ * and minimizes the risk of typos in string literals.
5
+ */
6
+ export declare const CLASSNAMES: {
7
+ /** Root class applied to all AudioUI components */
8
+ readonly root: "audioui";
9
+ /** Container helper class for components that manage their own SVG sizing */
10
+ readonly container: "audioui-component-container";
11
+ /** Highlight class used for interactive states */
12
+ readonly highlight: "audioui-highlight";
13
+ /** Icon wrapper class for HTML overlay - ensures SVG icons fill their container */
14
+ readonly iconWrapper: "audioui-icon-wrapper";
15
+ };
16
+ export type AudioUiClassName = (typeof CLASSNAMES)[keyof typeof CLASSNAMES];
17
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/constants/styles.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,eAAO,MAAM,UAAU;IACnB,mDAAmD;;IAEnD,6EAA6E;;IAE7E,kDAAkD;;IAElD,mFAAmF;;CAE7E,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Predefined theme colors as CSS color values
3
+ * These are just the primary color - variants (primary50, primary20) are computed automatically by components
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * import { themeColors, setThemeColor } from '@cutoff/audio-ui-react';
8
+ *
9
+ * // Set global theme color
10
+ * setThemeColor(themeColors.blue);
11
+ *
12
+ * // Or use in component props
13
+ * <Knob value={50} color={themeColors.blue} />
14
+ * ```
15
+ */
16
+ export declare const themeColors: {
17
+ /** Default adaptive color (white in dark mode, black in light mode) */
18
+ readonly default: "var(--audioui-theme-default)";
19
+ /** Blue theme color */
20
+ readonly blue: "var(--audioui-theme-blue)";
21
+ /** Orange theme color */
22
+ readonly orange: "var(--audioui-theme-orange)";
23
+ /** Pink theme color */
24
+ readonly pink: "var(--audioui-theme-pink)";
25
+ /** Green theme color */
26
+ readonly green: "var(--audioui-theme-green)";
27
+ /** Purple theme color */
28
+ readonly purple: "var(--audioui-theme-purple)";
29
+ /** Yellow theme color */
30
+ readonly yellow: "var(--audioui-theme-yellow)";
31
+ };
32
+ /**
33
+ * Predefined theme colors as direct HSL values
34
+ * Use these when CSS variables aren't available or you need direct color values
35
+ */
36
+ export declare const themeColorsDirect: {
37
+ readonly default: {
38
+ readonly light: "hsl(0, 0%, 10%)";
39
+ readonly dark: "hsl(0, 0%, 96%)";
40
+ };
41
+ readonly blue: {
42
+ readonly light: "hsl(204, 88%, 52%)";
43
+ readonly dark: "hsl(204, 88%, 53%)";
44
+ };
45
+ readonly orange: {
46
+ readonly light: "hsl(29, 100%, 48%)";
47
+ readonly dark: "hsl(29, 100%, 50%)";
48
+ };
49
+ readonly pink: {
50
+ readonly light: "hsl(332, 92%, 52%)";
51
+ readonly dark: "hsl(332, 95%, 54%)";
52
+ };
53
+ readonly green: {
54
+ readonly light: "hsl(160, 95%, 44%)";
55
+ readonly dark: "hsl(160, 98%, 37%)";
56
+ };
57
+ readonly purple: {
58
+ readonly light: "hsl(252, 96%, 54%)";
59
+ readonly dark: "hsl(252, 100%, 67%)";
60
+ };
61
+ readonly yellow: {
62
+ readonly light: "hsl(50, 100%, 50%)";
63
+ readonly dark: "hsl(50, 100%, 50%)";
64
+ };
65
+ };
66
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/constants/theme.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW;IACpB,uEAAuE;;IAEvE,uBAAuB;;IAEvB,yBAAyB;;IAEzB,uBAAuB;;IAEvB,wBAAwB;;IAExB,yBAAyB;;IAEzB,yBAAyB;;CAEnB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BpB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Default theme values for themable components.
3
+ * These constants provide a single source of truth for default values
4
+ * and can be easily adjusted to change the global appearance.
5
+ */
6
+ /**
7
+ * Default roundness value (normalized 0.0-1.0)
8
+ * @default 0.3
9
+ */
10
+ export declare const DEFAULT_ROUNDNESS = 0.3;
11
+ /**
12
+ * Default thickness value (normalized 0.0-1.0)
13
+ * @default 0.4
14
+ */
15
+ export declare const DEFAULT_THICKNESS = 0.4;
16
+ //# sourceMappingURL=themeDefaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themeDefaults.d.ts","sourceRoot":"","sources":["../../src/constants/themeDefaults.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AAEH;;;GAGG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC"}
@@ -0,0 +1,141 @@
1
+ export type BooleanInteractionMode = "toggle" | "momentary";
2
+ export interface BooleanInteractionConfig {
3
+ /** Current value of the control */
4
+ value: boolean;
5
+ /** Interaction mode: toggle (latch) or momentary */
6
+ mode: BooleanInteractionMode;
7
+ /** Callback to update the value */
8
+ onValueChange: (value: boolean) => void;
9
+ /** Whether the control is disabled */
10
+ disabled?: boolean;
11
+ }
12
+ /**
13
+ * Framework-agnostic controller for boolean interaction logic.
14
+ *
15
+ * Handles the logic for toggle and momentary button interactions, including:
16
+ * - Mouse down/up events for activation and release
17
+ * - Global pointer tracking (works even when press starts outside button)
18
+ * - Mouse enter/leave events for drag-in/drag-out behavior
19
+ * - Keyboard events (Enter/Space) for activation and release
20
+ * - Press state tracking for momentary mode
21
+ *
22
+ * **Drag-In/Drag-Out Behavior:**
23
+ * The controller tracks global pointer state to enable hardware-like button interactions:
24
+ * - **Momentary Mode**: Press inside → turns on; drag out while pressed → turns off; drag back in while pressed → turns on again. Works even when press starts outside the button.
25
+ * - **Toggle Mode**: Press inside → toggles state; drag out while pressed → no change; drag back in while pressed → toggles again. Works even when press starts outside the button.
26
+ *
27
+ * This enables step sequencer-like interactions where multiple buttons can be activated with a single drag gesture.
28
+ *
29
+ * This controller is designed to be framework-agnostic and can be used with any UI framework
30
+ * by wrapping it in framework-specific hooks (e.g., `useBooleanInteraction` for React).
31
+ */
32
+ export declare class BooleanInteractionController {
33
+ private config;
34
+ private isPressed;
35
+ private isGlobalPointerDown;
36
+ constructor(config: BooleanInteractionConfig);
37
+ /**
38
+ * Updates the controller configuration.
39
+ *
40
+ * This method should be called whenever the configuration changes (e.g., value, mode, disabled state).
41
+ * The controller will use the new configuration for all subsequent interactions.
42
+ *
43
+ * @param {BooleanInteractionConfig} config - New configuration object
44
+ */
45
+ updateConfig(config: BooleanInteractionConfig): void;
46
+ /**
47
+ * Handles global pointer down events (mouse or touch).
48
+ *
49
+ * This tracks when a pointer is pressed anywhere on the page, not just on this button.
50
+ * This allows the button to respond to drag-in behavior even when the press starts outside.
51
+ *
52
+ * @param {boolean} defaultPrevented - Whether the event's default action has been prevented. If true, the handler does nothing.
53
+ */
54
+ handleGlobalPointerDown: (defaultPrevented: boolean) => void;
55
+ /**
56
+ * Handles mouse down events on the button element.
57
+ *
58
+ * Behavior depends on interaction mode:
59
+ * - **Toggle mode**: Flips the current value (true ↔ false)
60
+ * - **Momentary mode**: Sets value to true and tracks press state for later release
61
+ *
62
+ * @param {boolean} defaultPrevented - Whether the event's default action has been prevented. If true, the handler does nothing.
63
+ */
64
+ handleMouseDown: (defaultPrevented: boolean) => void;
65
+ /**
66
+ * Handles mouse up events on the button element.
67
+ *
68
+ * For momentary mode: Sets value to false if the button is currently pressed.
69
+ * This prevents false releases if the button wasn't actually pressed.
70
+ * Toggle mode: No action (toggle happens on mousedown only).
71
+ *
72
+ * Note: This is called when mouse is released on the button. The global pointer up
73
+ * handler will also be called to reset global state.
74
+ *
75
+ * @param {boolean} defaultPrevented - Whether the event's default action has been prevented. If true, the handler does nothing.
76
+ */
77
+ handleMouseUp: (defaultPrevented: boolean) => void;
78
+ /**
79
+ * Handles global pointer up events (mouse or touch).
80
+ *
81
+ * This method is called when a pointer up event occurs anywhere on the page.
82
+ * It resets the global pointer state and handles release for momentary buttons.
83
+ *
84
+ * Only affects momentary mode buttons that are currently pressed.
85
+ */
86
+ handleGlobalPointerUp: () => void;
87
+ /**
88
+ * Handles mouse enter events (pointer enters the button element).
89
+ *
90
+ * When a pointer enters the button while globally pressed:
91
+ * - **Momentary mode**: Sets value to true
92
+ * - **Toggle mode**: Toggles the value
93
+ *
94
+ * This enables drag-in behavior: pressing outside and dragging into the button activates it.
95
+ */
96
+ handleMouseEnter: () => void;
97
+ /**
98
+ * Handles mouse leave events (pointer leaves the button element).
99
+ *
100
+ * When a pointer leaves the button while globally pressed:
101
+ * - **Momentary mode**: Sets value to false
102
+ * - **Toggle mode**: No action (state remains as-is)
103
+ *
104
+ * This enables drag-out behavior: pressing inside and dragging out deactivates momentary buttons.
105
+ */
106
+ handleMouseLeave: () => void;
107
+ /**
108
+ * Handles keyboard key down events.
109
+ *
110
+ * Supported keys:
111
+ * - `Enter` or `Space`: Activates the button
112
+ * - Toggle mode: Flips the value
113
+ * - Momentary mode: Sets value to true
114
+ *
115
+ * @param {string} key - The keyboard key that was pressed
116
+ * @returns {boolean} `true` if the event was handled (and should be prevented), `false` otherwise
117
+ */
118
+ handleKeyDown: (key: string) => boolean;
119
+ /**
120
+ * Handles keyboard key up events.
121
+ *
122
+ * Supported keys (momentary mode only):
123
+ * - `Enter` or `Space`: Releases the button (sets value to false)
124
+ *
125
+ * Toggle mode: No action (toggle happens on keydown only).
126
+ *
127
+ * @param {string} key - The keyboard key that was released
128
+ * @returns {boolean} `true` if the event was handled (and should be prevented), `false` otherwise
129
+ */
130
+ handleKeyUp: (key: string) => boolean;
131
+ /**
132
+ * Gets the current press state (for momentary buttons).
133
+ *
134
+ * This is primarily used for internal state tracking. External code typically
135
+ * doesn't need to check this, as the value reflects the button state.
136
+ *
137
+ * @returns {boolean} `true` if the button is currently pressed, `false` otherwise
138
+ */
139
+ getIsPressed(): boolean;
140
+ }
141
+ //# sourceMappingURL=BooleanInteractionController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BooleanInteractionController.d.ts","sourceRoot":"","sources":["../../src/controller/BooleanInteractionController.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE5D,MAAM,WAAW,wBAAwB;IACrC,mCAAmC;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,oDAAoD;IACpD,IAAI,EAAE,sBAAsB,CAAC;IAC7B,mCAAmC;IACnC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,4BAA4B;IAIzB,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,mBAAmB,CAAkB;gBAEzB,MAAM,EAAE,wBAAwB;IAEpD;;;;;;;OAOG;IACI,YAAY,CAAC,MAAM,EAAE,wBAAwB;IAIpD;;;;;;;OAOG;IACI,uBAAuB,GAAI,kBAAkB,OAAO,UAIzD;IAEF;;;;;;;;OAQG;IACI,eAAe,GAAI,kBAAkB,OAAO,UAcjD;IAEF;;;;;;;;;;;OAWG;IACI,aAAa,GAAI,kBAAkB,OAAO,UAW/C;IAEF;;;;;;;OAOG;IACI,qBAAqB,aAS1B;IAEF;;;;;;;;OAQG;IACI,gBAAgB,aAcrB;IAEF;;;;;;;;OAQG;IACI,gBAAgB,aAYrB;IAEF;;;;;;;;;;OAUG;IACI,aAAa,GAAI,KAAK,MAAM,KAAG,OAAO,CAc3C;IAEF;;;;;;;;;;OAUG;IACI,WAAW,GAAI,KAAK,MAAM,KAAG,OAAO,CAQzC;IAEF;;;;;;;OAOG;IACI,YAAY,IAAI,OAAO;CAGjC"}
@@ -0,0 +1,114 @@
1
+ import { InteractionDirection, InteractionMode } from '../types';
2
+
3
+ export interface ContinuousInteractionConfig {
4
+ /**
5
+ * Function to adjust the value based on a delta.
6
+ * ...
7
+ */
8
+ adjustValue: (delta: number, sensitivity?: number) => void;
9
+ /**
10
+ * Interaction mode: drag, wheel, or both.
11
+ * @default "both"
12
+ */
13
+ interactionMode?: InteractionMode;
14
+ /**
15
+ * Direction of the drag interaction.
16
+ * @default "both"
17
+ */
18
+ direction?: InteractionDirection;
19
+ /**
20
+ * Sensitivity of the control.
21
+ * ...
22
+ * @default 0.005
23
+ */
24
+ sensitivity?: number;
25
+ /**
26
+ * Separate sensitivity for wheel events.
27
+ * If not provided, defaults to DEFAULT_WHEEL_SENSITIVITY (0.005).
28
+ */
29
+ wheelSensitivity?: number;
30
+ /**
31
+ * Step size for keyboard interaction (normalized 0..1)
32
+ * @default 0.05
33
+ */
34
+ keyboardStep?: number;
35
+ /**
36
+ * Normalized step size of the parameter (0..1).
37
+ * Used for adaptive wheel interaction (accumulating deltas until a step is reached).
38
+ * If not provided, wheel interaction is continuous.
39
+ */
40
+ step?: number;
41
+ /**
42
+ * Callback when a drag interaction starts
43
+ */
44
+ onDragStart?: () => void;
45
+ /**
46
+ * Callback when a drag interaction ends
47
+ */
48
+ onDragEnd?: () => void;
49
+ /**
50
+ * Whether the control is disabled
51
+ */
52
+ disabled?: boolean;
53
+ }
54
+ /**
55
+ * Framework-agnostic controller for handling user interactions (Drag, Wheel, Keyboard)
56
+ * for continuous controls.
57
+ */
58
+ export declare class ContinuousInteractionController {
59
+ private config;
60
+ private startX;
61
+ private startY;
62
+ private centerX;
63
+ private centerY;
64
+ private isDragging;
65
+ private wheelAccumulator;
66
+ private dragAccumulator;
67
+ constructor(config: ContinuousInteractionConfig);
68
+ /**
69
+ * Updates the configuration of the controller.
70
+ * @param config Partial configuration to update.
71
+ */
72
+ updateConfig(config: Partial<ContinuousInteractionConfig>): void;
73
+ /**
74
+ * Handles the start of a mouse drag interaction.
75
+ * Should be called from the component's onMouseDown handler.
76
+ * @param clientX The X coordinate of the mouse event.
77
+ * @param clientY The Y coordinate of the mouse event.
78
+ * @param target The event target (used for circular center calculation).
79
+ */
80
+ handleMouseDown: (clientX: number, clientY: number, target?: EventTarget) => void;
81
+ /**
82
+ * Handles the start of a touch interaction.
83
+ * Should be called from the component's onTouchStart handler.
84
+ * @param clientX The X coordinate of the touch event.
85
+ * @param clientY The Y coordinate of the touch event.
86
+ * @param target The event target.
87
+ */
88
+ handleTouchStart: (clientX: number, clientY: number, target?: EventTarget) => void;
89
+ private startDrag;
90
+ private handleGlobalMouseMove;
91
+ private handleGlobalTouchMove;
92
+ private processDrag;
93
+ /**
94
+ * Handles global mouse up event to end drag.
95
+ */
96
+ private handleGlobalMouseUp;
97
+ /**
98
+ * Handles wheel events.
99
+ * Should be called from the component's onWheel handler.
100
+ * @param e The wheel event.
101
+ */
102
+ handleWheel: (e: WheelEvent) => void;
103
+ /**
104
+ * Handles keyboard events (Arrow keys, Home, End).
105
+ * Should be called from the component's onKeyDown handler.
106
+ * @param e The keyboard event.
107
+ */
108
+ handleKeyDown: (e: KeyboardEvent) => void;
109
+ /**
110
+ * Cleans up event listeners.
111
+ */
112
+ dispose(): void;
113
+ }
114
+ //# sourceMappingURL=ContinuousInteractionController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContinuousInteractionController.d.ts","sourceRoot":"","sources":["../../src/controller/ContinuousInteractionController.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAOjE,MAAM,WAAW,2BAA2B;IACxC;;;OAGG;IACH,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAE3D;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;;OAGG;IACH,SAAS,CAAC,EAAE,oBAAoB,CAAC;IAEjC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAEzB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,+BAA+B;IACxC,OAAO,CAAC,MAAM,CAOZ;IACF,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,eAAe,CAAK;gBAEhB,MAAM,EAAE,2BAA2B;IAgB/C;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,2BAA2B,CAAC;IAIhE;;;;;;OAMG;IACI,eAAe,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,EAAE,SAAS,WAAW,UAG9E;IAEF;;;;;;OAMG;IACI,gBAAgB,GAAI,SAAS,MAAM,EAAE,SAAS,MAAM,EAAE,SAAS,WAAW,UAG/E;IAEF,OAAO,CAAC,SAAS;IAgCjB,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,WAAW;IAuDnB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;;;OAIG;IACI,WAAW,GAAI,GAAG,UAAU,UA2BjC;IAEF;;;;OAIG;IACI,aAAa,GAAI,GAAG,aAAa,UA+BtC;IAEF;;OAEG;IACI,OAAO;CAGjB"}
@@ -0,0 +1,51 @@
1
+ export interface DiscreteInteractionConfig {
2
+ /** Current value of the control */
3
+ value: string | number;
4
+ /** List of available options */
5
+ options: Array<{
6
+ value: string | number;
7
+ }>;
8
+ /** Callback to update the value */
9
+ onValueChange: (value: string | number) => void;
10
+ /** Whether the control is disabled */
11
+ disabled?: boolean;
12
+ }
13
+ /**
14
+ * Framework-agnostic controller for discrete interaction logic.
15
+ * Handles the logic for cycling and stepping through discrete options.
16
+ */
17
+ export declare class DiscreteInteractionController {
18
+ private config;
19
+ constructor(config: DiscreteInteractionConfig);
20
+ /**
21
+ * Updates the configuration.
22
+ * @param config New configuration object.
23
+ */
24
+ updateConfig(config: DiscreteInteractionConfig): void;
25
+ private getCurrentIndex;
26
+ private setValueAtIndex;
27
+ /**
28
+ * Cycles to the next value, wrapping around to the start if needed.
29
+ */
30
+ cycleNext(): void;
31
+ /**
32
+ * Steps to the next value, clamping at the end.
33
+ */
34
+ stepNext(): void;
35
+ /**
36
+ * Steps to the previous value, clamping at the start.
37
+ */
38
+ stepPrev(): void;
39
+ /**
40
+ * Handles click events.
41
+ * Cycles to the next value if the event was not already prevented (e.g. by a drag).
42
+ * @param defaultPrevented Whether the event's default action has been prevented.
43
+ */
44
+ handleClick: (defaultPrevented: boolean) => void;
45
+ /**
46
+ * Handles keyboard events for discrete controls.
47
+ * Returns true if the event was handled (and thus should be prevented), false otherwise.
48
+ */
49
+ handleKeyDown: (key: string) => boolean;
50
+ }
51
+ //# sourceMappingURL=DiscreteInteractionController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiscreteInteractionController.d.ts","sourceRoot":"","sources":["../../src/controller/DiscreteInteractionController.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,yBAAyB;IACtC,mCAAmC;IACnC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,gCAAgC;IAChC,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3C,mCAAmC;IACnC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAChD,sCAAsC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,6BAA6B;IAC1B,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,yBAAyB;IAErD;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,yBAAyB;IAIrD,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACI,SAAS;IAOhB;;OAEG;IACI,QAAQ;IAQf;;OAEG;IACI,QAAQ;IAQf;;;;OAIG;IACI,WAAW,GAAI,kBAAkB,OAAO,UAK7C;IAEF;;;OAGG;IACI,aAAa,GAAI,KAAK,MAAM,KAAG,OAAO,CAkB3C;CACL"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Configuration for the NoteInteractionController.
3
+ */
4
+ export interface NoteInteractionConfig {
5
+ /** Callback triggered when a note is pressed (on) */
6
+ onNoteOn: (note: number, pointerId: number | string) => void;
7
+ /** Callback triggered when a note is released (off) */
8
+ onNoteOff: (note: number, pointerId: number | string) => void;
9
+ /** Whether the interaction is disabled */
10
+ disabled?: boolean;
11
+ }
12
+ /**
13
+ * Framework-agnostic controller for keyboard/note interaction logic.
14
+ *
15
+ * Handles polyphonic glissando-style interactions:
16
+ * - Tracks multiple concurrent pointers (mouse, multi-touch)
17
+ * - Detects note changes when sliding across keys
18
+ * - Triggers onNoteOn/onNoteOff events
19
+ *
20
+ * This controller is designed to be used by any UI framework by providing
21
+ * coordinates-to-note mapping and pointer events.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const controller = new NoteInteractionController({
26
+ * onNoteOn: (note) => console.log('Note On:', note),
27
+ * onNoteOff: (note) => console.log('Note Off:', note)
28
+ * });
29
+ *
30
+ * // On mouse/touch down
31
+ * controller.handlePointerDown(1, 60); // C4
32
+ *
33
+ * // On movement
34
+ * controller.handlePointerMove(1, 62); // D4 (triggers Note Off 60, Note On 62)
35
+ *
36
+ * // On mouse/touch up
37
+ * controller.handlePointerUp(1); // triggers Note Off 62
38
+ * ```
39
+ */
40
+ export declare class NoteInteractionController {
41
+ private config;
42
+ private pointerNotes;
43
+ /**
44
+ * Creates a new NoteInteractionController.
45
+ * @param config Initial configuration
46
+ */
47
+ constructor(config: NoteInteractionConfig);
48
+ /**
49
+ * Updates the controller configuration.
50
+ * @param config New configuration object
51
+ */
52
+ updateConfig(config: NoteInteractionConfig): void;
53
+ /**
54
+ * Handles the start of a pointer interaction (down).
55
+ *
56
+ * Tracks the pointer state globally and triggers onNoteOn if the pointer
57
+ * is over a specific note.
58
+ *
59
+ * @param pointerId Unique identifier for the pointer
60
+ * @param note The MIDI note number at the pointer location, or null if none
61
+ */
62
+ handlePointerDown(pointerId: number | string, note: number | null): void;
63
+ /**
64
+ * Handles pointer movement (move).
65
+ *
66
+ * Enables glissando behavior by detecting when a tracked pointer moves
67
+ * from one note to another.
68
+ *
69
+ * @param pointerId Unique identifier for the pointer
70
+ * @param note The MIDI note number at the current pointer location, or null if none
71
+ */
72
+ handlePointerMove(pointerId: number | string, note: number | null): void;
73
+ /**
74
+ * Handles the end of a pointer interaction (up).
75
+ *
76
+ * Releases any active note associated with the pointer and removes it
77
+ * from the tracking map.
78
+ *
79
+ * @param pointerId Unique identifier for the pointer
80
+ */
81
+ handlePointerUp(pointerId: number | string): void;
82
+ /**
83
+ * Cancels all active pointer interactions.
84
+ * Useful when the component is unmounted or focus is lost.
85
+ */
86
+ cancelAll(): void;
87
+ }
88
+ //# sourceMappingURL=NoteInteractionController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoteInteractionController.d.ts","sourceRoot":"","sources":["../../src/controller/NoteInteractionController.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,qDAAqD;IACrD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7D,uDAAuD;IACvD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAC9D,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,yBAAyB;IAOtB,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,YAAY,CAAkD;IAEtE;;;OAGG;gBACiB,MAAM,EAAE,qBAAqB;IAEjD;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,qBAAqB;IAIjD;;;;;;;;OAQG;IACI,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAcxE;;;;;;;;OAQG;IACI,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAyBxE;;;;;;;OAOG;IACI,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAUjD;;;OAGG;IACI,SAAS;CAQnB"}
@@ -0,0 +1,21 @@
1
+ export * from './types';
2
+ export * from './constants/styles';
3
+ export * from './constants/theme';
4
+ export * from './constants/themeDefaults';
5
+ export * from './constants/cssVars';
6
+ export * from './constants/cursors';
7
+ export * from './constants/interaction';
8
+ export * from './controller/ContinuousInteractionController';
9
+ export * from './controller/DiscreteInteractionController';
10
+ export * from './controller/BooleanInteractionController';
11
+ export * from './controller/NoteInteractionController';
12
+ export * from './model/AudioParameter';
13
+ export * from './utils/math';
14
+ export * from './utils/svg';
15
+ export * from './utils/sizing';
16
+ export * from './utils/colorUtils';
17
+ export * from './utils/normalizedProps';
18
+ export * from './utils/noteUtils';
19
+ export * from './utils/valueFormatters';
20
+ export * from './utils/propCompare';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8CAA8C,CAAC;AAC7D,cAAc,4CAA4C,CAAC;AAC3D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC"}