@godxjp/ui 21.0.0 → 23.0.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 (154) hide show
  1. package/README.md +4 -4
  2. package/dist/app/app-provider.js +2 -1
  3. package/dist/components/data-display/badge.d.ts +28 -1
  4. package/dist/components/data-display/badge.js +2 -0
  5. package/dist/components/data-display/data-table.d.ts +18 -2
  6. package/dist/components/data-display/data-table.js +4 -0
  7. package/dist/components/data-display/index.d.ts +1 -1
  8. package/dist/components/data-display/popover.d.ts +19 -1
  9. package/dist/components/data-display/popover.js +9 -1
  10. package/dist/components/data-display/progress.d.ts +37 -0
  11. package/dist/components/data-display/progress.js +57 -5
  12. package/dist/components/data-display/scroll-area.d.ts +24 -4
  13. package/dist/components/data-display/scroll-area.js +34 -72
  14. package/dist/components/data-entry/cascader.js +8 -6
  15. package/dist/components/data-entry/checkbox.js +2 -0
  16. package/dist/components/data-entry/choice-hit-target.d.ts +24 -0
  17. package/dist/components/data-entry/choice-hit-target.js +12 -0
  18. package/dist/components/data-entry/control-surface.d.ts +8 -0
  19. package/dist/components/data-entry/control-surface.js +10 -1
  20. package/dist/components/data-entry/date-picker.d.ts +10 -3
  21. package/dist/components/data-entry/date-picker.js +503 -238
  22. package/dist/components/data-entry/form-field.d.ts +1 -1
  23. package/dist/components/data-entry/form-field.js +7 -3
  24. package/dist/components/data-entry/form.js +10 -1
  25. package/dist/components/data-entry/index.d.ts +0 -6
  26. package/dist/components/data-entry/index.js +0 -6
  27. package/dist/components/data-entry/label.d.ts +14 -1
  28. package/dist/components/data-entry/label.js +6 -1
  29. package/dist/components/data-entry/radio.d.ts +27 -6
  30. package/dist/components/data-entry/radio.js +89 -43
  31. package/dist/components/data-entry/search-select.js +226 -89
  32. package/dist/components/data-entry/select.d.ts +76 -14
  33. package/dist/components/data-entry/select.js +497 -163
  34. package/dist/components/data-entry/slider.d.ts +3 -11
  35. package/dist/components/data-entry/slider.js +582 -93
  36. package/dist/components/data-entry/switch.d.ts +6 -3
  37. package/dist/components/data-entry/switch.js +36 -11
  38. package/dist/components/layout/mobile-shell.d.ts +1 -1
  39. package/dist/components/layout/mobile-shell.js +2 -0
  40. package/dist/components/navigation/dropdown-menu.d.ts +11 -3
  41. package/dist/components/navigation/dropdown-menu.js +190 -15
  42. package/dist/components/navigation/index.d.ts +0 -3
  43. package/dist/components/navigation/index.js +0 -78
  44. package/dist/components/navigation/steps.d.ts +1 -1
  45. package/dist/components/navigation/steps.js +3 -1
  46. package/dist/components/navigation/tabs-scroll.d.ts +27 -0
  47. package/dist/components/navigation/tabs-scroll.js +52 -1
  48. package/dist/components/navigation/tabs.d.ts +2 -2
  49. package/dist/components/navigation/tabs.js +88 -23
  50. package/dist/components/ui/index.d.ts +0 -4
  51. package/dist/components/ui/index.js +0 -4
  52. package/dist/components/ui/input-otp.d.ts +1 -1
  53. package/dist/components/ui/segmented.d.ts +15 -1
  54. package/dist/components/ui/segmented.js +15 -6
  55. package/dist/components/ui/tag-input.js +3 -5
  56. package/dist/i18n/messages/en.json +3 -2
  57. package/dist/i18n/messages/ja.json +3 -2
  58. package/dist/i18n/messages/vi.json +3 -2
  59. package/dist/lib/datetime/picker-format.d.ts +18 -0
  60. package/dist/lib/datetime/picker-format.js +35 -1
  61. package/dist/lib/field-a11y.d.ts +12 -0
  62. package/dist/lib/field-a11y.js +14 -1
  63. package/dist/lib/select-options.d.ts +21 -0
  64. package/dist/lib/select-options.js +46 -0
  65. package/dist/props/components/data-display.prop.d.ts +16 -6
  66. package/dist/props/components/data-entry.prop.d.ts +503 -129
  67. package/dist/props/components/index.d.ts +2 -2
  68. package/dist/props/components/layout.prop.d.ts +12 -1
  69. package/dist/props/components/navigation.prop.d.ts +93 -1
  70. package/dist/props/registry.d.ts +79 -16
  71. package/dist/props/registry.js +85 -15
  72. package/dist/props/vocabulary/data.prop.d.ts +12 -0
  73. package/dist/props/vocabulary/index.d.ts +2 -2
  74. package/dist/props/vocabulary/layout.prop.d.ts +11 -0
  75. package/dist/styles/badge-layout.css +4 -0
  76. package/dist/styles/card-layout.css +6 -6
  77. package/dist/styles/control.css +220 -29
  78. package/dist/styles/data-display-layout.css +94 -23
  79. package/dist/styles/focus-ring.css +6 -4
  80. package/dist/styles/fonts.css +88 -4
  81. package/dist/styles/navigation-layout.css +36 -236
  82. package/dist/styles/shell-layout.css +149 -139
  83. package/dist/styles/table-layout.css +41 -3
  84. package/dist/tokens/components/control.css +4 -0
  85. package/dist/tokens/components/data-display.css +9 -5
  86. package/dist/tokens/components/navigation.css +9 -5
  87. package/dist/tokens/components/scroll-area.css +7 -0
  88. package/dist/tokens/components/segmented.css +0 -2
  89. package/dist/tokens/components/shell.css +2 -0
  90. package/dist/tokens/components/table.css +3 -0
  91. package/dist/tokens/foundation.css +7 -0
  92. package/docs/COMPONENTS.md +14 -14
  93. package/docs/CONSUMER-RULES.md +24 -1
  94. package/docs/CUSTOMER-THEMING.md +7 -1
  95. package/docs/FRAME-COVERAGE-REPORT.md +5 -11
  96. package/docs/TOKENS.md +65 -0
  97. package/docs/data-display/badge.tsx +37 -0
  98. package/docs/data-display/data-table/index.tsx +45 -1
  99. package/docs/data-display/popover.tsx +43 -5
  100. package/docs/data-display/progress.tsx +28 -0
  101. package/docs/data-display/scroll-area.tsx +51 -45
  102. package/docs/data-entry/calendar.tsx +2 -2
  103. package/docs/data-entry/date-picker.tsx +144 -5
  104. package/docs/data-entry/form/examples/invoice-form.tsx +2 -2
  105. package/docs/data-entry/form-field/examples/a11y-contract.tsx +3 -5
  106. package/docs/data-entry/form.tsx +4 -4
  107. package/docs/data-entry/input-otp.tsx +5 -2
  108. package/docs/data-entry/number-input.tsx +31 -0
  109. package/docs/data-entry/segmented.tsx +143 -2
  110. package/docs/data-entry/select-matrix.tsx +1 -2
  111. package/docs/data-entry/select.tsx +108 -3
  112. package/docs/data-entry/slider.tsx +125 -47
  113. package/docs/feedback/dialog.tsx +1 -2
  114. package/docs/feedback/sheet.tsx +1 -2
  115. package/docs/layout/app-shell-states.tsx +143 -0
  116. package/docs/layout/mobile-shell.tsx +5 -0
  117. package/docs/navigation/dropdown-menu.tsx +75 -4
  118. package/docs/navigation/tabs.tsx +149 -0
  119. package/docs/roadmap/antd-parity.md +35 -34
  120. package/docs/roadmap/parity-audit-data-entry.md +196 -172
  121. package/docs/roadmap/parity-audit-layout-navigation-general.md +304 -310
  122. package/docs/roadmap/parity-backlog.md +8 -10
  123. package/docs/showcase/acme-portal.tsx +7 -0
  124. package/package.json +28 -64
  125. package/scripts/ui-audit.mjs +18 -5
  126. package/scripts/visual-audit-rules.mjs +0 -7
  127. package/scripts/visual-audit.mjs +6 -27
  128. package/dist/components/data-entry/date-range-picker.d.ts +0 -11
  129. package/dist/components/data-entry/date-range-picker.js +0 -349
  130. package/dist/components/data-entry/month-picker.d.ts +0 -10
  131. package/dist/components/data-entry/month-picker.js +0 -241
  132. package/dist/components/data-entry/month-range-picker.d.ts +0 -10
  133. package/dist/components/data-entry/month-range-picker.js +0 -301
  134. package/dist/components/navigation/context-menu.d.ts +0 -21
  135. package/dist/components/navigation/context-menu.js +0 -149
  136. package/dist/components/navigation/menubar.d.ts +0 -21
  137. package/dist/components/navigation/menubar.js +0 -136
  138. package/dist/components/navigation/navigation-menu.d.ts +0 -10
  139. package/dist/components/navigation/navigation-menu.js +0 -91
  140. package/dist/components/ui/context-menu.d.ts +0 -1
  141. package/dist/components/ui/context-menu.js +0 -2
  142. package/dist/components/ui/date-range-picker.d.ts +0 -1
  143. package/dist/components/ui/date-range-picker.js +0 -2
  144. package/dist/components/ui/menubar.d.ts +0 -1
  145. package/dist/components/ui/menubar.js +0 -2
  146. package/dist/components/ui/navigation-menu.d.ts +0 -1
  147. package/dist/components/ui/navigation-menu.js +0 -2
  148. package/docs/FRAME-A11Y-CI.md +0 -349
  149. package/docs/data-entry/date-range-picker.tsx +0 -175
  150. package/docs/data-entry/month-picker.tsx +0 -101
  151. package/docs/data-entry/month-range-picker.tsx +0 -115
  152. package/docs/navigation/context-menu.tsx +0 -128
  153. package/docs/navigation/menubar.tsx +0 -141
  154. 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"
