@nadicodeai/ui 12.1.82 → 12.1.84
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/accordion.js +1 -1
- package/dist/components/account-menu.js +1 -1
- package/dist/components/agent-card.js +1 -1
- package/dist/components/agent-profile.js +1 -1
- package/dist/components/alert-dialog.js +3 -3
- package/dist/components/alert.js +1 -1
- package/dist/components/automation-section.js +2 -2
- package/dist/components/avatar.d.ts +9 -1
- package/dist/components/avatar.d.ts.map +1 -1
- package/dist/components/avatar.js +8 -2
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/badge.d.ts.map +1 -1
- package/dist/components/badge.js +5 -6
- package/dist/components/button-group.js +4 -4
- package/dist/components/button.d.ts.map +1 -1
- package/dist/components/button.js +9 -9
- package/dist/components/calendar.js +3 -3
- package/dist/components/card.d.ts.map +1 -1
- package/dist/components/card.js +6 -11
- package/dist/components/catalog-tile.d.ts +2 -4
- package/dist/components/catalog-tile.d.ts.map +1 -1
- package/dist/components/catalog-tile.js +2 -2
- package/dist/components/channel-view.d.ts.map +1 -1
- package/dist/components/channel-view.js +8 -8
- package/dist/components/chart-card.js +1 -1
- package/dist/components/chart.js +1 -1
- package/dist/components/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox.js +2 -2
- package/dist/components/code-block.d.ts +8 -0
- package/dist/components/code-block.d.ts.map +1 -0
- package/dist/components/code-block.js +7 -0
- package/dist/components/collection-filters.d.ts.map +1 -1
- package/dist/components/collection-filters.js +3 -3
- package/dist/components/collection-toolbar.js +1 -1
- package/dist/components/combobox.js +3 -3
- package/dist/components/command.js +3 -3
- package/dist/components/copy-button.d.ts +9 -0
- package/dist/components/copy-button.d.ts.map +1 -0
- package/dist/components/copy-button.js +25 -0
- package/dist/components/data-table.d.ts +7 -7
- package/dist/components/data-table.d.ts.map +1 -1
- package/dist/components/data-table.js +21 -51
- package/dist/components/dialog.js +3 -3
- package/dist/components/drawer.js +4 -4
- package/dist/components/dropdown-menu.js +6 -6
- package/dist/components/empty-state.d.ts +10 -16
- package/dist/components/empty-state.d.ts.map +1 -1
- package/dist/components/empty-state.js +1 -1
- package/dist/components/field.js +3 -3
- package/dist/components/file-diff.js +1 -1
- package/dist/components/footer.d.ts.map +1 -1
- package/dist/components/footer.js +3 -3
- package/dist/components/form-dialog.d.ts +4 -0
- package/dist/components/form-dialog.d.ts.map +1 -0
- package/dist/components/form-dialog.js +13 -0
- package/dist/components/form-drawer.d.ts +1 -8
- package/dist/components/form-drawer.d.ts.map +1 -1
- package/dist/components/form-drawer.js +1 -8
- package/dist/components/glass-control.js +1 -1
- package/dist/components/input-group.js +3 -3
- package/dist/components/input-otp.js +2 -2
- package/dist/components/input.js +1 -1
- package/dist/components/item.js +2 -2
- package/dist/components/kbd.js +1 -1
- package/dist/components/kpi-card.d.ts +3 -3
- package/dist/components/kpi-card.d.ts.map +1 -1
- package/dist/components/kpi-card.js +5 -6
- package/dist/components/label-system.js +2 -2
- package/dist/components/label.js +1 -1
- package/dist/components/menubar.js +6 -6
- package/dist/components/native-select.js +1 -1
- package/dist/components/navigation-menu.js +4 -4
- package/dist/components/object-workspace.d.ts +2 -1
- package/dist/components/object-workspace.d.ts.map +1 -1
- package/dist/components/object-workspace.js +12 -6
- package/dist/components/page-actions.d.ts +3 -3
- package/dist/components/page-actions.d.ts.map +1 -1
- package/dist/components/page-actions.js +6 -3
- package/dist/components/page-header.js +1 -1
- package/dist/components/picture-label.d.ts.map +1 -1
- package/dist/components/picture-label.js +1 -1
- package/dist/components/plugin-slot-boundary.js +1 -1
- package/dist/components/popover.js +1 -1
- package/dist/components/reading-column.d.ts +1 -7
- package/dist/components/reading-column.d.ts.map +1 -1
- package/dist/components/reading-column.js +1 -7
- package/dist/components/record-identity.d.ts +8 -0
- package/dist/components/record-identity.d.ts.map +1 -0
- package/dist/components/record-identity.js +5 -0
- package/dist/components/select.js +2 -2
- package/dist/components/settings-facts.d.ts +2 -1
- package/dist/components/settings-facts.d.ts.map +1 -1
- package/dist/components/settings-facts.js +5 -3
- package/dist/components/settings-form.d.ts +9 -0
- package/dist/components/settings-form.d.ts.map +1 -0
- package/dist/components/settings-form.js +85 -0
- package/dist/components/settings-section.d.ts +5 -2
- package/dist/components/settings-section.d.ts.map +1 -1
- package/dist/components/settings-section.js +13 -6
- package/dist/components/sheet.d.ts.map +1 -1
- package/dist/components/sheet.js +3 -3
- package/dist/components/sidebar.js +9 -9
- package/dist/components/skeleton.d.ts +3 -5
- package/dist/components/skeleton.d.ts.map +1 -1
- package/dist/components/skeleton.js +2 -6
- package/dist/components/sonner.js +4 -4
- package/dist/components/status-row.js +1 -1
- package/dist/components/switch.js +1 -1
- package/dist/components/table.d.ts +4 -1
- package/dist/components/table.d.ts.map +1 -1
- package/dist/components/table.js +9 -9
- package/dist/components/tabs.d.ts +1 -1
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +7 -7
- package/dist/components/tag.d.ts +5 -3
- package/dist/components/tag.d.ts.map +1 -1
- package/dist/components/tag.js +10 -5
- package/dist/components/text-link.js +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/toggle-group.js +2 -2
- package/dist/components/toggle.js +3 -3
- package/dist/components/tooltip.js +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/internal/empty.d.ts +2 -6
- package/dist/internal/empty.d.ts.map +1 -1
- package/dist/internal/empty.js +5 -10
- package/dist/internal/footer-strip.js +1 -1
- package/dist/lib/merge-tokens.generated.js +2 -2
- package/dist/standalone/index.js +1 -1
- package/dist/styles/components.css +29 -6
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-filters.d.ts","sourceRoot":"","sources":["../../src/components/collection-filters.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;
|
|
1
|
+
{"version":3,"file":"collection-filters.d.ts","sourceRoot":"","sources":["../../src/components/collection-filters.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAoHF,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,IAAI,GACL,EAAE;IACD,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACpC,IAAI,EAAE,oBAAoB,CAAC;CAC5B,4BAuFA"}
|
|
@@ -36,7 +36,7 @@ function FilterPicker({ facets, copy, initialField, returnFocus, children, }) {
|
|
|
36
36
|
event.preventDefault();
|
|
37
37
|
changeField(undefined);
|
|
38
38
|
}
|
|
39
|
-
}, children: [_jsx(CommandInput, { ref: input, "aria-label": facet ? `${copy.searchValues}: ${facet.label}` : copy.searchFields, placeholder: facet ? copy.searchValues : copy.searchFields, value: search, onValueChange: setSearch }), _jsxs(CommandList, { label: facet?.label ?? copy.searchFields, children: [_jsx(CommandEmpty, { children: copy.empty }), _jsx(CommandGroup, { heading: facet?.label, children: facet ? (_jsxs(_Fragment, { children: [facet.value ? (_jsx(CommandItem, { value: facet.allLabel, onSelect: () => commit(""), children: facet.allLabel })) : null, facet.options.map((option) => (_jsxs(CommandItem, { value: option.value, keywords: [option.label], "data-checked": option.value === facet.value, onSelect: () => commit(option.value), children: [option.icon, _jsx("span", { className: option.mono ? "truncate
|
|
39
|
+
}, children: [_jsx(CommandInput, { ref: input, "aria-label": facet ? `${copy.searchValues}: ${facet.label}` : copy.searchFields, placeholder: facet ? copy.searchValues : copy.searchFields, value: search, onValueChange: setSearch }), _jsxs(CommandList, { label: facet?.label ?? copy.searchFields, children: [_jsx(CommandEmpty, { children: copy.empty }), _jsx(CommandGroup, { heading: facet?.label, children: facet ? (_jsxs(_Fragment, { children: [facet.value ? (_jsx(CommandItem, { value: facet.allLabel, onSelect: () => commit(""), children: facet.allLabel })) : null, facet.options.map((option) => (_jsxs(CommandItem, { value: option.value, keywords: [option.label], "data-checked": option.value === facet.value, onSelect: () => commit(option.value), children: [option.icon, _jsx("span", { className: option.mono ? "truncate font-label-mono text-label-mono" : "truncate", children: option.label })] }, option.value)))] })) : (facets.map((item) => (_jsx(CommandItem, { value: item.label, onSelect: () => changeField(item.label), children: item.label }, item.label)))) })] })] }, field ?? "fields")] })] }));
|
|
40
40
|
}
|
|
41
41
|
export function CollectionFilters({ facets, copy, }) {
|
|
42
42
|
const addTrigger = React.useRef(null);
|
|
@@ -46,7 +46,7 @@ export function CollectionFilters({ facets, copy, }) {
|
|
|
46
46
|
.filter((facet) => facet.value)
|
|
47
47
|
.map((facet) => {
|
|
48
48
|
const selected = facet.options.find((option) => option.value === facet.value);
|
|
49
|
-
return (_jsxs(ButtonGroup, { "aria-label": facet.label, className: "min-w-0 max-w-full", children: [_jsx(FilterPicker, { facets: facets, copy: copy, initialField: facet.label, returnFocus: addTrigger, children: _jsxs(Button, { variant: "outline", className: "max-w-64", children: [facet.selectedIcon ?? selected?.icon, _jsxs("span", { className: "truncate", children: [facet.label, ":", " ", _jsx("span", { className: selected?.mono ? "
|
|
49
|
+
return (_jsxs(ButtonGroup, { "aria-label": facet.label, className: "min-w-0 max-w-full", children: [_jsx(FilterPicker, { facets: facets, copy: copy, initialField: facet.label, returnFocus: addTrigger, children: _jsxs(Button, { variant: "outline", className: "max-w-64", children: [facet.selectedIcon ?? selected?.icon, _jsxs("span", { className: "truncate", children: [facet.label, ":", " ", _jsx("span", { className: selected?.mono ? "font-label-mono text-label-mono" : undefined, children: selected?.label ?? facet.value })] })] }) }), _jsx(Button, { variant: "outline", size: "icon", "aria-label": `${copy.remove}: ${facet.label}`, onClick: () => {
|
|
50
50
|
facet.onValueChange("");
|
|
51
51
|
addTrigger.current?.focus();
|
|
52
52
|
}, children: _jsx(X, { "aria-hidden": "true" }) })] }, facet.label));
|
|
@@ -60,7 +60,7 @@ export function CollectionFilters({ facets, copy, }) {
|
|
|
60
60
|
facet.onValueChange(value);
|
|
61
61
|
addTrigger.current?.focus();
|
|
62
62
|
}, children: [option.icon, _jsxs("span", { className: "truncate", children: [facet.label, " ", _jsx("span", { className: option.mono
|
|
63
|
-
? "text-foreground
|
|
63
|
+
? "text-foreground font-label-mono text-label-mono"
|
|
64
64
|
: "font-medium text-foreground", children: option.label })] })] }, `${facet.label}:${value}`),
|
|
65
65
|
]
|
|
66
66
|
: [];
|
|
@@ -7,7 +7,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
* it is the plain row it always was, and a page whose rows never pass under
|
|
8
8
|
* the bar asks for that plain row with `surface="plain"`.
|
|
9
9
|
*/
|
|
10
|
-
const ON_PAGE = "sticky top-3 z-20 mb-3 rounded-
|
|
10
|
+
const ON_PAGE = "sticky top-3 z-20 mb-3 rounded-lg p-2 nc-glass nc-elevation-floating";
|
|
11
11
|
const PLAIN = "relative mb-3";
|
|
12
12
|
const IN_CARD = "[[data-slot=table-card-toolbar]_&]:relative [[data-slot=table-card-toolbar]_&]:z-auto [[data-slot=table-card-toolbar]_&]:mb-0 [[data-slot=table-card-toolbar]_&]:rounded-none [[data-slot=table-card-toolbar]_&]:p-0 [[data-slot=table-card-toolbar]_&]:pb-4 [[data-slot=table-card-toolbar]_&]:[background:none] [[data-slot=table-card-toolbar]_&]:[backdrop-filter:none] [[data-slot=table-card-toolbar]_&]:[box-shadow:none]";
|
|
13
13
|
export function CollectionToolbar({ label, controls, search, actions, status, surface = "glass", ...props }) {
|
|
@@ -26,7 +26,7 @@ function ComboboxList({ className, ...props }) {
|
|
|
26
26
|
return (_jsx(ComboboxPrimitive.List, { "data-slot": "combobox-list", className: cn("no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-nadicode-xxs data-empty:p-0", className), ...props }));
|
|
27
27
|
}
|
|
28
28
|
function ComboboxItem({ className, children, ...props }) {
|
|
29
|
-
return (_jsxs(ComboboxPrimitive.Item, { "data-slot": "combobox-item", className: cn("relative flex min-h-touch-target w-full cursor-default items-center gap-2 rounded-
|
|
29
|
+
return (_jsxs(ComboboxPrimitive.Item, { "data-slot": "combobox-item", className: cn("relative flex min-h-touch-target w-full cursor-default items-center gap-2 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(ComboboxPrimitive.ItemIndicator, { render: _jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }), children: _jsx(CheckIcon, { className: "pointer-events-none" }) })] }));
|
|
30
30
|
}
|
|
31
31
|
function ComboboxGroup({ className, ...props }) {
|
|
32
32
|
return (_jsx(ComboboxPrimitive.Group, { "data-slot": "combobox-group", className: cn(className), ...props }));
|
|
@@ -44,10 +44,10 @@ function ComboboxSeparator({ className, ...props }) {
|
|
|
44
44
|
return (_jsx(ComboboxPrimitive.Separator, { "data-slot": "combobox-separator", className: cn("-mx-1 my-1 h-px bg-border", className), ...props }));
|
|
45
45
|
}
|
|
46
46
|
function ComboboxChips({ className, ...props }) {
|
|
47
|
-
return (_jsx(ComboboxPrimitive.Chips, { "data-slot": "combobox-chips", className: cn("flex min-h-touch-target flex-wrap items-center gap-1 rounded-
|
|
47
|
+
return (_jsx(ComboboxPrimitive.Chips, { "data-slot": "combobox-chips", className: cn("flex min-h-touch-target flex-wrap items-center gap-1 rounded-sm border border-input bg-background bg-clip-padding px-control-padding-inline py-1 text-sm transition-colors focus-within:nc-focus-outline focus-within:outline-ring has-aria-invalid:border-destructive has-aria-invalid:nc-focus-outline has-aria-invalid:outline-destructive has-data-[slot=combobox-chip]:px-1 [@media(hover:hover)_and_(pointer:fine)]:min-h-control-height", className), ...props }));
|
|
48
48
|
}
|
|
49
49
|
function ComboboxChip({ className, children, showRemove = true, ...props }) {
|
|
50
|
-
return (_jsxs(ComboboxPrimitive.Chip, { "data-slot": "combobox-chip", className: cn("flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-
|
|
50
|
+
return (_jsxs(ComboboxPrimitive.Chip, { "data-slot": "combobox-chip", className: cn("flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0", className), ...props, children: [children, showRemove && (_jsx(ComboboxPrimitive.ChipRemove, { render: _jsx(Button, { variant: "ghost", size: "icon-xs" }), className: "-ml-1 opacity-50 hover:opacity-100", "data-slot": "combobox-chip-remove", children: _jsx(XIcon, { className: "pointer-events-none" }) }))] }));
|
|
51
51
|
}
|
|
52
52
|
function ComboboxChipsInput({ className, ...props }) {
|
|
53
53
|
return (_jsx(ComboboxPrimitive.Input, { "data-slot": "combobox-chip-input", className: cn("min-w-16 flex-1 outline-none", className), ...props }));
|
|
@@ -9,10 +9,10 @@ function Command({ className, ...props }) {
|
|
|
9
9
|
return (_jsx(CommandPrimitive, { "data-slot": "command", className: cn("flex size-full flex-col overflow-hidden rounded-lg! nc-glass p-nadicode-xxs text-popover-foreground", className), ...props }));
|
|
10
10
|
}
|
|
11
11
|
function CommandDialog({ title = "Command Palette", description = "Search for a command to run...", children, className, showCloseButton = false, ...props }) {
|
|
12
|
-
return (_jsxs(Dialog, { ...props, children: [_jsxs(DialogHeader, { className: "sr-only", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogDescription, { children: description })] }), _jsx(DialogContent, { className: cn("top-1/3 translate-y-0 overflow-hidden rounded-
|
|
12
|
+
return (_jsxs(Dialog, { ...props, children: [_jsxs(DialogHeader, { className: "sr-only", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogDescription, { children: description })] }), _jsx(DialogContent, { className: cn("top-1/3 translate-y-0 overflow-hidden rounded-lg! bg-transparent p-0!", className), motion: "instant", showCloseButton: showCloseButton, children: children })] }));
|
|
13
13
|
}
|
|
14
14
|
function CommandInput({ className, ...props }) {
|
|
15
|
-
return (_jsx("div", { "data-slot": "command-input-wrapper", className: "p-1 pb-0", children: _jsxs(InputGroup, { className: "h-control-height! rounded-
|
|
15
|
+
return (_jsx("div", { "data-slot": "command-input-wrapper", className: "p-1 pb-0", children: _jsxs(InputGroup, { className: "h-control-height! rounded-sm! border-input bg-background shadow-none! *:data-[slot=input-group-addon]:pl-2!", children: [_jsx(CommandPrimitive.Input, { "data-slot": "command-input", className: cn("w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50", className), ...props }), _jsx(InputGroupAddon, { children: _jsx(SearchIcon, { className: "size-4 shrink-0 opacity-50" }) })] }) }));
|
|
16
16
|
}
|
|
17
17
|
function CommandList({ className, ...props }) {
|
|
18
18
|
return (_jsx(CommandPrimitive.List, { "data-slot": "command-list", className: cn("no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none", className), ...props }));
|
|
@@ -27,7 +27,7 @@ function CommandSeparator({ className, ...props }) {
|
|
|
27
27
|
return (_jsx(CommandPrimitive.Separator, { "data-slot": "command-separator", className: cn("-mx-1 h-px bg-border", className), ...props }));
|
|
28
28
|
}
|
|
29
29
|
function CommandItem({ className, children, ...props }) {
|
|
30
|
-
return (_jsxs(CommandPrimitive.Item, { "data-slot": "command-item", className: cn("group/command-item relative flex min-h-touch-target cursor-default items-center gap-2 rounded-
|
|
30
|
+
return (_jsxs(CommandPrimitive.Item, { "data-slot": "command-item", className: cn("group/command-item relative flex min-h-touch-target cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-muted data-[selected=true]:text-foreground [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[selected=true]:*:[svg]:text-foreground", className), ...props, children: [children, _jsx(CheckIcon, { className: "ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" })] }));
|
|
31
31
|
}
|
|
32
32
|
function CommandShortcut({ className, ...props }) {
|
|
33
33
|
return (_jsx("span", { "data-slot": "command-shortcut", className: cn("ml-auto text-xs tracking-widest text-muted-foreground group-data-selected/command-item:text-foreground", className), ...props }));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type CopyButtonProps = {
|
|
2
|
+
value: string;
|
|
3
|
+
copyLabel: string;
|
|
4
|
+
copiedLabel: string;
|
|
5
|
+
copyFailedLabel: string;
|
|
6
|
+
size?: "icon" | "icon-xs" | "icon-sm";
|
|
7
|
+
};
|
|
8
|
+
export declare function CopyButton(props: CopyButtonProps): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=copy-button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy-button.d.ts","sourceRoot":"","sources":["../../src/components/copy-button.tsx"],"names":[],"mappings":"AAQA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;CACvC,CAAC;AAEF,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,+BAEhD"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useTransition } from "react";
|
|
4
|
+
import { Check, CircleAlert, Copy } from "lucide-react";
|
|
5
|
+
import { Button } from "./button.js";
|
|
6
|
+
import { useCopyToClipboard } from "../lib/use-copy-to-clipboard.js";
|
|
7
|
+
export function CopyButton(props) {
|
|
8
|
+
return _jsx(CopyValueButton, { ...props }, props.value);
|
|
9
|
+
}
|
|
10
|
+
function CopyValueButton({ value, copyLabel, copiedLabel, copyFailedLabel, size = "icon", }) {
|
|
11
|
+
const [failed, setFailed] = useState(false);
|
|
12
|
+
const [pending, startTransition] = useTransition();
|
|
13
|
+
const { copyToClipboard, isCopied } = useCopyToClipboard({
|
|
14
|
+
text: value,
|
|
15
|
+
timeout: 2000,
|
|
16
|
+
onError: () => setFailed(true),
|
|
17
|
+
});
|
|
18
|
+
const copied = isCopied && !failed && !pending;
|
|
19
|
+
return (_jsxs(_Fragment, { children: [_jsx(Button, { "aria-label": copyLabel, "aria-busy": pending, title: failed ? copyFailedLabel : copyLabel, disabled: pending, focusableWhenDisabled: true, onClick: () => {
|
|
20
|
+
setFailed(false);
|
|
21
|
+
startTransition(async () => {
|
|
22
|
+
await copyToClipboard();
|
|
23
|
+
});
|
|
24
|
+
}, size: size, type: "button", variant: "ghost", children: pending ? (_jsx(Copy, { "data-icon": "inline-start" })) : failed ? (_jsx(CircleAlert, { "data-icon": "inline-start" })) : copied ? (_jsx(Check, { "data-icon": "inline-start" })) : (_jsx(Copy, { "data-icon": "inline-start" })) }), _jsx("span", { className: "sr-only", role: "status", children: pending ? "" : failed ? copyFailedLabel : copied ? copiedLabel : "" })] }));
|
|
25
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { columnFilteringFeature, columnVisibilityFeature, createFilteredRowModel, createPaginatedRowModel, createSortedRowModel, filterFn_arrIncludes, filterFn_equals, filterFn_inDateRange, filterFn_includesString, filterFn_inNumberRange, filterFn_weakEquals, rowPaginationFeature, rowSortingFeature, sortFn_alphanumeric, sortFn_datetime, sortFn_text, type CellData, type Column, type ColumnDef, type RowData } from "@tanstack/react-table";
|
|
3
3
|
import { type EmptyStateProps } from "./empty-state.js";
|
|
4
|
+
import { Table } from "./table.js";
|
|
4
5
|
import { type TableCompactLayout } from "./table-layouts.js";
|
|
5
6
|
type DataTableFeatures = {
|
|
6
7
|
columnFilteringFeature: typeof columnFilteringFeature;
|
|
@@ -86,19 +87,18 @@ type DataTableBaseProps<TData extends RowData> = {
|
|
|
86
87
|
* collection leaves it out, because the page heading already names it.
|
|
87
88
|
*/
|
|
88
89
|
heading?: {
|
|
89
|
-
title:
|
|
90
|
+
title: React.ReactNode;
|
|
90
91
|
description?: string;
|
|
91
92
|
};
|
|
92
93
|
/** A count or the paging under the rows; never a help sentence. */
|
|
93
94
|
footer?: React.ReactNode;
|
|
94
95
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* the header row is kept for screen readers only. Opt in only for a table
|
|
98
|
-
* whose columns are figures a reader cannot tell apart without their names,
|
|
99
|
-
* such as statements or analytics.
|
|
96
|
+
* Visible by default so comparable columns retain their names. A self-describing
|
|
97
|
+
* entity list can set false; its headers remain available to screen readers.
|
|
100
98
|
*/
|
|
101
99
|
showColumnHeaders?: boolean;
|
|
100
|
+
density?: React.ComponentProps<typeof Table>["density"];
|
|
101
|
+
interactive?: boolean;
|
|
102
102
|
/** A fixed comparison inside an existing detail Card keeps that one frame. */
|
|
103
103
|
embedded?: boolean;
|
|
104
104
|
summary?: {
|
|
@@ -150,6 +150,6 @@ type DataTableRowNav<TData extends RowData> = {
|
|
|
150
150
|
};
|
|
151
151
|
export type DataTableProps<TData extends RowData> = DataTableBaseProps<TData> & DataTableRowNav<TData>;
|
|
152
152
|
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, embedded, summary, rowHref, rowLabel, primaryColumnId, empty, noMatchMessage, columnsLabel, clearSearchLabel, pageLabels, toolbarActions, externalFilter, sorting: externalSorting, pagination, renderRowLink, renderToolbar, wrapCard, }: DataTableProps<TData>): React.JSX.Element;
|
|
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;
|
|
154
154
|
export {};
|
|
155
155
|
//# 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":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EAEnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,WAAW,EAGX,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,SAAS,EAGd,KAAK,OAAO,EAEb,MAAM,uBAAuB,CAAC;AAa/B,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/components/data-table.tsx"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ import { Button } from "./button.js";
|
|
|
9
9
|
import { CollectionToolbar } from "./collection-toolbar.js";
|
|
10
10
|
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuTrigger, } from "./dropdown-menu.js";
|
|
11
11
|
import { EmptyState } from "./empty-state.js";
|
|
12
|
-
import { Table,
|
|
12
|
+
import { Table, TableCell, TableDetailRow, TableHead, TableHeader, TableRecordGroup, TableRow, } from "./table.js";
|
|
13
13
|
import { TableCard } from "./table-card.js";
|
|
14
14
|
import { tableCompactLayouts } from "./table-layouts.js";
|
|
15
15
|
const dataTableFeatures = tableFeatures({
|
|
@@ -38,28 +38,14 @@ const dataTableFeatures = tableFeatures({
|
|
|
38
38
|
function isNumericColumn(column) {
|
|
39
39
|
return column.columnDef.meta?.numeric === true;
|
|
40
40
|
}
|
|
41
|
-
// DESIGN.md, "Tables and missing values": a row reads as its record's name on
|
|
42
|
-
// one line, then facts at their own width. Against `table-layout: auto` a
|
|
43
|
-
// declared width is only a hint and a percentage is honoured first, so a
|
|
44
|
-
// control column asks for `1px`, the identity claims a third and gives it back
|
|
45
|
-
// down to its floor with an ellipsis, a prose column holds its words on one
|
|
46
|
-
// line up to a cap and cuts the rest with an ellipsis, and every other cell
|
|
47
|
-
// holds its fact on one line. A record is one line at every desktop width.
|
|
48
41
|
const NARROW_COLUMN_CLASS = "w-px whitespace-nowrap";
|
|
49
|
-
const IDENTITY_COLUMN_CLASS = "
|
|
42
|
+
const IDENTITY_COLUMN_CLASS = "max-w-0 min-w-24";
|
|
50
43
|
const IDENTITY_CONTENT_CLASS = "truncate";
|
|
51
44
|
const PROSE_COLUMN_CLASS = "min-w-32";
|
|
52
|
-
// A document's text, such as a legal table's, is read whole: it wraps between
|
|
53
|
-
// words and is never cut, so its row grows instead.
|
|
54
45
|
const WRAPPING_COLUMN_CLASS = "min-w-32 whitespace-normal align-top";
|
|
55
|
-
// A one-track grid whose track runs from zero to the words' own width: the
|
|
56
|
-
// cell asks for its words up to the cap, yet a narrow table can still shrink
|
|
57
|
-
// the column to its floor instead of being pushed wider than its container.
|
|
58
46
|
const PROSE_FRAME_CLASS = "grid grid-cols-[minmax(0,max-content)]";
|
|
59
47
|
const PROSE_CONTENT_CLASS = "max-w-64 truncate";
|
|
60
48
|
const CELL_INSET_CLASS = "px-4";
|
|
61
|
-
// A name cut with an ellipsis is read whole on hover. The title is set when the
|
|
62
|
-
// pointer or focus arrives, and only while some part of the name is cut.
|
|
63
49
|
function titleWhenCut(event) {
|
|
64
50
|
const element = event.currentTarget;
|
|
65
51
|
const cut = [element, ...element.querySelectorAll("*")].some((node) => node.scrollWidth > node.clientWidth);
|
|
@@ -69,15 +55,13 @@ function titleWhenCut(event) {
|
|
|
69
55
|
else
|
|
70
56
|
element.removeAttribute("title");
|
|
71
57
|
}
|
|
72
|
-
// In the compact layout every other visible column already takes its narrowest
|
|
73
|
-
// width, so the identity takes the whole rest of the row.
|
|
74
58
|
const COMPACT_IDENTITY_CLASS = {
|
|
75
59
|
tight: "@max-xl/table:w-full",
|
|
76
60
|
standard: "@max-3xl/table:w-full",
|
|
77
61
|
wide: "@max-5xl/table:w-full",
|
|
78
62
|
spacious: "@max-6xl/table:w-full",
|
|
79
63
|
};
|
|
80
|
-
function widthClass(column, identityColumnId, compactLayout, identityAlone) {
|
|
64
|
+
function widthClass(column, identityColumnId, compactLayout, identityAlone, balancedIdentity) {
|
|
81
65
|
if (column.columnDef.meta?.narrow === true)
|
|
82
66
|
return NARROW_COLUMN_CLASS;
|
|
83
67
|
if (column.columnDef.meta?.prose === true)
|
|
@@ -86,11 +70,8 @@ function widthClass(column, identityColumnId, compactLayout, identityAlone) {
|
|
|
86
70
|
return WRAPPING_COLUMN_CLASS;
|
|
87
71
|
if (column.id !== identityColumnId)
|
|
88
72
|
return false;
|
|
89
|
-
|
|
90
|
-
// sit at its trailing edge instead of a third of the way across.
|
|
91
|
-
return cn(IDENTITY_COLUMN_CLASS, identityAlone && "w-full", compactLayout && COMPACT_IDENTITY_CLASS[compactLayout]);
|
|
73
|
+
return cn(IDENTITY_COLUMN_CLASS, balancedIdentity ? "w-1/4" : "w-1/3 sm:min-w-44", identityAlone && "w-full", compactLayout && COMPACT_IDENTITY_CLASS[compactLayout]);
|
|
92
74
|
}
|
|
93
|
-
// The id TanStack gives a column: its own, or the accessor key it reads.
|
|
94
75
|
function definitionId(column) {
|
|
95
76
|
if (!column)
|
|
96
77
|
return undefined;
|
|
@@ -98,8 +79,6 @@ function definitionId(column) {
|
|
|
98
79
|
return column.id;
|
|
99
80
|
return "accessorKey" in column ? String(column.accessorKey) : undefined;
|
|
100
81
|
}
|
|
101
|
-
// The column-visibility menu and the detail row name each column by its
|
|
102
|
-
// localized header; the id is a fallback for a header drawn by a function.
|
|
103
82
|
export function columnMenuLabel(column) {
|
|
104
83
|
const header = column.columnDef.header;
|
|
105
84
|
return typeof header === "string" ? header : column.id;
|
|
@@ -158,12 +137,10 @@ const defaultRowLink = (props) => _jsx("a", { ...props });
|
|
|
158
137
|
function DefaultToolbar({ actions }) {
|
|
159
138
|
return actions ? _jsx(CollectionToolbar, { label: "", actions: actions }) : null;
|
|
160
139
|
}
|
|
161
|
-
export function DataTable({ columns, data, getRowId, filterColumnId, filterPlaceholder, primaryColumns, compactLayout: requestedCompactLayout, tableLabel, heading, footer, showColumnHeaders =
|
|
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, }) {
|
|
162
141
|
const [sorting, setSorting] = React.useState([]);
|
|
163
142
|
const [columnFilters, setColumnFilters] = React.useState([]);
|
|
164
143
|
const [columnVisibility, setColumnVisibility] = React.useState({});
|
|
165
|
-
// One column absorbs the slack: a column of sentences when the table has
|
|
166
|
-
// one, otherwise the identity, the first column that is not a control.
|
|
167
144
|
const identityColumnId = definitionId(columns.find((column) => column.meta?.narrow !== true && column.meta?.prose !== true && column.meta?.wraps !== true));
|
|
168
145
|
const identityAlone = columns.every((column) => column.meta?.narrow === true || definitionId(column) === identityColumnId);
|
|
169
146
|
// An external pager means `data` is already one bounded server page:
|
|
@@ -186,12 +163,12 @@ export function DataTable({ columns, data, getRowId, filterColumnId, filterPlace
|
|
|
186
163
|
columnVisibility,
|
|
187
164
|
},
|
|
188
165
|
});
|
|
166
|
+
const balancedIdentity = showColumnHeaders && table.getVisibleLeafColumns().length > 5;
|
|
189
167
|
const hasDetailColumns = table
|
|
190
168
|
.getAllLeafColumns()
|
|
191
169
|
.some((column) => !primaryColumns.includes(column.id));
|
|
192
170
|
const compactLayout = hasDetailColumns
|
|
193
|
-
? (requestedCompactLayout ??
|
|
194
|
-
(columns.length > 7 ? "spacious" : columns.length > 5 ? "wide" : "standard"))
|
|
171
|
+
? (requestedCompactLayout ?? (table.getVisibleLeafColumns().length > 7 ? "wide" : "standard"))
|
|
195
172
|
: undefined;
|
|
196
173
|
const [shownLayout, layoutProbeRef] = useShownLayout();
|
|
197
174
|
const canPreviousPage = pagination ? pagination.hasPrevious : table.getCanPreviousPage();
|
|
@@ -207,21 +184,16 @@ export function DataTable({ columns, data, getRowId, filterColumnId, filterPlace
|
|
|
207
184
|
.filter((column) => column.getCanHide())
|
|
208
185
|
.map((column) => (_jsx(DropdownMenuCheckboxItem, { checked: column.getIsVisible(), onCheckedChange: (value) => column.toggleVisibility(!!value), children: columnMenuLabel(column) }, column.id))) }) })] })) : null;
|
|
209
186
|
const rows = table.getRowModel().rows;
|
|
210
|
-
const colSpan = Math.max(1, table.getVisibleLeafColumns().length);
|
|
211
187
|
const renderRow = (row) => {
|
|
212
188
|
const href = rowHref?.(row.original);
|
|
213
189
|
const label = rowLabel?.(row.original);
|
|
214
190
|
const visibleCells = row.getVisibleCells();
|
|
215
|
-
// The link rides one cell only, the named primary column or the first
|
|
216
|
-
// visible one, so the row is a single tab stop with a purposeful name.
|
|
217
191
|
const configuredPrimaryVisible = primaryColumnId !== undefined && table.getColumn(primaryColumnId)?.getIsVisible();
|
|
218
192
|
const primaryId = configuredPrimaryVisible ? primaryColumnId : visibleCells[0]?.column.id;
|
|
219
193
|
const detailCells = visibleCells.filter((cell) => !primaryColumns.includes(cell.column.id));
|
|
220
194
|
return (_jsxs(TableRecordGroup, { children: [_jsx(TableRow, { "data-href": href, className: cn(href && "cursor-pointer"), detailLayout: detailCells.length > 0 ? compactLayout : undefined, onClick: href
|
|
221
195
|
? (event) => {
|
|
222
196
|
const target = event.target;
|
|
223
|
-
// The row link and any interactive descendant own their own
|
|
224
|
-
// clicks; only a bare-cell click is delegated to the link.
|
|
225
197
|
if (!(target instanceof Element) ||
|
|
226
198
|
target.closest("a, button, input, select, textarea, label, [role='button'], [role='menuitem'], [role='checkbox']")) {
|
|
227
199
|
return;
|
|
@@ -232,7 +204,7 @@ export function DataTable({ columns, data, getRowId, filterColumnId, filterPlace
|
|
|
232
204
|
const numeric = isNumericColumn(cell.column);
|
|
233
205
|
const isPrimaryLink = href && cell.column.id === primaryId;
|
|
234
206
|
const collapsed = collapseClass(cell.column.id, primaryColumns, compactLayout);
|
|
235
|
-
const className = cn(CELL_INSET_CLASS, numeric && "text-right tabular-nums wrap-normal", widthClass(cell.column, identityColumnId, compactLayout, identityAlone), collapsed);
|
|
207
|
+
const className = cn(CELL_INSET_CLASS, numeric && "text-right tabular-nums wrap-normal", cell.column.columnDef.meta?.wraps && "whitespace-normal", widthClass(cell.column, identityColumnId, compactLayout, identityAlone, balancedIdentity), collapsed);
|
|
236
208
|
const drawnOnlyInDetailRow = Boolean(collapsed) && shownLayout === "details" && !isPrimaryLink;
|
|
237
209
|
if (drawnOnlyInDetailRow) {
|
|
238
210
|
return _jsx(TableCell, { className: className }, cell.id);
|
|
@@ -255,22 +227,20 @@ export function DataTable({ columns, data, getRowId, filterColumnId, filterPlace
|
|
|
255
227
|
value: flexRender(cell.column.columnDef.cell, cell.getContext()),
|
|
256
228
|
})) })) : null] }, row.id));
|
|
257
229
|
};
|
|
258
|
-
const tableNode =
|
|
230
|
+
const tableNode = rows.length === 0 ? (_jsx(EmptyState, { scope: "card", ...(filterValue && noMatchMessage && clearSearchLabel && filterColumn
|
|
231
|
+
? {
|
|
232
|
+
kind: "noResults",
|
|
233
|
+
presentation: empty.presentation,
|
|
234
|
+
message: noMatchMessage,
|
|
235
|
+
clear: {
|
|
236
|
+
label: clearSearchLabel,
|
|
237
|
+
onClick: () => filterColumn.setFilterValue(""),
|
|
238
|
+
},
|
|
239
|
+
}
|
|
240
|
+
: empty) })) : (_jsxs(Table, { "aria-label": tableLabel, className: "text-body-sm", compactDetails: compactLayout, density: density, interactive: interactive, children: [_jsx(TableHeader, { className: showColumnHeaders ? undefined : "sr-only", children: table.getHeaderGroups().map((headerGroup) => (_jsx(TableRow, { children: headerGroup.headers.map((header) => (_jsx(TableHead, { className: cn(CELL_INSET_CLASS, isNumericColumn(header.column) && "text-right tabular-nums", widthClass(header.column, identityColumnId, compactLayout, identityAlone, balancedIdentity), collapseClass(header.column.id, primaryColumns, compactLayout)), children: header.isPlaceholder
|
|
259
241
|
? null
|
|
260
|
-
: flexRender(header.column.columnDef.header, header.getContext()) }, header.id))) }, headerGroup.id))) }), _jsx(LayoutProbeLeadingRecords, { layout: compactLayout, probeRef: layoutProbeRef, children: rows.
|
|
261
|
-
? {
|
|
262
|
-
kind: "noResults",
|
|
263
|
-
message: noMatchMessage,
|
|
264
|
-
clear: {
|
|
265
|
-
label: clearSearchLabel,
|
|
266
|
-
onClick: () => filterColumn.setFilterValue(""),
|
|
267
|
-
},
|
|
268
|
-
}
|
|
269
|
-
: empty) }) }) }) })) })] }));
|
|
242
|
+
: flexRender(header.column.columnDef.header, header.getContext()) }, header.id))) }, headerGroup.id))) }), _jsx(LayoutProbeLeadingRecords, { layout: compactLayout, probeRef: layoutProbeRef, children: rows.map(renderRow) })] }));
|
|
270
243
|
const actions = columnsControl || toolbarActions ? (_jsxs(_Fragment, { children: [columnsControl, toolbarActions] })) : null;
|
|
271
|
-
// The toolbar belongs to the collection, so it sits at the top of the frame
|
|
272
|
-
// the collection owns: under the card's own title when it has one, and above
|
|
273
|
-
// the card when the page itself is the collection.
|
|
274
244
|
const toolbarRow = renderToolbar({
|
|
275
245
|
actions,
|
|
276
246
|
...(filterColumn
|
|
@@ -288,5 +258,5 @@ export function DataTable({ columns, data, getRowId, filterColumnId, filterPlace
|
|
|
288
258
|
: {}),
|
|
289
259
|
});
|
|
290
260
|
const card = (_jsx(TableCard, { surface: embedded ? "plain" : "resting", ...(heading ? { title: heading.title } : {}), ...(heading?.description ? { description: heading.description } : {}), ...(heading && toolbarRow ? { toolbar: toolbarRow } : {}), ...(summary ? { summary } : {}), ...(footer ? { footer } : {}), children: tableNode }));
|
|
291
|
-
return (_jsxs("div", { className: "min-w-0 w-full
|
|
261
|
+
return (_jsxs("div", { className: "min-w-0 w-full text-body-sm", "data-slot": "data-table", children: [heading ? null : toolbarRow, wrapCard ? wrapCard(card) : card, !pageLabels || pagination === false || (!canPreviousPage && !canNextPage) ? null : (_jsxs("div", { className: "flex items-center justify-end gap-2 py-4", children: [_jsx(Button, { variant: "outline", onClick: goPreviousPage, disabled: !canPreviousPage || (pagination && pagination.isPending), children: pageLabels.previous }), _jsx(Button, { variant: "outline", onClick: goNextPage, disabled: !canNextPage || (pagination && pagination.isPending), children: pageLabels.next })] }))] }));
|
|
292
262
|
}
|
|
@@ -43,12 +43,12 @@ function DialogBody({ className, ...props }) {
|
|
|
43
43
|
return (_jsx("div", { "data-slot": "dialog-body", className: cn("-mx-nadicode-xxs flex min-h-0 flex-1 flex-col gap-nadicode-md overflow-y-auto px-nadicode-xxs", className), ...props }));
|
|
44
44
|
}
|
|
45
45
|
function DialogFooter({ className, showCloseButton = false, closeLabel = "Close", children, ...props }) {
|
|
46
|
-
return (_jsxs("div", { "data-slot": "dialog-footer", className: cn("-mx-nadicode-lg -mb-nadicode-lg flex flex-col-reverse gap-2
|
|
46
|
+
return (_jsxs("div", { "data-slot": "dialog-footer", className: cn("-mx-nadicode-lg -mb-nadicode-lg flex flex-col-reverse gap-2 rounded-b-lg border-t border-border bg-recessed px-nadicode-lg py-control-padding-inline sm:flex-row sm:justify-end", className), ...props, children: [children, showCloseButton && (_jsx(DialogPrimitive.Close, { render: _jsx(Button, { variant: "outline" }), children: closeLabel }))] }));
|
|
47
47
|
}
|
|
48
48
|
function DialogTitle({ className, ...props }) {
|
|
49
|
-
return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn("text-
|
|
49
|
+
return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn("text-heading-sm", className), ...props }));
|
|
50
50
|
}
|
|
51
51
|
function DialogDescription({ className, ...props }) {
|
|
52
|
-
return (_jsx(DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn("text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className), ...props }));
|
|
52
|
+
return (_jsx(DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn("text-body-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className), ...props }));
|
|
53
53
|
}
|
|
54
54
|
export { Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };
|
|
@@ -66,7 +66,7 @@ function DrawerContent({ className, children, ...props }) {
|
|
|
66
66
|
* adds no edge of its own.
|
|
67
67
|
*/
|
|
68
68
|
function DrawerHeader({ className, ...props }) {
|
|
69
|
-
return (_jsx("div", { "data-slot": "drawer-header", className: cn("flex shrink-0 flex-col gap-0.5
|
|
69
|
+
return (_jsx("div", { "data-slot": "drawer-header", className: cn("flex shrink-0 flex-col gap-0.5 p-nadicode-lg pb-nadicode-md group-data-[swipe-axis=y]/drawer-popup:text-center md:gap-0.5 md:text-left", className), ...props }));
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
72
|
* The part of a drawer that scrolls, between its header and footer, which stay
|
|
@@ -76,12 +76,12 @@ function DrawerBody({ className, ...props }) {
|
|
|
76
76
|
return (_jsx("div", { "data-slot": "drawer-body", className: cn("flex min-h-0 flex-1 flex-col gap-nadicode-md overflow-y-auto p-nadicode-lg", className), ...props }));
|
|
77
77
|
}
|
|
78
78
|
function DrawerFooter({ className, ...props }) {
|
|
79
|
-
return (_jsx("div", { "data-slot": "drawer-footer", className: cn("mt-auto flex shrink-0 flex-col gap-2 border-t border-border
|
|
79
|
+
return (_jsx("div", { "data-slot": "drawer-footer", className: cn("mt-auto flex shrink-0 flex-col gap-2 border-t border-border bg-recessed px-nadicode-lg py-control-padding-inline", className), ...props }));
|
|
80
80
|
}
|
|
81
81
|
function DrawerTitle({ className, ...props }) {
|
|
82
|
-
return (_jsx(DrawerPrimitive.Title, { "data-slot": "drawer-title", className: cn("text-
|
|
82
|
+
return (_jsx(DrawerPrimitive.Title, { "data-slot": "drawer-title", className: cn("text-heading-sm text-foreground", className), ...props }));
|
|
83
83
|
}
|
|
84
84
|
function DrawerDescription({ className, ...props }) {
|
|
85
|
-
return (_jsx(DrawerPrimitive.Description, { "data-slot": "drawer-description", className: cn("text-sm text-balance text-muted-foreground", className), ...props }));
|
|
85
|
+
return (_jsx(DrawerPrimitive.Description, { "data-slot": "drawer-description", className: cn("text-body-sm text-balance text-muted-foreground", className), ...props }));
|
|
86
86
|
}
|
|
87
87
|
export { Drawer, DrawerPortal, DrawerOverlay, DrawerSwipeHandle, DrawerTrigger, DrawerClose, DrawerContent, DrawerHeader, DrawerBody, DrawerFooter, DrawerTitle, DrawerDescription, };
|
|
@@ -24,8 +24,8 @@ function DropdownMenuLabel({ className, inset, ...props }) {
|
|
|
24
24
|
return (_jsx(MenuPrimitive.GroupLabel, { "data-slot": "dropdown-menu-label", "data-inset": inset, className: cn("px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7", className), ...props }));
|
|
25
25
|
}
|
|
26
26
|
function DropdownMenuItem({ className, iconOnly = false, inset, variant = "default", ...props }) {
|
|
27
|
-
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, "data-variant": variant, className: cn("group/dropdown-menu-item relative flex min-h-touch-target cursor-default items-center gap-1.5 rounded-
|
|
28
|
-
"size-8 min-w-touch-target shrink-0 justify-center rounded-
|
|
27
|
+
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, "data-variant": variant, className: cn("group/dropdown-menu-item relative flex min-h-touch-target cursor-default items-center gap-1.5 rounded-sm px-1.5 py-1 group-data-[density=comfortable]/menu:px-3 group-data-[density=comfortable]/menu:py-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive-soft-foreground data-[variant=destructive]:focus:bg-destructive-soft data-[variant=destructive]:focus:text-destructive-soft-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive-soft-foreground", iconOnly &&
|
|
28
|
+
"size-8 min-w-touch-target shrink-0 justify-center rounded-sm p-0 group-data-[density=comfortable]/menu:p-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0", className), ...props }));
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* A command in a record's or a page's menu: its label first, a decorative icon
|
|
@@ -41,20 +41,20 @@ function DropdownMenuSub({ ...props }) {
|
|
|
41
41
|
return _jsx(MenuPrimitive.SubmenuRoot, { "data-slot": "dropdown-menu-sub", ...props });
|
|
42
42
|
}
|
|
43
43
|
function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
|
|
44
|
-
return (_jsxs(MenuPrimitive.SubmenuTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn("flex min-h-touch-target cursor-default items-center gap-1.5 rounded-
|
|
44
|
+
return (_jsxs(MenuPrimitive.SubmenuTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn("flex min-h-touch-target cursor-default items-center gap-1.5 rounded-sm px-1.5 py-1 group-data-[density=comfortable]/menu:px-3 group-data-[density=comfortable]/menu:py-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, _jsx(ChevronRightIcon, { className: "ml-auto" })] }));
|
|
45
45
|
}
|
|
46
46
|
function DropdownMenuSubContent({ align = "start", alignOffset = -3, side = "right", sideOffset = 0, className, ...props }) {
|
|
47
47
|
return (_jsx(DropdownMenuContent, { "data-slot": "dropdown-menu-sub-content", className: cn("w-auto min-w-24", className), align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, ...props }));
|
|
48
48
|
}
|
|
49
49
|
function DropdownMenuCheckboxItem({ className, children, checked, inset, ...props }) {
|
|
50
|
-
return (_jsxs(MenuPrimitive.CheckboxItem, { "data-slot": "dropdown-menu-checkbox-item", "data-inset": inset, className: cn("relative flex min-h-touch-target cursor-default items-center gap-1.5 rounded-
|
|
50
|
+
return (_jsxs(MenuPrimitive.CheckboxItem, { "data-slot": "dropdown-menu-checkbox-item", "data-inset": inset, className: cn("relative flex min-h-touch-target cursor-default items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), checked: checked, ...props, children: [_jsx("span", { className: "pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-checkbox-item-indicator", children: _jsx(MenuPrimitive.CheckboxItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
|
|
51
51
|
}
|
|
52
52
|
function DropdownMenuRadioGroup({ ...props }) {
|
|
53
53
|
return _jsx(MenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
|
|
54
54
|
}
|
|
55
55
|
function DropdownMenuRadioItem({ className, iconOnly = false, children, inset, ...props }) {
|
|
56
|
-
return (_jsxs(MenuPrimitive.RadioItem, { "data-slot": "dropdown-menu-radio-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, className: cn("relative flex min-h-touch-target cursor-default items-center gap-1.5 rounded-
|
|
57
|
-
"size-8 min-w-touch-target justify-center rounded-
|
|
56
|
+
return (_jsxs(MenuPrimitive.RadioItem, { "data-slot": "dropdown-menu-radio-item", "data-icon-only": iconOnly || undefined, "data-inset": inset, className: cn("relative flex min-h-touch-target cursor-default items-center gap-1.5 rounded-sm py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", iconOnly &&
|
|
57
|
+
"size-8 min-w-touch-target justify-center rounded-sm p-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 data-checked:bg-muted data-checked:text-foreground", className), ...props, children: [!iconOnly ? (_jsx("span", { className: "pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-radio-item-indicator", children: _jsx(MenuPrimitive.RadioItemIndicator, { children: _jsx(CheckIcon, {}) }) })) : null, children] }));
|
|
58
58
|
}
|
|
59
59
|
function DropdownMenuSeparator({ className, ...props }) {
|
|
60
60
|
return (_jsx(MenuPrimitive.Separator, { "data-slot": "dropdown-menu-separator", className: cn("-mx-1 my-1 h-px bg-border", className), ...props }));
|
|
@@ -1,38 +1,32 @@
|
|
|
1
1
|
import type { EmptyArt } from "./empty-art.js";
|
|
2
2
|
import { type PageCommand } from "./page-actions.js";
|
|
3
3
|
import { type ResolvedMessage } from "./product-message.js";
|
|
4
|
-
/**
|
|
5
|
-
* What a place with nothing in it says (DESIGN.md "Elevation & Depth", the
|
|
6
|
-
* absence paragraph):
|
|
7
|
-
* - `firstUse`: a collection with no records yet whose kind has a picture in
|
|
8
|
-
* the approved set: the picture, a title, one line saying what will live
|
|
9
|
-
* there, and, when this viewer can add one, the action that adds the first
|
|
10
|
-
* record;
|
|
11
|
-
* - `nothingYet`: a list with no picture of its own, such as invoices, history
|
|
12
|
-
* or a table inside a page: one line;
|
|
13
|
-
* - `noResults`: a search or filter that matches nothing: one line and the way
|
|
14
|
-
* to clear it, with no picture;
|
|
15
|
-
* - `failed`: a read that failed where the content would be: the warning mark
|
|
16
|
-
* and the catalogue's message, with its controls (Retry among them).
|
|
17
|
-
*/
|
|
18
4
|
export type EmptyStateProps = {
|
|
19
5
|
scope?: "page" | "region" | "card";
|
|
20
|
-
} & ({
|
|
6
|
+
} & (({
|
|
21
7
|
kind: "firstUse";
|
|
22
|
-
picture: EmptyArt;
|
|
23
8
|
title: string;
|
|
24
9
|
description: string;
|
|
25
10
|
action?: PageCommand;
|
|
11
|
+
} & ({
|
|
12
|
+
presentation?: "illustrated";
|
|
13
|
+
picture: EmptyArt;
|
|
26
14
|
} | {
|
|
15
|
+
presentation: "plain";
|
|
16
|
+
picture?: never;
|
|
17
|
+
})) | {
|
|
27
18
|
kind: "nothingYet";
|
|
28
19
|
message: string;
|
|
20
|
+
presentation?: "plain" | "illustrated";
|
|
29
21
|
} | {
|
|
30
22
|
kind: "noResults";
|
|
31
23
|
message: string;
|
|
32
24
|
clear: PageCommand;
|
|
25
|
+
presentation?: "plain" | "illustrated";
|
|
33
26
|
} | {
|
|
34
27
|
kind: "failed";
|
|
35
28
|
message: ResolvedMessage;
|
|
29
|
+
presentation?: "plain" | "illustrated";
|
|
36
30
|
});
|
|
37
31
|
export declare function EmptyState(props: EmptyStateProps): import("react").JSX.Element;
|
|
38
32
|
//# sourceMappingURL=empty-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE1E
|
|
1
|
+
{"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,KAAK,WAAW,EAAqB,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;CAAE,GAAG,CACnE,CAAC;IACC,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,CACA;IAAE,YAAY,CAAC,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,GACnD;IAAE,YAAY,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,CAC7C,CAAC,GACF;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,GAAG,aAAa,CAAA;CAAE,GAC/E;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,GAAG,aAAa,CAAC;CACxC,GACD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,eAAe,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,GAAG,aAAa,CAAA;CAAE,CACvF,CAAC;AAEF,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,+BA6ChD"}
|
|
@@ -6,7 +6,7 @@ import { PageCommandButton } from "./page-actions.js";
|
|
|
6
6
|
import { bodyBeyondTitle } from "./product-message.js";
|
|
7
7
|
export function EmptyState(props) {
|
|
8
8
|
const scope = props.scope ?? "region";
|
|
9
|
-
return (_jsxs(Empty, { "data-empty-state": props.kind, scope: scope, children: [_jsxs(EmptyHeader, { children: [props.kind === "firstUse" ? (_jsx(EmptyPicture, { size: scope === "page" ? "page" : "card", src: props.picture })) : null, props.kind === "failed" ? (_jsx(EmptyMedia, { variant: "icon", children: _jsx(AlertTriangleIcon, { "aria-hidden": "true" }) })) : null, props.kind === "firstUse" ? (_jsxs("div", { className: "grid gap-1", children: [_jsx(EmptyTitle, { children: _jsx("h2", { children: props.title }) }), _jsx(EmptyDescription, { children: props.description })] })) : props.kind === "failed" ? (_jsx(FailedRead, { message: props.message })) : (_jsx(EmptyDescription, { children: props.message }))] }), props.kind === "firstUse" && props.action ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.action, variant: "default" }) })) : null, props.kind === "noResults" ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.clear, variant: "outline" }) })) : null, props.kind === "failed" && props.message.actions.length > 0 ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: props.message.actions.map((action) => (_jsx(PageCommandButton, { command: action, variant: "outline" }, action.label))) })) : null] }));
|
|
9
|
+
return (_jsxs(Empty, { "data-empty-state": props.kind, scope: scope, presentation: props.presentation, children: [_jsxs(EmptyHeader, { children: [props.kind === "firstUse" && props.presentation !== "plain" ? (_jsx(EmptyPicture, { size: scope === "page" ? "page" : "card", src: props.picture })) : null, props.kind === "failed" ? (_jsx(EmptyMedia, { variant: "icon", children: _jsx(AlertTriangleIcon, { "aria-hidden": "true" }) })) : null, props.kind === "firstUse" ? (_jsxs("div", { className: "grid gap-1", children: [_jsx(EmptyTitle, { children: _jsx("h2", { children: props.title }) }), _jsx(EmptyDescription, { children: props.description })] })) : props.kind === "failed" ? (_jsx(FailedRead, { message: props.message })) : (_jsx(EmptyDescription, { children: props.message }))] }), props.kind === "firstUse" && props.action ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.action, variant: "default" }) })) : null, props.kind === "noResults" ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: _jsx(PageCommandButton, { command: props.clear, variant: "outline" }) })) : null, props.kind === "failed" && props.message.actions.length > 0 ? (_jsx(EmptyContent, { "data-empty-state-action": true, children: props.message.actions.map((action) => (_jsx(PageCommandButton, { command: action, variant: "outline" }, action.label))) })) : null] }));
|
|
10
10
|
}
|
|
11
11
|
function FailedRead({ message }) {
|
|
12
12
|
const body = bodyBeyondTitle(message);
|