@tensor_1/react 2.14.2 → 2.16.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 (58) hide show
  1. package/README.md +5 -0
  2. package/dist/ChartCore-Do6gRBN3.d.cts +44 -0
  3. package/dist/chart-preset.cjs +41 -9
  4. package/dist/chart-preset.d.cts +2 -2
  5. package/dist/chart-preset.d.ts +1 -1
  6. package/dist/chart-preset.js +4 -1
  7. package/dist/chart.cjs +41 -9
  8. package/dist/chart.d.cts +2 -2
  9. package/dist/chart.d.ts +1 -1
  10. package/dist/chart.js +4 -1
  11. package/dist/combobox-model.d.ts +9 -0
  12. package/dist/combobox-model.js +10 -0
  13. package/dist/components/AsyncOperationStatus.d.ts +16 -0
  14. package/dist/components/AsyncOperationStatus.js +24 -0
  15. package/dist/components/Breadcrumbs.d.ts +18 -0
  16. package/dist/components/Breadcrumbs.js +14 -0
  17. package/dist/components/Card.d.ts +11 -2
  18. package/dist/components/Card.js +16 -1
  19. package/dist/components/Chart.d.ts +1 -1
  20. package/dist/components/Chart.js +4 -1
  21. package/dist/components/ChartCore.d.ts +24 -3
  22. package/dist/components/ChartCore.js +38 -9
  23. package/dist/components/CollapsibleSection.d.ts +11 -0
  24. package/dist/components/CollapsibleSection.js +17 -0
  25. package/dist/components/Combobox.d.ts +19 -0
  26. package/dist/components/Combobox.js +120 -0
  27. package/dist/components/DetailPage.d.ts +33 -0
  28. package/dist/components/DetailPage.js +19 -0
  29. package/dist/components/Dialogs.d.ts +35 -0
  30. package/dist/components/Dialogs.js +55 -0
  31. package/dist/components/Flow.d.ts +26 -0
  32. package/dist/components/Flow.js +48 -0
  33. package/dist/components/Modal.d.ts +3 -1
  34. package/dist/components/Modal.js +6 -4
  35. package/dist/components/Pipeline.d.ts +25 -0
  36. package/dist/components/Pipeline.js +65 -0
  37. package/dist/components/RelatedLinks.d.ts +16 -0
  38. package/dist/components/RelatedLinks.js +14 -0
  39. package/dist/components/RelativeTime.d.ts +23 -0
  40. package/dist/components/RelativeTime.js +40 -0
  41. package/dist/components/Sidebar.d.ts +7 -2
  42. package/dist/components/Sidebar.js +27 -9
  43. package/dist/components/States.d.ts +23 -4
  44. package/dist/components/States.js +28 -6
  45. package/dist/components/TableControls.d.ts +77 -0
  46. package/dist/components/TableControls.js +61 -0
  47. package/dist/components/ToggleRow.d.ts +14 -0
  48. package/dist/components/ToggleRow.js +16 -0
  49. package/dist/index.cjs +1392 -786
  50. package/dist/index.d.cts +323 -8
  51. package/dist/index.d.ts +16 -2
  52. package/dist/index.js +40 -2
  53. package/dist/relative-time-clock.d.ts +4 -0
  54. package/dist/relative-time-clock.js +33 -0
  55. package/dist/relative-time-model.d.ts +9 -0
  56. package/dist/relative-time-model.js +16 -0
  57. package/package.json +1 -1
  58. package/dist/ChartCore-Bt1C84ty.d.cts +0 -22
