@tensor_1/react 2.10.0 → 2.12.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 (81) hide show
  1. package/README.md +10 -1
  2. package/dist/ChartCore-Bt1C84ty.d.cts +22 -0
  3. package/dist/chart-preset.cjs +168 -0
  4. package/dist/chart-preset.d.cts +9 -0
  5. package/dist/chart-preset.d.ts +9 -0
  6. package/dist/chart-preset.js +35 -0
  7. package/dist/chart.cjs +58 -41
  8. package/dist/chart.d.cts +6 -21
  9. package/dist/chart.d.ts +2 -1
  10. package/dist/components/Alert.js +7 -15
  11. package/dist/components/AppShell.d.ts +1 -3
  12. package/dist/components/AppShell.js +1 -3
  13. package/dist/components/Avatar.js +1 -2
  14. package/dist/components/Button.js +16 -32
  15. package/dist/components/Card.d.ts +1 -3
  16. package/dist/components/Card.js +2 -2
  17. package/dist/components/Chart.d.ts +6 -21
  18. package/dist/components/Chart.js +5 -85
  19. package/dist/components/ChartCore.d.ts +33 -0
  20. package/dist/components/ChartCore.js +100 -0
  21. package/dist/components/CommandPalette.d.ts +2 -4
  22. package/dist/components/CommandPalette.js +13 -66
  23. package/dist/components/Comments.d.ts +1 -5
  24. package/dist/components/Comments.js +1 -1
  25. package/dist/components/Composer.d.ts +1 -8
  26. package/dist/components/Composer.js +2 -7
  27. package/dist/components/DetailLayout.js +1 -1
  28. package/dist/components/Drawer.d.ts +4 -3
  29. package/dist/components/Drawer.js +4 -6
  30. package/dist/components/Field.js +3 -6
  31. package/dist/components/Inbox.d.ts +3 -13
  32. package/dist/components/Inbox.js +3 -62
  33. package/dist/components/Input.d.ts +2 -13
  34. package/dist/components/Input.js +5 -20
  35. package/dist/components/Kanban.d.ts +3 -15
  36. package/dist/components/Kanban.js +10 -42
  37. package/dist/components/Meter.d.ts +1 -3
  38. package/dist/components/Meter.js +1 -10
  39. package/dist/components/Modal.d.ts +5 -3
  40. package/dist/components/Modal.js +4 -6
  41. package/dist/components/NavFavourites.js +35 -119
  42. package/dist/components/PageHeader.d.ts +1 -3
  43. package/dist/components/PageHeader.js +2 -2
  44. package/dist/components/Peek.d.ts +4 -3
  45. package/dist/components/Peek.js +6 -9
  46. package/dist/components/Progress.d.ts +1 -3
  47. package/dist/components/Progress.js +3 -5
  48. package/dist/components/Radio.d.ts +1 -3
  49. package/dist/components/Radio.js +2 -6
  50. package/dist/components/Segmented.js +3 -2
  51. package/dist/components/Sidebar.js +2 -4
  52. package/dist/components/Spinner.d.ts +1 -3
  53. package/dist/components/Spinner.js +3 -3
  54. package/dist/components/Stat.js +1 -5
  55. package/dist/components/States.d.ts +1 -3
  56. package/dist/components/States.js +2 -8
  57. package/dist/components/Table.d.ts +2 -9
  58. package/dist/components/Table.js +8 -11
  59. package/dist/components/Tabs.d.ts +1 -13
  60. package/dist/components/Tabs.js +4 -78
  61. package/dist/components/Timeline.d.ts +3 -3
  62. package/dist/components/Timeline.js +3 -3
  63. package/dist/components/Toast.js +5 -42
  64. package/dist/components/Tooltip.d.ts +1 -3
  65. package/dist/components/Tooltip.js +5 -44
  66. package/dist/components/Tree.d.ts +0 -2
  67. package/dist/components/Tree.js +4 -26
  68. package/dist/hooks/useDialog.d.ts +1 -1
  69. package/dist/hooks/useDialog.js +2 -17
  70. package/dist/hooks/useTable.d.ts +0 -5
  71. package/dist/hooks/useTable.js +12 -27
  72. package/dist/hooks/useVirtualRows.d.ts +27 -0
  73. package/dist/hooks/useVirtualRows.js +50 -0
  74. package/dist/index.cjs +291 -760
  75. package/dist/index.d.cts +61 -127
  76. package/dist/index.d.ts +3 -2
  77. package/dist/index.js +4 -3
  78. package/dist/table-engine.js +8 -6
  79. package/dist/tree-model.d.ts +0 -4
  80. package/dist/tree-model.js +0 -8
  81. package/package.json +16 -2
