@nadicodeai/ui 12.1.168 → 12.1.170
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/entry-picture.d.ts +20 -0
- package/dist/components/entry-picture.d.ts.map +1 -0
- package/dist/components/entry-picture.js +22 -0
- package/dist/components/invite-card.d.ts +46 -0
- package/dist/components/invite-card.d.ts.map +1 -0
- package/dist/components/invite-card.js +23 -0
- package/dist/components/record-time.d.ts.map +1 -1
- package/dist/components/record-time.js +3 -0
- package/dist/components/settings-facts.d.ts +11 -6
- package/dist/components/settings-facts.d.ts.map +1 -1
- package/dist/components/settings-facts.js +8 -8
- package/dist/components/settings-section.d.ts +14 -3
- package/dist/components/settings-section.d.ts.map +1 -1
- package/dist/components/settings-section.js +8 -2
- package/dist/components/status-badge.js +1 -1
- package/dist/components/update-card.d.ts +7 -11
- package/dist/components/update-card.d.ts.map +1 -1
- package/dist/components/update-card.js +6 -7
- package/dist/showcase/specimens/compositions.d.ts +4 -0
- package/dist/showcase/specimens/compositions.d.ts.map +1 -1
- package/dist/showcase/specimens/compositions.js +26 -0
- package/dist/showcase/specimens/data.js +1 -1
- package/dist/showcase/specimens/feedback.d.ts.map +1 -1
- package/dist/showcase/specimens/feedback.js +1 -1
- package/dist/showcase/specimens/index.d.ts +2 -0
- package/dist/showcase/specimens/index.d.ts.map +1 -1
- package/dist/showcase/usage.generated.d.ts +1 -1
- package/dist/showcase/usage.generated.d.ts.map +1 -1
- package/dist/showcase/usage.generated.js +29 -7
- package/package.json +2 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The art-directed cut-out an entry page stands beside its centred column.
|
|
3
|
+
*
|
|
4
|
+
* @family Compositions
|
|
5
|
+
* @when A whole-page moment with a picture, at the window's left edge: a sign-in handed to Nadia, an invitation, an invite to a company's Alveare.
|
|
6
|
+
* @instead A failure page centres its picture above the words ("Failure surfaces"). A first use's picture is `EmptyState`'s. Nadia's desktop entry screens are `EntryScene` and Alveare's are `HiveScene`.
|
|
7
|
+
* @behaviour One whole cut-out fixed to the window's floor at the left edge, so a page taller than the window never cuts its feet. It keeps its own shape and is never wider than half its pixels, the width it stays sharp at on a DPR 2 screen, nor than the room left of the centred `column`, nor taller than 85 % of the window. It shows only from `lg`: below, the task keeps the screen and the browser does not fetch it. A page draws it only in the state the picture is about, so a page that cannot go on never shows one welcoming the person.
|
|
8
|
+
* @words None: the picture carries no caption.
|
|
9
|
+
* @access Decorative and inert: hidden from assistive technology, never focused or clicked.
|
|
10
|
+
*/
|
|
11
|
+
declare function EntryPicture({ src, width, height, column, }: {
|
|
12
|
+
src: string;
|
|
13
|
+
/** The file's width and height in pixels. */
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
/** The width of the column the page centres beside it. */
|
|
17
|
+
column?: string;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
19
|
+
export { EntryPicture };
|
|
20
|
+
//# sourceMappingURL=entry-picture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-picture.d.ts","sourceRoot":"","sources":["../../src/components/entry-picture.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AACH,iBAAS,YAAY,CAAC,EACpB,GAAG,EACH,KAAK,EACL,MAAM,EACN,MAAgB,GACjB,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,+BA0BA;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/** How far the picture stands from the window's left edge. */
|
|
3
|
+
const INSET = "clamp(0.5rem, 4vw, 6rem)";
|
|
4
|
+
/**
|
|
5
|
+
* The art-directed cut-out an entry page stands beside its centred column.
|
|
6
|
+
*
|
|
7
|
+
* @family Compositions
|
|
8
|
+
* @when A whole-page moment with a picture, at the window's left edge: a sign-in handed to Nadia, an invitation, an invite to a company's Alveare.
|
|
9
|
+
* @instead A failure page centres its picture above the words ("Failure surfaces"). A first use's picture is `EmptyState`'s. Nadia's desktop entry screens are `EntryScene` and Alveare's are `HiveScene`.
|
|
10
|
+
* @behaviour One whole cut-out fixed to the window's floor at the left edge, so a page taller than the window never cuts its feet. It keeps its own shape and is never wider than half its pixels, the width it stays sharp at on a DPR 2 screen, nor than the room left of the centred `column`, nor taller than 85 % of the window. It shows only from `lg`: below, the task keeps the screen and the browser does not fetch it. A page draws it only in the state the picture is about, so a page that cannot go on never shows one welcoming the person.
|
|
11
|
+
* @words None: the picture carries no caption.
|
|
12
|
+
* @access Decorative and inert: hidden from assistive technology, never focused or clicked.
|
|
13
|
+
*/
|
|
14
|
+
function EntryPicture({ src, width, height, column = "28rem", }) {
|
|
15
|
+
const box = {
|
|
16
|
+
left: INSET,
|
|
17
|
+
aspectRatio: `${width} / ${height}`,
|
|
18
|
+
width: `min(${width / 2}px, calc(85svh * ${width / height}), calc(50vw - ${column} / 2 - 1.5rem - ${INSET}))`,
|
|
19
|
+
};
|
|
20
|
+
return (_jsx("div", { "aria-hidden": "true", className: "pointer-events-none fixed bottom-0 z-0 hidden lg:block", "data-slot": "entry-picture", inert: true, style: box, children: _jsx("img", { alt: "", className: "size-full object-contain object-bottom", decoding: "async", fetchPriority: "high", height: height, loading: "lazy", src: src, width: width }) }));
|
|
21
|
+
}
|
|
22
|
+
export { EntryPicture };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type PlatformName } from "./platform-mark.js";
|
|
2
|
+
type Installer = {
|
|
3
|
+
platform: PlatformName;
|
|
4
|
+
/** The computer's name: *macOS*. */
|
|
5
|
+
name: string;
|
|
6
|
+
href: string;
|
|
7
|
+
/** The download's size, written: *119 MB*. */
|
|
8
|
+
size?: string;
|
|
9
|
+
/** The computer the page believes the reader is on. */
|
|
10
|
+
suggested?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A link that opens an app: the app's mark, the invite's words, the action that opens it, the
|
|
14
|
+
* installers for a computer without the app, and the code that opens the same link on a phone.
|
|
15
|
+
*
|
|
16
|
+
* @family Compositions
|
|
17
|
+
* @when The page an invite link opens: Alveare's invite to a company. It stands centred on an entry page, with `EntryPicture` at the window's left edge.
|
|
18
|
+
* @instead An invitation to a role the person accepts in the Portal is the Portal's invitation card. Downloads with formats and steps is the Portal's Downloads page. A code the phone takes to sign in is `QrCode` in Nadia's pairing drawer.
|
|
19
|
+
* @behaviour The mark, the title and the one line are centred; the open action fills the card's width under them. The installers are one row per computer, each with its mark, its name, its size and its download, so every row lines up whatever its words; the computer the reader is on carries the `suggested` badge. The installers show from `md` and the phone's code from `lg`, because a phone neither installs a computer's app nor scans its own screen. A link that holds no invite passes the title and the line alone.
|
|
20
|
+
* @words The title says what the person joins: *Join your company on Alveare*. The line says what happens and what to do if it does not. Each download is *Download*, named for its computer to assistive technology; the phone's line says what the code opens and how: *Open this invite on your phone*, *Point your phone's camera at the code*.
|
|
21
|
+
* @access The title is the page's level-1 heading and the installers a list under its own heading. The mark is decorative; the code is an image named by what it opens.
|
|
22
|
+
*/
|
|
23
|
+
declare function InviteCard({ mark, title, description, open, install, phone, }: {
|
|
24
|
+
/** The app's mark, as an image address. */
|
|
25
|
+
mark: string;
|
|
26
|
+
title: string;
|
|
27
|
+
description: string;
|
|
28
|
+
open?: {
|
|
29
|
+
label: string;
|
|
30
|
+
href: string;
|
|
31
|
+
};
|
|
32
|
+
install?: {
|
|
33
|
+
label: string;
|
|
34
|
+
download: string;
|
|
35
|
+
suggested: string;
|
|
36
|
+
installers: readonly Installer[];
|
|
37
|
+
};
|
|
38
|
+
/** The same link, for a phone's camera. */
|
|
39
|
+
phone?: {
|
|
40
|
+
link: string;
|
|
41
|
+
label: string;
|
|
42
|
+
how: string;
|
|
43
|
+
};
|
|
44
|
+
}): import("react").JSX.Element;
|
|
45
|
+
export { InviteCard };
|
|
46
|
+
//# sourceMappingURL=invite-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invite-card.d.ts","sourceRoot":"","sources":["../../src/components/invite-card.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG7E,KAAK,SAAS,GAAG;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,iBAAS,UAAU,CAAC,EAClB,IAAI,EACJ,KAAK,EACL,WAAW,EACX,IAAI,EACJ,OAAO,EACP,KAAK,GACN,EAAE;IACD,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;KAClC,CAAC;IACF,2CAA2C;IAC3C,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD,+BAgEA;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Download } from "lucide-react";
|
|
3
|
+
import { Badge } from "./badge.js";
|
|
4
|
+
import { ButtonLink } from "./button.js";
|
|
5
|
+
import { Card, CardContent } from "./card.js";
|
|
6
|
+
import { Item, ItemActions, ItemContent, ItemDescription, ItemGroup, ItemMedia, ItemTitle, } from "./item.js";
|
|
7
|
+
import { PlatformMark } from "./platform-mark.js";
|
|
8
|
+
import { QrCode } from "./qr-code.js";
|
|
9
|
+
/**
|
|
10
|
+
* A link that opens an app: the app's mark, the invite's words, the action that opens it, the
|
|
11
|
+
* installers for a computer without the app, and the code that opens the same link on a phone.
|
|
12
|
+
*
|
|
13
|
+
* @family Compositions
|
|
14
|
+
* @when The page an invite link opens: Alveare's invite to a company. It stands centred on an entry page, with `EntryPicture` at the window's left edge.
|
|
15
|
+
* @instead An invitation to a role the person accepts in the Portal is the Portal's invitation card. Downloads with formats and steps is the Portal's Downloads page. A code the phone takes to sign in is `QrCode` in Nadia's pairing drawer.
|
|
16
|
+
* @behaviour The mark, the title and the one line are centred; the open action fills the card's width under them. The installers are one row per computer, each with its mark, its name, its size and its download, so every row lines up whatever its words; the computer the reader is on carries the `suggested` badge. The installers show from `md` and the phone's code from `lg`, because a phone neither installs a computer's app nor scans its own screen. A link that holds no invite passes the title and the line alone.
|
|
17
|
+
* @words The title says what the person joins: *Join your company on Alveare*. The line says what happens and what to do if it does not. Each download is *Download*, named for its computer to assistive technology; the phone's line says what the code opens and how: *Open this invite on your phone*, *Point your phone's camera at the code*.
|
|
18
|
+
* @access The title is the page's level-1 heading and the installers a list under its own heading. The mark is decorative; the code is an image named by what it opens.
|
|
19
|
+
*/
|
|
20
|
+
function InviteCard({ mark, title, description, open, install, phone, }) {
|
|
21
|
+
return (_jsx(Card, { "data-slot": "invite-card", children: _jsxs(CardContent, { className: "flex flex-col gap-6", children: [_jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [_jsx("img", { alt: "", "aria-hidden": "true", className: "h-10 w-auto", src: mark }), _jsx("h1", { className: "nc-type-heading-sm m-0", children: title }), _jsx("p", { className: "nc-type-body-md m-0 text-muted-foreground", children: description })] }), open ? (_jsx(ButtonLink, { className: "w-full", href: open.href, size: "lg", children: open.label })) : null, install && install.installers.length > 0 ? (_jsxs("section", { "aria-labelledby": "invite-card-install", className: "hidden flex-col gap-2 md:flex", children: [_jsx("h2", { className: "nc-type-body-sm m-0 text-muted-foreground", id: "invite-card-install", children: install.label }), _jsx(ItemGroup, { className: "rounded-md border border-border", divided: true, render: _jsx("ul", {}), children: install.installers.map((installer) => (_jsxs(Item, { render: _jsx("li", {}), children: [_jsx(ItemMedia, { variant: "icon", children: _jsx(PlatformMark, { platform: installer.platform, size: 20 }) }), _jsxs(ItemContent, { children: [_jsxs(ItemTitle, { children: [installer.name, installer.suggested ? (_jsx(Badge, { size: "sm", variant: "outline", children: install.suggested })) : null] }), installer.size ? _jsx(ItemDescription, { children: installer.size }) : null] }), _jsx(ItemActions, { children: _jsxs(ButtonLink, { "aria-label": `${install.download} ${installer.name}`, href: installer.href, size: "sm", variant: "secondary", children: [_jsx(Download, { "aria-hidden": "true" }), install.download] }) })] }, installer.platform))) })] })) : null, phone ? (_jsxs("div", { className: "hidden items-center gap-4 rounded-md border border-border p-4 lg:flex", children: [_jsx(QrCode, { label: phone.label, size: 88, value: phone.link }), _jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [_jsx("span", { className: "nc-type-body-md font-medium", children: phone.label }), _jsx("span", { className: "nc-type-body-sm text-muted-foreground", children: phone.how })] })] })) : null] }) }));
|
|
22
|
+
}
|
|
23
|
+
export { InviteCard };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-time.d.ts","sourceRoot":"","sources":["../../src/components/record-time.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEhF,OAAO,EAAa,gBAAgB,EAAoB,MAAM,yBAAyB,CAAC;AAYxF,MAAM,MAAM,eAAe,GAAG;IAC5B,0FAA0F;IAC1F,EAAE,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kEAAkE;IAClE,IAAI,CAAC,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;IACvD,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kIAAkI;IAClI,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,CACA;IACE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;OAGG;IACH,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAClC;AACH,gEAAgE;GAC9D;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CACpB,CAAC;AAEF,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,IAAI,EACR,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,SAAa,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAWR;AAeD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAEA;
|
|
1
|
+
{"version":3,"file":"record-time.d.ts","sourceRoot":"","sources":["../../src/components/record-time.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEhF,OAAO,EAAa,gBAAgB,EAAoB,MAAM,yBAAyB,CAAC;AAYxF,MAAM,MAAM,eAAe,GAAG;IAC5B,0FAA0F;IAC1F,EAAE,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,kEAAkE;IAClE,IAAI,CAAC,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;IACvD,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kIAAkI;IAClI,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,CACA;IACE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;OAGG;IACH,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAClC;AACH,gEAAgE;GAC9D;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CACpB,CAAC;AAEF,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,IAAI,EACR,MAAM,CAAC,EAAE,MAAM,EACf,GAAG,SAAa,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAWR;AAeD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAEA;AAoDD,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAIrF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,sCA+EhD"}
|
|
@@ -41,6 +41,9 @@ export function RecordTimeRenderedAt({ moment, children, }) {
|
|
|
41
41
|
return _jsx(RenderedAt, { value: moment, children: children });
|
|
42
42
|
}
|
|
43
43
|
function useReadingTime(now, counted) {
|
|
44
|
+
// A compiling consumer (React Compiler in Nadia and the Portal) would keep the first render's clock for good, and a
|
|
45
|
+
// later `at` would then read as the future and fall back to its date.
|
|
46
|
+
"use no memo";
|
|
44
47
|
const hydrated = useHydrated();
|
|
45
48
|
if (now !== undefined || !counted)
|
|
46
49
|
return now;
|
|
@@ -11,9 +11,14 @@ export type SettingsFact = {
|
|
|
11
11
|
value: ReactNode;
|
|
12
12
|
};
|
|
13
13
|
type SettingsFactsBase = Omit<ComponentPropsWithoutRef<"section">, "children" | "className"> & {
|
|
14
|
+
/** A command on the facts themselves, at the title's right: the Edit that opens their editor, or a summary's control. */
|
|
15
|
+
command?: ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* The one action the card's state asks for, at the footer's right beside its line, as Vercel's settings cards keep
|
|
18
|
+
* theirs: Update, Start, Review billing. Never a Save.
|
|
19
|
+
*/
|
|
14
20
|
action?: ReactNode;
|
|
15
21
|
facts: readonly SettingsFact[];
|
|
16
|
-
footer?: ReactNode;
|
|
17
22
|
missingValueLabel: string;
|
|
18
23
|
/**
|
|
19
24
|
* Stable: the heading names this section's landmark, and it is where focus
|
|
@@ -44,18 +49,18 @@ export type SettingsFactsSectionProps = SettingsFactsBase & ({
|
|
|
44
49
|
size?: never;
|
|
45
50
|
});
|
|
46
51
|
/**
|
|
47
|
-
* Read-only facts about one object, framed as a card with a title, a line,
|
|
52
|
+
* Read-only facts about one object, framed as a card with a title, a line, the facts and a footer.
|
|
48
53
|
*
|
|
49
54
|
* @family Data
|
|
50
|
-
* @when Read-only facts about one object: who it is, where it belongs, its identifiers.
|
|
51
|
-
* `SettingsFactsSection` frames them as a card
|
|
55
|
+
* @when Read-only facts about one object: who it is, where it belongs, its identifiers; and a status, a read-only card whose `action` is the one action that fixes it.
|
|
56
|
+
* `SettingsFactsSection` frames them as a card; `ObjectFacts` is the
|
|
52
57
|
* list alone.
|
|
53
58
|
* @instead Facts a person changes are a `SettingsSection` with its own Save. One server-given value,
|
|
54
59
|
* an ID, is a `SettingsSection` with the value in a read-only mono `InputGroup` and its copy button, no Save. Facts
|
|
55
60
|
* compared across records are a table. A relation is its identity or a `Tag`, never its own card.
|
|
56
61
|
* @behaviour "Use `<Description>` for definition-list metadata: a short Title Case key paired with a single value (`Last Deployed`, `Region`, `Plan`)." (https://vercel.com/geist/description)
|
|
57
62
|
* Ours: required: the description and the footer's left line (`footerHint`), as on a
|
|
58
|
-
* `SettingsSection
|
|
63
|
+
* `SettingsSection`. Two places take a control, each for one job: `command` at the title's right is a command on the facts, the Edit that opens their editor; `action` at the footer's right, beside its line, is the one action the card's state asks for, as a status card's fix (Update, Start) and every Vercel settings card's button stand there. Facts are plain pairs, the label above
|
|
59
64
|
* its value, in two equal columns from 640 px (`sm`) and one column below it. Every label stays when its value is missing,
|
|
60
65
|
* as *—*. A long value
|
|
61
66
|
* spans both columns. No fact gets a box of its own. In a side column, `presentation="summary"`
|
|
@@ -69,6 +74,6 @@ export type SettingsFactsSectionProps = SettingsFactsBase & ({
|
|
|
69
74
|
* Ours: a `dl` of `dt` and `dd`, each value named by its label. The section is labelled by its heading, which also takes focus
|
|
70
75
|
* when an editor closes. A dash carries screen-reader text.
|
|
71
76
|
*/
|
|
72
|
-
export declare function SettingsFactsSection({ action, presentation, description, facts,
|
|
77
|
+
export declare function SettingsFactsSection({ action, command, presentation, description, facts, footerHint, missingValueLabel, headingId, headingLevel, title, surface, size, ...props }: SettingsFactsSectionProps): import("react").JSX.Element;
|
|
73
78
|
export {};
|
|
74
79
|
//# sourceMappingURL=settings-facts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-facts.d.ts","sourceRoot":"","sources":["../../src/components/settings-facts.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,SAAS,EAAS,MAAM,OAAO,CAAC;AAM7E,OAAO,EACL,IAAI,EAMJ,KAAK,WAAW,EACjB,MAAM,QAAQ,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,KAAK,iBAAiB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC,GAAG;IAC7F,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,
|
|
1
|
+
{"version":3,"file":"settings-facts.d.ts","sourceRoot":"","sources":["../../src/components/settings-facts.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,wBAAwB,EAAE,KAAK,SAAS,EAAS,MAAM,OAAO,CAAC;AAM7E,OAAO,EACL,IAAI,EAMJ,KAAK,WAAW,EACjB,MAAM,QAAQ,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,KAAK,iBAAiB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC,GAAG;IAC7F,yHAAyH;IACzH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,+GAA+G;IAC/G,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GACvD,CACI;IACE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,6FAA6F;IAC7F,UAAU,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACnC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,wBAAwB,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;CACtD,GACD;IACE,YAAY,EAAE,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,CACJ,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,OAAO,EACP,YAAqB,EACrB,WAAW,EACX,KAAK,EACL,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,YAAgB,EAChB,KAAK,EACL,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,yBAAyB,+BAkE3B"}
|
|
@@ -5,18 +5,18 @@ import { ObjectFacts } from "./object-workspace.js";
|
|
|
5
5
|
import { TableValue } from "./table-value.js";
|
|
6
6
|
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, } from "./card.js";
|
|
7
7
|
/**
|
|
8
|
-
* Read-only facts about one object, framed as a card with a title, a line,
|
|
8
|
+
* Read-only facts about one object, framed as a card with a title, a line, the facts and a footer.
|
|
9
9
|
*
|
|
10
10
|
* @family Data
|
|
11
|
-
* @when Read-only facts about one object: who it is, where it belongs, its identifiers.
|
|
12
|
-
* `SettingsFactsSection` frames them as a card
|
|
11
|
+
* @when Read-only facts about one object: who it is, where it belongs, its identifiers; and a status, a read-only card whose `action` is the one action that fixes it.
|
|
12
|
+
* `SettingsFactsSection` frames them as a card; `ObjectFacts` is the
|
|
13
13
|
* list alone.
|
|
14
14
|
* @instead Facts a person changes are a `SettingsSection` with its own Save. One server-given value,
|
|
15
15
|
* an ID, is a `SettingsSection` with the value in a read-only mono `InputGroup` and its copy button, no Save. Facts
|
|
16
16
|
* compared across records are a table. A relation is its identity or a `Tag`, never its own card.
|
|
17
17
|
* @behaviour "Use `<Description>` for definition-list metadata: a short Title Case key paired with a single value (`Last Deployed`, `Region`, `Plan`)." (https://vercel.com/geist/description)
|
|
18
18
|
* Ours: required: the description and the footer's left line (`footerHint`), as on a
|
|
19
|
-
* `SettingsSection
|
|
19
|
+
* `SettingsSection`. Two places take a control, each for one job: `command` at the title's right is a command on the facts, the Edit that opens their editor; `action` at the footer's right, beside its line, is the one action the card's state asks for, as a status card's fix (Update, Start) and every Vercel settings card's button stand there. Facts are plain pairs, the label above
|
|
20
20
|
* its value, in two equal columns from 640 px (`sm`) and one column below it. Every label stays when its value is missing,
|
|
21
21
|
* as *—*. A long value
|
|
22
22
|
* spans both columns. No fact gets a box of its own. In a side column, `presentation="summary"`
|
|
@@ -30,15 +30,15 @@ import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle,
|
|
|
30
30
|
* Ours: a `dl` of `dt` and `dd`, each value named by its label. The section is labelled by its heading, which also takes focus
|
|
31
31
|
* when an editor closes. A dash carries screen-reader text.
|
|
32
32
|
*/
|
|
33
|
-
export function SettingsFactsSection({ action, presentation = "card", description, facts,
|
|
33
|
+
export function SettingsFactsSection({ action, command, presentation = "card", description, facts, footerHint, missingValueLabel, headingId, headingLevel = 2, title, surface = "resting", size = "default", ...props }) {
|
|
34
34
|
const termId = useId();
|
|
35
35
|
const Heading = headingLevel === 3 ? "h3" : "h2";
|
|
36
36
|
if (presentation === "summary") {
|
|
37
|
-
return (_jsxs("section", { ...props, "aria-labelledby": headingId, className: "grid min-w-0 gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx(Heading, { id: headingId, tabIndex: -1, className: "text-sm font-medium", children: title }),
|
|
37
|
+
return (_jsxs("section", { ...props, "aria-labelledby": headingId, className: "grid min-w-0 gap-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx(Heading, { id: headingId, tabIndex: -1, className: "text-sm font-medium", children: title }), command] }), description ? _jsx("p", { className: "text-sm text-muted-foreground", children: description }) : null, _jsx("dl", { className: "flex flex-wrap items-start gap-x-6 gap-y-3", children: facts.map((fact, index) => (_jsxs("div", { className: "grid gap-1", children: [_jsx("dt", { className: "text-xs text-muted-foreground", id: `${termId}-${index}`, children: fact.label }), _jsx("dd", { "aria-labelledby": `${termId}-${index}`, className: "text-sm", children: fact.value ?? _jsx(TableValue, { missingLabel: missingValueLabel, value: null }) })] }, fact.label))) }), action] }));
|
|
38
38
|
}
|
|
39
|
-
return (_jsxs(Card, { render: _jsx("section", {}), ...props, "aria-labelledby": headingId, surface: surface, size: size, className: "min-w-0", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: _jsx(Heading, { id: headingId, tabIndex: -1, children: title }) }), description ? _jsx(CardDescription, { children: description }) : null,
|
|
39
|
+
return (_jsxs(Card, { render: _jsx("section", {}), ...props, "aria-labelledby": headingId, surface: surface, size: size, className: "min-w-0", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: _jsx(Heading, { id: headingId, tabIndex: -1, children: title }) }), description ? _jsx(CardDescription, { children: description }) : null, command ? _jsx(CardAction, { children: command }) : null] }), _jsx(CardContent, { children: _jsx(ObjectFacts, { facts: facts.map((fact) => ({
|
|
40
40
|
label: fact.label,
|
|
41
41
|
block: fact.block,
|
|
42
42
|
value: fact.value === null || fact.value === undefined || fact.value === "" ? (_jsx(TableValue, { missingLabel: missingValueLabel, value: null })) : (fact.value),
|
|
43
|
-
})) }) }), _jsx(FooterStrip, { hint: footerHint, hintSlot: "settings-facts-hint", children:
|
|
43
|
+
})) }) }), _jsx(FooterStrip, { hint: footerHint, hintSlot: "settings-facts-hint", children: action })] }));
|
|
44
44
|
}
|
|
@@ -142,6 +142,15 @@ type SettingsSwitchRow = SettingsRowBase & {
|
|
|
142
142
|
onCheckedChange: (checked: boolean) => void;
|
|
143
143
|
options?: never;
|
|
144
144
|
control?: never;
|
|
145
|
+
shows?: never;
|
|
146
|
+
};
|
|
147
|
+
/** A fact the card shows and nobody changes there, such as the app's version: no control, no (i). */
|
|
148
|
+
type SettingsValueRow = Pick<SettingsRowBase, "id" | "label"> & {
|
|
149
|
+
shows: NonNullable<React.ReactNode>;
|
|
150
|
+
info?: never;
|
|
151
|
+
checked?: never;
|
|
152
|
+
options?: never;
|
|
153
|
+
control?: never;
|
|
145
154
|
};
|
|
146
155
|
type SettingsSelectRow = SettingsRowBase & {
|
|
147
156
|
value: string;
|
|
@@ -152,6 +161,7 @@ type SettingsSelectRow = SettingsRowBase & {
|
|
|
152
161
|
}[];
|
|
153
162
|
checked?: never;
|
|
154
163
|
control?: never;
|
|
164
|
+
shows?: never;
|
|
155
165
|
};
|
|
156
166
|
type SettingsControlRow = SettingsRowBase & {
|
|
157
167
|
/** A control whose usage page puts it in a settings row, such as ThemeModeSwitcher. */
|
|
@@ -160,6 +170,7 @@ type SettingsControlRow = SettingsRowBase & {
|
|
|
160
170
|
}) => React.ReactNode;
|
|
161
171
|
options?: never;
|
|
162
172
|
checked?: never;
|
|
173
|
+
shows?: never;
|
|
163
174
|
};
|
|
164
175
|
type StateLabels = {
|
|
165
176
|
on: string;
|
|
@@ -168,10 +179,10 @@ type StateLabels = {
|
|
|
168
179
|
type SettingsRowsProps = {
|
|
169
180
|
/** The word beside each switch for its state: "Enabled" and "Disabled". */
|
|
170
181
|
stateLabels: StateLabels;
|
|
171
|
-
rows: readonly (SettingsSwitchRow | SettingsSelectRow | SettingsControlRow)[];
|
|
182
|
+
rows: readonly (SettingsSwitchRow | SettingsSelectRow | SettingsControlRow | SettingsValueRow)[];
|
|
172
183
|
} | {
|
|
173
184
|
stateLabels?: never;
|
|
174
|
-
rows: readonly (SettingsSelectRow | SettingsControlRow)[];
|
|
185
|
+
rows: readonly (SettingsSelectRow | SettingsControlRow | SettingsValueRow)[];
|
|
175
186
|
};
|
|
176
187
|
/**
|
|
177
188
|
* Several switches and selects in one card: each row its label on the left and its control on the right.
|
|
@@ -179,7 +190,7 @@ type SettingsRowsProps = {
|
|
|
179
190
|
* @family Inputs
|
|
180
191
|
* @when A card of switches and selects that the card's one description covers: a project's Git switches, a team's notification channels, a set of defaults, how long a computer stays awake beside whether the window goes to the tray.
|
|
181
192
|
* @instead One setting is a SettingsField. A text box is a field of its own card.
|
|
182
|
-
* @behaviour A row with `options` is a select, a row with `checked` a switch,
|
|
193
|
+
* @behaviour A row with `options` is a select, a row with `checked` a switch, a row with `control` draws a control whose usage page puts it in a row, such as ThemeModeSwitcher, and a row with `shows` is a fact the card shows and nobody changes there, such as the app's version, its value as text where a control would stand; a card may hold any of them together, as Vercel's Root Directory card holds its switches; `stateLabels` is required once any row is a switch. Required on every row that takes a value: the label and its `info` (an (i) with its sentence in a tooltip and on the control); a `shows` row has its label alone. No help line sits under a row. A switch row shows its state word beside the switch (`stateLabels`) and is controlled, so the word always follows the switch. Rows stand 16 px apart; below 28rem a row stacks its control under its label. "Pair with a form footer only when the setting needs an explicit `Save` step." (https://vercel.com/geist/toggle) Ours: a switch is a draft the card's Save applies.
|
|
183
194
|
* @words "Title Case noun phrase, 1–4 words, naming what is true when ON: `Password Protection`, not `Enable Password Protection`." (https://vercel.com/geist/toggle) Ours: sentence case, a noun for what it controls ("Pull request comments"), the same for a switch as for a select. "Render an optional one-sentence description as a sibling under the label that explains ON only. Don’t describe OFF; it’s the negation." (https://vercel.com/geist/toggle) Ours: that sentence is `info.text`. "Options are Title Case when short and match canonical branding (`Next.js`, not `NextJS`); keep the same register across the list." (https://vercel.com/geist/select) Ours: a select's options are sentence case.
|
|
184
195
|
* @access Each row's control is named by the row's label and described by its info and its error. The info button has its own name and opens on focus.
|
|
185
196
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-section.d.ts","sourceRoot":"","sources":["../../src/components/settings-section.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"settings-section.d.ts","sourceRoot":"","sources":["../../src/components/settings-section.tsx"],"names":[],"mappings":"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"}
|
|
@@ -84,7 +84,8 @@ function SettingsField({ id, label, info, error, invalid = Boolean(error), disab
|
|
|
84
84
|
function SettingsRow({ id, label, info, error, disabled, kind, children, }) {
|
|
85
85
|
const invalid = Boolean(error);
|
|
86
86
|
const controlProps = controlPropsOf({ id, info, error, invalid, disabled });
|
|
87
|
-
|
|
87
|
+
const shown = kind === "value";
|
|
88
|
+
return (_jsx("div", { "data-slot": "settings-row", "data-invalid": invalid ? true : undefined, className: "contents", children: _jsxs(Field, { "aria-labelledby": shown ? `${id}-label` : undefined, "data-invalid": invalid ? true : undefined, "data-disabled": disabled ? true : undefined, orientation: "horizontal", className: "flex-wrap has-[>[data-slot=field-content]]:items-center", children: [_jsxs(FieldContent, { className: "flex-auto", children: [shown ? (_jsx("span", { id: `${id}-label`, className: "text-xs font-medium text-foreground", children: label })) : (_jsx(SettingsFieldLabel, { id: id, label: label, info: info, beside: true })), _jsx(SettingsFieldErrors, { id: id, error: error })] }), _jsx("div", { "data-slot": "settings-row-control", "data-kind": kind, className: "flex items-center gap-2 data-[kind=value]:text-sm data-[kind=control]:w-64 data-[kind=control]:max-w-full data-[kind=select]:w-48 data-[kind=select]:max-w-full", children: children({ controlProps }) })] }) }));
|
|
88
89
|
}
|
|
89
90
|
/**
|
|
90
91
|
* Several switches and selects in one card: each row its label on the left and its control on the right.
|
|
@@ -92,12 +93,14 @@ function SettingsRow({ id, label, info, error, disabled, kind, children, }) {
|
|
|
92
93
|
* @family Inputs
|
|
93
94
|
* @when A card of switches and selects that the card's one description covers: a project's Git switches, a team's notification channels, a set of defaults, how long a computer stays awake beside whether the window goes to the tray.
|
|
94
95
|
* @instead One setting is a SettingsField. A text box is a field of its own card.
|
|
95
|
-
* @behaviour A row with `options` is a select, a row with `checked` a switch,
|
|
96
|
+
* @behaviour A row with `options` is a select, a row with `checked` a switch, a row with `control` draws a control whose usage page puts it in a row, such as ThemeModeSwitcher, and a row with `shows` is a fact the card shows and nobody changes there, such as the app's version, its value as text where a control would stand; a card may hold any of them together, as Vercel's Root Directory card holds its switches; `stateLabels` is required once any row is a switch. Required on every row that takes a value: the label and its `info` (an (i) with its sentence in a tooltip and on the control); a `shows` row has its label alone. No help line sits under a row. A switch row shows its state word beside the switch (`stateLabels`) and is controlled, so the word always follows the switch. Rows stand 16 px apart; below 28rem a row stacks its control under its label. "Pair with a form footer only when the setting needs an explicit `Save` step." (https://vercel.com/geist/toggle) Ours: a switch is a draft the card's Save applies.
|
|
96
97
|
* @words "Title Case noun phrase, 1–4 words, naming what is true when ON: `Password Protection`, not `Enable Password Protection`." (https://vercel.com/geist/toggle) Ours: sentence case, a noun for what it controls ("Pull request comments"), the same for a switch as for a select. "Render an optional one-sentence description as a sibling under the label that explains ON only. Don’t describe OFF; it’s the negation." (https://vercel.com/geist/toggle) Ours: that sentence is `info.text`. "Options are Title Case when short and match canonical branding (`Next.js`, not `NextJS`); keep the same register across the list." (https://vercel.com/geist/select) Ours: a select's options are sentence case.
|
|
97
98
|
* @access Each row's control is named by the row's label and described by its info and its error. The info button has its own name and opens on focus.
|
|
98
99
|
*/
|
|
99
100
|
function SettingsRows({ rows, stateLabels }) {
|
|
100
101
|
return (_jsx("div", { "data-slot": "settings-rows", className: "flex flex-col gap-4", children: rows.map((row) => {
|
|
102
|
+
if (row.shows !== undefined)
|
|
103
|
+
return valueRow(row);
|
|
101
104
|
if (row.control !== undefined)
|
|
102
105
|
return controlRow(row);
|
|
103
106
|
return row.options === undefined ? switchRow(row, stateLabels) : selectRow(row);
|
|
@@ -106,6 +109,9 @@ function SettingsRows({ rows, stateLabels }) {
|
|
|
106
109
|
function switchRow(row, stateLabels) {
|
|
107
110
|
return (_jsx(SettingsRow, { kind: "switch", ...row, children: ({ controlProps }) => (_jsxs(_Fragment, { children: [_jsx(Switch, { ...controlProps, checked: row.checked, name: row.name, onCheckedChange: row.onCheckedChange, size: "md" }), _jsx("span", { className: "text-sm", children: row.checked ? stateLabels?.on : stateLabels?.off })] })) }, row.id));
|
|
108
111
|
}
|
|
112
|
+
function valueRow(row) {
|
|
113
|
+
return (_jsx(SettingsRow, { kind: "value", ...row, children: () => row.shows }, row.id));
|
|
114
|
+
}
|
|
109
115
|
function controlRow(row) {
|
|
110
116
|
return (_jsx(SettingsRow, { kind: "control", ...row, children: row.control }, row.id));
|
|
111
117
|
}
|
|
@@ -13,7 +13,7 @@ const TONE = {
|
|
|
13
13
|
edge: "text-warning-soft-foreground",
|
|
14
14
|
},
|
|
15
15
|
danger: { name: "red", shape: "square", ink: "text-destructive" },
|
|
16
|
-
info: { name: "blue", shape: "diamond", ink: "text-info" },
|
|
16
|
+
info: { name: "blue", shape: "diamond", ink: "text-info-soft-foreground" },
|
|
17
17
|
neutral: { name: "gray", shape: "ring", ink: "text-muted-foreground" },
|
|
18
18
|
};
|
|
19
19
|
const SIZE = {
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
import { type PageCommand } from "./page-actions.js";
|
|
2
2
|
export type UpdateCardProps = {
|
|
3
3
|
state: "available";
|
|
4
|
-
/** "
|
|
4
|
+
/** The version on offer and that it is ready: "Nadia 0.42.0 is ready". */
|
|
5
5
|
title: string;
|
|
6
|
-
/**
|
|
7
|
-
version: string;
|
|
8
|
-
/** "Update and restart", with its pending word while it runs. */
|
|
6
|
+
/** "Update", with its pending word while it runs. */
|
|
9
7
|
action: PageCommand;
|
|
10
8
|
/** The rail is too narrow for words: one icon button. */
|
|
11
9
|
narrow?: boolean;
|
|
12
10
|
} | {
|
|
13
11
|
state: "updated";
|
|
14
|
-
/**
|
|
12
|
+
/** The version now running: "Updated to Nadia 0.42.0". */
|
|
15
13
|
title: string;
|
|
16
|
-
/**
|
|
17
|
-
version: string;
|
|
18
|
-
/** Closes the card: its label names the ghost close. */
|
|
14
|
+
/** Closes the row: its label names the ghost close. */
|
|
19
15
|
dismiss: {
|
|
20
16
|
label: string;
|
|
21
17
|
onClick: () => void;
|
|
@@ -28,9 +24,9 @@ export type UpdateCardProps = {
|
|
|
28
24
|
* @family Feedback
|
|
29
25
|
* @when Nadia's and Alveare's sidebar foot, only while an update is on offer or has just been installed.
|
|
30
26
|
* @instead A failed update or a download that needs the person is a NoticeBanner; the Portal's way to get the app is its Downloads row.
|
|
31
|
-
* @behaviour
|
|
32
|
-
* @words
|
|
33
|
-
* @access The
|
|
27
|
+
* @behaviour One outlined row of the column's width, shaped as the sidebar's Find: available, a download icon in the primary colour, the line, and a small primary command at the end that keeps its place and says its pending word while it runs; updated, a check, the line and a ghost close. A line too long for the column is cut with an ellipsis. Narrow, the row is one icon button whose tooltip shows the line. Nothing else in the window offers the update: no toast, no banner.
|
|
28
|
+
* @words One line names the product, its number and what happened ("Nadia 0.42.0 is ready", "Updated to Nadia 0.42.0"); the command is one verb ("Update").
|
|
29
|
+
* @access The row is a region named by its line. The narrow button is named by its command and the line ("Update: Nadia 0.42.0 is ready"), and the close carries its label; a running command is aria-busy.
|
|
34
30
|
*/
|
|
35
31
|
export declare function UpdateCard(props: UpdateCardProps): import("react").JSX.Element;
|
|
36
32
|
//# sourceMappingURL=update-card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-card.d.ts","sourceRoot":"","sources":["../../src/components/update-card.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"update-card.d.ts","sourceRoot":"","sources":["../../src/components/update-card.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGhF,MAAM,MAAM,eAAe,GACvB;IACE,KAAK,EAAE,WAAW,CAAC;IACnB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,MAAM,EAAE,WAAW,CAAC;IACpB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GACD;IACE,KAAK,EAAE,SAAS,CAAC;IACjB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IAChD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEN;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,+BA+BhD"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ArrowDownToLine, CircleCheck, X } from "lucide-react";
|
|
4
4
|
import { Button } from "./button.js";
|
|
5
|
-
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle, } from "./card.js";
|
|
6
5
|
import { PageCommandButton } from "./page-actions.js";
|
|
7
6
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
|
|
8
7
|
/**
|
|
@@ -11,18 +10,18 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
|
|
|
11
10
|
* @family Feedback
|
|
12
11
|
* @when Nadia's and Alveare's sidebar foot, only while an update is on offer or has just been installed.
|
|
13
12
|
* @instead A failed update or a download that needs the person is a NoticeBanner; the Portal's way to get the app is its Downloads row.
|
|
14
|
-
* @behaviour
|
|
15
|
-
* @words
|
|
16
|
-
* @access The
|
|
13
|
+
* @behaviour One outlined row of the column's width, shaped as the sidebar's Find: available, a download icon in the primary colour, the line, and a small primary command at the end that keeps its place and says its pending word while it runs; updated, a check, the line and a ghost close. A line too long for the column is cut with an ellipsis. Narrow, the row is one icon button whose tooltip shows the line. Nothing else in the window offers the update: no toast, no banner.
|
|
14
|
+
* @words One line names the product, its number and what happened ("Nadia 0.42.0 is ready", "Updated to Nadia 0.42.0"); the command is one verb ("Update").
|
|
15
|
+
* @access The row is a region named by its line. The narrow button is named by its command and the line ("Update: Nadia 0.42.0 is ready"), and the close carries its label; a running command is aria-busy.
|
|
17
16
|
*/
|
|
18
17
|
export function UpdateCard(props) {
|
|
19
18
|
if (props.narrow)
|
|
20
19
|
return _jsx(NarrowUpdate, { ...props });
|
|
21
|
-
return (_jsxs(
|
|
20
|
+
return (_jsxs("section", { "aria-label": props.title, className: "flex h-control-height min-w-0 items-center gap-2 rounded-sm border border-sidebar-border bg-background py-2 pr-1 pl-2 text-sm text-sidebar-foreground [&>svg]:size-5 [&>svg]:shrink-0", "data-slot": "update-card", "data-state": props.state, children: [props.state === "available" ? (_jsx(ArrowDownToLine, { "aria-hidden": "true", className: "text-primary" })) : (_jsx(CircleCheck, { "aria-hidden": "true", className: "text-muted-foreground" })), _jsx("span", { className: "min-w-0 flex-1 truncate", children: props.title }), props.state === "available" ? (_jsx(PageCommandButton, { command: props.action, size: "xs", variant: "default" })) : (_jsx(Button, { "aria-label": props.dismiss.label, onClick: props.dismiss.onClick, size: "icon-xs", type: "button", variant: "ghost", children: _jsx(X, { "aria-hidden": "true" }) }))] }));
|
|
22
21
|
}
|
|
23
22
|
function NarrowUpdate(props) {
|
|
24
|
-
const button = props.state === "available" ? (_jsx(Button, { "aria-label": `${props.action.pending ? (props.action.pendingLabel ?? props.action.label) : props.action.label}: ${props.
|
|
23
|
+
const button = props.state === "available" ? (_jsx(Button, { "aria-label": `${props.action.pending ? (props.action.pendingLabel ?? props.action.label) : props.action.label}: ${props.title}`, disabled: props.action.disabled, loading: props.action.pending, size: "icon", variant: "ghost", ...(props.action.render
|
|
25
24
|
? { render: props.action.render, nativeButton: false }
|
|
26
25
|
: { onClick: props.action.onClick, type: "button" }), children: _jsx(ArrowDownToLine, { "aria-hidden": "true" }) })) : (_jsx(Button, { "aria-label": `${props.dismiss.label}: ${props.title}`, onClick: props.dismiss.onClick, size: "icon", type: "button", variant: "ghost", children: _jsx(CircleCheck, { "aria-hidden": "true" }) }));
|
|
27
|
-
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: button }), _jsx(TooltipContent, { side: "right", children:
|
|
26
|
+
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: button }), _jsx(TooltipContent, { side: "right", children: props.title })] }));
|
|
28
27
|
}
|
|
@@ -6,6 +6,8 @@ declare function CollectionPageSpecimen(): import("react").JSX.Element;
|
|
|
6
6
|
declare function CollectionToolbarSpecimen(): import("react").JSX.Element;
|
|
7
7
|
declare function ConfirmDialogSpecimen(): import("react").JSX.Element;
|
|
8
8
|
declare function EntrySceneSpecimen(): import("react").JSX.Element;
|
|
9
|
+
declare function EntryPictureSpecimen(): import("react").JSX.Element;
|
|
10
|
+
declare function InviteCardSpecimen(): import("react").JSX.Element;
|
|
9
11
|
declare function FormDialogSpecimen(): import("react").JSX.Element;
|
|
10
12
|
declare function FormDrawerSpecimen(): import("react").JSX.Element;
|
|
11
13
|
declare function LibraryShelfSpecimen(): import("react").JSX.Element;
|
|
@@ -21,7 +23,9 @@ export declare const COMPOSITIONS: {
|
|
|
21
23
|
CollectionPage: typeof CollectionPageSpecimen;
|
|
22
24
|
CollectionToolbar: typeof CollectionToolbarSpecimen;
|
|
23
25
|
ConfirmDialog: typeof ConfirmDialogSpecimen;
|
|
26
|
+
EntryPicture: typeof EntryPictureSpecimen;
|
|
24
27
|
EntryScene: typeof EntrySceneSpecimen;
|
|
28
|
+
InviteCard: typeof InviteCardSpecimen;
|
|
25
29
|
FormDialog: typeof FormDialogSpecimen;
|
|
26
30
|
FormDrawer: typeof FormDrawerSpecimen;
|
|
27
31
|
LibraryShelf: typeof LibraryShelfSpecimen;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compositions.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/compositions.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compositions.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/compositions.tsx"],"names":[],"mappings":"AAsIA,iBAAS,oBAAoB,gCA+B5B;AAMD,iBAAS,wBAAwB,gCAahC;AAED,iBAAS,qBAAqB,gCA0B7B;AAED,iBAAS,yBAAyB,gCAGjC;AAED,iBAAS,sBAAsB,gCAyD9B;AAED,iBAAS,yBAAyB,gCAUjC;AAED,iBAAS,qBAAqB,gCAwC7B;AAED,iBAAS,kBAAkB,gCAiB1B;AAED,iBAAS,oBAAoB,gCAS5B;AAED,iBAAS,kBAAkB,gCA0B1B;AAED,iBAAS,kBAAkB,gCAuE1B;AAED,iBAAS,kBAAkB,gCAwB1B;AAED,iBAAS,oBAAoB,gCAkD5B;AAED,iBAAS,oBAAoB,gCAqC5B;AAED,iBAAS,mBAAmB,gCA2B3B;AAED,iBAAS,mBAAmB,gCAoB3B;AAwBD,iBAAS,uBAAuB,gCAkD/B;AA+BD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;CA6FE,CAAC"}
|
|
@@ -14,10 +14,12 @@ import { CollectionPage } from "../../components/collection-page.js";
|
|
|
14
14
|
import { CollectionSearch } from "../../components/collection-search.js";
|
|
15
15
|
import { CollectionToolbar } from "../../components/collection-toolbar.js";
|
|
16
16
|
import { ConfirmDialog } from "../../components/confirm-dialog.js";
|
|
17
|
+
import { EntryPicture } from "../../components/entry-picture.js";
|
|
17
18
|
import { EntryAction, EntryActions, EntryMessage, EntryScene } from "../../components/entry-scene.js";
|
|
18
19
|
import { FormDialog, FormDialogForm } from "../../components/form-dialog.js";
|
|
19
20
|
import { FormDrawer, FormDrawerBody, FormDrawerFooter } from "../../components/form-drawer.js";
|
|
20
21
|
import { Input } from "../../components/input.js";
|
|
22
|
+
import { InviteCard } from "../../components/invite-card.js";
|
|
21
23
|
import { LibraryShelf } from "../../components/library-shelf.js";
|
|
22
24
|
import { NadiaPresence } from "../../components/nadia-presence.js";
|
|
23
25
|
import { ObjectPage } from "../../components/object-page.js";
|
|
@@ -212,6 +214,28 @@ function EntrySceneSpecimen() {
|
|
|
212
214
|
const art = useEmptyArt();
|
|
213
215
|
return (_jsx("div", { className: "max-w-3xl overflow-hidden rounded-md", children: _jsxs(EntryScene, { picture: _jsx("img", { alt: "", className: "size-full object-cover", src: art.agents }), presence: _jsx(NadiaPresence, { label: "Nadia is ready", reveal: 1, state: "ready" }), title: "Nadia is ready", wordmark: _jsx(BrandWordmark, {}), children: [_jsx(EntryMessage, { children: "Sign in to bring your Agents to this computer." }), _jsx(EntryActions, { children: _jsx(EntryAction, { children: "Sign in" }) })] }) }));
|
|
214
216
|
}
|
|
217
|
+
function EntryPictureSpecimen() {
|
|
218
|
+
const art = useEmptyArt();
|
|
219
|
+
// A transform makes the box the picture's containing block, so it stands at this box's floor
|
|
220
|
+
// rather than the showcase window's.
|
|
221
|
+
return (_jsx("div", { className: "relative h-80 w-full overflow-hidden rounded-md border border-border [transform:translateZ(0)]", children: _jsx(EntryPicture, { column: "0rem", height: 1024, src: art.agents, width: 1024 }) }));
|
|
222
|
+
}
|
|
223
|
+
function InviteCardSpecimen() {
|
|
224
|
+
return (_jsx("div", { className: "max-w-130", children: _jsx(InviteCard, { description: "Alveare opens by itself with your invite. If it doesn't open, install it, then open the invite link again.", install: {
|
|
225
|
+
label: "Install Alveare",
|
|
226
|
+
download: "Download",
|
|
227
|
+
suggested: "Suggested",
|
|
228
|
+
installers: [
|
|
229
|
+
{ platform: "apple", name: "macOS", href: "#", size: "119 MB", suggested: true },
|
|
230
|
+
{ platform: "windows", name: "Windows", href: "#", size: "44 MB" },
|
|
231
|
+
{ platform: "linux", name: "Linux", href: "#", size: "133 MB" },
|
|
232
|
+
],
|
|
233
|
+
}, mark: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Ccircle cx='20' cy='20' r='18' fill='%231e3cff'/%3E%3C/svg%3E", open: { label: "Open Alveare", href: "#" }, phone: {
|
|
234
|
+
link: "https://nadicode.ai/en/join",
|
|
235
|
+
label: "Open this invite on your phone",
|
|
236
|
+
how: "Point your phone's camera at the code.",
|
|
237
|
+
}, title: "Join your company on Alveare" }) }));
|
|
238
|
+
}
|
|
215
239
|
function FormDialogSpecimen() {
|
|
216
240
|
const [open, setOpen] = useState(null);
|
|
217
241
|
const [discardOpen, setDiscardOpen] = useState(false);
|
|
@@ -358,7 +382,9 @@ export const COMPOSITIONS = {
|
|
|
358
382
|
CollectionPage: CollectionPageSpecimen,
|
|
359
383
|
CollectionToolbar: CollectionToolbarSpecimen,
|
|
360
384
|
ConfirmDialog: ConfirmDialogSpecimen,
|
|
385
|
+
EntryPicture: EntryPictureSpecimen,
|
|
361
386
|
EntryScene: EntrySceneSpecimen,
|
|
387
|
+
InviteCard: InviteCardSpecimen,
|
|
362
388
|
FormDialog: FormDialogSpecimen,
|
|
363
389
|
FormDrawer: FormDrawerSpecimen,
|
|
364
390
|
LibraryShelf: LibraryShelfSpecimen,
|
|
@@ -201,7 +201,7 @@ export const DATA = {
|
|
|
201
201
|
},
|
|
202
202
|
{ id: "send", label: "Step 03", title: "Send the quote", progress: "upcoming" },
|
|
203
203
|
] })),
|
|
204
|
-
SettingsFactsSection: () => (_jsx("div", { className: "max-w-lg", children: _jsx(SettingsFactsSection, {
|
|
204
|
+
SettingsFactsSection: () => (_jsx("div", { className: "max-w-lg", children: _jsx(SettingsFactsSection, { command: _jsx(Button, { variant: "outline", children: "Edit" }), description: "The legal details on every invoice.", facts: [
|
|
205
205
|
{ label: "Legal name", value: "Acme S.r.l." },
|
|
206
206
|
{ label: "VAT number", value: _jsx("span", { className: "font-mono", children: "IT01234567890" }) },
|
|
207
207
|
{ label: "PEC", value: null },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/feedback.tsx"],"names":[],"mappings":"AA4CA,iBAAS,kBAAkB,gCAoE1B;AAED,iBAAS,oBAAoB,gCAkB5B;AAED,iBAAS,eAAe,gCAyBvB;AAED,iBAAS,kBAAkB,
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/feedback.tsx"],"names":[],"mappings":"AA4CA,iBAAS,kBAAkB,gCAoE1B;AAED,iBAAS,oBAAoB,gCAkB5B;AAED,iBAAS,eAAe,gCAyBvB;AAED,iBAAS,kBAAkB,gCA2B1B;AAED,iBAAS,sBAAsB,gCAwB9B;AAED,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;CAyLM,CAAC"}
|
|
@@ -45,7 +45,7 @@ function ToasterSpecimen() {
|
|
|
45
45
|
}
|
|
46
46
|
function UpdateCardSpecimen() {
|
|
47
47
|
const [updated, setUpdated] = useState(false);
|
|
48
|
-
return (_jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "w-64", children: updated ? (_jsx(UpdateCard, { dismiss: { label: "Dismiss", onClick: () => setUpdated(false) }, state: "updated", title: "
|
|
48
|
+
return (_jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "w-64", children: updated ? (_jsx(UpdateCard, { dismiss: { label: "Dismiss", onClick: () => setUpdated(false) }, state: "updated", title: "Updated to Nadia 12.2.0" })) : (_jsx(UpdateCard, { action: { label: "Update", onClick: () => setUpdated(true) }, state: "available", title: "Nadia 12.2.0 is ready" })) }), _jsx(UpdateCard, { action: { label: "Update", onClick: nothing }, narrow: true, state: "available", title: "Nadia 12.2.0 is ready" })] }));
|
|
49
49
|
}
|
|
50
50
|
function SkeletonRegionSpecimen() {
|
|
51
51
|
const [busy, setBusy] = useState(true);
|
|
@@ -155,7 +155,9 @@ export declare const SPECIMENS: {
|
|
|
155
155
|
CollectionPage: () => import("react").JSX.Element;
|
|
156
156
|
CollectionToolbar: () => import("react").JSX.Element;
|
|
157
157
|
ConfirmDialog: () => import("react").JSX.Element;
|
|
158
|
+
EntryPicture: () => import("react").JSX.Element;
|
|
158
159
|
EntryScene: () => import("react").JSX.Element;
|
|
160
|
+
InviteCard: () => import("react").JSX.Element;
|
|
159
161
|
FormDialog: () => import("react").JSX.Element;
|
|
160
162
|
FormDrawer: () => import("react").JSX.Element;
|
|
161
163
|
LibraryShelf: () => import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAYiB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type UsageName = "ActivityFeed" | "AgentProfileCard" | "CatalogDrawer" | "CollectionFilters" | "CollectionPage" | "CollectionToolbar" | "ConfirmDialog" | "EntryScene" | "FormDialog" | "FormDrawer" | "LibraryShelf" | "ObjectPage" | "ObjectSection" | "OverviewPage" | "PageHeader" | "RecordList" | "RecordSheet" | "RowEditForm" | "SettingsPage" | "SettingsSection" | "Button" | "ButtonGroup" | "ButtonLink" | "CopyButton" | "LoadMoreButton" | "PageActions" | "Calendar" | "ClearableInput" | "CollectionSearch" | "Field" | "Form" | "Input" | "InputGroup" | "InputOTP" | "Label" | "NativeSelect" | "SettingsField" | "SettingsRows" | "Slider" | "Textarea" | "Checkbox" | "ChoiceboxGroup" | "CollectionSort" | "Combobox" | "ModelSelect" | "MultiSelect" | "RadioGroup" | "SegmentedChoice" | "SegmentedControl" | "Select" | "Switch" | "ThemeModeSegments" | "ThemeModeSwitcher" | "Toggle" | "ToggleGroup" | "ActionStatus" | "AgentOrb" | "AppMark" | "ArchIcon" | "Avatar" | "Badge" | "BrandWordmark" | "CheckCounts" | "FileTypeIcon" | "IdentityMark" | "ModelIdentity" | "ModelMark" | "ObjectFactValue" | "PlatformMark" | "ProgressChecklist" | "RecordIdentity" | "StatusBadge" | "Tag" | "AgentListRow" | "Breadcrumb" | "CommandDialog" | "Footer" | "PortalSidebarFrame" | "ScopeSwitcher" | "Sidebar" | "SidebarBrand" | "SidebarFind" | "SidebarFrame" | "SidebarMenuChevron" | "SidebarSections" | "Tabs" | "TabsNav" | "textLinkVariants" | "AgentCard" | "Card" | "CardRow" | "CodeBlock" | "DataTable" | "DiffCount" | "DisclosureRow" | "FileDiff" | "Gauge" | "Item" | "Kbd" | "MiddleTruncate" | "ObjectFacts" | "PairingCode" | "Progress" | "QrCode" | "RecordTime" | "RunTimeline" | "SettingsFactsSection" | "Snippet" | "Table" | "TableCard" | "TableValue" | "TextWithCopyButton" | "UsageMeter" | "Alert" | "EmptyState" | "EntryProgress" | "EntryStageList" | "HoverCard" | "MessageNotice" | "NoticeBanner" | "PendingLabel" | "Skeleton" | "SkeletonRegion" | "Toaster" | "Tooltip" | "UpdateCard" | "WaitingLine" | "AccountMenu" | "ActionContextMenu" | "ActionMenu" | "AlertDialog" | "ContextMenu" | "Dialog" | "Drawer" | "DropdownMenu" | "GlassControl" | "MenuChoiceRow" | "Popover" | "Sheet" | "SiteMenu" | "ThemeModeMenu" | "ActivityCalendar" | "ChartAreaStacked" | "ChartBarHorizontal" | "ChartBarMultiple" | "ChartBarStacked" | "ChartCard" | "ChartContainer" | "ChartRanking" | "ChartSparkline" | "DateRangeControl" | "KpiCard" | "TrendBadge" | "createEntityColorMap" | "Accordion" | "AspectRatio" | "BrandField" | "Collapsible" | "CompanyCard" | "Disclosure" | "HiveScene" | "NadiaPresence" | "NumberedSteps" | "Prose" | "ReadingColumn" | "ResizablePanelGroup" | "ScrollArea" | "Separator" | "ToolIcon";
|
|
1
|
+
export type UsageName = "ActivityFeed" | "AgentProfileCard" | "CatalogDrawer" | "CollectionFilters" | "CollectionPage" | "CollectionToolbar" | "ConfirmDialog" | "EntryPicture" | "EntryScene" | "FormDialog" | "FormDrawer" | "InviteCard" | "LibraryShelf" | "ObjectPage" | "ObjectSection" | "OverviewPage" | "PageHeader" | "RecordList" | "RecordSheet" | "RowEditForm" | "SettingsPage" | "SettingsSection" | "Button" | "ButtonGroup" | "ButtonLink" | "CopyButton" | "LoadMoreButton" | "PageActions" | "Calendar" | "ClearableInput" | "CollectionSearch" | "Field" | "Form" | "Input" | "InputGroup" | "InputOTP" | "Label" | "NativeSelect" | "SettingsField" | "SettingsRows" | "Slider" | "Textarea" | "Checkbox" | "ChoiceboxGroup" | "CollectionSort" | "Combobox" | "ModelSelect" | "MultiSelect" | "RadioGroup" | "SegmentedChoice" | "SegmentedControl" | "Select" | "Switch" | "ThemeModeSegments" | "ThemeModeSwitcher" | "Toggle" | "ToggleGroup" | "ActionStatus" | "AgentOrb" | "AppMark" | "ArchIcon" | "Avatar" | "Badge" | "BrandWordmark" | "CheckCounts" | "FileTypeIcon" | "IdentityMark" | "ModelIdentity" | "ModelMark" | "ObjectFactValue" | "PlatformMark" | "ProgressChecklist" | "RecordIdentity" | "StatusBadge" | "Tag" | "AgentListRow" | "Breadcrumb" | "CommandDialog" | "Footer" | "PortalSidebarFrame" | "ScopeSwitcher" | "Sidebar" | "SidebarBrand" | "SidebarFind" | "SidebarFrame" | "SidebarMenuChevron" | "SidebarSections" | "Tabs" | "TabsNav" | "textLinkVariants" | "AgentCard" | "Card" | "CardRow" | "CodeBlock" | "DataTable" | "DiffCount" | "DisclosureRow" | "FileDiff" | "Gauge" | "Item" | "Kbd" | "MiddleTruncate" | "ObjectFacts" | "PairingCode" | "Progress" | "QrCode" | "RecordTime" | "RunTimeline" | "SettingsFactsSection" | "Snippet" | "Table" | "TableCard" | "TableValue" | "TextWithCopyButton" | "UsageMeter" | "Alert" | "EmptyState" | "EntryProgress" | "EntryStageList" | "HoverCard" | "MessageNotice" | "NoticeBanner" | "PendingLabel" | "Skeleton" | "SkeletonRegion" | "Toaster" | "Tooltip" | "UpdateCard" | "WaitingLine" | "AccountMenu" | "ActionContextMenu" | "ActionMenu" | "AlertDialog" | "ContextMenu" | "Dialog" | "Drawer" | "DropdownMenu" | "GlassControl" | "MenuChoiceRow" | "Popover" | "Sheet" | "SiteMenu" | "ThemeModeMenu" | "ActivityCalendar" | "ChartAreaStacked" | "ChartBarHorizontal" | "ChartBarMultiple" | "ChartBarStacked" | "ChartCard" | "ChartContainer" | "ChartRanking" | "ChartSparkline" | "DateRangeControl" | "KpiCard" | "TrendBadge" | "createEntityColorMap" | "Accordion" | "AspectRatio" | "BrandField" | "Collapsible" | "CompanyCard" | "Disclosure" | "HiveScene" | "NadiaPresence" | "NumberedSteps" | "Prose" | "ReadingColumn" | "ResizablePanelGroup" | "ScrollArea" | "Separator" | "ToolIcon";
|
|
2
2
|
export type UsageFamily = "Compositions" | "Actions" | "Inputs" | "Choices" | "Status" | "Navigation" | "Data" | "Feedback" | "Menus" | "Charts" | "Other";
|
|
3
3
|
export type ComponentUsage = {
|
|
4
4
|
name: UsageName;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.generated.d.ts","sourceRoot":"","sources":["../../src/showcase/usage.generated.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"usage.generated.d.ts","sourceRoot":"","sources":["../../src/showcase/usage.generated.ts"],"names":[],"mappings":"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"}
|
|
@@ -91,6 +91,17 @@ export const USAGE = [
|
|
|
91
91
|
words: '"`title` is Title Case, `Verb + Noun`, a statement — never a question. `Delete Project`, not `Delete this project?`." (https://vercel.com/geist/destructive-action-modal) "`description` is sentence case, names the consequence, and interpolates the specific resource when relevant. `<b>my-project</b> and all its deployments will be permanently deleted.` reads stronger than `This project and all its deployments will be deleted.`." (https://vercel.com/geist/destructive-action-modal) "`confirmLabel` matches the title 1:1. Never generic (`Confirm`, `OK`, `Continue`), never a bare verb (`Delete`)." (https://vercel.com/geist/destructive-action-modal) "`cancelLabel` defaults to `Cancel`. Override when Cancel is ambiguous, such as `Keep Turn Running` when the primary action is itself a cancellation." (https://vercel.com/geist/destructive-action-modal) "`verificationPhrase`: for entity deletes, type the **resource name itself** (`my-project`) and pair with `verificationLabel="project name"` so the prompt reads `To confirm, type the project name "my-project"`. That\'s the canonical signal that the user knows which thing they\'re acting on. Fall back to a lowercase verb phrase (`disable vercel authentication`) only when there\'s no entity to name." (https://vercel.com/geist/destructive-action-modal) "`irreversibleDescription` names the specific action and resource and ends with `cannot be undone.` — `Deleting my-project cannot be undone.` rather than the generic `This cannot be undone.`. Omit the prop entirely for reversible actions; the prop\'s absence is the signal, not a falsy value." (https://vercel.com/geist/destructive-action-modal) "`error` surfaces the API failure verbatim in Vercel voice: `Couldn\'t save settings. Try again.`. Never dump a raw error object." (https://vercel.com/geist/destructive-action-modal) "Pair the post-confirm success toast verb 1:1 with the primary button: `Delete Project` button, `Project deleted` toast. Never `Project removed`." (https://vercel.com/geist/destructive-action-modal) "Close irreversible bodies with `This cannot be undone.`; close cascade-only bodies with `Some effects cannot be undone.`. Don’t claim full irreversibility for a partial cascade." (https://vercel.com/geist/modal) Ours: the title is sentence case and names the record, "Remove pec@acme.it", and the confirm repeats the verb and the noun, "Remove mailbox", so the two share a verb and not every word; its success toast uses the same verb ("Mailbox removed"). The description names the record in medium weight.',
|
|
92
92
|
access: '"The verification input is associated with its prompt via `aria-labelledby` + `htmlFor`. Screen readers announce the full prompt (`To confirm, type "delete my-project"`) on focus." (https://vercel.com/geist/destructive-action-modal) "The Warning icon in the irreversibility band is `aria-hidden`; the sentence carries the meaning so nothing is announced twice." (https://vercel.com/geist/destructive-action-modal) "Focus stays inside the modal across an `error` transition so the user can retry without losing context. After success, return focus to the trigger." (https://vercel.com/geist/destructive-action-modal) "Set `aria-labelledby` to the `Modal.Title` id so screen readers announce the title on open." (https://vercel.com/geist/modal) "Keep the Cancel button literally `Cancel` so screen-reader users hear a stable dismissal label across destructive flows." (https://vercel.com/geist/modal) Ours: `role="alertdialog"` named by its title and described by its consequence; the note is `role="note"` with its icon hidden. Focus starts on Cancel, or in the field with `verify`.',
|
|
93
93
|
},
|
|
94
|
+
{
|
|
95
|
+
name: "EntryPicture",
|
|
96
|
+
module: "entry-picture",
|
|
97
|
+
family: "Compositions",
|
|
98
|
+
summary: "The art-directed cut-out an entry page stands beside its centred column.",
|
|
99
|
+
when: "A whole-page moment with a picture, at the window's left edge: a sign-in handed to Nadia, an invitation, an invite to a company's Alveare.",
|
|
100
|
+
instead: "A failure page centres its picture above the words (\"Failure surfaces\"). A first use's picture is `EmptyState`'s. Nadia's desktop entry screens are `EntryScene` and Alveare's are `HiveScene`.",
|
|
101
|
+
behaviour: "One whole cut-out fixed to the window's floor at the left edge, so a page taller than the window never cuts its feet. It keeps its own shape and is never wider than half its pixels, the width it stays sharp at on a DPR 2 screen, nor than the room left of the centred `column`, nor taller than 85 % of the window. It shows only from `lg`: below, the task keeps the screen and the browser does not fetch it. A page draws it only in the state the picture is about, so a page that cannot go on never shows one welcoming the person.",
|
|
102
|
+
words: "None: the picture carries no caption.",
|
|
103
|
+
access: "Decorative and inert: hidden from assistive technology, never focused or clicked.",
|
|
104
|
+
},
|
|
94
105
|
{
|
|
95
106
|
name: "EntryScene",
|
|
96
107
|
module: "entry-scene",
|
|
@@ -124,6 +135,17 @@ export const USAGE = [
|
|
|
124
135
|
words: '"Title is Title Case and names the entity (`Deployment Details`, `Member Profile`), not the page action." (https://vercel.com/geist/sheet) "Body is read-mostly: sentence case prose with Title Case sub-headings. Action buttons are optional; when present, follow `Verb + Noun`." (https://vercel.com/geist/sheet) Ours: the title is sentence case and names the job and its object: "Connect Telegram", "Add a skill". The step reads "Step N of M". The primary says what it does: "Connect", "Continue", never "OK".',
|
|
125
136
|
access: '"Trap focus inside the sheet while it’s open and return focus to the trigger row on close so keyboard users keep their place in the list." (https://vercel.com/geist/sheet) "Provide a visible close button labeled `Close` (or an icon button with `aria-label="Close"`) since clicking outside doesn’t dismiss." (https://vercel.com/geist/sheet) "Announce the sheet with `aria-labelledby` pointing at the title; pair it with `aria-describedby` only when the body is short and load-bearing." (https://vercel.com/geist/sheet) Ours: a modal dialog named by its title; focus returns to the opener on close, or to `finalFocus` when the opener is gone. The step is read before the title.',
|
|
126
137
|
},
|
|
138
|
+
{
|
|
139
|
+
name: "InviteCard",
|
|
140
|
+
module: "invite-card",
|
|
141
|
+
family: "Compositions",
|
|
142
|
+
summary: "A link that opens an app: the app's mark, the invite's words, the action that opens it, the installers for a computer without the app, and the code that opens the same link on a phone.",
|
|
143
|
+
when: "The page an invite link opens: Alveare's invite to a company. It stands centred on an entry page, with `EntryPicture` at the window's left edge.",
|
|
144
|
+
instead: "An invitation to a role the person accepts in the Portal is the Portal's invitation card. Downloads with formats and steps is the Portal's Downloads page. A code the phone takes to sign in is `QrCode` in Nadia's pairing drawer.",
|
|
145
|
+
behaviour: "The mark, the title and the one line are centred; the open action fills the card's width under them. The installers are one row per computer, each with its mark, its name, its size and its download, so every row lines up whatever its words; the computer the reader is on carries the `suggested` badge. The installers show from `md` and the phone's code from `lg`, because a phone neither installs a computer's app nor scans its own screen. A link that holds no invite passes the title and the line alone.",
|
|
146
|
+
words: "The title says what the person joins: *Join your company on Alveare*. The line says what happens and what to do if it does not. Each download is *Download*, named for its computer to assistive technology; the phone's line says what the code opens and how: *Open this invite on your phone*, *Point your phone's camera at the code*.",
|
|
147
|
+
access: "The title is the page's level-1 heading and the installers a list under its own heading. The mark is decorative; the code is an image named by what it opens.",
|
|
148
|
+
},
|
|
127
149
|
{
|
|
128
150
|
name: "LibraryShelf",
|
|
129
151
|
module: "library-shelf",
|
|
@@ -428,7 +450,7 @@ export const USAGE = [
|
|
|
428
450
|
summary: "Several switches and selects in one card: each row its label on the left and its control on the right.",
|
|
429
451
|
when: "A card of switches and selects that the card's one description covers: a project's Git switches, a team's notification channels, a set of defaults, how long a computer stays awake beside whether the window goes to the tray.",
|
|
430
452
|
instead: "One setting is a SettingsField. A text box is a field of its own card.",
|
|
431
|
-
behaviour: "A row with `options` is a select, a row with `checked` a switch,
|
|
453
|
+
behaviour: "A row with `options` is a select, a row with `checked` a switch, a row with `control` draws a control whose usage page puts it in a row, such as ThemeModeSwitcher, and a row with `shows` is a fact the card shows and nobody changes there, such as the app's version, its value as text where a control would stand; a card may hold any of them together, as Vercel's Root Directory card holds its switches; `stateLabels` is required once any row is a switch. Required on every row that takes a value: the label and its `info` (an (i) with its sentence in a tooltip and on the control); a `shows` row has its label alone. No help line sits under a row. A switch row shows its state word beside the switch (`stateLabels`) and is controlled, so the word always follows the switch. Rows stand 16 px apart; below 28rem a row stacks its control under its label. \"Pair with a form footer only when the setting needs an explicit `Save` step.\" (https://vercel.com/geist/toggle) Ours: a switch is a draft the card's Save applies.",
|
|
432
454
|
words: '"Title Case noun phrase, 1–4 words, naming what is true when ON: `Password Protection`, not `Enable Password Protection`." (https://vercel.com/geist/toggle) Ours: sentence case, a noun for what it controls ("Pull request comments"), the same for a switch as for a select. "Render an optional one-sentence description as a sibling under the label that explains ON only. Don’t describe OFF; it’s the negation." (https://vercel.com/geist/toggle) Ours: that sentence is `info.text`. "Options are Title Case when short and match canonical branding (`Next.js`, not `NextJS`); keep the same register across the list." (https://vercel.com/geist/select) Ours: a select\'s options are sentence case.',
|
|
433
455
|
access: "Each row's control is named by the row's label and described by its info and its error. The info button has its own name and opens on focus.",
|
|
434
456
|
},
|
|
@@ -1184,10 +1206,10 @@ export const USAGE = [
|
|
|
1184
1206
|
name: "SettingsFactsSection",
|
|
1185
1207
|
module: "settings-facts",
|
|
1186
1208
|
family: "Data",
|
|
1187
|
-
summary: "Read-only facts about one object, framed as a card with a title, a line,
|
|
1188
|
-
when: "Read-only facts about one object: who it is, where it belongs, its identifiers. `SettingsFactsSection` frames them as a card
|
|
1209
|
+
summary: "Read-only facts about one object, framed as a card with a title, a line, the facts and a footer.",
|
|
1210
|
+
when: "Read-only facts about one object: who it is, where it belongs, its identifiers; and a status, a read-only card whose `action` is the one action that fixes it. `SettingsFactsSection` frames them as a card; `ObjectFacts` is the list alone.",
|
|
1189
1211
|
instead: "Facts a person changes are a `SettingsSection` with its own Save. One server-given value, an ID, is a `SettingsSection` with the value in a read-only mono `InputGroup` and its copy button, no Save. Facts compared across records are a table. A relation is its identity or a `Tag`, never its own card.",
|
|
1190
|
-
behaviour:
|
|
1212
|
+
behaviour: "\"Use `<Description>` for definition-list metadata: a short Title Case key paired with a single value (`Last Deployed`, `Region`, `Plan`).\" (https://vercel.com/geist/description) Ours: required: the description and the footer's left line (`footerHint`), as on a `SettingsSection`. Two places take a control, each for one job: `command` at the title's right is a command on the facts, the Edit that opens their editor; `action` at the footer's right, beside its line, is the one action the card's state asks for, as a status card's fix (Update, Start) and every Vercel settings card's button stand there. Facts are plain pairs, the label above its value, in two equal columns from 640 px (`sm`) and one column below it. Every label stays when its value is missing, as *—*. A long value spans both columns. No fact gets a box of its own. In a side column, `presentation=\"summary\"` drops the card, the description and the footer line.",
|
|
1191
1213
|
words: '"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: labels are nouns in sentence case, no colon: *VAT number*. Identifiers in mono with a copy button, dates in the person\'s locale. The footer line says what the facts are for or links to the docs.',
|
|
1192
1214
|
access: '"Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t put interactive controls in the title slot." (https://vercel.com/geist/description) Ours: a `dl` of `dt` and `dd`, each value named by its label. The section is labelled by its heading, which also takes focus when an editor closes. A dash carries screen-reader text.',
|
|
1193
1215
|
},
|
|
@@ -1396,9 +1418,9 @@ export const USAGE = [
|
|
|
1396
1418
|
summary: "The update offer at the foot of a desktop app's sidebar, above the account.",
|
|
1397
1419
|
when: "Nadia's and Alveare's sidebar foot, only while an update is on offer or has just been installed.",
|
|
1398
1420
|
instead: "A failed update or a download that needs the person is a NoticeBanner; the Portal's way to get the app is its Downloads row.",
|
|
1399
|
-
behaviour: "
|
|
1400
|
-
words: '
|
|
1401
|
-
access: 'The
|
|
1421
|
+
behaviour: "One outlined row of the column's width, shaped as the sidebar's Find: available, a download icon in the primary colour, the line, and a small primary command at the end that keeps its place and says its pending word while it runs; updated, a check, the line and a ghost close. A line too long for the column is cut with an ellipsis. Narrow, the row is one icon button whose tooltip shows the line. Nothing else in the window offers the update: no toast, no banner.",
|
|
1422
|
+
words: 'One line names the product, its number and what happened ("Nadia 0.42.0 is ready", "Updated to Nadia 0.42.0"); the command is one verb ("Update").',
|
|
1423
|
+
access: 'The row is a region named by its line. The narrow button is named by its command and the line ("Update: Nadia 0.42.0 is ready"), and the close carries its label; a running command is aria-busy.',
|
|
1402
1424
|
},
|
|
1403
1425
|
{
|
|
1404
1426
|
name: "WaitingLine",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nadicodeai/ui",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.170",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"imports": {
|
|
6
6
|
"#jsx": "./src/jsx/index.ts",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"@base-ui/react": "^1.9.0",
|
|
73
73
|
"@iconify-icons/logos": "^2.0.3",
|
|
74
74
|
"@iconify/react": "^6.0.2",
|
|
75
|
-
"@nadicodeai/design-system": "12.1.
|
|
75
|
+
"@nadicodeai/design-system": "12.1.170",
|
|
76
76
|
"@tanstack/react-table": "^9.3.1",
|
|
77
77
|
"@vgpu/wgsl": "0.6.0",
|
|
78
78
|
"class-variance-authority": "^0.7.1",
|