@neo-ui-kit/react 1.3.11 → 1.3.12
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/README.md +6 -1
- package/dist/index.js +79 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,11 @@ Migration: replace `@ad-voice/ui` with `@neo-ui-kit/react` in dependencies and i
|
|
|
4
4
|
|
|
5
5
|
NEO UI — React + TypeScript UI kit: glass/ruby surfaces, animated neon borders, fields, tabs, dialogs, audio controls and a melody editor.
|
|
6
6
|
|
|
7
|
+
## 1.3.12
|
|
8
|
+
|
|
9
|
+
- MelodyRoll avoids repeated full style measurements for unrelated animated CSS variables and native root shadows while its beat is idle. Theme aliases still trigger reconfiguration.
|
|
10
|
+
- Live-pitch measurements reached 59.7/59.0 main-thread FPS at CPU ×8/×16 in the library fixture. A karaoke-style animated native shadow still limits ×16 page updates; stable 60 FPS is not established for that scenario. See the [performance report](https://github.com/Pro100Dimka/adui/blob/main/evidence/performance-report.md).
|
|
11
|
+
|
|
7
12
|
## 1.3.11
|
|
8
13
|
|
|
9
14
|
LevelMeter resumes its waveform when a signal arrives after silence, including when the first animation frame precedes the next sample.
|
|
@@ -42,7 +47,7 @@ import "@neo-ui-kit/react/styles.css";
|
|
|
42
47
|
To test repository changes before publishing, run `npm run package` from the repository root and install the resulting archive in a separate application:
|
|
43
48
|
|
|
44
49
|
```bash
|
|
45
|
-
npm install /path/to/adui/release/neo-ui-kit-react-1.3.
|
|
50
|
+
npm install /path/to/adui/release/neo-ui-kit-react-1.3.12.tgz
|
|
46
51
|
```
|
|
47
52
|
|
|
48
53
|
Maintainers publish new versions from `Pro100Dimka/adui` using the `release.yml` GitHub Actions workflow, a matching `v<version>` tag, and the `npm-publication` environment. npm trusts its OIDC identity; no `NPM_TOKEN` is required. The workflow checks the project and packed consumer before publishing the tested archive. Published `1.0.0` cannot be overwritten: code and README changes in npm require a new package version. See the [repository release instructions](https://github.com/Pro100Dimka/adui#npm-пакет).
|
package/dist/index.js
CHANGED
|
@@ -6757,18 +6757,88 @@ function createMelodyGlow(root, initialState, onReady) {
|
|
|
6757
6757
|
for (const layer of [canvas, voiceCanvas, trailCanvas, noteCanvas, keyCanvas]) layer.setAttribute("aria-hidden", "true");
|
|
6758
6758
|
let state = initialState, disposed = false, transferred = false, inView = true, revision = 0, signature = "";
|
|
6759
6759
|
const visible = () => inView && !document.hidden && !root.closest("[data-ad-paused], [data-ad-offscreen]");
|
|
6760
|
-
|
|
6760
|
+
let lastVisible;
|
|
6761
|
+
const visibility = () => {
|
|
6762
|
+
const next = visible();
|
|
6763
|
+
if (next === lastVisible) return;
|
|
6764
|
+
lastVisible = next;
|
|
6765
|
+
worker.postMessage({ type: "visible", id, visible: next });
|
|
6766
|
+
};
|
|
6761
6767
|
const resize = new ResizeObserver(configure);
|
|
6762
6768
|
const intersection = new IntersectionObserver(([entry]) => {
|
|
6763
6769
|
inView = entry.isIntersecting;
|
|
6764
6770
|
visibility();
|
|
6765
6771
|
});
|
|
6772
|
+
let variableUses, variableSheets = [], nativeShadowChanged = false;
|
|
6773
|
+
const readVariableUses = () => {
|
|
6774
|
+
const uses = /* @__PURE__ */ new Map();
|
|
6775
|
+
const declarations = (style, selector) => {
|
|
6776
|
+
for (const property of style) for (const [, variable] of style.getPropertyValue(property).matchAll(/var\(\s*(--[\w-]+)/g)) {
|
|
6777
|
+
if (!uses.has(variable)) uses.set(variable, []);
|
|
6778
|
+
uses.get(variable).push({ property, selector });
|
|
6779
|
+
}
|
|
6780
|
+
};
|
|
6781
|
+
const visit = (rules) => {
|
|
6782
|
+
for (const rule of rules) {
|
|
6783
|
+
if (rule.selectorText?.includes("[style") || rule.conditionText?.includes("style(")) throw new Error("Style-dependent selectors require full measurement");
|
|
6784
|
+
if (rule.style) declarations(rule.style, rule.selectorText);
|
|
6785
|
+
if (rule.styleSheet) visit(rule.styleSheet.cssRules);
|
|
6786
|
+
else if (rule.cssRules) visit(rule.cssRules);
|
|
6787
|
+
}
|
|
6788
|
+
};
|
|
6789
|
+
variableSheets = [...document.styleSheets, ...document.adoptedStyleSheets ?? []];
|
|
6790
|
+
for (const sheet of variableSheets) visit(sheet.cssRules);
|
|
6791
|
+
for (let node = root; node; node = node.parentElement) declarations(node.style, node === root ? null : void 0);
|
|
6792
|
+
return uses;
|
|
6793
|
+
};
|
|
6794
|
+
const affectsRendering = (records) => {
|
|
6795
|
+
const changed = /* @__PURE__ */ new Set();
|
|
6796
|
+
for (const record of records) {
|
|
6797
|
+
if (["data-ad-paused", "data-ad-offscreen"].includes(record.attributeName)) continue;
|
|
6798
|
+
if (record.attributeName !== "style") return true;
|
|
6799
|
+
const old = document.createElement("div").style;
|
|
6800
|
+
old.cssText = record.oldValue ?? "";
|
|
6801
|
+
const current = record.target.style;
|
|
6802
|
+
for (const property of /* @__PURE__ */ new Set([...old, ...current])) {
|
|
6803
|
+
if (old.getPropertyValue(property) === current.getPropertyValue(property) && old.getPropertyPriority(property) === current.getPropertyPriority(property)) continue;
|
|
6804
|
+
if (["opacity", "transform", "translate", "rotate", "scale", "z-index"].includes(property)) continue;
|
|
6805
|
+
if (!property.startsWith("--")) return true;
|
|
6806
|
+
changed.add(property);
|
|
6807
|
+
if (current.getPropertyValue(property).includes("var(")) variableUses = void 0;
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
if (!changed.size) return false;
|
|
6811
|
+
try {
|
|
6812
|
+
const sheets = [...document.styleSheets, ...document.adoptedStyleSheets ?? []];
|
|
6813
|
+
if (sheets.length !== variableSheets.length || sheets.some((sheet, i) => sheet !== variableSheets[i])) variableUses = void 0;
|
|
6814
|
+
variableUses ??= readVariableUses();
|
|
6815
|
+
for (const variable of changed) for (const use of variableUses.get(variable) ?? []) {
|
|
6816
|
+
if (use.property.startsWith("--")) {
|
|
6817
|
+
changed.add(use.property);
|
|
6818
|
+
continue;
|
|
6819
|
+
}
|
|
6820
|
+
if (use.property === "box-shadow" && state.beat === 0 && (use.selector === null || use.selector && !use.selector.includes(",") && root.matches(use.selector) && !root.querySelector(use.selector))) {
|
|
6821
|
+
nativeShadowChanged = true;
|
|
6822
|
+
continue;
|
|
6823
|
+
}
|
|
6824
|
+
return true;
|
|
6825
|
+
}
|
|
6826
|
+
return false;
|
|
6827
|
+
} catch {
|
|
6828
|
+
return true;
|
|
6829
|
+
}
|
|
6830
|
+
};
|
|
6766
6831
|
const tokens = new MutationObserver((records) => {
|
|
6767
6832
|
visibility();
|
|
6768
|
-
if (records
|
|
6833
|
+
if (affectsRendering(records)) configure();
|
|
6769
6834
|
});
|
|
6835
|
+
const stylesheets = new MutationObserver((records) => {
|
|
6836
|
+
variableUses = void 0;
|
|
6837
|
+
if (records.some((record) => record.target.nodeName === "STYLE" || record.target.parentElement?.nodeName === "STYLE" || [...record.addedNodes, ...record.removedNodes].some((node) => node.nodeType === 1 && node.matches('style,link[rel="stylesheet"]')))) configure();
|
|
6838
|
+
});
|
|
6839
|
+
if (document.head) stylesheets.observe(document.head, { childList: true, subtree: true, characterData: true });
|
|
6770
6840
|
for (let node = root; node; node = node.parentElement)
|
|
6771
|
-
tokens.observe(node, { attributes: true, attributeFilter: ["style", "class", "data-ad-theme", "data-ad-color-scheme", "data-ad-motion", "data-ad-paused", "data-ad-offscreen"] });
|
|
6841
|
+
tokens.observe(node, { attributes: true, attributeOldValue: true, attributeFilter: ["style", "class", "data-ad-theme", "data-ad-color-scheme", "data-ad-motion", "data-ad-paused", "data-ad-offscreen"] });
|
|
6772
6842
|
resize.observe(root);
|
|
6773
6843
|
resize.observe(lane);
|
|
6774
6844
|
intersection.observe(root);
|
|
@@ -6866,6 +6936,7 @@ function createMelodyGlow(root, initialState, onReady) {
|
|
|
6866
6936
|
};
|
|
6867
6937
|
function configure() {
|
|
6868
6938
|
if (disposed || !root.clientWidth || !root.clientHeight) return;
|
|
6939
|
+
variableUses = void 0;
|
|
6869
6940
|
const temporary = [];
|
|
6870
6941
|
try {
|
|
6871
6942
|
const probe = document.createElement("div");
|
|
@@ -7074,6 +7145,7 @@ function createMelodyGlow(root, initialState, onReady) {
|
|
|
7074
7145
|
resize.disconnect();
|
|
7075
7146
|
intersection.disconnect();
|
|
7076
7147
|
tokens.disconnect();
|
|
7148
|
+
stylesheets.disconnect();
|
|
7077
7149
|
keyObserver.disconnect();
|
|
7078
7150
|
keyboard.removeEventListener("pointerover", keysChanged);
|
|
7079
7151
|
keyboard.removeEventListener("pointerout", keysChanged);
|
|
@@ -7104,6 +7176,10 @@ function createMelodyGlow(root, initialState, onReady) {
|
|
|
7104
7176
|
if (next.notes === state.notes) delete sent.notes;
|
|
7105
7177
|
if (next.hits === state.hits) delete sent.hits;
|
|
7106
7178
|
state = next;
|
|
7179
|
+
if (nativeShadowChanged && next.beat > 0) {
|
|
7180
|
+
nativeShadowChanged = false;
|
|
7181
|
+
configure();
|
|
7182
|
+
}
|
|
7107
7183
|
worker.postMessage({ type: "state", id, state: sent, time: performance.timeOrigin + performance.now() });
|
|
7108
7184
|
}
|
|
7109
7185
|
},
|