@@ -2332,6 +2337,11 @@
2332
2337
  --mobile-shell-block-size: 100%;
2333
2338
  }
2334
2339
 
2340
+ .ui-mobile-shell[data-width="phone"] {
2341
+ max-inline-size: var(--mobile-shell-max-inline-size);
2342
+ margin-inline: auto;
2343
+ }
2344
+
2335
2345
  .ui-mobile-shell-chrome {
2336
2346
  display: flex;
2337
2347
  min-inline-size: 0;
@@ -15,6 +15,40 @@
15
15
  border-block-end-width: 0;
16
16
  }
17
17
 
18
+ .ui-table-row[data-tone="primary"] {
19
+ --table-row-tone-color: var(--mark-primary);
20
+ }
21
+
22
+ .ui-table-row[data-tone="success"] {
23
+ --table-row-tone-color: var(--mark-success);
24
+ }
25
+
26
+ .ui-table-row[data-tone="warning"] {
27
+ --table-row-tone-color: var(--mark-warning);
28
+ }
29
+
30
+ .ui-table-row[data-tone="info"] {
31
+ --table-row-tone-color: var(--mark-info);
32
+ }
33
+
34
+ .ui-table-row[data-tone="attention"] {
35
+ --table-row-tone-color: var(--mark-attention);
36
+ }
37
+
38
+ .ui-table-row[data-tone="destructive"] {
39
+ --table-row-tone-color: var(--mark-destructive);
40
+ }
41
+
42
+ .ui-table-row[data-tone] {
43
+ background: hsl(var(--table-row-tone-color) / var(--table-row-tone-wash-alpha));
44
+ }
45
+
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));
49
+ padding-inline-start: calc(var(--table-cell-space-x) - var(--table-row-tone-rail-width));
50
+ }
51
+
18
52
  [data-slot="table-head"] {
19
53
  height: var(--table-row-height);
20
54
  padding: var(--table-cell-padding-y) var(--table-cell-space-x);
@@ -154,7 +188,7 @@
154
188
 
155
189
  overflow: clip;
156
190
 
157
- min-inline-size: var(--table-surface-min-inline-size);
191
+ min-inline-size: min-content;
158
192
  border: 1px solid hsl(var(--border));
159
193
  border-radius: var(--radius-md);
160
194
  }
