@nadicodeai/ui 12.1.67 → 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.
- package/dist/components/hive-scene.d.ts +63 -0
- package/dist/components/hive-scene.d.ts.map +1 -0
- package/dist/components/hive-scene.js +337 -0
- package/dist/components/qr-code.d.ts +14 -0
- package/dist/components/qr-code.d.ts.map +1 -0
- package/dist/components/qr-code.js +26 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/styles/components.css +130 -0
- package/package.json +3 -2
|
@@ -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 };
|
|
@@ -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
|
@@ -68,6 +68,7 @@ export * from "./components/footer.js";
|
|
|
68
68
|
export * from "./components/form-drawer.js";
|
|
69
69
|
export * from "./components/form.js";
|
|
70
70
|
export * from "./components/glass-control.js";
|
|
71
|
+
export * from "./components/hive-scene.js";
|
|
71
72
|
export * from "./components/house-icons.js";
|
|
72
73
|
export * from "./components/hover-card.js";
|
|
73
74
|
export * from "./components/input.js";
|
|
@@ -100,6 +101,7 @@ export * from "./components/plugin-slot-boundary.js";
|
|
|
100
101
|
export * from "./components/popover.js";
|
|
101
102
|
export * from "./components/portal-sidebar-frame.js";
|
|
102
103
|
export * from "./components/progress.js";
|
|
104
|
+
export * from "./components/qr-code.js";
|
|
103
105
|
export * from "./components/radio-group.js";
|
|
104
106
|
export * from "./components/reading-column.js";
|
|
105
107
|
export * from "./components/resizable.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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
|
@@ -68,6 +68,7 @@ export * from "./components/footer.js";
|
|
|
68
68
|
export * from "./components/form-drawer.js";
|
|
69
69
|
export * from "./components/form.js";
|
|
70
70
|
export * from "./components/glass-control.js";
|
|
71
|
+
export * from "./components/hive-scene.js";
|
|
71
72
|
export * from "./components/house-icons.js";
|
|
72
73
|
export * from "./components/hover-card.js";
|
|
73
74
|
export * from "./components/input.js";
|
|
@@ -100,6 +101,7 @@ export * from "./components/plugin-slot-boundary.js";
|
|
|
100
101
|
export * from "./components/popover.js";
|
|
101
102
|
export * from "./components/portal-sidebar-frame.js";
|
|
102
103
|
export * from "./components/progress.js";
|
|
104
|
+
export * from "./components/qr-code.js";
|
|
103
105
|
export * from "./components/radio-group.js";
|
|
104
106
|
export * from "./components/reading-column.js";
|
|
105
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.
|
|
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.
|
|
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",
|