@nadicodeai/ui 12.1.52 → 12.1.53
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/LICENSES/VGPU-MIT.txt +21 -0
- package/NOTICE +12 -0
- package/dist/components/agent-card.d.ts.map +1 -1
- package/dist/components/agent-card.js +1 -1
- package/dist/components/agent-list-row.d.ts +28 -0
- package/dist/components/agent-list-row.d.ts.map +1 -0
- package/dist/components/agent-list-row.js +17 -0
- package/dist/components/approval-row.d.ts +21 -0
- package/dist/components/approval-row.d.ts.map +1 -0
- package/dist/components/approval-row.js +14 -0
- package/dist/components/channel-view.d.ts +89 -0
- package/dist/components/channel-view.d.ts.map +1 -0
- package/dist/components/channel-view.js +75 -0
- package/dist/components/company-card/approach.d.ts +22 -0
- package/dist/components/company-card/approach.d.ts.map +1 -0
- package/dist/components/company-card/approach.js +17 -0
- package/dist/components/company-card/engraving.d.ts +8 -0
- package/dist/components/company-card/engraving.d.ts.map +1 -0
- package/dist/components/company-card/engraving.js +56 -0
- package/dist/components/company-card/foil-colors.d.ts +4 -0
- package/dist/components/company-card/foil-colors.d.ts.map +1 -0
- package/dist/components/company-card/foil-colors.js +29 -0
- package/dist/components/company-card/renderer.d.ts +13 -0
- package/dist/components/company-card/renderer.d.ts.map +1 -0
- package/dist/components/company-card/renderer.js +138 -0
- package/dist/components/company-card/scene.d.ts +10 -0
- package/dist/components/company-card/scene.d.ts.map +1 -0
- package/dist/components/company-card/scene.js +25 -0
- package/dist/components/company-card/shader.d.ts +10 -0
- package/dist/components/company-card/shader.d.ts.map +1 -0
- package/dist/components/company-card/shader.js +165 -0
- package/dist/components/company-card/snapshot.d.ts +7 -0
- package/dist/components/company-card/snapshot.d.ts.map +1 -0
- package/dist/components/company-card/snapshot.js +37 -0
- package/dist/components/company-card.d.ts +31 -0
- package/dist/components/company-card.d.ts.map +1 -0
- package/dist/components/company-card.js +200 -0
- package/dist/components/desktop-shell.js +1 -1
- package/dist/components/entry-scene.d.ts +90 -0
- package/dist/components/entry-scene.d.ts.map +1 -0
- package/dist/components/entry-scene.js +41 -0
- package/dist/components/nadia-presence.d.ts +22 -0
- package/dist/components/nadia-presence.d.ts.map +1 -0
- package/dist/components/nadia-presence.js +45 -0
- package/dist/components/portal-sidebar-frame.d.ts +40 -0
- package/dist/components/portal-sidebar-frame.d.ts.map +1 -0
- package/dist/components/portal-sidebar-frame.js +14 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/styles/components.css +567 -0
- package/package.json +3 -2
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
4
|
+
import { BrandWordmark } from "./brand.js";
|
|
5
|
+
import { approach, SWEEP_MS, SWEEP_TURN } from "./company-card/approach.js";
|
|
6
|
+
import { CARD_HEIGHT, CARD_WIDTH, ENGRAVING } from "./company-card/engraving.js";
|
|
7
|
+
import { foilColors } from "./company-card/foil-colors.js";
|
|
8
|
+
const MAX_TILT_DEGREES = 9;
|
|
9
|
+
/**
|
|
10
|
+
* The three hues each edition's foil falls in, named as the tokens the stripes
|
|
11
|
+
* are painted with: a company's card takes the cool half, a Partner's the warm.
|
|
12
|
+
*/
|
|
13
|
+
const FOIL = {
|
|
14
|
+
company: ["var(--nc-identity-cobalto)", "var(--nc-identity-azzurro)", "var(--nc-identity-verde)"],
|
|
15
|
+
partner: ["var(--nc-identity-giallo)", "var(--nc-identity-arancio)", "var(--nc-identity-rosso)"],
|
|
16
|
+
};
|
|
17
|
+
const STRIPE = 34;
|
|
18
|
+
/** How much of the card must be on screen before it turns, when the caller waits for it. */
|
|
19
|
+
const IN_VIEW = 0.6;
|
|
20
|
+
function reason(error) {
|
|
21
|
+
return error instanceof Error ? error.message : String(error);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The company's nadicode card: what the person is making while they sign up,
|
|
25
|
+
* and what the website shows being issued. It carries every word it shows as a
|
|
26
|
+
* prop, fills in as the form is typed and turns to the pointer, so the foil in
|
|
27
|
+
* its engraving catches the light. The words are the caller's, so the card is
|
|
28
|
+
* hidden from assistive technology and holds nothing interactive.
|
|
29
|
+
*/
|
|
30
|
+
export function CompanyCard({ name, domain, edition, issued, labels, logo, sweepInView = false, }) {
|
|
31
|
+
// A CSS `url(#…)` reference cannot carry the punctuation React puts in an id.
|
|
32
|
+
const id = `card${useId().replace(/[^\w-]/g, "")}`;
|
|
33
|
+
const cardRef = useRef(null);
|
|
34
|
+
const lightRef = useRef(null);
|
|
35
|
+
const stripesRef = useRef(null);
|
|
36
|
+
const frame = useRef(0);
|
|
37
|
+
const canvasRef = useRef(null);
|
|
38
|
+
const [gpuFoil, setGpuFoil] = useState(false);
|
|
39
|
+
const sweepRef = useRef(() => { });
|
|
40
|
+
const foil = FOIL[edition];
|
|
41
|
+
// Nothing starts for a card the page hides (the plane below its breakpoint,
|
|
42
|
+
// the phone card beside a wide form): the foil wakes when the card is seen.
|
|
43
|
+
// A browser that cannot tell whether the card is seen shows it as seen.
|
|
44
|
+
const [seen, setSeen] = useState(() => typeof IntersectionObserver === "undefined");
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const card = cardRef.current;
|
|
47
|
+
if (!card || seen)
|
|
48
|
+
return;
|
|
49
|
+
const observer = new IntersectionObserver((entries) => {
|
|
50
|
+
if (entries.some((entry) => entry.isIntersecting))
|
|
51
|
+
setSeen(true);
|
|
52
|
+
}, { threshold: sweepInView ? IN_VIEW : 0 });
|
|
53
|
+
observer.observe(card);
|
|
54
|
+
return () => observer.disconnect();
|
|
55
|
+
}, [seen, sweepInView]);
|
|
56
|
+
// Where the browser has WebGPU, vgpu's holographic shader strikes the foil;
|
|
57
|
+
// elsewhere the SVG engraving below stands in for it.
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const canvas = canvasRef.current;
|
|
60
|
+
const card = cardRef.current;
|
|
61
|
+
if (!seen || !canvas || !card || !("gpu" in navigator))
|
|
62
|
+
return;
|
|
63
|
+
let renderer;
|
|
64
|
+
let cancelled = false;
|
|
65
|
+
import("./company-card/renderer").then(({ createRenderer }) => {
|
|
66
|
+
if (cancelled)
|
|
67
|
+
return;
|
|
68
|
+
const created = createRenderer(canvas, {
|
|
69
|
+
colors: foilColors(card, edition),
|
|
70
|
+
onTilt: (tiltX, tiltY) => {
|
|
71
|
+
card.style.setProperty("--tilt-x", `${tiltY.toFixed(4)}rad`);
|
|
72
|
+
card.style.setProperty("--tilt-y", `${tiltX.toFixed(4)}rad`);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
renderer = created;
|
|
76
|
+
created.ready.then(() => {
|
|
77
|
+
if (cancelled)
|
|
78
|
+
return;
|
|
79
|
+
setGpuFoil(true);
|
|
80
|
+
sweepRef.current = created.sweep;
|
|
81
|
+
// The first time the card appears, it turns once in the light.
|
|
82
|
+
created.sweep();
|
|
83
|
+
}, (error) => {
|
|
84
|
+
console.warn(`The card's WebGPU foil could not start; the SVG foil stands in: ${reason(error)}`);
|
|
85
|
+
if (!cancelled)
|
|
86
|
+
setGpuFoil(false);
|
|
87
|
+
});
|
|
88
|
+
}, (error) => {
|
|
89
|
+
console.warn(`The card's WebGPU foil could not load; the SVG foil stands in: ${reason(error)}`);
|
|
90
|
+
setGpuFoil(false);
|
|
91
|
+
});
|
|
92
|
+
return () => {
|
|
93
|
+
cancelled = true;
|
|
94
|
+
sweepRef.current = () => { };
|
|
95
|
+
renderer?.dispose();
|
|
96
|
+
setGpuFoil(false);
|
|
97
|
+
};
|
|
98
|
+
}, [edition, seen]);
|
|
99
|
+
// The SVG foil behaves as the shader does: it turns once in the light when it
|
|
100
|
+
// appears and when it is issued, and wakes as the pointer comes within one
|
|
101
|
+
// card width, easing its turn by how near the pointer is.
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
const card = cardRef.current;
|
|
104
|
+
if (!seen || gpuFoil || !card)
|
|
105
|
+
return;
|
|
106
|
+
const motion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
107
|
+
let sweepFrame = 0;
|
|
108
|
+
let sweeping = false;
|
|
109
|
+
const light = (x, y) => {
|
|
110
|
+
lightRef.current?.setAttribute("cx", x.toFixed(3));
|
|
111
|
+
lightRef.current?.setAttribute("cy", y.toFixed(3));
|
|
112
|
+
stripesRef.current?.setAttribute("patternTransform", `rotate(28) translate(${((x + y) * STRIPE * foil.length * 0.9).toFixed(1)} 0)`);
|
|
113
|
+
};
|
|
114
|
+
const show = (x, y, strength, turnX, turnY) => {
|
|
115
|
+
card.dataset.tracking = "true";
|
|
116
|
+
const still = motion.matches;
|
|
117
|
+
card.style.setProperty("--tilt-x", `${(still ? 0 : turnX).toFixed(2)}deg`);
|
|
118
|
+
card.style.setProperty("--tilt-y", `${(still ? 0 : turnY).toFixed(2)}deg`);
|
|
119
|
+
card.style.setProperty("--light-x", `${(x * 100).toFixed(1)}%`);
|
|
120
|
+
card.style.setProperty("--light-y", `${(y * 100).toFixed(1)}%`);
|
|
121
|
+
card.style.setProperty("--foil", strength.toFixed(3));
|
|
122
|
+
light(x, y);
|
|
123
|
+
};
|
|
124
|
+
const rest = () => {
|
|
125
|
+
delete card.dataset.tracking;
|
|
126
|
+
for (const property of ["--tilt-x", "--tilt-y", "--light-x", "--light-y", "--foil"]) {
|
|
127
|
+
card.style.removeProperty(property);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const stopSweep = () => {
|
|
131
|
+
sweeping = false;
|
|
132
|
+
cancelAnimationFrame(sweepFrame);
|
|
133
|
+
};
|
|
134
|
+
const sweep = () => {
|
|
135
|
+
if (motion.matches)
|
|
136
|
+
return;
|
|
137
|
+
stopSweep();
|
|
138
|
+
sweeping = true;
|
|
139
|
+
const start = performance.now();
|
|
140
|
+
const step = (now) => {
|
|
141
|
+
const progress = Math.min(1, (now - start) / SWEEP_MS);
|
|
142
|
+
const along = progress * progress * (3 - 2 * progress);
|
|
143
|
+
const rise = Math.sin(Math.PI * progress);
|
|
144
|
+
show(-0.05 + along * 1.1, 0.22 + along * 0.56, rise ** 0.6 * 0.95, rise * MAX_TILT_DEGREES * 0.3, -Math.sin(2 * Math.PI * along) * ((SWEEP_TURN * 180) / Math.PI));
|
|
145
|
+
if (progress < 1)
|
|
146
|
+
sweepFrame = requestAnimationFrame(step);
|
|
147
|
+
else {
|
|
148
|
+
sweeping = false;
|
|
149
|
+
rest();
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
sweepFrame = requestAnimationFrame(step);
|
|
153
|
+
};
|
|
154
|
+
const move = (event) => {
|
|
155
|
+
if (!event.isPrimary)
|
|
156
|
+
return;
|
|
157
|
+
const near = approach(card.getBoundingClientRect(), event.clientX, event.clientY);
|
|
158
|
+
if (near.hover > 0)
|
|
159
|
+
stopSweep();
|
|
160
|
+
if (sweeping)
|
|
161
|
+
return;
|
|
162
|
+
cancelAnimationFrame(frame.current);
|
|
163
|
+
frame.current = requestAnimationFrame(() => {
|
|
164
|
+
if (near.hover === 0)
|
|
165
|
+
return rest();
|
|
166
|
+
const x = Math.min(1, Math.max(0, (near.x + 1) / 2));
|
|
167
|
+
const y = Math.min(1, Math.max(0, (near.y + 1) / 2));
|
|
168
|
+
show(x, y, near.hover, (0.5 - y) * 2 * MAX_TILT_DEGREES * near.hover, (x - 0.5) * 2 * MAX_TILT_DEGREES * near.hover);
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
const leave = () => {
|
|
172
|
+
if (!sweeping)
|
|
173
|
+
rest();
|
|
174
|
+
};
|
|
175
|
+
window.addEventListener("pointermove", move, { passive: true });
|
|
176
|
+
document.documentElement.addEventListener("pointerleave", leave);
|
|
177
|
+
sweepRef.current = sweep;
|
|
178
|
+
sweep();
|
|
179
|
+
return () => {
|
|
180
|
+
window.removeEventListener("pointermove", move);
|
|
181
|
+
document.documentElement.removeEventListener("pointerleave", leave);
|
|
182
|
+
stopSweep();
|
|
183
|
+
cancelAnimationFrame(frame.current);
|
|
184
|
+
sweepRef.current = () => { };
|
|
185
|
+
rest();
|
|
186
|
+
};
|
|
187
|
+
}, [seen, gpuFoil, foil]);
|
|
188
|
+
// Issuing the card turns it in the light once more.
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
if (issued)
|
|
191
|
+
sweepRef.current();
|
|
192
|
+
}, [issued]);
|
|
193
|
+
const engraving = `${id}-engraving`;
|
|
194
|
+
const stripes = `${id}-stripes`;
|
|
195
|
+
const lit = `${id}-light`;
|
|
196
|
+
const mask = `${id}-mask`;
|
|
197
|
+
return (_jsx("div", { "aria-hidden": "true", className: "nc-company-card-scene", "data-slot": "company-card", children: _jsxs("div", { className: "dark nc-elevation-floating nc-company-card", "data-edition": edition, "data-foil": gpuFoil ? "gpu" : "svg", "data-issued": issued, ref: cardRef, children: [_jsx("canvas", { className: "nc-company-card-gpu", ref: canvasRef }), _jsxs("svg", { className: "nc-company-card-engraving", preserveAspectRatio: "none", viewBox: `0 0 ${CARD_WIDTH} ${CARD_HEIGHT}`, children: [_jsxs("defs", { children: [_jsx("path", { d: ENGRAVING.waves, fill: "none", id: `${engraving}-waves`, strokeWidth: "1.1" }), _jsx("path", { d: ENGRAVING.rosette, fill: "none", id: `${engraving}-rosette`, strokeWidth: "1.3" }), _jsx("pattern", { height: CARD_HEIGHT, id: stripes, patternTransform: "rotate(28)", patternUnits: "userSpaceOnUse", ref: stripesRef, width: STRIPE * foil.length, children: foil.map((hue, index) => (_jsx("rect", { fill: hue, height: CARD_HEIGHT, width: STRIPE, x: index * STRIPE }, hue))) }), _jsxs("radialGradient", { cx: "0.3", cy: "0.25", id: lit, r: "0.55", ref: lightRef, children: [_jsx("stop", { offset: "0", stopColor: "currentColor" }), _jsx("stop", { offset: "0.35", stopColor: "currentColor", stopOpacity: "0.7" }), _jsx("stop", { offset: "1", stopColor: "currentColor", stopOpacity: "0" })] }), _jsx("mask", { id: mask, children: _jsx("rect", { fill: `url(#${lit})`, height: CARD_HEIGHT, width: CARD_WIDTH }) })] }), _jsxs("g", { className: "nc-company-card-lines", stroke: "currentColor", children: [_jsx("use", { className: "nc-company-card-waves", href: `#${engraving}-waves` }), _jsx("use", { href: `#${engraving}-rosette` })] }), _jsxs("g", { className: "nc-company-card-foil", mask: `url(#${mask})`, stroke: `url(#${stripes})`, children: [_jsx("use", { href: `#${engraving}-waves` }), _jsx("use", { href: `#${engraving}-rosette` })] })] }), _jsx("div", { className: "nc-company-card-glare" }), _jsxs("div", { className: "nc-company-card-face", children: [_jsxs("div", { className: "nc-company-card-top", children: [_jsxs("div", { className: "nc-company-card-marks", children: [_jsx(BrandWordmark, { alt: "", className: "h-[5.6cqi] w-auto", "data-card-mark": "" }), logo ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "nc-company-card-rule" }), _jsx("img", { alt: "", className: "nc-company-card-logo", "data-card-logo": "", decoding: "async", loading: "lazy", src: logo })] })) : null] }), _jsx("span", { className: "nc-company-card-edition", "data-card-text": "", children: labels.edition })] }), _jsxs("div", { className: "nc-company-card-bottom", children: [_jsxs("div", { className: "nc-company-card-holder", children: [_jsx("span", { className: name ? "nc-company-card-name" : "nc-company-card-name nc-company-card-placeholder", "data-card-text": "", children: name || labels.namePlaceholder }), _jsx("span", { className: domain
|
|
198
|
+
? "nc-company-card-domain"
|
|
199
|
+
: "nc-company-card-domain nc-company-card-placeholder", "data-card-text": "", children: domain || labels.domainPlaceholder })] }), _jsx("span", { className: "nc-company-card-since", "data-card-text": "", children: labels.since })] })] })] }) }));
|
|
200
|
+
}
|
|
@@ -3,6 +3,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { cn } from "../lib/utils.js";
|
|
4
4
|
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "./resizable.js";
|
|
5
5
|
function DesktopAppShell({ title, titlebar, titlebarActions, activityRail, inspectorRail, secondaryPane, statusbar, children, activityRailLabel = "Activity", primaryPaneLabel = "Primary workspace", secondaryPaneLabel = "Secondary workspace", inspectorRailLabel = "Inspector", primaryPaneSize = secondaryPane || inspectorRail ? 58 : 100, secondaryPaneSize = inspectorRail ? 24 : 36, inspectorPaneSize = 18, className, titlebarClassName, bodyClassName, primaryPaneClassName, secondaryPaneClassName, inspectorRailClassName, statusbarClassName, ...props }) {
|
|
6
|
-
return (_jsxs("section", { "data-slot": "desktop-app-shell", className: cn("flex h-svh min-h-0 flex-col overflow-hidden border bg-background text-foreground", className), ...props, children: [_jsxs("header", { "data-slot": "desktop-app-titlebar", className: cn("flex h-11 shrink-0 items-center justify-between gap-3 border-b bg-background px-3", titlebarClassName), children: [titlebar ?? (_jsx("div", { "data-slot": "desktop-app-titlebar-content", className: "flex min-w-0 flex-1 items-center gap-2", children: title && _jsx("
|
|
6
|
+
return (_jsxs("section", { "data-slot": "desktop-app-shell", className: cn("flex h-svh min-h-0 flex-col overflow-hidden border bg-background text-foreground", className), ...props, children: [_jsxs("header", { "data-slot": "desktop-app-titlebar", className: cn("flex h-11 shrink-0 items-center justify-between gap-3 border-b bg-background px-3", titlebarClassName), children: [titlebar ?? (_jsx("div", { "data-slot": "desktop-app-titlebar-content", className: "flex min-w-0 flex-1 items-center gap-2", children: title && _jsx("p", { className: "m-0 truncate text-sm font-medium", children: title }) })), titlebarActions && (_jsx("div", { "data-slot": "desktop-app-titlebar-actions", className: "flex shrink-0 items-center gap-2", children: titlebarActions }))] }), _jsxs("div", { "data-slot": "desktop-app-body", className: cn("flex min-h-0 flex-1", bodyClassName), children: [activityRail && (_jsx("nav", { "data-slot": "desktop-app-activity-rail", "aria-label": activityRailLabel, className: "flex w-14 shrink-0 flex-col items-center gap-2 border-r bg-sidebar p-2 text-sidebar-foreground", children: activityRail })), _jsx("div", { "data-slot": "desktop-app-panes", className: "min-w-0 flex-1", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", className: "min-w-0 flex-1", children: [_jsx(ResizablePanel, { defaultSize: primaryPaneSize, minSize: 30, children: _jsx("section", { "data-slot": "desktop-app-primary-pane", "aria-label": primaryPaneLabel, className: cn("h-full min-w-0 overflow-auto bg-background", primaryPaneClassName), children: children }) }), secondaryPane && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: secondaryPaneSize, minSize: 18, children: _jsx("section", { "data-slot": "desktop-app-secondary-pane", "aria-label": secondaryPaneLabel, className: cn("h-full min-w-0 overflow-auto bg-background", secondaryPaneClassName), children: secondaryPane }) })] })), inspectorRail && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: inspectorPaneSize, minSize: 16, maxSize: 36, children: _jsx("aside", { "data-slot": "desktop-app-inspector-rail", "aria-label": inspectorRailLabel, className: cn("h-full min-w-0 overflow-auto bg-background", inspectorRailClassName), children: inspectorRail }) })] }))] }) })] }), statusbar && (_jsx("footer", { "data-slot": "desktop-app-statusbar", className: cn("flex min-h-8 shrink-0 items-center justify-between gap-3 border-t bg-background px-3 text-xs text-muted-foreground", statusbarClassName), children: statusbar }))] }));
|
|
7
7
|
}
|
|
8
8
|
export { DesktopAppShell };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Nadia's entry screen, contained.
|
|
4
|
+
*
|
|
5
|
+
* The installer and the desktop paint the same screen: the approved picture of
|
|
6
|
+
* the surface behind, the nadicode wordmark still at the upper left, Nadia's
|
|
7
|
+
* ribbon and her words centred as one group. In the products it fills the
|
|
8
|
+
* window; here it is a box of the window's own shape, so the screen can stand
|
|
9
|
+
* on a page beside other things.
|
|
10
|
+
*
|
|
11
|
+
* Nothing here holds state or decides anything. Which view is open, what the
|
|
12
|
+
* words are and when the screen ends belong to whoever mounts it.
|
|
13
|
+
*
|
|
14
|
+
* The screen is black in every theme, so it scopes `dark` and reads the dark
|
|
15
|
+
* ladder directly rather than branching on the host's mode.
|
|
16
|
+
*/
|
|
17
|
+
export type EntryStageMark = "done" | "current" | "pending";
|
|
18
|
+
export type EntrySceneProps = {
|
|
19
|
+
/**
|
|
20
|
+
* The window's shape. The desktop opens at 1220x800 and the installer at
|
|
21
|
+
* 880x620, so each passes its own.
|
|
22
|
+
*/
|
|
23
|
+
aspectRatio?: string;
|
|
24
|
+
/** The room the screen keeps once the shape would leave it too little. */
|
|
25
|
+
minHeight?: string;
|
|
26
|
+
/** The approved picture of this surface: one image serves every view. */
|
|
27
|
+
picture?: ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* The lowest visible row of that picture, of its 941, so the figure's feet
|
|
30
|
+
* stand on the floor of the window. 906 for the sign-in, 876 for the
|
|
31
|
+
* installer.
|
|
32
|
+
*/
|
|
33
|
+
pictureFeet?: number;
|
|
34
|
+
/** The nadicode wordmark, still at the upper left. */
|
|
35
|
+
wordmark?: ReactNode;
|
|
36
|
+
/** The screen's real heading. It names the surface and is never seen. */
|
|
37
|
+
title?: string;
|
|
38
|
+
/** Nadia herself, centred: `NadiaPresence`. */
|
|
39
|
+
presence?: ReactNode;
|
|
40
|
+
/** Which view is open. A failure quiets the picture; it is never removed. */
|
|
41
|
+
view?: string;
|
|
42
|
+
className?: string;
|
|
43
|
+
/** The message, the actions, the progress line and the stage list. */
|
|
44
|
+
children?: ReactNode;
|
|
45
|
+
};
|
|
46
|
+
export declare function EntryScene({ aspectRatio, minHeight, picture, pictureFeet, wordmark, title, presence, view, className, children, }: EntrySceneProps): import("react").JSX.Element;
|
|
47
|
+
/**
|
|
48
|
+
* What the screen is doing, said plainly. `lines` reserves the room a longer
|
|
49
|
+
* translation needs, so nothing below it moves between stages.
|
|
50
|
+
*/
|
|
51
|
+
export declare function EntryMessage({ lines, live, className, children, }: {
|
|
52
|
+
lines?: number;
|
|
53
|
+
/** True while the line reports work in progress. */
|
|
54
|
+
live?: boolean;
|
|
55
|
+
className?: string;
|
|
56
|
+
children: ReactNode;
|
|
57
|
+
}): import("react").JSX.Element;
|
|
58
|
+
export declare function EntryActions({ className, children }: {
|
|
59
|
+
className?: string;
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
}): import("react").JSX.Element;
|
|
62
|
+
/**
|
|
63
|
+
* The screen's own control. It is not the product's `Button`: an entry screen
|
|
64
|
+
* loads the token layer and nothing else, so it paints from the dark action
|
|
65
|
+
* role directly. `pressed` holds the pressed appearance, for a screen driven
|
|
66
|
+
* by something other than a pointer.
|
|
67
|
+
*/
|
|
68
|
+
export declare function EntryAction({ variant, pressed, className, children, ...props }: ComponentProps<"button"> & {
|
|
69
|
+
variant?: "primary" | "secondary";
|
|
70
|
+
pressed?: boolean;
|
|
71
|
+
}): import("react").JSX.Element;
|
|
72
|
+
/**
|
|
73
|
+
* Measured work: a 2 px line with the count written under it. It is
|
|
74
|
+
* decorative, because Nadia's own hidden progress bar already carries the
|
|
75
|
+
* value and her ribbon above already says the work is hers.
|
|
76
|
+
*/
|
|
77
|
+
export declare function EntryProgress({ fraction, className }: {
|
|
78
|
+
fraction: number;
|
|
79
|
+
className?: string;
|
|
80
|
+
}): import("react").JSX.Element;
|
|
81
|
+
/** The stages of a long install, each done, current or still to come. */
|
|
82
|
+
export declare function EntryStageList({ stages, className, }: {
|
|
83
|
+
stages: ReadonlyArray<{
|
|
84
|
+
id: string;
|
|
85
|
+
label: string;
|
|
86
|
+
mark: EntryStageMark;
|
|
87
|
+
}>;
|
|
88
|
+
className?: string;
|
|
89
|
+
}): import("react").JSX.Element;
|
|
90
|
+
//# sourceMappingURL=entry-scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-scene.d.ts","sourceRoot":"","sources":["../../src/components/entry-scene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EACzB,WAA0B,EAC1B,SAAS,EACT,OAAO,EACP,WAAiB,EACjB,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,EAAE,eAAe,+BAsBjB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAY,EACZ,SAAS,EACT,QAAQ,GACT,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAUA;AAED,wBAAgB,YAAY,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAEhG;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAmB,EACnB,OAAO,EACP,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG;IAC5B,OAAO,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,+BAYA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAW9F;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,SAAS,GACV,EAAE;IACD,MAAM,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAeA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
export function EntryScene({ aspectRatio = "1220 / 800", minHeight, picture, pictureFeet = 906, wordmark, title, presence, view, className, children, }) {
|
|
4
|
+
return (_jsx("div", { "data-slot": "entry-scene", className: cn("nc-entry-scene", className), style: {
|
|
5
|
+
aspectRatio,
|
|
6
|
+
minHeight,
|
|
7
|
+
"--entry-picture-feet": pictureFeet,
|
|
8
|
+
}, children: _jsxs("div", { className: "dark nc-entry-room", "data-view": view, children: [picture ? _jsx("div", { className: "nc-entry-picture", children: picture }) : null, wordmark ? _jsx("header", { className: "nc-entry-header", children: wordmark }) : null, title ? _jsx("h1", { className: "nc-entry-sr", children: title }) : null, presence ? _jsx("div", { className: "nc-entry-figure", children: presence }) : null, _jsx("div", { className: "nc-entry-body", children: children })] }) }));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* What the screen is doing, said plainly. `lines` reserves the room a longer
|
|
12
|
+
* translation needs, so nothing below it moves between stages.
|
|
13
|
+
*/
|
|
14
|
+
export function EntryMessage({ lines, live = false, className, children, }) {
|
|
15
|
+
return (_jsx("p", { className: cn("nc-entry-message", className), role: live ? "status" : undefined, style: lines ? { "--entry-message-lines": lines } : undefined, children: children }));
|
|
16
|
+
}
|
|
17
|
+
export function EntryActions({ className, children }) {
|
|
18
|
+
return _jsx("div", { className: cn("nc-entry-actions", className), children: children });
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The screen's own control. It is not the product's `Button`: an entry screen
|
|
22
|
+
* loads the token layer and nothing else, so it paints from the dark action
|
|
23
|
+
* role directly. `pressed` holds the pressed appearance, for a screen driven
|
|
24
|
+
* by something other than a pointer.
|
|
25
|
+
*/
|
|
26
|
+
export function EntryAction({ variant = "primary", pressed, className, children, ...props }) {
|
|
27
|
+
return (_jsx("button", { type: "button", "data-variant": variant, "data-pressed": pressed ? "" : undefined, className: cn("nc-entry-action", className), ...props, children: children }));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Measured work: a 2 px line with the count written under it. It is
|
|
31
|
+
* decorative, because Nadia's own hidden progress bar already carries the
|
|
32
|
+
* value and her ribbon above already says the work is hers.
|
|
33
|
+
*/
|
|
34
|
+
export function EntryProgress({ fraction, className }) {
|
|
35
|
+
const percent = Math.min(100, Math.max(0, Math.round(fraction * 100)));
|
|
36
|
+
return (_jsxs("div", { "aria-hidden": "true", className: cn("nc-entry-progress", className), children: [_jsx("div", { className: "nc-entry-progress-track", children: _jsx("div", { className: "nc-entry-progress-value", style: { width: `${percent}%` } }) }), _jsxs("span", { className: "nc-entry-progress-count", children: [percent, "%"] })] }));
|
|
37
|
+
}
|
|
38
|
+
/** The stages of a long install, each done, current or still to come. */
|
|
39
|
+
export function EntryStageList({ stages, className, }) {
|
|
40
|
+
return (_jsx("ol", { className: cn("nc-entry-stages", className), children: stages.map((stage) => (_jsxs("li", { "aria-current": stage.mark === "current" ? "step" : undefined, "data-mark": stage.mark, children: [_jsx("span", { "aria-hidden": "true", className: "nc-entry-mark" }), stage.label] }, stage.id))) }));
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type PresenceState = "arriving" | "connecting" | "waiting" | "present" | "ready" | "error";
|
|
2
|
+
export type NadiaPresenceProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
/** The accessible name of the arrival, read by the hidden progress bar. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** 0 while she is behind the field, 1 when she stands clear. */
|
|
7
|
+
reveal: number;
|
|
8
|
+
state: PresenceState;
|
|
9
|
+
/** Bump to play `ready`'s celebration again, when a loop finishes twice. */
|
|
10
|
+
motionKey?: number;
|
|
11
|
+
};
|
|
12
|
+
/** The arrival curve: a trace at the start, not a ribbon already half-built. */
|
|
13
|
+
export declare function arrivalOpacity(reveal: number): number;
|
|
14
|
+
/**
|
|
15
|
+
* Nadia at an entry screen.
|
|
16
|
+
*
|
|
17
|
+
* `reveal` drives one opacity, so the value a Customer sees is the value
|
|
18
|
+
* assistive technology is told. The ribbon itself carries the celebration at
|
|
19
|
+
* `state="ready"`, so the screen spends no colour of its own on the moment.
|
|
20
|
+
*/
|
|
21
|
+
export declare function NadiaPresence({ className, label, reveal, state, motionKey, }: NadiaPresenceProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=nadia-presence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nadia-presence.d.ts","sourceRoot":"","sources":["../../src/components/nadia-presence.tsx"],"names":[],"mappings":"AAsBA,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAYlG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,KAAK,EACL,MAAM,EACN,KAAK,EACL,SAAa,GACd,EAAE,kBAAkB,+BAgCpB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AgentOrb } from "./agent-orb.js";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
/*
|
|
6
|
+
* Nadia's presence: her striped ribbon, arriving through the picture behind
|
|
7
|
+
* her. No medallion, no ring, no bar, and no second orb beside her. She is the
|
|
8
|
+
* one thing on an entry screen that moves, because the work is hers.
|
|
9
|
+
*
|
|
10
|
+
* The ribbon is the shared `AgentOrb`, the same Nadia the Agents list and the
|
|
11
|
+
* Portal draw, so an entry screen carries no picture of her. Every screen
|
|
12
|
+
* passes her real state, so a person reading it sees whether she is working,
|
|
13
|
+
* waiting on them, finished or stopped.
|
|
14
|
+
*
|
|
15
|
+
* Her laid-out size is `--entry-presence-size`, which `EntryScene` sets from
|
|
16
|
+
* the room it has; 160 px where nothing sets it.
|
|
17
|
+
*/
|
|
18
|
+
const ARRIVAL_FLOOR = 0.025;
|
|
19
|
+
const ARRIVAL_CURVE = 1.25;
|
|
20
|
+
const PRESENCE_SIZE = 160;
|
|
21
|
+
/** Each presence state in the orb's own motion vocabulary. */
|
|
22
|
+
const ORB_STATE = {
|
|
23
|
+
arriving: "working",
|
|
24
|
+
connecting: "working",
|
|
25
|
+
waiting: "waiting",
|
|
26
|
+
present: "idle",
|
|
27
|
+
ready: "done",
|
|
28
|
+
error: "blocked",
|
|
29
|
+
};
|
|
30
|
+
const clampUnit = (value) => Math.min(Math.max(value, 0), 1);
|
|
31
|
+
/** The arrival curve: a trace at the start, not a ribbon already half-built. */
|
|
32
|
+
export function arrivalOpacity(reveal) {
|
|
33
|
+
return ARRIVAL_FLOOR + (1 - ARRIVAL_FLOOR) * clampUnit(reveal) ** ARRIVAL_CURVE;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Nadia at an entry screen.
|
|
37
|
+
*
|
|
38
|
+
* `reveal` drives one opacity, so the value a Customer sees is the value
|
|
39
|
+
* assistive technology is told. The ribbon itself carries the celebration at
|
|
40
|
+
* `state="ready"`, so the screen spends no colour of its own on the moment.
|
|
41
|
+
*/
|
|
42
|
+
export function NadiaPresence({ className, label, reveal, state, motionKey = 0, }) {
|
|
43
|
+
const value = clampUnit(reveal);
|
|
44
|
+
return (_jsxs("div", { "data-slot": "nadia-presence", className: cn("nc-entry-presence", className), "data-state": state, children: [_jsx("div", { "aria-hidden": "true", className: "nc-entry-presence-figure", style: { opacity: state === "arriving" ? arrivalOpacity(value) : 1 }, children: _jsx(AgentOrb, { decorative: true, form: "nadia", size: PRESENCE_SIZE, state: ORB_STATE[state], motionKey: motionKey }) }), _jsx("div", { "aria-label": label, "aria-valuemax": 100, "aria-valuemin": 0, "aria-valuenow": Math.floor(value * 100), className: "nc-entry-sr", role: "progressbar" })] }));
|
|
45
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type AccountIdentity } from "./account-menu.js";
|
|
3
|
+
/**
|
|
4
|
+
* The Portal's navigation frame, without the Portal's routing: the wordmark and
|
|
5
|
+
* the section name over the collapse control, the Find control with its
|
|
6
|
+
* shortcut, the labelled nav bands, the band that leads out of the Portal, and
|
|
7
|
+
* the account at the foot. Its regions are separated by the 1 px guide over the
|
|
8
|
+
* line colour, as the Portal's own shell separates them, so a sidebar region
|
|
9
|
+
* takes no border of its own.
|
|
10
|
+
*
|
|
11
|
+
* The frame carries geometry and brand imagery only. Every word, icon and
|
|
12
|
+
* active marking arrives as a prop, so the Portal can pass its nav model and
|
|
13
|
+
* the website can pass a sample of it.
|
|
14
|
+
*/
|
|
15
|
+
export type PortalSidebarItem = {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
/** The section's icon, at the size the sidebar gives a nav icon. */
|
|
19
|
+
icon?: ReactNode;
|
|
20
|
+
current?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type PortalSidebarBand = {
|
|
23
|
+
id: string;
|
|
24
|
+
/** The band's heading, shown when the role has more than one band. */
|
|
25
|
+
label?: string;
|
|
26
|
+
items: PortalSidebarItem[];
|
|
27
|
+
};
|
|
28
|
+
export declare function PortalSidebarFrame({ account, bands, className, findLabel, footerItem, subtitle, toggleLabel, }: {
|
|
29
|
+
account: AccountIdentity;
|
|
30
|
+
bands: PortalSidebarBand[];
|
|
31
|
+
className?: string;
|
|
32
|
+
/** The Find control's own word, beside ⌘K. */
|
|
33
|
+
findLabel: string;
|
|
34
|
+
/** The band under the navigation that leads out of the Portal, such as Get Nadia. */
|
|
35
|
+
footerItem?: PortalSidebarItem;
|
|
36
|
+
/** Under the wordmark: which product this navigation belongs to. */
|
|
37
|
+
subtitle: string;
|
|
38
|
+
toggleLabel: string;
|
|
39
|
+
}): import("react").JSX.Element;
|
|
40
|
+
//# sourceMappingURL=portal-sidebar-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal-sidebar-frame.d.ts","sourceRoot":"","sources":["../../src/components/portal-sidebar-frame.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAkBtF;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B,CAAC;AAiBF,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,KAAK,EACL,SAAS,EACT,SAAS,EACT,UAAU,EACV,QAAQ,EACR,WAAW,GACZ,EAAE;IACD,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,+BAwEA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronsUpDown, Search } from "lucide-react";
|
|
4
|
+
import { AccountMenuIdentity } from "./account-menu.js";
|
|
5
|
+
import { BrandWordmark } from "./brand.js";
|
|
6
|
+
import { Kbd, KbdGroup } from "./kbd.js";
|
|
7
|
+
import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarTrigger, } from "./sidebar.js";
|
|
8
|
+
import { cn } from "../lib/utils.js";
|
|
9
|
+
function ItemRow({ item, variant }) {
|
|
10
|
+
return (_jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { isActive: item.current, tooltip: item.label, ...(variant ? { variant } : {}), children: [item.icon, _jsx("span", { className: "truncate", children: item.label })] }) }));
|
|
11
|
+
}
|
|
12
|
+
export function PortalSidebarFrame({ account, bands, className, findLabel, footerItem, subtitle, toggleLabel, }) {
|
|
13
|
+
return (_jsx(Sidebar, { collapsible: "none", className: cn("h-auto shrink-0", className), children: _jsxs("div", { className: "grid min-h-0 flex-1 grid-rows-[auto_minmax(0,1fr)_auto_auto] bg-border *:min-w-0", children: [_jsxs("div", { className: "grid grid-rows-[3.5rem_auto] gap-px bg-border *:bg-sidebar", children: [_jsxs(SidebarHeader, { className: "h-full flex-row items-center justify-between gap-1 px-3 py-0", children: [_jsxs("div", { className: "grid min-w-0 flex-1 gap-0", children: [_jsx(BrandWordmark, { alt: "", className: "h-5 w-28 max-w-full" }), _jsx("span", { className: "truncate text-xs text-muted-foreground", children: subtitle })] }), _jsx(SidebarTrigger, { "aria-label": toggleLabel, className: "shrink-0" })] }), _jsx("div", { className: "p-2", children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { variant: "outline", children: [_jsx(Search, { "aria-hidden": "true", className: "text-muted-foreground" }), _jsx("span", { className: "min-w-0 flex-1 truncate text-left text-muted-foreground", children: findLabel }), _jsxs(KbdGroup, { className: "ml-auto", children: [_jsx(Kbd, { children: "\u2318" }), _jsx(Kbd, { children: "K" })] })] }) }) }) })] }), _jsx(SidebarContent, { className: "bg-sidebar", children: bands.map((band) => (_jsxs(SidebarGroup, { children: [band.label ? (_jsx(SidebarGroupLabel, { render: _jsx("h2", {}), children: band.label })) : null, _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: band.items.map((item) => (_jsx(ItemRow, { item: item }, item.id))) }) })] }, band.id))) }), footerItem ? (_jsx(SidebarGroup, { className: "border-t bg-sidebar", children: _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: _jsx(ItemRow, { item: footerItem, variant: "outline" }) }) }) })) : null, _jsx(SidebarFooter, { className: "border-t bg-sidebar", children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { size: "lg", children: [_jsx(AccountMenuIdentity, { className: "flex-1", identity: account }), _jsx(ChevronsUpDown, { "aria-hidden": "true", className: "ml-auto size-4 text-muted-foreground" })] }) }) }) })] }) }));
|
|
14
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,15 +4,17 @@ export * from "./components/action-menu.js";
|
|
|
4
4
|
export * from "./components/action-status.js";
|
|
5
5
|
export * from "./components/activity-calendar.js";
|
|
6
6
|
export * from "./components/agent-card.js";
|
|
7
|
+
export * from "./components/agent-list-row.js";
|
|
7
8
|
export * from "./components/agent-orb.js";
|
|
8
9
|
export * from "./components/alert.js";
|
|
9
10
|
export * from "./components/alert-dialog.js";
|
|
10
11
|
export * from "./components/app-mark.js";
|
|
11
12
|
export * from "./components/app-mark-frame.js";
|
|
12
13
|
export * from "./components/app-mark-lazy.js";
|
|
14
|
+
export * from "./components/approval-row.js";
|
|
13
15
|
export * from "./components/aspect-ratio.js";
|
|
14
|
-
export * from "./components/avatar.js";
|
|
15
16
|
export * from "./components/automation-section.js";
|
|
17
|
+
export * from "./components/avatar.js";
|
|
16
18
|
export * from "./components/badge.js";
|
|
17
19
|
export * from "./components/brand.js";
|
|
18
20
|
export * from "./components/brand-field.js";
|
|
@@ -24,10 +26,11 @@ export * from "./components/calendar.js";
|
|
|
24
26
|
export * from "./components/card.js";
|
|
25
27
|
export * from "./components/card-row.js";
|
|
26
28
|
export * from "./components/carousel.js";
|
|
29
|
+
export * from "./components/channel-view.js";
|
|
27
30
|
export * from "./components/chart.js";
|
|
28
31
|
export * from "./components/chart-area-stacked.js";
|
|
29
|
-
export * from "./components/chart-bar-multiple.js";
|
|
30
32
|
export * from "./components/chart-bar-horizontal.js";
|
|
33
|
+
export * from "./components/chart-bar-multiple.js";
|
|
31
34
|
export * from "./components/chart-bar-stacked.js";
|
|
32
35
|
export * from "./components/chart-card.js";
|
|
33
36
|
export * from "./components/chart-date-range.js";
|
|
@@ -40,6 +43,7 @@ export * from "./components/collection-filters.js";
|
|
|
40
43
|
export * from "./components/collection-toolbar.js";
|
|
41
44
|
export * from "./components/combobox.js";
|
|
42
45
|
export * from "./components/command.js";
|
|
46
|
+
export * from "./components/company-card.js";
|
|
43
47
|
export * from "./components/confirm-dialog.js";
|
|
44
48
|
export * from "./components/context-menu.js";
|
|
45
49
|
export * from "./components/dashboard-shell.js";
|
|
@@ -52,6 +56,7 @@ export * from "./components/disclosure-row.js";
|
|
|
52
56
|
export * from "./components/drawer.js";
|
|
53
57
|
export * from "./components/dropdown-menu.js";
|
|
54
58
|
export * from "./components/empty.js";
|
|
59
|
+
export * from "./components/entry-scene.js";
|
|
55
60
|
export * from "./components/expandable-block.js";
|
|
56
61
|
export * from "./components/feedback-state.js";
|
|
57
62
|
export * from "./components/field.js";
|
|
@@ -76,14 +81,17 @@ export * from "./components/menu-choice-row.js";
|
|
|
76
81
|
export * from "./components/menubar.js";
|
|
77
82
|
export * from "./components/model-identity.js";
|
|
78
83
|
export * from "./components/model-mark.js";
|
|
84
|
+
export * from "./components/nadia-presence.js";
|
|
79
85
|
export * from "./components/native-select.js";
|
|
80
86
|
export * from "./components/navigation-menu.js";
|
|
81
87
|
export * from "./components/notice-banner.js";
|
|
88
|
+
export * from "./components/object-workspace.js";
|
|
82
89
|
export * from "./components/pagination.js";
|
|
83
90
|
export * from "./components/pending-label.js";
|
|
84
91
|
export * from "./components/picture-label.js";
|
|
85
92
|
export * from "./components/plugin-slot-boundary.js";
|
|
86
93
|
export * from "./components/popover.js";
|
|
94
|
+
export * from "./components/portal-sidebar-frame.js";
|
|
87
95
|
export * from "./components/progress.js";
|
|
88
96
|
export * from "./components/radio-group.js";
|
|
89
97
|
export * from "./components/reading-column.js";
|
|
@@ -106,7 +114,6 @@ export * from "./components/switch.js";
|
|
|
106
114
|
export * from "./components/table.js";
|
|
107
115
|
export * from "./components/table-card.js";
|
|
108
116
|
export * from "./components/table-value.js";
|
|
109
|
-
export * from "./components/object-workspace.js";
|
|
110
117
|
export * from "./components/tabs.js";
|
|
111
118
|
export * from "./components/text-link.js";
|
|
112
119
|
export * from "./components/textarea.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|