@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
|
@@ -23,10 +23,12 @@ import { MoreHorizontal } from "lucide-react";
|
|
|
23
23
|
|
|
24
24
|
import coverTerrain from "../../assets/cover-terrain.svg";
|
|
25
25
|
|
|
26
|
-
/*
|
|
26
|
+
/*
|
|
27
|
+
* A committed SVG under docs/assets, imported so the bundler rewrites the URL against
|
|
27
28
|
* PREVIEW_BASE. It replaces a picsum.photos fetch that hung `networkidle` and timed this page out
|
|
28
|
-
* at 30s in CI
|
|
29
|
-
* unreadable characters in the middle of the example a consumer is meant to copy.
|
|
29
|
+
* at 30s in CI; it was briefly an inline data: URI, which fixed the hang but put 700
|
|
30
|
+
* unreadable characters in the middle of the example a consumer is meant to copy.
|
|
31
|
+
*/
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* Card — surface container. Body content ALWAYS goes in CardContent (a bare Card
|
|
@@ -131,7 +133,7 @@ export default function Demo() {
|
|
|
131
133
|
</ResponsiveGrid>
|
|
132
134
|
</Flex>
|
|
133
135
|
|
|
134
|
-
{/* accentPlacement="perimeter" — the semantic attention border
|
|
136
|
+
{/* accentPlacement="perimeter" — the semantic attention border */}
|
|
135
137
|
<Flex direction="col" gap="sm">
|
|
136
138
|
<Text as="div" weight="medium">
|
|
137
139
|
Accent · accentPlacement="perimeter" (全周のアテンションボーダー)
|
|
@@ -39,7 +39,7 @@ const slides = [
|
|
|
39
39
|
function DotNavExample() {
|
|
40
40
|
return (
|
|
41
41
|
<Carousel
|
|
42
|
-
|
|
42
|
+
style={{ paddingInline: "var(--space-10)" }}
|
|
43
43
|
opts={{ loop: true }}
|
|
44
44
|
aria-label="ドットナビゲーション付きカルーセル"
|
|
45
45
|
>
|
|
@@ -71,7 +71,7 @@ export default function Demo() {
|
|
|
71
71
|
</CardDescription>
|
|
72
72
|
</CardHeader>
|
|
73
73
|
<CardContent>
|
|
74
|
-
<Carousel
|
|
74
|
+
<Carousel style={{ paddingInline: "var(--space-10)" }} aria-label="月次 KPI カルーセル">
|
|
75
75
|
<CarouselContent>
|
|
76
76
|
{months.map((m) => (
|
|
77
77
|
<CarouselItem key={m.label} className="basis-full sm:basis-1/2 lg:basis-1/3">
|
|
@@ -96,7 +96,7 @@ export default function Demo() {
|
|
|
96
96
|
</CardHeader>
|
|
97
97
|
<CardContent>
|
|
98
98
|
<Carousel
|
|
99
|
-
|
|
99
|
+
style={{ paddingInline: "var(--space-10)" }}
|
|
100
100
|
opts={{ loop: true, align: "start" }}
|
|
101
101
|
aria-label="ループギャラリーカルーセル"
|
|
102
102
|
>
|
|
@@ -137,7 +137,11 @@ export default function Demo() {
|
|
|
137
137
|
</CardDescription>
|
|
138
138
|
</CardHeader>
|
|
139
139
|
<CardContent>
|
|
140
|
-
<Carousel
|
|
140
|
+
<Carousel
|
|
141
|
+
style={{ paddingBlock: "var(--space-10)" }}
|
|
142
|
+
opts={{ axis: "y" }}
|
|
143
|
+
aria-label="縦方向カルーセル"
|
|
144
|
+
>
|
|
141
145
|
<CarouselContent className="h-48">
|
|
142
146
|
{slides.map((s) => (
|
|
143
147
|
<CarouselItem key={s.label}>
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import { ClipboardCheck, LayoutDashboard, MoreHorizontal, ScrollText } from "lucide-react";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Access-approval queue (SCR-105 /
|
|
22
|
+
* Access-approval queue (SCR-105 / ) — the canonical five-column approval collection driven
|
|
23
23
|
* by the TanStack-powered DataTable, at 1440 · 1024 · 390 with ONLY public API.
|
|
24
24
|
*
|
|
25
25
|
* The whole responsive contract is two props: `preset="action-collection"` on the DataTable and a
|
|
@@ -230,7 +230,7 @@ export default function Demo() {
|
|
|
230
230
|
<DataTable data={[]} columns={columns} getRowId={(row) => row.id} />
|
|
231
231
|
</Flex>
|
|
232
232
|
|
|
233
|
-
{/*
|
|
233
|
+
{/* — the two failure states, in the same table grid as empty/loading. */}
|
|
234
234
|
<Flex direction="col" gap="sm">
|
|
235
235
|
<Text as="div" weight="medium">
|
|
236
236
|
エラー(error · role="alert" · onRetry で再試行を表示)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PermissionMatrix — 権限マトリクス (canonical RBAC role × permission grid,
|
|
2
|
+
* PermissionMatrix — 権限マトリクス (canonical RBAC role × permission grid, ).
|
|
3
3
|
*
|
|
4
|
-
* A REAL export from `@godxjp/ui/data-display` (the
|
|
4
|
+
* A REAL export from `@godxjp/ui/data-display` (the lesson: a consumer cannot import a
|
|
5
5
|
* docs page). Read-only ✓/— by default; `onGrantChange` switches to editable checkbox cells with
|
|
6
6
|
* locked roles kept read-only; compare + 差分のみ come from `lib/permission-grid`; lifecycle
|
|
7
7
|
* states follow the DataTable #216 vocabulary. Domain data below is demo-only — the library
|
|
@@ -145,15 +145,19 @@ export default function Demo() {
|
|
|
145
145
|
<Label htmlFor="pm-doc-diff-only">差分のみ</Label>
|
|
146
146
|
</Flex>
|
|
147
147
|
</Flex>
|
|
148
|
-
<
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
148
|
+
<Card variant="outline" className="overflow-hidden">
|
|
149
|
+
<CardContent flush>
|
|
150
|
+
<div>
|
|
151
|
+
<PermissionMatrix
|
|
152
|
+
roles={ROLES}
|
|
153
|
+
permissions={PERMISSIONS}
|
|
154
|
+
grants={grants}
|
|
155
|
+
compare={[compareA, compareB]}
|
|
156
|
+
diffOnly={diffOnly}
|
|
157
|
+
/>
|
|
158
|
+
</div>
|
|
159
|
+
</CardContent>
|
|
160
|
+
</Card>
|
|
157
161
|
</Flex>
|
|
158
162
|
</CardContent>
|
|
159
163
|
</Card>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
import {
|
|
3
|
+
Badge,
|
|
3
4
|
Card,
|
|
4
5
|
CardContent,
|
|
5
6
|
CardDescription,
|
|
@@ -40,7 +41,7 @@ export default function Demo() {
|
|
|
40
41
|
<CardContent>
|
|
41
42
|
<Popover defaultOpen>
|
|
42
43
|
<PopoverAnchor asChild>
|
|
43
|
-
<
|
|
44
|
+
<Badge variant="outline">請求額 ¥482,000</Badge>
|
|
44
45
|
</PopoverAnchor>
|
|
45
46
|
<PopoverContent side="right" aria-label="請求額の補足">
|
|
46
47
|
<PopoverDescription>税額と支払条件の補足情報です。</PopoverDescription>
|
|
@@ -27,7 +27,7 @@ const entries = Array.from(
|
|
|
27
27
|
const shortEntries = entries.slice(0, 3);
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* The live-stream screen
|
|
30
|
+
* The live-stream screen. A deterministic clock: the demo never reads `Date.now()`, so the
|
|
31
31
|
* frame is stable, and every timestamp still goes through `Intl.DateTimeFormat` (IANA tz, 24h).
|
|
32
32
|
*/
|
|
33
33
|
const STREAM_EPOCH = Date.UTC(2026, 2, 3, 0, 30, 0);
|
|
@@ -109,31 +109,38 @@ export default function Demo() {
|
|
|
109
109
|
</CardDescription>
|
|
110
110
|
</CardHeader>
|
|
111
111
|
<CardContent>
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
112
|
+
<Card variant="outline" className="h-64 w-full">
|
|
113
|
+
<CardContent flush>
|
|
114
|
+
<ScrollArea
|
|
115
|
+
anchor="bottom"
|
|
116
|
+
viewportRef={streamViewport}
|
|
117
|
+
onAnchoredChange={setAnchored}
|
|
118
|
+
type="always"
|
|
119
|
+
>
|
|
120
|
+
<CardContent>
|
|
121
|
+
<Flex direction="col">
|
|
122
|
+
{posts.map((post) => (
|
|
123
|
+
<Flex key={post.id} direction="col" gap="xs">
|
|
124
|
+
<Flex gap="sm" align="baseline">
|
|
125
|
+
<Text size="sm" weight="medium">
|
|
126
|
+
{post.author}
|
|
127
|
+
</Text>
|
|
128
|
+
<Text size="xs" tone="muted">
|
|
129
|
+
{timeFormatter.format(
|
|
130
|
+
new Date(STREAM_EPOCH + post.id * STREAM_STEP_MS),
|
|
131
|
+
)}
|
|
132
|
+
</Text>
|
|
133
|
+
</Flex>
|
|
134
|
+
<Text size="sm" tone="muted">
|
|
135
|
+
{post.body}
|
|
136
|
+
</Text>
|
|
137
|
+
</Flex>
|
|
138
|
+
))}
|
|
129
139
|
</Flex>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
))}
|
|
135
|
-
</Flex>
|
|
136
|
-
</ScrollArea>
|
|
140
|
+
</CardContent>
|
|
141
|
+
</ScrollArea>
|
|
142
|
+
</CardContent>
|
|
143
|
+
</Card>
|
|
137
144
|
</CardContent>
|
|
138
145
|
<CardFooter>
|
|
139
146
|
<Flex gap="sm" wrap>
|
|
@@ -164,20 +171,21 @@ export default function Demo() {
|
|
|
164
171
|
</CardDescription>
|
|
165
172
|
</CardHeader>
|
|
166
173
|
<CardContent>
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
174
|
+
<Card variant="outline" className="h-40 w-full">
|
|
175
|
+
<CardContent flush>
|
|
176
|
+
<ScrollArea anchor="bottom" anchorOffset={0} type="always">
|
|
177
|
+
<CardContent>
|
|
178
|
+
<Flex direction="col" gap="xs">
|
|
179
|
+
{entries.map((e) => (
|
|
180
|
+
<Text key={e} size="sm" className="tabular-nums">
|
|
181
|
+
{e}
|
|
182
|
+
</Text>
|
|
183
|
+
))}
|
|
184
|
+
</Flex>
|
|
185
|
+
</CardContent>
|
|
186
|
+
</ScrollArea>
|
|
187
|
+
</CardContent>
|
|
188
|
+
</Card>
|
|
181
189
|
</CardContent>
|
|
182
190
|
</Card>
|
|
183
191
|
|
|
@@ -189,15 +197,21 @@ export default function Demo() {
|
|
|
189
197
|
</CardDescription>
|
|
190
198
|
</CardHeader>
|
|
191
199
|
<CardContent>
|
|
192
|
-
<
|
|
193
|
-
<
|
|
194
|
-
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
200
|
+
<Card variant="outline" className="h-56 w-full">
|
|
201
|
+
<CardContent flush>
|
|
202
|
+
<ScrollArea>
|
|
203
|
+
<CardContent>
|
|
204
|
+
<Flex direction="col" gap="xs">
|
|
205
|
+
{entries.map((e) => (
|
|
206
|
+
<div key={e} className="text-sm tabular-nums">
|
|
207
|
+
{e}
|
|
208
|
+
</div>
|
|
209
|
+
))}
|
|
210
|
+
</Flex>
|
|
211
|
+
</CardContent>
|
|
212
|
+
</ScrollArea>
|
|
213
|
+
</CardContent>
|
|
214
|
+
</Card>
|
|
201
215
|
</CardContent>
|
|
202
216
|
</Card>
|
|
203
217
|
|
|
@@ -210,15 +224,21 @@ export default function Demo() {
|
|
|
210
224
|
</CardDescription>
|
|
211
225
|
</CardHeader>
|
|
212
226
|
<CardContent>
|
|
213
|
-
<
|
|
214
|
-
<
|
|
215
|
-
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
227
|
+
<Card variant="outline" className="h-56 w-full">
|
|
228
|
+
<CardContent flush>
|
|
229
|
+
<ScrollArea type="always">
|
|
230
|
+
<CardContent>
|
|
231
|
+
<Flex direction="col" gap="xs">
|
|
232
|
+
{entries.map((e) => (
|
|
233
|
+
<div key={e} className="text-sm tabular-nums">
|
|
234
|
+
{e}
|
|
235
|
+
</div>
|
|
236
|
+
))}
|
|
237
|
+
</Flex>
|
|
238
|
+
</CardContent>
|
|
239
|
+
</ScrollArea>
|
|
240
|
+
</CardContent>
|
|
241
|
+
</Card>
|
|
222
242
|
</CardContent>
|
|
223
243
|
</Card>
|
|
224
244
|
|
|
@@ -233,16 +253,22 @@ export default function Demo() {
|
|
|
233
253
|
</CardDescription>
|
|
234
254
|
</CardHeader>
|
|
235
255
|
<CardContent>
|
|
236
|
-
<
|
|
237
|
-
<
|
|
238
|
-
|
|
239
|
-
<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
256
|
+
<Card variant="outline" className="w-full">
|
|
257
|
+
<CardContent flush>
|
|
258
|
+
<ScrollArea>
|
|
259
|
+
<CardContent>
|
|
260
|
+
<Flex gap="lg" className="w-max">
|
|
261
|
+
{columns.map((c) => (
|
|
262
|
+
<div key={c} className="text-sm whitespace-nowrap tabular-nums">
|
|
263
|
+
{c}
|
|
264
|
+
</div>
|
|
265
|
+
))}
|
|
266
|
+
</Flex>
|
|
267
|
+
</CardContent>
|
|
268
|
+
<ScrollBar orientation="horizontal" />
|
|
269
|
+
</ScrollArea>
|
|
270
|
+
</CardContent>
|
|
271
|
+
</Card>
|
|
246
272
|
</CardContent>
|
|
247
273
|
</Card>
|
|
248
274
|
|
|
@@ -254,15 +280,21 @@ export default function Demo() {
|
|
|
254
280
|
</CardDescription>
|
|
255
281
|
</CardHeader>
|
|
256
282
|
<CardContent>
|
|
257
|
-
<
|
|
258
|
-
<
|
|
259
|
-
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
283
|
+
<Card variant="outline" className="h-56 w-full">
|
|
284
|
+
<CardContent flush>
|
|
285
|
+
<ScrollArea type="always">
|
|
286
|
+
<CardContent>
|
|
287
|
+
<Flex direction="col" gap="xs">
|
|
288
|
+
{shortEntries.map((e) => (
|
|
289
|
+
<div key={e} className="text-sm tabular-nums">
|
|
290
|
+
{e}
|
|
291
|
+
</div>
|
|
292
|
+
))}
|
|
293
|
+
</Flex>
|
|
294
|
+
</CardContent>
|
|
295
|
+
</ScrollArea>
|
|
296
|
+
</CardContent>
|
|
297
|
+
</Card>
|
|
266
298
|
</CardContent>
|
|
267
299
|
</Card>
|
|
268
300
|
</Flex>
|
|
@@ -38,7 +38,7 @@ export default function Demo() {
|
|
|
38
38
|
</CardHeader>
|
|
39
39
|
<CardContent flush>
|
|
40
40
|
<Table>
|
|
41
|
-
<caption className="
|
|
41
|
+
<caption className="text-start" style={{ padding: "var(--space-2) var(--space-4)" }}>
|
|
42
42
|
<Text size="xs" tone="muted">
|
|
43
43
|
2026年5月 売上計上(税込)
|
|
44
44
|
</Text>
|
|
@@ -131,7 +131,7 @@ export default function Demo() {
|
|
|
131
131
|
</CardContent>
|
|
132
132
|
</Card>
|
|
133
133
|
|
|
134
|
-
{/* ── The flush full-bleed FRAME contract
|
|
134
|
+
{/* ── The flush full-bleed FRAME contract ───────────────────────────
|
|
135
135
|
Four cards, side by side, so the whole rule is visible at once: which edges a
|
|
136
136
|
full-bleed table keeps inside a card, and who draws the line under the header. */}
|
|
137
137
|
<Card>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Card,
|
|
3
|
+
CardContent,
|
|
4
|
+
CardDescription,
|
|
5
|
+
CardHeader,
|
|
6
|
+
CardTitle,
|
|
7
|
+
TimelineGrid,
|
|
8
|
+
type TimelineGridColumnProp,
|
|
9
|
+
type TimelineGridEventProp,
|
|
10
|
+
} from "@godxjp/ui/data-display";
|
|
11
|
+
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* TimelineGrid — a vertical hour axis, one column per day, and event blocks placed by start time
|
|
15
|
+
* and duration. It is the time-axis half of the Timeline family; Timeline itself is one lane of
|
|
16
|
+
* ordered events with no scale.
|
|
17
|
+
*/
|
|
18
|
+
const WEEK: TimelineGridColumnProp[] = [
|
|
19
|
+
{ id: "05-11", label: "月 11" },
|
|
20
|
+
{ id: "05-12", label: "火 12" },
|
|
21
|
+
{ id: "05-13", label: "水 13" },
|
|
22
|
+
{ id: "05-14", label: "木 14", description: "本日", current: true },
|
|
23
|
+
{ id: "05-15", label: "金 15" },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const SHIFTS: TimelineGridEventProp[] = [
|
|
27
|
+
{ id: "s1", columnId: "05-11", start: "09:00", end: "22:00", title: "通し", description: "佐藤" },
|
|
28
|
+
{ id: "s2", columnId: "05-12", start: "06:00", end: "22:00", title: "有給", description: "鈴木" },
|
|
29
|
+
{ id: "s3", columnId: "05-14", start: "09:00", end: "17:30", title: "早番", description: "田中" },
|
|
30
|
+
{ id: "s4", columnId: "05-14", start: "13:00", end: "22:00", title: "遅番", description: "高橋" },
|
|
31
|
+
// end at or before start = the shift runs into the next day (夜勤 22:00–06:00).
|
|
32
|
+
{ id: "s5", columnId: "05-14", start: "22:00", end: "06:00", title: "夜勤", description: "伊藤" },
|
|
33
|
+
{ id: "s6", columnId: "05-15", start: "09:00", end: "17:30", title: "早番", description: "佐藤" },
|
|
34
|
+
{ id: "s7", columnId: "05-15", start: "18:00", end: "21:00", title: "残業", description: "鈴木" },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
// One column, a finer axis, and a colour carried by the record itself — the day view of the same
|
|
38
|
+
// data. `color` is decorative: the block still prints its hours and its title as text.
|
|
39
|
+
const ROOMS: TimelineGridColumnProp[] = [
|
|
40
|
+
{ id: "a", label: "会議室 A", description: "12名" },
|
|
41
|
+
{ id: "b", label: "会議室 B", description: "6名" },
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const BOOKINGS: TimelineGridEventProp[] = [
|
|
45
|
+
{
|
|
46
|
+
id: "b1",
|
|
47
|
+
columnId: "a",
|
|
48
|
+
start: "09:30",
|
|
49
|
+
end: "10:30",
|
|
50
|
+
title: "定例会",
|
|
51
|
+
description: "営業部",
|
|
52
|
+
color: "var(--wa-gunjo)",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "b2",
|
|
56
|
+
columnId: "a",
|
|
57
|
+
start: "10:00",
|
|
58
|
+
end: "11:00",
|
|
59
|
+
title: "面談",
|
|
60
|
+
description: "人事",
|
|
61
|
+
color: "var(--wa-akane)",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "b3",
|
|
65
|
+
columnId: "b",
|
|
66
|
+
start: "13:00",
|
|
67
|
+
end: "14:30",
|
|
68
|
+
title: "設計レビュー",
|
|
69
|
+
description: "開発部",
|
|
70
|
+
color: "var(--wa-wakatake)",
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
export default function Demo() {
|
|
75
|
+
return (
|
|
76
|
+
<PageContainer title="TimelineGrid" subtitle="時間軸に沿って予定ブロックを置く週/日グリッド">
|
|
77
|
+
<Flex direction="col" gap="lg">
|
|
78
|
+
<Card>
|
|
79
|
+
<CardHeader>
|
|
80
|
+
<CardTitle level={2}>週シフト</CardTitle>
|
|
81
|
+
<CardDescription>
|
|
82
|
+
start / end で軸を 06:00–24:00 に固定し、interval=2
|
|
83
|
+
で2時間ごとに目盛りを引きます。木曜の早番と遅番は時間が重なるため、自動で横に並びます。
|
|
84
|
+
</CardDescription>
|
|
85
|
+
</CardHeader>
|
|
86
|
+
<CardContent flush>
|
|
87
|
+
<TimelineGrid
|
|
88
|
+
label="週シフト 2026年5月11日〜15日"
|
|
89
|
+
columns={WEEK}
|
|
90
|
+
events={SHIFTS}
|
|
91
|
+
start="06:00"
|
|
92
|
+
end="24:00"
|
|
93
|
+
interval={2}
|
|
94
|
+
now="14:35"
|
|
95
|
+
/>
|
|
96
|
+
</CardContent>
|
|
97
|
+
</Card>
|
|
98
|
+
|
|
99
|
+
<Card>
|
|
100
|
+
<CardHeader>
|
|
101
|
+
<CardTitle level={2}>会議室の予約</CardTitle>
|
|
102
|
+
<CardDescription>
|
|
103
|
+
start / end を省略すると、軸は予定の範囲から自動で決まります。onEventSelect
|
|
104
|
+
を渡すと各ブロックが button になり、キーボードでも選べます。
|
|
105
|
+
</CardDescription>
|
|
106
|
+
</CardHeader>
|
|
107
|
+
<CardContent flush>
|
|
108
|
+
<TimelineGrid
|
|
109
|
+
label="会議室の予約 5月14日"
|
|
110
|
+
columns={ROOMS}
|
|
111
|
+
events={BOOKINGS}
|
|
112
|
+
onEventSelect={() => {}}
|
|
113
|
+
/>
|
|
114
|
+
</CardContent>
|
|
115
|
+
</Card>
|
|
116
|
+
</Flex>
|
|
117
|
+
</PageContainer>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* BranchScopePicker — 適用範囲 (all branches vs an explicit subset
|
|
2
|
+
* BranchScopePicker — 適用範囲 (all branches vs an explicit subset).
|
|
3
3
|
*
|
|
4
4
|
* One controlled `{ mode, branchIds }` value; real RadioGroup + CheckboxGroup + SearchInput
|
|
5
5
|
* underneath. `error` is FIELD VALIDATION (aria-errormessage); a failed branch read is
|
|
@@ -111,7 +111,7 @@ export default function Demo() {
|
|
|
111
111
|
onCheckedChange={(next) => setScopes(next === true ? ALL_SCOPES : [])}
|
|
112
112
|
/>
|
|
113
113
|
</Field>
|
|
114
|
-
<Flex direction="col" gap="sm"
|
|
114
|
+
<Flex direction="col" gap="sm" style={{ paddingInlineStart: "var(--space-6)" }}>
|
|
115
115
|
<Field id="scope-read" label="閲覧">
|
|
116
116
|
<Checkbox
|
|
117
117
|
id="scope-read"
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Badge,
|
|
5
|
+
Card,
|
|
6
|
+
CardContent,
|
|
7
|
+
CardDescription,
|
|
8
|
+
CardHeader,
|
|
9
|
+
CardTitle,
|
|
10
|
+
} from "@godxjp/ui/data-display";
|
|
4
11
|
import { FormField, Select } from "@godxjp/ui/data-entry";
|
|
5
12
|
import { Text } from "@godxjp/ui/general";
|
|
6
13
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
@@ -63,12 +70,10 @@ async function loadCountries({ query }: SelectLoadParams): Promise<SelectLoadRes
|
|
|
63
70
|
// real product ships an SVG flag set and renders it here. Tokens only — no hex, no inline style.
|
|
64
71
|
function renderCountry(option: SelectOption) {
|
|
65
72
|
return (
|
|
66
|
-
<
|
|
67
|
-
<
|
|
68
|
-
{option.value}
|
|
69
|
-
</Text>
|
|
73
|
+
<Flex align="center" gap="sm">
|
|
74
|
+
<Badge variant="secondary">{option.value}</Badge>
|
|
70
75
|
<Text truncate>{option.label}</Text>
|
|
71
|
-
</
|
|
76
|
+
</Flex>
|
|
72
77
|
);
|
|
73
78
|
}
|
|
74
79
|
|