@@ -163,6 +197,10 @@
163
197
  min-inline-size: 0;
164
198
  }
165
199
 
200
+ .ui-data-table-surface:not([data-preset]) > * > [data-slot="table"] {
201
+ min-inline-size: var(--table-surface-min-inline-size);
202
+ }
203
+
166
204
  .ui-data-table-surface[data-striped] tbody tr:nth-child(even):not([data-state="selected"]) {
167
205
  background-color: var(--table-row-striped-background, hsl(var(--muted) / 0.4));
168
206
  }
@@ -252,7 +290,7 @@
252
290
  inset-inline-end: 0;
253
291
  }
254
292
 
255
- .ui-data-table-surface {
293
+ .ui-data-table-surface:not([data-preset]) > * > [data-slot="table"] {
256
294
  min-inline-size: 0;
257
295
  }
258
296
  }
@@ -322,7 +360,7 @@
322
360
  max-block-size: var(--table-scroll-block-size, none);
323
361
  }
324
362
 
325
- .ui-data-table-scroll[data-scroll-x] :is(.ui-data-table-surface, [data-slot="table"]) {
363
+ .ui-data-table-scroll[data-scroll-x] [data-slot="table"] {
326
364
  min-inline-size: var(--table-scroll-inline-size, auto);
327
365
  }
328
366
 
@@ -105,6 +105,8 @@
105
105
  --slider-track-height: 0.375rem;
106
106
  --slider-thumb-size: 1rem;
107
107
 
108
+ --slider-vertical-min-block-size: 10rem;
109
+
108
110
  --otp-slot-size: initial;
109
111
 
110
112
  --otp-slot-inline-size: initial;
@@ -198,6 +200,8 @@
198
200
  --search-select-panel-inline-size: auto;
199
201
  --search-select-panel-viewport-inset: var(--space-6);
200
202
  --search-select-list-space-inset: var(--space-1);
203
+
204
+ --search-select-list-max-height: none;
201
205
  --search-select-footer-space-inset: var(--space-1);
202
206
  --search-select-option-space-gap: var(--space-2);
203
207
  --search-select-option-font-size: var(--font-size-sm);
@@ -65,6 +65,15 @@
65
65
  --progress-breakdown-block-size: 1.375rem;
66
66
  --progress-breakdown-radius: var(--radius);
67
67
 
68
+ --progress-meter-block-size: 0.5rem;
69
+ --progress-meter-block-size-sm: 0.25rem;
70
+ --progress-breakdown-block-size-sm: 0.5rem;
71
+
72
+ --progress-ring-size: 2.75rem;
73
+ --progress-ring-size-sm: 2rem;
74
+ --progress-ring-border-width: var(--stroke-lg);
75
+ --progress-ring-label-font-size: var(--font-size-xs);
76
+
68
77
  --legend-gap: 0.875rem;
69
78
  --legend-item-gap: 0.3125rem;
70
79
  --legend-swatch-size: 0.625rem;
@@ -84,11 +93,6 @@
84
93
  --qr-code-size-md: 10rem;
85
94
  --qr-code-size-lg: 12.5rem;
86
95
 
87
- --scroll-area-bar-size: 0.625rem;
88
-
89
- --scroll-area-bar-padding: 1px;
90
- --scroll-area-thumb-radius: var(--radius-pill);
91
-
92
96
  --timeline-grid-hour-height: 2.5rem;
93
97
  --timeline-grid-axis-width: 3.25rem;
94
98
  --timeline-grid-column-min-width: 6rem;
@@ -37,7 +37,7 @@
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
 
@@ -49,6 +49,8 @@
49
49
 
50
50
  --tabs-list-line-space-inset: 0px;
51
51
 
52
+ --tabs-list-line-space-gap: 0.25rem;
53
+
52
54
  --tabs-list-focus-ring-space-inset: initial;
53
55
 
54
56
  --tabs-trigger-line-radius: 0px;
@@ -74,6 +76,10 @@
74
76
 
75
77
  --tabs-bar-gap: var(--space-2);
76
78
  --tabs-extra-gap: var(--space-2);
79
+
80
+ --tabs-overflow-size: var(--band-height-md);
81
+ --tabs-overflow-radius: var(--radius-md);
82
+ --tabs-overflow-icon-size: var(--control-icon-size);
77
83
  --tabs-add-size: var(--band-height-md);
78
84
  --tabs-add-radius: var(--radius-md);
79
85
  --tabs-add-icon-size: var(--control-icon-size);
@@ -83,8 +89,8 @@
83
89
  --tabs-tab-remove-icon-size: var(--icon-size-xs);
84
90
  --tabs-tab-remove-space-inline-end: var(--space-1);
85
91
 
86
- --menubar-item-hover-background: initial;
87
- --menubar-item-hover-foreground: initial;
92
+ --menu-item-hover-background: initial;
93
+ --menu-item-hover-foreground: initial;
88
94
 
89
95
  --filter-bar-sticky-offset: 0px;
90
96
 
@@ -122,8 +128,6 @@
122
128
  --menu-separator-space-block: var(--space-1);
123
129
  --menu-separator-space-inline: calc(var(--space-1) * -1);
124
130
 
125
- --navigation-menu-trigger-icon-size: var(--icon-size-sm);
126
-
127
131
  --steps-dot-size: 0.625rem;
128
132
  --steps-dot-process-ring-width: var(--stroke-xl);
129
133
  --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
  }
