@squadbase/vantage 0.6.2-dev1.9d91dda → 0.6.2-dev1.a881d95

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 (339) hide show
  1. package/dist/add-4GHF2TX2.js +6 -0
  2. package/dist/add-4GHF2TX2.js.map +1 -0
  3. package/dist/{build-TVKFIVFQ.js → build-U7GO26HR.js} +9 -9
  4. package/dist/{build-TVKFIVFQ.js.map → build-U7GO26HR.js.map} +1 -1
  5. package/dist/{check-3KHZXZMQ.js → check-MRVAIHG5.js} +7 -7
  6. package/dist/{check-3KHZXZMQ.js.map → check-MRVAIHG5.js.map} +1 -1
  7. package/dist/chunk-2IAPIOPS.js +152 -0
  8. package/dist/chunk-2IAPIOPS.js.map +1 -0
  9. package/dist/chunk-3RJEOP3J.js +174 -0
  10. package/dist/chunk-3RJEOP3J.js.map +1 -0
  11. package/dist/chunk-77CISBMG.js +7581 -0
  12. package/dist/chunk-77CISBMG.js.map +1 -0
  13. package/dist/{chunk-U2M6HGKQ.js → chunk-AABMKHEU.js} +4 -4
  14. package/dist/{chunk-U2M6HGKQ.js.map → chunk-AABMKHEU.js.map} +1 -1
  15. package/dist/{chunk-PVTHHV7X.js → chunk-ANZLVSEP.js} +28 -7
  16. package/dist/chunk-ANZLVSEP.js.map +1 -0
  17. package/dist/chunk-CKWPK4RO.js +50 -0
  18. package/dist/chunk-CKWPK4RO.js.map +1 -0
  19. package/dist/chunk-EG4PX726.js +678 -0
  20. package/dist/chunk-EG4PX726.js.map +1 -0
  21. package/dist/{chunk-QI3XQKHS.js → chunk-GNXCX4WE.js} +10 -3
  22. package/dist/chunk-GNXCX4WE.js.map +1 -0
  23. package/dist/chunk-NZ5QIIG4.js +74 -0
  24. package/dist/chunk-NZ5QIIG4.js.map +1 -0
  25. package/dist/{chunk-P7W4LR3Z.js → chunk-PJ4SPXHS.js} +24 -7
  26. package/dist/chunk-PJ4SPXHS.js.map +1 -0
  27. package/dist/{chunk-RPZAALCX.js → chunk-QNOX7WLZ.js} +256 -165
  28. package/dist/chunk-QNOX7WLZ.js.map +1 -0
  29. package/dist/{chunk-ZVANIULZ.js → chunk-RNTDBX6S.js} +4 -4
  30. package/dist/{chunk-ZVANIULZ.js.map → chunk-RNTDBX6S.js.map} +1 -1
  31. package/dist/{chunk-PXRX5PEC.js → chunk-ROHNXP7J.js} +73 -4
  32. package/dist/chunk-ROHNXP7J.js.map +1 -0
  33. package/dist/{chunk-CEXAQQ5W.js → chunk-S5MDTHH7.js} +180 -18
  34. package/dist/chunk-S5MDTHH7.js.map +1 -0
  35. package/dist/chunk-SDJTTMLK.js +1877 -0
  36. package/dist/chunk-SDJTTMLK.js.map +1 -0
  37. package/dist/{chunk-LMUACBMA.js → chunk-SHZM3EXB.js} +68 -12
  38. package/dist/chunk-SHZM3EXB.js.map +1 -0
  39. package/dist/chunk-TRMHNMMZ.js +61 -0
  40. package/dist/chunk-TRMHNMMZ.js.map +1 -0
  41. package/dist/{chunk-A2UUGASH.js → chunk-U736PVHY.js} +2 -2
  42. package/dist/chunk-U736PVHY.js.map +1 -0
  43. package/dist/{chunk-JKLLFVEU.js → chunk-UWSQUHX6.js} +4 -99
  44. package/dist/chunk-UWSQUHX6.js.map +1 -0
  45. package/dist/cli.js +12 -11
  46. package/dist/cli.js.map +1 -1
  47. package/dist/client/index.d.ts +34 -3
  48. package/dist/client/index.js +211 -12
  49. package/dist/client/index.js.map +1 -1
  50. package/dist/components/index.d.ts +1761 -30
  51. package/dist/components/index.js +7 -4
  52. package/dist/delta-text-CbrOaW83.d.ts +17 -0
  53. package/dist/{dev-GDKATCC7.js → dev-O42JFQ64.js} +10 -10
  54. package/dist/dev-O42JFQ64.js.map +1 -0
  55. package/dist/doc/index.d.ts +215 -2
  56. package/dist/doc/index.js +423 -5
  57. package/dist/doc/index.js.map +1 -1
  58. package/dist/{docs-EJJ3BECT.js → docs-JVP4RPKT.js} +3 -3
  59. package/dist/{docs-EJJ3BECT.js.map → docs-JVP4RPKT.js.map} +1 -1
  60. package/dist/{doctor-WQXPXP6K.js → doctor-YD3XAAOT.js} +7 -7
  61. package/dist/{doctor-WQXPXP6K.js.map → doctor-YD3XAAOT.js.map} +1 -1
  62. package/dist/format-DihQkL1N.d.ts +249 -0
  63. package/dist/markdown/index.js +1 -1
  64. package/dist/markdown/index.js.map +1 -1
  65. package/dist/{preview-OGMCNQUO.js → preview-T6CLSQVX.js} +3 -3
  66. package/dist/{preview-OGMCNQUO.js.map → preview-T6CLSQVX.js.map} +1 -1
  67. package/dist/query/index.d.ts +0 -11
  68. package/dist/query/index.js +2 -2
  69. package/dist/{routes-MWBWWOJ2.js → routes-PVKNT777.js} +6 -6
  70. package/dist/{routes-MWBWWOJ2.js.map → routes-PVKNT777.js.map} +1 -1
  71. package/dist/{search-6Y422SV6.js → search-5LC4XPB5.js} +3 -3
  72. package/dist/{search-6Y422SV6.js.map → search-5LC4XPB5.js.map} +1 -1
  73. package/dist/slide/index.d.ts +272 -1
  74. package/dist/slide/index.js +1025 -4
  75. package/dist/slide/index.js.map +1 -1
  76. package/dist/table/index.js +14 -10
  77. package/dist/table/index.js.map +1 -1
  78. package/dist/ui/index.d.ts +148 -12
  79. package/dist/ui/index.js +1340 -88
  80. package/dist/ui/index.js.map +1 -1
  81. package/dist/{upgrade-HCANX4GQ.js → upgrade-6DT7ADRP.js} +7 -7
  82. package/dist/{upgrade-HCANX4GQ.js.map → upgrade-6DT7ADRP.js.map} +1 -1
  83. package/dist/vite/index.d.ts +10 -0
  84. package/dist/vite/index.js +4 -4
  85. package/docs/en/agent-skills.md +1 -1
  86. package/docs/en/changelog.md +2 -0
  87. package/docs/en/components.md +42 -17
  88. package/docs/en/doc/delta-text.md +40 -0
  89. package/docs/en/doc/doc-action-items.md +49 -0
  90. package/docs/en/doc/doc-callout.md +38 -0
  91. package/docs/en/doc/doc-data-table.md +60 -0
  92. package/docs/en/doc/doc-executive-summary.md +64 -0
  93. package/docs/en/doc/doc-figure.md +56 -0
  94. package/docs/en/doc/doc-key-findings.md +61 -0
  95. package/docs/en/doc/doc-kpi-scorecard.md +80 -0
  96. package/docs/en/doc/doc-notes-and-sources.md +43 -0
  97. package/docs/en/doc/doc-report-header.md +46 -0
  98. package/docs/en/pages-and-metadata.md +15 -0
  99. package/docs/en/parts/area-chart.md +99 -0
  100. package/docs/en/parts/bar-chart.md +91 -0
  101. package/docs/en/parts/bar-list.md +50 -0
  102. package/docs/en/parts/category-bar.md +37 -0
  103. package/docs/en/parts/chart-frame.md +39 -0
  104. package/docs/en/parts/data-table.md +22 -0
  105. package/docs/en/parts/delta.md +51 -0
  106. package/docs/en/parts/donut-chart.md +72 -0
  107. package/docs/en/parts/format.md +43 -0
  108. package/docs/en/parts/funnel-steps.md +2 -1
  109. package/docs/en/parts/heatmap.md +53 -0
  110. package/docs/en/parts/kpi-card.md +58 -0
  111. package/docs/en/parts/legend.md +35 -0
  112. package/docs/en/parts/line-chart.md +94 -0
  113. package/docs/en/parts/metric-value.md +3 -2
  114. package/docs/en/parts/progress-circle.md +33 -0
  115. package/docs/en/parts/sample-data.md +39 -0
  116. package/docs/en/parts/scatter-chart.md +56 -0
  117. package/docs/en/parts/sparkline.md +1 -1
  118. package/docs/en/parts/tracker.md +36 -0
  119. package/docs/en/parts/trend-indicator.md +17 -1
  120. package/docs/en/parts/updated-at.md +30 -0
  121. package/docs/en/parts/waterfall-chart.md +56 -0
  122. package/docs/en/slide/slide-chart-full.md +48 -0
  123. package/docs/en/slide/slide-chart-insight.md +52 -0
  124. package/docs/en/slide/slide-columns.md +46 -0
  125. package/docs/en/slide/slide-comparison.md +68 -0
  126. package/docs/en/slide/slide-cover.md +39 -0
  127. package/docs/en/slide/slide-exec-summary.md +47 -0
  128. package/docs/en/slide/slide-heading.md +38 -0
  129. package/docs/en/slide/slide-kpi-grid.md +55 -0
  130. package/docs/en/slide/slide-kpi-hero.md +58 -0
  131. package/docs/en/slide/slide-next-actions.md +49 -0
  132. package/docs/en/slide/slide-scorecard-table.md +54 -0
  133. package/docs/en/slide/slide-section.md +44 -0
  134. package/docs/en/slide/slide-source-line.md +34 -0
  135. package/docs/en/ui/alert-dialog.md +42 -0
  136. package/docs/en/ui/avatar.md +31 -0
  137. package/docs/en/ui/combobox.md +74 -0
  138. package/docs/en/ui/drawer.md +41 -0
  139. package/docs/en/ui/empty.md +1 -1
  140. package/docs/en/ui/error-state.md +4 -3
  141. package/docs/en/ui/field.md +42 -0
  142. package/docs/en/ui/hover-card.md +21 -0
  143. package/docs/en/ui/kbd.md +17 -0
  144. package/docs/en/ui/loading.md +1 -1
  145. package/docs/en/ui/pagination.md +36 -0
  146. package/docs/en/ui/radio-group.md +21 -0
  147. package/docs/en/ui/toast.md +44 -0
  148. package/docs/en/ui/toggle-group.md +4 -3
  149. package/docs/en/ui-and-theming.md +1 -1
  150. package/docs/index.json +1184 -114
  151. package/docs/ja/agent-skills.md +1 -1
  152. package/docs/ja/changelog.md +33 -0
  153. package/docs/ja/components.md +68 -101
  154. package/docs/ja/doc/delta-text.md +40 -0
  155. package/docs/ja/doc/doc-action-items.md +49 -0
  156. package/docs/ja/doc/doc-callout.md +38 -0
  157. package/docs/ja/doc/doc-data-table.md +60 -0
  158. package/docs/ja/doc/doc-executive-summary.md +64 -0
  159. package/docs/ja/doc/doc-figure.md +56 -0
  160. package/docs/ja/doc/doc-key-findings.md +61 -0
  161. package/docs/ja/doc/doc-kpi-scorecard.md +80 -0
  162. package/docs/ja/doc/doc-notes-and-sources.md +43 -0
  163. package/docs/ja/doc/doc-report-header.md +46 -0
  164. package/docs/ja/page-types/csv.md +83 -0
  165. package/docs/ja/page-types/doc.md +83 -0
  166. package/docs/ja/page-types/excel.md +82 -0
  167. package/docs/ja/page-types/slide.md +133 -0
  168. package/docs/ja/page-types.md +47 -0
  169. package/docs/ja/pages-and-metadata.md +15 -0
  170. package/docs/ja/parts/area-chart.md +85 -0
  171. package/docs/ja/parts/bar-chart.md +95 -0
  172. package/docs/ja/parts/bar-list.md +58 -0
  173. package/docs/ja/parts/category-bar.md +36 -0
  174. package/docs/ja/parts/chart-frame.md +36 -0
  175. package/docs/ja/parts/data-table.md +22 -0
  176. package/docs/ja/parts/delta.md +51 -0
  177. package/docs/ja/parts/donut-chart.md +66 -0
  178. package/docs/ja/parts/echart.md +3 -0
  179. package/docs/ja/parts/format.md +44 -0
  180. package/docs/ja/parts/funnel-steps.md +27 -8
  181. package/docs/ja/parts/heatmap.md +45 -0
  182. package/docs/ja/parts/kpi-card.md +56 -0
  183. package/docs/ja/parts/legend.md +36 -0
  184. package/docs/ja/parts/line-chart.md +84 -0
  185. package/docs/ja/parts/metric-value.md +3 -2
  186. package/docs/ja/parts/progress-circle.md +34 -0
  187. package/docs/ja/parts/sample-data.md +61 -0
  188. package/docs/ja/parts/scatter-chart.md +69 -0
  189. package/docs/ja/parts/sparkline.md +2 -2
  190. package/docs/ja/parts/tracker.md +32 -0
  191. package/docs/ja/parts/trend-indicator.md +17 -1
  192. package/docs/ja/parts/updated-at.md +27 -0
  193. package/docs/ja/parts/waterfall-chart.md +61 -0
  194. package/docs/ja/routing.md +8 -86
  195. package/docs/ja/slide/slide-chart-full.md +48 -0
  196. package/docs/ja/slide/slide-chart-insight.md +52 -0
  197. package/docs/ja/slide/slide-columns.md +46 -0
  198. package/docs/ja/slide/slide-comparison.md +68 -0
  199. package/docs/ja/slide/slide-cover.md +39 -0
  200. package/docs/ja/slide/slide-exec-summary.md +47 -0
  201. package/docs/ja/slide/slide-heading.md +38 -0
  202. package/docs/ja/slide/slide-kpi-grid.md +55 -0
  203. package/docs/ja/slide/slide-kpi-hero.md +58 -0
  204. package/docs/ja/slide/slide-next-actions.md +49 -0
  205. package/docs/ja/slide/slide-scorecard-table.md +54 -0
  206. package/docs/ja/slide/slide-section.md +44 -0
  207. package/docs/ja/slide/slide-source-line.md +34 -0
  208. package/docs/ja/ui/alert-dialog.md +41 -0
  209. package/docs/ja/ui/avatar.md +31 -0
  210. package/docs/ja/ui/combobox.md +74 -0
  211. package/docs/ja/ui/drawer.md +41 -0
  212. package/docs/ja/ui/empty.md +1 -1
  213. package/docs/ja/ui/error-state.md +4 -3
  214. package/docs/ja/ui/field.md +42 -0
  215. package/docs/ja/ui/hover-card.md +21 -0
  216. package/docs/ja/ui/kbd.md +16 -0
  217. package/docs/ja/ui/loading.md +1 -1
  218. package/docs/ja/ui/pagination.md +36 -0
  219. package/docs/ja/ui/radio-group.md +21 -0
  220. package/docs/ja/ui/toast.md +46 -0
  221. package/docs/ja/ui/toggle-group.md +4 -3
  222. package/docs/ja/ui-and-theming.md +14 -7
  223. package/package.json +41 -31
  224. package/registry/ui/accordion.tsx +76 -0
  225. package/registry/ui/alert-dialog.tsx +189 -0
  226. package/registry/ui/alert.tsx +80 -0
  227. package/registry/ui/app-shell.tsx +424 -0
  228. package/registry/ui/area-chart.tsx +3960 -0
  229. package/registry/ui/attention-list.tsx +465 -0
  230. package/registry/ui/avatar.tsx +110 -0
  231. package/registry/ui/badge.tsx +56 -0
  232. package/registry/ui/bar-chart.tsx +3954 -0
  233. package/registry/ui/bar-list.tsx +3998 -0
  234. package/registry/ui/box-plot-chart.tsx +4214 -0
  235. package/registry/ui/breadcrumb.tsx +128 -0
  236. package/registry/ui/button.tsx +62 -0
  237. package/registry/ui/calendar.tsx +223 -0
  238. package/registry/ui/card.tsx +107 -0
  239. package/registry/ui/category-bar.tsx +1498 -0
  240. package/registry/ui/chart-frame.tsx +1604 -0
  241. package/registry/ui/checkbox.tsx +30 -0
  242. package/registry/ui/collapsible.tsx +23 -0
  243. package/registry/ui/combobox.tsx +310 -0
  244. package/registry/ui/command.tsx +198 -0
  245. package/registry/ui/dashboard-card.tsx +217 -0
  246. package/registry/ui/data-table.tsx +896 -157
  247. package/registry/ui/date-range-picker.tsx +544 -0
  248. package/registry/ui/delta.tsx +350 -0
  249. package/registry/ui/dialog.tsx +161 -0
  250. package/registry/ui/donut-chart.tsx +4006 -0
  251. package/registry/ui/drawer.tsx +229 -0
  252. package/registry/ui/dropdown-menu.tsx +274 -0
  253. package/registry/ui/echart.tsx +1178 -0
  254. package/registry/ui/field.tsx +240 -0
  255. package/registry/ui/filter-bar.tsx +551 -0
  256. package/registry/ui/funnel-steps.tsx +3843 -0
  257. package/registry/ui/heatmap.tsx +2027 -0
  258. package/registry/ui/histogram-chart.tsx +4284 -0
  259. package/registry/ui/hover-card.tsx +52 -0
  260. package/registry/ui/input-group.tsx +160 -0
  261. package/registry/ui/input.tsx +24 -0
  262. package/registry/ui/kbd.tsx +30 -0
  263. package/registry/ui/kpi-card.tsx +905 -0
  264. package/registry/ui/label.tsx +22 -0
  265. package/registry/ui/legend.tsx +3817 -0
  266. package/registry/ui/line-chart.tsx +3958 -0
  267. package/registry/ui/metric-value.tsx +62 -0
  268. package/registry/ui/multi-select.tsx +382 -0
  269. package/registry/ui/page-shell.tsx +420 -0
  270. package/registry/ui/pagination.tsx +140 -0
  271. package/registry/ui/paired-chart.tsx +4086 -0
  272. package/registry/ui/placeholder.tsx +36 -0
  273. package/registry/ui/popover.tsx +92 -0
  274. package/registry/ui/progress-circle.tsx +1033 -0
  275. package/registry/ui/progress.tsx +85 -0
  276. package/registry/ui/radio-group.tsx +39 -0
  277. package/registry/ui/sample-data.tsx +230 -0
  278. package/registry/ui/scatter-chart.tsx +4503 -0
  279. package/registry/ui/scroll-area.tsx +56 -0
  280. package/registry/ui/searchable-select.tsx +352 -0
  281. package/registry/ui/section-header.tsx +43 -0
  282. package/registry/ui/segmented-control.tsx +76 -0
  283. package/registry/ui/select.tsx +255 -0
  284. package/registry/ui/separator.tsx +27 -0
  285. package/registry/ui/sheet.tsx +139 -0
  286. package/registry/ui/sidebar.tsx +725 -0
  287. package/registry/ui/skeleton.tsx +17 -0
  288. package/registry/ui/slider.tsx +56 -0
  289. package/registry/ui/sparkline.tsx +230 -0
  290. package/registry/ui/spinner.tsx +14 -0
  291. package/registry/ui/states.tsx +247 -0
  292. package/registry/ui/status-badge.tsx +286 -0
  293. package/registry/ui/switch.tsx +34 -0
  294. package/registry/ui/table.tsx +118 -0
  295. package/registry/ui/tabs.tsx +84 -0
  296. package/registry/ui/textarea.tsx +22 -0
  297. package/registry/ui/toast.tsx +250 -0
  298. package/registry/ui/toggle-group.tsx +91 -0
  299. package/registry/ui/toggle.tsx +47 -0
  300. package/registry/ui/tooltip.tsx +72 -0
  301. package/registry/ui/tracker.tsx +1015 -0
  302. package/registry/ui/trend-indicator.tsx +217 -0
  303. package/registry/ui/updated-at.tsx +276 -0
  304. package/registry/ui/waterfall-chart.tsx +4561 -0
  305. package/skills/vantage-add-feature/SKILL.md +14 -7
  306. package/skills/vantage-design/SKILL.md +60 -52
  307. package/skills/vantage-design/references/extract.md +26 -27
  308. package/skills/vantage-design/references/format.md +12 -172
  309. package/skills/vantage-design/references/presets.md +50 -110
  310. package/skills/vantage-pitfalls/SKILL.md +10 -1
  311. package/skills/vantage-slide/SKILL.md +54 -36
  312. package/templates/AGENTS.md +53 -16
  313. package/templates/agents/api.md +7 -0
  314. package/templates/agents/csv.md +2 -1
  315. package/templates/agents/doc.md +52 -3
  316. package/templates/agents/page.md +91 -10
  317. package/templates/agents/slide.md +77 -3
  318. package/templates/agents/xlsx.md +2 -1
  319. package/theme.css +247 -138
  320. package/dist/add-DY4AXANK.js +0 -6
  321. package/dist/add-DY4AXANK.js.map +0 -1
  322. package/dist/chunk-5ZOP4SQR.js +0 -47
  323. package/dist/chunk-5ZOP4SQR.js.map +0 -1
  324. package/dist/chunk-A2UUGASH.js.map +0 -1
  325. package/dist/chunk-CEXAQQ5W.js.map +0 -1
  326. package/dist/chunk-DTDVSFRY.js +0 -29
  327. package/dist/chunk-DTDVSFRY.js.map +0 -1
  328. package/dist/chunk-JKLLFVEU.js.map +0 -1
  329. package/dist/chunk-LMUACBMA.js.map +0 -1
  330. package/dist/chunk-NKFBFDRZ.js +0 -2241
  331. package/dist/chunk-NKFBFDRZ.js.map +0 -1
  332. package/dist/chunk-P7W4LR3Z.js.map +0 -1
  333. package/dist/chunk-PVTHHV7X.js.map +0 -1
  334. package/dist/chunk-PXRX5PEC.js.map +0 -1
  335. package/dist/chunk-QI3XQKHS.js.map +0 -1
  336. package/dist/chunk-RPZAALCX.js.map +0 -1
  337. package/dist/chunk-VA776YE5.js +0 -316
  338. package/dist/chunk-VA776YE5.js.map +0 -1
  339. package/dist/dev-GDKATCC7.js.map +0 -1
