@godxjp/ui 23.2.1 → 23.4.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 (101) hide show
  1. package/dist/app/timezones.js +2 -1
  2. package/dist/components/charts/chart-cartesian.js +2 -4
  3. package/dist/components/charts/chart-frame.js +2 -1
  4. package/dist/components/data-display/card.d.ts +87 -1
  5. package/dist/components/data-display/card.js +88 -15
  6. package/dist/components/data-display/index.d.ts +5 -1
  7. package/dist/components/data-display/index.js +5 -0
  8. package/dist/components/data-display/thought-chain.d.ts +42 -0
  9. package/dist/components/data-display/thought-chain.js +177 -0
  10. package/dist/components/data-display/welcome.d.ts +26 -0
  11. package/dist/components/data-display/welcome.js +37 -0
  12. package/dist/components/data-entry/attachments.d.ts +19 -0
  13. package/dist/components/data-entry/attachments.js +322 -0
  14. package/dist/components/data-entry/date-picker.js +12 -14
  15. package/dist/components/data-entry/index.d.ts +2 -0
  16. package/dist/components/data-entry/index.js +2 -0
  17. package/dist/components/data-entry/number-input.js +2 -1
  18. package/dist/components/feedback/dialog.d.ts +10 -7
  19. package/dist/components/feedback/dialog.js +40 -17
  20. package/dist/components/feedback/index.d.ts +3 -3
  21. package/dist/components/feedback/index.js +2 -0
  22. package/dist/components/feedback/skeleton.d.ts +11 -2
  23. package/dist/components/feedback/skeleton.js +8 -0
  24. package/dist/components/general/actions.d.ts +59 -0
  25. package/dist/components/general/actions.js +253 -0
  26. package/dist/components/general/activity.js +1 -0
  27. package/dist/components/general/button.js +2 -1
  28. package/dist/components/general/float-button.d.ts +41 -0
  29. package/dist/components/general/float-button.js +336 -0
  30. package/dist/components/general/index.d.ts +6 -2
  31. package/dist/components/general/index.js +12 -1
  32. package/dist/components/general/typography.d.ts +79 -4
  33. package/dist/components/general/typography.js +598 -54
  34. package/dist/components/layout/draggable-panel.d.ts +18 -0
  35. package/dist/components/layout/draggable-panel.js +189 -0
  36. package/dist/components/layout/error-surface.js +3 -2
  37. package/dist/components/layout/index.d.ts +2 -0
  38. package/dist/components/layout/index.js +2 -0
  39. package/dist/components/navigation/conversations.d.ts +39 -0
  40. package/dist/components/navigation/conversations.js +371 -0
  41. package/dist/components/navigation/index.d.ts +2 -0
  42. package/dist/components/navigation/index.js +2 -0
  43. package/dist/components/ui/card.js +1 -0
  44. package/dist/components/ui/toggle.js +2 -1
  45. package/dist/i18n/messages/en.json +53 -0
  46. package/dist/i18n/messages/ja.json +53 -0
  47. package/dist/i18n/messages/vi.json +53 -0
  48. package/dist/i18n/translate.js +3 -2
  49. package/dist/lib/datetime/picker-format.js +2 -1
  50. package/dist/lib/format.js +3 -2
  51. package/dist/lib/intl-cache.d.ts +32 -0
  52. package/dist/lib/intl-cache.js +29 -0
  53. package/dist/props/components/data-display.prop.d.ts +143 -1
  54. package/dist/props/components/data-entry.prop.d.ts +87 -0
  55. package/dist/props/components/feedback.prop.d.ts +53 -1
  56. package/dist/props/components/general.prop.d.ts +440 -3
  57. package/dist/props/components/index.d.ts +2 -2
  58. package/dist/props/components/layout.prop.d.ts +63 -1
  59. package/dist/props/components/navigation.prop.d.ts +150 -0
  60. package/dist/props/registry.d.ts +431 -0
  61. package/dist/props/registry.js +551 -0
  62. package/dist/props/vocabulary/index.d.ts +1 -1
  63. package/dist/props/vocabulary/interaction.prop.d.ts +113 -0
  64. package/dist/styles/alert-layout.css +22 -0
  65. package/dist/styles/card-layout.css +34 -0
  66. package/dist/styles/core.css +1 -0
  67. package/dist/styles/data-display-layout.css +236 -0
  68. package/dist/styles/float-button-layout.css +168 -0
  69. package/dist/styles/form-layout.css +11 -1
  70. package/dist/styles/index.css +1 -0
  71. package/dist/styles/layout.css +196 -0
  72. package/dist/styles/navigation-layout.css +139 -0
  73. package/dist/styles/text-layout.css +156 -0
  74. package/dist/tokens/axes.css +5 -0
  75. package/dist/tokens/base.css +7 -0
  76. package/dist/tokens/components/actions.css +14 -0
  77. package/dist/tokens/components/attachments.css +15 -0
  78. package/dist/tokens/components/conversations.css +28 -0
  79. package/dist/tokens/components/draggable-panel.css +25 -0
  80. package/dist/tokens/components/float-button.css +39 -0
  81. package/dist/tokens/components/text.css +13 -0
  82. package/dist/tokens/components/thought-chain.css +31 -0
  83. package/dist/tokens/components/welcome.css +19 -0
  84. package/dist/tokens/foundation.css +6 -4
  85. package/docs/DESIGN-AUTHORITY.md +133 -20
  86. package/docs/FRAME-COVERAGE-REPORT.md +5 -2
  87. package/docs/data-display/card/examples/tab-list.tsx +97 -0
  88. package/docs/data-display/thought-chain.tsx +176 -0
  89. package/docs/data-display/welcome.tsx +115 -0
  90. package/docs/data-entry/attachments.tsx +160 -0
  91. package/docs/feedback/dialog.tsx +50 -0
  92. package/docs/general/actions.tsx +175 -0
  93. package/docs/general/float-button.tsx +133 -0
  94. package/docs/general/typography.tsx +63 -1
  95. package/docs/layout/draggable-panel.tsx +127 -0
  96. package/docs/navigation/conversations.tsx +176 -0
  97. package/docs/roadmap/parity-audit-layout-navigation-general.md +17 -16
  98. package/package.json +20 -4
  99. package/scripts/_agent-setup.mjs +36 -5
  100. package/scripts/guinea-pig-skill.md +14 -0
  101. package/scripts/ui-audit.mjs +69 -9
