@godxjp/ui 22.0.0 → 23.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/README.md +4 -4
  2. package/dist/app/date-format-labels.d.ts +14 -2
  3. package/dist/app/date-format-labels.js +1 -1
  4. package/dist/app/date-formats.d.ts +14 -2
  5. package/dist/app/date-formats.js +9 -2
  6. package/dist/components/data-display/data-table.d.ts +8 -1
  7. package/dist/components/data-display/data-table.js +9 -2
  8. package/dist/components/data-display/scroll-area.d.ts +24 -4
  9. package/dist/components/data-display/scroll-area.js +34 -72
  10. package/dist/components/data-entry/cascader.js +8 -6
  11. package/dist/components/data-entry/checkbox.js +3 -1
  12. package/dist/components/data-entry/choice-hit-target.d.ts +24 -0
  13. package/dist/components/data-entry/choice-hit-target.js +12 -0
  14. package/dist/components/data-entry/control-surface.d.ts +8 -0
  15. package/dist/components/data-entry/control-surface.js +10 -1
  16. package/dist/components/data-entry/form-field.js +5 -4
  17. package/dist/components/data-entry/input.js +1 -1
  18. package/dist/components/data-entry/number-input.js +27 -6
  19. package/dist/components/data-entry/radio.js +4 -3
  20. package/dist/components/data-entry/search-select.js +225 -95
  21. package/dist/components/data-entry/select.d.ts +76 -14
  22. package/dist/components/data-entry/select.js +495 -163
  23. package/dist/components/data-entry/slider.d.ts +3 -11
  24. package/dist/components/data-entry/slider.js +582 -93
  25. package/dist/components/data-entry/switch.js +3 -1
  26. package/dist/components/feedback/dialog.js +2 -2
  27. package/dist/components/feedback/sheet.js +2 -22
  28. package/dist/components/navigation/dropdown-menu.d.ts +11 -3
  29. package/dist/components/navigation/dropdown-menu.js +190 -15
  30. package/dist/components/navigation/filter-bar.js +2 -1
  31. package/dist/components/navigation/index.d.ts +0 -3
  32. package/dist/components/navigation/index.js +0 -78
  33. package/dist/components/navigation/tabs.js +16 -4
  34. package/dist/components/ui/index.d.ts +0 -3
  35. package/dist/components/ui/index.js +0 -3
  36. package/dist/components/ui/input-otp.d.ts +1 -1
  37. package/dist/components/ui/segmented.js +3 -1
  38. package/dist/components/ui/tag-input.js +3 -5
  39. package/dist/i18n/messages/en.json +5 -1
  40. package/dist/i18n/messages/ja.json +5 -1
  41. package/dist/i18n/messages/vi.json +5 -1
  42. package/dist/lib/breakpoint-token.d.ts +8 -0
  43. package/dist/lib/breakpoint-token.js +29 -0
  44. package/dist/lib/select-options.d.ts +21 -0
  45. package/dist/lib/select-options.js +46 -0
  46. package/dist/props/components/data-display.prop.d.ts +17 -7
  47. package/dist/props/components/data-entry.prop.d.ts +323 -30
  48. package/dist/props/components/index.d.ts +1 -1
  49. package/dist/props/components/navigation.prop.d.ts +25 -1
  50. package/dist/props/registry.d.ts +69 -1
  51. package/dist/props/registry.js +75 -0
  52. package/dist/props/vocabulary/data.prop.d.ts +5 -0
  53. package/dist/props/vocabulary/index.d.ts +1 -1
  54. package/dist/styles/control.css +246 -28
  55. package/dist/styles/data-display-layout.css +18 -10
  56. package/dist/styles/focus-ring.css +28 -0
  57. package/dist/styles/fonts.css +88 -4
  58. package/dist/styles/form-layout.css +4 -0
  59. package/dist/styles/layout.css +2 -1
  60. package/dist/styles/navigation-layout.css +24 -238
  61. package/dist/styles/shell-layout.css +148 -139
  62. package/dist/styles/table-layout.css +12 -5
  63. package/dist/tokens/components/control.css +12 -3
  64. package/dist/tokens/components/data-display.css +0 -5
  65. package/dist/tokens/components/navigation.css +5 -5
  66. package/dist/tokens/components/scroll-area.css +7 -0
  67. package/docs/CONSUMER-RULES.md +7 -2
  68. package/docs/CUSTOMER-THEMING.md +25 -9
  69. package/docs/DATETIME.md +11 -2
  70. package/docs/FRAME-COVERAGE-REPORT.md +4 -7
  71. package/docs/SPACING.md +35 -5
  72. package/docs/TOKENS.md +1 -1
  73. package/docs/data-display/data-table/index.tsx +44 -3
  74. package/docs/data-display/popover.tsx +4 -6
  75. package/docs/data-display/scroll-area.tsx +51 -45
  76. package/docs/data-display/table.tsx +1 -1
  77. package/docs/data-entry/date-picker.tsx +2 -3
  78. package/docs/data-entry/input-otp.tsx +5 -2
  79. package/docs/data-entry/segmented-in-filter-row.tsx +77 -0
  80. package/docs/data-entry/segmented.tsx +40 -1
  81. package/docs/data-entry/select-matrix.tsx +1 -2
  82. package/docs/data-entry/select.tsx +108 -3
  83. package/docs/data-entry/slider.tsx +125 -47
  84. package/docs/feedback/dialog.tsx +1 -2
  85. package/docs/feedback/sheet.tsx +1 -2
  86. package/docs/layout/app-shell-states.tsx +143 -0
  87. package/docs/navigation/dropdown-menu.tsx +77 -6
  88. package/docs/navigation/tabs.tsx +72 -0
  89. package/docs/roadmap/ai-chat-components.md +1 -2
  90. package/docs/roadmap/parity-audit-data-entry.md +44 -33
  91. package/docs/roadmap/parity-audit-layout-navigation-general.md +304 -310
  92. package/docs/roadmap/parity-backlog.md +2 -3
  93. package/docs/roadmap/tree-components.md +0 -1
  94. package/package.json +25 -55
  95. package/scripts/_agent-setup.mjs +18 -0
  96. package/scripts/guinea-pig-skill.md +12 -6
  97. package/scripts/ui-audit.mjs +185 -7
  98. package/scripts/visual-audit-rules.mjs +0 -7
  99. package/scripts/visual-audit.mjs +6 -27
  100. package/dist/components/navigation/context-menu.d.ts +0 -21
  101. package/dist/components/navigation/context-menu.js +0 -149
  102. package/dist/components/navigation/menubar.d.ts +0 -28
  103. package/dist/components/navigation/menubar.js +0 -136
  104. package/dist/components/navigation/navigation-menu.d.ts +0 -10
  105. package/dist/components/navigation/navigation-menu.js +0 -91
  106. package/dist/components/ui/context-menu.d.ts +0 -1
  107. package/dist/components/ui/context-menu.js +0 -2
  108. package/dist/components/ui/menubar.d.ts +0 -1
  109. package/dist/components/ui/menubar.js +0 -2
  110. package/dist/components/ui/navigation-menu.d.ts +0 -1
  111. package/dist/components/ui/navigation-menu.js +0 -2
  112. package/docs/FRAME-A11Y-CI.md +0 -349
  113. package/docs/navigation/context-menu.tsx +0 -128
  114. package/docs/navigation/menubar.tsx +0 -141
  115. package/docs/navigation/navigation-menu.tsx +0 -158