@@ -0,0 +1,17 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cx } from "../cx.js";
3
+ function CollapsibleSection({ title, summary, children, className, ...props }) {
4
+ return /* @__PURE__ */ jsxs("details", { className: cx("uix-collapsible", className), ...props, children: [
5
+ /* @__PURE__ */ jsxs("summary", { className: "uix-collapsible__summary", children: [
6
+ /* @__PURE__ */ jsxs("span", { children: [
7
+ /* @__PURE__ */ jsx("span", { className: "uix-collapsible__title", children: title }),
8
+ summary != null && /* @__PURE__ */ jsx("span", { className: "uix-collapsible__meta", children: summary })
9
+ ] }),
10
+ /* @__PURE__ */ jsx("span", { className: "uix-collapsible__chevron", "aria-hidden": "true", children: "\u2304" })
11
+ ] }),
12
+ /* @__PURE__ */ jsx("div", { className: "uix-collapsible__body", children })
13
+ ] });
14
+ }
15
+ export {
16
+ CollapsibleSection
17
+ };
@@ -0,0 +1,19 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes } from 'react';
3
+ import { ComboboxOption } from '../combobox-model.js';
4
+
5
+ interface ComboboxProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
6
+ options: readonly ComboboxOption[];
7
+ value?: string;
8
+ defaultValue?: string;
9
+ onValueChange?: (value: string, option: ComboboxOption) => void;
10
+ label: string;
11
+ placeholder?: string;
12
+ emptyLabel: string;
13
+ name?: string;
14
+ disabled?: boolean;
15
+ }
16
+ /** Searchable single-select combobox with keyboard navigation and no framework dependencies. */
17
+ declare function Combobox({ options, value, defaultValue, onValueChange, label, placeholder, emptyLabel, name, disabled, className, ...props }: ComboboxProps): react.JSX.Element;
18
+
19
+ export { Combobox, ComboboxOption, type ComboboxProps };
@@ -0,0 +1,120 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useId, useMemo, useRef, useState } from "react";
4
+ import { cx } from "../cx.js";
5
+ import { filterComboboxOptions } from "../combobox-model.js";
6
+ function Combobox({
7
+ options,
8
+ value,
9
+ defaultValue,
10
+ onValueChange,
11
+ label,
12
+ placeholder,
13
+ emptyLabel,
14
+ name,
15
+ disabled,
16
+ className,
17
+ ...props
18
+ }) {
19
+ const generatedId = useId();
20
+ const listboxId = `${generatedId}-listbox`;
21
+ const rootRef = useRef(null);
22
+ const [internalValue, setInternalValue] = useState(defaultValue ?? "");
23
+ const selectedValue = value ?? internalValue;
24
+ const selected = options.find((option) => option.value === selectedValue);
25
+ const [query, setQuery] = useState(selected?.label ?? "");
26
+ const [open, setOpen] = useState(false);
27
+ const [activeIndex, setActiveIndex] = useState(0);
28
+ const filtered = useMemo(() => filterComboboxOptions(options, open ? query : ""), [open, options, query]);
29
+ const activeOption = filtered[activeIndex];
30
+ useEffect(() => {
31
+ if (!open) setQuery(options.find((option) => option.value === selectedValue)?.label ?? "");
32
+ }, [open, options, selectedValue]);
33
+ const select = (option) => {
34
+ if (option.disabled) return;
35
+ if (value == null) setInternalValue(option.value);
36
+ setQuery(option.label);
37
+ setOpen(false);
38
+ onValueChange?.(option.value, option);
39
+ };
40
+ const move = (step) => {
41
+ if (!filtered.length) return;
42
+ let next = activeIndex;
43
+ for (let attempts = 0; attempts < filtered.length; attempts += 1) {
44
+ next = (next + step + filtered.length) % filtered.length;
45
+ if (!filtered[next]?.disabled) break;
46
+ }
47
+ setActiveIndex(next);
48
+ };
49
+ const handleKeyDown = (event) => {
50
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
51
+ event.preventDefault();
52
+ if (!open) setOpen(true);
53
+ else move(event.key === "ArrowDown" ? 1 : -1);
54
+ } else if (event.key === "Enter" && open && activeOption) {
55
+ event.preventDefault();
56
+ select(activeOption);
57
+ } else if (event.key === "Escape") {
58
+ setOpen(false);
59
+ setQuery(selected?.label ?? "");
60
+ }
61
+ };
62
+ const handleBlur = (event) => {
63
+ if (!rootRef.current?.contains(event.relatedTarget)) {
64
+ setOpen(false);
65
+ setQuery(options.find((option) => option.value === selectedValue)?.label ?? "");
66
+ }
67
+ };
68
+ const handleChange = (event) => {
69
+ setQuery(event.target.value);
70
+ setActiveIndex(0);
71
+ setOpen(true);
72
+ };
73
+ return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cx("uix-combobox", className), onBlur: handleBlur, ...props, children: [
74
+ name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selectedValue }),
75
+ /* @__PURE__ */ jsx(
76
+ "input",
77
+ {
78
+ className: "uix-input",
79
+ role: "combobox",
80
+ "aria-label": label,
81
+ "aria-autocomplete": "list",
82
+ "aria-expanded": open,
83
+ "aria-controls": listboxId,
84
+ "aria-activedescendant": open && activeOption ? `${listboxId}-${activeIndex}` : void 0,
85
+ value: query,
86
+ placeholder,
87
+ disabled,
88
+ onChange: handleChange,
89
+ onFocus: () => {
90
+ setQuery("");
91
+ setOpen(true);
92
+ setActiveIndex(Math.max(0, options.findIndex((option) => option.value === selectedValue)));
93
+ },
94
+ onKeyDown: handleKeyDown
95
+ }
96
+ ),
97
+ open && /* @__PURE__ */ jsxs("ul", { id: listboxId, className: "uix-listbox uix-combobox__listbox", role: "listbox", children: [
98
+ filtered.length === 0 && /* @__PURE__ */ jsx("li", { className: "uix-listbox__empty", children: emptyLabel }),
99
+ filtered.map((option, index) => /* @__PURE__ */ jsx(
100
+ "li",
101
+ {
102
+ id: `${listboxId}-${index}`,
103
+ className: "uix-listbox__option",
104
+ role: "option",
105
+ "aria-selected": option.value === selectedValue,
106
+ "aria-disabled": option.disabled || void 0,
107
+ "data-active": index === activeIndex || void 0,
108
+ onMouseDown: (event) => event.preventDefault(),
109
+ onMouseEnter: () => setActiveIndex(index),
110
+ onClick: () => select(option),
111
+ children: option.label
112
+ },
113
+ option.value
114
+ ))
115
+ ] })
116
+ ] });
117
+ }
118
+ export {
119
+ Combobox
120
+ };
@@ -0,0 +1,33 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ interface DetailPageTab {
5
+ id: string;
6
+ label: ReactNode;
7
+ href: string;
8
+ active?: boolean;
9
+ }
10
+ interface DetailPageMetric {
11
+ id: string;
12
+ label: ReactNode;
13
+ value: ReactNode;
14
+ }
15
+ interface DetailPageProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
16
+ back?: {
17
+ href: string;
18
+ label: ReactNode;
19
+ };
20
+ eyebrow?: ReactNode;
21
+ title: ReactNode;
22
+ subtitle?: ReactNode;
23
+ actions?: ReactNode;
24
+ tabs?: readonly DetailPageTab[];
25
+ metrics?: readonly DetailPageMetric[];
26
+ side?: ReactNode;
27
+ children?: ReactNode;
28
+ tabsLabel?: string;
29
+ }
30
+ /** Framework-neutral record-detail scaffold; routing and data policy stay with the application. */
31
+ declare function DetailPage({ back, eyebrow, title, subtitle, actions, tabs, metrics, side, children, tabsLabel, className, ...props }: DetailPageProps): react.JSX.Element;
32
+
33
+ export { DetailPage, type DetailPageMetric, type DetailPageProps, type DetailPageTab };
@@ -0,0 +1,19 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cx } from "../cx.js";
3
+ import { DetailLayout } from "./DetailLayout.js";
4
+ import { PageHeader } from "./PageHeader.js";
5
+ function DetailPage({ back, eyebrow, title, subtitle, actions, tabs, metrics, side, children, tabsLabel, className, ...props }) {
6
+ return /* @__PURE__ */ jsxs("section", { className: cx("uix-detail-page", className), ...props, children: [
7
+ back && /* @__PURE__ */ jsx("a", { className: "uix-link uix-link--quiet uix-detail-page__back", href: back.href, children: back.label }),
8
+ /* @__PURE__ */ jsx(PageHeader, { eyebrow, title, subtitle, actions }),
9
+ metrics && metrics.length > 0 && /* @__PURE__ */ jsx("dl", { className: "uix-detail-page__metrics", children: metrics.map((metric) => /* @__PURE__ */ jsxs("div", { children: [
10
+ /* @__PURE__ */ jsx("dt", { children: metric.label }),
11
+ /* @__PURE__ */ jsx("dd", { children: metric.value })
12
+ ] }, metric.id)) }),
13
+ tabs && tabs.length > 0 && /* @__PURE__ */ jsx("nav", { className: "uix-tabs", "aria-label": tabsLabel, children: tabs.map((tab) => /* @__PURE__ */ jsx("a", { className: "uix-tab", "aria-current": tab.active ? "page" : void 0, href: tab.href, children: tab.label }, tab.id)) }),
14
+ /* @__PURE__ */ jsx(DetailLayout, { side, children })
15
+ ] });
16
+ }
17
+ export {
18
+ DetailPage
19
+ };
@@ -0,0 +1,35 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface ConfirmDialogProps {
5
+ open: boolean;
6
+ title: ReactNode;
7
+ description?: ReactNode;
8
+ confirmLabel: ReactNode;
9
+ cancelLabel: ReactNode;
10
+ closeLabel: string;
11
+ onConfirm: () => void | Promise<void>;
12
+ onCancel: () => void;
13
+ pending?: boolean;
14
+ destructive?: boolean;
15
+ }
16
+ /** Generic confirmation shell. Audit, authorization and compensation policy remain application-owned. */
17
+ declare function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, closeLabel, onConfirm, onCancel, pending, destructive }: ConfirmDialogProps): react.JSX.Element;
18
+ interface PromptDialogProps {
19
+ open: boolean;
20
+ title: ReactNode;
21
+ description?: ReactNode;
22
+ inputLabel: string;
23
+ defaultValue?: string;
24
+ placeholder?: string;
25
+ submitLabel: ReactNode;
26
+ cancelLabel: ReactNode;
27
+ closeLabel: string;
28
+ onSubmit: (value: string) => void | Promise<void>;
29
+ onCancel: () => void;
30
+ validate?: (value: string) => ReactNode | undefined;
31
+ pending?: boolean;
32
+ }
33
+ declare function PromptDialog({ open, title, description, inputLabel, defaultValue, placeholder, submitLabel, cancelLabel, closeLabel, onSubmit, onCancel, validate, pending }: PromptDialogProps): react.JSX.Element;
34
+
35
+ export { ConfirmDialog, type ConfirmDialogProps, PromptDialog, type PromptDialogProps };
@@ -0,0 +1,55 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useId, useState } from "react";
4
+ import { Button } from "./Button.js";
5
+ import { Input } from "./Input.js";
6
+ import { Modal } from "./Modal.js";
7
+ function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, closeLabel, onConfirm, onCancel, pending, destructive }) {
8
+ return /* @__PURE__ */ jsx(
9
+ Modal,
10
+ {
11
+ open,
12
+ onClose: onCancel,
13
+ title,
14
+ closeLabel,
15
+ role: "alertdialog",
16
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
17
+ /* @__PURE__ */ jsx(Button, { type: "button", onClick: onCancel, disabled: pending, children: cancelLabel }),
18
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: destructive ? "danger" : "primary", onClick: () => void onConfirm(), loading: pending, children: confirmLabel })
19
+ ] }),
20
+ children: description
21
+ }
22
+ );
23
+ }
24
+ function PromptDialog({ open, title, description, inputLabel, defaultValue = "", placeholder, submitLabel, cancelLabel, closeLabel, onSubmit, onCancel, validate, pending }) {
25
+ const inputId = useId();
26
+ const errorId = `${inputId}-error`;
27
+ const [value, setValue] = useState(defaultValue);
28
+ const [error, setError] = useState();
29
+ useEffect(() => {
30
+ if (open) {
31
+ setValue(defaultValue);
32
+ setError(void 0);
33
+ }
34
+ }, [defaultValue, open]);
35
+ const handleSubmit = (event) => {
36
+ event.preventDefault();
37
+ const issue = validate?.(value);
38
+ setError(issue);
39
+ if (issue == null) void onSubmit(value);
40
+ };
41
+ return /* @__PURE__ */ jsx(Modal, { open, onClose: onCancel, title, closeLabel, children: /* @__PURE__ */ jsxs("form", { className: "uix-prompt", onSubmit: handleSubmit, children: [
42
+ description != null && /* @__PURE__ */ jsx("div", { children: description }),
43
+ /* @__PURE__ */ jsx("label", { className: "uix-label", htmlFor: inputId, children: inputLabel }),
44
+ /* @__PURE__ */ jsx(Input, { id: inputId, value, placeholder, "aria-describedby": error ? errorId : void 0, invalid: error != null, onChange: (event) => setValue(event.currentTarget.value), autoFocus: true }),
45
+ error != null && /* @__PURE__ */ jsx("div", { id: errorId, className: "uix-field__error", role: "alert", children: error }),
46
+ /* @__PURE__ */ jsxs("div", { className: "uix-dialog__footer uix-prompt__actions", children: [
47
+ /* @__PURE__ */ jsx(Button, { type: "button", onClick: onCancel, disabled: pending, children: cancelLabel }),
48
+ /* @__PURE__ */ jsx(Button, { type: "submit", variant: "primary", loading: pending, children: submitLabel })
49
+ ] })
50
+ ] }) });
51
+ }
52
+ export {
53
+ ConfirmDialog,
54
+ PromptDialog
55
+ };
@@ -0,0 +1,26 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ type FlowVariant = 'linear' | 'branch' | 'loop' | 'mindmap' | 'canvas';
5
+ type FlowNodeState = 'pending' | 'active' | 'running' | 'done' | 'error';
6
+ interface FlowProps extends HTMLAttributes<HTMLDivElement> {
7
+ variant?: FlowVariant;
8
+ panel?: boolean;
9
+ children?: ReactNode;
10
+ }
11
+ /** Presentational workflow surface. Consumers provide graph geometry and connectors. */
12
+ declare function Flow({ variant, panel, children, className, role, ...props }: FlowProps): react.JSX.Element;
13
+ interface FlowNodeProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
14
+ title: ReactNode;
15
+ state?: FlowNodeState;
16
+ stateLabel?: ReactNode;
17
+ eyebrow?: ReactNode;
18
+ meta?: ReactNode;
19
+ icon?: ReactNode;
20
+ footer?: ReactNode;
21
+ wide?: boolean;
22
+ }
23
+ /** Workflow node with explicit text state and optional operational metadata. */
24
+ declare function FlowNode({ title, state, stateLabel, eyebrow, meta, icon, footer, wide, className, ...props }: FlowNodeProps): react.JSX.Element;
25
+
26
+ export { Flow, FlowNode, type FlowNodeProps, type FlowNodeState, type FlowProps, type FlowVariant };
@@ -0,0 +1,48 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cx } from "../cx.js";
3
+ function Flow({ variant = "linear", panel = false, children, className, role = "group", ...props }) {
4
+ return /* @__PURE__ */ jsx(
5
+ "div",
6
+ {
7
+ className: cx("uix-flow", `uix-flow--${variant}`, panel && "uix-flow--panel", className),
8
+ role,
9
+ ...props,
10
+ children
11
+ }
12
+ );
13
+ }
14
+ const FLOW_STATE_LABELS = {
15
+ pending: "Pending",
16
+ active: "Active",
17
+ running: "Running",
18
+ done: "Done",
19
+ error: "Error"
20
+ };
21
+ function FlowNode({
22
+ title,
23
+ state = "pending",
24
+ stateLabel,
25
+ eyebrow,
26
+ meta,
27
+ icon,
28
+ footer,
29
+ wide = false,
30
+ className,
31
+ ...props
32
+ }) {
33
+ const resolvedStateLabel = stateLabel ?? FLOW_STATE_LABELS[state];
34
+ return /* @__PURE__ */ jsxs("div", { className: cx("uix-node", `uix-node--${state}`, icon == null && "uix-node--no-icon", wide && "uix-node--wide", className), ...props, children: [
35
+ icon != null && /* @__PURE__ */ jsx("span", { className: "uix-node__icon", "aria-hidden": "true", children: icon }),
36
+ /* @__PURE__ */ jsxs("div", { className: "uix-node__body", children: [
37
+ eyebrow != null && /* @__PURE__ */ jsx("div", { className: "uix-node__eyebrow", children: eyebrow }),
38
+ /* @__PURE__ */ jsx("div", { className: "uix-node__title", children: title }),
39
+ meta != null && /* @__PURE__ */ jsx("div", { className: "uix-node__meta", children: meta }),
40
+ /* @__PURE__ */ jsx("div", { className: "uix-node__status", children: resolvedStateLabel })
41
+ ] }),
42
+ footer != null && /* @__PURE__ */ jsx("div", { className: "uix-node__footer", children: footer })
43
+ ] });
44
+ }
45
+ export {
46
+ Flow,
47
+ FlowNode
48
+ };
@@ -9,7 +9,9 @@ interface ModalProps {
9
9
  footer?: ReactNode;
10
10
  className?: string;
11
11
  style?: CSSProperties;
12
+ closeLabel?: string;
13
+ role?: 'dialog' | 'alertdialog';
12
14
  }