@@ -0,0 +1,420 @@
1
+ // Copied by `vantage add ui page-shell`. This file is yours to edit.
2
+ // Generated from @squadbase/squadkit registry/components/page-shell.tsx by `pnpm run registry` (in Vantage, edit packages/squadkit, not registry/).
3
+ "use client"
4
+
5
+ /**
6
+ * PageShell — the standard page frame: a bordered header band (title,
7
+ * description, meta, actions), an optional summary card row, and the content
8
+ * area. Composed from parts so a page can use only what it needs.
9
+ */
10
+ import { forwardRef, type HTMLAttributes, type ReactNode } from "react"
11
+ import { cva, type VariantProps } from "class-variance-authority"
12
+
13
+ import { formatDateRange, EMPTY_VALUE } from "@squadbase/vantage/components"
14
+ import { cn } from "@squadbase/vantage/ui"
15
+ import { Badge } from "@squadbase/vantage/ui"
16
+ import { UpdatedAt, type UpdatedAtProps } from "@squadbase/vantage/components"
17
+ import { useSyncExternalStore } from "react"
18
+
19
+ /* ---------- inlined from @squadbase/squadkit registry/lib/locale.ts (internal to @squadbase/vantage) ---------- */
20
+
21
+ /**
22
+ * The display language of the parts and the defaults that follow it.
23
+ *
24
+ * The language comes from `<html lang>`: a tag starting with `ja` reads Japanese, anything else English.
25
+ * Without a usable `lang` (missing, invalid, or no `document` — SSR, Node) the locale is `FALLBACK_LOCALE`
26
+ * (`en-US`). A `locale` passed explicitly (a prop, an argument) always wins.
27
+ *
28
+ * Parts read the locale through `useLocale` (`hooks/use-locale`) and pass it down; the pure helpers here
29
+ * and in `format` / `comparison` / `chart-*` take it as an argument and fall back to `documentLocale()`.
30
+ */
31
+
32
+ /** The language of the built-in wording: Japanese or English. */
33
+ type UiLanguage = "ja" | "en"
34
+
35
+ /** The locale used when `<html lang>` gives none (and on the server). */
36
+ const FALLBACK_LOCALE = "en-US"
37
+
38
+ /** `"ja"` when `locale` starts with `ja` (`ja`, `ja-JP`), else `"en"`. A missing locale is `"en"`. */
39
+ function uiLanguage(locale: string | null | undefined): UiLanguage {
40
+ return typeof locale === "string" && locale.trim().toLowerCase().startsWith("ja") ? "ja" : "en"
41
+ }
42
+
43
+ /** A BCP 47 tag in its canonical form (`en-gb` → `en-GB`), or `FALLBACK_LOCALE` when it is empty or invalid. */
44
+ function normalizeLocale(tag: string | null | undefined): string {
45
+ const value = tag?.trim()
46
+ if (!value) return FALLBACK_LOCALE
47
+ try {
48
+ return Intl.getCanonicalLocales(value)[0] ?? FALLBACK_LOCALE
49
+ } catch {
50
+ return FALLBACK_LOCALE
51
+ }
52
+ }
53
+
54
+ /**
55
+ * The locale of the page: `document.documentElement.lang`, canonicalized. `FALLBACK_LOCALE` when it is empty or
56
+ * invalid, or there is no `document`. Parts read it through `useLocale`, never while rendering.
57
+ */
58
+ function documentLocale(): string {
59
+ if (typeof document === "undefined") return FALLBACK_LOCALE
60
+ return normalizeLocale(document.documentElement?.getAttribute("lang"))
61
+ }
62
+
63
+ /** `locale` when given, else the page's locale (`documentLocale()`). */
64
+ function resolveLocale(locale?: string | null): string {
65
+ return locale || documentLocale()
66
+ }
67
+
68
+ /** Picks the wording table of the locale's language. */
69
+ function pickLocale<T>(table: { ja: T; en: T }, locale?: string | null): T {
70
+ return table[uiLanguage(resolveLocale(locale))]
71
+ }
72
+
73
+ /** The currency `format="currency"` uses without a `currency`: JPY for Japanese, USD otherwise. */
74
+ function defaultCurrency(locale?: string | null): string {
75
+ return uiLanguage(resolveLocale(locale)) === "ja" ? "JPY" : "USD"
76
+ }
77
+
78
+ /** The month a fiscal year starts in (1–12) when none is given: April for Japanese, January otherwise. */
79
+ function defaultFiscalYearStartMonth(locale?: string | null): number {
80
+ return uiLanguage(resolveLocale(locale)) === "ja" ? 4 : 1
81
+ }
82
+
83
+ /** A day of the week, 0 = Sunday … 6 = Saturday (the `Date#getDay` / date-fns numbering). */
84
+ type WeekDay = 0 | 1 | 2 | 3 | 4 | 5 | 6
85
+
86
+ /** Locales whose week starts on Sunday when the runtime has no week data. */
87
+ const SUNDAY_FIRST = new Set(["en", "en-US", "en-CA"])
88
+
89
+ /**
90
+ * The first day of the week: Monday for Japanese; otherwise the locale's convention from `Intl.Locale`
91
+ * (`en-US` Sunday, `en-GB` Monday). Without week data in the runtime: Sunday for `en` / `en-US` / `en-CA`,
92
+ * Monday for the rest.
93
+ */
94
+ function weekStartsOn(locale?: string | null): WeekDay {
95
+ const tag = normalizeLocale(resolveLocale(locale))
96
+ if (uiLanguage(tag) === "ja") return 1
97
+ try {
98
+ const info = new Intl.Locale(tag) as Intl.Locale & {
99
+ getWeekInfo?: () => { firstDay: number }
100
+ weekInfo?: { firstDay: number }
101
+ }
102
+ const firstDay = info.getWeekInfo?.().firstDay ?? info.weekInfo?.firstDay
103
+ if (typeof firstDay === "number" && firstDay >= 1 && firstDay <= 7) return (firstDay % 7) as WeekDay
104
+ } catch {
105
+ // Fall through to the table below.
106
+ }
107
+ return SUNDAY_FIRST.has(tag) ? 0 : 1
108
+ }
109
+
110
+ /* ---------- inlined from @squadbase/squadkit registry/hooks/use-locale.ts (internal to @squadbase/vantage) ---------- */
111
+
112
+ const listeners = new Set<() => void>()
113
+ let observer: MutationObserver | null = null
114
+
115
+ /** One observer on `<html lang>` for every subscribed part. */
116
+ function subscribe(onChange: () => void): () => void {
117
+ if (typeof document === "undefined" || typeof MutationObserver === "undefined") return () => {}
118
+ listeners.add(onChange)
119
+ if (!observer) {
120
+ observer = new MutationObserver(() => {
121
+ for (const listener of [...listeners]) listener()
122
+ })
123
+ observer.observe(document.documentElement, { attributes: true, attributeFilter: ["lang"] })
124
+ }
125
+ return () => {
126
+ listeners.delete(onChange)
127
+ if (listeners.size === 0 && observer) {
128
+ observer.disconnect()
129
+ observer = null
130
+ }
131
+ }
132
+ }
133
+
134
+ const serverLocale = () => FALLBACK_LOCALE
135
+
136
+ /**
137
+ * The page's locale (`<html lang>`), following changes made while the page runs. On the server and during
138
+ * hydration it is `FALLBACK_LOCALE` (`en-US`), so the markup matches; it switches right after.
139
+ */
140
+ function useDocumentLocale(): string {
141
+ return useSyncExternalStore(subscribe, documentLocale, serverLocale)
142
+ }
143
+
144
+ /** The locale a part renders in: its `locale` prop when given, else the page's (`useDocumentLocale`). */
145
+ function useLocale(locale?: string | null): string {
146
+ const page = useDocumentLocale()
147
+ return locale || page
148
+ }
149
+
150
+ /* ---------- end of inlined code ---------- */
151
+
152
+ export interface PageShellProps extends HTMLAttributes<HTMLDivElement> {}
153
+
154
+ export const PageShell = forwardRef<HTMLDivElement, PageShellProps>(
155
+ ({ className, ...props }, ref) => (
156
+ <div ref={ref} data-slot="page-shell" className={cn("flex flex-col", className)} {...props} />
157
+ ),
158
+ )
159
+ PageShell.displayName = "PageShell"
160
+
161
+ const SOURCE_PREFIX = { ja: "出典:", en: "Source: " }
162
+
163
+ export interface PageShellHeaderProps extends HTMLAttributes<HTMLDivElement> {
164
+ /** When the data was last updated. Drawn by `UpdatedAt` at the right end of the title row. */
165
+ updatedAt?: UpdatedAtProps["at"]
166
+ /** `"relative"` (default) or `"absolute-first"` ("16:41 更新(23 分前)") for pages where "now" matters. */
167
+ updatedAtVariant?: UpdatedAtProps["variant"]
168
+ /** IANA time zone for the absolute time of `updatedAt`. Defaults to the runtime's zone. */
169
+ timeZone?: string
170
+ /** Where the data comes from. Shown as a chip "Source: ○○" (ja: "出典:○○") on the second row. */
171
+ source?: string
172
+ /** The period the data covers. Shown as a chip "2026/9/23〜10/20" on the second row. */
173
+ period?: { start: Date | string | number; end: Date | string | number }
174
+ /** The page's overall state (an alert, a status badge). Shown on the third row; no row when absent. */
175
+ status?: ReactNode
176
+ }
177
+
178
+ /**
179
+ * A wrapping flex row, not a two-column grid: when the heading cannot keep its
180
+ * 20rem basis next to `PageShellHeaderEnd`, the end block drops below it. A
181
+ * `1fr auto` grid would instead hand the heading whatever the end block leaves,
182
+ * and a CJK title — breakable between any two characters — collapses into a
183
+ * one-character column.
184
+ *
185
+ * The meta props (`updatedAt`, `source`, `period`, `status`) fix the order every
186
+ * page head shares: title and update time (right end) → source / period chips →
187
+ * overall status → summary cards. Empty rows are not drawn. Rows are placed with
188
+ * flex `order`, so they land before `PageShellSummary` whatever the child order.
189
+ */
190
+ export const PageShellHeader = forwardRef<HTMLDivElement, PageShellHeaderProps>(
191
+ ({ className, updatedAt, updatedAtVariant, timeZone, source, period, status, children, ...props }, ref) => {
192
+ const locale = useLocale()
193
+ const periodText = period ? formatDateRange(period.start, period.end, { timeZone, locale }) : undefined
194
+ const hasChips = Boolean(source) || (periodText !== undefined && periodText !== EMPTY_VALUE)
195
+ const hasStatus = status !== undefined && status !== null && status !== false && status !== ""
196
+ return (
197
+ <div
198
+ ref={ref}
199
+ data-slot="page-shell-header"
200
+ className={cn("flex flex-wrap items-start gap-x-4 gap-y-4 px-6 pt-8", className)}
201
+ {...props}
202
+ >
203
+ {children}
204
+ {updatedAt !== undefined && updatedAt !== null ? (
205
+ <div data-slot="page-shell-updated-at" className="ml-auto max-w-full shrink-0 text-right">
206
+ <UpdatedAt at={updatedAt} variant={updatedAtVariant} timeZone={timeZone} />
207
+ </div>
208
+ ) : null}
209
+ {hasChips ? (
210
+ <div data-slot="page-shell-chips" className="order-1 flex basis-full flex-wrap gap-1.5">
211
+ {source ? (
212
+ <Badge variant="outline" className="h-auto max-w-full whitespace-normal text-muted-foreground">
213
+ {SOURCE_PREFIX[uiLanguage(locale)]}
214
+ {source}
215
+ </Badge>
216
+ ) : null}
217
+ {periodText && periodText !== EMPTY_VALUE ? (
218
+ <Badge variant="outline" className="tabular-nums text-muted-foreground">
219
+ {periodText}
220
+ </Badge>
221
+ ) : null}
222
+ </div>
223
+ ) : null}
224
+ {hasStatus ? (
225
+ <div data-slot="page-shell-status" className="order-2 min-w-0 basis-full">
226
+ {status}
227
+ </div>
228
+ ) : null}
229
+ </div>
230
+ )
231
+ },
232
+ )
233
+ PageShellHeader.displayName = "PageShellHeader"
234
+
235
+ export interface PageShellHeadingProps extends HTMLAttributes<HTMLDivElement> {}
236
+
237
+ export const PageShellHeading = forwardRef<HTMLDivElement, PageShellHeadingProps>(
238
+ ({ className, ...props }, ref) => (
239
+ <div
240
+ ref={ref}
241
+ data-slot="page-shell-heading"
242
+ className={cn("min-w-0 grow basis-80", className)}
243
+ {...props}
244
+ />
245
+ ),
246
+ )
247
+ PageShellHeading.displayName = "PageShellHeading"
248
+
249
+ export interface PageShellTitleProps extends HTMLAttributes<HTMLHeadingElement> {}
250
+
251
+ export const PageShellTitle = forwardRef<HTMLHeadingElement, PageShellTitleProps>(
252
+ ({ className, ...props }, ref) => (
253
+ <h1
254
+ ref={ref}
255
+ data-slot="page-shell-title"
256
+ className={cn("text-2xl font-semibold tracking-tight text-foreground", className)}
257
+ {...props}
258
+ />
259
+ ),
260
+ )
261
+ PageShellTitle.displayName = "PageShellTitle"
262
+
263
+ export interface PageShellDescriptionProps extends HTMLAttributes<HTMLParagraphElement> {}
264
+
265
+ export const PageShellDescription = forwardRef<HTMLParagraphElement, PageShellDescriptionProps>(
266
+ ({ className, ...props }, ref) => (
267
+ <p
268
+ ref={ref}
269
+ data-slot="page-shell-description"
270
+ className={cn("mt-1 text-sm text-muted-foreground", className)}
271
+ {...props}
272
+ />
273
+ ),
274
+ )
275
+ PageShellDescription.displayName = "PageShellDescription"
276
+
277
+ export interface PageShellHeaderEndProps extends HTMLAttributes<HTMLDivElement> {}
278
+
279
+ export const PageShellHeaderEnd = forwardRef<HTMLDivElement, PageShellHeaderEndProps>(
280
+ ({ className, ...props }, ref) => (
281
+ <div
282
+ ref={ref}
283
+ data-slot="page-shell-header-end"
284
+ className={cn("flex max-w-full shrink-0 flex-col flex-wrap items-end gap-2", className)}
285
+ {...props}
286
+ />
287
+ ),
288
+ )
289
+ PageShellHeaderEnd.displayName = "PageShellHeaderEnd"
290
+
291
+ export interface PageShellMetaProps extends HTMLAttributes<HTMLDivElement> {}
292
+
293
+ export const PageShellMeta = forwardRef<HTMLDivElement, PageShellMetaProps>(
294
+ ({ className, ...props }, ref) => (
295
+ <div
296
+ ref={ref}
297
+ data-slot="page-shell-meta"
298
+ className={cn("text-sm text-muted-foreground", className)}
299
+ {...props}
300
+ />
301
+ ),
302
+ )
303
+ PageShellMeta.displayName = "PageShellMeta"
304
+
305
+ export interface PageShellActionsProps extends HTMLAttributes<HTMLDivElement> {}
306
+
307
+ export const PageShellActions = forwardRef<HTMLDivElement, PageShellActionsProps>(
308
+ ({ className, ...props }, ref) => (
309
+ <div
310
+ ref={ref}
311
+ data-slot="page-shell-actions"
312
+ className={cn("flex items-center gap-2", className)}
313
+ {...props}
314
+ />
315
+ ),
316
+ )
317
+ PageShellActions.displayName = "PageShellActions"
318
+
319
+ export interface PageShellSummaryProps extends HTMLAttributes<HTMLDivElement> {}
320
+
321
+ export const PageShellSummary = forwardRef<HTMLDivElement, PageShellSummaryProps>(
322
+ ({ className, ...props }, ref) => (
323
+ <div
324
+ ref={ref}
325
+ data-slot="page-shell-summary"
326
+ className={cn(
327
+ "order-3 grid basis-full grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4",
328
+ className,
329
+ )}
330
+ {...props}
331
+ />
332
+ ),
333
+ )
334
+ PageShellSummary.displayName = "PageShellSummary"
335
+
336
+ /**
337
+ * Accent tints come from theme tokens, never Tailwind palette colours: the
338
+ * semantic tones (`--positive` / `--negative` / `--warning` / `--info` /
339
+ * `--neutral` and their `*-subtle`) and, for hues with no status meaning,
340
+ * `--chart-4` / `--chart-5`. The colour-named accents are kept for compatibility
341
+ * and map to the nearest tone. Each set is a literal string — Tailwind only
342
+ * emits classes it can see literally in the source.
343
+ */
344
+ const summaryCardTones = {
345
+ positive: "border-positive/20 dark:border-positive/25 bg-positive-subtle [&>svg]:text-positive",
346
+ negative: "border-negative/20 dark:border-negative/25 bg-negative-subtle [&>svg]:text-negative",
347
+ warning: "border-warning/20 dark:border-warning/25 bg-warning-subtle [&>svg]:text-warning",
348
+ info: "border-info/20 dark:border-info/25 bg-info-subtle [&>svg]:text-info",
349
+ neutral: "border-neutral/20 dark:border-neutral/25 bg-neutral-subtle [&>svg]:text-neutral",
350
+ violet: "border-chart-4/30 bg-chart-4/5 [&>svg]:text-chart-4",
351
+ pink: "border-chart-5/30 bg-chart-5/5 [&>svg]:text-chart-5",
352
+ } as const
353
+
354
+ export const pageShellSummaryCardVariants = cva(
355
+ "relative flex items-start gap-3 rounded-lg border bg-background px-4 py-3 text-sm [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0",
356
+ {
357
+ variants: {
358
+ accent: {
359
+ default: "text-card-foreground",
360
+ accent:
361
+ "border-[var(--chart-1)]/30 bg-linear-to-r from-[var(--chart-1)]/5 to-[var(--chart-1)]/5 [&>svg]:text-[var(--chart-1)]",
362
+ amber: summaryCardTones.warning,
363
+ blue: summaryCardTones.info,
364
+ emerald: summaryCardTones.positive,
365
+ red: summaryCardTones.negative,
366
+ violet: summaryCardTones.violet,
367
+ orange: summaryCardTones.warning,
368
+ cyan: summaryCardTones.info,
369
+ slate: summaryCardTones.neutral,
370
+ green: summaryCardTones.positive,
371
+ teal: summaryCardTones.positive,
372
+ sky: summaryCardTones.info,
373
+ indigo: summaryCardTones.info,
374
+ purple: summaryCardTones.violet,
375
+ pink: summaryCardTones.pink,
376
+ rose: summaryCardTones.negative,
377
+ yellow: summaryCardTones.warning,
378
+ lime: summaryCardTones.positive,
379
+ gray: summaryCardTones.neutral,
380
+ zinc: summaryCardTones.neutral,
381
+ neutral: summaryCardTones.neutral,
382
+ stone: summaryCardTones.neutral,
383
+ fuchsia: summaryCardTones.violet,
384
+ },
385
+ },
386
+ defaultVariants: {
387
+ accent: "default",
388
+ },
389
+ },
390
+ )
391
+
392
+ export interface PageShellSummaryCardProps
393
+ extends HTMLAttributes<HTMLDivElement>,
394
+ VariantProps<typeof pageShellSummaryCardVariants> {}
395
+
396
+ export const PageShellSummaryCard = forwardRef<HTMLDivElement, PageShellSummaryCardProps>(
397
+ ({ className, accent, ...props }, ref) => (
398
+ <div
399
+ ref={ref}
400
+ data-slot="page-shell-summary-card"
401
+ className={cn(pageShellSummaryCardVariants({ accent }), className)}
402
+ {...props}
403
+ />
404
+ ),
405
+ )
406
+ PageShellSummaryCard.displayName = "PageShellSummaryCard"
407
+
408
+ export interface PageShellContentProps extends HTMLAttributes<HTMLDivElement> {}
409
+
410
+ export const PageShellContent = forwardRef<HTMLDivElement, PageShellContentProps>(
411
+ ({ className, ...props }, ref) => (
412
+ <div
413
+ ref={ref}
414
+ data-slot="page-shell-content"
415
+ className={cn("flex min-w-0 flex-1 flex-col gap-6 p-6", className)}
416
+ {...props}
417
+ />
418
+ ),
419
+ )
420
+ PageShellContent.displayName = "PageShellContent"
@@ -0,0 +1,140 @@
1
+ // Copied by `vantage add ui pagination`. This file is yours to edit.
2
+ // Generated from @squadbase/squadkit registry/ui/pagination.tsx by `pnpm run registry` (in Vantage, edit packages/squadkit, not registry/).
3
+ "use client"
4
+
5
+ import * as React from "react"
6
+ import { cn } from "@squadbase/vantage/ui"
7
+
8
+ import { Button } from "@squadbase/vantage/ui"
9
+ import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react"
10
+
11
+ function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
12
+ return (
13
+ <nav
14
+ role="navigation"
15
+ aria-label="pagination"
16
+ data-slot="pagination"
17
+ className={cn("mx-auto flex w-full justify-center", className)}
18
+ {...props}
19
+ />
20
+ )
21
+ }
22
+
23
+ function PaginationContent({
24
+ className,
25
+ ...props
26
+ }: React.ComponentProps<"ul">) {
27
+ return (
28
+ <ul
29
+ data-slot="pagination-content"
30
+ className={cn("flex items-center gap-0.5", className)}
31
+ {...props}
32
+ />
33
+ )
34
+ }
35
+
36
+ function PaginationItem({ ...props }: React.ComponentProps<"li">) {
37
+ return <li data-slot="pagination-item" {...props} />
38
+ }
39
+
40
+ type PaginationLinkProps = {
41
+ isActive?: boolean
42
+ } & Pick<React.ComponentProps<typeof Button>, "size"> &
43
+ React.ComponentProps<"a">
44
+
45
+ function PaginationLink({
46
+ className,
47
+ isActive,
48
+ size = "icon",
49
+ ...props
50
+ }: PaginationLinkProps) {
51
+ return (
52
+ <Button
53
+ variant={isActive ? "outline" : "ghost"}
54
+ size={size}
55
+ className={cn(className)}
56
+ nativeButton={false}
57
+ render={
58
+ <a
59
+ aria-current={isActive ? "page" : undefined}
60
+ data-slot="pagination-link"
61
+ data-active={isActive}
62
+ {...props}
63
+ />
64
+ }
65
+ />
66
+ )
67
+ }
68
+
69
+ function PaginationPrevious({
70
+ className,
71
+ text = "Previous",
72
+ ...props
73
+ }: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
74
+ return (
75
+ <PaginationLink
76
+ aria-label="Go to previous page"
77
+ size="default"
78
+ className={cn("pl-1.5!", className)}
79
+ {...props}
80
+ >
81
+ <ChevronLeftIcon
82
+ data-icon="inline-start"
83
+ className="cn-rtl-flip"
84
+ />
85
+ <span className="hidden sm:block">{text}</span>
86
+ </PaginationLink>
87
+ )
88
+ }
89
+
90
+ function PaginationNext({
91
+ className,
92
+ text = "Next",
93
+ ...props
94
+ }: React.ComponentProps<typeof PaginationLink> & { text?: string }) {
95
+ return (
96
+ <PaginationLink
97
+ aria-label="Go to next page"
98
+ size="default"
99
+ className={cn("pr-1.5!", className)}
100
+ {...props}
101
+ >
102
+ <span className="hidden sm:block">{text}</span>
103
+ <ChevronRightIcon
104
+ data-icon="inline-end"
105
+ className="cn-rtl-flip"
106
+ />
107
+ </PaginationLink>
108
+ )
109
+ }
110
+
111
+ function PaginationEllipsis({
112
+ className,
113
+ ...props
114
+ }: React.ComponentProps<"span">) {
115
+ return (
116
+ <span
117
+ aria-hidden
118
+ data-slot="pagination-ellipsis"
119
+ className={cn(
120
+ "flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4",
121
+ className
122
+ )}
123
+ {...props}
124
+ >
125
+ <MoreHorizontalIcon
126
+ />
127
+ <span className="sr-only">More pages</span>
128
+ </span>
129
+ )
130
+ }
131
+
132
+ export {
133
+ Pagination,
134
+ PaginationContent,
135
+ PaginationEllipsis,
136
+ PaginationItem,
137
+ PaginationLink,
138
+ PaginationNext,
139
+ PaginationPrevious,
140
+ }