@godxjp/ui 28.9.0 → 28.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.
Files changed (232) hide show
  1. package/agent/START-HERE.md +193 -0
  2. package/agent/anti-ai-tells.json +158 -0
  3. package/agent/components/Accordion.json +60 -0
  4. package/agent/components/AccountChip.json +59 -0
  5. package/agent/components/Actions.json +78 -0
  6. package/agent/components/Activity.json +80 -0
  7. package/agent/components/Affix.json +78 -0
  8. package/agent/components/Alert.json +65 -0
  9. package/agent/components/AlertDialog.json +109 -0
  10. package/agent/components/AlertDialogRoot.json +52 -0
  11. package/agent/components/Anchor.json +119 -0
  12. package/agent/components/AppLauncher.json +95 -0
  13. package/agent/components/AppProvider.json +105 -0
  14. package/agent/components/AppSettingPicker.json +88 -0
  15. package/agent/components/AppSettingToggle.json +70 -0
  16. package/agent/components/AppShell.json +159 -0
  17. package/agent/components/AreaChart.json +105 -0
  18. package/agent/components/AspectRatio.json +38 -0
  19. package/agent/components/Attachments.json +76 -0
  20. package/agent/components/AuthAccountSummary.json +64 -0
  21. package/agent/components/AuthDivider.json +35 -0
  22. package/agent/components/AuthFooter.json +48 -0
  23. package/agent/components/AuthIdentity.json +42 -0
  24. package/agent/components/AuthShell.json +108 -0
  25. package/agent/components/AuthStack.json +21 -0
  26. package/agent/components/Avatar.json +89 -0
  27. package/agent/components/Badge.json +96 -0
  28. package/agent/components/Banner.json +48 -0
  29. package/agent/components/BarChart.json +108 -0
  30. package/agent/components/BranchScopePicker.json +89 -0
  31. package/agent/components/Breadcrumb.json +54 -0
  32. package/agent/components/Button.json +133 -0
  33. package/agent/components/Calendar.json +259 -0
  34. package/agent/components/Callout.json +46 -0
  35. package/agent/components/Card.json +112 -0
  36. package/agent/components/CardBar.json +49 -0
  37. package/agent/components/CardContent.json +51 -0
  38. package/agent/components/Carousel.json +50 -0
  39. package/agent/components/Cascader.json +209 -0
  40. package/agent/components/CenteredShell.json +66 -0
  41. package/agent/components/ChatBubble.json +100 -0
  42. package/agent/components/ChatBubbleList.json +64 -0
  43. package/agent/components/ChatComposer.json +160 -0
  44. package/agent/components/ChatSuggestion.json +86 -0
  45. package/agent/components/Checkbox.json +68 -0
  46. package/agent/components/CheckboxGroup.json +96 -0
  47. package/agent/components/CodeBlock.json +64 -0
  48. package/agent/components/Collapsible.json +74 -0
  49. package/agent/components/ColorPicker.json +87 -0
  50. package/agent/components/Command.json +168 -0
  51. package/agent/components/CommandPalette.json +84 -0
  52. package/agent/components/CompactBarTrend.json +101 -0
  53. package/agent/components/Conversations.json +82 -0
  54. package/agent/components/CredentialReveal.json +93 -0
  55. package/agent/components/DataState.json +79 -0
  56. package/agent/components/DataTable.json +268 -0
  57. package/agent/components/DatePicker.json +275 -0
  58. package/agent/components/Descriptions.json +67 -0
  59. package/agent/components/Dialog.json +78 -0
  60. package/agent/components/DraggablePanel.json +106 -0
  61. package/agent/components/DropdownMenu.json +102 -0
  62. package/agent/components/EmptyState.json +83 -0
  63. package/agent/components/ErrorSurface.json +128 -0
  64. package/agent/components/FeatureList.json +43 -0
  65. package/agent/components/Field.json +64 -0
  66. package/agent/components/FilterBar.json +99 -0
  67. package/agent/components/Flex.json +153 -0
  68. package/agent/components/FloatButton.json +91 -0
  69. package/agent/components/Form.json +87 -0
  70. package/agent/components/FormErrors.json +51 -0
  71. package/agent/components/FormField.json +137 -0
  72. package/agent/components/FormFieldArray.json +39 -0
  73. package/agent/components/FormFieldControl.json +129 -0
  74. package/agent/components/FormRoot.json +122 -0
  75. package/agent/components/Heading.json +61 -0
  76. package/agent/components/HoverCard.json +55 -0
  77. package/agent/components/Icon.json +60 -0
  78. package/agent/components/InfiniteQueryState.json +58 -0
  79. package/agent/components/Input.json +122 -0
  80. package/agent/components/InputOTP.json +106 -0
  81. package/agent/components/Label.json +43 -0
  82. package/agent/components/LegalDocumentShell.json +102 -0
  83. package/agent/components/Legend.json +42 -0
  84. package/agent/components/LineChart.json +103 -0
  85. package/agent/components/Link.json +41 -0
  86. package/agent/components/ListRow.json +92 -0
  87. package/agent/components/Logo.json +85 -0
  88. package/agent/components/Marquee.json +91 -0
  89. package/agent/components/Masonry.json +82 -0
  90. package/agent/components/MasterDetail.json +95 -0
  91. package/agent/components/MegaMenu.json +120 -0
  92. package/agent/components/MobileShell.json +73 -0
  93. package/agent/components/NavList.json +63 -0
  94. package/agent/components/NumberInput.json +158 -0
  95. package/agent/components/OrgSwitcher.json +89 -0
  96. package/agent/components/OverlayPortalProvider.json +42 -0
  97. package/agent/components/PageContainer.json +181 -0
  98. package/agent/components/Pagination.json +132 -0
  99. package/agent/components/Paragraph.json +40 -0
  100. package/agent/components/PasswordInput.json +79 -0
  101. package/agent/components/PasswordStrength.json +51 -0
  102. package/agent/components/PermissionMatrix.json +81 -0
  103. package/agent/components/PieChart.json +99 -0
  104. package/agent/components/Popover.json +110 -0
  105. package/agent/components/PrefetchLink.json +65 -0
  106. package/agent/components/Progress.json +79 -0
  107. package/agent/components/Prose.json +57 -0
  108. package/agent/components/QrCode.json +62 -0
  109. package/agent/components/Radio.json +98 -0
  110. package/agent/components/RadioGroup.json +91 -0
  111. package/agent/components/RangeTimeline.json +80 -0
  112. package/agent/components/Rating.json +92 -0
  113. package/agent/components/ResizablePanel.json +69 -0
  114. package/agent/components/ResponsiveGrid.json +77 -0
  115. package/agent/components/Reveal.json +70 -0
  116. package/agent/components/ScrollArea.json +104 -0
  117. package/agent/components/SearchInput.json +98 -0
  118. package/agent/components/Segmented.json +96 -0
  119. package/agent/components/Select.json +397 -0
  120. package/agent/components/Separator.json +86 -0
  121. package/agent/components/ServiceCatalogCta.json +46 -0
  122. package/agent/components/ServiceLauncherCard.json +86 -0
  123. package/agent/components/ServiceRolePanel.json +83 -0
  124. package/agent/components/Sheet.json +85 -0
  125. package/agent/components/Sidebar.json +118 -0
  126. package/agent/components/Skeleton.json +57 -0
  127. package/agent/components/SkeletonArticle.json +71 -0
  128. package/agent/components/SkeletonAvatar.json +50 -0
  129. package/agent/components/SkeletonButton.json +57 -0
  130. package/agent/components/SkeletonForm.json +52 -0
  131. package/agent/components/SkeletonImage.json +37 -0
  132. package/agent/components/SkeletonInput.json +51 -0
  133. package/agent/components/SkeletonNode.json +42 -0
  134. package/agent/components/SkeletonRows.json +49 -0
  135. package/agent/components/SkeletonTable.json +45 -0
  136. package/agent/components/Slider.json +160 -0
  137. package/agent/components/SplitPane.json +66 -0
  138. package/agent/components/StatCard.json +83 -0
  139. package/agent/components/Steps.json +95 -0
  140. package/agent/components/Swatch.json +41 -0
  141. package/agent/components/Switch.json +81 -0
  142. package/agent/components/Table.json +112 -0
  143. package/agent/components/Tabs.json +158 -0
  144. package/agent/components/TagInput.json +105 -0
  145. package/agent/components/Text.json +201 -0
  146. package/agent/components/Textarea.json +126 -0
  147. package/agent/components/ThoughtChain.json +76 -0
  148. package/agent/components/Thumbnail.json +70 -0
  149. package/agent/components/TimePicker.json +200 -0
  150. package/agent/components/TimeRangePicker.json +90 -0
  151. package/agent/components/Timeline.json +47 -0
  152. package/agent/components/TimelineGrid.json +92 -0
  153. package/agent/components/Title.json +67 -0
  154. package/agent/components/Toaster.json +42 -0
  155. package/agent/components/Toggle.json +90 -0
  156. package/agent/components/ToggleGroup.json +102 -0
  157. package/agent/components/Toolbar.json +120 -0
  158. package/agent/components/Tooltip.json +110 -0
  159. package/agent/components/Topbar.json +83 -0
  160. package/agent/components/TopbarItem.json +79 -0
  161. package/agent/components/Transfer.json +141 -0
  162. package/agent/components/Tree.json +185 -0
  163. package/agent/components/TreeSelect.json +232 -0
  164. package/agent/components/TwoFactorSetup.json +79 -0
  165. package/agent/components/Typography.json +42 -0
  166. package/agent/components/Upload.json +221 -0
  167. package/agent/components/UploadCropDialog.json +60 -0
  168. package/agent/components/VisuallyHidden.json +20 -0
  169. package/agent/components/Welcome.json +65 -0
  170. package/agent/components/formatDate.json +46 -0
  171. package/agent/components/inertiaUpload.json +32 -0
  172. package/agent/components/useZodForm.json +39 -0
  173. package/agent/components-index.json +884 -0
  174. package/agent/components.json +15507 -0
  175. package/agent/index.json +56 -0
  176. package/agent/llms.txt +32 -0
  177. package/agent/patterns/account-recovery-settings.json +19 -0
  178. package/agent/patterns/async-data-state.json +20 -0
  179. package/agent/patterns/auth-recovery-panels.json +29 -0
  180. package/agent/patterns/badge-coloring.json +14 -0
  181. package/agent/patterns/common-fixes.json +16 -0
  182. package/agent/patterns/confirm-destructive.json +11 -0
  183. package/agent/patterns/data-table-page.json +18 -0
  184. package/agent/patterns/deferred-loading.json +12 -0
  185. package/agent/patterns/error-pages.json +28 -0
  186. package/agent/patterns/inertia-detail-page.json +13 -0
  187. package/agent/patterns/inertia-list-page.json +15 -0
  188. package/agent/patterns/inertia-persistent-layout.json +14 -0
  189. package/agent/patterns/organization-memberships.json +19 -0
  190. package/agent/patterns/page-sections.json +18 -0
  191. package/agent/patterns/settings-page-responsive.json +18 -0
  192. package/agent/patterns/settings-section-rows.json +23 -0
  193. package/agent/patterns/signup-form.json +13 -0
  194. package/agent/patterns/topbar-account-chip.json +18 -0
  195. package/agent/patterns/transactional-email.json +22 -0
  196. package/agent/patterns-index.json +323 -0
  197. package/agent/patterns.json +342 -0
  198. package/agent/rules.json +237 -0
  199. package/agent/tokens.json +8422 -0
  200. package/agent/vocabulary.json +198 -0
  201. package/dist/components/data-entry/input.js +8 -1
  202. package/dist/components/layout/flex.d.ts +2 -2
  203. package/dist/components/layout/flex.js +2 -0
  204. package/dist/components/ui/tag-input.d.ts +10 -0
  205. package/dist/components/ui/tag-input.js +35 -2
  206. package/dist/contracts/measurement.json +1 -1
  207. package/dist/i18n/messages/en.json +23 -1
  208. package/dist/i18n/messages/ja.json +21 -1
  209. package/dist/i18n/messages/vi.json +21 -1
  210. package/dist/props/components/data-entry.prop.d.ts +21 -2
  211. package/dist/props/components/layout.prop.d.ts +42 -0
  212. package/dist/props/registry.d.ts +9 -0
  213. package/dist/props/registry.js +6 -0
  214. package/dist/styles/card-layout.css +4 -4
  215. package/dist/styles/control.css +31 -2
  216. package/dist/styles/data-display-layout.css +1 -1
  217. package/dist/styles/layout.css +17 -0
  218. package/dist/styles/navigation-layout.css +3 -1
  219. package/dist/styles/shell-layout.css +2 -0
  220. package/dist/styles/table-layout.css +50 -9
  221. package/dist/tokens/components/segmented.css +5 -1
  222. package/dist/tokens/components/table.css +2 -1
  223. package/docs/COMPOSITION-VS-COMPONENT.md +41 -0
  224. package/docs/DESIGN-AUTHORITY.md +14 -0
  225. package/docs/DEVELOPMENT.md +81 -6
  226. package/docs/data-entry/tag-input.tsx +37 -0
  227. package/docs/layout/flex.tsx +40 -0
  228. package/docs/roadmap/website-components.md +34 -0
  229. package/docs/showcase/marketing-page.tsx +54 -45
  230. package/docs/showcase/table-pagination.tsx +88 -18
  231. package/docs/showcase/theme-customization.tsx +25 -2
  232. package/package.json +6 -4
