@vessel-dsp/control-ui 0.6.4

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 (76) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +74 -0
  3. package/dist/ControlSurface.d.ts +14 -0
  4. package/dist/ControlSurface.d.ts.map +1 -0
  5. package/dist/ControlSurface.js +81 -0
  6. package/dist/ControlSurface.js.map +1 -0
  7. package/dist/appearance.d.ts +3 -0
  8. package/dist/appearance.d.ts.map +1 -0
  9. package/dist/appearance.js +25 -0
  10. package/dist/appearance.js.map +1 -0
  11. package/dist/components/ControlFrame.d.ts +12 -0
  12. package/dist/components/ControlFrame.d.ts.map +1 -0
  13. package/dist/components/ControlFrame.js +6 -0
  14. package/dist/components/ControlFrame.js.map +1 -0
  15. package/dist/components/DetentedRotarySelect.d.ts +13 -0
  16. package/dist/components/DetentedRotarySelect.d.ts.map +1 -0
  17. package/dist/components/DetentedRotarySelect.js +13 -0
  18. package/dist/components/DetentedRotarySelect.js.map +1 -0
  19. package/dist/components/FootswitchButton.d.ts +15 -0
  20. package/dist/components/FootswitchButton.d.ts.map +1 -0
  21. package/dist/components/FootswitchButton.js +36 -0
  22. package/dist/components/FootswitchButton.js.map +1 -0
  23. package/dist/components/GraphicEqSlider.d.ts +13 -0
  24. package/dist/components/GraphicEqSlider.d.ts.map +1 -0
  25. package/dist/components/GraphicEqSlider.js +13 -0
  26. package/dist/components/GraphicEqSlider.js.map +1 -0
  27. package/dist/components/KnobControl.d.ts +13 -0
  28. package/dist/components/KnobControl.d.ts.map +1 -0
  29. package/dist/components/KnobControl.js +201 -0
  30. package/dist/components/KnobControl.js.map +1 -0
  31. package/dist/components/LedIndicator.d.ts +12 -0
  32. package/dist/components/LedIndicator.d.ts.map +1 -0
  33. package/dist/components/LedIndicator.js +11 -0
  34. package/dist/components/LedIndicator.js.map +1 -0
  35. package/dist/components/SwitchSelectControl.d.ts +13 -0
  36. package/dist/components/SwitchSelectControl.d.ts.map +1 -0
  37. package/dist/components/SwitchSelectControl.js +7 -0
  38. package/dist/components/SwitchSelectControl.js.map +1 -0
  39. package/dist/components/ToggleSwitchControl.d.ts +13 -0
  40. package/dist/components/ToggleSwitchControl.d.ts.map +1 -0
  41. package/dist/components/ToggleSwitchControl.js +13 -0
  42. package/dist/components/ToggleSwitchControl.js.map +1 -0
  43. package/dist/controls.d.ts +11 -0
  44. package/dist/controls.d.ts.map +1 -0
  45. package/dist/controls.js +115 -0
  46. package/dist/controls.js.map +1 -0
  47. package/dist/index.d.ts +29 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +16 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/render-plan.d.ts +16 -0
  52. package/dist/render-plan.d.ts.map +1 -0
  53. package/dist/render-plan.js +58 -0
  54. package/dist/render-plan.js.map +1 -0
  55. package/dist/state.d.ts +5 -0
  56. package/dist/state.d.ts.map +1 -0
  57. package/dist/state.js +33 -0
  58. package/dist/state.js.map +1 -0
  59. package/dist/styles.css +333 -0
  60. package/dist/theme.d.ts +14 -0
  61. package/dist/theme.d.ts.map +1 -0
  62. package/dist/theme.js +30 -0
  63. package/dist/theme.js.map +1 -0
  64. package/dist/types.d.ts +43 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/types.js +2 -0
  67. package/dist/types.js.map +1 -0
  68. package/dist/useControlState.d.ts +13 -0
  69. package/dist/useControlState.d.ts.map +1 -0
  70. package/dist/useControlState.js +23 -0
  71. package/dist/useControlState.js.map +1 -0
  72. package/dist/utils.d.ts +4 -0
  73. package/dist/utils.d.ts.map +1 -0
  74. package/dist/utils.js +23 -0
  75. package/dist/utils.js.map +1 -0
  76. package/package.json +72 -0
