@godxjp/ui 20.2.1 → 22.0.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 (141) hide show
  1. package/dist/app/app-provider.js +2 -1
  2. package/dist/components/data-display/badge.d.ts +28 -1
  3. package/dist/components/data-display/badge.js +2 -0
  4. package/dist/components/data-display/chat-bubble.d.ts +30 -0
  5. package/dist/components/data-display/chat-bubble.js +229 -0
  6. package/dist/components/data-display/data-table.d.ts +18 -2
  7. package/dist/components/data-display/data-table.js +4 -0
  8. package/dist/components/data-display/descriptions.js +4 -1
  9. package/dist/components/data-display/index.d.ts +5 -3
  10. package/dist/components/data-display/index.js +5 -2
  11. package/dist/components/data-display/popover.d.ts +19 -1
  12. package/dist/components/data-display/popover.js +12 -3
  13. package/dist/components/data-display/progress.d.ts +37 -0
  14. package/dist/components/data-display/progress.js +57 -5
  15. package/dist/components/data-display/scroll-area.js +26 -1
  16. package/dist/components/data-display/tree.d.ts +8 -0
  17. package/dist/components/data-display/tree.js +426 -0
  18. package/dist/components/data-entry/chat-composer.d.ts +50 -0
  19. package/dist/components/data-entry/chat-composer.js +163 -0
  20. package/dist/components/data-entry/chat-suggestion.d.ts +28 -0
  21. package/dist/components/data-entry/chat-suggestion.js +285 -0
  22. package/dist/components/data-entry/date-picker.d.ts +10 -3
  23. package/dist/components/data-entry/date-picker.js +503 -238
  24. package/dist/components/data-entry/form-field.d.ts +1 -1
  25. package/dist/components/data-entry/form-field.js +4 -1
  26. package/dist/components/data-entry/form.js +10 -1
  27. package/dist/components/data-entry/index.d.ts +4 -6
  28. package/dist/components/data-entry/index.js +4 -6
  29. package/dist/components/data-entry/label.d.ts +14 -1
  30. package/dist/components/data-entry/label.js +6 -1
  31. package/dist/components/data-entry/radio.d.ts +27 -6
  32. package/dist/components/data-entry/radio.js +88 -43
  33. package/dist/components/data-entry/search-select.js +8 -1
  34. package/dist/components/data-entry/select.js +2 -0
  35. package/dist/components/data-entry/switch.d.ts +6 -3
  36. package/dist/components/data-entry/switch.js +34 -11
  37. package/dist/components/data-entry/textarea.js +3 -1
  38. package/dist/components/data-entry/tree-utils.d.ts +10 -48
  39. package/dist/components/data-entry/tree-utils.js +1 -154
  40. package/dist/components/layout/mobile-shell.d.ts +1 -1
  41. package/dist/components/layout/mobile-shell.js +2 -0
  42. package/dist/components/navigation/menubar.d.ts +10 -3
  43. package/dist/components/navigation/steps.d.ts +1 -1
  44. package/dist/components/navigation/steps.js +3 -1
  45. package/dist/components/navigation/tabs-scroll.d.ts +27 -0
  46. package/dist/components/navigation/tabs-scroll.js +52 -1
  47. package/dist/components/navigation/tabs.d.ts +2 -2
  48. package/dist/components/navigation/tabs.js +88 -23
  49. package/dist/components/ui/index.d.ts +0 -1
  50. package/dist/components/ui/index.js +0 -1
  51. package/dist/components/ui/segmented.d.ts +15 -1
  52. package/dist/components/ui/segmented.js +13 -6
  53. package/dist/i18n/messages/en.json +48 -2
  54. package/dist/i18n/messages/ja.json +46 -2
  55. package/dist/i18n/messages/vi.json +47 -2
  56. package/dist/lib/datetime/picker-format.d.ts +18 -0
  57. package/dist/lib/datetime/picker-format.js +35 -1
  58. package/dist/lib/field-a11y.d.ts +12 -0
  59. package/dist/lib/field-a11y.js +14 -1
  60. package/dist/lib/tree.d.ts +53 -0
  61. package/dist/lib/tree.js +155 -0
  62. package/dist/props/components/data-display.prop.d.ts +194 -1
  63. package/dist/props/components/data-entry.prop.d.ts +307 -99
  64. package/dist/props/components/index.d.ts +1 -1
  65. package/dist/props/components/layout.prop.d.ts +12 -1
  66. package/dist/props/components/navigation.prop.d.ts +76 -1
  67. package/dist/props/registry.d.ts +156 -19
  68. package/dist/props/registry.js +218 -18
  69. package/dist/props/vocabulary/data.prop.d.ts +12 -0
  70. package/dist/props/vocabulary/index.d.ts +2 -2
  71. package/dist/props/vocabulary/layout.prop.d.ts +11 -0
  72. package/dist/styles/badge-layout.css +4 -0
  73. package/dist/styles/card-layout.css +6 -6
  74. package/dist/styles/control.css +22 -6
  75. package/dist/styles/data-display-layout.css +385 -68
  76. package/dist/styles/data-entry-layout.css +64 -0
  77. package/dist/styles/focus-ring.css +4 -2
  78. package/dist/styles/navigation-layout.css +25 -0
  79. package/dist/styles/shell-layout.css +7 -1
  80. package/dist/styles/table-layout.css +34 -0
  81. package/dist/tokens/base.css +3 -0
  82. package/dist/tokens/components/chat-bubble.css +36 -0
  83. package/dist/tokens/components/chat-composer.css +19 -0
  84. package/dist/tokens/components/data-display.css +9 -6
  85. package/dist/tokens/components/descriptions.css +4 -0
  86. package/dist/tokens/components/navigation.css +6 -0
  87. package/dist/tokens/components/segmented.css +0 -2
  88. package/dist/tokens/components/shell.css +3 -0
  89. package/dist/tokens/components/table.css +3 -0
  90. package/dist/tokens/components/tree.css +27 -0
  91. package/dist/tokens/foundation.css +7 -0
  92. package/docs/COMPONENTS.md +14 -14
  93. package/docs/CONSUMER-RULES.md +24 -1
  94. package/docs/FRAME-COVERAGE-LEDGER.md +1 -1
  95. package/docs/FRAME-COVERAGE-REPORT.md +9 -7
  96. package/docs/TOKENS.md +65 -0
  97. package/docs/data-display/badge.tsx +37 -0
  98. package/docs/data-display/chat-bubble.tsx +397 -0
  99. package/docs/data-display/data-table/index.tsx +18 -0
  100. package/docs/data-display/popover.tsx +41 -1
  101. package/docs/data-display/progress.tsx +28 -0
  102. package/docs/data-display/timeline.tsx +46 -0
  103. package/docs/data-display/tree.tsx +394 -0
  104. package/docs/data-entry/calendar.tsx +2 -2
  105. package/docs/data-entry/chat-composer.tsx +464 -0
  106. package/docs/data-entry/chat-suggestion.tsx +301 -0
  107. package/docs/data-entry/date-picker.tsx +143 -3
  108. package/docs/data-entry/form/examples/invoice-form.tsx +2 -2
  109. package/docs/data-entry/form-field/examples/a11y-contract.tsx +3 -5
  110. package/docs/data-entry/form.tsx +4 -4
  111. package/docs/data-entry/number-input.tsx +31 -0
  112. package/docs/data-entry/segmented.tsx +103 -1
  113. package/docs/layout/mobile-shell.tsx +5 -0
  114. package/docs/navigation/tabs.tsx +149 -0
  115. package/docs/roadmap/ai-chat-components.md +207 -0
  116. package/docs/roadmap/antd-parity.md +155 -0
  117. package/docs/roadmap/badge-tag-chip-count.md +172 -0
  118. package/docs/roadmap/list-masonry.md +159 -0
  119. package/docs/roadmap/parity-audit-data-display-feedback.md +567 -0
  120. package/docs/roadmap/parity-audit-data-entry.md +357 -0
  121. package/docs/roadmap/parity-audit-layout-navigation-general.md +464 -0
  122. package/docs/roadmap/parity-backlog.md +78 -0
  123. package/docs/roadmap/tree-components.md +151 -0
  124. package/docs/showcase/acme-portal.tsx +7 -0
  125. package/docs/showcase/table-tree-rows.tsx +4 -4
  126. package/package.json +13 -23
  127. package/scripts/ui-audit.mjs +17 -4
  128. package/dist/components/data-display/tree-list.d.ts +0 -13
  129. package/dist/components/data-display/tree-list.js +0 -26
  130. package/dist/components/data-entry/date-range-picker.d.ts +0 -11
  131. package/dist/components/data-entry/date-range-picker.js +0 -349
  132. package/dist/components/data-entry/month-picker.d.ts +0 -10
  133. package/dist/components/data-entry/month-picker.js +0 -241
  134. package/dist/components/data-entry/month-range-picker.d.ts +0 -10
  135. package/dist/components/data-entry/month-range-picker.js +0 -301
  136. package/dist/components/ui/date-range-picker.d.ts +0 -1
  137. package/dist/components/ui/date-range-picker.js +0 -2
  138. package/docs/data-display/tree-list.tsx +0 -107
  139. package/docs/data-entry/date-range-picker.tsx +0 -175
  140. package/docs/data-entry/month-picker.tsx +0 -101
  141. package/docs/data-entry/month-range-picker.tsx +0 -115
