@godxjp/ui 19.2.0 → 19.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 (144) hide show
  1. package/dist/components/data-display/badge.d.ts +26 -2
  2. package/dist/components/data-display/badge.js +20 -5
  3. package/dist/components/data-display/index.d.ts +2 -0
  4. package/dist/components/data-display/index.js +2 -0
  5. package/dist/components/data-display/popover.d.ts +13 -1
  6. package/dist/components/data-display/popover.js +3 -1
  7. package/dist/components/data-display/table.d.ts +19 -2
  8. package/dist/components/data-display/table.js +4 -1
  9. package/dist/components/data-display/timeline-grid.d.ts +18 -0
  10. package/dist/components/data-display/timeline-grid.js +222 -0
  11. package/dist/components/data-entry/cascader.js +4 -6
  12. package/dist/components/data-entry/checkbox.js +1 -1
  13. package/dist/components/data-entry/search-select.js +5 -7
  14. package/dist/components/data-entry/select.js +32 -28
  15. package/dist/components/data-entry/tree-select.js +4 -6
  16. package/dist/components/general/inert-background.d.ts +5 -0
  17. package/dist/components/general/inert-background.js +48 -0
  18. package/dist/components/layout/auth-shell.d.ts +4 -2
  19. package/dist/components/layout/auth-shell.js +7 -1
  20. package/dist/components/layout/centered-shell.d.ts +2 -2
  21. package/dist/components/layout/flex.d.ts +1 -1
  22. package/dist/components/layout/flex.js +2 -1
  23. package/dist/components/layout/index.d.ts +3 -0
  24. package/dist/components/layout/index.js +2 -0
  25. package/dist/components/layout/mobile-shell.d.ts +21 -0
  26. package/dist/components/layout/mobile-shell.js +43 -0
  27. package/dist/components/layout/sidebar-link.d.ts +1 -1
  28. package/dist/components/navigation/context-menu.js +13 -9
  29. package/dist/components/navigation/dropdown-menu.js +17 -13
  30. package/dist/inertia/index.d.ts +1 -1
  31. package/dist/lib/variants.d.ts +3 -3
  32. package/dist/lib/variants.js +1 -0
  33. package/dist/props/components/data-display.prop.d.ts +72 -0
  34. package/dist/props/components/data-entry.prop.d.ts +1 -1
  35. package/dist/props/components/layout.prop.d.ts +93 -6
  36. package/dist/props/registry.d.ts +113 -2
  37. package/dist/props/registry.js +155 -1
  38. package/dist/props/vocabulary/data.prop.d.ts +6 -0
  39. package/dist/props/vocabulary/index.d.ts +3 -3
  40. package/dist/props/vocabulary/layout.prop.d.ts +17 -2
  41. package/dist/props/vocabulary/shared.prop.d.ts +7 -0
  42. package/dist/styles/badge-layout.css +15 -0
  43. package/dist/styles/control.css +18 -1
  44. package/dist/styles/data-display-layout.css +167 -0
  45. package/dist/styles/layout.css +7 -0
  46. package/dist/styles/shell-layout.css +148 -0
  47. package/dist/styles/table-layout.css +23 -4
  48. package/dist/tokens/components/badge.css +8 -0
  49. package/dist/tokens/components/control.css +1 -0
  50. package/dist/tokens/components/data-display.css +20 -0
  51. package/dist/tokens/components/shell.css +22 -0
  52. package/dist/tokens/components/table.css +2 -0
  53. package/docs/SPACING.md +19 -6
  54. package/docs/charts/compact-bar-trend.tsx +5 -6
  55. package/docs/data-display/avatar.tsx +7 -9
  56. package/docs/data-display/badge.tsx +37 -1
  57. package/docs/data-display/card/index.tsx +6 -4
  58. package/docs/data-display/carousel.tsx +8 -4
  59. package/docs/data-display/data-table/examples/approval-queue.tsx +1 -1
  60. package/docs/data-display/data-table/examples/grid-features.tsx +1 -1
  61. package/docs/data-display/data-table/index.tsx +1 -1
  62. package/docs/data-display/permission-matrix.tsx +15 -11
  63. package/docs/data-display/popover.tsx +2 -1
  64. package/docs/data-display/scroll-area.tsx +108 -76
  65. package/docs/data-display/table.tsx +2 -2
  66. package/docs/data-display/timeline-grid.tsx +119 -0
  67. package/docs/data-entry/branch-scope-picker.tsx +1 -1
  68. package/docs/data-entry/calendar.tsx +1 -1
  69. package/docs/data-entry/checkbox.tsx +1 -1
  70. package/docs/data-entry/country-picker-recipe.tsx +11 -6
  71. package/docs/data-entry/form-field/index.tsx +33 -29
  72. package/docs/data-entry/form-root.tsx +1 -1
  73. package/docs/data-entry/input-otp.tsx +1 -1
  74. package/docs/data-entry/password-input.tsx +1 -5
  75. package/docs/data-entry/select.tsx +7 -7
  76. package/docs/data-entry/textarea.tsx +3 -3
  77. package/docs/data-entry/toggle-count.tsx +1 -1
  78. package/docs/feedback/alert.tsx +1 -1
  79. package/docs/feedback/banner.tsx +1 -1
  80. package/docs/feedback/sheet.tsx +112 -102
  81. package/docs/feedback/skeleton.tsx +2 -2
  82. package/docs/foundation/colors.tsx +8 -6
  83. package/docs/foundation/email-tokens.tsx +83 -66
  84. package/docs/foundation/radius-shadow.tsx +13 -11
  85. package/docs/general/activity.tsx +1 -1
  86. package/docs/layout/app-shell.tsx +2 -2
  87. package/docs/layout/aspect-ratio.tsx +30 -14
  88. package/docs/layout/auth-account-summary.tsx +1 -1
  89. package/docs/layout/auth-recovery/examples/mobile-390.tsx +1 -1
  90. package/docs/layout/auth-recovery/examples/password-recovery.tsx +0 -2
  91. package/docs/layout/auth-shell-context.tsx +1 -1
  92. package/docs/layout/auth-shell-device.tsx +2 -2
  93. package/docs/layout/auth-shell-registration.tsx +1 -1
  94. package/docs/layout/auth-shell.tsx +1 -1
  95. package/docs/layout/flex.tsx +6 -2
  96. package/docs/layout/master-detail.tsx +2 -2
  97. package/docs/layout/mobile-shell.tsx +101 -0
  98. package/docs/layout/page-container.tsx +15 -7
  99. package/docs/layout/responsive-grid.tsx +12 -4
  100. package/docs/layout/separator.tsx +2 -2
  101. package/docs/layout/service-role-panel.tsx +1 -1
  102. package/docs/layout/sidebar.tsx +175 -152
  103. package/docs/layout/split-pane.tsx +45 -28
  104. package/docs/layout/topbar.tsx +19 -23
  105. package/docs/navigation/app-setting-picker.tsx +5 -4
  106. package/docs/navigation/breadcrumb.tsx +12 -5
  107. package/docs/navigation/context-menu.tsx +10 -4
  108. package/docs/navigation/filter-bar.tsx +2 -2
  109. package/docs/navigation/navigation-menu.tsx +89 -96
  110. package/docs/navigation/pagination.tsx +2 -2
  111. package/docs/navigation/steps.tsx +13 -11
  112. package/docs/navigation/tabs.tsx +27 -21
  113. package/docs/navigation/toolbar.tsx +15 -15
  114. package/docs/providers/format-date.tsx +2 -2
  115. package/docs/showcase/acme-portal.tsx +41 -28
  116. package/docs/showcase/acme-website.tsx +67 -61
  117. package/docs/showcase/case1-warehouse-dashboard.tsx +46 -31
  118. package/docs/showcase/case2-employee-me.tsx +33 -36
  119. package/docs/showcase/case3-approval-workflow.tsx +34 -32
  120. package/docs/showcase/case4-login.tsx +95 -101
  121. package/docs/showcase/case5-shift-calendar.tsx +182 -281
  122. package/docs/showcase/case6-agency-handy.tsx +514 -470
  123. package/docs/showcase/futurelastic-web.tsx +32 -29
  124. package/docs/showcase/org-switcher.tsx +20 -13
  125. package/docs/showcase/permission-matrix.tsx +20 -17
  126. package/docs/showcase/public-landing.tsx +1 -1
  127. package/docs/showcase/settings-account-sections.tsx +2 -2
  128. package/docs/showcase/settings-security-mfa.tsx +3 -3
  129. package/docs/showcase/table-approval-queue.tsx +1 -1
  130. package/docs/showcase/table-bulk-actions.tsx +49 -52
  131. package/docs/showcase/table-conditional-format.tsx +9 -9
  132. package/docs/showcase/table-crud-list.tsx +4 -4
  133. package/docs/showcase/table-density.tsx +49 -42
  134. package/docs/showcase/table-expandable-rows.tsx +112 -100
  135. package/docs/showcase/table-filter-chips.tsx +78 -71
  136. package/docs/showcase/table-footer-totals.tsx +30 -23
  137. package/docs/showcase/table-grouped-subtotals.tsx +31 -25
  138. package/docs/showcase/table-master-detail.tsx +27 -24
  139. package/docs/showcase/table-pagination.tsx +34 -27
  140. package/docs/showcase/table-states.tsx +42 -34
  141. package/docs/showcase/table-sticky-columns.tsx +11 -7
  142. package/docs/showcase/table-tree-rows.tsx +22 -15
  143. package/docs/showcase/table-view-tabs.tsx +12 -14
  144. package/package.json +7 -7
