@neo-ui-kit/react 1.3.9 → 1.3.10
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 +9 -1
- package/dist/chunks/{chunk-VK6GHRLV.js → chunk-RM7YNNMZ.js} +1 -0
- package/dist/components/media/MelodyRoll/melody-glow.d.ts +5 -0
- package/dist/components/media/MelodyRoll/styles.css +60 -9
- package/dist/editor.js +1 -1
- package/dist/index.js +1085 -78
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,12 @@ 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.10
|
|
8
|
+
|
|
9
|
+
- MelodyRoll renders notes, lyrics, key effects and voice effects in a shared worker while keeping native keyboard input and focus.
|
|
10
|
+
- Bounded sprite caches and stable DOM reduce playback work; CSS/SVG fallback remains available.
|
|
11
|
+
- CPU ×8 measurements are near 60 FPS; ×16 page updates measured 49.5–59.8 FPS while worker rendering stayed near 60. Stable 60 FPS for the complete scene is not yet established. See the [performance report](https://github.com/Pro100Dimka/adui/blob/main/evidence/performance-report.md).
|
|
12
|
+
|
|
7
13
|
## 1.3.9
|
|
8
14
|
|
|
9
15
|
- Rounded field variants share the existing neon outline; outlined and underlined fields have transparent backgrounds, and filled fields have no animated border.
|
|
@@ -32,7 +38,7 @@ import "@neo-ui-kit/react/styles.css";
|
|
|
32
38
|
To test repository changes before publishing, run `npm run package` from the repository root and install the resulting archive in a separate application:
|
|
33
39
|
|
|
34
40
|
```bash
|
|
35
|
-
npm install /path/to/adui/release/neo-ui-kit-react-1.3.
|
|
41
|
+
npm install /path/to/adui/release/neo-ui-kit-react-1.3.10.tgz
|
|
36
42
|
```
|
|
37
43
|
|
|
38
44
|
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-пакет).
|
|
@@ -189,6 +195,8 @@ Keep `rows`, `columns`, `options`, and `initialValues` immutable: replace them w
|
|
|
189
195
|
|
|
190
196
|
MelodyRoll also expects an immutable `notes` array: keep its reference stable during playback and replace it after editing notes. It caches pitch bounds and time bounds for blocks of 128 notes, skipping blocks outside the visible window. Input order and overlapping notes are preserved; heavily interleaved unsorted data can still require a full scan. The moving strip uses nearby time coordinates instead of ever-growing song offsets. Beat, voice level and accuracy updates are scoped to the elements that use them, avoiding restyling the whole keyboard and note strip. These changes preserve the existing glow, transitions, lyrics, seeking and wheel zoom; CPU ×8/×16 stress results are in the performance report.
|
|
191
197
|
|
|
198
|
+
Version 1.3.10 renders notes, lyrics, key effects, beat glow, voice marker and the three-layer voice trail through a shared OffscreenCanvas worker. Two adjacent note windows bound the data sent to it; unchanged note batches are not resent on each tick. Native keyboard buttons retain pointer input, keyboard activation and focus. CSS supplies colours, shadows, timing and text geometry; readable webfont sources are loaded into the worker before handoff. Note sprites are cached (512 base sprites; filtered sprites limited to 8 × 1024² physical pixels), and structural DOM stays unchanged during playback. CSS/SVG remains active until readiness and returns on failure, unavailable APIs/CSP, or unsupported styles/font sources. Hidden/paused scenes stop drawing; the last unmount terminates the worker. Canvas and CSS antialiasing differ slightly. In repeated 30-second runs, page updates reached about 59.9–60 FPS at CPU ×8 and 49.5–59.5 FPS at ×16; the worker drawing loop stayed near 60 FPS. Stable 60 FPS for the complete scene is **not yet established**. See the [performance report](https://github.com/Pro100Dimka/adui/blob/main/evidence/performance-report.md) for measurements and limits.
|
|
199
|
+
|
|
192
200
|
For large tables, use `pageSize` or opt into `virtualize` to bound mounted rows. Virtualization bounds rendering, not the cost of client-side sorting/filtering: use the manual server contracts for datasets that are too large to process locally. Open Select/Autocomplete lists are not virtualized: filter very large datasets before supplying options. `PeoplePicker.onSearch(query, signal)` receives an optional `AbortSignal`; forward it to your data client to cancel superseded requests. Expensive custom renderers, validators, and aggregates still need their own work budget.
|
|
193
201
|
|
|
194
202
|
## Entry points
|
|
@@ -49,6 +49,7 @@ var PianoKeyboard = /* @__PURE__ */ memo(function PianoKeyboard2({
|
|
|
49
49
|
const key = (midi, top, size, black) => {
|
|
50
50
|
const props = {
|
|
51
51
|
className: "ad-piano-key",
|
|
52
|
+
"data-midi": midi,
|
|
52
53
|
"data-black": black || void 0,
|
|
53
54
|
"data-active": midi === activeMidi || void 0,
|
|
54
55
|
"data-hit": midi === activeMidi && hit || void 0,
|
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
--ad-roll-keys: clamp(2.75rem, 8%, 4.5rem);
|
|
10
10
|
position: relative;
|
|
11
11
|
display: grid;
|
|
12
|
-
grid-template-columns: var(--ad-roll-keys) minmax(0, 1fr);
|
|
13
12
|
width: 100%;
|
|
14
13
|
height: 100%;
|
|
15
14
|
min-height: 8rem;
|
|
16
|
-
overflow:
|
|
15
|
+
overflow: visible;
|
|
17
16
|
isolation: isolate;
|
|
18
17
|
/* Room for the hairline edge that the glass layer below draws. */
|
|
19
18
|
padding: 0.0625rem;
|
|
@@ -21,11 +20,66 @@
|
|
|
21
20
|
box-shadow: 0 0 calc(var(--ad-roll-beat) * 1.6rem) rgb(from var(--ad-primary) r g b / 0.25);
|
|
22
21
|
transition: box-shadow 0.12s;
|
|
23
22
|
}
|
|
23
|
+
.ad-melody-roll-content {
|
|
24
|
+
display: grid;
|
|
25
|
+
grid-template-columns: var(--ad-roll-keys) minmax(0, 1fr);
|
|
26
|
+
width: calc(100% + 0.125rem);
|
|
27
|
+
height: calc(100% + 0.125rem);
|
|
28
|
+
margin: -0.0625rem;
|
|
29
|
+
padding: 0.0625rem;
|
|
30
|
+
min-height: 0;
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
border-radius: inherit;
|
|
33
|
+
}
|
|
34
|
+
.ad-melody-glow {
|
|
35
|
+
position: absolute;
|
|
36
|
+
pointer-events: none;
|
|
37
|
+
z-index: -1;
|
|
38
|
+
}
|
|
39
|
+
.ad-melody-voice-canvas {
|
|
40
|
+
position: absolute;
|
|
41
|
+
inset: 0;
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
z-index: 3;
|
|
45
|
+
pointer-events: none;
|
|
46
|
+
}
|
|
47
|
+
.ad-melody-note-canvas, .ad-melody-key-canvas {
|
|
48
|
+
position: absolute;
|
|
49
|
+
inset: 0;
|
|
50
|
+
width: 100%;
|
|
51
|
+
height: 100%;
|
|
52
|
+
pointer-events: none;
|
|
53
|
+
}
|
|
54
|
+
.ad-melody-key-canvas { z-index: -1; }
|
|
55
|
+
.ad-melody-roll[data-ad-foreground] .ad-melody-roll-seconds { visibility: hidden; }
|
|
56
|
+
.ad-melody-roll-keys { isolation: isolate; }
|
|
57
|
+
.ad-melody-roll[data-ad-foreground] .ad-melody-note:not([data-render-probe]) {
|
|
58
|
+
visibility: hidden;
|
|
59
|
+
transition: none;
|
|
60
|
+
animation: none;
|
|
61
|
+
}
|
|
62
|
+
.ad-melody-roll[data-ad-foreground] .ad-melody-roll-keys:not([data-render-probe]) > .ad-piano-key {
|
|
63
|
+
background: transparent;
|
|
64
|
+
box-shadow: none;
|
|
65
|
+
color: transparent;
|
|
66
|
+
border-color: transparent;
|
|
67
|
+
filter: none;
|
|
68
|
+
translate: none;
|
|
69
|
+
transition: none;
|
|
70
|
+
animation: none;
|
|
71
|
+
}
|
|
72
|
+
.ad-melody-roll[data-ad-glow] {
|
|
73
|
+
box-shadow: none;
|
|
74
|
+
transition: none;
|
|
75
|
+
}
|
|
76
|
+
.ad-melody-roll[data-ad-glow] :is(.ad-melody-roll-light, .ad-melody-playhead-light, .ad-melody-voice, svg.ad-melody-trail) {
|
|
77
|
+
visibility: hidden;
|
|
78
|
+
}
|
|
24
79
|
/* The glass: its own still layer, so the frosted backdrop is never redrawn by the beat or by the
|
|
25
80
|
notes moving over it. */
|
|
26
81
|
.ad-melody-roll::before,
|
|
27
|
-
.ad-melody-roll
|
|
28
|
-
--ad-roll-beat: inherit;
|
|
82
|
+
.ad-melody-roll-light {
|
|
29
83
|
content: "";
|
|
30
84
|
position: absolute;
|
|
31
85
|
inset: 0;
|
|
@@ -42,10 +96,9 @@
|
|
|
42
96
|
backdrop-filter: blur(0.5rem);
|
|
43
97
|
}
|
|
44
98
|
/* The beat: a brighter edge and a warmer light over the glass, faded in with the music. */
|
|
45
|
-
.ad-melody-roll
|
|
99
|
+
.ad-melody-roll-light {
|
|
46
100
|
border-color: rgb(from var(--ad-primary) r g b / 0.35);
|
|
47
101
|
background: radial-gradient(80% 120% at 25% 50%, rgb(from var(--ad-primary) r g b / 0.12), transparent 70%);
|
|
48
|
-
opacity: var(--ad-roll-beat);
|
|
49
102
|
transition: opacity 0.12s;
|
|
50
103
|
will-change: opacity;
|
|
51
104
|
}
|
|
@@ -161,15 +214,13 @@
|
|
|
161
214
|
0 0 1rem var(--ad-primary);
|
|
162
215
|
}
|
|
163
216
|
/* The playhead flares on the beat: a wider glow, drawn once, faded in. */
|
|
164
|
-
.ad-melody-playhead
|
|
165
|
-
--ad-roll-beat: inherit;
|
|
217
|
+
.ad-melody-playhead-light {
|
|
166
218
|
content: "";
|
|
167
219
|
position: absolute;
|
|
168
220
|
inset: 0;
|
|
169
221
|
box-shadow:
|
|
170
222
|
0 0 1.6rem #fff,
|
|
171
223
|
0 0 2.6rem var(--ad-primary);
|
|
172
|
-
opacity: var(--ad-roll-beat);
|
|
173
224
|
will-change: opacity;
|
|
174
225
|
}
|
|
175
226
|
/* The singer's voice: grows with loudness, greens with accuracy. */
|