@godxjp/ui 31.13.0 → 31.15.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 +4 -4
- package/agent/components/Image.json +18 -2
- package/agent/components/Timeline.json +4 -3
- package/agent/components/Tree.json +22 -1
- package/agent/components-index.json +2 -2
- package/agent/components.json +44 -6
- package/agent/index.json +4 -4
- package/agent/llms.txt +5 -5
- package/agent/tokens.json +18 -0
- package/dist/components/data-display/image.d.ts +6 -1
- package/dist/components/data-display/image.js +90 -49
- package/dist/components/data-display/index.d.ts +1 -1
- package/dist/components/data-display/timeline.d.ts +12 -2
- package/dist/components/data-display/timeline.js +6 -2
- package/dist/components/data-display/tree.d.ts +1 -1
- package/dist/components/data-display/tree.js +147 -0
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +6 -1
- package/dist/i18n/messages/ja.json +6 -1
- package/dist/i18n/messages/vi.json +6 -1
- package/dist/props/components/data-display.prop.d.ts +67 -1
- package/dist/props/registry.d.ts +69 -0
- package/dist/props/registry.js +71 -0
- package/dist/styles/data-display-layout.css +92 -1
- package/dist/styles/layers.json +1 -1
- package/dist/tokens/components/data-display.css +1 -0
- package/dist/tokens/components/tree.css +3 -0
- package/docs/DESIGN-AUTHORITY.md +6 -0
- package/docs/FRAME-COVERAGE-REPORT.md +1 -1
- package/docs/data-display/image.tsx +40 -0
- package/docs/data-display/timeline.tsx +28 -0
- package/docs/data-display/tree.tsx +82 -0
- package/docs/i18n/messages/en.json +24 -0
- package/docs/i18n/messages/ja.json +24 -0
- package/docs/i18n/messages/vi.json +24 -0
- package/package.json +2 -2
package/agent/START-HERE.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
You are about to write code against a design system you did not author. This file is the whole
|
|
4
4
|
contract. Read it before you write JSX.
|
|
5
5
|
|
|
6
|
-
**This catalog describes `@godxjp/ui` 31.
|
|
6
|
+
**This catalog describes `@godxjp/ui` 31.15.0.** If the project you are editing has a different
|
|
7
7
|
version in its `package.json`, read the pinned catalog for THAT version instead
|
|
8
8
|
(`…/v<their-version>/agent/…`). A catalog newer than the installed package describes props that do
|
|
9
9
|
not exist yet; older, and it hides props that do. Neither failure announces itself.
|
|
@@ -56,10 +56,10 @@ Then ask it: `search_components`, `get_component`, `get_tokens`, `get_rule`, `li
|
|
|
56
56
|
its `importPath`, and its examples. Fetch only the handful you picked in step 1.
|
|
57
57
|
3. `rules.json` — 50 cardinal rules. The ones about raw HTML and hardcoded colour are not
|
|
58
58
|
style advice.
|
|
59
|
-
4. `tokens.json` —
|
|
59
|
+
4. `tokens.json` — 2121 design tokens, each tagged with its `tier`. **If you were handed a
|
|
60
60
|
brand, read the 211 `foundation` entries first** — `--primary`, `--background`,
|
|
61
61
|
`--radius`, `--font-size-base` are the handful everything else derives from. The
|
|
62
|
-
|
|
62
|
+
1806 `component` entries are per-part knobs; reach for one only when a role is
|
|
63
63
|
right everywhere except one component.
|
|
64
64
|
5. `anti-ai-tells.json` — 26 shapes that make generated UI look generated, each with the
|
|
65
65
|
fix. Read before you reach for a gradient hero or a wall of coloured chips.
|
|
@@ -145,7 +145,7 @@ has stopped following the brand.
|
|
|
145
145
|
|---|---|---|---|
|
|
146
146
|
| `foundation` | 211 | the seeds — `--primary`, `--background`, `--foreground`, `--radius`, `--font-size-base`, `--shadow-color`. Everything below is derived from these | **yes — this is the main road.** Handed a brand colour, this is where it goes: `:root { --primary: <H> <S>% <L>%; }` (HSL components, no `hsl()` wrapper) |
|
|
147
147
|
| `semantic` | 104 | named roles that follow the seeds — `--ring`, `--text-link`, `--primary-hover`, `--overlay-background` | only when the seed is right and ONE role must differ. That role then stops following a later brand change |
|
|
148
|
-
| `component` |
|
|
148
|
+
| `component` | 1806 | per-part knobs, `--{component}-{part}-{property}` | rarely. Most are declared `initial` with the real default at the call site — deliberate, so a scoped override re-resolves instead of freezing at `:root` |
|
|
149
149
|
|
|
150
150
|
A token whose `value` is `initial` is not empty and not broken: `initial` is the guaranteed-invalid
|
|
151
151
|
value, so the real default is computed where the element paints it. Set it and yours wins.
|
|
@@ -31,10 +31,25 @@
|
|
|
31
31
|
"type": "ReactNode | boolean"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
-
"description": "
|
|
34
|
+
"description": "antd Image: size the FRAME (number = px, or a CSS length); the picture fills it. `width` alone keeps the picture's ratio; a fixed height crops per `fit`. Also set on the img.",
|
|
35
35
|
"name": "width / height",
|
|
36
36
|
"type": "number | string"
|
|
37
37
|
},
|
|
38
|
+
{
|
|
39
|
+
"description": "Thumbnail frame on the Thumbnail height scale (64 / 96 / 160px) at `--thumbnail-width-ratio` (4 / 3), cropped to fill. godx extension; `width`/`height` override the side they name.",
|
|
40
|
+
"name": "size",
|
|
41
|
+
"type": "\"sm\" | \"md\" | \"lg\""
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"description": "object-fit inside a fixed frame. Default `cover` once the height is fixed (size or height).",
|
|
45
|
+
"name": "fit",
|
|
46
|
+
"type": "\"cover\" | \"contain\""
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"description": "Text under the picture in a figure held to the picture's width — a long file name truncates instead of widening the tile. godx extension.",
|
|
50
|
+
"name": "caption",
|
|
51
|
+
"type": "ReactNode"
|
|
52
|
+
},
|
|
38
53
|
{
|
|
39
54
|
"description": "Class on the wrapper (the button).",
|
|
40
55
|
"name": "className",
|
|
@@ -78,7 +93,8 @@
|
|
|
78
93
|
"DO pass `preview={false}` for a logo or icon inside that body so it neither opens nor counts.",
|
|
79
94
|
"DO use `Image.PreviewGroup` or `ImagePreviewGroup` — the same component.",
|
|
80
95
|
"DON'T hand-roll a lightbox from Dialog + Carousel: it has no zoom, no arrow keys and a 32rem box. That composition is what this replaces.",
|
|
81
|
-
"DON'T nest an Image inside a link or button: the thumbnail is itself a button."
|
|
96
|
+
"DON'T nest an Image inside a link or button: the thumbnail is itself a button.",
|
|
97
|
+
"DO size an attachment gallery with `size=\"md\"` (96px, 4:3, cropped) and put the file name in `caption` — never an inline style reading `--thumbnail-block-size`."
|
|
82
98
|
],
|
|
83
99
|
"useCases": [
|
|
84
100
|
"Screenshots in a test result or wiki page that the reader opens large and pages through.",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"example": "import { Timeline } from \"@godxjp/ui/data-display\";\n\n// Default icon variant\n<Timeline items={[\n { title: \"注文受付\", time: \"2024-06-01 10:00\" },\n { title: \"発送準備中\", time: \"2024-06-01 14:00\" },\n { title: \"配送中\", current: true },\n]} />\n\n// Numbered route stepper (Pattern A)\n<Timeline variant=\"ordinal\" items={[\n { title: \"集荷\", location: \"東京 → 名古屋\", status: \"pending\" },\n { title: \"幹線輸送\", location: \"名古屋 → 大阪\", status: \"pending\" },\n]} />\n\n// Status tracker (Pattern B): done → check, current → dot, pending → number\n<Timeline variant=\"status\" items={[\n { title: \"請求書を発行\", status: \"done\" },\n { title: \"承認待ち\", status: \"current\" },\n { title: \"消費税を計上\", status: \"pending\" },\n]} />",
|
|
2
|
+
"example": "import { Timeline } from \"@godxjp/ui/data-display\";\nimport { ArrowRightLeft, MessageSquare } from \"lucide-react\";\n\n// Default icon variant\n<Timeline items={[\n { title: \"注文受付\", time: \"2024-06-01 10:00\" },\n { title: \"発送準備中\", time: \"2024-06-01 14:00\" },\n { title: \"配送中\", current: true },\n]} />\n\n// Numbered route stepper (Pattern A)\n<Timeline variant=\"ordinal\" items={[\n { title: \"集荷\", location: \"東京 → 名古屋\", status: \"pending\" },\n { title: \"幹線輸送\", location: \"名古屋 → 大阪\", status: \"pending\" },\n]} />\n\n// Activity log / issue history: neutral dots, no status prefix (gh#1092)\n<Timeline density=\"compact\" items={[\n { title: \"Aki がステータスを変更 未対応 → 処理中\", time: \"10/01 08:12\", status: \"log\", icon: ArrowRightLeft },\n { title: \"Ken がコメント\", time: \"10/01 09:30\", status: \"log\", icon: MessageSquare },\n]} />\n\n// Status tracker (Pattern B): done → check, current → dot, pending → number\n<Timeline variant=\"status\" items={[\n { title: \"請求書を発行\", status: \"done\" },\n { title: \"承認待ち\", status: \"current\" },\n { title: \"消費税を計上\", status: \"pending\" },\n]} />",
|
|
3
3
|
"group": "data-display",
|
|
4
4
|
"importPath": "@godxjp/ui/data-display",
|
|
5
5
|
"name": "Timeline",
|
|
6
6
|
"props": [
|
|
7
7
|
{
|
|
8
|
-
"description": "Array of `{ title, location?, time?, note?, current?, status?, icon? }`. `status` is
|
|
8
|
+
"description": "Array of `{ title, location?, time?, note?, current?, status?, icon? }`. `status` is 'done' | 'current' | 'pending' | 'log'; `current: true` is shorthand for `status: 'current'`. 'log' (gh#1092) is an activity-log / history row: the neutral dot + hairline rail `pending` draws, and NO sr-only status prefix (antd's `color=\"gray\"` item). `icon` (a LucideIcon) overrides the auto-glyph for that item.",
|
|
9
9
|
"name": "items",
|
|
10
10
|
"required": true,
|
|
11
11
|
"type": "TimelineItem[]"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"rules": [],
|
|
31
31
|
"storyPath": "data-display/Timeline.stories.tsx",
|
|
32
|
-
"tagline": "Vertical event list with an icon rail. Current item gets a highlighted glyph. `variant` switches the rail to numbered (ordinal) or status-driven glyphs, and each item carries a
|
|
32
|
+
"tagline": "Vertical event list with an icon rail. Current item gets a highlighted glyph. `variant` switches the rail to numbered (ordinal) or status-driven glyphs, and each item carries a `status` (done/current/pending, or `log` for an activity-log entry with no status semantics) plus an optional per-item `icon`. The whole progress column is ONE hue: done dot, current dot and travelled line all paint `--primary`, exactly as `Steps` paints `finish` and `process`.",
|
|
33
33
|
"usage": [
|
|
34
34
|
"DO pass an array of `TimelineItem` objects to `items`. Each item is `{ title, location?, time?, note?, current?, status?, icon? }`. All fields except `title` are optional. The only other props are `variant` and `density`.",
|
|
35
35
|
"DO mark the in-progress event with `current: true` (or `status: 'current'`). In the default `variant='icon'`, the current item renders a `Plane` icon and every other item a `CheckCircle2`. Use `variant='ordinal'` for a numbered route stepper (1,2,3…) or `variant='status'` for a done→check / current→dot / pending→number tracker. Pass `status: 'done' | 'current' | 'pending'` per item to drive colour and (in the status variant) the glyph; pass `icon` (a LucideIcon) to override the glyph for a single item.",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"DO NOT use Timeline for user-facing wizard progress (steps the user must complete in order) — use `Steps` for that. Timeline is read-only historical/status display; it has no interactive state, no `onClick`, and no concept of 'go to step'.",
|
|
40
40
|
"DO wrap Timeline in `<CardContent>` when placing it inside a `Card` — bare `Card` has no inner padding, so the rail will render flush against the card edge without `CardContent`.",
|
|
41
41
|
"THE PROGRESS COLUMN IS ONE HUE (gh#731). The done dot, the current dot and the travelled line all default to `hsl(var(--primary))` — the same contract `Steps` uses for `finish` + `process`, and antd's (only `error` leaves the primary hue). The current item is told apart by a ring (`--timeline-dot-current-ring-width`, `--steps-dot-process-ring-width`'s value), by `aria-current=\"step\"` + a localized sr-only prefix, and by a different glyph — never by a second colour role. Re-theme `--primary` and the whole rail follows. Measured light: done 2.18:1 → 6.31:1 against the card, glyph 6.31:1 on the fill; dark 7.22:1 → 9.84:1, glyph 10.72:1.",
|
|
42
|
+
"DO use `status: 'log'` for every row of an activity log / issue history / audit trail (gh#1092). Those rows already HAPPENED and are not steps: `done` paints them primary and prefixes 「Completed:」, `pending` reads 「Upcoming:」 to a screen reader. `log` draws the quiet neutral dot (a plain pip, or the item's `icon`) and hairline rail, with no prefix — antd's gray item.",
|
|
42
43
|
"DON'T expect `--success` on a `status: 'done'` item — `done | current | pending` is POSITION IN A SEQUENCE, not status, and Timeline has no `tone` axis. Put a real status on the item's `title` or `note` with a `<Badge tone=\"success\">`, which is the surface that owns the status green.",
|
|
43
44
|
"TO RESTORE the pre-27.9 green/violet pairing, set the done dot's fill AND its ink together in your theme (global or `[data-tenant]`) — the two roles have opposite ink polarity, so the fill alone leaves a near-white glyph on 若竹 green at 2.18:1 (gh#643): `--timeline-dot-done-background: hsl(var(--success)); --timeline-dot-done-foreground: hsl(var(--success-foreground));`. `--timeline-dot-current-background` and `--timeline-line-completed-background` retint the other two surfaces the same way."
|
|
44
45
|
],
|
|
@@ -90,6 +90,27 @@
|
|
|
90
90
|
"name": "loadData",
|
|
91
91
|
"type": "(node: TreeNodeProp) => void | Promise<void>"
|
|
92
92
|
},
|
|
93
|
+
{
|
|
94
|
+
"defaultValue": "false",
|
|
95
|
+
"description": "Move nodes by dragging (antd `draggable`, gh#1093). Dropping on a row's upper / lower quarter lands in the gap before / after it, the middle files it inside. The tree never edits `treeData` — it reports the move via `onDrop` and you persist it. Keyboard equivalent (WCAG 2.5.7): Alt+↑ / Alt+↓ move past the previous / next sibling, Alt+← outdents (after the parent), Alt+→ indents (into the previous sibling, as its last child); every move is announced in a live region and described on the tree. A node never drops into itself or its own subtree.",
|
|
96
|
+
"name": "draggable",
|
|
97
|
+
"type": "boolean"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"description": "Per-node drag gate (antd `draggable.nodeDraggable`). Disabled nodes never drag.",
|
|
101
|
+
"name": "allowDrag",
|
|
102
|
+
"type": "(node: TreeNodeProp) => boolean"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"description": "Per-target drop gate (antd `allowDrop`), asked for pointer AND keyboard moves. Use it for your own rules (max depth, no leaf parents); the self/subtree cycle is already refused.",
|
|
106
|
+
"name": "allowDrop",
|
|
107
|
+
"type": "(info: { dragNode: TreeNodeProp; dropNode: TreeNodeProp; dropPosition: -1 | 0 | 1 }) => boolean"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"description": "A committed move (antd `onDrop`). `dropPosition` is RELATIVE to `node` — -1 before, 0 inside, 1 after (antd reports an absolute index that every antd demo converts back to this). `dropToGap` is true for before/after (sibling of `node`), false for inside (child of `node`). Update `treeData` here.",
|
|
111
|
+
"name": "onDrop",
|
|
112
|
+
"type": "(info: { dragNode: TreeNodeProp; node: TreeNodeProp; dropPosition: -1 | 0 | 1; dropToGap: boolean }) => void"
|
|
113
|
+
},
|
|
93
114
|
{
|
|
94
115
|
"description": "Render a node's title yourself (antd `titleRender`).",
|
|
95
116
|
"name": "titleRender",
|
|
@@ -179,7 +200,7 @@
|
|
|
179
200
|
45
|
|
180
201
|
],
|
|
181
202
|
"storyPath": "data-display/Tree.stories.tsx",
|
|
182
|
-
"tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes
|
|
203
|
+
"tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes, async `loadData` and `draggable` reorder/reparent (antd `onDrop`). Reach for it whenever nodes expand, collapse or are navigated by keyboard; TreeSelect is the same hierarchy inside a Popover.",
|
|
183
204
|
"usage": [
|
|
184
205
|
"DO name the tree — pass `aria-label` (through your own `t()`) or `aria-labelledby`. A tree with no name is an unlabelled landmark for every screen reader user.",
|
|
185
206
|
"DO keep SELECTION and CHECKS apart: `value`/`onValueChange` is which node is open in the detail pane; `checkedValues`/`onCheckedValuesChange` is which nodes are ticked. They are two axes, exactly as in antd — never drive one from the other.",
|
|
@@ -304,7 +304,7 @@
|
|
|
304
304
|
{
|
|
305
305
|
"group": "data-display",
|
|
306
306
|
"name": "Timeline",
|
|
307
|
-
"tagline": "Vertical event list with an icon rail. Current item gets a highlighted glyph. `variant` switches the rail to numbered (ordinal) or status-driven glyphs, and each item carries a
|
|
307
|
+
"tagline": "Vertical event list with an icon rail. Current item gets a highlighted glyph. `variant` switches the rail to numbered (ordinal) or status-driven glyphs, and each item carries a `status` (done/current/pending, or `log` for an activity-log entry with no status semantics) plus an optional per-item `icon`. The whole progress column is ONE hue: done dot, current dot and travelled line all paint `--primary`, exactly as `Steps` paints `finish` and `process`."
|
|
308
308
|
},
|
|
309
309
|
{
|
|
310
310
|
"group": "data-display",
|
|
@@ -585,7 +585,7 @@
|
|
|
585
585
|
{
|
|
586
586
|
"group": "data-display",
|
|
587
587
|
"name": "Tree",
|
|
588
|
-
"tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes
|
|
588
|
+
"tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes, async `loadData` and `draggable` reorder/reparent (antd `onDrop`). Reach for it whenever nodes expand, collapse or are navigated by keyboard; TreeSelect is the same hierarchy inside a Popover."
|
|
589
589
|
},
|
|
590
590
|
{
|
|
591
591
|
"group": "feedback",
|
package/agent/components.json
CHANGED
|
@@ -4959,13 +4959,13 @@
|
|
|
4959
4959
|
]
|
|
4960
4960
|
},
|
|
4961
4961
|
{
|
|
4962
|
-
"example": "import { Timeline } from \"@godxjp/ui/data-display\";\n\n// Default icon variant\n<Timeline items={[\n { title: \"注文受付\", time: \"2024-06-01 10:00\" },\n { title: \"発送準備中\", time: \"2024-06-01 14:00\" },\n { title: \"配送中\", current: true },\n]} />\n\n// Numbered route stepper (Pattern A)\n<Timeline variant=\"ordinal\" items={[\n { title: \"集荷\", location: \"東京 → 名古屋\", status: \"pending\" },\n { title: \"幹線輸送\", location: \"名古屋 → 大阪\", status: \"pending\" },\n]} />\n\n// Status tracker (Pattern B): done → check, current → dot, pending → number\n<Timeline variant=\"status\" items={[\n { title: \"請求書を発行\", status: \"done\" },\n { title: \"承認待ち\", status: \"current\" },\n { title: \"消費税を計上\", status: \"pending\" },\n]} />",
|
|
4962
|
+
"example": "import { Timeline } from \"@godxjp/ui/data-display\";\nimport { ArrowRightLeft, MessageSquare } from \"lucide-react\";\n\n// Default icon variant\n<Timeline items={[\n { title: \"注文受付\", time: \"2024-06-01 10:00\" },\n { title: \"発送準備中\", time: \"2024-06-01 14:00\" },\n { title: \"配送中\", current: true },\n]} />\n\n// Numbered route stepper (Pattern A)\n<Timeline variant=\"ordinal\" items={[\n { title: \"集荷\", location: \"東京 → 名古屋\", status: \"pending\" },\n { title: \"幹線輸送\", location: \"名古屋 → 大阪\", status: \"pending\" },\n]} />\n\n// Activity log / issue history: neutral dots, no status prefix (gh#1092)\n<Timeline density=\"compact\" items={[\n { title: \"Aki がステータスを変更 未対応 → 処理中\", time: \"10/01 08:12\", status: \"log\", icon: ArrowRightLeft },\n { title: \"Ken がコメント\", time: \"10/01 09:30\", status: \"log\", icon: MessageSquare },\n]} />\n\n// Status tracker (Pattern B): done → check, current → dot, pending → number\n<Timeline variant=\"status\" items={[\n { title: \"請求書を発行\", status: \"done\" },\n { title: \"承認待ち\", status: \"current\" },\n { title: \"消費税を計上\", status: \"pending\" },\n]} />",
|
|
4963
4963
|
"group": "data-display",
|
|
4964
4964
|
"importPath": "@godxjp/ui/data-display",
|
|
4965
4965
|
"name": "Timeline",
|
|
4966
4966
|
"props": [
|
|
4967
4967
|
{
|
|
4968
|
-
"description": "Array of `{ title, location?, time?, note?, current?, status?, icon? }`. `status` is
|
|
4968
|
+
"description": "Array of `{ title, location?, time?, note?, current?, status?, icon? }`. `status` is 'done' | 'current' | 'pending' | 'log'; `current: true` is shorthand for `status: 'current'`. 'log' (gh#1092) is an activity-log / history row: the neutral dot + hairline rail `pending` draws, and NO sr-only status prefix (antd's `color=\"gray\"` item). `icon` (a LucideIcon) overrides the auto-glyph for that item.",
|
|
4969
4969
|
"name": "items",
|
|
4970
4970
|
"required": true,
|
|
4971
4971
|
"type": "TimelineItem[]"
|
|
@@ -4989,7 +4989,7 @@
|
|
|
4989
4989
|
],
|
|
4990
4990
|
"rules": [],
|
|
4991
4991
|
"storyPath": "data-display/Timeline.stories.tsx",
|
|
4992
|
-
"tagline": "Vertical event list with an icon rail. Current item gets a highlighted glyph. `variant` switches the rail to numbered (ordinal) or status-driven glyphs, and each item carries a
|
|
4992
|
+
"tagline": "Vertical event list with an icon rail. Current item gets a highlighted glyph. `variant` switches the rail to numbered (ordinal) or status-driven glyphs, and each item carries a `status` (done/current/pending, or `log` for an activity-log entry with no status semantics) plus an optional per-item `icon`. The whole progress column is ONE hue: done dot, current dot and travelled line all paint `--primary`, exactly as `Steps` paints `finish` and `process`.",
|
|
4993
4993
|
"usage": [
|
|
4994
4994
|
"DO pass an array of `TimelineItem` objects to `items`. Each item is `{ title, location?, time?, note?, current?, status?, icon? }`. All fields except `title` are optional. The only other props are `variant` and `density`.",
|
|
4995
4995
|
"DO mark the in-progress event with `current: true` (or `status: 'current'`). In the default `variant='icon'`, the current item renders a `Plane` icon and every other item a `CheckCircle2`. Use `variant='ordinal'` for a numbered route stepper (1,2,3…) or `variant='status'` for a done→check / current→dot / pending→number tracker. Pass `status: 'done' | 'current' | 'pending'` per item to drive colour and (in the status variant) the glyph; pass `icon` (a LucideIcon) to override the glyph for a single item.",
|
|
@@ -4999,6 +4999,7 @@
|
|
|
4999
4999
|
"DO NOT use Timeline for user-facing wizard progress (steps the user must complete in order) — use `Steps` for that. Timeline is read-only historical/status display; it has no interactive state, no `onClick`, and no concept of 'go to step'.",
|
|
5000
5000
|
"DO wrap Timeline in `<CardContent>` when placing it inside a `Card` — bare `Card` has no inner padding, so the rail will render flush against the card edge without `CardContent`.",
|
|
5001
5001
|
"THE PROGRESS COLUMN IS ONE HUE (gh#731). The done dot, the current dot and the travelled line all default to `hsl(var(--primary))` — the same contract `Steps` uses for `finish` + `process`, and antd's (only `error` leaves the primary hue). The current item is told apart by a ring (`--timeline-dot-current-ring-width`, `--steps-dot-process-ring-width`'s value), by `aria-current=\"step\"` + a localized sr-only prefix, and by a different glyph — never by a second colour role. Re-theme `--primary` and the whole rail follows. Measured light: done 2.18:1 → 6.31:1 against the card, glyph 6.31:1 on the fill; dark 7.22:1 → 9.84:1, glyph 10.72:1.",
|
|
5002
|
+
"DO use `status: 'log'` for every row of an activity log / issue history / audit trail (gh#1092). Those rows already HAPPENED and are not steps: `done` paints them primary and prefixes 「Completed:」, `pending` reads 「Upcoming:」 to a screen reader. `log` draws the quiet neutral dot (a plain pip, or the item's `icon`) and hairline rail, with no prefix — antd's gray item.",
|
|
5002
5003
|
"DON'T expect `--success` on a `status: 'done'` item — `done | current | pending` is POSITION IN A SEQUENCE, not status, and Timeline has no `tone` axis. Put a real status on the item's `title` or `note` with a `<Badge tone=\"success\">`, which is the surface that owns the status green.",
|
|
5003
5004
|
"TO RESTORE the pre-27.9 green/violet pairing, set the done dot's fill AND its ink together in your theme (global or `[data-tenant]`) — the two roles have opposite ink polarity, so the fill alone leaves a near-white glyph on 若竹 green at 2.18:1 (gh#643): `--timeline-dot-done-background: hsl(var(--success)); --timeline-dot-done-foreground: hsl(var(--success-foreground));`. `--timeline-dot-current-background` and `--timeline-line-completed-background` retint the other two surfaces the same way."
|
|
5004
5005
|
],
|
|
@@ -11130,6 +11131,27 @@
|
|
|
11130
11131
|
"name": "loadData",
|
|
11131
11132
|
"type": "(node: TreeNodeProp) => void | Promise<void>"
|
|
11132
11133
|
},
|
|
11134
|
+
{
|
|
11135
|
+
"defaultValue": "false",
|
|
11136
|
+
"description": "Move nodes by dragging (antd `draggable`, gh#1093). Dropping on a row's upper / lower quarter lands in the gap before / after it, the middle files it inside. The tree never edits `treeData` — it reports the move via `onDrop` and you persist it. Keyboard equivalent (WCAG 2.5.7): Alt+↑ / Alt+↓ move past the previous / next sibling, Alt+← outdents (after the parent), Alt+→ indents (into the previous sibling, as its last child); every move is announced in a live region and described on the tree. A node never drops into itself or its own subtree.",
|
|
11137
|
+
"name": "draggable",
|
|
11138
|
+
"type": "boolean"
|
|
11139
|
+
},
|
|
11140
|
+
{
|
|
11141
|
+
"description": "Per-node drag gate (antd `draggable.nodeDraggable`). Disabled nodes never drag.",
|
|
11142
|
+
"name": "allowDrag",
|
|
11143
|
+
"type": "(node: TreeNodeProp) => boolean"
|
|
11144
|
+
},
|
|
11145
|
+
{
|
|
11146
|
+
"description": "Per-target drop gate (antd `allowDrop`), asked for pointer AND keyboard moves. Use it for your own rules (max depth, no leaf parents); the self/subtree cycle is already refused.",
|
|
11147
|
+
"name": "allowDrop",
|
|
11148
|
+
"type": "(info: { dragNode: TreeNodeProp; dropNode: TreeNodeProp; dropPosition: -1 | 0 | 1 }) => boolean"
|
|
11149
|
+
},
|
|
11150
|
+
{
|
|
11151
|
+
"description": "A committed move (antd `onDrop`). `dropPosition` is RELATIVE to `node` — -1 before, 0 inside, 1 after (antd reports an absolute index that every antd demo converts back to this). `dropToGap` is true for before/after (sibling of `node`), false for inside (child of `node`). Update `treeData` here.",
|
|
11152
|
+
"name": "onDrop",
|
|
11153
|
+
"type": "(info: { dragNode: TreeNodeProp; node: TreeNodeProp; dropPosition: -1 | 0 | 1; dropToGap: boolean }) => void"
|
|
11154
|
+
},
|
|
11133
11155
|
{
|
|
11134
11156
|
"description": "Render a node's title yourself (antd `titleRender`).",
|
|
11135
11157
|
"name": "titleRender",
|
|
@@ -11219,7 +11241,7 @@
|
|
|
11219
11241
|
45
|
|
11220
11242
|
],
|
|
11221
11243
|
"storyPath": "data-display/Tree.stories.tsx",
|
|
11222
|
-
"tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes
|
|
11244
|
+
"tagline": "The standalone WAI-ARIA tree view on a page (antd `Tree` / `DirectoryTree`) — nested `treeData`, a disclosure triangle per branch, roving-tabindex arrow navigation, optional tri-state checkboxes, async `loadData` and `draggable` reorder/reparent (antd `onDrop`). Reach for it whenever nodes expand, collapse or are navigated by keyboard; TreeSelect is the same hierarchy inside a Popover.",
|
|
11223
11245
|
"usage": [
|
|
11224
11246
|
"DO name the tree — pass `aria-label` (through your own `t()`) or `aria-labelledby`. A tree with no name is an unlabelled landmark for every screen reader user.",
|
|
11225
11247
|
"DO keep SELECTION and CHECKS apart: `value`/`onValueChange` is which node is open in the detail pane; `checkedValues`/`onCheckedValuesChange` is which nodes are ticked. They are two axes, exactly as in antd — never drive one from the other.",
|
|
@@ -15808,10 +15830,25 @@
|
|
|
15808
15830
|
"type": "ReactNode | boolean"
|
|
15809
15831
|
},
|
|
15810
15832
|
{
|
|
15811
|
-
"description": "
|
|
15833
|
+
"description": "antd Image: size the FRAME (number = px, or a CSS length); the picture fills it. `width` alone keeps the picture's ratio; a fixed height crops per `fit`. Also set on the img.",
|
|
15812
15834
|
"name": "width / height",
|
|
15813
15835
|
"type": "number | string"
|
|
15814
15836
|
},
|
|
15837
|
+
{
|
|
15838
|
+
"description": "Thumbnail frame on the Thumbnail height scale (64 / 96 / 160px) at `--thumbnail-width-ratio` (4 / 3), cropped to fill. godx extension; `width`/`height` override the side they name.",
|
|
15839
|
+
"name": "size",
|
|
15840
|
+
"type": "\"sm\" | \"md\" | \"lg\""
|
|
15841
|
+
},
|
|
15842
|
+
{
|
|
15843
|
+
"description": "object-fit inside a fixed frame. Default `cover` once the height is fixed (size or height).",
|
|
15844
|
+
"name": "fit",
|
|
15845
|
+
"type": "\"cover\" | \"contain\""
|
|
15846
|
+
},
|
|
15847
|
+
{
|
|
15848
|
+
"description": "Text under the picture in a figure held to the picture's width — a long file name truncates instead of widening the tile. godx extension.",
|
|
15849
|
+
"name": "caption",
|
|
15850
|
+
"type": "ReactNode"
|
|
15851
|
+
},
|
|
15815
15852
|
{
|
|
15816
15853
|
"description": "Class on the wrapper (the button).",
|
|
15817
15854
|
"name": "className",
|
|
@@ -15855,7 +15892,8 @@
|
|
|
15855
15892
|
"DO pass `preview={false}` for a logo or icon inside that body so it neither opens nor counts.",
|
|
15856
15893
|
"DO use `Image.PreviewGroup` or `ImagePreviewGroup` — the same component.",
|
|
15857
15894
|
"DON'T hand-roll a lightbox from Dialog + Carousel: it has no zoom, no arrow keys and a 32rem box. That composition is what this replaces.",
|
|
15858
|
-
"DON'T nest an Image inside a link or button: the thumbnail is itself a button."
|
|
15895
|
+
"DON'T nest an Image inside a link or button: the thumbnail is itself a button.",
|
|
15896
|
+
"DO size an attachment gallery with `size=\"md\"` (96px, 4:3, cropped) and put the file name in `caption` — never an inline style reading `--thumbnail-block-size`."
|
|
15859
15897
|
],
|
|
15860
15898
|
"useCases": [
|
|
15861
15899
|
"Screenshots in a test result or wiki page that the reader opens large and pages through.",
|
package/agent/index.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"components": 178,
|
|
5
5
|
"patterns": 21,
|
|
6
6
|
"rules": 50,
|
|
7
|
-
"tokens":
|
|
7
|
+
"tokens": 2121,
|
|
8
8
|
"vocabulary": 14
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
@@ -48,19 +48,19 @@
|
|
|
48
48
|
"note": "Pin to the tag that matches the @godxjp/ui version you installed. A catalog newer than your package describes props you do not have; older, and it hides props you do.",
|
|
49
49
|
"read": {
|
|
50
50
|
"live": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json",
|
|
51
|
-
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v31.
|
|
51
|
+
"pinned": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/v31.15.0/agent/index.json"
|
|
52
52
|
},
|
|
53
53
|
"source": "mcp/src/data — the same data @godxjp/ui-mcp serves — plus the foundation and semantic token tiers, read from src/tokens/*.css",
|
|
54
54
|
"start": "https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md",
|
|
55
55
|
"tokenTiers": {
|
|
56
56
|
"component": "per-part knobs, --{component}-{part}-{property}; usually leave these alone",
|
|
57
57
|
"counts": {
|
|
58
|
-
"component":
|
|
58
|
+
"component": 1806,
|
|
59
59
|
"foundation": 211,
|
|
60
60
|
"semantic": 104
|
|
61
61
|
},
|
|
62
62
|
"foundation": "the seeds a consumer is invited to set — --primary, --background, --radius",
|
|
63
63
|
"semantic": "named roles that follow the seeds — --ring, --text-link, --overlay-background"
|
|
64
64
|
},
|
|
65
|
-
"version": "31.
|
|
65
|
+
"version": "31.15.0"
|
|
66
66
|
}
|
package/agent/llms.txt
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @godxjp/ui
|
|
2
2
|
|
|
3
|
-
> A Japanese-enterprise React design system: 178 components,
|
|
4
|
-
> 50 cardinal rules. This file is the entry point for AI agents. Catalog version 31.
|
|
3
|
+
> A Japanese-enterprise React design system: 178 components, 2121 design tokens,
|
|
4
|
+
> 50 cardinal rules. This file is the entry point for AI agents. Catalog version 31.15.0.
|
|
5
5
|
|
|
6
6
|
If your client can run a process, do not read these files — run the MCP server instead
|
|
7
|
-
(`npx @godxjp/ui-mcp@31.
|
|
7
|
+
(`npx @godxjp/ui-mcp@31.15.0`). It is searchable and version-locked. These files exist for agents
|
|
8
8
|
that can only fetch URLs.
|
|
9
9
|
|
|
10
10
|
## Start
|
|
@@ -18,7 +18,7 @@ that can only fetch URLs.
|
|
|
18
18
|
- [components-index.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json): 48 KB — all 178 components as name, group, tagline, plus `absorbed`: the names that do NOT exist and map to it (`Combobox` → `Select`).
|
|
19
19
|
- [components/<Name>.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components/Select.json): one file per component (1 KB–36 KB, median 6 KB). Read the index, then fetch only the ones you chose — this is the selective route, and the reason you do not need the blob.
|
|
20
20
|
- [components.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components.json): 1.2 MB — every entry in one file. Most URL fetchers truncate a response this size without saying so; prefer the per-component files.
|
|
21
|
-
- [tokens.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json): every design token with its value, the reason it exists, and its `tier` — 211 `foundation` seeds (`--primary`, `--background`, `--radius`: set these when you are handed a brand), 104 `semantic` roles,
|
|
21
|
+
- [tokens.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json): every design token with its value, the reason it exists, and its `tier` — 211 `foundation` seeds (`--primary`, `--background`, `--radius`: set these when you are handed a brand), 104 `semantic` roles, 1806 `component` knobs.
|
|
22
22
|
- [vocabulary.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/vocabulary.json): the controlled prop vocabulary — which prop name means what, across every component.
|
|
23
23
|
- [rules.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json): 50 cardinal rules.
|
|
24
24
|
- [anti-ai-tells.json](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/anti-ai-tells.json): 26 shapes that make generated UI look generated, each with its fix.
|
|
@@ -26,7 +26,7 @@ that can only fetch URLs.
|
|
|
26
26
|
## Pinning
|
|
27
27
|
|
|
28
28
|
Every URL above tracks `main`. To pin to the release a project actually installed, swap `main` for
|
|
29
|
-
the tag: `.../godx-jp/godxjp-ui/v31.
|
|
29
|
+
the tag: `.../godx-jp/godxjp-ui/v31.15.0/agent/...`. A catalog that does not match the installed
|
|
30
30
|
package describes props that are absent, or hides props that are present, and says nothing either way.
|
|
31
31
|
|
|
32
32
|
Pinned catalogs only exist for releases whose tag actually contains `agent/`. If `…/v<version>/agent/index.json` returns 404, that release predates this catalog: read `…/main/…` instead and compare `index.json` → `version` against the package you have, so you at least know which way it drifted.
|
package/agent/tokens.json
CHANGED
|
@@ -5633,6 +5633,12 @@
|
|
|
5633
5633
|
"tier": "component",
|
|
5634
5634
|
"value": "10rem"
|
|
5635
5635
|
},
|
|
5636
|
+
{
|
|
5637
|
+
"description": "Image `size` frame: width = the Thumbnail height × this ratio.",
|
|
5638
|
+
"name": "--thumbnail-width-ratio",
|
|
5639
|
+
"tier": "component",
|
|
5640
|
+
"value": "4 / 3"
|
|
5641
|
+
},
|
|
5636
5642
|
{
|
|
5637
5643
|
"description": "default = var(--stroke-hairline), resolved at the call site (gh#906)",
|
|
5638
5644
|
"name": "--thumbnail-border-width",
|
|
@@ -12311,6 +12317,18 @@
|
|
|
12311
12317
|
"tier": "component",
|
|
12312
12318
|
"value": "initial"
|
|
12313
12319
|
},
|
|
12320
|
+
{
|
|
12321
|
+
"description": "Drop indicator of a `draggable` tree (gh#1093): the gap line / inside frame. A role mirror, so `initial` with the role at the call site. Documented defaults: --tree-drop-indicator-color = hsl(var(--primary)); --tree-drop-indicator-width = var(--stroke-md).",
|
|
12322
|
+
"name": "--tree-drop-indicator-color",
|
|
12323
|
+
"tier": "component",
|
|
12324
|
+
"value": "initial"
|
|
12325
|
+
},
|
|
12326
|
+
{
|
|
12327
|
+
"description": "TREE — the standalone, on-page WAI-ARIA \"Tree View\" (`src/components/data-display/tree.tsx`). Every value the tree paints is a knob (cardinal rule #45), and the defaults are the QUIETEST reading (#44): no rails, a muted disclosure glyph, a selected band that tints rather than inverts. A service retunes the whole outline in one place instead of forking a row. ROLE-MIRROR KNOBS ARE `initial`, WITH THE DEFAULT AT THE CALL SITE. A knob whose default is a role token or a RE-SCOPED tier may not be bound at `:root` — CSS substitutes the `var()` where it is DECLARED, so the value would freeze at `:root` and a scoped `[data-tenant]` / `.dark` / a shell that re-scopes `--control-height` would never reach it. @see docs/TOKENS.md · \"Role-mirror knobs MUST be `initial`\".",
|
|
12328
|
+
"name": "--tree-drop-indicator-width",
|
|
12329
|
+
"tier": "component",
|
|
12330
|
+
"value": "initial"
|
|
12331
|
+
},
|
|
12314
12332
|
{
|
|
12315
12333
|
"description": "Width of the indeterminate bar shown while `loadData` resolves a branch. A fraction, not a length: it has to read as \"part of a row\" at every row width and every density.",
|
|
12316
12334
|
"name": "--tree-loading-bar-inline-size",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { ImagePreviewConfigProp, ImagePreviewGroupProp } from "../../props/components/data-display.prop.js";
|
|
3
|
-
export type { ImagePreviewConfigProp, ImagePreviewGroupConfigProp, ImagePreviewGroupProp, ImagePreviewGroupProp as ImagePreviewGroupProps, ImagePreviewItemProp, ImageProp, ImageProp as ImageProps, } from "../../props/components/data-display.prop.js";
|
|
3
|
+
export type { ImageFitProp, ImagePreviewConfigProp, ImagePreviewGroupConfigProp, ImagePreviewGroupProp, ImagePreviewGroupProp as ImagePreviewGroupProps, ImagePreviewItemProp, ImageProp, ImageProp as ImageProps, ImageSizeProp, } from "../../props/components/data-display.prop.js";
|
|
4
4
|
/**
|
|
5
5
|
* ImagePreviewGroup — pages one preview across many pictures (antd `Image.PreviewGroup`).
|
|
6
6
|
*
|
|
@@ -15,6 +15,11 @@ export declare const Image: React.ForwardRefExoticComponent<Omit<React.ImgHTMLAt
|
|
|
15
15
|
fallback?: string;
|
|
16
16
|
placeholder?: React.ReactNode | boolean;
|
|
17
17
|
preview?: boolean | ImagePreviewConfigProp;
|
|
18
|
+
width?: number | string;
|
|
19
|
+
height?: number | string;
|
|
20
|
+
size?: import("./image.js").ImageSizeProp;
|
|
21
|
+
fit?: import("./image.js").ImageFitProp;
|
|
22
|
+
caption?: React.ReactNode;
|
|
18
23
|
className?: import("../../props/index.js").ClassNameProp;
|
|
19
24
|
} & React.RefAttributes<HTMLImageElement>> & {
|
|
20
25
|
PreviewGroup: typeof ImagePreviewGroup;
|
|
@@ -386,7 +386,22 @@ function ImagePreviewGroup({
|
|
|
386
386
|
) : null
|
|
387
387
|
] }) });
|
|
388
388
|
}
|
|
389
|
-
const ImageRoot = React.forwardRef(function Image({
|
|
389
|
+
const ImageRoot = React.forwardRef(function Image({
|
|
390
|
+
src,
|
|
391
|
+
alt,
|
|
392
|
+
fallback,
|
|
393
|
+
placeholder,
|
|
394
|
+
preview = true,
|
|
395
|
+
width,
|
|
396
|
+
height,
|
|
397
|
+
size,
|
|
398
|
+
fit,
|
|
399
|
+
caption,
|
|
400
|
+
className,
|
|
401
|
+
onLoad,
|
|
402
|
+
onError,
|
|
403
|
+
...imgProps
|
|
404
|
+
}, ref) {
|
|
390
405
|
const { t } = useTranslation();
|
|
391
406
|
const group = React.useContext(ImageGroupContext);
|
|
392
407
|
const groupDisabled = React.useContext(ImageGroupDisabledContext);
|
|
@@ -420,13 +435,26 @@ const ImageRoot = React.forwardRef(function Image({ src, alt, fallback, placehol
|
|
|
420
435
|
const [visible, setVisible] = useMergedState(config.visible, false, config.onVisibleChange);
|
|
421
436
|
const shownSrc = isError && fallback ? fallback : src;
|
|
422
437
|
const showPlaceholder = placeholder != null && placeholder !== false && status === "loading";
|
|
438
|
+
const sized = size != null || width != null || height != null;
|
|
439
|
+
const frameFit = fit ?? (size != null || height != null ? "cover" : void 0);
|
|
440
|
+
const frame = sized ? {
|
|
441
|
+
"data-sized": "",
|
|
442
|
+
"data-size": size,
|
|
443
|
+
style: {
|
|
444
|
+
...width != null ? { "--image-inline-size": cssLength(width) } : null,
|
|
445
|
+
...height != null ? { "--image-block-size": cssLength(height) } : null
|
|
446
|
+
}
|
|
447
|
+
} : null;
|
|
423
448
|
const picture = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
424
449
|
/* @__PURE__ */ jsx(
|
|
425
450
|
"img",
|
|
426
451
|
{
|
|
427
452
|
...imgProps,
|
|
453
|
+
width,
|
|
454
|
+
height,
|
|
428
455
|
ref: setImgRef,
|
|
429
456
|
"data-slot": "image-img",
|
|
457
|
+
"data-fit": frameFit,
|
|
430
458
|
className: "ui-image-img",
|
|
431
459
|
src: shownSrc,
|
|
432
460
|
alt,
|
|
@@ -442,59 +470,72 @@ const ImageRoot = React.forwardRef(function Image({ src, alt, fallback, placehol
|
|
|
442
470
|
),
|
|
443
471
|
showPlaceholder ? /* @__PURE__ */ jsx("span", { "data-slot": "image-placeholder", className: "ui-image-placeholder", "aria-hidden": "true", children: placeholder === true ? null : placeholder }) : null
|
|
444
472
|
] });
|
|
473
|
+
const withCaption = (image) => caption == null ? image : /* @__PURE__ */ jsxs("figure", { "data-slot": "image-tile", className: "ui-image-tile", ...frame, children: [
|
|
474
|
+
image,
|
|
475
|
+
/* @__PURE__ */ jsx("figcaption", { "data-slot": "image-caption", className: "ui-image-caption", children: caption })
|
|
476
|
+
] });
|
|
445
477
|
if (!canPreview) {
|
|
446
|
-
return
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
478
|
+
return withCaption(
|
|
479
|
+
/* @__PURE__ */ jsx(
|
|
480
|
+
"span",
|
|
481
|
+
{
|
|
482
|
+
ref: wrapperRef,
|
|
483
|
+
"data-slot": "image",
|
|
484
|
+
"data-status": status,
|
|
485
|
+
...frame,
|
|
486
|
+
className: cn("ui-image", className),
|
|
487
|
+
children: picture
|
|
488
|
+
}
|
|
489
|
+
)
|
|
455
490
|
);
|
|
456
491
|
}
|
|
457
|
-
return
|
|
458
|
-
/* @__PURE__ */ jsxs(
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
492
|
+
return withCaption(
|
|
493
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
494
|
+
/* @__PURE__ */ jsxs(
|
|
495
|
+
"button",
|
|
496
|
+
{
|
|
497
|
+
ref: (node) => {
|
|
498
|
+
wrapperRef.current = node;
|
|
499
|
+
},
|
|
500
|
+
type: "button",
|
|
501
|
+
"data-slot": "image",
|
|
502
|
+
"data-status": status,
|
|
503
|
+
"data-preview": "",
|
|
504
|
+
...frame,
|
|
505
|
+
className: cn("ui-image ui-focus-ring", className),
|
|
506
|
+
"aria-label": alt ? t("dataDisplay.image.previewLabel", { alt }) : t("dataDisplay.image.previewUnnamed"),
|
|
507
|
+
"aria-haspopup": "dialog",
|
|
508
|
+
onClick: () => inGroup && group ? group.open(id) : setVisible(true),
|
|
509
|
+
children: [
|
|
510
|
+
picture,
|
|
511
|
+
/* @__PURE__ */ jsx("span", { "data-slot": "image-mask", className: "ui-image-mask", "aria-hidden": "true", children: config.mask ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
512
|
+
/* @__PURE__ */ jsx(Eye, { className: "ui-image-mask-icon" }),
|
|
513
|
+
t("dataDisplay.image.preview")
|
|
514
|
+
] }) })
|
|
515
|
+
]
|
|
516
|
+
}
|
|
517
|
+
),
|
|
518
|
+
inGroup ? null : /* @__PURE__ */ jsx(
|
|
519
|
+
ImagePreviewDialog,
|
|
520
|
+
{
|
|
521
|
+
open: visible,
|
|
522
|
+
onOpenChange: setVisible,
|
|
523
|
+
items: [{ src: previewSrc, alt }],
|
|
524
|
+
current: 0,
|
|
525
|
+
onCurrentChange: () => void 0,
|
|
526
|
+
fallback,
|
|
527
|
+
scaleStep: config.scaleStep,
|
|
528
|
+
minScale: config.minScale,
|
|
529
|
+
maxScale: config.maxScale
|
|
530
|
+
}
|
|
531
|
+
)
|
|
532
|
+
] })
|
|
533
|
+
);
|
|
496
534
|
});
|
|
497
535
|
ImageRoot.displayName = "Image";
|
|
536
|
+
function cssLength(value) {
|
|
537
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
538
|
+
}
|
|
498
539
|
const Image2 = Object.assign(ImageRoot, { PreviewGroup: ImagePreviewGroup });
|
|
499
540
|
export {
|
|
500
541
|
Image2 as Image,
|
|
@@ -52,7 +52,7 @@ export type { RangeTimelineProps, RangeTimelineRow } from "./range-timeline.js";
|
|
|
52
52
|
export { ChatBubble, ChatBubbleList } from "./chat-bubble.js";
|
|
53
53
|
export type { ChatBubbleListProp, ChatBubbleListProps, ChatBubblePlacementProp, ChatBubbleProp, ChatBubbleProps, ChatBubbleToneProp, ChatBubbleTypingProp, ChatBubbleVariantProp, ChatMessageProp, } from "./chat-bubble.js";
|
|
54
54
|
export { Tree } from "./tree.js";
|
|
55
|
-
export type { TreeNodeProp, TreeProp, TreeProps } from "./tree.js";
|
|
55
|
+
export type { TreeAllowDropInfoProp, TreeDropInfoProp, TreeDropPositionProp, TreeNodeProp, TreeProp, TreeProps, } from "./tree.js";
|
|
56
56
|
export { OrgChart } from "./org-chart.js";
|
|
57
57
|
export type { OrgChartNodeProp, OrgChartNodeVariantProp, OrgChartProp, OrgChartProps, } from "./org-chart.js";
|
|
58
58
|
export { Welcome } from "./welcome.js";
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import { type LucideIcon } from "lucide-react";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* `done` / `current` / `pending` are a PROCESS: steps behind, the one you are on, steps ahead.
|
|
5
|
+
* `log` is not a step at all — it is an entry in an activity log or history (antd's
|
|
6
|
+
* `<Timeline.Item color="gray">`, GitHub's conversation rail): a neutral dot, a hairline rail and
|
|
7
|
+
* NO screen-reader status prefix, because a thing that merely happened is neither "completed" nor
|
|
8
|
+
* "upcoming" (gh#1092).
|
|
9
|
+
*/
|
|
10
|
+
export type TimelineStatus = "done" | "current" | "pending" | "log";
|
|
4
11
|
export type TimelineVariant = "icon" | "ordinal" | "status";
|
|
5
12
|
/**
|
|
6
13
|
* A Timeline-local subset of the density vocabulary — it has no `comfortable` step, the same shape
|
|
@@ -14,7 +21,10 @@ export type TimelineItem = {
|
|
|
14
21
|
note?: ReactNode;
|
|
15
22
|
/** Shorthand for `status: "current"`. `status` wins when both are set. */
|
|
16
23
|
current?: boolean;
|
|
17
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Explicit status. Resolves as `status ?? (current ? "current" : "done")`. Use `log` for an
|
|
26
|
+
* activity-log / history row: neutral look, no "Completed:"/"Upcoming:" prefix.
|
|
27
|
+
*/
|
|
18
28
|
status?: TimelineStatus;
|
|
19
29
|
/** Per-item glyph override; wins over the variant/status auto-glyph. */
|
|
20
30
|
icon?: LucideIcon;
|