@@ -17,116 +17,118 @@
17
17
  background: hsl(var(--background));
18
18
  }
19
19
 
20
- .app-root[data-collapsed="true"] {
21
- grid-template-columns: var(--app-shell-sidebar-collapsed-width) minmax(0, 1fr);
22
- }
20
+ @media (width > 56.25rem) {
21
+ .app-root[data-collapsed="true"] {
22
+ grid-template-columns: var(--app-shell-sidebar-collapsed-width) minmax(0, 1fr);
23
+ }
23
24
 
24
- .app-root[data-topbar-span="full"] {
25
- grid-template-areas:
26
- "topbar topbar"
27
- "sidebar main"
28
- "sidebar footer";
29
- }
25
+ .app-root[data-topbar-span="full"] {
26
+ grid-template-areas:
27
+ "topbar topbar"
28
+ "sidebar main"
29
+ "sidebar footer";
30
+ }
30
31
 
31
- .app-root[data-nav-rail][data-nav-rail-position="start"] {
32
- grid-template-areas:
33
- "navrail sidebar topbar"
34
- "navrail sidebar main"
35
- "navrail sidebar footer";
36
- grid-template-columns:
37
- var(--app-shell-nav-rail-width)
38
- var(--app-shell-sidebar-width)
39
- minmax(0, 1fr);
40
- }
32
+ .app-root[data-nav-rail][data-nav-rail-position="start"] {
33
+ grid-template-areas:
34
+ "navrail sidebar topbar"
35
+ "navrail sidebar main"
36
+ "navrail sidebar footer";
37
+ grid-template-columns:
38
+ var(--app-shell-nav-rail-width)
39
+ var(--app-shell-sidebar-width)
40
+ minmax(0, 1fr);
41
+ }
41
42
 
42
- .app-root[data-nav-rail][data-nav-rail-position="start"][data-topbar-span="full"] {
43
- grid-template-areas:
44
- "topbar topbar topbar"
45
- "navrail sidebar main"
46
- "navrail sidebar footer";
47
- }
43
+ .app-root[data-nav-rail][data-nav-rail-position="start"][data-topbar-span="full"] {
44
+ grid-template-areas:
45
+ "topbar topbar topbar"
46
+ "navrail sidebar main"
47
+ "navrail sidebar footer";
48
+ }
48
49
 
49
- .app-root[data-nav-rail][data-nav-rail-position="end"] {
50
- grid-template-areas:
51
- "sidebar topbar navrail"
52
- "sidebar main navrail"
53
- "sidebar footer navrail";
54
- grid-template-columns:
55
- var(--app-shell-sidebar-width)
56
- minmax(0, 1fr)
57
- var(--app-shell-nav-rail-width);
58
- }
50
+ .app-root[data-nav-rail][data-nav-rail-position="end"] {
51
+ grid-template-areas:
52
+ "sidebar topbar navrail"
53
+ "sidebar main navrail"
54
+ "sidebar footer navrail";
55
+ grid-template-columns:
56
+ var(--app-shell-sidebar-width)
57
+ minmax(0, 1fr)
58
+ var(--app-shell-nav-rail-width);
59
+ }
59
60
 
60
- .app-root[data-nav-rail][data-nav-rail-position="end"][data-topbar-span="full"] {
61
- grid-template-areas:
62
- "topbar topbar topbar"
63
- "sidebar main navrail"
64
- "sidebar footer navrail";
65
- }
61
+ .app-root[data-nav-rail][data-nav-rail-position="end"][data-topbar-span="full"] {
62
+ grid-template-areas:
63
+ "topbar topbar topbar"
64
+ "sidebar main navrail"
65
+ "sidebar footer navrail";
66
+ }
66
67
 
67
- .app-root[data-nav-rail][data-nav-rail-position="top"] {
68
- grid-template-areas:
69
- "navrail navrail"
70
- "sidebar topbar"
71
- "sidebar main"
72
- "sidebar footer";
73
- grid-template-columns: var(--app-shell-sidebar-width) minmax(0, 1fr);
74
- grid-template-rows:
75
- var(--app-shell-nav-rail-height)
76
- var(--app-shell-bar-height)
77
- minmax(0, 1fr)
78
- auto;
79
- }
68
+ .app-root[data-nav-rail][data-nav-rail-position="top"] {
69
+ grid-template-areas:
70
+ "navrail navrail"
71
+ "sidebar topbar"
72
+ "sidebar main"
73
+ "sidebar footer";
74
+ grid-template-columns: var(--app-shell-sidebar-width) minmax(0, 1fr);
75
+ grid-template-rows:
76
+ var(--app-shell-nav-rail-height)
77
+ var(--app-shell-bar-height)
78
+ minmax(0, 1fr)
79
+ auto;
80
+ }
80
81
 
81
- .app-root[data-nav-rail][data-nav-rail-position="top"][data-topbar-span="full"] {
82
- grid-template-areas:
83
- "navrail navrail"
84
- "topbar topbar"
85
- "sidebar main"
86
- "sidebar footer";
87
- }
82
+ .app-root[data-nav-rail][data-nav-rail-position="top"][data-topbar-span="full"] {
83
+ grid-template-areas:
84
+ "navrail navrail"
85
+ "topbar topbar"
86
+ "sidebar main"
87
+ "sidebar footer";
88
+ }
88
89
 
89
- .app-root[data-nav-rail][data-nav-rail-position="bottom"] {
90
- grid-template-areas:
91
- "sidebar topbar"
92
- "sidebar main"
93
- "sidebar footer"
94
- "navrail navrail";
95
- grid-template-columns: var(--app-shell-sidebar-width) minmax(0, 1fr);
96
- grid-template-rows:
97
- var(--app-shell-bar-height)
98
- minmax(0, 1fr)
99
- auto
100
- var(--app-shell-nav-rail-height);
101
- }
90
+ .app-root[data-nav-rail][data-nav-rail-position="bottom"] {
91
+ grid-template-areas:
92
+ "sidebar topbar"
93
+ "sidebar main"
94
+ "sidebar footer"
95
+ "navrail navrail";
96
+ grid-template-columns: var(--app-shell-sidebar-width) minmax(0, 1fr);
97
+ grid-template-rows:
98
+ var(--app-shell-bar-height)
99
+ minmax(0, 1fr)
100
+ auto
101
+ var(--app-shell-nav-rail-height);
102
+ }
102
103
 
103
- .app-root[data-nav-rail][data-nav-rail-position="bottom"][data-topbar-span="full"] {
104
- grid-template-areas:
105
- "topbar topbar"
106
- "sidebar main"
107
- "sidebar footer"
108
- "navrail navrail";
109
- }
104
+ .app-root[data-nav-rail][data-nav-rail-position="bottom"][data-topbar-span="full"] {
105
+ grid-template-areas:
106
+ "topbar topbar"
107
+ "sidebar main"
108
+ "sidebar footer"
109
+ "navrail navrail";
110
+ }
110
111
 
111
- .app-root[data-nav-rail][data-nav-rail-position="start"][data-collapsed="true"] {
112
- grid-template-columns:
113
- var(--app-shell-nav-rail-width)
114
- var(--app-shell-sidebar-collapsed-width)
115
- minmax(0, 1fr);
116
- }
112
+ .app-root[data-nav-rail][data-nav-rail-position="start"][data-collapsed="true"] {
113
+ grid-template-columns:
114
+ var(--app-shell-nav-rail-width)
115
+ var(--app-shell-sidebar-collapsed-width)
116
+ minmax(0, 1fr);
117
+ }
117
118
 
118
- .app-root[data-nav-rail][data-nav-rail-position="end"][data-collapsed="true"] {
119
- grid-template-columns:
120
- var(--app-shell-sidebar-collapsed-width)
121
- minmax(0, 1fr)
122
- var(--app-shell-nav-rail-width);
123
- }
119
+ .app-root[data-nav-rail][data-nav-rail-position="end"][data-collapsed="true"] {
120
+ grid-template-columns:
121
+ var(--app-shell-sidebar-collapsed-width)
122
+ minmax(0, 1fr)
123
+ var(--app-shell-nav-rail-width);
124
+ }
124
125
 
125
- .app-root[data-nav-rail]:is(
126
- [data-nav-rail-position="top"],
127
- [data-nav-rail-position="bottom"]
128
- )[data-collapsed="true"] {
129
- grid-template-columns: var(--app-shell-sidebar-collapsed-width) minmax(0, 1fr);
126
+ .app-root[data-nav-rail]:is(
127
+ [data-nav-rail-position="top"],
128
+ [data-nav-rail-position="bottom"]
129
+ )[data-collapsed="true"] {
130
+ grid-template-columns: var(--app-shell-sidebar-collapsed-width) minmax(0, 1fr);
131
+ }
130
132
  }
131
133
 
132
134
  .app-root[data-topbar="none"] {
@@ -817,51 +819,54 @@
817
819
  font-size: var(--font-size-base);
818
820
  }
819
821
 
820
- .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="start"] {
821
- grid-template-columns: var(--app-shell-nav-rail-width) minmax(0, 1fr);
822
- grid-template-areas: "navrail topbar" "navrail main" "navrail footer";
823
- }
824
- .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="start"][data-topbar-span="full"] {
825
- grid-template-areas: "topbar topbar" "navrail main" "navrail footer";
826
- }
827
- .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="end"] {
828
- grid-template-columns: minmax(0, 1fr) var(--app-shell-nav-rail-width);
829
- grid-template-areas: "topbar navrail" "main navrail" "footer navrail";
830
- }
831
- .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="end"][data-topbar-span="full"] {
832
- grid-template-areas: "topbar topbar" "main navrail" "footer navrail";
833
- }
822
+ @media (width > 56.25rem) {
823
+ .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="start"] {
824
+ grid-template-columns: var(--app-shell-nav-rail-width) minmax(0, 1fr);
825
+ grid-template-areas: "navrail topbar" "navrail main" "navrail footer";
826
+ }
827
+ .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="start"][data-topbar-span="full"] {
828
+ grid-template-areas: "topbar topbar" "navrail main" "navrail footer";
829
+ }
830
+ .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="end"] {
831
+ grid-template-columns: minmax(0, 1fr) var(--app-shell-nav-rail-width);
832
+ grid-template-areas: "topbar navrail" "main navrail" "footer navrail";
833
+ }
834
+ .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="end"][data-topbar-span="full"] {
835
+ grid-template-areas: "topbar topbar" "main navrail" "footer navrail";
836
+ }
834
837
 