@@ -9,8 +9,6 @@
9
9
  --segmented-track-radius: var(--radius);
10
10
  --segmented-item-radius: var(--radius-md);
11
11
 
12
- --segmented-item-height: calc(var(--control-height) - var(--segmented-track-padding) * 2);
13
-
14
12
  --segmented-item-padding-inline: calc(var(--control-padding-x) - 1px);
15
13
 
16
14
  --segmented-item-gap: calc(var(--space-3) / 2);
@@ -355,6 +355,8 @@
355
355
 
356
356
  :root {
357
357
  --mobile-shell-block-size: 100dvh;
358
+
359
+ --mobile-shell-max-inline-size: 26.875rem;
358
360
  --mobile-shell-safe-inset-block-start: env(safe-area-inset-top);
359
361
  --mobile-shell-safe-inset-block-end: env(safe-area-inset-bottom);
360
362
  --mobile-shell-safe-inset-inline: max(env(safe-area-inset-left), env(safe-area-inset-right));
@@ -91,4 +91,7 @@
91
91
  --table-row-border-width: var(--stroke-hairline);
92
92
 
93
93
  --table-flush-divider-width: var(--table-row-border-width);
94
+
95
+ --table-row-tone-rail-width: var(--stroke-2xl);
96
+ --table-row-tone-wash-alpha: 0.06;
94
97
  }
