@tensor_1/react 2.47.0 → 2.49.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/README.md +540 -2
- package/dist/{SchedulingCalendar-B6TakO2h.d.ts → SchedulingCalendar-WWyFL3Eo.d.ts} +51 -2
- package/dist/announce.d.ts +10 -0
- package/dist/announce.js +30 -0
- package/dist/chart-analytic.cjs +33 -25
- package/dist/chart-preset.cjs +23 -15
- package/dist/chart.cjs +23 -15
- package/dist/combobox-model.d.ts +10 -1
- package/dist/combobox-model.js +15 -0
- package/dist/command-palette-model.d.ts +44 -0
- package/dist/command-palette-model.js +36 -0
- package/dist/components/AccountMenu.d.ts +44 -0
- package/dist/components/AccountMenu.js +43 -0
- package/dist/components/AppShell.d.ts +45 -2
- package/dist/components/AppShell.js +116 -5
- package/dist/components/AuditLog.d.ts +128 -0
- package/dist/components/AuditLog.js +196 -0
- package/dist/components/BrandProfiles.js +4 -3
- package/dist/components/Breadcrumbs.d.ts +9 -2
- package/dist/components/Breadcrumbs.js +3 -2
- package/dist/components/Button.d.ts +12 -5
- package/dist/components/Button.js +7 -3
- package/dist/components/Card.d.ts +18 -1
- package/dist/components/Card.js +5 -1
- package/dist/components/ChangeHighlight.d.ts +30 -0
- package/dist/components/ChangeHighlight.js +21 -0
- package/dist/components/ChartCore.js +2 -1
- package/dist/components/Checkbox.d.ts +27 -1
- package/dist/components/Checkbox.js +31 -2
- package/dist/components/Chip.d.ts +7 -3
- package/dist/components/Chip.js +2 -2
- package/dist/components/CodeDisplay.d.ts +65 -0
- package/dist/components/CodeDisplay.js +124 -0
- package/dist/components/Combobox.d.ts +27 -6
- package/dist/components/Combobox.js +195 -58
- package/dist/components/CommandPalette.d.ts +36 -1
- package/dist/components/CommandPalette.js +254 -2
- package/dist/components/ContactCard.d.ts +66 -0
- package/dist/components/ContactCard.js +74 -0
- package/dist/components/Count.d.ts +24 -0
- package/dist/components/Count.js +32 -0
- package/dist/components/DashboardCanvas.js +14 -0
- package/dist/components/DataWorkspace.d.ts +167 -0
- package/dist/components/DataWorkspace.js +380 -0
- package/dist/components/DateFieldParts.d.ts +2 -1
- package/dist/components/DateFieldParts.js +7 -0
- package/dist/components/DatePicker.d.ts +9 -2
- package/dist/components/DatePicker.js +67 -28
- package/dist/components/DateRangePicker.d.ts +12 -2
- package/dist/components/DateRangePicker.js +13 -12
- package/dist/components/DetailPage.d.ts +7 -1
- package/dist/components/DetailPage.js +2 -1
- package/dist/components/Dialogs.d.ts +71 -10
- package/dist/components/Dialogs.js +130 -30
- package/dist/components/DiffViewer.d.ts +23 -3
- package/dist/components/DiffViewer.js +26 -12
- package/dist/components/DiscardPrompt.js +16 -0
- package/dist/components/DisplayPreferences.d.ts +83 -0
- package/dist/components/DisplayPreferences.js +185 -0
- package/dist/components/EditorialHome.d.ts +23 -3
- package/dist/components/EditorialHome.js +16 -11
- package/dist/components/EntityPicker.d.ts +20 -3
- package/dist/components/EntityPicker.js +32 -13
- package/dist/components/FilterEditor.d.ts +18 -4
- package/dist/components/FilterEditor.js +141 -19
- package/dist/components/FocusOnMount.d.ts +282 -0
- package/dist/components/FocusOnMount.js +12 -0
- package/dist/components/InfoTip.js +11 -12
- package/dist/components/InlineEdit.d.ts +87 -20
- package/dist/components/InlineEdit.js +197 -54
- package/dist/components/Input.d.ts +12 -2
- package/dist/components/Input.js +5 -3
- package/dist/components/Kanban.d.ts +14 -3
- package/dist/components/Kanban.js +9 -4
- package/dist/components/Kbd.d.ts +6 -1
- package/dist/components/Kbd.js +6 -6
- package/dist/components/Lightbox.d.ts +41 -5
- package/dist/components/Lightbox.js +95 -9
- package/dist/components/MatchReview.d.ts +40 -1
- package/dist/components/MatchReview.js +130 -4
- package/dist/components/MetricInput.js +3 -2
- package/dist/components/Modal.d.ts +2 -1
- package/dist/components/Modal.js +13 -4
- package/dist/components/MotionList.d.ts +303 -0
- package/dist/components/MotionList.js +175 -0
- package/dist/components/NavFavourites.d.ts +5 -0
- package/dist/components/NavFavourites.js +7 -7
- package/dist/components/OtpInput.d.ts +33 -0
- package/dist/components/OtpInput.js +123 -0
- package/dist/components/PageHeader.d.ts +7 -1
- package/dist/components/PageHeader.js +2 -2
- package/dist/components/Pagination.js +6 -5
- package/dist/components/PasswordInput.d.ts +34 -0
- package/dist/components/PasswordInput.js +101 -0
- package/dist/components/Peek.js +3 -3
- package/dist/components/Popover.js +11 -0
- package/dist/components/PrintLayout.d.ts +63 -0
- package/dist/components/PrintLayout.js +114 -0
- package/dist/components/QrCode.d.ts +47 -0
- package/dist/components/QrCode.js +55 -0
- package/dist/components/QrScanner.d.ts +95 -0
- package/dist/components/QrScanner.js +266 -0
- package/dist/components/RelationshipGraph.d.ts +32 -1
- package/dist/components/RelationshipGraph.js +22 -6
- package/dist/components/RelationshipGraphLayered.d.ts +1 -1
- package/dist/components/RelationshipGraphLayered.js +268 -118
- package/dist/components/RelationshipGraphList.js +33 -6
- package/dist/components/RuleBuilder.js +39 -7
- package/dist/components/SchedulingAgenda.d.ts +3 -1
- package/dist/components/SchedulingCalendar.d.ts +3 -1
- package/dist/components/SchedulingCalendar.js +43 -4
- package/dist/components/SchedulingResourceDay.d.ts +57 -0
- package/dist/components/SchedulingResourceDay.js +287 -0
- package/dist/components/SchedulingTimeGrid.d.ts +3 -1
- package/dist/components/SchedulingTimeline.d.ts +3 -1
- package/dist/components/SearchSuggest.d.ts +23 -3
- package/dist/components/SearchSuggest.js +56 -18
- package/dist/components/Segmented.d.ts +39 -4
- package/dist/components/Segmented.js +39 -5
- package/dist/components/Select.d.ts +3 -2
- package/dist/components/Select.js +7 -1
- package/dist/components/ShortcutHint.d.ts +11 -10
- package/dist/components/ShortcutHint.js +44 -38
- package/dist/components/Sidebar.d.ts +36 -4
- package/dist/components/Sidebar.js +37 -12
- package/dist/components/SortableList.d.ts +45 -0
- package/dist/components/SortableList.js +147 -0
- package/dist/components/Stat.d.ts +28 -3
- package/dist/components/Stat.js +13 -3
- package/dist/components/States.d.ts +33 -1
- package/dist/components/States.js +43 -1
- package/dist/components/StatusPill.d.ts +14 -3
- package/dist/components/StatusPill.js +11 -3
- package/dist/components/Steps.js +2 -1
- package/dist/components/Table.d.ts +9 -2
- package/dist/components/Table.js +4 -2
- package/dist/components/TableControls.js +18 -58
- package/dist/components/TableOverflowProbe.d.ts +12 -0
- package/dist/components/TableOverflowProbe.js +27 -0
- package/dist/components/Tabs.d.ts +2 -1
- package/dist/components/Tabs.js +10 -2
- package/dist/components/TagInput.d.ts +67 -0
- package/dist/components/TagInput.js +342 -0
- package/dist/components/Textarea.d.ts +5 -0
- package/dist/components/Textarea.js +2 -2
- package/dist/components/TimePicker.d.ts +80 -0
- package/dist/components/TimePicker.js +347 -0
- package/dist/components/Toast.d.ts +1 -1
- package/dist/components/Toast.js +109 -4
- package/dist/components/Tooltip.d.ts +8 -4
- package/dist/components/Tooltip.js +86 -28
- package/dist/components/Tree.d.ts +8 -0
- package/dist/components/Tree.js +11 -5
- package/dist/display-preferences-model.d.ts +53 -0
- package/dist/display-preferences-model.js +64 -0
- package/dist/emoji.cjs +143 -49
- package/dist/filter-model.d.ts +59 -3
- package/dist/filter-model.js +67 -2
- package/dist/hooks/useAnchoredPosition.js +14 -2
- package/dist/hooks/useChangeHighlight.d.ts +33 -0
- package/dist/hooks/useChangeHighlight.js +44 -0
- package/dist/hooks/useDeferredReorder.d.ts +32 -0
- package/dist/hooks/useDeferredReorder.js +47 -0
- package/dist/hooks/useDialog.d.ts +5 -0
- package/dist/hooks/useDialog.js +17 -3
- package/dist/hooks/useKeyboardGrab.d.ts +58 -0
- package/dist/hooks/useKeyboardGrab.js +118 -0
- package/dist/hooks/useOptimisticValue.d.ts +51 -0
- package/dist/hooks/useOptimisticValue.js +61 -0
- package/dist/hooks/useReducedMotion.d.ts +4 -1
- package/dist/hooks/useReducedMotion.js +7 -1
- package/dist/hooks/useResolvedFilterLabels.d.ts +15 -0
- package/dist/hooks/useResolvedFilterLabels.js +34 -0
- package/dist/hooks/useSlidingIndicator.d.ts +18 -0
- package/dist/hooks/useSlidingIndicator.js +80 -0
- package/dist/hooks/useVirtualRows.d.ts +21 -2
- package/dist/hooks/useVirtualRows.js +30 -3
- package/dist/icons/Icon.d.ts +1 -1
- package/dist/index.cjs +19687 -13423
- package/dist/index.d.cts +3419 -651
- package/dist/index.d.ts +48 -18
- package/dist/index.js +153 -9
- package/dist/labels-context.d.ts +93 -3
- package/dist/motion.d.ts +11 -0
- package/dist/motion.js +35 -0
- package/dist/overlay-stack.d.ts +6 -0
- package/dist/overlay-stack.js +13 -0
- package/dist/qr-model.d.ts +65 -0
- package/dist/qr-model.js +323 -0
- package/dist/relationship-graph-model.d.ts +92 -3
- package/dist/relationship-graph-model.js +134 -15
- package/dist/reorder.d.ts +30 -0
- package/dist/reorder.js +74 -0
- package/dist/rich-text.cjs +46 -4
- package/dist/scheduling-resource-model.d.ts +76 -0
- package/dist/scheduling-resource-model.js +74 -0
- package/dist/search-suggest-model.js +3 -1
- package/dist/shell-context.d.ts +11 -0
- package/dist/shell-context.js +7 -0
- package/dist/time-field-model.d.ts +46 -0
- package/dist/time-field-model.js +152 -0
- package/dist/toast-store.d.ts +22 -3
- package/dist/toast-store.js +26 -9
- package/package.json +2 -1
|
@@ -1,24 +1,45 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useId, useRef, useState } from "react";
|
|
3
|
+
import { forwardRef, useEffect, useId, useRef, useState } from "react";
|
|
4
4
|
import { cx } from "../cx.js";
|
|
5
5
|
import { useUixLabels } from "../labels-context.js";
|
|
6
|
+
import { SearchIcon } from "../icons/components.js";
|
|
7
|
+
import { useInShellDrawer } from "../shell-context.js";
|
|
8
|
+
import { KbdCombo, ariaKeyShortcuts, useKbdPlatform } from "./Kbd.js";
|
|
6
9
|
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" }) });
|
|
7
|
-
function Sidebar({ collapsed, nav, onToggle, brand, toggleIcon, children, expandLabel: expandLabelProp, collapseLabel: collapseLabelProp, className, ...props }) {
|
|
10
|
+
function Sidebar({ collapsed, nav, onToggle, brand, toggleIcon, actions, search, footer, children, expandLabel: expandLabelProp, collapseLabel: collapseLabelProp, className, ...props }) {
|
|
8
11
|
const uixLabels = useUixLabels();
|
|
9
12
|
const expandLabel = expandLabelProp ?? uixLabels.sidebar?.expand ?? "Expand sidebar";
|
|
10
13
|
const collapseLabel = collapseLabelProp ?? uixLabels.sidebar?.collapse ?? "Collapse sidebar";
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
const inDrawer = useInShellDrawer();
|
|
15
|
+
const isCollapsed = !inDrawer && (collapsed ?? nav === "rail");
|
|
16
|
+
const platform = useKbdPlatform();
|
|
17
|
+
return /* @__PURE__ */ jsxs("nav", { className: cx("uix-sidebar", className), "data-collapsed": isCollapsed || void 0, "data-nav": inDrawer ? void 0 : nav, ...props, children: [
|
|
18
|
+
(brand != null || onToggle || actions != null) && /* @__PURE__ */ jsxs("div", { className: "uix-sidebar__head", children: [
|
|
14
19
|
brand && /* @__PURE__ */ jsx("div", { className: "uix-sidebar__brand", children: brand }),
|
|
20
|
+
actions != null && /* @__PURE__ */ jsx("div", { className: "uix-sidebar__actions", children: actions }),
|
|
15
21
|
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: [
|
|
16
22
|
/* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "12", height: "1.5", rx: ".75" }),
|
|
17
23
|
/* @__PURE__ */ jsx("rect", { x: "3", y: "8.25", width: "8", height: "1.5", rx: ".75" }),
|
|
18
24
|
/* @__PURE__ */ jsx("rect", { x: "3", y: "12.5", width: "12", height: "1.5", rx: ".75" })
|
|
19
25
|
] }) })
|
|
20
26
|
] }),
|
|
21
|
-
|
|
27
|
+
search && /* @__PURE__ */ jsxs(
|
|
28
|
+
"button",
|
|
29
|
+
{
|
|
30
|
+
type: "button",
|
|
31
|
+
className: "uix-sidebar__search",
|
|
32
|
+
onClick: search.onActivate,
|
|
33
|
+
"aria-keyshortcuts": search.shortcut ? ariaKeyShortcuts(search.shortcut, platform) : void 0,
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ jsx(SearchIcon, { className: "uix-sidebar__search-icon" }),
|
|
36
|
+
/* @__PURE__ */ jsx("span", { className: "uix-sidebar__search-label", children: search.label }),
|
|
37
|
+
search.shortcut && /* @__PURE__ */ jsx(KbdCombo, { className: "uix-sidebar__search-keys", keys: [...search.shortcut], platform, "aria-hidden": "true" })
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
),
|
|
41
|
+
children,
|
|
42
|
+
footer != null && /* @__PURE__ */ jsx("div", { className: "uix-sidebar__foot", children: footer })
|
|
22
43
|
] });
|
|
23
44
|
}
|
|
24
45
|
function SidebarSection({ label, children }) {
|
|
@@ -27,7 +48,7 @@ function SidebarSection({ label, children }) {
|
|
|
27
48
|
children
|
|
28
49
|
] });
|
|
29
50
|
}
|
|
30
|
-
|
|
51
|
+
const NavItem = forwardRef(function NavItem2({ icon, badge, active, as: Tag = "a", description, children, className, ...props }, ref) {
|
|
31
52
|
const text = description == null ? /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) : /* @__PURE__ */ jsxs("span", { className: "uix-navitem__text", children: [
|
|
32
53
|
/* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }),
|
|
33
54
|
/* @__PURE__ */ jsx("span", { className: "uix-navitem__desc", children: description })
|
|
@@ -38,6 +59,7 @@ function NavItem({ icon, badge, active, as: Tag = "a", description, children, cl
|
|
|
38
59
|
return /* @__PURE__ */ jsxs(
|
|
39
60
|
"button",
|
|
40
61
|
{
|
|
62
|
+
ref,
|
|
41
63
|
type: "button",
|
|
42
64
|
className: cx("uix-navitem", className),
|
|
43
65
|
"aria-current": active ? "page" : void 0,
|
|
@@ -54,6 +76,7 @@ function NavItem({ icon, badge, active, as: Tag = "a", description, children, cl
|
|
|
54
76
|
return /* @__PURE__ */ jsxs(
|
|
55
77
|
"a",
|
|
56
78
|
{
|
|
79
|
+
ref,
|
|
57
80
|
className: cx("uix-navitem", className),
|
|
58
81
|
"aria-current": active ? "page" : void 0,
|
|
59
82
|
"data-multiline": multiline,
|
|
@@ -65,7 +88,8 @@ function NavItem({ icon, badge, active, as: Tag = "a", description, children, cl
|
|
|
65
88
|
]
|
|
66
89
|
}
|
|
67
90
|
);
|
|
68
|
-
}
|
|
91
|
+
});
|
|
92
|
+
NavItem.displayName = "NavItem";
|
|
69
93
|
function NavGroup({ icon, label, children, defaultExpanded = true, expanded: controlledExpanded, onExpandedChange }) {
|
|
70
94
|
const [internalExpanded, setInternalExpanded] = useState(defaultExpanded);
|
|
71
95
|
const expanded = controlledExpanded ?? internalExpanded;
|
|
@@ -101,14 +125,15 @@ function NavGroup({ icon, label, children, defaultExpanded = true, expanded: con
|
|
|
101
125
|
/* @__PURE__ */ jsx("div", { ref: panelRef, id: panelId, className: "uix-navgroup__panel", "aria-hidden": !expanded, children: /* @__PURE__ */ jsx("div", { children }) })
|
|
102
126
|
] });
|
|
103
127
|
}
|
|
104
|
-
|
|
128
|
+
const SubNavItem = forwardRef(function SubNavItem2({ active, as: Tag = "a", children, className, ...props }, ref) {
|
|
105
129
|
const cls = cx("uix-navitem uix-subitem", className);
|
|
106
130
|
if (Tag === "button") {
|
|
107
131
|
const { href: _href, ...btnProps } = props;
|
|
108
|
-
return /* @__PURE__ */ jsx("button", { type: "button", className: cls, "aria-current": active ? "page" : void 0, ...btnProps, children: /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) });
|
|
132
|
+
return /* @__PURE__ */ jsx("button", { ref, type: "button", className: cls, "aria-current": active ? "page" : void 0, ...btnProps, children: /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) });
|
|
109
133
|
}
|
|
110
|
-
return /* @__PURE__ */ jsx("a", { className: cls, "aria-current": active ? "page" : void 0, ...props, children: /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) });
|
|
111
|
-
}
|
|
134
|
+
return /* @__PURE__ */ jsx("a", { ref, className: cls, "aria-current": active ? "page" : void 0, ...props, children: /* @__PURE__ */ jsx("span", { className: "uix-navitem__label", children }) });
|
|
135
|
+
});
|
|
136
|
+
SubNavItem.displayName = "SubNavItem";
|
|
112
137
|
export {
|
|
113
138
|
NavGroup,
|
|
114
139
|
NavItem,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/** Every word `SortableList` renders or announces. `{label}` is the row's name. */
|
|
5
|
+
interface SortableListLabels {
|
|
6
|
+
/** The drag grip's name. */
|
|
7
|
+
grip: string;
|
|
8
|
+
moveUp: string;
|
|
9
|
+
moveDown: string;
|
|
10
|
+
/** Polite announcement after a move: `{label}`, `{position}`, `{count}`. */
|
|
11
|
+
moved: string;
|
|
12
|
+
}
|
|
13
|
+
declare const DEFAULT_SORTABLE_LIST_LABELS: SortableListLabels;
|
|
14
|
+
/** What `renderItem` receives besides the item. */
|
|
15
|
+
interface SortableListItemContext {
|
|
16
|
+
index: number;
|
|
17
|
+
count: number;
|
|
18
|
+
/** This row is being dragged. */
|
|
19
|
+
dragging: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface SortableListProps<T> extends Omit<HTMLAttributes<HTMLUListElement>, 'children' | 'onChange'> {
|
|
22
|
+
items: readonly T[];
|
|
23
|
+
getId: (item: T) => string;
|
|
24
|
+
/** The row's name in the grip, the move buttons and the announcement. Default: its id. */
|
|
25
|
+
getLabel?: (item: T) => string;
|
|
26
|
+
renderItem: (item: T, context: SortableListItemContext) => ReactNode;
|
|
27
|
+
/** Called with the full new order of ids after each keyboard move, and once when a drag ends. */
|
|
28
|
+
onReorder: (orderedIds: string[]) => void;
|
|
29
|
+
/** Rows show no grip and no move buttons. */
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
/** Each word defaults to `UixLabelsProvider` `sortableList`, then to English. */
|
|
32
|
+
labels?: Partial<SortableListLabels>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A list the person reorders (HAR-1375; MOTUS C-16 photo order, TENSOR preset and start-page
|
|
36
|
+
* order): media, priorities, steps. Each row has a grip to drag with a pointer, and Move up /
|
|
37
|
+
* Move down buttons that are always there (a drag is never the only way). With focus anywhere
|
|
38
|
+
* in a row, Alt+↑ / Alt+↓ move it; a focused grip moves with ↑ / ↓ alone. Focus stays with the
|
|
39
|
+
* moved row, and a polite status says where it went. Keyboard moves are instant; a drag lifts
|
|
40
|
+
* the row (drag.css), places it under the pointer frame by frame, and it settles when dropped. Shares its order model with `ViewMenu`,
|
|
41
|
+
* `SavedViewMenu` and `NavFavourites`.
|
|
42
|
+
*/
|
|
43
|
+
declare function SortableList<T>({ items, getId, getLabel, renderItem, onReorder, disabled, labels: labelOverrides, className, ...props }: SortableListProps<T>): react.JSX.Element;
|
|
44
|
+
|
|
45
|
+
export { DEFAULT_SORTABLE_LIST_LABELS, SortableList, type SortableListItemContext, type SortableListLabels, type SortableListProps };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { cx } from "../cx.js";
|
|
5
|
+
import { fillLabel } from "../fill-label.js";
|
|
6
|
+
import { useUixLabels } from "../labels-context.js";
|
|
7
|
+
import { placeId, sameOrder, useRowDrag } from "../reorder.js";
|
|
8
|
+
import { EditorIcon } from "./EditorIcons.js";
|
|
9
|
+
import { settleDrop } from "../hooks/useKeyboardGrab.js";
|
|
10
|
+
const DEFAULT_SORTABLE_LIST_LABELS = {
|
|
11
|
+
grip: "Drag to reorder: {label}",
|
|
12
|
+
moveUp: "Move {label} up",
|
|
13
|
+
moveDown: "Move {label} down",
|
|
14
|
+
moved: "{label} moved to position {position} of {count}"
|
|
15
|
+
};
|
|
16
|
+
const ArrowIcon = ({ dir }) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx("path", { d: dir === "up" ? "m18 15-6-6-6 6" : "m6 9 6 6 6-6" }) });
|
|
17
|
+
function SortableList({
|
|
18
|
+
items,
|
|
19
|
+
getId,
|
|
20
|
+
getLabel,
|
|
21
|
+
renderItem,
|
|
22
|
+
onReorder,
|
|
23
|
+
disabled = false,
|
|
24
|
+
labels: labelOverrides,
|
|
25
|
+
className,
|
|
26
|
+
...props
|
|
27
|
+
}) {
|
|
28
|
+
const labels = { ...DEFAULT_SORTABLE_LIST_LABELS, ...useUixLabels().sortableList, ...labelOverrides };
|
|
29
|
+
const ids = items.map(getId);
|
|
30
|
+
const orderKey = ids.join("\0");
|
|
31
|
+
const [draft, setDraft] = useState(null);
|
|
32
|
+
useEffect(() => setDraft(null), [orderKey]);
|
|
33
|
+
const order = draft && sameOrder([...draft].sort(), [...ids].sort()) ? draft : ids;
|
|
34
|
+
const byId = new Map(items.map((item) => [getId(item), item]));
|
|
35
|
+
const nameOf = (id) => {
|
|
36
|
+
const item = byId.get(id);
|
|
37
|
+
return item !== void 0 && getLabel ? getLabel(item) : id;
|
|
38
|
+
};
|
|
39
|
+
const [announcement, setAnnouncement] = useState("");
|
|
40
|
+
const listRef = useRef(null);
|
|
41
|
+
const refocus = useRef(null);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
const target = refocus.current;
|
|
44
|
+
refocus.current = null;
|
|
45
|
+
if (!target) return;
|
|
46
|
+
if (target.el) {
|
|
47
|
+
if (target.el.isConnected && document.activeElement !== target.el) target.el.focus();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const row = Array.from(listRef.current?.children ?? []).find((child) => child.dataset.id === target.id);
|
|
51
|
+
if (!row) return;
|
|
52
|
+
const want = target.part === "up" ? ".uix-sortable__move--up" : target.part === "down" ? ".uix-sortable__move--down" : target.part === "grip" ? ".uix-sortable__grip" : null;
|
|
53
|
+
const other = target.part === "up" ? ".uix-sortable__move--down" : ".uix-sortable__move--up";
|
|
54
|
+
const button = want ? row.querySelector(want) : null;
|
|
55
|
+
const el = button && !button.disabled ? button : row.querySelector(other);
|
|
56
|
+
if (el && document.activeElement !== el) el.focus();
|
|
57
|
+
});
|
|
58
|
+
const commit = (next, id) => {
|
|
59
|
+
setDraft(null);
|
|
60
|
+
onReorder([...next]);
|
|
61
|
+
setAnnouncement(fillLabel(labels.moved, { label: nameOf(id), position: next.indexOf(id) + 1, count: next.length }));
|
|
62
|
+
};
|
|
63
|
+
const move = (id, delta, part, el) => {
|
|
64
|
+
const next = placeId(order, id, order.indexOf(id) + delta);
|
|
65
|
+
if (next === order) return;
|
|
66
|
+
refocus.current = { id, part, el };
|
|
67
|
+
commit(next, id);
|
|
68
|
+
};
|
|
69
|
+
const settle = useRef(null);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const pending = settle.current;
|
|
72
|
+
if (!pending || draft !== null) return;
|
|
73
|
+
if (orderKey === pending.from) return;
|
|
74
|
+
settle.current = null;
|
|
75
|
+
if (orderKey !== pending.to) return;
|
|
76
|
+
const row = Array.from(listRef.current?.children ?? []).find((child) => child.dataset.id === pending.id);
|
|
77
|
+
settleDrop(row);
|
|
78
|
+
});
|
|
79
|
+
const dragStart = useRef(null);
|
|
80
|
+
const { dragging, start } = useRowDrag(".uix-sortable__row", {
|
|
81
|
+
over: (id, index) => {
|
|
82
|
+
const next = placeId(order, id, index);
|
|
83
|
+
if (next !== order) setDraft(next);
|
|
84
|
+
},
|
|
85
|
+
drop: (id) => {
|
|
86
|
+
const begin = dragStart.current;
|
|
87
|
+
dragStart.current = null;
|
|
88
|
+
if (begin && !sameOrder(begin, order)) {
|
|
89
|
+
settle.current = { id, to: order.join("\0"), from: orderKey };
|
|
90
|
+
commit(order, id);
|
|
91
|
+
} else setDraft(null);
|
|
92
|
+
},
|
|
93
|
+
cancel: () => {
|
|
94
|
+
dragStart.current = null;
|
|
95
|
+
setDraft(null);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
const onRowKeyDown = (event, id) => {
|
|
99
|
+
if (disabled || !event.altKey || event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
100
|
+
if (event.target.closest('input, textarea, select, [contenteditable="true"]')) return;
|
|
101
|
+
event.preventDefault();
|
|
102
|
+
const target = event.target;
|
|
103
|
+
const part = target.closest(".uix-sortable__move--up") ? "up" : target.closest(".uix-sortable__move--down") ? "down" : target.closest(".uix-sortable__grip") ? "grip" : "row";
|
|
104
|
+
move(id, event.key === "ArrowUp" ? -1 : 1, part, part === "row" ? target : void 0);
|
|
105
|
+
};
|
|
106
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
107
|
+
/* @__PURE__ */ jsx("ul", { ref: listRef, className: cx("uix-sortable", className), "data-dragging": dragging ? "" : void 0, ...props, children: order.map((id, index) => {
|
|
108
|
+
const item = byId.get(id);
|
|
109
|
+
if (item === void 0) return null;
|
|
110
|
+
const name = nameOf(id);
|
|
111
|
+
return /* @__PURE__ */ jsxs("li", { className: "uix-sortable__row", "data-id": id, "data-dragging": dragging === id || void 0, "data-uix-drag": dragging === id ? "lifted" : void 0, onKeyDown: (event) => onRowKeyDown(event, id), children: [
|
|
112
|
+
!disabled && /* @__PURE__ */ jsx(
|
|
113
|
+
"button",
|
|
114
|
+
{
|
|
115
|
+
type: "button",
|
|
116
|
+
className: "uix-sortable__grip",
|
|
117
|
+
tabIndex: -1,
|
|
118
|
+
"aria-label": fillLabel(labels.grip, { label: name }),
|
|
119
|
+
onPointerDown: (event) => {
|
|
120
|
+
if (event.button !== 0) return;
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
event.currentTarget.focus({ preventScroll: true });
|
|
123
|
+
dragStart.current = order;
|
|
124
|
+
start(event, id);
|
|
125
|
+
},
|
|
126
|
+
onKeyDown: (event) => {
|
|
127
|
+
if (event.altKey || event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
128
|
+
event.preventDefault();
|
|
129
|
+
move(id, event.key === "ArrowUp" ? -1 : 1, "grip");
|
|
130
|
+
},
|
|
131
|
+
children: /* @__PURE__ */ jsx(EditorIcon, { name: "grip" })
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ jsx("div", { className: "uix-sortable__content", children: renderItem(item, { index, count: order.length, dragging: dragging === id }) }),
|
|
135
|
+
!disabled && /* @__PURE__ */ jsxs("span", { className: "uix-sortable__moves", children: [
|
|
136
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "uix-sortable__move uix-sortable__move--up", "aria-label": fillLabel(labels.moveUp, { label: name }), disabled: index === 0, onClick: () => move(id, -1, "up"), children: /* @__PURE__ */ jsx(ArrowIcon, { dir: "up" }) }),
|
|
137
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "uix-sortable__move uix-sortable__move--down", "aria-label": fillLabel(labels.moveDown, { label: name }), disabled: index === order.length - 1, onClick: () => move(id, 1, "down"), children: /* @__PURE__ */ jsx(ArrowIcon, { dir: "down" }) })
|
|
138
|
+
] })
|
|
139
|
+
] }, id);
|
|
140
|
+
}) }),
|
|
141
|
+
/* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", role: "status", children: announcement })
|
|
142
|
+
] });
|
|
143
|
+
}
|
|
144
|
+
export {
|
|
145
|
+
DEFAULT_SORTABLE_LIST_LABELS,
|
|
146
|
+
SortableList
|
|
147
|
+
};
|
|
@@ -3,8 +3,15 @@ import { HTMLAttributes, ReactNode } from 'react';
|
|
|
3
3
|
import { UixRenderLink } from '../link.js';
|
|
4
4
|
|
|
5
5
|
interface StatTrend {
|
|
6
|
+
/** Which way the figure moved: the arrow, and the spoken "up" / "down". */
|
|
6
7
|
direction: 'up' | 'down';
|
|
7
8
|
label: ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* What the change means, which sets the colour (HAR-1563): `positive` green, `negative` red,
|
|
11
|
+
* `neutral` (default) grey. A rise in breached SLAs is `negative`; direction never picks the
|
|
12
|
+
* colour.
|
|
13
|
+
*/
|
|
14
|
+
sentiment?: 'positive' | 'negative' | 'neutral';
|
|
8
15
|
}
|
|
9
16
|
interface StatProps extends HTMLAttributes<HTMLElement> {
|
|
10
17
|
label: ReactNode;
|
|
@@ -15,7 +22,10 @@ interface StatProps extends HTMLAttributes<HTMLElement> {
|
|
|
15
22
|
meta?: ReactNode;
|
|
16
23
|
/** Trend chip rendered before the meta text. */
|
|
17
24
|
trend?: StatTrend;
|
|
18
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* `warning` / `danger` colour the value and put a dot of that tone before it; the border stays
|
|
27
|
+
* neutral (HAR-1563). `neutral` (default) is the plain tile.
|
|
28
|
+
*/
|
|
19
29
|
tone?: 'neutral' | 'warning' | 'danger';
|
|
20
30
|
/** `hero` (default) is today's KPI size; `compact` is for dense fact bands. */
|
|
21
31
|
size?: 'hero' | 'compact';
|
|
@@ -48,7 +58,8 @@ interface StatProps extends HTMLAttributes<HTMLElement> {
|
|
|
48
58
|
/**
|
|
49
59
|
* Makes the whole tile a link (HAR-1350; TENSOR B7, MOTUS B-A7). Server-renderable, unlike
|
|
50
60
|
* `onActivate`. Ignored when `onActivate` is set. The forwarded ref reaches the `<a>` only
|
|
51
|
-
* without `renderLink`.
|
|
61
|
+
* without `renderLink`. A trailing chevron in the label row marks the tile as a link at rest,
|
|
62
|
+
* since a touch screen has no hover (HAR-1803).
|
|
52
63
|
*/
|
|
53
64
|
href?: string;
|
|
54
65
|
/** The link tile is the current page (`aria-current="page"`). */
|
|
@@ -61,5 +72,19 @@ interface StatProps extends HTMLAttributes<HTMLElement> {
|
|
|
61
72
|
* ref then points at that button, so a popover can anchor to it.
|
|
62
73
|
*/
|
|
63
74
|
declare const Stat: react.ForwardRefExoticComponent<StatProps & react.RefAttributes<HTMLElement>>;
|
|
75
|
+
interface StatRowProps extends HTMLAttributes<HTMLDivElement> {
|
|
76
|
+
/**
|
|
77
|
+
* The narrowest a tile may get before the row puts fewer tiles side by side, as a CSS length
|
|
78
|
+
* (`--stat-row-min`). Default `8.5rem`, and `12rem` once a hero tile is in the row.
|
|
79
|
+
*/
|
|
80
|
+
minTileWidth?: string;
|
|
81
|
+
children?: ReactNode;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A row of `Stat` tiles over `.uix-stat-row` (HAR-1803 review): as many tiles per row as fit at
|
|
85
|
+
* `minTileWidth`, all the same height, down to one per row on a phone. Use it instead of a fixed
|
|
86
|
+
* column count, which squeezes tiles until their labels break letter by letter.
|
|
87
|
+
*/
|
|
88
|
+
declare function StatRow({ minTileWidth, className, style, children, ...props }: StatRowProps): react.JSX.Element;
|
|
64
89
|
|
|
65
|
-
export { Stat, type StatProps, type StatTrend };
|
|
90
|
+
export { Stat, type StatProps, StatRow, type StatRowProps, type StatTrend };
|
package/dist/components/Stat.js
CHANGED
|
@@ -2,7 +2,9 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef, useId } from "react";
|
|
3
3
|
import { cx } from "../cx.js";
|
|
4
4
|
import { renderUixLink } from "../link.js";
|
|
5
|
+
import { ChevronRightIcon } from "../icons/components.js";
|
|
5
6
|
const Chevron = () => /* @__PURE__ */ jsx("span", { className: "uix-stat__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" }) }) });
|
|
7
|
+
const Go = () => /* @__PURE__ */ jsx("span", { className: "uix-stat__go", "aria-hidden": "true", children: /* @__PURE__ */ jsx(ChevronRightIcon, {}) });
|
|
6
8
|
const Stat = forwardRef(function Stat2({ label, value, icon, meta, trend, tone = "neutral", size = "hero", onActivate, activateLabel, expanded, trendLabels, haspopup = "dialog", href, current, renderLink, className, onClick, onKeyDown, pending = false, ...props }, ref) {
|
|
7
9
|
const id = useId();
|
|
8
10
|
const interactive = onActivate != null;
|
|
@@ -13,6 +15,8 @@ const Stat = forwardRef(function Stat2({ label, value, icon, meta, trend, tone =
|
|
|
13
15
|
size === "compact" && "uix-stat--compact",
|
|
14
16
|
(interactive || linked) && "uix-stat--interactive",
|
|
15
17
|
linked && "uix-stat--link",
|
|
18
|
+
// an in-place action has no chevron: its value is underlined at rest instead (HAR-1803)
|
|
19
|
+
interactive && haspopup === false && "uix-stat--action",
|
|
16
20
|
className
|
|
17
21
|
);
|
|
18
22
|
const Row = interactive || linked ? "span" : "div";
|
|
@@ -20,11 +24,12 @@ const Stat = forwardRef(function Stat2({ label, value, icon, meta, trend, tone =
|
|
|
20
24
|
/* @__PURE__ */ jsxs(Row, { className: "uix-stat__label", children: [
|
|
21
25
|
/* @__PURE__ */ jsx("span", { id: interactive ? `${id}-label` : void 0, children: label }),
|
|
22
26
|
icon,
|
|
23
|
-
interactive && haspopup !== false && /* @__PURE__ */ jsx(Chevron, {})
|
|
27
|
+
interactive && haspopup !== false && /* @__PURE__ */ jsx(Chevron, {}),
|
|
28
|
+
linked && /* @__PURE__ */ jsx(Go, {})
|
|
24
29
|
] }),
|
|
25
30
|
/* @__PURE__ */ jsx(Row, { className: "uix-stat__value", id: interactive ? `${id}-value` : void 0, children: value }),
|
|
26
31
|
(meta != null || trend != null) && /* @__PURE__ */ jsxs(Row, { className: "uix-stat__meta", id: interactive ? `${id}-meta` : void 0, children: [
|
|
27
|
-
trend != null && /* @__PURE__ */ jsxs("span", { className: cx("uix-stat__trend", `uix-stat__trend--${trend.direction}`), children: [
|
|
32
|
+
trend != null && /* @__PURE__ */ jsxs("span", { className: cx("uix-stat__trend", `uix-stat__trend--${trend.direction}`, trend.sentiment != null && trend.sentiment !== "neutral" && `uix-stat__trend--${trend.sentiment}`), children: [
|
|
28
33
|
/* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: trend.direction === "up" ? /* @__PURE__ */ jsx("path", { d: "M12 19V5m-6 6 6-6 6 6" }) : /* @__PURE__ */ jsx("path", { d: "M12 5v14m6-6-6 6-6-6" }) }),
|
|
29
34
|
/* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: trend.direction === "up" ? trendLabels?.up ?? "up" : trendLabels?.down ?? "down" }),
|
|
30
35
|
trend.label
|
|
@@ -68,6 +73,11 @@ const Stat = forwardRef(function Stat2({ label, value, icon, meta, trend, tone =
|
|
|
68
73
|
}
|
|
69
74
|
);
|
|
70
75
|
});
|
|
76
|
+
function StatRow({ minTileWidth, className, style, children, ...props }) {
|
|
77
|
+
const rowStyle = minTileWidth ? { ...style, "--stat-row-min": minTileWidth } : style;
|
|
78
|
+
return /* @__PURE__ */ jsx("div", { className: cx("uix-stat-row", className), style: rowStyle, ...props, children });
|
|
79
|
+
}
|
|
71
80
|
export {
|
|
72
|
-
Stat
|
|
81
|
+
Stat,
|
|
82
|
+
StatRow
|
|
73
83
|
};
|
|
@@ -38,6 +38,38 @@ declare function ForbiddenState({ icon, title, detail, action, variant, classNam
|
|
|
38
38
|
declare function NotFoundState({ icon, title, detail, action, variant, className, ...props }: AccessStateProps): react.JSX.Element;
|
|
39
39
|
/** Empty-result state for an active search or filter, kept distinct for analytics and recovery copy. */
|
|
40
40
|
declare function FilteredEmptyState(props: EmptyStateProps): react.JSX.Element;
|
|
41
|
+
interface SuccessStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
42
|
+
/** What happened, e.g. "Request submitted". Rendered as a heading that takes focus on mount. */
|
|
43
|
+
title: ReactNode;
|
|
44
|
+
/** The heading level (default 1: the outcome usually replaces the page's form). */
|
|
45
|
+
headingLevel?: 1 | 2 | 3;
|
|
46
|
+
/** Supporting copy under the title. */
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
/** The record's reference, e.g. `<>REQ-0233 <CopyButton … /></>`. */
|
|
49
|
+
reference?: ReactNode;
|
|
50
|
+
/** The words before the reference (default "Your reference"). */
|
|
51
|
+
referenceLabel?: ReactNode;
|
|
52
|
+
/** A short, ordered "what happens next": two to four steps in the person's words. */
|
|
53
|
+
next?: ReactNode[];
|
|
54
|
+
/** The heading of `next` (default "What happens next"). */
|
|
55
|
+
nextTitle?: ReactNode;
|
|
56
|
+
/** The next action, e.g. a `ButtonLink` to the request or back to the portal. */
|
|
57
|
+
action?: ReactNode;
|
|
58
|
+
/**
|
|
59
|
+
* Move focus to the title when it mounts. Default: on for `page` and `full-page` (the outcome
|
|
60
|
+
* replaces the form the person was in), off for a state inside a section, card or drawer.
|
|
61
|
+
*/
|
|
62
|
+
focusOnMount?: boolean;
|
|
63
|
+
variant?: StateVariant;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The outcome of a rare, important journey (HAR-2588; motion standard §2.2 "Rare", §2.8
|
|
67
|
+
* "portal peak"): a request submitted, an application sent. A success mark draws once — never
|
|
68
|
+
* repeats, never a game — then the title, the reference, what happens next, and the next
|
|
69
|
+
* action. On a page, focus moves to the title, so a screen reader reads the outcome first. Under
|
|
70
|
+
* reduced motion the mark is simply there.
|
|
71
|
+
*/
|
|
72
|
+
declare function SuccessState({ title, headingLevel, children, reference, referenceLabel, next, nextTitle, action, focusOnMount, variant, className, ...props }: SuccessStateProps): react.JSX.Element;
|
|
41
73
|
interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {
|
|
42
74
|
variant?: 'block' | 'text' | 'circle';
|
|
43
75
|
width?: number | string;
|
|
@@ -61,4 +93,4 @@ interface LoadingStateProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
61
93
|
/** A stack of skeleton rows for list/section loading. `role="status"`. */
|
|
62
94
|
declare function LoadingState({ delay, ...props }: LoadingStateProps): react.JSX.Element;
|
|
63
95
|
|
|
64
|
-
export { type AccessStateProps, EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, FilteredEmptyState, ForbiddenState, LoadingState, type LoadingStateProps, NotFoundState, Skeleton, type SkeletonProps, type StateVariant };
|
|
96
|
+
export { type AccessStateProps, EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, FilteredEmptyState, ForbiddenState, LoadingState, type LoadingStateProps, NotFoundState, Skeleton, type SkeletonProps, type StateVariant, SuccessState, type SuccessStateProps };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createElement } from "react";
|
|
2
3
|
import { cx } from "../cx.js";
|
|
3
4
|
import { DelayedRender } from "./DelayedRender.js";
|
|
5
|
+
import { FocusOnMount } from "./FocusOnMount.js";
|
|
4
6
|
import { PENDING_DELAY_MS } from "../motion-timing.js";
|
|
5
7
|
function EmptyState({ icon, title, children, action, variant = "section", className, ...props }) {
|
|
6
8
|
return /* @__PURE__ */ jsxs("div", { className: cx("uix-empty", `uix-empty--${variant}`, className), ...props, children: [
|
|
@@ -37,6 +39,45 @@ function NotFoundState({ icon, title, detail, action, variant = "section", class
|
|
|
37
39
|
function FilteredEmptyState(props) {
|
|
38
40
|
return /* @__PURE__ */ jsx(EmptyState, { "data-filtered": "true", ...props });
|
|
39
41
|
}
|
|
42
|
+
function SuccessState({
|
|
43
|
+
title,
|
|
44
|
+
headingLevel = 1,
|
|
45
|
+
children,
|
|
46
|
+
reference,
|
|
47
|
+
referenceLabel = "Your reference",
|
|
48
|
+
next,
|
|
49
|
+
nextTitle = "What happens next",
|
|
50
|
+
action,
|
|
51
|
+
focusOnMount,
|
|
52
|
+
variant = "page",
|
|
53
|
+
className,
|
|
54
|
+
...props
|
|
55
|
+
}) {
|
|
56
|
+
const focusTitle = focusOnMount ?? (variant === "page" || variant === "full-page");
|
|
57
|
+
const heading = `h${headingLevel}`;
|
|
58
|
+
const subheading = `h${Math.min(headingLevel + 1, 6)}`;
|
|
59
|
+
return (
|
|
60
|
+
// `section` is the base look: no modifier class (there is no rule for one)
|
|
61
|
+
/* @__PURE__ */ jsxs("div", { className: cx("uix-empty", "uix-success", variant !== "section" && `uix-empty--${variant}`, className), ...props, children: [
|
|
62
|
+
/* @__PURE__ */ jsx("div", { className: "uix-success__mark", "aria-hidden": "true", children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 48 48", fill: "none", children: [
|
|
63
|
+
/* @__PURE__ */ jsx("circle", { className: "uix-success__disc", cx: "24", cy: "24", r: "22" }),
|
|
64
|
+
/* @__PURE__ */ jsx("path", { className: "uix-success__check", d: "M14 24.5 21 31.5 34 17.5", pathLength: 1 })
|
|
65
|
+
] }) }),
|
|
66
|
+
/* @__PURE__ */ jsx(FocusOnMount, { as: heading, enabled: focusTitle, className: "uix-empty__title uix-success__title", children: title }),
|
|
67
|
+
children != null && /* @__PURE__ */ jsx("div", { className: "uix-success__body", children }),
|
|
68
|
+
reference != null && /* @__PURE__ */ jsxs("p", { className: "uix-success__reference", children: [
|
|
69
|
+
/* @__PURE__ */ jsx("span", { className: "uix-success__reference-label", children: referenceLabel }),
|
|
70
|
+
" ",
|
|
71
|
+
/* @__PURE__ */ jsx("span", { className: "uix-success__reference-value", children: reference })
|
|
72
|
+
] }),
|
|
73
|
+
next && next.length > 0 && /* @__PURE__ */ jsxs("div", { className: "uix-success__next", children: [
|
|
74
|
+
createElement(subheading, { className: "uix-success__next-title" }, nextTitle),
|
|
75
|
+
/* @__PURE__ */ jsx("ol", { className: "uix-success__steps", children: next.map((step, i) => /* @__PURE__ */ jsx("li", { children: step }, i)) })
|
|
76
|
+
] }),
|
|
77
|
+
action
|
|
78
|
+
] })
|
|
79
|
+
);
|
|
80
|
+
}
|
|
40
81
|
function Skeleton({ variant = "block", width, height, className, style, ...props }) {
|
|
41
82
|
const dims = { width, height, ...style };
|
|
42
83
|
return /* @__PURE__ */ jsx(
|
|
@@ -73,5 +114,6 @@ export {
|
|
|
73
114
|
ForbiddenState,
|
|
74
115
|
LoadingState,
|
|
75
116
|
NotFoundState,
|
|
76
|
-
Skeleton
|
|
117
|
+
Skeleton,
|
|
118
|
+
SuccessState
|
|
77
119
|
};
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
-
type PillTone = 'neutral' | 'success' | 'info' | 'warning' | 'danger' | 'critical' | 'muted' | 'attention' | 'overdue' | 'sla-ok' | 'sla-at-risk' | 'sla-breached' | 'p1' | 'p2' | 'p3' | 'p4' | 'p5';
|
|
5
|
-
|
|
4
|
+
type PillTone = 'neutral' | 'success' | 'info' | 'warning' | 'danger' | 'critical' | 'muted' | 'progress' | 'attention' | 'overdue' | 'sla-ok' | 'sla-at-risk' | 'sla-breached' | 'p1' | 'p2' | 'p3' | 'p4' | 'p5';
|
|
5
|
+
/**
|
|
6
|
+
* How loud the pill is (HAR-1563). `soft` (default) is the tinted wash; `filled` is its old name
|
|
7
|
+
* and still works. `dot` is the quiet one for tables: no fill, a neutral label and a coloured dot.
|
|
8
|
+
* `outline` is a neutral hairline with a hushed label and a dot; only `critical` keeps a toned
|
|
9
|
+
* border.
|
|
10
|
+
*/
|
|
11
|
+
type PillTreatment = 'soft' | 'filled' | 'dot' | 'outline';
|
|
6
12
|
type PillSize = 'sm' | 'md' | 'lg';
|
|
7
13
|
interface StatusPillProps extends HTMLAttributes<HTMLSpanElement> {
|
|
8
14
|
tone?: PillTone;
|
|
9
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* `soft` (default; `filled` is an alias) = tinted wash; `dot` = a coloured dot beside a neutral
|
|
17
|
+
* label, for dense tables; `outline` = a neutral hairline, a hushed label and a dot. `dot` and
|
|
18
|
+
* `outline` always draw the dot.
|
|
19
|
+
*/
|
|
10
20
|
treatment?: PillTreatment;
|
|
11
21
|
/**
|
|
12
22
|
* `sm` for a dense table cell or beside small text, `lg` for a page header (the public status
|
|
13
23
|
* page). Default `md`, the size every pill had before (HAR-1614).
|
|
14
24
|
*/
|
|
15
25
|
size?: PillSize;
|
|
26
|
+
/** Draws the tone's dot before the label. Always on for the `dot` and `outline` treatments. */
|
|
16
27
|
dot?: boolean;
|
|
17
28
|
children?: ReactNode;
|
|
18
29
|
}
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from "../cx.js";
|
|
3
|
-
function StatusPill({ tone = "neutral", treatment = "
|
|
3
|
+
function StatusPill({ tone = "neutral", treatment = "soft", size = "md", dot, children, className, ...props }) {
|
|
4
|
+
const quiet = treatment === "dot" || treatment === "outline";
|
|
4
5
|
return /* @__PURE__ */ jsxs(
|
|
5
6
|
"span",
|
|
6
7
|
{
|
|
7
|
-
className: cx(
|
|
8
|
+
className: cx(
|
|
9
|
+
"uix-pill",
|
|
10
|
+
`uix-pill--${tone}`,
|
|
11
|
+
quiet && `uix-pill--${treatment}`,
|
|
12
|
+
size === "sm" && "uix-pill--sm",
|
|
13
|
+
size === "lg" && "uix-pill--lg",
|
|
14
|
+
className
|
|
15
|
+
),
|
|
8
16
|
...props,
|
|
9
17
|
children: [
|
|
10
|
-
dot && /* @__PURE__ */ jsx("span", { className: "uix-pill__dot", "aria-hidden": "true" }),
|
|
18
|
+
(dot || quiet) && /* @__PURE__ */ jsx("span", { className: "uix-pill__dot", "aria-hidden": "true" }),
|
|
11
19
|
children
|
|
12
20
|
]
|
|
13
21
|
}
|
package/dist/components/Steps.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Children, cloneElement, isValidElement, useId } from "react";
|
|
3
3
|
import { cx } from "../cx.js";
|
|
4
4
|
import { renderUixLink } from "../link.js";
|
|
5
|
+
import { XIcon } from "../icons/components.js";
|
|
5
6
|
const DEFAULT_STEP_STATE_LABELS = {
|
|
6
7
|
complete: "Completed",
|
|
7
8
|
current: "Current step",
|
|
@@ -35,7 +36,7 @@ function Step({
|
|
|
35
36
|
...props
|
|
36
37
|
}) {
|
|
37
38
|
const titleId = useId();
|
|
38
|
-
const glyph = marker ?? (!progress ? index + 1 : state === "complete" ? /* @__PURE__ */ jsx(Check, {}) : state === "error" ?
|
|
39
|
+
const glyph = marker ?? (!progress ? index + 1 : state === "complete" ? /* @__PURE__ */ jsx(Check, {}) : state === "error" ? /* @__PURE__ */ jsx(XIcon, {}) : index + 1);
|
|
39
40
|
const Title = headingLevel ? `h${headingLevel}` : "span";
|
|
40
41
|
const name = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
41
42
|
/* @__PURE__ */ jsx(Title, { id: children != null ? titleId : void 0, className: "uix-step__title", children: title }),
|
|
@@ -86,8 +86,15 @@ interface ExpandToggleProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
|
86
86
|
declare function ExpandToggle({ expanded, controls, expandLabel, collapseLabel, className, type, ...props }: ExpandToggleProps): react.JSX.Element;
|
|
87
87
|
/** Emphasised primary cell text. */
|
|
88
88
|
declare function CellStrong({ children, className, ...props }: HTMLAttributes<HTMLSpanElement>): react.JSX.Element;
|
|
89
|
+
interface CellSubProps extends HTMLAttributes<HTMLSpanElement> {
|
|
90
|
+
/**
|
|
91
|
+
* Tabular numerals (HAR-1815): for a read-back code, a reference or a time, so digits line up
|
|
92
|
+
* down the column and a 1 is as wide as an 8.
|
|
93
|
+
*/
|
|
94
|
+
tabular?: boolean;
|
|
95
|
+
}
|
|
89
96
|
/** Secondary line under a primary cell value (muted, meta size). */
|
|
90
|
-
declare function CellSub({ children, className, ...props }:
|
|
97
|
+
declare function CellSub({ tabular, children, className, ...props }: CellSubProps): react.JSX.Element;
|
|
91
98
|
interface MarkProps extends HTMLAttributes<HTMLElement> {
|
|
92
99
|
children?: ReactNode;
|
|
93
100
|
}
|
|
@@ -100,4 +107,4 @@ interface HighlightedProps {
|
|
|
100
107
|
/** Render `text` with case-insensitive matches of `query` wrapped in <mark>. */
|
|
101
108
|
declare function Highlighted({ text, query }: HighlightedProps): react.JSX.Element;
|
|
102
109
|
|
|
103
|
-
export { BulkBar, type BulkBarProps, CellStrong, CellSub, ExpandToggle, type ExpandToggleProps, Highlighted, type HighlightedProps, Mark, type MarkProps, RowAction, type RowActionProps, RowActions, type RowActionsProps, type SortDirection, Table, type TableDensity, type TableProps, TableWrap, type TableWrapProps, Td, type TdProps, Th, type ThProps, Tr, type TrProps };
|
|
110
|
+
export { BulkBar, type BulkBarProps, CellStrong, CellSub, type CellSubProps, ExpandToggle, type ExpandToggleProps, Highlighted, type HighlightedProps, Mark, type MarkProps, RowAction, type RowActionProps, RowActions, type RowActionsProps, type SortDirection, Table, type TableDensity, type TableProps, TableWrap, type TableWrapProps, Td, type TdProps, Th, type ThProps, Tr, type TrProps };
|
package/dist/components/Table.js
CHANGED
|
@@ -3,9 +3,11 @@ import { forwardRef } from "react";
|
|
|
3
3
|
import { cx } from "../cx.js";
|
|
4
4
|
import { highlightSegments } from "../table-engine.js";
|
|
5
5
|
import { BusyBar } from "./BusyBar.js";
|
|
6
|
+
import { TableOverflowProbe } from "./TableOverflowProbe.js";
|
|
6
7
|
const TableWrap = forwardRef(function TableWrap2({ announcement, refreshing, children, className, ...props }, ref) {
|
|
7
8
|
return /* @__PURE__ */ jsxs("div", { ref, className: cx("uix-table-wrap", className), "aria-busy": refreshing || void 0, ...props, children: [
|
|
8
9
|
refreshing !== void 0 && /* @__PURE__ */ jsx(BusyBar, { busy: refreshing }),
|
|
10
|
+
/* @__PURE__ */ jsx(TableOverflowProbe, {}),
|
|
9
11
|
announcement != null && /* @__PURE__ */ jsx("div", { role: "status", className: "uix-visually-hidden", children: announcement }),
|
|
10
12
|
children
|
|
11
13
|
] });
|
|
@@ -100,8 +102,8 @@ function ExpandToggle({ expanded, controls, expandLabel = "Expand row", collapse
|
|
|
100
102
|
function CellStrong({ children, className, ...props }) {
|
|
101
103
|
return /* @__PURE__ */ jsx("span", { className: cx("uix-cell-strong", className), ...props, children });
|
|
102
104
|
}
|
|
103
|
-
function CellSub({ children, className, ...props }) {
|
|
104
|
-
return /* @__PURE__ */ jsx("span", { className: cx("uix-cell-sub", className), ...props, children });
|
|
105
|
+
function CellSub({ tabular, children, className, ...props }) {
|
|
106
|
+
return /* @__PURE__ */ jsx("span", { className: cx("uix-cell-sub", tabular && "uix-cell-sub--tabular", className), ...props, children });
|
|
105
107
|
}
|
|
106
108
|
function Mark({ children, className, ...props }) {
|
|
107
109
|
return /* @__PURE__ */ jsx("mark", { className: cx("uix-mark", className), ...props, children });
|