@polyxd/react 0.1.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 (63) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +177 -0
  3. package/README.md +39 -0
  4. package/dist/components/avatar.d.ts +10 -0
  5. package/dist/components/avatar.js +47 -0
  6. package/dist/components/avatar.js.map +1 -0
  7. package/dist/components/chart.d.ts +5 -0
  8. package/dist/components/chart.js +98 -0
  9. package/dist/components/chart.js.map +1 -0
  10. package/dist/components/content.d.ts +23 -0
  11. package/dist/components/content.js +108 -0
  12. package/dist/components/content.js.map +1 -0
  13. package/dist/components/filter.d.ts +9 -0
  14. package/dist/components/filter.js +97 -0
  15. package/dist/components/filter.js.map +1 -0
  16. package/dist/components/flow.d.ts +22 -0
  17. package/dist/components/flow.js +143 -0
  18. package/dist/components/flow.js.map +1 -0
  19. package/dist/components/index.d.ts +10 -0
  20. package/dist/components/index.js +19 -0
  21. package/dist/components/index.js.map +1 -0
  22. package/dist/components/inputs.d.ts +38 -0
  23. package/dist/components/inputs.js +230 -0
  24. package/dist/components/inputs.js.map +1 -0
  25. package/dist/components/navigation.d.ts +8 -0
  26. package/dist/components/navigation.js +51 -0
  27. package/dist/components/navigation.js.map +1 -0
  28. package/dist/components/structure.d.ts +25 -0
  29. package/dist/components/structure.js +58 -0
  30. package/dist/components/structure.js.map +1 -0
  31. package/dist/components/table.d.ts +9 -0
  32. package/dist/components/table.js +144 -0
  33. package/dist/components/table.js.map +1 -0
  34. package/dist/context.d.ts +93 -0
  35. package/dist/context.js +42 -0
  36. package/dist/context.js.map +1 -0
  37. package/dist/data.d.ts +26 -0
  38. package/dist/data.js +52 -0
  39. package/dist/data.js.map +1 -0
  40. package/dist/format.d.ts +12 -0
  41. package/dist/format.js +51 -0
  42. package/dist/format.js.map +1 -0
  43. package/dist/index.d.ts +5 -0
  44. package/dist/index.js +6 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/surface.d.ts +37 -0
  47. package/dist/surface.js +80 -0
  48. package/dist/surface.js.map +1 -0
  49. package/package.json +53 -0
  50. package/src/styles.css +2182 -0
  51. package/themes/antd.css +300 -0
  52. package/themes/bootstrap.css +300 -0
  53. package/themes/carbon.css +310 -0
  54. package/themes/chakra.css +300 -0
  55. package/themes/fluent.css +300 -0
  56. package/themes/govuk.css +150 -0
  57. package/themes/mantine.css +300 -0
  58. package/themes/material3.css +300 -0
  59. package/themes/polaris.css +300 -0
  60. package/themes/primer.css +300 -0
  61. package/themes/radix.css +300 -0
  62. package/themes/shadcn.css +300 -0
  63. package/themes/spectrum.css +300 -0