@@ -47,6 +47,13 @@
47
47
  --text-info: 221 70% 38%;
48
48
  --text-error: 357 75% 38%;
49
49
 
50
+ --mark-primary: var(--text-primary);
51
+ --mark-success: var(--text-success);
52
+ --mark-warning: var(--text-warning);
53
+ --mark-info: var(--text-info);
54
+ --mark-destructive: var(--text-error);
55
+ --mark-attention: var(--attention);
56
+
50
57
  --secondary-hover: 45 15% 91%;
51
58
  --secondary-active: 45 15% 88%;
52
59
 
@@ -48,8 +48,8 @@ All UI is **mobile-first**: base layout targets ~320–428px viewport; `sm` (640
48
48
 
49
49
  Default `direction="row"`; use `direction="col"` for vertical rhythm.
50
50
 
51
- | Component | Prop | Key props |
52
- | --------- | ---------- | ---------------------------------------------------------------------------------------------------- |
51
+ | Component | Prop | Key props |
52
+ | --------- | ---------- | ------------------------------------------------------------------------------------------------------------------- |
53
53
  | `Flex` | `FlexProp` | `direction: "row" \| "col"`, `gap: GapProp`, `gapRaw`, `pad`, `padRaw`, `fill`, `width`, `align`, `justify`, `wrap` |
54
54
 
55
55
  `fill` / `width` are the `fixed | elastic | fixed` row: `width` pins a column (number = px, and
@@ -82,25 +82,25 @@ and sets `min-inline-size: 0` so a truncating child ellipses instead of widening
82
82
  | `Textarea` | `TextareaProp` | extends native textarea |
83
83
  | `FormField` | `FormFieldProp` | `id`, `label`, `required`, `helper`, `error` |
84
84
  | `SearchInput` | `SearchInputProp` | `onSearchChange: OnSearchChangeProp` |
85
- | `Checkbox` | `CheckboxProp` | Radix checkbox; `Checkbox.Group` với `options` |
85
+ | `Checkbox` | `CheckboxProp` | Checkbox (RAC); `Checkbox.Group` với `options` |
86
86
  | `Radio` | `RadioGroupProp` | `Radio.Group` single-select; `Radio.Root` compound |
87
87
 
88
88
  ---
89
89
 
90
90
  ## Data Display
91
91
 
92
- | Component | Prop type | Key props |
93
- | -------------- | ------------------ | ---------------------------------------- |
94
- | `EmptyState` | `EmptyStateProp` | `icon`, `title`, `description`, `action` |
95
- | `DataTable` | `DataTableProp<T>` | `columns`, `density: TableDensityProp` |
96
- | `Descriptions` | `DescriptionsProp` | `items[]` |
97
- | `Badge` | `BadgeProp` | `status`, `tone: ToneProp` |
98
- | `Badge` | `BadgeProp` | shadcn badge variants |
92
+ | Component | Prop type | Key props |
93
+ | -------------- | ------------------ | ----------------------------------------- |
94
+ | `EmptyState` | `EmptyStateProp` | `icon`, `title`, `description`, `action` |
95
+ | `DataTable` | `DataTableProp<T>` | `columns`, `density: TableDensityProp` |
96
+ | `Descriptions` | `DescriptionsProp` | `items[]` |
97
+ | `Badge` | `BadgeProp` | `status`, `tone: ToneProp` |
98
+ | `Badge` | `BadgeProp` | shadcn badge variants |
99
99
  | `Progress` | `ProgressProp` | `value` (meter) \| `segments` (breakdown) |
100
- | `Legend` | `LegendProp` | `items[]` — the key for a tone |
101
- | `Popover` | Radix primitives | floating content panel |
102
- | `ScrollArea` | Radix primitives | scrollable regions |
103
- | `Collapsible` | Radix primitives | expand/collapse sections |
100
+ | `Legend` | `LegendProp` | `items[]` — the key for a tone |
101
+ | `Popover` | Radix primitives | floating content panel |
102
+ | `ScrollArea` | Radix primitives | scrollable regions |
103
+ | `Collapsible` | Radix primitives | expand/collapse sections |
104
104
 
105
105
  ---
106
106
 
@@ -6,7 +6,7 @@ Read this once; the audit enforces it. Everything else in `docs/` is for contrib
6
6
  2. Every page is `<PageContainer title subtitle extra footer>`; its sections are spaced by the page. Group items inside a section with `<Flex direction="col" gap>` or `<ResponsiveGrid>`.
7
7
  3. No Tailwind layout on your own elements: no `flex`, `grid`, `gap-*`, `p-*`, `m-*`, `space-*`. Rows are `<Flex>` (default row), stacks are `<Flex direction="col">`, grids are `<ResponsiveGrid>`.
8
8
  4. No hand-rolled surfaces: no `rounded-* border bg-*` divs. A box is `Card`, a pill is `Badge`, a person is `Avatar`, a row is `ListRow`, a label/value pair is `Descriptions`, an empty area is `EmptyState`.
9
- 5. Real controls only: `Button`, `Input`, `Select`, `Textarea`, `Checkbox`… never raw `<button>`/`<input>`; a labelled control lives in `<FormField label>`. A Select outside a form takes `width="auto"`.
9
+ 5. Real controls only: `Button`, `Input`, `Select`, `Textarea`, `Checkbox`… never raw `<button>`/`<input>`; a labelled control lives in `<FormField label>`. A Select outside a form takes `width="auto"`. **A disabled control's reason is visible text, never a tooltip** — see below.
10
10
  6. Text is `<Text>` / `<Heading>` with `tone`, `size`, `weight`, `truncate`, `mono` — not `className="text-muted-foreground font-semibold"`.
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]`.
@@ -25,3 +25,26 @@ const legacyClasses = ["gap-3", "p-2"];
25
25
  ```
26
26
 
27
27
  A block with no reason (or under 12 characters of it) is ignored and the finding stands; an unclosed block runs to the end of the file. The class-shaped rules (`gap-*`, `bg-red-500`, `w-[37px]`, `pr-*`, `dark:*`) only read class expressions — a `className`/`class` attribute, a class-named binding (`baseClass`, `statusStyles`, `badgeVariants`) or a `cn()`/`clsx()`/`cva()` call — so product copy or an i18n value that happens to spell a utility is never a finding.
28
+
29
+ ---
30
+
31
+ ## Why a disabled control's reason cannot be a tooltip
32
+
33
+ A disabled `<button>` receives no pointer events and is not in the tab order, so an explanation
34
+ attached to it never reaches anyone. Measured in Chromium on this package's own tooltip page: the
35
+ same trigger produced **1** tooltip on hover while enabled and **0** while disabled, and calling
36
+ `focus()` on it left `document.activeElement` as `BODY` — so keyboard and touch get nothing either.
37
+ Hover-only would fail a touch user in any case.
38
+
39
+ This is not a gap waiting for a DS prop. The reason is required information, and required
40
+ information belongs on the screen:
41
+
42
+ - Render it as a `<Text size="xs" tone="muted">` line **before** the control, so a screen-reader or
43
+ keyboard user meets the explanation ahead of the thing they cannot use (WCAG 2.2 · 1.3.2,
44
+ meaningful sequence).
45
+ - `ServiceLauncherCard` already has this shape as a prop — `disabledReason`, rendered above the
46
+ action — and it is the pattern to copy anywhere else.
47
+
48
+ If the control is disabled *pending something the user can fix*, prefer leaving it enabled and
49
+ explaining on submit: an inert control with a paragraph beside it is often a validation message
50
+ wearing a disguise.