@@ -1,16 +1,14 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { cx } from "../cx.js";
3
- function Progress({ value = 0, max = 100, indeterminate, label, className, ...props }) {
4
- const clamped = Math.max(0, Math.min(max || 100, value));
5
- const pct = clamped / (max || 100) * 100;
3
+ function Progress({ value = 0, max = 100, indeterminate, className, ...props }) {
4
+ const pct = Math.max(0, Math.min(100, value / (max || 100) * 100));
6
5
  return /* @__PURE__ */ jsx(
7
6
  "div",
8
7
  {
9
8
  role: "progressbar",
10
9
  "aria-valuemin": 0,
11
10
  "aria-valuemax": max,
12
- "aria-valuenow": indeterminate ? void 0 : clamped,
13
- "aria-label": label,
11
+ "aria-valuenow": indeterminate ? void 0 : value,
14
12
  className: cx("uix-progress", indeterminate && "uix-progress--indeterminate", className),
15
13
  ...props,
16
14
  children: /* @__PURE__ */ jsx("div", { className: "uix-progress__bar", style: indeterminate ? void 0 : { width: `${pct}%` } })
@@ -8,9 +8,7 @@ declare const Radio: react.ForwardRefExoticComponent<RadioProps & react.RefAttri
8
8
  interface RadioGroupProps {
9
9
  children: ReactNode;
10
10
  className?: string;
11
- /** Group name; when set the group renders as fieldset/legend so it's announced with each radio. */
12
- label?: ReactNode;
13
11
  }
14
- declare function RadioGroup({ children, className, label }: RadioGroupProps): react.JSX.Element;
12
+ declare function RadioGroup({ children, className }: RadioGroupProps): react.JSX.Element;
15
13
 
16
14
  export { Radio, RadioGroup, type RadioGroupProps, type RadioProps };
@@ -9,12 +9,8 @@ const Radio = forwardRef(
9
9
  ] })
10
10
  );
11
11
  Radio.displayName = "Radio";
12
- function RadioGroup({ children, className, label }) {
13
- if (label == null) return /* @__PURE__ */ jsx("div", { className: cx("uix-radio-group", className), children });
14
- return /* @__PURE__ */ jsxs("fieldset", { className: cx("uix-radio-group", className), children: [
15
- /* @__PURE__ */ jsx("legend", { className: "uix-radio-group__legend", children: label }),
16
- children
17
- ] });
12
+ function RadioGroup({ children, className }) {
13
+ return /* @__PURE__ */ jsx("div", { className: cx("uix-radio-group", className), children });
18
14
  }
19
15
  export {
20
16
  Radio,
@@ -1,10 +1,11 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { createContext, useContext } from "react";
3
+ import { createContext, useContext, useMemo } from "react";
4
4
  import { cx } from "../cx.js";
5
5
  const SegmentedCtx = createContext({});
6
6
  function Segmented({ value, onChange, children, className, ...props }) {
7
- return /* @__PURE__ */ jsx(SegmentedCtx.Provider, { value: { value, onChange }, children: /* @__PURE__ */ jsx("div", { role: "group", className: cx("uix-segmented", className), ...props, children }) });
7
+ const contextValue = useMemo(() => ({ value, onChange }), [value, onChange]);
8
+ return /* @__PURE__ */ jsx(SegmentedCtx.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { role: "group", className: cx("uix-segmented", className), ...props, children }) });
8
9
  }
9
10
  function SegmentedOption({
10
11
  value,
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useId, useState } from "react";
3
+ import { 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
6
  function Sidebar({ collapsed, onToggle, brand, toggleIcon, children, className, ...props }) {
@@ -55,14 +55,12 @@ function NavItem({ icon, badge, active, as: Tag = "a", children, className, ...p
55
55
  }
56
56
  function NavGroup({ icon, label, children, defaultExpanded = true }) {
57
57
  const [expanded, setExpanded] = useState(defaultExpanded);
58
- const panelId = useId();
59
58
  return /* @__PURE__ */ jsxs("div", { className: "uix-navgroup", children: [
60
59
  /* @__PURE__ */ jsxs(
61
60
  "button",
62
61
  {
63
62
  className: "uix-navitem uix-navgroup__trigger",
64
63
  "aria-expanded": expanded,
65
- "aria-controls": panelId,
66
64
  onClick: () => setExpanded((v) => !v),
67
65
  children: [
68
66
  icon && /* @__PURE__ */ jsx("span", { className: "uix-navitem__icon", "aria-hidden": "true", children: icon }),
@@ -71,7 +69,7 @@ function NavGroup({ icon, label, children, defaultExpanded = true }) {
71
69
  ]
72
70
  }
73
71
  ),
74
- /* @__PURE__ */ jsx("div", { className: "uix-navgroup__panel", id: panelId, children: /* @__PURE__ */ jsx("div", { children }) })
72
+ /* @__PURE__ */ jsx("div", { className: "uix-navgroup__panel", children: /* @__PURE__ */ jsx("div", { children }) })
75
73
  ] });
76
74
  }
77
75
  function SubNavItem({ active, as: Tag = "a", children, className, ...props }) {
@@ -4,9 +4,7 @@ import { HTMLAttributes } from 'react';
4
4
  interface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {
5
5
  size?: 'md' | 'lg';
6
6
  accent?: boolean;
7
- /** Announced loading text (default "Loading…"). */
8
- label?: string;
9
7
  }
10
- declare function Spinner({ size, accent, label, className, ...props }: SpinnerProps): react.JSX.Element;
8
+ declare function Spinner({ size, accent, className, ...props }: SpinnerProps): react.JSX.Element;
11
9
 
12
10
  export { Spinner, type SpinnerProps };
@@ -1,13 +1,13 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { cx } from "../cx.js";
3
- function Spinner({ size = "md", accent, label, className, ...props }) {
3
+ function Spinner({ size = "md", accent, className, ...props }) {
4
4
  return /* @__PURE__ */ jsx(
5
5
  "span",
6
6
  {
7
7
  className: cx("uix-spinner", accent && "uix-spinner--accent", size === "lg" && "uix-spinner--lg", className),
8
8
  role: "status",
9
- ...props,
10
- children: /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: label ?? "Loading\u2026" })
9
+ "aria-label": "Loading",
10
+ ...props
11
11
  }
12
12
  );
13
13
  }
@@ -8,11 +8,7 @@ function Stat({ label, value, icon, meta, trend, className, ...props }) {
8
8
  ] }),
9
9
  /* @__PURE__ */ jsx("div", { className: "uix-stat__value", children: value }),
10
10
  (meta != null || trend != null) && /* @__PURE__ */ jsxs("div", { className: "uix-stat__meta", children: [
11
- trend != null && /* @__PURE__ */ jsxs("span", { className: cx("uix-stat__trend", `uix-stat__trend--${trend.direction}`), children: [
12
- /* @__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" }) }),
13
- /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: trend.direction === "up" ? "up" : "down" }),
14
- trend.label
15
- ] }),
11
+ trend != null && /* @__PURE__ */ jsx("span", { className: cx("uix-stat__trend", `uix-stat__trend--${trend.direction}`), children: trend.label }),
16
12
  meta
17
13
  ] })
18
14
  ] });
@@ -31,10 +31,8 @@ declare function Skeleton({ variant, width, height, className, style, ...props }
31
31
  interface LoadingStateProps extends HTMLAttributes<HTMLDivElement> {
32
32
  /** Number of skeleton rows to render. */
33
33
  rows?: number;
34
- /** Announced loading text (default "Loading"). */
35
- label?: string;
36
34
  }
37
35
  /** A stack of skeleton rows for list/section loading. `role="status"`. */
38
- declare function LoadingState({ rows, label, className, ...props }: LoadingStateProps): react.JSX.Element;
36
+ declare function LoadingState({ rows, className, ...props }: LoadingStateProps): react.JSX.Element;
39
37
 
40
38
  export { EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, LoadingState, type LoadingStateProps, Skeleton, type SkeletonProps };
@@ -32,14 +32,8 @@ function Skeleton({ variant = "block", width, height, className, style, ...props
32
32
  }
33
33
  );
34
34
  }
35
- function LoadingState({ rows = 3, label, className, ...props }) {
36
- return (
37
- // no aria-busy: busy=true tells AT the region isn't ready and suppresses the announcement (UIX-A11Y-4)
38
- /* @__PURE__ */ jsxs("div", { className: cx("uix-stack", className), role: "status", ...props, children: [
39
- /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: label ?? "Loading" }),
40
- Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: `${92 - i % 3 * 14}%` }, i))
41
- ] })
42
- );
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)) });
43
37
  }
