@ketvietlab/design-system 0.1.9 → 0.1.13

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 (371) hide show
  1. package/README.md +92 -6
  2. package/dist/atlas/README.md +35 -0
  3. package/dist/atlas/adapter.schema.json +78 -0
  4. package/dist/atlas/profile.json +43 -0
  5. package/dist/atlas-cli.d.ts +3 -0
  6. package/dist/atlas-cli.d.ts.map +1 -0
  7. package/dist/atlas-cli.js +213 -0
  8. package/dist/atlas-cli.js.map +1 -0
  9. package/dist/catalogue/catalogue.css +198 -5
  10. package/dist/catalogue/groups.d.ts +11 -0
  11. package/dist/catalogue/groups.d.ts.map +1 -0
  12. package/dist/catalogue/groups.js +47 -0
  13. package/dist/catalogue/groups.js.map +1 -0
  14. package/dist/catalogue/index.d.ts +16 -17
  15. package/dist/catalogue/index.d.ts.map +1 -1
  16. package/dist/catalogue/index.js +39 -751
  17. package/dist/catalogue/index.js.map +1 -1
  18. package/dist/catalogue/inventory-policy.json +560 -0
  19. package/dist/catalogue/inventory.css +574 -0
  20. package/dist/catalogue/inventory.d.ts +16 -0
  21. package/dist/catalogue/inventory.d.ts.map +1 -0
  22. package/dist/catalogue/inventory.generated.d.ts +42 -0
  23. package/dist/catalogue/inventory.generated.d.ts.map +1 -0
  24. package/dist/catalogue/inventory.generated.js +3 -0
  25. package/dist/catalogue/inventory.generated.js.map +1 -0
  26. package/dist/catalogue/inventory.generated.json +9993 -0
  27. package/dist/catalogue/inventory.js +48 -0
  28. package/dist/catalogue/inventory.js.map +1 -0
  29. package/dist/catalogue/registry.d.ts +12 -0
  30. package/dist/catalogue/registry.d.ts.map +1 -0
  31. package/dist/catalogue/registry.js +134 -0
  32. package/dist/catalogue/registry.js.map +1 -0
  33. package/dist/catalogue/specimens.d.ts +15 -0
  34. package/dist/catalogue/specimens.d.ts.map +1 -0
  35. package/dist/catalogue/specimens.js +1186 -0
  36. package/dist/catalogue/specimens.js.map +1 -0
  37. package/dist/catalogue/styles.css +1 -0
  38. package/dist/contract/index.d.ts.map +1 -1
  39. package/dist/contract/index.js +64 -18
  40. package/dist/contract/index.js.map +1 -1
  41. package/dist/data-display/data-grid/index.d.ts +22 -0
  42. package/dist/data-display/data-grid/index.d.ts.map +1 -0
  43. package/dist/data-display/data-grid/index.js +15 -0
  44. package/dist/data-display/data-grid/index.js.map +1 -0
  45. package/dist/data-display/data-grid/styles.css +49 -0
  46. package/dist/data-display/resource-list/index.d.ts +22 -0
  47. package/dist/data-display/resource-list/index.d.ts.map +1 -0
  48. package/dist/data-display/resource-list/index.js +21 -0
  49. package/dist/data-display/resource-list/index.js.map +1 -0
  50. package/dist/data-display/resource-list/styles.css +39 -0
  51. package/dist/data-display/tree/index.d.ts +33 -0
  52. package/dist/data-display/tree/index.d.ts.map +1 -0
  53. package/dist/data-display/tree/index.js +21 -0
  54. package/dist/data-display/tree/index.js.map +1 -0
  55. package/dist/data-display/tree/styles.css +45 -0
  56. package/dist/data-operations/inline-edit/index.d.ts +19 -0
  57. package/dist/data-operations/inline-edit/index.d.ts.map +1 -0
  58. package/dist/data-operations/inline-edit/index.js +5 -0
  59. package/dist/data-operations/inline-edit/index.js.map +1 -0
  60. package/dist/data-operations/inline-edit/styles.css +34 -0
  61. package/dist/data-operations/list-controls/index.d.ts +67 -0
  62. package/dist/data-operations/list-controls/index.d.ts.map +1 -0
  63. package/dist/data-operations/list-controls/index.js +35 -0
  64. package/dist/data-operations/list-controls/index.js.map +1 -0
  65. package/dist/data-operations/list-controls/styles.css +82 -0
  66. package/dist/forms/combobox/index.d.ts +39 -0
  67. package/dist/forms/combobox/index.d.ts.map +1 -0
  68. package/dist/forms/combobox/index.js +23 -0
  69. package/dist/forms/combobox/index.js.map +1 -0
  70. package/dist/forms/combobox/styles.css +76 -0
  71. package/dist/forms/date-time/index.d.ts +25 -0
  72. package/dist/forms/date-time/index.d.ts.map +1 -0
  73. package/dist/forms/date-time/index.js +15 -0
  74. package/dist/forms/date-time/index.js.map +1 -0
  75. package/dist/forms/date-time/styles.css +25 -0
  76. package/dist/forms/relation-picker/index.d.ts +12 -0
  77. package/dist/forms/relation-picker/index.d.ts.map +1 -0
  78. package/dist/forms/relation-picker/index.js +13 -0
  79. package/dist/forms/relation-picker/index.js.map +1 -0
  80. package/dist/forms/relation-picker/styles.css +5 -0
  81. package/dist/forms/scalar-fields/index.d.ts +24 -0
  82. package/dist/forms/scalar-fields/index.d.ts.map +1 -0
  83. package/dist/forms/scalar-fields/index.js +23 -0
  84. package/dist/forms/scalar-fields/index.js.map +1 -0
  85. package/dist/forms/scalar-fields/styles.css +52 -0
  86. package/dist/forms/shared.d.ts +19 -0
  87. package/dist/forms/shared.d.ts.map +1 -0
  88. package/dist/forms/shared.js +9 -0
  89. package/dist/forms/shared.js.map +1 -0
  90. package/dist/forms/upload/index.d.ts +20 -0
  91. package/dist/forms/upload/index.d.ts.map +1 -0
  92. package/dist/forms/upload/index.js +11 -0
  93. package/dist/forms/upload/index.js.map +1 -0
  94. package/dist/forms/upload/styles.css +21 -0
  95. package/dist/foundations/reset.css +4 -0
  96. package/dist/foundations/tokens.css +31 -4
  97. package/dist/index.d.ts +78 -35
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +43 -19
  100. package/dist/index.js.map +1 -1
  101. package/dist/interactions/dialog/index.d.ts +25 -0
  102. package/dist/interactions/dialog/index.d.ts.map +1 -0
  103. package/dist/interactions/dialog/index.js +10 -0
  104. package/dist/interactions/dialog/index.js.map +1 -0
  105. package/dist/interactions/dialog/styles.css +11 -0
  106. package/dist/interactions/menu/index.d.ts +27 -0
  107. package/dist/interactions/menu/index.d.ts.map +1 -0
  108. package/dist/interactions/menu/index.js +13 -0
  109. package/dist/interactions/menu/index.js.map +1 -0
  110. package/dist/interactions/menu/styles.css +85 -0
  111. package/dist/interactions/popover/index.d.ts +15 -0
  112. package/dist/interactions/popover/index.d.ts.map +1 -0
  113. package/dist/interactions/popover/index.js +4 -0
  114. package/dist/interactions/popover/index.js.map +1 -0
  115. package/dist/interactions/popover/styles.css +47 -0
  116. package/dist/interactions/skeleton/index.d.ts +7 -0
  117. package/dist/interactions/skeleton/index.d.ts.map +1 -0
  118. package/dist/interactions/skeleton/index.js +5 -0
  119. package/dist/interactions/skeleton/index.js.map +1 -0
  120. package/dist/interactions/skeleton/styles.css +32 -0
  121. package/dist/interactions/spinner/index.d.ts +7 -0
  122. package/dist/interactions/spinner/index.d.ts.map +1 -0
  123. package/dist/interactions/spinner/index.js +4 -0
  124. package/dist/interactions/spinner/index.js.map +1 -0
  125. package/dist/interactions/spinner/styles.css +38 -0
  126. package/dist/interactions/toast/index.d.ts +16 -0
  127. package/dist/interactions/toast/index.d.ts.map +1 -0
  128. package/dist/interactions/toast/index.js +13 -0
  129. package/dist/interactions/toast/index.js.map +1 -0
  130. package/dist/interactions/toast/styles.css +64 -0
  131. package/dist/interactions/tooltip/index.d.ts +9 -0
  132. package/dist/interactions/tooltip/index.d.ts.map +1 -0
  133. package/dist/interactions/tooltip/index.js +4 -0
  134. package/dist/interactions/tooltip/index.js.map +1 -0
  135. package/dist/interactions/tooltip/styles.css +65 -0
  136. package/dist/layouts/app-navigation/index.d.ts +63 -0
  137. package/dist/layouts/app-navigation/index.d.ts.map +1 -0
  138. package/dist/layouts/app-navigation/index.js +50 -0
  139. package/dist/layouts/app-navigation/index.js.map +1 -0
  140. package/dist/layouts/app-navigation/styles.css +331 -0
  141. package/dist/layouts/app-navigation.d.ts +2 -0
  142. package/dist/layouts/app-navigation.d.ts.map +1 -0
  143. package/dist/layouts/app-navigation.js +2 -0
  144. package/dist/layouts/app-navigation.js.map +1 -0
  145. package/dist/layouts/flat/styles.css +74 -0
  146. package/dist/layouts/flat.css +1 -74
  147. package/dist/layouts/grouped/styles.css +131 -0
  148. package/dist/layouts/grouped.css +1 -126
  149. package/dist/layouts/index.d.ts +1 -69
  150. package/dist/layouts/index.d.ts.map +1 -1
  151. package/dist/layouts/index.js +1 -68
  152. package/dist/layouts/index.js.map +1 -1
  153. package/dist/layouts/layout/index.d.ts +70 -0
  154. package/dist/layouts/layout/index.d.ts.map +1 -0
  155. package/dist/layouts/layout/index.js +71 -0
  156. package/dist/layouts/layout/index.js.map +1 -0
  157. package/dist/layouts/layout/styles.css +369 -0
  158. package/dist/layouts/layouts.css +1 -369
  159. package/dist/layouts/shell/index.d.ts +27 -0
  160. package/dist/layouts/shell/index.d.ts.map +1 -0
  161. package/dist/layouts/shell/index.js +24 -0
  162. package/dist/layouts/shell/index.js.map +1 -0
  163. package/dist/layouts/shell/styles.css +168 -0
  164. package/dist/layouts/shell.css +1 -168
  165. package/dist/layouts/shell.d.ts +1 -26
  166. package/dist/layouts/shell.d.ts.map +1 -1
  167. package/dist/layouts/shell.js +1 -23
  168. package/dist/layouts/shell.js.map +1 -1
  169. package/dist/patterns/board-page/index.d.ts +16 -0
  170. package/dist/patterns/board-page/index.d.ts.map +1 -0
  171. package/dist/patterns/board-page/index.js +30 -0
  172. package/dist/patterns/board-page/index.js.map +1 -0
  173. package/dist/patterns/board-page/styles.css +164 -0
  174. package/dist/patterns/board-page.d.ts +1 -13
  175. package/dist/patterns/board-page.d.ts.map +1 -1
  176. package/dist/patterns/board-page.js +1 -27
  177. package/dist/patterns/board-page.js.map +1 -1
  178. package/dist/patterns/dashboard-page/index.d.ts +15 -0
  179. package/dist/patterns/dashboard-page/index.d.ts.map +1 -0
  180. package/dist/patterns/dashboard-page/index.js +27 -0
  181. package/dist/patterns/dashboard-page/index.js.map +1 -0
  182. package/dist/patterns/dashboard-page/styles.css +169 -0
  183. package/dist/patterns/dashboard-page.d.ts +1 -12
  184. package/dist/patterns/dashboard-page.d.ts.map +1 -1
  185. package/dist/patterns/dashboard-page.js +1 -24
  186. package/dist/patterns/dashboard-page.js.map +1 -1
  187. package/dist/patterns/data-table/index.d.ts +74 -0
  188. package/dist/patterns/data-table/index.d.ts.map +1 -0
  189. package/dist/patterns/data-table/index.js +60 -0
  190. package/dist/patterns/data-table/index.js.map +1 -0
  191. package/dist/patterns/data-table/styles.css +269 -0
  192. package/dist/patterns/data-table.d.ts +1 -73
  193. package/dist/patterns/data-table.d.ts.map +1 -1
  194. package/dist/patterns/data-table.js +1 -59
  195. package/dist/patterns/data-table.js.map +1 -1
  196. package/dist/patterns/form-page/index.d.ts +8 -0
  197. package/dist/patterns/form-page/index.d.ts.map +1 -0
  198. package/dist/patterns/form-page/index.js +22 -0
  199. package/dist/patterns/form-page/index.js.map +1 -0
  200. package/dist/patterns/form-page/styles.css +237 -0
  201. package/dist/patterns/form-page.d.ts +1 -7
  202. package/dist/patterns/form-page.d.ts.map +1 -1
  203. package/dist/patterns/form-page.js +1 -21
  204. package/dist/patterns/form-page.js.map +1 -1
  205. package/dist/patterns/list-chrome/index.d.ts +80 -0
  206. package/dist/patterns/list-chrome/index.d.ts.map +1 -0
  207. package/dist/patterns/list-chrome/index.js +45 -0
  208. package/dist/patterns/list-chrome/index.js.map +1 -0
  209. package/dist/patterns/list-chrome/styles.css +245 -0
  210. package/dist/patterns/list-chrome.d.ts +1 -79
  211. package/dist/patterns/list-chrome.d.ts.map +1 -1
  212. package/dist/patterns/list-chrome.js +1 -44
  213. package/dist/patterns/list-chrome.js.map +1 -1
  214. package/dist/patterns/list-page/index.d.ts +31 -0
  215. package/dist/patterns/list-page/index.d.ts.map +1 -0
  216. package/dist/patterns/list-page/index.js +41 -0
  217. package/dist/patterns/list-page/index.js.map +1 -0
  218. package/dist/patterns/list-page/responsive.css +140 -0
  219. package/dist/patterns/list-page/styles.css +228 -0
  220. package/dist/patterns/list-page.d.ts +1 -30
  221. package/dist/patterns/list-page.d.ts.map +1 -1
  222. package/dist/patterns/list-page.js +1 -40
  223. package/dist/patterns/list-page.js.map +1 -1
  224. package/dist/patterns/modal-sheet/index.d.ts +16 -0
  225. package/dist/patterns/modal-sheet/index.d.ts.map +1 -0
  226. package/dist/patterns/modal-sheet/index.js +15 -0
  227. package/dist/patterns/modal-sheet/index.js.map +1 -0
  228. package/dist/patterns/modal-sheet/styles.css +219 -0
  229. package/dist/patterns/modal-sheet.d.ts +1 -15
  230. package/dist/patterns/modal-sheet.d.ts.map +1 -1
  231. package/dist/patterns/modal-sheet.js +1 -14
  232. package/dist/patterns/modal-sheet.js.map +1 -1
  233. package/dist/patterns/page-shell/index.d.ts +24 -0
  234. package/dist/patterns/page-shell/index.d.ts.map +1 -0
  235. package/dist/patterns/page-shell/index.js +11 -0
  236. package/dist/patterns/page-shell/index.js.map +1 -0
  237. package/dist/patterns/page-shell.d.ts +1 -23
  238. package/dist/patterns/page-shell.d.ts.map +1 -1
  239. package/dist/patterns/page-shell.js +1 -10
  240. package/dist/patterns/page-shell.js.map +1 -1
  241. package/dist/patterns/patterns.css +12 -2247
  242. package/dist/patterns/pipeline/index.d.ts +29 -0
  243. package/dist/patterns/pipeline/index.d.ts.map +1 -0
  244. package/dist/patterns/pipeline/index.js +26 -0
  245. package/dist/patterns/pipeline/index.js.map +1 -0
  246. package/dist/patterns/pipeline/styles.css +168 -0
  247. package/dist/patterns/pipeline.d.ts +1 -28
  248. package/dist/patterns/pipeline.d.ts.map +1 -1
  249. package/dist/patterns/pipeline.js +1 -25
  250. package/dist/patterns/pipeline.js.map +1 -1
  251. package/dist/patterns/record-form/index.d.ts +18 -0
  252. package/dist/patterns/record-form/index.d.ts.map +1 -0
  253. package/dist/patterns/record-form/index.js +14 -0
  254. package/dist/patterns/record-form/index.js.map +1 -0
  255. package/dist/patterns/record-form/styles.css +175 -0
  256. package/dist/patterns/record-form.d.ts +1 -17
  257. package/dist/patterns/record-form.d.ts.map +1 -1
  258. package/dist/patterns/record-form.js +1 -13
  259. package/dist/patterns/record-form.js.map +1 -1
  260. package/dist/patterns/record-page/index.d.ts +31 -0
  261. package/dist/patterns/record-page/index.d.ts.map +1 -0
  262. package/dist/patterns/record-page/index.js +29 -0
  263. package/dist/patterns/record-page/index.js.map +1 -0
  264. package/dist/patterns/record-page/styles.css +228 -0
  265. package/dist/patterns/record-page.d.ts +1 -30
  266. package/dist/patterns/record-page.d.ts.map +1 -1
  267. package/dist/patterns/record-page.js +1 -28
  268. package/dist/patterns/record-page.js.map +1 -1
  269. package/dist/patterns/workspace-page/index.d.ts +23 -0
  270. package/dist/patterns/workspace-page/index.d.ts.map +1 -0
  271. package/dist/patterns/workspace-page/index.js +26 -0
  272. package/dist/patterns/workspace-page/index.js.map +1 -0
  273. package/dist/patterns/workspace-page/styles.css +9 -0
  274. package/dist/patterns/workspace-page.d.ts +1 -22
  275. package/dist/patterns/workspace-page.d.ts.map +1 -1
  276. package/dist/patterns/workspace-page.js +1 -25
  277. package/dist/patterns/workspace-page.js.map +1 -1
  278. package/dist/primitives/actions/index.d.ts +36 -0
  279. package/dist/primitives/actions/index.d.ts.map +1 -0
  280. package/dist/primitives/actions/index.js +10 -0
  281. package/dist/primitives/actions/index.js.map +1 -0
  282. package/dist/primitives/actions/styles.css +149 -0
  283. package/dist/primitives/actions.d.ts +1 -35
  284. package/dist/primitives/actions.d.ts.map +1 -1
  285. package/dist/primitives/actions.js +1 -9
  286. package/dist/primitives/actions.js.map +1 -1
  287. package/dist/primitives/feedback/index.d.ts +19 -0
  288. package/dist/primitives/feedback/index.d.ts.map +1 -0
  289. package/dist/primitives/feedback/index.js +21 -0
  290. package/dist/primitives/feedback/index.js.map +1 -0
  291. package/dist/primitives/feedback/styles.css +117 -0
  292. package/dist/primitives/feedback.d.ts +1 -18
  293. package/dist/primitives/feedback.d.ts.map +1 -1
  294. package/dist/primitives/feedback.js +1 -22
  295. package/dist/primitives/feedback.js.map +1 -1
  296. package/dist/primitives/field/index.d.ts +35 -0
  297. package/dist/primitives/field/index.d.ts.map +1 -0
  298. package/dist/primitives/field/index.js +34 -0
  299. package/dist/primitives/field/index.js.map +1 -0
  300. package/dist/primitives/field/native-control.d.ts +4 -0
  301. package/dist/primitives/field/native-control.d.ts.map +1 -0
  302. package/dist/primitives/field/native-control.js +12 -0
  303. package/dist/primitives/field/native-control.js.map +1 -0
  304. package/dist/primitives/field/styles.css +160 -0
  305. package/dist/primitives/field.d.ts +1 -34
  306. package/dist/primitives/field.d.ts.map +1 -1
  307. package/dist/primitives/field.js +1 -41
  308. package/dist/primitives/field.js.map +1 -1
  309. package/dist/primitives/navigation/index.d.ts +36 -0
  310. package/dist/primitives/navigation/index.d.ts.map +1 -0
  311. package/dist/primitives/navigation/index.js +19 -0
  312. package/dist/primitives/navigation/index.js.map +1 -0
  313. package/dist/primitives/{navigation.css → navigation/styles.css} +51 -0
  314. package/dist/primitives/navigation.d.ts +1 -25
  315. package/dist/primitives/navigation.d.ts.map +1 -1
  316. package/dist/primitives/navigation.js +1 -15
  317. package/dist/primitives/navigation.js.map +1 -1
  318. package/dist/primitives/primitives.css +4 -570
  319. package/dist/primitives/progress/index.d.ts +10 -0
  320. package/dist/primitives/progress/index.d.ts.map +1 -0
  321. package/dist/primitives/progress/index.js +13 -0
  322. package/dist/primitives/progress/index.js.map +1 -0
  323. package/dist/primitives/progress.d.ts +1 -9
  324. package/dist/primitives/progress.d.ts.map +1 -1
  325. package/dist/primitives/progress.js +1 -12
  326. package/dist/primitives/progress.js.map +1 -1
  327. package/dist/primitives/status/index.d.ts +27 -0
  328. package/dist/primitives/status/index.d.ts.map +1 -0
  329. package/dist/primitives/status/index.js +16 -0
  330. package/dist/primitives/status/index.js.map +1 -0
  331. package/dist/primitives/status/styles.css +114 -0
  332. package/dist/primitives/status.d.ts +1 -26
  333. package/dist/primitives/status.d.ts.map +1 -1
  334. package/dist/primitives/status.js +1 -15
  335. package/dist/primitives/status.js.map +1 -1
  336. package/dist/record/activity/index.d.ts +26 -0
  337. package/dist/record/activity/index.d.ts.map +1 -0
  338. package/dist/record/activity/index.js +33 -0
  339. package/dist/record/activity/index.js.map +1 -0
  340. package/dist/record/activity/styles.css +38 -0
  341. package/dist/record/composition/index.d.ts +33 -0
  342. package/dist/record/composition/index.d.ts.map +1 -0
  343. package/dist/record/composition/index.js +10 -0
  344. package/dist/record/composition/index.js.map +1 -0
  345. package/dist/record/composition/styles.css +30 -0
  346. package/dist/record/display/index.d.ts +37 -0
  347. package/dist/record/display/index.d.ts.map +1 -0
  348. package/dist/record/display/index.js +23 -0
  349. package/dist/record/display/index.js.map +1 -0
  350. package/dist/record/display/styles.css +63 -0
  351. package/dist/record/formatted-values/index.d.ts +19 -0
  352. package/dist/record/formatted-values/index.d.ts.map +1 -0
  353. package/dist/record/formatted-values/index.js +21 -0
  354. package/dist/record/formatted-values/index.js.map +1 -0
  355. package/dist/record/formatted-values/styles.css +8 -0
  356. package/dist/record/media/index.d.ts +31 -0
  357. package/dist/record/media/index.d.ts.map +1 -0
  358. package/dist/record/media/index.js +19 -0
  359. package/dist/record/media/index.js.map +1 -0
  360. package/dist/record/media/styles.css +38 -0
  361. package/dist/runtime/auto.d.ts +2 -0
  362. package/dist/runtime/auto.d.ts.map +1 -0
  363. package/dist/runtime/auto.js +5 -0
  364. package/dist/runtime/auto.js.map +1 -0
  365. package/dist/runtime/index.d.ts +9 -0
  366. package/dist/runtime/index.d.ts.map +1 -0
  367. package/dist/runtime/index.js +369 -0
  368. package/dist/runtime/index.js.map +1 -0
  369. package/dist/styles.css +47 -8
  370. package/package.json +9 -2
  371. /package/dist/primitives/{progress.css → progress/styles.css} +0 -0