835
- .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="top"] {
836
- grid-template-columns: minmax(0, 1fr);
837
- grid-template-areas: "navrail" "topbar" "main" "footer";
838
- grid-template-rows:
839
- var(--app-shell-nav-rail-height)
840
- var(--app-shell-bar-height)
841
- minmax(0, 1fr)
842
- auto;
843
- }
844
- .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="top"][data-topbar-span="full"] {
845
- grid-template-areas: "navrail" "topbar" "main" "footer";
846
- }
847
- .app-root:where([data-sidebar="none"])[data-nav-rail]:is(
848
- [data-nav-rail-position="bottom"]
849
- ) {
850
- grid-template-columns: minmax(0, 1fr);
851
- grid-template-areas: "topbar" "main" "footer" "navrail";
852
- grid-template-rows:
853
- var(--app-shell-bar-height)
854
- minmax(0, 1fr)
855
- auto
856
- var(--app-shell-nav-rail-height);
838
+ .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="top"] {
839
+ grid-template-columns: minmax(0, 1fr);
840
+ grid-template-areas: "navrail" "topbar" "main" "footer";
841
+ grid-template-rows:
842
+ var(--app-shell-nav-rail-height)
843
+ var(--app-shell-bar-height)
844
+ minmax(0, 1fr)
845
+ auto;
846
+ }
847
+ .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="top"][data-topbar-span="full"] {
848
+ grid-template-areas: "navrail" "topbar" "main" "footer";
849
+ }
850
+ .app-root:where([data-sidebar="none"])[data-nav-rail]:is(
851
+ [data-nav-rail-position="bottom"]
852
+ ) {
853
+ grid-template-columns: minmax(0, 1fr);
854
+ grid-template-areas: "topbar" "main" "footer" "navrail";
855
+ grid-template-rows:
856
+ var(--app-shell-bar-height)
857
+ minmax(0, 1fr)
858
+ auto
859
+ var(--app-shell-nav-rail-height);
860
+ }
861
+
862
+ .app-root:where([data-sidebar="none"])[data-nav-rail][data-nav-rail-position="bottom"][data-topbar-span="full"] {
863
+ grid-template-areas: "topbar" "main" "footer" "navrail";
864
+ }
857
865
  }
