@tensor_1/react 2.47.0 → 2.48.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.
Files changed (183) hide show
  1. package/README.md +470 -1
  2. package/dist/{SchedulingCalendar-B6TakO2h.d.ts → SchedulingCalendar-WWyFL3Eo.d.ts} +51 -2
  3. package/dist/announce.d.ts +10 -0
  4. package/dist/announce.js +30 -0
  5. package/dist/chart-analytic.cjs +33 -25
  6. package/dist/chart-preset.cjs +23 -15
  7. package/dist/chart.cjs +23 -15
  8. package/dist/combobox-model.d.ts +10 -1
  9. package/dist/combobox-model.js +15 -0
  10. package/dist/command-palette-model.d.ts +44 -0
  11. package/dist/command-palette-model.js +36 -0
  12. package/dist/components/AccountMenu.d.ts +44 -0
  13. package/dist/components/AccountMenu.js +43 -0
  14. package/dist/components/AppShell.d.ts +45 -2
  15. package/dist/components/AppShell.js +116 -5
  16. package/dist/components/AuditLog.d.ts +128 -0
  17. package/dist/components/AuditLog.js +196 -0
  18. package/dist/components/BrandProfiles.js +4 -3
  19. package/dist/components/Breadcrumbs.d.ts +9 -2
  20. package/dist/components/Breadcrumbs.js +3 -2
  21. package/dist/components/Button.d.ts +12 -5
  22. package/dist/components/Button.js +7 -3
  23. package/dist/components/Card.d.ts +18 -1
  24. package/dist/components/Card.js +5 -1
  25. package/dist/components/ChangeHighlight.d.ts +30 -0
  26. package/dist/components/ChangeHighlight.js +21 -0
  27. package/dist/components/ChartCore.js +2 -1
  28. package/dist/components/Checkbox.d.ts +27 -1
  29. package/dist/components/Checkbox.js +31 -2
  30. package/dist/components/CodeDisplay.d.ts +65 -0
  31. package/dist/components/CodeDisplay.js +124 -0
  32. package/dist/components/Combobox.d.ts +27 -6
  33. package/dist/components/Combobox.js +195 -58
  34. package/dist/components/CommandPalette.d.ts +36 -1
  35. package/dist/components/CommandPalette.js +254 -2
  36. package/dist/components/ContactCard.d.ts +66 -0
  37. package/dist/components/ContactCard.js +74 -0
  38. package/dist/components/Count.d.ts +24 -0
  39. package/dist/components/Count.js +32 -0
  40. package/dist/components/DataWorkspace.d.ts +167 -0
  41. package/dist/components/DataWorkspace.js +383 -0
  42. package/dist/components/DateFieldParts.d.ts +2 -1
  43. package/dist/components/DateFieldParts.js +7 -0
  44. package/dist/components/DatePicker.d.ts +9 -2
  45. package/dist/components/DatePicker.js +67 -28
  46. package/dist/components/DateRangePicker.d.ts +12 -2
  47. package/dist/components/DateRangePicker.js +13 -12
  48. package/dist/components/DetailPage.d.ts +7 -1
  49. package/dist/components/DetailPage.js +2 -1
  50. package/dist/components/Dialogs.d.ts +71 -10
  51. package/dist/components/Dialogs.js +130 -30
  52. package/dist/components/DiffViewer.d.ts +23 -3
  53. package/dist/components/DiffViewer.js +26 -12
  54. package/dist/components/DiscardPrompt.js +16 -0
  55. package/dist/components/DisplayPreferences.d.ts +83 -0
  56. package/dist/components/DisplayPreferences.js +185 -0
  57. package/dist/components/EditorialHome.d.ts +23 -3
  58. package/dist/components/EditorialHome.js +16 -11
  59. package/dist/components/EntityPicker.d.ts +20 -3
  60. package/dist/components/EntityPicker.js +32 -13
  61. package/dist/components/FilterEditor.d.ts +18 -4
  62. package/dist/components/FilterEditor.js +141 -19
  63. package/dist/components/InfoTip.js +11 -12
  64. package/dist/components/InlineEdit.d.ts +87 -20
  65. package/dist/components/InlineEdit.js +197 -54
  66. package/dist/components/Input.d.ts +12 -2
  67. package/dist/components/Input.js +5 -3
  68. package/dist/components/Kbd.d.ts +6 -1
  69. package/dist/components/Kbd.js +6 -6
  70. package/dist/components/Lightbox.d.ts +41 -5
  71. package/dist/components/Lightbox.js +95 -9
  72. package/dist/components/MatchReview.d.ts +40 -1
  73. package/dist/components/MatchReview.js +130 -4
  74. package/dist/components/MetricInput.js +3 -2
  75. package/dist/components/Modal.d.ts +2 -1
  76. package/dist/components/Modal.js +13 -4
  77. package/dist/components/NavFavourites.d.ts +5 -0
  78. package/dist/components/NavFavourites.js +7 -7
  79. package/dist/components/OtpInput.d.ts +33 -0
  80. package/dist/components/OtpInput.js +123 -0
  81. package/dist/components/PageHeader.d.ts +7 -1
  82. package/dist/components/PageHeader.js +2 -2
  83. package/dist/components/Pagination.js +6 -5
  84. package/dist/components/PasswordInput.d.ts +34 -0
  85. package/dist/components/PasswordInput.js +101 -0
  86. package/dist/components/Peek.js +3 -3
  87. package/dist/components/Popover.js +2 -0
  88. package/dist/components/PrintLayout.d.ts +63 -0
  89. package/dist/components/PrintLayout.js +114 -0
  90. package/dist/components/QrCode.d.ts +47 -0
  91. package/dist/components/QrCode.js +55 -0
  92. package/dist/components/QrScanner.d.ts +95 -0
  93. package/dist/components/QrScanner.js +266 -0
  94. package/dist/components/RelationshipGraph.d.ts +32 -1
  95. package/dist/components/RelationshipGraph.js +18 -5
  96. package/dist/components/RelationshipGraphLayered.d.ts +1 -1
  97. package/dist/components/RelationshipGraphLayered.js +190 -115
  98. package/dist/components/RelationshipGraphList.js +33 -6
  99. package/dist/components/RuleBuilder.js +39 -7
  100. package/dist/components/SchedulingAgenda.d.ts +3 -1
  101. package/dist/components/SchedulingCalendar.d.ts +3 -1
  102. package/dist/components/SchedulingCalendar.js +43 -4
  103. package/dist/components/SchedulingResourceDay.d.ts +57 -0
  104. package/dist/components/SchedulingResourceDay.js +287 -0
  105. package/dist/components/SchedulingTimeGrid.d.ts +3 -1
  106. package/dist/components/SchedulingTimeline.d.ts +3 -1
  107. package/dist/components/SearchSuggest.d.ts +23 -3
  108. package/dist/components/SearchSuggest.js +48 -17
  109. package/dist/components/Segmented.d.ts +39 -4
  110. package/dist/components/Segmented.js +31 -3
  111. package/dist/components/Select.d.ts +3 -2
  112. package/dist/components/Select.js +1 -1
  113. package/dist/components/ShortcutHint.d.ts +11 -10
  114. package/dist/components/ShortcutHint.js +44 -38
  115. package/dist/components/Sidebar.d.ts +36 -4
  116. package/dist/components/Sidebar.js +37 -12
  117. package/dist/components/SortableList.d.ts +45 -0
  118. package/dist/components/SortableList.js +134 -0
  119. package/dist/components/Stat.d.ts +28 -3
  120. package/dist/components/Stat.js +13 -3
  121. package/dist/components/StatusPill.d.ts +14 -3
  122. package/dist/components/StatusPill.js +11 -3
  123. package/dist/components/Steps.js +2 -1
  124. package/dist/components/Table.d.ts +9 -2
  125. package/dist/components/Table.js +4 -2
  126. package/dist/components/TableControls.js +18 -58
  127. package/dist/components/TableOverflowProbe.d.ts +12 -0
  128. package/dist/components/TableOverflowProbe.js +27 -0
  129. package/dist/components/Tabs.d.ts +2 -1
  130. package/dist/components/Tabs.js +1 -0
  131. package/dist/components/TagInput.d.ts +67 -0
  132. package/dist/components/TagInput.js +342 -0
  133. package/dist/components/Textarea.d.ts +5 -0
  134. package/dist/components/Textarea.js +2 -2
  135. package/dist/components/TimePicker.d.ts +80 -0
  136. package/dist/components/TimePicker.js +347 -0
  137. package/dist/components/Toast.js +3 -2
  138. package/dist/components/Tooltip.d.ts +8 -4
  139. package/dist/components/Tooltip.js +24 -21
  140. package/dist/components/Tree.d.ts +8 -0
  141. package/dist/components/Tree.js +11 -5
  142. package/dist/display-preferences-model.d.ts +53 -0
  143. package/dist/display-preferences-model.js +64 -0
  144. package/dist/emoji.cjs +28 -35
  145. package/dist/filter-model.d.ts +59 -3
  146. package/dist/filter-model.js +67 -2
  147. package/dist/hooks/useChangeHighlight.d.ts +33 -0
  148. package/dist/hooks/useChangeHighlight.js +44 -0
  149. package/dist/hooks/useDialog.d.ts +5 -0
  150. package/dist/hooks/useDialog.js +3 -2
  151. package/dist/hooks/useOptimisticValue.d.ts +51 -0
  152. package/dist/hooks/useOptimisticValue.js +61 -0
  153. package/dist/hooks/useReducedMotion.d.ts +4 -1
  154. package/dist/hooks/useReducedMotion.js +7 -1
  155. package/dist/hooks/useResolvedFilterLabels.d.ts +15 -0
  156. package/dist/hooks/useResolvedFilterLabels.js +34 -0
  157. package/dist/hooks/useVirtualRows.d.ts +21 -2
  158. package/dist/hooks/useVirtualRows.js +30 -3
  159. package/dist/icons/Icon.d.ts +1 -1
  160. package/dist/index.cjs +18644 -13210
  161. package/dist/index.d.cts +3003 -699
  162. package/dist/index.d.ts +42 -16
  163. package/dist/index.js +139 -7
  164. package/dist/labels-context.d.ts +90 -3
  165. package/dist/overlay-stack.d.ts +6 -0
  166. package/dist/overlay-stack.js +13 -0
  167. package/dist/qr-model.d.ts +65 -0
  168. package/dist/qr-model.js +323 -0
  169. package/dist/relationship-graph-model.d.ts +78 -3
  170. package/dist/relationship-graph-model.js +112 -5
  171. package/dist/reorder.d.ts +30 -0
  172. package/dist/reorder.js +74 -0
  173. package/dist/rich-text.cjs +4 -2
  174. package/dist/scheduling-resource-model.d.ts +76 -0
  175. package/dist/scheduling-resource-model.js +74 -0
  176. package/dist/search-suggest-model.js +3 -1
  177. package/dist/shell-context.d.ts +11 -0
  178. package/dist/shell-context.js +7 -0
  179. package/dist/time-field-model.d.ts +46 -0
  180. package/dist/time-field-model.js +152 -0
  181. package/dist/toast-store.d.ts +17 -1
  182. package/dist/toast-store.js +23 -7
  183. package/package.json +2 -1