@@ -0,0 +1,201 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { knobStepSize } from '@vessel-dsp/core';
4
+ import { formatControlValue, snapControlPosition } from '../controls.js';
5
+ import { cx } from '../utils.js';
6
+ import { ControlFrame } from './ControlFrame.js';
7
+ const KNOB_SWEEP_DEGREES = 300;
8
+ const KNOB_START_DEGREES = -150;
9
+ const KNOB_DRAG_PIXELS_PER_RANGE = 160;
10
+ export function KnobControl({ control, position, disabled = false, label = control.name, className, classNames, onPositionChange, }) {
11
+ const drag = useRef(undefined);
12
+ const [localPosition, setLocalPosition] = useState(undefined);
13
+ const [isDragging, setIsDragging] = useState(false);
14
+ const normalizedPosition = snapControlPosition({ kind: 'knob', control }, position);
15
+ const previousNormalizedPosition = useRef(normalizedPosition);
16
+ const displayPosition = localPosition ?? normalizedPosition;
17
+ const rotation = KNOB_START_DEGREES + displayPosition * KNOB_SWEEP_DEGREES;
18
+ const progress = displayPosition * KNOB_SWEEP_DEGREES;
19
+ const readout = formatControlValue({ kind: 'knob', control }, { kind: 'knob', position: displayPosition });
20
+ useEffect(() => {
21
+ if (previousNormalizedPosition.current === normalizedPosition) {
22
+ return;
23
+ }
24
+ previousNormalizedPosition.current = normalizedPosition;
25
+ if (drag.current === undefined) {
26
+ setLocalPosition(undefined);
27
+ }
28
+ }, [normalizedPosition]);
29
+ function snapPosition(nextPosition) {
30
+ if (disabled) {
31
+ return undefined;
32
+ }
33
+ return snapControlPosition({ kind: 'knob', control }, nextPosition);
34
+ }
35
+ function setPosition(nextPosition) {
36
+ const snapped = snapPosition(nextPosition);
37
+ if (snapped === undefined) {
38
+ return;
39
+ }
40
+ setLocalPosition(snapped);
41
+ onPositionChange?.(snapped);
42
+ }
43
+ function updateDragPosition(pointerId, clientX, movementX) {
44
+ const currentDrag = drag.current;
45
+ if (currentDrag === undefined || (pointerId !== undefined && currentDrag.pointerId !== pointerId)) {
46
+ return;
47
+ }
48
+ const hasRelativeMovement = movementX !== undefined && Number.isFinite(movementX);
49
+ const nextPosition = hasRelativeMovement
50
+ ? currentDrag.position + movementX / KNOB_DRAG_PIXELS_PER_RANGE
51
+ : currentDrag.startPosition + (clientX - currentDrag.startX) / KNOB_DRAG_PIXELS_PER_RANGE;
52
+ const snapped = snapPosition(nextPosition);
53
+ if (snapped === undefined) {
54
+ return;
55
+ }
56
+ if (snapped === currentDrag.position) {
57
+ return;
58
+ }
59
+ currentDrag.position = snapped;
60
+ setLocalPosition(snapped);
61
+ onPositionChange?.(snapped);
62
+ }
63
+ function finishDrag(pointerId) {
64
+ const currentDrag = drag.current;
65
+ if (currentDrag === undefined || (pointerId !== undefined && currentDrag.pointerId !== pointerId)) {
66
+ return;
67
+ }
68
+ drag.current = undefined;
69
+ setIsDragging(false);
70
+ currentDrag.removeDocumentListeners();
71
+ currentDrag.removeCursorLockClass();
72
+ try {
73
+ currentDrag.target.releasePointerCapture(currentDrag.pointerId);
74
+ }
75
+ catch {
76
+ // Pointer capture may already be released by the browser.
77
+ }
78
+ try {
79
+ currentDrag.ownerDocument.exitPointerLock?.();
80
+ }
81
+ catch {
82
+ // Some test and embedded environments expose partial pointer-lock APIs.
83
+ }
84
+ }
85
+ function handlePointerDown(event) {
86
+ if (disabled) {
87
+ return;
88
+ }
89
+ event.preventDefault?.();
90
+ const target = event.currentTarget;
91
+ const ownerDocument = target.ownerDocument;
92
+ const removeDocumentListeners = addKnobDragDocumentListeners(ownerDocument, {
93
+ move: (clientX, movementX, pointerId) => updateDragPosition(pointerId, clientX, movementX),
94
+ end: (pointerId) => finishDrag(pointerId),
95
+ });
96
+ const removeCursorLockClass = addKnobDraggingDocumentClass(ownerDocument);
97
+ drag.current = {
98
+ pointerId: event.pointerId,
99
+ startX: event.clientX,
100
+ startPosition: normalizedPosition,
101
+ position: normalizedPosition,
102
+ target,
103
+ ownerDocument,
104
+ removeDocumentListeners,
105
+ removeCursorLockClass,
106
+ };
107
+ setLocalPosition(normalizedPosition);
108
+ setIsDragging(true);
109
+ try {
110
+ target.setPointerCapture(event.pointerId);
111
+ }
112
+ catch {
113
+ // Document-level listeners still keep the drag active when capture is unavailable.
114
+ }
115
+ requestKnobPointerLock(target);
116
+ }
117
+ function handlePointerMove(event) {
118
+ if (drag.current?.removeDocumentListeners !== undefined) {
119
+ return;
120
+ }
121
+ updateDragPosition(event.pointerId, event.clientX, event.movementX);
122
+ }
123
+ function handlePointerUp(event) {
124
+ finishDrag(event.pointerId);
125
+ }
126
+ function handleKeyDown(event) {
127
+ const step = knobStepSize(control) ?? 0.01;
128
+ if (event.key === 'ArrowRight' || event.key === 'ArrowUp') {
129
+ event.preventDefault();
130
+ setPosition(normalizedPosition + step);
131
+ }
132
+ if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') {
133
+ event.preventDefault();
134
+ setPosition(normalizedPosition - step);
135
+ }
136
+ if (event.key === 'Home') {
137
+ event.preventDefault();
138
+ setPosition(0);
139
+ }
140
+ if (event.key === 'End') {
141
+ event.preventDefault();
142
+ setPosition(1);
143
+ }
144
+ }
145
+ const knobStyle = {
146
+ '--vdsp-control-ui-knob-rotation': `${rotation}deg`,
147
+ '--vdsp-control-ui-knob-sweep': `${KNOB_SWEEP_DEGREES}deg`,
148
+ '--vdsp-control-ui-knob-progress': `${progress}deg`,
149
+ };
150
+ return (_jsx(ControlFrame, { label: label, readout: readout, disabled: disabled, className: className, classNames: classNames, children: _jsxs("button", { type: "button", className: cx('vdsp-control-ui-control', 'vdsp-control-ui-knob', isDragging && 'is-dragging', classNames?.control), style: knobStyle, role: "slider", "aria-label": control.name, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": Math.round(displayPosition * 100), disabled: disabled, "data-vdsp-control-id": control.id, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerCancel: handlePointerUp, onKeyDown: handleKeyDown, children: [_jsx("span", { className: "vdsp-control-ui-knob__progress", "aria-hidden": "true", children: _jsx("span", { className: "vdsp-control-ui-knob__progress-fill" }) }), _jsx("span", { className: "vdsp-control-ui-knob__body", children: _jsx("span", { className: "vdsp-control-ui-knob__indicator-line" }) })] }) }));
151
+ }
152
+ function addKnobDragDocumentListeners(ownerDocument, handlers) {
153
+ function handlePointerMove(event) {
154
+ event.preventDefault();
155
+ handlers.move(event.clientX, event.movementX, event.pointerId);
156
+ }
157
+ function handleMouseMove(event) {
158
+ event.preventDefault();
159
+ handlers.move(event.clientX, event.movementX, undefined);
160
+ }
161
+ function handlePointerEnd(event) {
162
+ handlers.end(event.pointerId);
163
+ }
164
+ function handleMouseEnd() {
165
+ handlers.end(undefined);
166
+ }
167
+ ownerDocument.addEventListener('pointermove', handlePointerMove, { passive: false });
168
+ ownerDocument.addEventListener('pointerup', handlePointerEnd);
169
+ ownerDocument.addEventListener('pointercancel', handlePointerEnd);
170
+ ownerDocument.addEventListener('mousemove', handleMouseMove, { passive: false });
171
+ ownerDocument.addEventListener('mouseup', handleMouseEnd);
172
+ return () => {
173
+ ownerDocument.removeEventListener('pointermove', handlePointerMove);
174
+ ownerDocument.removeEventListener('pointerup', handlePointerEnd);
175
+ ownerDocument.removeEventListener('pointercancel', handlePointerEnd);
176
+ ownerDocument.removeEventListener('mousemove', handleMouseMove);
177
+ ownerDocument.removeEventListener('mouseup', handleMouseEnd);
178
+ };
179
+ }
180
+ function addKnobDraggingDocumentClass(ownerDocument) {
181
+ const className = 'vdsp-control-ui-is-knob-dragging';
182
+ ownerDocument.documentElement.classList.add(className);
183
+ return () => ownerDocument.documentElement.classList.remove(className);
184
+ }
185
+ function requestKnobPointerLock(target) {
186
+ const candidates = [target, target.ownerDocument.body, target.ownerDocument.documentElement];
187
+ for (const candidate of candidates) {
188
+ const requestPointerLock = candidate?.requestPointerLock;
189
+ if (requestPointerLock === undefined) {
190
+ continue;
191
+ }
192
+ try {
193
+ requestPointerLock.call(candidate);
194
+ return;
195
+ }
196
+ catch {
197
+ // Try the next DOM target. Pointer capture still works without pointer lock.
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=KnobControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KnobControl.js","sourceRoot":"","sources":["../../src/components/KnobControl.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { LedIndicator as CoreLedIndicator, LedValue } from '@vessel-dsp/core';
2
+ import type { ControlFrameClassNames } from '../types';
3
+ export type LedIndicatorProps = Readonly<{
4
+ control: CoreLedIndicator;
5
+ value: LedValue;
6
+ disabled?: boolean;
7
+ label?: string;
8
+ className?: string | undefined;
9
+ classNames?: ControlFrameClassNames | undefined;
10
+ }>;
11
+ export declare function LedIndicator({ control, value, disabled, label, className, classNames, }: LedIndicatorProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=LedIndicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LedIndicator.d.ts","sourceRoot":"","sources":["../../src/components/LedIndicator.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAIvD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACrC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;CACnD,CAAC,CAAC;AAEH,wBAAgB,YAAY,CAAC,EACzB,OAAO,EACP,KAAK,EACL,QAAgB,EAChB,KAAoB,EACpB,SAAS,EACT,UAAU,GACb,EAAE,iBAAiB,+BAkBnB"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cx } from '../utils.js';
3
+ import { ControlFrame } from './ControlFrame.js';
4
+ export function LedIndicator({ control, value, disabled = false, label = control.name, className, classNames, }) {
5
+ const intensity = value.intensity ?? (value.on ? 1 : 0);
6
+ const ledStyle = {
7
+ '--vdsp-control-ui-led-intensity': intensity,
8
+ };
9
+ return (_jsx(ControlFrame, { label: label, readout: value.on ? 'On' : 'Off', disabled: disabled, className: className, classNames: classNames, children: _jsx("span", { className: cx('vdsp-control-ui-control', 'vdsp-control-ui-led', value.on && 'is-on', classNames?.control), style: ledStyle, role: "status", "aria-label": `${control.name} ${value.on ? 'on' : 'off'}`, "data-vdsp-control-id": control.id }) }));
10
+ }
11
+ //# sourceMappingURL=LedIndicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LedIndicator.js","sourceRoot":"","sources":["../../src/components/LedIndicator.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAW9C,MAAM,UAAU,YAAY,CAAC,EACzB,OAAO,EACP,KAAK,EACL,QAAQ,GAAG,KAAK,EAChB,KAAK,GAAG,OAAO,CAAC,IAAI,EACpB,SAAS,EACT,UAAU,GACM;IAChB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAExD,MAAM,QAAQ,GAAG;QACb,iCAAiC,EAAE,SAAS;KACsB,CAAC;IAEvE,OAAO,CACH,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,YAC1H,eACI,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,qBAAqB,EAAE,KAAK,CAAC,EAAE,IAAI,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EACzG,KAAK,EAAE,QAAQ,EACf,IAAI,EAAC,QAAQ,gBACD,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,0BAClC,OAAO,CAAC,EAAE,GAClC,GACS,CAClB,CAAC;AACN,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { SwitchControl } from '@vessel-dsp/core';
2
+ import type { ControlFrameClassNames } from '../types';
3
+ export type SwitchSelectControlProps = Readonly<{
4
+ control: SwitchControl;
5
+ position: number;
6
+ disabled?: boolean;
7
+ label?: string;
8
+ className?: string | undefined;
9
+ classNames?: ControlFrameClassNames | undefined;
10
+ onPositionChange?: ((position: number) => void) | undefined;
11
+ }>;
12
+ export declare function SwitchSelectControl({ control, position, disabled, label, className, classNames, onPositionChange, }: SwitchSelectControlProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=SwitchSelectControl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwitchSelectControl.d.ts","sourceRoot":"","sources":["../../src/components/SwitchSelectControl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAIvD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC5C,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAChD,gBAAgB,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC/D,CAAC,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,QAAgB,EAChB,KAAoB,EACpB,SAAS,EACT,UAAU,EACV,gBAAgB,GACnB,EAAE,wBAAwB,+BAmB1B"}
@@ -0,0 +1,7 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { cx } from '../utils.js';
3
+ import { ControlFrame } from './ControlFrame.js';
4
+ export function SwitchSelectControl({ control, position, disabled = false, label = control.name, className, classNames, onPositionChange, }) {
5
+ return (_jsx(ControlFrame, { label: label, disabled: disabled, className: className, classNames: classNames, children: _jsx("select", { className: cx('vdsp-control-ui-control', 'vdsp-control-ui-select', classNames?.control), value: String(position), "aria-label": control.name, disabled: disabled, "data-vdsp-control-id": control.id, onChange: (event) => onPositionChange?.(Number(event.currentTarget.value)), children: Array.from({ length: control.positions }, (_, index) => (_jsxs("option", { value: String(index), children: ["Position ", index + 1] }, index))) }) }));
6
+ }
7
+ //# sourceMappingURL=SwitchSelectControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwitchSelectControl.js","sourceRoot":"","sources":["../../src/components/SwitchSelectControl.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAY9C,MAAM,UAAU,mBAAmB,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,KAAK,GAAG,OAAO,CAAC,IAAI,EACpB,SAAS,EACT,UAAU,EACV,gBAAgB,GACO;IACvB,OAAO,CACH,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,YACxF,iBACI,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,wBAAwB,EAAE,UAAU,EAAE,OAAO,CAAC,EACvF,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,gBACX,OAAO,CAAC,IAAI,EACxB,QAAQ,EAAE,QAAQ,0BACI,OAAO,CAAC,EAAE,EAChC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,YAEzE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CACrD,kBAAoB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,0BAC1B,KAAK,GAAG,CAAC,KADV,KAAK,CAET,CACZ,CAAC,GACG,GACE,CAClB,CAAC;AACN,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { SwitchControl } from '@vessel-dsp/core';
2
+ import type { ControlFrameClassNames } from '../types';
3
+ export type ToggleSwitchControlProps = Readonly<{
4
+ control: SwitchControl;
5
+ position: number;
6
+ disabled?: boolean;
7
+ label?: string;
8
+ className?: string | undefined;
9
+ classNames?: ControlFrameClassNames | undefined;
10
+ onPositionChange?: ((position: number) => void) | undefined;
11
+ }>;
12
+ export declare function ToggleSwitchControl({ control, position, disabled, label, className, classNames, onPositionChange, }: ToggleSwitchControlProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=ToggleSwitchControl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToggleSwitchControl.d.ts","sourceRoot":"","sources":["../../src/components/ToggleSwitchControl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAIvD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC5C,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAChD,gBAAgB,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC/D,CAAC,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,QAAgB,EAChB,KAAoB,EACpB,SAAS,EACT,UAAU,EACV,gBAAgB,GACnB,EAAE,wBAAwB,+BAgC1B"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cx } from '../utils.js';
3
+ import { ControlFrame } from './ControlFrame.js';
4
+ export function ToggleSwitchControl({ control, position, disabled = false, label = control.name, className, classNames, onPositionChange, }) {
5
+ const checked = position > 0;
6
+ function handleClick() {
7
+ if (!disabled) {
8
+ onPositionChange?.(checked ? 0 : 1);
9
+ }
10
+ }
11
+ return (_jsx(ControlFrame, { label: label, readout: `Position ${position + 1}`, disabled: disabled, className: className, classNames: classNames, children: _jsx("button", { type: "button", className: cx('vdsp-control-ui-control', 'vdsp-control-ui-toggle', checked && 'is-checked', classNames?.control), role: "switch", "aria-label": control.name, "aria-checked": checked, disabled: disabled, "data-vdsp-control-id": control.id, onClick: handleClick, children: _jsx("span", { className: "vdsp-control-ui-toggle__track", children: _jsx("span", { className: "vdsp-control-ui-toggle__thumb" }) }) }) }));
12
+ }
13
+ //# sourceMappingURL=ToggleSwitchControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToggleSwitchControl.js","sourceRoot":"","sources":["../../src/components/ToggleSwitchControl.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAY9C,MAAM,UAAU,mBAAmB,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,KAAK,GAAG,OAAO,CAAC,IAAI,EACpB,SAAS,EACT,UAAU,EACV,gBAAgB,GACO;IACvB,MAAM,OAAO,GAAG,QAAQ,GAAG,CAAC,CAAC;IAE7B,SAAS,WAAW;QAChB,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC;IACL,CAAC;IAED,OAAO,CACH,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,QAAQ,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,YAC7H,iBACI,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,EAAE,CACT,yBAAyB,EACzB,wBAAwB,EACxB,OAAO,IAAI,YAAY,EACvB,UAAU,EAAE,OAAO,CACtB,EACD,IAAI,EAAC,QAAQ,gBACD,OAAO,CAAC,IAAI,kBACV,OAAO,EACrB,QAAQ,EAAE,QAAQ,0BACI,OAAO,CAAC,EAAE,EAChC,OAAO,EAAE,WAAW,YAEpB,eAAM,SAAS,EAAC,+BAA+B,YAC3C,eAAM,SAAS,EAAC,+BAA+B,GAAG,GAC/C,GACF,GACE,CAClB,CAAC;AACN,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ControlState, ControlValue, Panel } from '@vessel-dsp/core';
2
+ import type { ControlUiControlRef } from './types';
3
+ export declare function findPanelControl(panel: Panel, controlId: string): ControlUiControlRef | undefined;
4
+ export declare function controlValueForId(state: ControlState, controlId: string): ControlValue | undefined;
5
+ export declare function clampControlPosition(position: number): number;
6
+ export declare function snapControlPosition(control: ControlUiControlRef, position: number): number;
7
+ export declare function normalizeSwitchPosition(position: number, positions: number): number;
8
+ export declare function valuePosition(value: ControlValue | number | boolean): number;
9
+ export declare function valueForControl(control: ControlUiControlRef, value: ControlValue | number | boolean): ControlValue;
10
+ export declare function formatControlValue(control: ControlUiControlRef, value: ControlValue | undefined): string;
11
+ //# sourceMappingURL=controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.d.ts","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,YAAY,EACZ,YAAY,EAIZ,KAAK,EAGR,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAGnD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAsBjG;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAElG;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM1F;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAGnF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAe5E;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,CAkBlH;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CA2BxG"}
@@ -0,0 +1,115 @@
1
+ import { nearestKnobStep, snapKnobPosition } from '@vessel-dsp/core';
2
+ import { clampNumber, formatNumber } from './utils.js';
3
+ export function findPanelControl(panel, controlId) {
4
+ const knob = panel.knobs.find((control) => control.id === controlId);
5
+ if (knob !== undefined) {
6
+ return { kind: 'knob', control: knob };
7
+ }
8
+ const slider = (panel.sliders ?? []).find((control) => control.id === controlId);
9
+ if (slider !== undefined) {
10
+ return { kind: 'slider', control: slider };
11
+ }
12
+ const switchControl = panel.switches.find((control) => control.id === controlId);
13
+ if (switchControl !== undefined) {
14
+ return { kind: 'switch', control: switchControl };
15
+ }
16
+ const led = panel.leds.find((control) => control.id === controlId);
17
+ if (led !== undefined) {
18
+ return { kind: 'led', control: led };
19
+ }
20
+ return undefined;
21
+ }
22
+ export function controlValueForId(state, controlId) {
23
+ return state[controlId];
24
+ }
25
+ export function clampControlPosition(position) {
26
+ return clampNumber(position, 0, 1);
27
+ }
28
+ export function snapControlPosition(control, position) {
29
+ const clamped = clampControlPosition(position);
30
+ if (control.kind !== 'knob') {
31
+ return clamped;
32
+ }
33
+ return snapKnobPosition(control.control, clamped);
34
+ }
35
+ export function normalizeSwitchPosition(position, positions) {
36
+ const maxPosition = Math.max(0, positions - 1);
37
+ return Math.round(clampNumber(position, 0, maxPosition));
38
+ }
39
+ export function valuePosition(value) {
40
+ if (typeof value === 'number') {
41
+ return value;
42
+ }
43
+ if (typeof value === 'boolean') {
44
+ return value ? 1 : 0;
45
+ }
46
+ switch (value.kind) {
47
+ case 'knob':
48
+ case 'slider':
49
+ case 'switch':
50
+ return value.position;
51
+ case 'led':
52
+ return value.on ? 1 : 0;
53
+ }
54
+ }
55
+ export function valueForControl(control, value) {
56
+ switch (control.kind) {
57
+ case 'knob':
58
+ return { kind: 'knob', position: snapControlPosition(control, valuePosition(value)) };
59
+ case 'slider':
60
+ return { kind: 'slider', position: clampControlPosition(valuePosition(value)) };
61
+ case 'switch':
62
+ return {
63
+ kind: 'switch',
64
+ position: normalizeSwitchPosition(valuePosition(value), control.control.positions),
65
+ };
66
+ case 'led': {
67
+ if (typeof value === 'object' && value.kind === 'led') {
68
+ return value;
69
+ }
70
+ throw new Error(`LED control "${control.control.id}" is read-only in control-ui`);
71
+ }
72
+ }
73
+ }
74
+ export function formatControlValue(control, value) {
75
+ if (value === undefined) {
76
+ return '';
77
+ }
78
+ switch (control.kind) {
79
+ case 'knob':
80
+ if (value.kind !== 'knob') {
81
+ return '';
82
+ }
83
+ return formatKnobValue(control.control, value.position);
84
+ case 'slider':
85
+ if (value.kind !== 'slider') {
86
+ return '';
87
+ }
88
+ return formatSliderValue(control.control, value.position);
89
+ case 'switch':
90
+ if (value.kind !== 'switch') {
91
+ return '';
92
+ }
93
+ return `Position ${value.position + 1}`;
94
+ case 'led':
95
+ if (value.kind !== 'led') {
96
+ return '';
97
+ }
98
+ return value.on ? 'On' : 'Off';
99
+ }
100
+ }
101
+ function formatKnobValue(knob, position) {
102
+ const step = nearestKnobStep(knob.steps, position);
103
+ if (step?.label !== undefined) {
104
+ return step.label;
105
+ }
106
+ return `${Math.round(clampControlPosition(position) * 100)}%`;
107
+ }
108
+ function formatSliderValue(slider, position) {
109
+ if (slider.range === undefined) {
110
+ return `${Math.round(clampControlPosition(position) * 100)}%`;
111
+ }
112
+ const value = slider.range.min + clampControlPosition(position) * (slider.range.max - slider.range.min);
113
+ return `${formatNumber(value)}${slider.range.unit === undefined ? '' : ` ${slider.range.unit}`}`;
114
+ }
115
+ //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.js","sourceRoot":"","sources":["../src/controls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type { ControlAppearance, ControlAppearanceMap, ControlFrameClassNames, ControlSurfaceClassNames, ControlUiControlRef, ControlUiTheme, } from './types';
2
+ export { resolveControlAppearance } from './appearance';
3
+ export { clampControlPosition, controlValueForId, findPanelControl, formatControlValue, normalizeSwitchPosition, snapControlPosition, valueForControl, valuePosition, } from './controls';
4
+ export { applyControlUiMessage, controlMessageForValue, createControlUiState, } from './state';
5
+ export type { ControlSurfaceRenderItem, ControlSurfaceRenderPlanOptions } from './render-plan';
6
+ export { createControlSurfaceRenderPlan } from './render-plan';
7
+ export type { ControlUiThemeProviderProps } from './theme';
8
+ export { ControlUiThemeProvider, themeToCssVariables, useControlUiTheme } from './theme';
9
+ export type { ControlFrameProps } from './components/ControlFrame';
10
+ export { ControlFrame } from './components/ControlFrame';
11
+ export type { KnobControlProps } from './components/KnobControl';
12
+ export { KnobControl } from './components/KnobControl';
13
+ export type { FootswitchButtonProps } from './components/FootswitchButton';
14
+ export { FootswitchButton } from './components/FootswitchButton';
15
+ export type { ToggleSwitchControlProps } from './components/ToggleSwitchControl';
16
+ export { ToggleSwitchControl } from './components/ToggleSwitchControl';
17
+ export type { GraphicEqSliderProps } from './components/GraphicEqSlider';
18
+ export { GraphicEqSlider } from './components/GraphicEqSlider';
19
+ export type { DetentedRotarySelectProps } from './components/DetentedRotarySelect';
20
+ export { DetentedRotarySelect } from './components/DetentedRotarySelect';
21
+ export type { LedIndicatorProps } from './components/LedIndicator';
22
+ export { LedIndicator } from './components/LedIndicator';
23
+ export type { SwitchSelectControlProps } from './components/SwitchSelectControl';
24
+ export { SwitchSelectControl } from './components/SwitchSelectControl';
25
+ export type { ControlSurfaceProps } from './ControlSurface';
26
+ export { ControlSurface } from './ControlSurface';
27
+ export type { UseControlStateOptions, UseControlStateResult } from './useControlState';
28
+ export { useControlState } from './useControlState';
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACR,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,cAAc,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EACH,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EACf,aAAa,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,GACvB,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAC/F,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAC/D,YAAY,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACzF,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,YAAY,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,YAAY,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ export { resolveControlAppearance } from './appearance.js';
2
+ export { clampControlPosition, controlValueForId, findPanelControl, formatControlValue, normalizeSwitchPosition, snapControlPosition, valueForControl, valuePosition, } from './controls.js';
3
+ export { applyControlUiMessage, controlMessageForValue, createControlUiState, } from './state.js';
4
+ export { createControlSurfaceRenderPlan } from './render-plan.js';
5
+ export { ControlUiThemeProvider, themeToCssVariables, useControlUiTheme } from './theme.js';
6
+ export { ControlFrame } from './components/ControlFrame.js';
7
+ export { KnobControl } from './components/KnobControl.js';
8
+ export { FootswitchButton } from './components/FootswitchButton.js';
9
+ export { ToggleSwitchControl } from './components/ToggleSwitchControl.js';
10
+ export { GraphicEqSlider } from './components/GraphicEqSlider.js';
11
+ export { DetentedRotarySelect } from './components/DetentedRotarySelect.js';
12
+ export { LedIndicator } from './components/LedIndicator.js';
13
+ export { SwitchSelectControl } from './components/SwitchSelectControl.js';
14
+ export { ControlSurface } from './ControlSurface.js';
15
+ export { useControlState } from './useControlState.js';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EACH,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EACf,aAAa,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACH,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,GACvB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEzF,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Panel, PanelElementPlacement } from '@vessel-dsp/core';
2
+ import type { ControlAppearance, ControlAppearanceMap, ControlUiControlRef } from './types';
3
+ export type ControlSurfaceRenderItem = Readonly<{
4
+ id: string;
5
+ controlId: string;
6
+ label: string;
7
+ faceId?: string;
8
+ element?: PanelElementPlacement;
9
+ control: ControlUiControlRef;
10
+ appearance: ControlAppearance;
11
+ }>;
12
+ export type ControlSurfaceRenderPlanOptions = Readonly<{
13
+ appearance?: ControlAppearanceMap | undefined;
14
+ }>;
15
+ export declare function createControlSurfaceRenderPlan(panel: Panel, options?: ControlSurfaceRenderPlanOptions): readonly ControlSurfaceRenderItem[];
16
+ //# sourceMappingURL=render-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-plan.d.ts","sourceRoot":"","sources":["../src/render-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE5F,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,UAAU,EAAE,iBAAiB,CAAC;CACjC,CAAC,CAAC;AAEH,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACnD,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;CACjD,CAAC,CAAC;AAEH,wBAAgB,8BAA8B,CAC1C,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,+BAAoC,GAC9C,SAAS,wBAAwB,EAAE,CAkCrC"}
@@ -0,0 +1,58 @@
1
+ import { findPanelControl } from './controls.js';
2
+ import { resolveControlAppearance } from './appearance.js';
3
+ export function createControlSurfaceRenderPlan(panel, options = {}) {
4
+ const items = [];
5
+ const seen = new Set();
6
+ for (const face of panel.placement?.faces ?? []) {
7
+ for (const element of face.elements) {
8
+ const controlId = element.bind.controlId;
9
+ if (controlId === undefined || seen.has(controlId)) {
10
+ continue;
11
+ }
12
+ const control = findPanelControl(panel, controlId);
13
+ if (control === undefined) {
14
+ continue;
15
+ }
16
+ const item = renderItemForControl(control, options.appearance?.[controlId], element, face.id);
17
+ if (item !== undefined) {
18
+ items.push(item);
19
+ seen.add(controlId);
20
+ }
21
+ }
22
+ }
23
+ for (const control of fallbackControls(panel)) {
24
+ if (seen.has(control.control.id)) {
25
+ continue;
26
+ }
27
+ const item = renderItemForControl(control, options.appearance?.[control.control.id]);
28
+ if (item !== undefined) {
29
+ items.push(item);
30
+ seen.add(control.control.id);
31
+ }
32
+ }
33
+ return items;
34
+ }
35
+ function renderItemForControl(control, override, element, faceId) {
36
+ const appearance = resolveControlAppearance(control, override);
37
+ if (appearance === 'hidden') {
38
+ return undefined;
39
+ }
40
+ return {
41
+ id: element?.id ?? control.control.id,
42
+ controlId: control.control.id,
43
+ label: element?.label ?? control.control.name,
44
+ ...(faceId === undefined ? {} : { faceId }),
45
+ ...(element === undefined ? {} : { element }),
46
+ control,
47
+ appearance,
48
+ };
49
+ }
50
+ function fallbackControls(panel) {
51
+ return [
52
+ ...panel.knobs.map((control) => ({ kind: 'knob', control })),
53
+ ...(panel.sliders ?? []).map((control) => ({ kind: 'slider', control })),
54
+ ...panel.switches.map((control) => ({ kind: 'switch', control })),
55
+ ...panel.leds.map((control) => ({ kind: 'led', control })),
56
+ ];
57
+ }
58
+ //# sourceMappingURL=render-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-plan.js","sourceRoot":"","sources":["../src/render-plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAiBxD,MAAM,UAAU,8BAA8B,CAC1C,KAAY,EACZ,UAA2C,EAAE;IAE7C,MAAM,KAAK,GAA+B,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC;QAC9C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YACzC,IAAI,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACjD,SAAS;YACb,CAAC;YACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YACnD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBACxB,SAAS;YACb,CAAC;YACD,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9F,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/B,SAAS;QACb,CAAC;QACD,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACrF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CACzB,OAA4B,EAC5B,QAA4B,EAC5B,OAA+B,EAC/B,MAAe;IAEf,MAAM,UAAU,GAAG,wBAAwB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC/D,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO;QACH,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QACrC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;QAC7B,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI;QAC7C,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3C,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7C,OAAO;QACP,UAAU;KACb,CAAC;AACN,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAY;IAClC,OAAO;QACH,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,OAAO,EAAE,CAAC,CAAC;QACrE,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,OAAO,EAAE,CAAC,CAAC;QACjF,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAiB,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1E,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAc,EAAE,OAAO,EAAE,CAAC,CAAC;KACtE,CAAC;AACN,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ControlState, ControlValue, Panel, PanelMessage } from '@vessel-dsp/core';
2
+ export declare function createControlUiState(panel: Panel): ControlState;
3
+ export declare function applyControlUiMessage(panel: Panel, state: ControlState, message: PanelMessage): ControlState;
4
+ export declare function controlMessageForValue(panel: Panel, controlId: string, value: ControlValue | number | boolean, requestId?: string): PanelMessage;
5
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIxF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,GAAG,YAAY,CAE/D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY,CAM5G;AAED,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,EACtC,SAAS,CAAC,EAAE,MAAM,GACnB,YAAY,CAoBd"}