858
866
 
859
867
  @media (width <= 56.25rem) {
860
- .app-root,
861
- .app-root[data-collapsed="true"],
862
- .app-root[data-nav-rail],
863
- .app-root[data-nav-rail][data-collapsed="true"],
864
- .app-root[data-nav-rail][data-topbar-span="full"] {
868
+
869
+ .app-root {
865
870
  grid-template-areas:
866
871
  "topbar"
867
872
  "main"
@@ -2317,6 +2322,10 @@
2317
2322
  .ui-mobile-shell {
2318
2323
  --control-height: var(--mobile-shell-control-height);
2319
2324
 
2325
+ --control-height-sm: calc(var(--control-height) - calc(0.25rem * var(--scaling)));
2326
+ --control-height-lg: calc(var(--control-height) + calc(0.25rem * var(--scaling)));
2327
+ --control-height-xs: calc(var(--control-height) - calc(0.5rem * var(--scaling)));
2328
+
2320
2329
  --mobile-shell-padding-inline: calc(
2321
2330
  var(--mobile-shell-inset-inline) + var(--mobile-shell-safe-inset-inline)
2322
2331
  );
@@ -44,8 +44,7 @@
44
44
  }
45
45
 
46
46
  .ui-table-row[data-tone] > [data-slot="table-cell"]:first-child {
47
- border-inline-start: var(--table-row-tone-rail-width) solid
48
- hsl(var(--table-row-tone-color));
47
+ border-inline-start: var(--table-row-tone-rail-width) solid hsl(var(--table-row-tone-color));
49
48
  padding-inline-start: calc(var(--table-cell-space-x) - var(--table-row-tone-rail-width));
50
49
  }
51
50
 
@@ -188,7 +187,7 @@
188
187
 
189
188
  overflow: clip;
190
189
 
191
- min-inline-size: var(--table-surface-min-inline-size);
190
+ min-inline-size: min-content;
192
191
  border: 1px solid hsl(var(--border));
193
192
  border-radius: var(--radius-md);
194
193
  }
@@ -197,11 +196,19 @@
197
196
  min-inline-size: 0;
198
197
  }
199
198
 
199
+ .ui-data-table-surface:not([data-preset]) > * > [data-slot="table"] {
200
+ min-inline-size: var(--table-surface-min-inline-size);
201
+ }
202
+
200
203
  .ui-data-table-surface[data-striped] tbody tr:nth-child(even):not([data-state="selected"]) {
201
204
  background-color: var(--table-row-striped-background, hsl(var(--muted) / 0.4));
202
205
  }
203
206
 
204
207
  .ui-data-table-empty {
208
+ padding: var(--empty-state-space-y) var(--empty-state-space-x);
209
+ }
210
+
211
+ .ui-data-table-empty .ui-empty-state {
205
212
  padding: 0;
206
213
  }
207
214
 
@@ -286,7 +293,7 @@
286
293
  inset-inline-end: 0;
287
294
  }
