@godxjp/ui 17.0.1 → 18.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 (71) hide show
  1. package/dist/components/data-display/card.d.ts +37 -1
  2. package/dist/components/data-display/card.js +7 -1
  3. package/dist/components/data-display/data-table.js +18 -3
  4. package/dist/components/data-display/empty-state.d.ts +1 -1
  5. package/dist/components/data-display/empty-state.js +5 -1
  6. package/dist/components/data-display/scroll-area.js +1 -1
  7. package/dist/components/data-display/table.js +14 -9
  8. package/dist/components/data-entry/calendar.js +4 -0
  9. package/dist/components/data-entry/cascader.d.ts +1 -1
  10. package/dist/components/data-entry/cascader.js +10 -1
  11. package/dist/components/data-entry/checkbox-group.d.ts +1 -1
  12. package/dist/components/data-entry/checkbox-group.js +13 -4
  13. package/dist/components/data-entry/color-picker.d.ts +1 -1
  14. package/dist/components/data-entry/color-picker.js +5 -2
  15. package/dist/components/data-entry/command.d.ts +2 -2
  16. package/dist/components/data-entry/date-picker.d.ts +1 -1
  17. package/dist/components/data-entry/date-picker.js +11 -1
  18. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  19. package/dist/components/data-entry/date-range-picker.js +11 -3
  20. package/dist/components/data-entry/form-field.js +7 -3
  21. package/dist/components/data-entry/month-picker.d.ts +1 -1
  22. package/dist/components/data-entry/month-picker.js +13 -1
  23. package/dist/components/data-entry/month-range-picker.d.ts +1 -1
  24. package/dist/components/data-entry/month-range-picker.js +11 -3
  25. package/dist/components/data-entry/number-input.d.ts +19 -2
  26. package/dist/components/data-entry/number-input.js +5 -7
  27. package/dist/components/data-entry/radio.d.ts +1 -1
  28. package/dist/components/data-entry/radio.js +11 -3
  29. package/dist/components/data-entry/search-input.d.ts +3 -2
  30. package/dist/components/data-entry/search-input.js +5 -2
  31. package/dist/components/data-entry/search-select.d.ts +1 -1
  32. package/dist/components/data-entry/search-select.js +51 -10
  33. package/dist/components/data-entry/select.d.ts +7 -0
  34. package/dist/components/data-entry/select.js +21 -3
  35. package/dist/components/data-entry/time-picker.d.ts +1 -1
  36. package/dist/components/data-entry/time-picker.js +11 -1
  37. package/dist/components/data-entry/transfer.d.ts +1 -1
  38. package/dist/components/data-entry/transfer.js +73 -59
  39. package/dist/components/data-entry/tree-select.d.ts +1 -1
  40. package/dist/components/data-entry/tree-select.js +10 -1
  41. package/dist/components/data-entry/upload.d.ts +1 -1
  42. package/dist/components/data-entry/upload.js +7 -2
  43. package/dist/components/layout/app-shell.d.ts +1 -1
  44. package/dist/components/layout/app-shell.js +42 -2
  45. package/dist/components/layout/breadcrumb.d.ts +7 -1
  46. package/dist/components/layout/breadcrumb.js +6 -2
  47. package/dist/components/layout/page-container.d.ts +1 -1
  48. package/dist/components/layout/page-container.js +32 -22
  49. package/dist/components/layout/responsive-grid.js +1 -1
  50. package/dist/components/layout/sidebar.d.ts +1 -1
  51. package/dist/components/layout/sidebar.js +44 -11
  52. package/dist/components/layout/split-pane.js +2 -2
  53. package/dist/components/navigation/app-setting-picker.js +8 -1
  54. package/dist/components/navigation/pagination.d.ts +1 -1
  55. package/dist/components/navigation/pagination.js +84 -95
  56. package/dist/components/navigation/tabs.js +21 -4
  57. package/dist/i18n/messages/en.json +3 -1
  58. package/dist/i18n/messages/ja.json +3 -1
  59. package/dist/i18n/messages/vi.json +3 -1
  60. package/dist/lib/field-a11y.d.ts +66 -0
  61. package/dist/lib/field-a11y.js +44 -0
  62. package/dist/props/components/data-display.prop.d.ts +16 -1
  63. package/dist/props/components/data-entry.prop.d.ts +69 -19
  64. package/dist/props/components/layout.prop.d.ts +42 -0
  65. package/dist/props/components/navigation.prop.d.ts +16 -0
  66. package/dist/props/registry.d.ts +8 -3
  67. package/dist/props/registry.js +21 -3
  68. package/dist/props/vocabulary/data.prop.d.ts +9 -0
  69. package/dist/styles/layout.css +46 -9
  70. package/dist/styles/shell-layout.css +19 -0
  71. package/package.json +8 -4