44
38
  export {
45
39
  EmptyState,
@@ -2,14 +2,9 @@ import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode, ButtonHTMLAttributes, TdHTMLAttributes, TableHTMLAttributes, ThHTMLAttributes } from 'react';
3
3
 
4
4
  interface TableWrapProps extends HTMLAttributes<HTMLDivElement> {
5
- /**
6
- * Polite live-region text for table state changes — "Sorted by …", "N results",
7
- * "N selected". Pass `useTable().announcement` straight through (UIX-A11Y-2).
8
- */
9
- announcement?: string;
10
5
  children?: ReactNode;
11
6
  }
12
- declare function TableWrap({ announcement, children, className, ...props }: TableWrapProps): react.JSX.Element;
7
+ declare const TableWrap: react.ForwardRefExoticComponent<TableWrapProps & react.RefAttributes<HTMLDivElement>>;
13
8
  type TableDensity = 'compact' | 'standard' | 'comfortable';
14
9
  type SortDirection = 'ascending' | 'descending' | 'none';
15
10
  interface TableProps extends TableHTMLAttributes<HTMLTableElement> {
@@ -58,11 +53,9 @@ interface RowActionProps extends ButtonHTMLAttributes<HTMLButtonElement> {
58
53
  declare function RowAction({ children, className, type, ...props }: RowActionProps): react.JSX.Element;
59
54
  interface ExpandToggleProps extends ButtonHTMLAttributes<HTMLButtonElement> {
60
55
  expanded?: boolean;
61
- /** id of the detail row this toggle controls → `aria-controls` (UIX-A11Y-2). */
62
- controls?: string;
63
56
  }
64
57
  /** Chevron button that expands/collapses an inline detail row. */
65
- declare function ExpandToggle({ expanded, controls, className, type, ...props }: ExpandToggleProps): react.JSX.Element;
58
+ declare function ExpandToggle({ expanded, className, type, ...props }: ExpandToggleProps): react.JSX.Element;
66
59
  /** Emphasised primary cell text. */
67
60
  declare function CellStrong({ children, className, ...props }: HTMLAttributes<HTMLSpanElement>): react.JSX.Element;
68
61
  /** Secondary line under a primary cell value (muted, meta size). */
@@ -1,12 +1,10 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from "react";
2
3
  import { cx } from "../cx.js";
3
4
  import { highlightSegments } from "../table-engine.js";
4
- function TableWrap({ announcement, children, className, ...props }) {
5
- return /* @__PURE__ */ jsxs("div", { className: cx("uix-table-wrap", className), ...props, children: [
6
- announcement != null && /* @__PURE__ */ jsx("div", { role: "status", className: "uix-visually-hidden", children: announcement }),
7
- children
8
- ] });
9
- }
5
+ const TableWrap = forwardRef(function TableWrap2({ children, className, ...props }, ref) {
6
+ return /* @__PURE__ */ jsx("div", { ref, className: cx("uix-table-wrap", className), ...props, children });
7
+ });
10
8
  function Table({
11
9
  density = "standard",
12
10
  zebra = true,
@@ -44,9 +42,9 @@ function Th({ sortable, sortDirection, sortOrder, onSort, className, children, o
44
42
  "data-sort": sortable || void 0,
45
43
  "data-sort-order": sortOrder != null && sortOrder > 0 ? sortOrder : void 0,
46
44
  "aria-sort": sortDirection && sortDirection !== "none" ? sortDirection : void 0,
47
- onClick: sortable && onSort ? void 0 : onClick,
45
+ onClick: sortable ? onSort ?? onClick : onClick,
48
46
  ...props,
49
- children: sortable ? /* @__PURE__ */ jsx("button", { type: "button", className: "uix-th__sortbtn", onClick: onSort, children }) : children
47
+ children
50
48
  }
51
49
  );
52
50
  }
@@ -58,7 +56,7 @@ function Tr({ selected, pinned, className, children, ...props }) {
58
56
  "tr",
59
57
  {
60
58
  className,
61
- "data-selected": selected || void 0,
59
+ "aria-selected": selected || void 0,
62
60
  "data-pinned": pinned || void 0,
63
61
  ...props,
64
62
  children
@@ -81,14 +79,13 @@ function RowActions({ children, className, ...props }) {
81
79
  function RowAction({ children, className, type = "button", ...props }) {
82
80
  return /* @__PURE__ */ jsx("button", { type, className: cx("uix-rowact", className), ...props, children });
83
81
  }
84
- function ExpandToggle({ expanded, controls, className, type = "button", ...props }) {
82
+ function ExpandToggle({ expanded, className, type = "button", ...props }) {
85
83
  return /* @__PURE__ */ jsx(
86
84
  "button",
87
85
  {
88
86
  type,
89
87
  className: cx("uix-table__expand", className),
90
88
  "aria-expanded": expanded,
91
- "aria-controls": controls,
92
89
  "aria-label": expanded ? "Collapse row" : "Expand row",
93
90
  ...props,
94
91
  children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M6 4l4 4-4 4" }) })
@@ -15,17 +15,5 @@ interface TabProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'onChange'> {
15
15
  disabled?: boolean;
16
16
  }
17
17
  declare function Tab({ value, children, disabled, className, onClick, ...props }: TabProps): react.JSX.Element;
18
- interface TabPanelProps extends HTMLAttributes<HTMLDivElement> {
19
- /** The owning `<Tab>`'s value — the panel renders only while that tab is selected. */
20
- value: string;
21
- children?: ReactNode;
22
- }
23
- /**
24
- * The tabpanel paired with a `<Tab>` by `value` (UIX-A11Y-2): labelled by its tab,
25
- * `tabIndex 0` so Tab from the tablist lands in the content, rendered only while
26
- * selected. Place it as a direct child of `<Tabs>` — it is hoisted out of the tablist —
27
- * or anywhere the Tabs context reaches.
28
- */
29
- declare function TabPanel({ value, children, ...props }: TabPanelProps): react.JSX.Element | null;
30
18
 
31
- export { Tab, TabPanel, type TabPanelProps, type TabProps, Tabs, type TabsProps };
19
+ export { Tab, type TabProps, Tabs, type TabsProps };
@@ -1,66 +1,11 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import { Children, createContext, isValidElement, useContext, useEffect, useId, useRef } from "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useMemo } from "react";
4
4
  import { cx } from "../cx.js";
5
5
  const TabsCtx = createContext({});
6
6
  function Tabs({ variant = "line", value, onChange, children, className }) {
7
- const baseId = useId();
8
- const listRef = useRef(null);
9
- const kids = Children.toArray(children);
10
- const panels = kids.filter((k) => isValidElement(k) && k.type === TabPanel);
11
- const tabs = kids.filter((k) => !(isValidElement(k) && k.type === TabPanel));
12
- useEffect(() => {
13
- const list = listRef.current;
14
- if (!list) return;
15
- const all = Array.from(list.querySelectorAll('[role="tab"]'));
16
- const enabled = all.filter((t) => !t.matches(":disabled"));
17
- const active = enabled.find((t) => t.getAttribute("aria-selected") === "true") ?? enabled[0];
18
- for (const t of all) t.tabIndex = t === active ? 0 : -1;
19
- });
20
- const onKeyDown = (e) => {
21
- const items = Array.from(
22
- listRef.current?.querySelectorAll('[role="tab"]:not(:disabled)') ?? []
23
- );
24
- const cur = e.target.closest('[role="tab"]');
25
- const idx = cur ? items.indexOf(cur) : -1;
26
- if (idx < 0 || items.length === 0) return;
27
- let next;
28
- switch (e.key) {
29
- case "ArrowRight":
30
- next = (idx + 1) % items.length;
31
- break;
32
- case "ArrowLeft":
33
- next = (idx - 1 + items.length) % items.length;
34
- break;
35
- case "Home":
36
- next = 0;
37
- break;
38
- case "End":
39
- next = items.length - 1;
40
- break;
41
- default:
42
- return;
43
- }
44
- e.preventDefault();
45
- const target = items[next];
46
- if (target) {
47
- target.focus();
48
- target.click();
49
- }
50
- };
51
- return /* @__PURE__ */ jsxs(TabsCtx.Provider, { value: { value, onChange, baseId }, children: [
52
- /* @__PURE__ */ jsx(
53
- "div",
54
- {
55
- ref: listRef,
56
- role: "tablist",
57
- className: cx("uix-tabs", `uix-tabs--${variant}`, className),
58
- onKeyDown,
59
- children: tabs
60
- }
61
- ),
62
- panels
63
- ] });
7
+ const contextValue = useMemo(() => ({ value, onChange }), [value, onChange]);
8
+ return /* @__PURE__ */ jsx(TabsCtx.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { role: "tablist", className: cx("uix-tabs", `uix-tabs--${variant}`, className), children }) });
64
9
  }
65
10
  function Tab({ value, children, disabled, className, onClick, ...props }) {
66
11
  const ctx = useContext(TabsCtx);
@@ -69,11 +14,8 @@ function Tab({ value, children, disabled, className, onClick, ...props }) {
69
14
  "button",
70
15
  {
71
16
  role: "tab",
72
- id: ctx.baseId ? `${ctx.baseId}-tab-${value}` : void 0,
73
- "aria-controls": ctx.baseId ? `${ctx.baseId}-panel-${value}` : void 0,
74
17
  className: cx("uix-tab", className),
75
18
  "aria-selected": selected,
76
- tabIndex: selected ? 0 : -1,
77
19
  disabled,
78
20
  onClick: (e) => {
79
21
  ctx.onChange?.(value);
@@ -84,23 +26,7 @@ function Tab({ value, children, disabled, className, onClick, ...props }) {
84
26
  }
85
27
  );
86
28
  }
87
- function TabPanel({ value, children, ...props }) {
88
- const ctx = useContext(TabsCtx);
89
- if (ctx.value !== value) return null;
90
- return /* @__PURE__ */ jsx(
91
- "div",
92
- {
93
- role: "tabpanel",
94
- id: ctx.baseId ? `${ctx.baseId}-panel-${value}` : void 0,
95
- "aria-labelledby": ctx.baseId ? `${ctx.baseId}-tab-${value}` : void 0,
96
- tabIndex: 0,
97
- ...props,
98
- children
99
- }
100
- );
101
- }
102
29
  export {
103
30
  Tab,
104
- TabPanel,
105
31
  Tabs
106
32
  };
@@ -1,12 +1,12 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
- interface TimelineProps extends HTMLAttributes<HTMLOListElement> {
4
+ interface TimelineProps extends HTMLAttributes<HTMLDivElement> {
5
5
  children?: ReactNode;
6
6
  }
7
- /** Activity timeline container over `.uix-timeline`. Ordered list so AT reads entry count + sequence (UIX-A11Y-4). */
7
+ /** Activity timeline container over `.uix-timeline`. */
8
8
  declare function Timeline({ children, className, ...props }: TimelineProps): react.JSX.Element;
9
- interface TimelineItemProps extends HTMLAttributes<HTMLLIElement> {
9
+ interface TimelineItemProps extends HTMLAttributes<HTMLDivElement> {
10
10
  /**
11
11
  * Custom rail node — an icon puck, an avatar, a tinted dot. Defaults to the
12
12
  * accent `.uix-timeline__node` dot. Supply this to make a heterogeneous feed
@@ -1,11 +1,11 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cx } from "../cx.js";
3
3
  function Timeline({ children, className, ...props }) {
4
- return /* @__PURE__ */ jsx("ol", { className: cx("uix-timeline", className), ...props, children });
4
+ return /* @__PURE__ */ jsx("div", { className: cx("uix-timeline", className), ...props, children });
5
5
  }
6
6
  function TimelineItem({ node, meta, children, className, ...props }) {
7
- return /* @__PURE__ */ jsxs("li", { className: cx("uix-timeline__item", className), ...props, children: [
8
- /* @__PURE__ */ jsxs("div", { className: "uix-timeline__rail", "aria-hidden": "true", children: [
7
+ return /* @__PURE__ */ jsxs("div", { className: cx("uix-timeline__item", className), ...props, children: [
8
+ /* @__PURE__ */ jsxs("div", { className: "uix-timeline__rail", children: [
9
9
  node ?? /* @__PURE__ */ jsx("span", { className: "uix-timeline__node" }),
10
10
  /* @__PURE__ */ jsx("span", { className: "uix-timeline__line" })
11
11
  ] }),
@@ -1,65 +1,28 @@
1
- "use client";
2
1
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
4
2
  import { cx } from "../cx.js";
5
- const ToasterContext = createContext(null);
6
3
  function Toast({ title, message, tone, icon, onClose, leaving, className, ...props }) {
7
4
  const assertive = tone === "danger";
8
- const toaster = useContext(ToasterContext);
9
- const bodyRef = useRef(null);
10
- useEffect(() => {
11
- if (assertive || !toaster) return;
12
- const text = bodyRef.current?.textContent?.trim();
13
- if (text) toaster.announce(text);
14
- }, []);
15
- const handleClose = (e) => {
16
- const btn = e.currentTarget;
17
- if (document.activeElement === btn) {
18
- const toasterEl = btn.closest(".uix-toaster");
19
- if (toasterEl) {
20
- const closes = Array.from(toasterEl.querySelectorAll(".uix-toast__close"));
21
- const i = closes.indexOf(btn);
22
- (closes[i + 1] ?? closes[i - 1])?.focus();
23
- }
24
- }
25
- onClose?.();
26
- };
27
- const ownLiveRegion = assertive || !toaster;
28
5
  return /* @__PURE__ */ jsxs(
29
6
  "div",
30
7
  {
31
8
  className: cx("uix-toast", tone && `uix-toast--${tone}`, className),
32
9
  "data-leaving": leaving || void 0,
33
- role: ownLiveRegion ? assertive ? "alert" : "status" : void 0,
34
- "aria-live": ownLiveRegion ? assertive ? "assertive" : "polite" : void 0,
10
+ role: assertive ? "alert" : "status",
11
+ "aria-live": assertive ? "assertive" : "polite",
35
12
  ...props,
36
13
  children: [
37
14
  icon && /* @__PURE__ */ jsx("div", { className: "uix-toast__icon", "aria-hidden": "true", children: icon }),
38
- /* @__PURE__ */ jsxs("div", { className: "uix-toast__body", ref: bodyRef, children: [
15
+ /* @__PURE__ */ jsxs("div", { className: "uix-toast__body", children: [
39
16
  title && /* @__PURE__ */ jsx("div", { className: "uix-toast__title", children: title }),
40
17
  message && /* @__PURE__ */ jsx("div", { className: "uix-toast__msg", children: message })
41
18
  ] }),
42
- onClose && /* @__PURE__ */ jsx("button", { className: "uix-toast__close", onClick: handleClose, "aria-label": "Dismiss", children: "\xD7" })
19
+ onClose && /* @__PURE__ */ jsx("button", { className: "uix-toast__close", onClick: onClose, "aria-label": "Dismiss", children: "\xD7" })
43
20
  ]
44
21
  }
45
22
  );
46
23
  }
47
24
  function Toaster({ children, className, ...props }) {
48
- const [announced, setAnnounced] = useState("");
49
- const clearTimer = useRef(null);
50
- const announce = useCallback((text) => {
51
- setAnnounced((cur) => cur ? `${cur} ${text}` : text);
52
- if (clearTimer.current != null) clearTimeout(clearTimer.current);
53
- clearTimer.current = window.setTimeout(() => setAnnounced(""), 3e3);
54
- }, []);
55
- useEffect(() => () => {
56
- if (clearTimer.current != null) clearTimeout(clearTimer.current);
57
- }, []);
58
- const ctx = useMemo(() => ({ announce }), [announce]);
59
- return /* @__PURE__ */ jsx(ToasterContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxs("div", { className: cx("uix-toaster", className), role: "region", "aria-label": "Notifications", ...props, children: [
60
- /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", role: "status", "aria-live": "polite", children: announced }),
61
- children
62
- ] }) });
25
+ return /* @__PURE__ */ jsx("div", { className: cx("uix-toaster", className), ...props, children });
63
26
  }
64
27
  export {
65
28
  Toast,
@@ -13,9 +13,7 @@ interface TooltipProps extends HTMLAttributes<HTMLSpanElement> {
13
13
  * Tooltip whose bubble renders in the top layer via the native Popover API, so it
14
14
  * escapes any `overflow: hidden/scroll` ancestor that would clip the old CSS-only
15
15
  * `[data-uix-tip]` tooltip (UIX-FIX-02). Positioned by the shared overlay engine
16
- * (flip/shift), shown on hover and keyboard focus, dismissed on blur or Escape
17
- * (document-level, per WCAG 1.4.13), and hoverable: the bubble stays open while
18
- * the pointer is over it (UIX-A11Y-1).
16
+ * (flip/shift), shown on hover and keyboard focus, dismissed on blur or Escape.
19
17
  */
20
18
  declare function Tooltip({ label, placement, className, children, ...props }: TooltipProps): react.JSX.Element;
21
19
 
@@ -1,23 +1,15 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { cloneElement, isValidElement, useEffect, useId, useRef, useState } from "react";
3
+ import { useEffect, useId, useRef, useState } from "react";
4
4
  import { cx } from "../cx.js";
5
5
  import { useAnchoredPosition } from "../hooks/useAnchoredPosition.js";
6
6
  function Tooltip({ label, placement = "top", className, children, ...props }) {
7
7
  const triggerRef = useRef(null);
8
8
  const bubbleRef = useRef(null);
9
- const closeTimer = useRef(null);
10
9
  const [open, setOpen] = useState(false);
11
10
  const id = useId();
12
11
  useAnchoredPosition(triggerRef, bubbleRef, { open, placement, offset: 6 });
13
- const cancelClose = () => {
14
- if (closeTimer.current != null) {
15
- clearTimeout(closeTimer.current);
16
- closeTimer.current = null;
17
- }
18
- };
19
12
  const show = () => {
20
- cancelClose();
21
13
  const b = bubbleRef.current;
22
14
  if (b && !b.matches(":popover-open")) {
23
15
  try {
@@ -28,7 +20,6 @@ function Tooltip({ label, placement = "top", className, children, ...props }) {
28
20
  setOpen(true);
29
21
  };
30
22
  const hide = () => {
31
- cancelClose();
32
23
  const b = bubbleRef.current;
33
24
  if (b && b.matches(":popover-open")) {
34
25
  try {
@@ -38,20 +29,7 @@ function Tooltip({ label, placement = "top", className, children, ...props }) {
38
29
  }
39
30
  setOpen(false);
40
31
  };
41
- const scheduleHide = () => {
42
- cancelClose();
43
- closeTimer.current = window.setTimeout(hide, 100);
44
- };
45
- useEffect(() => {
46
- if (!open) return;
47
- const onKey = (e) => {
48
- if (e.key === "Escape") hide();
49
- };
50
- document.addEventListener("keydown", onKey);
51
- return () => document.removeEventListener("keydown", onKey);
52
- }, [open]);
53
32
  useEffect(() => () => {
54
- if (closeTimer.current != null) clearTimeout(closeTimer.current);
55
33
  const b = bubbleRef.current;
56
34
  if (b && b.matches(":popover-open")) {
57
35
  try {
@@ -61,19 +39,14 @@ function Tooltip({ label, placement = "top", className, children, ...props }) {
61
39
  }
62
40
  }, []);
63
41
  const bubbleAttr = { popover: "manual" };
64
- const single = isValidElement(children);
65
- const child = single ? cloneElement(children, {
66
- "aria-describedby": [children.props["aria-describedby"], id].filter(Boolean).join(" ")
67
- }) : children;
68
42
  return /* @__PURE__ */ jsxs(
69
43
  "span",
70
44
  {
71
45
  ref: triggerRef,
72
46
  className: cx("uix-tooltip", className),
73
- "aria-describedby": single ? void 0 : id,
74
- tabIndex: single ? void 0 : 0,
47
+ "aria-describedby": id,
75
48
  onMouseEnter: show,
76
- onMouseLeave: scheduleHide,
49
+ onMouseLeave: hide,
77
50
  onFocus: show,
78
51
  onBlur: hide,
79
52
  onKeyDown: (e) => {
@@ -81,20 +54,8 @@ function Tooltip({ label, placement = "top", className, children, ...props }) {
81
54
  },
82
55
  ...props,
83
56
  children: [
84
- child,
85
- /* @__PURE__ */ jsx(
86
- "span",
87
- {
88
- ref: bubbleRef,
89
- id,
90
- role: "tooltip",
91
- className: "uix-tooltip__bubble",
92
- onMouseEnter: cancelClose,
93
- onMouseLeave: scheduleHide,
94
- ...bubbleAttr,
95
- children: label
96
- }
97
- )
57
+ children,
58
+ /* @__PURE__ */ jsx("span", { ref: bubbleRef, id, role: "tooltip", className: "uix-tooltip__bubble", ...bubbleAttr, children: label })
98
59
  ]
99
60
  }
100
61
  );
@@ -4,8 +4,6 @@ import { HTMLAttributes, ReactNode } from 'react';
4
4
  interface TreeNodeData {
5
5
  id: string;
6
6
  label: ReactNode;
7
- /** Plain-text label for keyboard typeahead when `label` is not a string (UIX-A11Y-2). */
8
- typeaheadLabel?: string;
9
7
  icon?: ReactNode;
10
8
  children?: TreeNodeData[];
11
9
  }