@@ -560,7 +560,9 @@
560
560
 
561
561
  .ui-switch-thumb {
562
562
  pointer-events: none;
563
- display: block;
563
+
564
+ display: grid;
565
+ place-items: center;
564
566
  width: var(--switch-thumb-size);
565
567
  height: var(--switch-thumb-size);
566
568
  border-radius: var(--radius-pill);
@@ -1195,8 +1197,13 @@
1195
1197
 
1196
1198
  .ui-segmented-item[data-state="checked"] {
1197
1199
  background: hsl(var(--segmented-item-selected-background));
1198
- box-shadow: var(--segmented-item-selected-shadow);
1200
+
1201
+ box-shadow:
1202
+ var(--segmented-item-selected-shadow),
1203
+ inset 0 0 0 1px hsl(var(--segmented-item-selected-border-color, var(--input)));
1199
1204
  color: hsl(var(--segmented-item-selected-color));
1205
+
1206
+ font-weight: var(--segmented-item-selected-font-weight);
1200
1207
  }
1201
1208
 
1202
1209
  .ui-segmented-item[data-disabled] {
@@ -1332,6 +1339,13 @@
1332
1339
  cursor: pointer;
1333
1340
  }
1334
1341
 
1342
+ .ui-toggle > svg,
1343
+ .ui-control-trigger > svg {
1344
+ inline-size: var(--control-icon-size);
1345
+ block-size: var(--control-icon-size);
1346
+ flex-shrink: 0;
1347
+ }
1348
+
1335
1349
  .ui-control-trigger:disabled,
1336
1350
  .ui-control-trigger[data-disabled] {
1337
1351
  cursor: not-allowed;
@@ -2102,6 +2116,13 @@
2102
2116
  color: hsl(var(--muted-foreground));
2103
2117
  }
2104
2118
 
2119
+ .ui-input-leading > svg,
2120
+ .ui-input-trailing > svg {
2121
+ inline-size: var(--control-icon-size);
2122
+ block-size: var(--control-icon-size);
2123
+ flex-shrink: 0;
2124
+ }
2125
+
2105
2126
  .ui-input-trailing {
2106
2127
  inset-inline-end: var(--control-inline-affix-inset-inline);
2107
2128
  }
@@ -2873,6 +2894,12 @@
2873
2894
  white-space: nowrap;
2874
2895
  }
