@tensor_1/react 2.13.0 → 2.15.0
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/combobox-model.d.ts +9 -0
- package/dist/combobox-model.js +10 -0
- package/dist/components/AsyncOperationStatus.d.ts +16 -0
- package/dist/components/AsyncOperationStatus.js +24 -0
- package/dist/components/Breadcrumbs.d.ts +18 -0
- package/dist/components/Breadcrumbs.js +14 -0
- package/dist/components/Card.d.ts +11 -2
- package/dist/components/Card.js +16 -1
- package/dist/components/CollapsibleSection.d.ts +11 -0
- package/dist/components/CollapsibleSection.js +17 -0
- package/dist/components/Combobox.d.ts +19 -0
- package/dist/components/Combobox.js +120 -0
- package/dist/components/DetailPage.d.ts +33 -0
- package/dist/components/DetailPage.js +19 -0
- package/dist/components/Dialogs.d.ts +35 -0
- package/dist/components/Dialogs.js +55 -0
- package/dist/components/Modal.d.ts +3 -1
- package/dist/components/Modal.js +6 -4
- package/dist/components/RelatedLinks.d.ts +16 -0
- package/dist/components/RelatedLinks.js +14 -0
- package/dist/components/RelativeTime.d.ts +23 -0
- package/dist/components/RelativeTime.js +40 -0
- package/dist/components/Sidebar.d.ts +7 -2
- package/dist/components/Sidebar.js +27 -9
- package/dist/components/States.d.ts +23 -4
- package/dist/components/States.js +28 -6
- package/dist/components/TableControls.d.ts +77 -0
- package/dist/components/TableControls.js +61 -0
- package/dist/components/ToggleRow.d.ts +14 -0
- package/dist/components/ToggleRow.js +16 -0
- package/dist/index.cjs +1277 -786
- package/dist/index.d.cts +280 -8
- package/dist/index.d.ts +14 -2
- package/dist/index.js +34 -2
- package/dist/relative-time-clock.d.ts +4 -0
- package/dist/relative-time-clock.js +33 -0
- package/dist/relative-time-model.d.ts +9 -0
- package/dist/relative-time-model.js +16 -0
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from "react";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
4
4
|
import { cx } from "../cx.js";
|
|
5
5
|
const ChevronIcon = () => /* @__PURE__ */ jsx("svg", { className: "uix-navgroup__chevron", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M2 4l4 4 4-4" }) });
|
|
6
|
-
function Sidebar({ collapsed, onToggle, brand, toggleIcon, children, className, ...props }) {
|
|
7
|
-
|
|
6
|
+
function Sidebar({ collapsed, nav, onToggle, brand, toggleIcon, children, expandLabel = "Expand sidebar", collapseLabel = "Collapse sidebar", className, ...props }) {
|
|
7
|
+
const isCollapsed = collapsed ?? nav === "rail";
|
|
8
|
+
return /* @__PURE__ */ jsxs("nav", { className: cx("uix-sidebar", className), "data-collapsed": isCollapsed || void 0, "data-nav": nav, ...props, children: [
|
|
8
9
|
(brand != null || onToggle) && /* @__PURE__ */ jsxs("div", { className: "uix-sidebar__head", children: [
|
|
9
10
|
brand && /* @__PURE__ */ jsx("div", { className: "uix-sidebar__brand", children: brand }),
|
|
10
|
-
onToggle && /* @__PURE__ */ jsx("button", { className: "uix-sidebar__toggle", onClick: onToggle, "aria-label":
|
|
11
|
+
onToggle && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-sidebar__toggle", onClick: onToggle, "aria-label": isCollapsed ? expandLabel : collapseLabel, children: toggleIcon ?? /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", strokeWidth: 1.5, "aria-hidden": "true", children: [
|
|
11
12
|
/* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "12", height: "1.5", rx: ".75" }),
|
|
12
13
|
/* @__PURE__ */ jsx("rect", { x: "3", y: "8.25", width: "8", height: "1.5", rx: ".75" }),
|
|
13
14
|
/* @__PURE__ */ jsx("rect", { x: "3", y: "12.5", width: "12", height: "1.5", rx: ".75" })
|
|
@@ -28,6 +29,7 @@ function NavItem({ icon, badge, active, as: Tag = "a", children, className, ...p
|
|
|
28
29
|
return /* @__PURE__ */ jsxs(
|
|
29
30
|
"button",
|
|
30
31
|
{
|
|
32
|
+
type: "button",
|
|
31
33
|
className: cx("uix-navitem", className),
|
|
32
34
|
"aria-current": active ? "page" : void 0,
|
|
33
35
|
...btnProps,
|
|
@@ -53,15 +55,31 @@ function NavItem({ icon, badge, active, as: Tag = "a", children, className, ...p
|
|
|
53
55
|
}
|
|
54
56
|
);
|
|
55
57
|
}
|
|
56
|
-
function NavGroup({ icon, label, children, defaultExpanded = true }) {
|
|
57
|
-
const [
|
|
58
|
+
function NavGroup({ icon, label, children, defaultExpanded = true, expanded: controlledExpanded, onExpandedChange }) {
|
|
59
|
+
const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
|
|
60
|
+
const expanded = controlledExpanded ?? internalExpanded;
|
|
61
|
+
const panelId = useId();
|
|
62
|
+
const triggerRef = useRef(null);
|
|
63
|
+
const panelRef = useRef(null);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
panelRef.current?.toggleAttribute("inert", !expanded);
|
|
66
|
+
if (!expanded && panelRef.current?.contains(document.activeElement)) triggerRef.current?.focus();
|
|
67
|
+
}, [expanded]);
|
|
68
|
+
const setExpanded = (next) => {
|
|
69
|
+
if (!next && panelRef.current?.contains(document.activeElement)) triggerRef.current?.focus();
|
|
70
|
+
if (controlledExpanded == null) setInternalExpanded(next);
|
|
71
|
+
onExpandedChange?.(next);
|
|
72
|
+
};
|
|
58
73
|
return /* @__PURE__ */ jsxs("div", { className: "uix-navgroup", children: [
|
|
59
74
|
/* @__PURE__ */ jsxs(
|
|
60
75
|
"button",
|
|
61
76
|
{
|
|
77
|
+
ref: triggerRef,
|
|
78
|
+
type: "button",
|
|
62
79
|
className: "uix-navitem uix-navgroup__trigger",
|
|
63
80
|
"aria-expanded": expanded,
|
|
64
|
-
|
|
81
|
+
"aria-controls": panelId,
|
|
82
|
+
onClick: () => setExpanded(!expanded),
|
|
65
83
|
children: [
|
|
66
84
|
icon && /* @__PURE__ */ jsx("span", { className: "uix-navitem__icon", "aria-hidden": "true", children: icon }),
|
|
67
85
|
/* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children: label }),
|
|
@@ -69,14 +87,14 @@ function NavGroup({ icon, label, children, defaultExpanded = true }) {
|
|
|
69
87
|
]
|
|
70
88
|
}
|
|
71
89
|
),
|
|
72
|
-
/* @__PURE__ */ jsx("div", { className: "uix-navgroup__panel", children: /* @__PURE__ */ jsx("div", { children }) })
|
|
90
|
+
/* @__PURE__ */ jsx("div", { ref: panelRef, id: panelId, className: "uix-navgroup__panel", "aria-hidden": !expanded, children: /* @__PURE__ */ jsx("div", { children }) })
|
|
73
91
|
] });
|
|
74
92
|
}
|
|
75
93
|
function SubNavItem({ active, as: Tag = "a", children, className, ...props }) {
|
|
76
94
|
const cls = cx("uix-navitem uix-subitem", className);
|
|
77
95
|
if (Tag === "button") {
|
|
78
96
|
const { href: _href, ...btnProps } = props;
|
|
79
|
-
return /* @__PURE__ */ jsx("button", { className: cls, "aria-current": active ? "page" : void 0, ...btnProps, children: /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) });
|
|
97
|
+
return /* @__PURE__ */ jsx("button", { type: "button", className: cls, "aria-current": active ? "page" : void 0, ...btnProps, children: /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) });
|
|
80
98
|
}
|
|
81
99
|
return /* @__PURE__ */ jsx("a", { className: cls, "aria-current": active ? "page" : void 0, ...props, children: /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) });
|
|
82
100
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
+
type StateVariant = 'section' | 'inline' | 'drawer' | 'page' | 'full-page';
|
|
4
5
|
interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
5
6
|
icon?: ReactNode;
|
|
6
7
|
title?: ReactNode;
|
|
@@ -8,9 +9,11 @@ interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
|
|
|
8
9
|
children?: ReactNode;
|
|
9
10
|
/** Primary action (e.g. a Button) shown under the body. */
|
|
10
11
|
action?: ReactNode;
|
|
12
|
+
/** Layout context changes spacing without changing semantics. */
|
|
13
|
+
variant?: StateVariant;
|
|
11
14
|
}
|
|
12
15
|
/** Centered empty state over `.uix-empty`. */
|
|
13
|
-
declare function EmptyState({ icon, title, children, action, className, ...props }: EmptyStateProps): react.JSX.Element;
|
|
16
|
+
declare function EmptyState({ icon, title, children, action, variant, className, ...props }: EmptyStateProps): react.JSX.Element;
|
|
14
17
|
interface ErrorStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
15
18
|
icon?: ReactNode;
|
|
16
19
|
title?: ReactNode;
|
|
@@ -18,9 +21,23 @@ interface ErrorStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
|
|
|
18
21
|
detail?: ReactNode;
|
|
19
22
|
/** Recovery action (e.g. a Retry Button). */
|
|
20
23
|
action?: ReactNode;
|
|
24
|
+
variant?: StateVariant;
|
|
21
25
|
}
|
|
22
26
|
/** Error state over `.uix-empty` with a danger-toned icon; `role="alert"`. */
|
|
23
|
-
declare function ErrorState({ icon, title, detail, action, className, ...props }: ErrorStateProps): react.JSX.Element;
|
|
27
|
+
declare function ErrorState({ icon, title, detail, action, variant, className, ...props }: ErrorStateProps): react.JSX.Element;
|
|
28
|
+
interface AccessStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
29
|
+
icon?: ReactNode;
|
|
30
|
+
title?: ReactNode;
|
|
31
|
+
detail?: ReactNode;
|
|
32
|
+
action?: ReactNode;
|
|
33
|
+
variant?: StateVariant;
|
|
34
|
+
}
|
|
35
|
+
/** Permission-denied state. Copy and recovery controls stay application-owned. */
|
|
36
|
+
declare function ForbiddenState({ icon, title, detail, action, variant, className, ...props }: AccessStateProps): react.JSX.Element;
|
|
37
|
+
/** Not-found state. Copy and navigation remain application-owned. */
|
|
38
|
+
declare function NotFoundState({ icon, title, detail, action, variant, className, ...props }: AccessStateProps): react.JSX.Element;
|
|
39
|
+
/** Empty-result state for an active search or filter, kept distinct for analytics and recovery copy. */
|
|
40
|
+
declare function FilteredEmptyState(props: EmptyStateProps): react.JSX.Element;
|
|
24
41
|
interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {
|
|
25
42
|
variant?: 'block' | 'text' | 'circle';
|
|
26
43
|
width?: number | string;
|
|
@@ -31,8 +48,10 @@ declare function Skeleton({ variant, width, height, className, style, ...props }
|
|
|
31
48
|
interface LoadingStateProps extends HTMLAttributes<HTMLDivElement> {
|
|
32
49
|
/** Number of skeleton rows to render. */
|
|
33
50
|
rows?: number;
|
|
51
|
+
density?: 'compact' | 'comfortable';
|
|
52
|
+
label?: string;
|
|
34
53
|
}
|
|
35
54
|
/** A stack of skeleton rows for list/section loading. `role="status"`. */
|
|
36
|
-
declare function LoadingState({ rows, className, ...props }: LoadingStateProps): react.JSX.Element;
|
|
55
|
+
declare function LoadingState({ rows, density, label, className, ...props }: LoadingStateProps): react.JSX.Element;
|
|
37
56
|
|
|
38
|
-
export { EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, LoadingState, type LoadingStateProps, Skeleton, type SkeletonProps };
|
|
57
|
+
export { type AccessStateProps, EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, FilteredEmptyState, ForbiddenState, LoadingState, type LoadingStateProps, NotFoundState, Skeleton, type SkeletonProps, type StateVariant };
|
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from "../cx.js";
|
|
3
|
-
function EmptyState({ icon, title, children, action, className, ...props }) {
|
|
4
|
-
return /* @__PURE__ */ jsxs("div", { className: cx("uix-empty", className), ...props, children: [
|
|
3
|
+
function EmptyState({ icon, title, children, action, variant = "section", className, ...props }) {
|
|
4
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-empty", `uix-empty--${variant}`, className), ...props, children: [
|
|
5
5
|
icon != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__icon", children: icon }),
|
|
6
6
|
title != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__title", children: title }),
|
|
7
7
|
children,
|
|
8
8
|
action
|
|
9
9
|
] });
|
|
10
10
|
}
|
|
11
|
-
function ErrorState({ icon, title, detail, action, className, ...props }) {
|
|
12
|
-
return /* @__PURE__ */ jsxs("div", { className: cx("uix-empty", "uix-empty--danger", className), role: "alert", ...props, children: [
|
|
11
|
+
function ErrorState({ icon, title, detail, action, variant = "section", className, ...props }) {
|
|
12
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-empty", "uix-empty--danger", `uix-empty--${variant}`, className), role: "alert", ...props, children: [
|
|
13
13
|
icon != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__icon uix-empty__icon--danger", children: icon }),
|
|
14
14
|
title != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__title", children: title }),
|
|
15
15
|
detail != null && /* @__PURE__ */ jsx("p", { children: detail }),
|
|
16
16
|
action
|
|
17
17
|
] });
|
|
18
18
|
}
|
|
19
|
+
function ForbiddenState({ icon, title, detail, action, variant = "section", className, ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-empty", "uix-empty--warning", `uix-empty--${variant}`, className), ...props, children: [
|
|
21
|
+
icon != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__icon uix-empty__icon--warning", children: icon }),
|
|
22
|
+
title != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__title", children: title }),
|
|
23
|
+
detail != null && /* @__PURE__ */ jsx("p", { children: detail }),
|
|
24
|
+
action
|
|
25
|
+
] });
|
|
26
|
+
}
|
|
27
|
+
function NotFoundState({ icon, title, detail, action, variant = "section", className, ...props }) {
|
|
28
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-empty", `uix-empty--${variant}`, className), ...props, children: [
|
|
29
|
+
icon != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__icon", children: icon }),
|
|
30
|
+
title != null && /* @__PURE__ */ jsx("div", { className: "uix-empty__title", children: title }),
|
|
31
|
+
detail != null && /* @__PURE__ */ jsx("p", { children: detail }),
|
|
32
|
+
action
|
|
33
|
+
] });
|
|
34
|
+
}
|
|
35
|
+
function FilteredEmptyState(props) {
|
|
36
|
+
return /* @__PURE__ */ jsx(EmptyState, { "data-filtered": "true", ...props });
|
|
37
|
+
}
|
|
19
38
|
function Skeleton({ variant = "block", width, height, className, style, ...props }) {
|
|
20
39
|
const dims = { width, height, ...style };
|
|
21
40
|
return /* @__PURE__ */ jsx(
|
|
@@ -32,12 +51,15 @@ function Skeleton({ variant = "block", width, height, className, style, ...props
|
|
|
32
51
|
}
|
|
33
52
|
);
|
|
34
53
|
}
|
|
35
|
-
function LoadingState({ rows = 3, className, ...props }) {
|
|
36
|
-
return /* @__PURE__ */ jsx("div", { className: cx("uix-stack", className), role: "status", "aria-busy": "true", ...props, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: `${92 - i % 3 * 14}%` }, i)) });
|
|
54
|
+
function LoadingState({ rows = 3, density = "comfortable", label, className, ...props }) {
|
|
55
|
+
return /* @__PURE__ */ jsx("div", { className: cx("uix-stack", density === "compact" && "uix-stack--compact", className), role: "status", "aria-busy": "true", "aria-label": label, ...props, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: `${92 - i % 3 * 14}%` }, i)) });
|
|
37
56
|
}
|
|
38
57
|
export {
|
|
39
58
|
EmptyState,
|
|
40
59
|
ErrorState,
|
|
60
|
+
FilteredEmptyState,
|
|
61
|
+
ForbiddenState,
|
|
41
62
|
LoadingState,
|
|
63
|
+
NotFoundState,
|
|
42
64
|
Skeleton
|
|
43
65
|
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ViewMenuColumn {
|
|
5
|
+
id: string;
|
|
6
|
+
label: ReactNode;
|
|
7
|
+
visible: boolean;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface ViewMenuProps {
|
|
11
|
+
density: string;
|
|
12
|
+
densityLabel: ReactNode;
|
|
13
|
+
densityOptions: readonly {
|
|
14
|
+
value: string;
|
|
15
|
+
label: ReactNode;
|
|
16
|
+
}[];
|
|
17
|
+
onDensityChange: (value: string) => void;
|
|
18
|
+
zebra?: {
|
|
19
|
+
checked: boolean;
|
|
20
|
+
label: ReactNode;
|
|
21
|
+
onChange: (checked: boolean) => void;
|
|
22
|
+
};
|
|
23
|
+
freeze?: {
|
|
24
|
+
checked: boolean;
|
|
25
|
+
label: ReactNode;
|
|
26
|
+
onChange: (checked: boolean) => void;
|
|
27
|
+
};
|
|
28
|
+
columns?: readonly ViewMenuColumn[];
|
|
29
|
+
columnsLabel?: ReactNode;
|
|
30
|
+
onColumnVisibilityChange?: (id: string, visible: boolean) => void;
|
|
31
|
+
}
|
|
32
|
+
/** Controlled table presentation menu; wrap it with Popover when trigger behavior is needed. */
|
|
33
|
+
declare function ViewMenu({ density, densityLabel, densityOptions, onDensityChange, zebra, freeze, columns, columnsLabel, onColumnVisibilityChange }: ViewMenuProps): react.JSX.Element;
|
|
34
|
+
interface FilterOption {
|
|
35
|
+
value: string;
|
|
36
|
+
label: string;
|
|
37
|
+
}
|
|
38
|
+
interface FilterPopoverProps {
|
|
39
|
+
label: ReactNode;
|
|
40
|
+
type?: 'text' | 'number' | 'date' | 'select' | 'enum' | 'boolean';
|
|
41
|
+
value: string;
|
|
42
|
+
onValueChange: (value: string) => void;
|
|
43
|
+
options?: readonly FilterOption[];
|
|
44
|
+
applyLabel: ReactNode;
|
|
45
|
+
clearLabel: ReactNode;
|
|
46
|
+
onApply: () => void;
|
|
47
|
+
onClear: () => void;
|
|
48
|
+
placeholder?: string;
|
|
49
|
+
}
|
|
50
|
+
/** Controlled filter editor content; applications own query serialization and the popover trigger. */
|
|
51
|
+
declare function FilterPopover({ label, type, value, onValueChange, options, applyLabel, clearLabel, onApply, onClear, placeholder }: FilterPopoverProps): react.JSX.Element;
|
|
52
|
+
interface SavedViewItem {
|
|
53
|
+
id: string;
|
|
54
|
+
label: ReactNode;
|
|
55
|
+
active?: boolean;
|
|
56
|
+
pinned?: boolean;
|
|
57
|
+
}
|
|
58
|
+
interface SavedViewMenuBaseProps {
|
|
59
|
+
items: readonly SavedViewItem[];
|
|
60
|
+
onSelect: (id: string) => void;
|
|
61
|
+
emptyLabel?: ReactNode;
|
|
62
|
+
actions?: (item: SavedViewItem) => ReactNode;
|
|
63
|
+
footer?: ReactNode;
|
|
64
|
+
}
|
|
65
|
+
type SavedViewMenuProps = SavedViewMenuBaseProps & ({
|
|
66
|
+
onPinChange: (id: string, pinned: boolean) => void;
|
|
67
|
+
pinLabel: string;
|
|
68
|
+
unpinLabel: string;
|
|
69
|
+
} | {
|
|
70
|
+
onPinChange?: undefined;
|
|
71
|
+
pinLabel?: never;
|
|
72
|
+
unpinLabel?: never;
|
|
73
|
+
});
|
|
74
|
+
/** Generic saved-view selector. Persistence, ownership and authorization remain application concerns. */
|
|
75
|
+
declare function SavedViewMenu({ items, onSelect, onPinChange, pinLabel, unpinLabel, emptyLabel, actions, footer }: SavedViewMenuProps): react.JSX.Element;
|
|
76
|
+
|
|
77
|
+
export { type FilterOption, FilterPopover, type FilterPopoverProps, type SavedViewItem, SavedViewMenu, type SavedViewMenuProps, ViewMenu, type ViewMenuColumn, type ViewMenuProps };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId } from "react";
|
|
4
|
+
import { Button } from "./Button.js";
|
|
5
|
+
import { Checkbox } from "./Checkbox.js";
|
|
6
|
+
import { Input } from "./Input.js";
|
|
7
|
+
import { Segmented, SegmentedOption } from "./Segmented.js";
|
|
8
|
+
import { Switch } from "./Switch.js";
|
|
9
|
+
function ViewMenu({ density, densityLabel, densityOptions, onDensityChange, zebra, freeze, columns, columnsLabel, onColumnVisibilityChange }) {
|
|
10
|
+
const densityLabelId = useId();
|
|
11
|
+
const zebraLabelId = useId();
|
|
12
|
+
const freezeLabelId = useId();
|
|
13
|
+
return /* @__PURE__ */ jsxs("div", { className: "uix-view-menu", children: [
|
|
14
|
+
/* @__PURE__ */ jsxs("div", { className: "uix-view-menu__group", children: [
|
|
15
|
+
/* @__PURE__ */ jsx("div", { id: densityLabelId, className: "uix-view-menu__label", children: densityLabel }),
|
|
16
|
+
/* @__PURE__ */ jsx(Segmented, { value: density, onChange: onDensityChange, "aria-labelledby": densityLabelId, children: densityOptions.map((option) => /* @__PURE__ */ jsx(SegmentedOption, { value: option.value, children: option.label }, option.value)) })
|
|
17
|
+
] }),
|
|
18
|
+
(zebra || freeze) && /* @__PURE__ */ jsxs("div", { className: "uix-view-menu__group", children: [
|
|
19
|
+
zebra && /* @__PURE__ */ jsxs("div", { className: "uix-view-menu__row", children: [
|
|
20
|
+
/* @__PURE__ */ jsx("span", { id: zebraLabelId, children: zebra.label }),
|
|
21
|
+
/* @__PURE__ */ jsx(Switch, { checked: zebra.checked, "aria-labelledby": zebraLabelId, onChange: (event) => zebra.onChange(event.currentTarget.checked) })
|
|
22
|
+
] }),
|
|
23
|
+
freeze && /* @__PURE__ */ jsxs("div", { className: "uix-view-menu__row", children: [
|
|
24
|
+
/* @__PURE__ */ jsx("span", { id: freezeLabelId, children: freeze.label }),
|
|
25
|
+
/* @__PURE__ */ jsx(Switch, { checked: freeze.checked, "aria-labelledby": freezeLabelId, onChange: (event) => freeze.onChange(event.currentTarget.checked) })
|
|
26
|
+
] })
|
|
27
|
+
] }),
|
|
28
|
+
columns && columns.length > 0 && /* @__PURE__ */ jsxs("div", { className: "uix-view-menu__group", children: [
|
|
29
|
+
columnsLabel != null && /* @__PURE__ */ jsx("div", { className: "uix-view-menu__label", children: columnsLabel }),
|
|
30
|
+
/* @__PURE__ */ jsx("div", { className: "uix-view-menu__cols", children: columns.map((column) => /* @__PURE__ */ jsx(Checkbox, { label: column.label, checked: column.visible, disabled: column.disabled, onChange: (event) => onColumnVisibilityChange?.(column.id, event.currentTarget.checked) }, column.id)) })
|
|
31
|
+
] })
|
|
32
|
+
] });
|
|
33
|
+
}
|
|
34
|
+
function FilterPopover({ label, type = "text", value, onValueChange, options, applyLabel, clearLabel, onApply, onClear, placeholder }) {
|
|
35
|
+
return /* @__PURE__ */ jsxs("div", { className: "uix-filter-popover", children: [
|
|
36
|
+
/* @__PURE__ */ jsxs("label", { className: "uix-label", children: [
|
|
37
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
38
|
+
type === "select" || type === "enum" || type === "boolean" ? /* @__PURE__ */ jsx("select", { className: "uix-select", value, onChange: (event) => onValueChange(event.currentTarget.value), children: options?.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value)) }) : /* @__PURE__ */ jsx(Input, { type, value, placeholder, onChange: (event) => onValueChange(event.currentTarget.value) })
|
|
39
|
+
] }),
|
|
40
|
+
/* @__PURE__ */ jsxs("div", { className: "uix-filter-popover__actions", children: [
|
|
41
|
+
/* @__PURE__ */ jsx(Button, { type: "button", onClick: onClear, children: clearLabel }),
|
|
42
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "primary", onClick: onApply, children: applyLabel })
|
|
43
|
+
] })
|
|
44
|
+
] });
|
|
45
|
+
}
|
|
46
|
+
function SavedViewMenu({ items, onSelect, onPinChange, pinLabel, unpinLabel, emptyLabel, actions, footer }) {
|
|
47
|
+
return /* @__PURE__ */ jsxs("ul", { className: "uix-menu uix-saved-views", children: [
|
|
48
|
+
items.length === 0 && emptyLabel != null && /* @__PURE__ */ jsx("li", { className: "uix-menu__label", children: emptyLabel }),
|
|
49
|
+
items.map((item) => /* @__PURE__ */ jsxs("li", { className: "uix-saved-views__row", children: [
|
|
50
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "uix-menu__item", "data-active": item.active || void 0, onClick: () => onSelect(item.id), children: item.label }),
|
|
51
|
+
onPinChange && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-saved-views__pin", "aria-label": item.pinned ? unpinLabel : pinLabel, "data-on": item.pinned || void 0, onClick: () => onPinChange(item.id, !item.pinned), children: "\u2605" }),
|
|
52
|
+
actions?.(item)
|
|
53
|
+
] }, item.id)),
|
|
54
|
+
footer != null && /* @__PURE__ */ jsx("li", { className: "uix-saved-views__footer", children: footer })
|
|
55
|
+
] });
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
FilterPopover,
|
|
59
|
+
SavedViewMenu,
|
|
60
|
+
ViewMenu
|
|
61
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ToggleRowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
description?: ReactNode;
|
|
7
|
+
checked: boolean;
|
|
8
|
+
onCheckedChange: (checked: boolean) => void;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
accessibleLabel: string;
|
|
11
|
+
}
|
|
12
|
+
declare function ToggleRow({ label, description, checked, onCheckedChange, disabled, accessibleLabel, className, ...props }: ToggleRowProps): react.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { ToggleRow, type ToggleRowProps };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cx } from "../cx.js";
|
|
4
|
+
import { Switch } from "./Switch.js";
|
|
5
|
+
function ToggleRow({ label, description, checked, onCheckedChange, disabled, accessibleLabel, className, ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("uix-toggle-row", className), ...props, children: [
|
|
7
|
+
/* @__PURE__ */ jsxs("div", { className: "uix-toggle-row__copy", children: [
|
|
8
|
+
/* @__PURE__ */ jsx("div", { className: "uix-toggle-row__label", children: label }),
|
|
9
|
+
description != null && /* @__PURE__ */ jsx("div", { className: "uix-toggle-row__description", children: description })
|
|
10
|
+
] }),
|
|
11
|
+
/* @__PURE__ */ jsx(Switch, { checked, disabled, "aria-label": accessibleLabel, onChange: (event) => onCheckedChange(event.currentTarget.checked) })
|
|
12
|
+
] });
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
ToggleRow
|
|
16
|
+
};
|