@xsynaptic/sonic-ui 0.17.0 → 0.18.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.
- package/CHANGELOG.md +13 -0
- package/README.md +112 -19
- package/dist/default/dat.js +1 -0
- package/dist/default/elements/button.js +2 -0
- package/dist/default/elements/dial.js +2 -0
- package/dist/default/elements/display-element.js +9 -7
- package/dist/default/elements/envelope.js +31 -72
- package/dist/default/elements/field-gesture.js +81 -0
- package/dist/default/elements/meter.js +4 -0
- package/dist/default/elements/position-group.js +42 -26
- package/dist/default/elements/radio-group.js +59 -56
- package/dist/default/elements/scale.js +3 -3
- package/dist/default/elements/slider.js +11 -13
- package/dist/default/elements/split.js +14 -13
- package/dist/default/elements/switch.js +31 -46
- package/dist/default/elements/toggle.js +20 -44
- package/dist/default/elements/value-element.js +65 -91
- package/dist/default/elements/value-gestures.js +22 -22
- package/dist/default/elements/wave-element.js +9 -12
- package/dist/default/elements/waveform.js +42 -241
- package/dist/default/elements/wavestrip.js +10 -5
- package/dist/default/elements/xy.js +67 -112
- package/dist/default/lib/canvas-surface.js +25 -0
- package/dist/default/lib/crossfade.js +1 -0
- package/dist/default/lib/envelope-curve.js +1 -0
- package/dist/default/lib/peaks-request.js +44 -0
- package/dist/default/lib/positions.js +58 -0
- package/dist/default/lib/scrub.js +12 -0
- package/dist/default/lib/value-model.js +62 -0
- package/dist/default/lib/waveform-scene.js +108 -0
- package/dist/default/lib/zoom-gesture.js +97 -1
- package/dist/dev/dat.d.ts +1 -0
- package/dist/dev/dat.js +1 -0
- package/dist/dev/dat.js.map +1 -1
- package/dist/dev/elements/button.d.ts +2 -0
- package/dist/dev/elements/button.js +2 -0
- package/dist/dev/elements/button.js.map +1 -1
- package/dist/dev/elements/dial.d.ts +2 -0
- package/dist/dev/elements/dial.js +2 -0
- package/dist/dev/elements/dial.js.map +1 -1
- package/dist/dev/elements/display-element.d.ts +5 -3
- package/dist/dev/elements/display-element.js +9 -7
- package/dist/dev/elements/display-element.js.map +1 -1
- package/dist/dev/elements/envelope.js +31 -72
- package/dist/dev/elements/envelope.js.map +1 -1
- package/dist/dev/elements/field-gesture.js +82 -0
- package/dist/dev/elements/field-gesture.js.map +1 -0
- package/dist/dev/elements/meter.d.ts +10 -5
- package/dist/dev/elements/meter.js +4 -0
- package/dist/dev/elements/meter.js.map +1 -1
- package/dist/dev/elements/position-group.d.ts +12 -6
- package/dist/dev/elements/position-group.js +42 -26
- package/dist/dev/elements/position-group.js.map +1 -1
- package/dist/dev/elements/radio-group.d.ts +11 -7
- package/dist/dev/elements/radio-group.js +59 -56
- package/dist/dev/elements/radio-group.js.map +1 -1
- package/dist/dev/elements/scale.js +3 -3
- package/dist/dev/elements/scale.js.map +1 -1
- package/dist/dev/elements/slider.d.ts +4 -2
- package/dist/dev/elements/slider.js +11 -13
- package/dist/dev/elements/slider.js.map +1 -1
- package/dist/dev/elements/split.d.ts +1 -0
- package/dist/dev/elements/split.js +14 -13
- package/dist/dev/elements/split.js.map +1 -1
- package/dist/dev/elements/switch.d.ts +2 -2
- package/dist/dev/elements/switch.js +31 -46
- package/dist/dev/elements/switch.js.map +1 -1
- package/dist/dev/elements/toggle.js +20 -44
- package/dist/dev/elements/toggle.js.map +1 -1
- package/dist/dev/elements/value-element.d.ts +5 -5
- package/dist/dev/elements/value-element.js +65 -91
- package/dist/dev/elements/value-element.js.map +1 -1
- package/dist/dev/elements/value-gestures.js +22 -22
- package/dist/dev/elements/value-gestures.js.map +1 -1
- package/dist/dev/elements/wave-element.d.ts +6 -4
- package/dist/dev/elements/wave-element.js +9 -12
- package/dist/dev/elements/wave-element.js.map +1 -1
- package/dist/dev/elements/waveform.d.ts +19 -21
- package/dist/dev/elements/waveform.js +42 -241
- package/dist/dev/elements/waveform.js.map +1 -1
- package/dist/dev/elements/wavestrip.d.ts +5 -1
- package/dist/dev/elements/wavestrip.js +10 -5
- package/dist/dev/elements/wavestrip.js.map +1 -1
- package/dist/dev/elements/xy.js +67 -112
- package/dist/dev/elements/xy.js.map +1 -1
- package/dist/dev/index.d.ts +2 -1
- package/dist/dev/lib/canvas-surface.d.ts +1 -0
- package/dist/dev/lib/canvas-surface.js +25 -0
- package/dist/dev/lib/canvas-surface.js.map +1 -1
- package/dist/dev/lib/crossfade.d.ts +1 -0
- package/dist/dev/lib/crossfade.js +1 -0
- package/dist/dev/lib/crossfade.js.map +1 -1
- package/dist/dev/lib/envelope-curve.d.ts +1 -0
- package/dist/dev/lib/envelope-curve.js +1 -0
- package/dist/dev/lib/envelope-curve.js.map +1 -1
- package/dist/dev/lib/peaks-request.d.ts +5 -0
- package/dist/dev/lib/peaks-request.js +45 -0
- package/dist/dev/lib/peaks-request.js.map +1 -0
- package/dist/dev/lib/positions.d.ts +7 -0
- package/dist/dev/lib/positions.js +59 -0
- package/dist/dev/lib/positions.js.map +1 -0
- package/dist/dev/lib/scrub.d.ts +8 -0
- package/dist/dev/lib/scrub.js +13 -0
- package/dist/dev/lib/scrub.js.map +1 -0
- package/dist/dev/lib/time-regions.d.ts +1 -0
- package/dist/dev/lib/time-regions.js.map +1 -1
- package/dist/dev/lib/units.d.ts +8 -0
- package/dist/dev/lib/value-model.js +63 -0
- package/dist/dev/lib/value-model.js.map +1 -0
- package/dist/dev/lib/waveform-buckets.d.ts +1 -0
- package/dist/dev/lib/waveform-buckets.js.map +1 -1
- package/dist/dev/lib/waveform-scene.d.ts +11 -0
- package/dist/dev/lib/waveform-scene.js +109 -0
- package/dist/dev/lib/waveform-scene.js.map +1 -0
- package/dist/dev/lib/zoom-gesture.js +97 -1
- package/dist/dev/lib/zoom-gesture.js.map +1 -1
- package/dist/styles/button.css +16 -6
- package/dist/styles/waveform.css +2 -1
- package/package.json +1 -1
- package/dist/default/lib/asked-value.js +0 -21
- package/dist/default/lib/fill-watch.js +0 -29
- package/dist/dev/lib/asked-value.js +0 -22
- package/dist/dev/lib/asked-value.js.map +0 -1
- package/dist/dev/lib/fill-watch.js +0 -30
- package/dist/dev/lib/fill-watch.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { clamp } from "./math.js";
|
|
2
|
+
import { capturePointer } from "./pointer-drag.js";
|
|
2
3
|
|
|
3
4
|
//#region src/lib/zoom-gesture.ts
|
|
4
5
|
const wheelRate = .01;
|
|
@@ -6,6 +7,11 @@ const linePx = 16;
|
|
|
6
7
|
const pixelMode = 0;
|
|
7
8
|
const wheelCapPx = 25;
|
|
8
9
|
const minSpanPx = 16;
|
|
10
|
+
const zoomKeys = /* @__PURE__ */ new Map([
|
|
11
|
+
["+", 1],
|
|
12
|
+
["-", -1],
|
|
13
|
+
["=", 1]
|
|
14
|
+
]);
|
|
9
15
|
const zoomKeyFactor = Math.exp(wheelCapPx * wheelRate);
|
|
10
16
|
function wheelFactor(deltaY, deltaMode) {
|
|
11
17
|
const pixels = deltaMode === pixelMode ? deltaY : deltaY * linePx;
|
|
@@ -14,7 +20,97 @@ function wheelFactor(deltaY, deltaMode) {
|
|
|
14
20
|
function pinchFactor(startSpanPx, spanPx) {
|
|
15
21
|
return Math.max(minSpanPx, Math.abs(spanPx)) / Math.max(minSpanPx, Math.abs(startSpanPx));
|
|
16
22
|
}
|
|
23
|
+
function bindPinch(control, options, signal) {
|
|
24
|
+
const touches = /* @__PURE__ */ new Map();
|
|
25
|
+
let pinch;
|
|
26
|
+
let isPinchSpent = false;
|
|
27
|
+
const spanPx = ([first, second]) => (touches.get(second) ?? 0) - (touches.get(first) ?? 0);
|
|
28
|
+
const touchPair = () => {
|
|
29
|
+
const [first, second, third] = touches.keys();
|
|
30
|
+
if (first === void 0 || second === void 0 || third !== void 0) return void 0;
|
|
31
|
+
return [first, second];
|
|
32
|
+
};
|
|
33
|
+
control.addEventListener("pointerdown", (event) => {
|
|
34
|
+
if (event.pointerType !== "touch" || !options.isZoomable() || options.isDisabled()) return;
|
|
35
|
+
touches.set(event.pointerId, event.clientX);
|
|
36
|
+
if (pinch || isPinchSpent) return;
|
|
37
|
+
const pointerIds = touchPair();
|
|
38
|
+
if (!pointerIds) return;
|
|
39
|
+
options.claim();
|
|
40
|
+
capturePointer(control, event.pointerId);
|
|
41
|
+
pinch = {
|
|
42
|
+
pointerIds,
|
|
43
|
+
startSpanPx: spanPx(pointerIds),
|
|
44
|
+
startZoom: options.zoom()
|
|
45
|
+
};
|
|
46
|
+
}, { signal });
|
|
47
|
+
control.addEventListener("pointermove", (event) => {
|
|
48
|
+
if (!touches.has(event.pointerId)) return;
|
|
49
|
+
touches.set(event.pointerId, event.clientX);
|
|
50
|
+
if (!pinch?.pointerIds.includes(event.pointerId)) return;
|
|
51
|
+
options.zoomTo(pinch.startZoom * pinchFactor(pinch.startSpanPx, spanPx(pinch.pointerIds)));
|
|
52
|
+
}, { signal });
|
|
53
|
+
for (const type of ["pointerup", "pointercancel"]) control.addEventListener(type, (event) => {
|
|
54
|
+
if (!touches.delete(event.pointerId)) return;
|
|
55
|
+
if (pinch?.pointerIds.includes(event.pointerId)) {
|
|
56
|
+
pinch = void 0;
|
|
57
|
+
isPinchSpent = true;
|
|
58
|
+
}
|
|
59
|
+
if (touches.size === 0) isPinchSpent = false;
|
|
60
|
+
}, { signal });
|
|
61
|
+
return {
|
|
62
|
+
isPinching: () => pinch !== void 0 || isPinchSpent,
|
|
63
|
+
isTouched: () => touches.size > 0
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function bindWheel(control, options, signal) {
|
|
67
|
+
control.addEventListener("wheel", (event) => {
|
|
68
|
+
if (!event.ctrlKey && !event.metaKey || options.isDisabled()) return;
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
options.zoomTo(options.zoom() * wheelFactor(event.deltaY, event.deltaMode));
|
|
71
|
+
}, {
|
|
72
|
+
passive: false,
|
|
73
|
+
signal
|
|
74
|
+
});
|
|
75
|
+
let startZoom = options.zoom();
|
|
76
|
+
for (const type of ["gesturestart", "gesturechange"]) control.addEventListener(type, (event) => {
|
|
77
|
+
if (options.isDisabled() || options.isTouched()) return;
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
if (type === "gesturestart") startZoom = options.zoom();
|
|
80
|
+
else if ("scale" in event && typeof event.scale === "number") options.zoomTo(startZoom * event.scale);
|
|
81
|
+
}, { signal });
|
|
82
|
+
}
|
|
83
|
+
function bindZoom(control, options, signal) {
|
|
84
|
+
const { isPinching, isTouched } = bindPinch(control, options, signal);
|
|
85
|
+
let wheel;
|
|
86
|
+
const sync = () => {
|
|
87
|
+
wheel?.abort();
|
|
88
|
+
wheel = void 0;
|
|
89
|
+
if (signal.aborted || !options.isZoomable()) return;
|
|
90
|
+
wheel = new AbortController();
|
|
91
|
+
bindWheel(control, {
|
|
92
|
+
...options,
|
|
93
|
+
isTouched
|
|
94
|
+
}, wheel.signal);
|
|
95
|
+
};
|
|
96
|
+
signal.addEventListener("abort", sync, { once: true });
|
|
97
|
+
sync();
|
|
98
|
+
return {
|
|
99
|
+
isPinching,
|
|
100
|
+
sync
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function bindZoomKeys(control, target, signal) {
|
|
104
|
+
control.addEventListener("keydown", (event) => {
|
|
105
|
+
if (!target.isZoomable() || target.isDisabled() || event.target !== control) return;
|
|
106
|
+
if (event.ctrlKey || event.metaKey || event.altKey) return;
|
|
107
|
+
const direction = zoomKeys.get(event.key);
|
|
108
|
+
if (direction === void 0) return;
|
|
109
|
+
event.preventDefault();
|
|
110
|
+
target.zoomTo(target.zoom() * zoomKeyFactor ** direction);
|
|
111
|
+
}, { signal });
|
|
112
|
+
}
|
|
17
113
|
|
|
18
114
|
//#endregion
|
|
19
|
-
export { pinchFactor, wheelFactor, zoomKeyFactor };
|
|
115
|
+
export { bindZoom, bindZoomKeys, pinchFactor, wheelFactor, zoomKeyFactor };
|
|
20
116
|
//# sourceMappingURL=zoom-gesture.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zoom-gesture.js","names":[],"sources":["../../../src/lib/zoom-gesture.ts"],"sourcesContent":["import { clamp } from '#lib/math.ts';\n\nconst wheelRate = 0.01;\nconst linePx = 16;\nconst pixelMode = 0;\n\nconst wheelCapPx = 25;\n\nconst minSpanPx = 16;\n\nexport const zoomKeyFactor = Math.exp(wheelCapPx * wheelRate);\n\nexport function wheelFactor(deltaY: number, deltaMode: number): number {\n\tconst pixels = deltaMode === pixelMode ? deltaY : deltaY * linePx;\n\n\treturn Math.exp(-clamp(pixels, -wheelCapPx, wheelCapPx) * wheelRate);\n}\n\nexport function pinchFactor(startSpanPx: number, spanPx: number): number {\n\treturn Math.max(minSpanPx, Math.abs(spanPx)) / Math.max(minSpanPx, Math.abs(startSpanPx));\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"zoom-gesture.js","names":[],"sources":["../../../src/lib/zoom-gesture.ts"],"sourcesContent":["import { clamp } from '#lib/math.ts';\nimport { capturePointer } from '#lib/pointer-drag.ts';\n\ninterface Pinch {\n\tpointerIds: [number, number];\n\tstartSpanPx: number;\n\tstartZoom: number;\n}\n\ninterface ZoomTarget {\n\tisDisabled: () => boolean;\n\tisZoomable: () => boolean;\n\tzoom: () => number;\n\tzoomTo: (target: number) => void;\n}\n\ninterface ZoomOptions extends ZoomTarget {\n\tclaim: () => void;\n}\n\ninterface Touches {\n\tisPinching: () => boolean;\n\tisTouched: () => boolean;\n}\n\nexport interface ZoomGesture {\n\tisPinching: () => boolean;\n\tsync: () => void;\n}\n\nconst wheelRate = 0.01;\nconst linePx = 16;\nconst pixelMode = 0;\n\nconst wheelCapPx = 25;\n\nconst minSpanPx = 16;\n\nconst zoomKeys = new Map([\n\t['+', 1],\n\t['-', -1],\n\t['=', 1],\n]);\n\nexport const zoomKeyFactor = Math.exp(wheelCapPx * wheelRate);\n\nexport function wheelFactor(deltaY: number, deltaMode: number): number {\n\tconst pixels = deltaMode === pixelMode ? deltaY : deltaY * linePx;\n\n\treturn Math.exp(-clamp(pixels, -wheelCapPx, wheelCapPx) * wheelRate);\n}\n\nexport function pinchFactor(startSpanPx: number, spanPx: number): number {\n\treturn Math.max(minSpanPx, Math.abs(spanPx)) / Math.max(minSpanPx, Math.abs(startSpanPx));\n}\n\nfunction bindPinch(control: HTMLElement, options: ZoomOptions, signal: AbortSignal): Touches {\n\tconst touches = new Map<number, number>();\n\tlet pinch: Pinch | undefined;\n\tlet isPinchSpent = false;\n\n\tconst spanPx = ([first, second]: [number, number]): number =>\n\t\t(touches.get(second) ?? 0) - (touches.get(first) ?? 0);\n\tconst touchPair = (): [number, number] | undefined => {\n\t\tconst [first, second, third] = touches.keys();\n\t\tif (first === undefined || second === undefined || third !== undefined) return undefined;\n\n\t\treturn [first, second];\n\t};\n\n\tcontrol.addEventListener(\n\t\t'pointerdown',\n\t\t(event) => {\n\t\t\tif (event.pointerType !== 'touch' || !options.isZoomable() || options.isDisabled()) return;\n\n\t\t\ttouches.set(event.pointerId, event.clientX);\n\t\t\tif (pinch || isPinchSpent) return;\n\n\t\t\tconst pointerIds = touchPair();\n\t\t\tif (!pointerIds) return;\n\n\t\t\toptions.claim();\n\t\t\tcapturePointer(control, event.pointerId);\n\t\t\tpinch = { pointerIds, startSpanPx: spanPx(pointerIds), startZoom: options.zoom() };\n\t\t},\n\t\t{ signal },\n\t);\n\tcontrol.addEventListener(\n\t\t'pointermove',\n\t\t(event) => {\n\t\t\tif (!touches.has(event.pointerId)) return;\n\n\t\t\ttouches.set(event.pointerId, event.clientX);\n\t\t\tif (!pinch?.pointerIds.includes(event.pointerId)) return;\n\n\t\t\toptions.zoomTo(pinch.startZoom * pinchFactor(pinch.startSpanPx, spanPx(pinch.pointerIds)));\n\t\t},\n\t\t{ signal },\n\t);\n\tfor (const type of ['pointerup', 'pointercancel'] as const) {\n\t\tcontrol.addEventListener(\n\t\t\ttype,\n\t\t\t(event) => {\n\t\t\t\tif (!touches.delete(event.pointerId)) return;\n\n\t\t\t\tif (pinch?.pointerIds.includes(event.pointerId)) {\n\t\t\t\t\tpinch = undefined;\n\t\t\t\t\tisPinchSpent = true;\n\t\t\t\t}\n\t\t\t\tif (touches.size === 0) isPinchSpent = false;\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t}\n\n\treturn {\n\t\tisPinching: () => pinch !== undefined || isPinchSpent,\n\t\tisTouched: () => touches.size > 0,\n\t};\n}\n\nfunction bindWheel(\n\tcontrol: HTMLElement,\n\toptions: Pick<Touches, 'isTouched'> & ZoomTarget,\n\tsignal: AbortSignal,\n): void {\n\t// Chromium cannot cancel a wheel heard only on the `display: contents` host\n\tcontrol.addEventListener(\n\t\t'wheel',\n\t\t(event) => {\n\t\t\tif ((!event.ctrlKey && !event.metaKey) || options.isDisabled()) return;\n\n\t\t\tevent.preventDefault();\n\t\t\toptions.zoomTo(options.zoom() * wheelFactor(event.deltaY, event.deltaMode));\n\t\t},\n\t\t{ passive: false, signal },\n\t);\n\n\tlet startZoom = options.zoom();\n\n\t// Safari sends a trackpad pinch as gesture events, never as a ctrl wheel\n\tfor (const type of ['gesturestart', 'gesturechange']) {\n\t\tcontrol.addEventListener(\n\t\t\ttype,\n\t\t\t(event) => {\n\t\t\t\tif (options.isDisabled() || options.isTouched()) return;\n\n\t\t\t\tevent.preventDefault();\n\t\t\t\tif (type === 'gesturestart') startZoom = options.zoom();\n\t\t\t\telse if ('scale' in event && typeof event.scale === 'number') {\n\t\t\t\t\toptions.zoomTo(startZoom * event.scale);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t}\n}\n\nexport function bindZoom(\n\tcontrol: HTMLElement,\n\toptions: ZoomOptions,\n\tsignal: AbortSignal,\n): ZoomGesture {\n\tconst { isPinching, isTouched } = bindPinch(control, options, signal);\n\tlet wheel: AbortController | undefined;\n\n\t// The wheel listener is not passive, so it is bound only while zooming is on\n\tconst sync = (): void => {\n\t\twheel?.abort();\n\t\twheel = undefined;\n\t\tif (signal.aborted || !options.isZoomable()) return;\n\n\t\twheel = new AbortController();\n\t\tbindWheel(control, { ...options, isTouched }, wheel.signal);\n\t};\n\n\tsignal.addEventListener('abort', sync, { once: true });\n\tsync();\n\n\treturn { isPinching, sync };\n}\n\nexport function bindZoomKeys(control: HTMLElement, target: ZoomTarget, signal: AbortSignal): void {\n\tcontrol.addEventListener(\n\t\t'keydown',\n\t\t(event) => {\n\t\t\tif (!target.isZoomable() || target.isDisabled() || event.target !== control) return;\n\t\t\tif (event.ctrlKey || event.metaKey || event.altKey) return;\n\n\t\t\tconst direction = zoomKeys.get(event.key);\n\t\t\tif (direction === undefined) return;\n\n\t\t\tevent.preventDefault();\n\t\t\ttarget.zoomTo(target.zoom() * zoomKeyFactor ** direction);\n\t\t},\n\t\t{ signal },\n\t);\n}\n"],"mappings":"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"}
|
package/dist/styles/button.css
CHANGED
|
@@ -31,13 +31,23 @@
|
|
|
31
31
|
overflow: hidden;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
sonic-button:not(:defined, [hidden]):has(> :not(
|
|
34
|
+
sonic-button:not(:defined, [hidden]):has(> :not(.sonic-led)) {
|
|
35
35
|
inline-size: max-content;
|
|
36
36
|
min-inline-size: calc(var(--_sonic-button-size) * var(--_sonic-button-aspect-ratio));
|
|
37
|
-
padding-inline: calc(var(--_sonic-button-size) * var(--sonic-button-padding-ratio, 0.25));
|
|
38
37
|
white-space: nowrap;
|
|
39
38
|
}
|
|
40
39
|
|
|
40
|
+
sonic-button:not(:defined, [hidden]):has(> :not(svg, .sonic-led)) {
|
|
41
|
+
padding-inline: calc(var(--_sonic-button-size) * var(--sonic-button-padding-ratio, 0.25));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
:where(sonic-button:not(:defined)) > svg {
|
|
45
|
+
display: block;
|
|
46
|
+
inline-size: auto;
|
|
47
|
+
block-size: calc(var(--_sonic-button-size) * var(--sonic-button-icon-ratio, 0.5));
|
|
48
|
+
aspect-ratio: auto 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
41
51
|
.sonic-button {
|
|
42
52
|
--_sonic-button-gap-ratio: var(--sonic-button-gap-ratio, 0);
|
|
43
53
|
--_sonic-button-radius-ratio: var(--sonic-button-radius-ratio, 0.2);
|
|
@@ -75,7 +85,7 @@
|
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
/* An `auto` width stretches in a column flex or grid parent */
|
|
78
|
-
.sonic-button:where(:has(> .sonic-button-cap > :not(
|
|
88
|
+
.sonic-button:where(:has(> .sonic-button-cap > :not(.sonic-led))) {
|
|
79
89
|
inline-size: max-content;
|
|
80
90
|
min-inline-size: calc(var(--_sonic-button-size) * var(--_sonic-button-aspect-ratio));
|
|
81
91
|
}
|
|
@@ -250,8 +260,9 @@
|
|
|
250
260
|
}
|
|
251
261
|
|
|
252
262
|
& > svg {
|
|
253
|
-
inline-size:
|
|
263
|
+
inline-size: auto;
|
|
254
264
|
block-size: calc(var(--_sonic-button-size) * var(--_sonic-button-icon-ratio));
|
|
265
|
+
aspect-ratio: auto 1;
|
|
255
266
|
mask-image: linear-gradient(
|
|
256
267
|
var(--_sonic-light-fall),
|
|
257
268
|
#000 15%,
|
|
@@ -261,7 +272,7 @@
|
|
|
261
272
|
}
|
|
262
273
|
}
|
|
263
274
|
|
|
264
|
-
.sonic-button-cap:has(> :not(
|
|
275
|
+
.sonic-button-cap:has(> :not(.sonic-led)) {
|
|
265
276
|
position: relative;
|
|
266
277
|
inset: auto;
|
|
267
278
|
block-size: calc(var(--_sonic-button-size) - 2 * var(--_sonic-button-gap));
|
|
@@ -269,7 +280,6 @@
|
|
|
269
280
|
}
|
|
270
281
|
|
|
271
282
|
.sonic-button-cap:has(> .sonic-led) > svg {
|
|
272
|
-
inline-size: calc(var(--_sonic-button-size) * var(--_sonic-button-led-icon-ratio));
|
|
273
283
|
block-size: calc(var(--_sonic-button-size) * var(--_sonic-button-led-icon-ratio));
|
|
274
284
|
}
|
|
275
285
|
|
package/dist/styles/waveform.css
CHANGED
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
.sonic-waveform-label[data-sonic-dimmed] {
|
|
216
|
-
|
|
216
|
+
filter: opacity(0.5);
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
/* Opaque, since a system highlight carries alpha that would blend the wave into the glass */
|
|
@@ -245,6 +245,7 @@
|
|
|
245
245
|
|
|
246
246
|
&[data-sonic-dimmed] {
|
|
247
247
|
color: GrayText;
|
|
248
|
+
filter: none;
|
|
248
249
|
}
|
|
249
250
|
}
|
|
250
251
|
|
package/package.json
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
//#region src/lib/asked-value.ts
|
|
2
|
-
function moveTo(cell, mapping, next) {
|
|
3
|
-
if (!Number.isFinite(next)) return false;
|
|
4
|
-
const snapped = mapping.snap(next);
|
|
5
|
-
cell.asked = snapped;
|
|
6
|
-
if (snapped === cell.value) return false;
|
|
7
|
-
cell.value = snapped;
|
|
8
|
-
return true;
|
|
9
|
-
}
|
|
10
|
-
function setAsked(cell, mapping, next) {
|
|
11
|
-
if (!Number.isFinite(next)) return false;
|
|
12
|
-
const hasMoved = moveTo(cell, mapping, next);
|
|
13
|
-
cell.asked = next;
|
|
14
|
-
return hasMoved;
|
|
15
|
-
}
|
|
16
|
-
function resnap(cell, mapping, fallback) {
|
|
17
|
-
cell.value = mapping.snap(cell.asked ?? fallback);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
//#endregion
|
|
21
|
-
export { moveTo, resnap, setAsked };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
//#region src/lib/fill-watch.ts
|
|
2
|
-
function bindFill(control, sizeProperty, signal) {
|
|
3
|
-
let watch;
|
|
4
|
-
const stop = () => {
|
|
5
|
-
watch?.disconnect();
|
|
6
|
-
watch = void 0;
|
|
7
|
-
};
|
|
8
|
-
signal.addEventListener("abort", stop, { once: true });
|
|
9
|
-
return (isFilling) => {
|
|
10
|
-
if (signal.aborted || isFilling === (watch !== void 0)) return;
|
|
11
|
-
stop();
|
|
12
|
-
if (!isFilling) {
|
|
13
|
-
control.style.removeProperty(sizeProperty);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const started = new ResizeObserver((entries) => {
|
|
17
|
-
const box = entries.at(-1)?.borderBoxSize[0];
|
|
18
|
-
if (!box) return;
|
|
19
|
-
requestAnimationFrame(() => {
|
|
20
|
-
if (watch === started) control.style.setProperty(sizeProperty, `${String(box.blockSize)}px`);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
watch = started;
|
|
24
|
-
started.observe(control);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
29
|
-
export { bindFill };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
//#region src/lib/asked-value.ts
|
|
2
|
-
function moveTo(cell, mapping, next) {
|
|
3
|
-
if (!Number.isFinite(next)) return false;
|
|
4
|
-
const snapped = mapping.snap(next);
|
|
5
|
-
cell.asked = snapped;
|
|
6
|
-
if (snapped === cell.value) return false;
|
|
7
|
-
cell.value = snapped;
|
|
8
|
-
return true;
|
|
9
|
-
}
|
|
10
|
-
function setAsked(cell, mapping, next) {
|
|
11
|
-
if (!Number.isFinite(next)) return false;
|
|
12
|
-
const hasMoved = moveTo(cell, mapping, next);
|
|
13
|
-
cell.asked = next;
|
|
14
|
-
return hasMoved;
|
|
15
|
-
}
|
|
16
|
-
function resnap(cell, mapping, fallback) {
|
|
17
|
-
cell.value = mapping.snap(cell.asked ?? fallback);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
//#endregion
|
|
21
|
-
export { moveTo, resnap, setAsked };
|
|
22
|
-
//# sourceMappingURL=asked-value.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"asked-value.js","names":[],"sources":["../../../src/lib/asked-value.ts"],"sourcesContent":["import type { ValueMapping } from '#lib/value-mapping.ts';\n\nexport interface AskedValue {\n\tasked: number | undefined;\n\tvalue: number;\n}\n\n// A gesture: what was asked is the snapped value\n// eslint-disable-next-line unicorn/consistent-boolean-name -- a writer; the result says whether the value moved\nexport function moveTo(cell: AskedValue, mapping: ValueMapping, next: number): boolean {\n\tif (!Number.isFinite(next)) return false;\n\n\tconst snapped = mapping.snap(next);\n\n\tcell.asked = snapped;\n\tif (snapped === cell.value) return false;\n\n\tcell.value = snapped;\n\n\treturn true;\n}\n\n// A host write: the raw ask survives a change of range\n// eslint-disable-next-line unicorn/consistent-boolean-name -- a writer; the result says whether the value moved\nexport function setAsked(cell: AskedValue, mapping: ValueMapping, next: number): boolean {\n\tif (!Number.isFinite(next)) return false;\n\n\tconst hasMoved = moveTo(cell, mapping, next);\n\n\tcell.asked = next;\n\n\treturn hasMoved;\n}\n\nexport function resnap(cell: AskedValue, mapping: ValueMapping, fallback: number): void {\n\tcell.value = mapping.snap(cell.asked ?? fallback);\n}\n"],"mappings":";AASA,SAAgB,OAAO,MAAkB,SAAuB,MAAuB;CACtF,IAAI,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;CAEnC,MAAM,UAAU,QAAQ,KAAK,IAAI;CAEjC,KAAK,QAAQ;CACb,IAAI,YAAY,KAAK,OAAO,OAAO;CAEnC,KAAK,QAAQ;CAEb,OAAO;AACR;AAIA,SAAgB,SAAS,MAAkB,SAAuB,MAAuB;CACxF,IAAI,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;CAEnC,MAAM,WAAW,OAAO,MAAM,SAAS,IAAI;CAE3C,KAAK,QAAQ;CAEb,OAAO;AACR;AAEA,SAAgB,OAAO,MAAkB,SAAuB,UAAwB;CACvF,KAAK,QAAQ,QAAQ,KAAK,KAAK,SAAS,QAAQ;AACjD"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
//#region src/lib/fill-watch.ts
|
|
2
|
-
function bindFill(control, sizeProperty, signal) {
|
|
3
|
-
let watch;
|
|
4
|
-
const stop = () => {
|
|
5
|
-
watch?.disconnect();
|
|
6
|
-
watch = void 0;
|
|
7
|
-
};
|
|
8
|
-
signal.addEventListener("abort", stop, { once: true });
|
|
9
|
-
return (isFilling) => {
|
|
10
|
-
if (signal.aborted || isFilling === (watch !== void 0)) return;
|
|
11
|
-
stop();
|
|
12
|
-
if (!isFilling) {
|
|
13
|
-
control.style.removeProperty(sizeProperty);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const started = new ResizeObserver((entries) => {
|
|
17
|
-
const box = entries.at(-1)?.borderBoxSize[0];
|
|
18
|
-
if (!box) return;
|
|
19
|
-
requestAnimationFrame(() => {
|
|
20
|
-
if (watch === started) control.style.setProperty(sizeProperty, `${String(box.blockSize)}px`);
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
watch = started;
|
|
24
|
-
started.observe(control);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
29
|
-
export { bindFill };
|
|
30
|
-
//# sourceMappingURL=fill-watch.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fill-watch.js","names":[],"sources":["../../../src/lib/fill-watch.ts"],"sourcesContent":["export function bindFill(\n\tcontrol: HTMLElement,\n\tsizeProperty: `--_sonic-${string}`,\n\tsignal: AbortSignal,\n): (isFilling: boolean) => void {\n\tlet watch: ResizeObserver | undefined;\n\n\tconst stop = (): void => {\n\t\twatch?.disconnect();\n\t\twatch = undefined;\n\t};\n\n\tsignal.addEventListener('abort', stop, { once: true });\n\n\treturn (isFilling) => {\n\t\tif (signal.aborted || isFilling === (watch !== undefined)) return;\n\n\t\tstop();\n\t\tif (!isFilling) {\n\t\t\tcontrol.style.removeProperty(sizeProperty);\n\t\t\treturn;\n\t\t}\n\n\t\tconst started = new ResizeObserver((entries) => {\n\t\t\tconst box = entries.at(-1)?.borderBoxSize[0];\n\t\t\tif (!box) return;\n\n\t\t\t// Written a frame on, or the canvas resizes inside this delivery and WebKit reports a loop\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tif (watch === started) {\n\t\t\t\t\tcontrol.style.setProperty(sizeProperty, `${String(box.blockSize)}px`);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\twatch = started;\n\t\tstarted.observe(control);\n\t};\n}\n"],"mappings":";AAAA,SAAgB,SACf,SACA,cACA,QAC+B;CAC/B,IAAI;CAEJ,MAAM,aAAmB;EACxB,OAAO,WAAW;EAClB,QAAQ;CACT;CAEA,OAAO,iBAAiB,SAAS,MAAM,EAAE,MAAM,KAAK,CAAC;CAErD,QAAQ,cAAc;EACrB,IAAI,OAAO,WAAW,eAAe,UAAU,SAAY;EAE3D,KAAK;EACL,IAAI,CAAC,WAAW;GACf,QAAQ,MAAM,eAAe,YAAY;GACzC;EACD;EAEA,MAAM,UAAU,IAAI,gBAAgB,YAAY;GAC/C,MAAM,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,cAAc;GAC1C,IAAI,CAAC,KAAK;GAGV,4BAA4B;IAC3B,IAAI,UAAU,SACb,QAAQ,MAAM,YAAY,cAAc,GAAG,OAAO,IAAI,SAAS,EAAE,GAAG;GAEtE,CAAC;EACF,CAAC;EAED,QAAQ;EACR,QAAQ,QAAQ,OAAO;CACxB;AACD"}
|