@nadicodeai/ui 5.3.7 → 6.0.1
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/AGENTS.md +1 -1
- package/dist/components/forma-avatar.d.ts +23 -0
- package/dist/components/forma-avatar.d.ts.map +1 -0
- package/dist/components/forma-avatar.js +95 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/forma/frame.d.ts +10 -0
- package/dist/internal/forma/frame.d.ts.map +1 -0
- package/dist/internal/forma/frame.js +211 -0
- package/dist/internal/forma/geometry.d.ts +41 -0
- package/dist/internal/forma/geometry.d.ts.map +1 -0
- package/dist/internal/forma/geometry.js +235 -0
- package/dist/internal/forma/hallmark.d.ts +5 -0
- package/dist/internal/forma/hallmark.d.ts.map +1 -0
- package/dist/internal/forma/hallmark.js +4 -0
- package/dist/internal/forma/model.d.ts +53 -0
- package/dist/internal/forma/model.d.ts.map +1 -0
- package/dist/internal/forma/model.js +70 -0
- package/dist/internal/forma/motion.d.ts +42 -0
- package/dist/internal/forma/motion.d.ts.map +1 -0
- package/dist/internal/forma/motion.js +194 -0
- package/dist/internal/forma/rig.d.ts +10 -0
- package/dist/internal/forma/rig.d.ts.map +1 -0
- package/dist/internal/forma/rig.js +211 -0
- package/dist/internal/forma/still.d.ts +4 -0
- package/dist/internal/forma/still.d.ts.map +1 -0
- package/dist/internal/forma/still.js +8 -0
- package/docs/contract.md +1 -1
- package/docs/forma-avatar.md +92 -0
- package/docs/migration/6.0.0.md +30 -0
- package/package.json +2 -2
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { computeFrame } from "./frame.js";
|
|
2
|
+
import { createMotion, needsMotion, settled, stepPose, updateMotion, } from "./motion.js";
|
|
3
|
+
const attributeName = (prop) => prop.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
4
|
+
function write(element, attributes) {
|
|
5
|
+
for (const prop in attributes) {
|
|
6
|
+
const value = attributes[prop] ?? "";
|
|
7
|
+
if (prop === "display") {
|
|
8
|
+
element.style.display = value;
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
const name = attributeName(prop);
|
|
12
|
+
if (element.getAttribute(name) !== value)
|
|
13
|
+
element.setAttribute(name, value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const pools = new WeakMap();
|
|
17
|
+
class Pool {
|
|
18
|
+
document;
|
|
19
|
+
entries = new Map();
|
|
20
|
+
observer;
|
|
21
|
+
reduced = typeof matchMedia === "function"
|
|
22
|
+
? matchMedia("(prefers-reduced-motion: reduce)")
|
|
23
|
+
: { matches: false, addEventListener() { }, removeEventListener() { } };
|
|
24
|
+
pointer = { x: NaN, y: NaN };
|
|
25
|
+
frame;
|
|
26
|
+
lastFrame = -Infinity;
|
|
27
|
+
constructor(document) {
|
|
28
|
+
this.document = document;
|
|
29
|
+
this.observer =
|
|
30
|
+
typeof IntersectionObserver === "undefined"
|
|
31
|
+
? undefined
|
|
32
|
+
: new IntersectionObserver((records) => {
|
|
33
|
+
for (const record of records) {
|
|
34
|
+
const entry = this.entries.get(record.target);
|
|
35
|
+
if (!entry)
|
|
36
|
+
continue;
|
|
37
|
+
if (record.isIntersecting && !entry.visible)
|
|
38
|
+
entry.motion.snap = true;
|
|
39
|
+
entry.visible = record.isIntersecting;
|
|
40
|
+
entry.dirty = true;
|
|
41
|
+
}
|
|
42
|
+
this.request();
|
|
43
|
+
}, { rootMargin: "80px" });
|
|
44
|
+
document.addEventListener("visibilitychange", this.onWake);
|
|
45
|
+
document.addEventListener("pointermove", this.onPointer, { passive: true });
|
|
46
|
+
document.addEventListener("pointerleave", this.onPointerLeave);
|
|
47
|
+
this.reduced.addEventListener("change", this.onWake);
|
|
48
|
+
window.addEventListener("resize", this.onWake);
|
|
49
|
+
}
|
|
50
|
+
onWake = () => {
|
|
51
|
+
for (const entry of this.entries.values()) {
|
|
52
|
+
entry.dirty = true;
|
|
53
|
+
entry.motion.snap = true;
|
|
54
|
+
entry.rect = null;
|
|
55
|
+
}
|
|
56
|
+
if (this.document.hidden && this.frame !== undefined) {
|
|
57
|
+
cancelAnimationFrame(this.frame);
|
|
58
|
+
this.frame = undefined;
|
|
59
|
+
}
|
|
60
|
+
this.request();
|
|
61
|
+
};
|
|
62
|
+
onPointer = (event) => {
|
|
63
|
+
if (event.pointerType === "touch")
|
|
64
|
+
return;
|
|
65
|
+
this.pointer.x = event.clientX;
|
|
66
|
+
this.pointer.y = event.clientY;
|
|
67
|
+
this.request();
|
|
68
|
+
};
|
|
69
|
+
onPointerLeave = () => {
|
|
70
|
+
this.pointer.x = NaN;
|
|
71
|
+
this.pointer.y = NaN;
|
|
72
|
+
this.request();
|
|
73
|
+
};
|
|
74
|
+
request() {
|
|
75
|
+
if (this.frame === undefined &&
|
|
76
|
+
!this.document.hidden &&
|
|
77
|
+
this.entries.size > 0 &&
|
|
78
|
+
typeof requestAnimationFrame === "function")
|
|
79
|
+
this.frame = requestAnimationFrame(this.tick);
|
|
80
|
+
}
|
|
81
|
+
aim(entry, now) {
|
|
82
|
+
const { motion } = entry;
|
|
83
|
+
if (motion.still || motion.view !== "front" || Number.isNaN(this.pointer.x)) {
|
|
84
|
+
motion.pointer.x = 0;
|
|
85
|
+
motion.pointer.y = 0;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (!entry.rect || now - entry.rectAt > 500) {
|
|
89
|
+
entry.rect = entry.svg.getBoundingClientRect();
|
|
90
|
+
entry.rectAt = now;
|
|
91
|
+
}
|
|
92
|
+
const rect = entry.rect;
|
|
93
|
+
if (!rect.width)
|
|
94
|
+
return;
|
|
95
|
+
const cx = rect.left + rect.width / 2;
|
|
96
|
+
const cy = rect.top + rect.height / 2;
|
|
97
|
+
const reach = Math.max(rect.width, 32) * 2.5;
|
|
98
|
+
const dx = this.pointer.x - cx;
|
|
99
|
+
const dy = this.pointer.y - cy;
|
|
100
|
+
const distance = Math.hypot(dx, dy);
|
|
101
|
+
const k = Math.min(1, distance / reach) / (distance || 1);
|
|
102
|
+
motion.pointer.x = Math.max(-1, Math.min(1, dx * k));
|
|
103
|
+
motion.pointer.y = Math.max(-1, Math.min(1, dy * k));
|
|
104
|
+
}
|
|
105
|
+
tick = (now) => {
|
|
106
|
+
this.frame = undefined;
|
|
107
|
+
if (this.document.hidden)
|
|
108
|
+
return;
|
|
109
|
+
if (now - this.lastFrame < 1000 / 30) {
|
|
110
|
+
this.request();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const dt = Math.min(0.05, Math.max(0, (now - this.lastFrame) / 1000));
|
|
114
|
+
this.lastFrame = now;
|
|
115
|
+
let again = false;
|
|
116
|
+
for (const entry of this.entries.values()) {
|
|
117
|
+
if (!entry.visible)
|
|
118
|
+
continue;
|
|
119
|
+
const { motion } = entry;
|
|
120
|
+
motion.still = motion.paused || this.reduced.matches;
|
|
121
|
+
this.aim(entry, now);
|
|
122
|
+
const moving = needsMotion(motion, now);
|
|
123
|
+
if (entry.dirty || moving || entry.terminalFrameDue) {
|
|
124
|
+
const pose = stepPose(motion, now, entry.dirty ? 0 : dt);
|
|
125
|
+
this.paint(entry, pose, now);
|
|
126
|
+
this.setMode(entry, motion.still ? "still" : "live");
|
|
127
|
+
entry.dirty = false;
|
|
128
|
+
entry.terminalFrameDue = moving;
|
|
129
|
+
}
|
|
130
|
+
again ||= needsMotion(motion, now) && !settled(motion, now);
|
|
131
|
+
if (Number.isFinite(this.pointer.x) && motion.state === "idle" && !motion.still)
|
|
132
|
+
again = true;
|
|
133
|
+
}
|
|
134
|
+
if (again)
|
|
135
|
+
this.request();
|
|
136
|
+
};
|
|
137
|
+
paint(entry, pose, now) {
|
|
138
|
+
const frame = computeFrame(entry.motion, pose, now);
|
|
139
|
+
for (const part in frame) {
|
|
140
|
+
const element = entry.parts.get(part);
|
|
141
|
+
if (element)
|
|
142
|
+
write(element, frame[part]);
|
|
143
|
+
}
|
|
144
|
+
entry.svg.dataset.state = entry.motion.state;
|
|
145
|
+
}
|
|
146
|
+
setMode(entry, mode) {
|
|
147
|
+
if (entry.svg.dataset.renderMode === mode)
|
|
148
|
+
return;
|
|
149
|
+
entry.svg.dataset.renderMode = mode;
|
|
150
|
+
entry.callbacks.onModeChange?.(mode);
|
|
151
|
+
}
|
|
152
|
+
release(svg) {
|
|
153
|
+
this.observer?.unobserve(svg);
|
|
154
|
+
this.entries.delete(svg);
|
|
155
|
+
if (this.entries.size !== 0)
|
|
156
|
+
return;
|
|
157
|
+
if (this.frame !== undefined)
|
|
158
|
+
cancelAnimationFrame(this.frame);
|
|
159
|
+
this.observer?.disconnect();
|
|
160
|
+
this.document.removeEventListener("visibilitychange", this.onWake);
|
|
161
|
+
this.document.removeEventListener("pointermove", this.onPointer);
|
|
162
|
+
this.document.removeEventListener("pointerleave", this.onPointerLeave);
|
|
163
|
+
this.reduced.removeEventListener("change", this.onWake);
|
|
164
|
+
window.removeEventListener("resize", this.onWake);
|
|
165
|
+
pools.delete(this.document);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export function mountForma(svg, options, callbacks = {}) {
|
|
169
|
+
const doc = svg.ownerDocument;
|
|
170
|
+
let pool = pools.get(doc);
|
|
171
|
+
if (!pool) {
|
|
172
|
+
pool = new Pool(doc);
|
|
173
|
+
pools.set(doc, pool);
|
|
174
|
+
}
|
|
175
|
+
if (pool.entries.has(svg))
|
|
176
|
+
throw new Error("This element already has a Forma avatar");
|
|
177
|
+
const parts = new Map();
|
|
178
|
+
for (const element of svg.querySelectorAll("[data-part]"))
|
|
179
|
+
parts.set(element.getAttribute("data-part"), element);
|
|
180
|
+
const entry = {
|
|
181
|
+
svg,
|
|
182
|
+
parts,
|
|
183
|
+
motion: createMotion(options, performance.now()),
|
|
184
|
+
visible: !pool.observer,
|
|
185
|
+
dirty: true,
|
|
186
|
+
terminalFrameDue: false,
|
|
187
|
+
callbacks,
|
|
188
|
+
rect: null,
|
|
189
|
+
rectAt: -Infinity,
|
|
190
|
+
};
|
|
191
|
+
const activePool = pool;
|
|
192
|
+
pool.entries.set(svg, entry);
|
|
193
|
+
pool.observer?.observe(svg);
|
|
194
|
+
pool.request();
|
|
195
|
+
let disposed = false;
|
|
196
|
+
return {
|
|
197
|
+
update(next) {
|
|
198
|
+
if (disposed)
|
|
199
|
+
return;
|
|
200
|
+
updateMotion(entry.motion, next, performance.now());
|
|
201
|
+
entry.dirty = true;
|
|
202
|
+
activePool.request();
|
|
203
|
+
},
|
|
204
|
+
dispose() {
|
|
205
|
+
if (disposed)
|
|
206
|
+
return;
|
|
207
|
+
disposed = true;
|
|
208
|
+
activePool.release(svg);
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"still.d.ts","sourceRoot":"","sources":["../../../src/internal/forma/still.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAgB,MAAM,SAAS,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAGpD,wBAAgB,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,KAAK,CAK/D"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { computeFrame } from "./frame.js";
|
|
2
|
+
import { createMotion, stepPose } from "./motion.js";
|
|
3
|
+
export function stillFrame(options) {
|
|
4
|
+
const motion = createMotion({ ...options, paused: true }, 0);
|
|
5
|
+
motion.still = true;
|
|
6
|
+
const pose = stepPose(motion, 0, 0);
|
|
7
|
+
return computeFrame(motion, pose, 0);
|
|
8
|
+
}
|
package/docs/contract.md
CHANGED
|
@@ -107,7 +107,7 @@ this same renderer.
|
|
|
107
107
|
|
|
108
108
|
## Admission Rules
|
|
109
109
|
|
|
110
|
-
Assistant conversation and runtime APIs enter through `@nadicodeai/ui/agents`; Agent identity enters through `@nadicodeai/ui/components/agent-card
|
|
110
|
+
Assistant conversation and runtime APIs enter through `@nadicodeai/ui/agents`; Agent identity enters through `@nadicodeai/ui/components/agent-card`, `@nadicodeai/ui/components/agent-visual`, and the Forma avatars in `@nadicodeai/ui/components/forma-avatar` (owned by [`forma-avatar.md`](forma-avatar.md)). The consuming application still constructs the runtime and owns transport, persistence, permissions, tools, approvals, and failure policy. Shared non-Agent product components (a shell, a settings surface, a generic section, a diff, or a file preview) are admitted only with a named consuming surface landing in the same change. App-bespoke UI and behavior (window chrome, PTY/xterm embeds, queues, approvals, and persistence) stay in the consuming app; they never become package abstractions. `@nadicodeai/ui/threshold` is the plan-approved package surface for the room, Nadia's presence, the status orb and the typed line used by the Nadia desktop app. The screen, its copy and its state machine stay in the consuming app, and the entry ships no screen. Its contract is [`threshold.md`](threshold.md). A component left unconsumed after its target migration ships gets removed.
|
|
111
111
|
|
|
112
112
|
### Agent identity presentation
|
|
113
113
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Forma Avatars
|
|
2
|
+
|
|
3
|
+
Forma is the avatar family for the Agents a company operates inside Nadia,
|
|
4
|
+
and for Nadia herself. It is a character: a coloured shell with a visor and
|
|
5
|
+
two eyes, alive through the approved lifecycle gestures. `@nadicodeai/ui`
|
|
6
|
+
owns its rendering as one SVG per avatar; consuming products own the stored
|
|
7
|
+
appearance, the Agent data, and every fact about status or work.
|
|
8
|
+
|
|
9
|
+
This system is distinct from Nadia's portrait, which stays the one canonical
|
|
10
|
+
identity in `brand/AGENTS.md` "Nadia's identity". Nadia's avatar here is her
|
|
11
|
+
approved Forma shell: the tricolour, the signature eyes and lash flicks, and
|
|
12
|
+
the Italy hallmark on her right flank (Natural Earth 110m Italy from
|
|
13
|
+
AshKyd/geojson-regions, projected once with d3-geo 3.1.1 into a 512-unit box).
|
|
14
|
+
|
|
15
|
+
## Forms and colours
|
|
16
|
+
|
|
17
|
+
A customer picks a form and a colour. Forms are shapes, never roles: choosing
|
|
18
|
+
Goccia grants no tools and changes no instructions, and the product names the
|
|
19
|
+
job. The closed set is Nadia plus seven forms:
|
|
20
|
+
|
|
21
|
+
| Form | Silhouette | Default shell | Visor | Eyes |
|
|
22
|
+
| --- | --- | --- | --- | --- |
|
|
23
|
+
| `nadia` | The approved shell, tricolour, fixed | verde | black | signature mint |
|
|
24
|
+
| `goccia` | Drop | rosso | black | white |
|
|
25
|
+
| `nuvola` | Cloud | cobalto | ivory | ink |
|
|
26
|
+
| `triangolo` | Rounded triangle | verde | ivory | ink |
|
|
27
|
+
| `esagono` | Hexagon | giallo | black | white |
|
|
28
|
+
| `quadrato` | Squircle | arancio | ivory | ink |
|
|
29
|
+
| `pillola` | Stadium | verde | black | white |
|
|
30
|
+
| `uovo` | Egg | cobalto | black | white |
|
|
31
|
+
|
|
32
|
+
Shell colours are the Agent identity palette (`identity-verde`, `-cobalto`,
|
|
33
|
+
`-rosso`, `-arancio`, `-giallo`) plus `forma-avorio`; the visor, bezel,
|
|
34
|
+
Nadia's eye light and the blocked sand are the `forma-*` tokens. All of them are owned by
|
|
35
|
+
`packages/design-system/DESIGN.md` and read through their CSS custom
|
|
36
|
+
properties, so an avatar carries no colour of its own. `uovo` is the form an
|
|
37
|
+
Agent wears until a customer chooses; it is never inferred from a name, an
|
|
38
|
+
id, a role label, or a position in a list.
|
|
39
|
+
|
|
40
|
+
## Construction
|
|
41
|
+
|
|
42
|
+
Every form carries a core sphere inside its silhouette. The one approved
|
|
43
|
+
visor and the form's eyes ride on that sphere, seen through the engine's
|
|
44
|
+
camera (perspective from 5.2 radii), and the silhouette clips them: the face
|
|
45
|
+
is the same size and curvature on every form, and turning the head moves it
|
|
46
|
+
across the shell the same way, foreshortening at the rim.
|
|
47
|
+
|
|
48
|
+
The lighting reproduces the engine's studio, number for number where a
|
|
49
|
+
gradient can: the shell is enamel deepened by its own pigment toward the
|
|
50
|
+
rim (a multiply layer), shaded by the hemisphere light toward the floor,
|
|
51
|
+
lit by the wide top-left key card, a hot spot, and the right rim card; the
|
|
52
|
+
visor is black glass with one crisp reflection at its top-left corner, a
|
|
53
|
+
soft haze across the top, the right-edge reflection, and a thin bezel lit
|
|
54
|
+
only where the key reaches it; the eyes carry their halo and a glint, and
|
|
55
|
+
Nadia's Italy hallmark is the engine's ivory engraving at longitude 1.24 on
|
|
56
|
+
her right flank, visible from the side. Blocked morphs every form into the same torus and drains
|
|
57
|
+
its pigment 28% toward `forma-sabbia`, as the approved renders do.
|
|
58
|
+
|
|
59
|
+
## States and motion
|
|
60
|
+
|
|
61
|
+
Six states: `idle`, `working`, `thinking`, `waiting`, `blocked`, `done`. The
|
|
62
|
+
choreography is the approved engine's, number for number: the idle sway and
|
|
63
|
+
pointer-following gaze; working's acknowledging nod, scan, beat, three pulsing
|
|
64
|
+
ticks and two orbiting bead trails; thinking's tilt and three thought beads;
|
|
65
|
+
waiting's pause bars; blocked's morph into the ring and bar; done's wind-up,
|
|
66
|
+
full turn, hop, happy eyes and the three-ribbon celebration. A completion
|
|
67
|
+
celebrates once per real transition or `motionKey` change; an initially
|
|
68
|
+
completed avatar holds its finished pose. Waiting and blocked always face
|
|
69
|
+
forward; `view="side"` shows the flank otherwise.
|
|
70
|
+
|
|
71
|
+
One loop per document drives every mounted avatar at up to 30 frames a
|
|
72
|
+
second. Offscreen and hidden avatars do not render, settled states stop the
|
|
73
|
+
loop, and the pointer turns the heads nearest to it. `paused` and reduced
|
|
74
|
+
motion hold the state's deterministic resting frame, which is also what the
|
|
75
|
+
server renders, effects included (a working still carries its orbit beads, a
|
|
76
|
+
thinking still its thought beads), so no surface ever shows an empty slot and
|
|
77
|
+
no still image is shipped.
|
|
78
|
+
|
|
79
|
+
## Package shape
|
|
80
|
+
|
|
81
|
+
`FormaAvatar` (`@nadicodeai/ui/components/forma-avatar`) takes `form`,
|
|
82
|
+
`color`, `state`, `size` (12–512 CSS pixels), `paused`, `view`, and
|
|
83
|
+
`motionKey`. It is decorative by default; a visual that is itself the
|
|
84
|
+
choice, as in a picker, opts into `decorative={false}` with a `label`. It
|
|
85
|
+
exposes `data-forma-avatar`, `data-state`, `data-color` on its host and
|
|
86
|
+
`data-render-mode` (`still` or `live`) on the SVG. The model's closed lists
|
|
87
|
+
(`formaForms`, `formaChoices`, `formaColors`, `formaStates`, `formDetails`,
|
|
88
|
+
`defaultForm`) are exported beside it for pickers and stored-appearance
|
|
89
|
+
mapping; the geometry, rig and frame computation are internal.
|
|
90
|
+
|
|
91
|
+
Additions to the family go through this document and the design-system
|
|
92
|
+
token contract, never through an ad-hoc visual.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Migrating to `@nadicodeai/ui` 6.0.0
|
|
2
|
+
|
|
3
|
+
This release removes contract entries that nothing rendered. `@nadicodeai/ui`
|
|
4
|
+
6.0.0 requires `@nadicodeai/design-system` 6.0.0; the two packages are
|
|
5
|
+
released in lockstep.
|
|
6
|
+
|
|
7
|
+
## Removed colour tokens
|
|
8
|
+
|
|
9
|
+
| Removed | Use instead |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `--nc-flag-red` | `--nc-identity-rosso` for the identity red, `--nc-error` for validation feedback. Same hex as both. |
|
|
12
|
+
| `--nc-background-100`, `--nc-background-200` | `--nc-canvas`, `--nc-canvas-soft`. Same hex. |
|
|
13
|
+
| `--nc-dark-cyan`, `--nc-dark-cyan-soft`, `--nc-dark-cyan-deep` | No replacement; the family had no light counterpart, no prose, and no consumer. |
|
|
14
|
+
| `register.nadia.color.*.medallion` | No replacement; the first-run medallion no longer exists. |
|
|
15
|
+
|
|
16
|
+
`register.nadia.color.dark.destructive` now aliases `dark-error` with
|
|
17
|
+
`dark-on-primary` text, the same pair the foundation's `.dark` shadcn map
|
|
18
|
+
already resolves `destructive` to. It aliased the removed `flag-red` with
|
|
19
|
+
white text.
|
|
20
|
+
|
|
21
|
+
## Removed Nadia asset routes
|
|
22
|
+
|
|
23
|
+
`./assets/nadia-ordered-points`, `./assets/nadia-triangulated-wire` and
|
|
24
|
+
`./assets/nadia-irregular-particles` are gone. `./assets/nadia-solid-surface`
|
|
25
|
+
is the one approved master and the one route. The authored files stay in
|
|
26
|
+
`brand/visual-design/images/nadia/material-states/transparent/`.
|
|
27
|
+
|
|
28
|
+
## Removed layout entry
|
|
29
|
+
|
|
30
|
+
`article-frame` is no longer documented; it never had CSS.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nadicodeai/ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@assistant-ui/react": "0.15.18",
|
|
71
71
|
"@assistant-ui/react-markdown": "0.14.14",
|
|
72
72
|
"@base-ui/react": "^1.8.0",
|
|
73
|
-
"@nadicodeai/design-system": "
|
|
73
|
+
"@nadicodeai/design-system": "6.0.1",
|
|
74
74
|
"@paper-design/shaders": "0.0.80",
|
|
75
75
|
"class-variance-authority": "^0.7.1",
|
|
76
76
|
"clsx": "^2.1.1",
|