@nadicodeai/ui 12.1.150 → 12.1.152
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 +18 -7
- package/dist/components/hive-scene.d.ts.map +1 -1
- package/dist/components/hive-scene.js +32 -11
- package/dist/components/object-page.d.ts +3 -1
- package/dist/components/object-page.d.ts.map +1 -1
- package/dist/components/object-page.js +4 -2
- package/dist/showcase/usage.generated.js +2 -2
- package/dist/styles/components.css +7 -1
- package/package.json +2 -2
|
@@ -25,6 +25,13 @@ export type HivePoint = {
|
|
|
25
25
|
x: number;
|
|
26
26
|
y: number;
|
|
27
27
|
};
|
|
28
|
+
/** A box in the scene's pixels, from its top left corner. */
|
|
29
|
+
export type HiveBox = {
|
|
30
|
+
left: number;
|
|
31
|
+
top: number;
|
|
32
|
+
right: number;
|
|
33
|
+
bottom: number;
|
|
34
|
+
};
|
|
28
35
|
/** Where the work comes from and goes to in the picture, in the scene's pixels. */
|
|
29
36
|
export type HiveWork = {
|
|
30
37
|
senders: readonly HivePoint[];
|
|
@@ -41,13 +48,16 @@ export type HiveSceneProps = Omit<React.ComponentProps<"div">, "children"> & {
|
|
|
41
48
|
src: string;
|
|
42
49
|
label: string;
|
|
43
50
|
};
|
|
44
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* The app's picture, placed by the app's own stylesheet, which keeps it clear of the words by
|
|
53
|
+
* the width the scene sets on itself as `--hive-words-width`.
|
|
54
|
+
*/
|
|
45
55
|
picture?: React.ReactNode;
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
/**
|
|
57
|
+
* The picture's people, so the work reaches them: `pictures` are the boxes the picture's
|
|
58
|
+
* elements are drawn in now, in their order, an element not drawn as an empty box.
|
|
59
|
+
*/
|
|
60
|
+
work?: (pictures: readonly HiveBox[]) => HiveWork;
|
|
51
61
|
/** Window chrome the scene must carry, such as a drag region. */
|
|
52
62
|
chrome?: React.ReactNode;
|
|
53
63
|
/** What `loading` is waiting for, read by assistive technology. */
|
|
@@ -62,7 +72,8 @@ export type HiveSceneProps = Omit<React.ComponentProps<"div">, "children"> & {
|
|
|
62
72
|
* @instead Nadia's entry screens are `EntryScene`. A product page never stands on a scene.
|
|
63
73
|
* @behaviour `join` puts the words in the hexagon's middle, `loading` draws the orbs in with no
|
|
64
74
|
* words, `still` shows no Agent and no work. Only the orbs and the particles move; reduced motion
|
|
65
|
-
* stops both. Black in every theme.
|
|
75
|
+
* stops both. Black in every theme. The scene sets the width its words are drawn at on itself as
|
|
76
|
+
* `--hive-words-width`, so the app's picture keeps clear of them, and draws no honeycomb near them.
|
|
66
77
|
* @words The words are the screen's own: a title, a line, one action. The logo's label names
|
|
67
78
|
* Alveare.
|
|
68
79
|
* @access The canvases are hidden; the logo's image is named by its label. In `loading` the scene
|
|
@@ -1 +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;;;;;;;;;;;;;;;;;;;;;GAqBG;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,eAAe,GAAG,SAAS,GAAG,OAAO,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG;IAC3E,IAAI,EAAE,aAAa,CAAC;IACpB,qFAAqF;IACrF,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,kFAAkF;IAClF,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC
|
|
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;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD,6DAA6D;AAC7D,MAAM,MAAM,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,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,eAAe,GAAG,SAAS,GAAG,OAAO,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG;IAC3E,IAAI,EAAE,aAAa,CAAC;IACpB,qFAAqF;IACrF,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,kFAAkF;IAClF,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,KAAK,QAAQ,CAAC;IAClD,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;AA4LF;;;;;;;;;;;;;;GAcG;AACH,iBAAS,SAAS,CAAC,EACjB,IAAI,EACJ,MAAkB,EAClB,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,qBA4QhB;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"}
|
|
@@ -111,7 +111,7 @@ const COMB_CLUSTERS = [
|
|
|
111
111
|
],
|
|
112
112
|
},
|
|
113
113
|
];
|
|
114
|
-
function drawComb(canvas, width, height) {
|
|
114
|
+
function drawComb(canvas, width, height, words) {
|
|
115
115
|
const context = sizeCanvas(canvas, width, height);
|
|
116
116
|
if (!context)
|
|
117
117
|
return;
|
|
@@ -120,14 +120,22 @@ function drawComb(canvas, width, height) {
|
|
|
120
120
|
// Pointy-top cells in axial coordinates: q along the row, r down the rows.
|
|
121
121
|
// One path per cluster, stroked once, so an edge two cells share is one line.
|
|
122
122
|
const across = Math.sqrt(3) * COMB_RADIUS;
|
|
123
|
+
const reach = COMB_RADIUS + WORDS_GAP;
|
|
123
124
|
for (const cluster of COMB_CLUSTERS) {
|
|
125
|
+
const centres = cluster.cells.map(([q, r]) => ({
|
|
126
|
+
x: cluster.x * width + across * (q + r / 2),
|
|
127
|
+
y: cluster.y * height + 1.5 * COMB_RADIUS * r,
|
|
128
|
+
}));
|
|
129
|
+
const nearWords = words &&
|
|
130
|
+
centres.some(({ x, y }) => x + reach > words.left &&
|
|
131
|
+
x - reach < words.right &&
|
|
132
|
+
y + reach > words.top &&
|
|
133
|
+
y - reach < words.bottom);
|
|
134
|
+
if (nearWords)
|
|
135
|
+
continue;
|
|
124
136
|
context.globalAlpha = cluster.alpha;
|
|
125
137
|
context.beginPath();
|
|
126
|
-
for (const
|
|
127
|
-
const centre = {
|
|
128
|
-
x: cluster.x * width + across * (q + r / 2),
|
|
129
|
-
y: cluster.y * height + 1.5 * COMB_RADIUS * r,
|
|
130
|
-
};
|
|
138
|
+
for (const centre of centres) {
|
|
131
139
|
for (let k = 0; k <= 6; k += 1) {
|
|
132
140
|
const { x, y } = corner(k % 6, centre, COMB_RADIUS);
|
|
133
141
|
if (k === 0)
|
|
@@ -158,7 +166,8 @@ function pick(items) {
|
|
|
158
166
|
* @instead Nadia's entry screens are `EntryScene`. A product page never stands on a scene.
|
|
159
167
|
* @behaviour `join` puts the words in the hexagon's middle, `loading` draws the orbs in with no
|
|
160
168
|
* words, `still` shows no Agent and no work. Only the orbs and the particles move; reduced motion
|
|
161
|
-
* stops both. Black in every theme.
|
|
169
|
+
* stops both. Black in every theme. The scene sets the width its words are drawn at on itself as
|
|
170
|
+
* `--hive-words-width`, so the app's picture keeps clear of them, and draws no honeycomb near them.
|
|
162
171
|
* @words The words are the screen's own: a title, a line, one action. The logo's label names
|
|
163
172
|
* Alveare.
|
|
164
173
|
* @access The canvases are hidden; the logo's image is named by its label. In `loading` the scene
|
|
@@ -168,6 +177,7 @@ function HiveScene({ mode, column = "default", logo, picture, work, chrome, labe
|
|
|
168
177
|
const sceneRef = React.useRef(null);
|
|
169
178
|
const combRef = React.useRef(null);
|
|
170
179
|
const flowRef = React.useRef(null);
|
|
180
|
+
const picturesRef = React.useRef(null);
|
|
171
181
|
const orbRefs = React.useRef([]);
|
|
172
182
|
const holderRefs = React.useRef([]);
|
|
173
183
|
// The words' box, kept as state so the scene places the orbs again when it appears.
|
|
@@ -208,12 +218,13 @@ function HiveScene({ mode, column = "default", logo, picture, work, chrome, labe
|
|
|
208
218
|
let height = 0;
|
|
209
219
|
let context = null;
|
|
210
220
|
let seats = [];
|
|
221
|
+
let bounds = scene.getBoundingClientRect();
|
|
211
222
|
const place = () => {
|
|
212
223
|
width = scene.clientWidth;
|
|
213
224
|
height = scene.clientHeight;
|
|
214
225
|
const centre = { x: width / 2, y: height / 2 };
|
|
215
226
|
const radius = cellRadius(width, height) * (mode === "loading" ? 0.62 : 1);
|
|
216
|
-
|
|
227
|
+
bounds = scene.getBoundingClientRect();
|
|
217
228
|
const box = wordsColumn?.getBoundingClientRect();
|
|
218
229
|
const words = box?.width
|
|
219
230
|
? {
|
|
@@ -223,6 +234,7 @@ function HiveScene({ mode, column = "default", logo, picture, work, chrome, labe
|
|
|
223
234
|
bottom: box.bottom - bounds.top,
|
|
224
235
|
}
|
|
225
236
|
: null;
|
|
237
|
+
scene.style.setProperty("--hive-words-width", `${words ? words.right - words.left : 0}px`);
|
|
226
238
|
seats = still
|
|
227
239
|
? []
|
|
228
240
|
: AGENTS.map((agent, index) => clearOfWords(corner(index, centre, radius), agent.size, words, { width, height }));
|
|
@@ -236,7 +248,7 @@ function HiveScene({ mode, column = "default", logo, picture, work, chrome, labe
|
|
|
236
248
|
holder.style.left = `${seat.x}px`;
|
|
237
249
|
holder.style.top = `${seat.y}px`;
|
|
238
250
|
});
|
|
239
|
-
drawComb(comb, width, height);
|
|
251
|
+
drawComb(comb, width, height, words);
|
|
240
252
|
context = sizeCanvas(flow, width, height);
|
|
241
253
|
};
|
|
242
254
|
const observeLayout = (onLayout) => {
|
|
@@ -266,7 +278,16 @@ function HiveScene({ mode, column = "default", logo, picture, work, chrome, labe
|
|
|
266
278
|
const others = seats.filter((other) => other !== null && other !== seat);
|
|
267
279
|
const neighbour = (source + 1 + (Math.random() < 0.5 ? 0 : 4)) % AGENTS.length;
|
|
268
280
|
const next = seats[neighbour] ?? pick(others);
|
|
269
|
-
const
|
|
281
|
+
const pictures = Array.from(picturesRef.current?.children ?? [], (element) => {
|
|
282
|
+
const drawn = element.getBoundingClientRect();
|
|
283
|
+
return {
|
|
284
|
+
left: drawn.left - bounds.left,
|
|
285
|
+
top: drawn.top - bounds.top,
|
|
286
|
+
right: drawn.right - bounds.left,
|
|
287
|
+
bottom: drawn.bottom - bounds.top,
|
|
288
|
+
};
|
|
289
|
+
});
|
|
290
|
+
const people = workRef.current?.(pictures);
|
|
270
291
|
const sender = people ? pick(people.senders) : undefined;
|
|
271
292
|
const receiver = people ? pick(people.receivers) : undefined;
|
|
272
293
|
const roll = Math.random();
|
|
@@ -368,7 +389,7 @@ function HiveScene({ mode, column = "default", logo, picture, work, chrome, labe
|
|
|
368
389
|
reduced.removeEventListener("change", play);
|
|
369
390
|
};
|
|
370
391
|
}, [mode, still, wordsColumn]);
|
|
371
|
-
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
|
|
392
|
+
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 }), _jsx("div", { className: "nc-hive-pictures", ref: picturesRef, children: picture }), _jsx("canvas", { "aria-hidden": "true", className: "nc-hive-comb", ref: combRef }), _jsx("canvas", { "aria-hidden": "true", className: "nc-hive-flow", ref: flowRef }), still
|
|
372
393
|
? null
|
|
373
394
|
: AGENTS.map((agent, index) => (_jsx("div", { "aria-hidden": "true", className: "nc-hive-agent", "data-slot": "hive-agent", "data-size": agent.size, ref: (holder) => {
|
|
374
395
|
holderRefs.current[index] = holder;
|
|
@@ -10,6 +10,8 @@ export type ObjectPageEntry = {
|
|
|
10
10
|
title: string;
|
|
11
11
|
/** What the row counts or states, at its trailing edge before the chevron: a Badge or a count. */
|
|
12
12
|
summary?: ReactNode;
|
|
13
|
+
/** Opens with the page, for a link that names this row. */
|
|
14
|
+
defaultOpen?: boolean;
|
|
13
15
|
children: ReactNode;
|
|
14
16
|
};
|
|
15
17
|
export type ObjectPageLink = {
|
|
@@ -51,7 +53,7 @@ export type ObjectPageProps = {
|
|
|
51
53
|
* @family Compositions
|
|
52
54
|
* @when One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.
|
|
53
55
|
* @instead "Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.
|
|
54
|
-
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
|
|
56
|
+
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows; an entry marked `defaultOpen` opens with the page, for a link that names it. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
|
|
55
57
|
* @words "Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact's label is a noun ("Plan"), its value the figure; an entry's title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu's trigger reads "More for {name}".
|
|
56
58
|
* @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is a button with `aria-expanded` that controls its panel.
|
|
57
59
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-page.d.ts","sourceRoot":"","sources":["../../src/components/object-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,KAAK,gBAAgB,EAAqC,MAAM,gBAAgB,CAAC;AAE1F,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,EAAE,YAAY,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kHAAkH;IAClH,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,wFAAwF;IACxF,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;IACtD,qFAAqF;IACrF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,kFAAkF;IAClF,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IACtD,8FAA8F;IAC9F,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAC3C,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,4FAA4F;IAC5F,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,+HAA+H;IAC/H,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,eAAe,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"object-page.d.ts","sourceRoot":"","sources":["../../src/components/object-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,KAAK,gBAAgB,EAAqC,MAAM,gBAAgB,CAAC;AAE1F,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,EAAE,YAAY,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kHAAkH;IAClH,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,wFAAwF;IACxF,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;IACtD,qFAAqF;IACrF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,kFAAkF;IAClF,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IACtD,8FAA8F;IAC9F,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;IAC3C,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,4FAA4F;IAC5F,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,+HAA+H;IAC/H,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,eAAe,GAAG,YAAY,CAqGhC"}
|
|
@@ -12,12 +12,14 @@ import { PageActionsRow, PageCommandButton } from "./page-actions.js";
|
|
|
12
12
|
* @family Compositions
|
|
13
13
|
* @when One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.
|
|
14
14
|
* @instead "Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.
|
|
15
|
-
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
|
|
15
|
+
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows; an entry marked `defaultOpen` opens with the page, for a link that names it. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
|
|
16
16
|
* @words "Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact's label is a noun ("Plan"), its value the figure; an entry's title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu's trigger reads "More for {name}".
|
|
17
17
|
* @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is a button with `aria-expanded` that controls its panel.
|
|
18
18
|
*/
|
|
19
19
|
export function ObjectPage({ mark, name, headingProps, description, facts, actions, entries, footer, children, }) {
|
|
20
20
|
const company = mark.kind === "company";
|
|
21
21
|
const title = headingProps ? (_jsx("h1", { ...headingProps, className: cn("outline-none", headingProps.className), children: name })) : (name);
|
|
22
|
-
return (_jsxs("div", { className: "grid min-w-0 gap-6", "data-slot": "object-page", children: [_jsxs("div", { className: "grid min-w-0 gap-3", children: [_jsxs(Card, { className: "min-w-0", render: _jsx("div", { "data-slot": "object-card" }), size: "sm", children: [_jsxs(CardHeader, { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-3 border-b", children: [company ? (_jsxs("div", { className: cn("flex min-w-0 flex-1 items-center gap-4", actions?.menu && !actions.secondary && !actions.primary ? "basis-0" : "basis-64"), children: [_jsx(IdentityMark, { ...mark, size: 64 }), _jsxs("div", { className: "grid min-w-0 gap-1", children: [_jsx(CardTitle, { className: "min-w-0 break-words group-data-[size=sm]/card:text-heading-sm", children: title }), description ? _jsx(CardDescription, { children: description }) : null] })] })) : (_jsx(CardTitle, { className: "min-w-0 flex-1 basis-32 break-words", children: title })), actions ? _jsx(PageActionsRow, { ...actions }) : null] }), _jsxs(CardContent, { className: cn("grid min-w-0 gap-x-6 gap-y-5", !company && "md:grid-cols-[minmax(0,18.75rem)_minmax(0,1fr)]"), children: [!company ? (_jsx("div", { className: "flex h-32 min-w-0 items-center md:h-auto md:aspect-[16/10] justify-center rounded-sm border border-border bg-muted", "data-slot": "object-page-tile", children: _jsx(IdentityMark, { ...mark, size: 64 }) })) : null, _jsxs("div", { className: "grid min-w-0 content-start gap-4", children: [!company && description ? (_jsx("div", { className: "min-w-0 text-body-sm text-muted-foreground", children: description })) : null, _jsx("dl", { className: "grid min-w-0 grid-cols-2 gap-x-6 gap-y-4 lg:grid-cols-4", "data-slot": "object-page-facts", children: facts.map((fact) => (_jsxs("div", { className: "grid min-w-0 content-start gap-1", children: [_jsx("dt", { className: "text-label-sm text-muted-foreground", children: fact.label }), _jsx("dd", { className: "min-w-0 text-body-sm break-words text-foreground", children: fact.value })] }, fact.label))) })] })] }), footer ? (_jsx(FooterStrip, { hint: footer.hint, hintSlot: "object-page-hint", children: _jsx(PageCommandButton, { command: footer.link, variant: "outline" }) })) : null] }), entries && entries.length > 0 ? (_jsx(Card, { className: "min-w-0 py-0", render: _jsx("div", { "data-slot": "object-page-entries" }), size: "sm", children: _jsx(Accordion, { className: "[&>:last-child]:border-b-0",
|
|
22
|
+
return (_jsxs("div", { className: "grid min-w-0 gap-6", "data-slot": "object-page", children: [_jsxs("div", { className: "grid min-w-0 gap-3", children: [_jsxs(Card, { className: "min-w-0", render: _jsx("div", { "data-slot": "object-card" }), size: "sm", children: [_jsxs(CardHeader, { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-3 border-b", children: [company ? (_jsxs("div", { className: cn("flex min-w-0 flex-1 items-center gap-4", actions?.menu && !actions.secondary && !actions.primary ? "basis-0" : "basis-64"), children: [_jsx(IdentityMark, { ...mark, size: 64 }), _jsxs("div", { className: "grid min-w-0 gap-1", children: [_jsx(CardTitle, { className: "min-w-0 break-words group-data-[size=sm]/card:text-heading-sm", children: title }), description ? _jsx(CardDescription, { children: description }) : null] })] })) : (_jsx(CardTitle, { className: "min-w-0 flex-1 basis-32 break-words", children: title })), actions ? _jsx(PageActionsRow, { ...actions }) : null] }), _jsxs(CardContent, { className: cn("grid min-w-0 gap-x-6 gap-y-5", !company && "md:grid-cols-[minmax(0,18.75rem)_minmax(0,1fr)]"), children: [!company ? (_jsx("div", { className: "flex h-32 min-w-0 items-center md:h-auto md:aspect-[16/10] justify-center rounded-sm border border-border bg-muted", "data-slot": "object-page-tile", children: _jsx(IdentityMark, { ...mark, size: 64 }) })) : null, _jsxs("div", { className: "grid min-w-0 content-start gap-4", children: [!company && description ? (_jsx("div", { className: "min-w-0 text-body-sm text-muted-foreground", children: description })) : null, _jsx("dl", { className: "grid min-w-0 grid-cols-2 gap-x-6 gap-y-4 lg:grid-cols-4", "data-slot": "object-page-facts", children: facts.map((fact) => (_jsxs("div", { className: "grid min-w-0 content-start gap-1", children: [_jsx("dt", { className: "text-label-sm text-muted-foreground", children: fact.label }), _jsx("dd", { className: "min-w-0 text-body-sm break-words text-foreground", children: fact.value })] }, fact.label))) })] })] }), footer ? (_jsx(FooterStrip, { hint: footer.hint, hintSlot: "object-page-hint", children: _jsx(PageCommandButton, { command: footer.link, variant: "outline" }) })) : null] }), entries && entries.length > 0 ? (_jsx(Card, { className: "min-w-0 py-0", render: _jsx("div", { "data-slot": "object-page-entries" }), size: "sm", children: _jsx(Accordion, { className: "[&>:last-child]:border-b-0", defaultValue: entries
|
|
23
|
+
.filter((entry) => entry.defaultOpen)
|
|
24
|
+
.map((entry) => entry.title), multiple: true, size: "small", children: entries.map((entry) => (_jsxs(AccordionItem, { value: entry.title, children: [_jsxs(AccordionTrigger, { className: "justify-start gap-3 px-(--card-spacing) group-data-[size=small]/accordion:text-body-sm focus-visible:-outline-offset-2 [&>[data-slot=accordion-trigger-icon]]:order-first [&>[data-slot=accordion-trigger-icon]]:text-muted-foreground", children: [_jsx("span", { className: "min-w-0 flex-1", children: entry.title }), entry.summary] }), _jsx(AccordionContent, { className: "ps-[calc(var(--card-spacing)+1.75rem)] pe-(--card-spacing)", children: entry.children })] }, entry.title))) }) })) : null] }), children] }));
|
|
23
25
|
}
|
|
@@ -142,7 +142,7 @@ export const USAGE = [
|
|
|
142
142
|
summary: "One object's page: the object card with its name, commands, facts, rows that open and one link elsewhere, then its sections as cards.",
|
|
143
143
|
when: "One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.",
|
|
144
144
|
instead: '"Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.',
|
|
145
|
-
behaviour: "\"For a static key/value metadata block on a detail page, use `Description`.\" (https://vercel.com/geist/entity) \"The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`.\" (https://vercel.com/geist/entity) \"Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`).\" (https://vercel.com/geist/entity) \"Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`).\" (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.",
|
|
145
|
+
behaviour: "\"For a static key/value metadata block on a detail page, use `Description`.\" (https://vercel.com/geist/entity) \"The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`.\" (https://vercel.com/geist/entity) \"Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`).\" (https://vercel.com/geist/entity) \"Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`).\" (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (a secondary, then the primary as the filled button, then the three dots, in `PageActions`' order, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise; the primary is the one thing the object waits on its viewer for, such as approving a company that waits for approval, beside its alternative as the secondary, and an object with nothing waiting has none), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows; an entry marked `defaultOpen` opens with the page, for a link that names it. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.",
|
|
146
146
|
words: '"Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact\'s label is a noun ("Plan"), its value the figure; an entry\'s title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu\'s trigger reads "More for {name}".',
|
|
147
147
|
access: '"Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page\'s h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is a button with `aria-expanded` that controls its panel.',
|
|
148
148
|
},
|
|
@@ -1759,7 +1759,7 @@ export const USAGE = [
|
|
|
1759
1759
|
summary: "Alveare's entry scene: its picture, its logo and six Agent orbs around the words.",
|
|
1760
1760
|
when: "Alveare's entry screens, on its desktop and on Alveare Server: joining, loading, a failure.",
|
|
1761
1761
|
instead: "Nadia's entry screens are `EntryScene`. A product page never stands on a scene.",
|
|
1762
|
-
behaviour: "`join` puts the words in the hexagon's middle, `loading` draws the orbs in with no words, `still` shows no Agent and no work. Only the orbs and the particles move; reduced motion stops both. Black in every theme.",
|
|
1762
|
+
behaviour: "`join` puts the words in the hexagon's middle, `loading` draws the orbs in with no words, `still` shows no Agent and no work. Only the orbs and the particles move; reduced motion stops both. Black in every theme. The scene sets the width its words are drawn at on itself as `--hive-words-width`, so the app's picture keeps clear of them, and draws no honeycomb near them.",
|
|
1763
1763
|
words: "The words are the screen's own: a title, a line, one action. The logo's label names Alveare.",
|
|
1764
1764
|
access: 'The canvases are hidden; the logo\'s image is named by its label. In `loading` the scene is `role="status"` named by `label`; otherwise the words and their action are the reading.',
|
|
1765
1765
|
},
|
|
@@ -636,6 +636,12 @@
|
|
|
636
636
|
background: var(--nc-identity-ink);
|
|
637
637
|
color: var(--nc-ink);
|
|
638
638
|
color-scheme: dark;
|
|
639
|
+
--hive-column-width: min(20rem, 80vw);
|
|
640
|
+
--hive-words-width: var(--hive-column-width);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.nc-hive-pictures {
|
|
644
|
+
display: contents;
|
|
639
645
|
}
|
|
640
646
|
|
|
641
647
|
/*
|
|
@@ -718,7 +724,7 @@
|
|
|
718
724
|
display: grid;
|
|
719
725
|
justify-items: stretch;
|
|
720
726
|
gap: var(--nc-md);
|
|
721
|
-
width:
|
|
727
|
+
width: var(--hive-column-width);
|
|
722
728
|
text-align: center;
|
|
723
729
|
text-wrap-style: balance;
|
|
724
730
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nadicodeai/ui",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.152",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"@base-ui/react": "^1.9.0",
|
|
85
85
|
"@iconify-icons/logos": "^2.0.3",
|
|
86
86
|
"@iconify/react": "^6.0.2",
|
|
87
|
-
"@nadicodeai/design-system": "12.1.
|
|
87
|
+
"@nadicodeai/design-system": "12.1.152",
|
|
88
88
|
"@tanstack/react-table": "^9.3.1",
|
|
89
89
|
"@vgpu/wgsl": "0.6.0",
|
|
90
90
|
"class-variance-authority": "^0.7.1",
|