2875
2896
 
2897
+ .ui-input-addon > svg {
2898
+ inline-size: var(--control-icon-size);
2899
+ block-size: var(--control-icon-size);
2900
+ flex-shrink: 0;
2901
+ }
2902
+
2876
2903
  .ui-input-group > [data-slot="input-addon-before"] {
2877
2904
  border-start-start-radius: var(--control-radius);
2878
2905
  border-end-start-radius: var(--control-radius);
@@ -2887,12 +2914,14 @@
2887
2914
 
2888
2915
  .ui-input-group:has(> [data-slot="input-addon-before"]) .ui-input,
2889
2916
  .ui-input-group:has(> [data-slot="input-addon-before"]) .ui-input-affix-wrapper {
2917
+ --input-radius-start: 0;
2890
2918
  border-start-start-radius: 0;
2891
2919
  border-end-start-radius: 0;
2892
2920
  }
2893
2921
 
2894
2922
  .ui-input-group:has(> [data-slot="input-addon-after"]) .ui-input,
2895
2923
  .ui-input-group:has(> [data-slot="input-addon-after"]) .ui-input-affix-wrapper {
2924
+ --input-radius-end: 0;
2896
2925
  border-start-end-radius: 0;
2897
2926
  border-end-end-radius: 0;
2898
2927
  }
@@ -1232,7 +1232,7 @@
1232
1232
 
1233
1233
  .ui-prose :is(th, td) {
1234
1234
  border: var(--stroke-hairline) solid hsl(var(--border));
1235
- padding: var(--table-cell-padding-y) var(--table-cell-space-x);
1235
+ padding: var(--table-cell-padding-y) var(--table-cell-space-x, var(--space-section-active));
1236
1236
  text-align: start;
1237
1237
  vertical-align: top;
1238
1238
  }
@@ -142,6 +142,23 @@
142
142
  flex: none;
143
143
  }
144
144
 
145
+ .ui-flex[data-measure] {
146
+ margin-inline: auto;
147
+ inline-size: 100%;
148
+ }
149
+
150
+ .ui-flex[data-measure="narrow"] {
151
+ max-inline-size: var(--page-measure-narrow);
152
+ }
153
+
154
+ .ui-flex[data-measure="medium"] {
155
+ max-inline-size: var(--page-measure-medium);
156
+ }
157
+
158
+ .ui-flex[data-measure="wide"] {
159
+ max-inline-size: var(--page-measure-wide);
160
+ }
161
+
145
162
  .ui-flex[data-align="start"] {
146
163
  align-items: flex-start;
147
164
  }
