@xsynaptic/sonic-ui 0.26.0 → 0.27.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 +7 -0
- package/dist/default/elements/{display-element.js → analyser-element.js} +10 -12
- package/dist/default/elements/button.js +12 -9
- package/dist/default/elements/dial.js +9 -13
- package/dist/default/elements/envelope.js +26 -23
- package/dist/default/elements/field-gesture.js +49 -8
- package/dist/default/elements/meter.js +6 -8
- package/dist/default/elements/number.js +5 -14
- package/dist/default/elements/position-group.js +4 -4
- package/dist/default/elements/radio-group.js +6 -9
- package/dist/default/elements/segmented.js +7 -4
- package/dist/default/elements/slider.js +12 -13
- package/dist/default/elements/sonic-element.js +7 -5
- package/dist/default/elements/spectrum.js +3 -3
- package/dist/default/elements/switch.js +11 -6
- package/dist/default/elements/toggle.js +14 -8
- package/dist/default/elements/value-element.js +11 -3
- package/dist/default/elements/wave-element.js +11 -12
- package/dist/default/elements/waveform.js +1 -4
- package/dist/default/elements/wavestrip.js +1 -1
- package/dist/default/elements/xy.js +34 -47
- package/dist/default/lib/canvas-surface.js +13 -1
- package/dist/default/lib/render.js +2 -2
- package/dist/dev/elements/{display-element.d.ts → analyser-element.d.ts} +3 -3
- package/dist/dev/elements/{display-element.js → analyser-element.js} +11 -14
- package/dist/dev/elements/analyser-element.js.map +1 -0
- package/dist/dev/elements/button.d.ts +4 -1
- package/dist/dev/elements/button.js +12 -14
- package/dist/dev/elements/button.js.map +1 -1
- package/dist/dev/elements/dial.d.ts +4 -2
- package/dist/dev/elements/dial.js +9 -17
- package/dist/dev/elements/dial.js.map +1 -1
- package/dist/dev/elements/envelope.d.ts +5 -1
- package/dist/dev/elements/envelope.js +26 -27
- package/dist/dev/elements/envelope.js.map +1 -1
- package/dist/dev/elements/field-gesture.js +49 -8
- package/dist/dev/elements/field-gesture.js.map +1 -1
- package/dist/dev/elements/meter.d.ts +2 -1
- package/dist/dev/elements/meter.js +6 -9
- package/dist/dev/elements/meter.js.map +1 -1
- package/dist/dev/elements/number.d.ts +2 -2
- package/dist/dev/elements/number.js +5 -15
- package/dist/dev/elements/number.js.map +1 -1
- package/dist/dev/elements/position-group.js +4 -4
- package/dist/dev/elements/position-group.js.map +1 -1
- package/dist/dev/elements/radio-group.d.ts +1 -2
- package/dist/dev/elements/radio-group.js +6 -9
- package/dist/dev/elements/radio-group.js.map +1 -1
- package/dist/dev/elements/segmented.d.ts +4 -2
- package/dist/dev/elements/segmented.js +7 -9
- package/dist/dev/elements/segmented.js.map +1 -1
- package/dist/dev/elements/slider.d.ts +4 -2
- package/dist/dev/elements/slider.js +12 -17
- package/dist/dev/elements/slider.js.map +1 -1
- package/dist/dev/elements/sonic-element.d.ts +5 -7
- package/dist/dev/elements/sonic-element.js +13 -83
- package/dist/dev/elements/sonic-element.js.map +1 -1
- package/dist/dev/elements/spectrum.d.ts +2 -2
- package/dist/dev/elements/spectrum.js +3 -3
- package/dist/dev/elements/spectrum.js.map +1 -1
- package/dist/dev/elements/switch.d.ts +4 -1
- package/dist/dev/elements/switch.js +11 -10
- package/dist/dev/elements/switch.js.map +1 -1
- package/dist/dev/elements/toggle.d.ts +4 -1
- package/dist/dev/elements/toggle.js +14 -13
- package/dist/dev/elements/toggle.js.map +1 -1
- package/dist/dev/elements/value-element.d.ts +4 -3
- package/dist/dev/elements/value-element.js +11 -3
- package/dist/dev/elements/value-element.js.map +1 -1
- package/dist/dev/elements/wave-element.d.ts +2 -2
- package/dist/dev/elements/wave-element.js +11 -16
- package/dist/dev/elements/wave-element.js.map +1 -1
- package/dist/dev/elements/waveform.d.ts +0 -1
- package/dist/dev/elements/waveform.js +1 -4
- package/dist/dev/elements/waveform.js.map +1 -1
- package/dist/dev/elements/wavestrip.js +1 -1
- package/dist/dev/elements/wavestrip.js.map +1 -1
- package/dist/dev/elements/xy.d.ts +4 -1
- package/dist/dev/elements/xy.js +34 -51
- package/dist/dev/elements/xy.js.map +1 -1
- package/dist/dev/index.d.ts +3 -1
- package/dist/dev/lib/canvas-surface.js +13 -1
- package/dist/dev/lib/canvas-surface.js.map +1 -1
- package/dist/dev/lib/check-styles.d.ts +8 -0
- package/dist/dev/lib/check-styles.js +87 -0
- package/dist/dev/lib/check-styles.js.map +1 -0
- package/dist/dev/lib/render.js +2 -2
- package/dist/dev/lib/render.js.map +1 -1
- package/package.json +1 -1
- package/dist/dev/elements/display-element.js.map +0 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//#region src/lib/check-styles.ts
|
|
2
|
+
const checkedSheets = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function isLost(drawn, { token }) {
|
|
4
|
+
return getComputedStyle(drawn).getPropertyValue(token) === "";
|
|
5
|
+
}
|
|
6
|
+
const hostBoxProperties = [
|
|
7
|
+
"margin-top",
|
|
8
|
+
"margin-right",
|
|
9
|
+
"margin-bottom",
|
|
10
|
+
"margin-left",
|
|
11
|
+
"padding-top",
|
|
12
|
+
"padding-right",
|
|
13
|
+
"padding-bottom",
|
|
14
|
+
"padding-left",
|
|
15
|
+
"width",
|
|
16
|
+
"height"
|
|
17
|
+
];
|
|
18
|
+
function readHostBox(host) {
|
|
19
|
+
const style = getComputedStyle(host);
|
|
20
|
+
if (style.display === "none") return void 0;
|
|
21
|
+
if (style.display !== "contents") return "display";
|
|
22
|
+
return hostBoxProperties.find((property) => ![
|
|
23
|
+
"",
|
|
24
|
+
"0px",
|
|
25
|
+
"auto"
|
|
26
|
+
].includes(style.getPropertyValue(property)));
|
|
27
|
+
}
|
|
28
|
+
function isZeroed(control, { property, ratio, selector }) {
|
|
29
|
+
const part = selector === void 0 ? control : control.querySelector(selector);
|
|
30
|
+
if (!part || getComputedStyle(part).getPropertyValue(property) !== "0px") return false;
|
|
31
|
+
return ratio === void 0 || Number(getComputedStyle(control).getPropertyValue(ratio)) !== 0;
|
|
32
|
+
}
|
|
33
|
+
function checkHost(host, checked) {
|
|
34
|
+
const hostBox = readHostBox(host);
|
|
35
|
+
if (hostBox === void 0) return;
|
|
36
|
+
checked.add("host");
|
|
37
|
+
console.warn(hostBox === "display" ? `<${host.localName}> is given a display, but it has to stay display: contents; lay it out through a parent or a wrapper` : `<${host.localName}> is display: contents and has no box, so its ${hostBox} does nothing; set it on a parent or a wrapper`);
|
|
38
|
+
}
|
|
39
|
+
function checkReset(host, { box, control }, checked) {
|
|
40
|
+
if (!control.isConnected) return;
|
|
41
|
+
if (!checked.has("host")) checkHost(host, checked);
|
|
42
|
+
if (!box || checked.has("reset") || !isZeroed(control, box)) return;
|
|
43
|
+
checked.add("reset");
|
|
44
|
+
console.warn(`<${host.localName}> has lost its ${box.property} to a rule outside a layer, which beats every sonic rule; import that stylesheet into a layer declared before sonic`);
|
|
45
|
+
}
|
|
46
|
+
function checkStyles(host, check) {
|
|
47
|
+
const { box, control, sheet } = check;
|
|
48
|
+
const elementClass = host.constructor;
|
|
49
|
+
const checked = checkedSheets.get(elementClass) ?? /* @__PURE__ */ new Set();
|
|
50
|
+
const part = ({ selector }) => selector === void 0 ? control : host.querySelector(selector) ?? void 0;
|
|
51
|
+
const probes = [
|
|
52
|
+
{
|
|
53
|
+
sheet: "material/core.css",
|
|
54
|
+
token: "--_sonic-unlit"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
sheet,
|
|
58
|
+
token: "--_sonic-unit"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
selector: ".sonic-led",
|
|
62
|
+
sheet: "led.css",
|
|
63
|
+
token: "--_sonic-led-lens-ratio"
|
|
64
|
+
}
|
|
65
|
+
].filter((probe) => !checked.has(probe.sheet) && part(probe) !== void 0);
|
|
66
|
+
if ((!box || checked.has("reset")) && checked.has("host") && probes.length === 0) return;
|
|
67
|
+
checkedSheets.set(elementClass, checked);
|
|
68
|
+
for (const probe of probes) checked.add(probe.sheet);
|
|
69
|
+
requestAnimationFrame(() => {
|
|
70
|
+
const missing = [];
|
|
71
|
+
for (const probe of probes) {
|
|
72
|
+
const drawn = control.isConnected ? part(probe) : void 0;
|
|
73
|
+
if (!drawn) checked.delete(probe.sheet);
|
|
74
|
+
else if (isLost(drawn, probe)) missing.push(`@xsynaptic/sonic-ui/${probe.sheet}`);
|
|
75
|
+
}
|
|
76
|
+
if (missing.length === 0) {
|
|
77
|
+
checkReset(host, check, checked);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
checked.add("host").add("reset");
|
|
81
|
+
console.warn(`<${host.localName}> draws blank without ${missing.join(" and ")} (or controls.css)`);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { checkStyles };
|
|
87
|
+
//# sourceMappingURL=check-styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-styles.js","names":[],"sources":["../../../src/lib/check-styles.ts"],"sourcesContent":["declare const __DEV__: boolean;\n\nconst checkedSheets = new WeakMap<object, Set<string>>();\n\ninterface StyleProbe {\n\tselector?: string;\n\tsheet: string;\n\ttoken: string;\n}\n\n// A padding or margin the sheets leave at zero only where `ratio` is zero\nexport interface BoxProbe {\n\tproperty: string;\n\tratio?: `--_sonic-${string}`;\n\tselector?: string;\n}\n\nfunction isLost(drawn: Element, { token }: StyleProbe): boolean {\n\treturn getComputedStyle(drawn).getPropertyValue(token) === '';\n}\n\nconst hostBoxProperties = [\n\t'margin-top',\n\t'margin-right',\n\t'margin-bottom',\n\t'margin-left',\n\t'padding-top',\n\t'padding-right',\n\t'padding-bottom',\n\t'padding-left',\n\t'width',\n\t'height',\n];\n\n// An environment with no computed styles answers '', which is no box property\nfunction readHostBox(host: Element): string | undefined {\n\tconst style = getComputedStyle(host);\n\tif (style.display === 'none') return undefined;\n\tif (style.display !== 'contents') return 'display';\n\n\treturn hostBoxProperties.find(\n\t\t(property) => !['', '0px', 'auto'].includes(style.getPropertyValue(property)),\n\t);\n}\n\nfunction isZeroed(control: Element, { property, ratio, selector }: BoxProbe): boolean {\n\tconst part = selector === undefined ? control : control.querySelector(selector);\n\tif (!part || getComputedStyle(part).getPropertyValue(property) !== '0px') return false;\n\n\treturn ratio === undefined || Number(getComputedStyle(control).getPropertyValue(ratio)) !== 0;\n}\n\nfunction checkHost(host: Element, checked: Set<string>): void {\n\tconst hostBox = readHostBox(host);\n\tif (hostBox === undefined) return;\n\n\tchecked.add('host');\n\tconsole.warn(\n\t\thostBox === 'display'\n\t\t\t? `<${host.localName}> is given a display, but it has to stay display: contents; lay it out through a parent or a wrapper`\n\t\t\t: `<${host.localName}> is display: contents and has no box, so its ${hostBox} does nothing; set it on a parent or a wrapper`,\n\t);\n}\n\nexport interface StyleCheck {\n\tbox?: BoxProbe | undefined;\n\tcontrol: HTMLElement;\n\tsheet: string;\n}\n\n// Once a class; a sheet that is missing has already said why the control looks wrong\nfunction checkReset(host: Element, { box, control }: StyleCheck, checked: Set<string>): void {\n\tif (!control.isConnected) return;\n\n\tif (!checked.has('host')) checkHost(host, checked);\n\tif (!box || checked.has('reset') || !isZeroed(control, box)) return;\n\n\tchecked.add('reset');\n\tconsole.warn(\n\t\t`<${host.localName}> has lost its ${box.property} to a rule outside a layer, which beats every sonic rule; import that stylesheet into a layer declared before sonic`,\n\t);\n}\n\nexport function checkStyles(host: Element, check: StyleCheck): void {\n\tif (!__DEV__) return;\n\n\tconst { box, control, sheet } = check;\n\tconst elementClass = host.constructor;\n\tconst checked = checkedSheets.get(elementClass) ?? new Set<string>();\n\tconst part = ({ selector }: StyleProbe): Element | undefined =>\n\t\tselector === undefined ? control : (host.querySelector(selector) ?? undefined);\n\t// An LED inherits `--_sonic-unit` from its control, so a token of its own probes it\n\tconst probes: Array<StyleProbe> = [\n\t\t{ sheet: 'material/core.css', token: '--_sonic-unlit' },\n\t\t{ sheet, token: '--_sonic-unit' },\n\t\t{ selector: '.sonic-led', sheet: 'led.css', token: '--_sonic-led-lens-ratio' },\n\t].filter((probe) => !checked.has(probe.sheet) && part(probe) !== undefined);\n\tconst isResetChecked = !box || checked.has('reset');\n\tconst isBoxChecked = isResetChecked && checked.has('host');\n\tif (isBoxChecked && probes.length === 0) return;\n\n\tcheckedSheets.set(elementClass, checked);\n\tfor (const probe of probes) checked.add(probe.sheet);\n\trequestAnimationFrame(() => {\n\t\tconst missing: Array<string> = [];\n\n\t\tfor (const probe of probes) {\n\t\t\tconst drawn = control.isConnected ? part(probe) : undefined;\n\n\t\t\tif (!drawn) checked.delete(probe.sheet);\n\t\t\telse if (isLost(drawn, probe)) missing.push(`@xsynaptic/sonic-ui/${probe.sheet}`);\n\t\t}\n\t\tif (missing.length === 0) {\n\t\t\tcheckReset(host, check, checked);\n\t\t\treturn;\n\t\t}\n\n\t\tchecked.add('host').add('reset');\n\t\tconsole.warn(\n\t\t\t`<${host.localName}> draws blank without ${missing.join(' and ')} (or controls.css)`,\n\t\t);\n\t});\n}\n"],"mappings":";AAEA,MAAM,gCAAgB,IAAI,QAA6B;AAevD,SAAS,OAAO,OAAgB,EAAE,SAA8B;CAC/D,OAAO,iBAAiB,KAAK,CAAC,CAAC,iBAAiB,KAAK,MAAM;AAC5D;AAEA,MAAM,oBAAoB;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAGA,SAAS,YAAY,MAAmC;CACvD,MAAM,QAAQ,iBAAiB,IAAI;CACnC,IAAI,MAAM,YAAY,QAAQ,OAAO;CACrC,IAAI,MAAM,YAAY,YAAY,OAAO;CAEzC,OAAO,kBAAkB,MACvB,aAAa,CAAC;EAAC;EAAI;EAAO;CAAM,CAAC,CAAC,SAAS,MAAM,iBAAiB,QAAQ,CAAC,CAC7E;AACD;AAEA,SAAS,SAAS,SAAkB,EAAE,UAAU,OAAO,YAA+B;CACrF,MAAM,OAAO,aAAa,SAAY,UAAU,QAAQ,cAAc,QAAQ;CAC9E,IAAI,CAAC,QAAQ,iBAAiB,IAAI,CAAC,CAAC,iBAAiB,QAAQ,MAAM,OAAO,OAAO;CAEjF,OAAO,UAAU,UAAa,OAAO,iBAAiB,OAAO,CAAC,CAAC,iBAAiB,KAAK,CAAC,MAAM;AAC7F;AAEA,SAAS,UAAU,MAAe,SAA4B;CAC7D,MAAM,UAAU,YAAY,IAAI;CAChC,IAAI,YAAY,QAAW;CAE3B,QAAQ,IAAI,MAAM;CAClB,QAAQ,KACP,YAAY,YACT,IAAI,KAAK,UAAU,wGACnB,IAAI,KAAK,UAAU,gDAAgD,QAAQ,+CAC/E;AACD;AASA,SAAS,WAAW,MAAe,EAAE,KAAK,WAAuB,SAA4B;CAC5F,IAAI,CAAC,QAAQ,aAAa;CAE1B,IAAI,CAAC,QAAQ,IAAI,MAAM,GAAG,UAAU,MAAM,OAAO;CACjD,IAAI,CAAC,OAAO,QAAQ,IAAI,OAAO,KAAK,CAAC,SAAS,SAAS,GAAG,GAAG;CAE7D,QAAQ,IAAI,OAAO;CACnB,QAAQ,KACP,IAAI,KAAK,UAAU,iBAAiB,IAAI,SAAS,oHAClD;AACD;AAEA,SAAgB,YAAY,MAAe,OAAyB;CAGnE,MAAM,EAAE,KAAK,SAAS,UAAU;CAChC,MAAM,eAAe,KAAK;CAC1B,MAAM,UAAU,cAAc,IAAI,YAAY,qBAAK,IAAI,IAAY;CACnE,MAAM,QAAQ,EAAE,eACf,aAAa,SAAY,UAAW,KAAK,cAAc,QAAQ,KAAK;CAErE,MAAM,SAA4B;EACjC;GAAE,OAAO;GAAqB,OAAO;EAAiB;EACtD;GAAE;GAAO,OAAO;EAAgB;EAChC;GAAE,UAAU;GAAc,OAAO;GAAW,OAAO;EAA0B;CAC9E,CAAC,CAAC,QAAQ,UAAU,CAAC,QAAQ,IAAI,MAAM,KAAK,KAAK,KAAK,KAAK,MAAM,MAAS;CAG1E,KAFuB,CAAC,OAAO,QAAQ,IAAI,OAAO,MACX,QAAQ,IAAI,MAAM,KACrC,OAAO,WAAW,GAAG;CAEzC,cAAc,IAAI,cAAc,OAAO;CACvC,KAAK,MAAM,SAAS,QAAQ,QAAQ,IAAI,MAAM,KAAK;CACnD,4BAA4B;EAC3B,MAAM,UAAyB,CAAC;EAEhC,KAAK,MAAM,SAAS,QAAQ;GAC3B,MAAM,QAAQ,QAAQ,cAAc,KAAK,KAAK,IAAI;GAElD,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM,KAAK;QACjC,IAAI,OAAO,OAAO,KAAK,GAAG,QAAQ,KAAK,uBAAuB,MAAM,OAAO;EACjF;EACA,IAAI,QAAQ,WAAW,GAAG;GACzB,WAAW,MAAM,OAAO,OAAO;GAC/B;EACD;EAEA,QAAQ,IAAI,MAAM,CAAC,CAAC,IAAI,OAAO;EAC/B,QAAQ,KACP,IAAI,KAAK,UAAU,wBAAwB,QAAQ,KAAK,OAAO,EAAE,mBAClE;CACD,CAAC;AACF"}
|
package/dist/dev/lib/render.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/lib/render.ts
|
|
2
2
|
function requireChild(root, selector, child) {
|
|
3
3
|
const found = root.querySelector(selector);
|
|
4
|
-
if (!(found instanceof child)) throw new
|
|
4
|
+
if (!(found instanceof child)) throw new TypeError(`A template is missing its ${selector}`);
|
|
5
5
|
return found;
|
|
6
6
|
}
|
|
7
7
|
function template(html, root) {
|
|
@@ -9,7 +9,7 @@ function template(html, root) {
|
|
|
9
9
|
parsed.innerHTML = html;
|
|
10
10
|
return () => {
|
|
11
11
|
const clone = document.importNode(parsed.content, true).firstElementChild;
|
|
12
|
-
if (!(clone instanceof root)) throw new
|
|
12
|
+
if (!(clone instanceof root)) throw new TypeError(`A template's root is not a ${root.name}`);
|
|
13
13
|
return clone;
|
|
14
14
|
};
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","names":[],"sources":["../../../src/lib/render.ts"],"sourcesContent":["export function requireChild<Child extends Element>(\n\troot: Element,\n\tselector: string,\n\tchild: new () => Child,\n): Child {\n\tconst found = root.querySelector(selector);\n\tif (!(found instanceof child)) throw new
|
|
1
|
+
{"version":3,"file":"render.js","names":[],"sources":["../../../src/lib/render.ts"],"sourcesContent":["export function requireChild<Child extends Element>(\n\troot: Element,\n\tselector: string,\n\tchild: new () => Child,\n): Child {\n\tconst found = root.querySelector(selector);\n\tif (!(found instanceof child)) throw new TypeError(`A template is missing its ${selector}`);\n\n\treturn found;\n}\n\nexport function template<Root extends Element>(html: string, root: new () => Root): () => Root {\n\tconst parsed = document.createElement('template');\n\n\tparsed.innerHTML = html;\n\n\treturn () => {\n\t\tconst clone = document.importNode(parsed.content, true).firstElementChild;\n\t\tif (!(clone instanceof root)) throw new TypeError(`A template's root is not a ${root.name}`);\n\n\t\treturn clone;\n\t};\n}\n\nexport function placeChildren(parent: Element, children: Array<Node>): void {\n\tconst dropped = [...parent.childNodes].filter((child) => !children.includes(child));\n\n\tfor (const child of dropped) child.remove();\n\tfor (const [index, child] of children.entries()) {\n\t\tconst current = parent.childNodes[index];\n\n\t\t// A node taken out and put back restarts its animations\n\t\tif (current === child) continue;\n\n\t\tif (current) current.before(child);\n\t\telse parent.append(child);\n\t}\n}\n\nexport interface MirrorSlots {\n\tkept: HTMLSlotElement;\n\tshown: HTMLSlotElement;\n}\n\n// An id resolves to the first element in the tree that carries it, and paints nothing when that one has no box\nexport function attachSlots(host: HTMLElement): MirrorSlots {\n\tconst shown = document.createElement('slot');\n\tconst kept = document.createElement('slot');\n\n\tkept.style.cssText =\n\t\t'position: absolute; display: block; inline-size: 0; block-size: 0; overflow: hidden; visibility: hidden';\n\thost.attachShadow({ mode: 'open', slotAssignment: 'manual' }).append(shown, kept);\n\n\treturn { kept, shown };\n}\n"],"mappings":";AAAA,SAAgB,aACf,MACA,UACA,OACQ;CACR,MAAM,QAAQ,KAAK,cAAc,QAAQ;CACzC,IAAI,EAAE,iBAAiB,QAAQ,MAAM,IAAI,UAAU,6BAA6B,UAAU;CAE1F,OAAO;AACR;AAEA,SAAgB,SAA+B,MAAc,MAAkC;CAC9F,MAAM,SAAS,SAAS,cAAc,UAAU;CAEhD,OAAO,YAAY;CAEnB,aAAa;EACZ,MAAM,QAAQ,SAAS,WAAW,OAAO,SAAS,IAAI,CAAC,CAAC;EACxD,IAAI,EAAE,iBAAiB,OAAO,MAAM,IAAI,UAAU,8BAA8B,KAAK,MAAM;EAE3F,OAAO;CACR;AACD;AAEA,SAAgB,cAAc,QAAiB,UAA6B;CAC3E,MAAM,UAAU,CAAC,GAAG,OAAO,UAAU,CAAC,CAAC,QAAQ,UAAU,CAAC,SAAS,SAAS,KAAK,CAAC;CAElF,KAAK,MAAM,SAAS,SAAS,MAAM,OAAO;CAC1C,KAAK,MAAM,CAAC,OAAO,UAAU,SAAS,QAAQ,GAAG;EAChD,MAAM,UAAU,OAAO,WAAW;EAGlC,IAAI,YAAY,OAAO;EAEvB,IAAI,SAAS,QAAQ,OAAO,KAAK;OAC5B,OAAO,OAAO,KAAK;CACzB;AACD;AAQA,SAAgB,YAAY,MAAgC;CAC3D,MAAM,QAAQ,SAAS,cAAc,MAAM;CAC3C,MAAM,OAAO,SAAS,cAAc,MAAM;CAE1C,KAAK,MAAM,UACV;CACD,KAAK,aAAa;EAAE,MAAM;EAAQ,gBAAgB;CAAS,CAAC,CAAC,CAAC,OAAO,OAAO,IAAI;CAEhF,OAAO;EAAE;EAAM;CAAM;AACtB"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"display-element.js","names":[],"sources":["../../../src/elements/display-element.ts"],"sourcesContent":["import type { Surface, SurfaceFrame } from '#lib/canvas-surface.ts';\nimport type { Decibels } from '#lib/units.ts';\n\nimport { SonicElement } from '#elements/sonic-element.ts';\nimport { bindSurface } from '#lib/canvas-surface.ts';\n\ndeclare const __DEV__: boolean;\n\nexport abstract class SonicDisplayElement<\n\tColour extends string,\n\tNumeric extends string = never,\n> extends SonicElement {\n\tstatic override readonly observedAttributes = [\n\t\t...SonicElement.observedAttributes,\n\t\t'fill',\n\t\t'max',\n\t\t'min',\n\t];\n\n\tget analyser(): AnalyserNode | undefined {\n\t\treturn this.#analyser;\n\t}\n\n\tset analyser(node: AnalyserNode | null | undefined) {\n\t\tthis.#analyser = node ?? undefined;\n\t\tthis.#surface?.requestFrame();\n\t}\n\n\t// fallow-ignore-next-line code-duplication -- one accessor pair per reflected attribute\n\tget fill(): boolean {\n\t\treturn this.hasAttribute('fill');\n\t}\n\n\tset fill(isFilling: boolean) {\n\t\tthis.reflect('fill', isFilling);\n\t}\n\n\t// fallow-ignore-next-line code-duplication -- one accessor pair per reflected attribute\n\tget max(): Decibels {\n\t\treturn this.numberAttribute('max', 0);\n\t}\n\n\tset max(decibels: number | undefined) {\n\t\tthis.reflect('max', decibels);\n\t}\n\n\tget min(): Decibels {\n\t\treturn this.numberAttribute('min', -90);\n\t}\n\n\tset min(decibels: number | undefined) {\n\t\tthis.reflect('min', decibels);\n\t}\n\n\tprotected abstract readonly canvas: HTMLCanvasElement;\n\n\tprotected abstract readonly colours: Record<Colour, `--_sonic-${string}`>;\n\n\tprotected abstract readonly control: HTMLElement;\n\n\tprotected abstract readonly numbers: Record<Numeric, `--_sonic-${string}`>;\n\n\tprotected abstract readonly sheet: string;\n\n\tprotected abstract readonly sizeProperty: `--_sonic-${string}`;\n\n\t#analyser: AnalyserNode | undefined;\n\n\t#buffer = new Float32Array(0);\n\n\t#surface: Surface | undefined;\n\n\tattributeChangedCallback(name: string): void {\n\t\tif (name === 'fill') this.#surface?.setFill(this.fill);\n\t\tthis.#surface?.invalidate();\n\t}\n\n\toverride connectedCallback(): void {\n\t\tthis.upgradeProperties('analyser', 'fill', 'max', 'min');\n\t\tsuper.connectedCallback();\n\t}\n\n\t/** One level per bin, as `AnalyserNode.getFloatFrequencyData` fills it */\n\tpush(decibels: Float32Array): void {\n\t\tthis.receive(decibels);\n\t\tthis.#surface?.requestFrame();\n\t}\n\n\t// fallow-ignore-next-line code-duplication -- the wave controls keep their own copy of the surface binding\n\trepaint(): void {\n\t\tthis.#surface?.rebuild();\n\t}\n\n\tprotected connect(signal: AbortSignal): void {\n\t\tconst control = this.control;\n\n\t\tthis.keepControl(control, signal);\n\t\tthis.#surface = bindSurface({\n\t\t\tcanvas: this.canvas,\n\t\t\tcolours: this.colours,\n\t\t\tfill: { control, sizeProperty: this.sizeProperty },\n\t\t\tnumbers: this.numbers,\n\t\t\tpaint: (context, frame) => {\n\t\t\t\tthis.#paint(context, frame);\n\t\t\t},\n\t\t\tsignal,\n\t\t});\n\t\tif (__DEV__) this.checkStyles(control, this.sheet);\n\t\tthis.#surface.setFill(this.fill);\n\t}\n\n\tprotected abstract paint(\n\t\tcontext: CanvasRenderingContext2D,\n\t\tframe: SurfaceFrame<Colour, never, Numeric>,\n\t): void;\n\n\tprotected abstract pull(analyser: AnalyserNode, buffer: Float32Array<ArrayBuffer>): void;\n\n\tprotected abstract receive(frame: Float32Array): void;\n\n\tprotected surface(): Surface | undefined {\n\t\treturn this.#surface;\n\t}\n\n\t// The node never signals that sound came back, so every paint pulls\n\t#paint(context: CanvasRenderingContext2D, frame: SurfaceFrame<Colour, never, Numeric>): void {\n\t\tconst analyser = this.isDisabled() ? undefined : this.#analyser;\n\n\t\tif (analyser) {\n\t\t\tif (this.#buffer.length !== analyser.frequencyBinCount) {\n\t\t\t\tthis.#buffer = new Float32Array(analyser.frequencyBinCount);\n\t\t\t}\n\t\t\tthis.pull(analyser, this.#buffer);\n\t\t\tthis.receive(this.#buffer);\n\t\t}\n\t\tthis.paint(context, frame);\n\t\tif (analyser) this.#surface?.requestFrame();\n\t}\n}\n"],"mappings":";;;;AAQA,IAAsB,sBAAtB,cAGU,aAAa;CACtB,OAAyB,qBAAqB;EAC7C,GAAG,aAAa;EAChB;EACA;EACA;CACD;CAEA,IAAI,WAAqC;EACxC,OAAO,KAAK;CACb;CAEA,IAAI,SAAS,MAAuC;EACnD,KAAK,YAAY,QAAQ;EACzB,KAAK,UAAU,aAAa;CAC7B;CAGA,IAAI,OAAgB;EACnB,OAAO,KAAK,aAAa,MAAM;CAChC;CAEA,IAAI,KAAK,WAAoB;EAC5B,KAAK,QAAQ,QAAQ,SAAS;CAC/B;CAGA,IAAI,MAAgB;EACnB,OAAO,KAAK,gBAAgB,OAAO,CAAC;CACrC;CAEA,IAAI,IAAI,UAA8B;EACrC,KAAK,QAAQ,OAAO,QAAQ;CAC7B;CAEA,IAAI,MAAgB;EACnB,OAAO,KAAK,gBAAgB,OAAO,GAAG;CACvC;CAEA,IAAI,IAAI,UAA8B;EACrC,KAAK,QAAQ,OAAO,QAAQ;CAC7B;CAcA;CAEA,0BAAU,IAAI,aAAa,CAAC;CAE5B;CAEA,yBAAyB,MAAoB;EAC5C,IAAI,SAAS,QAAQ,KAAK,UAAU,QAAQ,KAAK,IAAI;EACrD,KAAK,UAAU,WAAW;CAC3B;CAEA,AAAS,oBAA0B;EAClC,KAAK,kBAAkB,YAAY,QAAQ,OAAO,KAAK;EACvD,MAAM,kBAAkB;CACzB;;CAGA,KAAK,UAA8B;EAClC,KAAK,QAAQ,QAAQ;EACrB,KAAK,UAAU,aAAa;CAC7B;CAGA,UAAgB;EACf,KAAK,UAAU,QAAQ;CACxB;CAEA,AAAU,QAAQ,QAA2B;EAC5C,MAAM,UAAU,KAAK;EAErB,KAAK,YAAY,SAAS,MAAM;EAChC,KAAK,WAAW,YAAY;GAC3B,QAAQ,KAAK;GACb,SAAS,KAAK;GACd,MAAM;IAAE;IAAS,cAAc,KAAK;GAAa;GACjD,SAAS,KAAK;GACd,QAAQ,SAAS,UAAU;IAC1B,KAAK,OAAO,SAAS,KAAK;GAC3B;GACA;EACD,CAAC;EACY,KAAK,YAAY,SAAS,KAAK,KAAK;EACjD,KAAK,SAAS,QAAQ,KAAK,IAAI;CAChC;CAWA,AAAU,UAA+B;EACxC,OAAO,KAAK;CACb;CAGA,OAAO,SAAmC,OAAmD;EAC5F,MAAM,WAAW,KAAK,WAAW,IAAI,SAAY,KAAK;EAEtD,IAAI,UAAU;GACb,IAAI,KAAK,QAAQ,WAAW,SAAS,mBACpC,KAAK,UAAU,IAAI,aAAa,SAAS,iBAAiB;GAE3D,KAAK,KAAK,UAAU,KAAK,OAAO;GAChC,KAAK,QAAQ,KAAK,OAAO;EAC1B;EACA,KAAK,MAAM,SAAS,KAAK;EACzB,IAAI,UAAU,KAAK,UAAU,aAAa;CAC3C;AACD"}
|