@godxjp/ui 18.8.0 → 18.10.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/LICENSE +202 -0
- package/dist/components/data-display/badge.d.ts +7 -0
- package/dist/components/data-display/badge.js +1 -1
- package/dist/components/data-display/card.d.ts +3 -27
- package/dist/components/data-display/card.js +1 -4
- package/dist/components/data-display/data-table.js +2 -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/permission-matrix.d.ts +26 -0
- package/dist/components/data-display/permission-matrix.js +219 -0
- package/dist/components/data-display/table.d.ts +12 -0
- package/dist/components/data-entry/branch-scope-picker.d.ts +43 -0
- package/dist/components/data-entry/branch-scope-picker.js +200 -0
- package/dist/components/data-entry/command-palette.js +8 -1
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/input-otp.d.ts +1 -1
- package/dist/components/feedback/alert.d.ts +2 -20
- package/dist/components/feedback/alert.js +1 -11
- package/dist/components/feedback/banner.d.ts +21 -0
- package/dist/components/feedback/banner.js +15 -0
- package/dist/components/feedback/index.d.ts +4 -2
- package/dist/components/feedback/index.js +2 -2
- package/dist/components/general/typography.d.ts +1 -0
- package/dist/components/general/typography.js +32 -13
- package/dist/components/layout/auth-shell.d.ts +2 -2
- package/dist/components/layout/index.d.ts +2 -2
- package/dist/components/layout/index.js +2 -2
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +45 -19
- package/dist/components/layout/service-role-panel.d.ts +25 -0
- package/dist/components/layout/service-role-panel.js +206 -0
- package/dist/components/navigation/filter-bar.d.ts +2 -2
- package/dist/components/navigation/filter-bar.js +113 -34
- package/dist/components/navigation/index.d.ts +1 -1
- package/dist/components/navigation/steps.d.ts +2 -2
- package/dist/components/navigation/steps.js +2 -4
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +1 -2
- package/dist/components/ui/input-otp.d.ts +3 -15
- package/dist/components/ui/input-otp.js +1 -2
- package/dist/email/tokens.generated.d.ts +2 -2
- package/dist/email/tokens.generated.js +2 -2
- package/dist/i18n/messages/en.json +56 -4
- package/dist/i18n/messages/ja.json +51 -5
- package/dist/i18n/messages/vi.json +50 -4
- package/dist/props/components/data-display.prop.d.ts +66 -16
- package/dist/props/components/data-entry.prop.d.ts +54 -7
- package/dist/props/components/feedback.prop.d.ts +3 -3
- package/dist/props/components/general.prop.d.ts +8 -1
- package/dist/props/components/layout.prop.d.ts +75 -54
- package/dist/props/components/navigation.prop.d.ts +77 -59
- package/dist/props/registry.d.ts +273 -72
- package/dist/props/registry.js +361 -92
- package/dist/props/vocabulary/content.prop.d.ts +5 -0
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +4 -7
- package/dist/props/vocabulary/layout.prop.d.ts +2 -2
- package/dist/styles/alert-layout.css +15 -32
- package/dist/styles/badge-layout.css +5 -0
- package/dist/styles/card-layout.css +13 -49
- package/dist/styles/control.css +2 -12
- package/dist/styles/data-display-layout.css +0 -16
- package/dist/styles/layout.css +102 -108
- package/dist/styles/navigation-layout.css +3 -8
- package/dist/styles/shell-layout.css +17 -17
- package/dist/styles/table-layout.css +77 -2
- package/dist/styles/text-layout.css +13 -0
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/badge.css +5 -0
- package/dist/tokens/components/banner.css +16 -0
- package/dist/tokens/components/card.css +0 -12
- package/dist/tokens/components/control.css +0 -16
- package/dist/tokens/components/data-display.css +0 -12
- package/dist/tokens/components/email.css +2 -8
- package/dist/tokens/components/feedback.css +0 -20
- package/dist/tokens/components/navigation.css +10 -34
- package/dist/tokens/components/shell.css +24 -36
- package/dist/tokens/components/table.css +41 -1
- package/dist/tokens/semantic/layout.css +5 -12
- package/package.json +15 -2
- package/dist/components/layout/page-header.d.ts +0 -22
- package/dist/components/layout/page-header.js +0 -89
|
@@ -51,16 +51,9 @@
|
|
|
51
51
|
background: transparent;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
/* `featured` = the brand-toned perimeter. Its colour is a role-mirror knob (rule #45): declared
|
|
55
|
-
* `initial` in the token layer so the --primary default resolves HERE, at the call site, and a
|
|
56
|
-
* scoped [data-tenant]/.dark override of --primary still reaches it. A service that wants the
|
|
57
|
-
* featured ring in a non-brand tone overrides --card-featured-border-color; a card that wants a
|
|
58
|
-
* SEMANTIC perimeter (attention / destructive / success …) uses
|
|
59
|
-
* `accent="…" accentPlacement="perimeter"` instead — same geometry, tone-owned. */
|
|
60
54
|
[data-slot="card"][data-variant="featured"] {
|
|
61
|
-
border-color:
|
|
62
|
-
box-shadow: 0 0 0 var(--
|
|
63
|
-
var(--card-featured-border-color, hsl(var(--primary)));
|
|
55
|
+
border-color: hsl(var(--primary));
|
|
56
|
+
box-shadow: 0 0 0 1px hsl(var(--primary));
|
|
64
57
|
}
|
|
65
58
|
|
|
66
59
|
/* ── Density — override the shell inset/body tokens ──────────────────────
|
|
@@ -79,39 +72,33 @@
|
|
|
79
72
|
--card-space-body-y: var(--space-5);
|
|
80
73
|
}
|
|
81
74
|
|
|
82
|
-
/* ── Accent
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
/* ── Accent edge — semantic left stripe (token width), content on shell ─ */
|
|
76
|
+
[data-slot="card"][data-accent] {
|
|
77
|
+
border-inline-start-width: var(--card-accent-rail-width);
|
|
78
|
+
}
|
|
79
|
+
|
|
87
80
|
[data-slot="card"][data-accent="primary"] {
|
|
88
|
-
|
|
81
|
+
border-inline-start-color: hsl(var(--primary));
|
|
89
82
|
}
|
|
90
83
|
|
|
91
84
|
[data-slot="card"][data-accent="success"] {
|
|
92
|
-
|
|
85
|
+
border-inline-start-color: hsl(var(--success));
|
|
93
86
|
}
|
|
94
87
|
|
|
95
88
|
[data-slot="card"][data-accent="warning"] {
|
|
96
|
-
|
|
89
|
+
border-inline-start-color: hsl(var(--warning));
|
|
97
90
|
}
|
|
98
91
|
|
|
99
92
|
[data-slot="card"][data-accent="info"] {
|
|
100
|
-
|
|
93
|
+
border-inline-start-color: hsl(var(--info));
|
|
101
94
|
}
|
|
102
95
|
|
|
103
96
|
[data-slot="card"][data-accent="attention"] {
|
|
104
|
-
|
|
97
|
+
border-inline-start-color: hsl(var(--attention));
|
|
105
98
|
}
|
|
106
99
|
|
|
107
100
|
[data-slot="card"][data-accent="destructive"] {
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/* ── Accent placement `edge` (DEFAULT) — semantic left stripe (token width), content on shell ─ */
|
|
112
|
-
[data-slot="card"][data-accent] {
|
|
113
|
-
border-inline-start-width: var(--card-accent-rail-width);
|
|
114
|
-
border-inline-start-color: var(--card-accent-color);
|
|
101
|
+
border-inline-start-color: hsl(var(--destructive));
|
|
115
102
|
}
|
|
116
103
|
|
|
117
104
|
[data-slot="card"][data-accent] > [data-slot="card-header"],
|
|
@@ -120,29 +107,6 @@
|
|
|
120
107
|
padding-inline-start: calc(var(--card-space-inset) - var(--card-accent-rail-width));
|
|
121
108
|
}
|
|
122
109
|
|
|
123
|
-
/* ── Accent placement `perimeter` — the full attention border (gh#12) ───
|
|
124
|
-
* The whole edge carries the semantic tone instead of one rail, so a card can read as
|
|
125
|
-
* "action required" / "failed" at a glance without borrowing `--primary` the way
|
|
126
|
-
* `variant="featured"` does. Same optical weight as `featured` (border + 1px ring), tone-owned.
|
|
127
|
-
* Because the rail is gone, the slot padding compensation above is undone — content returns to
|
|
128
|
-
* the normal shell column, so switching placement never shifts the text. */
|
|
129
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"] {
|
|
130
|
-
border-width: var(--card-accent-perimeter-width);
|
|
131
|
-
border-color: var(--card-accent-color);
|
|
132
|
-
box-shadow:
|
|
133
|
-
0 0 0 var(--card-accent-perimeter-ring-width) var(--card-accent-color),
|
|
134
|
-
var(--card-shadow),
|
|
135
|
-
var(--card-glow);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"] > [data-slot="card-header"],
|
|
139
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"]
|
|
140
|
-
> [data-slot="card-content"]:not([data-flush]),
|
|
141
|
-
[data-slot="card"][data-accent][data-accent-placement="perimeter"]
|
|
142
|
-
> [data-slot="card-footer"]:not([data-flush]) {
|
|
143
|
-
padding-inline-start: var(--card-space-inset);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
110
|
/* ── Header ──────────────────────────────────────────────────────────── */
|
|
147
111
|
[data-slot="card-header"] {
|
|
148
112
|
display: flex;
|
package/dist/styles/control.css
CHANGED
|
@@ -714,18 +714,8 @@
|
|
|
714
714
|
.ui-otp-container {
|
|
715
715
|
display: flex;
|
|
716
716
|
align-items: center;
|
|
717
|
-
justify-content: var(--otp-container-align, flex-start);
|
|
718
717
|
gap: var(--space-2);
|
|
719
718
|
}
|
|
720
|
-
/* `align` on InputOTP lands on the hidden <input> (input-otp owns the container element), so the
|
|
721
|
-
* container reads it through :has() — the same mechanism this file already uses for the invalid
|
|
722
|
-
* and disabled states. Specificity puts the per-instance prop above the theme token. */
|
|
723
|
-
.ui-otp-container:has(.ui-otp-input[data-align="center"]) {
|
|
724
|
-
justify-content: center;
|
|
725
|
-
}
|
|
726
|
-
.ui-otp-container:has(.ui-otp-input[data-align="end"]) {
|
|
727
|
-
justify-content: flex-end;
|
|
728
|
-
}
|
|
729
719
|
.ui-otp-input:disabled {
|
|
730
720
|
cursor: not-allowed;
|
|
731
721
|
}
|
|
@@ -736,8 +726,8 @@
|
|
|
736
726
|
.ui-otp-slot {
|
|
737
727
|
position: relative;
|
|
738
728
|
display: flex;
|
|
739
|
-
width: var(--otp-slot-
|
|
740
|
-
height: var(--otp-slot-
|
|
729
|
+
width: var(--otp-slot-size, var(--control-height));
|
|
730
|
+
height: var(--otp-slot-size, var(--control-height));
|
|
741
731
|
align-items: center;
|
|
742
732
|
justify-content: center;
|
|
743
733
|
font-size: var(--font-size-base);
|
|
@@ -30,22 +30,6 @@
|
|
|
30
30
|
color: var(--avatar-square-foreground, hsl(var(--primary-foreground)));
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/* CAPABILITY MEDALLION — `<Avatar appearance="tinted">` (gh#12). The tinted companion of the
|
|
34
|
-
* solid entity mark: same box, same radius, a soft role wash instead of a solid fill and the
|
|
35
|
-
* glyph in the role itself. Declared AFTER the square rule (equal specificity) so it retints
|
|
36
|
-
* either shape. The glyph rule is scoped to this appearance ON PURPOSE — a global
|
|
37
|
-
* `.ui-avatar svg` would outrank the per-call-site icon classes existing avatars already use. */
|
|
38
|
-
.ui-avatar[data-appearance="tinted"] {
|
|
39
|
-
--avatar-background: var(--avatar-tinted-background, hsl(var(--primary) / 0.1));
|
|
40
|
-
color: var(--avatar-tinted-foreground, hsl(var(--primary)));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.ui-avatar[data-appearance="tinted"] svg {
|
|
44
|
-
inline-size: var(--avatar-tinted-glyph-size);
|
|
45
|
-
block-size: var(--avatar-tinted-glyph-size);
|
|
46
|
-
flex: none;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
33
|
.ui-avatar-image {
|
|
50
34
|
width: 100%;
|
|
51
35
|
height: 100%;
|
package/dist/styles/layout.css
CHANGED
|
@@ -521,47 +521,35 @@
|
|
|
521
521
|
width: 100%;
|
|
522
522
|
}
|
|
523
523
|
|
|
524
|
-
.
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
line-height: var(--line-height-tight);
|
|
529
|
-
overflow-wrap: anywhere;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/* Title + `meta` share one baseline-aligned band (gh#255). The band only exists when `meta` is
|
|
533
|
-
* passed, so a header without it keeps its historical bare-`<h1>` DOM. `wrap` is what keeps a
|
|
534
|
-
* long JA/VI title and a status Badge legible at 390px instead of squeezing the title column. */
|
|
535
|
-
.ui-page-title-band {
|
|
524
|
+
/* Title line + status/meta band (PageContainer `status`, godxjp-ui#255). The band sits on
|
|
525
|
+
* the title's baseline row at the token-owned gap and WRAPS under the title when the
|
|
526
|
+
* viewport (390px) or a long JA/VI title leaves no room — never clips, never overlaps. */
|
|
527
|
+
.ui-page-header-title-row {
|
|
536
528
|
display: flex;
|
|
537
529
|
flex-wrap: wrap;
|
|
538
|
-
align-items:
|
|
539
|
-
gap: var(--page-header-
|
|
530
|
+
align-items: center;
|
|
531
|
+
gap: var(--page-header-status-gap);
|
|
532
|
+
min-inline-size: 0;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
.ui-page-header-title-row > .ui-page-title {
|
|
540
536
|
min-inline-size: 0;
|
|
541
537
|
}
|
|
542
538
|
|
|
543
|
-
.ui-page-header-
|
|
539
|
+
.ui-page-header-status {
|
|
544
540
|
display: flex;
|
|
545
541
|
flex-wrap: wrap;
|
|
546
542
|
align-items: center;
|
|
547
|
-
gap: var(--page-header-
|
|
543
|
+
gap: var(--page-header-status-gap);
|
|
548
544
|
min-inline-size: 0;
|
|
549
545
|
}
|
|
550
546
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
max-inline-size: 100%;
|
|
558
|
-
min-block-size: var(--page-title-placeholder-block-size);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
.ui-page-subtitle-placeholder {
|
|
562
|
-
inline-size: var(--page-subtitle-placeholder-measure);
|
|
563
|
-
max-inline-size: 100%;
|
|
564
|
-
min-block-size: var(--page-subtitle-placeholder-block-size);
|
|
547
|
+
.ui-page-title {
|
|
548
|
+
font-size: var(--page-title-font-size);
|
|
549
|
+
font-weight: var(--font-weight-medium);
|
|
550
|
+
letter-spacing: var(--letter-spacing-tight);
|
|
551
|
+
line-height: var(--line-height-tight);
|
|
552
|
+
overflow-wrap: anywhere;
|
|
565
553
|
}
|
|
566
554
|
|
|
567
555
|
/* Compact viewports use a responsive type step, not compact density: body/control text and
|
|
@@ -953,84 +941,6 @@
|
|
|
953
941
|
font-size: var(--filter-label-font-size);
|
|
954
942
|
}
|
|
955
943
|
|
|
956
|
-
/* ── FilterBar typed model (#258) ──────────────────────────────────────────────────────────
|
|
957
|
-
* Every rule below is scoped to a region the bar only emits when its prop is passed, so a bar
|
|
958
|
-
* built the old way (children + onClear) matches none of them and is geometrically untouched.
|
|
959
|
-
*
|
|
960
|
-
* SEARCH — full-width while the strip is stacked (a bounded search box on a 390px screen wastes
|
|
961
|
-
* the row), then one shared token-owned measure from the 640px step up. This single measure is
|
|
962
|
-
* what the issue was filed against: as a plain child, every page picked its own width. */
|
|
963
|
-
.ui-filter-bar-search {
|
|
964
|
-
width: 100%;
|
|
965
|
-
min-width: 0;
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
@media (min-width: 640px) {
|
|
969
|
-
.ui-filter-bar-search {
|
|
970
|
-
width: var(--filter-bar-search-width);
|
|
971
|
-
max-width: 100%;
|
|
972
|
-
flex: 0 0 auto;
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
/* CHIPS — always their own full-width line. Applied filters are a record of state, not another
|
|
977
|
-
* control in the row; wrapping them in beside the pickers makes both harder to scan. */
|
|
978
|
-
.ui-filter-bar-chips {
|
|
979
|
-
display: flex;
|
|
980
|
-
width: 100%;
|
|
981
|
-
flex-basis: 100%;
|
|
982
|
-
flex-wrap: wrap;
|
|
983
|
-
align-items: center;
|
|
984
|
-
gap: var(--filter-bar-chip-row-gap);
|
|
985
|
-
min-width: 0;
|
|
986
|
-
}
|
|
987
|
-
|
|
988
|
-
.ui-filter-bar-chip {
|
|
989
|
-
display: inline-flex;
|
|
990
|
-
max-width: 100%;
|
|
991
|
-
align-items: center;
|
|
992
|
-
gap: var(--filter-bar-chip-gap);
|
|
993
|
-
padding: var(--filter-bar-chip-padding-block) var(--filter-bar-chip-padding-inline);
|
|
994
|
-
border-radius: var(--filter-bar-chip-radius);
|
|
995
|
-
background: hsl(var(--filter-bar-chip-background, var(--muted)));
|
|
996
|
-
color: hsl(var(--filter-bar-chip-foreground, var(--muted-foreground)));
|
|
997
|
-
font-size: var(--filter-bar-chip-font-size);
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
/* A long JA/VI chip value wraps inside the chip rather than pushing the row into a horizontal
|
|
1001
|
-
* scroll — the remove control must stay reachable at 390px. */
|
|
1002
|
-
.ui-filter-bar-chip-label {
|
|
1003
|
-
min-width: 0;
|
|
1004
|
-
overflow-wrap: anywhere;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
.ui-filter-bar-chip-remove {
|
|
1008
|
-
flex: none;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
.ui-filter-bar-count {
|
|
1012
|
-
color: hsl(var(--filter-bar-count-foreground, var(--muted-foreground)));
|
|
1013
|
-
font-size: var(--filter-bar-count-font-size);
|
|
1014
|
-
/* The count is a number that changes in place — tabular figures stop the row from twitching
|
|
1015
|
-
* as it goes 9 → 10 → 100. */
|
|
1016
|
-
font-variant-numeric: tabular-nums;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
.ui-filter-bar-actions {
|
|
1020
|
-
display: flex;
|
|
1021
|
-
width: 100%;
|
|
1022
|
-
flex-wrap: wrap;
|
|
1023
|
-
align-items: center;
|
|
1024
|
-
gap: var(--space-inline-sm);
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
@media (min-width: 640px) {
|
|
1028
|
-
.ui-filter-bar-actions {
|
|
1029
|
-
width: auto;
|
|
1030
|
-
flex: 0 0 auto;
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
944
|
/* Toolbar/FilterBar `overflow="scroll"` (#216) — one bounded row that scrolls INLINE instead of
|
|
1035
945
|
* wrapping onto extra rows. Below 640px the strip still stacks (the `wrap` base rules above own
|
|
1036
946
|
* that): a 390px viewport must never hide a filter behind a horizontal scroll it cannot see.
|
|
@@ -1063,6 +973,90 @@
|
|
|
1063
973
|
z-index: 1;
|
|
1064
974
|
background: hsl(var(--filter-bar-sticky-background, var(--background)));
|
|
1065
975
|
}
|
|
976
|
+
|
|
977
|
+
/* Typed-model reset+actions cluster gets the same viewport-pinned treatment (gh#258). */
|
|
978
|
+
.ui-toolbar[data-overflow="scroll"] > .ui-filter-bar-end {
|
|
979
|
+
position: sticky;
|
|
980
|
+
inset-inline-end: 0;
|
|
981
|
+
margin-inline-start: auto;
|
|
982
|
+
flex: 0 0 auto;
|
|
983
|
+
z-index: 1;
|
|
984
|
+
background: hsl(var(--filter-bar-sticky-background, var(--background)));
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/* ── FilterBar typed model (gh#258) ─────────────────────────────────────────────
|
|
989
|
+
* Canonical model layout: strip (search → filters → children → reset → actions) →
|
|
990
|
+
* applied-chips row → result-count/error line. Geometry is entirely token-owned
|
|
991
|
+
* (`--filter-bar-*`); stacking below 640px reuses the `.ui-toolbar` base rules, so
|
|
992
|
+
* 1440/1024/390 behave identically to the composition form. */
|
|
993
|
+
.ui-filter-bar {
|
|
994
|
+
display: flex;
|
|
995
|
+
flex-direction: column;
|
|
996
|
+
gap: var(--filter-bar-section-gap);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
.ui-filter-bar .ui-filter-bar-search {
|
|
1000
|
+
inline-size: 100%;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
.ui-filter-bar-end {
|
|
1004
|
+
display: flex;
|
|
1005
|
+
flex-wrap: wrap;
|
|
1006
|
+
align-items: center;
|
|
1007
|
+
gap: var(--space-2);
|
|
1008
|
+
width: 100%;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
/* Inside the end cluster the clear button gives up its own auto margin — the CLUSTER is what
|
|
1012
|
+
* parks at the inline end, so reset and actions stay adjacent in the keyboard/DOM order. */
|
|
1013
|
+
.ui-filter-bar-end .ui-toolbar-clear {
|
|
1014
|
+
margin-inline-start: 0;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
.ui-filter-bar-actions {
|
|
1018
|
+
display: flex;
|
|
1019
|
+
flex-wrap: wrap;
|
|
1020
|
+
align-items: center;
|
|
1021
|
+
gap: var(--space-2);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
@media (min-width: 640px) {
|
|
1025
|
+
.ui-filter-bar .ui-filter-bar-search {
|
|
1026
|
+
inline-size: min(100%, var(--filter-bar-search-width));
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.ui-filter-bar .ui-filter-bar-filter {
|
|
1030
|
+
min-inline-size: min(100%, var(--filter-bar-filter-width));
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
.ui-filter-bar-end {
|
|
1034
|
+
width: auto;
|
|
1035
|
+
margin-inline-start: auto;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.ui-filter-bar-chips {
|
|
1040
|
+
display: flex;
|
|
1041
|
+
flex-wrap: wrap;
|
|
1042
|
+
align-items: center;
|
|
1043
|
+
gap: var(--filter-bar-chip-gap);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
.ui-filter-bar-chip {
|
|
1047
|
+
display: inline-flex;
|
|
1048
|
+
align-items: center;
|
|
1049
|
+
gap: var(--space-1);
|
|
1050
|
+
min-width: 0;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.ui-filter-bar-meta {
|
|
1054
|
+
font-size: var(--filter-label-font-size);
|
|
1055
|
+
color: hsl(var(--muted-foreground));
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.ui-filter-bar-error {
|
|
1059
|
+
color: hsl(var(--destructive));
|
|
1066
1060
|
}
|
|
1067
1061
|
|
|
1068
1062
|
/* ── LegalDocumentShell (#222) ─────────────────────────────────────────────────
|
|
@@ -394,15 +394,10 @@
|
|
|
394
394
|
box-shadow: 0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color, var(--ring)));
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
/* The step NUMBER carries the emphasis. Both knobs exist because the canonical hosted-identity
|
|
398
|
-
* row marks the step with an accent TINT at normal weight, while the original marked it with
|
|
399
|
-
* bold at the inherited colour — a service picks its own emphasis instead of forking this rule
|
|
400
|
-
* (rule #45). Defaults are the original bold + inherited colour, so nothing moves. */
|
|
401
397
|
.ui-steps-inline-index {
|
|
402
398
|
flex: none;
|
|
403
399
|
font-variant-numeric: tabular-nums;
|
|
404
|
-
font-weight: var(--
|
|
405
|
-
color: var(--steps-inline-index-color, currentColor);
|
|
400
|
+
font-weight: var(--font-weight-bold);
|
|
406
401
|
}
|
|
407
402
|
|
|
408
403
|
.ui-steps-inline-title {
|
|
@@ -423,7 +418,8 @@
|
|
|
423
418
|
color: hsl(var(--destructive));
|
|
424
419
|
}
|
|
425
420
|
|
|
426
|
-
.ui-steps-inline-item[data-status="wait"] .ui-steps-inline-control
|
|
421
|
+
.ui-steps-inline-item[data-status="wait"] .ui-steps-inline-control,
|
|
422
|
+
.ui-steps-inline-separator {
|
|
427
423
|
color: hsl(var(--muted-foreground));
|
|
428
424
|
}
|
|
429
425
|
|
|
@@ -431,6 +427,5 @@
|
|
|
431
427
|
width: var(--steps-inline-separator-size);
|
|
432
428
|
height: var(--steps-inline-separator-size);
|
|
433
429
|
flex: none;
|
|
434
|
-
color: var(--steps-inline-separator-color, hsl(var(--muted-foreground)));
|
|
435
430
|
}
|
|
436
431
|
}
|
|
@@ -192,14 +192,9 @@
|
|
|
192
192
|
text-align: center;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
/* Device-authorization also owns its CODE FIELD (gh#12): the preset's subject is the code, so
|
|
196
|
-
* the slot box comes from the preset instead of the generic square control tier. Scoped on the
|
|
197
|
-
* shell so every OTP inside the device flow inherits it; a per-instance override still wins. */
|
|
198
195
|
.ui-auth-shell[data-preset="device-authorization"] {
|
|
199
196
|
--auth-shell-card-max-width: var(--auth-shell-device-card-max-width);
|
|
200
197
|
--auth-shell-main-padding: var(--auth-shell-device-main-padding);
|
|
201
|
-
--otp-slot-inline-size: var(--auth-shell-device-otp-slot-inline-size);
|
|
202
|
-
--otp-slot-block-size: var(--auth-shell-device-otp-slot-block-size);
|
|
203
198
|
}
|
|
204
199
|
|
|
205
200
|
.ui-auth-shell[data-preset="context-selection"] {
|
|
@@ -343,12 +338,21 @@
|
|
|
343
338
|
.ui-auth-shell[data-variant="canonical"] .ui-form-field {
|
|
344
339
|
--field-label-gap: var(--auth-shell-field-label-gap);
|
|
345
340
|
}
|
|
341
|
+
}
|
|
346
342
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
343
|
+
/* INTENTIONALLY UNLAYERED (like density.css) — the Label primitive carries `text-sm leading-none`
|
|
344
|
+
* Tailwind utility classes, and the utilities layer is declared after `components`, so a
|
|
345
|
+
* components-layer declaration of the same properties can NEVER win regardless of specificity.
|
|
346
|
+
* That left `--auth-shell-field-label-font-size` / `--auth-shell-field-label-line-height` dead and
|
|
347
|
+
* the canonical field label rendering as a 14px/1.0 line box instead of the canonical 12px/1.5 =
|
|
348
|
+
* 18px, sitting the email input 4px high (gh#263). Unlayered author CSS out-cascades every layer;
|
|
349
|
+
* the two tokens remain the public tuning knobs. */
|
|
350
|
+
.ui-auth-shell[data-variant="canonical"] [data-slot="form-field-label"] [data-slot="label"] {
|
|
351
|
+
font-size: var(--auth-shell-field-label-font-size);
|
|
352
|
+
line-height: var(--auth-shell-field-label-line-height);
|
|
353
|
+
}
|
|
351
354
|
|
|
355
|
+
@layer components {
|
|
352
356
|
/*
|
|
353
357
|
* Compact auth card density — the two card axes are wired to SEPARATE knobs (gh#232), so a
|
|
354
358
|
* service can shorten the canonical Login card without narrowing its column (or vice versa):
|
|
@@ -384,7 +388,7 @@
|
|
|
384
388
|
gap: var(--auth-shell-divider-gap);
|
|
385
389
|
color: hsl(var(--auth-shell-divider-label-color));
|
|
386
390
|
font-size: var(--auth-shell-divider-label-font-size);
|
|
387
|
-
line-height:
|
|
391
|
+
line-height: var(--auth-shell-divider-label-line-height);
|
|
388
392
|
}
|
|
389
393
|
|
|
390
394
|
.ui-auth-divider-rule {
|
|
@@ -423,8 +427,8 @@
|
|
|
423
427
|
|
|
424
428
|
/* registration = 15px inline at 390 (card x=15, width=360 — the same page rhythm as Login, so
|
|
425
429
|
* sign-in → sign-up never jumps on a phone). The block insets tighten but the footer clearance
|
|
426
|
-
* stays deliberately larger than
|
|
427
|
-
*
|
|
430
|
+
* stays deliberately larger than a bare gutter: at 390 the form is at its tallest and the
|
|
431
|
+
* consent/legal footer must not sit flush against the submit button. */
|
|
428
432
|
.ui-auth-shell[data-preset="registration"] {
|
|
429
433
|
--auth-shell-main-padding: var(--auth-shell-registration-main-padding-block-start-mobile)
|
|
430
434
|
var(--auth-shell-registration-main-padding-inline-mobile)
|
|
@@ -524,11 +528,7 @@
|
|
|
524
528
|
}
|
|
525
529
|
|
|
526
530
|
/* AppShell-owned mobile drawer trigger — hidden on desktop, shown once the docked sidebar
|
|
527
|
-
* collapses out
|
|
528
|
-
* (1024px): this comment said "below lg" for six minors while the shipped rule below and the
|
|
529
|
-
* hamburger's own `max-[900px]:inline-flex` both fired at 900 — see the block comment on the
|
|
530
|
-
* `@media (width <= 56.25rem)` rule for why 900 is the canonical value. The drawer nav itself is
|
|
531
|
-
* a focus-trapped Sheet. */
|
|
531
|
+
* collapses out below `lg` (gh#165). The drawer nav itself is a focus-trapped Sheet. */
|
|
532
532
|
.app-mobile-nav-trigger {
|
|
533
533
|
display: none;
|
|
534
534
|
flex: 0 0 auto;
|
|
@@ -284,8 +284,23 @@
|
|
|
284
284
|
|
|
285
285
|
.ui-table-collection :is([data-slot="table-head"], [data-slot="table-cell"]) {
|
|
286
286
|
/* The column measure comes from `priority`; an unmarked column takes what is left (`auto`),
|
|
287
|
-
* which is the free-text column
|
|
288
|
-
|
|
287
|
+
* which is the free-text column — EXCEPT past the seven-column budget below the collapse
|
|
288
|
+
* step, where the `:has()` tier re-points the middle fallback at the flex floor (gh#262):
|
|
289
|
+
* the fixed algorithm hands an auto column 0px once the marked columns over-constrain the
|
|
290
|
+
* table, which is the one-character-per-line shredding this preset must never produce.
|
|
291
|
+
* There every column carries a rem floor-measure; once the floors outgrow the container the
|
|
292
|
+
* table's used width grows past its specified 100% (CSS 2.1 §17.5.2.1) and the DIRECT
|
|
293
|
+
* wrapper's keyboard-reachable overflow-x region scrolls — the SC 1.4.10-permitted
|
|
294
|
+
* one-dimensional scroll, instead of unreadable shredding (see tokens/components/table.css). */
|
|
295
|
+
inline-size: var(
|
|
296
|
+
--table-action-collection-column-width,
|
|
297
|
+
var(--table-action-collection-flex-width, auto)
|
|
298
|
+
);
|
|
299
|
+
/* Wrapping guard, considered for gh#262: this stays `overflow-wrap: anywhere`, NOT
|
|
300
|
+
* `word-break: keep-all`. Under `table-layout: fixed` a column cannot grow to fit an
|
|
301
|
+
* unbreakable CJK run, so keep-all would overflow/clip a long JA header instead of widening
|
|
302
|
+
* its column. With the floors guaranteeing a ~5-glyph measure, a wrapped JA header is two
|
|
303
|
+
* readable lines — never a vertical character column — and losing no text beats clipping. */
|
|
289
304
|
overflow-wrap: anywhere;
|
|
290
305
|
white-space: normal;
|
|
291
306
|
vertical-align: top;
|
|
@@ -331,6 +346,21 @@
|
|
|
331
346
|
[data-collapse-below="sm"] [data-slot="table-cell"] * {
|
|
332
347
|
white-space: normal;
|
|
333
348
|
}
|
|
349
|
+
|
|
350
|
+
/* SEVEN columns and up — the wide-collection floor tier (gh#262). Percent shares are
|
|
351
|
+
* guaranteed to sum past 100% here and fixed layout would normalize them into sub-glyph
|
|
352
|
+
* columns, so every column (the unmarked free-text one included) takes its rem floor
|
|
353
|
+
* instead; the over-constrained table grows past 100% and its wrapper scrolls. Up to six
|
|
354
|
+
* columns this rule never matches and the percent tier above keeps the canonical queues
|
|
355
|
+
* scroll-free — the preset's documented column-count ceiling. */
|
|
356
|
+
[data-collapse-below="sm"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
|
|
357
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
358
|
+
--table-action-collection-secondary-width: var(
|
|
359
|
+
--table-action-collection-secondary-width-floor
|
|
360
|
+
);
|
|
361
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-floor);
|
|
362
|
+
--table-action-collection-flex-width: var(--table-action-collection-flex-width-floor);
|
|
363
|
+
}
|
|
334
364
|
}
|
|
335
365
|
|
|
336
366
|
@container ui-table-collection (width < 48rem) {
|
|
@@ -352,6 +382,21 @@
|
|
|
352
382
|
[data-collapse-below="md"] [data-slot="table-cell"] * {
|
|
353
383
|
white-space: normal;
|
|
354
384
|
}
|
|
385
|
+
|
|
386
|
+
/* SEVEN columns and up — the wide-collection floor tier (gh#262). Percent shares are
|
|
387
|
+
* guaranteed to sum past 100% here and fixed layout would normalize them into sub-glyph
|
|
388
|
+
* columns, so every column (the unmarked free-text one included) takes its rem floor
|
|
389
|
+
* instead; the over-constrained table grows past 100% and its wrapper scrolls. Up to six
|
|
390
|
+
* columns this rule never matches and the percent tier above keeps the canonical queues
|
|
391
|
+
* scroll-free — the preset's documented column-count ceiling. */
|
|
392
|
+
[data-collapse-below="md"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
|
|
393
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
394
|
+
--table-action-collection-secondary-width: var(
|
|
395
|
+
--table-action-collection-secondary-width-floor
|
|
396
|
+
);
|
|
397
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-floor);
|
|
398
|
+
--table-action-collection-flex-width: var(--table-action-collection-flex-width-floor);
|
|
399
|
+
}
|
|
355
400
|
}
|
|
356
401
|
|
|
357
402
|
@container ui-table-collection (width < 64rem) {
|
|
@@ -373,6 +418,21 @@
|
|
|
373
418
|
[data-collapse-below="lg"] [data-slot="table-cell"] * {
|
|
374
419
|
white-space: normal;
|
|
375
420
|
}
|
|
421
|
+
|
|
422
|
+
/* SEVEN columns and up — the wide-collection floor tier (gh#262). Percent shares are
|
|
423
|
+
* guaranteed to sum past 100% here and fixed layout would normalize them into sub-glyph
|
|
424
|
+
* columns, so every column (the unmarked free-text one included) takes its rem floor
|
|
425
|
+
* instead; the over-constrained table grows past 100% and its wrapper scrolls. Up to six
|
|
426
|
+
* columns this rule never matches and the percent tier above keeps the canonical queues
|
|
427
|
+
* scroll-free — the preset's documented column-count ceiling. */
|
|
428
|
+
[data-collapse-below="lg"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
|
|
429
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
430
|
+
--table-action-collection-secondary-width: var(
|
|
431
|
+
--table-action-collection-secondary-width-floor
|
|
432
|
+
);
|
|
433
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-floor);
|
|
434
|
+
--table-action-collection-flex-width: var(--table-action-collection-flex-width-floor);
|
|
435
|
+
}
|
|
376
436
|
}
|
|
377
437
|
|
|
378
438
|
@container ui-table-collection (width < 80rem) {
|
|
@@ -394,5 +454,20 @@
|
|
|
394
454
|
[data-collapse-below="xl"] [data-slot="table-cell"] * {
|
|
395
455
|
white-space: normal;
|
|
396
456
|
}
|
|
457
|
+
|
|
458
|
+
/* SEVEN columns and up — the wide-collection floor tier (gh#262). Percent shares are
|
|
459
|
+
* guaranteed to sum past 100% here and fixed layout would normalize them into sub-glyph
|
|
460
|
+
* columns, so every column (the unmarked free-text one included) takes its rem floor
|
|
461
|
+
* instead; the over-constrained table grows past 100% and its wrapper scrolls. Up to six
|
|
462
|
+
* columns this rule never matches and the percent tier above keeps the canonical queues
|
|
463
|
+
* scroll-free — the preset's documented column-count ceiling. */
|
|
464
|
+
[data-collapse-below="xl"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
|
|
465
|
+
--table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
|
|
466
|
+
--table-action-collection-secondary-width: var(
|
|
467
|
+
--table-action-collection-secondary-width-floor
|
|
468
|
+
);
|
|
469
|
+
--table-action-collection-meta-width: var(--table-action-collection-meta-width-floor);
|
|
470
|
+
--table-action-collection-flex-width: var(--table-action-collection-flex-width-floor);
|
|
471
|
+
}
|
|
397
472
|
}
|
|
398
473
|
}
|
|
@@ -107,6 +107,19 @@
|
|
|
107
107
|
* having to add `min-w-0` — the documented flex-truncate idiom (issue #114). */
|
|
108
108
|
min-width: 0;
|
|
109
109
|
}
|
|
110
|
+
/* Multi-line clamp (`clamp` prop, issue #261) — the token-owned line-clamp so consumers never
|
|
111
|
+
* write a page-local `line-clamp-N` utility. Visual-only: the full text stays in the DOM and
|
|
112
|
+
* the accessible name. `--text-clamp` is set inline by the component from the prop value. */
|
|
113
|
+
[data-slot="text"][data-clamp] {
|
|
114
|
+
display: -webkit-box;
|
|
115
|
+
-webkit-box-orient: vertical;
|
|
116
|
+
-webkit-line-clamp: var(--text-clamp, 2);
|
|
117
|
+
line-clamp: var(--text-clamp, 2);
|
|
118
|
+
overflow: hidden;
|
|
119
|
+
/* Same flex-shrink contract as truncate (issue #114): clamps inside a flex row without
|
|
120
|
+
* the consumer adding `min-w-0`. */
|
|
121
|
+
min-width: 0;
|
|
122
|
+
}
|
|
110
123
|
[data-slot="text"][data-tabular] {
|
|
111
124
|
font-variant-numeric: tabular-nums;
|
|
112
125
|
}
|
package/dist/tokens/base.css
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
@import "./components/descriptions.css";
|
|
14
14
|
@import "./components/table.css";
|
|
15
15
|
@import "./components/feedback.css";
|
|
16
|
+
@import "./components/banner.css";
|
|
16
17
|
@import "./components/sheet.css";
|
|
17
18
|
@import "./components/badge.css";
|
|
18
19
|
@import "./components/navigation.css";
|
|
@@ -7,4 +7,9 @@
|
|
|
7
7
|
/* Small-by-design (badge/pill/counter). A knob (rule #45) so a service can
|
|
8
8
|
* re-tune badge text without touching the global --font-size-xs step. */
|
|
9
9
|
--badge-font-size: var(--font-size-xs);
|
|
10
|
+
/* Companion to --badge-font-size (gh#260). The cva's old `text-xs` utility also set
|
|
11
|
+
* line-height via Tailwind's default `--text-xs--line-height: calc(1 / 0.75)` (the theme
|
|
12
|
+
* remaps --text-xs but never that companion). Same unitless ratio here keeps the default
|
|
13
|
+
* badge pixel-identical now that badge-layout.css owns the type metrics. */
|
|
14
|
+
--badge-line-height: calc(1 / 0.75);
|
|
10
15
|
}
|