288
295
 
289
- .ui-data-table-surface {
296
+ .ui-data-table-surface:not([data-preset]) > * > [data-slot="table"] {
290
297
  min-inline-size: 0;
291
298
  }
292
299
  }
@@ -356,7 +363,7 @@
356
363
  max-block-size: var(--table-scroll-block-size, none);
357
364
  }
358
365
 
359
- .ui-data-table-scroll[data-scroll-x] :is(.ui-data-table-surface, [data-slot="table"]) {
366
+ .ui-data-table-scroll[data-scroll-x] [data-slot="table"] {
360
367
  min-inline-size: var(--table-scroll-inline-size, auto);
361
368
  }
362
369
 
@@ -32,6 +32,8 @@
32
32
  --control-status-warning-glow-color: var(--warning);
33
33
  --control-status-warning-glow-alpha: var(--control-outline-error-alpha);
34
34
 
35
+ --number-input-touch-height: var(--band-height-2xl);
36
+
35
37
  --control-variant-filled-background: var(--muted);
36
38
  --control-variant-filled-hover-background: var(--accent);
37
39
 
@@ -105,6 +107,8 @@
105
107
  --slider-track-height: 0.375rem;
106
108
  --slider-thumb-size: 1rem;
107
109
 
110
+ --slider-vertical-min-block-size: 10rem;
111
+
108
112
  --otp-slot-size: initial;
109
113
 
110
114
  --otp-slot-inline-size: initial;
@@ -198,6 +202,8 @@
198
202
  --search-select-panel-inline-size: auto;
199
203
  --search-select-panel-viewport-inset: var(--space-6);
200
204
  --search-select-list-space-inset: var(--space-1);
205
+
206
+ --search-select-list-max-height: none;
201
207
  --search-select-footer-space-inset: var(--space-1);
202
208
  --search-select-option-space-gap: var(--space-2);
203
209
  --search-select-option-font-size: var(--font-size-sm);
@@ -282,6 +288,8 @@
282
288
  --calendar-footer-space-block-start: var(--space-2);
283
289
  --calendar-footer-border-width: var(--stroke-hairline);
284
290
 
291
+ --calendar-bordered-weekday-padding-block: var(--space-1);
292
+
285
293
  --transfer-pane-min-height: 14rem;
286
294
  --transfer-pane-radius: var(--radius-md);
287
295
  --transfer-panes-space-gap: var(--space-3);
@@ -313,9 +321,9 @@
313
321
  --month-picker-icon-size: var(--icon-size-md);
314
322
  --month-picker-separator-icon-size: var(--icon-size-sm);
315
323
 
316
- --button-xs-height: var(--control-height-xs);
324
+ --button-xs-height: initial;
317
325
 
318
- --button-bare-target-size: var(--control-height-xs);
326
+ --button-bare-target-size: initial;
319
327
  --button-xs-space-inline: var(--space-2);
320
328
  --button-xs-space-gap: var(--space-1);
321
329
  --button-xs-font-size: var(--font-size-xs);
@@ -365,7 +373,8 @@
365
373
 
366
374
  --control-status-error-border-color: hsl(var(--destructive));
367
375
  --control-status-warning-border-color: hsl(var(--text-warning));
368
- --control-status-warning-outline-color: var(--warning);
376
+
377
+ --control-status-warning-outline-color: var(--text-warning);
369
378
  }
370
379
 
