@nadicodeai/ui 12.1.89 → 12.1.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/agent-profile.d.ts +12 -5
- package/dist/components/agent-profile.d.ts.map +1 -1
- package/dist/components/agent-profile.js +10 -10
- package/dist/components/catalog-entry.d.ts +8 -5
- package/dist/components/catalog-entry.d.ts.map +1 -1
- package/dist/components/catalog-entry.js +9 -6
- package/dist/components/collection-page.d.ts +125 -0
- package/dist/components/collection-page.d.ts.map +1 -0
- package/dist/components/collection-page.js +149 -0
- package/dist/components/data-table.d.ts +12 -3
- package/dist/components/data-table.d.ts.map +1 -1
- package/dist/components/data-table.js +2 -2
- package/dist/components/form-dialog.d.ts +8 -3
- package/dist/components/form-dialog.d.ts.map +1 -1
- package/dist/components/form-dialog.js +7 -4
- package/dist/components/form-drawer.d.ts +15 -22
- package/dist/components/form-drawer.d.ts.map +1 -1
- package/dist/components/form-drawer.js +4 -4
- package/dist/components/record-identity.d.ts +12 -2
- package/dist/components/record-identity.d.ts.map +1 -1
- package/dist/components/record-identity.js +11 -2
- package/dist/components/record-time.d.ts +25 -0
- package/dist/components/record-time.d.ts.map +1 -0
- package/dist/components/record-time.js +52 -0
- package/dist/components/row-edit-form.d.ts +22 -0
- package/dist/components/row-edit-form.d.ts.map +1 -0
- package/dist/components/row-edit-form.js +16 -0
- package/dist/components/sidebar.js +3 -3
- package/dist/components/theme-mode-switcher.d.ts.map +1 -1
- package/dist/components/theme-mode-switcher.js +2 -8
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -1
- package/dist/hooks/use-mobile.js +9 -11
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/internal/form-submit.d.ts +25 -0
- package/dist/internal/form-submit.d.ts.map +1 -0
- package/dist/internal/form-submit.js +8 -0
- package/dist/internal/row-message.d.ts +18 -0
- package/dist/internal/row-message.d.ts.map +1 -0
- package/dist/internal/row-message.js +12 -0
- package/package.json +2 -2
|
@@ -4,11 +4,16 @@ import type { AgentOrbSize } from "./agent-orb.js";
|
|
|
4
4
|
import { type PageActionsProps } from "./page-actions.js";
|
|
5
5
|
import { RadioGroup } from "./radio-group.js";
|
|
6
6
|
import { type StatusBadgeTone } from "./status-badge.js";
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* A fact on the card whose label stays in place when its value is missing.
|
|
9
|
+
* `pending` draws the value's place while it is read, so a value not yet known
|
|
10
|
+
* never reads as missing.
|
|
11
|
+
*/
|
|
8
12
|
export type AgentProfileFact = {
|
|
9
13
|
label: string;
|
|
10
14
|
value?: string | null;
|
|
11
15
|
missingLabel: string;
|
|
16
|
+
pending?: boolean;
|
|
12
17
|
};
|
|
13
18
|
export type AgentProfileCardProps = {
|
|
14
19
|
/** Draws the Agent's orb at the size the card gives it. */
|
|
@@ -27,9 +32,10 @@ export type AgentProfileCardProps = {
|
|
|
27
32
|
ref?: Ref<HTMLButtonElement>;
|
|
28
33
|
} | undefined;
|
|
29
34
|
/**
|
|
30
|
-
* Her name, description and look as fields, drawn
|
|
31
|
-
*
|
|
32
|
-
*
|
|
35
|
+
* Her name, description and look as fields, drawn in place of her name and
|
|
36
|
+
* description while the person edits, with her facts kept under them; her
|
|
37
|
+
* name stays the page's heading for assistive technology, and the card's
|
|
38
|
+
* footer saves the fields with the rest of the card.
|
|
33
39
|
*/
|
|
34
40
|
editor?: ReactNode;
|
|
35
41
|
state: {
|
|
@@ -57,7 +63,8 @@ export type AgentProfileCardProps = {
|
|
|
57
63
|
/**
|
|
58
64
|
* The card an Agent's Profile opens with in every product (DESIGN.md, "Page
|
|
59
65
|
* compositions"): on the left her orb at 64, her name with the pencil, her
|
|
60
|
-
* description and her facts
|
|
66
|
+
* description and her facts; the pencil turns her name and description into
|
|
67
|
+
* fields in place, above the same facts; on
|
|
61
68
|
* the right her model and her reasoning; the card's footer saves both sides. Each product brings its own data,
|
|
62
69
|
* fields and words; the shape, sizes and order are this component's.
|
|
63
70
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-profile.d.ts","sourceRoot":"","sources":["../../src/components/agent-profile.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-profile.d.ts","sourceRoot":"","sources":["../../src/components/agent-profile.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMnE;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,2DAA2D;IAC3D,GAAG,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,SAAS,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAA;KAAE,GAAG,SAAS,CAAC;IACxF;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,eAAe,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,uEAAuE;IACvE,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,4CAA4C;IAC5C,MAAM,EAAE,gBAAgB,CAAC;IACzB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iFAAiF;IACjF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACvC,wDAAwD;IACxD,YAAY,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;CACvD,CAAC;AAUF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,IAAI,EACJ,WAAW,EACX,uBAAuB,EACvB,IAAI,EACJ,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,MAAM,EACN,UAAU,EACV,OAAO,EACP,YAAY,GACb,EAAE,qBAAqB,+BA4FvB;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,CAAC,EAC9C,UAAU,GAAG,OAAO,GAAG,UAAU,CAClC,GAAG;IACF,yDAAyD;IACzD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8DAA8D;IAC9D,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,OAAO,EACP,aAAa,EACb,WAAW,EACX,MAAM,EACN,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAuClB;AAED,MAAM,MAAM,oBAAoB,CAAC,MAAM,SAAS,MAAM,IAAI,IAAI,CAC5D,cAAc,CAAC,OAAO,UAAU,CAAC,EACjC,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO,CACxD,GAAG;IACF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrD,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,SAAS,MAAM,EAAE,EACrD,KAAK,EACL,OAAO,EACP,aAAa,EACb,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,oBAAoB,CAAC,MAAM,CAAC,+BA8B9B"}
|
|
@@ -11,31 +11,31 @@ import { ModelIdentity } from "./model-identity.js";
|
|
|
11
11
|
import { PageActionsRow } from "./page-actions.js";
|
|
12
12
|
import { RadioGroup } from "./radio-group.js";
|
|
13
13
|
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger } from "./select.js";
|
|
14
|
+
import { Skeleton } from "./skeleton.js";
|
|
14
15
|
import { StatusBadge } from "./status-badge.js";
|
|
15
16
|
import { TableValue } from "./table-value.js";
|
|
16
17
|
import { toggleVariants } from "./toggle.js";
|
|
17
18
|
const AGENT_PROFILE_ORB_SIZE = 64;
|
|
19
|
+
function FactValue({ fact }) {
|
|
20
|
+
return fact.pending ? (_jsx(Skeleton, { "aria-busy": "true", className: "h-4 w-24" })) : (_jsx(TableValue, { missingLabel: fact.missingLabel, value: fact.value }));
|
|
21
|
+
}
|
|
18
22
|
/**
|
|
19
23
|
* The card an Agent's Profile opens with in every product (DESIGN.md, "Page
|
|
20
24
|
* compositions"): on the left her orb at 64, her name with the pencil, her
|
|
21
|
-
* description and her facts
|
|
25
|
+
* description and her facts; the pencil turns her name and description into
|
|
26
|
+
* fields in place, above the same facts; on
|
|
22
27
|
* the right her model and her reasoning; the card's footer saves both sides. Each product brings its own data,
|
|
23
28
|
* fields and words; the shape, sizes and order are this component's.
|
|
24
29
|
*/
|
|
25
30
|
export function AgentProfileCard({ orb, name, description, descriptionMissingLabel, edit, editor, state, activity, origin, settings, footer, footerHint, actions, headingProps, }) {
|
|
26
31
|
const facts = [
|
|
27
32
|
{ label: state.label, value: _jsx(StatusBadge, { label: state.text, tone: state.tone }) },
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
value: _jsx(TableValue, { missingLabel: activity.missingLabel, value: activity.value }),
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
label: origin.label,
|
|
34
|
-
value: _jsx(TableValue, { missingLabel: origin.missingLabel, value: origin.value }),
|
|
35
|
-
},
|
|
33
|
+
{ label: activity.label, value: _jsx(FactValue, { fact: activity }) },
|
|
34
|
+
{ label: origin.label, value: _jsx(FactValue, { fact: origin }) },
|
|
36
35
|
];
|
|
36
|
+
const factList = (_jsx("dl", { className: "mt-nadicode-sm flex min-w-0 flex-wrap gap-x-nadicode-lg gap-y-nadicode-sm", "data-slot": "agent-profile-facts", children: facts.map((fact) => (_jsxs("div", { className: "grid min-w-0 gap-1", children: [_jsx("dt", { className: "text-xs text-muted-foreground", children: fact.label }), _jsx("dd", { className: "flex min-h-6 min-w-0 items-center text-sm", children: fact.value })] }, fact.label))) }));
|
|
37
37
|
const text = description?.trim();
|
|
38
|
-
return (_jsxs(Card, { className: "@container/agent-profile min-w-0", render: _jsx("section", { "aria-labelledby": headingProps?.id }), "data-slot": "agent-profile", children: [_jsxs(CardContent, { className: "grid min-w-0 gap-nadicode-lg @3xl/agent-profile:grid-cols-[minmax(0,1fr)_minmax(18rem,22rem)] @3xl/agent-profile:gap-nadicode-xl", children: [_jsxs("div", { className: "grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-start gap-nadicode-md", children: [_jsx("div", { className: "shrink-0", children: orb(AGENT_PROFILE_ORB_SIZE) }), editor ? (_jsxs("div", { className: "grid min-w-0 gap-nadicode-md", "data-slot": "agent-profile-editor", children: [_jsx("h1", { ...headingProps, className: cn("
|
|
38
|
+
return (_jsxs(Card, { className: "@container/agent-profile min-w-0", render: _jsx("section", { "aria-labelledby": headingProps?.id }), "data-slot": "agent-profile", children: [_jsxs(CardContent, { className: "grid min-w-0 gap-nadicode-lg @3xl/agent-profile:grid-cols-[minmax(0,1fr)_minmax(18rem,22rem)] @3xl/agent-profile:gap-nadicode-xl", children: [_jsxs("div", { className: "grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-start gap-nadicode-md", children: [_jsx("div", { className: "shrink-0", children: orb(AGENT_PROFILE_ORB_SIZE) }), editor ? (_jsxs("div", { className: "grid min-w-0 gap-nadicode-md", "data-slot": "agent-profile-editor", children: [_jsx("h1", { ...headingProps, className: cn("sr-only", headingProps?.className), children: name }), editor, factList] })) : (_jsxs("div", { className: "grid min-w-0 gap-1", children: [_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-x-1 gap-y-nadicode-sm", children: [_jsx("h1", { ...headingProps, className: cn("min-w-0 text-heading-md break-words text-foreground outline-none", headingProps?.className), children: name }), edit ? (_jsx(Button, { "aria-label": edit.label, onClick: edit.onClick, ref: edit.ref, size: "icon", title: edit.label, type: "button", variant: "ghost", children: _jsx(PencilIcon, { "aria-hidden": "true", "data-icon": true }) })) : null, actions ? (_jsx("div", { className: "ml-auto flex shrink-0 items-center gap-2 pl-nadicode-sm", "data-slot": "agent-profile-actions", children: _jsx(PageActionsRow, { ...actions }) })) : null] }), _jsx("p", { className: "line-clamp-2 min-w-0 text-sm text-muted-foreground", title: text, children: _jsx(TableValue, { missingLabel: descriptionMissingLabel, value: text }) }), factList] }))] }), settings ? (_jsx("div", { className: "grid min-w-0 content-start gap-nadicode-md border-t border-border pt-nadicode-md @3xl/agent-profile:border-t-0 @3xl/agent-profile:border-l @3xl/agent-profile:pt-0 @3xl/agent-profile:pl-nadicode-lg", "data-slot": "agent-profile-settings", children: settings })) : null] }), _jsx(FooterStrip, { hint: footerHint, hintSlot: "agent-profile-hint", children: footer })] }));
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* A model chosen from a list: the trigger and every option read the model the
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type * as React from "react";
|
|
2
|
+
import { type RowMessage } from "../internal/row-message.js";
|
|
3
|
+
export type { RowMessage };
|
|
2
4
|
/**
|
|
3
5
|
* The line icon a catalog entry names. A name outside `CATALOG_ICONS`, or
|
|
4
6
|
* none, draws the sparkles every unnamed entry shares.
|
|
@@ -17,15 +19,16 @@ export declare function CatalogEntryList({ children, className, columns, }: {
|
|
|
17
19
|
}): React.JSX.Element;
|
|
18
20
|
/**
|
|
19
21
|
* One entry of a Library shelf: its kind's tile, its name, one line of
|
|
20
|
-
* description, and at the trailing end what the viewer can do with it.
|
|
21
|
-
*
|
|
22
|
-
* the entry's
|
|
22
|
+
* description, and at the trailing end what the viewer can do with it. When
|
|
23
|
+
* that action failed or cannot run, `state` puts its message in the
|
|
24
|
+
* description's place and its actions before the entry's own, inside the entry. The
|
|
25
|
+
* caller writes the entry's `<li>`.
|
|
23
26
|
*/
|
|
24
|
-
export declare function CatalogEntryRow({ actions, description, media,
|
|
27
|
+
export declare function CatalogEntryRow({ actions, description, media, state, title, }: {
|
|
25
28
|
actions?: React.ReactNode;
|
|
26
29
|
description: React.ReactNode;
|
|
27
30
|
media: React.ReactNode;
|
|
28
|
-
|
|
31
|
+
state?: RowMessage | null;
|
|
29
32
|
title: React.ReactNode;
|
|
30
33
|
}): React.JSX.Element;
|
|
31
34
|
//# sourceMappingURL=catalog-entry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-entry.d.ts","sourceRoot":"","sources":["../../src/components/catalog-entry.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog-entry.d.ts","sourceRoot":"","sources":["../../src/components/catalog-entry.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAYpC,OAAO,EAAE,KAAK,UAAU,EAAqC,MAAM,wBAAwB,CAAC;AAE5F,YAAY,EAAE,UAAU,EAAE,CAAC;AAoC3B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,qBAGxE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,SAAS,EACT,OAAW,GACZ,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;CACjB,qBASA;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,WAAW,EACX,KAAK,EACL,KAAK,EACL,KAAK,GACN,EAAE;IACD,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,qBAqBA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { BookOpen, Briefcase, Calculator, Calendar, FileCheck, FileSearch, FileText, Globe, Inbox, Landmark, Languages, ListChecks, Mail, MessageCircle, Mic, NotebookPen, Phone, Presentation, Receipt, Scale, Send, ShieldCheck, Sparkles, Truck, Users, Wallet, } from "lucide-react";
|
|
3
3
|
import { Item, ItemActions, ItemContent, ItemDescription, ItemGroup, ItemMedia, ItemTitle, } from "./item.js";
|
|
4
|
+
import { RowMessageActions, RowMessageLine } from "../internal/row-message.js";
|
|
4
5
|
import { cn } from "../lib/utils.js";
|
|
5
6
|
const ICONS = {
|
|
6
7
|
"book-open": BookOpen,
|
|
@@ -50,10 +51,12 @@ export function CatalogEntryList({ children, className, columns = 1, }) {
|
|
|
50
51
|
}
|
|
51
52
|
/**
|
|
52
53
|
* One entry of a Library shelf: its kind's tile, its name, one line of
|
|
53
|
-
* description, and at the trailing end what the viewer can do with it.
|
|
54
|
-
*
|
|
55
|
-
* the entry's
|
|
54
|
+
* description, and at the trailing end what the viewer can do with it. When
|
|
55
|
+
* that action failed or cannot run, `state` puts its message in the
|
|
56
|
+
* description's place and its actions before the entry's own, inside the entry. The
|
|
57
|
+
* caller writes the entry's `<li>`.
|
|
56
58
|
*/
|
|
57
|
-
export function CatalogEntryRow({ actions, description, media,
|
|
58
|
-
|
|
59
|
+
export function CatalogEntryRow({ actions, description, media, state, title, }) {
|
|
60
|
+
const controls = state ? (_jsxs(_Fragment, { children: [_jsx(RowMessageActions, { state: state }), actions] })) : (actions);
|
|
61
|
+
return (_jsxs(Item, { children: [_jsx(ItemMedia, { children: media }), _jsxs(ItemContent, { className: "min-w-0", children: [_jsx(ItemTitle, { children: title }), _jsx(ItemDescription, { className: state ? undefined : "line-clamp-1", children: state ? _jsx(RowMessageLine, { state: state }) : description })] }), controls ? _jsx(ItemActions, { children: controls }) : null] }));
|
|
59
62
|
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { RowData } from "@tanstack/react-table";
|
|
2
|
+
import { type ReactElement, type ReactNode } from "react";
|
|
3
|
+
import { type CollectionSortProps } from "./collection-sort.js";
|
|
4
|
+
import { type DataTableRowLinkProps } from "./data-table.js";
|
|
5
|
+
import { type EmptyStateProps } from "./empty-state.js";
|
|
6
|
+
import { type PageActionsProps } from "./page-actions.js";
|
|
7
|
+
import { type StatusBadgeTone } from "./status-badge.js";
|
|
8
|
+
import { type RowMessage } from "../internal/row-message.js";
|
|
9
|
+
/** One thing a person can do to a record. */
|
|
10
|
+
export type RecordCommand = {
|
|
11
|
+
label: string;
|
|
12
|
+
/** Its name for assistive technology when the label alone does not say what it does: "Let Sofia use Gmail". */
|
|
13
|
+
accessibleName?: string;
|
|
14
|
+
icon: ReactElement;
|
|
15
|
+
onSelect: () => void;
|
|
16
|
+
destructive?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
/** Why the command cannot run now, read after its name. */
|
|
19
|
+
reason?: ReactNode;
|
|
20
|
+
};
|
|
21
|
+
export type { RowMessage };
|
|
22
|
+
export type CollectionPageProps<TRecord extends RowData> = {
|
|
23
|
+
/** Names the collection for assistive technology: "Skills". */
|
|
24
|
+
label: string;
|
|
25
|
+
/** The page's title, when the collection is the page; a section titled by its shell leaves it out. */
|
|
26
|
+
title?: string;
|
|
27
|
+
/** The title's commands; a `primary` that is also the first-use action shows only once there are records. */
|
|
28
|
+
actions?: PageActionsProps;
|
|
29
|
+
search?: {
|
|
30
|
+
label: string;
|
|
31
|
+
value: string;
|
|
32
|
+
onValueChange: (value: string) => void;
|
|
33
|
+
};
|
|
34
|
+
sort?: CollectionSortProps;
|
|
35
|
+
/** The records to show, already searched and ordered; `undefined` while they load. */
|
|
36
|
+
records: readonly TRecord[] | undefined;
|
|
37
|
+
/** Names the rows while they load; the collection's `label` when left out. */
|
|
38
|
+
loadingLabel?: string;
|
|
39
|
+
/** The read failed: shown in place of the rows. */
|
|
40
|
+
failed?: Extract<EmptyStateProps, {
|
|
41
|
+
kind: "failed";
|
|
42
|
+
}>;
|
|
43
|
+
/** There are no records at all; a collection shown only when it has records leaves it out. */
|
|
44
|
+
empty?: Extract<EmptyStateProps, {
|
|
45
|
+
kind: "firstUse" | "nothingYet";
|
|
46
|
+
}>;
|
|
47
|
+
/** The search matched nothing; a collection without one leaves it out. */
|
|
48
|
+
noMatch?: Omit<Extract<EmptyStateProps, {
|
|
49
|
+
kind: "noResults";
|
|
50
|
+
}>, "kind">;
|
|
51
|
+
getId: (record: TRecord) => string;
|
|
52
|
+
/** The record's name, and one line saying what it is or where it comes from. */
|
|
53
|
+
name: (record: TRecord) => {
|
|
54
|
+
name: ReactNode;
|
|
55
|
+
detail?: ReactNode;
|
|
56
|
+
mark?: ReactNode;
|
|
57
|
+
};
|
|
58
|
+
/** The name is the record's whole text, such as a memory, and wraps in full instead of ending in an ellipsis. */
|
|
59
|
+
wraps?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Facts of one kind each, a column apiece after the name, every value saying
|
|
62
|
+
* what it is by its own word or mark: "Skills: price-quotes", a commit. A fact
|
|
63
|
+
* holds one line at its own width; `prose` is a phrase that takes the row's spare width.
|
|
64
|
+
*/
|
|
65
|
+
facts?: readonly {
|
|
66
|
+
id: string;
|
|
67
|
+
label: string;
|
|
68
|
+
of: (record: TRecord) => ReactNode;
|
|
69
|
+
prose?: boolean;
|
|
70
|
+
}[];
|
|
71
|
+
/** A status only when it tells this record apart from the others; `null` for the usual case. */
|
|
72
|
+
status?: {
|
|
73
|
+
label: string;
|
|
74
|
+
of: (record: TRecord) => {
|
|
75
|
+
label: string;
|
|
76
|
+
tone: StatusBadgeTone;
|
|
77
|
+
} | null;
|
|
78
|
+
};
|
|
79
|
+
/** When something happened to the record, in its verb's sentence. */
|
|
80
|
+
time?: {
|
|
81
|
+
label: string;
|
|
82
|
+
of: (record: TRecord) => Date | number | string | null | undefined;
|
|
83
|
+
phrase: (when: string) => string;
|
|
84
|
+
/** What a screen reader hears where a record has no time, beside the muted dash. */
|
|
85
|
+
missing: string;
|
|
86
|
+
locale?: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* What a person can do to the record: one command is a button in the row; two or
|
|
90
|
+
* more, or a destructive one, open the row's menu, the destructive last.
|
|
91
|
+
*/
|
|
92
|
+
commands?: (record: TRecord) => readonly RecordCommand[];
|
|
93
|
+
/**
|
|
94
|
+
* The row's one outline button that starts what the record is not doing yet,
|
|
95
|
+
* "Connect", with what it is waiting for; its commands then stay in the menu after it.
|
|
96
|
+
*/
|
|
97
|
+
start?: (record: TRecord) => ReactNode;
|
|
98
|
+
commandsLabel?: (record: TRecord) => string;
|
|
99
|
+
/** Names the commands column for assistive technology: "Actions". */
|
|
100
|
+
commandsHeader?: string;
|
|
101
|
+
/** The record opens its own page; the row shows the way in. A record that opens nothing has no `href`. */
|
|
102
|
+
open?: {
|
|
103
|
+
href: (record: TRecord) => string | null;
|
|
104
|
+
label: (record: TRecord) => string;
|
|
105
|
+
/** Draws the row's link, for a router that opens it itself. */
|
|
106
|
+
renderLink?: (props: DataTableRowLinkProps) => ReactNode;
|
|
107
|
+
};
|
|
108
|
+
/** The record's own action failed or cannot run: its message, inside the row. */
|
|
109
|
+
state?: (record: TRecord) => RowMessage | null;
|
|
110
|
+
/** The record being edited, and its `RowEditForm`, drawn inside its row. */
|
|
111
|
+
editor?: {
|
|
112
|
+
id: string;
|
|
113
|
+
render: (record: TRecord) => ReactNode;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* The Collection composition (DESIGN.md "Page compositions", "Tables and
|
|
118
|
+
* missing values"), whole: the title with the page's actions, the toolbar's
|
|
119
|
+
* search and sort, then one row per record that reads without a header row:
|
|
120
|
+
* its name over what it is, a status only when it is the exception, when it
|
|
121
|
+
* happened in its verb's sentence, and its commands. A failed or refused action
|
|
122
|
+
* and an edit stay inside their own row.
|
|
123
|
+
*/
|
|
124
|
+
export declare function CollectionPage<TRecord extends RowData>(props: CollectionPageProps<TRecord>): import("react").JSX.Element;
|
|
125
|
+
//# sourceMappingURL=collection-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-page.d.ts","sourceRoot":"","sources":["../../src/components/collection-page.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronRight } from "lucide-react";
|
|
4
|
+
import { createContext, useContext } from "react";
|
|
5
|
+
import { ActionMenu } from "./action-menu.js";
|
|
6
|
+
import { Button } from "./button.js";
|
|
7
|
+
import { CollectionSearch } from "./collection-search.js";
|
|
8
|
+
import { CollectionSort } from "./collection-sort.js";
|
|
9
|
+
import { CollectionToolbar } from "./collection-toolbar.js";
|
|
10
|
+
import { DataTable, } from "./data-table.js";
|
|
11
|
+
import { DropdownMenuCommand, DropdownMenuSeparator } from "./dropdown-menu.js";
|
|
12
|
+
import { EmptyState } from "./empty-state.js";
|
|
13
|
+
import { PageActions } from "./page-actions.js";
|
|
14
|
+
import { PageHeader } from "./page-header.js";
|
|
15
|
+
import { RecordIdentity } from "./record-identity.js";
|
|
16
|
+
import { RecordTime, recordDate } from "./record-time.js";
|
|
17
|
+
import { TableValue } from "./table-value.js";
|
|
18
|
+
import { Skeleton } from "./skeleton.js";
|
|
19
|
+
import { StatusBadge } from "./status-badge.js";
|
|
20
|
+
import { TableCard } from "./table-card.js";
|
|
21
|
+
import { RowMessageActions, RowMessageLine } from "../internal/row-message.js";
|
|
22
|
+
const ShownCollection = createContext(undefined);
|
|
23
|
+
function useShownCollection() {
|
|
24
|
+
return useContext(ShownCollection);
|
|
25
|
+
}
|
|
26
|
+
/*
|
|
27
|
+
* Each cell is one component for the page's whole life: TanStack renders a
|
|
28
|
+
* column's `cell` as a component, so a function made anew on each render would
|
|
29
|
+
* remount every row's cells on every render, closing a row's open menu when
|
|
30
|
+
* the records are read again. The cells read the page's current props instead.
|
|
31
|
+
*/
|
|
32
|
+
function NameCell({ row }) {
|
|
33
|
+
const props = useShownCollection();
|
|
34
|
+
const shown = props.name(row.original);
|
|
35
|
+
const state = props.state?.(row.original);
|
|
36
|
+
return (_jsx(RecordIdentity, { detail: state ? _jsx(RowMessageLine, { state: state }) : shown.detail, mark: shown.mark, name: shown.name, wraps: props.wraps }));
|
|
37
|
+
}
|
|
38
|
+
function FactCell({ column, row }) {
|
|
39
|
+
const fact = useShownCollection().facts?.find((each) => each.id === column.id);
|
|
40
|
+
return _jsx(_Fragment, { children: fact?.of(row.original) });
|
|
41
|
+
}
|
|
42
|
+
function StatusCell({ row }) {
|
|
43
|
+
const shown = useShownCollection().status?.of(row.original);
|
|
44
|
+
return shown ? _jsx(StatusBadge, { label: shown.label, tone: shown.tone }) : null;
|
|
45
|
+
}
|
|
46
|
+
function TimeCell({ row }) {
|
|
47
|
+
const time = useShownCollection().time;
|
|
48
|
+
if (!time)
|
|
49
|
+
return null;
|
|
50
|
+
const at = recordDate(time.of(row.original));
|
|
51
|
+
return (_jsx(TableValue, { missingLabel: time.missing, value: at ? _jsx(RecordTime, { at: at, locale: time.locale, phrase: time.phrase }) : null }));
|
|
52
|
+
}
|
|
53
|
+
function CommandsCell({ row }) {
|
|
54
|
+
const props = useShownCollection();
|
|
55
|
+
const state = props.state?.(row.original);
|
|
56
|
+
const commands = props.commands?.(row.original) ?? [];
|
|
57
|
+
const way = commands.length > 0 ? (_jsx(Commands, { commands: commands, label: props.commandsLabel?.(row.original) ?? props.label, menu: props.start !== undefined })) : props.open?.href(row.original) && !state ? (_jsx(ChevronRight, { "aria-hidden": "true", className: "size-4 text-muted-foreground" })) : null;
|
|
58
|
+
if (!props.start && !state)
|
|
59
|
+
return way;
|
|
60
|
+
return (_jsxs("div", { className: "flex items-center justify-end gap-2", children: [props.start?.(row.original), state ? _jsx(RowMessageActions, { state: state }) : null, way] }));
|
|
61
|
+
}
|
|
62
|
+
function LoadingRecords({ label }) {
|
|
63
|
+
return (_jsx("div", { "aria-busy": "true", "aria-label": label, className: "divide-y divide-border", role: "status", children: Array.from({ length: 3 }, (_, index) => (_jsxs("div", { className: "flex h-16 items-center gap-3 px-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsx(Skeleton, { className: "h-4 w-40 max-w-full" }), _jsx(Skeleton, { className: "h-3 w-56 max-w-full" })] }), _jsx(Skeleton, { className: "ml-auto h-4 w-28" })] }, index))) }));
|
|
64
|
+
}
|
|
65
|
+
function Commands({ commands, label, menu, }) {
|
|
66
|
+
const [only] = commands;
|
|
67
|
+
if (!only)
|
|
68
|
+
return null;
|
|
69
|
+
if (commands.length === 1 && !only.destructive && !menu) {
|
|
70
|
+
return (_jsx(Button, { "aria-label": only.accessibleName, disabled: only.disabled, onClick: only.onSelect, type: "button", variant: "outline", children: only.label }));
|
|
71
|
+
}
|
|
72
|
+
const kept = commands.filter((command) => !command.destructive);
|
|
73
|
+
const destructive = commands.filter((command) => command.destructive);
|
|
74
|
+
return (_jsxs(ActionMenu, { label: label, children: [kept.map((command) => (_jsx(DropdownMenuCommand, { "aria-label": command.accessibleName, disabled: command.disabled, icon: command.icon, onClick: command.onSelect, reason: command.reason, children: command.label }, command.label))), kept.length > 0 && destructive.length > 0 ? _jsx(DropdownMenuSeparator, {}) : null, destructive.map((command) => (_jsx(DropdownMenuCommand, { "aria-label": command.accessibleName, disabled: command.disabled, icon: command.icon, onClick: command.onSelect, reason: command.reason, variant: "destructive", children: command.label }, command.label)))] }));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The Collection composition (DESIGN.md "Page compositions", "Tables and
|
|
78
|
+
* missing values"), whole: the title with the page's actions, the toolbar's
|
|
79
|
+
* search and sort, then one row per record that reads without a header row:
|
|
80
|
+
* its name over what it is, a status only when it is the exception, when it
|
|
81
|
+
* happened in its verb's sentence, and its commands. A failed or refused action
|
|
82
|
+
* and an edit stay inside their own row.
|
|
83
|
+
*/
|
|
84
|
+
export function CollectionPage(props) {
|
|
85
|
+
const { label, title, actions, search, sort, records } = props;
|
|
86
|
+
const hasRecords = records !== undefined && records.length > 0;
|
|
87
|
+
const searching = Boolean(search?.value);
|
|
88
|
+
const addsFirst = props.empty?.kind === "firstUse" && props.empty.action === actions?.primary;
|
|
89
|
+
const shownActions = addsFirst && !hasRecords && !searching ? { ...actions, primary: undefined } : actions;
|
|
90
|
+
const columns = [
|
|
91
|
+
{ id: "name", header: label, meta: props.wraps ? { wraps: true } : undefined, cell: NameCell },
|
|
92
|
+
];
|
|
93
|
+
for (const fact of props.facts ?? []) {
|
|
94
|
+
columns.push({
|
|
95
|
+
id: fact.id,
|
|
96
|
+
header: fact.label,
|
|
97
|
+
meta: fact.prose ? { prose: true } : { narrow: true },
|
|
98
|
+
cell: FactCell,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (props.status) {
|
|
102
|
+
columns.push({
|
|
103
|
+
id: "status",
|
|
104
|
+
header: props.status.label,
|
|
105
|
+
meta: { narrow: true },
|
|
106
|
+
cell: StatusCell,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (props.time) {
|
|
110
|
+
columns.push({ id: "time", header: props.time.label, meta: { narrow: true }, cell: TimeCell });
|
|
111
|
+
}
|
|
112
|
+
if (props.commands || props.open || props.state || props.start) {
|
|
113
|
+
columns.push({
|
|
114
|
+
id: "commands",
|
|
115
|
+
header: props.commandsHeader ?? label,
|
|
116
|
+
meta: { narrow: true },
|
|
117
|
+
cell: CommandsCell,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const primaryColumns = columns.map((column) => String(column.id));
|
|
121
|
+
let body;
|
|
122
|
+
if (props.failed) {
|
|
123
|
+
body = _jsx(EmptyState, { ...props.failed });
|
|
124
|
+
}
|
|
125
|
+
else if (records === undefined) {
|
|
126
|
+
body = _jsx(LoadingRecords, { label: props.loadingLabel ?? label });
|
|
127
|
+
}
|
|
128
|
+
else if (!hasRecords && searching && props.noMatch) {
|
|
129
|
+
body = _jsx(EmptyState, { kind: "noResults", ...props.noMatch });
|
|
130
|
+
}
|
|
131
|
+
else if (!hasRecords) {
|
|
132
|
+
body = props.empty ? _jsx(EmptyState, { ...props.empty }) : null;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const table = {
|
|
136
|
+
columns,
|
|
137
|
+
data: [...records],
|
|
138
|
+
embedded: true,
|
|
139
|
+
empty: { kind: "nothingYet", message: label },
|
|
140
|
+
getRowId: props.getId,
|
|
141
|
+
primaryColumns,
|
|
142
|
+
showColumnHeaders: false,
|
|
143
|
+
rowEditor: props.editor ? { rowId: props.editor.id, render: props.editor.render } : undefined,
|
|
144
|
+
tableLabel: label,
|
|
145
|
+
};
|
|
146
|
+
body = props.open ? (_jsx(DataTable, { ...table, primaryColumnId: "name", renderRowLink: props.open.renderLink, rowHref: props.open.href, rowLabel: props.open.label })) : (_jsx(DataTable, { ...table }));
|
|
147
|
+
}
|
|
148
|
+
return (_jsxs("div", { className: "grid min-w-0 gap-4", "data-slot": "collection-page", children: [title ? _jsx(PageHeader, { title: title }) : null, shownActions ? _jsx(PageActions, { ...shownActions }) : null, search && (hasRecords || searching) ? (_jsx(CollectionToolbar, { actions: sort ? _jsx(CollectionSort, { ...sort }) : undefined, label: label, search: _jsx(CollectionSearch, { ...search }), surface: "plain" })) : null, _jsx(TableCard, { children: _jsx(ShownCollection.Provider, { value: props, children: body }) })] }));
|
|
149
|
+
}
|
|
@@ -135,14 +135,23 @@ type DataTableBaseProps<TData extends RowData> = {
|
|
|
135
135
|
renderToolbar?: (slots: DataTableToolbarSlots) => React.ReactNode;
|
|
136
136
|
/** Wraps the card, such as a frame that keeps it readable while new data loads. */
|
|
137
137
|
wrapCard?: (card: React.ReactNode) => React.ReactNode;
|
|
138
|
+
/**
|
|
139
|
+
* The record being edited and its form, drawn inside its row under the
|
|
140
|
+
* record's own line (DESIGN.md "Menus and commands"); `rowId` is the
|
|
141
|
+
* `getRowId` of that record. The form is a `RowEditForm`.
|
|
142
|
+
*/
|
|
143
|
+
rowEditor?: {
|
|
144
|
+
rowId: string;
|
|
145
|
+
render: (row: TData) => React.ReactNode;
|
|
146
|
+
};
|
|
138
147
|
};
|
|
139
148
|
type DataTableRowNav<TData extends RowData> = {
|
|
140
149
|
rowHref?: undefined;
|
|
141
150
|
rowLabel?: undefined;
|
|
142
151
|
primaryColumnId?: undefined;
|
|
143
152
|
} | {
|
|
144
|
-
/** Makes each row navigable through exactly one link placed on the primary cell. */
|
|
145
|
-
rowHref: (row: TData) => string;
|
|
153
|
+
/** Makes each row navigable through exactly one link placed on the primary cell; `null` for a row that opens nothing. */
|
|
154
|
+
rowHref: (row: TData) => string | null;
|
|
146
155
|
/** Purposeful, localized accessible name for the row link (e.g. "Open Studio Rossi"). */
|
|
147
156
|
rowLabel: (row: TData) => string;
|
|
148
157
|
/** Column id that carries the link; defaults to the row's first visible column. */
|
|
@@ -150,6 +159,6 @@ type DataTableRowNav<TData extends RowData> = {
|
|
|
150
159
|
};
|
|
151
160
|
export type DataTableProps<TData extends RowData> = DataTableBaseProps<TData> & DataTableRowNav<TData>;
|
|
152
161
|
export declare function columnMenuLabel<TData extends RowData, TValue extends CellData = CellData>(column: DataTableColumn<TData, TValue>): string;
|
|
153
|
-
export declare function DataTable<TData extends RowData>({ columns, data, getRowId, filterColumnId, filterPlaceholder, primaryColumns, compactLayout: requestedCompactLayout, tableLabel, heading, footer, showColumnHeaders, density, interactive, embedded, summary, rowHref, rowLabel, primaryColumnId, empty, noMatchMessage, columnsLabel, clearSearchLabel, pageLabels, toolbarActions, externalFilter, sorting: externalSorting, pagination, renderRowLink, renderToolbar, wrapCard, }: DataTableProps<TData>): React.JSX.Element;
|
|
162
|
+
export declare function DataTable<TData extends RowData>({ columns, data, getRowId, filterColumnId, filterPlaceholder, primaryColumns, compactLayout: requestedCompactLayout, tableLabel, heading, footer, showColumnHeaders, density, interactive, embedded, summary, rowHref, rowLabel, primaryColumnId, empty, noMatchMessage, columnsLabel, clearSearchLabel, pageLabels, toolbarActions, externalFilter, sorting: externalSorting, pagination, renderRowLink, renderToolbar, wrapCard, rowEditor, }: DataTableProps<TData>): React.JSX.Element;
|
|
154
163
|
export {};
|
|
155
164
|
//# sourceMappingURL=data-table.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/components/data-table.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/components/data-table.tsx"],"names":[],"mappings":"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"}
|
|
@@ -137,7 +137,7 @@ const defaultRowLink = (props) => _jsx("a", { ...props });
|
|
|
137
137
|
function DefaultToolbar({ actions }) {
|
|
138
138
|
return actions ? _jsx(CollectionToolbar, { label: "", actions: actions }) : null;
|
|
139
139
|
}
|
|
140
|
-
export function DataTable({ columns, data, getRowId, filterColumnId, filterPlaceholder, primaryColumns, compactLayout: requestedCompactLayout, tableLabel, heading, footer, showColumnHeaders = true, density = "comfortable", interactive = true, embedded = false, summary, rowHref, rowLabel, primaryColumnId, empty, noMatchMessage, columnsLabel, clearSearchLabel, pageLabels, toolbarActions, externalFilter, sorting: externalSorting, pagination, renderRowLink = defaultRowLink, renderToolbar = DefaultToolbar, wrapCard, }) {
|
|
140
|
+
export function DataTable({ columns, data, getRowId, filterColumnId, filterPlaceholder, primaryColumns, compactLayout: requestedCompactLayout, tableLabel, heading, footer, showColumnHeaders = true, density = "comfortable", interactive = true, embedded = false, summary, rowHref, rowLabel, primaryColumnId, empty, noMatchMessage, columnsLabel, clearSearchLabel, pageLabels, toolbarActions, externalFilter, sorting: externalSorting, pagination, renderRowLink = defaultRowLink, renderToolbar = DefaultToolbar, wrapCard, rowEditor, }) {
|
|
141
141
|
const [sorting, setSorting] = React.useState([]);
|
|
142
142
|
const [columnFilters, setColumnFilters] = React.useState([]);
|
|
143
143
|
const [columnVisibility, setColumnVisibility] = React.useState({});
|
|
@@ -220,7 +220,7 @@ export function DataTable({ columns, data, getRowId, filterColumnId, filterPlace
|
|
|
220
220
|
...(identity ? { onFocus: titleWhenCut, onPointerEnter: titleWhenCut } : {}),
|
|
221
221
|
children: content,
|
|
222
222
|
})) : identity ? (_jsx("div", { className: IDENTITY_CONTENT_CLASS, onFocus: titleWhenCut, onPointerEnter: titleWhenCut, children: content })) : prose ? (_jsx("div", { className: PROSE_FRAME_CLASS, children: _jsx("div", { className: PROSE_CONTENT_CLASS, onFocus: titleWhenCut, onPointerEnter: titleWhenCut, children: content }) })) : (content) }, cell.id));
|
|
223
|
-
}) }), detailCells.length > 0 && shownLayout !== "columns" ? (_jsx(TableDetailRow, { layout: compactLayout, colSpan: visibleCells.filter((cell) => !collapseClass(cell.column.id, primaryColumns, compactLayout)).length, facts: detailCells.map((cell) => ({
|
|
223
|
+
}) }), rowEditor?.rowId === row.id ? (_jsx(TableRow, { "data-slot": "table-row-editor", className: "in-[tbody]:hover:bg-transparent", children: _jsx(TableCell, { colSpan: visibleCells.length, className: "p-0 whitespace-normal", children: rowEditor.render(row.original) }) })) : null, detailCells.length > 0 && shownLayout !== "columns" ? (_jsx(TableDetailRow, { layout: compactLayout, colSpan: visibleCells.filter((cell) => !collapseClass(cell.column.id, primaryColumns, compactLayout)).length, facts: detailCells.map((cell) => ({
|
|
224
224
|
id: cell.id,
|
|
225
225
|
label: columnMenuLabel(cell.column),
|
|
226
226
|
numeric: isNumericColumn(cell.column),
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export
|
|
1
|
+
import type { FormSurfaceProps } from "./form-drawer.js";
|
|
2
|
+
import { type FormProps } from "../internal/form-submit.js";
|
|
3
|
+
export type FormDialogProps = FormSurfaceProps & {
|
|
4
|
+
/** Its form's save is running: the dialog stays open until it settles. */
|
|
5
|
+
pending?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function FormDialog({ open, onOpenChange, onOpenChangeComplete, title, description, closeLabel, children, initialFocus, finalFocus, pending, }: FormDialogProps): import("react").JSX.Element;
|
|
8
|
+
export declare function FormDialogForm({ cancelLabel, submit, notice, children, ...form }: FormProps): import("react").JSX.Element;
|
|
4
9
|
//# sourceMappingURL=form-dialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-dialog.d.ts","sourceRoot":"","sources":["../../src/components/form-dialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"form-dialog.d.ts","sourceRoot":"","sources":["../../src/components/form-dialog.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,wBAAwB,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG;IAC/C,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,WAAW,EACX,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,OAAe,GAChB,EAAE,eAAe,+BAuBjB;AAED,wBAAgB,cAAc,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,+BAsB3F"}
|
|
@@ -3,11 +3,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Button } from "./button.js";
|
|
4
4
|
import { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "./dialog.js";
|
|
5
5
|
import { WaitingLine } from "./waiting-line.js";
|
|
6
|
-
import {
|
|
7
|
-
export function FormDialog({ open, onOpenChange, onOpenChangeComplete, title, description, closeLabel, children, initialFocus, finalFocus, }) {
|
|
8
|
-
return (_jsx(Dialog, { open: open, onOpenChange:
|
|
6
|
+
import { FormSubmitButton } from "../internal/form-submit.js";
|
|
7
|
+
export function FormDialog({ open, onOpenChange, onOpenChangeComplete, title, description, closeLabel, children, initialFocus, finalFocus, pending = false, }) {
|
|
8
|
+
return (_jsx(Dialog, { open: open, onOpenChange: (next) => {
|
|
9
|
+
if (next || !pending)
|
|
10
|
+
onOpenChange(next);
|
|
11
|
+
}, onOpenChangeComplete: onOpenChangeComplete, children: _jsxs(DialogContent, { className: "sm:max-w-lg", closeLabel: closeLabel, initialFocus: initialFocus, finalFocus: finalFocus, children: [_jsxs(DialogHeader, { className: "pr-8", children: [_jsx(DialogTitle, { children: title }), description ? _jsx(DialogDescription, { children: description }) : null] }), children] }) }));
|
|
9
12
|
}
|
|
10
13
|
export function FormDialogForm({ cancelLabel, submit, notice, children, ...form }) {
|
|
11
14
|
const pending = submit.pending === true;
|
|
12
|
-
return (_jsxs("form", { className: "flex min-h-0 flex-col gap-6", "aria-busy": pending || undefined, ...form, children: [_jsx(DialogBody, { children: children }), notice, _jsxs(DialogFooter, { className: "relative", children: [_jsx(DialogClose, { disabled: pending, render: _jsx(Button, { type: "button", variant: "outline" }), children: cancelLabel }), _jsx(
|
|
15
|
+
return (_jsxs("form", { className: "flex min-h-0 flex-col gap-6", "aria-busy": pending || undefined, "data-slot": "form-dialog-form", ...form, children: [_jsx(DialogBody, { children: children }), notice, _jsxs(DialogFooter, { className: "relative", children: [_jsx(DialogClose, { disabled: pending, render: _jsx(Button, { type: "button", variant: "outline" }), children: cancelLabel }), _jsx(FormSubmitButton, { submit: submit }), pending ? (_jsx(WaitingLine, { className: "absolute inset-x-nadicode-lg bottom-1 w-auto", decorative: true })) : null] })] }));
|
|
13
16
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ComponentProps, ReactNode } from "react";
|
|
2
2
|
import { SheetContent } from "./sheet.js";
|
|
3
|
-
|
|
3
|
+
import { type FormProps } from "../internal/form-submit.js";
|
|
4
|
+
export type { FormProps, FormSubmit } from "../internal/form-submit.js";
|
|
5
|
+
/** What a form surface is told by its caller, whether it draws a drawer or a dialog. */
|
|
6
|
+
export type FormSurfaceProps = {
|
|
4
7
|
open: boolean;
|
|
5
8
|
onOpenChange: (open: boolean) => void;
|
|
6
9
|
/** Runs once the drawer has finished opening or closing, such as to return focus. */
|
|
@@ -17,7 +20,16 @@ export type FormDrawerProps = {
|
|
|
17
20
|
/** Where focus returns when the drawer closes, when its opener is gone. */
|
|
18
21
|
finalFocus?: ComponentProps<typeof SheetContent>["finalFocus"];
|
|
19
22
|
};
|
|
20
|
-
|
|
23
|
+
export type FormDrawerProps = FormSurfaceProps & {
|
|
24
|
+
/**
|
|
25
|
+
* Why this is a drawer and not a dialog: "catalog" chooses from a list too
|
|
26
|
+
* long for a dialog, "steps" sets something up over several steps, with a
|
|
27
|
+
* wait. A form of a few fields is a `FormDialog`, and a record already on
|
|
28
|
+
* screen edits inside its row.
|
|
29
|
+
*/
|
|
30
|
+
job: "catalog" | "steps";
|
|
31
|
+
};
|
|
32
|
+
/** The right-side drawer for a catalog or a setup in steps, at one width. */
|
|
21
33
|
export declare function FormDrawer({ open, onOpenChange, onOpenChangeComplete, title, description, closeLabel, children, initialFocus, finalFocus, }: FormDrawerProps): import("react").JSX.Element;
|
|
22
34
|
/** The part of the drawer that scrolls between its title and its footer. */
|
|
23
35
|
export declare function FormDrawerBody({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
@@ -32,29 +44,10 @@ export type FormDrawerFooterProps = {
|
|
|
32
44
|
};
|
|
33
45
|
/** The footer that stays in place under the body: Cancel, then the actions, right-aligned. */
|
|
34
46
|
export declare function FormDrawerFooter({ cancel, children }: FormDrawerFooterProps): import("react").JSX.Element;
|
|
35
|
-
export type FormDrawerSubmit = {
|
|
36
|
-
label: string;
|
|
37
|
-
/** The button's own word while the save runs. */
|
|
38
|
-
pendingLabel?: string;
|
|
39
|
-
/** The save is running: the button says so and holds, and the waiting line follows. */
|
|
40
|
-
pending?: boolean;
|
|
41
|
-
/** Nothing to save yet, or a field still needs an answer. */
|
|
42
|
-
disabled?: boolean;
|
|
43
|
-
destructive?: boolean;
|
|
44
|
-
/** The id of the line that says why the save cannot run yet. */
|
|
45
|
-
describedBy?: string;
|
|
46
|
-
};
|
|
47
|
-
export type FormDrawerFormProps = Omit<ComponentProps<"form">, "children" | "className"> & {
|
|
48
|
-
cancelLabel: string;
|
|
49
|
-
submit: FormDrawerSubmit;
|
|
50
|
-
/** A refusal or a failure of the save, between the body and the footer, where the button is. */
|
|
51
|
-
notice?: ReactNode;
|
|
52
|
-
children: ReactNode;
|
|
53
|
-
};
|
|
54
47
|
/**
|
|
55
48
|
* The drawer's form: the fields in the body, a notice where the save button
|
|
56
49
|
* is, and the footer with Cancel and the save rightmost. Cancel holds while the
|
|
57
50
|
* save runs, so a running save is never left without its drawer.
|
|
58
51
|
*/
|
|
59
|
-
export declare function FormDrawerForm({ cancelLabel, submit, notice, children, ...form }:
|
|
52
|
+
export declare function FormDrawerForm({ cancelLabel, submit, notice, children, ...form }: FormProps): import("react").JSX.Element;
|
|
60
53
|
//# sourceMappingURL=form-drawer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-drawer.d.ts","sourceRoot":"","sources":["../../src/components/form-drawer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"form-drawer.d.ts","sourceRoot":"","sources":["../../src/components/form-drawer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,EAGL,YAAY,EAKb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,wBAAwB,CAAC;AAG1E,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpE,wFAAwF;AACxF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,qFAAqF;IACrF,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,6FAA6F;IAC7F,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,wGAAwG;IACxG,QAAQ,EAAE,SAAS,CAAC;IACpB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC,cAAc,CAAC,CAAC;IACnE,2EAA2E;IAC3E,UAAU,CAAC,EAAE,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC,YAAY,CAAC,CAAC;CAChE,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG;IAC/C;;;;;OAKG;IACH,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,YAAY,EACZ,oBAAoB,EACpB,KAAK,EACL,WAAW,EACX,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,UAAU,GACX,EAAE,eAAe,+BAkBjB;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,+BAW5E;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,+DAA+D;IAC/D,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/C,qEAAqE;IACrE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,qBAAqB,+BAc3E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,+BAqB3F"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Button } from "./button.js";
|
|
4
|
-
import { PendingLabel } from "./pending-label.js";
|
|
5
4
|
import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "./sheet.js";
|
|
6
5
|
import { WaitingLine } from "./waiting-line.js";
|
|
6
|
+
import { FormSubmitButton } from "../internal/form-submit.js";
|
|
7
7
|
import { cn } from "../lib/utils.js";
|
|
8
|
-
/**
|
|
8
|
+
/** The right-side drawer for a catalog or a setup in steps, at one width. */
|
|
9
9
|
export function FormDrawer({ open, onOpenChange, onOpenChangeComplete, title, description, closeLabel, children, initialFocus, finalFocus, }) {
|
|
10
|
-
return (_jsx(Sheet, { open: open, onOpenChange: onOpenChange, onOpenChangeComplete: onOpenChangeComplete, children: _jsxs(SheetContent, { className: "max-sm:data-[side=right]:left-nadicode-sm max-sm:data-[side=right]:w-auto", closeLabel: closeLabel, finalFocus: finalFocus, initialFocus: initialFocus, side: "right", children: [_jsxs(SheetHeader, { className: "pr-12", children: [_jsx(SheetTitle, { className: "break-words", children: title }), description ? _jsx(SheetDescription, { children: description }) : null] }), children] }) }));
|
|
10
|
+
return (_jsx(Sheet, { open: open, onOpenChange: onOpenChange, onOpenChangeComplete: onOpenChangeComplete, children: _jsxs(SheetContent, { className: "max-sm:data-[side=right]:left-nadicode-sm max-sm:data-[side=right]:w-auto data-[side=right]:sm:w-[560px] data-[side=right]:sm:max-w-[calc(100%-var(--nc-lg))]", closeLabel: closeLabel, finalFocus: finalFocus, initialFocus: initialFocus, side: "right", children: [_jsxs(SheetHeader, { className: "pr-12", children: [_jsx(SheetTitle, { className: "break-words", children: title }), description ? _jsx(SheetDescription, { children: description }) : null] }), children] }) }));
|
|
11
11
|
}
|
|
12
12
|
/** The part of the drawer that scrolls between its title and its footer. */
|
|
13
13
|
export function FormDrawerBody({ className, ...props }) {
|
|
@@ -24,5 +24,5 @@ export function FormDrawerFooter({ cancel, children }) {
|
|
|
24
24
|
*/
|
|
25
25
|
export function FormDrawerForm({ cancelLabel, submit, notice, children, ...form }) {
|
|
26
26
|
const pending = submit.pending === true;
|
|
27
|
-
return (_jsxs("form", { "aria-busy": pending || undefined, className: "flex min-h-0 flex-1 flex-col", "data-slot": "form-drawer-form", ...form, children: [_jsx(FormDrawerBody, { children: children }), notice ? (_jsx("div", { className: "px-nadicode-lg pt-nadicode-md", "data-slot": "form-drawer-notice", children: notice })) : null, _jsxs(FormDrawerFooter, { cancel: { label: cancelLabel, disabled: pending }, children: [_jsx(
|
|
27
|
+
return (_jsxs("form", { "aria-busy": pending || undefined, className: "flex min-h-0 flex-1 flex-col", "data-slot": "form-drawer-form", ...form, children: [_jsx(FormDrawerBody, { children: children }), notice ? (_jsx("div", { className: "px-nadicode-lg pt-nadicode-md", "data-slot": "form-drawer-notice", children: notice })) : null, _jsxs(FormDrawerFooter, { cancel: { label: cancelLabel, disabled: pending }, children: [_jsx(FormSubmitButton, { submit: submit }), pending ? _jsx(WaitingLine, { className: "basis-full", decorative: true }) : null] })] }));
|
|
28
28
|
}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* A record's identity in a row (DESIGN.md "Tables and missing values"): its
|
|
4
|
+
* mark, its name, and under it one muted `detail` line saying what the record
|
|
5
|
+
* is or where it comes from, so the row reads without a column heading. The
|
|
6
|
+
* name holds one line and ends in an ellipsis, whole in its title, unless it
|
|
7
|
+
* is the record's whole text, such as a memory, which `wraps` in full.
|
|
8
|
+
*/
|
|
9
|
+
declare function RecordIdentity({ name, mark, hint, detail, wraps, }: {
|
|
10
|
+
name: ReactNode;
|
|
4
11
|
mark?: ReactNode;
|
|
12
|
+
/** Read after the name in its title, such as an identifier the row does not show. */
|
|
5
13
|
hint?: string;
|
|
14
|
+
detail?: ReactNode;
|
|
15
|
+
wraps?: boolean;
|
|
6
16
|
}): import("react").JSX.Element;
|
|
7
17
|
export { RecordIdentity };
|
|
8
18
|
//# sourceMappingURL=record-identity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record-identity.d.ts","sourceRoot":"","sources":["../../src/components/record-identity.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"record-identity.d.ts","sourceRoot":"","sources":["../../src/components/record-identity.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC;;;;;;GAMG;AACH,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,KAAa,GACd,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,+BA0BA;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
/**
|
|
4
|
+
* A record's identity in a row (DESIGN.md "Tables and missing values"): its
|
|
5
|
+
* mark, its name, and under it one muted `detail` line saying what the record
|
|
6
|
+
* is or where it comes from, so the row reads without a column heading. The
|
|
7
|
+
* name holds one line and ends in an ellipsis, whole in its title, unless it
|
|
8
|
+
* is the record's whole text, such as a memory, which `wraps` in full.
|
|
9
|
+
*/
|
|
10
|
+
function RecordIdentity({ name, mark, hint, detail, wraps = false, }) {
|
|
11
|
+
const title = typeof name === "string" ? (hint ? `${name} · ${hint}` : name) : undefined;
|
|
12
|
+
return (_jsxs("span", { className: "flex min-w-0 items-center gap-2.5", "data-slot": "record-identity", children: [mark, _jsxs("span", { className: "grid min-w-0", children: [_jsx("span", { className: cn("min-w-0 font-medium", wraps ? "break-words whitespace-pre-wrap" : "truncate"), title: wraps ? undefined : title, children: name }), detail ? (_jsx("span", { className: "text-xs break-words text-muted-foreground", "data-slot": "record-identity-detail", children: detail })) : null] })] }));
|
|
4
13
|
}
|
|
5
14
|
export { RecordIdentity };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type RecordTimeProps = {
|
|
2
|
+
/** When it happened. */
|
|
3
|
+
at: Date | number | string;
|
|
4
|
+
/**
|
|
5
|
+
* The sentence the time sits in, which says what happened:
|
|
6
|
+
* `(when) => t("skills.updated", { when })` gives "Updated 3 hours ago".
|
|
7
|
+
*/
|
|
8
|
+
phrase: (when: string) => string;
|
|
9
|
+
/** The person's language; the runtime's when left out. */
|
|
10
|
+
locale?: string;
|
|
11
|
+
/** The current time, for a reading that must not drift while it renders. */
|
|
12
|
+
now?: number;
|
|
13
|
+
};
|
|
14
|
+
/** "3 hours ago" within a week, then "12 Sep", with the year when it is not this year. */
|
|
15
|
+
export declare function formatRecordTime(at: Date, locale?: string, now?: number): string;
|
|
16
|
+
/** The moment `at` names, or null when it names none, such as an empty or malformed time. */
|
|
17
|
+
export declare function recordDate(at: Date | number | string | null | undefined): Date | null;
|
|
18
|
+
/**
|
|
19
|
+
* When something happened to a record, in the sentence that says what
|
|
20
|
+
* (DESIGN.md "Complete compositions", relative timestamp preview): hovering it
|
|
21
|
+
* shows the exact moment in the person's time and in UTC, as Vercel's
|
|
22
|
+
* dashboard does, and assistive technology reads the exact moment with it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function RecordTime({ at, phrase, locale, now }: RecordTimeProps): import("react").JSX.Element | null;
|
|
25
|
+
//# sourceMappingURL=record-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-time.d.ts","sourceRoot":"","sources":["../../src/components/record-time.tsx"],"names":[],"mappings":"AAWA,MAAM,MAAM,eAAe,GAAG;IAC5B,wBAAwB;IACxB,EAAE,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3B;;;OAGG;IACH,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACjC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,MAAM,CAepF;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAIrF;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,eAAe,sCAwCtE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { HoverCard, HoverCardContent, HoverCardTrigger } from "./hover-card.js";
|
|
3
|
+
const DAY = 86_400_000;
|
|
4
|
+
const WEEK = 7 * DAY;
|
|
5
|
+
const UNITS = [
|
|
6
|
+
["day", DAY],
|
|
7
|
+
["hour", 3_600_000],
|
|
8
|
+
["minute", 60_000],
|
|
9
|
+
];
|
|
10
|
+
/** "3 hours ago" within a week, then "12 Sep", with the year when it is not this year. */
|
|
11
|
+
export function formatRecordTime(at, locale, now = Date.now()) {
|
|
12
|
+
const elapsed = now - at.getTime();
|
|
13
|
+
if (elapsed >= 0 && elapsed < WEEK) {
|
|
14
|
+
const relative = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
|
|
15
|
+
for (const [unit, size] of UNITS) {
|
|
16
|
+
if (elapsed >= size)
|
|
17
|
+
return relative.format(-Math.floor(elapsed / size), unit);
|
|
18
|
+
}
|
|
19
|
+
return relative.format(0, "minute");
|
|
20
|
+
}
|
|
21
|
+
const sameYear = at.getFullYear() === new Date(now).getFullYear();
|
|
22
|
+
return new Intl.DateTimeFormat(locale, {
|
|
23
|
+
day: "numeric",
|
|
24
|
+
month: "short",
|
|
25
|
+
...(sameYear ? {} : { year: "numeric" }),
|
|
26
|
+
}).format(at);
|
|
27
|
+
}
|
|
28
|
+
/** The moment `at` names, or null when it names none, such as an empty or malformed time. */
|
|
29
|
+
export function recordDate(at) {
|
|
30
|
+
if (at == null)
|
|
31
|
+
return null;
|
|
32
|
+
const date = at instanceof Date ? at : new Date(at);
|
|
33
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* When something happened to a record, in the sentence that says what
|
|
37
|
+
* (DESIGN.md "Complete compositions", relative timestamp preview): hovering it
|
|
38
|
+
* shows the exact moment in the person's time and in UTC, as Vercel's
|
|
39
|
+
* dashboard does, and assistive technology reads the exact moment with it.
|
|
40
|
+
*/
|
|
41
|
+
export function RecordTime({ at, phrase, locale, now }) {
|
|
42
|
+
const date = recordDate(at);
|
|
43
|
+
if (!date)
|
|
44
|
+
return null;
|
|
45
|
+
const local = new Intl.DateTimeFormat(locale, { dateStyle: "long", timeStyle: "medium" }).format(date);
|
|
46
|
+
const utc = new Intl.DateTimeFormat(locale, {
|
|
47
|
+
dateStyle: "long",
|
|
48
|
+
timeStyle: "medium",
|
|
49
|
+
timeZone: "UTC",
|
|
50
|
+
}).format(date);
|
|
51
|
+
return (_jsxs(HoverCard, { children: [_jsxs(HoverCardTrigger, { render: _jsx("time", { className: "whitespace-nowrap text-muted-foreground", "data-slot": "record-time", dateTime: date.toISOString() }), children: [phrase(formatRecordTime(date, locale, now)), _jsxs("span", { className: "sr-only", children: [", ", local] })] }), _jsx(HoverCardContent, { className: "w-auto", children: _jsxs("dl", { className: "grid grid-cols-[auto_auto] gap-x-4 gap-y-1 text-xs", "data-slot": "record-time-exact", children: [_jsx("dt", { className: "text-muted-foreground", children: "UTC" }), _jsx("dd", { className: "tabular-nums", children: utc }), _jsx("dt", { className: "text-muted-foreground", children: Intl.DateTimeFormat(locale).resolvedOptions().timeZone }), _jsx("dd", { className: "tabular-nums", children: local })] }) })] }));
|
|
52
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
import { type FormSubmit } from "../internal/form-submit.js";
|
|
3
|
+
export type RowEditFormProps = Omit<ComponentProps<"form">, "children" | "className"> & {
|
|
4
|
+
cancelLabel: string;
|
|
5
|
+
/** Closes the form and keeps the record as it was. */
|
|
6
|
+
onCancel: () => void;
|
|
7
|
+
submit: FormSubmit;
|
|
8
|
+
/** A refusal or a failure of the save, above the footer, where the button is. */
|
|
9
|
+
notice?: ReactNode;
|
|
10
|
+
/** A way on beside the actions, such as where to find a token, at the footer's leading edge. */
|
|
11
|
+
hint?: ReactNode;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A record's form opened inside its own row (DESIGN.md "Menus and commands"),
|
|
16
|
+
* a `DataTable`'s `rowEditor`: the fields under the record's line, then a
|
|
17
|
+
* footer one tone below with an optional hint at its leading edge, then Cancel
|
|
18
|
+
* and the save rightmost. Cancel holds while
|
|
19
|
+
* the save runs.
|
|
20
|
+
*/
|
|
21
|
+
export declare function RowEditForm({ cancelLabel, onCancel, submit, notice, hint, children, ...form }: RowEditFormProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=row-edit-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-edit-form.d.ts","sourceRoot":"","sources":["../../src/components/row-edit-form.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvD,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,wBAAwB,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC,GAAG;IACtF,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC;IACnB,iFAAiF;IACjF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,gGAAgG;IAChG,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAC1B,WAAW,EACX,QAAQ,EACR,MAAM,EACN,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,gBAAgB,+BAqBlB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { WaitingLine } from "./waiting-line.js";
|
|
5
|
+
import { FormSubmitButton } from "../internal/form-submit.js";
|
|
6
|
+
/**
|
|
7
|
+
* A record's form opened inside its own row (DESIGN.md "Menus and commands"),
|
|
8
|
+
* a `DataTable`'s `rowEditor`: the fields under the record's line, then a
|
|
9
|
+
* footer one tone below with an optional hint at its leading edge, then Cancel
|
|
10
|
+
* and the save rightmost. Cancel holds while
|
|
11
|
+
* the save runs.
|
|
12
|
+
*/
|
|
13
|
+
export function RowEditForm({ cancelLabel, onCancel, submit, notice, hint, children, ...form }) {
|
|
14
|
+
const pending = submit.pending === true;
|
|
15
|
+
return (_jsxs("form", { "aria-busy": pending || undefined, "data-slot": "row-edit-form", ...form, children: [_jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)] gap-4 px-nadicode-md pt-nadicode-sm pb-nadicode-md", children: [children, notice ? _jsx("div", { "data-slot": "row-edit-form-notice", children: notice }) : null] }), _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-3 border-t border-border bg-recessed px-nadicode-md py-3", "data-slot": "row-edit-form-footer", children: [hint ? _jsx("div", { className: "mr-auto min-w-0", children: hint }) : null, _jsx(Button, { disabled: pending, onClick: onCancel, type: "button", variant: "outline", children: cancelLabel }), _jsx(FormSubmitButton, { submit: submit }), pending ? _jsx(WaitingLine, { className: "basis-full", decorative: true }) : null] })] }));
|
|
16
|
+
}
|
|
@@ -4,7 +4,7 @@ import * as React from "react";
|
|
|
4
4
|
import { mergeProps } from "@base-ui/react/merge-props";
|
|
5
5
|
import { useRender } from "@base-ui/react/use-render";
|
|
6
6
|
import { cva } from "class-variance-authority";
|
|
7
|
-
import { useIsMobile } from "../hooks/use-mobile.js";
|
|
7
|
+
import { isMobileNow, useIsMobile } from "../hooks/use-mobile.js";
|
|
8
8
|
import { cn } from "../lib/utils.js";
|
|
9
9
|
import { Button } from "./button.js";
|
|
10
10
|
import { Input } from "./input.js";
|
|
@@ -49,8 +49,8 @@ function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: set
|
|
|
49
49
|
}, [setOpenProp, open, passive]);
|
|
50
50
|
// Helper to toggle the sidebar.
|
|
51
51
|
const toggleSidebar = React.useCallback(() => {
|
|
52
|
-
return
|
|
53
|
-
}, [
|
|
52
|
+
return mobileSheet && isMobileNow() ? setOpenMobile((open) => !open) : setOpen((open) => !open);
|
|
53
|
+
}, [mobileSheet, setOpen, setOpenMobile]);
|
|
54
54
|
// Adds a keyboard shortcut to toggle the sidebar.
|
|
55
55
|
React.useEffect(() => {
|
|
56
56
|
if (passive)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-mode-switcher.d.ts","sourceRoot":"","sources":["../../src/components/theme-mode-switcher.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,UAAU,EAAkB,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAE9D,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EACvC,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO,CACxD,GAAG;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1D,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAQF,iBAAS,iBAAiB,CAAC,EACzB,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,OAAe,EACf,QAAQ,EACR,aAAa,EACb,MAAM,EACN,aAAa,EACb,UAAU,EACV,KAAK,EACL,GAAG,KAAK,EACT,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"theme-mode-switcher.d.ts","sourceRoot":"","sources":["../../src/components/theme-mode-switcher.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,UAAU,EAAkB,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAE9D,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EACvC,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO,CACxD,GAAG;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1D,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAQF,iBAAS,iBAAiB,CAAC,EACzB,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,OAAe,EACf,QAAQ,EACR,aAAa,EACb,MAAM,EACN,aAAa,EACb,UAAU,EACV,KAAK,EACL,GAAG,KAAK,EACT,EAAE,sBAAsB,qBA6CxB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,KAAK,EACL,aAAa,EACb,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,qBAkBA"}
|
|
@@ -13,7 +13,7 @@ const themeModeIcons = {
|
|
|
13
13
|
system: MonitorIcon,
|
|
14
14
|
};
|
|
15
15
|
function ThemeModeSwitcher({ "aria-label": ariaLabel, className, compact = false, disabled, itemClassName, labels, onValueChange, renderItem, value, ...props }) {
|
|
16
|
-
return (_jsx(RadioGroup, { "aria-label": ariaLabel, className: cn("max-w-full", className), disabled: disabled, onValueChange: (nextMode) => {
|
|
16
|
+
return (_jsx(RadioGroup, { "aria-label": ariaLabel, className: cn("max-w-full grid-cols-3", className), disabled: disabled, onValueChange: (nextMode) => {
|
|
17
17
|
if (isThemeMode(nextMode)) {
|
|
18
18
|
onValueChange(nextMode);
|
|
19
19
|
}
|
|
@@ -21,13 +21,7 @@ function ThemeModeSwitcher({ "aria-label": ariaLabel, className, compact = false
|
|
|
21
21
|
const Icon = themeModeIcons[mode];
|
|
22
22
|
const label = labels[mode];
|
|
23
23
|
const selected = value === mode;
|
|
24
|
-
return (_jsx(RadioGroupItem, { "aria-label": label, className: cn(toggleVariants({ variant: "outline" }),
|
|
25
|
-
// The selected tile takes the muted interaction surface the
|
|
26
|
-
// toggle uses for its own on-state, so it takes that surface's
|
|
27
|
-
// foreground with it. Left on the radio primitive's on-primary
|
|
28
|
-
// foreground, the selected label reads white on near-white in
|
|
29
|
-
// light and black on black in dark.
|
|
30
|
-
"aspect-auto w-auto gap-1.5 data-checked:bg-muted data-checked:text-foreground", compact && "text-xs", itemClassName), disabled: disabled, value: mode, children: renderItem ? (renderItem({ Icon, label, mode, selected })) : (_jsxs(_Fragment, { children: [_jsx(Icon, { "aria-hidden": "true", "data-icon": true }), _jsx("span", { className: "min-w-0 truncate", children: label })] })) }, mode));
|
|
24
|
+
return (_jsx(RadioGroupItem, { "aria-label": label, className: cn(toggleVariants({ variant: "outline" }), "aspect-auto w-auto min-w-0 gap-1.5 data-checked:border-transparent data-checked:bg-selection data-checked:text-selection-foreground", compact && "text-xs", itemClassName), disabled: disabled, value: mode, children: renderItem ? (renderItem({ Icon, label, mode, selected })) : (_jsxs(_Fragment, { children: [_jsx(Icon, { "aria-hidden": "true", "data-icon": true }), _jsx("span", { className: "min-w-0 truncate", children: label })] })) }, mode));
|
|
31
25
|
}) }));
|
|
32
26
|
}
|
|
33
27
|
export { ThemeModeSwitcher };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mobile.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mobile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-mobile.d.ts","sourceRoot":"","sources":["../../src/hooks/use-mobile.ts"],"names":[],"mappings":"AAUA,8GAA8G;AAC9G,eAAO,MAAM,WAAW,eAA8C,CAAC;AAGvE,wBAAgB,WAAW,YAE1B"}
|
package/dist/hooks/use-mobile.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
const MOBILE_BREAKPOINT = 768;
|
|
3
|
+
function subscribe(onChange) {
|
|
4
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
5
|
+
mql.addEventListener("change", onChange);
|
|
6
|
+
return () => mql.removeEventListener("change", onChange);
|
|
7
|
+
}
|
|
8
|
+
/** Whether the window is under the mobile breakpoint at the moment of asking, whatever the page last drew. */
|
|
9
|
+
export const isMobileNow = () => window.innerWidth < MOBILE_BREAKPOINT;
|
|
10
|
+
const onServer = () => false;
|
|
3
11
|
export function useIsMobile() {
|
|
4
|
-
|
|
5
|
-
React.useEffect(() => {
|
|
6
|
-
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
7
|
-
const onChange = () => {
|
|
8
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
9
|
-
};
|
|
10
|
-
mql.addEventListener("change", onChange);
|
|
11
|
-
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
12
|
-
return () => mql.removeEventListener("change", onChange);
|
|
13
|
-
}, []);
|
|
14
|
-
return !!isMobile;
|
|
12
|
+
return React.useSyncExternalStore(subscribe, isMobileNow, onServer);
|
|
15
13
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export * from "./components/checkbox.js";
|
|
|
41
41
|
export * from "./components/code-block.js";
|
|
42
42
|
export * from "./components/collapsible.js";
|
|
43
43
|
export * from "./components/collection-filters.js";
|
|
44
|
+
export * from "./components/collection-page.js";
|
|
44
45
|
export * from "./components/collection-search.js";
|
|
45
46
|
export * from "./components/collection-sort.js";
|
|
46
47
|
export * from "./components/collection-toolbar.js";
|
|
@@ -110,7 +111,9 @@ export * from "./components/qr-code.js";
|
|
|
110
111
|
export * from "./components/radio-group.js";
|
|
111
112
|
export * from "./components/reading-column.js";
|
|
112
113
|
export * from "./components/record-identity.js";
|
|
114
|
+
export * from "./components/record-time.js";
|
|
113
115
|
export * from "./components/resizable.js";
|
|
116
|
+
export * from "./components/row-edit-form.js";
|
|
114
117
|
export * from "./components/run-timeline.js";
|
|
115
118
|
export * from "./components/scope-switcher.js";
|
|
116
119
|
export * from "./components/scroll-area.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
|
@@ -41,6 +41,7 @@ export * from "./components/checkbox.js";
|
|
|
41
41
|
export * from "./components/code-block.js";
|
|
42
42
|
export * from "./components/collapsible.js";
|
|
43
43
|
export * from "./components/collection-filters.js";
|
|
44
|
+
export * from "./components/collection-page.js";
|
|
44
45
|
export * from "./components/collection-search.js";
|
|
45
46
|
export * from "./components/collection-sort.js";
|
|
46
47
|
export * from "./components/collection-toolbar.js";
|
|
@@ -110,7 +111,9 @@ export * from "./components/qr-code.js";
|
|
|
110
111
|
export * from "./components/radio-group.js";
|
|
111
112
|
export * from "./components/reading-column.js";
|
|
112
113
|
export * from "./components/record-identity.js";
|
|
114
|
+
export * from "./components/record-time.js";
|
|
113
115
|
export * from "./components/resizable.js";
|
|
116
|
+
export * from "./components/row-edit-form.js";
|
|
114
117
|
export * from "./components/run-timeline.js";
|
|
115
118
|
export * from "./components/scope-switcher.js";
|
|
116
119
|
export * from "./components/scroll-area.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
/** The save of a drawer's, a dialog's or a row's form. */
|
|
3
|
+
export type FormSubmit = {
|
|
4
|
+
label: string;
|
|
5
|
+
/** The button's own word while the save runs. */
|
|
6
|
+
pendingLabel?: string;
|
|
7
|
+
/** The save is running: the button says so and holds, and the waiting line follows. */
|
|
8
|
+
pending?: boolean;
|
|
9
|
+
/** Nothing to save yet, or a field still needs an answer. */
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
destructive?: boolean;
|
|
12
|
+
/** The id of the line that says why the save cannot run yet. */
|
|
13
|
+
describedBy?: string;
|
|
14
|
+
};
|
|
15
|
+
export type FormProps = Omit<ComponentProps<"form">, "children" | "className"> & {
|
|
16
|
+
cancelLabel: string;
|
|
17
|
+
submit: FormSubmit;
|
|
18
|
+
/** A refusal or a failure of the save, above the footer, where the button is. */
|
|
19
|
+
notice?: ReactNode;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
};
|
|
22
|
+
export declare function FormSubmitButton({ submit }: {
|
|
23
|
+
submit: FormSubmit;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=form-submit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-submit.d.ts","sourceRoot":"","sources":["../../src/internal/form-submit.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvD,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC,GAAG;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,iFAAiF;IACjF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,+BAelE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from "../components/button.js";
|
|
4
|
+
import { PendingLabel } from "../components/pending-label.js";
|
|
5
|
+
export function FormSubmitButton({ submit }) {
|
|
6
|
+
const pending = submit.pending === true;
|
|
7
|
+
return (_jsx(Button, { "aria-busy": pending || undefined, "aria-describedby": submit.describedBy, disabled: pending || submit.disabled, type: "submit", variant: submit.destructive ? "destructive" : "default", children: _jsx(PendingLabel, { pending: pending, pendingLabel: submit.pendingLabel ?? submit.label, children: submit.label }) }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ResolvedMessage } from "../components/product-message.js";
|
|
2
|
+
/**
|
|
3
|
+
* A record's own action that failed or cannot run, drawn inside its row
|
|
4
|
+
* (DESIGN.md "Tables and missing values"): the message takes the line under
|
|
5
|
+
* the record's name and its actions take the row's controls.
|
|
6
|
+
*/
|
|
7
|
+
export type RowMessage = {
|
|
8
|
+
kind: "failed" | "refused";
|
|
9
|
+
message: ResolvedMessage;
|
|
10
|
+
};
|
|
11
|
+
export declare function RowMessageLine({ state }: {
|
|
12
|
+
state: RowMessage;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
/** The message's next steps, laid out by the row's own controls beside its commands. */
|
|
15
|
+
export declare function RowMessageActions({ state }: {
|
|
16
|
+
state: RowMessage;
|
|
17
|
+
}): import("react").JSX.Element[];
|
|
18
|
+
//# sourceMappingURL=row-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-message.d.ts","sourceRoot":"","sources":["../../src/internal/row-message.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAGrF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAElF,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,+BAY9D;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,iCAIjE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PageCommandButton } from "../components/page-actions.js";
|
|
3
|
+
import { bodyBeyondTitle } from "../components/product-message.js";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
export function RowMessageLine({ state }) {
|
|
6
|
+
const body = bodyBeyondTitle(state.message);
|
|
7
|
+
return (_jsxs("span", { className: cn(state.kind === "failed" && "text-destructive"), "data-slot": "row-message", role: state.kind === "failed" ? "alert" : undefined, children: [_jsx("span", { children: state.message.title }), body ? _jsxs("span", { children: [" ", body] }) : null] }));
|
|
8
|
+
}
|
|
9
|
+
/** The message's next steps, laid out by the row's own controls beside its commands. */
|
|
10
|
+
export function RowMessageActions({ state }) {
|
|
11
|
+
return state.message.actions.map((action) => (_jsx(PageCommandButton, { command: action, variant: "outline" }, action.label)));
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nadicodeai/ui",
|
|
3
|
-
"version": "12.1.
|
|
3
|
+
"version": "12.1.90",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@base-ui/react": "^1.9.0",
|
|
76
76
|
"@iconify-icons/logos": "^2.0.2",
|
|
77
77
|
"@iconify/react": "^6.0.2",
|
|
78
|
-
"@nadicodeai/design-system": "12.1.
|
|
78
|
+
"@nadicodeai/design-system": "12.1.90",
|
|
79
79
|
"@tanstack/react-table": "^9.2.8",
|
|
80
80
|
"class-variance-authority": "^0.7.1",
|
|
81
81
|
"clsx": "^2.1.1",
|