@godxjp/ui 31.4.0 → 31.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent/START-HERE.md +5 -5
- package/agent/components/CodeBlock.json +7 -1
- package/agent/components/OrgChart.json +59 -0
- package/agent/components-index.json +5 -0
- package/agent/components.json +66 -1
- package/agent/index.json +6 -6
- package/agent/llms.txt +6 -6
- package/agent/tokens.json +108 -0
- package/dist/components/data-display/code-block.js +90 -4
- package/dist/components/data-display/index.d.ts +2 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/org-chart.d.ts +5 -0
- package/dist/components/data-display/org-chart.js +169 -0
- package/dist/components/general/typography.d.ts +32 -0
- package/dist/components/general/typography.js +11 -2
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +10 -0
- package/dist/i18n/messages/ja.json +10 -0
- package/dist/i18n/messages/vi.json +10 -0
- package/dist/props/components/data-display.prop.d.ts +51 -1
- package/dist/props/registry.d.ts +39 -0
- package/dist/props/registry.js +49 -0
- package/dist/styles/data-display-layout.css +173 -0
- package/dist/styles/layers.json +14 -1
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/org-chart.css +27 -0
- package/docs/FRAME-COVERAGE-REPORT.md +3 -2
- package/docs/data-display/code-block.tsx +27 -0
- package/docs/data-display/org-chart.tsx +165 -0
- package/docs/navigation/tabs.tsx +17 -15
- package/docs/query/data-state.tsx +2 -4
- package/docs/showcase/table-view-tabs.tsx +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
|
+
import { useScrollsHorizontally } from "../../lib/hooks.js";
|
|
6
|
+
import { cn } from "../../lib/utils.js";
|
|
7
|
+
import { Tree } from "./tree.js";
|
|
8
|
+
function flatten(nodes) {
|
|
9
|
+
const out = [];
|
|
10
|
+
const walk = (list, depth, parent) => {
|
|
11
|
+
for (const node of list) {
|
|
12
|
+
const index = out.length;
|
|
13
|
+
out.push({ node, depth, parent, firstChild: null });
|
|
14
|
+
if (node.children?.length) {
|
|
15
|
+
out[index].firstChild = out.length;
|
|
16
|
+
walk(node.children, depth + 1, index);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
walk(nodes, 0, null);
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
function toTreeData(nodes) {
|
|
24
|
+
return nodes.map((node) => ({
|
|
25
|
+
value: node.key,
|
|
26
|
+
label: node.name,
|
|
27
|
+
children: node.children?.length ? toTreeData(node.children) : void 0
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
function isRtl(element) {
|
|
31
|
+
return element.closest("[dir]")?.getAttribute("dir")?.toLowerCase() === "rtl";
|
|
32
|
+
}
|
|
33
|
+
function OrgChartRoot({
|
|
34
|
+
data,
|
|
35
|
+
renderNode,
|
|
36
|
+
label,
|
|
37
|
+
className,
|
|
38
|
+
id,
|
|
39
|
+
forwardedRef,
|
|
40
|
+
...rest
|
|
41
|
+
}) {
|
|
42
|
+
const { t } = useTranslation();
|
|
43
|
+
const reactId = React.useId();
|
|
44
|
+
const baseId = id ?? `${reactId}-org-chart`;
|
|
45
|
+
const treeLabel = label ?? t("dataDisplay.orgChart.label");
|
|
46
|
+
const flat = React.useMemo(() => flatten(data), [data]);
|
|
47
|
+
const indexByKey = React.useMemo(
|
|
48
|
+
() => new Map(flat.map((entry, index) => [entry.node.key, index])),
|
|
49
|
+
[flat]
|
|
50
|
+
);
|
|
51
|
+
const scrollRef = React.useRef(null);
|
|
52
|
+
const scrolls = useScrollsHorizontally(scrollRef, true);
|
|
53
|
+
const [activeKey, setActiveKey] = React.useState(null);
|
|
54
|
+
const rovingKey = (activeKey && indexByKey.has(activeKey) ? activeKey : null) ?? flat[0]?.node.key ?? null;
|
|
55
|
+
const nodeRefs = React.useRef(/* @__PURE__ */ new Map());
|
|
56
|
+
const moveTo = (index) => {
|
|
57
|
+
if (index == null) return;
|
|
58
|
+
const entry = flat[index];
|
|
59
|
+
if (!entry) return;
|
|
60
|
+
setActiveKey(entry.node.key);
|
|
61
|
+
nodeRefs.current.get(entry.node.key)?.focus();
|
|
62
|
+
};
|
|
63
|
+
const onKeyDown = (event, index) => {
|
|
64
|
+
const entry = flat[index];
|
|
65
|
+
const rtl = isRtl(event.currentTarget);
|
|
66
|
+
const inward = rtl ? "ArrowLeft" : "ArrowRight";
|
|
67
|
+
const outward = rtl ? "ArrowRight" : "ArrowLeft";
|
|
68
|
+
let target;
|
|
69
|
+
if (event.key === "ArrowDown") target = index + 1 < flat.length ? index + 1 : null;
|
|
70
|
+
else if (event.key === "ArrowUp") target = index > 0 ? index - 1 : null;
|
|
71
|
+
else if (event.key === "Home") target = 0;
|
|
72
|
+
else if (event.key === "End") target = flat.length - 1;
|
|
73
|
+
else if (event.key === inward) target = entry.firstChild;
|
|
74
|
+
else if (event.key === outward) target = entry.parent;
|
|
75
|
+
else return;
|
|
76
|
+
event.preventDefault();
|
|
77
|
+
moveTo(target ?? null);
|
|
78
|
+
};
|
|
79
|
+
const renderBranch = (nodes) => nodes.map((node, position) => {
|
|
80
|
+
const index = indexByKey.get(node.key);
|
|
81
|
+
const { depth } = flat[index];
|
|
82
|
+
const nodeId = `${baseId}-n${index}`;
|
|
83
|
+
const groupId = `${nodeId}-group`;
|
|
84
|
+
const hasChildren = Boolean(node.children?.length);
|
|
85
|
+
const isAgent = node.variant === "agent";
|
|
86
|
+
const labelledBy = renderNode ? void 0 : [
|
|
87
|
+
`${nodeId}-name`,
|
|
88
|
+
node.title ? `${nodeId}-title` : null,
|
|
89
|
+
isAgent ? `${nodeId}-kind` : null
|
|
90
|
+
].filter(Boolean).join(" ");
|
|
91
|
+
return /* @__PURE__ */ jsxs("li", { role: "none", className: "ui-org-chart-branch", children: [
|
|
92
|
+
/* @__PURE__ */ jsxs(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
ref: (element) => {
|
|
96
|
+
nodeRefs.current.set(node.key, element);
|
|
97
|
+
},
|
|
98
|
+
id: nodeId,
|
|
99
|
+
role: "treeitem",
|
|
100
|
+
"aria-level": depth + 1,
|
|
101
|
+
"aria-setsize": nodes.length,
|
|
102
|
+
"aria-posinset": position + 1,
|
|
103
|
+
"aria-labelledby": labelledBy,
|
|
104
|
+
"aria-describedby": !renderNode && node.extra ? `${nodeId}-extra` : void 0,
|
|
105
|
+
"aria-owns": hasChildren ? groupId : void 0,
|
|
106
|
+
tabIndex: rovingKey === node.key ? 0 : -1,
|
|
107
|
+
"data-key": node.key,
|
|
108
|
+
"data-variant": isAgent ? "agent" : "person",
|
|
109
|
+
className: "ui-org-chart-node ui-focus-ring",
|
|
110
|
+
onFocus: () => setActiveKey(node.key),
|
|
111
|
+
onKeyDown: (event) => onKeyDown(event, index),
|
|
112
|
+
children: [
|
|
113
|
+
renderNode ? renderNode(node) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
114
|
+
node.avatar ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ui-org-chart-avatar", children: node.avatar }) : null,
|
|
115
|
+
/* @__PURE__ */ jsxs("span", { className: "ui-org-chart-text", children: [
|
|
116
|
+
/* @__PURE__ */ jsx("span", { id: `${nodeId}-name`, className: "ui-org-chart-name", children: node.name }),
|
|
117
|
+
node.title ? /* @__PURE__ */ jsx("span", { id: `${nodeId}-title`, className: "ui-org-chart-title", children: node.title }) : null,
|
|
118
|
+
node.extra ? /* @__PURE__ */ jsx("span", { id: `${nodeId}-extra`, className: "ui-org-chart-extra", children: node.extra }) : null
|
|
119
|
+
] })
|
|
120
|
+
] }),
|
|
121
|
+
isAgent ? /* @__PURE__ */ jsx("span", { id: `${nodeId}-kind`, className: "sr-only", children: t("dataDisplay.orgChart.agent") }) : null
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
hasChildren ? /* @__PURE__ */ jsx("ul", { id: groupId, role: "group", className: "ui-org-chart-children", children: renderBranch(node.children) }) : null
|
|
126
|
+
] }, node.key);
|
|
127
|
+
});
|
|
128
|
+
const treeData = React.useMemo(() => toTreeData(data), [data]);
|
|
129
|
+
const nodeByKey = React.useMemo(
|
|
130
|
+
() => new Map(flat.map((entry) => [entry.node.key, entry.node])),
|
|
131
|
+
[flat]
|
|
132
|
+
);
|
|
133
|
+
return /* @__PURE__ */ jsxs("div", { ...rest, ref: forwardedRef, id, className: cn("ui-org-chart", className), children: [
|
|
134
|
+
/* @__PURE__ */ jsx(
|
|
135
|
+
"div",
|
|
136
|
+
{
|
|
137
|
+
ref: scrollRef,
|
|
138
|
+
className: "ui-org-chart-scroll",
|
|
139
|
+
...scrolls ? { role: "region", "aria-label": t("dataDisplay.orgChart.scrollRegion"), tabIndex: 0 } : {},
|
|
140
|
+
children: /* @__PURE__ */ jsx("ul", { role: "tree", "aria-label": treeLabel, className: "ui-org-chart-tree", children: renderBranch(data) })
|
|
141
|
+
}
|
|
142
|
+
),
|
|
143
|
+
/* @__PURE__ */ jsx("div", { className: "ui-org-chart-list", children: /* @__PURE__ */ jsx(
|
|
144
|
+
Tree,
|
|
145
|
+
{
|
|
146
|
+
"aria-label": treeLabel,
|
|
147
|
+
treeData,
|
|
148
|
+
defaultExpandAll: true,
|
|
149
|
+
titleRender: (treeNode) => {
|
|
150
|
+
const node = nodeByKey.get(treeNode.value);
|
|
151
|
+
if (!node) return treeNode.label;
|
|
152
|
+
if (renderNode) return renderNode(node);
|
|
153
|
+
return /* @__PURE__ */ jsxs("span", { className: "ui-org-chart-list-row", children: [
|
|
154
|
+
node.avatar ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ui-org-chart-avatar", children: node.avatar }) : null,
|
|
155
|
+
/* @__PURE__ */ jsx("span", { className: "ui-org-chart-name", children: node.name }),
|
|
156
|
+
node.title ? /* @__PURE__ */ jsx("span", { className: "ui-org-chart-title", children: node.title }) : null,
|
|
157
|
+
node.variant === "agent" ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("dataDisplay.orgChart.agent") }) : null,
|
|
158
|
+
node.extra ? /* @__PURE__ */ jsx("span", { className: "ui-org-chart-extra", children: node.extra }) : null
|
|
159
|
+
] });
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
) })
|
|
163
|
+
] });
|
|
164
|
+
}
|
|
165
|
+
const OrgChart = React.forwardRef((props, ref) => /* @__PURE__ */ jsx(OrgChartRoot, { ...props, forwardedRef: ref }));
|
|
166
|
+
OrgChart.displayName = "OrgChart";
|
|
167
|
+
export {
|
|
168
|
+
OrgChart
|
|
169
|
+
};
|
|
@@ -2,6 +2,38 @@ import * as React from "react";
|
|
|
2
2
|
import type { TextProp, TypographyBlockProp } from "../../props/components/general.prop.js";
|
|
3
3
|
import type { TypographyEllipsisConfigProp } from "../../props/vocabulary/index.js";
|
|
4
4
|
export type { TextProp, TextProp as TextProps, HeadingProp, HeadingProp as HeadingProps, TypographyProp, TypographyProp as TypographyProps, TypographyBlockProp, TypographyTitleProp, TypographyTitleProp as TitleProps, ParagraphProp, ParagraphProp as ParagraphProps, LinkProp, LinkProp as LinkProps, } from "../../props/components/general.prop.js";
|
|
5
|
+
/** How long the copy button shows its confirmed state. antd's value (`useCopyClick`). */
|
|
6
|
+
export declare const COPIED_RESET_MS = 3000;
|
|
7
|
+
/** antd `getNode` — `true`/`undefined` take the default; `false` suppresses unless a DOM node is required. */
|
|
8
|
+
export declare function getNode(node: React.ReactNode | boolean | undefined, fallback: React.ReactNode, needDom?: boolean): React.ReactNode;
|
|
9
|
+
/** antd `toCopyConfigList` — `false` suppresses BOTH states, otherwise index 0 = idle, 1 = copied. */
|
|
10
|
+
export declare function toCopyConfigList(value: React.ReactNode | false | undefined): (string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | Iterable<React.ReactNode> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined)[] | readonly [false, false];
|
|
11
|
+
/**
|
|
12
|
+
* antd `useMergedConfig` — `true` means "on, all defaults"; an object means "on, these overrides".
|
|
13
|
+
* The boolean is the SUPPORT flag, so `copyable={false}` and `copyable={undefined}` are both off.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useMergedConfig<T extends object>(propConfig: boolean | T | undefined, template?: Partial<T>): [boolean, T];
|
|
16
|
+
/**
|
|
17
|
+
* The clipboard write, antd's `_util/copy` reduced to the one path a modern browser takes.
|
|
18
|
+
*
|
|
19
|
+
* antd keeps a `document.execCommand("copy")` fallback for browsers without the async Clipboard
|
|
20
|
+
* API. It is NOT ported: `execCommand` is deprecated, every browser in this package's support
|
|
21
|
+
* matrix ships `navigator.clipboard`, and the fallback's failure mode is worse than none — it
|
|
22
|
+
* reports success from a synchronous flag that a permission prompt can leave stale, so the UI
|
|
23
|
+
* claims a copy that never happened. Here a refusal throws, `onCopy` never fires, and the button
|
|
24
|
+
* never shows its confirmed state.
|
|
25
|
+
*/
|
|
26
|
+
export declare function writeClipboard(text: string, format: "text/plain" | "text/html" | undefined): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* A tooltip that disappears entirely when its title is suppressed.
|
|
29
|
+
*
|
|
30
|
+
* antd wraps every action in `<Tooltip>`; this library's Tooltip is the house primitive and is
|
|
31
|
+
* composed (`Tooltip > TooltipTrigger > TooltipContent`), so the wrapper lives here.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ActionTooltip({ title, children, }: {
|
|
34
|
+
title: React.ReactNode;
|
|
35
|
+
children: React.ReactNode;
|
|
36
|
+
}): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | Iterable<React.ReactNode> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined> | null | undefined;
|
|
5
37
|
/**
|
|
6
38
|
* Text — the typographic primitive, and antd's `Typography.Text`.
|
|
7
39
|
*
|
|
@@ -62,7 +62,10 @@ async function writeClipboard(text, format) {
|
|
|
62
62
|
function childrenToText(children) {
|
|
63
63
|
return React.Children.toArray(children).map((node) => typeof node === "string" || typeof node === "number" ? String(node) : "").join("");
|
|
64
64
|
}
|
|
65
|
-
function ActionTooltip({
|
|
65
|
+
function ActionTooltip({
|
|
66
|
+
title,
|
|
67
|
+
children
|
|
68
|
+
}) {
|
|
66
69
|
if (title === null || title === void 0 || title === false || title === "") return children;
|
|
67
70
|
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
68
71
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children }),
|
|
@@ -654,10 +657,16 @@ const Typography = Object.assign(TypographyRoot, {
|
|
|
654
657
|
Link
|
|
655
658
|
});
|
|
656
659
|
export {
|
|
660
|
+
ActionTooltip,
|
|
661
|
+
COPIED_RESET_MS,
|
|
657
662
|
Heading,
|
|
658
663
|
Link,
|
|
659
664
|
Paragraph,
|
|
660
665
|
Text,
|
|
661
666
|
Title,
|
|
662
|
-
Typography
|
|
667
|
+
Typography,
|
|
668
|
+
getNode,
|
|
669
|
+
toCopyConfigList,
|
|
670
|
+
useMergedConfig,
|
|
671
|
+
writeClipboard
|
|
663
672
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
|
|
3
|
-
"version": "31.
|
|
3
|
+
"version": "31.5.0",
|
|
4
4
|
"targetSize": {
|
|
5
5
|
"standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
|
|
6
6
|
"min": 24,
|
|
@@ -371,6 +371,11 @@
|
|
|
371
371
|
"abort": "stopped"
|
|
372
372
|
}
|
|
373
373
|
},
|
|
374
|
+
"orgChart": {
|
|
375
|
+
"label": "Organization chart",
|
|
376
|
+
"scrollRegion": "Scrollable organization chart",
|
|
377
|
+
"agent": "AI agent"
|
|
378
|
+
},
|
|
374
379
|
"timeline": {
|
|
375
380
|
"statusDone": "Completed: ",
|
|
376
381
|
"statusCurrent": "Current: ",
|
|
@@ -419,6 +424,11 @@
|
|
|
419
424
|
"edit": "Edit",
|
|
420
425
|
"expand": "Expand",
|
|
421
426
|
"collapse": "Collapse"
|
|
427
|
+
},
|
|
428
|
+
"codeBlock": {
|
|
429
|
+
"copy": "Copy code",
|
|
430
|
+
"copied": "Copied",
|
|
431
|
+
"copiedAnnounce": "Code copied to clipboard"
|
|
422
432
|
}
|
|
423
433
|
},
|
|
424
434
|
"navigation": {
|
|
@@ -364,6 +364,11 @@
|
|
|
364
364
|
"abort": "中断"
|
|
365
365
|
}
|
|
366
366
|
},
|
|
367
|
+
"orgChart": {
|
|
368
|
+
"label": "組織図",
|
|
369
|
+
"scrollRegion": "スクロールできる組織図",
|
|
370
|
+
"agent": "AIエージェント"
|
|
371
|
+
},
|
|
367
372
|
"timeline": {
|
|
368
373
|
"statusDone": "完了: ",
|
|
369
374
|
"statusCurrent": "現在: ",
|
|
@@ -412,6 +417,11 @@
|
|
|
412
417
|
"edit": "編集",
|
|
413
418
|
"expand": "展開",
|
|
414
419
|
"collapse": "折りたたむ"
|
|
420
|
+
},
|
|
421
|
+
"codeBlock": {
|
|
422
|
+
"copy": "コードをコピー",
|
|
423
|
+
"copied": "コピーしました",
|
|
424
|
+
"copiedAnnounce": "コードをクリップボードにコピーしました"
|
|
415
425
|
}
|
|
416
426
|
},
|
|
417
427
|
"navigation": {
|
|
@@ -365,6 +365,11 @@
|
|
|
365
365
|
"abort": "đã dừng"
|
|
366
366
|
}
|
|
367
367
|
},
|
|
368
|
+
"orgChart": {
|
|
369
|
+
"label": "Sơ đồ tổ chức",
|
|
370
|
+
"scrollRegion": "Sơ đồ tổ chức có thể cuộn",
|
|
371
|
+
"agent": "Tác tử AI"
|
|
372
|
+
},
|
|
368
373
|
"timeline": {
|
|
369
374
|
"statusDone": "Đã xong: ",
|
|
370
375
|
"statusCurrent": "Hiện tại: ",
|
|
@@ -413,6 +418,11 @@
|
|
|
413
418
|
"edit": "Sửa",
|
|
414
419
|
"expand": "Mở rộng",
|
|
415
420
|
"collapse": "Thu gọn"
|
|
421
|
+
},
|
|
422
|
+
"codeBlock": {
|
|
423
|
+
"copy": "Sao chép mã",
|
|
424
|
+
"copied": "Đã sao chép",
|
|
425
|
+
"copiedAnnounce": "Đã sao chép mã vào bộ nhớ tạm"
|
|
416
426
|
}
|
|
417
427
|
},
|
|
418
428
|
"navigation": {
|
|
@@ -22,6 +22,13 @@ export type CodeBlockProp = {
|
|
|
22
22
|
size?: Extract<SizeProp, "xs" | "sm">;
|
|
23
23
|
/** Lands on `data-language`; no highlighter is bundled — see `children` for colouring its output. */
|
|
24
24
|
language?: string;
|
|
25
|
+
/**
|
|
26
|
+
* A copy button in the block's inline-end corner — antd `Typography`'s `copyable`, same name and
|
|
27
|
+
* semantics. `true` copies the block's text content; the object form sets `text`, `onCopy`,
|
|
28
|
+
* `tooltips` (`[copy, copied]`, or `false`), `icon` (`[copy, copied]`), `format` and `tabIndex`.
|
|
29
|
+
* The copy is announced politely to assistive technology.
|
|
30
|
+
*/
|
|
31
|
+
copyable?: boolean | TypographyCopyConfigProp;
|
|
25
32
|
className?: ClassNameProp;
|
|
26
33
|
};
|
|
27
34
|
/**
|
|
@@ -36,7 +43,7 @@ export type ProseProp = {
|
|
|
36
43
|
className?: ClassNameProp;
|
|
37
44
|
children?: ChildrenProp;
|
|
38
45
|
};
|
|
39
|
-
import type { ActionProp, ClassNameProp, DescriptionProp, IconProp, TitleProp, ColumnDefProp, GetRowIdProp, GetRowLabelProp, OnRowClickProp, OnSelectChangeProp, OnSortChangeProp, OnTableDensityChangeProp, SelectedIdsProp, SortStateProp, TableDensityProp, TablePresetProp, BreakpointProp, DensityProp, ChildrenProp, PendingProp, ToneProp, AvatarShapeProp, HeadingLevelProp, HandlerProp, SizeProp, LabelProp, IdProp, DescriptionsLayoutProp, DescriptionsColumnProp, DescriptionsSpanProp, DescriptionsItemsProp, GapProp, SortDirectionProp, OnColumnFilterChangeProp, OnRowProp, TableExpandableProp, TableRowSelectionProp, TableScrollProp, TableStickyProp, TableSummaryProp, DisabledProp, OnClickProp, ValueProp, DefaultValueProp, OnValueChangeProp } from "../vocabulary/index.js";
|
|
46
|
+
import type { ActionProp, ClassNameProp, DescriptionProp, IconProp, TitleProp, ExtraProp, ColumnDefProp, GetRowIdProp, GetRowLabelProp, OnRowClickProp, OnSelectChangeProp, OnSortChangeProp, OnTableDensityChangeProp, SelectedIdsProp, SortStateProp, TableDensityProp, TablePresetProp, BreakpointProp, DensityProp, ChildrenProp, PendingProp, ToneProp, AvatarShapeProp, HeadingLevelProp, HandlerProp, SizeProp, LabelProp, IdProp, DescriptionsLayoutProp, DescriptionsColumnProp, DescriptionsSpanProp, DescriptionsItemsProp, GapProp, SortDirectionProp, OnColumnFilterChangeProp, OnRowProp, TableExpandableProp, TableRowSelectionProp, TableScrollProp, TableStickyProp, TableSummaryProp, DisabledProp, OnClickProp, ValueProp, DefaultValueProp, OnValueChangeProp, TypographyCopyConfigProp } from "../vocabulary/index.js";
|
|
40
47
|
import type { TreeFieldNamesProp, TreeOptionProp } from "./data-entry.prop.js";
|
|
41
48
|
/**
|
|
42
49
|
* One key in a `Legend`: a tone, and the words that tone stands for.
|
|
@@ -1126,3 +1133,46 @@ export type MarqueeProp = Omit<React.HTMLAttributes<HTMLDivElement>, "onPlay" |
|
|
|
1126
1133
|
label?: LabelProp;
|
|
1127
1134
|
className?: ClassNameProp;
|
|
1128
1135
|
};
|
|
1136
|
+
/**
|
|
1137
|
+
* @see OrgChart — who a box stands for. `agent` draws the box with a DASHED border so an AI agent
|
|
1138
|
+
* is told apart from a person at a glance, and adds a localized visually hidden "AI agent" to the
|
|
1139
|
+
* node's accessible name, so the difference is never carried by the stroke alone (WCAG 1.4.1).
|
|
1140
|
+
*/
|
|
1141
|
+
export type OrgChartNodeVariantProp = "person" | "agent";
|
|
1142
|
+
/** @see OrgChart — one box of the chart. */
|
|
1143
|
+
export type OrgChartNodeProp = {
|
|
1144
|
+
/** Identity of the node. Unique across the whole chart. */
|
|
1145
|
+
key: string;
|
|
1146
|
+
/** The person's or agent's name — the box's first line and the start of its accessible name. */
|
|
1147
|
+
name: React.ReactNode;
|
|
1148
|
+
/** Role / job title, the line under the name. */
|
|
1149
|
+
title?: TitleProp;
|
|
1150
|
+
/** The mark at the box's inline start — usually an `<Avatar>`. Decorative; the name carries identity. */
|
|
1151
|
+
avatar?: React.ReactNode;
|
|
1152
|
+
/** Free slot under the text — a Badge, a status, a count. */
|
|
1153
|
+
extra?: ExtraProp;
|
|
1154
|
+
/** `person` (default) or `agent` (dashed box). */
|
|
1155
|
+
variant?: OrgChartNodeVariantProp;
|
|
1156
|
+
children?: readonly OrgChartNodeProp[];
|
|
1157
|
+
};
|
|
1158
|
+
/**
|
|
1159
|
+
* @see OrgChart — an organization chart: boxes joined by lines, top-down, with a horizontal scroll
|
|
1160
|
+
* region of its own when the chart is wider than its container, and an indented `Tree` of the same
|
|
1161
|
+
* data when the CONTAINER is narrow. It is the WAI-ARIA APG tree view in both forms.
|
|
1162
|
+
*/
|
|
1163
|
+
export type OrgChartProp = {
|
|
1164
|
+
/** The hierarchy. Usually one root; several roots render side by side. */
|
|
1165
|
+
data: readonly OrgChartNodeProp[];
|
|
1166
|
+
/**
|
|
1167
|
+
* Replace the box's content (avatar · name · title · extra) with your own. The box, its border,
|
|
1168
|
+
* the connectors and the keyboard stay the library's. Used by the narrow `Tree` form too.
|
|
1169
|
+
*/
|
|
1170
|
+
renderNode?: (node: OrgChartNodeProp) => React.ReactNode;
|
|
1171
|
+
/**
|
|
1172
|
+
* Accessible name of the chart (the `role="tree"`) — a plain string. A localized default
|
|
1173
|
+
* ("Organization chart") applies when omitted.
|
|
1174
|
+
*/
|
|
1175
|
+
label?: Extract<LabelProp, string>;
|
|
1176
|
+
className?: ClassNameProp;
|
|
1177
|
+
id?: IdProp;
|
|
1178
|
+
};
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -3929,6 +3929,45 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
3929
3929
|
readonly file: "components/data-display.prop.ts";
|
|
3930
3930
|
readonly vocabulary: readonly ["TitleProp", "DescriptionProp", "IconProp", "StatusProp", "ControlVariantProp", "DisabledProp", "OnClickProp", "IdProp", "ClassNameProp"];
|
|
3931
3931
|
};
|
|
3932
|
+
readonly OrgChartNodeVariantProp: {
|
|
3933
|
+
readonly group: "data-display";
|
|
3934
|
+
readonly file: "components/data-display.prop.ts";
|
|
3935
|
+
readonly vocabulary: readonly ["ControlVariantProp"];
|
|
3936
|
+
};
|
|
3937
|
+
readonly OrgChartNodeProp: {
|
|
3938
|
+
readonly group: "data-display";
|
|
3939
|
+
readonly file: "components/data-display.prop.ts";
|
|
3940
|
+
readonly vocabulary: readonly ["TitleProp", "ExtraProp", "ControlVariantProp", {
|
|
3941
|
+
readonly field: "key";
|
|
3942
|
+
readonly local: true;
|
|
3943
|
+
readonly reason: "The node's identity, unique across the chart.";
|
|
3944
|
+
}, {
|
|
3945
|
+
readonly field: "name";
|
|
3946
|
+
readonly local: true;
|
|
3947
|
+
readonly reason: "The person's or agent's display name (a ReactNode), not a form field `name` — NameProp is the submitted-field key.";
|
|
3948
|
+
}, {
|
|
3949
|
+
readonly field: "avatar";
|
|
3950
|
+
readonly local: true;
|
|
3951
|
+
readonly reason: "The mark at the box's inline start, usually an <Avatar>. Decorative.";
|
|
3952
|
+
}, {
|
|
3953
|
+
readonly field: "children";
|
|
3954
|
+
readonly local: true;
|
|
3955
|
+
readonly reason: "The node's own reports — the hierarchy itself, not a slot.";
|
|
3956
|
+
}];
|
|
3957
|
+
};
|
|
3958
|
+
readonly OrgChartProp: {
|
|
3959
|
+
readonly group: "data-display";
|
|
3960
|
+
readonly file: "components/data-display.prop.ts";
|
|
3961
|
+
readonly vocabulary: readonly ["LabelProp", "ClassNameProp", "IdProp", {
|
|
3962
|
+
readonly field: "data";
|
|
3963
|
+
readonly local: true;
|
|
3964
|
+
readonly reason: "The hierarchy of OrgChartNodeProp — the same shape feeds the boxes and the narrow Tree.";
|
|
3965
|
+
}, {
|
|
3966
|
+
readonly field: "renderNode";
|
|
3967
|
+
readonly local: true;
|
|
3968
|
+
readonly reason: "Escape hatch replacing a box's content; the box, connectors and keyboard stay the library's.";
|
|
3969
|
+
}];
|
|
3970
|
+
};
|
|
3932
3971
|
};
|
|
3933
3972
|
export type ComponentPropName = keyof typeof COMPONENT_PROP_REGISTRY;
|
|
3934
3973
|
/** Forbidden duplicate concepts — use the canonical name on the left. */
|
package/dist/props/registry.js
CHANGED
|
@@ -4764,6 +4764,55 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
4764
4764
|
"IdProp",
|
|
4765
4765
|
"ClassNameProp"
|
|
4766
4766
|
]
|
|
4767
|
+
},
|
|
4768
|
+
OrgChartNodeVariantProp: {
|
|
4769
|
+
group: "data-display",
|
|
4770
|
+
file: "components/data-display.prop.ts",
|
|
4771
|
+
vocabulary: ["ControlVariantProp"]
|
|
4772
|
+
},
|
|
4773
|
+
OrgChartNodeProp: {
|
|
4774
|
+
group: "data-display",
|
|
4775
|
+
file: "components/data-display.prop.ts",
|
|
4776
|
+
vocabulary: [
|
|
4777
|
+
"TitleProp",
|
|
4778
|
+
"ExtraProp",
|
|
4779
|
+
"ControlVariantProp",
|
|
4780
|
+
{ field: "key", local: true, reason: "The node's identity, unique across the chart." },
|
|
4781
|
+
{
|
|
4782
|
+
field: "name",
|
|
4783
|
+
local: true,
|
|
4784
|
+
reason: "The person's or agent's display name (a ReactNode), not a form field `name` \u2014 NameProp is the submitted-field key."
|
|
4785
|
+
},
|
|
4786
|
+
{
|
|
4787
|
+
field: "avatar",
|
|
4788
|
+
local: true,
|
|
4789
|
+
reason: "The mark at the box's inline start, usually an <Avatar>. Decorative."
|
|
4790
|
+
},
|
|
4791
|
+
{
|
|
4792
|
+
field: "children",
|
|
4793
|
+
local: true,
|
|
4794
|
+
reason: "The node's own reports \u2014 the hierarchy itself, not a slot."
|
|
4795
|
+
}
|
|
4796
|
+
]
|
|
4797
|
+
},
|
|
4798
|
+
OrgChartProp: {
|
|
4799
|
+
group: "data-display",
|
|
4800
|
+
file: "components/data-display.prop.ts",
|
|
4801
|
+
vocabulary: [
|
|
4802
|
+
"LabelProp",
|
|
4803
|
+
"ClassNameProp",
|
|
4804
|
+
"IdProp",
|
|
4805
|
+
{
|
|
4806
|
+
field: "data",
|
|
4807
|
+
local: true,
|
|
4808
|
+
reason: "The hierarchy of OrgChartNodeProp \u2014 the same shape feeds the boxes and the narrow Tree."
|
|
4809
|
+
},
|
|
4810
|
+
{
|
|
4811
|
+
field: "renderNode",
|
|
4812
|
+
local: true,
|
|
4813
|
+
reason: "Escape hatch replacing a box's content; the box, connectors and keyboard stay the library's."
|
|
4814
|
+
}
|
|
4815
|
+
]
|
|
4767
4816
|
}
|
|
4768
4817
|
};
|
|
4769
4818
|
const PROP_ALIASES_FORBIDDEN = {
|
|
@@ -1120,6 +1120,27 @@
|
|
|
1120
1120
|
max-block-size: var(--code-block-max-height-lg);
|
|
1121
1121
|
}
|
|
1122
1122
|
|
|
1123
|
+
.ui-code-block-frame {
|
|
1124
|
+
position: relative;
|
|
1125
|
+
min-inline-size: 0;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
.ui-code-block[data-copyable] {
|
|
1129
|
+
padding-inline-end: calc(var(--code-block-space-inset) + var(--control-height-xs));
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
.ui-code-block-copy {
|
|
1133
|
+
position: absolute;
|
|
1134
|
+
inset-block-start: var(--space-1);
|
|
1135
|
+
inset-inline-end: var(--space-1);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
@media (pointer: coarse) {
|
|
1139
|
+
.ui-code-block[data-copyable] {
|
|
1140
|
+
padding-inline-end: calc(var(--code-block-space-inset) + var(--control-height-default));
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1123
1144
|
.ui-code-block [data-code-token="comment"],
|
|
1124
1145
|
.ui-prose pre [data-code-token="comment"] {
|
|
1125
1146
|
color: var(--code-block-token-comment-color, hsl(var(--muted-foreground)));
|
|
@@ -2430,3 +2451,155 @@
|
|
|
2430
2451
|
flex-direction: column;
|
|
2431
2452
|
}
|
|
2432
2453
|
}
|
|
2454
|
+
|
|
2455
|
+
@layer components {
|
|
2456
|
+
|
|
2457
|
+
.ui-org-chart {
|
|
2458
|
+
min-inline-size: 0;
|
|
2459
|
+
container: org-chart / inline-size;
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
.ui-org-chart-scroll {
|
|
2463
|
+
overflow-x: auto;
|
|
2464
|
+
padding: var(--org-chart-padding);
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
.ui-org-chart-tree,
|
|
2468
|
+
.ui-org-chart-children {
|
|
2469
|
+
display: flex;
|
|
2470
|
+
justify-content: center;
|
|
2471
|
+
margin: 0;
|
|
2472
|
+
padding: 0;
|
|
2473
|
+
list-style: none;
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
.ui-org-chart-tree {
|
|
2477
|
+
inline-size: max-content;
|
|
2478
|
+
min-inline-size: 100%;
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
.ui-org-chart-branch {
|
|
2482
|
+
position: relative;
|
|
2483
|
+
display: flex;
|
|
2484
|
+
flex-direction: column;
|
|
2485
|
+
align-items: center;
|
|
2486
|
+
padding-inline: calc(var(--org-chart-sibling-gap) / 2);
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
.ui-org-chart-children {
|
|
2490
|
+
position: relative;
|
|
2491
|
+
padding-block-start: calc(var(--org-chart-level-gap) / 2);
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
.ui-org-chart-children::before,
|
|
2495
|
+
.ui-org-chart-children > .ui-org-chart-branch::before,
|
|
2496
|
+
.ui-org-chart-children > .ui-org-chart-branch::after {
|
|
2497
|
+
position: absolute;
|
|
2498
|
+
box-sizing: border-box;
|
|
2499
|
+
inset-block-start: 0;
|
|
2500
|
+
block-size: calc(var(--org-chart-level-gap) / 2);
|
|
2501
|
+
border: 0 solid var(--org-chart-line-color, hsl(var(--border)));
|
|
2502
|
+
content: "";
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
.ui-org-chart-children::before {
|
|
2506
|
+
inset-inline-start: calc(50% - var(--org-chart-line-width, var(--stroke-hairline)) / 2);
|
|
2507
|
+
border-inline-start-width: var(--org-chart-line-width, var(--stroke-hairline));
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
.ui-org-chart-children > .ui-org-chart-branch {
|
|
2511
|
+
padding-block-start: calc(var(--org-chart-level-gap) / 2);
|
|
2512
|
+
}
|
|
2513
|
+
|
|
2514
|
+
.ui-org-chart-children > .ui-org-chart-branch::before {
|
|
2515
|
+
inset-inline: 0 50%;
|
|
2516
|
+
border-block-start-width: var(--org-chart-line-width, var(--stroke-hairline));
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
.ui-org-chart-children > .ui-org-chart-branch::after {
|
|
2520
|
+
inset-inline: calc(50% - var(--org-chart-line-width, var(--stroke-hairline)) / 2) 0;
|
|
2521
|
+
border-block-start-width: var(--org-chart-line-width, var(--stroke-hairline));
|
|
2522
|
+
border-inline-start-width: var(--org-chart-line-width, var(--stroke-hairline));
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
.ui-org-chart-children > .ui-org-chart-branch:first-child::before,
|
|
2526
|
+
.ui-org-chart-children > .ui-org-chart-branch:last-child::after {
|
|
2527
|
+
border-block-start-width: 0;
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
.ui-org-chart-node {
|
|
2531
|
+
position: relative;
|
|
2532
|
+
display: flex;
|
|
2533
|
+
box-sizing: border-box;
|
|
2534
|
+
inline-size: var(--org-chart-node-inline-size);
|
|
2535
|
+
align-items: flex-start;
|
|
2536
|
+
gap: var(--org-chart-node-gap);
|
|
2537
|
+
padding-block: var(--org-chart-node-padding-block);
|
|
2538
|
+
padding-inline: var(--org-chart-node-padding-inline);
|
|
2539
|
+
border: var(--org-chart-node-border-width, var(--stroke-hairline)) solid
|
|
2540
|
+
var(--org-chart-node-border-color, hsl(var(--border)));
|
|
2541
|
+
border-radius: var(--org-chart-node-radius, var(--radius));
|
|
2542
|
+
background: var(--org-chart-node-background, hsl(var(--card)));
|
|
2543
|
+
color: var(--org-chart-node-foreground, hsl(var(--card-foreground)));
|
|
2544
|
+
font-size: var(--org-chart-node-font-size);
|
|
2545
|
+
text-align: start;
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
.ui-org-chart-node[data-variant="agent"] {
|
|
2549
|
+
border-style: var(--org-chart-agent-border-style);
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
.ui-org-chart-avatar {
|
|
2553
|
+
display: inline-flex;
|
|
2554
|
+
flex: 0 0 auto;
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
.ui-org-chart-text {
|
|
2558
|
+
display: flex;
|
|
2559
|
+
min-inline-size: 0;
|
|
2560
|
+
flex: 1 1 auto;
|
|
2561
|
+
flex-direction: column;
|
|
2562
|
+
gap: var(--org-chart-node-text-gap);
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
.ui-org-chart-name {
|
|
2566
|
+
font-weight: var(--font-weight-medium);
|
|
2567
|
+
overflow-wrap: anywhere;
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
.ui-org-chart-title {
|
|
2571
|
+
color: var(--org-chart-node-title-color, hsl(var(--muted-foreground)));
|
|
2572
|
+
overflow-wrap: anywhere;
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
.ui-org-chart-extra {
|
|
2576
|
+
display: flex;
|
|
2577
|
+
flex-wrap: wrap;
|
|
2578
|
+
gap: var(--org-chart-node-text-gap);
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
.ui-org-chart-list {
|
|
2582
|
+
display: none;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
.ui-org-chart-list-row {
|
|
2586
|
+
display: inline-flex;
|
|
2587
|
+
min-inline-size: 0;
|
|
2588
|
+
align-items: center;
|
|
2589
|
+
gap: var(--org-chart-node-gap);
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
.ui-org-chart-list-row .ui-org-chart-extra {
|
|
2593
|
+
display: inline-flex;
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
@container org-chart (width < 40rem) {
|
|
2597
|
+
.ui-org-chart-scroll {
|
|
2598
|
+
display: none;
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
.ui-org-chart-list {
|
|
2602
|
+
display: block;
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
}
|