@@ -0,0 +1,66 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+ import { UixRenderLink } from '../link.js';
4
+
5
+ /** The words of a `ContactCard` (HAR-1379). */
6
+ interface ContactCardLabels {
7
+ /** The email action's visible text. */
8
+ email: string;
9
+ /** The phone action's visible text. */
10
+ call: string;
11
+ /** The email action's accessible name; `{name}` is the contact's name. Starts with the visible text (WCAG 2.5.3). */
12
+ emailName: string;
13
+ /** The phone action's accessible name; `{name}`. */
14
+ callName: string;
15
+ /** Shown in place of the name when the person's data was erased and no name is left. */
16
+ purgedName: string;
17
+ /** The line under the name of an erased contact. */
18
+ purged: string;
19
+ /** The line under the name of a contact whose details cannot be shown (no access, or not loaded). */
20
+ unavailable: string;
21
+ }
22
+ declare const DEFAULT_CONTACT_CARD_LABELS: ContactCardLabels;
23
+ /**
24
+ * `active` shows everything given. `purged`: the person's data was erased; a neutral
25
+ * placeholder, no details and no actions. `unavailable`: the name stays, the details and actions
26
+ * do not (no access, or they could not be loaded).
27
+ */
28
+ type ContactCardState = 'active' | 'purged' | 'unavailable';
29
+ interface ContactCardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'role'> {
30
+ /** The person's or the organisation's name. Leave it out for an erased contact. */
31
+ name?: string;
32
+ /** Role or relation, e.g. "Practice manager · Dom zdravlja Centar". */
33
+ role?: ReactNode;
34
+ /** An `Avatar` (size `lg` reads best). An erased contact always gets the placeholder. */
35
+ avatar?: ReactNode;
36
+ /** Shown as text and offered as a `mailto:` action. */
37
+ email?: string;
38
+ /** Shown as written and offered as a `tel:` action (spaces, dashes and brackets are dropped from the link). */
39
+ phone?: string;
40
+ /** More actions after Email and Call, e.g. a `ButtonLink` to the record. */
41
+ actions?: ReactNode;
42
+ /** Figures under the role (`.uix-contact__stats`). */
43
+ stats?: ReactNode;
44
+ /** The name as a link to the person's record. */
45
+ href?: string;
46
+ /** Your router's link for `href`. */
47
+ renderLink?: UixRenderLink;
48
+ /** The element of the name: a heading when the card stands for a section. Default `div`. */
49
+ nameAs?: 'h2' | 'h3' | 'h4' | 'div';
50
+ state?: ContactCardState;
51
+ /** Without the card frame, for a peek, a popover or a sidebar that is already a surface. */
52
+ bare?: boolean;
53
+ /** The words. Default: `UixLabelsProvider` `contactCard`, then English. */
54
+ labels?: Partial<ContactCardLabels>;
55
+ }
56
+ /** The digits and a leading + of a phone number, for a `tel:` link. */
57
+ declare const telHref: (phone: string) => string;
58
+ /**
59
+ * A person or an organisation at a glance (HAR-1379; MOTUS C-15, TENSOR incident people card):
60
+ * avatar, name, role, the email address and phone number as text, and Email / Call actions as
61
+ * `mailto:` / `tel:` links. An erased contact (`state="purged"`) shows a neutral placeholder
62
+ * and no way to reach anyone, so a purge is never undone on screen by a stale address.
63
+ */
64
+ declare function ContactCard({ name, role, avatar, email, phone, actions, stats, href, renderLink, nameAs: NameTag, state, bare, labels: labelsProp, className, ...props }: ContactCardProps): react.JSX.Element;
65
+
66
+ export { ContactCard, type ContactCardLabels, type ContactCardProps, type ContactCardState, DEFAULT_CONTACT_CARD_LABELS, telHref };
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { cx } from "../cx.js";
4
+ import { fillLabel } from "../fill-label.js";
5
+ import { useUixLabels } from "../labels-context.js";
6
+ import { renderUixLink } from "../link.js";
7
+ import { ButtonLink } from "./Button.js";
8
+ const DEFAULT_CONTACT_CARD_LABELS = {
9
+ email: "Email",
10
+ call: "Call",
11
+ emailName: "Email {name}",
12
+ callName: "Call {name}",
13
+ purgedName: "Removed contact",
14
+ purged: "Personal data erased",
15
+ unavailable: "Contact details unavailable"
16
+ };
17
+ const telHref = (phone) => {
18
+ const extension = /[\s,;]*(?:ext\.?|extn\.?|extension|x|#|lok(?:al)?\.?)\s*:?\s*(\d+)\s*$/i.exec(phone);
19
+ const number = (extension ? phone.slice(0, extension.index) : phone).trim().replace(/(?!^\+)[^\d]/g, "");
20
+ return `tel:${number}${extension ? `;ext=${extension[1]}` : ""}`;
21
+ };
22
+ const PersonGlyph = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", focusable: "false", children: [
23
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "8", r: "4" }),
24
+ /* @__PURE__ */ jsx("path", { d: "M4 21a8 8 0 0 1 16 0" })
25
+ ] });
26
+ function ContactCard({
27
+ name,
28
+ role,
29
+ avatar,
30
+ email,
31
+ phone,
32
+ actions,
33
+ stats,
34
+ href,
35
+ renderLink,
36
+ nameAs: NameTag = "div",
37
+ state = "active",
38
+ bare = false,
39
+ labels: labelsProp,
40
+ className,
41
+ ...props
42
+ }) {
43
+ const uixLabels = useUixLabels();
44
+ const labels = { ...DEFAULT_CONTACT_CARD_LABELS, ...uixLabels.contactCard, ...labelsProp };
45
+ const purged = state === "purged";
46
+ const reachable = state === "active";
47
+ const shownName = purged ? labels.purgedName : name ?? "";
48
+ const note = purged ? labels.purged : state === "unavailable" ? labels.unavailable : null;
49
+ const nameContent = href && !purged ? renderUixLink(renderLink, { href, children: shownName }) : shownName;
50
+ const hasActions = reachable && (email || phone || actions);
51
+ const contact = /* @__PURE__ */ jsxs("div", { className: cx("uix-contact", bare && "uix-contact--bare", bare && className), "data-state": state, ...bare ? props : {}, children: [
52
+ purged || avatar == null ? /* @__PURE__ */ jsx("span", { className: "uix-avatar uix-avatar--lg uix-contact__placeholder", "aria-hidden": "true", children: /* @__PURE__ */ jsx(PersonGlyph, {}) }) : avatar,
53
+ /* @__PURE__ */ jsx(NameTag, { className: "uix-contact__name", children: nameContent }),
54
+ role != null && !purged && /* @__PURE__ */ jsx("div", { className: "uix-contact__role", children: role }),
55
+ note && /* @__PURE__ */ jsx("div", { className: "uix-contact__note", children: note }),
56
+ reachable && (email || phone) && /* @__PURE__ */ jsxs("div", { className: "uix-contact__details", children: [
57
+ email && /* @__PURE__ */ jsx("span", { className: "uix-contact__detail", children: email }),
58
+ phone && /* @__PURE__ */ jsx("span", { className: "uix-contact__detail", children: phone })
59
+ ] }),
60
+ stats != null && !purged && /* @__PURE__ */ jsx("div", { className: "uix-contact__stats", children: stats }),
61
+ hasActions && /* @__PURE__ */ jsxs("div", { className: "uix-contact__actions", children: [
62
+ email && /* @__PURE__ */ jsx(ButtonLink, { href: `mailto:${email}`, size: "sm", variant: "primary", "aria-label": fillLabel(labels.emailName, { name: shownName }), children: labels.email }),
63
+ phone && /* @__PURE__ */ jsx(ButtonLink, { href: telHref(phone), size: "sm", "aria-label": fillLabel(labels.callName, { name: shownName }), children: labels.call }),
64
+ actions
65
+ ] })
66
+ ] });
67
+ if (bare) return contact;
68
+ return /* @__PURE__ */ jsx("div", { className: cx("uix-card", className), ...props, children: contact });
69
+ }
70
+ export {
71
+ ContactCard,
72
+ DEFAULT_CONTACT_CARD_LABELS,
73
+ telHref
74
+ };
@@ -0,0 +1,24 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes } from 'react';
3
+
4
+ interface CountProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
5
+ /** The number shown. */
6
+ value: number;
7
+ /**
8
+ * Formats the number, e.g. `n > 99 ? '99+' : String(n)` or your i18n formatter. The default is
9
+ * `toLocaleString()` in the runtime's locale: pass `format` when the server renders it, so the
10
+ * server's and the browser's thousands separators cannot differ.
11
+ */
12
+ format?: (value: number) => string;
13
+ }
14
+ /**
15
+ * A number that ticks once when it changes (HAR-2587, motion standard §2.8): a badge count, a
16
+ * stat tile's value, an unread total. The new figure slides 4 px in from below when it went
17
+ * up and from above when it went down, with a fade; never on the first render, never a loop,
18
+ * never a count-up through the numbers between. Tabular figures, so neighbours do not shift.
19
+ * Under reduced motion it only fades. It announces nothing: say what changed where it
20
+ * matters (a toast, `ChangeHighlight announce`).
21
+ */
22
+ declare function Count({ value, format, className, ...props }: CountProps): react.JSX.Element;
23
+
24
+ export { Count, type CountProps };
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ import { cx } from "../cx.js";
5
+ function Count({ value, format, className, ...props }) {
6
+ const ref = useRef(null);
7
+ const previous = useRef(value);
8
+ useEffect(() => {
9
+ const before = previous.current;
10
+ previous.current = value;
11
+ const el = ref.current;
12
+ if (!el || Object.is(before, value) || !Number.isFinite(value) || !Number.isFinite(before)) return;
13
+ if (el.hasAttribute("data-uix-tick")) {
14
+ el.removeAttribute("data-uix-tick");
15
+ void el.offsetWidth;
16
+ }
17
+ el.setAttribute("data-uix-tick", value > before ? "up" : "down");
18
+ }, [value]);
19
+ useEffect(() => {
20
+ const el = ref.current;
21
+ if (!el) return void 0;
22
+ const done = (event) => {
23
+ if (event.target === el) el.removeAttribute("data-uix-tick");
24
+ };
25
+ el.addEventListener("animationend", done);
26
+ return () => el.removeEventListener("animationend", done);
27
+ }, []);
28
+ return /* @__PURE__ */ jsx("span", { ref, className: cx("uix-count", className), ...props, children: format ? format(value) : value.toLocaleString() });
29
+ }
30
+ export {
31
+ Count
32
+ };
@@ -0,0 +1,167 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+ import { UixRenderLink } from '../link.js';
4
+ import { FilterField, FilterValue, SummarizeFilterOptions } from '../filter-model.js';
5
+ import { TableDensity } from './Table.js';
6
+ import { SavedViewMenuProps, ViewMenuProps } from './TableControls.js';
7
+
8
+ /** Every word the workspace renders or announces. `{…}` are placeholders. */
9
+ interface DataWorkspaceLabels {
10
+ search: string;
11
+ searchPlaceholder: string;
12
+ addFilter: string;
13
+ clearFilters: string;
14
+ /** The saved-view trigger's name before the current view: "View: {name}". */
15
+ savedView: string;
16
+ view: string;
17
+ saveView: string;
18
+ saveViewAs: string;
19
+ maximize: string;
20
+ restore: string;
21
+ selectAll: string;
22
+ /** `{label}`: the row's id. */
23
+ selectRow: string;
24
+ /** `{count}` selected, in the bulk bar. */
25
+ selected: string;
26
+ bulkActions: string;
27
+ /** The record-id cell's ↗ button. `{label}`. */
28
+ open: string;
29
+ rowActions: string;
30
+ /** Offset footer: `{from}`, `{to}`, `{total}`. */
31
+ range: string;
32
+ rowsPerPage: string;
33
+ loading: string;
34
+ empty: string;
35
+ emptyDetail: string;
36
+ filteredEmpty: string;
37
+ filteredEmptyDetail: string;
38
+ error: string;
39
+ retry: string;
40
+ }
41
+ declare const DEFAULT_DATA_WORKSPACE_LABELS: DataWorkspaceLabels;
42
+ interface DataWorkspaceColumn<T> {
43
+ id: string;
44
+ header: ReactNode;
45
+ cell: (row: T) => ReactNode;
46
+ sortable?: boolean;
47
+ /** `end` for numbers and amounts. */
48
+ align?: 'start' | 'end';
49
+ /** A CSS width for the column, e.g. `12rem`. */
50
+ width?: string;
51
+ }
52
+ interface DataWorkspaceSort {
53
+ columnId: string;
54
+ direction: 'ascending' | 'descending';
55
+ }
56
+ /** The record-id column: the first column, the row's way into its record. */
57
+ interface DataWorkspaceIdColumn<T> {
58
+ header: ReactNode;
59
+ /** The id as shown, e.g. "INC-20418". Also names the row's checkbox and ↗ button. */
60
+ text: (row: T) => string;
61
+ /** The id button opens a peek of the record. */
62
+ onPeek?: (row: T) => void;
63
+ /** The ↗ link goes to the full record. */
64
+ href?: (row: T) => string;
65
+ renderLink?: UixRenderLink;
66
+ }
67
+ type DataWorkspacePagination = {
68
+ mode: 'offset';
69
+ page: number;
70
+ pageSize: number;
71
+ total: number;
72
+ onPageChange: (page: number) => void;
73
+ pageSizes?: readonly number[];
74
+ onPageSizeChange?: (size: number) => void;
75
+ } | {
76
+ mode: 'cursor';
77
+ hasPrevious: boolean;
78
+ hasNext: boolean;
79
+ onFirst?: () => void;
80
+ onPrevious: () => void;
81
+ onNext: () => void;
82
+ summary?: ReactNode;
83
+ pageSize?: number;
84
+ pageSizes?: readonly number[];
85
+ onPageSizeChange?: (size: number) => void;
86
+ };
87
+ interface DataWorkspaceProps<T> extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
88
+ /** Names the workspace region and the table. */
89
+ label: string;
90
+ rows: readonly T[];
91
+ getRowId: (row: T) => string;
92
+ columns: readonly DataWorkspaceColumn<T>[];
93
+ idColumn?: DataWorkspaceIdColumn<T>;
94
+ sort?: DataWorkspaceSort | null;
95
+ onSortChange?: (sort: DataWorkspaceSort | null) => void;
96
+ /** The selected row ids. Kept by id, so a refresh or a new page keeps them. */
97
+ selection?: ReadonlySet<string>;
98
+ onSelectionChange?: (selection: Set<string>) => void;
99
+ /** The bulk bar's actions for the selection (a `Menu` for the overflow). */
100
+ bulkActions?: (selectedIds: string[]) => ReactNode;
101
+ /**
102
+ * A row's actions (a `Menu`, quick buttons), in a column frozen at the right edge and sized to
103
+ * them. Return `null` for a row without actions; with none on the page there is no column.
104
+ */
105
+ rowActions?: (row: T) => ReactNode;
106
+ /** More props for a row, e.g. a data attribute that marks it changed (see ChangeHighlight, PR #164). */
107
+ getRowProps?: (row: T) => HTMLAttributes<HTMLTableRowElement> & Record<`data-${string}`, string | undefined>;
108
+ density?: TableDensity;
109
+ /**
110
+ * Toolbar: the search field. Ctrl/⌘ + / focuses it from inside the workspace, or from the page
111
+ * when nothing has focus and this is the page's first workspace.
112
+ */
113
+ search?: {
114
+ value: string;
115
+ onChange: (value: string) => void;
116
+ label?: string;
117
+ placeholder?: string;
118
+ };
119
+ /**
120
+ * Toolbar: filter chips and "+ Filter" over `FilterEditor`. A chip whose value holds ids
121
+ * restored from a URL or saved view asks `field.resolveLabels` for their names.
122
+ */
123
+ filters?: {
124
+ fields: readonly FilterField[];
125
+ values: Readonly<Record<string, FilterValue | undefined>>;
126
+ onChange: (fieldId: string, value: FilterValue | undefined) => void;
127
+ /** Rows matching each filter, shown on its chip. */
128
+ counts?: Readonly<Record<string, number>>;
129
+ summary?: SummarizeFilterOptions;
130
+ };
131
+ /** Toolbar: the saved-view trigger, named by the current view, opening a `SavedViewMenu`. */
132
+ savedViews?: {
133
+ current: ReactNode;
134
+ menu: SavedViewMenuProps;
135
+ };
136
+ /** Toolbar: the View button, opening a `ViewMenu` (columns, density). */
137
+ viewMenu?: ViewMenuProps;
138
+ /** The view differs from its saved version: Save changes and Save as show. */
139
+ viewChanged?: boolean;
140
+ onSaveView?: () => void;
141
+ onSaveViewAs?: () => void;
142
+ /** Toolbar: a maximize toggle; Escape restores, unless an open popover or menu takes it first. */
143
+ maximized?: boolean;
144
+ onMaximizedChange?: (maximized: boolean) => void;
145
+ /** Toolbar: the product's own actions at the end ("New incident"). */
146
+ toolbarEnd?: ReactNode;
147
+ pagination?: DataWorkspacePagination;
148
+ /** `loading`: the first load (skeleton rows). `error`: with `onRetry`. */
149
+ status?: 'ready' | 'loading' | 'error';
150
+ /** A refetch (filter, sort, page, saved view): the rows stay under `TableWrap refreshing`. */
151
+ refreshing?: boolean;
152
+ onRetry?: () => void;
153
+ labels?: Partial<DataWorkspaceLabels>;
154
+ }
155
+ /**
156
+ * The generic presentation half of a product's data table (HAR-1388; TENSOR `data-table.tsx`,
157
+ * MOTUS `UixDataWorkspace.tsx`; UIx ADR-0005). Composes the kit's pieces in one order: saved
158
+ * view · Save changes / Save as (when the view changed) · filter chips and "+ Filter" ·
159
+ * search (Ctrl/⌘ + /) · View · maximize · the product's actions; a `Table` with a record-id cell (id → peek, ↗ → record),
160
+ * selection with Shift-click ranges, a frozen row-actions column and a `BulkBar`; an "x–y of N"
161
+ * footer with rows per page and `Pagination` (offset or cursor); first-load, empty,
162
+ * filtered-empty and error states, and a refetch that keeps the rows. Prop-driven: the product
163
+ * keeps its surface registry, URL state, data fetching and permissions.
164
+ */
165
+ declare function DataWorkspace<T>({ label, rows, getRowId, columns, idColumn, sort, onSortChange, selection, onSelectionChange, bulkActions, rowActions, getRowProps, density, search, filters, savedViews, viewMenu, viewChanged, onSaveView, onSaveViewAs, maximized, onMaximizedChange, toolbarEnd, pagination, status, refreshing, onRetry, labels: labelOverrides, className, ...props }: DataWorkspaceProps<T>): react.JSX.Element;
166
+
167
+ export { DEFAULT_DATA_WORKSPACE_LABELS, DataWorkspace, type DataWorkspaceColumn, type DataWorkspaceIdColumn, type DataWorkspaceLabels, type DataWorkspacePagination, type DataWorkspaceProps, type DataWorkspaceSort };