@@ -441,7 +441,9 @@
441
441
  }
442
442
 
443
443
  .ui-pagination .ui-button svg,
444
- .ui-pagination .ui-pagination-link svg {
444
+ .ui-pagination .ui-pagination-link svg,
445
+
446
+ .ui-pagination .ui-pagination-ellipsis svg {
445
447
  inline-size: var(--pagination-icon-size);
446
448
  block-size: var(--pagination-icon-size);
447
449
  }
@@ -1741,6 +1741,8 @@
1741
1741
  .sb-nav-group-trigger .sb-chevron {
1742
1742
  margin-inline-start: auto;
1743
1743
  flex: 0 0 auto;
1744
+ inline-size: var(--sidebar-nav-icon-size);
1745
+ block-size: var(--sidebar-nav-icon-size);
1744
1746
  opacity: 0.6;
1745
1747
  transition: transform 150ms ease;
1746
1748
  }
@@ -88,12 +88,14 @@
88
88
 
89
89
  .ui-table-row[data-tone] > [data-slot="table-cell"]:first-child {
90
90
  border-inline-start: var(--table-row-tone-rail-width) solid hsl(var(--table-row-tone-color));
91
- padding-inline-start: calc(var(--table-cell-space-x) - var(--table-row-tone-rail-width));
91
+ padding-inline-start: calc(
92
+ var(--table-cell-space-x, var(--space-section-active)) - var(--table-row-tone-rail-width)
93
+ );
92
94
  }
93
95
 
94
96
  [data-slot="table-head"] {
95
97
  height: var(--table-row-height);
96
- padding: var(--table-cell-padding-y) var(--table-cell-space-x);
98
+ padding: var(--table-cell-padding-y) var(--table-cell-space-x, var(--space-section-active));
97
99
  text-align: start;
98
100
  vertical-align: middle;
99
101
  background: var(--table-header-background, hsl(var(--muted)));
@@ -113,7 +115,7 @@
113
115
  }
114
116
 
115
117
  [data-slot="table-cell"] {
116
- padding: var(--table-cell-padding-y) var(--table-cell-space-x);
118
+ padding: var(--table-cell-padding-y) var(--table-cell-space-x, var(--space-section-active));
117
119
  vertical-align: middle;
118
120
 
119
121
  white-space: nowrap;
@@ -146,7 +148,7 @@
146
148
 
147
149
  [data-slot="table-cell"][data-indent] {
148
150
  padding-inline-start: calc(
149
- var(--table-cell-space-x) + var(--table-cell-indent-level, 0) *
151
+ var(--table-cell-space-x, var(--space-section-active)) + var(--table-cell-indent-level, 0) *
150
152
  var(--table-cell-indent-space-step)
151
153
  );
152
154
  }
@@ -207,7 +209,10 @@
207
209
  justify-content: flex-end;
208
210
  gap: var(--space-inline-sm);
209
211
  padding-block: var(--table-pagination-padding-y, var(--space-stack-sm));
210
- padding-inline: var(--table-pagination-padding-x, var(--table-cell-space-x));
212
+ padding-inline: var(
213
+ --table-pagination-padding-x,
214
+ var(--table-cell-space-x, var(--space-section-active))
215
+ );
211
216
  }
212
217
 
213
218
  .ui-data-table-pagination--numbered {
@@ -634,7 +639,16 @@
634
639
  white-space: normal;
635
640
  }
636
641
 
637
- [data-collapse-below="sm"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
642
+ [data-collapse-below="sm"]
643
+ [data-slot="table"]:has(
644
+ [data-slot="table-head"]:nth-child(7),
645
+ [data-slot="table-head"][data-priority="primary"]
646
+ ~ [data-slot="table-head"][data-priority="primary"],
647
+ [data-slot="table-head"][data-priority="secondary"]
648
+ ~ [data-slot="table-head"][data-priority="secondary"],
649
+ [data-slot="table-head"][data-priority="meta"]
650
+ ~ [data-slot="table-head"][data-priority="meta"]
651
+ ) {
638
652
  --table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
639
653
  --table-action-collection-secondary-width: var(
640
654
  --table-action-collection-secondary-width-floor
@@ -664,7 +678,16 @@
664
678
  white-space: normal;
665
679
  }
666
680
 
667
- [data-collapse-below="md"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
681
+ [data-collapse-below="md"]
682
+ [data-slot="table"]:has(
683
+ [data-slot="table-head"]:nth-child(7),
684
+ [data-slot="table-head"][data-priority="primary"]
685
+ ~ [data-slot="table-head"][data-priority="primary"],
686
+ [data-slot="table-head"][data-priority="secondary"]
687
+ ~ [data-slot="table-head"][data-priority="secondary"],
688
+ [data-slot="table-head"][data-priority="meta"]
689
+ ~ [data-slot="table-head"][data-priority="meta"]
690
+ ) {
668
691
  --table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
669
692
  --table-action-collection-secondary-width: var(
670
693
  --table-action-collection-secondary-width-floor
@@ -694,7 +717,16 @@
694
717
  white-space: normal;
695
718
  }
696
719
 
697
- [data-collapse-below="lg"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
720
+ [data-collapse-below="lg"]
721
+ [data-slot="table"]:has(
722
+ [data-slot="table-head"]:nth-child(7),
723
+ [data-slot="table-head"][data-priority="primary"]
724
+ ~ [data-slot="table-head"][data-priority="primary"],
725
+ [data-slot="table-head"][data-priority="secondary"]
726
+ ~ [data-slot="table-head"][data-priority="secondary"],
727
+ [data-slot="table-head"][data-priority="meta"]
728
+ ~ [data-slot="table-head"][data-priority="meta"]
729
+ ) {
698
730
  --table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
699
731
  --table-action-collection-secondary-width: var(
700
732
  --table-action-collection-secondary-width-floor
@@ -724,7 +756,16 @@
724
756
  white-space: normal;
725
757
  }
726
758
 
727
- [data-collapse-below="xl"] [data-slot="table"]:has([data-slot="table-head"]:nth-child(7)) {
759
+ [data-collapse-below="xl"]
760
+ [data-slot="table"]:has(
761
+ [data-slot="table-head"]:nth-child(7),
762
+ [data-slot="table-head"][data-priority="primary"]
763
+ ~ [data-slot="table-head"][data-priority="primary"],
764
+ [data-slot="table-head"][data-priority="secondary"]
765
+ ~ [data-slot="table-head"][data-priority="secondary"],
766
+ [data-slot="table-head"][data-priority="meta"]
767
+ ~ [data-slot="table-head"][data-priority="meta"]
768
+ ) {
728
769
  --table-action-collection-primary-width: var(--table-action-collection-primary-width-floor);
729
770
  --table-action-collection-secondary-width: var(
730
771
  --table-action-collection-secondary-width-floor
@@ -28,7 +28,11 @@
28
28
  --segmented-item-active-background: var(--secondary);
29
29
 
30
30
  --segmented-item-selected-background: var(--background);
31
- --segmented-item-selected-shadow: var(--shadow-sm);
31
+ --segmented-item-selected-shadow: var(--shadow-md);
32
+
33
+ --segmented-item-selected-font-weight: var(--font-weight-medium);
34
+
35
+ --segmented-item-selected-border-color: initial;
32
36
 
33
37
  --segmented-count-min-width: var(--button-count-min-width);
34
38
  --segmented-count-space-inline: var(--button-count-space-inline);
@@ -6,7 +6,8 @@
6
6
  --table-row-height-comfortable: var(--band-height-xl);
7
7
  --table-row-height: calc(var(--table-row-height-default) * var(--scaling));
8
8
  --table-cell-padding-y: var(--space-2);
9
- --table-cell-space-x: var(--control-padding-x);
9
+
10
+ --table-cell-space-x: initial;
10
11
 
11
12
  --table-cell-indent-space-step: var(--space-4);
12
13
 
@@ -84,6 +84,7 @@ new UI need
84
84
  | **PricingTable** / feature grid | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | **Composition** — `ResponsiveGrid` + `Card` |
85
85
  | Dashboard **page layout** | ❌ | ❌ | ❌ | ❌ | ➖ | ❌ | ❌ | **Composition** — `AppShell` + `PageContainer` + `ResponsiveGrid` |
86
86
  | "Icon medallion" | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | **Composition** — `Avatar` (square) + a Lucide glyph |
87
+ | **Section** / **Band** (full-bleed + measured column) | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | **Composition** — `<section>` + `Flex measure` + `pad`; see §3.1 |
87
88
 
88
89
  `✅ pass · ❌ fail · ➖ borderline`. **StatCard** is the instructive borderline: C2 is weak (it owns little behavior), but it is a universal KPI tile with a controlled API, fully tokenized, broadly reused — so it earns its place. A **Hero** fails six of seven; it is unambiguously a composition.
89
90
 
@@ -106,6 +107,46 @@ C2 rather than C7.
106
107
 
107
108
  **ServiceLauncherCard is the ONE recorded exception, and it is recorded so that it stays one.** It shipped before the test was run against it, and when the test was run it came back with two hard FAILs: **C2** — no state, no keyboard handling, no focus management, its only ARIA three static attributes — and **C3** — its own imports are `Card` + `CardContent` + `Badge` + a Lucide glyph, so "could I build this right now from primitives?" is yes. By §2 that makes it a composition pattern. It is kept anyway because `src/components/layout/app-launcher.tsx` consumes it: it is an internal building block of a component that **does** pass, so the question was never "should it exist" but "should it be PUBLIC", and removing a public export is breaking. Keeping it public was the cheaper call and the ledger lives on gh#814 and at the top of `src/components/data-display/service-launcher-card.tsx`. **Consumers should compose `Card` + `Badge` for a service tile** — reach for `ServiceLauncherCard` only to match `AppLauncher`'s own tiles — and this row is not precedent for adding another static tile to `src/components/`.
108
109
 
110
+ ### 3.1 "Full-bleed outside, measured column inside" — the case that was answered with a PROP (gh#839)
111
+
112
+ This row exists because the question it settles was asked the other way round, and the right answer
113
+ turned out to be neither "add a component" nor "do nothing".
114
+
115
+ **A `Section` component is refused, and it is refused for Hero's reasons.** It owns no state, no
116
+ keyboard, no focus and no ARIA a `<section aria-labelledby>` does not already have (**C2**); it is
117
+ `<section>` + `Flex` + padding + a max-width, i.e. buildable today (**C3**); its API would be the
118
+ grab-bag `band` / `measure` / `glow` / `surface` / `bleed` that **C4** names by name; and a JP
119
+ business-software library would be shipping a marketing band to every consumer (**C7**). One
120
+ criterion of seven passes. Nothing about that is close.
121
+
122
+ **But "do nothing" was also refused, and that is the part worth remembering.** The doctrine's own
123
+ remedy for a composition is a TOKEN (§4.3), and `--page-measure-wide` shipped in 28.8.0 — so on
124
+ paper the gap was already closed. It was not. A token is only closed when something can READ it,
125
+ and three unrelated pages had each hand-written the identical four declarations to do so:
126
+ `docs/showcase/marketing-page.tsx` as an inline `style` constant, `acme-website.tsx` as `.tx-shell`,
127
+ `futurelastic-web.tsx` as `.fl-shell` — one shape, three spellings, two of them page-local CSS
128
+ classes on the pages whose entire claim is that they need none. `docs/TOKENS.md` calls a value that
129
+ appears in more than one place tier 1, and the same logic reads on a SHAPE.
130
+
131
+ **The third move is a prop on a primitive that already passes the test.** `Flex measure` (narrow |
132
+ medium | wide) centres the box and caps it at `var(--page-measure-*)`; it adds no gutter, because
133
+ `pad` owns that. A full-bleed band is now `<section>` — carrying the edge-to-edge paint — around one
134
+ `<Flex direction="col" measure="wide" pad={{ inline: 6, block: 20 }}>`. Measured on
135
+ `marketing-page.tsx`: seven bands, 7 inline `style` spreads and 3 `CSSProperties` constants gone,
136
+ the metric that page defends (0 bespoke classes, 0 raw px/rem literals) unchanged at 0/0, and the
137
+ geometry byte-identical (1440: section 1440px, column 1152px, band 96/80px, gutter 24px).
138
+
139
+ **`PageContainer measure="wide"` stays refused, and for the original reason.** A marketing page is
140
+ full-bleed `<section>`s; `PageContainer` owns page padding and a header/toolbar/footer scaffold, so
141
+ the two pages that are the prop's proof still cannot consume it. The prop went to the primitive
142
+ those pages CAN put inside a `<section>`, which is the distinction the earlier deferral was missing
143
+ rather than a reversal of it.
144
+
145
+ **The rule this leaves behind:** when a composition repeats a shape, ask whether an existing
146
+ primitive is missing ONE AXIS before you ask whether a new component is missing. A component that
147
+ fails C1–C7 and a prop that closes the same gap are not the same proposal, and the test above is
148
+ only asking about the first.
149
+
109
150
  ---
110
151
 
111
152
  ## 4. How to build a composition pattern correctly
@@ -449,6 +449,20 @@ expandable.expandedRowKeys` / `onExpandedRowsChange`. This library already mappe
449
449
  (`role="toolbar"`, `aria-pressed`); the prop there only keeps the last item selected.
450
450
  Divergence from Radix's markup is the point of the change, not a side effect of it.
451
451
 
452
+ - **`Input addonBefore` / `addonAfter` stay, although antd DEPRECATED them (gh#841).** Verified in
453
+ `ant-design@master` rather than on the docs page: `components/input/Input.tsx` carries
454
+ `@deprecated Use Space.Compact instead` on both props and fires a dev-time
455
+ `devUseWarning('Input').deprecated(…)` for each, while still rendering them; both locale tables
456
+ strike the rows through and the `addon` demo is flagged `debug`, so it no longer appears on the
457
+ published page. The deprecation is a REFACTOR onto `Space.Compact`, and this library has no
458
+ `Space` — so following it would delete the joined control and put nothing in its place, which is
459
+ a breaking change bought for nothing. `addonBefore` IS the joined control here: it renders
460
+ `.ui-input-group`, and gh#841 squared its seam. The steer that IS followed is the one antd's own
461
+ live surface gives: a GLYPH belongs in `prefix`, inside the field, where there is one box, one
462
+ border and no seam; an addon is for a label segment. Written on the prop
463
+ (`src/props/components/data-entry.prop.ts`) and in the MCP catalog. Revisit if a `Space`/compact
464
+ primitive is ever ported — then antd's steer is followable and this becomes a migration.
465
+
452
466
  **A knob that only a fork could reach is not parity either.** antd's `components`,
453
467
  `filterDropdown`, `classNames`/`styles` semantic maps and `prefixCls` all exist to let a consumer
454
468
  replace the rendered markup. This library answers that layer with tokens (cardinal rule #45), so
@@ -112,16 +112,91 @@ A change isn't done until its documentation reflects it:
112
112
 
113
113
  ---
114
114
 
115
- ## 5. Verify before finishing
115
+ ## 5. Verify before finishing — scope the checks to the DIFF
116
+
117
+ > **Read §5.0 before you run anything.** This section was rewritten after the owner watched a
118
+ > two-file change take six minutes of gates and asked, correctly, _"bản chất chỉ sửa rất ít, check
119
+ > diff đéo được hay sao? có phải release đâu mà run hết thế?"_ — it is not a release, so stop
120
+ > running a release's worth of checks.
121
+
122
+ ### 5.0 MEASURE FIRST, THEN COMPLAIN — the real cost table
123
+
124
+ Every number below was measured on this repo, on an M-series Mac, warm. **Measure again before you
125
+ believe them; a cost you assumed is how you end up optimising the wrong thing.**
126
+
127
+ | command | cost | scope |
128
+ | -------------------------- | --------------- | ------------------------------------------ |
129
+ | `check:token-tiers` | **0.2s** | whole repo |
130
+ | `audit` | **0.5s** | whole repo (~600 files) |
131
+ | `typecheck:docs` | **0.7s** | whole `docs/` program |
132
+ | `typecheck` | **1.3s** | whole `src/` program |
133
+ | `build` | **1.5s** | whole package |
134
+ | `preview:build` | **1.9s** | whole preview |
135
+ | `lint` | **12.9s** | whole repo |
136
+ | **`check:frame-overflow`** | **52s** (was 339s before it was parallelised, gh#851) | **199 frames x 2 viewports, in a browser** |
137
+
138
+ **The lesson is the opposite of the intuition.** "Typecheck the whole system" sounds wasteful and
139
+ costs **1.3 seconds** — typescript-7 is the native compiler, there is nothing to save there, and
140
+ scoping it to changed files would cost more in ceremony than it saves in wall clock. Meanwhile the
141
+ one command that _does_ cost real time is the browser sweep, and it is the one that looks innocent
142
+ in a shell script.
143
+
144
+ `check:frame-overflow` alone was **~96% of the wall clock** of a full local pass. It ran all 398
145
+ navigations down a SINGLE page, in series. It now runs a pool of one page per core (capped at 8):
146
+ **339s -> 52.3s, 6.5x**, byte-identical output, and a planted overflow is still caught at both
147
+ viewports by both. `FRAME_CONCURRENCY=1` restores the serial run for debugging.
148
+
149
+ > **Never argue about the cost of a gate you have not timed.** Time it:
150
+ > `st=$(date +%s); pnpm <gate> >/dev/null 2>&1; echo $(( $(date +%s) - st ))s`
151
+
152
+ ### 5.1 What to run, by what you touched
153
+
154
+ Find the row that matches your diff. Run that row. Do not run the rows below it.
155
+
156
+ | you changed | run | why |
157
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
158
+ | a `.css` file only | `audit` · `check:token-tiers` · the component's own tests · `check:frame-overflow --only <slug>` | no TS changed, so `typecheck` has nothing to say |
159
+ | a `.tsx`/`.ts` in `src/` | `typecheck` · `lint` · `audit` · that group's tests | 1.3s + 12.9s, both worth it |
160
+ | a file in `docs/` | `typecheck:docs` · `audit` · `check:example-imports` | `typecheck` covers `src/`, not `docs/` |
161
+ | a token in `src/tokens/` | + `check:token-tiers` · `src/tokens/__tests__` · `pnpm regen` twice (gh#847) | frozen tier tables go stale instantly |
162
+ | a public export / prop | + `pnpm ship:surface` | 8 stacked generators; the list is derived, not remembered |
163
+ | anything that moves LAYOUT | `check:frame-overflow --only <slug>` while you work; the FULL sweep once, before the PR | 17.5s vs 339s |
164
+ | opening the PR / cutting a release | the full sweep, `verify:ci:static`, the full suite in CI | the only place "run everything" is right |
165
+
166
+ ### 5.2 `--only` — the diff-scoped browser sweep
167
+
168
+ Added in gh#851 for exactly this. The sweep had no filter at all: 199 frames or nothing.
169
+
170
+ ```bash
171
+ pnpm check:frame-overflow --only table # 9 frames, 17.5s
172
+ pnpm check:frame-overflow --only '/^data-entry-(switch|segmented)/' # 3 frames
173
+ pnpm check:frame-overflow # all 199, 52s
174
+ ```
175
+
176
+ Measured: `--only table` is **17.5s against the full sweep's 52.3s**. Both matter — the pool cut
177
+ the full sweep 6.5x, and `--only` cuts what is left to the frames a diff can actually reach.
178
+
179
+ Two guards, both deliberate:
180
+
181
+ - **`--only` refuses `--update-baseline`.** A partial sweep does not know whether the frames it
182
+ skipped are still clean, and recording that as the whole truth is how a baseline stops meaning
183
+ anything. Rebaselining needs the full sweep.
184
+ - **Its success line says `PARTIAL, not a release gate`** and prints how many frames it skipped, so
185
+ a filtered green can never be pasted into a PR as if it were the real thing.
186
+
187
+ ### 5.3 The commands, for reference
116
188
 
117
189
  ```bash
118
- pnpm lint # eslint — self-contained flat config
119
- pnpm typecheck # tsc --noEmit
190
+ pnpm lint # eslint — self-contained flat config 12.9s
191
+ pnpm typecheck # tsc --noEmit over src/ 1.3s
192
+ pnpm typecheck:docs # tsc --noEmit over docs/ 0.7s
193
+ pnpm audit # godxjp-ui-audit — 0 errors for touched files 0.5s
194
+ pnpm check:mcp-sync # MCP registry <-> library export drift guard
120
195
  pnpm vitest run src/components/<group>/__tests__ --maxWorkers=2 # ONLY what you touched
196
+ pnpm check:frame-overflow --only <slug> # the frames your change can reach ~18s
197
+ pnpm check:frame-overflow # all 199 — pre-PR and CI only 52s
198
+ pnpm preview:build # integration test: examples + docs must build 1.9s
121
199
  pnpm test # FULL suite — CI only, never from an agent loop
122
- pnpm preview:build # integration test: examples + docs must build — at most once, pre-PR
123
- pnpm audit # godxjp-ui-audit — 0 errors for touched files
124
- pnpm check:mcp-sync # MCP registry ↔ library export drift guard
125
200
  pnpm check:frame-axe # WCAG 2.2 AA over every frame — LOCAL ONLY, never in CI (FRAME-A11Y-CI.md)
126
201
  ```
127
202
 
@@ -2,6 +2,7 @@ import { useState } from "react";
2
2
 
3
3
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
4
4
  import { FormField, TagInput } from "@godxjp/ui/data-entry";
5
+ import { useTranslation } from "@godxjp/ui/i18n";
5
6
  import { Flex, PageContainer } from "@godxjp/ui/layout";
6
7
 
7
8
  /**
@@ -11,9 +12,17 @@ import { Flex, PageContainer } from "@godxjp/ui/layout";
11
12
  * Composed only from real @godxjp/ui components.
12
13
  */
13
14
  export default function Demo() {
15
+ const { t } = useTranslation();
14
16
  const [invoiceTags, setInvoiceTags] = useState<string[]>(["営業部", "Q1"]);
15
17
  const [skillTags, setSkillTags] = useState<string[]>(["経理", "仕訳入力"]);
16
18
  const [recipientEmails, setRecipientEmails] = useState<string[]>([]);
19
+ /* The reporter's exact 71-character string, held FIRST so the truncated chip is one of the two
20
+ that render rather than one of the ones `+N` hides (gh#840). */
21
+ const [ledgerTags, setLedgerTags] = useState<string[]>([
22
+ "THEME_SEED_LEDGER_0007_CONTRAST_VERIFIED_AGAINST_CANVAS_AND_LABEL_00042",
23
+ "本番",
24
+ "ổn định",
25
+ ]);
17
26
 
18
27
  return (
19
28
  <PageContainer
@@ -87,6 +96,34 @@ export default function Demo() {
87
96
  </CardContent>
88
97
  </Card>
89
98
 
99
+ <Card>
100
+ <CardHeader>
101
+ <CardTitle level={2}>{t("showcase.tagInput.longIdTitle")}</CardTitle>
102
+ <CardDescription>
103
+ maxTagTextLength cuts the chip TEXT only — the whole value stays in the chip&apos;s
104
+ title and in the remove button&apos;s accessible name. maxTagCount collapses the rest
105
+ into a +N that names, in its own title and aria-label, exactly which tags it hides.
106
+ Neither may swallow a value silently (gh#840).
107
+ </CardDescription>
108
+ </CardHeader>
109
+ <CardContent>
110
+ <FormField
111
+ id="ledger-tags"
112
+ label={t("showcase.tagInput.ledgerLabel")}
113
+ helper={t("showcase.tagInput.ledgerHelper")}
114
+ >
115
+ <TagInput
116
+ id="ledger-tags"
117
+ value={ledgerTags}
118
+ onValueChange={setLedgerTags}
119
+ maxTagCount={2}
120
+ maxTagTextLength={16}
121
+ aria-label={t("showcase.tagInput.ledgerLabel")}
122
+ />
123
+ </FormField>
124
+ </CardContent>
125
+ </Card>
126
+
90
127
  <Card>
91
128
  <CardHeader>
92
129
  <CardTitle level={2}>無効状態</CardTitle>
@@ -8,6 +8,7 @@ import {
8
8
  ListRow,
9
9
  } from "@godxjp/ui/data-display";
10
10
  import { Button, Text } from "@godxjp/ui/general";
11
+ import { useTranslation } from "@godxjp/ui/i18n";
11
12
  import { Flex, PageContainer } from "@godxjp/ui/layout";
12
13
 
13
14
  /**
@@ -20,6 +21,7 @@ import { Flex, PageContainer } from "@godxjp/ui/layout";
20
21
  * @godxjp/ui components.
21
22
  */
22
23
  export default function Demo() {
24
+ const { t } = useTranslation();
23
25
  return (
24
26
  <PageContainer
25
27
  title="Flex"
@@ -398,6 +400,44 @@ export default function Demo() {
398
400
  </Flex>
399
401
  </CardContent>
400
402
  </Card>
403
+
404
+ <Card>
405
+ <CardHeader>
406
+ <CardTitle level={2}>{t("showcase.flexMeasure.title")}</CardTitle>
407
+ <CardDescription>{t("showcase.flexMeasure.lead")}</CardDescription>
408
+ </CardHeader>
409
+ <CardContent>
410
+ <Flex direction="col" gap="sm">
411
+ <Flex
412
+ id="measure-narrow"
413
+ measure="narrow"
414
+ surface="muted"
415
+ pad={{ block: 2, inline: 6 }}
416
+ justify="center"
417
+ >
418
+ <Text tone="muted">measure=&quot;narrow&quot; · 42rem</Text>
419
+ </Flex>
420
+ <Flex
421
+ id="measure-medium"
422
+ measure="medium"
423
+ surface="muted"
424
+ pad={{ block: 2, inline: 6 }}
425
+ justify="center"
426
+ >
427
+ <Text tone="muted">measure=&quot;medium&quot; · 48rem</Text>
428
+ </Flex>
429
+ <Flex
430
+ id="measure-wide"
431
+ measure="wide"
432
+ surface="muted"
433
+ pad={{ block: 2, inline: 6 }}
434
+ justify="center"
435
+ >
436
+ <Text tone="muted">measure=&quot;wide&quot; · 72rem</Text>
437
+ </Flex>
438
+ </Flex>
439
+ </CardContent>
440
+ </Card>
401
441
  </Flex>
402
442
  </PageContainer>
403
443
  );
@@ -649,6 +649,40 @@ with no call site in the two pages that are its proof, which is the tier-2 mista
649
649
  warns about. The token stands on its own as the vocabulary a composition caps its shell with, the
650
650
  way `--gradient-hero` does.
651
651
 
652
+ **CLOSED in gh#839, and the refusal above still stands.** Leaving the centred column to "the
653
+ composition writes it" was measured and found wanting: three unrelated pages hand-wrote the SAME
654
+ four declarations — `marketing-page.tsx` as an inline `style` constant, `acme-website.tsx` as
655
+ `.tx-shell`, `futurelastic-web.tsx` as `.fl-shell` — which `docs/TOKENS.md` calls tier 1, and two of
656
+ the three spelled it as a page-local CSS class. The answer was not a `Section` component (it fails
657
+ C1–C7 the way Hero does — `docs/COMPOSITION-VS-COMPONENT.md` §3.1 carries the ledger) and not
658
+ `PageContainer`, which still cannot be consumed by a full-bleed page. It is **`Flex measure`**
659
+ (`narrow | medium | wide`, reading `--page-measure-*`), on the primitive a `<section>` CAN put
660
+ inside itself. It centres and caps and nothing else: `pad` keeps the gutter, so a band is
661
+ `<section>` around one `<Flex direction="col" measure="wide" pad={{ inline: 6, block: 20 }}>`.
662
+
663
+ | step | reader |
664
+ | ---------------------------------- | -------------------------------------------------------------- |
665
+ | `--space-section-band` (80px) | `pad={{ block: 20 }}` — `GapStepProp` gained 20/24 |
666
+ | `--space-section-hero` (96px) | `pad={{ block: 24 }}` |
667
+ | `--page-measure-{narrow,med,wide}` | `Flex measure` — and `PageContainer measure` for the first two |
668
+
669
+ **No compact rung for the band steps, decided on measurement.** At 320×568 the hero band is 96px
670
+ at both edges = 33.8% of the first screen, and the `<h1>` still lands fully above the fold (top
671
+ 195px, bottom 315px). Three reasons not to add one: (1) 96px is already the NARROW rung of the
672
+ industry pair — Tailwind UI's marketing sections are `py-24 sm:py-32`, i.e. 96px on a phone and
673
+ 128px from `sm` up, so the missing step is at the wide end, not the narrow one; (2) a numeric `pad`
674
+ step is a VALUE by contract (`pad={3}` is 12px at every width — `GapStepProp`'s own docstring says
675
+ so), and making 20/24 responsive would make them the two steps whose number lies; (3) a
676
+ `--space-section-band-compact` token would have nowhere to be flipped: every `-active`/`-compact`
677
+ pair in this repo switches inside a COMPONENT's scope (`.ui-page-container`,
678
+ `.ui-centered-shell[data-preset="public-landing"]`), and a plain `<section>` has no such scope — so
679
+ it would ship as vocabulary with no caller, the exact defect gh#839 exists to stop.
680
+ `--centered-shell-landing-main-padding-block-compact` is not the counter-example it looks like: it
681
+ is 40px → 24px of a SHELL's `main` padding, not a marketing band, and it lives inside that shell's
682
+ own scope. **The real capability the band wants is a responsive object form for `pad`**, the one
683
+ `direction` and `ResponsiveGrid columns` already take (`pad={{ block: { base: 12, md: 20 } }}`) —
684
+ that is its own issue, and a much larger one than a token rung.
685
+
652
686
  ---
653
687
 
654
688
  ## 6. The animation and motion story