@@ -47,7 +47,7 @@ const TOOLBAR_CHROME_TOKENS = {
47
47
  } as CSSProperties;
48
48
 
49
49
  /**
50
- * `--page-header-min-block-size-chrome` · クロム帯の「高さ」(gh#331)。文書のヘッダーは中身なりの
50
+ * `--page-header-min-block-size-chrome` · クロム帯の「高さ」。文書のヘッダーは中身なりの
51
51
  * 高さで正しい · 見出しは見出しの高さだからです。クロムは逆で、家具には「ものが中央に収まる帯」が
52
52
  * 要ります。既定は `auto`(=rule #44 の最も静かな状態)なので、このトークンを置くまで DOM も
53
53
  * 見え方も従来どおり · 文書ページはそもそもこの規則に一致しません。
@@ -109,7 +109,7 @@ const journalColumns: ColumnDef<JournalEntry>[] = [
109
109
  * PageContainer · mandatory page shell.
110
110
  * Covers: title/subtitle/status/extra/footer/breadcrumb/linkComponent + variant
111
111
  * default/narrow/flush/ghost + density compact/default/comfortable + PageContainer.Inset.
112
- * The embedded header is the CANONICAL DXS PageHeader (gh#255) — status/meta band included.
112
+ * The embedded header is the CANONICAL DXS PageHeader — status/meta band included.
113
113
  * Each example is standalone (no AppShell) so the variant behaviour is visible in
114
114
  * isolation. Composed only from real @godxjp/ui components.
115
115
  */