@@ -13,6 +13,15 @@ export type OnRowClickProp<T> = (row: T) => void;
13
13
  export type ColumnDefProp<T> = {
14
14
  key: string;
15
15
  header: React.ReactNode;
16
+ /**
17
+ * Accessible header text for a column whose `header` is visually empty — the
18
+ * standard case for a row-actions or selection column. Rendered as an
19
+ * `sr-only` label inside the `<th>` so the column keeps a screen-reader name
20
+ * (e.g. "Actions" / "Select") while showing nothing on screen. Required
21
+ * (dev-warned) when `header` is empty; ignored when `header` has visible text.
22
+ * Route the string through `t()` for i18n.
23
+ */
24
+ ariaLabel?: string;
16
25
  render?: (row: T) => React.ReactNode;
17
26
  sortable?: boolean;
18
27
  width?: string;
@@ -175,6 +175,16 @@
175
175
  gap: var(--space-inline-lg);
176
176
  }
177
177
 
178
+ /* ResponsiveGrid OWNS its query container. The component wraps the grid in
179
+ * `.ui-responsive-grid-scope` (container-type: inline-size, named `responsive-grid`) so the
180
+ * column breakpoints resolve against the WIDTH AVAILABLE TO THE GRID — not the viewport and not
181
+ * an undeclared ancestor `container-type`. This makes it correct inside a narrow card, a
182
+ * SplitPane aside, or a bare `<div>`; it can never silently stay one column for want of an
183
+ * external container context (gh#165). Named so it queries its own scope, never a closer one. */
184
+ .ui-responsive-grid-scope {
185
+ container: responsive-grid / inline-size;
186
+ }
187
+
178
188
  .ui-responsive-grid {
179
189
  display: grid;
180
190
  gap: var(--space-stack-md);
@@ -185,24 +195,33 @@
185
195
  min-width: 0;
186
196
  }
187
197
 
