@nadicodeai/ui 12.1.123 → 12.1.125
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/AGENTS.md +3 -2
- package/dist/components/account-menu.d.ts +1 -1
- package/dist/components/account-menu.d.ts.map +1 -1
- package/dist/components/agent-list-row.d.ts +6 -6
- package/dist/components/agent-list-row.d.ts.map +1 -1
- package/dist/components/agent-list-row.js +5 -5
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/gauge.d.ts +1 -1
- package/dist/components/gauge.js +1 -1
- package/dist/components/identity-mark.d.ts +3 -1
- package/dist/components/identity-mark.d.ts.map +1 -1
- package/dist/components/identity-mark.js +10 -4
- package/dist/components/object-fact-value.d.ts +32 -0
- package/dist/components/object-fact-value.d.ts.map +1 -0
- package/dist/components/object-fact-value.js +24 -0
- package/dist/components/object-page.d.ts +2 -2
- package/dist/components/object-page.d.ts.map +1 -1
- package/dist/components/object-page.js +5 -3
- package/dist/components/status-badge.d.ts +3 -2
- package/dist/components/status-badge.d.ts.map +1 -1
- package/dist/components/status-badge.js +3 -2
- package/dist/components/tag.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/company-logo.d.ts +2 -1
- package/dist/internal/company-logo.d.ts.map +1 -1
- package/dist/internal/company-logo.js +6 -2
- package/dist/showcase/specimens/index.d.ts +1 -1
- package/dist/showcase/specimens/navigation.js +1 -1
- package/dist/showcase/specimens/status.d.ts +1 -1
- package/dist/showcase/specimens/status.d.ts.map +1 -1
- package/dist/showcase/specimens/status.js +2 -2
- 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 +20 -20
- package/package.json +2 -2
- package/dist/components/status-dot.d.ts +0 -53
- package/dist/components/status-dot.d.ts.map +0 -1
- package/dist/components/status-dot.js +0 -54
package/AGENTS.md
CHANGED
|
@@ -52,5 +52,6 @@ and `lint` checks. A component change a person can see goes through
|
|
|
52
52
|
|
|
53
53
|
`npm run dev -w @nadicodeai/ui` watches source and refreshes `dist/`;
|
|
54
54
|
`build:dev` refreshes it once. Validation policy is in
|
|
55
|
-
`../../docs/agents/develop.md`.
|
|
56
|
-
|
|
55
|
+
`../../docs/agents/develop.md`. Find a shadcn or assistant-ui component through
|
|
56
|
+
its current discovery; `--overwrite` replaces a component only with
|
|
57
|
+
authorization.
|
|
@@ -50,7 +50,7 @@ export type AccountMenuChoice = {
|
|
|
50
50
|
/** Each option's name, its mark, and one muted line under the name when the name alone does not say what it is. */
|
|
51
51
|
options: readonly {
|
|
52
52
|
value: string;
|
|
53
|
-
label:
|
|
53
|
+
label: ReactNode;
|
|
54
54
|
mark?: ReactNode;
|
|
55
55
|
detail?: string;
|
|
56
56
|
}[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-menu.d.ts","sourceRoot":"","sources":["../../src/components/account-menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAC;AAGrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAiB5D,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAIjE,2FAA2F;AAC3F,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,QAAQ,EACR,WAAmB,GACpB,EAAE,wBAAwB,+BAgC1B;AAED,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG;IAC7C,8CAA8C;IAC9C,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,mHAAmH;IACnH,OAAO,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"account-menu.d.ts","sourceRoot":"","sources":["../../src/components/account-menu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties } from "react";
|
|
2
2
|
import { type AgentOrbFigure, type AgentOrbState } from "./agent-orb.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type StatusBadgeTone } from "./status-badge.js";
|
|
4
4
|
/**
|
|
5
5
|
* One Agent in a list of them: the orb, the name, and the line that says what
|
|
6
6
|
* the Agent is doing now or what it is for.
|
|
@@ -8,9 +8,9 @@ import { type StatusTone } from "./status-dot.js";
|
|
|
8
8
|
* @family Navigation
|
|
9
9
|
* @when Nadia's Agents in her window's sidebar, and a website scene that shows a list of Agents.
|
|
10
10
|
* @instead An Agent as a record among others in a page's list is a RecordList row with an agent IdentityMark; an Agent's own page heads with ObjectPage.
|
|
11
|
-
* @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone
|
|
12
|
-
* @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia's list says "Working", "Idle" or "Needs you"; the
|
|
13
|
-
* @access The orb is decorative; the name and the state line are the row's text, read by its control.
|
|
11
|
+
* @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone draws the state line as a small StatusBadge; without a tone it stays plain text. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. In Nadia's list the row is at least 52 px high, her orb at 32 px in her real state, in the narrow column from 640 to 899 px as in the wide one.
|
|
12
|
+
* @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia's list says "Working", "Idle" or "Needs you"; the badge marks a state that needs the person ("Needs you", a failed set-up), and the orb shows working by itself.
|
|
13
|
+
* @access The orb is decorative; the name and the state line are the row's text, read by its control. StatusBadge owns its decorative mark, so the line carries its meaning.
|
|
14
14
|
*/
|
|
15
15
|
export declare function AgentListRow({ className, color, current, form, motionKey, name, narrow, size, state, stateLine, stateTone, ...props }: Omit<React.ComponentProps<"span">, "color"> & {
|
|
16
16
|
/** The pigment of the Agent's chosen form; Nadia's striped ribbon keeps her own. */
|
|
@@ -26,7 +26,7 @@ export declare function AgentListRow({ className, color, current, form, motionKe
|
|
|
26
26
|
state?: AgentOrbState;
|
|
27
27
|
/** What the Agent is doing, or what it is for. Absent, the name stands alone. */
|
|
28
28
|
stateLine?: string;
|
|
29
|
-
/** How the state line stands: a failure is `
|
|
30
|
-
stateTone?:
|
|
29
|
+
/** How the state line stands: a failure is `danger`. Absent, the line stays plain text. */
|
|
30
|
+
stateTone?: StatusBadgeTone;
|
|
31
31
|
}): import("react").JSX.Element;
|
|
32
32
|
//# sourceMappingURL=agent-list-row.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-list-row.d.ts","sourceRoot":"","sources":["../../src/components/agent-list-row.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAY,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,
|
|
1
|
+
{"version":3,"file":"agent-list-row.d.ts","sourceRoot":"","sources":["../../src/components/agent-list-row.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAY,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG9E;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,KAAK,EACL,OAAe,EACf,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,MAAc,EACd,IAAS,EACT,KAAc,EACd,SAAS,EACT,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG;IAC/C,oFAAoF;IACpF,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B,+BAkCA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { AgentOrb } from "./agent-orb.js";
|
|
4
|
-
import {
|
|
4
|
+
import { StatusBadge } from "./status-badge.js";
|
|
5
5
|
import { cn } from "../lib/utils.js";
|
|
6
6
|
/**
|
|
7
7
|
* One Agent in a list of them: the orb, the name, and the line that says what
|
|
@@ -10,10 +10,10 @@ import { cn } from "../lib/utils.js";
|
|
|
10
10
|
* @family Navigation
|
|
11
11
|
* @when Nadia's Agents in her window's sidebar, and a website scene that shows a list of Agents.
|
|
12
12
|
* @instead An Agent as a record among others in a page's list is a RecordList row with an agent IdentityMark; an Agent's own page heads with ObjectPage.
|
|
13
|
-
* @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone
|
|
14
|
-
* @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia's list says "Working", "Idle" or "Needs you"; the
|
|
15
|
-
* @access The orb is decorative; the name and the state line are the row's text, read by its control.
|
|
13
|
+
* @behaviour It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone draws the state line as a small StatusBadge; without a tone it stays plain text. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. In Nadia's list the row is at least 52 px high, her orb at 32 px in her real state, in the narrow column from 640 to 899 px as in the wide one.
|
|
14
|
+
* @words The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia's list says "Working", "Idle" or "Needs you"; the badge marks a state that needs the person ("Needs you", a failed set-up), and the orb shows working by itself.
|
|
15
|
+
* @access The orb is decorative; the name and the state line are the row's text, read by its control. StatusBadge owns its decorative mark, so the line carries its meaning.
|
|
16
16
|
*/
|
|
17
17
|
export function AgentListRow({ className, color, current = false, form, motionKey, name, narrow = false, size = 40, state = "idle", stateLine, stateTone, ...props }) {
|
|
18
|
-
return (_jsxs("span", { className: cn("flex w-full min-w-0 items-center gap-3 text-left text-sm", narrow && "justify-center", className), "data-slot": "agent-list-row", "data-current": current || undefined, ...props, children: [_jsx(AgentOrb, { color: color, decorative: true, form: form, motionKey: motionKey, size: size, state: state }), _jsxs("span", { className: cn("grid min-w-0", narrow && "sr-only"), children: [_jsx("span", { className: cn("truncate text-foreground", current && "font-medium"), children: name }), stateLine ? (
|
|
18
|
+
return (_jsxs("span", { className: cn("flex w-full min-w-0 items-center gap-3 text-left text-sm", narrow && "justify-center", className), "data-slot": "agent-list-row", "data-current": current || undefined, ...props, children: [_jsx(AgentOrb, { color: color, decorative: true, form: form, motionKey: motionKey, size: size, state: state }), _jsxs("span", { className: cn("grid min-w-0", narrow && "sr-only"), children: [_jsx("span", { className: cn("truncate text-foreground", current && "font-medium"), children: name }), stateLine ? (_jsx("span", { className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground", children: stateTone ? (_jsx(StatusBadge, { label: stateLine, size: "sm", tone: stateTone })) : (_jsx("span", { className: "truncate", children: stateLine })) })) : null] })] }));
|
|
19
19
|
}
|
|
@@ -28,7 +28,7 @@ type BadgeProps = Omit<useRender.ComponentProps<"span">, "onClick" | "children"
|
|
|
28
28
|
* type beside it: `sm` (20 px) next to small labels, `md` (24 px) in a row, `lg` (32 px) in a
|
|
29
29
|
* header. The category fills (teal, purple, pink) name a kind.
|
|
30
30
|
* @instead "For a colored dot without text, use `Status Dot`." (https://vercel.com/geist/badge)
|
|
31
|
-
* Ours:
|
|
31
|
+
* Ours: status dots are not used; a state keeps its mark and word together in `StatusBadge`.
|
|
32
32
|
* "For clickable filter chips that toggle a query, use the `pill` variant or a small `Button`." (https://vercel.com/geist/badge)
|
|
33
33
|
* Ours: there is no `pill` variant; a filter that toggles a query is a `Button` or
|
|
34
34
|
* `CollectionFilters`. For a state use `StatusBadge`, which picks the tone and its mark: the gray,
|
package/dist/components/badge.js
CHANGED
|
@@ -35,7 +35,7 @@ const badgeVariants = cva("group/badge inline-flex w-fit max-w-full shrink-0 ite
|
|
|
35
35
|
* type beside it: `sm` (20 px) next to small labels, `md` (24 px) in a row, `lg` (32 px) in a
|
|
36
36
|
* header. The category fills (teal, purple, pink) name a kind.
|
|
37
37
|
* @instead "For a colored dot without text, use `Status Dot`." (https://vercel.com/geist/badge)
|
|
38
|
-
* Ours:
|
|
38
|
+
* Ours: status dots are not used; a state keeps its mark and word together in `StatusBadge`.
|
|
39
39
|
* "For clickable filter chips that toggle a query, use the `pill` variant or a small `Button`." (https://vercel.com/geist/badge)
|
|
40
40
|
* Ours: there is no `pill` variant; a filter that toggles a query is a `Button` or
|
|
41
41
|
* `CollectionFilters`. For a state use `StatusBadge`, which picks the tone and its mark: the gray,
|
|
@@ -33,7 +33,7 @@ type GaugeProps = Omit<Meter.Root.Props, "value" | "min" | "max" | "children" |
|
|
|
33
33
|
* `xs` (20 px), `sm` (32), `md` (64) and `lg` (128). The centre holds the number or an icon.
|
|
34
34
|
* @instead "For determinate task progress with a known total (uploads, multi-step setup), use `Progress`." (https://vercel.com/geist/gauge)
|
|
35
35
|
* "For binary or enumerated state, use `Status Dot` for deployments or `Badge` for everything else." (https://vercel.com/geist/gauge)
|
|
36
|
-
* Ours:
|
|
36
|
+
* Ours: every state uses `StatusBadge`. A single figure on its own is a `KpiCard`. A wait
|
|
37
37
|
* of unknown length is the waiting line; the gauge has no indeterminate form. Two shares of one
|
|
38
38
|
* whole are a chart: the gauge is a control for one ratio, never a chart.
|
|
39
39
|
* @behaviour "Use `arc="equal"` for true ratios so 50% reads as exactly half." (https://vercel.com/geist/gauge)
|
package/dist/components/gauge.js
CHANGED
|
@@ -37,7 +37,7 @@ const GAUGE_ARC_MOTION = "transition-[stroke-dasharray,stroke-dashoffset,stroke]
|
|
|
37
37
|
* `xs` (20 px), `sm` (32), `md` (64) and `lg` (128). The centre holds the number or an icon.
|
|
38
38
|
* @instead "For determinate task progress with a known total (uploads, multi-step setup), use `Progress`." (https://vercel.com/geist/gauge)
|
|
39
39
|
* "For binary or enumerated state, use `Status Dot` for deployments or `Badge` for everything else." (https://vercel.com/geist/gauge)
|
|
40
|
-
* Ours:
|
|
40
|
+
* Ours: every state uses `StatusBadge`. A single figure on its own is a `KpiCard`. A wait
|
|
41
41
|
* of unknown length is the waiting line; the gauge has no indeterminate form. Two shares of one
|
|
42
42
|
* whole are a chart: the gauge is a control for one ratio, never a chart.
|
|
43
43
|
* @behaviour "Use `arc="equal"` for true ratios so 50% reads as exactly half." (https://vercel.com/geist/gauge)
|
|
@@ -33,6 +33,8 @@ export type IdentityMarkProps = {
|
|
|
33
33
|
* theme, or a square icon in its own colours (an SVG tile), which fills the tile as it is.
|
|
34
34
|
*/
|
|
35
35
|
logo?: string;
|
|
36
|
+
/** The company's standing, independent of which directory opened it. */
|
|
37
|
+
edition?: "company" | "partner";
|
|
36
38
|
} | {
|
|
37
39
|
kind: "person";
|
|
38
40
|
name: string;
|
|
@@ -54,7 +56,7 @@ export type IdentityMarkProps = {
|
|
|
54
56
|
* @family Status
|
|
55
57
|
* @when The first thing in a record's row (32), at the head of its object page (64), in a feed or a sidebar identity line (24), on a Library entry (40), for the company at the top of Nadia's list (28): wherever it tells a person which thing they are looking at.
|
|
56
58
|
* @instead An icon beside a card's title, a KPI's label or a section heading only repeats the words and is left out. A picture for a first use or a whole-page moment is the empty state's or the page's own. A model is its `ModelIdentity`.
|
|
57
|
-
* @behaviour Static, except an Agent's orb, which moves with her state. An Agent is always her real orb from the orb engine, at the largest orb size not above the mark's, with no tile and no ring, never an avatar or a painted circle, and `frame` lets the product wrap that orb, such as in the transition that carries her to her page; an app keeps its own logo in its bordered tile on the page ground, or its first letter when it has no logo; a company is its logo: the one white ink Sofia kept from its site on a black
|
|
59
|
+
* @behaviour Static, except an Agent's orb, which moves with her state. An Agent is always her real orb from the orb engine, at the largest orb size not above the mark's, with no tile and no ring, never an avatar or a painted circle, and `frame` lets the product wrap that orb, such as in the transition that carries her to her page; an app keeps its own logo in its bordered tile on the page ground, or its first letter when it has no logo; a company is its logo: the one white ink Sofia kept from its site on a black arch with its edition's colour edge in both themes, or a square SVG icon in its own colours filling the tile, as Vercel shows a project's favicon; its two initials on a compact arch, cobalto for a company and arancio for an approved Partner, until a logo is found or when the stored logo does not load. The edition follows the company's standing, never the directory it was opened from; a person is their picture, then their initials, in a round mark; a record with its own object picture, such as a Library skill or plugin, draws that picture on its kind's ground; a record with no picture of its own takes its kind's own icon, the same icon its section has in the navigation (Mail for a mailbox, a server for an MCP server, a key for a password), in a ringed tile on the card ground; a Library skill takes the purple category ground with the Skills icon and a plugin the `info-soft` ground with the Plugins icon, both without a ring, so the ground says which kind it is, and an entry that has its own object picture draws it on that ground in the icon's place. A company arch has a semicircular top and `{rounded.sm}` bottom corners; a record tile takes `{rounded.sm}` (6 px) corners, `{rounded.md}` (8 px) at 40 and 64; an app's tile takes `{rounded.md}` at every size.
|
|
58
60
|
* @words None of its own: the record's name stands beside it. Initials stand for a company or a person: the first letters of the name's first two words. An app with no logo takes the first letter of its name as a monogram, and no other kind takes letters.
|
|
59
61
|
* @access Decorative beside the record's name. Alone, as in a narrow rail, `label` names it.
|
|
60
62
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-mark.d.ts","sourceRoot":"","sources":["../../src/components/identity-mark.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEnF,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAKnE,MAAM,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAE3D,qHAAqH;AACrH,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;CAC5C,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,4GAA4G;IAC5G,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,4GAA4G;IAC5G,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,CACA;IACE,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC;IACrF,kGAAkG;IAClG,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,SAAS,CAAC;CAC1C,GACD,CAAC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAAC,GAC7C;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"identity-mark.d.ts","sourceRoot":"","sources":["../../src/components/identity-mark.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEnF,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAKnE,MAAM,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAE3D,qHAAqH;AACrH,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;CAC5C,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,4GAA4G;IAC5G,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,4GAA4G;IAC5G,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,CACA;IACE,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC;IACrF,kGAAkG;IAClG,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,SAAS,CAAC;CAC1C,GACD,CAAC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAAC,GAC7C;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,0FAA0F;IAC1F,IAAI,EAAE,aAAa,CAAC;IACpB,oEAAoE;IACpE,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,4GAA4G;IAC5G,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CACJ,CAAC;AAmGF;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,SAAS,CA0EhE"}
|
|
@@ -17,6 +17,8 @@ const TONES = {
|
|
|
17
17
|
skill: "bg-category-purple text-category-purple-foreground",
|
|
18
18
|
plugin: "bg-info-soft text-info-soft-foreground",
|
|
19
19
|
teal: "bg-category-teal text-category-teal-foreground",
|
|
20
|
+
company: "bg-nc-identity-cobalto text-nc-identity-white",
|
|
21
|
+
partner: "bg-nc-identity-arancio text-nc-identity-ink",
|
|
20
22
|
};
|
|
21
23
|
const SVG_DATA = "data:image/svg+xml";
|
|
22
24
|
/**
|
|
@@ -56,7 +58,11 @@ function avatarName(label) {
|
|
|
56
58
|
return label ? { label } : { decorative: true };
|
|
57
59
|
}
|
|
58
60
|
function Tile({ kind, label, size, tone, children, }) {
|
|
59
|
-
return (_jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center",
|
|
61
|
+
return (_jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center", kind === "company"
|
|
62
|
+
? "rounded-t-full rounded-b-sm"
|
|
63
|
+
: size >= 40
|
|
64
|
+
? "rounded-md"
|
|
65
|
+
: "rounded-sm", TONES[tone]), "data-kind": kind, "data-slot": "identity-mark", style: { width: size, height: size }, ...naming(label), children: children }));
|
|
60
66
|
}
|
|
61
67
|
/**
|
|
62
68
|
* What says which thing a record is, at a fixed size at the start of its row,
|
|
@@ -66,7 +72,7 @@ function Tile({ kind, label, size, tone, children, }) {
|
|
|
66
72
|
* @family Status
|
|
67
73
|
* @when The first thing in a record's row (32), at the head of its object page (64), in a feed or a sidebar identity line (24), on a Library entry (40), for the company at the top of Nadia's list (28): wherever it tells a person which thing they are looking at.
|
|
68
74
|
* @instead An icon beside a card's title, a KPI's label or a section heading only repeats the words and is left out. A picture for a first use or a whole-page moment is the empty state's or the page's own. A model is its `ModelIdentity`.
|
|
69
|
-
* @behaviour Static, except an Agent's orb, which moves with her state. An Agent is always her real orb from the orb engine, at the largest orb size not above the mark's, with no tile and no ring, never an avatar or a painted circle, and `frame` lets the product wrap that orb, such as in the transition that carries her to her page; an app keeps its own logo in its bordered tile on the page ground, or its first letter when it has no logo; a company is its logo: the one white ink Sofia kept from its site on a black
|
|
75
|
+
* @behaviour Static, except an Agent's orb, which moves with her state. An Agent is always her real orb from the orb engine, at the largest orb size not above the mark's, with no tile and no ring, never an avatar or a painted circle, and `frame` lets the product wrap that orb, such as in the transition that carries her to her page; an app keeps its own logo in its bordered tile on the page ground, or its first letter when it has no logo; a company is its logo: the one white ink Sofia kept from its site on a black arch with its edition's colour edge in both themes, or a square SVG icon in its own colours filling the tile, as Vercel shows a project's favicon; its two initials on a compact arch, cobalto for a company and arancio for an approved Partner, until a logo is found or when the stored logo does not load. The edition follows the company's standing, never the directory it was opened from; a person is their picture, then their initials, in a round mark; a record with its own object picture, such as a Library skill or plugin, draws that picture on its kind's ground; a record with no picture of its own takes its kind's own icon, the same icon its section has in the navigation (Mail for a mailbox, a server for an MCP server, a key for a password), in a ringed tile on the card ground; a Library skill takes the purple category ground with the Skills icon and a plugin the `info-soft` ground with the Plugins icon, both without a ring, so the ground says which kind it is, and an entry that has its own object picture draws it on that ground in the icon's place. A company arch has a semicircular top and `{rounded.sm}` bottom corners; a record tile takes `{rounded.sm}` (6 px) corners, `{rounded.md}` (8 px) at 40 and 64; an app's tile takes `{rounded.md}` at every size.
|
|
70
76
|
* @words None of its own: the record's name stands beside it. Initials stand for a company or a person: the first letters of the name's first two words. An app with no logo takes the first letter of its name as a monogram, and no other kind takes letters.
|
|
71
77
|
* @access Decorative beside the record's name. Alone, as in a narrow rail, `label` names it.
|
|
72
78
|
*/
|
|
@@ -83,8 +89,8 @@ export function IdentityMark(props) {
|
|
|
83
89
|
case "person":
|
|
84
90
|
return (_jsxs(Avatar, { "data-kind": "person", "data-slot": "identity-mark", style: { width: size, height: size }, ...avatarName(props.label), children: [props.image ? _jsx(AvatarImage, { alt: "", src: props.image }) : null, _jsx(AvatarFallback, { style: { fontSize: measures.initials }, children: identityInitials(props.name) })] }));
|
|
85
91
|
case "company": {
|
|
86
|
-
const initials = (_jsx(Tile, { kind: "company", label: props.label, size: size, tone: "
|
|
87
|
-
return props.logo ? (_jsx(CompanyLogo, { colourTile: logoIsColourTile(props.logo), fallback: initials, logo: props.logo, naming: naming(props.label), size: size })) : (initials);
|
|
92
|
+
const initials = (_jsx(Tile, { kind: "company", label: props.label, size: size, tone: props.edition ?? "company", children: _jsx("span", { "aria-hidden": "true", className: "leading-none font-semibold", style: { fontSize: measures.initials }, children: identityInitials(props.name) }) }));
|
|
93
|
+
return props.logo ? (_jsx(CompanyLogo, { colourTile: logoIsColourTile(props.logo), edition: props.edition ?? "company", fallback: initials, logo: props.logo, naming: naming(props.label), size: size })) : (initials);
|
|
88
94
|
}
|
|
89
95
|
case "record":
|
|
90
96
|
return (_jsx(Tile, { kind: "record", label: props.label, size: size, tone: props.tone ?? "neutral", children: props.picture ? (_jsx("img", { alt: "", className: "size-[84%] object-contain", "data-slot": "identity-mark-picture", src: props.picture })) : (_jsx(props.icon, { "aria-hidden": "true", size: measures.icon })) }));
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
declare const KINDS: {
|
|
3
|
+
readonly agents: {
|
|
4
|
+
readonly icon: import("lucide-react").LucideIcon;
|
|
5
|
+
readonly tone: "blue";
|
|
6
|
+
};
|
|
7
|
+
readonly installations: {
|
|
8
|
+
readonly icon: import("lucide-react").LucideIcon;
|
|
9
|
+
readonly tone: "teal";
|
|
10
|
+
};
|
|
11
|
+
readonly customers: {
|
|
12
|
+
readonly icon: import("lucide-react").LucideIcon;
|
|
13
|
+
readonly tone: "purple";
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A company fact whose kind should be recognised across object pages.
|
|
18
|
+
*
|
|
19
|
+
* @family Status
|
|
20
|
+
* @when Agent, Installation and Customer counts in an object's labelled facts.
|
|
21
|
+
* @instead A state is StatusBadge; ordinary legal and contact facts stay plain text.
|
|
22
|
+
* @behaviour Composes Tag with the kind's fixed icon and colour: cobalto for Agents,
|
|
23
|
+
* acqua for Installations and viola for Customers. The pairing never changes by page.
|
|
24
|
+
* @words The value or count; the containing fact supplies its visible label.
|
|
25
|
+
* @access The icon is decorative. Wrap this value in a real link when it opens that collection.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ObjectFactValue({ kind, children, }: {
|
|
28
|
+
kind: keyof typeof KINDS;
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
}): import("react").JSX.Element;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=object-fact-value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object-fact-value.d.ts","sourceRoot":"","sources":["../../src/components/object-fact-value.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,QAAA,MAAM,KAAK;;;;;;;;;;;;;CAIiE,CAAC;AAE7E;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,MAAM,OAAO,KAAK,CAAC;IACzB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAOA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Monitor } from "lucide-react";
|
|
3
|
+
import { AgentIcon, ArchIcon } from "./house-icons.js";
|
|
4
|
+
import { Tag } from "./tag.js";
|
|
5
|
+
const KINDS = {
|
|
6
|
+
agents: { icon: AgentIcon, tone: "blue" },
|
|
7
|
+
installations: { icon: Monitor, tone: "teal" },
|
|
8
|
+
customers: { icon: ArchIcon, tone: "purple" },
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A company fact whose kind should be recognised across object pages.
|
|
12
|
+
*
|
|
13
|
+
* @family Status
|
|
14
|
+
* @when Agent, Installation and Customer counts in an object's labelled facts.
|
|
15
|
+
* @instead A state is StatusBadge; ordinary legal and contact facts stay plain text.
|
|
16
|
+
* @behaviour Composes Tag with the kind's fixed icon and colour: cobalto for Agents,
|
|
17
|
+
* acqua for Installations and viola for Customers. The pairing never changes by page.
|
|
18
|
+
* @words The value or count; the containing fact supplies its visible label.
|
|
19
|
+
* @access The icon is decorative. Wrap this value in a real link when it opens that collection.
|
|
20
|
+
*/
|
|
21
|
+
export function ObjectFactValue({ kind, children, }) {
|
|
22
|
+
const { icon: Icon, tone } = KINDS[kind];
|
|
23
|
+
return (_jsx(Tag, { mark: _jsx(Icon, { "aria-hidden": "true" }), tone: tone, children: children }));
|
|
24
|
+
}
|
|
@@ -26,7 +26,7 @@ export type ObjectPageFooter = {
|
|
|
26
26
|
link: ObjectPageLink;
|
|
27
27
|
};
|
|
28
28
|
export type ObjectPageProps = {
|
|
29
|
-
/** The object's mark, drawn at 64 beside
|
|
29
|
+
/** The object's mark, drawn at 64 beside a company's name or another object's facts. */
|
|
30
30
|
mark: IdentityMarkProps;
|
|
31
31
|
name: string;
|
|
32
32
|
/** Given where the name is the page's h1 (the product's chrome draws no title row here). */
|
|
@@ -54,7 +54,7 @@ export type ObjectPageProps = {
|
|
|
54
54
|
* @family Compositions
|
|
55
55
|
* @when One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.
|
|
56
56
|
* @instead "Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.
|
|
57
|
-
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (one secondary action, then the three dots, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise),
|
|
57
|
+
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (one secondary action, then the three dots, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
|
|
58
58
|
* @words "Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact's label is a noun ("Plan"), its value the figure; an entry's title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu's trigger reads "More for {name}".
|
|
59
59
|
* @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is a button with `aria-expanded` that controls its panel.
|
|
60
60
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-page.d.ts","sourceRoot":"","sources":["../../src/components/object-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAqC,MAAM,gBAAgB,CAAC;AAEpG,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,EAAE,YAAY,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kHAAkH;IAClH,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,
|
|
1
|
+
{"version":3,"file":"object-page.d.ts","sourceRoot":"","sources":["../../src/components/object-page.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAqC,MAAM,gBAAgB,CAAC;AAEpG,KAAK,cAAc,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,IAAI,EAAE,YAAY,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kHAAkH;IAClH,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,wFAAwF;IACxF,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;IACtD,qFAAqF;IACrF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,kFAAkF;IAClF,KAAK,EAAE,SAAS,CAAC,cAAc,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IACtD,0FAA0F;IAC1F,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,WAAW,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IACvD,2FAA2F;IAC3F,OAAO,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACrC,4FAA4F;IAC5F,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,+HAA+H;IAC/H,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,eAAe,GAAG,YAAY,CA8FhC"}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { FooterStrip } from "../internal/footer-strip.js";
|
|
3
3
|
import { cn } from "../lib/utils.js";
|
|
4
4
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./accordion.js";
|
|
5
|
-
import { Card, CardContent, CardHeader, CardTitle } from "./card.js";
|
|
5
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./card.js";
|
|
6
6
|
import { IdentityMark } from "./identity-mark.js";
|
|
7
7
|
import { PageActionsRow, PageCommandButton } from "./page-actions.js";
|
|
8
8
|
/**
|
|
@@ -12,10 +12,12 @@ import { PageActionsRow, PageCommandButton } from "./page-actions.js";
|
|
|
12
12
|
* @family Compositions
|
|
13
13
|
* @when One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.
|
|
14
14
|
* @instead "Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.
|
|
15
|
-
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (one secondary action, then the three dots, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise),
|
|
15
|
+
* @behaviour "For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel's deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object's commands at the end (one secondary action, then the three dots, on the name's row while the name keeps 128 px, as on a phone, and under it otherwise), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel's Build Logs and Deployment Checks rows. The footer takes a link only, so no Save or other command of the object fits in it; the object's changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company's compact identity, a semantic fact value, or an entry's status summary, with no coloured card ground.
|
|
16
16
|
* @words "Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact's label is a noun ("Plan"), its value the figure; an entry's title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu's trigger reads "More for {name}".
|
|
17
17
|
* @access "Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page's h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is a button with `aria-expanded` that controls its panel.
|
|
18
18
|
*/
|
|
19
19
|
export function ObjectPage({ mark, name, headingProps, description, facts, actions, entries, footer, children, }) {
|
|
20
|
-
|
|
20
|
+
const company = mark.kind === "company";
|
|
21
|
+
const title = headingProps ? (_jsx("h1", { ...headingProps, className: cn("outline-none", headingProps.className), children: name })) : (name);
|
|
22
|
+
return (_jsxs("div", { className: "grid min-w-0 gap-6", "data-slot": "object-page", children: [_jsxs("div", { className: "grid min-w-0 gap-3", children: [_jsxs(Card, { className: "min-w-0", render: _jsx("div", { "data-slot": "object-card" }), size: "sm", children: [_jsxs(CardHeader, { className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-3 border-b", children: [company ? (_jsxs("div", { className: cn("flex min-w-0 flex-1 items-center gap-4", actions?.menu && !actions.secondary ? "basis-0" : "basis-64"), children: [_jsx(IdentityMark, { ...mark, size: 64 }), _jsxs("div", { className: "grid min-w-0 gap-1", children: [_jsx(CardTitle, { className: "min-w-0 break-words group-data-[size=sm]/card:text-heading-sm", children: title }), description ? _jsx(CardDescription, { children: description }) : null] })] })) : (_jsx(CardTitle, { className: "min-w-0 flex-1 basis-32 break-words", children: title })), actions?.secondary || actions?.menu ? _jsx(PageActionsRow, { ...actions }) : null] }), _jsxs(CardContent, { className: cn("grid min-w-0 gap-x-6 gap-y-5", !company && "md:grid-cols-[minmax(0,18.75rem)_minmax(0,1fr)]"), children: [!company ? (_jsx("div", { className: "flex h-32 min-w-0 items-center md:h-auto md:aspect-[16/10] justify-center rounded-sm border border-border bg-muted", "data-slot": "object-page-tile", children: _jsx(IdentityMark, { ...mark, size: 64 }) })) : null, _jsxs("div", { className: "grid min-w-0 content-start gap-4", children: [!company && description ? (_jsx("div", { className: "min-w-0 text-body-sm text-muted-foreground", children: description })) : null, _jsx("dl", { className: "grid min-w-0 grid-cols-2 gap-x-6 gap-y-4 lg:grid-cols-4", "data-slot": "object-page-facts", children: facts.map((fact) => (_jsxs("div", { className: "grid min-w-0 content-start gap-1", children: [_jsx("dt", { className: "text-label-sm text-muted-foreground", children: fact.label }), _jsx("dd", { className: "min-w-0 text-body-sm break-words text-foreground", children: fact.value })] }, fact.label))) })] })] }), footer ? (_jsx(FooterStrip, { hint: footer.hint, hintSlot: "object-page-hint", children: _jsx(PageCommandButton, { command: footer.link, variant: "outline" }) })) : null] }), entries && entries.length > 0 ? (_jsx(Card, { className: "min-w-0 py-0", render: _jsx("div", { "data-slot": "object-page-entries" }), size: "sm", children: _jsx(Accordion, { className: "[&>:last-child]:border-b-0", multiple: true, size: "small", children: entries.map((entry) => (_jsxs(AccordionItem, { value: entry.title, children: [_jsxs(AccordionTrigger, { className: "justify-start gap-3 px-(--card-spacing) group-data-[size=small]/accordion:text-body-sm focus-visible:-outline-offset-2 [&>[data-slot=accordion-trigger-icon]]:order-first [&>[data-slot=accordion-trigger-icon]]:text-muted-foreground", children: [_jsx("span", { className: "min-w-0 flex-1", children: entry.title }), entry.summary] }), _jsx(AccordionContent, { className: "ps-[calc(var(--card-spacing)+1.75rem)] pe-(--card-spacing)", children: entry.children })] }, entry.title))) }) })) : null] }), children] }));
|
|
21
23
|
}
|
|
@@ -26,7 +26,7 @@ type StatusBadgeProps = Omit<ComponentProps<"span">, "children" | "onClick"> & {
|
|
|
26
26
|
* @instead "For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot)
|
|
27
27
|
* Ours: that `Badge` is `StatusBadge`. For a category (an installation, a partner) use `Tag`. For
|
|
28
28
|
* plain metadata (a role, a plan) use `Badge`. For a control reporting its own action use
|
|
29
|
-
* `ActionStatus`.
|
|
29
|
+
* `ActionStatus`. A state beside its name still uses this badge; status dots are not used.
|
|
30
30
|
* @behaviour "Badges are static labels." (https://vercel.com/geist/badge)
|
|
31
31
|
* "Don’t wire `onClick` onto them; promote to a Button or link if the user can act on the value." (https://vercel.com/geist/badge)
|
|
32
32
|
* Ours: a status never moves and is never a button.
|
|
@@ -40,7 +40,8 @@ type StatusBadgeProps = Omit<ComponentProps<"span">, "children" | "onClick"> & {
|
|
|
40
40
|
* "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge)
|
|
41
41
|
* Ours: it always draws its tone's mark, even for success and error: the mark repeats the tone as a
|
|
42
42
|
* shape so a status reads without colour. Each app keeps one value-to-tone map in one module;
|
|
43
|
-
* nothing else picks a status colour. A healthy record shows no badge
|
|
43
|
+
* nothing else picks a status colour. A healthy record shows no badge, except the
|
|
44
|
+
* operational-state and run-outcome columns defined by DESIGN.md's Status rule.
|
|
44
45
|
* @words "Title Case, one word when possible, two max: `Active`, `Pending`, `Pro`, `Enterprise Trial`." (https://vercel.com/geist/badge)
|
|
45
46
|
* Ours: a state, not a verb (*Failed*, *Waiting for you*), in sentence case, one to three words, no
|
|
46
47
|
* trailing ellipsis. Italian runs a third longer: *In attesa di te*.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-badge.d.ts","sourceRoot":"","sources":["../../src/components/status-badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG3D,KAAK,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,KAAK,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAgD9C,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAC7E,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"status-badge.d.ts","sourceRoot":"","sources":["../../src/components/status-badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG3D,KAAK,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,KAAK,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAgD9C,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAC7E,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,iBAAS,WAAW,CAAC,EACnB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,SAAS,EACT,IAAW,EACX,QAAmB,EACnB,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAqBlB;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,CAAC"}
|
|
@@ -60,7 +60,7 @@ const CIRCLE_MARK_INSET = {
|
|
|
60
60
|
* @instead "For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot)
|
|
61
61
|
* Ours: that `Badge` is `StatusBadge`. For a category (an installation, a partner) use `Tag`. For
|
|
62
62
|
* plain metadata (a role, a plan) use `Badge`. For a control reporting its own action use
|
|
63
|
-
* `ActionStatus`.
|
|
63
|
+
* `ActionStatus`. A state beside its name still uses this badge; status dots are not used.
|
|
64
64
|
* @behaviour "Badges are static labels." (https://vercel.com/geist/badge)
|
|
65
65
|
* "Don’t wire `onClick` onto them; promote to a Button or link if the user can act on the value." (https://vercel.com/geist/badge)
|
|
66
66
|
* Ours: a status never moves and is never a button.
|
|
@@ -74,7 +74,8 @@ const CIRCLE_MARK_INSET = {
|
|
|
74
74
|
* "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge)
|
|
75
75
|
* Ours: it always draws its tone's mark, even for success and error: the mark repeats the tone as a
|
|
76
76
|
* shape so a status reads without colour. Each app keeps one value-to-tone map in one module;
|
|
77
|
-
* nothing else picks a status colour. A healthy record shows no badge
|
|
77
|
+
* nothing else picks a status colour. A healthy record shows no badge, except the
|
|
78
|
+
* operational-state and run-outcome columns defined by DESIGN.md's Status rule.
|
|
78
79
|
* @words "Title Case, one word when possible, two max: `Active`, `Pending`, `Pro`, `Enterprise Trial`." (https://vercel.com/geist/badge)
|
|
79
80
|
* Ours: a state, not a verb (*Failed*, *Waiting for you*), in sentence case, one to three words, no
|
|
80
81
|
* trailing ellipsis. Italian runs a third longer: *In attesa di te*.
|
package/dist/components/tag.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { cn } from "../lib/utils.js";
|
|
3
3
|
const TONE_CLASS = {
|
|
4
4
|
neutral: "border-border text-foreground",
|
|
5
|
-
blue: "border-transparent bg-
|
|
5
|
+
blue: "border-transparent bg-category-blue text-category-blue-foreground",
|
|
6
6
|
teal: "border-transparent bg-category-teal text-category-teal-foreground",
|
|
7
7
|
purple: "border-transparent bg-category-purple text-category-purple-foreground",
|
|
8
8
|
pink: "border-transparent bg-category-pink text-category-pink-foreground",
|
package/dist/index.d.ts
CHANGED
|
@@ -91,6 +91,7 @@ export * from "./components/nadia-presence.js";
|
|
|
91
91
|
export * from "./components/native-select.js";
|
|
92
92
|
export * from "./components/notice-banner.js";
|
|
93
93
|
export * from "./components/numbered-steps.js";
|
|
94
|
+
export * from "./components/object-fact-value.js";
|
|
94
95
|
export * from "./components/object-page.js";
|
|
95
96
|
export * from "./components/object-workspace.js";
|
|
96
97
|
export * from "./components/overview-page.js";
|
|
@@ -130,7 +131,6 @@ export * from "./components/slider.js";
|
|
|
130
131
|
export * from "./components/snippet.js";
|
|
131
132
|
export * from "./components/sonner.js";
|
|
132
133
|
export * from "./components/status-badge.js";
|
|
133
|
-
export * from "./components/status-dot.js";
|
|
134
134
|
export * from "./components/switch.js";
|
|
135
135
|
export * from "./components/table.js";
|
|
136
136
|
export * from "./components/table-card.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -91,6 +91,7 @@ export * from "./components/nadia-presence.js";
|
|
|
91
91
|
export * from "./components/native-select.js";
|
|
92
92
|
export * from "./components/notice-banner.js";
|
|
93
93
|
export * from "./components/numbered-steps.js";
|
|
94
|
+
export * from "./components/object-fact-value.js";
|
|
94
95
|
export * from "./components/object-page.js";
|
|
95
96
|
export * from "./components/object-workspace.js";
|
|
96
97
|
export * from "./components/overview-page.js";
|
|
@@ -130,7 +131,6 @@ export * from "./components/slider.js";
|
|
|
130
131
|
export * from "./components/snippet.js";
|
|
131
132
|
export * from "./components/sonner.js";
|
|
132
133
|
export * from "./components/status-badge.js";
|
|
133
|
-
export * from "./components/status-dot.js";
|
|
134
134
|
export * from "./components/switch.js";
|
|
135
135
|
export * from "./components/table.js";
|
|
136
136
|
export * from "./components/table-card.js";
|
|
@@ -3,9 +3,10 @@ import { type ReactNode } from "react";
|
|
|
3
3
|
* A company's logo on its tile, and `fallback`, its initials, when the stored logo does not load,
|
|
4
4
|
* so a broken address never leaves an empty tile.
|
|
5
5
|
*/
|
|
6
|
-
export declare function CompanyLogo({ logo, colourTile, size, naming, fallback, }: {
|
|
6
|
+
export declare function CompanyLogo({ logo, colourTile, edition, size, naming, fallback, }: {
|
|
7
7
|
logo: string;
|
|
8
8
|
colourTile: boolean;
|
|
9
|
+
edition: "company" | "partner";
|
|
9
10
|
size: number;
|
|
10
11
|
naming: {
|
|
11
12
|
role: "img";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"company-logo.d.ts","sourceRoot":"","sources":["../../src/internal/company-logo.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAIjD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IACxE,QAAQ,EAAE,SAAS,CAAC;CACrB,+
|
|
1
|
+
{"version":3,"file":"company-logo.d.ts","sourceRoot":"","sources":["../../src/internal/company-logo.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAIjD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,UAAU,EACV,OAAO,EACP,IAAI,EACJ,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,aAAa,EAAE,IAAI,CAAA;KAAE,CAAC;IACxE,QAAQ,EAAE,SAAS,CAAC;CACrB,+TAgCA"}
|
|
@@ -6,9 +6,13 @@ import { cn } from "../lib/utils.js";
|
|
|
6
6
|
* A company's logo on its tile, and `fallback`, its initials, when the stored logo does not load,
|
|
7
7
|
* so a broken address never leaves an empty tile.
|
|
8
8
|
*/
|
|
9
|
-
export function CompanyLogo({ logo, colourTile, size, naming, fallback, }) {
|
|
9
|
+
export function CompanyLogo({ logo, colourTile, edition, size, naming, fallback, }) {
|
|
10
10
|
const [failedLogo, setFailedLogo] = useState(null);
|
|
11
11
|
if (failedLogo === logo)
|
|
12
12
|
return fallback;
|
|
13
|
-
return (_jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center overflow-hidden", colourTile
|
|
13
|
+
return (_jsx("span", { className: cn("inline-flex shrink-0 items-center justify-center overflow-hidden", colourTile
|
|
14
|
+
? size >= 40
|
|
15
|
+
? "rounded-md"
|
|
16
|
+
: "rounded-sm"
|
|
17
|
+
: cn("rounded-t-full rounded-b-sm border-2 bg-nc-identity-ink", edition === "partner" ? "border-nc-identity-arancio" : "border-nc-identity-cobalto")), "data-kind": "company", "data-slot": "identity-mark", style: { width: size, height: size }, ...naming, children: _jsx("img", { alt: "", className: colourTile ? "size-full object-contain" : "max-h-[60%] max-w-[78%] object-contain", "data-slot": "identity-mark-logo", onError: () => setFailedLogo(logo), src: logo }) }));
|
|
14
18
|
}
|
|
@@ -111,7 +111,7 @@ export declare const SPECIMENS: {
|
|
|
111
111
|
ProgressChecklist: () => import("react").JSX.Element;
|
|
112
112
|
RecordIdentity: () => import("react").JSX.Element;
|
|
113
113
|
StatusBadge: () => import("react").JSX.Element;
|
|
114
|
-
|
|
114
|
+
ObjectFactValue: () => import("react").JSX.Element;
|
|
115
115
|
Tag: () => import("react").JSX.Element;
|
|
116
116
|
Checkbox: () => import("react").JSX.Element;
|
|
117
117
|
ChoiceboxGroup: () => import("react").JSX.Element;
|
|
@@ -86,7 +86,7 @@ function TabsSpecimen() {
|
|
|
86
86
|
return (_jsxs("div", { className: "grid gap-8", children: [_jsxs(Tabs, { onValueChange: setPlain, value: plain, children: [_jsxs(TabsList, { "aria-label": "Rossi Ottica", children: [_jsx(TabsTrigger, { value: "overview", children: "Overview" }), _jsx(TabsTrigger, { value: "installations", children: "Installations" }), _jsx(TabsTrigger, { disabled: true, disabledReason: "Only owners see billing", value: "billing", children: "Billing" })] }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "overview", children: "What the customer runs, at a glance." }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "installations", children: "Every machine Nadia is installed on." })] }), _jsxs(Tabs, { onValueChange: setLined, value: lined, children: [_jsxs(TabsList, { "aria-label": "Rossi Ottica, with a rule", variant: "line", children: [_jsx(TabsTrigger, { value: "overview", children: "Overview" }), _jsx(TabsTrigger, { value: "installations", children: "Installations" }), _jsx(TabsTrigger, { disabled: true, disabledReason: "Only owners see billing", value: "billing", children: "Billing" })] }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "overview", children: "What the customer runs, at a glance." }), _jsx(TabsContent, { className: "pt-3 text-sm text-muted-foreground", value: "installations", children: "Every machine Nadia is installed on." })] })] }));
|
|
87
87
|
}
|
|
88
88
|
export const NAVIGATION = {
|
|
89
|
-
AgentListRow: () => (_jsxs("ul", { className: "grid max-w-xs gap-1", children: [_jsx("li", { children: _jsx(AgentListRow, { color: COBALTO, current: true, form: "orbit", name: "Invoices", state: "working", stateLine: "Drafting October's invoices" }) }), _jsx("li", { children: _jsx(AgentListRow, { color: VERDE, form: "lattice", name: "Orders", state: "waiting", stateLine: "Waiting for you", stateTone: "
|
|
89
|
+
AgentListRow: () => (_jsxs("ul", { className: "grid max-w-xs gap-1", children: [_jsx("li", { children: _jsx(AgentListRow, { color: COBALTO, current: true, form: "orbit", name: "Invoices", state: "working", stateLine: "Drafting October's invoices" }) }), _jsx("li", { children: _jsx(AgentListRow, { color: VERDE, form: "lattice", name: "Orders", state: "waiting", stateLine: "Waiting for you", stateTone: "warning" }) })] })),
|
|
90
90
|
Breadcrumb: () => (_jsxs("div", { className: "grid gap-4", children: [_jsx(Breadcrumb, { "aria-label": "Path", children: _jsxs(BreadcrumbList, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#customers", children: "Customers" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Rossi Ottica" }) })] }) }), _jsx(Breadcrumb, { "aria-label": "Path with a closed ancestor", children: _jsxs(BreadcrumbList, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { disabled: true, children: "Partners" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#customers", children: "Customers" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Rossi Ottica" }) })] }) }), _jsx(Breadcrumb, { "aria-label": "Long path", children: _jsxs(BreadcrumbList, { children: [_jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#customers", children: "Customers" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbEllipsis, { label: "More" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbLink, { href: "#installations", children: "Installations" }) }), _jsx(BreadcrumbSeparator, {}), _jsx(BreadcrumbItem, { children: _jsx(BreadcrumbPage, { children: "Rossi Ottica, Milano" }) })] }) })] })),
|
|
91
91
|
CommandDialog: CommandDialogSpecimen,
|
|
92
92
|
Footer: () => (_jsx(Footer, { children: _jsxs(FooterInner, { children: [_jsx(FooterBrand, { "aria-label": "nadicode", href: "#top", children: _jsx(BrandWordmark, { alt: "" }) }), _jsx(FooterIdentity, { children: "Agents that do the work, for Italian companies." }), _jsxs(FooterNav, { "aria-label": "Company", children: [_jsx("a", { href: "#privacy", children: "Privacy" }), _jsx("a", { href: "#terms", children: "Terms" })] }), _jsx(FooterMeta, { children: "\u00A9 2026 nadicode" })] }) })),
|
|
@@ -18,7 +18,7 @@ export declare const STATUS: {
|
|
|
18
18
|
ProgressChecklist: () => import("react").JSX.Element;
|
|
19
19
|
RecordIdentity: () => import("react").JSX.Element;
|
|
20
20
|
StatusBadge: () => import("react").JSX.Element;
|
|
21
|
-
|
|
21
|
+
ObjectFactValue: () => import("react").JSX.Element;
|
|
22
22
|
Tag: () => import("react").JSX.Element;
|
|
23
23
|
};
|
|
24
24
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/status.tsx"],"names":[],"mappings":"AAyDA,iBAAS,oBAAoB,gCAiB5B;AAYD,iBAAS,aAAa,gCA2DrB;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/showcase/specimens/status.tsx"],"names":[],"mappings":"AAyDA,iBAAS,oBAAoB,gCAiB5B;AAYD,iBAAS,aAAa,gCA2DrB;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;CAoQQ,CAAC"}
|
|
@@ -19,8 +19,8 @@ import { PlatformMark } from "../../components/platform-mark.js";
|
|
|
19
19
|
import { ProgressChecklist } from "../../components/progress-checklist.js";
|
|
20
20
|
import { RecordIdentity } from "../../components/record-identity.js";
|
|
21
21
|
import { StatusBadge } from "../../components/status-badge.js";
|
|
22
|
-
import { StatusDot } from "../../components/status-dot.js";
|
|
23
22
|
import { Tag } from "../../components/tag.js";
|
|
23
|
+
import { ObjectFactValue } from "../../components/object-fact-value.js";
|
|
24
24
|
import { ARANCIO, COBALTO, nothing, VERDE } from "../samples.js";
|
|
25
25
|
// A one-ink logo as Sofia keeps it: white where the mark is, transparent elsewhere.
|
|
26
26
|
const SAMPLE_LOGO = `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 16"><text x="0" y="13" fill="white" font-family="sans-serif" font-size="14" font-weight="700">ROSSI</text></svg>')}`;
|
|
@@ -92,6 +92,6 @@ export const STATUS = {
|
|
|
92
92
|
], title: "Customer setup" })),
|
|
93
93
|
RecordIdentity: () => (_jsx("div", { className: "max-w-sm", children: _jsx(RecordIdentity, { detail: "Company skill \u00B7 every Agent has it", hint: "skl_0042", mark: { kind: "record", icon: Wrench, tone: "skill" }, name: "Write quotes from the price list" }) })),
|
|
94
94
|
StatusBadge: () => (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(StatusBadge, { label: "Connected", tone: "success" }), _jsx(StatusBadge, { label: "Waiting for you", since: "2h", tone: "warning" }), _jsx(StatusBadge, { label: "Failed", tone: "danger" }), _jsx(StatusBadge, { label: "Running", tone: "info" }), _jsx(StatusBadge, { label: "Paused", tone: "neutral" })] })),
|
|
95
|
-
|
|
95
|
+
ObjectFactValue: () => (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(ObjectFactValue, { kind: "agents", children: "5 active" }), _jsx(ObjectFactValue, { kind: "installations", children: "2" }), _jsx(ObjectFactValue, { kind: "customers", children: "12" })] })),
|
|
96
96
|
Tag: () => (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx(Tag, { tone: "blue", children: "Rossi Ottica" }), _jsx(Tag, { tone: "teal", children: "Partner" }), _jsx(Tag, { note: "Your account", quiet: true, children: "Direct customer" })] })),
|
|
97
97
|
};
|
|
@@ -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" | "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" | "
|
|
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" | "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" | "ThemeModeMenu" | "ActivityCalendar" | "ChartAreaStacked" | "ChartBarHorizontal" | "ChartBarMultiple" | "ChartBarStacked" | "ChartCard" | "ChartContainer" | "ChartRanking" | "ChartSparkline" | "DateRangeControl" | "KpiCard" | "TrendBadge" | "createEntityColorMap" | "Accordion" | "AspectRatio" | "BrandField" | "Carousel" | "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":"AAGA,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,YAAY,GACZ,eAAe,GACf,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,aAAa,GACb,cAAc,GACd,iBAAiB,GACjB,QAAQ,GACR,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,gBAAgB,GAChB,aAAa,GACb,UAAU,GACV,gBAAgB,GAChB,kBAAkB,GAClB,OAAO,GACP,OAAO,GACP,YAAY,GACZ,UAAU,GACV,OAAO,GACP,cAAc,GACd,eAAe,GACf,cAAc,GACd,QAAQ,GACR,UAAU,GACV,UAAU,GACV,gBAAgB,GAChB,gBAAgB,GAChB,UAAU,GACV,aAAa,GACb,aAAa,GACb,YAAY,GACZ,iBAAiB,GACjB,kBAAkB,GAClB,QAAQ,GACR,QAAQ,GACR,mBAAmB,GACnB,mBAAmB,GACnB,QAAQ,GACR,aAAa,GACb,cAAc,GACd,UAAU,GACV,SAAS,GACT,UAAU,GACV,QAAQ,GACR,OAAO,GACP,eAAe,GACf,aAAa,GACb,cAAc,GACd,cAAc,GACd,eAAe,GACf,WAAW,GACX,cAAc,GACd,mBAAmB,GACnB,gBAAgB,GAChB,aAAa,GACb,
|
|
1
|
+
{"version":3,"file":"usage.generated.d.ts","sourceRoot":"","sources":["../../src/showcase/usage.generated.ts"],"names":[],"mappings":"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"}
|
|
@@ -142,7 +142,7 @@ export const USAGE = [
|
|
|
142
142
|
summary: "One object's page: the object card with its name, commands, facts, rows that open and one link elsewhere, then its sections as cards.",
|
|
143
143
|
when: "One thing a person opened from a list and now reads or acts on: a customer, a partner, an Installation, a Library entry.",
|
|
144
144
|
instead: '"Use Context Card to reveal entity metadata on hover or focus: a user, a deployment, a project, an API key." (https://vercel.com/geist/context-card) Ours: that hover is a `HoverCard`, never this page. A list of records is a CollectionPage; a page of settings only is a SettingsPage, whose cards are SettingsSections; an Agent opens on its AgentProfileCard, the documented exception. A card of values a person saves is a setting card, never this one.',
|
|
145
|
-
behaviour: '"For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel\'s deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object\'s commands at the end (one secondary action, then the three dots, on the name\'s row while the name keeps 128 px, as on a phone, and under it otherwise),
|
|
145
|
+
behaviour: '"For a static key/value metadata block on a detail page, use `Description`." (https://vercel.com/geist/entity) "The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`." (https://vercel.com/geist/entity) "Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`)." (https://vercel.com/geist/entity) "Don’t put interactive controls in the title slot. Buttons, menus, and links belong in the content (`<dd>`) or in the parent layout, not the label (`<dt>`)." (https://vercel.com/geist/description) Ours: as Vercel\'s deployment page (Deployment Details, then its steps), the object card is the first card of the page: a header bar with the name at the start and the object\'s commands at the end (one secondary action, then the three dots, on the name\'s row while the name keeps 128 px, as on a phone, and under it otherwise), for a company, the compact mark at 64 stands beside the name and optional line in the header, followed by full-width facts with four columns from `lg` and two below; other object kinds keep their mark and line beside their facts in the existing preview treatment (at least one fact is required: an object is never shown without what it is), each a muted label over its value in body text, then an optional footer with a hint at the start and one link at the end. Optional `entries` follow in a card of their own 12 px under it: rows that open one by one, each with its chevron first (it turns down when open), its title, and its summary at the trailing edge, as Vercel\'s Build Logs and Deployment Checks rows. The footer takes a link only, so no Save or other command of the object fits in it; the object\'s changes live in its sections, each a setting card with its own footer. The sections follow, 24 apart, each drawing its own states. The card is neutral; colour belongs to the company\'s compact identity, a semantic fact value, or an entry\'s status summary, with no coloured card ground.',
|
|
146
146
|
words: '"Keep right-column buttons Verb + Noun (`Remove Member`, `Resend Invite`). Bare verbs like `Remove` or `Confirm` lose context once the row scrolls offscreen." (https://vercel.com/geist/entity) "Title slot is Title Case noun (`Last Deployed`, `Build Duration`); content is sentence case unless the value is a literal identifier, ID, or timestamp that should be preserved verbatim." (https://vercel.com/geist/description) Ours: sentence case throughout. The name as the object is called everywhere else; the line says what it is and whose ("Customer of Partner Alpha · since 3 August 2026"); a fact\'s label is a noun ("Plan"), its value the figure; an entry\'s title is a noun phrase; the hint is one sentence ("To update it, push to the main branch."); the link names where it goes ("Deployments"); the menu\'s trigger reads "More for {name}".',
|
|
147
147
|
access: '"Geist renders `<dl>`/`<dt>`/`<dd>` so screen readers announce each key/value pair as a definition." (https://vercel.com/geist/description) "Don’t wrap the component in extra paragraphs that break the list semantics." (https://vercel.com/geist/description) Ours: with `headingProps` the name is the page\'s h1; without them it is text, for a product whose chrome already titles the page. The mark is decorative beside the facts. Each entry is a button with `aria-expanded` that controls its panel.',
|
|
148
148
|
},
|
|
@@ -669,7 +669,7 @@ export const USAGE = [
|
|
|
669
669
|
family: "Status",
|
|
670
670
|
summary: 'Short metadata beside its subject: a role, a plan, "Beta".',
|
|
671
671
|
when: '"Use Badge for short, scannable metadata that sits next to the thing it describes: status, plan tier, environment, or role." (https://vercel.com/geist/badge) "One badge per row; two side by side is a sign the row needs a second column." (https://vercel.com/geist/badge) Ours: a state is a `StatusBadge`; a `Badge` is a role (*Owner*), a plan, an environment, *Beta*. It always has a word, or one `icon` with a `title`, and the type asks for it. `size` follows the type beside it: `sm` (20 px) next to small labels, `md` (24 px) in a row, `lg` (32 px) in a header. The category fills (teal, purple, pink) name a kind.',
|
|
672
|
-
instead: '"For a colored dot without text, use `Status Dot`." (https://vercel.com/geist/badge) Ours:
|
|
672
|
+
instead: '"For a colored dot without text, use `Status Dot`." (https://vercel.com/geist/badge) Ours: status dots are not used; a state keeps its mark and word together in `StatusBadge`. "For clickable filter chips that toggle a query, use the `pill` variant or a small `Button`." (https://vercel.com/geist/badge) Ours: there is no `pill` variant; a filter that toggles a query is a `Button` or `CollectionFilters`. For a state use `StatusBadge`, which picks the tone and its mark: the gray, green, red, amber and blue fills, soft or solid, are its alone. One categorical fact in a row is a `Tag`. A change in a figure is a `TrendBadge`.',
|
|
673
673
|
behaviour: '"Badges are static labels." (https://vercel.com/geist/badge) "Don’t wire `onClick` onto them; promote to a Button or link if the user can act on the value." (https://vercel.com/geist/badge) Ours: it takes no `onClick`, no hover and no focus; it becomes a link only through `render` with a real anchor, and only `outline` takes the hover, a gray fill. "Keep badge content to text or `icon` + text." (https://vercel.com/geist/badge) "Never stack two icons or a child Badge inside a Badge." (https://vercel.com/geist/badge) Ours: never a paragraph either. "Pair lifecycle badges (`Alpha`, `Beta`, `Early Access`) with a `Tooltip` that names the limit, like `Alpha: API may change before GA`." (https://vercel.com/geist/badge) Ours: the badge is the `render` of a `TooltipTrigger` with `tabIndex={0}`, so keyboard and touch users reach the limit it names. "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge) Ours: only `StatusBadge` carries a state, and it always draws its tone\'s mark. "Map meaning to color: `green` for healthy, `red` for error, `amber` for warning, `blue` for informational or production, `gray` for neutral." (https://vercel.com/geist/badge) "The `-subtle` suffix tones any of them down on dense surfaces." (https://vercel.com/geist/badge) Ours: those fills are `StatusBadge`\'s, as the tones `success`, `danger`, `warning`, `info` and `neutral`, with `emphasis` `subtle` or `solid`. `Badge` is a fixed-height pill (20, 24 or 32 px) with no border: colour sits on the fill and the word. A soft fill takes its hue\'s strong shade for the word, `default` is the foreground colour inverted, and `outline` is neutral, a page-colour fill held by a 1 px inset ring. With an icon, the left padding is 6, 8 or 12 px, so the mark and the word look evenly spaced. The icon takes the word\'s colour.',
|
|
674
674
|
words: '"Title Case, one word when possible, two max: `Active`, `Pending`, `Pro`, `Enterprise Trial`." (https://vercel.com/geist/badge) Ours: sentence case (*Enterprise trial*). "Match the canonical API or log term: `Production` not `Prod`, `Deployed` not `Live`, `Canceled` not `Cancelled` (the Vercel API uses one L)." (https://vercel.com/geist/badge) Ours: the term is our own API\'s. "Skip stuffing sentences inside (`Currently Active`, `You are on Pro`); the surrounding row supplies the context." (https://vercel.com/geist/badge)',
|
|
675
675
|
access: '"Set `title` for icon-only or ambiguous badges so screen readers announce the meaning." (https://vercel.com/geist/badge) Ours: an icon alone must set `title`, and the type asks for it. Read in place as text. "Don’t rely on color alone; the text has to be readable without it." (https://vercel.com/geist/badge) Ours: a coloured variant still carries its word.',
|
|
@@ -714,7 +714,7 @@ export const USAGE = [
|
|
|
714
714
|
summary: "What says which thing a record is, at a fixed size at the start of its row, its object's head or its feed line: an Agent's orb, an app's logo, a company's initials, a person's picture, or a record kind's icon on its tile.",
|
|
715
715
|
when: "The first thing in a record's row (32), at the head of its object page (64), in a feed or a sidebar identity line (24), on a Library entry (40), for the company at the top of Nadia's list (28): wherever it tells a person which thing they are looking at.",
|
|
716
716
|
instead: "An icon beside a card's title, a KPI's label or a section heading only repeats the words and is left out. A picture for a first use or a whole-page moment is the empty state's or the page's own. A model is its `ModelIdentity`.",
|
|
717
|
-
behaviour: "Static, except an Agent's orb, which moves with her state. An Agent is always her real orb from the orb engine, at the largest orb size not above the mark's, with no tile and no ring, never an avatar or a painted circle, and `frame` lets the product wrap that orb, such as in the transition that carries her to her page; an app keeps its own logo in its bordered tile on the page ground, or its first letter when it has no logo; a company is its logo: the one white ink Sofia kept from its site on a black
|
|
717
|
+
behaviour: "Static, except an Agent's orb, which moves with her state. An Agent is always her real orb from the orb engine, at the largest orb size not above the mark's, with no tile and no ring, never an avatar or a painted circle, and `frame` lets the product wrap that orb, such as in the transition that carries her to her page; an app keeps its own logo in its bordered tile on the page ground, or its first letter when it has no logo; a company is its logo: the one white ink Sofia kept from its site on a black arch with its edition's colour edge in both themes, or a square SVG icon in its own colours filling the tile, as Vercel shows a project's favicon; its two initials on a compact arch, cobalto for a company and arancio for an approved Partner, until a logo is found or when the stored logo does not load. The edition follows the company's standing, never the directory it was opened from; a person is their picture, then their initials, in a round mark; a record with its own object picture, such as a Library skill or plugin, draws that picture on its kind's ground; a record with no picture of its own takes its kind's own icon, the same icon its section has in the navigation (Mail for a mailbox, a server for an MCP server, a key for a password), in a ringed tile on the card ground; a Library skill takes the purple category ground with the Skills icon and a plugin the `info-soft` ground with the Plugins icon, both without a ring, so the ground says which kind it is, and an entry that has its own object picture draws it on that ground in the icon's place. A company arch has a semicircular top and `{rounded.sm}` bottom corners; a record tile takes `{rounded.sm}` (6 px) corners, `{rounded.md}` (8 px) at 40 and 64; an app's tile takes `{rounded.md}` at every size.",
|
|
718
718
|
words: "None of its own: the record's name stands beside it. Initials stand for a company or a person: the first letters of the name's first two words. An app with no logo takes the first letter of its name as a monogram, and no other kind takes letters.",
|
|
719
719
|
access: "Decorative beside the record's name. Alone, as in a narrow rail, `label` names it.",
|
|
720
720
|
},
|
|
@@ -740,6 +740,17 @@ export const USAGE = [
|
|
|
740
740
|
words: "The model's name as the product reads it; the maker is never spelled by this component.",
|
|
741
741
|
access: 'Decorative beside the name. A bare mark takes `label` and becomes `role="img"`; with no name it stays hidden.',
|
|
742
742
|
},
|
|
743
|
+
{
|
|
744
|
+
name: "ObjectFactValue",
|
|
745
|
+
module: "object-fact-value",
|
|
746
|
+
family: "Status",
|
|
747
|
+
summary: "A company fact whose kind should be recognised across object pages.",
|
|
748
|
+
when: "Agent, Installation and Customer counts in an object's labelled facts.",
|
|
749
|
+
instead: "A state is StatusBadge; ordinary legal and contact facts stay plain text.",
|
|
750
|
+
behaviour: "Composes Tag with the kind's fixed icon and colour: cobalto for Agents, acqua for Installations and viola for Customers. The pairing never changes by page.",
|
|
751
|
+
words: "The value or count; the containing fact supplies its visible label.",
|
|
752
|
+
access: "The icon is decorative. Wrap this value in a real link when it opens that collection.",
|
|
753
|
+
},
|
|
743
754
|
{
|
|
744
755
|
name: "PlatformMark",
|
|
745
756
|
module: "platform-mark",
|
|
@@ -779,22 +790,11 @@ export const USAGE = [
|
|
|
779
790
|
family: "Status",
|
|
780
791
|
summary: "A record's state: a mark and a word in one of five tones.",
|
|
781
792
|
when: '"Use Badge for short, scannable metadata that sits next to the thing it describes: status, plan tier, environment, or role." (https://vercel.com/geist/badge) Ours: a record\'s state, when it sets the row apart: failed, waiting on a person, a step in motion, paused, connected. Gray is the default and every terminal state that needs no action; green is healthy or complete; red is unusable or failed; amber is waiting on a person\'s decision; blue is a step in motion. "Map meaning to color: `green` for healthy, `red` for error, `amber` for warning, `blue` for informational or production, `gray` for neutral." (https://vercel.com/geist/badge) Ours: success is green, danger red, warning amber, info blue, neutral gray, whatever the state\'s name, in our colour values. The tone and the word are required, and the type asks for both.',
|
|
782
|
-
instead: '"For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot) Ours: that `Badge` is `StatusBadge`. For a category (an installation, a partner) use `Tag`. For plain metadata (a role, a plan) use `Badge`. For a control reporting its own action use `ActionStatus`.
|
|
783
|
-
behaviour: '"Badges are static labels." (https://vercel.com/geist/badge) "Don’t wire `onClick` onto them; promote to a Button or link if the user can act on the value." (https://vercel.com/geist/badge) Ours: a status never moves and is never a button. "The `-subtle` suffix tones any of them down on dense surfaces." (https://vercel.com/geist/badge) Ours: `subtle`, the default, is for rows, tables, lists and menus: it fills the pill with the tone\'s soft ground and sets the mark and the word in its strong shade; gray takes the foreground colour, never a muted one. `solid` is for a status that stands on its own, such as an object\'s page header or a card title: it fills the pill with the tone\'s strong colour and sets the mark and the word on it. No border and no ring either way. The `subtle` pairs are the tone\'s soft ground with its deep shade (gray: `canvas-soft-2` with the foreground colour). "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge) Ours: it always draws its tone\'s mark, even for success and error: the mark repeats the tone as a shape so a status reads without colour. Each app keeps one value-to-tone map in one module; nothing else picks a status colour. A healthy record shows no badge.',
|
|
793
|
+
instead: '"For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot) Ours: that `Badge` is `StatusBadge`. For a category (an installation, a partner) use `Tag`. For plain metadata (a role, a plan) use `Badge`. For a control reporting its own action use `ActionStatus`. A state beside its name still uses this badge; status dots are not used.',
|
|
794
|
+
behaviour: '"Badges are static labels." (https://vercel.com/geist/badge) "Don’t wire `onClick` onto them; promote to a Button or link if the user can act on the value." (https://vercel.com/geist/badge) Ours: a status never moves and is never a button. "The `-subtle` suffix tones any of them down on dense surfaces." (https://vercel.com/geist/badge) Ours: `subtle`, the default, is for rows, tables, lists and menus: it fills the pill with the tone\'s soft ground and sets the mark and the word in its strong shade; gray takes the foreground colour, never a muted one. `solid` is for a status that stands on its own, such as an object\'s page header or a card title: it fills the pill with the tone\'s strong colour and sets the mark and the word on it. No border and no ring either way. The `subtle` pairs are the tone\'s soft ground with its deep shade (gray: `canvas-soft-2` with the foreground colour). "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge) Ours: it always draws its tone\'s mark, even for success and error: the mark repeats the tone as a shape so a status reads without colour. Each app keeps one value-to-tone map in one module; nothing else picks a status colour. A healthy record shows no badge, except the operational-state and run-outcome columns defined by DESIGN.md\'s Status rule.',
|
|
784
795
|
words: '"Title Case, one word when possible, two max: `Active`, `Pending`, `Pro`, `Enterprise Trial`." (https://vercel.com/geist/badge) Ours: a state, not a verb (*Failed*, *Waiting for you*), in sentence case, one to three words, no trailing ellipsis. Italian runs a third longer: *In attesa di te*. "Match the canonical API or log term: `Production` not `Prod`, `Deployed` not `Live`, `Canceled` not `Cancelled` (the Vercel API uses one L)." (https://vercel.com/geist/badge) "Skip stuffing sentences inside (`Currently Active`, `You are on Pro`); the surrounding row supplies the context." (https://vercel.com/geist/badge)',
|
|
785
796
|
access: '"Don’t rely on color alone; the text has to be readable without it." (https://vercel.com/geist/badge) Ours: the word is the name; the mark is `aria-hidden`, so colour never carries the state alone. Not focusable.',
|
|
786
797
|
},
|
|
787
|
-
{
|
|
788
|
-
name: "StatusDot",
|
|
789
|
-
module: "status-dot",
|
|
790
|
-
family: "Status",
|
|
791
|
-
summary: "A small still dot for one state, named by its label or by the word beside it.",
|
|
792
|
-
when: '"Deployment lifecycle only. `state` accepts `QUEUED | BUILDING | READY | ERROR | CANCELED | DELETED`." (https://vercel.com/geist/status-dot) Ours: any one state in dense chrome (a channel, a machine in a list), set as `tone`. It always says which state it shows: `label` names it (*Ready*), and `decorative` stands for a word beside it that already does. The type asks for one of the two. "Don’t flash the color through every transitional state on a polling tick; only update when the readyState changes." (https://vercel.com/geist/status-dot) Ours: pick the tone from the state and keep it until the state changes.',
|
|
793
|
-
instead: '"For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot) Ours: that `Badge` is `StatusBadge`; so is a status that stands alone, or one that needs a mark and a word. "For health summaries that need a number (uptime, hit rate), use `Gauge`; for in-flight work with a knowable total, use `Progress`." (https://vercel.com/geist/status-dot) Ours: something in motion is the waiting line or an Agent\'s orb; the dot has no info tone.',
|
|
794
|
-
behaviour: '"The dot animates while `BUILDING` or `QUEUED` and goes static once the deployment reaches a terminal state." (https://vercel.com/geist/status-dot) "Don’t add a separate spinner alongside it." (https://vercel.com/geist/status-dot) Ours: still, even while a state is in progress: it never pulses. It has no deployment states and no `state` prop, only four generic tones. A 10 px dot; tones are `good`, `muted`, `warn`, `bad`, at full strength. Colour sits on the dot alone: with `showLabel` the word beside it is 14 px and neutral, never in the tone\'s colour. `label` alone draws the dot with the word as its name and tooltip; `showLabel` draws the word 8 px after it, for a dot with no other text around it.',
|
|
795
|
-
words: '"Use `label` only when the dot stands alone without surrounding text; Geist sentence-cases the state for you (`Building`, `Ready`, `Error`)." (https://vercel.com/geist/status-dot) Ours: `label` is the required name unless the dot is `decorative`, and we write it in sentence case ourselves: *Ready*, *Error*, *Canceled*. "Don’t wrap the dot in extra prose like `Status: Ready`. The label already names the state." (https://vercel.com/geist/status-dot)',
|
|
796
|
-
access: '"The component composes its own `aria-label` from `titlePrefix` plus the state message; don’t override it with a generic `aria-label="status"`." (https://vercel.com/geist/status-dot) Ours: there is no `titlePrefix` and no `aria-label` prop; `label` is the dot\'s name, an image role with that name. "When the dot sits inline with text that already names the state, mark the dot decorative with `aria-hidden` so screen readers don’t announce it twice." (https://vercel.com/geist/status-dot) Ours: `decorative` does it; the word beside the dot must name the state, and if that word is missing, the state is missing. "Color is not the only signal: every state ships with a distinct title and label so colorblind users get the same information." (https://vercel.com/geist/status-dot)',
|
|
797
|
-
},
|
|
798
798
|
{
|
|
799
799
|
name: "Tag",
|
|
800
800
|
module: "tag",
|
|
@@ -813,9 +813,9 @@ export const USAGE = [
|
|
|
813
813
|
summary: "One Agent in a list of them: the orb, the name, and the line that says what the Agent is doing now or what it is for.",
|
|
814
814
|
when: "Nadia's Agents in her window's sidebar, and a website scene that shows a list of Agents.",
|
|
815
815
|
instead: "An Agent as a record among others in a page's list is a RecordList row with an agent IdentityMark; an Agent's own page heads with ObjectPage.",
|
|
816
|
-
behaviour: "It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone
|
|
817
|
-
words: 'The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia\'s list says "Working", "Idle" or "Needs you"; the
|
|
818
|
-
access: "The orb is decorative; the name and the state line are the row's text, read by its control.
|
|
816
|
+
behaviour: "It is the row's presentation alone: the consumer owns the control around it (Nadia's button that opens the Agent, a scene's list item that opens nothing). The current row's name is set in 500. A state tone draws the state line as a small StatusBadge; without a tone it stays plain text. Narrow, the orb stands alone and the words stay for a screen reader; the consumer names it with its state line in a tooltip, as Nadia's list does. Only the orb moves in the list. In Nadia's list the row is at least 52 px high, her orb at 32 px in her real state, in the narrow column from 640 to 899 px as in the wide one.",
|
|
817
|
+
words: 'The name, then one state line: what she is doing now ("Answering on Telegram", "Working") or what she is for ("Sorts requests"). The tone never says more than the line does. Nadia\'s list says "Working", "Idle" or "Needs you"; the badge marks a state that needs the person ("Needs you", a failed set-up), and the orb shows working by itself.',
|
|
818
|
+
access: "The orb is decorative; the name and the state line are the row's text, read by its control. StatusBadge owns its decorative mark, so the line carries its meaning.",
|
|
819
819
|
},
|
|
820
820
|
{
|
|
821
821
|
name: "Breadcrumb",
|
|
@@ -1065,7 +1065,7 @@ export const USAGE = [
|
|
|
1065
1065
|
family: "Data",
|
|
1066
1066
|
summary: "A ring that shows one ratio out of 100.",
|
|
1067
1067
|
when: '"A 0–100 ratio against a fixed maximum where the comparison is the point, like quota usage, build cache hit rate, uptime, or billing-period consumption." (https://vercel.com/geist/gauge) Ours: one ratio out of 100 on Base UI `Meter`. `size` follows the weight of the figure beside it: `xs` (20 px), `sm` (32), `md` (64) and `lg` (128). The centre holds the number or an icon.',
|
|
1068
|
-
instead: '"For determinate task progress with a known total (uploads, multi-step setup), use `Progress`." (https://vercel.com/geist/gauge) "For binary or enumerated state, use `Status Dot` for deployments or `Badge` for everything else." (https://vercel.com/geist/gauge) Ours:
|
|
1068
|
+
instead: '"For determinate task progress with a known total (uploads, multi-step setup), use `Progress`." (https://vercel.com/geist/gauge) "For binary or enumerated state, use `Status Dot` for deployments or `Badge` for everything else." (https://vercel.com/geist/gauge) Ours: every state uses `StatusBadge`. A single figure on its own is a `KpiCard`. A wait of unknown length is the waiting line; the gauge has no indeterminate form. Two shares of one whole are a chart: the gauge is a control for one ratio, never a chart.',
|
|
1069
1069
|
behaviour: '"Use `arc="equal"` for true ratios so 50% reads as exactly half." (https://vercel.com/geist/gauge) "Use the default `primary` arc for single-percentage usage where the filled portion is the story." (https://vercel.com/geist/gauge) "When using the gauge to display a ratio, use the `equal` arc priority to make both arcs are equally sized." (https://vercel.com/geist/gauge) Ours: there is no `arc` prop and so no two-arc `equal` ratio; the gauge always draws the primary arc, from the top, clockwise, with round ends and a small gap before the neutral track; at 0 or 100 there is no gap. Colour sits on the arc alone: the track stays the neutral line colour, and the number and icon stay neutral. "Threshold colors should match the same numeric breakpoints used elsewhere in the product (`>=80%` warning, `>=95%` error). Don’t invent gauge-only thresholds." (https://vercel.com/geist/gauge) Ours: `tone` is that threshold, never derived from the value, and takes `Progress`\'s tones; there is no `colors` map. "Pair `indeterminate` with explanatory copy nearby (`Calculating usage…`) so the user knows the value is loading, not zero." (https://vercel.com/geist/gauge) Ours: there is no `indeterminate`; a value still loading is the waiting line. The smallest size has room only for an icon. The arc moves on `open`, still under reduced motion.',
|
|
1070
1070
|
words: '"Always pair the gauge with an adjacent label or `Tooltip` naming what the number represents (`Build Cache Hit Rate`). The gauge alone is not self-describing." (https://vercel.com/geist/gauge) "Don’t put units inside `children`; the label carries the unit (`Uptime · 99.97%`). `children` is reserved for an icon overlay." (https://vercel.com/geist/gauge) "When `showValue` is on, the rendered number is the value only. Never inject a `%` or unit string into the prop." (https://vercel.com/geist/gauge) Ours: sentence case, *Cache hit rate · 99.97%*. `showValue` prints the number; `children` is only an icon.',
|
|
1071
1071
|
access: '"The component sets `role="progressbar"` with `aria-valuemin`, `aria-valuemax`, and `aria-valuenow`. Don’t override those." (https://vercel.com/geist/gauge) Ours: the role is `meter`, with the same three values. "The adjacent label is the gauge’s accessible name. Tie it with `aria-labelledby` on the gauge wrapper so screen readers read “Uptime, 99 percent.”" (https://vercel.com/geist/gauge) Ours: it always has a name, `aria-label` or `aria-labelledby` pointing at the adjacent label, and the type asks for one. "Don’t use color to encode the threshold without redundant text; pair the warning tint with copy below or in the Tooltip." (https://vercel.com/geist/gauge)',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nadicodeai/ui",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.125",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@base-ui/react": "^1.9.0",
|
|
84
84
|
"@iconify-icons/logos": "^2.0.3",
|
|
85
85
|
"@iconify/react": "^6.0.2",
|
|
86
|
-
"@nadicodeai/design-system": "12.1.
|
|
86
|
+
"@nadicodeai/design-system": "12.1.125",
|
|
87
87
|
"@tanstack/react-table": "^9.3.1",
|
|
88
88
|
"@vgpu/wgsl": "0.6.0",
|
|
89
89
|
"class-variance-authority": "^0.7.1",
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import type { ComponentProps } from "react";
|
|
2
|
-
type StatusTone = "good" | "muted" | "warn" | "bad";
|
|
3
|
-
type StatusDotName = {
|
|
4
|
-
label: string;
|
|
5
|
-
showLabel?: boolean;
|
|
6
|
-
decorative?: never;
|
|
7
|
-
} | {
|
|
8
|
-
decorative: true;
|
|
9
|
-
label?: never;
|
|
10
|
-
showLabel?: never;
|
|
11
|
-
};
|
|
12
|
-
type StatusDotProps = Omit<ComponentProps<"span">, "children" | "role" | "title" | "aria-hidden" | "aria-label" | "aria-labelledby"> & {
|
|
13
|
-
tone: StatusTone;
|
|
14
|
-
} & StatusDotName;
|
|
15
|
-
/**
|
|
16
|
-
* A small still dot for one state, named by its label or by the word beside it.
|
|
17
|
-
*
|
|
18
|
-
* @family Status
|
|
19
|
-
* @when "Deployment lifecycle only. `state` accepts `QUEUED | BUILDING | READY | ERROR | CANCELED | DELETED`." (https://vercel.com/geist/status-dot)
|
|
20
|
-
* Ours: any one state in dense chrome (a channel, a machine in a list), set as `tone`. It always
|
|
21
|
-
* says which state it shows: `label` names it (*Ready*), and `decorative` stands for a word beside
|
|
22
|
-
* it that already does. The type asks for one of the two.
|
|
23
|
-
* "Don’t flash the color through every transitional state on a polling tick; only update when the readyState changes." (https://vercel.com/geist/status-dot)
|
|
24
|
-
* Ours: pick the tone from the state and keep it until the state changes.
|
|
25
|
-
* @instead "For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot)
|
|
26
|
-
* Ours: that `Badge` is `StatusBadge`; so is a status that stands alone, or one that needs a mark
|
|
27
|
-
* and a word.
|
|
28
|
-
* "For health summaries that need a number (uptime, hit rate), use `Gauge`; for in-flight work with a knowable total, use `Progress`." (https://vercel.com/geist/status-dot)
|
|
29
|
-
* Ours: something in motion is the waiting line or an Agent's orb; the dot has no info tone.
|
|
30
|
-
* @behaviour "The dot animates while `BUILDING` or `QUEUED` and goes static once the deployment reaches a terminal state." (https://vercel.com/geist/status-dot)
|
|
31
|
-
* "Don’t add a separate spinner alongside it." (https://vercel.com/geist/status-dot) Ours: still,
|
|
32
|
-
* even while a state is in progress: it never pulses. It has no deployment states and no `state`
|
|
33
|
-
* prop, only four generic tones. A 10 px dot; tones are `good`, `muted`,
|
|
34
|
-
* `warn`, `bad`, at full strength. Colour sits on the dot alone: with `showLabel` the word beside
|
|
35
|
-
* it is 14 px and neutral, never in the tone's colour. `label` alone draws the dot with the word as
|
|
36
|
-
* its name and tooltip; `showLabel` draws the word 8 px after it, for a dot with no other text
|
|
37
|
-
* around it.
|
|
38
|
-
* @words "Use `label` only when the dot stands alone without surrounding text; Geist sentence-cases the state for you (`Building`, `Ready`, `Error`)." (https://vercel.com/geist/status-dot)
|
|
39
|
-
* Ours: `label` is the required name unless the dot is `decorative`, and we write it in sentence
|
|
40
|
-
* case ourselves: *Ready*, *Error*, *Canceled*.
|
|
41
|
-
* "Don’t wrap the dot in extra prose like `Status: Ready`. The label already names the state." (https://vercel.com/geist/status-dot)
|
|
42
|
-
* @access "The component composes its own `aria-label` from `titlePrefix` plus the state message; don’t override it with a generic `aria-label="status"`." (https://vercel.com/geist/status-dot)
|
|
43
|
-
* Ours: there is no `titlePrefix` and no `aria-label` prop; `label` is the dot's name, an image
|
|
44
|
-
* role with that name.
|
|
45
|
-
* "When the dot sits inline with text that already names the state, mark the dot decorative with `aria-hidden` so screen readers don’t announce it twice." (https://vercel.com/geist/status-dot)
|
|
46
|
-
* Ours: `decorative` does it; the word beside the dot must name the state, and if that word is
|
|
47
|
-
* missing, the state is missing.
|
|
48
|
-
* "Color is not the only signal: every state ships with a distinct title and label so colorblind users get the same information." (https://vercel.com/geist/status-dot)
|
|
49
|
-
*/
|
|
50
|
-
declare function StatusDot({ className, tone, label, showLabel, decorative, ...props }: StatusDotProps): import("react").JSX.Element;
|
|
51
|
-
export { StatusDot };
|
|
52
|
-
export type { StatusTone };
|
|
53
|
-
//# sourceMappingURL=status-dot.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"status-dot.d.ts","sourceRoot":"","sources":["../../src/components/status-dot.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,KAAK,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAUpD,KAAK,aAAa,GACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAA;CAAE,GAC1D;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE3D,KAAK,cAAc,GAAG,IAAI,CACxB,cAAc,CAAC,MAAM,CAAC,EACtB,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,YAAY,GAAG,iBAAiB,CACjF,GAAG;IACF,IAAI,EAAE,UAAU,CAAC;CAClB,GAAG,aAAa,CAAC;AAElB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,IAAI,EACJ,KAAK,EACL,SAAiB,EACjB,UAAU,EACV,GAAG,KAAK,EACT,EAAE,cAAc,+BAuChB;AACD,OAAO,EAAE,SAAS,EAAE,CAAC;AACrB,YAAY,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { cn } from "../lib/utils.js";
|
|
3
|
-
const TONE_BG_CLASS = {
|
|
4
|
-
good: "bg-success",
|
|
5
|
-
muted: "bg-placeholder",
|
|
6
|
-
warn: "bg-warning",
|
|
7
|
-
bad: "bg-destructive",
|
|
8
|
-
};
|
|
9
|
-
const DOT_CLASS = "inline-block size-2.5 shrink-0 rounded-full";
|
|
10
|
-
/**
|
|
11
|
-
* A small still dot for one state, named by its label or by the word beside it.
|
|
12
|
-
*
|
|
13
|
-
* @family Status
|
|
14
|
-
* @when "Deployment lifecycle only. `state` accepts `QUEUED | BUILDING | READY | ERROR | CANCELED | DELETED`." (https://vercel.com/geist/status-dot)
|
|
15
|
-
* Ours: any one state in dense chrome (a channel, a machine in a list), set as `tone`. It always
|
|
16
|
-
* says which state it shows: `label` names it (*Ready*), and `decorative` stands for a word beside
|
|
17
|
-
* it that already does. The type asks for one of the two.
|
|
18
|
-
* "Don’t flash the color through every transitional state on a polling tick; only update when the readyState changes." (https://vercel.com/geist/status-dot)
|
|
19
|
-
* Ours: pick the tone from the state and keep it until the state changes.
|
|
20
|
-
* @instead "For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot)
|
|
21
|
-
* Ours: that `Badge` is `StatusBadge`; so is a status that stands alone, or one that needs a mark
|
|
22
|
-
* and a word.
|
|
23
|
-
* "For health summaries that need a number (uptime, hit rate), use `Gauge`; for in-flight work with a knowable total, use `Progress`." (https://vercel.com/geist/status-dot)
|
|
24
|
-
* Ours: something in motion is the waiting line or an Agent's orb; the dot has no info tone.
|
|
25
|
-
* @behaviour "The dot animates while `BUILDING` or `QUEUED` and goes static once the deployment reaches a terminal state." (https://vercel.com/geist/status-dot)
|
|
26
|
-
* "Don’t add a separate spinner alongside it." (https://vercel.com/geist/status-dot) Ours: still,
|
|
27
|
-
* even while a state is in progress: it never pulses. It has no deployment states and no `state`
|
|
28
|
-
* prop, only four generic tones. A 10 px dot; tones are `good`, `muted`,
|
|
29
|
-
* `warn`, `bad`, at full strength. Colour sits on the dot alone: with `showLabel` the word beside
|
|
30
|
-
* it is 14 px and neutral, never in the tone's colour. `label` alone draws the dot with the word as
|
|
31
|
-
* its name and tooltip; `showLabel` draws the word 8 px after it, for a dot with no other text
|
|
32
|
-
* around it.
|
|
33
|
-
* @words "Use `label` only when the dot stands alone without surrounding text; Geist sentence-cases the state for you (`Building`, `Ready`, `Error`)." (https://vercel.com/geist/status-dot)
|
|
34
|
-
* Ours: `label` is the required name unless the dot is `decorative`, and we write it in sentence
|
|
35
|
-
* case ourselves: *Ready*, *Error*, *Canceled*.
|
|
36
|
-
* "Don’t wrap the dot in extra prose like `Status: Ready`. The label already names the state." (https://vercel.com/geist/status-dot)
|
|
37
|
-
* @access "The component composes its own `aria-label` from `titlePrefix` plus the state message; don’t override it with a generic `aria-label="status"`." (https://vercel.com/geist/status-dot)
|
|
38
|
-
* Ours: there is no `titlePrefix` and no `aria-label` prop; `label` is the dot's name, an image
|
|
39
|
-
* role with that name.
|
|
40
|
-
* "When the dot sits inline with text that already names the state, mark the dot decorative with `aria-hidden` so screen readers don’t announce it twice." (https://vercel.com/geist/status-dot)
|
|
41
|
-
* Ours: `decorative` does it; the word beside the dot must name the state, and if that word is
|
|
42
|
-
* missing, the state is missing.
|
|
43
|
-
* "Color is not the only signal: every state ships with a distinct title and label so colorblind users get the same information." (https://vercel.com/geist/status-dot)
|
|
44
|
-
*/
|
|
45
|
-
function StatusDot({ className, tone, label, showLabel = false, decorative, ...props }) {
|
|
46
|
-
if (decorative) {
|
|
47
|
-
return (_jsx("span", { ...props, "aria-hidden": "true", className: cn(DOT_CLASS, TONE_BG_CLASS[tone], className), "data-slot": "status-dot", "data-tone": tone }));
|
|
48
|
-
}
|
|
49
|
-
if (showLabel) {
|
|
50
|
-
return (_jsxs("span", { ...props, className: cn("inline-flex items-center gap-2 text-sm leading-4 text-foreground", className), "data-slot": "status-dot", "data-tone": tone, children: [_jsx("span", { "aria-hidden": "true", className: cn(DOT_CLASS, TONE_BG_CLASS[tone]) }), label] }));
|
|
51
|
-
}
|
|
52
|
-
return (_jsx("span", { ...props, "aria-label": label, className: cn(DOT_CLASS, TONE_BG_CLASS[tone], className), "data-slot": "status-dot", "data-tone": tone, role: "img", title: label }));
|
|
53
|
-
}
|
|
54
|
-
export { StatusDot };
|