@@ -0,0 +1,394 @@
1
+ import * as React from "react";
2
+ import {
3
+ Badge,
4
+ Card,
5
+ CardContent,
6
+ CardDescription,
7
+ CardHeader,
8
+ CardTitle,
9
+ Descriptions,
10
+ EmptyState,
11
+ ScrollArea,
12
+ Tree,
13
+ type TreeNodeProp,
14
+ } from "@godxjp/ui/data-display";
15
+ import { Text } from "@godxjp/ui/general";
16
+ import { Flex, PageContainer, Separator } from "@godxjp/ui/layout";
17
+ import { Building2, FolderTree, ShieldCheck } from "lucide-react";
18
+
19
+ /**
20
+ * Tree — the standalone WAI-ARIA "Tree View" on a page.
21
+ *
22
+ * The screen is a real one: an access-control settings page whose left column is the permission
23
+ * tree the administrator ticks, and whose right column reads back exactly what that means. Every
24
+ * card below is an independent pattern with its own data and its own state, and every prop the
25
+ * component declares is exercised somewhere on the page, at rest, without clicking.
26
+ */
27
+
28
+ // ── card 1 · the permission tree ────────────────────────────────────────────────────────────
29
+ const permissions: TreeNodeProp[] = [
30
+ {
31
+ value: "billing",
32
+ label: "請求管理",
33
+ children: [
34
+ { value: "billing.invoice.read", label: "請求書を閲覧" },
35
+ { value: "billing.invoice.write", label: "請求書を発行" },
36
+ { value: "billing.refund", label: "返金を実行", disableCheckbox: true },
37
+ ],
38
+ },
39
+ {
40
+ value: "people",
41
+ label: "人事",
42
+ children: [
43
+ { value: "people.read", label: "プロフィールを閲覧" },
44
+ { value: "people.write", label: "プロフィールを編集" },
45
+ {
46
+ value: "people.payroll",
47
+ label: "給与",
48
+ children: [
49
+ { value: "people.payroll.read", label: "給与明細を閲覧" },
50
+ { value: "people.payroll.approve", label: "給与を承認", disabled: true },
51
+ ],
52
+ },
53
+ ],
54
+ },
55
+ { value: "audit", label: "監査ログ", isLeaf: true },
56
+ ];
57
+
58
+ const permissionLabels = new Map<string, string>([
59
+ ["billing", "請求管理"],
60
+ ["billing.invoice.read", "請求書を閲覧"],
61
+ ["billing.invoice.write", "請求書を発行"],
62
+ ["billing.refund", "返金を実行"],
63
+ ["people", "人事"],
64
+ ["people.read", "プロフィールを閲覧"],
65
+ ["people.write", "プロフィールを編集"],
66
+ ["people.payroll", "給与"],
67
+ ["people.payroll.read", "給与明細を閲覧"],
68
+ ["people.payroll.approve", "給与を承認"],
69
+ ["audit", "監査ログ"],
70
+ ]);
71
+
72
+ // ── card 2 · the directory browser ──────────────────────────────────────────────────────────
73
+ const repository: TreeNodeProp[] = [
74
+ {
75
+ value: "src",
76
+ label: "src",
77
+ children: [
78
+ {
79
+ value: "src/components",
80
+ label: "components",
81
+ children: [
82
+ { value: "src/components/tree.tsx", label: "tree.tsx", isLeaf: true },
83
+ { value: "src/components/tree-list.tsx", label: "tree-list.tsx", isLeaf: true },
84
+ ],
85
+ },
86
+ { value: "src/index.ts", label: "index.ts", isLeaf: true },
87
+ ],
88
+ },
89
+ {
90
+ value: "docs",
91
+ label: "docs",
92
+ children: [{ value: "docs/tree.mdx", label: "tree.mdx", isLeaf: true }],
93
+ },
94
+ ];
95
+
96
+ const fileDetails: Record<string, { size: string; changed: string }> = {
97
+ "src/components/tree.tsx": { size: "18.4 KB", changed: "2026-09-10" },
98
+ "src/components/tree-list.tsx": { size: "1.2 KB", changed: "2025-11-02" },
99
+ "src/index.ts": { size: "0.9 KB", changed: "2026-08-21" },
100
+ "docs/tree.mdx": { size: "4.1 KB", changed: "2026-09-10" },
101
+ };
102
+
103
+ // ── card 3 · async branches (fieldNames + loadData + titleRender) ────────────────────────────
104
+ type Department = { id: string; name: string; leaf?: boolean; units?: Department[] };
105
+
106
+ const initialDepartments: Department[] = [
107
+ { id: "jp", name: "日本法人" },
108
+ { id: "vn", name: "ベトナム法人" },
109
+ { id: "sg", name: "シンガポール支店", leaf: true },
110
+ ];
111
+
112
+ const departmentChildren: Record<string, Department[]> = {
113
+ jp: [
114
+ { id: "jp-sales", name: "営業部", leaf: true },
115
+ { id: "jp-dev", name: "開発部", leaf: true },
116
+ ],
117
+ vn: [{ id: "vn-dev", name: "開発センター", leaf: true }],
118
+ };
119
+
120
+ function attachChildren(nodes: Department[], id: string, children: Department[]): Department[] {
121
+ return nodes.map((node) =>
122
+ node.id === id
123
+ ? { ...node, units: children }
124
+ : { ...node, units: node.units ? attachChildren(node.units, id, children) : undefined },
125
+ );
126
+ }
127
+
128
+ export default function Demo() {
129
+ // Card 1 — checks are controlled so the readout beside the tree can never disagree with it.
130
+ const [granted, setGranted] = React.useState<string[]>(["billing.invoice.read"]);
131
+ // Card 2 — selection is controlled and drives the detail pane.
132
+ const [openFile, setOpenFile] = React.useState<string | undefined>("src/components/tree.tsx");
133
+ // Card 3 — async children land in state, exactly as a real fetch would.
134
+ const [departments, setDepartments] = React.useState<Department[]>(initialDepartments);
135
+ // Card 5 — independent (strict) checks, and a multi-select tree.
136
+ const [strictChecks, setStrictChecks] = React.useState<string[]>(["people", "people.read"]);
137
+ const [picked, setPicked] = React.useState<string[]>(["billing", "audit"]);
138
+
139
+ const loadDepartment = async (node: TreeNodeProp) => {
140
+ // A real delay, so the Skeleton row and aria-busy are OBSERVABLE rather than theoretical.
141
+ await new Promise((resolve) => setTimeout(resolve, 1200));
142
+ const children = departmentChildren[node.value] ?? [];
143
+ setDepartments((current) => attachChildren(current, node.value, children));
144
+ };
145
+
146
+ return (
147
+ <PageContainer
148
+ title="Tree"
149
+ subtitle="アクセス権限の設定 · 展開・折りたたみ・キーボード操作のある階層はすべて Tree"
150
+ >
151
+ <Flex direction="col" gap="lg">
152
+ <Card>
153
+ <CardHeader>
154
+ <CardTitle level={2}>権限ツリー(checkable · 三状態)</CardTitle>
155
+ <CardDescription>
156
+ 親をチェックすると配下すべてが入り、一部だけのときは親がダッシュ(indeterminate)
157
+ になります。「返金を実行」は disableCheckbox(チェックだけ不可)、「給与を承認」は
158
+ disabled。どちらも親の分母に入らないため、残りを全部入れれば親はチェック済みになります。
159
+ showLine で接続線、defaultExpandAll で最初から全展開。
160
+ </CardDescription>
161
+ </CardHeader>
162
+ <CardContent>
163
+ <Flex gap="lg" wrap>
164
+ <Tree
165
+ aria-label="権限ツリー"
166
+ treeData={permissions}
167
+ checkable
168
+ showLine
169
+ defaultExpandAll
170
+ checkedValues={granted}
171
+ onCheckedValuesChange={setGranted}
172
+ />
173
+ <Separator orientation="vertical" />
174
+ <Flex direction="col" gap="sm">
175
+ <Text size="sm" tone="muted">
176
+ 付与された権限({granted.length} 件)
177
+ </Text>
178
+ {granted.length === 0 ? (
179
+ <EmptyState
180
+ icon={ShieldCheck}
181
+ title="権限がありません"
182
+ description="ツリーから付与する権限を選んでください。"
183
+ />
184
+ ) : (
185
+ <Flex gap="xs" wrap>
186
+ {granted.map((value) => (
187
+ <Badge key={value} variant="secondary">
188
+ {permissionLabels.get(value) ?? value}
189
+ </Badge>
190
+ ))}
191
+ </Flex>
192
+ )}
193
+ </Flex>
194
+ </Flex>
195
+ </CardContent>
196
+ </Card>
197
+
198
+ <Card>
199
+ <CardHeader>
200
+ <CardTitle level={2}>ファイルブラウザ(variant=&quot;directory&quot;)</CardTitle>
201
+ <CardDescription>
202
+ DirectoryTree 相当。showIcon でフォルダ/ファイルのグリフが出て、選択行は行全体が帯に
203
+ なります。選択は value / onValueChange
204
+ の制御コンポーネントで、右の詳細と常に一致します。 長いツリーは ScrollArea
205
+ で高さを止めます(v1 に仮想スクロールはありません)。
206
+ </CardDescription>
207
+ </CardHeader>
208
+ <CardContent>
209
+ <Flex gap="lg" wrap>
210
+ <ScrollArea className="max-h-64 w-72">
211
+ <Tree
212
+ aria-label="リポジトリ"
213
+ variant="directory"
214
+ showIcon
215
+ treeData={repository}
216
+ defaultExpandedValues={["src", "src/components"]}
217
+ value={openFile}
218
+ onValueChange={(next) => setOpenFile(next as string | undefined)}
219
+ />
220
+ </ScrollArea>
221
+ <Flex direction="col" gap="sm">
222
+ {openFile && fileDetails[openFile] ? (
223
+ <Descriptions
224
+ items={[
225
+ { label: "パス", children: openFile },
226
+ { label: "サイズ", children: fileDetails[openFile].size },
227
+ { label: "最終更新", children: fileDetails[openFile].changed },
228
+ ]}
229
+ />
230
+ ) : (
231
+ <EmptyState
232
+ icon={FolderTree}
233
+ title="ファイルが選択されていません"
234
+ description="ツリーからファイルを選ぶと詳細が出ます。"
235
+ />
236
+ )}
237
+ </Flex>
238
+ </Flex>
239
+ </CardContent>
240
+ </Card>
241
+
242
+ <Card>
243
+ <CardHeader>
244
+ <CardTitle level={2}>組織ツリー(loadData · fieldNames · titleRender)</CardTitle>
245
+ <CardDescription>
246
+ API のキーが id / name / units でも fieldNames で読み替えるだけ。子を持たない枝は
247
+ isLeaf: false 扱いで、初回展開時に loadData が一度だけ走り、その間は Skeleton 行と
248
+ aria-busy が出ます(1.2 秒の実待ち)。titleRender で行の見た目を差し替えています。
249
+ </CardDescription>
250
+ </CardHeader>
251
+ <CardContent>
252
+ <Tree
253
+ aria-label="組織ツリー"
254
+ size="lg"
255
+ showIcon
256
+ treeData={
257
+ departments.map((node) => ({
258
+ ...node,
259
+ isLeaf: node.leaf ?? false,
260
+ icon: <Building2 />,
261
+ })) as unknown as TreeNodeProp[]
262
+ }
263
+ fieldNames={{ label: "name", value: "id", children: "units" }}
264
+ loadData={loadDepartment}
265
+ titleRender={(node) => (
266
+ <Text size="sm" weight="medium">
267
+ {node.label}
268
+ </Text>
269
+ )}
270
+ />
271
+ </CardContent>
272
+ </Card>
273
+
274
+ <Card>
275
+ <CardHeader>
276
+ <CardTitle level={2}>checkStrictly と multiple(チェックと選択は別の軸)</CardTitle>
277
+ <CardDescription>
278
+ 左は checkStrictly:親と子のチェックは独立で、カスケードも indeterminate
279
+ もありません。 右は multiple の選択(チェックボックスなし)。ひとつの Tree で value と
280
+ checkedValues が別々に動くことが分かるよう、読み出しを両方出しています。
281
+ </CardDescription>
282
+ </CardHeader>
283
+ <CardContent>
284
+ <Flex gap="lg" wrap>
285
+ <Flex direction="col" gap="sm">
286
+ <Text size="sm" tone="muted">
287
+ checkStrictly · チェック: {strictChecks.length} 件
288
+ </Text>
289
+ <Tree
290
+ aria-label="権限ツリー(独立チェック)"
291
+ treeData={permissions}
292
+ checkable
293
+ checkStrictly
294
+ defaultExpandedValues={["people"]}
295
+ checkedValues={strictChecks}
296
+ onCheckedValuesChange={setStrictChecks}
297
+ />
298
+ </Flex>
299
+ <Separator orientation="vertical" />
300
+ <Flex direction="col" gap="sm">
301
+ <Text size="sm" tone="muted">
302
+ multiple · 選択:{" "}
303
+ {picked.map((value) => permissionLabels.get(value) ?? value).join(" / ")}
304
+ </Text>
305
+ <Tree
306
+ aria-label="権限ツリー(複数選択)"
307
+ treeData={permissions}
308
+ multiple
309
+ defaultExpandAll
310
+ value={picked}
311
+ onValueChange={(next) => setPicked((next ?? []) as string[])}
312
+ />
313
+ </Flex>
314
+ </Flex>
315
+ </CardContent>
316
+ </Card>
317
+
318
+ <Card>
319
+ <CardHeader>
320
+ <CardTitle level={2}>size の全段階 · disabled · 空</CardTitle>
321
+ <CardDescription>
322
+ 行の高さは --control-height の段(xs / sm / md / lg)から来るので、同じ行に並ぶ他の
323
+ コントロールと常に揃います。disabled
324
+ はツリー全体を固め(読めるまま、開閉も選択も不可)、 treeData が空なら
325
+ role=&quot;status&quot; の空メッセージが出ます。
326
+ </CardDescription>
327
+ </CardHeader>
328
+ <CardContent>
329
+ <Flex gap="lg" wrap>
330
+ {(["xs", "sm", "md", "lg"] as const).map((step) => (
331
+ <Flex key={step} direction="col" gap="xs">
332
+ <Text size="sm" tone="muted">
333
+ size=&quot;{step}&quot;
334
+ </Text>
335
+ <Tree
336
+ aria-label={`サイズ ${step}`}
337
+ size={step}
338
+ treeData={repository}
339
+ defaultExpandedValues={["src"]}
340
+ />
341
+ </Flex>
342
+ ))}
343
+ <Flex direction="col" gap="xs">
344
+ <Text size="sm" tone="muted">
345
+ disabled
346
+ </Text>
347
+ <Tree
348
+ aria-label="読み取り専用ツリー"
349
+ disabled
350
+ treeData={repository}
351
+ defaultExpandAll
352
+ defaultValue="src/index.ts"
353
+ />
354
+ </Flex>
355
+ <Flex direction="col" gap="xs">
356
+ <Text size="sm" tone="muted">
357
+
358
+ </Text>
359
+ <Tree aria-label="空のツリー" treeData={[]} />
360
+ </Flex>
361
+ </Flex>
362
+ </CardContent>
363
+ </Card>
364
+
365
+ <Card>
366
+ <CardHeader>
367
+ <CardTitle level={2}>キーボード(WAI-ARIA APG)</CardTitle>
368
+ <CardDescription>
369
+ ツリーに Tab で入るとタブストップはひとつだけ(roving
370
+ tabindex)。あとは矢印で歩けます。 dir=&quot;rtl&quot; では → と ←
371
+ の意味が入れ替わり、インデントも反転します。
372
+ </CardDescription>
373
+ </CardHeader>
374
+ <CardContent>
375
+ <Descriptions
376
+ items={[
377
+ { label: "↓ / ↑", children: "表示されている次/前のノードへ" },
378
+ { label: "→", children: "閉じた枝を開く。開いていれば最初の子へ" },
379
+ { label: "←", children: "開いた枝を閉じる。閉じていれば親へ" },
380
+ { label: "Home / End", children: "表示されている最初/最後のノードへ" },
381
+ {
382
+ label: "Enter / Space",
383
+ children: "選択(checkable のときはチェックを切り替え)",
384
+ },
385
+ { label: "*", children: "同じ階層の兄弟をすべて展開" },
386
+ { label: "文字キー", children: "先頭一致で次のノードへジャンプ(type-ahead)" },
387
+ ]}
388
+ />
389
+ </CardContent>
390
+ </Card>
391
+ </Flex>
392
+ </PageContainer>
393
+ );
394
+ }
@@ -20,7 +20,7 @@ import type { DateRange } from "react-day-picker";
20
20
  /**
21
21
  * Calendar — styled react-day-picker grid for single, multiple, or range
22
22
  * selection. Embed inside a Popover for picker UX; use DatePicker /
23
- * DateRangePicker for form-submittable inputs instead. Composed only from
23
+ * `DatePicker range` for form-submittable inputs instead. Composed only from
24
24
  * real @godxjp/ui components.
25
25
  */
26
26
  export default function Demo() {
@@ -71,7 +71,7 @@ export default function Demo() {
71
71
  <CardHeader>
72
72
  <CardTitle level={2}>範囲選択 · Popover 内</CardTitle>
73
73
  <CardDescription>
74
- mode="range" でポップオーバー内に配置。DateRangePicker
74
+ mode="range" でポップオーバー内に配置。DatePicker range
75
75
  はこのパターンにフォーム送信を加えた上位コンポーネント。
76
76
  </CardDescription>
77
77
  </CardHeader>