@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.
- package/dist/components/data-display/badge.d.ts +26 -2
- package/dist/components/data-display/badge.js +20 -5
- package/dist/components/data-display/index.d.ts +2 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/popover.d.ts +13 -1
- package/dist/components/data-display/popover.js +3 -1
- package/dist/components/data-display/table.d.ts +19 -2
- package/dist/components/data-display/table.js +4 -1
- package/dist/components/data-display/timeline-grid.d.ts +18 -0
- package/dist/components/data-display/timeline-grid.js +222 -0
- package/dist/components/data-entry/cascader.js +4 -6
- package/dist/components/data-entry/checkbox.js +1 -1
- package/dist/components/data-entry/search-select.js +5 -7
- package/dist/components/data-entry/select.js +32 -28
- package/dist/components/data-entry/tree-select.js +4 -6
- package/dist/components/general/inert-background.d.ts +5 -0
- package/dist/components/general/inert-background.js +48 -0
- package/dist/components/layout/auth-shell.d.ts +4 -2
- package/dist/components/layout/auth-shell.js +7 -1
- package/dist/components/layout/centered-shell.d.ts +2 -2
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +2 -1
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/layout/mobile-shell.d.ts +21 -0
- package/dist/components/layout/mobile-shell.js +43 -0
- package/dist/components/layout/sidebar-link.d.ts +1 -1
- package/dist/components/navigation/context-menu.js +13 -9
- package/dist/components/navigation/dropdown-menu.js +17 -13
- package/dist/inertia/index.d.ts +1 -1
- package/dist/lib/variants.d.ts +3 -3
- package/dist/lib/variants.js +1 -0
- package/dist/props/components/data-display.prop.d.ts +72 -0
- package/dist/props/components/data-entry.prop.d.ts +1 -1
- package/dist/props/components/layout.prop.d.ts +93 -6
- package/dist/props/registry.d.ts +113 -2
- package/dist/props/registry.js +155 -1
- package/dist/props/vocabulary/data.prop.d.ts +6 -0
- package/dist/props/vocabulary/index.d.ts +3 -3
- package/dist/props/vocabulary/layout.prop.d.ts +17 -2
- package/dist/props/vocabulary/shared.prop.d.ts +7 -0
- package/dist/styles/badge-layout.css +15 -0
- package/dist/styles/control.css +18 -1
- package/dist/styles/data-display-layout.css +167 -0
- package/dist/styles/layout.css +7 -0
- package/dist/styles/shell-layout.css +148 -0
- package/dist/styles/table-layout.css +23 -4
- package/dist/tokens/components/badge.css +8 -0
- package/dist/tokens/components/control.css +1 -0
- package/dist/tokens/components/data-display.css +20 -0
- package/dist/tokens/components/shell.css +22 -0
- package/dist/tokens/components/table.css +2 -0
- package/docs/SPACING.md +19 -6
- package/docs/charts/compact-bar-trend.tsx +5 -6
- package/docs/data-display/avatar.tsx +7 -9
- package/docs/data-display/badge.tsx +37 -1
- package/docs/data-display/card/index.tsx +6 -4
- package/docs/data-display/carousel.tsx +8 -4
- package/docs/data-display/data-table/examples/approval-queue.tsx +1 -1
- package/docs/data-display/data-table/examples/grid-features.tsx +1 -1
- package/docs/data-display/data-table/index.tsx +1 -1
- package/docs/data-display/permission-matrix.tsx +15 -11
- package/docs/data-display/popover.tsx +2 -1
- package/docs/data-display/scroll-area.tsx +108 -76
- package/docs/data-display/table.tsx +2 -2
- package/docs/data-display/timeline-grid.tsx +119 -0
- package/docs/data-entry/branch-scope-picker.tsx +1 -1
- package/docs/data-entry/calendar.tsx +1 -1
- package/docs/data-entry/checkbox.tsx +1 -1
- package/docs/data-entry/country-picker-recipe.tsx +11 -6
- package/docs/data-entry/form-field/index.tsx +33 -29
- package/docs/data-entry/form-root.tsx +1 -1
- package/docs/data-entry/input-otp.tsx +1 -1
- package/docs/data-entry/password-input.tsx +1 -5
- package/docs/data-entry/select.tsx +7 -7
- package/docs/data-entry/textarea.tsx +3 -3
- package/docs/data-entry/toggle-count.tsx +1 -1
- package/docs/feedback/alert.tsx +1 -1
- package/docs/feedback/banner.tsx +1 -1
- package/docs/feedback/sheet.tsx +112 -102
- package/docs/feedback/skeleton.tsx +2 -2
- package/docs/foundation/colors.tsx +8 -6
- package/docs/foundation/email-tokens.tsx +83 -66
- package/docs/foundation/radius-shadow.tsx +13 -11
- package/docs/general/activity.tsx +1 -1
- package/docs/layout/app-shell.tsx +2 -2
- package/docs/layout/aspect-ratio.tsx +30 -14
- package/docs/layout/auth-account-summary.tsx +1 -1
- package/docs/layout/auth-recovery/examples/mobile-390.tsx +1 -1
- package/docs/layout/auth-recovery/examples/password-recovery.tsx +0 -2
- package/docs/layout/auth-shell-context.tsx +1 -1
- package/docs/layout/auth-shell-device.tsx +2 -2
- package/docs/layout/auth-shell-registration.tsx +1 -1
- package/docs/layout/auth-shell.tsx +1 -1
- package/docs/layout/flex.tsx +6 -2
- package/docs/layout/master-detail.tsx +2 -2
- package/docs/layout/mobile-shell.tsx +101 -0
- package/docs/layout/page-container.tsx +15 -7
- package/docs/layout/responsive-grid.tsx +12 -4
- package/docs/layout/separator.tsx +2 -2
- package/docs/layout/service-role-panel.tsx +1 -1
- package/docs/layout/sidebar.tsx +175 -152
- package/docs/layout/split-pane.tsx +45 -28
- package/docs/layout/topbar.tsx +19 -23
- package/docs/navigation/app-setting-picker.tsx +5 -4
- package/docs/navigation/breadcrumb.tsx +12 -5
- package/docs/navigation/context-menu.tsx +10 -4
- package/docs/navigation/filter-bar.tsx +2 -2
- package/docs/navigation/navigation-menu.tsx +89 -96
- package/docs/navigation/pagination.tsx +2 -2
- package/docs/navigation/steps.tsx +13 -11
- package/docs/navigation/tabs.tsx +27 -21
- package/docs/navigation/toolbar.tsx +15 -15
- package/docs/providers/format-date.tsx +2 -2
- package/docs/showcase/acme-portal.tsx +41 -28
- package/docs/showcase/acme-website.tsx +67 -61
- package/docs/showcase/case1-warehouse-dashboard.tsx +46 -31
- package/docs/showcase/case2-employee-me.tsx +33 -36
- package/docs/showcase/case3-approval-workflow.tsx +34 -32
- package/docs/showcase/case4-login.tsx +95 -101
- package/docs/showcase/case5-shift-calendar.tsx +182 -281
- package/docs/showcase/case6-agency-handy.tsx +514 -470
- package/docs/showcase/futurelastic-web.tsx +32 -29
- package/docs/showcase/org-switcher.tsx +20 -13
- package/docs/showcase/permission-matrix.tsx +20 -17
- package/docs/showcase/public-landing.tsx +1 -1
- package/docs/showcase/settings-account-sections.tsx +2 -2
- package/docs/showcase/settings-security-mfa.tsx +3 -3
- package/docs/showcase/table-approval-queue.tsx +1 -1
- package/docs/showcase/table-bulk-actions.tsx +49 -52
- package/docs/showcase/table-conditional-format.tsx +9 -9
- package/docs/showcase/table-crud-list.tsx +4 -4
- package/docs/showcase/table-density.tsx +49 -42
- package/docs/showcase/table-expandable-rows.tsx +112 -100
- package/docs/showcase/table-filter-chips.tsx +78 -71
- package/docs/showcase/table-footer-totals.tsx +30 -23
- package/docs/showcase/table-grouped-subtotals.tsx +31 -25
- package/docs/showcase/table-master-detail.tsx +27 -24
- package/docs/showcase/table-pagination.tsx +34 -27
- package/docs/showcase/table-states.tsx +42 -34
- package/docs/showcase/table-sticky-columns.tsx +11 -7
- package/docs/showcase/table-tree-rows.tsx +22 -15
- package/docs/showcase/table-view-tabs.tsx +12 -14
- 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` ·
|
|
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
|
|
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
|
|
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
|
|
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 をタイトル行に残す
|
|
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 つの測度で束ねる
|
|
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
|
-
"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
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
|
-
{/* ──
|
|
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
|
|
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,
|
package/docs/layout/sidebar.tsx
CHANGED
|
@@ -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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
-
<
|
|
317
|
-
<
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
<
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
|
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
|
-
<
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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
|
|
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
|
-
<
|
|
405
|
-
<
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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
|
-
<
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
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
|
-
<
|
|
500
|
-
<
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
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
|
|
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
|
-
<
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
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>
|