@godxjp/ui 19.3.1 → 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 +9 -1
- package/dist/components/data-display/badge.js +3 -2
- 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 +65 -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 +109 -2
- package/dist/props/registry.js +143 -0
- 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/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/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 +1 -1
- package/docs/data-display/card/index.tsx +6 -4
- package/docs/data-display/data-table/examples/approval-queue.tsx +1 -1
- package/docs/data-display/data-table/index.tsx +1 -1
- package/docs/data-display/permission-matrix.tsx +2 -2
- package/docs/data-display/scroll-area.tsx +1 -1
- package/docs/data-display/table.tsx +1 -1
- package/docs/data-display/timeline-grid.tsx +119 -0
- package/docs/data-entry/branch-scope-picker.tsx +1 -1
- package/docs/data-entry/input-otp.tsx +1 -1
- package/docs/data-entry/textarea.tsx +1 -1
- 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/foundation/email-tokens.tsx +1 -1
- package/docs/general/activity.tsx +1 -1
- 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/master-detail.tsx +2 -2
- package/docs/layout/mobile-shell.tsx +101 -0
- package/docs/layout/page-container.tsx +6 -6
- package/docs/layout/responsive-grid.tsx +2 -2
- package/docs/layout/separator.tsx +2 -2
- package/docs/layout/service-role-panel.tsx +1 -1
- package/docs/layout/sidebar.tsx +6 -6
- package/docs/layout/split-pane.tsx +1 -1
- package/docs/layout/topbar.tsx +2 -8
- package/docs/navigation/filter-bar.tsx +2 -2
- package/docs/navigation/pagination.tsx +2 -2
- package/docs/navigation/steps.tsx +1 -1
- package/docs/navigation/tabs.tsx +1 -1
- package/docs/showcase/acme-portal.tsx +11 -12
- package/docs/showcase/acme-website.tsx +7 -7
- package/docs/showcase/case1-warehouse-dashboard.tsx +11 -12
- package/docs/showcase/case2-employee-me.tsx +10 -16
- package/docs/showcase/case4-login.tsx +144 -156
- package/docs/showcase/case5-shift-calendar.tsx +181 -280
- package/docs/showcase/case6-agency-handy.tsx +446 -443
- package/docs/showcase/futurelastic-web.tsx +9 -8
- package/docs/showcase/org-switcher.tsx +18 -11
- package/docs/showcase/permission-matrix.tsx +13 -13
- 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 +1 -1
- package/docs/showcase/table-crud-list.tsx +1 -1
- package/docs/showcase/table-expandable-rows.tsx +101 -98
- package/docs/showcase/table-filter-chips.tsx +78 -66
- package/docs/showcase/table-footer-totals.tsx +23 -19
- package/docs/showcase/table-grouped-subtotals.tsx +7 -4
- package/docs/showcase/table-master-detail.tsx +12 -14
- package/docs/showcase/table-states.tsx +34 -29
- package/docs/showcase/table-sticky-columns.tsx +3 -2
- package/docs/showcase/table-tree-rows.tsx +22 -15
- package/docs/showcase/table-view-tabs.tsx +12 -14
- package/package.json +7 -6
|
@@ -112,9 +112,19 @@
|
|
|
112
112
|
.ui-auth-shell-bar {
|
|
113
113
|
display: flex;
|
|
114
114
|
align-items: center;
|
|
115
|
+
|
|
116
|
+
flex-wrap: wrap;
|
|
117
|
+
gap: var(--auth-shell-bar-gap);
|
|
115
118
|
padding: var(--auth-shell-bar-padding);
|
|
116
119
|
}
|
|
117
120
|
|
|
121
|
+
.ui-auth-shell-bar-actions {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: var(--auth-shell-bar-gap);
|
|
125
|
+
margin-inline-start: auto;
|
|
126
|
+
}
|
|
127
|
+
|
|
118
128
|
.ui-auth-shell-main {
|
|
119
129
|
display: flex;
|
|
120
130
|
flex: 1 1 auto;
|
|
@@ -142,6 +152,15 @@
|
|
|
142
152
|
--auth-shell-main-padding: var(--auth-shell-canonical-main-padding);
|
|
143
153
|
}
|
|
144
154
|
|
|
155
|
+
.ui-auth-shell[data-measure="wide"]:not([data-preset]) {
|
|
156
|
+
--auth-shell-card-max-width: var(--auth-shell-wide-card-max-width);
|
|
157
|
+
--auth-shell-main-align: flex-start;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.ui-auth-shell[data-measure="wide"]:not([data-preset]) .ui-auth-shell-card {
|
|
161
|
+
margin-block: auto;
|
|
162
|
+
}
|
|
163
|
+
|
|
145
164
|
.ui-auth-shell[data-preset] .ui-auth-shell-card {
|
|
146
165
|
display: flex;
|
|
147
166
|
flex-direction: column;
|
|
@@ -1417,6 +1436,135 @@
|
|
|
1417
1436
|
}
|
|
1418
1437
|
}
|
|
1419
1438
|
|
|
1439
|
+
@layer components {
|
|
1440
|
+
.ui-mobile-shell {
|
|
1441
|
+
--control-height: var(--mobile-shell-control-height);
|
|
1442
|
+
|
|
1443
|
+
--mobile-shell-padding-inline: calc(
|
|
1444
|
+
var(--mobile-shell-inset-inline) + var(--mobile-shell-safe-inset-inline)
|
|
1445
|
+
);
|
|
1446
|
+
display: flex;
|
|
1447
|
+
|
|
1448
|
+
block-size: var(--mobile-shell-block-size);
|
|
1449
|
+
flex-direction: column;
|
|
1450
|
+
overflow: hidden;
|
|
1451
|
+
background: hsl(var(--background));
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
.ui-mobile-shell[data-height="fill"] {
|
|
1455
|
+
--mobile-shell-block-size: 100%;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
.ui-mobile-shell-chrome {
|
|
1459
|
+
display: flex;
|
|
1460
|
+
min-inline-size: 0;
|
|
1461
|
+
flex: 0 0 auto;
|
|
1462
|
+
flex-direction: column;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
.ui-mobile-shell-status {
|
|
1466
|
+
display: flex;
|
|
1467
|
+
min-block-size: calc(
|
|
1468
|
+
var(--mobile-shell-status-bar-height) + var(--mobile-shell-safe-inset-block-start)
|
|
1469
|
+
);
|
|
1470
|
+
flex: 0 0 auto;
|
|
1471
|
+
align-items: center;
|
|
1472
|
+
justify-content: space-between;
|
|
1473
|
+
gap: var(--mobile-shell-region-gap);
|
|
1474
|
+
padding-block-start: var(--mobile-shell-safe-inset-block-start);
|
|
1475
|
+
padding-inline: var(--mobile-shell-padding-inline);
|
|
1476
|
+
background: hsl(var(--card));
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
.ui-mobile-shell-header {
|
|
1480
|
+
display: flex;
|
|
1481
|
+
min-block-size: var(--mobile-shell-header-bar-height);
|
|
1482
|
+
min-inline-size: 0;
|
|
1483
|
+
flex: 0 0 auto;
|
|
1484
|
+
|
|
1485
|
+
overflow: clip;
|
|
1486
|
+
overflow-clip-margin: var(--focus-ring-clip-margin);
|
|
1487
|
+
align-items: center;
|
|
1488
|
+
gap: var(--mobile-shell-region-gap);
|
|
1489
|
+
padding-inline: var(--mobile-shell-padding-inline);
|
|
1490
|
+
border-block-end: 1px solid hsl(var(--border));
|
|
1491
|
+
background: hsl(var(--card));
|
|
1492
|
+
background-image: var(--topbar-gradient);
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
.ui-mobile-shell-header:first-child {
|
|
1496
|
+
min-block-size: calc(
|
|
1497
|
+
var(--mobile-shell-header-bar-height) + var(--mobile-shell-safe-inset-block-start)
|
|
1498
|
+
);
|
|
1499
|
+
padding-block-start: var(--mobile-shell-safe-inset-block-start);
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
.ui-mobile-shell-main {
|
|
1503
|
+
display: flex;
|
|
1504
|
+
min-block-size: 0;
|
|
1505
|
+
min-inline-size: 0;
|
|
1506
|
+
|
|
1507
|
+
flex: 1 1 auto;
|
|
1508
|
+
flex-direction: column;
|
|
1509
|
+
overflow-y: auto;
|
|
1510
|
+
|
|
1511
|
+
overscroll-behavior-block: contain;
|
|
1512
|
+
|
|
1513
|
+
contain: paint;
|
|
1514
|
+
padding-block: var(--mobile-shell-main-padding-block);
|
|
1515
|
+
padding-inline: var(--mobile-shell-padding-inline);
|
|
1516
|
+
background-image: var(--gradient-glow);
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
.ui-mobile-shell-main:focus-visible {
|
|
1520
|
+
outline: none;
|
|
1521
|
+
box-shadow: inset 0 0 0 var(--region-focus-ring-width)
|
|
1522
|
+
var(--region-focus-ring-color, hsl(var(--focus-ring-color, var(--ring))));
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
.ui-mobile-shell-actions {
|
|
1526
|
+
display: flex;
|
|
1527
|
+
min-inline-size: 0;
|
|
1528
|
+
flex: 0 0 auto;
|
|
1529
|
+
align-items: center;
|
|
1530
|
+
gap: var(--mobile-shell-region-gap);
|
|
1531
|
+
padding-block: var(--mobile-shell-actions-padding-block);
|
|
1532
|
+
padding-inline: var(--mobile-shell-padding-inline);
|
|
1533
|
+
border-block-start: 1px solid hsl(var(--border));
|
|
1534
|
+
background: hsl(var(--card));
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
.ui-mobile-shell-tabbar {
|
|
1538
|
+
display: flex;
|
|
1539
|
+
min-block-size: calc(
|
|
1540
|
+
var(--mobile-shell-tab-bar-height) + var(--mobile-shell-safe-inset-block-end)
|
|
1541
|
+
);
|
|
1542
|
+
min-inline-size: 0;
|
|
1543
|
+
flex: 0 0 auto;
|
|
1544
|
+
padding-block-end: var(--mobile-shell-safe-inset-block-end);
|
|
1545
|
+
padding-inline: var(--mobile-shell-safe-inset-inline);
|
|
1546
|
+
border-block-start: 1px solid hsl(var(--border));
|
|
1547
|
+
background: hsl(var(--card));
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
.ui-mobile-shell-tabbar > * {
|
|
1551
|
+
min-inline-size: 0;
|
|
1552
|
+
flex: 1 1 0;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
.ui-mobile-shell-actions:last-child {
|
|
1556
|
+
padding-block-end: calc(
|
|
1557
|
+
var(--mobile-shell-actions-padding-block) + var(--mobile-shell-safe-inset-block-end)
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
.ui-mobile-shell-main:last-child {
|
|
1562
|
+
padding-block-end: calc(
|
|
1563
|
+
var(--mobile-shell-main-padding-block) + var(--mobile-shell-safe-inset-block-end)
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1420
1568
|
@layer components {
|
|
1421
1569
|
|
|
1422
1570
|
.ui-centered-shell[data-preset="public-landing"] {
|
|
@@ -46,6 +46,17 @@
|
|
|
46
46
|
padding-inline-end: 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
[data-slot="table-cell"][data-indent] {
|
|
50
|
+
padding-inline-start: calc(
|
|
51
|
+
var(--table-cell-space-x) + var(--table-cell-indent-level, 0) *
|
|
52
|
+
var(--table-cell-indent-space-step)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[data-slot="table-cell"][data-flush] {
|
|
57
|
+
padding: 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
.ui-data-table-toolbar {
|
|
50
61
|
display: flex;
|
|
51
62
|
flex-wrap: wrap;
|
|
@@ -520,7 +531,9 @@
|
|
|
520
531
|
|
|
521
532
|
[data-collapse-below="sm"] .ui-table-row {
|
|
522
533
|
display: block;
|
|
523
|
-
|
|
534
|
+
|
|
535
|
+
height: auto;
|
|
536
|
+
border: var(--stroke-hairline) solid hsl(var(--border));
|
|
524
537
|
border-radius: var(--radius-md);
|
|
525
538
|
padding: var(--table-stacked-collection-card-padding-y)
|
|
526
539
|
var(--table-stacked-collection-card-padding-x);
|
|
@@ -562,7 +575,9 @@
|
|
|
562
575
|
|
|
563
576
|
[data-collapse-below="md"] .ui-table-row {
|
|
564
577
|
display: block;
|
|
565
|
-
|
|
578
|
+
|
|
579
|
+
height: auto;
|
|
580
|
+
border: var(--stroke-hairline) solid hsl(var(--border));
|
|
566
581
|
border-radius: var(--radius-md);
|
|
567
582
|
padding: var(--table-stacked-collection-card-padding-y)
|
|
568
583
|
var(--table-stacked-collection-card-padding-x);
|
|
@@ -604,7 +619,9 @@
|
|
|
604
619
|
|
|
605
620
|
[data-collapse-below="lg"] .ui-table-row {
|
|
606
621
|
display: block;
|
|
607
|
-
|
|
622
|
+
|
|
623
|
+
height: auto;
|
|
624
|
+
border: var(--stroke-hairline) solid hsl(var(--border));
|
|
608
625
|
border-radius: var(--radius-md);
|
|
609
626
|
padding: var(--table-stacked-collection-card-padding-y)
|
|
610
627
|
var(--table-stacked-collection-card-padding-x);
|
|
@@ -646,7 +663,9 @@
|
|
|
646
663
|
|
|
647
664
|
[data-collapse-below="xl"] .ui-table-row {
|
|
648
665
|
display: block;
|
|
649
|
-
|
|
666
|
+
|
|
667
|
+
height: auto;
|
|
668
|
+
border: var(--stroke-hairline) solid hsl(var(--border));
|
|
650
669
|
border-radius: var(--radius-md);
|
|
651
670
|
padding: var(--table-stacked-collection-card-padding-y)
|
|
652
671
|
var(--table-stacked-collection-card-padding-x);
|
|
@@ -83,6 +83,26 @@
|
|
|
83
83
|
--scroll-area-bar-padding: 1px;
|
|
84
84
|
--scroll-area-thumb-radius: var(--radius-pill);
|
|
85
85
|
|
|
86
|
+
--timeline-grid-hour-height: 2.5rem;
|
|
87
|
+
--timeline-grid-axis-width: 3.25rem;
|
|
88
|
+
--timeline-grid-column-min-width: 6rem;
|
|
89
|
+
--timeline-grid-event-min-height: 1.5rem;
|
|
90
|
+
--timeline-grid-axis-font-size: var(--font-size-2xs);
|
|
91
|
+
--timeline-grid-head-font-size: var(--font-size-xs);
|
|
92
|
+
--timeline-grid-event-font-size: var(--font-size-2xs);
|
|
93
|
+
--timeline-grid-event-gap: var(--space-1);
|
|
94
|
+
--timeline-grid-event-space-inset: var(--space-1);
|
|
95
|
+
--timeline-grid-event-radius: var(--radius-sm);
|
|
96
|
+
--timeline-grid-event-border-width: var(--stroke-md);
|
|
97
|
+
--timeline-grid-now-width: var(--stroke-sm);
|
|
98
|
+
|
|
99
|
+
--timeline-grid-line-color: initial;
|
|
100
|
+
--timeline-grid-event-color: initial;
|
|
101
|
+
|
|
102
|
+
--timeline-grid-event-muted-color: hsl(var(--foreground));
|
|
103
|
+
--timeline-grid-now-color: initial;
|
|
104
|
+
--timeline-grid-current-tint: initial;
|
|
105
|
+
|
|
86
106
|
--permission-matrix-label-width: 16rem;
|
|
87
107
|
--permission-matrix-role-space-gap: var(--space-1);
|
|
88
108
|
--permission-matrix-name-space-gap: 0.375rem;
|
|
@@ -107,6 +107,10 @@
|
|
|
107
107
|
--auth-shell-main-padding: var(--space-6);
|
|
108
108
|
--auth-shell-footer-padding: var(--space-3) var(--space-6) var(--space-4);
|
|
109
109
|
|
|
110
|
+
--auth-shell-bar-gap: var(--space-inline-sm);
|
|
111
|
+
|
|
112
|
+
--auth-shell-wide-card-max-width: 64rem;
|
|
113
|
+
|
|
110
114
|
--auth-shell-canonical-control-height: var(--band-height-lg);
|
|
111
115
|
--auth-shell-canonical-card-max-width: 22.5rem;
|
|
112
116
|
--auth-shell-canonical-heading-size: var(--font-size-base);
|
|
@@ -228,3 +232,21 @@
|
|
|
228
232
|
--app-shell-bar-height: var(--band-height-3xl);
|
|
229
233
|
}
|
|
230
234
|
}
|
|
235
|
+
|
|
236
|
+
:root {
|
|
237
|
+
--mobile-shell-block-size: 100dvh;
|
|
238
|
+
--mobile-shell-safe-inset-block-start: env(safe-area-inset-top);
|
|
239
|
+
--mobile-shell-safe-inset-block-end: env(safe-area-inset-bottom);
|
|
240
|
+
--mobile-shell-safe-inset-inline: max(env(safe-area-inset-left), env(safe-area-inset-right));
|
|
241
|
+
|
|
242
|
+
--mobile-shell-inset-inline: var(--space-4);
|
|
243
|
+
|
|
244
|
+
--mobile-shell-control-height: var(--control-height-comfortable);
|
|
245
|
+
--mobile-shell-region-gap: var(--space-2);
|
|
246
|
+
--mobile-shell-status-bar-height: var(--band-height-lg);
|
|
247
|
+
--mobile-shell-header-bar-height: var(--band-height-3xl);
|
|
248
|
+
|
|
249
|
+
--mobile-shell-tab-bar-height: calc(var(--band-height-3xl) + var(--space-2));
|
|
250
|
+
--mobile-shell-main-padding-block: var(--space-4);
|
|
251
|
+
--mobile-shell-actions-padding-block: var(--space-3);
|
|
252
|
+
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
--table-cell-padding-y: var(--space-2);
|
|
9
9
|
--table-cell-space-x: var(--control-padding-x);
|
|
10
10
|
|
|
11
|
+
--table-cell-indent-space-step: var(--space-4);
|
|
12
|
+
|
|
11
13
|
--table-border-color: initial;
|
|
12
14
|
--table-pagination-padding-y: initial;
|
|
13
15
|
--table-pagination-padding-x: initial;
|
package/docs/SPACING.md
CHANGED
|
@@ -42,15 +42,28 @@ Implementation: `src/tokens/base.css` (values) · layout owners: `src/styles/*-l
|
|
|
42
42
|
| `--card-space-body-y` | `--space-section-active` | Header↔body gap |
|
|
43
43
|
| `--card-space-header-y` / `--card-space-footer-y` | `--space-stack-sm` | Banded header + separated footer band |
|
|
44
44
|
|
|
45
|
-
| Component | Use
|
|
46
|
-
| ------------------------- |
|
|
47
|
-
| `StatCard` | KPI / stat tile (`solo` path)
|
|
48
|
-
| `CardContent solo` | Body-only card (same padding as `StatCard`)
|
|
49
|
-
| `CardContent flush tight` | Edge-to-edge table/tabs in card
|
|
50
|
-
| `ui-card-inset-x` | Align nested cells to shell (tables in flush body) |
|
|
45
|
+
| Component | Use |
|
|
46
|
+
| ------------------------- | ------------------------------------------- |
|
|
47
|
+
| `StatCard` | KPI / stat tile (`solo` path) |
|
|
48
|
+
| `CardContent solo` | Body-only card (same padding as `StatCard`) |
|
|
49
|
+
| `CardContent flush tight` | Edge-to-edge table/tabs in card |
|
|
51
50
|
|
|
52
51
|
See preview **Data Display → Card** for live examples.
|
|
53
52
|
|
|
53
|
+
### Inset classes (padding on something that is not a `Card*` slot)
|
|
54
|
+
|
|
55
|
+
`Card*` slots get their padding from `data-slot`. Everything else that must sit on the same rhythm (a table cell, a grid header strip, a scroll body, a sticky action row, a full-bleed toolbar) uses one of three public classes. They are the only legal way to take card-token padding onto a plain element, because the audit rejects Tailwind `p-*` / `px-*` (`no-utility-spacing`).
|
|
56
|
+
|
|
57
|
+
Pick by AXIS, and note that the three do **not** share one value: each reads a different card token, so `ui-card-inset` is not `ui-card-inset-x` plus `ui-card-inset-y`.
|
|
58
|
+
|
|
59
|
+
| Class | Axis | Token | Use when |
|
|
60
|
+
| ----------------- | ------------------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
61
|
+
| `ui-card-inset-x` | inline (start/end) | `--card-space-inset` | The element must line up with the card shell edge, and the block axis is owned by something else (a fixed row height, a table cell). Rows in a `CardContent flush` table, a header strip in a bordered grid. |
|
|
62
|
+
| `ui-card-inset-y` | block (top/bottom) | `--card-space-header-y` | The element runs edge to edge inline but needs the band rhythm of a banded header / separated footer. A weekday header strip, a full-bleed toolbar cell. |
|
|
63
|
+
| `ui-card-inset` | all four sides | `--card-space-body-y` | A self-contained panel that owns its own padding on every side: a scrollable body, a sticky action bar, an expanded row panel below a table row. |
|
|
64
|
+
|
|
65
|
+
Because `ui-card-inset-x` reads `--card-space-inset`, it follows the card it sits in: a `Card density="tight"` or `"cozy"` moves those cells with the shell. The other two read fixed steps (band and body) and do not.
|
|
66
|
+
|
|
54
67
|
## MCP
|
|
55
68
|
|
|
56
69
|
`get_pattern page-sections` (a page of Cards, spaced by the page) · `get_rule 40` (mobile-first spacing) · `list_audit_rules` (the spacing rules the CLI enforces).
|
|
@@ -13,13 +13,12 @@ import { Text } from "@godxjp/ui/general";
|
|
|
13
13
|
import { Flex, PageContainer, ResponsiveGrid } from "@godxjp/ui/layout";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* CompactBarTrend — the DEPENDENCY-FREE compact bar trend
|
|
16
|
+
* CompactBarTrend — the DEPENDENCY-FREE compact bar trend.
|
|
17
17
|
*
|
|
18
|
-
* `BarChart` needs the `recharts` optional peer
|
|
19
|
-
* implementers from adding dependencies cannot use it
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* consumer CSS, zero inline height math and zero hardcoded colour.
|
|
18
|
+
* `BarChart` needs the `recharts` optional peer, so a platform whose policy forbids screen
|
|
19
|
+
* implementers from adding dependencies cannot use it. The marks here are token-sized CSS
|
|
20
|
+
* blocks instead, so a dashboard gets a real framework chart with zero consumer CSS, zero
|
|
21
|
+
* inline height math and zero hardcoded colour.
|
|
23
22
|
*
|
|
24
23
|
* Everything below is composed from real @godxjp/ui primitives only.
|
|
25
24
|
*/
|
|
@@ -25,12 +25,10 @@ import portraitSlate from "../assets/portrait-slate.svg";
|
|
|
25
25
|
* URL against PREVIEW_BASE — an absolute "/assets/…" would 404 wherever the site is served from a
|
|
26
26
|
* sub-path.
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* geometry sweeps (gh#333), long after the preview server itself was fixed. Committed files cost
|
|
33
|
-
* no request that can hang and no service that can disappear.
|
|
28
|
+
* A docs page must never fetch a THIRD-PARTY image: without the public internet it cannot render,
|
|
29
|
+
* and on CI it does not merely look wrong, it hangs — the request never settles, `networkidle`
|
|
30
|
+
* never fires, and `page.goto` times out. Committed files cost no request that can hang and no
|
|
31
|
+
* service that can disappear.
|
|
34
32
|
*/
|
|
35
33
|
|
|
36
34
|
/**
|
|
@@ -93,7 +91,7 @@ export default function Demo() {
|
|
|
93
91
|
</CardContent>
|
|
94
92
|
</Card>
|
|
95
93
|
|
|
96
|
-
{/* shape="square" — the entity-header organization / service mark
|
|
94
|
+
{/* shape="square" — the entity-header organization / service mark */}
|
|
97
95
|
<Card>
|
|
98
96
|
<CardHeader>
|
|
99
97
|
<CardTitle level={2}>エンティティヘッダー · shape="square"</CardTitle>
|
|
@@ -136,7 +134,7 @@ export default function Demo() {
|
|
|
136
134
|
</CardContent>
|
|
137
135
|
</Card>
|
|
138
136
|
|
|
139
|
-
{/* appearance="tinted" — the capability medallion
|
|
137
|
+
{/* appearance="tinted" — the capability medallion */}
|
|
140
138
|
<Card>
|
|
141
139
|
<CardHeader>
|
|
142
140
|
<CardTitle level={2}>
|
|
@@ -192,7 +190,7 @@ export default function Demo() {
|
|
|
192
190
|
</CardContent>
|
|
193
191
|
</Card>
|
|
194
192
|
|
|
195
|
-
{/* presence — the realtime reachability dot
|
|
193
|
+
{/* presence — the realtime reachability dot */}
|
|
196
194
|
<Card>
|
|
197
195
|
<CardHeader>
|
|
198
196
|
<CardTitle level={2}>プレゼンス · presence</CardTitle>
|
|
@@ -59,7 +59,7 @@ const tones = [
|
|
|
59
59
|
const statuses = ["active", "draft", "pending", "cancelled", "failed", "scheduled"];
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
* Subscription/billing lifecycle keys
|
|
62
|
+
* Subscription/billing lifecycle keys. They ship the SAME canonical status→tone→icon
|
|
63
63
|
* map as every other key, so a billing screen never keeps a page-local colour table. They are
|
|
64
64
|
* demoed explicitly because their i18n labels were once missing. A missing key renders the raw
|
|
65
65
|
* `status.trialing` string, and only a rendered demo makes that regression visible.
|
|
@@ -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" (全周のアテンションボーダー)
|
|
@@ -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
|
|
@@ -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);
|
|
@@ -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
|
|
@@ -140,7 +140,7 @@ export default function Demo() {
|
|
|
140
140
|
</CardContent>
|
|
141
141
|
</Card>
|
|
142
142
|
|
|
143
|
-
{/*
|
|
143
|
+
{/* Align — the centred challenge, without a consumer wrapper div */}
|
|
144
144
|
<Card>
|
|
145
145
|
<CardHeader>
|
|
146
146
|
<CardTitle level={2}>中央寄せ(align="center")</CardTitle>
|
|
@@ -18,7 +18,7 @@ const SEED_MESSAGES: Message[] = [
|
|
|
18
18
|
];
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* The godx-chatter composer
|
|
21
|
+
* The godx-chatter composer. One line at rest, grows line by line, scrolls itself past
|
|
22
22
|
* eight rows, and collapses back to one line the moment the post is sent — the send button just
|
|
23
23
|
* resets the controlled value, and `autoGrow` follows it without a single line of layout code.
|
|
24
24
|
*/
|
|
@@ -14,7 +14,7 @@ import { Button, Text } from "@godxjp/ui/general";
|
|
|
14
14
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Toggle `count` — the counted, PRESSED chip
|
|
17
|
+
* Toggle `count` — the counted, PRESSED chip.
|
|
18
18
|
*
|
|
19
19
|
* `Button` owns the counter-pill vocabulary (`count` / `overflowCount` / `showZero`) and `Toggle`
|
|
20
20
|
* owns the pressed state, so a faceted filter chip ("未対応 42", selected or not) and a reaction
|