@@ -165,7 +165,7 @@ export default function Demo() {
165
165
  </ResponsiveGrid>
166
166
  </PageContainer>
167
167
 
168
- {/* ── 1b. Canonical page-header contract (gh#255) · status/meta band ── */}
168
+ {/* ── 1b. Canonical page-header contract · status/meta band ── */}
169
169
  {/* PageContainer's embedded header IS the DXS PageHeader: breadcrumbs + title +
170
170
  subtitle + status/meta + actions + responsive overflow on ONE renderer. The
171
171
  `status` band shares the title line at --page-header-status-gap and wraps
@@ -405,12 +405,13 @@ export default function Demo() {
405
405
  </Card>
406
406
  </PageContainer>
407
407
 
408
- {/* ── 6. fill · body height behaviour on a tall shell (gh#103) ──
408
+ {/* ── 6. fill · body height behaviour on a tall shell ──
409
409
  Each PageContainer sits in a fixed-height framed box that stands in for the
410
410
  viewport-tall app shell, so the two behaviours are visible side by side. */}
411
411
  <ResponsiveGrid columns={{ sm: 1, md: 2 }}>
412
412
  {/* Default: top-packed. Short content does NOT stretch · the space below is
413
413
  just neutral page background, never a jarring void. */}
414
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
414
415
  <div className="h-80 overflow-auto rounded-md border">
415
416
  <PageContainer title="既定(top-pack)" subtitle="fill なし · 余白は中立な背景">
416
417
  <Card>
@@ -424,6 +425,7 @@ export default function Demo() {
424
425
  </div>
425
426
 
426
427
  {/* fill: body grows to fill the shell; the composer footer pins to the bottom. */}
428
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
427
429
  <div className="h-80 overflow-auto rounded-md border">
428
430
  <PageContainer
429
431
  fill
@@ -450,7 +452,7 @@ export default function Demo() {
450
452
  </div>
451
453
  </ResponsiveGrid>
452
454
 
453
- {/* ── 7. headerLayout · 390px でヘッダー extra をタイトル行に残す (gh#231) ──
455
+ {/* ── 7. headerLayout · 390px でヘッダー extra をタイトル行に残す ──
454
456
  stack (既定) は 640px 未満で extra を subtitle の下の全幅行に落とす。
455
457
  responsive-inline は --page-header-extra-measure (11rem) の測度で
456
458
  title 帯の横に残す。640px 以上では両者は同一。
@@ -503,7 +505,7 @@ export default function Demo() {
503
505
  </PageContainer>
504
506
  </ResponsiveGrid>
505
507
 
506
- {/* ── 8. measure · ヘッダーとボディを 1 つの測度で束ねる (gh#245 / gh#247) ──
508
+ {/* ── 8. measure · ヘッダーとボディを 1 つの測度で束ねる ──
507
509
  measure は variant(クローム)と直交する第 3 の軸。variant="narrow" は
508
510
  .ui-page-body しか絞らないため、ヘッダーのアクションはページ端に取り残される。
509
511
  measure はヘッダーとボディの両方を同じトークン測度で絞るので、extra の終端が
@@ -603,6 +605,7 @@ export default function Demo() {
603
605
  帯の内側(--page-toolbar-pad-block)だけ。 */}
604
606
  <ResponsiveGrid columns={{ sm: 1, md: 2 }}>
605
607
  {/* fill · 帯は固定、トランスクリプトだけがその下でスクロールする(帯の下に潜り込まない)。 */}
608
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
606
609
  <div className="h-80 overflow-auto rounded-md border">
607
610
  <PageContainer
608
611
  fill
@@ -739,6 +742,7 @@ export default function Demo() {
739
742
  footer の上罫線も --page-footer-divider で消せます · 入力欄が自前で枠を持つ Card の
740
743
  場合、全幅の罫線がその真上に重なって 2 本目の線になるためです。既定は「引く」のまま
741
744
  (フォームの保存/取消バーはこの線で本文と分かれる)。 */}
745
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
742
746
  <div className="h-80 overflow-auto rounded-md border">
743
747
  <PageContainer
744
748
  fill
@@ -803,6 +807,7 @@ export default function Demo() {
803
807
  テナントごとの再テーマも効かなくなるためです。帯を塗るなら内側の余白も一緒に
804
808
  (--page-toolbar-pad-block)· 既定の 0 は「透明な帯には内側がない」ことに由来します。 */}
805
809
  <ResponsiveGrid columns={{ sm: 1, md: 2 }}>
810
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
806
811
  <div className="h-80 overflow-auto rounded-md border">
807
812
  <PageContainer
808
813
  fill
@@ -837,6 +842,7 @@ export default function Demo() {
837
842
  </PageContainer>
838
843
  </div>
839
844
 
845
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
840
846
  <div className="h-80 overflow-auto rounded-md border" style={TOOLBAR_CHROME_TOKENS}>
841
847
  <PageContainer
842
848
  fill
@@ -859,7 +865,7 @@ export default function Demo() {
859
865
  {[
860
866
  "帯がカード面に乗り、本文から分離して読めます。",
861
867
  "塗った帯には内側の余白が要るので pad-block も同じテーマで指定します。",
862
- "呼び出し側の bg-card / py-1.5 は不要 · どちらもトークンの仕事です。",
868
+ "呼び出し側で背景色や上下の余白を足す必要はありません · どちらもトークンの仕事です。",
863
869
  ].map((message) => (
864
870
  <Card key={message}>
865
871
  <CardContent>
@@ -881,6 +887,7 @@ export default function Demo() {
881
887
  --app-shell-bar-height にすると帯は 48px に固定され、タイトル列も extra も帯の中心
882
888
  (y=24)に載ります。min なので、より背の高い extra は今までどおり収まります。 */}
883
889
  <ResponsiveGrid columns={{ sm: 1, md: 2 }}>
890
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
884
891
  <div className="h-80 overflow-auto rounded-md border">
885
892
  <PageContainer
886
893
  fill
@@ -911,6 +918,7 @@ export default function Demo() {
911
918
  </PageContainer>
912
919
  </div>
913
920
 
921
+ {/* ui-audit-disable-next-line no-hand-rolled-surface — a bounded viewport so the page-level scroll behaviour is visible in a docs page — a frame around the demo, not product chrome */}
914
922
  <div className="h-80 overflow-auto rounded-md border" style={CHROME_BAND_TOKENS}>
915
923
  <PageContainer
916
924
  fill
@@ -13,7 +13,7 @@ import { Flex, PageContainer, ResponsiveGrid, SplitPane } from "@godxjp/ui/layou
13
13
  * ResponsiveGrid · equal-width multi-column tile grid with automatic responsive
14
14
  * collapse (CSS container queries, not viewport). It OWNS its query container
15
15
  * (container-type: inline-size), so it responds to the width available to the grid
16
- * with no external container-type declaration (gh#165). Direct children are typically
16
+ * with no external container-type declaration. Direct children are typically
17
17
  * StatCard (self-contained bordered card · never wrap in Card/CardContent) or
18
18
  * Card+CardContent for richer tile bodies. columns accepts a number OR breakpoint
19
19
  * object { sm?, md?, lg? } — or use the named `preset` prop (e.g. "pricing-plans") for a
@@ -45,7 +45,7 @@ export default function Demo() {
45
45
  aside={
46
46
  <Flex direction="col" gap="sm">
47
47
  <Text tone="muted">狭いコンテナ(約 20rem)→ sm=1 列</Text>
48
- {/* No wrapping `@container` needed — ResponsiveGrid OWNS its query container (gh#165). */}
48
+ {/* No wrapping `@container` needed — ResponsiveGrid OWNS its query container. */}
49
49
  <ResponsiveGrid columns={4}>
50
50
  <StatCard label="今日の入金" value="¥420,000" />
51
51
  <StatCard label="未処理" value="6 件" />
@@ -78,10 +78,18 @@ export default function Demo() {
78
78
  <CardContent>
79
79
  <Flex direction="col" gap="md">
80
80
  {["max-w-80", "max-w-3xl"].map((width) => (
81
- <div key={width} className={`${width} border p-2`}>
81
+ <div
82
+ key={width}
83
+ className={width}
84
+ style={{ border: "1px solid hsl(var(--border))", padding: "var(--space-2)" }}
85
+ >
82
86
  <ResponsiveGrid columns={4}>
83
87
  {Array.from({ length: 4 }, (_, index) => (
84
- <div key={index} className="bg-muted rounded p-3 text-center">
88
+ <div
89
+ key={index}
90
+ className="bg-muted rounded text-center"
91
+ style={{ padding: "var(--space-3)" }}
92
+ >
85
93
  {index + 1}
86
94
  </div>
87
95
  ))}
@@ -19,7 +19,7 @@ import { Flex, PageContainer, Separator } from "@godxjp/ui/layout";
19
19
  * defaults to true · set false only when the divider carries semantic meaning for
20
20
  * a11y.
21
21
  *
22
- * gh#308 — `label` INTERRUPTS the rule: a message stream's day divider, a "new messages"
22
+ * `label` INTERRUPTS the rule: a message stream's day divider, a "new messages"
23
23
  * watermark, an auth conjunction. A labelled rule flips `decorative` to false, so it is a real
24
24
  * role="separator" NAMED by the label (the visible node is aria-hidden, so the string is announced
25
25
  * exactly once). `labelAlign` is a controlled vocabulary value — start | center | end, logical, so
@@ -172,7 +172,7 @@ export default function Demo() {
172
172
  </CardContent>
173
173
  </Card>
174
174
 
175
- {/* ── gh#308 — the real screen the labelled rule exists for ─────────────────────────── */}
175
+ {/* ── — the real screen the labelled rule exists for ─────────────────────────── */}
176
176
  <Card>
177
177
  <CardHeader>
178
178
  <CardTitle level={2}>実画面 · チャンネルの投稿ストリーム</CardTitle>
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ServiceRolePanel — ロール一覧 ⇄ 詳細 (canonical master-detail roles surface, gh#257).
2
+ * ServiceRolePanel — ロール一覧 ⇄ 詳細 (canonical master-detail roles surface).
3
3
  *
4
4
  * MasterDetail (rail=master) underneath owns all geometry: two tracks at 1440/1024, stacked
5
5
  * list-then-detail at 390. The panel adds selection (aria-current rows), locked system roles,
@@ -13,14 +13,14 @@ import {
13
13
  } from "@godxjp/ui/layout";
14
14
  import type { SidebarItemData, SidebarRenderItemProp, SidebarSectionProp } from "@godxjp/ui/layout";
15
15
  import {
16
+ Avatar,
17
+ AvatarFallback,
18
+ Badge,
16
19
  Card,
17
20
  CardContent,
18
21
  CardDescription,
19
22
  CardHeader,
20
23
  CardTitle,
21
- Badge,
22
- Avatar,
23
- AvatarFallback,
24
24
  } from "@godxjp/ui/data-display";
25
25
  import { Button, Text } from "@godxjp/ui/general";
26
26
  import {
@@ -127,7 +127,7 @@ const MENTION_SECTIONS: SidebarSectionProp[] = [
127
127
  ];
128
128
 
129
129
  /**
130
- * gh#228 · nav row and nav icon read SEPARATE colour tokens. A service normally sets these once in
130
+ * nav row and nav icon read SEPARATE colour tokens. A service normally sets these once in
131
131
  * its theme.css (`:root` or a scoped `[data-tenant] .app-sidebar`); here they are scoped to one
132
132
  * demo frame so the default rail can sit next to the themed one. Icons only — geometry (16px icon,
133
133
  * 32px row, 10px gap) is untouched.
@@ -138,7 +138,7 @@ const CANONICAL_NAV_TOKENS = {
138
138
  } as CSSProperties;
139
139
 
140
140
  /**
141
- * gh#213 · THE router-link contract. `createSidebarLink` adapts any router `Link` — React Router /
141
+ * THE router-link contract. `createSidebarLink` adapts any router `Link` — React Router /
142
142
  * TanStack use `to`, Inertia and Next.js use `href` (the default, and
143
143
  * `inertiaSidebarLink(Link)` from `@godxjp/ui/inertia` is the same thing pre-bound). The consumer
144
144
  * writes NO row markup: the Sidebar composes the icon slot, the label, the badge, the active state
@@ -171,7 +171,7 @@ const ROUTED_SECTIONS: SidebarSectionProp[] = [
171
171
  ];
172
172
 
173
173
  /**
174
- * renderItem · DEPRECATED (gh#213) — kept working for existing consumers. It leaves the row CONTENT
174
+ * renderItem · DEPRECATED — kept working for existing consumers. It leaves the row CONTENT
175
175
  * to the caller, which is how a `<Link>{item.label}</Link>` silently dropped every icon in
176
176
  * production. `rowProps` now carries the library-composed `children`, so spreading it (or rendering
177
177
  * `rowProps.children`) restores the canonical row; the star is a decorative, non-interactive affix.
@@ -313,34 +313,40 @@ export default function Demo() {
313
313
  </CardDescription>
314
314
  </CardHeader>
315
315
  <CardContent>
316
- <Flex direction="col" className="bg-card h-80 w-64 overflow-hidden rounded-lg border">
317
- <Sidebar
318
- ariaLabel="ブランド例のナビゲーション"
319
- activeId={brandActiveId}
320
- onSelect={setBrandActiveId}
321
- sections={BRAND_SECTIONS}
322
- aria-label="brand プロップ例のナビゲーション"
323
- brand={
324
- <SidebarHeader>
325
- <span className="bg-primary text-primary-foreground grid size-7 shrink-0 place-items-center rounded-md">
326
- <Boxes className="size-4" aria-hidden="true" />
327
- </span>
328
- <span className="flex min-w-0 flex-col">
329
- <Text weight="bold" truncate>
330
- Acme Suite
331
- </Text>
332
- <Text size="xs" tone="muted" truncate>
333
- v7.0 Enterprise
334
- </Text>
335
- </span>
336
- </SidebarHeader>
337
- }
338
- />
339
- </Flex>
316
+ <Card className="h-80 w-64 overflow-hidden">
317
+ <CardContent flush>
318
+ <Flex direction="col">
319
+ <Sidebar
320
+ ariaLabel="ブランド例のナビゲーション"
321
+ activeId={brandActiveId}
322
+ onSelect={setBrandActiveId}
323
+ sections={BRAND_SECTIONS}
324
+ aria-label="brand プロップ例のナビゲーション"
325
+ brand={
326
+ <SidebarHeader>
327
+ <Avatar className="size-7 shrink-0 rounded-md">
328
+ <AvatarFallback className="bg-primary text-primary-foreground">
329
+ <Boxes className="size-4" aria-hidden="true" />
330
+ </AvatarFallback>
331
+ </Avatar>
332
+ <Flex direction="col" gap="xs" className="min-w-0">
333
+ <Text weight="bold" truncate>
334
+ Acme Suite
335
+ </Text>
336
+ <Text size="xs" tone="muted" truncate>
337
+ v7.0 Enterprise
338
+ </Text>
339
+ </Flex>
340
+ </SidebarHeader>
341
+ }
342
+ />
343
+ </Flex>
344
+ </CardContent>
345
+ </Card>
340
346
  </CardContent>
341
347
  </Card>
342
348
 
343
- {/* linkComponent prop · THE router-link contract (gh#213) — library composes the row. */}
349
+ {/* linkComponent prop · THE router-link contract — library composes the row. */}
344
350
  <Card>
345
351
  <CardHeader>
346
352
  <CardTitle level={2}>linkComponent プロップ(ルーターリンク)</CardTitle>
@@ -356,38 +362,40 @@ export default function Demo() {
356
362
  </CardHeader>
357
363
  <CardContent>
358
364
  <Flex gap="md" wrap>
359
- <Flex
360
- direction="col"
361
- className="bg-card h-72 w-64 overflow-hidden rounded-lg border"
362
- >
363
- <Sidebar
364
- ariaLabel="ルーターリンク行のナビゲーション"
365
- activeId={routedActiveId}
366
- onSelect={setRoutedActiveId}
367
- sections={ROUTED_SECTIONS}
368
- linkComponent={RouterLink}
369
- aria-label="linkComponent プロップ例のナビゲーション(展開)"
370
- />
371
- </Flex>
372
- <Flex
373
- direction="col"
374
- className="bg-card h-72 w-16 overflow-hidden rounded-lg border"
375
- >
376
- <Sidebar
377
- ariaLabel="折りたたみレールのルーターリンク"
378
- activeId={routedActiveId}
379
- onSelect={setRoutedActiveId}
380
- sections={ROUTED_SECTIONS}
381
- linkComponent={RouterLink}
382
- collapsed
383
- aria-label="linkComponent プロップ例のナビゲーション(折りたたみ)"
384
- />
385
- </Flex>
365
+ <Card className="h-72 w-64 overflow-hidden">
366
+ <CardContent flush>
367
+ <Flex direction="col">
368
+ <Sidebar
369
+ ariaLabel="ルーターリンク行のナビゲーション"
370
+ activeId={routedActiveId}
371
+ onSelect={setRoutedActiveId}
372
+ sections={ROUTED_SECTIONS}
373
+ linkComponent={RouterLink}
374
+ aria-label="linkComponent プロップ例のナビゲーション(展開)"
375
+ />
376
+ </Flex>
377
+ </CardContent>
378
+ </Card>
379
+ <Card className="h-72 w-16 overflow-hidden">
380
+ <CardContent flush>
381
+ <Flex direction="col">
382
+ <Sidebar
383
+ ariaLabel="折りたたみレールのルーターリンク"
384
+ activeId={routedActiveId}
385
+ onSelect={setRoutedActiveId}
386
+ sections={ROUTED_SECTIONS}
387
+ linkComponent={RouterLink}
388
+ collapsed
389
+ aria-label="linkComponent プロップ例のナビゲーション(折りたたみ)"
390
+ />
391
+ </Flex>
392
+ </CardContent>
393
+ </Card>
386
394
  </Flex>
387
395
  </CardContent>
388
396
  </Card>
389
397
 
390
- {/* renderItem prop · DEPRECATED escape hatch (gh#213) — kept for back-compat. */}
398
+ {/* renderItem prop · DEPRECATED escape hatch — kept for back-compat. */}
391
399
  <Card>
392
400
  <CardHeader>
393
401
  <CardTitle level={2}>renderItem プロップ(非推奨)</CardTitle>
@@ -401,18 +409,22 @@ export default function Demo() {
401
409
  </CardDescription>
402
410
  </CardHeader>
403
411
  <CardContent>
404
- <Flex direction="col" className="bg-card h-72 w-64 overflow-hidden rounded-lg border">
405
- <Sidebar
406
- ariaLabel="カスタム行例のナビゲーション"
407
- activeId={renderActiveId}
408
- onSelect={setRenderActiveId}
409
- sections={FAVOURITE_SECTIONS}
410
- renderItem={(item, rowProps) =>
411
- renderFavouriteRow(item, rowProps, setRenderActiveId)
412
- }
413
- aria-label="renderItem プロップ例のナビゲーション"
414
- />
415
- </Flex>
412
+ <Card className="h-72 w-64 overflow-hidden">
413
+ <CardContent flush>
414
+ <Flex direction="col">
415
+ <Sidebar
416
+ ariaLabel="カスタム行例のナビゲーション"
417
+ activeId={renderActiveId}
418
+ onSelect={setRenderActiveId}
419
+ sections={FAVOURITE_SECTIONS}
420
+ renderItem={(item, rowProps) =>
421
+ renderFavouriteRow(item, rowProps, setRenderActiveId)
422
+ }
423
+ aria-label="renderItem プロップ例のナビゲーション"
424
+ />
425
+ </Flex>
426
+ </CardContent>
427
+ </Card>
416
428
  </CardContent>
417
429
  </Card>
418
430
 
@@ -430,52 +442,54 @@ export default function Demo() {
430
442
  </CardHeader>
431
443
  <CardContent>
432
444
  <Flex gap="md" wrap>
433
- <Flex
434
- direction="col"
435
- className="bg-card h-64 w-64 overflow-hidden rounded-lg border"
436
- >
437
- <Sidebar
438
- ariaLabel="構成可能な例のナビゲーション"
439
- activeId={composedActiveId}
440
- onSelect={setComposedActiveId}
441
- >
442
- <SidebarSection label="お気に入り">
443
- {COMPOSED_ITEMS.map((item) => (
444
- <SidebarItem
445
- key={item.id}
446
- item={item}
447
- active={composedActiveId === item.id}
448
- onActivate={setComposedActiveId}
449
- />
450
- ))}
451
- </SidebarSection>
452
- </Sidebar>
453
- </Flex>
454
- <Flex
455
- direction="col"
456
- className="bg-card h-64 w-64 overflow-hidden rounded-lg border"
457
- >
458
- <Sidebar
459
- ariaLabel="asChild 例のナビゲーション"
460
- activeId={composedActiveId}
461
- onSelect={setComposedActiveId}
462
- aria-label="SidebarItem asChild 例のナビゲーション"
463
- >
464
- <SidebarSection label="お気に入り(asChild)">
465
- {COMPOSED_ITEMS.map((item) => (
466
- <SidebarItem
467
- key={item.id}
468
- item={item}
469
- active={composedActiveId === item.id}
470
- onActivate={setComposedActiveId}
471
- asChild
472
- >
473
- <Link to={item.href ?? "/"} />
474
- </SidebarItem>
475
- ))}
476
- </SidebarSection>
477
- </Sidebar>
478
- </Flex>
445
+ <Card className="h-64 w-64 overflow-hidden">
446
+ <CardContent flush>
447
+ <Flex direction="col">
448
+ <Sidebar
449
+ ariaLabel="構成可能な例のナビゲーション"
450
+ activeId={composedActiveId}
451
+ onSelect={setComposedActiveId}
452
+ >
453
+ <SidebarSection label="お気に入り">
454
+ {COMPOSED_ITEMS.map((item) => (
455
+ <SidebarItem
456
+ key={item.id}
457
+ item={item}
458
+ active={composedActiveId === item.id}
459
+ onActivate={setComposedActiveId}
460
+ />
461
+ ))}
462
+ </SidebarSection>
463
+ </Sidebar>
464
+ </Flex>
465
+ </CardContent>
466
+ </Card>
467
+ <Card className="h-64 w-64 overflow-hidden">
468
+ <CardContent flush>
469
+ <Flex direction="col">
470
+ <Sidebar
471
+ ariaLabel="asChild 例のナビゲーション"
472
+ activeId={composedActiveId}
473
+ onSelect={setComposedActiveId}
474
+ aria-label="SidebarItem asChild 例のナビゲーション"
475
+ >
476
+ <SidebarSection label="お気に入り(asChild)">
477
+ {COMPOSED_ITEMS.map((item) => (
478
+ <SidebarItem
479
+ key={item.id}
480
+ item={item}
481
+ active={composedActiveId === item.id}
482
+ onActivate={setComposedActiveId}
483
+ asChild
484
+ >
485
+ <Link to={item.href ?? "/"} />
486
+ </SidebarItem>
487
+ ))}
488
+ </SidebarSection>
489
+ </Sidebar>
490
+ </Flex>
491
+ </CardContent>
492
+ </Card>
479
493
  </Flex>
480
494
  </CardContent>
481
495
  </Card>
@@ -496,19 +510,23 @@ export default function Demo() {
496
510
  </CardDescription>
497
511
  </CardHeader>
498
512
  <CardContent>
499
- <Flex direction="col" className="bg-card h-64 w-64 overflow-hidden rounded-lg border">
500
- <Sidebar
501
- ariaLabel="チャンネル一覧のナビゲーション"
502
- activeId={mentionActiveId}
503
- onSelect={setMentionActiveId}
504
- sections={MENTION_SECTIONS}
505
- aria-label="badgeTone 例のナビゲーション"
506
- />
507
- </Flex>
513
+ <Card className="h-64 w-64 overflow-hidden">
514
+ <CardContent flush>
515
+ <Flex direction="col">
516
+ <Sidebar
517
+ ariaLabel="チャンネル一覧のナビゲーション"
518
+ activeId={mentionActiveId}
519
+ onSelect={setMentionActiveId}
520
+ sections={MENTION_SECTIONS}
521
+ aria-label="badgeTone 例のナビゲーション"
522
+ />
523
+ </Flex>
524
+ </CardContent>
525
+ </Card>
508
526
  </CardContent>
509
527
  </Card>
510
528
 
511
- {/* Nav colour tokens · icon and label are themed SEPARATELY (gh#228). */}
529
+ {/* Nav colour tokens · icon and label are themed SEPARATELY. */}
512
530
  <Card>
513
531
  <CardHeader>
514
532
  <CardTitle level={2}>ナビの配色トークン(アイコンとラベルを別々に)</CardTitle>
@@ -522,31 +540,36 @@ export default function Demo() {
522
540
  </CardHeader>
523
541
  <CardContent>
524
542
  <Flex gap="md" wrap>
525
- <Flex
526
- direction="col"
527
- className="bg-card h-64 w-64 overflow-hidden rounded-lg border"
528
- >
529
- <Sidebar
530
- ariaLabel="既定の配色のナビゲーション"
531
- activeId={tokenActiveId}
532
- onSelect={setTokenActiveId}
533
- sections={FAVOURITE_SECTIONS}
534
- aria-label="既定の配色(アイコンは行の色を継承)"
535
- />
536
- </Flex>
537
- <Flex
538
- direction="col"
539
- className="bg-card h-64 w-64 overflow-hidden rounded-lg border"
540
- style={CANONICAL_NAV_TOKENS}
541
- >
542
- <Sidebar
543
- ariaLabel="アイコンを濃くしたナビゲーション"
544
- activeId={tokenActiveId}
545
- onSelect={setTokenActiveId}
546
- sections={FAVOURITE_SECTIONS}
547
- aria-label="トークン上書き(アイコンのみ --foreground)"
548
- />
549
- </Flex>
543
+ <Card className="h-64 w-64 overflow-hidden">
544
+ <CardContent flush>
545
+ <Flex direction="col">
546
+ <Sidebar
547
+ ariaLabel="既定の配色のナビゲーション"
548
+ activeId={tokenActiveId}
549
+ onSelect={setTokenActiveId}
550
+ sections={FAVOURITE_SECTIONS}
551
+ aria-label="既定の配色(アイコンは行の色を継承)"
552
+ />
553
+ </Flex>
554
+ </CardContent>
555
+ </Card>
556
+ <Card className="h-64 w-64 overflow-hidden">
557
+ <CardContent flush>
558
+ <Flex
559
+ direction="col"
560
+
561
+ style={CANONICAL_NAV_TOKENS}
562
+ >
563
+ <Sidebar
564
+ ariaLabel="アイコンを濃くしたナビゲーション"
565
+ activeId={tokenActiveId}
566
+ onSelect={setTokenActiveId}
567
+ sections={FAVOURITE_SECTIONS}
568
+ aria-label="トークン上書き(アイコンのみ --foreground)"
569
+ />
570
+ </Flex>
571
+ </CardContent>
572
+ </Card>
550
573
  </Flex>
551
574
  </CardContent>
552
575
  </Card>