188
- @container (min-width: 640px) {
198
+ @container responsive-grid (min-width: 40rem) {
189
199
  .ui-responsive-grid {
190
200
  grid-template-columns: repeat(var(--responsive-grid-sm, 2), minmax(0, 1fr));
191
201
  }
192
202
  }
193
203
 
194
- @container (min-width: 768px) {
204
+ @container responsive-grid (min-width: 48rem) {
195
205
  .ui-responsive-grid {
196
206
  grid-template-columns: repeat(var(--responsive-grid-md, 3), minmax(0, 1fr));
197
207
  }
198
208
  }
199
209
 
200
- @container (min-width: 1024px) {
210
+ @container responsive-grid (min-width: 64rem) {
201
211
  .ui-responsive-grid {
202
212
  grid-template-columns: repeat(var(--responsive-grid-lg, 4), minmax(0, 1fr));
203
213
  }
204
214
  }
205
215
 
216
+ /* SplitPane OWNS its query container too — `.ui-split-pane-scope`
217
+ * (container-type: inline-size, named `split-pane`). The two-column layout is chosen from the
218
+ * pane's OWN available width, so a narrow embedded pane on a large viewport correctly stays a
219
+ * single column, and a wide pane on a small viewport can split (gh#165 — replaces the old
220
+ * `@media (min-width: 1080px)` viewport query that ignored the container). */
221
+ .ui-split-pane-scope {
222
+ container: split-pane / inline-size;
223
+ }
224
+
206
225
  .ui-split-pane {
207
226
  display: grid;
208
227
  gap: var(--space-stack-md);
@@ -259,7 +278,7 @@
259
278
  opacity: 0.5;
260
279
  }
261
280
 
262
- @media (min-width: 1080px) {
281
+ @container split-pane (min-width: 48rem) {
263
282
  .ui-split-pane[data-aside-width="sm"] {
264
283
  grid-template-columns: minmax(0, 1fr) 20rem;
265
284
  }
@@ -543,22 +562,30 @@
543
562
  }
544
563
 
545
564
  @layer components {
565
+ /* Pagination is ONE horizontal row and never wraps to a second desktop line (gh#153 — the old
566
+ * `flex-wrap: wrap` split the range / size-changer / page strip across rows). The number strip
567
+ * (`.ui-pagination-list`) absorbs any overflow by scrolling horizontally rather than wrapping; a
568
+ * genuinely narrow viewport uses the INTENTIONAL compact form via the `simple` prop (Prev · n/N ·
569
+ * Next, no page buttons) — not browser-driven wrapping. */
546
570
  .ui-pagination {
547
571
  display: flex;
548
- flex-wrap: wrap;
572
+ flex-wrap: nowrap;
573
+ min-width: 0;
549
574
  align-items: center;
550
575
  justify-content: flex-end;
551
576
  gap: var(--pagination-gap);
552
577
  }
553
578
 
554
- .ui-pagination[data-simple="true"] {
555
- flex-wrap: nowrap;
556
- }
557
-
579
+ /* Total / range label sits at the start and truncates rather than pushing the controls onto a
580
+ * second line — the nav row stays one line at every width (gh#153). */
558
581
  .ui-pagination-total {
582
+ min-width: 0;
559
583
  margin-inline-end: auto;
584
+ overflow: hidden;
560
585
  color: hsl(var(--muted-foreground));
561
586
  font-size: var(--pagination-total-font-size);
587
+ text-overflow: ellipsis;
588
+ white-space: nowrap;
562
589
  }
563
590
 
564
591
  .ui-pagination-count {
@@ -576,12 +603,22 @@
576
603
 
577
604
  .ui-pagination-list {
578
605
  display: flex;
606
+ min-width: 0;
579
607
  align-items: center;
580
608
  gap: var(--pagination-item-gap);
609
+ /* Overflow scrolls horizontally instead of wrapping onto a second row. Hidden scrollbar keeps
610
+ * the desktop bar clean; the strip stays swipeable on touch. */
611
+ overflow-x: auto;
612
+ scrollbar-width: none;
613
+ }
614
+
615
+ .ui-pagination-list::-webkit-scrollbar {
616
+ display: none;
581
617
  }
582
618
 
583
619
  .ui-pagination-item {
584
620
  display: flex;
621
+ flex: 0 0 auto;
585
622
  align-items: center;
586
623
  justify-content: center;
587
624
  }
@@ -143,6 +143,21 @@
143
143
  display: none;
144
144
  }
145
145
 
146
+ /* AppShell-owned mobile drawer trigger — hidden on desktop, shown once the docked sidebar
147
+ * collapses out below `lg` (gh#165). The drawer nav itself is a focus-trapped Sheet. */
148
+ .app-mobile-nav-trigger {
149
+ display: none;
150
+ flex: 0 0 auto;
151
+ margin-inline-end: var(--space-1);
152
+ }
153
+
154
+ /* The drawer nav reuses the docked Sidebar node; its `.sb-root { display: contents }` flattens
155
+ * into the scrollable SheetBody so sections/footer flow naturally in the panel. */
156
+ .app-mobile-nav-body {
157
+ display: flex;
158
+ flex-direction: column;
159
+ }
160
+
146
161
  .app-topbar-spacer {
147
162
  flex: 1;
148
163
  }
@@ -171,6 +186,10 @@
171
186
  .app-topbar-left:has(.app-mobile-sidebar-trigger) {
172
187
  display: flex;
173
188
  }
189
+
190
+ .app-mobile-nav-trigger {
191
+ display: inline-flex;
192
+ }
174
193
  }
175
194
 
176
195
  .sb-root {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "17.0.1",
4
- "godxUiMcp": "17.0.0",
3
+ "version": "18.0.0",
4
+ "godxUiMcp": "17.0.1",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.29.1",
7
7
  "sideEffects": false,
@@ -276,9 +276,10 @@
276
276
  "test:watch": "vitest",
277
277
  "test:coverage": "vitest run --coverage",
278
278
  "check:example-imports": "node scripts/check-example-imports.mjs",
279
- "verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm test",
280
- "verify:release": "pnpm build && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm test",
279
+ "verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage && pnpm test",
280
+ "verify:release": "pnpm build && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-token-sync && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm check:frame-coverage && pnpm check:frame-axe && pnpm test",
281
281
  "check:mcp-lockstep": "node scripts/check-release-lockstep.mjs",
282
+ "check:mcp-pattern-imports": "node scripts/check-mcp-pattern-imports.mjs",
282
283
  "check:mcp-sync": "node scripts/check-mcp-sync.mjs",
283
284
  "check:mcp-orphans": "node scripts/check-mcp-orphans.mjs",
284
285
  "check:mcp-prop-sync": "node scripts/check-mcp-prop-sync.mjs",
@@ -304,6 +305,9 @@
304
305
  "check:contrast": "node scripts/check-contrast.mjs",
305
306
  "visual-audit": "node scripts/visual-audit.mjs",
306
307
  "check:visual-audit": "node scripts/visual-audit-smoke.mjs",
308
+ "check:frame-axe": "node scripts/check-frame-axe.mjs",
309
+ "check:frame-geometry": "node scripts/frame-geometry.mjs",
310
+ "check:frame-coverage": "node scripts/frame-coverage.mjs",
307
311
  "postinstall": "node scripts/postinstall.mjs",
308
312
  "init-agent": "node scripts/init-agent-kit.mjs",
309
313
  "check:use-client": "node scripts/check-use-client.mjs"