@@ -0,0 +1,144 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useRef, useState } from "react";
3
+ import { Checkbox, DropdownMenu } from "radix-ui";
4
+ import { resolveFormat, useBindings, useSurface } from "../context.js";
5
+ import { asList, absolute, childPointer, get } from "../data.js";
6
+ import { formatValue } from "../format.js";
7
+ import { Render, useA11y } from "../surface.js";
8
+ import { Avatar, Icon } from "./avatar.js";
9
+ /** Below this width a table becomes a list of rows. */
10
+ const COMPACT_PX = 720;
11
+ const NUMERIC = new Set(["number", "currency", "percent", "duration"]);
12
+ const PAGE_SIZES = [10, 25, 50, 100];
13
+ const isNumeric = (c) => c.align === "end" || (c.align !== "start" && (c.kind === "number" || c.kind === "currency" || NUMERIC.has(c.format?.type)));
14
+ /**
15
+ * Table: the dense list B2B software is made of. Saved views, a toolbar with search and filters,
16
+ * sortable columns, selection with bulk actions, a menu per row, and paging. On compact surfaces
17
+ * it becomes a list of rows, because 7 columns don't fit a phone.
18
+ */
19
+ export function Table({ node }) {
20
+ const b = useBindings();
21
+ const s = useSurface();
22
+ const ref = useRef(null);
23
+ const [compact, setCompact] = useState(false);
24
+ const pointer = absolute(node.rows.path, b.scope);
25
+ const rows = asList(get(s.data, pointer));
26
+ const caption = b.text(node.caption);
27
+ useLayoutEffect(() => {
28
+ const el = ref.current;
29
+ if (!el || typeof ResizeObserver === "undefined")
30
+ return;
31
+ const measure = () => setCompact(el.getBoundingClientRect().width < COMPACT_PX);
32
+ measure();
33
+ const ro = new ResizeObserver(measure);
34
+ ro.observe(el);
35
+ return () => ro.disconnect();
36
+ }, []);
37
+ // Selection is host state: an array of row values.
38
+ const selection = node.selection === "multiple";
39
+ const selected = selection && node.selected ? (b.value(node.selected) ?? []) : [];
40
+ const valueOf = (scope, i) => (node.rowValuePath ? get(s.data, absolute(node.rowValuePath, scope)) : (rows[i]?.id ?? i));
41
+ const toggle = (v) => b.write(node.selected, selected.includes(v) ? selected.filter((x) => x !== v) : [...selected, v]);
42
+ const allValues = rows.map((_, i) => valueOf({ pointer: childPointer(pointer, i) }, i));
43
+ const allSelected = rows.length > 0 && allValues.every((v) => selected.includes(v));
44
+ const toggleAll = () => b.write(node.selected, allSelected ? [] : allValues);
45
+ // Sorting is host state too: the column key and direction it re-queried with.
46
+ const sortColumn = node.sort?.column ? b.value(node.sort.column) : undefined;
47
+ const sortDirection = node.sort?.direction ? b.value(node.sort.direction) : "ascending";
48
+ const sortBy = (key) => {
49
+ const next = key === sortColumn && sortDirection === "ascending" ? "descending" : "ascending";
50
+ if (node.sort?.column)
51
+ b.write(node.sort.column, key);
52
+ if (node.sort?.direction)
53
+ b.write(node.sort.direction, next);
54
+ if (node.sort?.action)
55
+ s.dispatch(node.sort.action, b.scope, node.id);
56
+ };
57
+ const cell = (c, scope) => {
58
+ const raw = get(s.data, absolute(c.path, scope));
59
+ const text = formatValue(raw, resolveFormat(c.format, s.data, b.scope), s.locale);
60
+ if (c.kind === "status")
61
+ return _jsx("span", { className: `pxd-badge pxd-tone-${c.tones?.[String(raw)] ?? "neutral"}`, children: text });
62
+ if (c.kind === "entity") {
63
+ const second = c.secondaryPath ? String(get(s.data, absolute(c.secondaryPath, scope)) ?? "") : "";
64
+ return (_jsxs("span", { className: "pxd-entity", children: [c.avatarPath && _jsx(Avatar, { value: get(s.data, absolute(c.avatarPath, scope)), name: text, size: 28 }), _jsxs("span", { className: "pxd-entity-text", children: [node.rowAction ? (_jsx("button", { type: "button", className: "pxd-link", onClick: () => s.dispatch(node.rowAction, scope, node.id), children: text })) : (_jsx("span", { className: "pxd-entity-name", children: text })), second && _jsx("span", { className: "pxd-entity-secondary", children: second })] })] }));
65
+ }
66
+ if (c.kind === "link" && node.rowAction)
67
+ return (_jsx("button", { type: "button", className: "pxd-link", onClick: () => s.dispatch(node.rowAction, scope, node.id), children: text }));
68
+ return text;
69
+ };
70
+ const rowMenu = (scope, name) => {
71
+ const bar = s.byId.get(node.rowActions);
72
+ const actions = (bar?.children ?? []).map((id) => s.byId.get(id)).filter(Boolean);
73
+ if (!actions.length)
74
+ return null;
75
+ return (_jsxs(DropdownMenu.Root, { children: [_jsx(DropdownMenu.Trigger, { className: "pxd-icon-button", "aria-label": `Actions for ${name}`, children: _jsx(Icon, { name: "dots", size: 18 }) }), _jsx(DropdownMenu.Portal, { container: s.portal, children: _jsx(DropdownMenu.Content, { className: "pxd-menu", align: "end", children: actions.map((a) => (_jsx(DropdownMenu.Item, { className: `pxd-menu-item${a.tone === "danger" ? " pxd-menu-item-danger" : ""}`, onSelect: () => s.dispatch(a.action, scope, a.id), children: b.text(a.label) }, a.id))) }) })] }));
76
+ };
77
+ const header = (_jsxs(_Fragment, { children: [node.views && _jsx(Views, { node: node }), (node.search || node.toolbar || (selection && selected.length > 0)) && (_jsx("div", { className: `pxd-table-toolbar${selected.length > 0 ? " pxd-table-bulk" : ""}`, role: "toolbar", "aria-label": selected.length > 0 ? `Actions for ${selected.length} selected` : "Table tools", children: selected.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs("p", { className: "pxd-bulk-count", "aria-live": "polite", children: [selected.length, " selected"] }), node.bulkActions && _jsx(Render, { id: node.bulkActions }), _jsx("button", { type: "button", className: "pxd-button pxd-button-tertiary", onClick: () => b.write(node.selected, []), children: "Cancel" })] })) : (_jsxs(_Fragment, { children: [node.search && _jsx(Render, { id: node.search }), _jsx("span", { className: "pxd-table-toolbar-spacer" }), node.toolbar && _jsx(Render, { id: node.toolbar })] })) }))] }));
78
+ const body = !rows.length && node.empty ? _jsx(Render, { id: node.empty }) : compact ? _jsx(RowList, {}) : _jsx(Grid, {});
79
+ function RowList() {
80
+ return (_jsx("ul", { className: "pxd-row-list", "aria-label": caption, children: rows.map((_, i) => {
81
+ const scope = { pointer: childPointer(pointer, i) };
82
+ const [first, ...rest] = node.columns;
83
+ const name = formatValue(get(s.data, absolute(first.path, scope)), resolveFormat(first.format, s.data, b.scope), s.locale);
84
+ const status = rest.find((c) => c.kind === "status");
85
+ const details = rest.filter((c) => c.kind !== "status").slice(0, 3);
86
+ return (_jsxs("li", { className: "pxd-row-item", children: [selection && node.selected && (_jsx(Checkbox.Root, { className: "pxd-checkbox", checked: selected.includes(valueOf(scope, i)), onCheckedChange: () => toggle(valueOf(scope, i)), "aria-label": `Select ${name}`, children: _jsx(Checkbox.Indicator, { children: _jsx(Icon, { name: "check", size: 14 }) }) })), _jsxs("div", { className: "pxd-row-main", children: [_jsx("div", { className: "pxd-row-title", children: cell(first, scope) }), _jsx("p", { className: "pxd-row-details", children: details.map((c, ci) => (_jsxs("span", { children: [ci > 0 && _jsx("span", { "aria-hidden": "true", children: " \u00B7 " }), _jsxs("span", { className: "pxd-sr-only", children: [b.text(c.label), ": "] }), formatValue(get(s.data, absolute(c.path, scope)), resolveFormat(c.format, s.data, b.scope), s.locale)] }, c.key))) })] }), status && cell(status, scope), node.rowActions ? (rowMenu(scope, name)) : node.rowAction && !node.columns[0].kind ? (_jsxs("button", { type: "button", className: "pxd-button pxd-button-tertiary", onClick: () => s.dispatch(node.rowAction, scope, node.id), children: ["Select", _jsxs("span", { className: "pxd-sr-only", children: [" ", name] })] })) : null] }, String(valueOf(scope, i))));
87
+ }) }));
88
+ }
89
+ function Grid() {
90
+ return (_jsx("div", { className: "pxd-table-scroll", children: _jsxs("table", { className: "pxd-table", children: [_jsx("caption", { className: node.views || node.search ? "pxd-sr-only" : undefined, children: caption }), _jsx("thead", { children: _jsxs("tr", { children: [selection && node.selected && (_jsx("th", { scope: "col", className: "pxd-table-select", children: _jsx(Checkbox.Root, { className: "pxd-checkbox", checked: allSelected ? true : selected.length > 0 ? "indeterminate" : false, onCheckedChange: toggleAll, "aria-label": "Select all rows", children: _jsx(Checkbox.Indicator, { children: _jsx(Icon, { name: allSelected ? "check" : "dash", size: 14 }) }) }) })), node.columns.map((c) => {
91
+ const sorted = c.key === sortColumn;
92
+ return (_jsx("th", { scope: "col", className: isNumeric(c) ? "pxd-num" : undefined, "aria-sort": c.sortable ? (sorted ? sortDirection : "none") : undefined, children: c.sortable ? (_jsxs("button", { type: "button", className: "pxd-sort", onClick: () => sortBy(c.key), children: [b.text(c.label), _jsx(Icon, { name: sorted ? (sortDirection === "descending" ? "sortDown" : "sortUp") : "sort", size: 16 })] })) : (b.text(c.label)) }, c.key));
93
+ }), (node.rowActions || node.rowAction) && (_jsx("th", { scope: "col", children: _jsx("span", { className: "pxd-sr-only", children: "Actions" }) }))] }) }), _jsx("tbody", { children: rows.map((_, i) => {
94
+ const scope = { pointer: childPointer(pointer, i) };
95
+ const v = valueOf(scope, i);
96
+ const name = formatValue(get(s.data, absolute(node.columns[0].path, scope)), resolveFormat(node.columns[0].format, s.data, b.scope), s.locale);
97
+ return (_jsxs("tr", { className: selected.includes(v) ? "pxd-row-selected" : undefined, "aria-selected": selection ? selected.includes(v) : undefined, children: [selection && node.selected && (_jsx("td", { className: "pxd-table-select", children: _jsx(Checkbox.Root, { className: "pxd-checkbox", checked: selected.includes(v), onCheckedChange: () => toggle(v), "aria-label": `Select ${name}`, children: _jsx(Checkbox.Indicator, { children: _jsx(Icon, { name: "check", size: 14 }) }) }) })), node.columns.map((c, ci) => {
98
+ const Cell = ci === 0 ? "th" : "td";
99
+ return (_jsx(Cell, { scope: ci === 0 ? "row" : undefined, "data-label": b.text(c.label), className: isNumeric(c) ? "pxd-num" : undefined, children: cell(c, scope) }, c.key));
100
+ }), (node.rowActions || node.rowAction) && (_jsx("td", { className: "pxd-table-action", children: node.rowActions ? (rowMenu(scope, name)) : (_jsxs("button", { type: "button", className: "pxd-button pxd-button-tertiary", onClick: () => s.dispatch(node.rowAction, scope, node.id), children: ["Select", _jsxs("span", { className: "pxd-sr-only", children: [" ", name] })] })) }))] }, String(v)));
101
+ }) })] }) }));
102
+ }
103
+ return (_jsxs("div", { ref: ref, className: "pxd-table-wrap", ...useA11y(node), children: [header, body, node.page && _jsx(Paging, { node: node, rows: rows.length })] }));
104
+ }
105
+ /** Saved views: All, Mine, Past due — tabs with counts, switching what the host sends. */
106
+ function Views({ node }) {
107
+ const b = useBindings();
108
+ const s = useSurface();
109
+ const current = node.view ? b.value(node.view) : node.views[0].key;
110
+ return (_jsx("div", { className: "pxd-table-views", role: "tablist", "aria-label": "Saved views", children: node.views.map((v) => {
111
+ const count = v.count !== undefined ? b.value(v.count) : undefined;
112
+ const on = v.key === current;
113
+ return (_jsxs("button", { type: "button", role: "tab", "aria-selected": on, className: `pxd-table-view${on ? " pxd-table-view-current" : ""}`, onClick: () => {
114
+ if (node.view)
115
+ b.write(node.view, v.key);
116
+ s.dispatch(v.action, b.scope, node.id);
117
+ }, children: [b.text(v.label), count !== undefined && _jsx("span", { className: "pxd-views-count", children: new Intl.NumberFormat(s.locale).format(count) })] }, v.key));
118
+ }) }));
119
+ }
120
+ /** Rows per page, the range shown, and the way to the next page. */
121
+ function Paging({ node, rows }) {
122
+ const b = useBindings();
123
+ const s = useSurface();
124
+ const p = node.page;
125
+ const index = p.index ? (b.value(p.index) ?? 1) : 1;
126
+ const size = p.size ? (b.value(p.size) ?? rows) : rows;
127
+ const total = p.total ? (b.value(p.total) ?? rows) : rows;
128
+ const pages = Math.max(1, Math.ceil(total / (size || 1)));
129
+ const from = total === 0 ? 0 : (index - 1) * size + 1;
130
+ const to = Math.min(index * size, total);
131
+ const n = (v) => new Intl.NumberFormat(s.locale).format(v);
132
+ const go = (next) => {
133
+ if (p.index)
134
+ b.write(p.index, next);
135
+ s.dispatch(p.action, b.scope, node.id);
136
+ };
137
+ return (_jsxs("div", { className: "pxd-paging", children: [p.size && (_jsxs("label", { className: "pxd-paging-size", children: ["Rows per page", _jsx("select", { value: size, onChange: (e) => {
138
+ b.write(p.size, Number(e.target.value));
139
+ if (p.index)
140
+ b.write(p.index, 1);
141
+ s.dispatch(p.action, b.scope, node.id);
142
+ }, children: [...new Set([...PAGE_SIZES, size])].sort((a, c) => a - c).map((x) => (_jsx("option", { value: x, children: x }, x))) })] })), _jsxs("p", { className: "pxd-paging-range", "aria-live": "polite", children: [n(from), "\u2013", n(to), " of ", n(total)] }), _jsxs("div", { className: "pxd-paging-controls", children: [_jsx("button", { type: "button", className: "pxd-icon-button", "aria-label": "Previous page", disabled: index <= 1, onClick: () => go(index - 1), children: _jsx(Icon, { name: "chevronLeft", size: 18 }) }), _jsxs("span", { className: "pxd-paging-page", children: ["Page ", n(index), " of ", n(pages)] }), _jsx("button", { type: "button", className: "pxd-icon-button", "aria-label": "Next page", disabled: index >= pages, onClick: () => go(index + 1), children: _jsx(Icon, { name: "chevronRight", size: 18 }) })] })] }));
143
+ }
144
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/components/table.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { type ReactNode } from "react";
2
+ import { set, type Data, type Scope } from "./data.ts";
3
+ import { type Format } from "./format.ts";
4
+ export type Node = Record<string, any> & {
5
+ id: string;
6
+ component: string;
7
+ };
8
+ export interface UIDocument {
9
+ specVersion: string;
10
+ surface: {
11
+ id: string;
12
+ title: string;
13
+ intent?: string;
14
+ pattern?: string;
15
+ journey?: string;
16
+ dismissible?: boolean;
17
+ subtitle?: string;
18
+ breadcrumbs?: {
19
+ label: unknown;
20
+ action?: any;
21
+ }[];
22
+ badge?: {
23
+ text: unknown;
24
+ tone?: string;
25
+ };
26
+ avatar?: unknown;
27
+ /** ActionBar id: what you can do to this record */
28
+ actions?: string;
29
+ presentation?: "page" | "panel";
30
+ };
31
+ root: string;
32
+ components: Node[];
33
+ data?: Data;
34
+ }
35
+ export interface ActionEvent {
36
+ /** Capability name, e.g. "transfer.confirm" */
37
+ name: string;
38
+ /** Resolved context values */
39
+ context: Record<string, unknown>;
40
+ /** Id of the component that triggered it */
41
+ source: string;
42
+ }
43
+ export interface SurfaceContextValue {
44
+ doc: UIDocument;
45
+ byId: Map<string, Node>;
46
+ data: Data;
47
+ setValue: (pointer: string, value: unknown) => void;
48
+ dispatch: (action: {
49
+ event: {
50
+ name: string;
51
+ context?: Record<string, unknown>;
52
+ };
53
+ } | undefined, scope: Scope, source: string) => void;
54
+ locale: string;
55
+ resolveMedia?: (ref: string) => string | undefined;
56
+ /** Element dialogs portal into, so they stay inside the themed surface */
57
+ portal: HTMLElement | null;
58
+ /** Component renderers in use (the default adapter plus any overrides) */
59
+ components: Record<string, React.ComponentType<{
60
+ node: Node;
61
+ }>>;
62
+ /** Design Direction's profile.disclosure: whether secondary detail starts hidden. */
63
+ disclosure: "progressive" | "show-everything";
64
+ }
65
+ export declare const SurfaceContext: import("react").Context<SurfaceContextValue | null>;
66
+ export declare const ScopeContext: import("react").Context<Scope>;
67
+ /** Heading level for the next Section (the surface title is h1). */
68
+ export declare const HeadingContext: import("react").Context<number>;
69
+ /** Handles ui.back / ui.next inside Steps. */
70
+ export declare const StepsContext: import("react").Context<{
71
+ back: () => void;
72
+ next: () => void;
73
+ } | null>;
74
+ export declare function useSurface(): SurfaceContextValue;
75
+ /** Binding helpers for the current scope. */
76
+ export declare function useBindings(): {
77
+ scope: Scope;
78
+ /** Resolve a literal-or-binding value. */
79
+ value: <T = unknown>(v: unknown) => T;
80
+ /** Resolve and render as text, applying a format. */
81
+ text: (v: unknown, format?: Format) => string;
82
+ /** Absolute pointer of a binding (for inputs that write back). */
83
+ pointer: (v: {
84
+ path: string;
85
+ }) => string;
86
+ write: (v: {
87
+ path: string;
88
+ }, value: unknown) => void;
89
+ context: (c: Record<string, unknown> | undefined) => Record<string, unknown>;
90
+ };
91
+ /** A format's currency may itself be bound to data (e.g. the account's currency). */
92
+ export declare function resolveFormat(format: Format | undefined, data: unknown, scope: Scope): Format | undefined;
93
+ export { set, type Data, type Scope, type ReactNode };
@@ -0,0 +1,42 @@
1
+ import { createContext, useContext } from "react";
2
+ import { resolve, resolveContext, set, absolute } from "./data.js";
3
+ import { formatValue } from "./format.js";
4
+ export const SurfaceContext = createContext(null);
5
+ export const ScopeContext = createContext({ pointer: "" });
6
+ /** Heading level for the next Section (the surface title is h1). */
7
+ export const HeadingContext = createContext(2);
8
+ /** Handles ui.back / ui.next inside Steps. */
9
+ export const StepsContext = createContext(null);
10
+ export function useSurface() {
11
+ const ctx = useContext(SurfaceContext);
12
+ if (!ctx)
13
+ throw new Error("Polyxd components must be rendered inside <PolyxdSurface>");
14
+ return ctx;
15
+ }
16
+ /** Binding helpers for the current scope. */
17
+ export function useBindings() {
18
+ const s = useSurface();
19
+ const scope = useContext(ScopeContext);
20
+ return {
21
+ scope,
22
+ /** Resolve a literal-or-binding value. */
23
+ value: (v) => resolve(v, s.data, scope),
24
+ /** Resolve and render as text, applying a format. */
25
+ text: (v, format) => {
26
+ const r = resolve(v, s.data, scope);
27
+ return format ? formatValue(r, resolveFormat(format, s.data, scope), s.locale) : r === undefined || r === null ? "" : String(r);
28
+ },
29
+ /** Absolute pointer of a binding (for inputs that write back). */
30
+ pointer: (v) => absolute(v.path, scope),
31
+ write: (v, value) => s.setValue(absolute(v.path, scope), value),
32
+ context: (c) => resolveContext(c, s.data, scope),
33
+ };
34
+ }
35
+ /** A format's currency may itself be bound to data (e.g. the account's currency). */
36
+ export function resolveFormat(format, data, scope) {
37
+ if (!format?.currency || typeof format.currency === "string")
38
+ return format;
39
+ return { ...format, currency: resolve(format.currency, data, scope) };
40
+ }
41
+ export { set };
42
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAkB,MAAM,OAAO,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAyB,MAAM,WAAW,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAe,MAAM,aAAa,CAAC;AAmDvD,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAA6B,IAAI,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;AAClE,oEAAoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/C,8CAA8C;AAC9C,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAgD,IAAI,CAAC,CAAC;AAE/F,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IACvC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IACvF,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACvC,OAAO;QACL,KAAK;QACL,0CAA0C;QAC1C,KAAK,EAAE,CAAe,CAAU,EAAK,EAAE,CAAC,OAAO,CAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;QACpE,qDAAqD;QACrD,IAAI,EAAE,CAAC,CAAU,EAAE,MAAe,EAAU,EAAE;YAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACpC,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAClI,CAAC;QACD,kEAAkE;QAClE,OAAO,EAAE,CAAC,CAAmB,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;QACzD,KAAK,EAAE,CAAC,CAAmB,EAAE,KAAc,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAC1F,OAAO,EAAE,CAAC,CAAsC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC;KACtF,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAC,MAA0B,EAAE,IAAa,EAAE,KAAY;IACnF,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC5E,OAAO,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAS,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;AAChF,CAAC;AAED,OAAO,EAAE,GAAG,EAAyC,CAAC"}
package/dist/data.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /** JSON Pointer helpers and binding resolution. Every binding resolves to an absolute pointer. */
2
+ export type Data = Record<string, unknown>;
3
+ /** Where relative paths resolve: the pointer of the current repeated item, or "" at top level. */
4
+ export interface Scope {
5
+ pointer: string;
6
+ }
7
+ export declare const ROOT_SCOPE: Scope;
8
+ export declare const isBinding: (v: unknown) => v is {
9
+ path: string;
10
+ };
11
+ /** Absolute pointer for a path: absolute paths stay; relative ones join the item scope. */
12
+ export declare function absolute(path: string, scope: Scope): string;
13
+ export declare function childPointer(pointer: string, key: string | number): string;
14
+ export declare function get(data: unknown, pointer: string): unknown;
15
+ /** Immutable set; creates intermediate objects (or arrays for numeric keys). */
16
+ export declare function set(data: Data, pointer: string, value: unknown): Data;
17
+ /**
18
+ * Host data as a list. A binding that a component repeats over should point at an array; when the
19
+ * host (or a generated document) points it somewhere else, the component shows nothing instead of
20
+ * throwing. The validator reports the mismatch.
21
+ */
22
+ export declare const asList: (value: unknown) => unknown[];
23
+ /** Resolves a literal-or-binding value. */
24
+ export declare function resolve<T = unknown>(value: unknown, data: unknown, scope: Scope): T;
25
+ /** Resolves every value in an action context. */
26
+ export declare function resolveContext(context: Record<string, unknown> | undefined, data: unknown, scope: Scope): Record<string, unknown>;
package/dist/data.js ADDED
@@ -0,0 +1,52 @@
1
+ /** JSON Pointer helpers and binding resolution. Every binding resolves to an absolute pointer. */
2
+ export const ROOT_SCOPE = { pointer: "" };
3
+ const decode = (s) => s.replace(/~1/g, "/").replace(/~0/g, "~");
4
+ const encode = (s) => s.replace(/~/g, "~0").replace(/\//g, "~1");
5
+ export const isBinding = (v) => !!v && typeof v === "object" && !Array.isArray(v) && typeof v.path === "string";
6
+ /** Absolute pointer for a path: absolute paths stay; relative ones join the item scope. */
7
+ export function absolute(path, scope) {
8
+ return path.startsWith("/") ? path : `${scope.pointer}/${path}`;
9
+ }
10
+ export function childPointer(pointer, key) {
11
+ return `${pointer}/${encode(String(key))}`;
12
+ }
13
+ export function get(data, pointer) {
14
+ if (pointer === "")
15
+ return data;
16
+ let cur = data;
17
+ for (const part of pointer.slice(1).split("/").map(decode)) {
18
+ if (cur === null || typeof cur !== "object")
19
+ return undefined;
20
+ cur = cur[part];
21
+ }
22
+ return cur;
23
+ }
24
+ /** Immutable set; creates intermediate objects (or arrays for numeric keys). */
25
+ export function set(data, pointer, value) {
26
+ const parts = pointer.slice(1).split("/").map(decode);
27
+ const write = (node, i) => {
28
+ const key = parts[i];
29
+ const copy = Array.isArray(node) ? [...node] : { ...(node ?? {}) };
30
+ if (i === parts.length - 1)
31
+ copy[key] = value;
32
+ else
33
+ copy[key] = write(node?.[key] ?? (/^\d+$/.test(parts[i + 1]) ? [] : {}), i + 1);
34
+ return copy;
35
+ };
36
+ return write(data, 0);
37
+ }
38
+ /**
39
+ * Host data as a list. A binding that a component repeats over should point at an array; when the
40
+ * host (or a generated document) points it somewhere else, the component shows nothing instead of
41
+ * throwing. The validator reports the mismatch.
42
+ */
43
+ export const asList = (value) => (Array.isArray(value) ? value : []);
44
+ /** Resolves a literal-or-binding value. */
45
+ export function resolve(value, data, scope) {
46
+ return (isBinding(value) ? get(data, absolute(value.path, scope)) : value);
47
+ }
48
+ /** Resolves every value in an action context. */
49
+ export function resolveContext(context, data, scope) {
50
+ return Object.fromEntries(Object.entries(context ?? {}).map(([k, v]) => [k, resolve(v, data, scope)]));
51
+ }
52
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** Localised presentation of values. The model never pre-formats; the renderer does it here. */
2
+ export interface Format {
3
+ type: "text" | "number" | "currency" | "percent" | "date" | "time" | "datetime" | "relativeTime" | "duration";
4
+ /** ISO 4217 code, or a binding to one (resolved by the renderer before formatting) */
5
+ currency?: string | {
6
+ path: string;
7
+ };
8
+ precision?: number;
9
+ }
10
+ export declare function formatValue(value: unknown, format: Format | undefined, locale: string, now?: number): string;
11
+ /** Currency symbol for input adornments, e.g. "£". */
12
+ export declare function currencySymbol(currency: string, locale: string): string;
package/dist/format.js ADDED
@@ -0,0 +1,51 @@
1
+ /** Localised presentation of values. The model never pre-formats; the renderer does it here. */
2
+ export function formatValue(value, format, locale, now = Date.now()) {
3
+ if (value === null || value === undefined || value === "")
4
+ return "—";
5
+ if (!format || format.type === "text")
6
+ return Array.isArray(value) ? value.join(", ") : String(value);
7
+ const n = typeof value === "number" ? value : Number(value);
8
+ const digits = format.precision === undefined ? {} : { minimumFractionDigits: format.precision, maximumFractionDigits: format.precision };
9
+ try {
10
+ switch (format.type) {
11
+ case "number":
12
+ return new Intl.NumberFormat(locale, digits).format(n);
13
+ case "currency":
14
+ return new Intl.NumberFormat(locale, { style: "currency", currency: typeof format.currency === "string" ? format.currency : "USD", ...digits }).format(n);
15
+ case "percent":
16
+ return new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: format.precision ?? 1 }).format(n);
17
+ case "date":
18
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeZone: "UTC" }).format(new Date(String(value)));
19
+ case "time":
20
+ return new Intl.DateTimeFormat(locale, { timeStyle: "short", timeZone: "UTC" }).format(new Date(String(value)));
21
+ case "datetime":
22
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short", timeZone: "UTC" }).format(new Date(String(value)));
23
+ case "relativeTime": {
24
+ const diff = (new Date(String(value)).getTime() - now) / 1000;
25
+ const units = [["year", 31536000], ["month", 2592000], ["day", 86400], ["hour", 3600], ["minute", 60]];
26
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
27
+ for (const [unit, secs] of units)
28
+ if (Math.abs(diff) >= secs)
29
+ return rtf.format(Math.round(diff / secs), unit);
30
+ return rtf.format(Math.round(diff), "second");
31
+ }
32
+ case "duration": {
33
+ const mins = Math.round(n / 60);
34
+ return mins >= 60 ? `${Math.floor(mins / 60)} h ${mins % 60} min` : `${mins} min`;
35
+ }
36
+ }
37
+ }
38
+ catch {
39
+ return String(value);
40
+ }
41
+ }
42
+ /** Currency symbol for input adornments, e.g. "£". */
43
+ export function currencySymbol(currency, locale) {
44
+ try {
45
+ return new Intl.NumberFormat(locale, { style: "currency", currency }).formatToParts(0).find((p) => p.type === "currency")?.value ?? currency;
46
+ }
47
+ catch {
48
+ return currency;
49
+ }
50
+ }
51
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAShG,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,MAA0B,EAAE,MAAc,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IACtG,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC;IACtE,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtG,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,qBAAqB,EAAE,MAAM,CAAC,SAAS,EAAE,qBAAqB,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;IAC1I,IAAI,CAAC;QACH,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,QAAQ;gBACX,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACzD,KAAK,UAAU;gBACb,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC5J,KAAK,SAAS;gBACZ,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACrH,KAAK,MAAM;gBACT,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACnH,KAAK,MAAM;gBACT,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAClH,KAAK,UAAU;gBACb,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACvI,KAAK,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC;gBAC9D,MAAM,KAAK,GAA4C,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;gBAChJ,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;gBACrE,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK;oBAAE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;wBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;gBAC/G,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;YAChD,CAAC;YACD,KAAK,UAAU,EAAE,CAAC;gBAChB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBAChC,OAAO,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,MAAM,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC;YACpF,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,MAAc;IAC7D,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,KAAK,IAAI,QAAQ,CAAC;IAC/I,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { PolyxdSurface, Render, type PolyxdSurfaceProps } from "./surface.tsx";
2
+ export { useBindings, useSurface, type UIDocument, type ActionEvent, type Node } from "./context.tsx";
3
+ export { registry, type ComponentRenderer } from "./components/index.ts";
4
+ export { formatValue, type Format } from "./format.ts";
5
+ export { get as getPointer, set as setPointer, type Data } from "./data.ts";
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { PolyxdSurface, Render } from "./surface.js";
2
+ export { useBindings, useSurface } from "./context.js";
3
+ export { registry } from "./components/index.js";
4
+ export { formatValue } from "./format.js";
5
+ export { get as getPointer, set as setPointer } from "./data.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,EAA2B,MAAM,cAAe,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAgD,MAAM,cAAe,CAAC;AACtG,OAAO,EAAE,QAAQ,EAA0B,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAe,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,GAAG,IAAI,UAAU,EAAE,GAAG,IAAI,UAAU,EAAa,MAAM,WAAW,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { StepsContext, type ActionEvent, type Node, type UIDocument } from "./context.tsx";
2
+ import { type Data, type Scope } from "./data.ts";
3
+ import { type ComponentRenderer } from "./components/index.ts";
4
+ export interface PolyxdSurfaceProps {
5
+ document: UIDocument;
6
+ /** Host data. Defaults to document.data. The surface keeps its own copy as inputs change. */
7
+ data?: Data;
8
+ /** Called for every capability action the user triggers. */
9
+ onAction?: (event: ActionEvent) => void;
10
+ /** Called with the new data whenever an input changes it. */
11
+ onDataChange?: (data: Data) => void;
12
+ /** Called for ui.dismiss (Cancel on a dialog, closing the surface). */
13
+ onDismiss?: () => void;
14
+ /** Design-system pack name, e.g. "material3" (matching a loaded theme CSS file). */
15
+ theme?: string;
16
+ /** Design Direction's profile.density. Sets row heights and spacing; compact is for pointer surfaces. */
17
+ density?: "compact" | "comfortable" | "spacious";
18
+ /** Design Direction's profile.disclosure. "show-everything" opens every Disclosure by default. */
19
+ disclosure?: "progressive" | "show-everything";
20
+ mode?: "light" | "dark";
21
+ locale?: string;
22
+ /** Turns a host media reference into a URL. Generated UIs never contain URLs. */
23
+ resolveMedia?: (ref: string) => string | undefined;
24
+ /** Renderer adapter overrides: replace any component's renderer (e.g. with Astryx or your own). */
25
+ components?: Partial<Record<string, ComponentRenderer>>;
26
+ className?: string;
27
+ }
28
+ /** Renders one Polyxd UI document. */
29
+ export declare function PolyxdSurface({ document: doc, data: initial, onAction, onDataChange, onDismiss, theme, mode, density, disclosure, locale, resolveMedia, components: overrides, className }: PolyxdSurfaceProps): import("react").JSX.Element;
30
+ /** Renders a component by id in the current scope. */
31
+ export declare function Render({ id, scope }: {
32
+ id: string;
33
+ scope?: Scope;
34
+ }): import("react").JSX.Element | null;
35
+ /** Accessibility props from a node's `accessibility` block. */
36
+ export declare function useA11y(node: Node): Record<string, unknown>;
37
+ export { StepsContext };