@nadicodeai/ui 12.1.66 → 12.1.68

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.
@@ -0,0 +1,21 @@
1
+ import type * as React from "react";
2
+ type CatalogTileProps = Omit<React.ComponentProps<"span">, "children" | "className"> & {
3
+ /** The entry's line icon. */
4
+ icon: React.ReactNode;
5
+ /**
6
+ * The ground that says what kind of entry it is: `neutral`, a card tile with
7
+ * a hairline border like an app mark's, for a skill; `info`, the soft blue,
8
+ * for a plugin.
9
+ */
10
+ tone: "neutral" | "info";
11
+ /** 40 px where the tile names a row, 64 px at the head of the entry's own page. */
12
+ size?: "row" | "page";
13
+ };
14
+ /**
15
+ * A catalog entry's picture: its line icon on a tile whose ground says which
16
+ * kind of entry it is. Decorative beside the entry's name, which it never
17
+ * replaces.
18
+ */
19
+ declare function CatalogTile({ icon, tone, size, ...props }: CatalogTileProps): React.JSX.Element;
20
+ export { CatalogTile, type CatalogTileProps };
21
+ //# sourceMappingURL=catalog-tile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-tile.d.ts","sourceRoot":"","sources":["../../src/components/catalog-tile.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC,KAAK,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC,GAAG;IACrF,6BAA6B;IAC7B,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB;;;;OAIG;IACH,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,iBAAS,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAY,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,qBAmB5E;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ /**
4
+ * A catalog entry's picture: its line icon on a tile whose ground says which
5
+ * kind of entry it is. Decorative beside the entry's name, which it never
6
+ * replaces.
7
+ */
8
+ function CatalogTile({ icon, tone, size = "row", ...props }) {
9
+ return (_jsx("span", { "aria-hidden": "true", className: cn("flex shrink-0 items-center justify-center rounded-md", tone === "neutral"
10
+ ? "bg-card text-foreground ring-1 ring-border"
11
+ : "bg-info-soft text-info-soft-foreground", size === "row" ? "size-10 [&>svg]:size-5" : "size-16 [&>svg]:size-6"), "data-size": size, "data-slot": "catalog-tile", "data-tone": tone, ...props, children: icon }));
12
+ }
13
+ export { CatalogTile };
@@ -0,0 +1,63 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Alveare's entry scene, the hive, which Alveare's desktop and Alveare Server
4
+ * both stand their entry screens on (apps/alveare/docs/design-doctrine.md,
5
+ * "Screens"): the app's picture on black, Alveare's logo at the upper left,
6
+ * six Agent orbs on the corners of a hexagon around the words, and the work
7
+ * flowing between them and the people in the picture as particles in the
8
+ * sending orb's colour. The orbs are artwork, so they take ambient motion and
9
+ * claim no activity (DESIGN.md, "Agent orbs"). Only the orbs and the particles
10
+ * move; reduced motion stops both, an ambient orb holding still.
11
+ *
12
+ * - `join`: the words stand in the middle of the hexagon.
13
+ * - `loading`: the orbs draw in and there are no words.
14
+ * - `still`: no Agent and no work, for a failure (no orb turns on one) or a
15
+ * screen read at length.
16
+ *
17
+ * The scene is black in every theme, so it scopes `dark`. The app owns its
18
+ * picture and where it stands, through its own stylesheet.
19
+ */
20
+ export type HivePoint = {
21
+ x: number;
22
+ y: number;
23
+ };
24
+ /** Where the work comes from and goes to in the picture, in the scene's pixels. */
25
+ export type HiveWork = {
26
+ senders: readonly HivePoint[];
27
+ receivers: readonly HivePoint[];
28
+ };
29
+ export type HiveSceneMode = "join" | "loading" | "still";
30
+ export type HiveSceneProps = Omit<React.ComponentProps<"div">, "children"> & {
31
+ mode: HiveSceneMode;
32
+ /** Alveare's logo, its app icon without the construction guides, and its name. */
33
+ logo: {
34
+ src: string;
35
+ label: string;
36
+ };
37
+ /** The app's picture, placed by the app's own stylesheet. */
38
+ picture?: React.ReactNode;
39
+ /** The picture's people for the scene's current size, so the work reaches them. */
40
+ work?: (size: {
41
+ width: number;
42
+ height: number;
43
+ }) => HiveWork;
44
+ /** Window chrome the scene must carry, such as a drag region. */
45
+ chrome?: React.ReactNode;
46
+ /** What `loading` is waiting for, read by assistive technology. */
47
+ label?: string;
48
+ children?: React.ReactNode;
49
+ };
50
+ declare function HiveScene({ mode, logo, picture, work, chrome, label, className, children, ...props }: HiveSceneProps): React.JSX.Element;
51
+ /** The screen's one heading, in the middle of the hive. */
52
+ declare function HiveTitle({ children, id }: {
53
+ children: React.ReactNode;
54
+ id?: string;
55
+ }): React.JSX.Element;
56
+ /** A line under the title saying what happened or what to do. */
57
+ declare function HiveLine({ children, id, tone, }: {
58
+ children: React.ReactNode;
59
+ id?: string;
60
+ tone?: "body" | "error";
61
+ }): React.JSX.Element;
62
+ export { HiveLine, HiveScene, HiveTitle };
63
+ //# sourceMappingURL=hive-scene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hive-scene.d.ts","sourceRoot":"","sources":["../../src/components/hive-scene.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,mFAAmF;AACnF,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IAC9B,SAAS,EAAE,SAAS,SAAS,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG;IAC3E,IAAI,EAAE,aAAa,CAAC;IACpB,kFAAkF;IAClF,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mFAAmF;IACnF,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,QAAQ,CAAC;IAC7D,iEAAiE;IACjE,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAmLF,iBAAS,SAAS,CAAC,EACjB,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,qBAiNhB;AAED,2DAA2D;AAC3D,iBAAS,SAAS,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,qBAM9E;AAED,iEAAiE;AACjE,iBAAS,QAAQ,CAAC,EAChB,QAAQ,EACR,EAAE,EACF,IAAa,GACd,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzB,qBAMA;AAED,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,337 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { mountAgentOrb } from "../internal/agent-orb.js";
5
+ import { cn } from "../lib/utils.js";
6
+ const COBALTO = "var(--nc-identity-cobalto)";
7
+ const VERDE = "var(--nc-identity-verde)";
8
+ const ARANCIO = "var(--nc-identity-arancio)";
9
+ const AGENTS = [
10
+ { form: "orbit", colour: COBALTO, size: 96 },
11
+ { form: "network", colour: VERDE, size: 64 },
12
+ { form: "globe", colour: ARANCIO, size: 96 },
13
+ { form: "lattice", colour: null, size: 64 },
14
+ { form: "braid", colour: COBALTO, size: 96 },
15
+ { form: "morph", colour: VERDE, size: 64 },
16
+ ];
17
+ function cellRadius(width, height) {
18
+ return Math.min(width, height) * 0.3;
19
+ }
20
+ function corner(index, centre, radius) {
21
+ const angle = -Math.PI / 2 + (index * Math.PI) / 3;
22
+ return {
23
+ x: centre.x + Math.cos(angle) * radius,
24
+ y: centre.y + Math.sin(angle) * radius,
25
+ };
26
+ }
27
+ /** The room an orb keeps from the words, so text never sits on an Agent. */
28
+ const WORDS_GAP = 16;
29
+ /**
30
+ * An orb's seat moved clear of the words: a seat at the side steps out
31
+ * sideways, the top and bottom ones up and down. An orb with no room left
32
+ * inside the scene is not drawn.
33
+ */
34
+ function clearOfWords(seat, size, words, scene) {
35
+ const half = size / 2 + WORDS_GAP;
36
+ let { x, y } = seat;
37
+ const covers = words &&
38
+ x + half > words.left &&
39
+ x - half < words.right &&
40
+ y + half > words.top &&
41
+ y - half < words.bottom;
42
+ if (words && covers) {
43
+ const centre = (words.left + words.right) / 2;
44
+ if (Math.abs(x - centre) > 1)
45
+ x = x > centre ? words.right + half : words.left - half;
46
+ else
47
+ y = y > (words.top + words.bottom) / 2 ? words.bottom + half : words.top - half;
48
+ }
49
+ const inside = x - size / 2 >= 0 &&
50
+ x + size / 2 <= scene.width &&
51
+ y - size / 2 >= 0 &&
52
+ y + size / 2 <= scene.height;
53
+ return inside ? { x, y } : null;
54
+ }
55
+ function sizeCanvas(canvas, width, height) {
56
+ const ratio = Math.min(window.devicePixelRatio || 1, 2);
57
+ canvas.width = width * ratio;
58
+ canvas.height = height * ratio;
59
+ const context = canvas.getContext("2d");
60
+ context?.setTransform(ratio, 0, 0, ratio, 0, 0);
61
+ return context;
62
+ }
63
+ /**
64
+ * Small groups of touching honeycomb cells in faint white lines, three
65
+ * clusters at the edges, clear of the people and the centre: the hive seen in
66
+ * passing, never a pattern. Each cluster is its centre (a share of the window)
67
+ * and its cells in axial hex coordinates, so the comb never moves.
68
+ */
69
+ const COMB_RADIUS = 15;
70
+ const COMB_CLUSTERS = [
71
+ {
72
+ x: 0.1,
73
+ y: 0.13,
74
+ alpha: 0.2,
75
+ cells: [
76
+ [0, 0],
77
+ [1, 0],
78
+ [0, 1],
79
+ [-1, 1],
80
+ [1, -1],
81
+ [2, -1],
82
+ ],
83
+ },
84
+ {
85
+ x: 0.83,
86
+ y: 0.16,
87
+ alpha: 0.2,
88
+ cells: [
89
+ [0, 0],
90
+ [1, 0],
91
+ [0, 1],
92
+ [1, 1],
93
+ [-1, 1],
94
+ [2, -1],
95
+ [1, -1],
96
+ ],
97
+ },
98
+ {
99
+ x: 0.22,
100
+ y: 0.3,
101
+ alpha: 0.13,
102
+ cells: [
103
+ [0, 0],
104
+ [1, 0],
105
+ [0, 1],
106
+ [1, -1],
107
+ [-1, 1],
108
+ [0, 2],
109
+ [-1, 2],
110
+ [1, 1],
111
+ ],
112
+ },
113
+ ];
114
+ function drawComb(canvas, width, height) {
115
+ const context = sizeCanvas(canvas, width, height);
116
+ if (!context)
117
+ return;
118
+ context.strokeStyle = getComputedStyle(canvas).color;
119
+ context.lineWidth = 1;
120
+ // Pointy-top cells in axial coordinates: q along the row, r down the rows.
121
+ // One path per cluster, stroked once, so an edge two cells share is one line.
122
+ const across = Math.sqrt(3) * COMB_RADIUS;
123
+ for (const cluster of COMB_CLUSTERS) {
124
+ context.globalAlpha = cluster.alpha;
125
+ context.beginPath();
126
+ for (const [q, r] of cluster.cells) {
127
+ const centre = {
128
+ x: cluster.x * width + across * (q + r / 2),
129
+ y: cluster.y * height + 1.5 * COMB_RADIUS * r,
130
+ };
131
+ for (let k = 0; k <= 6; k += 1) {
132
+ const { x, y } = corner(k % 6, centre, COMB_RADIUS);
133
+ if (k === 0)
134
+ context.moveTo(x, y);
135
+ else
136
+ context.lineTo(x, y);
137
+ }
138
+ }
139
+ context.stroke();
140
+ }
141
+ context.globalAlpha = 1;
142
+ }
143
+ function along(particle, t) {
144
+ const u = 1 - t;
145
+ return {
146
+ x: u * u * particle.from.x + 2 * u * t * particle.bend.x + t * t * particle.to.x,
147
+ y: u * u * particle.from.y + 2 * u * t * particle.bend.y + t * t * particle.to.y,
148
+ };
149
+ }
150
+ function pick(items) {
151
+ return items[Math.floor(Math.random() * items.length)];
152
+ }
153
+ function HiveScene({ mode, logo, picture, work, chrome, label, className, children, ...props }) {
154
+ const sceneRef = React.useRef(null);
155
+ const combRef = React.useRef(null);
156
+ const flowRef = React.useRef(null);
157
+ const orbRefs = React.useRef([]);
158
+ const holderRefs = React.useRef([]);
159
+ // The words' box, kept as state so the scene places the orbs again when it appears.
160
+ const [column, setColumn] = React.useState(null);
161
+ const workRef = React.useRef(work);
162
+ workRef.current = work;
163
+ const still = mode === "still";
164
+ React.useEffect(() => {
165
+ if (still)
166
+ return;
167
+ const mounted = orbRefs.current.flatMap((canvas, index) => {
168
+ const agent = AGENTS[index];
169
+ return canvas && agent
170
+ ? [
171
+ mountAgentOrb(canvas, {
172
+ form: agent.form,
173
+ size: agent.size,
174
+ // Artwork, not Agents at work: each form moves at its own pace and claims no activity.
175
+ motion: "ambient",
176
+ presence: "over-picture",
177
+ }),
178
+ ]
179
+ : [];
180
+ });
181
+ return () => {
182
+ for (const orb of mounted)
183
+ orb.destroy();
184
+ };
185
+ }, [still]);
186
+ React.useEffect(() => {
187
+ const scene = sceneRef.current;
188
+ const comb = combRef.current;
189
+ const flow = flowRef.current;
190
+ if (!scene || !comb || !flow)
191
+ return;
192
+ const reduced = window.matchMedia("(prefers-reduced-motion: reduce)");
193
+ let width = 0;
194
+ let height = 0;
195
+ let context = null;
196
+ let seats = [];
197
+ const place = () => {
198
+ width = scene.clientWidth;
199
+ height = scene.clientHeight;
200
+ const centre = { x: width / 2, y: height / 2 };
201
+ const radius = cellRadius(width, height) * (mode === "loading" ? 0.62 : 1);
202
+ const bounds = scene.getBoundingClientRect();
203
+ const box = column?.getBoundingClientRect();
204
+ const words = box?.width
205
+ ? {
206
+ left: box.left - bounds.left,
207
+ top: box.top - bounds.top,
208
+ right: box.right - bounds.left,
209
+ bottom: box.bottom - bounds.top,
210
+ }
211
+ : null;
212
+ seats = still
213
+ ? []
214
+ : AGENTS.map((agent, index) => clearOfWords(corner(index, centre, radius), agent.size, words, { width, height }));
215
+ holderRefs.current.forEach((holder, index) => {
216
+ if (!holder)
217
+ return;
218
+ const seat = seats[index];
219
+ holder.hidden = !seat;
220
+ if (!seat)
221
+ return;
222
+ holder.style.left = `${seat.x}px`;
223
+ holder.style.top = `${seat.y}px`;
224
+ });
225
+ drawComb(comb, width, height);
226
+ context = sizeCanvas(flow, width, height);
227
+ };
228
+ place();
229
+ const resize = new ResizeObserver(place);
230
+ resize.observe(scene);
231
+ if (column)
232
+ resize.observe(column);
233
+ if (still)
234
+ return () => resize.disconnect();
235
+ const colours = orbRefs.current.map((canvas) => canvas ? getComputedStyle(canvas).color : "white");
236
+ const particles = [];
237
+ let frame = 0;
238
+ let last = performance.now();
239
+ let nextSpawn = 0;
240
+ const spawn = () => {
241
+ const source = Math.floor(Math.random() * AGENTS.length);
242
+ const seat = seats[source];
243
+ if (!seat)
244
+ return;
245
+ const others = seats.filter((other) => other !== null && other !== seat);
246
+ const neighbour = (source + 1 + (Math.random() < 0.5 ? 0 : 4)) % AGENTS.length;
247
+ const next = seats[neighbour] ?? pick(others);
248
+ const people = workRef.current?.({ width, height });
249
+ const sender = people ? pick(people.senders) : undefined;
250
+ const receiver = people ? pick(people.receivers) : undefined;
251
+ const roll = Math.random();
252
+ const [from, to] = roll < 0.3 && sender
253
+ ? [sender, seat]
254
+ : roll < 0.6 && receiver
255
+ ? [seat, receiver]
256
+ : next
257
+ ? [seat, next]
258
+ : [];
259
+ if (!from || !to)
260
+ return;
261
+ const bend = (Math.random() - 0.5) * 120;
262
+ particles.push({
263
+ from,
264
+ to,
265
+ bend: {
266
+ x: (from.x + to.x) / 2 + bend,
267
+ y: (from.y + to.y) / 2 - Math.abs(bend),
268
+ },
269
+ t: 0,
270
+ speed: 0.07 + Math.random() * 0.06,
271
+ colour: colours[source] ?? "white",
272
+ size: 1.2 + Math.random() * 1.8,
273
+ trail: [],
274
+ });
275
+ };
276
+ const tick = (now) => {
277
+ const dt = Math.min(0.05, (now - last) / 1000);
278
+ last = now;
279
+ nextSpawn -= dt;
280
+ const paint = context;
281
+ if (paint) {
282
+ paint.clearRect(0, 0, width, height);
283
+ if (!reduced.matches && nextSpawn <= 0 && seats.length === AGENTS.length) {
284
+ nextSpawn = 0.3;
285
+ spawn();
286
+ }
287
+ for (let k = particles.length - 1; k >= 0; k -= 1) {
288
+ const particle = particles[k];
289
+ if (!particle)
290
+ continue;
291
+ particle.t += particle.speed * dt;
292
+ if (particle.t >= 1 || reduced.matches) {
293
+ particles.splice(k, 1);
294
+ continue;
295
+ }
296
+ const fade = Math.sin(particle.t * Math.PI);
297
+ particle.trail.push(along(particle, particle.t));
298
+ if (particle.trail.length > 10)
299
+ particle.trail.shift();
300
+ paint.fillStyle = particle.colour;
301
+ particle.trail.forEach((point, j) => {
302
+ const share = (j + 1) / particle.trail.length;
303
+ paint.globalAlpha = 0.9 * fade * share ** 2;
304
+ paint.beginPath();
305
+ paint.arc(point.x, point.y, particle.size * (0.4 + 0.6 * share), 0, Math.PI * 2);
306
+ paint.fill();
307
+ });
308
+ }
309
+ paint.globalAlpha = 1;
310
+ }
311
+ frame = requestAnimationFrame(tick);
312
+ };
313
+ frame = requestAnimationFrame(tick);
314
+ return () => {
315
+ cancelAnimationFrame(frame);
316
+ resize.disconnect();
317
+ };
318
+ }, [mode, still, column]);
319
+ return (_jsxs("div", { ...props, className: cn("nc-hive dark", className), "data-mode": mode, "data-slot": "hive-scene", ref: sceneRef, ...(mode === "loading" ? { "aria-label": label, role: "status" } : {}), children: [chrome, _jsx("img", { alt: logo.label, className: "nc-hive-logo", "data-slot": "hive-logo", src: logo.src }), picture, _jsx("canvas", { "aria-hidden": "true", className: "nc-hive-comb", ref: combRef }), _jsx("canvas", { "aria-hidden": "true", className: "nc-hive-flow", ref: flowRef }), still
320
+ ? null
321
+ : AGENTS.map((agent, index) => (_jsx("div", { "aria-hidden": "true", className: "nc-hive-agent", "data-slot": "hive-agent", "data-size": agent.size, ref: (holder) => {
322
+ holderRefs.current[index] = holder;
323
+ }, children: _jsx("canvas", { ref: (canvas) => {
324
+ orbRefs.current[index] = canvas;
325
+ if (canvas && agent.colour)
326
+ canvas.style.color = agent.colour;
327
+ } }) }, agent.form))), children ? (_jsx("div", { className: "nc-hive-column", "data-slot": "hive-column", ref: setColumn, children: children })) : null] }));
328
+ }
329
+ /** The screen's one heading, in the middle of the hive. */
330
+ function HiveTitle({ children, id }) {
331
+ return (_jsx("h1", { className: "nc-hive-title", id: id, children: children }));
332
+ }
333
+ /** A line under the title saying what happened or what to do. */
334
+ function HiveLine({ children, id, tone = "body", }) {
335
+ return (_jsx("p", { className: "nc-hive-line", "data-tone": tone, id: id, children: children }));
336
+ }
337
+ export { HiveLine, HiveScene, HiveTitle };
@@ -21,7 +21,7 @@ export type ObjectIdentityFact = {
21
21
  * title and its name is the h1; elsewhere the name is text at heading size.
22
22
  */
23
23
  export declare function ObjectIdentity({ visual, title, description, facts, action, menu, headingProps, }: {
24
- /** The object's picture: an Agent's orb, an app's mark. A skill, which is text, has none. */
24
+ /** The object's picture: an Agent's orb, an app's mark, a Library entry's tile. */
25
25
  visual?: ReactNode;
26
26
  title: ReactNode;
27
27
  description?: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"object-workspace.d.ts","sourceRoot":"","sources":["../../src/components/object-workspace.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvD,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,IAAI,EACJ,YAAY,GACb,EAAE;IACD,6FAA6F;IAC7F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACtC,wCAAwC;IACxC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;CACvD,+BA0CA;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,UAAU,GACX,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,EAAE,SAAS,CAAC;CACvB,+BAUA;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,YAAgB,GACjB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC1B,+BAkBA;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAmB,GACpB,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,+BAkCA"}
1
+ {"version":3,"file":"object-workspace.d.ts","sourceRoot":"","sources":["../../src/components/object-workspace.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvD,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,IAAI,EACJ,YAAY,GACb,EAAE;IACD,mFAAmF;IACnF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACtC,wCAAwC;IACxC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;CACvD,+BA0CA;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,UAAU,GACX,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,UAAU,EAAE,SAAS,CAAC;CACvB,+BAUA;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,EACX,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,YAAgB,GACjB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,sFAAsF;IACtF,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC1B,+BAkBA;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAmB,GACpB,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,+BAkCA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A link drawn as a QR code another device can scan: square dark modules on a
3
+ * white tile in every theme, because readers expect dark on light. `label`
4
+ * names what the code opens; the code itself is the image.
5
+ */
6
+ declare function QrCode({ value, label, size, className, }: {
7
+ value: string;
8
+ label: string;
9
+ /** The drawn width and height, in CSS pixels. */
10
+ size: number;
11
+ className?: string;
12
+ }): import("react").JSX.Element;
13
+ export { QrCode };
14
+ //# sourceMappingURL=qr-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-code.d.ts","sourceRoot":"","sources":["../../src/components/qr-code.tsx"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,iBAAS,MAAM,CAAC,EACd,KAAK,EACL,KAAK,EACL,IAAI,EACJ,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BA0BA;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { create } from "qrcode";
4
+ import { cn } from "../lib/utils.js";
5
+ /** The blank border a reader needs around the code, in modules. */
6
+ const QUIET_ZONE = 4;
7
+ /**
8
+ * A link drawn as a QR code another device can scan: square dark modules on a
9
+ * white tile in every theme, because readers expect dark on light. `label`
10
+ * names what the code opens; the code itself is the image.
11
+ */
12
+ function QrCode({ value, label, size, className, }) {
13
+ const { box, path } = useMemo(() => {
14
+ const { modules } = create(value, { errorCorrectionLevel: "M" });
15
+ let d = "";
16
+ for (let row = 0; row < modules.size; row += 1) {
17
+ for (let column = 0; column < modules.size; column += 1) {
18
+ if (modules.get(row, column))
19
+ d += `M${column + QUIET_ZONE} ${row + QUIET_ZONE}h1v1h-1z`;
20
+ }
21
+ }
22
+ return { box: modules.size + QUIET_ZONE * 2, path: d };
23
+ }, [value]);
24
+ return (_jsx("svg", { "aria-label": label, className: cn("block rounded-md bg-nc-identity-white text-nc-identity-ink", className), "data-slot": "qr-code", height: size, role: "img", shapeRendering: "crispEdges", viewBox: `0 0 ${box} ${box}`, width: size, children: _jsx("path", { d: path, fill: "currentColor" }) }));
25
+ }
26
+ export { QrCode };
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export * from "./components/button-group.js";
23
23
  export * from "./components/calendar.js";
24
24
  export * from "./components/card.js";
25
25
  export * from "./components/card-row.js";
26
+ export * from "./components/catalog-tile.js";
26
27
  export * from "./components/carousel.js";
27
28
  export * from "./components/channel-view.js";
28
29
  export * from "./components/chart.js";
@@ -67,6 +68,7 @@ export * from "./components/footer.js";
67
68
  export * from "./components/form-drawer.js";
68
69
  export * from "./components/form.js";
69
70
  export * from "./components/glass-control.js";
71
+ export * from "./components/hive-scene.js";
70
72
  export * from "./components/house-icons.js";
71
73
  export * from "./components/hover-card.js";
72
74
  export * from "./components/input.js";
@@ -99,6 +101,7 @@ export * from "./components/plugin-slot-boundary.js";
99
101
  export * from "./components/popover.js";
100
102
  export * from "./components/portal-sidebar-frame.js";
101
103
  export * from "./components/progress.js";
104
+ export * from "./components/qr-code.js";
102
105
  export * from "./components/radio-group.js";
103
106
  export * from "./components/reading-column.js";
104
107
  export * from "./components/resizable.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ export * from "./components/button-group.js";
23
23
  export * from "./components/calendar.js";
24
24
  export * from "./components/card.js";
25
25
  export * from "./components/card-row.js";
26
+ export * from "./components/catalog-tile.js";
26
27
  export * from "./components/carousel.js";
27
28
  export * from "./components/channel-view.js";
28
29
  export * from "./components/chart.js";
@@ -67,6 +68,7 @@ export * from "./components/footer.js";
67
68
  export * from "./components/form-drawer.js";
68
69
  export * from "./components/form.js";
69
70
  export * from "./components/glass-control.js";
71
+ export * from "./components/hive-scene.js";
70
72
  export * from "./components/house-icons.js";
71
73
  export * from "./components/hover-card.js";
72
74
  export * from "./components/input.js";
@@ -99,6 +101,7 @@ export * from "./components/plugin-slot-boundary.js";
99
101
  export * from "./components/popover.js";
100
102
  export * from "./components/portal-sidebar-frame.js";
101
103
  export * from "./components/progress.js";
104
+ export * from "./components/qr-code.js";
102
105
  export * from "./components/radio-group.js";
103
106
  export * from "./components/reading-column.js";
104
107
  export * from "./components/resizable.js";
@@ -516,6 +516,136 @@
516
516
  }
517
517
  }
518
518
 
519
+ /*
520
+ * Alveare's entry scene, the hive (`components/hive-scene.tsx`), in the
521
+ * composition of Nadia's entry screen: the app's picture on a black ground and
522
+ * the words standing on its empty centre, with no panel, card or ground behind
523
+ * them. The scene scopes `dark`, so every token inside it takes its dark value
524
+ * whatever the app's mode. Each app places its own picture.
525
+ */
526
+
527
+ .nc-hive {
528
+ position: fixed;
529
+ inset: 0;
530
+ z-index: 0;
531
+ isolation: isolate;
532
+ overflow: hidden auto;
533
+ display: grid;
534
+ place-items: safe center;
535
+ padding: var(--nc-xl) var(--nc-md);
536
+ background: var(--nc-identity-ink);
537
+ color: var(--nc-ink);
538
+ color-scheme: dark;
539
+ }
540
+
541
+ /*
542
+ * Alveare's own logo at the upper left, where Nadia's and the Portal's entry
543
+ * screens put the nadicode wordmark, at the wordmark's height and inset. The
544
+ * icon's tile is 824 of its 1024 units; the image box is sized so the tile,
545
+ * not the file's margin, takes the wordmark's height. An app with window
546
+ * controls over the scene sets `--hive-chrome-clearance` to their height, which
547
+ * the narrow inset clears.
548
+ */
549
+ .nc-hive-logo {
550
+ --hive-logo-tile: 24px;
551
+ --hive-logo-inset: var(--nc-lg);
552
+ --hive-logo-box: calc(var(--hive-logo-tile) * 1024 / 824);
553
+ --hive-logo-margin: calc(var(--hive-logo-box) * 100 / 1024);
554
+ position: absolute;
555
+ z-index: 2;
556
+ top: calc(
557
+ max(var(--hive-logo-inset), var(--hive-chrome-clearance, 0px)) -
558
+ var(--hive-logo-margin)
559
+ );
560
+ left: calc(var(--hive-logo-inset) - var(--hive-logo-margin));
561
+ width: var(--hive-logo-box);
562
+ height: var(--hive-logo-box);
563
+ pointer-events: none;
564
+ user-select: none;
565
+ }
566
+
567
+ @media (min-width: 640px) {
568
+ .nc-hive-logo {
569
+ --hive-logo-tile: 32px;
570
+ }
571
+ }
572
+
573
+ @media (min-width: 768px) {
574
+ .nc-hive-logo {
575
+ --hive-logo-inset: var(--nc-2xl);
576
+ top: calc(var(--hive-logo-inset) - var(--hive-logo-margin));
577
+ }
578
+ }
579
+
580
+ .nc-hive-comb,
581
+ .nc-hive-flow {
582
+ position: absolute;
583
+ inset: 0;
584
+ width: 100%;
585
+ height: 100%;
586
+ pointer-events: none;
587
+ }
588
+
589
+ .nc-hive-comb {
590
+ color: var(--nc-identity-white);
591
+ }
592
+
593
+ .nc-hive-agent {
594
+ position: absolute;
595
+ translate: -50% -50%;
596
+ pointer-events: none;
597
+ }
598
+
599
+ .nc-hive-agent[data-size="64"] {
600
+ width: 64px;
601
+ height: 64px;
602
+ }
603
+
604
+ .nc-hive-agent[data-size="96"] {
605
+ width: 96px;
606
+ height: 96px;
607
+ }
608
+
609
+ .nc-hive-agent canvas {
610
+ display: block;
611
+ width: 100%;
612
+ height: 100%;
613
+ }
614
+
615
+ .nc-hive-column {
616
+ position: relative;
617
+ z-index: 1;
618
+ display: grid;
619
+ justify-items: stretch;
620
+ gap: var(--nc-md);
621
+ width: min(20rem, 80vw);
622
+ text-align: center;
623
+ }
624
+
625
+ .nc-hive-title {
626
+ margin: 0;
627
+ font-family: var(--nc-type-heading-md-font-family);
628
+ font-size: var(--nc-type-heading-md-font-size);
629
+ font-weight: var(--nc-type-heading-md-font-weight);
630
+ line-height: var(--nc-type-heading-md-line-height);
631
+ letter-spacing: var(--nc-type-heading-md-letter-spacing);
632
+ text-wrap: balance;
633
+ overflow-wrap: break-word;
634
+ }
635
+
636
+ .nc-hive-line {
637
+ margin: 0;
638
+ font-family: var(--nc-type-body-sm-font-family);
639
+ font-size: var(--nc-type-body-sm-font-size);
640
+ line-height: var(--nc-type-body-sm-line-height);
641
+ overflow-wrap: break-word;
642
+ color: var(--nc-body);
643
+ }
644
+
645
+ .nc-hive-line[data-tone="error"] {
646
+ color: var(--nc-error);
647
+ }
648
+
519
649
  /*
520
650
  * The company card, contained (`components/company-card.tsx`;
521
651
  * design-system DESIGN.md, "Company card").
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nadicodeai/ui",
3
- "version": "12.1.66",
3
+ "version": "12.1.68",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -75,7 +75,7 @@
75
75
  "@base-ui/react": "^1.8.0",
76
76
  "@iconify-icons/logos": "^2.0.2",
77
77
  "@iconify/react": "^6.0.2",
78
- "@nadicodeai/design-system": "12.1.66",
78
+ "@nadicodeai/design-system": "12.1.68",
79
79
  "@tanstack/react-table": "^9.2.4",
80
80
  "class-variance-authority": "^0.7.1",
81
81
  "clsx": "^2.1.1",
@@ -86,6 +86,7 @@
86
86
  "lucide-react": "1.49.0",
87
87
  "motion": "^13.4.4",
88
88
  "next-themes": "^0.4.6",
89
+ "qrcode": "^1.5.4",
89
90
  "react-day-picker": "^10.0.1",
90
91
  "react-hook-form": "^7.89.0",
91
92
  "react-resizable-panels": "^4.13.3",