@@ -1,753 +1,15 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "@ketvietlab/ketjs-view/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "@ketvietlab/ketjs-view/jsx-runtime";
2
2
  import { each, html } from '@ketvietlab/ketjs-view';
3
- import { ActionGroup, Button, IconButton, LinkButton } from '../primitives/actions.js';
4
- import { Avatar, Badge, Code, CountBadge, Tag } from '../primitives/status.js';
5
- import { EmptyState, LoadingState, Notice } from '../primitives/feedback.js';
6
- import { Field } from '../primitives/field.js';
7
- import { NavList, Tabs } from '../primitives/navigation.js';
8
- import { Progress } from '../primitives/progress.js';
9
- import { ContentCard, Disclosure, Grid, Inline, Metric, Section, Stack, Surface } from '../layouts/index.js';
10
- import { AppShell } from '../layouts/shell.js';
11
- import { DataTable } from '../patterns/data-table.js';
12
- import { ListChrome } from '../patterns/list-chrome.js';
13
- import { BoardPage } from '../patterns/board-page.js';
14
- import { DashboardPage } from '../patterns/dashboard-page.js';
15
- import { ListPage } from '../patterns/list-page.js';
16
- import { FormPage } from '../patterns/form-page.js';
17
- import { RecordPage } from '../patterns/record-page.js';
18
- import { WorkspacePage } from '../patterns/workspace-page.js';
19
- import { ModalSheet } from '../patterns/modal-sheet.js';
20
- import { Pipeline } from '../patterns/pipeline.js';
21
- import { RecordForm } from '../patterns/record-form.js';
3
+ import { LinkButton } from '../primitives/actions/index.js';
4
+ import { Code } from '../primitives/status/index.js';
5
+ import { componentGroups } from './groups.js';
6
+ import { designSystemInventory } from './inventory.generated.js';
7
+ import { componentRegistry } from './registry.js';
22
8
  export { PageSurfacePreview, surfaceKinds, surfaceStates } from './page-surfaces.js';