371
380
  @media (pointer: coarse) {
@@ -93,11 +93,6 @@
93
93
  --qr-code-size-md: 10rem;
94
94
  --qr-code-size-lg: 12.5rem;
95
95
 
96
- --scroll-area-bar-size: 0.625rem;
97
-
98
- --scroll-area-bar-padding: 1px;
99
- --scroll-area-thumb-radius: var(--radius-pill);
100
-
101
96
  --timeline-grid-hour-height: 2.5rem;
102
97
  --timeline-grid-axis-width: 3.25rem;
103
98
  --timeline-grid-column-min-width: 6rem;
@@ -37,10 +37,12 @@
37
37
  --breadcrumb-font-size: var(--font-size-xs);
38
38
 
39
39
  --breadcrumb-menu-trigger-gap: var(--space-inline-xs);
40
- --menubar-shortcut-font-size: var(--font-size-xs);
40
+ --menu-shortcut-font-size: var(--font-size-xs);
41
41
  --tabs-list-max-inline-size: 100%;
42
42
  --tabs-list-overflow: auto;
43
43
 
44
+ --tabs-placement-responsive-breakpoint-width: 48rem;
45
+
44
46
  --tabs-indicator-background: initial;
45
47
  --tabs-indicator-size: 2px;
46
48
  --tabs-indicator-offset: 0px;
@@ -89,8 +91,8 @@
89
91
  --tabs-tab-remove-icon-size: var(--icon-size-xs);
90
92
  --tabs-tab-remove-space-inline-end: var(--space-1);
91
93
 
92
- --menubar-item-hover-background: initial;
93
- --menubar-item-hover-foreground: initial;
94
+ --menu-item-hover-background: initial;
95
+ --menu-item-hover-foreground: initial;
94
96
 
95
97
  --filter-bar-sticky-offset: 0px;
96
98
 
@@ -128,8 +130,6 @@
128
130
  --menu-separator-space-block: var(--space-1);
129
131
  --menu-separator-space-inline: calc(var(--space-1) * -1);
130
132
 
131
- --navigation-menu-trigger-icon-size: var(--icon-size-sm);
132
-
133
133
  --steps-dot-size: 0.625rem;
134
134
  --steps-dot-process-ring-width: var(--stroke-xl);
135
135
  --steps-marker-border-width: var(--stroke-md);
@@ -1,5 +1,12 @@
1
1
 
2
2
  :root {
3
3
 
4
+ --scroll-area-scrollbar-width: thin;
5
+
6
+ --scroll-area-thumb-color: initial;
7
+ --scroll-area-track-color: initial;
8
+
9
+ --scroll-area-scrollbar-space: auto;
10
+
4
11
  --scroll-area-anchor-offset: 3rem;
5
12
  }
@@ -11,7 +11,12 @@ Read this once; the audit enforces it. Everything else in `docs/` is for contrib
11
11
  7. Colours are semantic tokens (`tone="destructive"`, `bg-primary`), never palette names, hex, or `bg-black` / `text-white`.
12
12
  8. Sizes come from props (`size`, `width`, `columns`), never `w-[240px]` / `max-h-[420px]`.
13
13
  9. Logical directions (`ms-`, `me-`, `start-`, `end-`) when a utility is unavoidable; never `ml-` / `left-`.
14
- 10. Run `node node_modules/@godxjp/ui/scripts/ui-audit.mjs <dir>` before every review; then `visual-audit.mjs <url>` on the running app. Zero errors is the bar.
14
+ 10. A `Card` whose whole body is a table gets `<CardContent flush>` the table must touch the
15
+ card's inner edge. A default `CardContent` pads 16px while the table draws its own border, so
16
+ the table reads as a second box inside the card, and a wide one runs past the card entirely.
17
+ (`flush` alone is enough: it drops the border, the radius and the inline padding. `tight` is a
18
+ different knob — it governs the header band, not the body's edges.)
19
+ 11. Run `node node_modules/@godxjp/ui/scripts/ui-audit.mjs --changed` before every review; a browser sweep with `visual-audit.mjs` is a separate, heavier run — do it when the work is a visual review, not on every change; `visual-audit.mjs <url>` on the running app. Zero errors is the bar.
15
20
 
16
21
  **Opting a deliberate exception out.** Name the rule; the block form also has to say why.
17
22
 
@@ -45,6 +50,6 @@ information belongs on the screen:
45
50
  - `ServiceLauncherCard` already has this shape as a prop — `disabledReason`, rendered above the
46
51
  action — and it is the pattern to copy anywhere else.
47
52
 
48
- If the control is disabled *pending something the user can fix*, prefer leaving it enabled and
53
+ If the control is disabled _pending something the user can fix_, prefer leaving it enabled and
49
54
  explaining on submit: an inert control with a paragraph beside it is often a validation message
50
55
  wearing a disguise.
@@ -56,7 +56,13 @@ overwrites `--font-sans-base` (and `--font-sans-vi`) with the bundled stack —
56
56
  Noto Sans JP + Montserrat; v18.12.0–18.12.19 bundled M PLUS 2 + Noto Sans JP;
57
57
  v18.12.20+ bundles Noto Sans JP + M PLUS 2 (product override, direct
58
58
  instruction). If your design spec named an earlier bundle's faces, set the
59
- tokens yourself rather than relying on the bundle.) Headings read
59
+ tokens yourself rather than relying on the bundle.) Second in that stack is
60
+ `"Noto Sans JP Fallback"`: local faces (Arial / Liberation Sans for Latin, the
61
+ platform's gothic face for Japanese) with `size-adjust` and ascent/descent
62
+ overrides tuned to Noto Sans JP. The bundled faces are `font-display: swap`, so
63
+ a cold visit paints in this fallback first; because it occupies the same line
64
+ boxes and nearly the same advances, the swap does not reflow the page (#475).
65
+ If you restate the stack yourself, keep it directly after "Noto Sans JP". Headings read
60
66
  `--font-family-display` and body reads `--font-family-body`, both defaulting to
61
67
  `--font-family-sans` — override them for a dual-font (display + body) brand.
62
68
 
@@ -83,7 +89,7 @@ Import the styles, then set anchor tokens in your app's `theme.css` (loaded afte
83
89
 
84
90
  /* ── Shadow tint — ONE knob ─────────────────────────────────────── */ --shadow-color: 12 26 49; /* RGB channels (default 0 0 0). Tints the WHOLE shadow ramp. */
85
91
 
86
- /* ── Brand depth — all opt-in, all quiet by default ─────────────── */ --shadow-glow: 0 8px 20px hsl(var(--primary) / 0.32); /* glow halo on the primary CTA */ --card-shadow: 0 1px 2px rgb(12 26 49 / 0.06), 0 10px 28px -14px rgb(12 26 49 / 0.2); /* lift every Card */ --focus-ring-color: var(--ring); /* hue of every focus ring */ --focus-ring-width: 2px; /* thickness of every focus ring — 0 turns it OFF */ --focus-ring-opacity: 1; /* alpha of every focus ring */ --focus-ring-offset: 0px; /* gap, outline-form rings only (star, dot, anchor) */ --gradient-hero: linear-gradient( 180deg, hsl(var(--accent)), transparent ); /* PageContainer header banner */ --gradient-glow: radial-gradient( 60% 70% at 90% -8%, hsl(var(--primary) / 0.1), transparent 70% ); /* AppShell ambient wash */ --overlay-background: rgb(12 26 49 / 0.55); /* modal scrim (Dialog / Sheet / Drawer) */ } ```
92
+ /* ── Brand depth — all opt-in, all quiet by default ─────────────── */ --shadow-glow: 0 8px 20px hsl(var(--primary) / 0.32); /* glow halo on the primary CTA */ --card-shadow: 0 1px 2px rgb(12 26 49 / 0.06), 0 10px 28px -14px rgb(12 26 49 / 0.2); /* lift every Card */ --focus-ring-color: var(--ring); /* hue of every focus ring */ --focus-ring-weight: var(--stroke-md); /* thickness of every focus ring — 2px; nothing paints until <html data-focus-outline="on"> */ --focus-ring-opacity: 1; /* alpha of every focus ring */ --focus-ring-offset: 0px; /* gap, outline-form rings only (star, dot, anchor) */ --gradient-hero: linear-gradient( 180deg, hsl(var(--accent)), transparent ); /* PageContainer header banner */ --gradient-glow: radial-gradient( 60% 70% at 90% -8%, hsl(var(--primary) / 0.1), transparent 70% ); /* AppShell ambient wash */ --overlay-background: rgb(12 26 49 / 0.55); /* modal scrim (Dialog / Sheet / Drawer) */ } ```
87
93
 
88
94
  ### The anchor tokens (single knobs that propagate)
89
95
 
@@ -95,23 +101,33 @@ Import the styles, then set anchor tokens in your app's `theme.css` (loaded afte
95
101
  | `--shadow-color` | `0 0 0` | every shadow step `--shadow-{xs…2xl}` (`rgb(color / α)`) |
96
102
  | `--shadow-glow` | invisible | brand glow halo on the primary CTA (set the full shadow value) |
97
103
  | `--card-shadow` | `none` | resting elevation of every Card |
98
- | `--focus-ring-color` / `--focus-ring-width` | `var(--ring)` / `2px` | hue & thickness of every keyboard-focus ring (`width: 0` turns every ring OFF) |
104
+ | `--focus-ring-color` / `--focus-ring-weight` | `var(--ring)` / `1px` | hue & thickness of every keyboard-focus ring but nothing paints until the switch below is on |
99
105
  | `--focus-ring-opacity` / `--focus-ring-offset` | `1` / `0px` | alpha of every ring · gap for outline-form rings (star, carousel dot, heading anchor) |
100
106
  | `--gradient-{hero,glow,brand}` | `none` | hero header banner / AppShell ambient wash / spare (set the full gradient) |
101
107
  | `--overlay-background` | `rgb(0 0 0 / .5)` | the scrim of every overlay (Dialog / AlertDialog / Sheet / Drawer) |
102
108
 
103
- ### Focus ring — one definition, three levels of override
109
+ ### Focus ring — THE SWITCH FIRST, then three levels of override
104
110
 
105
- Every keyboard-focus ring in the system is drawn by a single rule (`src/styles/focus-ring.css`) reading the four tokens above. Nothing else paints one; a test fails the build if a stylesheet tries.
111
+ **The indicator ships OFF.** `--focus-outline` is `0`, and every painted focus length multiplies by it, so by default nothing paints a focus mark. That is a product decision with a stated cost — it forfeits WCAG 2.2 SC 2.4.7 (AA) and a JIS X 8341-3 AA claim — recorded in `docs/DESIGN-AUTHORITY.md`. Turning it on is ONE attribute on the root element, no CSS:
106
112
 
107
- That means retuning is a one-liner and it reaches everything:
113
+ ```html
114
+ <html data-focus-outline="on"></html>
115
+ ```
116
+
117
+ (`AppProvider` has the equivalent.) Every `:focus-visible` selector is present either way; only the paint is switched.
118
+
119
+ Every ring is then drawn by a single rule (`src/styles/focus-ring.css`) reading the tokens above. Nothing else paints one; a test fails the build if a stylesheet tries.
120
+
121
+ **Thickness is `--focus-ring-weight`, never `--focus-ring-width`.** The width is DERIVED — `calc(var(--focus-ring-weight) * var(--focus-outline))` — so assigning it directly paints a ring even while the indicator is switched off, and that is exactly what the build-failing test forbids a stylesheet to do.
108
122
 
109
123
  ```css
110
124
  :root {
111
125
  --focus-ring-color: 24 99% 46%; /* every ring, brand orange */
112
- --focus-ring-width: 3px; /* every ring, thicker */
126
+ --focus-ring-weight: var(--stroke-md); /* every ring, 2px */
113
127
  }
114
- ````
128
+ ```
129
+
130
+ **A slim ring that still satisfies the criteria.** Switched on, the shipped weight is one hairline (1px) in the focus hue, measured in Chromium at **5.05:1** light and **7.07:1** dark on every surface a control sits on — so SC 1.4.11 (3:1, non-text contrast) is met on colour, independent of thickness. SC 2.4.13 Focus Appearance (AAA) additionally wants a perimeter of at least 2 CSS px: set `--focus-ring-weight: var(--stroke-md)` (measured: a 2px ring, same hue, same ratio). `var(--stroke-lg)` is the heavy 3px mark.
115
131
 
116
132
  **Per component.** A component that genuinely needs a different ring publishes its own knob and the rule picks it up locally — Toggle and TimeInput ship a heavier, softer ring because they are filled surfaces where a hard 2px reads as a second border:
117
133
 
@@ -130,7 +146,7 @@ That means retuning is a one-liner and it reaches everything:
130
146
  <div style={{ "--focus-ring-color": "0 84% 60%" } as React.CSSProperties}>…</div>
131
147
  ```
132
148
 
133
- **Turning it off** — `--focus-ring-width: 0`, at any of the three levels. It ships **on** (WCAG 2.4.7 / 2.4.11); switching it off is a deliberate act on your side, never a default of this package. Removing the visible focus indicator fails WCAG 2.4.7do it only where another indicator takes over.
149
+ **Turning it back off** — drop the `data-focus-outline` attribute (or set `--focus-outline: 0`), which is the shipped state. Do NOT reach for `--focus-ring-width`: it is derived from the weight and the switch, and pinning it to any value is the same mistake in the other direction. Note the cost either way with no visible focus indicator the package does not meet WCAG 2.2 SC 2.4.7.
134
150
 
135
151
  **Adding your own component to the system**: put `ui-focus-ring` (or `ui-focus-ring-outline` when the mark needs a gap) on the focusable element.
136
152
 
package/docs/DATETIME.md CHANGED
@@ -23,10 +23,18 @@ Omit `locale`, `timezone`, `timeFormat`, `dateFormat` → synced from AppProvide
23
23
 
24
24
  | value | Pattern | Default locale |
25
25
  | ----- | ------------ | -------------- |
26
- | `iso` | `yyyy-MM-dd` | ja |
26
+ | `iso` | `yyyy-MM-dd` | |
27
+ | `ymd` | `yyyy/MM/dd` | ja |
27
28
  | `dmy` | `dd/MM/yyyy` | vi |
28
29
  | `mdy` | `MM/dd/yyyy` | en |
29
30
 
31
+ `ymd` and `iso` are both year-first and are NOT interchangeable: a Japanese business document
32
+ (請求書, 申請書) is written `2026/05/01`, never `2026-05-01`. `ja` defaulted to `iso` until a
33
+ Japanese-first consumer shipped its own date formatter as an explicit stopgap purely to get the
34
+ slashes — rule 1 above broken by this package's own default. Only the DEFAULT moved: a stored
35
+ preference still wins, `defaultDateFormat` still pins any value, and `iso` is one option away in
36
+ `<DateFormatPicker />`.
37
+
30
38
  Sent to backend as `x-date-format`. Pick with `<DateFormatPicker />`.
31
39
 
32
40
  ## kind presets
@@ -43,9 +51,10 @@ Sent to backend as `x-date-format`. Pick with `<DateFormatPicker />`.
43
51
 
44
52
  ## ISO 8601 patterns
45
53
 
46
- Date order follows `dateFormat` from AppProvider (`iso` | `dmy` | `mdy`):
54
+ Date order follows `dateFormat` from AppProvider (`iso` | `ymd` | `dmy` | `mdy`):
47
55
 
48
56
  - `iso`: `yyyy-MM-dd` + `yyyy-MM-dd HH:mm`
57
+ - `ymd`: `yyyy/MM/dd` + `yyyy/MM/dd HH:mm`
49
58
  - `dmy`: `dd/MM/yyyy` + `dd/MM/yyyy HH:mm`
50
59
  - `mdy`: `MM/dd/yyyy` + `MM/dd/yyyy HH:mm`
51
60