13
- declare function Modal({ open, onClose, title, children, footer, className, style }: ModalProps): react.JSX.Element;
15
+ declare function Modal({ open, onClose, title, children, footer, className, style, closeLabel, role }: ModalProps): react.JSX.Element;
14
16
 
15
17
  export { Modal, type ModalProps };
@@ -1,14 +1,16 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useId } from "react";
3
4
  import { cx } from "../cx.js";
4
5
  import { useDialog } from "../hooks/useDialog.js";
5
6
  const CloseIcon = () => /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M4 4l8 8M12 4l-8 8" }) });
6
- function Modal({ open, onClose, title, children, footer, className, style }) {
7
+ function Modal({ open, onClose, title, children, footer, className, style, closeLabel = "Close dialog", role = "dialog" }) {
7
8
  const ref = useDialog(open);
8
- return /* @__PURE__ */ jsxs("dialog", { ref, className: cx("uix-dialog", className), style, onClose, children: [
9
+ const titleId = useId();
10
+ return /* @__PURE__ */ jsxs("dialog", { ref, className: cx("uix-dialog", className), style, onClose, role, "aria-labelledby": title != null ? titleId : void 0, children: [
9
11
  (title != null || onClose) && /* @__PURE__ */ jsxs("div", { className: "uix-dialog__header", children: [
10
- title && /* @__PURE__ */ jsx("div", { className: "uix-dialog__title", children: title }),
11
- onClose && /* @__PURE__ */ jsx("button", { className: "uix-dialog__close", onClick: onClose, "aria-label": "Close dialog", children: /* @__PURE__ */ jsx(CloseIcon, {}) })
12
+ title && /* @__PURE__ */ jsx("div", { id: titleId, className: "uix-dialog__title", children: title }),
13
+ onClose && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-dialog__close", onClick: onClose, "aria-label": closeLabel, children: /* @__PURE__ */ jsx(CloseIcon, {}) })
12
14
  ] }),
13
15
  children != null && /* @__PURE__ */ jsx("div", { className: "uix-dialog__body", children }),
14
16
  footer != null && /* @__PURE__ */ jsx("div", { className: "uix-dialog__footer", children: footer })
@@ -0,0 +1,25 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ type PipelineStageState = 'pending' | 'waiting' | 'active' | 'current' | 'running' | 'done' | 'complete' | 'blocked' | 'failed' | 'error';
5
+ interface PipelineProps extends HTMLAttributes<HTMLOListElement> {
6
+ detailed?: boolean;
7
+ children?: ReactNode;
8
+ }
9
+ /** Ordered progress rail. Consumers own workflow meaning; UIx owns stage semantics and presentation. */
10
+ declare function Pipeline({ detailed, children, className, tabIndex, ...props }: PipelineProps): react.JSX.Element;
11
+ interface PipelineStageProps extends Omit<HTMLAttributes<HTMLLIElement>, 'title'> {
12
+ label: ReactNode;
13
+ state?: PipelineStageState;
14
+ stateLabel?: ReactNode;
15
+ description?: ReactNode;
16
+ meta?: ReactNode;
17
+ marker?: ReactNode;
18
+ detailed?: boolean;
19
+ /** Marks the stage as the current position independently of its operational state. */
20
+ current?: boolean;
21
+ }
22
+ /** One pipeline stage. `stateLabel` keeps status explicit instead of relying on colour. */
23
+ declare function PipelineStage({ label, state, stateLabel, description, meta, marker, detailed, current: currentProp, className, ...props }: PipelineStageProps): react.JSX.Element;
24
+
25
+ export { Pipeline, type PipelineProps, PipelineStage, type PipelineStageProps, type PipelineStageState };
@@ -0,0 +1,65 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Children, cloneElement, isValidElement } from "react";
3
+ import { cx } from "../cx.js";
4
+ function Pipeline({ detailed = false, children, className, tabIndex, ...props }) {
5
+ const stages = detailed ? Children.map(children, (child) => isValidElement(child) && child.type === PipelineStage ? cloneElement(child, { detailed: child.props.detailed ?? true }) : child) : children;
6
+ return /* @__PURE__ */ jsx(
7
+ "ol",
8
+ {
9
+ className: cx("uix-pipeline", detailed && "uix-pipeline--detailed", className),
10
+ tabIndex: tabIndex ?? (detailed ? 0 : void 0),
11
+ ...props,
12
+ children: stages
13
+ }
14
+ );
15
+ }
16
+ const DEFAULT_STATE_LABELS = {
17
+ pending: "Pending",
18
+ waiting: "Waiting",
19
+ active: "Active",
20
+ current: "Current",
21
+ running: "Running",
22
+ done: "Done",
23
+ complete: "Complete",
24
+ blocked: "Blocked",
25
+ failed: "Failed",
26
+ error: "Error"
27
+ };
28
+ function PipelineStage({
29
+ label,
30
+ state = "pending",
31
+ stateLabel,
32
+ description,
33
+ meta,
34
+ marker,
35
+ detailed = false,
36
+ current: currentProp,
37
+ className,
38
+ ...props
39
+ }) {
40
+ const current = currentProp ?? (state === "active" || state === "current" || state === "running");
41
+ const resolvedStateLabel = stateLabel ?? DEFAULT_STATE_LABELS[state];
42
+ const showDetails = detailed || description != null || meta != null || marker != null;
43
+ return /* @__PURE__ */ jsx(
44
+ "li",
45
+ {
46
+ className: cx("uix-pipeline__stage", className),
47
+ "data-state": state,
48
+ "aria-current": current ? "step" : void 0,
49
+ ...props,
50
+ children: showDetails ? /* @__PURE__ */ jsxs(Fragment, { children: [
51
+ /* @__PURE__ */ jsx("span", { className: "uix-pipeline__marker", "aria-hidden": "true", children: marker }),
52
+ /* @__PURE__ */ jsxs("div", { className: "uix-pipeline__content", children: [
53
+ /* @__PURE__ */ jsx("div", { className: "uix-pipeline__eyebrow", children: /* @__PURE__ */ jsx("span", { className: "uix-pipeline__state", children: resolvedStateLabel }) }),
54
+ /* @__PURE__ */ jsx("div", { className: "uix-pipeline__title", children: label }),
55
+ description != null && /* @__PURE__ */ jsx("div", { className: "uix-pipeline__description", children: description }),
56
+ meta != null && /* @__PURE__ */ jsx("div", { className: "uix-pipeline__meta", children: meta })
57
+ ] })
58
+ ] }) : label
59
+ }
60
+ );
61
+ }
62
+ export {
63
+ Pipeline,
64
+ PipelineStage
65
+ };
@@ -0,0 +1,16 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, HTMLAttributes } from 'react';
3
+
4
+ interface RelatedLinkItem {
5
+ id: string;
6
+ label: ReactNode;
7
+ href: string;
8
+ meta?: ReactNode;
9
+ }
10
+ interface RelatedLinksProps extends Omit<HTMLAttributes<HTMLElement>, 'title' | 'children'> {
11
+ title?: ReactNode;
12
+ items: readonly RelatedLinkItem[];
13
+ }
14
+ declare function RelatedLinks({ title, items, className, ...props }: RelatedLinksProps): react.JSX.Element;
15
+
16
+ export { type RelatedLinkItem, RelatedLinks, type RelatedLinksProps };
@@ -0,0 +1,14 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { cx } from "../cx.js";
3
+ function RelatedLinks({ title, items, className, ...props }) {
4
+ return /* @__PURE__ */ jsxs("section", { className: cx("uix-related-links", className), ...props, children: [
5
+ title != null && /* @__PURE__ */ jsx("h2", { className: "uix-related-links__title", children: title }),
6
+ /* @__PURE__ */ jsx("ul", { className: "uix-related-links__list", children: items.map((item) => /* @__PURE__ */ jsxs("li", { children: [
7
+ /* @__PURE__ */ jsx("a", { className: "uix-link uix-link--quiet", href: item.href, children: item.label }),
8
+ item.meta != null && /* @__PURE__ */ jsx("span", { children: item.meta })
9
+ ] }, item.id)) })
10
+ ] });
11
+ }
12
+ export {
13
+ RelatedLinks
14
+ };
@@ -0,0 +1,23 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ReactNode } from 'react';
3
+
4
+ interface RelativeTimeFormatContext {
5
+ date: Date;
6
+ now: Date;
7
+ locale?: string | readonly string[];
8
+ timeZone?: string;
9
+ }
10
+ interface RelativeTimeProps extends Omit<HTMLAttributes<HTMLTimeElement>, 'children' | 'dateTime'> {
11
+ value: Date | number | string;
12
+ now?: Date | number;
13
+ locale?: string | readonly string[];
14
+ timeZone?: string;
15
+ numeric?: Intl.RelativeTimeFormatNumeric;
16
+ invalidLabel?: ReactNode;
17
+ refreshInterval?: number | false;
18
+ formatter?: (context: RelativeTimeFormatContext) => ReactNode;
19
+ }
20
+ /** Locale-aware relative time with deterministic `now` support for SSR and tests. */
21
+ declare function RelativeTime({ value, now, locale, timeZone, numeric, invalidLabel, refreshInterval, formatter, title, ...props }: RelativeTimeProps): react.JSX.Element;
22
+
23
+ export { RelativeTime, type RelativeTimeFormatContext, type RelativeTimeProps };
@@ -0,0 +1,40 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useCallback, useMemo, useSyncExternalStore } from "react";
4
+ import { parseDateValue, relativeTimeValue } from "../relative-time-model.js";
5
+ import { readRelativeClock, subscribeRelativeClock } from "../relative-time-clock.js";
6
+ function RelativeTime({
7
+ value,
8
+ now,
9
+ locale,
10
+ timeZone,
11
+ numeric = "auto",
12
+ invalidLabel = "\u2014",
13
+ refreshInterval = 3e4,
14
+ formatter,
15
+ title,
16
+ ...props
17
+ }) {
18
+ const interval = refreshInterval === false ? 0 : Math.max(0, refreshInterval);
19
+ const fixedNow = now == null ? void 0 : new Date(now).getTime();
20
+ const subscribe = useCallback((listener) => fixedNow == null ? subscribeRelativeClock(interval, listener) : () => {
21
+ }, [fixedNow, interval]);
22
+ const getSnapshot = useCallback(() => fixedNow ?? readRelativeClock(interval), [fixedNow, interval]);
23
+ const getServerSnapshot = useCallback(() => fixedNow ?? Date.now(), [fixedNow]);
24
+ const clock = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
25
+ const date = useMemo(() => parseDateValue(value), [value]);
26
+ if (!date) return /* @__PURE__ */ jsx("time", { "data-invalid": "true", suppressHydrationWarning: true, ...props, children: invalidLabel });
27
+ const current = new Date(clock);
28
+ const content = formatter ? formatter({ date, now: current, locale, timeZone }) : (() => {
29
+ const relative = relativeTimeValue(date, current);
30
+ if (relative.unit === "day" && Math.abs(relative.value) >= 7) {
31
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeZone }).format(date);
32
+ }
33
+ return new Intl.RelativeTimeFormat(locale, { numeric }).format(relative.value, relative.unit);
34
+ })();
35
+ const absolute = new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short", timeZone }).format(date);
36
+ return /* @__PURE__ */ jsx("time", { dateTime: date.toISOString(), title: title ?? absolute, suppressHydrationWarning: true, ...props, children: content });
37
+ }
38
+ export {
39
+ RelativeTime
40
+ };
@@ -3,12 +3,15 @@ import { ReactNode, AnchorHTMLAttributes, HTMLAttributes } from 'react';
3
3
 
4
4
  interface SidebarProps extends HTMLAttributes<HTMLElement> {
5
5
  collapsed?: boolean;
6
+ nav?: 'full' | 'rail';
6
7
  onToggle?: () => void;
7
8
  brand?: ReactNode;
8
9
  toggleIcon?: ReactNode;
9
10
  children?: ReactNode;
11
+ expandLabel?: string;
12
+ collapseLabel?: string;
10
13
  }
11
- declare function Sidebar({ collapsed, onToggle, brand, toggleIcon, children, className, ...props }: SidebarProps): react.JSX.Element;
14
+ declare function Sidebar({ collapsed, nav, onToggle, brand, toggleIcon, children, expandLabel, collapseLabel, className, ...props }: SidebarProps): react.JSX.Element;
12
15
  interface SidebarSectionProps {
13
16
  label?: string;
14
17
  children?: ReactNode;
@@ -27,8 +30,10 @@ interface NavGroupProps {
27
30
  label: ReactNode;
28
31
  children?: ReactNode;
29
32
  defaultExpanded?: boolean;
33
+ expanded?: boolean;
34
+ onExpandedChange?: (expanded: boolean) => void;
30
35
  }
31
- declare function NavGroup({ icon, label, children, defaultExpanded }: NavGroupProps): react.JSX.Element;
36
+ declare function NavGroup({ icon, label, children, defaultExpanded, expanded: controlledExpanded, onExpandedChange }: NavGroupProps): react.JSX.Element;
32
37
  interface SubNavItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
33
38
  active?: boolean;
34
39
  as?: 'a' | 'button';