@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.
Files changed (33) hide show
  1. package/agent/START-HERE.md +5 -5
  2. package/agent/components/CodeBlock.json +7 -1
  3. package/agent/components/OrgChart.json +59 -0
  4. package/agent/components-index.json +5 -0
  5. package/agent/components.json +66 -1
  6. package/agent/index.json +6 -6
  7. package/agent/llms.txt +6 -6
  8. package/agent/tokens.json +108 -0
  9. package/dist/components/data-display/code-block.js +90 -4
  10. package/dist/components/data-display/index.d.ts +2 -0
  11. package/dist/components/data-display/index.js +2 -0
  12. package/dist/components/data-display/org-chart.d.ts +5 -0
  13. package/dist/components/data-display/org-chart.js +169 -0
  14. package/dist/components/general/typography.d.ts +32 -0
  15. package/dist/components/general/typography.js +11 -2
  16. package/dist/contracts/measurement.json +1 -1
  17. package/dist/i18n/messages/en.json +10 -0
  18. package/dist/i18n/messages/ja.json +10 -0
  19. package/dist/i18n/messages/vi.json +10 -0
  20. package/dist/props/components/data-display.prop.d.ts +51 -1
  21. package/dist/props/registry.d.ts +39 -0
  22. package/dist/props/registry.js +49 -0
  23. package/dist/styles/data-display-layout.css +173 -0
  24. package/dist/styles/layers.json +14 -1
  25. package/dist/tokens/base.css +1 -0
  26. package/dist/tokens/components/org-chart.css +27 -0
  27. package/docs/FRAME-COVERAGE-REPORT.md +3 -2
  28. package/docs/data-display/code-block.tsx +27 -0
  29. package/docs/data-display/org-chart.tsx +165 -0
  30. package/docs/navigation/tabs.tsx +17 -15
  31. package/docs/query/data-state.tsx +2 -4
  32. package/docs/showcase/table-view-tabs.tsx +1 -1
  33. 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({ title, children }) {
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.4.0",
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
+ };
@@ -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. */
@@ -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
+ }