@@ -1,4 +1,5 @@
1
1
  import { translate } from "../i18n/translate.js";
2
+ import { dateTimeFormat } from "../lib/intl-cache.js";
2
3
  const APP_TIMEZONE_PRESET = [
3
4
  "UTC",
4
5
  "Asia/Ho_Chi_Minh",
@@ -113,7 +114,7 @@ function getTimezoneCityName(timezone) {
113
114
  function getTimezoneOffsetLabel(timezone, locale = "en") {
114
115
  if (timezone === "UTC") return "UTC";
115
116
  try {
116
- const parts = new Intl.DateTimeFormat(locale, {
117
+ const parts = dateTimeFormat(locale, {
117
118
  timeZone: resolveTimezoneForIntl(timezone),
118
119
  timeZoneName: "shortOffset"
119
120
  }).formatToParts(/* @__PURE__ */ new Date());
@@ -22,6 +22,7 @@ import { useTranslation } from "../../i18n/use-translation.js";
22
22
  import { ChartFrame, chartColor, chartHeight, useChartNumberFormat } from "./chart-frame.js";
23
23
  import { buildCartesianSummary } from "./chart-summary.js";
24
24
  import { useCategoryAxisMetrics } from "./chart-category-axis.js";
25
+ import { listFormat } from "../../lib/intl-cache.js";
25
26
  function CartesianChart({
26
27
  kind,
27
28
  data,
@@ -45,10 +46,7 @@ function CartesianChart({
45
46
  assertRechartsPeer();
46
47
  const { t, locale } = useTranslation();
47
48
  const fmt = useChartNumberFormat(numberFormat);
48
- const list = React.useMemo(
49
- () => new Intl.ListFormat(locale, { style: "narrow", type: "unit" }),
50
- [locale]
51
- );
49
+ const list = React.useMemo(() => listFormat(locale, { style: "narrow", type: "unit" }), [locale]);
52
50
  const hasData = data.length > 0 && series.length > 0;
53
51
  const summary = buildCartesianSummary(
54
52
  data,
@@ -3,6 +3,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { cn } from "../../lib/utils.js";
5
5
  import { useTranslation } from "../../i18n/use-translation.js";
6
+ import { numberFormat } from "../../lib/intl-cache.js";
6
7
  const CHART_COLORS = [
7
8
  "var(--chart-1)",
8
9
  "var(--chart-2)",
@@ -25,7 +26,7 @@ function chartHeight(size = "md", height) {
25
26
  }
26
27
  function useChartNumberFormat(options) {
27
28
  const { locale } = useTranslation();
28
- return React.useMemo(() => new Intl.NumberFormat(locale, options), [locale, options]);
29
+ return React.useMemo(() => numberFormat(locale, options), [locale, options]);
29
30
  }
30
31
  function ChartFrame({
31
32
  label,
@@ -2,6 +2,9 @@ import type { GapProp, PadProp, PadRawProp } from "../../props/vocabulary/index.
2
2
  import * as React from "react";
3
3
  import type { LucideIcon } from "lucide-react";
4
4
  import type { HeadingLevelProp } from "../../props/vocabulary/index.js";
5
+ import type { CardTabItemProp } from "../../props/components/data-display.prop.js";
6
+ import { type TabsExtraProp, type TabsProps } from "../navigation/tabs.js";
7
+ export type { CardTabItemProp, CardTabItemProp as CardTabItemProps, } from "../../props/components/data-display.prop.js";
5
8
  /** Semantic accent tone. `accentPlacement` decides WHERE it is drawn — a leading-edge
6
9
  * stripe (default) or the full perimeter. */
7
10
  type CardAccent = "primary" | "success" | "warning" | "info" | "attention" | "destructive";
@@ -41,6 +44,48 @@ export type CardProps = React.HTMLAttributes<HTMLDivElement> & {
41
44
  * bare `onClick` on this div, which a keyboard or screen-reader user cannot reach.
42
45
  */
43
46
  hoverable?: boolean;
47
+ /**
48
+ * Ant Design `tabList` — the tab strip that lives IN THE CARD'S HEAD, under the title, inside
49
+ * the same border and on the same surface, so the card and its tabs read as one object. The
50
+ * card's remaining children become the selected tab's body.
51
+ *
52
+ * Ported name for name and semantic for semantic (docs/DESIGN-AUTHORITY.md): the entry is
53
+ * antd's `{ key, tab, disabled }`, not the `Tabs` component's `{ value, label, content }`.
54
+ * @see CardTabItemProp for why the two item shapes stay apart.
55
+ */
56
+ tabList?: CardTabItemProp[];
57
+ /** Ant Design `activeTabKey` — the controlled selection. Pair it with `onTabChange`. */
58
+ activeTabKey?: string;
59
+ /**
60
+ * Ant Design `defaultActiveTabKey` — the uncontrolled initial selection. Without it the first
61
+ * entry of `tabList` opens, which is antd's own fallback.
62
+ */
63
+ defaultActiveTabKey?: string;
64
+ /** Ant Design `onTabChange` — fires with the newly selected `key`, however the selection moved. */
65
+ onTabChange?: (key: string) => void;
66
+ /**
67
+ * Ant Design `tabBarExtraContent`, RENAMED to `extra` and made logical — the one deviation from
68
+ * antd's spelling here, and it follows the precedent this package already set on
69
+ * `TabsProp.extra` ("Ant Design `tabBarExtraContent`, renamed and made logical"). A second
70
+ * spelling of a slot the package has already named once is exactly what
71
+ * `check:prop-vocabulary` exists to prevent, and antd's `{ left, right }` keys cannot mirror
72
+ * for an RTL locale where `{ start, end }` can.
73
+ *
74
+ * Inert without `tabList`: antd draws this content in the tab bar, and with no tab bar there is
75
+ * nowhere for it to go. A header-level action is `<CardAction>` inside `<CardHeader>`.
76
+ */
77
+ extra?: TabsExtraProp;
78
+ /**
79
+ * Ant Design `tabProps` — passed straight down to the `Tabs` that draws the strip, so
80
+ * `variant`, `size`, `centered`, `overflow`, `indicator` and the rest are reachable.
81
+ *
82
+ * The four fields the CARD owns are omitted rather than passed through: `items` is built from
83
+ * `tabList`, and `value` / `defaultValue` / `onValueChange` are what `activeTabKey` /
84
+ * `defaultActiveTabKey` / `onTabChange` already say. antd drops the same fields — it spreads
85
+ * `tabProps` first and then writes its own `items`/`activeKey`/`onChange` over them — so this
86
+ * is that behaviour made visible in the type instead of silent at runtime.
87
+ */
88
+ tabProps?: Omit<TabsProps, "items" | "value" | "defaultValue" | "onValueChange" | "extra" | "children">;
44
89
  };
45
90
  export declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
46
91
  accent?: CardAccent;
@@ -61,6 +106,48 @@ export declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<
61
106
  * bare `onClick` on this div, which a keyboard or screen-reader user cannot reach.
62
107
  */
63
108
  hoverable?: boolean;
109
+ /**
110
+ * Ant Design `tabList` — the tab strip that lives IN THE CARD'S HEAD, under the title, inside
111
+ * the same border and on the same surface, so the card and its tabs read as one object. The
112
+ * card's remaining children become the selected tab's body.
113
+ *
114
+ * Ported name for name and semantic for semantic (docs/DESIGN-AUTHORITY.md): the entry is
115
+ * antd's `{ key, tab, disabled }`, not the `Tabs` component's `{ value, label, content }`.
116
+ * @see CardTabItemProp for why the two item shapes stay apart.
117
+ */
118
+ tabList?: CardTabItemProp[];
119
+ /** Ant Design `activeTabKey` — the controlled selection. Pair it with `onTabChange`. */
120
+ activeTabKey?: string;
121
+ /**
122
+ * Ant Design `defaultActiveTabKey` — the uncontrolled initial selection. Without it the first
123
+ * entry of `tabList` opens, which is antd's own fallback.
124
+ */
125
+ defaultActiveTabKey?: string;
126
+ /** Ant Design `onTabChange` — fires with the newly selected `key`, however the selection moved. */
127
+ onTabChange?: (key: string) => void;
128
+ /**
129
+ * Ant Design `tabBarExtraContent`, RENAMED to `extra` and made logical — the one deviation from
130
+ * antd's spelling here, and it follows the precedent this package already set on
131
+ * `TabsProp.extra` ("Ant Design `tabBarExtraContent`, renamed and made logical"). A second
132
+ * spelling of a slot the package has already named once is exactly what
133
+ * `check:prop-vocabulary` exists to prevent, and antd's `{ left, right }` keys cannot mirror
134
+ * for an RTL locale where `{ start, end }` can.
135
+ *
136
+ * Inert without `tabList`: antd draws this content in the tab bar, and with no tab bar there is
137
+ * nowhere for it to go. A header-level action is `<CardAction>` inside `<CardHeader>`.
138
+ */
139
+ extra?: TabsExtraProp;
140
+ /**
141
+ * Ant Design `tabProps` — passed straight down to the `Tabs` that draws the strip, so
142
+ * `variant`, `size`, `centered`, `overflow`, `indicator` and the rest are reachable.
143
+ *
144
+ * The four fields the CARD owns are omitted rather than passed through: `items` is built from
145
+ * `tabList`, and `value` / `defaultValue` / `onValueChange` are what `activeTabKey` /
146
+ * `defaultActiveTabKey` / `onTabChange` already say. antd drops the same fields — it spreads
147
+ * `tabProps` first and then writes its own `items`/`activeKey`/`onChange` over them — so this
148
+ * is that behaviour made visible in the type instead of silent at runtime.
149
+ */
150
+ tabProps?: Omit<TabsProps, "items" | "value" | "defaultValue" | "onValueChange" | "extra" | "children">;
64
151
  } & React.RefAttributes<HTMLDivElement>>;
65
152
  /** Full-bleed cover media — first child; header below uses section top (φ⁰), not shell. */
66
153
  export type CardCoverProps = React.HTMLAttributes<HTMLDivElement>;
@@ -190,4 +277,3 @@ export type StatCardProps = React.HTMLAttributes<HTMLDivElement> & {
190
277
  export declare function StatCard({ label, value, hint, icon: Icon, delta, layout, align, inverse, accent, accentPlacement, className, ...props }: StatCardProps): React.JSX.Element;
191
278
  /** Header actions slot — compose beside CardTitle inside CardHeader; the header owns positioning. */
192
279
  export declare const CardAction: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
193
- export {};
@@ -1,22 +1,95 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
3
  import { padStyle, padStepToken } from "../../lib/variants.js";
3
4
  import * as React from "react";
4
5
  import { cn } from "../../lib/utils.js";
6
+ import { Tabs } from "../navigation/tabs.js";
7
+ function resolveActiveCardTabKey(tabList, requested) {
8
+ if (requested !== void 0) {
9
+ const item = tabList.find((entry) => entry.key === requested);
10
+ if (item && !item.disabled) return requested;
11
+ }
12
+ return tabList.find((entry) => !entry.disabled)?.key;
13
+ }
14
+ function splitCardBands(children) {
15
+ const head = [];
16
+ const body = [];
17
+ const foot = [];
18
+ for (const child of React.Children.toArray(children)) {
19
+ const type = React.isValidElement(child) ? child.type : void 0;
20
+ if (type === CardCover || type === CardHeader) head.push(child);
21
+ else if (type === CardFooter) foot.push(child);
22
+ else body.push(child);
23
+ }
24
+ return { head, body, foot };
25
+ }
5
26
  const Card = React.forwardRef(
6
- ({ className, accent, accentPlacement, variant, density, hoverable, ...props }, ref) => /* @__PURE__ */ jsx(
7
- "div",
8
- {
9
- ref,
10
- className: cn("group/card", className),
11
- "data-slot": "card",
12
- "data-accent": accent,
13
- "data-hoverable": hoverable ? "" : void 0,
14
- "data-accent-placement": accentPlacement === "perimeter" ? "perimeter" : void 0,
15
- "data-variant": variant && variant !== "default" ? variant : void 0,
16
- "data-density": density,
17
- ...props
18
- }
19
- )
27
+ ({
28
+ className,
29
+ accent,
30
+ accentPlacement,
31
+ variant,
32
+ density,
33
+ hoverable,
34
+ tabList,
35
+ activeTabKey,
36
+ defaultActiveTabKey,
37
+ onTabChange,
38
+ extra,
39
+ tabProps,
40
+ children,
41
+ ...props
42
+ }, ref) => {
43
+ const [mirroredKey, setMirroredKey] = React.useState(void 0);
44
+ const activeKey = tabList?.length ? resolveActiveCardTabKey(tabList, activeTabKey ?? mirroredKey ?? defaultActiveTabKey) : void 0;
45
+ const handleTabChange = React.useCallback(
46
+ (key) => {
47
+ setMirroredKey(key);
48
+ onTabChange?.(key);
49
+ },
50
+ [onTabChange]
51
+ );
52
+ const { head, body, foot } = tabList?.length ? splitCardBands(children) : { head: void 0, body: void 0, foot: void 0 };
53
+ return /* @__PURE__ */ jsx(
54
+ "div",
55
+ {
56
+ ref,
57
+ className: cn("group/card", className),
58
+ "data-slot": "card",
59
+ "data-accent": accent,
60
+ "data-hoverable": hoverable ? "" : void 0,
61
+ "data-accent-placement": accentPlacement === "perimeter" ? "perimeter" : void 0,
62
+ "data-variant": variant && variant !== "default" ? variant : void 0,
63
+ "data-density": density,
64
+ "data-tab-list": tabList?.length ? "" : void 0,
65
+ ...props,
66
+ children: tabList?.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
67
+ head,
68
+ /* @__PURE__ */ jsx(
69
+ Tabs,
70
+ {
71
+ variant: "line",
72
+ ...tabProps,
73
+ items: tabList.map((item) => ({
74
+ value: item.key,
75
+ label: item.tab,
76
+ disabled: item.disabled,
77
+ // The body belongs to the SELECTED tab and to no other: the card has exactly one
78
+ // set of children, so handing them to every panel would render them N times the
79
+ // moment `destroyOnHidden={false}` kept the hidden panels mounted.
80
+ content: item.key === activeKey ? body : null
81
+ })),
82
+ value: activeKey,
83
+ onValueChange: handleTabChange,
84
+ extra,
85
+ listClassName: cn("px-[var(--card-space-inset)]", tabProps?.listClassName)
86
+ }
87
+ ),
88
+ foot
89
+ ] }) : children
90
+ }
91
+ );
92
+ }
20
93
  );
21
94
  Card.displayName = "Card";
22
95
  const CardCover = React.forwardRef(
@@ -17,7 +17,7 @@ export type { QrCodeProps } from "./qr-code.js";
17
17
  export type { QrCodeProp } from "../../props/components/data-display.prop.js";
18
18
  export { Avatar, AvatarImage, AvatarFallback } from "./avatar.js";
19
19
  export { Card, CardBar, CardContent, CardCover, CardDescription, CardFooter, CardHeader, CardTitle, CardAction, StatCard, } from "./card.js";
20
- export type { StatCardProps, CardBarProps } from "./card.js";
20
+ export type { StatCardProps, CardBarProps, CardTabItemProp, CardTabItemProps } from "./card.js";
21
21
  export { ServiceCatalogCta, ServiceLauncherCard, ServiceLauncherCardSkeleton, } from "./service-launcher-card.js";
22
22
  export type { ServiceCatalogCtaProps, ServiceLauncherCardProps, ServiceLauncherCardSkeletonProps, ServiceLauncherStatusTone, } from "./service-launcher-card.js";
23
23
  export { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table.js";
@@ -51,3 +51,7 @@ export { ChatBubble, ChatBubbleList } from "./chat-bubble.js";
51
51
  export type { ChatBubbleListProp, ChatBubbleListProps, ChatBubblePlacementProp, ChatBubbleProp, ChatBubbleProps, ChatBubbleToneProp, ChatBubbleTypingProp, ChatBubbleVariantProp, ChatMessageProp, } from "./chat-bubble.js";
52
52
  export { Tree } from "./tree.js";
53
53
  export type { TreeNodeProp, TreeProp, TreeProps } from "./tree.js";
54
+ export { Welcome } from "./welcome.js";
55
+ export type { WelcomeProp, WelcomeProps, WelcomeVariantProp } from "./welcome.js";
56
+ export { ThoughtChain, ThoughtChainItem } from "./thought-chain.js";
57
+ export type { ThoughtChainProp, ThoughtChainProps, ThoughtChainItemsProp, ThoughtChainItemProp, ThoughtChainItemProps, ThoughtChainStatusProp, ThoughtChainLineProp, ThoughtChainVariantProp, } from "./thought-chain.js";
@@ -59,6 +59,8 @@ import { PermissionMatrix } from "./permission-matrix.js";
59
59
  import { RangeTimeline } from "./range-timeline.js";
60
60
  import { ChatBubble, ChatBubbleList } from "./chat-bubble.js";
61
61
  import { Tree } from "./tree.js";
62
+ import { Welcome } from "./welcome.js";
63
+ import { ThoughtChain, ThoughtChainItem } from "./thought-chain.js";
62
64
  export {
63
65
  Accordion,
64
66
  AccordionContent,
@@ -125,10 +127,13 @@ export {
125
127
  TableHead,
126
128
  TableHeader,
127
129
  TableRow,
130
+ ThoughtChain,
131
+ ThoughtChainItem,
128
132
  Thumbnail,
129
133
  Timeline,
130
134
  TimelineGrid,
131
135
  Tree,
136
+ Welcome,
132
137
  flexRender,
133
138
  useCarousel
134
139
  };
@@ -0,0 +1,42 @@
1
+ import * as React from "react";
2
+ import type { ThoughtChainItemProp, ThoughtChainProp } from "../../props/components/data-display.prop.js";
3
+ export type { ThoughtChainProp, ThoughtChainProp as ThoughtChainProps, ThoughtChainItemsProp, ThoughtChainItemProp, ThoughtChainItemProp as ThoughtChainItemProps, ThoughtChainStatusProp, ThoughtChainLineProp, ThoughtChainVariantProp, } from "../../props/components/data-display.prop.js";
4
+ /**
5
+ * ThoughtChain — the assistant's reasoning, step by step (Ant Design X `ThoughtChain`).
6
+ *
7
+ * ## The shape, and why it is an `<ol>`
8
+ *
9
+ * Ant renders the whole chain as nested `<div>`s and paints the step number itself
10
+ * (`index + 1` in `es/thought-chain/Node.js`). The order of the steps IS the content here — step 3
11
+ * only makes sense after step 2 — so the chain is an ordered list and a screen reader gets "list,
12
+ * 4 items" plus each step's position for free. The visible ordinal stays, because the same number
13
+ * has to be on screen for a sighted reader following a long chain.
14
+ *
15
+ * ## The disclosure is a real button
16
+ *
17
+ * A `collapsible` step's title in Ant is a `<div onClick>` with a rotating chevron — no role, no
18
+ * `tabIndex`, no `aria-expanded`. Here it is a `<button aria-expanded aria-controls>` over the
19
+ * body it opens: the WAI-ARIA APG Disclosure pattern, so the step can be opened from the keyboard
20
+ * and its state is announced rather than inferred from a rotation.
21
+ *
22
+ * Everything a caller passes keeps Ant's spelling: `items` (with `icon`, `title`, `description`,
23
+ * `content`, `footer`, `status`, `collapsible`, `blink`, `destroyOnHidden`), the
24
+ * `defaultExpandedKeys` / `expandedKeys` / `onExpand` triad, and `line`. `styles` / `classNames` /
25
+ * `prefixCls` / `rootClassName` are not ported — the standing style-hole decision
26
+ * (docs/WHAT-BELONGS-HERE.md, docs/DESIGN-AUTHORITY.md); the chain is retuned through
27
+ * `src/tokens/components/thought-chain.css`.
28
+ */
29
+ export declare const ThoughtChain: React.ForwardRefExoticComponent<ThoughtChainProp & React.RefAttributes<HTMLOListElement>>;
30
+ /**
31
+ * ThoughtChainItem — one step OUTSIDE a chain (Ant Design X `ThoughtChain.Item`).
32
+ *
33
+ * A named export rather than `ThoughtChain.Item`, for the same reason `ActionsItem` is: every
34
+ * compound in this library is separate named exports (`CardHeader`, `TabsList`), and attaching
35
+ * statics to one component would be the only instance of it here.
36
+ *
37
+ * ONE DEVIATION: Ant renders the chip as a `<div>` and hangs `onClick` on it, so a clickable step
38
+ * is invisible to the keyboard and to assistive technology. Here an item WITH `onClick` renders a
39
+ * real `<button>` and one without renders a plain `<div>` — the element follows whether the thing
40
+ * is actually a control.
41
+ */
42
+ export declare const ThoughtChainItem: React.ForwardRefExoticComponent<ThoughtChainItemProp & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,177 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { ChevronRight, CircleCheck, CircleMinus, CircleX, Loader2 } from "lucide-react";
5
+ import { useTranslation } from "../../i18n/use-translation.js";
6
+ import { cn } from "../../lib/utils.js";
7
+ import { VisuallyHidden } from "../general/visually-hidden.js";
8
+ import { Text } from "../general/typography.js";
9
+ const STATUS_GLYPH = {
10
+ loading: /* @__PURE__ */ jsx(Loader2, { "aria-hidden": "true", className: "ui-thought-chain-spinner" }),
11
+ success: /* @__PURE__ */ jsx(CircleCheck, { "aria-hidden": "true" }),
12
+ error: /* @__PURE__ */ jsx(CircleX, { "aria-hidden": "true" }),
13
+ abort: /* @__PURE__ */ jsx(CircleMinus, { "aria-hidden": "true" })
14
+ };
15
+ function StatusMark({
16
+ status,
17
+ fallback
18
+ }) {
19
+ const { t } = useTranslation();
20
+ if (!status) return /* @__PURE__ */ jsx(Fragment, { children: fallback });
21
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
22
+ STATUS_GLYPH[status],
23
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: t(`dataDisplay.thoughtChain.status.${status}`) })
24
+ ] });
25
+ }
26
+ const ThoughtChain = React.forwardRef(
27
+ ({
28
+ items = [],
29
+ defaultExpandedKeys,
30
+ expandedKeys,
31
+ onExpand,
32
+ line = true,
33
+ label,
34
+ id,
35
+ className,
36
+ ...rest
37
+ }, ref) => {
38
+ const { t } = useTranslation();
39
+ const reactId = React.useId();
40
+ const [uncontrolled, setUncontrolled] = React.useState(() => [
41
+ ...defaultExpandedKeys ?? []
42
+ ]);
43
+ const open = expandedKeys ? [...expandedKeys] : uncontrolled;
44
+ const toggle = (key) => {
45
+ const next = open.includes(key) ? open.filter((k) => k !== key) : [...open, key];
46
+ if (!expandedKeys) setUncontrolled(next);
47
+ onExpand?.(next);
48
+ };
49
+ return /* @__PURE__ */ jsx(
50
+ "ol",
51
+ {
52
+ ref,
53
+ id,
54
+ "aria-label": label ?? t("dataDisplay.thoughtChain.label"),
55
+ "data-slot": "thought-chain",
56
+ "data-line": line === false ? "none" : line === true ? "solid" : line,
57
+ className: cn("ui-thought-chain", className),
58
+ ...rest,
59
+ children: items.map((item, index) => {
60
+ const key = item.key ?? `${reactId}-${index}`;
61
+ const bodyId = `${reactId}-body-${index}`;
62
+ const collapsible = Boolean(item.collapsible && item.content);
63
+ const expanded = collapsible ? open.includes(key) : true;
64
+ const glyph = item.icon === false ? null : item.icon ?? index + 1;
65
+ return /* @__PURE__ */ jsxs(
66
+ "li",
67
+ {
68
+ "data-slot": "thought-chain-node",
69
+ "data-status": item.status,
70
+ className: "ui-thought-chain-node",
71
+ children: [
72
+ glyph === null ? null : /* @__PURE__ */ jsx(
73
+ "span",
74
+ {
75
+ "data-slot": "thought-chain-icon",
76
+ "data-status": item.status,
77
+ className: "ui-thought-chain-icon",
78
+ children: /* @__PURE__ */ jsx(StatusMark, { status: item.status, fallback: glyph })
79
+ }
80
+ ),
81
+ /* @__PURE__ */ jsxs("div", { className: "ui-thought-chain-body", children: [
82
+ /* @__PURE__ */ jsxs("div", { className: "ui-thought-chain-header", children: [
83
+ collapsible ? /* @__PURE__ */ jsxs(
84
+ "button",
85
+ {
86
+ type: "button",
87
+ "aria-expanded": expanded,
88
+ "aria-controls": bodyId,
89
+ "data-blink": item.blink ? "" : void 0,
90
+ className: "ui-thought-chain-trigger",
91
+ onClick: () => toggle(key),
92
+ children: [
93
+ /* @__PURE__ */ jsx(
94
+ ChevronRight,
95
+ {
96
+ "aria-hidden": "true",
97
+ "data-expanded": expanded ? "true" : void 0,
98
+ className: "ui-thought-chain-chevron"
99
+ }
100
+ ),
101
+ /* @__PURE__ */ jsx(Text, { weight: "medium", children: item.title })
102
+ ]
103
+ }
104
+ ) : /* @__PURE__ */ jsx(Text, { weight: "medium", "data-blink": item.blink ? "" : void 0, children: item.title }),
105
+ item.description ? /* @__PURE__ */ jsx(Text, { size: "xs", tone: "muted", children: item.description }) : null
106
+ ] }),
107
+ item.content && (expanded || item.destroyOnHidden === false) ? /* @__PURE__ */ jsx(
108
+ "div",
109
+ {
110
+ id: bodyId,
111
+ hidden: !expanded,
112
+ "data-blink": item.blink ? "" : void 0,
113
+ className: "ui-thought-chain-content",
114
+ children: item.content
115
+ }
116
+ ) : null,
117
+ item.footer ? /* @__PURE__ */ jsx("div", { className: "ui-thought-chain-footer", children: item.footer }) : null
118
+ ] })
119
+ ]
120
+ },
121
+ key
122
+ );
123
+ })
124
+ }
125
+ );
126
+ }
127
+ );
128
+ ThoughtChain.displayName = "ThoughtChain";
129
+ const ThoughtChainItem = React.forwardRef(
130
+ ({
131
+ title,
132
+ description,
133
+ icon,
134
+ status,
135
+ variant = "solid",
136
+ blink,
137
+ disabled,
138
+ onClick,
139
+ id,
140
+ className
141
+ }, ref) => {
142
+ const shared = {
143
+ id,
144
+ "data-slot": "thought-chain-item",
145
+ "data-variant": variant,
146
+ "data-status": status,
147
+ "data-blink": blink ? "" : void 0,
148
+ className: cn("ui-thought-chain-item", className)
149
+ };
150
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
151
+ status || icon ? /* @__PURE__ */ jsx("span", { "data-status": status, className: "ui-thought-chain-icon", children: /* @__PURE__ */ jsx(StatusMark, { status, fallback: icon }) }) : null,
152
+ /* @__PURE__ */ jsxs("span", { className: "ui-thought-chain-item-text", children: [
153
+ title ? /* @__PURE__ */ jsx(Text, { weight: "medium", children: title }) : null,
154
+ description ? /* @__PURE__ */ jsx(Text, { size: "xs", tone: "muted", children: description }) : null
155
+ ] })
156
+ ] });
157
+ if (!onClick) {
158
+ return /* @__PURE__ */ jsx("div", { ref, ...shared, children: inner });
159
+ }
160
+ return /* @__PURE__ */ jsx(
161
+ "button",
162
+ {
163
+ ref,
164
+ type: "button",
165
+ disabled,
166
+ onClick,
167
+ ...shared,
168
+ children: inner
169
+ }
170
+ );
171
+ }
172
+ );
173
+ ThoughtChainItem.displayName = "ThoughtChainItem";
174
+ export {
175
+ ThoughtChain,
176
+ ThoughtChainItem
177
+ };
@@ -0,0 +1,26 @@
1
+ import * as React from "react";
2
+ import type { WelcomeProp } from "../../props/components/data-display.prop.js";
3
+ export type { WelcomeProp, WelcomeProp as WelcomeProps, WelcomeVariantProp, } from "../../props/components/data-display.prop.js";
4
+ /**
5
+ * Welcome — the greeting block at the head of an empty conversation (Ant Design X `Welcome`).
6
+ *
7
+ * ## Why this is a component and not four lines of composition
8
+ *
9
+ * It is close to the line, and the honest answer is that the SHAPE is the value: an assistant's
10
+ * first screen is the same object in every product — glyph, greeting, one line under it, one
11
+ * trailing action — and Ant X named it, so every consumer that builds a chat now expects the name.
12
+ * What it owns beyond a `Flex` is the `extra` slot's placement (on the TITLE row, not below the
13
+ * description, which is where a hand-roll puts it) and the `icon`-as-URL rule below.
14
+ *
15
+ * ## Two deliberate differences from Ant X, both in the same direction
16
+ *
17
+ * - **The image icon is decorative.** Ant renders `alt="icon"` — a screen reader then reads the
18
+ * word "icon" beside a title the glyph is only decorating. Here it is `alt=""`, which is what an
19
+ * image that duplicates adjacent text is supposed to be.
20
+ * - **The heading level is Ant's.** Ant hardcodes `Typography.Title level={4}`, so this renders an
21
+ * `<h4>`. Hardcoding a level is a document-structure decision a component should not normally
22
+ * make, but the alternative — inventing a `level` prop Ant does not have — is a second spelling
23
+ * of an axis the issue asked to port verbatim. Wrap it in your own heading hierarchy if the page
24
+ * needs a different rung.
25
+ */
26
+ export declare const Welcome: React.ForwardRefExoticComponent<WelcomeProp & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { Heading, Text } from "../general/typography.js";
6
+ function isImageUrl(icon) {
7
+ return typeof icon === "string" && icon.startsWith("http");
8
+ }
9
+ const Welcome = React.forwardRef(
10
+ ({ icon, title, description, extra, variant = "filled", id, className, ...rest }, ref) => {
11
+ return /* @__PURE__ */ jsxs(
12
+ "div",
13
+ {
14
+ ref,
15
+ id,
16
+ "data-slot": "welcome",
17
+ "data-variant": variant,
18
+ className: cn("ui-welcome", className),
19
+ ...rest,
20
+ children: [
21
+ icon ? /* @__PURE__ */ jsx("div", { "data-slot": "welcome-icon", className: "ui-welcome-icon", "aria-hidden": "true", children: isImageUrl(icon) ? /* @__PURE__ */ jsx("img", { src: icon, alt: "" }) : icon }) : null,
22
+ /* @__PURE__ */ jsxs("div", { "data-slot": "welcome-content", className: "ui-welcome-content", children: [
23
+ title || extra ? /* @__PURE__ */ jsxs("div", { "data-slot": "welcome-title-row", className: "ui-welcome-title-row", children: [
24
+ title ? /* @__PURE__ */ jsx(Heading, { level: 4, className: "ui-welcome-title", children: title }) : null,
25
+ extra ? /* @__PURE__ */ jsx("div", { "data-slot": "welcome-extra", className: "ui-welcome-extra", children: extra }) : null
26
+ ] }) : null,
27
+ description ? /* @__PURE__ */ jsx(Text, { size: "sm", tone: "muted", className: "ui-welcome-description", children: description }) : null
28
+ ] })
29
+ ]
30
+ }
31
+ );
32
+ }
33
+ );
34
+ Welcome.displayName = "Welcome";
35
+ export {
36
+ Welcome
37
+ };
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ import type { AttachmentsItemProp, AttachmentsPlaceholderProp, AttachmentsRefProp } from "../../props/components/data-entry.prop.js";
3
+ export type { AttachmentsProp, AttachmentsProp as AttachmentsProps, AttachmentsItemProp, AttachmentsPlaceholderProp, AttachmentsOverflowProp, AttachmentsRefProp, } from "../../props/components/data-entry.prop.js";
4
+ export declare const Attachments: React.ForwardRefExoticComponent<Omit<import("./upload.js").UploadProp, "children" | "defaultValue" | "onRemove" | "onValueChange" | "showUploadList" | "value" | "variant"> & {
5
+ items?: readonly AttachmentsItemProp[];
6
+ onChange?: (info: {
7
+ file: AttachmentsItemProp;
8
+ fileList: AttachmentsItemProp[];
9
+ }) => void;
10
+ onRemove?: (item: AttachmentsItemProp) => boolean | void | Promise<boolean | void>;
11
+ overflow?: import("./attachments.js").AttachmentsOverflowProp;
12
+ placeholder?: AttachmentsPlaceholderProp | ((type: "inline" | "drop") => AttachmentsPlaceholderProp);
13
+ getDropContainer?: (() => HTMLElement | null | undefined) | null;
14
+ classNames?: Partial<Record<import("../../props/components/data-entry.prop.js").AttachmentsSemanticProp, string>>;
15
+ styles?: Partial<Record<import("../../props/components/data-entry.prop.js").AttachmentsSemanticProp, React.CSSProperties>>;
16
+ rootClassName?: import("../../props/index.js").ClassNameProp;
17
+ children?: React.ReactElement;
18
+ imageProps?: Record<string, unknown>;
19
+ } & React.RefAttributes<AttachmentsRefProp>>;