23
- const orders = [
24
- { id: 'SO-1042', customer: 'Công ty Ánh Dương', total: '18.450.000 ₫', state: 'Ready' },
25
- { id: 'SO-1041', customer: 'Khách sạn Mùa Hạ', total: '6.800.000 ₫', state: 'Review' },
26
- { id: 'SO-1039', customer: 'Nguyễn Minh Châu', total: '2.150.000 ₫', state: 'Blocked' },
27
- ];
28
- const toneOf = (state) => state === 'Ready' ? 'positive' : state === 'Review' ? 'warning' : 'danger';
29
- const demoNavItems = (active) => [
30
- { label: 'Collection', href: '#app-shell', leading: '≡', active: active === 'collection', count: 148 },
31
- { label: 'Record', href: '#record-page', leading: '◇', active: active === 'record' },
32
- { label: 'Flow', href: '#workspace-flow', leading: '▦', active: active === 'flow', count: 7 },
33
- { label: 'Canvas', href: '#workspace-canvas', leading: '□', active: active === 'canvas' },
34
- ];
35
- const DemoSidebar = (props) => (_jsxs("div", { "data-ui": "shell-demo-sidebar", children: [_jsx("strong", { children: "K\u00E9tSuite" }), _jsx(NavList, { label: "Workspace layouts", items: demoNavItems(props.active) })] }));
36
- const DemoRail = (props) => (_jsxs("div", { "data-ui": "shell-demo-rail", children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Context" }), _jsx("strong", { children: props.title }), _jsx("p", { children: props.detail }), props.progress !== undefined && _jsx(Progress, { label: props.title, value: props.progress }), props.items !== undefined && _jsx(Stack, { gap: "compact", items: props.items })] }));
37
- const DemoShell = (props) => (_jsx(AppShell, { mode: "embedded", sidebar: _jsx(DemoSidebar, { active: props.active }), main: props.main, rightRail: props.railTitle !== undefined ? (_jsx(DemoRail, { title: props.railTitle, detail: props.railDetail ?? '', progress: props.railProgress, items: props.railItems })) : undefined }));
38
- const OrdersTable = (props = {}) => (_jsx(DataTable, { title: props.title, rows: props.grouped ? [] : orders, id: (row) => row.id, rowHref: (row) => `#${row.id}`, responsive: "stack", selection: { selectedIds: ['SO-1042'] }, groups: props.grouped
39
- ? [
40
- {
41
- id: 'ready',
42
- label: 'Ready to invoice',
43
- count: 2,
44
- rows: orders.slice(0, 2),
45
- pager: { label: '2 shown in Ready', nextHref: '#data-table' },
46
- },
47
- {
48
- id: 'blocked',
49
- label: 'Needs decision',
50
- count: 1,
51
- rows: orders.slice(2),
52
- },
53
- ]
54
- : undefined, columns: [
55
- {
56
- key: 'id',
57
- label: 'Order',
58
- cell: (row) => row.id,
59
- priority: 'primary',
60
- kind: 'identifier',
61
- sort: { href: '#data-table', direction: 'descending' },
62
- },
63
- { key: 'customer', label: 'Customer', cell: (row) => row.customer },
64
- { key: 'total', label: 'Total', cell: (row) => row.total, align: 'end', kind: 'currency' },
65
- {
66
- key: 'state',
67
- label: 'State',
68
- cell: (row) => _jsx(Badge, { label: row.state, tone: toneOf(row.state) }),
69
- kind: 'status',
70
- },
71
- ] }));
72
- const ListDemoChrome = (props) => (_jsx(ListChrome, { search: {
73
- id: `${props.id}-query`,
74
- action: `#${props.id}`,
75
- value: props.id === 'list-page' ? 'Mùa Hạ' : '',
76
- placeholder: 'Search records',
77
- hidden: { view: 'table' },
78
- }, facets: [
79
- { id: 'all', label: 'All', href: `#${props.id}`, active: true, count: 148 },
80
- { id: 'ready', label: 'Ready', href: `#${props.id}`, count: 91 },
81
- { id: 'review', label: 'Review', href: `#${props.id}`, count: 7 },
82
- ], views: [
83
- { id: 'table', label: 'Table', href: `#${props.id}`, active: true },
84
- { id: 'kanban', label: 'Kanban', href: `#${props.id}` },
85
- ], sort: {
86
- id: `${props.id}-sort`,
87
- action: `#${props.id}`,
88
- choices: [
89
- { value: 'date-desc', label: 'Newest first', selected: true },
90
- { value: 'total-desc', label: 'Largest total' },
91
- ],
92
- }, bulk: {
93
- selectedCount: props.selected ?? 1,
94
- summary: `${props.selected ?? 1} selected`,
95
- clearHref: `#${props.id}`,
96
- actions: [{ id: 'approve', label: 'Approve', name: 'intent', value: 'approve', variant: 'primary' }],
97
- }, pager: {
98
- summary: 'Showing 1-3 of 148',
99
- previousHref: null,
100
- nextHref: `#${props.id}`,
101
- pages: [
102
- { label: '1', href: `#${props.id}`, active: true },
103
- { label: '2', href: `#${props.id}` },
104
- ],
105
- } }));
106
- export const componentGroups = [
107
- {
108
- id: 'actions',
109
- name: 'Actions',
110
- description: 'Business hierarchy expressed independently from colour.',
111
- examples: [
112
- {
113
- id: 'button',
114
- name: 'Button',
115
- description: 'Primary, secondary, tertiary, destructive, loading and disabled states.',
116
- render: () => (_jsx(ActionGroup, { label: "Button variants", actions: [
117
- _jsx(Button, { label: "Create order", variant: "primary", leading: "+" }),
118
- _jsx(Button, { label: "Save draft", variant: "secondary" }),
119
- _jsx(Button, { label: "More details", variant: "tertiary" }),
120
- _jsx(Button, { label: "Terminate", variant: "destructive" }),
121
- _jsx(Button, { label: "Saving", loading: true }),
122
- _jsx(Button, { label: "Unavailable", disabled: true }),
123
- _jsx(LinkButton, { label: "Opening record", href: "#record-page", loading: true }),
124
- _jsx(IconButton, { label: "Toggle theme", icon: "\u263E" }),
125
- ] })),
126
- },
127
- {
128
- id: 'action-sizes',
129
- name: 'Action sizes',
130
- description: 'Density changes target size without changing hierarchy.',
131
- render: () => (_jsx(ActionGroup, { label: "Action sizes", actions: [
132
- _jsx(Button, { label: "Compact", size: "compact" }),
133
- _jsx(Button, { label: "Default" }),
134
- _jsx(Button, { label: "Prominent decision", size: "prominent", variant: "primary" }),
135
- _jsx(IconButton, { label: "Compact theme toggle", icon: "\u263E", size: "compact" }),
136
- _jsx(IconButton, { label: "Prominent theme toggle", icon: "\u263E", size: "prominent" }),
137
- _jsx(LinkButton, { label: "Open record", href: "#data-table", variant: "tertiary", leading: "\u2197" }),
138
- ] })),
139
- },
140
- ],
141
- },
142
- {
143
- id: 'status',
144
- name: 'Status & identity',
145
- description: 'Compact objects for operational scanning.',
146
- examples: [
147
- {
148
- id: 'badges',
149
- name: 'Badge and tag',
150
- description: 'Tones carry meaning; tags represent categories and active filters.',
151
- render: () => (_jsx(Inline, { items: [
152
- _jsx(Badge, { label: "Neutral" }),
153
- _jsx(Badge, { label: "Synchronized", tone: "info" }),
154
- _jsx(Badge, { label: "Ready", tone: "positive" }),
155
- _jsx(Badge, { label: "Needs review", tone: "warning" }),
156
- _jsx(Badge, { label: "Failed", tone: "danger" }),
157
- _jsx(Tag, { label: "H\u00E0 N\u1ED9i", removeHref: "#status", removeLabel: "Remove H\u00E0 N\u1ED9i filter" }),
158
- _jsx(CountBadge, { count: 12, label: "12 pending items" }),
159
- ] })),
160
- },
161
- {
162
- id: 'identity',
163
- name: 'Avatar and code',
164
- description: 'Stable fallbacks for people and exact machine-readable values.',
165
- render: () => (_jsx(Inline, { items: [
166
- _jsx(Avatar, { name: "Nguy\u1EC5n Minh Ch\u00E2u", size: "small" }),
167
- _jsx(Avatar, { name: "Nguy\u1EC5n Minh Ch\u00E2u" }),
168
- _jsx(Avatar, { name: "Nguy\u1EC5n Minh Ch\u00E2u", size: "large" }),
169
- _jsx(Code, { value: "tenant-vn-hn-0042", context: "tenant" }),
170
- ] })),
171
- },
172
- ],
173
- },
174
- {
175
- id: 'feedback',
176
- name: 'Feedback',
177
- description: 'Complete operational states, including the paths nobody screenshots first.',
178
- examples: [
179
- {
180
- id: 'notice',
181
- name: 'Notice',
182
- description: 'Status, warning and recovery information with an optional action.',
183
- render: () => (_jsx(Stack, { gap: "compact", items: [
184
- _jsx(Notice, { title: "Sync complete", message: "42 records are ready for review.", tone: "positive" }),
185
- _jsx(Notice, { title: "Release drift", message: "Two tenants are one release behind.", tone: "warning" }),
186
- _jsx(Notice, { title: "Connection failed", message: "The provider rejected the stored credential. Rotate it before retrying.", tone: "danger", actions: _jsx(Button, { label: "Rotate", size: "compact" }) }),
187
- ] })),
188
- },
189
- {
190
- id: 'empty-loading',
191
- name: 'Empty and loading',
192
- description: 'Explicit state preserves layout and gives the reader a next step.',
193
- render: () => (_jsx(Grid, { columns: 2, items: [
194
- _jsx(Surface, { padding: "none", body: _jsx(EmptyState, { title: "No saved views", message: "Save the current filters to reuse them later.", actions: _jsx(Button, { label: "Save current view", size: "compact" }) }) }),
195
- _jsx(Surface, { padding: "none", body: _jsx(LoadingState, { label: "Loading order history", lines: 3 }) }),
196
- ] })),
197
- },
198
- ],
199
- },
200
- {
201
- id: 'fields',
202
- name: 'Fields',
203
- description: 'Native controls with one label, help and error contract.',
204
- examples: [
205
- {
206
- id: 'field',
207
- name: 'Field',
208
- description: 'Text, select, checkbox and error states without application-owned markup.',
209
- render: () => (_jsx(Surface, { body: _jsx(Grid, { columns: 2, items: [
210
- _jsx(Field, { id: "company-name", name: "company", label: "Company name", value: "K\u00E9t Vi\u1EC7t", required: true }),
211
- _jsx(Field, { id: "deployment", name: "deployment", label: "Deployment", type: "select", value: "commerce", options: [
212
- { value: 'commerce', label: 'Commerce' },
213
- { value: 'cosmetic', label: 'Cosmetic' },
214
- { value: 'hospitality', label: 'Hospitality' },
215
- ], help: "A tenant belongs to exactly one deployment." }),
216
- _jsx(Field, { id: "database-key", name: "databaseKey", label: "Database key", value: "Invalid Key", error: "Use lowercase letters, numbers and hyphens only." }),
217
- _jsx(Field, { id: "active", name: "active", label: "Active for new orders", type: "checkbox", value: true, help: "New orders can be assigned to this company." }),
218
- ] }) })),
219
- },
220
- ],
221
- },
222
- {
223
- id: 'field-states',
224
- name: 'Field states',
225
- description: 'Native input types, validation, read-only values and nested groups.',
226
- examples: [
227
- {
228
- id: 'advanced-fields',
229
- name: 'Operational fields',
230
- description: 'Numeric constraints, dates, options and nested validation use the same field contract.',
231
- render: () => (_jsx(Surface, { title: "Settings", body: _jsx(RecordForm, { action: "#advanced-fields", submitLabel: "Save settings", fields: [
232
- {
233
- id: 'settings-reference',
234
- name: 'reference',
235
- label: 'Reference',
236
- value: 'CUS-0042',
237
- readOnly: true,
238
- help: 'Assigned when the account was created.',
239
- },
240
- {
241
- id: 'settings-locked',
242
- name: 'locked',
243
- label: 'External reference',
244
- value: 'Pending verification',
245
- disabled: true,
246
- },
247
- {
248
- id: 'settings-limit',
249
- name: 'limit',
250
- label: 'Credit limit',
251
- type: 'decimal',
252
- value: 80000000,
253
- min: 0,
254
- step: '1000',
255
- },
256
- {
257
- id: 'settings-date',
258
- name: 'date',
259
- label: 'Effective date',
260
- type: 'date',
261
- value: '2026-09-08',
262
- },
263
- { id: 'settings-time', name: 'time', label: 'Delivery time', type: 'time', value: '09:00' },
264
- {
265
- id: 'settings-color',
266
- name: 'color',
267
- label: 'Calendar colour',
268
- type: 'color',
269
- value: '#5167c4',
270
- },
271
- {
272
- id: 'settings-billing',
273
- name: 'billing',
274
- label: 'Billing frequency',
275
- type: 'radio',
276
- value: 'monthly',
277
- required: true,
278
- options: [
279
- { value: 'monthly', label: 'Monthly' },
280
- { value: 'quarterly', label: 'Quarterly' },
281
- ],
282
- },
283
- {
284
- id: 'settings-channels',
285
- name: 'channels',
286
- label: 'Notifications',
287
- type: 'checkbox-group',
288
- options: [
289
- { value: 'email', label: 'Email', checked: true },
290
- { value: 'sms', label: 'SMS' },
291
- ],
292
- },
293
- {
294
- id: 'settings-address',
295
- name: 'address',
296
- label: 'Delivery address',
297
- error: 'Check the delivery address.',
298
- fields: [
299
- {
300
- id: 'settings-street',
301
- name: 'street',
302
- label: 'Street',
303
- value: '',
304
- required: true,
305
- error: 'Enter a street address.',
306
- span: 'full',
307
- },
308
- {
309
- id: 'settings-city',
310
- name: 'city',
311
- label: 'City',
312
- value: 'Hồ Chí Minh',
313
- autocomplete: 'address-level2',
314
- },
315
- ],
316
- },
317
- ] }) })),
318
- },
319
- ],
320
- },
321
- {
322
- id: 'layouts',
323
- name: 'Layouts',
324
- description: 'Quiet hierarchy for dense application screens.',
325
- examples: [
326
- {
327
- id: 'surface-section',
328
- name: 'Surface and section',
329
- description: 'Layout components establish rhythm without domain assumptions.',
330
- render: () => (_jsx(Section, { eyebrow: "Operations", title: "Daily overview", description: "The section owns hierarchy; its body remains application data.", actions: _jsx(LinkButton, { label: "View report", href: "#patterns", size: "compact" }), body: _jsx(Grid, { columns: 4, items: [
331
- _jsx(Metric, { label: "Orders", value: "148", detail: "+12 today", tone: "positive", icon: _jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.75", "aria-hidden": "true", focusable: "false", children: [_jsx("path", { d: "M3 6h18v12H3z" }), _jsx("circle", { cx: "12", cy: "12", r: "2.5" })] }) }),
332
- _jsx(Metric, { label: "Review queue", value: "7", detail: "Oldest 42 min", tone: "warning", href: "#surface-section" }),
333
- _jsx(Metric, { label: "Blocked", value: "2", detail: "Credential required", tone: "danger" }),
334
- _jsx(Metric, { label: "Archived", value: "1 204", detail: "No state to report" }),
335
- ] }) })),
336
- },
337
- {
338
- id: 'content-card',
339
- name: 'Content card',
340
- description: 'A composable record summary with valid nested actions.',
341
- render: () => (_jsx(Grid, { columns: 3, items: [
342
- _jsx(ContentCard, { title: "Commerce", summary: "General retail operations", body: "24 ready tenants", meta: _jsx(Badge, { label: "Stable", tone: "positive" }), href: "#content-card" }),
343
- _jsx(ContentCard, { title: "Cosmetic", summary: "Care and marketplace workflows", body: "9 ready tenants", meta: _jsx(Badge, { label: "Review", tone: "warning" }), selected: true }),
344
- _jsx(ContentCard, { title: "Hospitality", summary: "Property and OTA operations", body: "6 ready tenants", actions: _jsx(Button, { label: "Open cohort", size: "compact" }) }),
345
- ] })),
346
- },
347
- {
348
- id: 'disclosure',
349
- name: 'Disclosure',
350
- description: 'Secondary detail stays available without dominating the primary workflow.',
351
- render: () => (_jsx(Disclosure, { summary: "Permission provenance", body: _jsx(Stack, { gap: "compact", items: [
352
- _jsx(Code, { value: "sales.order.approve", context: "managed-template" }),
353
- _jsx(Code, { value: "sales.order.read", context: "managed-template" }),
354
- ] }) })),
355
- },
356
- ],
357
- },
358
- {
359
- id: 'application-structure',
360
- name: 'Application structure',
361
- description: 'Four practical layouts inside the same shell: collection, record, flow workspace and canvas workspace.',
362
- examples: [
363
- {
364
- id: 'app-shell',
365
- name: 'Collection shell',
366
- description: 'A full list workspace with sidebar navigation, URL-owned list chrome, selectable rows and a context rail.',
367
- render: () => (_jsx(DemoShell, { active: "collection", main: _jsx(ListPage, { variant: "operational", context: "Sales / Sales orders", title: "Sales orders", description: "Review demand, fulfillment and payment state from one operational list.", actions: _jsx(Button, { label: "Create order", variant: "primary" }), controls: _jsx(ListDemoChrome, { id: "app-shell" }), body: _jsx(OrdersTable, { title: "Order list" }) }), railTitle: "List health", railDetail: "Seven orders need a human decision before invoicing.", railProgress: 72, railItems: [
368
- _jsx(Badge, { label: "91 ready", tone: "positive" }),
369
- _jsx(Badge, { label: "7 review", tone: "warning" }),
370
- ] })),
371
- },
372
- {
373
- id: 'record-page',
374
- name: 'Record shell',
375
- description: 'A durable subject with record identity, tabs, form content and a right-hand facts rail.',
376
- render: () => (_jsx(DemoShell, { active: "record", main: _jsx(RecordPage, { variant: "operational", context: "Customers / M\u00F9a H\u1EA1 Riverside", title: "M\u00F9a H\u1EA1 Riverside", description: "Customer \u00B7 CUS-0042", status: _jsx(Badge, { label: "Active", tone: "positive" }), actions: _jsx(ActionGroup, { actions: [
377
- _jsx(Button, { label: "Save", variant: "primary", size: "compact" }),
378
- _jsx(Button, { label: "Archive", variant: "tertiary", size: "compact" }),
379
- ] }), navigation: _jsx(Tabs, { label: "Customer record", items: [
380
- { id: 'details', label: 'Details', href: '#record-page', active: true },
381
- { id: 'orders', label: 'Orders', href: '#record-page', count: 6 },
382
- { id: 'activity', label: 'Activity', href: '#record-page', count: 8 },
383
- ] }), body: _jsx(Stack, { items: [
384
- _jsx(Surface, { title: "Main information", body: _jsx(RecordForm, { action: "#record-page", fields: [
385
- {
386
- id: 'layout-partner-name',
387
- span: 'full',
388
- name: 'name',
389
- label: 'Name',
390
- value: 'Mùa Hạ Riverside',
391
- },
392
- {
393
- id: 'layout-partner-email',
394
- span: 'full',
395
- name: 'email',
396
- label: 'Email',
397
- type: 'email',
398
- value: 'hello@muaha.example',
399
- },
400
- {
401
- id: 'layout-partner-tags',
402
- name: 'tags',
403
- label: 'Tags',
404
- type: 'checkbox-group',
405
- span: 'full',
406
- options: [
407
- { value: 'vip', label: 'VIP', checked: true },
408
- { value: 'hospitality', label: 'Hospitality', checked: true },
409
- ],
410
- },
411
- ], submitLabel: "Save" }) }),
412
- _jsx(OrdersTable, { title: "Recent orders" }),
413
- ] }), aside: _jsx(Stack, { items: [
414
- _jsx(Metric, { label: "Credit limit", value: "80m \u20AB", detail: "42m \u20AB available" }),
415
- _jsx(Progress, { label: "Onboarding complete", value: 84, tone: "positive" }),
416
- ] }), asideLabel: "Customer context" }) })),
417
- },
418
- {
419
- id: 'workspace-flow',
420
- name: 'Flow workspace',
421
- description: 'A vertical operations overview where metrics, process state and exception lists sit on one grey canvas.',
422
- render: () => (_jsx(DemoShell, { active: "flow", main: _jsx(WorkspacePage, { variant: "operational", layout: "flow", context: "Sales / Overview", title: "Revenue operations", description: "Follow confirmed demand, open work and handoffs across the team.", actions: _jsx(Button, { label: "Create quotation", variant: "primary" }), controls: _jsx(ActionGroup, { label: "Flow controls", actions: [
423
- _jsx(LinkButton, { label: "Today", href: "#workspace-flow", size: "compact" }),
424
- _jsx(LinkButton, { label: "This week", href: "#workspace-flow", size: "compact", variant: "tertiary" }),
425
- ] }), body: _jsx(Stack, { gap: "loose", items: [
426
- _jsx(Grid, { columns: 4, items: [
427
- _jsx(Metric, { label: "Quotations", value: 24, detail: "5 new today" }),
428
- _jsx(Metric, { label: "Sent", value: 9, detail: "Awaiting reply", tone: "info" }),
429
- _jsx(Metric, { label: "Confirmed", value: 18, detail: "82,000,000 \u20AB", tone: "positive" }),
430
- _jsx(Metric, { label: "Blocked", value: 2, detail: "Needs attention", tone: "danger" }),
431
- ] }),
432
- _jsx(Surface, { title: "Sales flow", body: _jsx(Pipeline, { label: "Sales flow", steps: [
433
- { id: 'draft', label: 'Quotation', value: 24 },
434
- { id: 'sent', label: 'Sent', value: 9, tone: 'info' },
435
- { id: 'confirmed', label: 'Confirmed', value: 18, tone: 'positive' },
436
- { id: 'invoice', label: 'To invoice', value: 6, tone: 'warning' },
437
- ] }) }),
438
- _jsx(OrdersTable, { grouped: true, title: "Exceptions" }),
439
- ] }) }), railTitle: "Daily target", railDetail: "56 of 82 confirmed orders have been invoiced today.", railProgress: 68 })),
440
- },
441
- {
442
- id: 'workspace-canvas',
443
- name: 'Canvas workspace',
444
- description: 'A horizontal board-style surface where the main content can scroll without changing the shell.',
445
- render: () => (_jsx(DemoShell, { active: "canvas", main: _jsx(WorkspacePage, { variant: "operational", layout: "canvas", context: "CRM / Pipeline", title: "Opportunities board", description: "Move active opportunities through a spatial workflow.", actions: _jsx(Button, { label: "Create opportunity", variant: "primary" }), controls: _jsx(Inline, { items: [
446
- _jsx(LinkButton, { label: "My pipeline", href: "#workspace-canvas", size: "compact" }),
447
- _jsx(LinkButton, { label: "All teams", href: "#workspace-canvas", size: "compact", variant: "tertiary" }),
448
- _jsx(Tag, { label: "High value", removeHref: "#workspace-canvas", removeLabel: "Remove filter" }),
449
- ] }), body: _jsx(Grid, { columns: 3, items: [
450
- _jsx(Section, { title: "Qualified", body: _jsx(Stack, { gap: "compact", items: [
451
- _jsx(ContentCard, { title: "M\u00F9a H\u1EA1 Riverside", meta: "42,000,000 \u20AB", body: "Needs proposal" }),
452
- _jsx(ContentCard, { title: "\u00C1nh D\u01B0\u01A1ng Group", meta: "18,000,000 \u20AB", body: "Demo booked" }),
453
- ] }) }),
454
- _jsx(Section, { title: "Proposal", body: _jsx(Stack, { gap: "compact", items: [
455
- _jsx(ContentCard, { title: "Lotus Hotels", meta: "64,000,000 \u20AB", body: "Awaiting CFO" }),
456
- _jsx(ContentCard, { title: "B\u00ECnh Minh Retail", meta: "30,000,000 \u20AB", body: "Legal review" }),
457
- ] }) }),
458
- _jsx(Section, { title: "Negotiation", body: _jsx(Stack, { gap: "compact", items: [
459
- _jsx(ContentCard, { title: "S\u00F4ng Xanh", meta: "52,000,000 \u20AB", body: "Discount requested" }),
460
- _jsx(ContentCard, { title: "Urban Stay", meta: "40,000,000 \u20AB", body: "Close this week" }),
461
- ] }) }),
462
- ] }) }), railTitle: "Pipeline risk", railDetail: "Three opportunities need owner follow-up before Friday.", railItems: [
463
- _jsx(Badge, { label: "2 overdue", tone: "danger" }),
464
- _jsx(Badge, { label: "6 due this week", tone: "warning" }),
465
- ] })),
466
- },
467
- ],
468
- },
469
- {
470
- id: 'navigation',
471
- name: 'Navigation & progress',
472
- description: 'Low-luminance selection and compact progress keep attention on the working content.',
473
- examples: [
474
- {
475
- id: 'navigation-items',
476
- name: 'Navigation and tabs',
477
- description: 'The active indigo remains restrained in both vertical and horizontal navigation.',
478
- render: () => (_jsx(Stack, { items: [
479
- _jsx(NavList, { label: "Product", items: [
480
- { label: 'Details', href: '#navigation-items', leading: '◇', active: true },
481
- { label: 'Variants', href: '#navigation-items', leading: '□', count: 12 },
482
- { label: 'Inventory', href: '#navigation-items', leading: '≡' },
483
- ] }),
484
- _jsx(Tabs, { label: "Record views", items: [
485
- { id: 'summary', label: 'Summary', href: '#navigation-items', active: true },
486
- { id: 'activity', label: 'Activity', href: '#navigation-items', count: 8 },
487
- { id: 'files', label: 'Files', href: '#navigation-items', count: 3 },
488
- ] }),
489
- ] })),
490
- },
491
- {
492
- id: 'progress',
493
- name: 'Progress',
494
- description: 'A four-pixel track communicates state without becoming another panel.',
495
- render: () => (_jsx(Stack, { gap: "compact", items: [
496
- _jsx(Progress, { label: "Project completion", value: 68 }),
497
- _jsx(Progress, { label: "Approved", value: 92, tone: "positive" }),
498
- _jsx(Progress, { label: "At risk", value: 54, tone: "warning" }),
499
- _jsx(Progress, { label: "Overdue", value: 31, tone: "danger" }),
500
- ] })),
501
- },
502
- ],
503
- },
504
- {
505
- id: 'patterns',
506
- name: 'Patterns',
507
- description: 'Generic workflows assembled from the same primitives.',
508
- examples: [
509
- {
510
- id: 'list-chrome',
511
- name: 'List chrome',
512
- description: 'Search, filters, view switch, bulk state and paging for URL-driven collection screens.',
513
- render: () => (_jsx(ListChrome, { search: {
514
- id: 'customer-query',
515
- action: '#list-chrome',
516
- placeholder: 'Search customers',
517
- }, facets: [
518
- { id: 'active', label: 'Active', href: '#list-chrome', active: true, count: 42 },
519
- { id: 'draft', label: 'Draft', href: '#list-chrome', count: 6 },
520
- ], views: [
521
- { id: 'table', label: 'Table', href: '#list-chrome', active: true },
522
- { id: 'cards', label: 'Cards', href: '#list-chrome' },
523
- ], sort: {
524
- id: 'customer-sort',
525
- action: '#list-chrome',
526
- choices: [
527
- { value: 'updated-desc', label: 'Recently updated', selected: true },
528
- { value: 'name-asc', label: 'Name A-Z' },
529
- ],
530
- }, status: "48 customers", actions: _jsx(Button, { label: "Create", variant: "primary", size: "compact" }), bulk: {
531
- selectedCount: 2,
532
- summary: '2 customers selected',
533
- clearHref: '#list-chrome',
534
- actions: [{ id: 'archive', label: 'Archive', name: 'intent', value: 'archive' }],
535
- }, pager: {
536
- summary: 'Showing 1-25 of 48',
537
- nextHref: '#list-chrome',
538
- pages: [
539
- { label: '1', href: '#list-chrome', active: true },
540
- { label: '2', href: '#list-chrome' },
541
- ],
542
- } })),
543
- },
544
- {
545
- id: 'list-page',
546
- name: 'List page',
547
- description: 'The canonical collection hierarchy: identity, actions, URL-driven controls, result context and records.',
548
- render: () => (_jsx(ListPage, { variant: "operational", context: "Sales / Sales orders", eyebrow: "Sales", title: "Sales orders", description: "Review demand, fulfillment and payment state from one operational list.", actions: _jsx(Button, { label: "Create order", variant: "primary" }), controls: _jsx(ListChrome, { search: {
549
- id: 'orders-query',
550
- action: '#list-page',
551
- value: 'Mùa Hạ',
552
- placeholder: 'Search orders',
553
- hidden: { view: 'all' },
554
- }, facets: [
555
- { id: 'all', label: 'All', href: '#list-page', active: true, count: 148 },
556
- { id: 'ready', label: 'Ready', href: '#list-page', count: 91 },
557
- { id: 'review', label: 'Review', href: '#list-page', count: 7 },
558
- ], views: [
559
- { id: 'table', label: 'Table', href: '#list-page', active: true },
560
- { id: 'kanban', label: 'Kanban', href: '#list-page' },
561
- ], sort: {
562
- id: 'orders-sort',
563
- action: '#list-page',
564
- choices: [
565
- { value: 'date-desc', label: 'Newest first', selected: true },
566
- { value: 'total-desc', label: 'Largest total' },
567
- { value: 'customer-asc', label: 'Customer A-Z' },
568
- ],
569
- }, bulk: {
570
- selectedCount: 1,
571
- summary: '1 order selected',
572
- clearHref: '#list-page',
573
- actions: [
574
- { id: 'approve', label: 'Approve', name: 'intent', value: 'approve', variant: 'primary' },
575
- { id: 'export', label: 'Export', name: 'intent', value: 'export' },
576
- ],
577
- }, pager: {
578
- summary: 'Showing 1-3 of 148',
579
- previousHref: null,
580
- nextHref: '#list-page',
581
- pages: [
582
- { label: '1', href: '#list-page', active: true },
583
- { label: '2', href: '#list-page' },
584
- { label: '3', href: '#list-page' },
585
- ],
586
- } }), body: _jsx(DataTable, { title: "Order list", rows: orders, id: (row) => row.id, rowHref: (row) => `#${row.id}`, responsive: "stack", selection: { selectedIds: ['SO-1042'] }, columns: [
587
- {
588
- key: 'id',
589
- label: 'Order',
590
- cell: (row) => row.id,
591
- priority: 'primary',
592
- kind: 'identifier',
593
- sort: { href: '#list-page', direction: 'descending' },
594
- },
595
- { key: 'customer', label: 'Customer', cell: (row) => row.customer },
596
- { key: 'total', label: 'Total', cell: (row) => row.total, align: 'end', kind: 'currency' },
597
- {
598
- key: 'state',
599
- label: 'State',
600
- cell: (row) => _jsx(Badge, { label: row.state, tone: toneOf(row.state) }),
601
- kind: 'status',
602
- },
603
- ] }) })),
604
- },
605
- {
606
- id: 'dashboard-page',
607
- name: 'Dashboard page',
608
- description: 'The canonical overview hierarchy: durable context, compact identity, primary action and an uninterrupted analytical canvas.',
609
- render: () => (_jsx(DashboardPage, { variant: "operational", context: "Sales / Overview", eyebrow: "Commercial workspace", title: "Sales overview", description: "Follow demand, confirmed revenue and the work waiting for the team.", actions: _jsx(Button, { label: "Create quotation", variant: "primary" }), body: _jsx(Stack, { gap: "loose", items: [
610
- _jsx(Grid, { columns: 4, items: [
611
- _jsx(Metric, { label: "Quotations", value: 24, detail: "5 new today" }),
612
- _jsx(Metric, { label: "Sent", value: 9, detail: "Awaiting a reply", tone: "info" }),
613
- _jsx(Metric, { label: "Confirmed", value: 18, detail: "82,000,000 \u20AB", tone: "positive" }),
614
- _jsx(Metric, { label: "To invoice", value: 6, detail: "Needs attention", tone: "warning" }),
615
- ] }),
616
- _jsx(Surface, { title: "Sales flow", body: _jsx(Pipeline, { label: "Sales flow", steps: [
617
- { id: 'draft', label: 'Quotation', value: 24 },
618
- { id: 'sent', label: 'Sent', value: 9, tone: 'info' },
619
- { id: 'confirmed', label: 'Confirmed', value: 18, tone: 'positive' },
620
- { id: 'invoice', label: 'To invoice', value: 6, tone: 'warning' },
621
- ] }) }),
622
- ] }) })),
623
- },
624
- {
625
- id: 'board-page',
626
- name: 'Board page',
627
- description: 'The canonical horizontal workspace: durable context, compact identity, global controls and an uninterrupted board canvas.',
628
- render: () => (_jsx(BoardPage, { variant: "operational", context: "CRM / Pipeline", eyebrow: "Pipeline", title: "Sales opportunities", description: "Move active opportunities through the sales process.", actions: _jsx(Button, { label: "Create opportunity", variant: "primary" }), controls: _jsx(ActionGroup, { label: "Board controls", actions: [
629
- _jsx(LinkButton, { label: "My opportunities", href: "#board-page", size: "compact" }),
630
- _jsx(LinkButton, { label: "All teams", href: "#board-page", size: "compact", variant: "tertiary" }),
631
- ] }), body: _jsx(Grid, { columns: 3, items: [
632
- _jsx(ContentCard, { title: "Qualified", meta: "8 opportunities", body: "125,000,000 \u20AB" }),
633
- _jsx(ContentCard, { title: "Proposal", meta: "5 opportunities", body: "94,000,000 \u20AB" }),
634
- _jsx(ContentCard, { title: "Negotiation", meta: "3 opportunities", body: "62,000,000 \u20AB" }),
635
- ] }) })),
636
- },
637
- {
638
- id: 'pipeline',
639
- name: 'Pipeline',
640
- description: 'Stages of a process and the work sitting in each. A later stage may hold more than the one before it.',
641
- render: () => (_jsx(Pipeline, { label: "Order pipeline", steps: [
642
- { id: 'draft', label: 'Draft', value: 24, href: '#pipeline' },
643
- { id: 'sent', label: 'Sent', value: 9, href: '#pipeline', tone: 'info' },
644
- { id: 'confirmed', label: 'Confirmed', value: 18, href: '#pipeline', tone: 'positive' },
645
- { id: 'to-invoice', label: 'To invoice', value: 6, href: '#pipeline', tone: 'warning' },
646
- ] })),
647
- },
648
- {
649
- id: 'data-table',
650
- name: 'Data table',
651
- description: 'Columns are data; rows remain semantic and horizontally contained.',
652
- render: () => (_jsx(DataTable, { title: "Recent sales orders", actions: _jsx(LinkButton, { label: "View all orders", href: "#app-shell", variant: "tertiary" }), rows: [], id: (row) => row.id, rowHref: (row) => `#${row.id}`, responsive: "stack", gutter: "compact", selection: { selectedIds: ['SO-1042'] }, groups: [
653
- {
654
- id: 'ready',
655
- label: 'Ready to invoice',
656
- count: 2,
657
- href: '#data-table',
658
- rows: orders.slice(0, 2),
659
- pager: { label: '2 shown in Ready', nextHref: '#data-table' },
660
- },
661
- {
662
- id: 'blocked',
663
- label: 'Needs decision',
664
- count: 1,
665
- rows: orders.slice(2),
666
- },
667
- ], columns: [
668
- {
669
- key: 'id',
670
- label: 'Order',
671
- cell: (row) => row.id,
672
- priority: 'primary',
673
- kind: 'identifier',
674
- sort: { href: '#data-table', direction: 'descending' },
675
- },
676
- { key: 'customer', label: 'Customer', cell: (row) => row.customer },
677
- { key: 'total', label: 'Total', cell: (row) => row.total, align: 'end', kind: 'currency' },
678
- {
679
- key: 'state',
680
- label: 'State',
681
- cell: (row) => _jsx(Badge, { label: row.state, tone: toneOf(row.state) }),
682
- kind: 'status',
683
- },
684
- ] })),
685
- },
686
- {
687
- id: 'form-page',
688
- name: 'Form page',
689
- description: 'The canonical form hierarchy: record identity and decision first, a stable form column, then durable context.',
690
- render: () => (_jsx(FormPage, { variant: "operational", context: "Customers / M\u00F9a H\u1EA1 Riverside", title: "M\u00F9a H\u1EA1 Riverside", description: "Customer \u00B7 CUS-0042", status: _jsx(Badge, { label: "Active", tone: "positive" }), actions: _jsx(Button, { label: "Save partner", variant: "primary" }), body: _jsx(Surface, { title: "Main information", body: _jsx(RecordForm, { action: "#form-page", fields: [
691
- { id: 'partner-name', name: 'name', label: 'Name', value: 'Mùa Hạ Riverside' },
692
- { id: 'partner-ref', name: 'ref', label: 'Reference', value: 'CUS-0042' },
693
- {
694
- id: 'partner-email',
695
- name: 'email',
696
- label: 'Email',
697
- type: 'email',
698
- value: 'hello@muaha.example',
699
- },
700
- {
701
- id: 'partner-phone',
702
- name: 'phone',
703
- label: 'Phone',
704
- type: 'tel',
705
- value: '+84 28 3822 0042',
706
- },
707
- ], submitLabel: "Save partner" }) }), aside: _jsx(Section, { title: "Record context", body: _jsx(Stack, { gap: "compact", items: ['Customer since 2023', '6 delivery addresses'] }) }), asideLabel: "Partner context" })),
708
- },
709
- {
710
- id: 'record-form',
711
- name: 'Record form',
712
- description: 'Application supplies translated labels and values, not form markup.',
713
- render: () => (_jsx(Surface, { title: "Main information", body: _jsx(RecordForm, { action: "#record-form", fields: [
714
- { id: 'record-name', name: 'name', label: 'Display name', value: 'Mùa Hạ Riverside' },
715
- {
716
- id: 'record-status',
717
- name: 'status',
718
- label: 'Lifecycle',
719
- type: 'select',
720
- value: 'ready',
721
- options: [
722
- { value: 'draft', label: 'Draft' },
723
- { value: 'ready', label: 'Ready' },
724
- ],
725
- },
726
- {
727
- id: 'record-note',
728
- name: 'note',
729
- label: 'Internal note',
730
- type: 'textarea',
731
- value: 'Migration approved by the operations team.',
732
- span: 'full',
733
- },
734
- ], submitLabel: "Save record", cancelHref: "#patterns", cancelLabel: "Cancel" }) })),
735
- },
736
- {
737
- id: 'modal-sheet',
738
- name: 'Modal sheet',
739
- description: 'Shown embedded here; the production mode occupies the viewport.',
740
- render: () => (_jsx(ModalSheet, { id: "release-drift-modal", mode: "embedded", title: "Resolve release drift", closeHref: "#modal-sheet", closeLabel: "Close modal", body: _jsx(Stack, { items: [
741
- _jsx(Notice, { title: "Two tenants are behind", message: "Migration runs separately for each database and preserves failed tenants for retry.", tone: "warning" }),
742
- _jsx(ActionGroup, { actions: [
743
- _jsx(Button, { label: "Start migration", variant: "primary" }),
744
- _jsx(LinkButton, { label: "Review plan", href: "#data-table", variant: "tertiary" }),
745
- ] }),
746
- ] }) })),
747
- },
748
- ],
749
- },
750
- ];
9
+ export { InventoryPage, inventoryDecisions, inventoryKinds, inventoryScopes, } from './inventory.js';
10
+ export { designSystemInventory } from './inventory.generated.js';
11
+ export { componentGroups, groupGovernance } from './groups.js';
12
+ export { componentRegistry } from './registry.js';
751
13
  export const CATALOGUE_HOOKS = [
752
14
  'catalogue-surface-preview',
753
15
  'catalogue',
@@ -755,6 +17,7 @@ export const CATALOGUE_HOOKS = [
755
17
  'catalogue-brand',
756
18
  'catalogue-kicker',
757
19
  'catalogue-nav',
20
+ 'catalogue-nav-section',
758
21
  'catalogue-nav-group',
759
22
  'catalogue-nav-count',
760
23
  'catalogue-main',
@@ -762,19 +25,44 @@ export const CATALOGUE_HOOKS = [
762
25
  'catalogue-title',
763
26
  'catalogue-intro',
764
27
  'catalogue-controls',
28
+ 'catalogue-metrics',
29
+ 'catalogue-doc-grid',
30
+ 'catalogue-doc-card',
31
+ 'catalogue-component-index',
32
+ 'catalogue-component-list',
33
+ 'catalogue-component-link',
765
34
  'catalogue-group',
766
35
  'catalogue-group-head',
36
+ 'catalogue-governance',
767
37
  'catalogue-specimen',
768
38
  'catalogue-specimen-head',
769
39
  'catalogue-specimen-name',
770
40
  'catalogue-specimen-description',
41
+ 'catalogue-specimen-components',
771
42
  'catalogue-stage',
772
43
  ];
773
- export const CatalogueHead = () => html `<meta name="description" content="Két Việt public component catalogue"><link rel="stylesheet" href="/design-system/catalogue/styles.css">`;
44
+ export const CatalogueHead = () => html `<meta name="description" content="Két Việt public component documentation"><link rel="stylesheet" href="/design-system/catalogue/styles.css"><script type="module" src="/design-system/runtime/auto.js"></script>`;
45
+ const registrationsFor = (groupId) => componentRegistry.filter((registration) => registration.groupId === groupId);
46
+ const pathWithPreferences = (path, theme, density) => `${path}?theme=${theme}&density=${density}`;
47
+ const CatalogueRail = (props) => (_jsxs("aside", { "data-ui": "catalogue-rail", children: [_jsxs("a", { "data-ui": "catalogue-brand", href: pathWithPreferences('/', props.theme, props.density), children: [_jsx("span", { "aria-hidden": "true", children: "K" }), _jsx("strong", { children: "K\u00E9t Vi\u1EC7t" })] }), _jsxs("p", { "data-ui": "catalogue-kicker", children: ["Design system \u00B7 ", designSystemInventory.version] }), _jsxs("nav", { "data-ui": "catalogue-nav", "aria-label": "Design system documentation", children: [_jsx("span", { "data-ui": "catalogue-nav-section", children: "Get started" }), _jsx("a", { "data-ui": "catalogue-nav-group", href: pathWithPreferences('/', props.theme, props.density), "aria-current": props.active === 'overview' ? 'page' : null, children: _jsx("span", { children: "Overview" }) }), _jsxs("a", { "data-ui": "catalogue-nav-group", href: pathWithPreferences('/components', props.theme, props.density), "aria-current": props.active === 'components' ? 'page' : null, children: [_jsx("span", { children: "Components" }), _jsx("span", { "data-ui": "catalogue-nav-count", children: String(componentRegistry.length) })] }), _jsx("a", { "data-ui": "catalogue-nav-group", href: `/demo?theme=${props.theme}`, children: _jsx("span", { children: "Application demo" }) }), _jsx("a", { "data-ui": "catalogue-nav-group", href: `/demo2?theme=${props.theme}`, children: _jsx("span", { children: "Application submenu demo" }) }), _jsx("span", { "data-ui": "catalogue-nav-section", children: "Component groups" }), each(componentGroups, (group) => group.id, (group) => (_jsxs("a", { "data-ui": "catalogue-nav-group", href: pathWithPreferences(`/components/${group.id}`, props.theme, props.density), "aria-current": props.active === group.id ? 'page' : null, children: [_jsx("span", { children: group.name }), _jsx("span", { "data-ui": "catalogue-nav-count", children: String(registrationsFor(group.id).length) })] }))), _jsx("span", { "data-ui": "catalogue-nav-section", children: "Reference" }), _jsxs("a", { "data-ui": "catalogue-nav-group", href: "/surfaces?kind=record&theme=light", children: [_jsx("span", { children: "Page patterns" }), _jsx("span", { "data-ui": "catalogue-nav-count", children: "3" })] }), _jsx("a", { "data-ui": "catalogue-nav-group", href: "/inventory", children: _jsx("span", { children: "Inventory" }) })] })] }));
48
+ const CataloguePreferences = (props) => (_jsxs("div", { "data-ui": "catalogue-controls", role: "group", "aria-label": "Catalogue preferences", children: [_jsx("span", { children: "Theme" }), each(['light', 'dark', 'system'], (value) => value, (value) => (_jsx("a", { href: pathWithPreferences(props.path, value, props.density), "aria-current": props.theme === value ? 'page' : null, children: value[0].toUpperCase() + value.slice(1) }))), _jsx("span", { children: "Density" }), each(['compact', 'default', 'comfortable'], (value) => value, (value) => (_jsx("a", { href: pathWithPreferences(props.path, props.theme, value), "aria-current": props.density === value ? 'page' : null, children: value === 'comfortable' ? 'Comfort' : value[0].toUpperCase() + value.slice(1) })))] }));
49
+ const Overview = (props) => (_jsxs(_Fragment, { children: [_jsxs("header", { "data-ui": "catalogue-hero", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "SSR-first \u00B7 operational \u00B7 accessible" }), _jsx("h1", { "data-ui": "catalogue-title", children: "The interface language for K\u00E9t applications." }), _jsx("p", { "data-ui": "catalogue-intro", children: "Reusable contracts for dense business software\u2014designed to remain useful before JavaScript arrives and predictable when the workflow gets complicated." }), _jsx(LinkButton, { label: `Explore ${String(componentRegistry.length)} components`, href: pathWithPreferences('/components', props.theme, props.density), variant: "primary" }), _jsx(LinkButton, { label: "Review inventory", href: "/inventory", variant: "secondary" }), _jsx(LinkButton, { label: "Open application demo", href: `/demo?theme=${props.theme === 'system' ? 'light' : props.theme}`, variant: "secondary" }), _jsx(LinkButton, { label: "Try submenu navigation", href: `/demo2?theme=${props.theme === 'system' ? 'light' : props.theme}`, variant: "secondary" })] }), _jsx(CataloguePreferences, { path: "/", theme: props.theme, density: props.density })] }), _jsxs("section", { "data-ui": "catalogue-metrics", "aria-label": "Design system summary", children: [_jsxs("article", { children: [_jsx("strong", { children: String(componentRegistry.length) }), _jsx("span", { children: "public components" })] }), _jsxs("article", { children: [_jsx("strong", { children: String(componentGroups.reduce((total, group) => total + group.examples.length, 0)) }), _jsx("span", { children: "executable specimens" })] }), _jsxs("article", { children: [_jsx("strong", { children: String(componentGroups.length) }), _jsx("span", { children: "documented groups" })] }), _jsxs("article", { children: [_jsx("strong", { children: String(designSystemInventory.summary.plannedComponents) }), _jsx("span", { children: "planned contracts" })] })] }), _jsxs("section", { "data-ui": "catalogue-group", children: [_jsxs("header", { "data-ui": "catalogue-group-head", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "System map" }), _jsx("h2", { children: "Start with the contract" })] }), _jsx("p", { children: "Use the smallest stable layer that owns the behavior. Recipes compose components; applications own business state." })] }), _jsxs("div", { "data-ui": "catalogue-doc-grid", children: [_jsxs("article", { "data-ui": "catalogue-doc-card", children: [_jsx("span", { children: "01" }), _jsx("h3", { children: "Foundations" }), _jsx("p", { children: "Semantic tokens, density, focus, motion and responsive rules form one cascade." }), _jsx("a", { href: "/inventory#css", children: "Inspect CSS ownership \u2192" })] }), _jsxs("article", { "data-ui": "catalogue-doc-card", children: [_jsx("span", { children: "02" }), _jsx("h3", { children: "Components" }), _jsxs("p", { children: [String(componentRegistry.length), " renderer contracts with explicit owners, states and specimens."] }), _jsx("a", { href: pathWithPreferences('/components', props.theme, props.density), children: "Browse components \u2192" })] }), _jsxs("article", { "data-ui": "catalogue-doc-card", children: [_jsx("span", { children: "03" }), _jsx("h3", { children: "Page patterns" }), _jsx("p", { children: "ListPage, RecordPage and WorkspacePage are the only full-page identities." }), _jsx("a", { href: "/surfaces?kind=record&theme=light", children: "Review page surfaces \u2192" })] })] })] }), _jsxs("section", { "data-ui": "catalogue-group", children: [_jsxs("header", { "data-ui": "catalogue-group-head", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Component library" }), _jsx("h2", { children: "Explore the system" })] }), _jsx("p", { children: "Every number below is a component contract, not a specimen card." })] }), _jsx("div", { "data-ui": "catalogue-doc-grid", children: each(componentGroups, (group) => group.id, (group) => (_jsxs("a", { "data-ui": "catalogue-doc-card", href: pathWithPreferences(`/components/${group.id}`, props.theme, props.density), children: [_jsx("span", { children: String(registrationsFor(group.id).length).padStart(2, '0') }), _jsx("h3", { children: group.name }), _jsx("p", { children: group.description })] }))) })] })] }));
50
+ const ComponentIndex = (props) => (_jsxs(_Fragment, { children: [_jsxs("header", { "data-ui": "catalogue-hero", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Reference / components" }), _jsxs("h1", { "data-ui": "catalogue-title", children: [String(componentRegistry.length), " public components"] }), _jsx("p", { "data-ui": "catalogue-intro", children: "Search the complete public surface by ownership group. Components may share a specimen, but every contract remains visible here." })] }), _jsx(CataloguePreferences, { path: props.path, theme: props.theme, density: props.density })] }), _jsx("div", { "data-ui": "catalogue-component-index", children: each(componentGroups, (group) => group.id, (group) => (_jsxs("section", { "data-ui": "catalogue-component-list", "aria-labelledby": `${group.id}-title`, children: [_jsxs("header", { children: [_jsx("h2", { id: `${group.id}-title`, children: group.name }), _jsx("span", { children: String(registrationsFor(group.id).length) })] }), each(registrationsFor(group.id), (registration) => registration.name, (registration) => (_jsxs("a", { "data-ui": "catalogue-component-link", href: `${pathWithPreferences(`/components/${group.id}`, props.theme, props.density)}#${registration.specimenId}`, children: [_jsx("strong", { children: registration.name }), _jsx("small", { children: registration.maturity })] })))] }))) })] }));
51
+ const ComponentGroup = (props) => {
52
+ const registrations = registrationsFor(props.group.id);
53
+ return (_jsxs(_Fragment, { children: [_jsxs("header", { "data-ui": "catalogue-hero", children: [_jsxs("div", { children: [_jsxs("p", { "data-ui": "catalogue-kicker", children: ["Components / ", props.group.owner] }), _jsx("h1", { "data-ui": "catalogue-title", children: props.group.name }), _jsx("p", { "data-ui": "catalogue-intro", children: props.group.description }), _jsxs("p", { "data-ui": "catalogue-governance", children: [String(registrations.length), " components \u00B7 ", String(props.group.examples.length), " specimens \u00B7", ' ', props.group.maturity, " \u00B7 ", props.group.states.join(' / ')] })] }), _jsx(CataloguePreferences, { path: props.path, theme: props.theme, density: props.density })] }), _jsxs("section", { "data-ui": "catalogue-component-list", "aria-label": `${props.group.name} components`, children: [_jsxs("header", { children: [_jsx("h2", { children: "Component contracts" }), _jsx("span", { children: String(registrations.length) })] }), each(registrations, (registration) => registration.name, (registration) => (_jsxs("a", { "data-ui": "catalogue-component-link", href: `#${registration.specimenId}`, children: [_jsx("strong", { children: registration.name }), _jsx("small", { children: registration.maturity })] })))] }), _jsxs("section", { "data-ui": "catalogue-group", id: props.group.id, children: [_jsxs("header", { "data-ui": "catalogue-group-head", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Executable reference" }), _jsx("h2", { children: "Specimens" })] }), _jsx("p", { children: "Each specimen demonstrates one or more component contracts using production markup and CSS." })] }), each(props.group.examples, (example) => example.id, (example) => {
54
+ const covered = registrations.filter((registration) => registration.specimenId === example.id);
55
+ return (_jsxs("article", { "data-ui": "catalogue-specimen", id: example.id, children: [_jsxs("header", { "data-ui": "catalogue-specimen-head", children: [_jsxs("div", { children: [_jsx("h3", { "data-ui": "catalogue-specimen-name", children: example.name }), _jsx("p", { "data-ui": "catalogue-specimen-description", children: example.description }), _jsx("p", { "data-ui": "catalogue-specimen-components", children: covered.map((registration) => registration.name).join(' · ') })] }), _jsx(Code, { value: "@ketvietlab/design-system", context: "package" })] }), _jsx("div", { "data-ui": "catalogue-stage", children: example.render() })] }));
56
+ })] })] }));
57
+ };
774
58
  export const CataloguePage = (props = {}) => {
775
59
  const theme = props.theme ?? 'system';
776
60
  const density = props.density ?? 'default';
777
- const count = componentGroups.reduce((total, group) => total + group.examples.length, 0);
778
- return (_jsxs("main", { "data-kv-design-system": true, "data-ui": "catalogue", "data-theme": theme === 'system' ? null : theme, "data-density": density, children: [_jsxs("aside", { "data-ui": "catalogue-rail", children: [_jsxs("a", { "data-ui": "catalogue-brand", href: "#top", children: [_jsx("span", { "aria-hidden": "true", children: "K" }), _jsx("strong", { children: "K\u00E9t Vi\u1EC7t" })] }), _jsx("p", { "data-ui": "catalogue-kicker", children: "Design system \u00B7 0.1.9" }), _jsx("nav", { "data-ui": "catalogue-nav", "aria-label": "Component groups", children: each(componentGroups, (group) => group.id, (group) => (_jsxs("a", { "data-ui": "catalogue-nav-group", href: `#${group.id}`, children: [_jsx("span", { children: group.name }), _jsx("span", { "data-ui": "catalogue-nav-count", children: String(group.examples.length) })] }))) })] }), _jsxs("div", { "data-ui": "catalogue-main", id: "top", children: [_jsxs("header", { "data-ui": "catalogue-hero", children: [_jsxs("div", { children: [_jsx("p", { "data-ui": "catalogue-kicker", children: "Public components \u00B7 server rendered" }), _jsx("h1", { "data-ui": "catalogue-title", children: "K\u00E9t Vi\u1EC7t Design System" }), _jsxs("p", { "data-ui": "catalogue-intro", children: [String(count), " specimens from one markup, token and state contract. Dense enough for daily work; quiet enough for decisions."] }), _jsx(LinkButton, { label: "Review page surfaces", href: "/surfaces?kind=record&theme=light", variant: "secondary" })] }), _jsxs("div", { "data-ui": "catalogue-controls", role: "group", "aria-label": "Catalogue preferences", children: [_jsx("span", { children: "Theme" }), _jsx("a", { href: `/?theme=light&density=${density}`, "aria-current": theme === 'light' ? 'page' : null, children: "Light" }), _jsx("a", { href: `/?theme=dark&density=${density}`, "aria-current": theme === 'dark' ? 'page' : null, children: "Dark" }), _jsx("a", { href: `/?theme=system&density=${density}`, "aria-current": theme === 'system' ? 'page' : null, children: "System" }), _jsx("span", { children: "Density" }), _jsx("a", { href: `/?theme=${theme}&density=compact`, "aria-current": density === 'compact' ? 'page' : null, children: "Compact" }), _jsx("a", { href: `/?theme=${theme}&density=default`, "aria-current": density === 'default' ? 'page' : null, children: "Default" }), _jsx("a", { href: `/?theme=${theme}&density=comfortable`, "aria-current": density === 'comfortable' ? 'page' : null, children: "Comfort" })] })] }), each(componentGroups, (group) => group.id, (group) => (_jsxs("section", { "data-ui": "catalogue-group", id: group.id, children: [_jsxs("header", { "data-ui": "catalogue-group-head", children: [_jsxs("div", { children: [_jsxs("p", { "data-ui": "catalogue-kicker", children: [String(group.examples.length).padStart(2, '0'), " components"] }), _jsx("h2", { children: group.name })] }), _jsx("p", { children: group.description })] }), each(group.examples, (example) => example.id, (example) => (_jsxs("article", { "data-ui": "catalogue-specimen", id: example.id, children: [_jsxs("header", { "data-ui": "catalogue-specimen-head", children: [_jsxs("div", { children: [_jsx("h3", { "data-ui": "catalogue-specimen-name", children: example.name }), _jsx("p", { "data-ui": "catalogue-specimen-description", children: example.description })] }), _jsx(Code, { value: "@ketvietlab/design-system", context: "package" })] }), _jsx("div", { "data-ui": "catalogue-stage", children: example.render() })] })))] })))] })] }));
61
+ const mode = props.mode ?? 'overview';
62
+ const selectedGroup = componentGroups.find((group) => group.id === props.groupId);
63
+ const path = props.path ??
64
+ (selectedGroup ? `/components/${selectedGroup.id}` : mode === 'components' ? '/components' : '/');
65
+ const active = selectedGroup?.id ?? mode;
66
+ return (_jsxs("main", { "data-kv-design-system": true, "data-ui": "catalogue", "data-theme": theme === 'system' ? null : theme, "data-density": density, children: [_jsx(CatalogueRail, { active: active, theme: theme, density: density }), _jsx("div", { "data-ui": "catalogue-main", id: "top", children: selectedGroup ? (_jsx(ComponentGroup, { group: selectedGroup, theme: theme, density: density, path: path })) : mode === 'components' ? (_jsx(ComponentIndex, { theme: theme, density: density, path: path })) : mode === 'all' ? (_jsxs(_Fragment, { children: [_jsx(Overview, { theme: theme, density: density }), each(componentGroups, (group) => group.id, (group) => (_jsx(ComponentGroup, { group: group, theme: theme, density: density, path: `/components/${group.id}` })))] })) : (_jsx(Overview, { theme: theme, density: density })) })] }));
779
67
  };
780
68
  //# sourceMappingURL=index.js.map