@godxjp/ui 19.1.0 → 19.3.1

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 (437) hide show
  1. package/README.md +25 -128
  2. package/dist/app/theme-axes.d.ts +4 -15
  3. package/dist/app/timezones.d.ts +1 -4
  4. package/dist/components/charts/area-chart.d.ts +2 -3
  5. package/dist/components/charts/bar-chart.d.ts +2 -3
  6. package/dist/components/charts/chart-frame.d.ts +7 -16
  7. package/dist/components/charts/chart-summary.d.ts +2 -2
  8. package/dist/components/charts/compact-bar-trend.d.ts +9 -24
  9. package/dist/components/charts/index.d.ts +1 -6
  10. package/dist/components/data-display/badge.d.ts +20 -14
  11. package/dist/components/data-display/badge.js +18 -4
  12. package/dist/components/data-display/card.d.ts +21 -41
  13. package/dist/components/data-display/carousel.d.ts +1 -2
  14. package/dist/components/data-display/code-block.d.ts +4 -0
  15. package/dist/components/data-display/code-block.js +24 -0
  16. package/dist/components/data-display/data-table.d.ts +15 -37
  17. package/dist/components/data-display/data-table.js +1 -3
  18. package/dist/components/data-display/descriptions.d.ts +2 -6
  19. package/dist/components/data-display/descriptions.js +0 -2
  20. package/dist/components/data-display/index.d.ts +4 -0
  21. package/dist/components/data-display/index.js +4 -0
  22. package/dist/components/data-display/list-row.d.ts +3 -22
  23. package/dist/components/data-display/permission-matrix.d.ts +7 -20
  24. package/dist/components/data-display/progress.d.ts +1 -1
  25. package/dist/components/data-display/prose.d.ts +4 -0
  26. package/dist/components/data-display/prose.js +20 -0
  27. package/dist/components/data-display/service-launcher-card.d.ts +3 -10
  28. package/dist/components/data-display/table.d.ts +20 -80
  29. package/dist/components/data-display/table.js +0 -3
  30. package/dist/components/data-display/timeline.d.ts +3 -5
  31. package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
  32. package/dist/components/data-entry/branch-scope-picker.js +0 -1
  33. package/dist/components/data-entry/calendar.d.ts +3 -2
  34. package/dist/components/data-entry/calendar.js +58 -3
  35. package/dist/components/data-entry/command-palette.d.ts +8 -22
  36. package/dist/components/data-entry/date-picker.d.ts +4 -5
  37. package/dist/components/data-entry/date-picker.js +6 -1
  38. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  39. package/dist/components/data-entry/date-range-picker.js +8 -3
  40. package/dist/components/data-entry/form-errors.d.ts +7 -18
  41. package/dist/components/data-entry/form-field.js +1 -5
  42. package/dist/components/data-entry/form.d.ts +1 -9
  43. package/dist/components/data-entry/input.d.ts +16 -14
  44. package/dist/components/data-entry/input.js +3 -0
  45. package/dist/components/data-entry/month-picker.js +2 -2
  46. package/dist/components/data-entry/month-range-picker.d.ts +4 -6
  47. package/dist/components/data-entry/month-range-picker.js +2 -2
  48. package/dist/components/data-entry/number-input.d.ts +1 -5
  49. package/dist/components/data-entry/number-input.js +1 -0
  50. package/dist/components/data-entry/radio.js +0 -1
  51. package/dist/components/data-entry/search-select.d.ts +2 -4
  52. package/dist/components/data-entry/select.d.ts +11 -6
  53. package/dist/components/data-entry/select.js +4 -2
  54. package/dist/components/data-entry/switch.js +0 -1
  55. package/dist/components/data-entry/textarea.d.ts +10 -16
  56. package/dist/components/data-entry/time-picker.d.ts +3 -5
  57. package/dist/components/data-entry/upload-types.d.ts +1 -5
  58. package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
  59. package/dist/components/feedback/dialog.d.ts +6 -15
  60. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  61. package/dist/components/feedback/sheet.d.ts +3 -10
  62. package/dist/components/feedback/sheet.js +1 -1
  63. package/dist/components/feedback/sonner.js +2 -3
  64. package/dist/components/general/activity.d.ts +4 -30
  65. package/dist/components/general/button.js +1 -10
  66. package/dist/components/general/logo.d.ts +6 -28
  67. package/dist/components/general/reveal.d.ts +3 -9
  68. package/dist/components/general/typography.d.ts +1 -3
  69. package/dist/components/layout/account-chip.d.ts +8 -0
  70. package/dist/components/layout/account-chip.js +45 -0
  71. package/dist/components/layout/auth-divider.d.ts +2 -9
  72. package/dist/components/layout/auth-shell.d.ts +1 -14
  73. package/dist/components/layout/breadcrumb.d.ts +1 -5
  74. package/dist/components/layout/centered-shell.d.ts +4 -18
  75. package/dist/components/layout/error-surface.d.ts +11 -28
  76. package/dist/components/layout/error-surface.js +4 -1
  77. package/dist/components/layout/index.d.ts +2 -0
  78. package/dist/components/layout/index.js +2 -0
  79. package/dist/components/layout/legal-document-shell.d.ts +5 -28
  80. package/dist/components/layout/master-detail.d.ts +2 -18
  81. package/dist/components/layout/page-container.js +0 -1
  82. package/dist/components/layout/responsive-grid.d.ts +6 -1
  83. package/dist/components/layout/responsive-grid.js +9 -2
  84. package/dist/components/layout/service-role-panel.d.ts +7 -19
  85. package/dist/components/layout/sidebar.d.ts +5 -27
  86. package/dist/components/layout/sidebar.js +0 -1
  87. package/dist/components/layout/split-pane.d.ts +0 -7
  88. package/dist/components/layout/topbar.d.ts +1 -14
  89. package/dist/components/navigation/app-setting-picker.js +1 -3
  90. package/dist/components/navigation/filter-bar.d.ts +1 -6
  91. package/dist/components/navigation/pagination-utils.d.ts +2 -12
  92. package/dist/components/navigation/tabs-scroll.d.ts +2 -36
  93. package/dist/components/navigation/tabs.js +4 -8
  94. package/dist/components/query/data-state.d.ts +2 -2
  95. package/dist/components/ui/credential-reveal.d.ts +1 -4
  96. package/dist/components/ui/hover-card.d.ts +1 -2
  97. package/dist/components/ui/separator.d.ts +2 -15
  98. package/dist/components/ui/toggle-group.d.ts +1 -5
  99. package/dist/components/ui/toggle.d.ts +6 -31
  100. package/dist/email/brand-mark.d.ts +6 -34
  101. package/dist/email/color.d.ts +7 -17
  102. package/dist/email/geometry.d.ts +4 -8
  103. package/dist/email/index.d.ts +4 -48
  104. package/dist/email/inline-style.d.ts +3 -9
  105. package/dist/email/urgency.d.ts +2 -7
  106. package/dist/form/form-context.d.ts +2 -5
  107. package/dist/form/form-root.d.ts +1 -2
  108. package/dist/i18n/messages/en.json +4 -0
  109. package/dist/i18n/messages/ja.json +4 -0
  110. package/dist/i18n/messages/vi.json +4 -0
  111. package/dist/inertia/index.d.ts +2 -10
  112. package/dist/lib/control-styles.d.ts +10 -21
  113. package/dist/lib/control-styles.js +4 -6
  114. package/dist/lib/datetime/format-date.d.ts +1 -4
  115. package/dist/lib/field-a11y.d.ts +11 -68
  116. package/dist/lib/field-a11y.js +0 -1
  117. package/dist/lib/format.d.ts +4 -8
  118. package/dist/lib/hooks.d.ts +6 -12
  119. package/dist/lib/permission-grid.d.ts +3 -18
  120. package/dist/lib/query-error.d.ts +3 -3
  121. package/dist/props/components/app.prop.d.ts +15 -38
  122. package/dist/props/components/charts.prop.d.ts +2 -3
  123. package/dist/props/components/data-display.prop.d.ts +55 -72
  124. package/dist/props/components/data-entry.prop.d.ts +35 -40
  125. package/dist/props/components/form.prop.d.ts +2 -6
  126. package/dist/props/components/general.prop.d.ts +11 -27
  127. package/dist/props/components/layout.prop.d.ts +89 -260
  128. package/dist/props/components/navigation.prop.d.ts +27 -42
  129. package/dist/props/registry.d.ts +36 -1
  130. package/dist/props/registry.js +45 -1
  131. package/dist/props/vocabulary/data.prop.d.ts +18 -49
  132. package/dist/props/vocabulary/index.d.ts +1 -1
  133. package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
  134. package/dist/props/vocabulary/layout.prop.d.ts +8 -30
  135. package/dist/props/vocabulary/shared.prop.d.ts +3 -2
  136. package/dist/styles/alert-layout.css +1 -32
  137. package/dist/styles/badge-layout.css +19 -18
  138. package/dist/styles/base.css +14 -113
  139. package/dist/styles/card-layout.css +6 -128
  140. package/dist/styles/chart-layout.css +2 -17
  141. package/dist/styles/control.css +380 -458
  142. package/dist/styles/core.css +21 -0
  143. package/dist/styles/data-display-layout.css +175 -94
  144. package/dist/styles/data-entry-layout.css +0 -45
  145. package/dist/styles/density.css +1 -30
  146. package/dist/styles/dialog-layout.css +5 -69
  147. package/dist/styles/focus-ring.css +13 -87
  148. package/dist/styles/fonts.css +1 -31
  149. package/dist/styles/form-layout.css +7 -91
  150. package/dist/styles/index.css +2 -20
  151. package/dist/styles/layout.css +38 -456
  152. package/dist/styles/logo-layout.css +1 -35
  153. package/dist/styles/motion.css +3 -42
  154. package/dist/styles/navigation-layout.css +3 -50
  155. package/dist/styles/shell-layout.css +37 -403
  156. package/dist/styles/table-layout.css +16 -274
  157. package/dist/styles/text-layout.css +7 -21
  158. package/dist/styles/toggle.css +1 -23
  159. package/dist/theme/dxs.canonical.css +1 -55
  160. package/dist/theme/example.service.css +1 -26
  161. package/dist/theme/famgia.service.css +5 -15
  162. package/dist/tokens/axes.css +3 -40
  163. package/dist/tokens/base.css +1 -4
  164. package/dist/tokens/components/activity.css +6 -42
  165. package/dist/tokens/components/badge.css +12 -13
  166. package/dist/tokens/components/banner.css +4 -9
  167. package/dist/tokens/components/card.css +32 -88
  168. package/dist/tokens/components/chart.css +9 -26
  169. package/dist/tokens/components/control.css +37 -222
  170. package/dist/tokens/components/data-display.css +28 -79
  171. package/dist/tokens/components/data-entry.css +5 -19
  172. package/dist/tokens/components/descriptions.css +7 -27
  173. package/dist/tokens/components/email.css +38 -84
  174. package/dist/tokens/components/error-surface.css +2 -18
  175. package/dist/tokens/components/feedback.css +27 -124
  176. package/dist/tokens/components/form.css +13 -45
  177. package/dist/tokens/components/legal-document.css +16 -41
  178. package/dist/tokens/components/list-row.css +11 -36
  179. package/dist/tokens/components/logo.css +2 -57
  180. package/dist/tokens/components/navigation.css +16 -94
  181. package/dist/tokens/components/scroll-area.css +2 -18
  182. package/dist/tokens/components/separator.css +8 -30
  183. package/dist/tokens/components/sheet.css +3 -14
  184. package/dist/tokens/components/shell.css +53 -307
  185. package/dist/tokens/components/sidebar.css +5 -22
  186. package/dist/tokens/components/table.css +19 -140
  187. package/dist/tokens/components/toggle.css +3 -65
  188. package/dist/tokens/components/upload.css +7 -43
  189. package/dist/tokens/foundation.css +108 -383
  190. package/dist/tokens/semantic/layout.css +33 -207
  191. package/docs/CANONICAL-CONTRACTS.md +206 -0
  192. package/docs/COMPONENTS.md +157 -0
  193. package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
  194. package/docs/CONSUMER-RULES.md +14 -0
  195. package/docs/CUSTOMER-THEMING.md +162 -0
  196. package/docs/DATETIME.md +69 -0
  197. package/docs/DEVELOPMENT.md +173 -0
  198. package/docs/FORMS.md +143 -0
  199. package/docs/FRAME-A11Y-CI.md +267 -0
  200. package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
  201. package/docs/FRAME-COVERAGE-REPORT.md +140 -0
  202. package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
  203. package/docs/FRAME-COVERAGE.md +29 -0
  204. package/docs/PROPS-REGISTRY.md +61 -0
  205. package/docs/PROPS-VOCABULARY.md +100 -0
  206. package/docs/README.md +60 -0
  207. package/docs/REGISTRY.md +70 -0
  208. package/docs/SPACING.md +56 -0
  209. package/docs/STANDARDS-vocabulary-tokens.md +48 -0
  210. package/docs/TESTING.md +98 -0
  211. package/docs/TOKENS.md +347 -0
  212. package/docs/asset-modules.d.ts +46 -0
  213. package/docs/assets/cover-terrain.svg +6 -0
  214. package/docs/assets/portrait-amber.svg +5 -0
  215. package/docs/assets/portrait-clay.svg +5 -0
  216. package/docs/assets/portrait-indigo.svg +5 -0
  217. package/docs/assets/portrait-iris.svg +5 -0
  218. package/docs/assets/portrait-moss.svg +5 -0
  219. package/docs/assets/portrait-plum.svg +5 -0
  220. package/docs/assets/portrait-slate.svg +5 -0
  221. package/docs/charts/compact-bar-trend.tsx +328 -0
  222. package/docs/charts/size-tiers.tsx +192 -0
  223. package/docs/data-display/accordion.tsx +99 -0
  224. package/docs/data-display/avatar.tsx +355 -0
  225. package/docs/data-display/badge.tsx +283 -0
  226. package/docs/data-display/card/examples/detail-panel.tsx +106 -0
  227. package/docs/data-display/card/index.md +3 -0
  228. package/docs/data-display/card/index.tsx +285 -0
  229. package/docs/data-display/carousel.tsx +160 -0
  230. package/docs/data-display/charts.tsx +198 -0
  231. package/docs/data-display/code-block.tsx +90 -0
  232. package/docs/data-display/collapsible.tsx +162 -0
  233. package/docs/data-display/credential-reveal.tsx +145 -0
  234. package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
  235. package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
  236. package/docs/data-display/data-table/examples/list-page.tsx +175 -0
  237. package/docs/data-display/data-table/index.md +5 -0
  238. package/docs/data-display/data-table/index.tsx +295 -0
  239. package/docs/data-display/descriptions.tsx +143 -0
  240. package/docs/data-display/empty-state.tsx +164 -0
  241. package/docs/data-display/hover-card.tsx +181 -0
  242. package/docs/data-display/list-row.tsx +420 -0
  243. package/docs/data-display/permission-matrix.tsx +188 -0
  244. package/docs/data-display/popover-touch.tsx +27 -0
  245. package/docs/data-display/popover.tsx +246 -0
  246. package/docs/data-display/progress.tsx +84 -0
  247. package/docs/data-display/prose.tsx +105 -0
  248. package/docs/data-display/qr-code.tsx +68 -0
  249. package/docs/data-display/scroll-area.tsx +303 -0
  250. package/docs/data-display/service-launcher-card.tsx +145 -0
  251. package/docs/data-display/stat-card.tsx +99 -0
  252. package/docs/data-display/table.tsx +251 -0
  253. package/docs/data-display/timeline.tsx +112 -0
  254. package/docs/data-display/touch-actions.tsx +36 -0
  255. package/docs/data-display/tree-list.tsx +107 -0
  256. package/docs/data-entry/branch-scope-picker.tsx +123 -0
  257. package/docs/data-entry/calendar.tsx +180 -0
  258. package/docs/data-entry/cascader.tsx +378 -0
  259. package/docs/data-entry/checkbox.tsx +256 -0
  260. package/docs/data-entry/color-picker.tsx +117 -0
  261. package/docs/data-entry/command-palette.tsx +179 -0
  262. package/docs/data-entry/command.tsx +262 -0
  263. package/docs/data-entry/country-picker-recipe.tsx +175 -0
  264. package/docs/data-entry/date-picker.tsx +191 -0
  265. package/docs/data-entry/date-range-picker.tsx +149 -0
  266. package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
  267. package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
  268. package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
  269. package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
  270. package/docs/data-entry/form-field/index.md +8 -0
  271. package/docs/data-entry/form-field/index.tsx +330 -0
  272. package/docs/data-entry/form-inertia.tsx +80 -0
  273. package/docs/data-entry/form-root.tsx +102 -0
  274. package/docs/data-entry/form.tsx +724 -0
  275. package/docs/data-entry/input-otp.tsx +231 -0
  276. package/docs/data-entry/input.tsx +114 -0
  277. package/docs/data-entry/label.tsx +100 -0
  278. package/docs/data-entry/month-picker.tsx +101 -0
  279. package/docs/data-entry/month-range-picker.tsx +115 -0
  280. package/docs/data-entry/number-input.tsx +240 -0
  281. package/docs/data-entry/password-input.tsx +102 -0
  282. package/docs/data-entry/password-strength.tsx +97 -0
  283. package/docs/data-entry/radio-group.tsx +95 -0
  284. package/docs/data-entry/rating.tsx +87 -0
  285. package/docs/data-entry/search-input.tsx +120 -0
  286. package/docs/data-entry/select-async-contracts.tsx +108 -0
  287. package/docs/data-entry/select-matrix.tsx +204 -0
  288. package/docs/data-entry/select.tsx +369 -0
  289. package/docs/data-entry/slider.tsx +130 -0
  290. package/docs/data-entry/switch.tsx +67 -0
  291. package/docs/data-entry/tag-input.tsx +108 -0
  292. package/docs/data-entry/textarea.tsx +209 -0
  293. package/docs/data-entry/time-picker.tsx +99 -0
  294. package/docs/data-entry/toggle-count.tsx +293 -0
  295. package/docs/data-entry/toggle-group.tsx +225 -0
  296. package/docs/data-entry/toggle.tsx +127 -0
  297. package/docs/data-entry/transfer.tsx +97 -0
  298. package/docs/data-entry/tree-select.tsx +204 -0
  299. package/docs/data-entry/upload.tsx +184 -0
  300. package/docs/feedback/alert-dialog.tsx +270 -0
  301. package/docs/feedback/alert.tsx +248 -0
  302. package/docs/feedback/banner.tsx +183 -0
  303. package/docs/feedback/danger-confirm.tsx +88 -0
  304. package/docs/feedback/dialog-touch.tsx +24 -0
  305. package/docs/feedback/dialog.tsx +193 -0
  306. package/docs/feedback/sheet.tsx +420 -0
  307. package/docs/feedback/skeleton.tsx +111 -0
  308. package/docs/feedback/toast.tsx +135 -0
  309. package/docs/feedback/tooltip.tsx +171 -0
  310. package/docs/feedback/two-factor-setup.tsx +68 -0
  311. package/docs/foundation/_email-specimen.ts +274 -0
  312. package/docs/foundation/colors.tsx +204 -0
  313. package/docs/foundation/density.tsx +232 -0
  314. package/docs/foundation/email-tokens.tsx +323 -0
  315. package/docs/foundation/radius-shadow.tsx +154 -0
  316. package/docs/foundation/spacing.tsx +211 -0
  317. package/docs/foundation/typography.tsx +147 -0
  318. package/docs/general/activity.tsx +224 -0
  319. package/docs/general/button/examples/destructive-confirm.tsx +90 -0
  320. package/docs/general/button/examples/form-actions.tsx +85 -0
  321. package/docs/general/button/examples/toolbar.tsx +160 -0
  322. package/docs/general/button/index.md +12 -0
  323. package/docs/general/button/index.tsx +211 -0
  324. package/docs/general/logo.tsx +131 -0
  325. package/docs/general/reveal.tsx +41 -0
  326. package/docs/general/typography.tsx +152 -0
  327. package/docs/layout/account-chip.tsx +72 -0
  328. package/docs/layout/admin-collection.tsx +122 -0
  329. package/docs/layout/app-shell.tsx +374 -0
  330. package/docs/layout/aspect-ratio.tsx +135 -0
  331. package/docs/layout/auth-account-summary.tsx +103 -0
  332. package/docs/layout/auth-divider.tsx +28 -0
  333. package/docs/layout/auth-footer.tsx +37 -0
  334. package/docs/layout/auth-identity.tsx +36 -0
  335. package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
  336. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
  337. package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
  338. package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
  339. package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
  340. package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
  341. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
  342. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
  343. package/docs/layout/auth-recovery/index.md +140 -0
  344. package/docs/layout/auth-recovery/index.tsx +96 -0
  345. package/docs/layout/auth-shell-context.tsx +103 -0
  346. package/docs/layout/auth-shell-device.tsx +112 -0
  347. package/docs/layout/auth-shell-registration.tsx +335 -0
  348. package/docs/layout/auth-shell-variants.tsx +139 -0
  349. package/docs/layout/auth-shell.tsx +59 -0
  350. package/docs/layout/auth-stack.tsx +40 -0
  351. package/docs/layout/centered-shell.tsx +102 -0
  352. package/docs/layout/error-surface/examples/application-403.tsx +84 -0
  353. package/docs/layout/error-surface/examples/application-404.tsx +77 -0
  354. package/docs/layout/error-surface/examples/system-500.tsx +47 -0
  355. package/docs/layout/error-surface/examples/system-503.tsx +48 -0
  356. package/docs/layout/error-surface/index.md +153 -0
  357. package/docs/layout/error-surface/index.tsx +239 -0
  358. package/docs/layout/flex.tsx +266 -0
  359. package/docs/layout/legal-document-shell/_data.ts +110 -0
  360. package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
  361. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
  362. package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
  363. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
  364. package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
  365. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
  366. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
  367. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
  368. package/docs/layout/legal-document-shell/index.md +51 -0
  369. package/docs/layout/legal-document-shell/index.tsx +101 -0
  370. package/docs/layout/master-detail.tsx +387 -0
  371. package/docs/layout/org-switcher.tsx +131 -0
  372. package/docs/layout/page-container.tsx +954 -0
  373. package/docs/layout/resizable-panel.tsx +419 -0
  374. package/docs/layout/responsive-grid.tsx +243 -0
  375. package/docs/layout/separator.tsx +327 -0
  376. package/docs/layout/service-role-panel.tsx +144 -0
  377. package/docs/layout/sidebar.tsx +609 -0
  378. package/docs/layout/split-pane.tsx +468 -0
  379. package/docs/layout/topbar.tsx +349 -0
  380. package/docs/navigation/app-setting-picker.tsx +142 -0
  381. package/docs/navigation/breadcrumb.tsx +135 -0
  382. package/docs/navigation/context-menu.tsx +123 -0
  383. package/docs/navigation/dropdown-menu.tsx +213 -0
  384. package/docs/navigation/filter-bar.tsx +227 -0
  385. package/docs/navigation/menubar.tsx +141 -0
  386. package/docs/navigation/navigation-menu.tsx +158 -0
  387. package/docs/navigation/pagination.tsx +241 -0
  388. package/docs/navigation/steps.tsx +265 -0
  389. package/docs/navigation/tabs-rtl.tsx +28 -0
  390. package/docs/navigation/tabs.tsx +314 -0
  391. package/docs/navigation/toolbar.tsx +339 -0
  392. package/docs/providers/app-provider.tsx +191 -0
  393. package/docs/providers/format-date.tsx +230 -0
  394. package/docs/query/button-refetch.tsx +160 -0
  395. package/docs/query/data-state.tsx +192 -0
  396. package/docs/query/infinite-query-state.tsx +93 -0
  397. package/docs/query/mutation-feedback.tsx +70 -0
  398. package/docs/query/prefetch-link.tsx +262 -0
  399. package/docs/query/touch-actions.tsx +68 -0
  400. package/docs/showcase/acme-portal.tsx +455 -0
  401. package/docs/showcase/acme-website.tsx +461 -0
  402. package/docs/showcase/case1-warehouse-dashboard.tsx +359 -0
  403. package/docs/showcase/case2-employee-me.tsx +444 -0
  404. package/docs/showcase/case3-approval-workflow.tsx +529 -0
  405. package/docs/showcase/case4-login.tsx +313 -0
  406. package/docs/showcase/case5-shift-calendar.tsx +795 -0
  407. package/docs/showcase/case6-agency-handy.tsx +1113 -0
  408. package/docs/showcase/futurelastic-web.tsx +392 -0
  409. package/docs/showcase/org-switcher.tsx +313 -0
  410. package/docs/showcase/permission-matrix.tsx +346 -0
  411. package/docs/showcase/public-landing.tsx +210 -0
  412. package/docs/showcase/settings-account-sections.tsx +559 -0
  413. package/docs/showcase/settings-security-mfa.tsx +145 -0
  414. package/docs/showcase/table-approval-queue.tsx +199 -0
  415. package/docs/showcase/table-bulk-actions.tsx +460 -0
  416. package/docs/showcase/table-compact-kintone.tsx +438 -0
  417. package/docs/showcase/table-conditional-format.tsx +367 -0
  418. package/docs/showcase/table-crud-list.tsx +544 -0
  419. package/docs/showcase/table-density.tsx +347 -0
  420. package/docs/showcase/table-expandable-rows.tsx +480 -0
  421. package/docs/showcase/table-filter-chips.tsx +456 -0
  422. package/docs/showcase/table-footer-totals.tsx +314 -0
  423. package/docs/showcase/table-grouped-subtotals.tsx +391 -0
  424. package/docs/showcase/table-master-detail.tsx +484 -0
  425. package/docs/showcase/table-pagination.tsx +327 -0
  426. package/docs/showcase/table-states.tsx +366 -0
  427. package/docs/showcase/table-sticky-columns.tsx +376 -0
  428. package/docs/showcase/table-tree-rows.tsx +444 -0
  429. package/docs/showcase/table-view-tabs.tsx +488 -0
  430. package/package.json +9 -12
  431. package/scripts/_agent-setup.mjs +16 -2
  432. package/scripts/audit-hook.mjs +3 -13
  433. package/scripts/init-agent-kit.mjs +1 -14
  434. package/scripts/postinstall.mjs +12 -12
  435. package/scripts/ui-audit.mjs +93 -31
  436. package/scripts/visual-audit-rules.mjs +51 -7
  437. package/scripts/visual-audit.mjs +118 -47
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Showcase · table-pagination — ページネーション (V14)
3
+ *
4
+ * Three pagination modes for a 勤怠 (attendance) DataTable, shown side by side so a
5
+ * consumer can pick the right one for their dataset shape:
6
+ *
7
+ * 1. 番号付き + 件数選択 … numbered pages + page-size Select
8
+ * → real <Pagination showSizeChanger showTotal> (navigation primitive,
9
+ * which embeds the page-size Select itself). DataTable slices the page.
10
+ * 2. もっと読む … "load more" / infinite-style append button
11
+ * → real <Button> that grows the visible window; quiet remaining-count copy.
12
+ * 3. カーソル / 期間ジャンプ … cursor first/next + period jump
13
+ * → real <DataTable.Pagination> (cursor first/next) paired with a period
14
+ * <Select> to jump between months — for time-series 勤怠 logs where
15
+ * offset paging is meaningless.
16
+ *
17
+ * Each card is an INDEPENDENT pattern: its own state setters, its own data.
18
+ *
19
+ * Built ENTIRELY from real @godxjp/ui primitives. NO hand-rolled <table>, NO
20
+ * raw HTML controls. reference-design DNA: compact density, tabular-nums on numeric
21
+ * columns, fixed color signaling via Badge status/tone, small headings, quiet
22
+ * JP copy, no emoji.
23
+ */
24
+ import * as React from "react";
25
+
26
+ import {
27
+ Badge,
28
+ Card,
29
+ CardAction,
30
+ CardContent,
31
+ CardHeader,
32
+ CardTitle,
33
+ DataTable,
34
+ type ColumnDef,
35
+ } from "@godxjp/ui/data-display";
36
+ import { Button, Text } from "@godxjp/ui/general";
37
+ import { Flex, PageContainer } from "@godxjp/ui/layout";
38
+ import { Pagination } from "@godxjp/ui/navigation";
39
+ import {
40
+ Select,
41
+ SelectContent,
42
+ SelectItem,
43
+ SelectTrigger,
44
+ SelectValue,
45
+ } from "@godxjp/ui/data-entry";
46
+ import { ChevronDown } from "lucide-react";
47
+
48
+ // ── Domain: a 勤怠 (attendance) record ────────────────────────────────────────
49
+
50
+ type AttendanceStatus = "active" | "pending" | "failed" | "scheduled";
51
+
52
+ type Attendance = {
53
+ id: string;
54
+ date: string; // 勤務日
55
+ employee: string; // 従業員
56
+ dept: string; // 部署
57
+ clockIn: string; // 出勤
58
+ clockOut: string; // 退勤
59
+ overtime: number; // 残業 (分)
60
+ /** active=承認済 / pending=承認待ち / failed=打刻漏れ / scheduled=シフト予定 */
61
+ status: AttendanceStatus;
62
+ };
63
+
64
+ const STATUS_LABEL: Record<AttendanceStatus, string> = {
65
+ active: "承認済",
66
+ pending: "承認待ち",
67
+ failed: "打刻漏れ",
68
+ scheduled: "シフト予定",
69
+ };
70
+
71
+ const DEPTS = ["営業部", "開発部", "総務部", "物流部"] as const;
72
+ const NAMES = [
73
+ "山田 太郎",
74
+ "佐藤 花子",
75
+ "鈴木 一郎",
76
+ "高橋 美咲",
77
+ "田中 健",
78
+ "伊藤 さくら",
79
+ "渡辺 大輔",
80
+ "中村 由美",
81
+ ];
82
+
83
+ // Deterministic, realistic-looking 勤怠 rows (no Math.random — stable at rest).
84
+ function makeRows(count: number, prefix = "ATT"): Attendance[] {
85
+ const statuses: AttendanceStatus[] = ["active", "active", "pending", "failed", "scheduled"];
86
+ return Array.from({ length: count }, (_, i) => {
87
+ const ot = [0, 15, 30, 45, 60, 90, 120][i % 7];
88
+ const startHour = 9 + (i % 2);
89
+ return {
90
+ id: `${prefix}-${String(1000 + i)}`,
91
+ date: `2026-06-${String((i % 28) + 1).padStart(2, "0")}`,
92
+ employee: NAMES[i % NAMES.length],
93
+ dept: DEPTS[i % DEPTS.length],
94
+ clockIn: `0${startHour}:${["02", "58", "31", "07"][i % 4]}`,
95
+ clockOut: ot ? `${18 + Math.floor(ot / 60)}:${String(ot % 60).padStart(2, "0")}` : "18:00",
96
+ overtime: ot,
97
+ status: statuses[i % statuses.length],
98
+ };
99
+ });
100
+ }
101
+
102
+ const minutesFmt = (m: number) => (m === 0 ? "—" : `${m}分`);
103
+
104
+ // Columns are shared between the cards (pure data — no per-card state inside).
105
+ const columns: ColumnDef<Attendance>[] = [
106
+ { key: "date", header: "勤務日", width: "w-28" },
107
+ { key: "employee", header: "従業員" },
108
+ { key: "dept", header: "部署", hiddenOnMobile: true },
109
+ {
110
+ key: "clockIn",
111
+ header: "出勤",
112
+ align: "right",
113
+ render: (row) => <Text tabular>{row.clockIn}</Text>,
114
+ },
115
+ {
116
+ key: "clockOut",
117
+ header: "退勤",
118
+ align: "right",
119
+ render: (row) => <Text tabular>{row.clockOut}</Text>,
120
+ },
121
+ {
122
+ key: "overtime",
123
+ header: "残業",
124
+ align: "right",
125
+ hiddenOnMobile: true,
126
+ render: (row) => <Text tabular>{minutesFmt(row.overtime)}</Text>,
127
+ },
128
+ {
129
+ key: "status",
130
+ header: "状態",
131
+ align: "center",
132
+ render: (row) => <Badge status={row.status}>{STATUS_LABEL[row.status]}</Badge>,
133
+ },
134
+ ];
135
+
136
+ // ── Mode 1: numbered pages + page-size Select ─────────────────────────────────
137
+
138
+ const NUMBERED_DATA = makeRows(83, "OFS");
139
+
140
+ function NumberedPaginationCard() {
141
+ const [page, setPage] = React.useState(2); // start mid-set so prev/next are both live
142
+ const [pageSize, setPageSize] = React.useState(10);
143
+
144
+ const start = (page - 1) * pageSize;
145
+ const rows = NUMBERED_DATA.slice(start, start + pageSize);
146
+
147
+ return (
148
+ <Card>
149
+ <CardHeader>
150
+ <CardTitle level={2}>番号付き + 件数選択</CardTitle>
151
+ <CardAction>
152
+ <Text size="xs" tone="muted" tabular>
153
+ 全 {NUMBERED_DATA.length} 件
154
+ </Text>
155
+ </CardAction>
156
+ </CardHeader>
157
+ <CardContent flush>
158
+ <DataTable data={rows} columns={columns} getRowId={(row) => row.id} density="compact" />
159
+ </CardContent>
160
+ <CardContent className="border-t">
161
+ <Pagination
162
+ value={page}
163
+ total={NUMBERED_DATA.length}
164
+ pageSize={pageSize}
165
+ pageSizeOptions={[10, 20, 50]}
166
+ showSizeChanger
167
+ showTotal={(total, [from, to]) => `${from}–${to} / ${total} 件`}
168
+ onValueChange={(nextPage, nextSize) => {
169
+ setPage(nextPage);
170
+ setPageSize(nextSize);
171
+ }}
172
+ />
173
+ </CardContent>
174
+ </Card>
175
+ );
176
+ }
177
+
178
+ // ── Mode 2: load-more button ─────────────────────────────────────────────────
179
+
180
+ const LOADMORE_DATA = makeRows(42, "LDM");
181
+ const LOADMORE_STEP = 8;
182
+
183
+ function LoadMoreCard() {
184
+ // Mid-load state at rest: some rows already revealed, more remaining.
185
+ const [visible, setVisible] = React.useState(LOADMORE_STEP * 2);
186
+ const [loading, setLoading] = React.useState(false);
187
+
188
+ const rows = LOADMORE_DATA.slice(0, visible);
189
+ const remaining = LOADMORE_DATA.length - visible;
190
+ const done = remaining <= 0;
191
+
192
+ const loadMore = () => {
193
+ if (done || loading) return;
194
+ setLoading(true);
195
+ // Simulate a fetch so the disabled-while-pending state is observable.
196
+ window.setTimeout(() => {
197
+ setVisible((v) => Math.min(v + LOADMORE_STEP, LOADMORE_DATA.length));
198
+ setLoading(false);
199
+ }, 900);
200
+ };
201
+
202
+ return (
203
+ <Card>
204
+ <CardHeader>
205
+ <CardTitle level={2}>もっと読む</CardTitle>
206
+ <CardAction>
207
+ <Text size="xs" tone="muted" tabular>
208
+ {rows.length} / {LOADMORE_DATA.length} 件表示
209
+ </Text>
210
+ </CardAction>
211
+ </CardHeader>
212
+ <CardContent flush>
213
+ <DataTable data={rows} columns={columns} getRowId={(row) => row.id} density="compact" />
214
+ </CardContent>
215
+ <CardContent className="border-t">
216
+ <Flex direction="col" align="center" gap="xs">
217
+ <Button
218
+ variant="outline"
219
+ size="sm"
220
+ onClick={loadMore}
221
+ disabled={done}
222
+ loading={loading}
223
+ loadingText="読み込み中…"
224
+ >
225
+ {!done && <ChevronDown aria-hidden="true" />}
226
+ {done
227
+ ? "すべて表示しました"
228
+ : `さらに ${Math.min(LOADMORE_STEP, remaining)} 件を読み込む`}
229
+ </Button>
230
+ {!done && (
231
+ <Text size="xs" tone="muted" tabular>
232
+ 残り {remaining} 件
233
+ </Text>
234
+ )}
235
+ </Flex>
236
+ </CardContent>
237
+ </Card>
238
+ );
239
+ }
240
+
241
+ // ── Mode 3: cursor first/next + period jump ──────────────────────────────────
242
+
243
+ // Time-series 勤怠 logs grouped by month — offset paging is meaningless here,
244
+ // so we use cursor first/next (DataTable.Pagination) + a period Select to jump.
245
+ const PERIODS = [
246
+ { value: "2026-06", label: "2026年 6月" },
247
+ { value: "2026-05", label: "2026年 5月" },
248
+ { value: "2026-04", label: "2026年 4月" },
249
+ ] as const;
250
+
251
+ const PERIOD_DATA: Record<string, Attendance[]> = {
252
+ "2026-06": makeRows(7, "CUR-06"),
253
+ "2026-05": makeRows(7, "CUR-05"),
254
+ "2026-04": makeRows(5, "CUR-04"),
255
+ };
256
+
257
+ function CursorPeriodCard() {
258
+ const [period, setPeriod] = React.useState<string>("2026-06");
259
+ // cursor === id of the last row of the previous page; undefined = first page.
260
+ const [cursor, setCursor] = React.useState<string | undefined>(undefined);
261
+
262
+ const all = PERIOD_DATA[period] ?? [];
263
+ const PAGE = 4;
264
+ const startIndex = cursor ? all.findIndex((r) => r.id === cursor) + 1 : 0;
265
+ const rows = all.slice(startIndex, startIndex + PAGE);
266
+ const lastVisibleId = rows.at(-1)?.id;
267
+ const hasMore = startIndex + PAGE < all.length;
268
+
269
+ return (
270
+ <Card>
271
+ <CardHeader>
272
+ <CardTitle level={2}>カーソル / 期間ジャンプ</CardTitle>
273
+ <CardAction>
274
+ <Select
275
+ value={period}
276
+ onValueChange={(v: string) => {
277
+ setPeriod(v);
278
+ setCursor(undefined); // jumping period resets the cursor to the first page
279
+ }}
280
+ >
281
+ <SelectTrigger size="sm" aria-label="期間を選択" className="w-36">
282
+ <SelectValue />
283
+ </SelectTrigger>
284
+ <SelectContent>
285
+ {PERIODS.map((p) => (
286
+ <SelectItem key={p.value} value={p.value}>
287
+ {p.label}
288
+ </SelectItem>
289
+ ))}
290
+ </SelectContent>
291
+ </Select>
292
+ </CardAction>
293
+ </CardHeader>
294
+ <CardContent flush>
295
+ <DataTable data={rows} columns={columns} getRowId={(row) => row.id} density="compact" />
296
+ </CardContent>
297
+ <CardContent className="border-t">
298
+ <Flex direction="row" align="center" justify="between" wrap gap="sm">
299
+ <Text size="xs" tone="muted" tabular>
300
+ {PERIODS.find((p) => p.value === period)?.label} · {all.length} 件
301
+ </Text>
302
+ <DataTable.Pagination
303
+ cursor={lastVisibleId}
304
+ hasMore={hasMore}
305
+ onChange={(next) => setCursor(next)}
306
+ />
307
+ </Flex>
308
+ </CardContent>
309
+ </Card>
310
+ );
311
+ }
312
+
313
+ export default function Demo() {
314
+ return (
315
+ <PageContainer
316
+ title="ページネーション"
317
+ subtitle="番号付き + 件数選択 · もっと読む · カーソル / 期間ジャンプ。用途に応じて使い分ける 3 つの方式"
318
+ density="compact"
319
+ >
320
+ <Flex direction="col" gap="lg">
321
+ <NumberedPaginationCard />
322
+ <LoadMoreCard />
323
+ <CursorPeriodCard />
324
+ </Flex>
325
+ </PageContainer>
326
+ );
327
+ }
@@ -0,0 +1,366 @@
1
+ /**
2
+ * Showcase · table-states — 状態 (V16)
3
+ *
4
+ * The five states a 勤怠 (attendance) DataTable must render — each shown statically,
5
+ * side by side, so a reader learns every state at rest without clicking:
6
+ *
7
+ * 1. loading … SkeletonTable inside the real Card+toolbar chrome, preserving
8
+ * the column layout (no spinner overlay).
9
+ * 2. empty … two distinct wordings — filter-empty (絞り込み結果なし, offers
10
+ * 「条件をクリア」) vs truly-empty (データなし, offers a create CTA).
11
+ * 3. error … Alert tone="destructive" carrying an error code + request-id
12
+ * (copyable, tabular-nums) + a 再試行 retry action.
13
+ * 4. partial … rows that DID load, with a warning Alert that one segment
14
+ * failed / is stale, plus a 部分再取得 retry for the missing part.
15
+ * 5. ideal … the fully-populated DataTable (sorted, status Badges).
16
+ *
17
+ * Built ENTIRELY from real @godxjp/ui primitives — DataTable / Table chrome via
18
+ * Card + DataTable.Toolbar, Skeleton family, Alert family, EmptyState, Badge,
19
+ * Button. No hand-rolled <table>, no raw controls, tokens only.
20
+ *
21
+ * DNA: compact density · small headings · tabular-nums on 時刻/件数 · fixed color
22
+ * signaling (success 若竹 / warning 山吹 / attention 朱 / danger 茜 / info 群青 via
23
+ * tone) · quiet factual JP copy · no emoji.
24
+ */
25
+ import * as React from "react";
26
+ import { Clock, Inbox, Plus, RefreshCw, SearchX } from "lucide-react";
27
+
28
+ import { Button, Heading, Text } from "@godxjp/ui/general";
29
+ import {
30
+ Badge,
31
+ Card,
32
+ CardAction,
33
+ CardContent,
34
+ CardHeader,
35
+ CardTitle,
36
+ DataTable,
37
+ EmptyState,
38
+ type ColumnDef,
39
+ } from "@godxjp/ui/data-display";
40
+ import {
41
+ Alert,
42
+ AlertActions,
43
+ AlertDescription,
44
+ AlertTitle,
45
+ SkeletonTable,
46
+ } from "@godxjp/ui/feedback";
47
+ import { Flex, PageContainer } from "@godxjp/ui/layout";
48
+
49
+ // ── Domain: 勤怠 (打刻) records ────────────────────────────────────────────────
50
+
51
+ type Punch = {
52
+ id: string;
53
+ employee: string;
54
+ dept: string;
55
+ clockIn: string;
56
+ clockOut: string;
57
+ workH: string;
58
+ status: "present" | "late" | "early" | "pending";
59
+ };
60
+
61
+ /** 勤怠ステータス → Badge tone (fixed color signaling). */
62
+ const STATUS_META: Record<
63
+ Punch["status"],
64
+ { label: string; tone: "success" | "warning" | "info" | "neutral" }
65
+ > = {
66
+ // 出勤 = 若竹(success) · 遅刻 = 山吹(warning, non-destructive lateness) ·
67
+ // 早退 = 群青(info) · 承認待ち = neutral(quiet, not a warning yet).
68
+ present: { label: "出勤", tone: "success" },
69
+ late: { label: "遅刻", tone: "warning" },
70
+ early: { label: "早退", tone: "info" },
71
+ pending: { label: "承認待ち", tone: "neutral" },
72
+ };
73
+
74
+ const COLUMNS: ColumnDef<Punch>[] = [
75
+ { key: "employee", header: "従業員", width: "w-40" },
76
+ { key: "dept", header: "部署", hiddenOnMobile: true },
77
+ {
78
+ key: "clockIn",
79
+ header: "出勤",
80
+ align: "right",
81
+ render: (r) => <Text tabular>{r.clockIn}</Text>,
82
+ },
83
+ {
84
+ key: "clockOut",
85
+ header: "退勤",
86
+ align: "right",
87
+ render: (r) => <Text tabular>{r.clockOut}</Text>,
88
+ },
89
+ {
90
+ key: "workH",
91
+ header: "実働",
92
+ align: "right",
93
+ hiddenOnMobile: true,
94
+ render: (r) => <Text tabular>{r.workH}</Text>,
95
+ },
96
+ {
97
+ key: "status",
98
+ header: "状態",
99
+ align: "center",
100
+ render: (r) => (
101
+ <Badge tone={STATUS_META[r.status].tone} variant="outline">
102
+ {STATUS_META[r.status].label}
103
+ </Badge>
104
+ ),
105
+ },
106
+ ];
107
+
108
+ const ROWS: Punch[] = [
109
+ {
110
+ id: "EMP-1042",
111
+ employee: "佐藤 美咲",
112
+ dept: "受付",
113
+ clockIn: "08:58",
114
+ clockOut: "18:02",
115
+ workH: "8.0h",
116
+ status: "present",
117
+ },
118
+ {
119
+ id: "EMP-1043",
120
+ employee: "鈴木 一郎",
121
+ dept: "倉庫",
122
+ clockIn: "09:14",
123
+ clockOut: "18:05",
124
+ workH: "7.8h",
125
+ status: "late",
126
+ },
127
+ {
128
+ id: "EMP-1044",
129
+ employee: "高橋 結衣",
130
+ dept: "経理",
131
+ clockIn: "08:55",
132
+ clockOut: "16:30",
133
+ workH: "6.6h",
134
+ status: "early",
135
+ },
136
+ {
137
+ id: "EMP-1045",
138
+ employee: "田中 健太",
139
+ dept: "配送",
140
+ clockIn: "08:49",
141
+ clockOut: "—",
142
+ workH: "—",
143
+ status: "pending",
144
+ },
145
+ {
146
+ id: "EMP-1046",
147
+ employee: "伊藤 さくら",
148
+ dept: "受付",
149
+ clockIn: "08:52",
150
+ clockOut: "18:00",
151
+ workH: "8.1h",
152
+ status: "present",
153
+ },
154
+ ];
155
+
156
+ /** Only the segment that succeeded in the `partial` case (倉庫 fetch failed). */
157
+ const PARTIAL_ROWS = ROWS.filter((r) => r.dept !== "倉庫");
158
+
159
+ // ── Local chrome: a titled section that frames each state demo ─────────────────
160
+
161
+ function StateSection({
162
+ step,
163
+ title,
164
+ note,
165
+ children,
166
+ }: {
167
+ step: string;
168
+ title: string;
169
+ note: string;
170
+ children: React.ReactNode;
171
+ }) {
172
+ return (
173
+ <Flex direction="col" gap="sm">
174
+ <Flex direction="row" align="baseline" gap="sm" wrap>
175
+ <Text size="xs" tone="muted" tabular>
176
+ {step}
177
+ </Text>
178
+ <Heading level={3} as="h2">
179
+ {title}
180
+ </Heading>
181
+ <Text size="xs" tone="muted">
182
+ {note}
183
+ </Text>
184
+ </Flex>
185
+ {children}
186
+ </Flex>
187
+ );
188
+ }
189
+
190
+ /** Shared table-card shell: the toolbar chrome stays identical across states so
191
+ * the loading skeleton visibly preserves the table's column layout. */
192
+ function TableShell({
193
+ caption,
194
+ children,
195
+ }: {
196
+ caption: React.ReactNode;
197
+ children: React.ReactNode;
198
+ }) {
199
+ return (
200
+ <Card>
201
+ <CardHeader>
202
+ <CardTitle level={2}>本日の打刻</CardTitle>
203
+ <CardAction>
204
+ <Text size="xs" tone="muted">
205
+ {caption}
206
+ </Text>
207
+ </CardAction>
208
+ </CardHeader>
209
+ <CardContent flush>{children}</CardContent>
210
+ </Card>
211
+ );
212
+ }
213
+
214
+ export default function Demo() {
215
+ return (
216
+ <PageContainer
217
+ title="DataTable の状態"
218
+ subtitle="勤怠一覧が取りうる 5 つの状態。loading · empty(絞り込み / データなし) · error · partial · ideal をすべて静止状態で並べて確認する。"
219
+ density="compact"
220
+ >
221
+ <Flex direction="col" gap="lg">
222
+ {/* 1 ─ loading: skeleton that preserves the column layout */}
223
+ <StateSection
224
+ step="1 / 5"
225
+ title="読み込み中"
226
+ note="列レイアウトを保持した SkeletonTable。スピナーオーバーレイは使わない。"
227
+ >
228
+ <TableShell caption="取得中…">
229
+ <SkeletonTable rows={5} columns={6} />
230
+ </TableShell>
231
+ </StateSection>
232
+
233
+ {/* 2 ─ empty: filter-empty vs truly-empty wording */}
234
+ <StateSection
235
+ step="2 / 5"
236
+ title="空"
237
+ note="「絞り込み結果なし」と「データなし」は文言とアクションを使い分ける。"
238
+ >
239
+ <Flex direction="col" gap="md" className="md:flex-row md:[&>*]:flex-1">
240
+ <TableShell caption="絞り込み: 部署=倉庫 / 状態=遅刻">
241
+ {/* filter-empty: data exists, the FILTER matched nothing → clear filters */}
242
+ <DataTable
243
+ data={[]}
244
+ columns={COLUMNS}
245
+ getRowId={(r) => r.id}
246
+ empty={
247
+ <EmptyState
248
+ icon={SearchX}
249
+ title="条件に一致する打刻はありません"
250
+ description="絞り込み条件を緩めるか、条件をクリアしてください。"
251
+ action={
252
+ <Button variant="outline" size="sm">
253
+ 条件をクリア
254
+ </Button>
255
+ }
256
+ />
257
+ }
258
+ />
259
+ </TableShell>
260
+
261
+ <TableShell caption="2026-06-04 · 打刻 0 件">
262
+ {/* truly-empty: no data at all for the day → create / 打刻登録 CTA */}
263
+ <DataTable
264
+ data={[]}
265
+ columns={COLUMNS}
266
+ getRowId={(r) => r.id}
267
+ empty={
268
+ <EmptyState
269
+ icon={Inbox}
270
+ title="本日の打刻はまだありません"
271
+ description="従業員が打刻すると、ここに一覧が表示されます。"
272
+ action={
273
+ <Button size="sm">
274
+ <Plus aria-hidden="true" />
275
+ 打刻を登録
276
+ </Button>
277
+ }
278
+ />
279
+ }
280
+ />
281
+ </TableShell>
282
+ </Flex>
283
+ </StateSection>
284
+
285
+ {/* 3 ─ error: code + request-id + retry */}
286
+ <StateSection
287
+ step="3 / 5"
288
+ title="エラー"
289
+ note="エラーコード・リクエストID・再試行を明示する。"
290
+ >
291
+ <TableShell caption="取得に失敗しました">
292
+ <div className="p-4">
293
+ <Alert tone="destructive">
294
+ <AlertTitle>勤怠データを取得できませんでした</AlertTitle>
295
+ <AlertDescription>
296
+ サーバーが応答しませんでした。時間をおいて再試行してください。
297
+ <br />
298
+ <Text tone="muted">
299
+ コード <code className="tabular-nums">ATTEND_FETCH_504</code> ・ リクエストID{" "}
300
+ <code className="tabular-nums">req_7f3a91c0d2</code>
301
+ </Text>
302
+ </AlertDescription>
303
+ <AlertActions>
304
+ <Button variant="outline" size="sm">
305
+ <RefreshCw aria-hidden="true" />
306
+ 再試行
307
+ </Button>
308
+ </AlertActions>
309
+ </Alert>
310
+ </div>
311
+ </TableShell>
312
+ </StateSection>
313
+
314
+ {/* 4 ─ partial: some rows loaded, one segment failed / stale */}
315
+ <StateSection
316
+ step="4 / 5"
317
+ title="部分的"
318
+ note="一部のみ取得できた状態。失敗した区分だけを再取得できる。"
319
+ >
320
+ <TableShell caption="4 / 5 部署を表示中">
321
+ <div>
322
+ <div className="p-4 pb-0">
323
+ <Alert tone="warning">
324
+ <AlertTitle>一部のデータを取得できませんでした</AlertTitle>
325
+ <AlertDescription>
326
+ 「倉庫」部署の打刻が取得できなかったため、最新ではない可能性があります。
327
+ <br />
328
+ <Text tone="muted">
329
+ コード <code className="tabular-nums">ATTEND_PARTIAL_倉庫</code> ・
330
+ リクエストID <code className="tabular-nums">req_7f3a91c0e8</code>
331
+ </Text>
332
+ </AlertDescription>
333
+ <AlertActions>
334
+ <Button variant="outline" size="sm">
335
+ <RefreshCw aria-hidden="true" />
336
+ 倉庫を再取得
337
+ </Button>
338
+ </AlertActions>
339
+ </Alert>
340
+ </div>
341
+ <DataTable data={PARTIAL_ROWS} columns={COLUMNS} getRowId={(r) => r.id} />
342
+ </div>
343
+ </TableShell>
344
+ </StateSection>
345
+
346
+ {/* 5 ─ ideal: fully populated */}
347
+ <StateSection
348
+ step="5 / 5"
349
+ title="理想"
350
+ note="全件取得済み。状態は Badge tone で固定マッピング表示。"
351
+ >
352
+ <TableShell
353
+ caption={
354
+ <Flex direction="row" align="center" gap="xs">
355
+ <Clock className="size-3" aria-hidden="true" />
356
+ <Text tabular>5 件 · 14:32 更新</Text>
357
+ </Flex>
358
+ }
359
+ >
360
+ <DataTable data={ROWS} columns={COLUMNS} getRowId={(r) => r.id} />
361
+ </TableShell>
362
+ </StateSection>
363
+ </Flex>
364
+ </PageContainer>
365
+ );
366
+ }