themelia-ui 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (746) hide show
  1. package/.agents/skills/themelia-ui/SKILL.md +60 -33
  2. package/.agents/skills/themelia-ui/manifest.json +23 -0
  3. package/.agents/skills/themelia-ui/references/api-compatibility.md +5 -4
  4. package/.agents/skills/themelia-ui/references/blocks.md +123 -0
  5. package/.agents/skills/themelia-ui/references/composition-ladder.md +8 -8
  6. package/.agents/skills/themelia-ui/references/composition.md +100 -19
  7. package/.agents/skills/themelia-ui/references/forms.md +23 -3
  8. package/.agents/skills/themelia-ui/references/framework-wiring.md +41 -13
  9. package/.agents/skills/themelia-ui/references/i18n.md +4 -2
  10. package/.agents/skills/themelia-ui/references/imports.md +104 -104
  11. package/.agents/skills/themelia-ui/references/installation.md +60 -31
  12. package/.agents/skills/themelia-ui/references/migration.md +156 -5
  13. package/.agents/skills/themelia-ui/references/provider-and-scoping.md +37 -25
  14. package/.agents/skills/themelia-ui/references/reference-workflows.md +43 -0
  15. package/.agents/skills/themelia-ui/references/structure-and-spacing.md +147 -0
  16. package/.agents/skills/themelia-ui/references/theming.md +174 -131
  17. package/.agents/skills/themelia-ui/references/troubleshooting.md +88 -30
  18. package/.agents/skills/themelia-ui/references/verification.md +60 -5
  19. package/CHANGELOG.md +212 -0
  20. package/README.md +48 -60
  21. package/dist/accordion-CHuzMmWL.js +143 -0
  22. package/dist/{action-menu-BNLURfMK.js → action-menu-BwiL_F6I.js} +35 -33
  23. package/dist/{alert-dialog-BMVo6Z-8.js → alert-dialog-Cg2HhuBe.js} +1 -1
  24. package/dist/avatar-Dc_BNYfB.js +93 -0
  25. package/dist/badge-VlJVZjdm.js +45 -0
  26. package/dist/base/accordion.js +1 -1
  27. package/dist/base/action-menu.js +1 -1
  28. package/dist/base/alert-dialog.js +1 -1
  29. package/dist/base/aspect-ratio.js +3 -1
  30. package/dist/base/avatar.js +1 -1
  31. package/dist/base/badge.js +2 -2
  32. package/dist/base/batch-action-bar.js +1 -1
  33. package/dist/base/buttons.js +1 -1
  34. package/dist/base/cards.js +1 -1
  35. package/dist/base/carousel.js +6 -4
  36. package/dist/base/chart.js +1 -1
  37. package/dist/base/choice-inputs.js +1 -1
  38. package/dist/base/combobox.js +1 -1
  39. package/dist/base/command.js +1 -1
  40. package/dist/base/context-menu.js +22 -21
  41. package/dist/base/copyable.js +1 -1
  42. package/dist/base/date-pickers.js +1 -1
  43. package/dist/base/dialog.js +1 -1
  44. package/dist/base/display.js +1 -1
  45. package/dist/base/dropdown-menu.js +1 -1
  46. package/dist/base/feedback.js +1 -1
  47. package/dist/base/forms-numeric.js +1 -1
  48. package/dist/base/forms.js +1 -1
  49. package/dist/base/hover-card.js +26 -23
  50. package/dist/base/input-group.js +1 -1
  51. package/dist/base/item.js +1 -1
  52. package/dist/base/label.js +1 -1
  53. package/dist/base/menubar.js +20 -14
  54. package/dist/base/navigation-menu.js +47 -38
  55. package/dist/base/navigation.js +1 -1
  56. package/dist/base/otp-input.js +36 -30
  57. package/dist/base/overlay.js +1 -1
  58. package/dist/base/popover-menu.js +1 -1
  59. package/dist/base/popover.js +1 -1
  60. package/dist/base/qr-code.js +51 -47
  61. package/dist/base/repeaters.js +1 -1
  62. package/dist/base/resizable.js +2 -0
  63. package/dist/base/sheet.js +1 -1
  64. package/dist/base/sidebar.js +1 -1
  65. package/dist/base/skeleton.js +1 -1
  66. package/dist/base/spinner.js +1 -1
  67. package/dist/base/structure.js +1 -1
  68. package/dist/base/table.js +1 -1
  69. package/dist/base/text-inputs.js +1 -1
  70. package/dist/base/timeline.js +1 -1
  71. package/dist/base/toaster.js +1 -1
  72. package/dist/base/toggle.js +21 -15
  73. package/dist/base/toolbar.js +1 -1
  74. package/dist/base/tooltip.js +1 -1
  75. package/dist/base/typography.js +2 -2
  76. package/dist/base/upload.js +1 -1
  77. package/dist/base/value-inputs.js +1 -1
  78. package/dist/{batch-action-bar-BZYNKXdV.js → batch-action-bar-DZVMVW83.js} +11 -8
  79. package/dist/{admin/patterns → blocks/admin}/access.js +79 -76
  80. package/dist/blocks/admin/commerce.js +2493 -0
  81. package/dist/{patterns → blocks}/analytics.js +312 -303
  82. package/dist/{patterns → blocks}/onboarding.js +27 -23
  83. package/dist/{patterns → blocks}/timelines.js +1 -1
  84. package/dist/buttons-BX2JfL5X.js +173 -0
  85. package/dist/cards-Ddhz43Bz.js +279 -0
  86. package/dist/chart-BkK3Xm10.js +201 -0
  87. package/dist/choice-inputs-NwRxvmZN.js +694 -0
  88. package/dist/combobox-519ubijc.js +292 -0
  89. package/dist/command-JjApYFds.js +156 -0
  90. package/dist/comments-CCQ2QRaU.js +1443 -0
  91. package/dist/components/base/action-menu/action-menu.d.ts +1 -1
  92. package/dist/components/base/action-menu/action-menu.types.d.ts +2 -2
  93. package/dist/components/base/avatar/avatar.d.ts +5 -2
  94. package/dist/components/base/badge/badge.d.ts +10 -10
  95. package/dist/components/base/badge/badge.variants.d.ts +1 -2
  96. package/dist/components/base/badge/index.d.ts +1 -2
  97. package/dist/components/base/buttons/button.d.ts +9 -8
  98. package/dist/components/base/buttons/button.types.d.ts +2 -2
  99. package/dist/components/base/buttons/index.d.ts +1 -1
  100. package/dist/components/base/buttons/text-button.d.ts +1 -1
  101. package/dist/components/base/cards/card-actions.d.ts +1 -1
  102. package/dist/components/base/cards/card.d.ts +3 -1
  103. package/dist/components/base/cards/partials/card-header.d.ts +2 -1
  104. package/dist/components/base/choice-inputs/choice.types.d.ts +2 -2
  105. package/dist/components/base/choice-inputs/partials/choice-parts.d.ts +3 -3
  106. package/dist/components/base/command/command.d.ts +5 -2
  107. package/dist/components/base/display/icon-badge.d.ts +5 -3
  108. package/dist/components/base/display/index.d.ts +1 -1
  109. package/dist/components/base/display/metadata-list.d.ts +6 -6
  110. package/dist/components/base/display/metadata-value.d.ts +1 -1
  111. package/dist/components/base/display/separator.d.ts +2 -2
  112. package/dist/components/base/feedback/alert.d.ts +3 -2
  113. package/dist/components/base/feedback/empty.d.ts +5 -4
  114. package/dist/components/base/feedback/progress-circle.d.ts +2 -2
  115. package/dist/components/base/feedback/progress.d.ts +3 -1
  116. package/dist/components/base/forms/form-field.d.ts +2 -2
  117. package/dist/components/base/input-group/input-group.d.ts +8 -10
  118. package/dist/components/base/item/item.d.ts +2 -2
  119. package/dist/components/base/overlay/index.d.ts +1 -1
  120. package/dist/components/base/overlay/overlay.types.d.ts +7 -5
  121. package/dist/components/base/qr-code/qr-code.d.ts +4 -4
  122. package/dist/components/base/sheet/sheet.d.ts +1 -1
  123. package/dist/components/base/sidebar/sidebar.d.ts +9 -13
  124. package/dist/components/base/spinner/spinner.d.ts +2 -2
  125. package/dist/components/base/structure/adaptive-grid.d.ts +3 -3
  126. package/dist/components/base/structure/bleed.d.ts +4 -2
  127. package/dist/components/base/structure/grid.d.ts +10 -4
  128. package/dist/components/base/structure/index.d.ts +1 -1
  129. package/dist/components/base/structure/split.d.ts +4 -3
  130. package/dist/components/base/structure/stack.d.ts +5 -5
  131. package/dist/components/base/structure/structure.maps.d.ts +2 -1
  132. package/dist/components/base/structure/structure.types.d.ts +10 -4
  133. package/dist/components/base/toggle/toggle.d.ts +2 -2
  134. package/dist/components/base/toolbar/toolbar.d.ts +3 -3
  135. package/dist/components/base/typography/index.d.ts +2 -0
  136. package/dist/components/base/typography/rich-text/rich-text.variants.d.ts +9 -0
  137. package/dist/components/base/typography/text/index.d.ts +1 -0
  138. package/dist/components/base/typography/text/text.d.ts +15 -8
  139. package/dist/components/base/typography/text/text.variants.d.ts +41 -0
  140. package/dist/components/base/value-inputs/color-input.d.ts +1 -7
  141. package/dist/components/base/value-inputs/slider.d.ts +2 -7
  142. package/dist/components/{admin/patterns → blocks/admin}/commerce/vendor-profile.d.ts +2 -1
  143. package/dist/components/{patterns → blocks}/analytics/analytics.strings.d.ts +2 -5
  144. package/dist/components/features/actions/action-adapters.d.ts +3 -3
  145. package/dist/components/features/actions/actions.types.d.ts +3 -5
  146. package/dist/components/features/actions/index.d.ts +1 -1
  147. package/dist/components/features/activities/activities-feed.d.ts +1 -1
  148. package/dist/components/features/activities/activities.types.d.ts +4 -4
  149. package/dist/components/features/activities/activity-parts.d.ts +3 -3
  150. package/dist/components/features/activities/activity-row.d.ts +4 -4
  151. package/dist/components/features/activities/index.d.ts +1 -1
  152. package/dist/components/features/ai-chat/ai-chat.types.d.ts +10 -3
  153. package/dist/components/features/ai-chat/ai-message-surfaces.d.ts +1 -1
  154. package/dist/components/features/ai-chat/ai-work-surfaces.d.ts +1 -1
  155. package/dist/components/features/combobox/combobox.strings.d.ts +2 -2
  156. package/dist/components/features/combobox/fetching-combobox.d.ts +2 -1
  157. package/dist/components/features/combobox/resource-combobox.d.ts +3 -0
  158. package/dist/components/features/combobox/use-suggestions.d.ts +7 -0
  159. package/dist/components/features/event-calendar/event-calendar.types.d.ts +3 -0
  160. package/dist/components/features/media-library/index.d.ts +1 -1
  161. package/dist/components/features/media-library/media-library-parts.d.ts +4 -3
  162. package/dist/components/features/media-library/media-library-views.d.ts +4 -3
  163. package/dist/components/features/media-library/media-library.d.ts +1 -1
  164. package/dist/components/features/media-library/media-library.strings.d.ts +12 -13
  165. package/dist/components/features/media-library/media-library.types.d.ts +11 -9
  166. package/dist/components/features/media-library/media-resource-gallery.d.ts +1 -1
  167. package/dist/components/features/media-library/use-media-library.d.ts +1 -4
  168. package/dist/components/features/overlays/action-overlay-frame.d.ts +1 -1
  169. package/dist/components/features/overlays/index.d.ts +1 -1
  170. package/dist/components/features/overlays/overlay-parts.d.ts +3 -3
  171. package/dist/components/features/overlays/overlays.types.d.ts +8 -7
  172. package/dist/components/features/rich-text-editor/index.d.ts +0 -1
  173. package/dist/components/features/table/data-table-body.d.ts +1 -1
  174. package/dist/components/features/table/data-table-expanded-row.d.ts +27 -0
  175. package/dist/components/features/table/data-table-header.d.ts +1 -1
  176. package/dist/components/features/table/data-table-size.d.ts +1 -1
  177. package/dist/components/features/table/data-table.d.ts +1 -1
  178. package/dist/components/features/table/index.d.ts +1 -1
  179. package/dist/components/features/table/table-helpers.d.ts +9 -3
  180. package/dist/components/features/table/table.strings.d.ts +11 -0
  181. package/dist/components/features/table/table.types.d.ts +60 -2
  182. package/dist/components/features/theme-tweaker/index.d.ts +1 -1
  183. package/dist/components/features/theme-tweaker/theme-tweaker.strings.d.ts +1 -1
  184. package/dist/components/features/theme-tweaker/theme-tweaker.types.d.ts +6 -10
  185. package/dist/components/features/theme-tweaker/theme-tweaker.utils.d.ts +22 -6
  186. package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +1 -1
  187. package/dist/components/layout/auth/auth.d.ts +1 -1
  188. package/dist/components/layout/auth/auth.types.d.ts +1 -1
  189. package/dist/components/primitives/value.d.ts +3 -1
  190. package/dist/containers-B8d8U9GS.js +2 -0
  191. package/dist/{copyable-H1TUEY-H.js → copyable-D9Okb1w6.js} +12 -11
  192. package/dist/core.css +2 -2
  193. package/dist/css/access.css +2 -1
  194. package/dist/css/accordion.css +2 -1
  195. package/dist/css/action-menu.css +2 -1
  196. package/dist/css/activities.css +2 -1
  197. package/dist/css/ai-chat.css +2 -1
  198. package/dist/css/analytics.css +2 -1
  199. package/dist/css/app-shell.css +2 -1
  200. package/dist/css/aspect-ratio.css +2 -1
  201. package/dist/css/async-preview.css +2 -1
  202. package/dist/css/auth.css +2 -1
  203. package/dist/css/avatar.css +2 -1
  204. package/dist/css/badge.css +2 -1
  205. package/dist/css/batch-action-bar.css +2 -1
  206. package/dist/css/buttons.css +2 -1
  207. package/dist/css/cards.css +2 -1
  208. package/dist/css/carousel.css +2 -1
  209. package/dist/css/chart.css +2 -1
  210. package/dist/css/choice-inputs.css +2 -1
  211. package/dist/css/combobox.css +2 -1
  212. package/dist/css/combobox2.css +2 -1
  213. package/dist/css/command.css +2 -1
  214. package/dist/css/comments.css +2 -1
  215. package/dist/css/commerce.css +2 -1
  216. package/dist/css/containers.css +2 -1
  217. package/dist/css/copyable.css +2 -1
  218. package/dist/css/data-view.css +2 -1
  219. package/dist/css/date-pickers.css +2 -1
  220. package/dist/css/display.css +2 -1
  221. package/dist/css/dropdown-menu.css +2 -1
  222. package/dist/css/event-calendar.css +2 -1
  223. package/dist/css/feedback.css +2 -1
  224. package/dist/css/filters.css +2 -1
  225. package/dist/css/forms-numeric.css +2 -1
  226. package/dist/css/forms.css +2 -1
  227. package/dist/css/global-search.css +2 -1
  228. package/dist/css/header.css +2 -1
  229. package/dist/css/hover-card.css +2 -1
  230. package/dist/css/input-group.css +2 -1
  231. package/dist/css/item.css +2 -1
  232. package/dist/css/kanban.css +2 -1
  233. package/dist/css/label.css +2 -1
  234. package/dist/css/map.css +2 -1
  235. package/dist/css/media-library.css +2 -1
  236. package/dist/css/mentions.css +2 -1
  237. package/dist/css/menubar.css +2 -1
  238. package/dist/css/navigation-menu.css +2 -1
  239. package/dist/css/navigation.css +2 -1
  240. package/dist/css/navigation2.css +2 -1
  241. package/dist/css/onboarding.css +2 -1
  242. package/dist/css/otp-input.css +2 -1
  243. package/dist/css/overlay.css +2 -1
  244. package/dist/css/overlays.css +2 -1
  245. package/dist/css/page.css +2 -1
  246. package/dist/css/popover-menu.css +2 -1
  247. package/dist/css/popover.css +2 -1
  248. package/dist/css/primitives.css +2 -1
  249. package/dist/css/products.css +2 -1
  250. package/dist/css/qr-code.css +2 -1
  251. package/dist/css/repeaters.css +2 -1
  252. package/dist/css/resizable.css +2 -1
  253. package/dist/css/resource-assignment.css +2 -1
  254. package/dist/css/resource.css +2 -1
  255. package/dist/css/rich-text-editor.css +2 -1
  256. package/dist/css/schema-form.css +2 -1
  257. package/dist/css/sidebar.css +2 -1
  258. package/dist/css/sidebar2.css +2 -1
  259. package/dist/css/skeleton.css +2 -1
  260. package/dist/css/spinner.css +2 -1
  261. package/dist/css/structure.css +2 -1
  262. package/dist/css/sync.css +2 -1
  263. package/dist/css/table.css +2 -1
  264. package/dist/css/table2.css +2 -1
  265. package/dist/css/text-inputs.css +2 -1
  266. package/dist/css/theme-tweaker.css +2 -1
  267. package/dist/css/timeline.css +2 -1
  268. package/dist/css/timelines.css +2 -1
  269. package/dist/css/toaster.css +2 -1
  270. package/dist/css/toggle.css +2 -1
  271. package/dist/css/toolbar.css +2 -1
  272. package/dist/css/tooltip.css +2 -1
  273. package/dist/css/typography.css +2 -1
  274. package/dist/css/upload.css +2 -1
  275. package/dist/css/value-inputs.css +2 -1
  276. package/dist/css/workspace.css +2 -1
  277. package/dist/css-graph.json +1027 -0
  278. package/dist/date-pickers-BwCwKIVM.js +685 -0
  279. package/dist/{dialog-CtFCuTUF.js → dialog-CAnwRNrm.js} +1 -1
  280. package/dist/display-a7AoX_u7.js +664 -0
  281. package/dist/dropdown-menu-Br8kvjrF.js +235 -0
  282. package/dist/empty.js +0 -0
  283. package/dist/features/actions.js +6 -6
  284. package/dist/features/activities.js +219 -216
  285. package/dist/features/ai-chat.js +593 -565
  286. package/dist/features/async-preview.js +105 -286
  287. package/dist/features/combobox.js +328 -314
  288. package/dist/features/comments.js +1 -1
  289. package/dist/features/data-view.js +56 -55
  290. package/dist/features/event-calendar.js +189 -185
  291. package/dist/features/filters.js +1 -1
  292. package/dist/features/global-search.js +259 -260
  293. package/dist/features/kanban.js +39 -37
  294. package/dist/features/map.js +357 -354
  295. package/dist/features/media-library.js +931 -931
  296. package/dist/features/mentions.js +1 -1
  297. package/dist/features/overlays.js +1 -1
  298. package/dist/features/products.js +950 -942
  299. package/dist/features/resource-assignment.js +39 -37
  300. package/dist/features/resource.js +70 -71
  301. package/dist/features/rich-text-editor.js +2 -2
  302. package/dist/features/schema-form.js +342 -338
  303. package/dist/features/sync.js +14 -12
  304. package/dist/features/table.js +1 -1
  305. package/dist/features/theme-tweaker.js +1002 -962
  306. package/dist/feedback-D4qVsKlD.js +430 -0
  307. package/dist/{filters-DOLKRSmb.js → filters-BhsTkWpZ.js} +386 -383
  308. package/dist/forms-C0WeNPFF.js +250 -0
  309. package/dist/forms-numeric-IwQ1ltNf.js +582 -0
  310. package/dist/hooks/use-native-dialog.d.ts +1 -1
  311. package/dist/index.js +2 -2
  312. package/dist/input-group-HS_Z0Ei_.js +119 -0
  313. package/dist/item-M2pmpWXh.js +150 -0
  314. package/dist/{label-DumoMDm6.js → label-HOBXAscw.js} +7 -5
  315. package/dist/layout/app-shell.js +4 -2
  316. package/dist/layout/auth.js +102 -100
  317. package/dist/layout/header.js +190 -180
  318. package/dist/layout/navigation.js +1 -1
  319. package/dist/layout/page.js +18 -16
  320. package/dist/layout/settings.js +2 -2
  321. package/dist/layout/sidebar.js +50 -46
  322. package/dist/layout/workspace.js +71 -69
  323. package/dist/lib/action-presentation.d.ts +3 -3
  324. package/dist/lib/component-vocabulary.d.ts +2 -2
  325. package/dist/lib/css-length.d.ts +2 -0
  326. package/dist/lib/responsive.d.ts +1 -1
  327. package/dist/lib/theming/index.d.ts +1 -0
  328. package/dist/lib/theming/recipes.d.ts +2 -2
  329. package/dist/lib/theming/themes/dense.d.ts +3 -0
  330. package/dist/lib/theming/themes/editorial.d.ts +3 -0
  331. package/dist/lib/theming/themes/index.d.ts +8 -0
  332. package/dist/lib/theming/themes/pair.d.ts +7 -0
  333. package/dist/lib/theming/themes/sharp.d.ts +3 -0
  334. package/dist/lib/theming/themes/soft.d.ts +3 -0
  335. package/dist/lib/theming/themes/types.d.ts +12 -0
  336. package/dist/lib/ui-provider/index.d.ts +1 -1
  337. package/dist/lib/ui-provider/scope.d.ts +5 -8
  338. package/dist/lib/ui-provider/tokens.d.ts +11 -3
  339. package/dist/lib/ui-provider/tokens.generated.d.ts +6 -4
  340. package/dist/lib/ui-provider/types.d.ts +17 -19
  341. package/dist/lib/ui-provider/ui-scope.d.ts +1 -1
  342. package/dist/{mentions-BbsEHlcH.js → mentions-BOxbigwp.js} +113 -111
  343. package/dist/navigation-Bgu7Vc0M.js +622 -0
  344. package/dist/navigation-DiYACqpE.js +216 -0
  345. package/dist/overlay-BuQOl8aP.js +356 -0
  346. package/dist/{overlays-DvVoS3td.js → overlays-1sULyytH.js} +77 -75
  347. package/dist/popover-CA7SP_iz.js +127 -0
  348. package/dist/popover-menu-QXgQeWeG.js +192 -0
  349. package/dist/{primitives-D0bdDozz.js → primitives-BskKlf35.js} +181 -178
  350. package/dist/primitives.js +1 -1
  351. package/dist/profiles/admin.json +6 -36
  352. package/dist/profiles/general.json +6 -96
  353. package/dist/repeaters-CeH20dvr.js +445 -0
  354. package/dist/rich-text-editor-D_Ppm8yh.js +491 -0
  355. package/dist/{sheet-CKcmRbJ9.js → sheet-CJ1-OAla.js} +3 -3
  356. package/dist/sidebar-D8uGqxio.js +421 -0
  357. package/dist/skeleton-BTKNKTdj.js +173 -0
  358. package/dist/spinner-Tc1QCnxM.js +30 -0
  359. package/dist/{structure-D0WGQAP3.js → structure-CynEZ-OY.js} +15 -23
  360. package/dist/style.css +1 -1
  361. package/dist/styles/TOKENS.md +116 -275
  362. package/dist/styles/animation.css +114 -0
  363. package/dist/styles/base.css +7 -6
  364. package/dist/styles/fields.css +45 -63
  365. package/dist/styles/focus.css +12 -0
  366. package/dist/styles/forced-colors.css +11 -10
  367. package/dist/styles/index.css +23 -30
  368. package/dist/styles/map.css +45 -34
  369. package/dist/styles/mentions.css +14 -52
  370. package/dist/styles/overlays.css +7 -7
  371. package/dist/styles/tailwind.css +76 -127
  372. package/dist/styles/targets.css +3 -3
  373. package/dist/styles/theme/colour.css +86 -0
  374. package/dist/styles/theme/density.css +31 -0
  375. package/dist/styles/theme/elevation.css +9 -0
  376. package/dist/styles/theme/layout.css +18 -0
  377. package/dist/styles/theme/motion.css +18 -0
  378. package/dist/styles/theme/shape.css +12 -0
  379. package/dist/styles/theme/size.css +10 -0
  380. package/dist/styles/theme/spacing.css +11 -0
  381. package/dist/styles/theme/typography.css +20 -0
  382. package/dist/styles/tone.css +61 -0
  383. package/dist/table-B7dtIFUx.js +1262 -0
  384. package/dist/table-Ds_eO9av.js +191 -0
  385. package/dist/tailwind.css +76 -127
  386. package/dist/text-inputs-BboE77nZ.js +395 -0
  387. package/dist/theming-C5ygF5uf.js +292 -0
  388. package/dist/theming.js +2 -2
  389. package/dist/{timeline-BdaGRyj-.js → timeline-BR_jNgvz.js} +57 -49
  390. package/dist/{timelines-BB7550mz.js → timelines-DXG1BfIN.js} +69 -67
  391. package/dist/{toaster-bBMgXm8z.js → toaster-CXL8L7Mm.js} +106 -99
  392. package/dist/tokens.json +1027 -636
  393. package/dist/toolbar-DBK-c4yy.js +74 -0
  394. package/dist/tooltip-BPYP-jUm.js +76 -0
  395. package/dist/{typography-BkxEiwQ1.js → typography-DmeR05Er.js} +87 -53
  396. package/dist/{ui-provider-Cmoq6i_D.js → ui-provider-DpzLUD12.js} +117 -69
  397. package/dist/ui-provider.js +1 -1
  398. package/dist/upload-CYuoJykZ.js +968 -0
  399. package/dist/use-async-preview-BFwf9ElY.js +188 -0
  400. package/dist/value-inputs-ng8aVJJZ.js +728 -0
  401. package/docs/README.md +13 -3
  402. package/docs/build/browser-composition-fixture.ts +28 -0
  403. package/docs/build/recipes.md +11484 -10723
  404. package/docs/generated/component-index.json +9809 -9169
  405. package/docs/generated/components/INDEX.md +5 -5
  406. package/docs/generated/components/base--accordion.md +51 -2
  407. package/docs/generated/components/base--action-menu.md +14 -15
  408. package/docs/generated/components/base--alert-dialog.md +3 -4
  409. package/docs/generated/components/base--aspect-ratio.md +3 -4
  410. package/docs/generated/components/base--avatar.md +7 -7
  411. package/docs/generated/components/base--badge.md +159 -27
  412. package/docs/generated/components/base--batch-action-bar.md +6 -7
  413. package/docs/generated/components/base--buttons.md +151 -47
  414. package/docs/generated/components/base--cards.md +107 -14
  415. package/docs/generated/components/base--carousel.md +1 -2
  416. package/docs/generated/components/base--chart.md +44 -8
  417. package/docs/generated/components/base--choice-inputs.md +10 -11
  418. package/docs/generated/components/base--combobox.md +3 -4
  419. package/docs/generated/components/base--command.md +6 -6
  420. package/docs/generated/components/base--context-menu.md +1 -2
  421. package/docs/generated/components/base--copyable.md +6 -7
  422. package/docs/generated/components/base--date-pickers.md +6 -7
  423. package/docs/generated/components/base--dialog.md +6 -7
  424. package/docs/generated/components/base--direction.md +1 -1
  425. package/docs/generated/components/base--display.md +234 -54
  426. package/docs/generated/components/base--dropdown-menu.md +6 -7
  427. package/docs/generated/components/base--feedback.md +71 -18
  428. package/docs/generated/components/base--forms-numeric.md +6 -7
  429. package/docs/generated/components/base--forms.md +84 -14
  430. package/docs/generated/components/base--hover-card.md +3 -4
  431. package/docs/generated/components/base--input-group.md +27 -30
  432. package/docs/generated/components/base--item.md +8 -9
  433. package/docs/generated/components/base--label.md +2 -3
  434. package/docs/generated/components/base--menubar.md +2 -4
  435. package/docs/generated/components/base--navigation-menu.md +2 -3
  436. package/docs/generated/components/base--navigation.md +2 -3
  437. package/docs/generated/components/base--otp-input.md +3 -4
  438. package/docs/generated/components/base--overlay.md +56 -47
  439. package/docs/generated/components/base--popover-menu.md +7 -8
  440. package/docs/generated/components/base--popover.md +9 -10
  441. package/docs/generated/components/base--qr-code.md +7 -8
  442. package/docs/generated/components/base--repeaters.md +6 -7
  443. package/docs/generated/components/base--resizable.md +2 -3
  444. package/docs/generated/components/base--sheet.md +12 -13
  445. package/docs/generated/components/base--sidebar.md +9 -11
  446. package/docs/generated/components/base--skeleton.md +6 -7
  447. package/docs/generated/components/base--slot.md +1 -1
  448. package/docs/generated/components/base--spinner.md +5 -7
  449. package/docs/generated/components/base--structure.md +320 -70
  450. package/docs/generated/components/base--table.md +61 -3
  451. package/docs/generated/components/base--text-inputs.md +17 -18
  452. package/docs/generated/components/base--timeline.md +45 -4
  453. package/docs/generated/components/base--toaster.md +43 -12
  454. package/docs/generated/components/base--toggle.md +11 -12
  455. package/docs/generated/components/base--toolbar.md +7 -8
  456. package/docs/generated/components/base--tooltip.md +5 -6
  457. package/docs/generated/components/base--typography.md +317 -32
  458. package/docs/generated/components/base--upload.md +8 -9
  459. package/docs/generated/components/base--value-inputs.md +9 -38
  460. package/docs/generated/components/{admin--patterns--access.md → blocks--admin--access.md} +15 -6
  461. package/docs/generated/components/{admin--patterns--commerce.md → blocks--admin--commerce.md} +40 -41
  462. package/docs/generated/components/{patterns--analytics.md → blocks--analytics.md} +57 -14
  463. package/docs/generated/components/{patterns--onboarding.md → blocks--onboarding.md} +6 -7
  464. package/docs/generated/components/{patterns--timelines.md → blocks--timelines.md} +6 -7
  465. package/docs/generated/components/features--actions.md +8 -18
  466. package/docs/generated/components/features--activities.md +31 -32
  467. package/docs/generated/components/features--ai-chat.md +15 -15
  468. package/docs/generated/components/features--async-preview.md +5 -6
  469. package/docs/generated/components/features--combobox.md +71 -5
  470. package/docs/generated/components/features--comments.md +0 -1
  471. package/docs/generated/components/features--data-view.md +63 -8
  472. package/docs/generated/components/features--event-calendar.md +1 -2
  473. package/docs/generated/components/features--filters.md +11 -2
  474. package/docs/generated/components/features--global-search.md +1 -2
  475. package/docs/generated/components/features--kanban.md +1 -2
  476. package/docs/generated/components/features--map.md +1 -2
  477. package/docs/generated/components/features--media-library.md +105 -38
  478. package/docs/generated/components/features--mentions.md +7 -7
  479. package/docs/generated/components/features--overlays.md +75 -22
  480. package/docs/generated/components/features--products.md +10 -11
  481. package/docs/generated/components/features--resource-assignment.md +2 -3
  482. package/docs/generated/components/features--resource.md +3 -4
  483. package/docs/generated/components/features--rich-text-editor.md +42 -13
  484. package/docs/generated/components/features--schema-form.md +1 -2
  485. package/docs/generated/components/features--sync.md +2 -3
  486. package/docs/generated/components/features--table.md +162 -12
  487. package/docs/generated/components/features--theme-tweaker.md +30 -15
  488. package/docs/generated/components/forms.md +2 -2
  489. package/docs/generated/components/layout--app-shell.md +41 -11
  490. package/docs/generated/components/layout--auth.md +8 -9
  491. package/docs/generated/components/layout--containers.md +40 -1
  492. package/docs/generated/components/layout--header.md +2 -3
  493. package/docs/generated/components/layout--navigation.md +0 -1
  494. package/docs/generated/components/layout--page.md +33 -5
  495. package/docs/generated/components/layout--settings.md +0 -1
  496. package/docs/generated/components/layout--sidebar.md +47 -7
  497. package/docs/generated/components/layout--workspace.md +3 -4
  498. package/docs/generated/components/primitives.md +128 -17
  499. package/docs/generated/components/theming.md +147 -4
  500. package/docs/generated/components/ui-provider.md +96 -78
  501. package/docs/generated/composition-ladder.md +8 -8
  502. package/docs/generated/consumer-contract.json +5736 -0
  503. package/docs/generated/imports.md +104 -104
  504. package/docs/generated/migration-broad-imports.json +267 -90
  505. package/docs/generated/migration-broad-imports.md +266 -101
  506. package/docs/generated/migration-codemod.json +365 -70
  507. package/docs/generated/migration.md +665 -95
  508. package/docs/generated/profiles.md +27 -27
  509. package/docs/generated/public-api.md +104 -102
  510. package/docs/generated/recipes.json +755 -810
  511. package/docs/generated/workflows/communications-overview/analytics/communications-reference.tsx +19 -0
  512. package/docs/generated/workflows/index.json +691 -0
  513. package/docs/generated/workflows/media-picking/media-library/media-picking-reference.tsx +63 -0
  514. package/docs/generated/workflows/media-picking/media-library/reference-data.ts +3 -0
  515. package/docs/generated/workflows/multi-section-form/form-workflow/multi-section-reference.tsx +46 -0
  516. package/docs/generated/workflows/nested-action-flow/action-overlays/nested-action-reference.tsx +39 -0
  517. package/docs/generated/workflows/record-detail/page-layout/record-detail-reference.tsx +24 -0
  518. package/docs/generated/workflows/resource-index/data-view/resource-index-reference.tsx +51 -0
  519. package/docs/generated/workflows/scoped-resource-selection/combobox/scoped-resource-reference.tsx +50 -0
  520. package/docs/generated/workflows/website-content-editor/media-library/reference-data.ts +3 -0
  521. package/docs/generated/workflows/website-content-editor/rich-text-editor/website-content-reference.tsx +33 -0
  522. package/docs/generated/workflows/workspace-navigation/app-shell/workspace-navigation-reference.tsx +26 -0
  523. package/docs/learn/api-compatibility.md +5 -4
  524. package/docs/learn/blocks.md +123 -0
  525. package/docs/learn/composition.md +100 -19
  526. package/docs/learn/forms.md +23 -3
  527. package/docs/learn/framework-wiring.md +41 -13
  528. package/docs/learn/i18n.md +4 -2
  529. package/docs/learn/installation.md +60 -31
  530. package/docs/learn/migration.md +156 -5
  531. package/docs/learn/provider-and-scoping.md +37 -25
  532. package/docs/learn/reference-workflows.md +43 -0
  533. package/docs/learn/structure-and-spacing.md +147 -0
  534. package/docs/learn/theming.md +174 -131
  535. package/docs/learn/troubleshooting.md +88 -30
  536. package/docs/learn/verification.md +60 -5
  537. package/package.json +42 -473
  538. package/scripts/consumer/codemod.mjs +50 -32
  539. package/scripts/consumer/contract-reader.mjs +42 -0
  540. package/scripts/consumer/css-scan.mjs +51 -0
  541. package/scripts/consumer/diagnose.mjs +136 -0
  542. package/scripts/consumer/find-component.mjs +30 -17
  543. package/scripts/consumer/install-skill.mjs +93 -11
  544. package/src/styles/TOKENS.md +116 -275
  545. package/dist/accordion-6YPJ9XRO.js +0 -135
  546. package/dist/admin/patterns/access.css +0 -15
  547. package/dist/admin/patterns/commerce.css +0 -29
  548. package/dist/admin/patterns/commerce.js +0 -2493
  549. package/dist/avatar-CS7zow2q.js +0 -85
  550. package/dist/badge-CxOuTfVr.js +0 -63
  551. package/dist/base/accordion.css +0 -3
  552. package/dist/base/action-menu.css +0 -6
  553. package/dist/base/alert-dialog.css +0 -4
  554. package/dist/base/aspect-ratio.css +0 -2
  555. package/dist/base/avatar.css +0 -4
  556. package/dist/base/badge.css +0 -2
  557. package/dist/base/batch-action-bar.css +0 -5
  558. package/dist/base/buttons.css +0 -4
  559. package/dist/base/cards.css +0 -13
  560. package/dist/base/carousel.css +0 -5
  561. package/dist/base/chart.css +0 -2
  562. package/dist/base/choice-inputs.css +0 -10
  563. package/dist/base/combobox.css +0 -3
  564. package/dist/base/command.css +0 -9
  565. package/dist/base/context-menu.css +0 -2
  566. package/dist/base/copyable.css +0 -6
  567. package/dist/base/date-pickers.css +0 -11
  568. package/dist/base/dialog.css +0 -4
  569. package/dist/base/display.css +0 -8
  570. package/dist/base/dropdown-menu.css +0 -2
  571. package/dist/base/feedback.css +0 -5
  572. package/dist/base/forms-numeric.css +0 -12
  573. package/dist/base/forms.css +0 -14
  574. package/dist/base/hover-card.css +0 -2
  575. package/dist/base/input-group.css +0 -6
  576. package/dist/base/item.css +0 -9
  577. package/dist/base/label.css +0 -3
  578. package/dist/base/menubar.css +0 -2
  579. package/dist/base/navigation-menu.css +0 -2
  580. package/dist/base/navigation.css +0 -12
  581. package/dist/base/otp-input.css +0 -9
  582. package/dist/base/overlay.css +0 -4
  583. package/dist/base/popover-menu.css +0 -11
  584. package/dist/base/popover.css +0 -3
  585. package/dist/base/qr-code.css +0 -2
  586. package/dist/base/repeaters.css +0 -18
  587. package/dist/base/resizable.css +0 -2
  588. package/dist/base/sheet.css +0 -4
  589. package/dist/base/sidebar.css +0 -12
  590. package/dist/base/skeleton.css +0 -9
  591. package/dist/base/spinner.css +0 -2
  592. package/dist/base/structure.css +0 -2
  593. package/dist/base/table.css +0 -3
  594. package/dist/base/text-inputs.css +0 -2
  595. package/dist/base/timeline.css +0 -9
  596. package/dist/base/toaster.css +0 -2
  597. package/dist/base/toggle.css +0 -2
  598. package/dist/base/toolbar.css +0 -5
  599. package/dist/base/tooltip.css +0 -2
  600. package/dist/base/typography.css +0 -2
  601. package/dist/base/upload.css +0 -10
  602. package/dist/base/value-inputs.css +0 -14
  603. package/dist/buttons-CqXKWty3.js +0 -179
  604. package/dist/cards-C6Ulbkw7.js +0 -271
  605. package/dist/chart-nomhJ87z.js +0 -193
  606. package/dist/choice-inputs-OUDn0kQw.js +0 -680
  607. package/dist/combobox-C8oP92bT.js +0 -266
  608. package/dist/command-Bp3B6pUu.js +0 -143
  609. package/dist/comments-CAnDlyXO.js +0 -1438
  610. package/dist/components/admin/patterns/index.d.ts +0 -2
  611. package/dist/components/features/rich-text-editor/exec-command-engine.d.ts +0 -2
  612. package/dist/components/patterns/index.d.ts +0 -3
  613. package/dist/css/styles.css +0 -1
  614. package/dist/date-pickers-DOwIT-Nk.js +0 -661
  615. package/dist/display-B3Q17h5z.js +0 -645
  616. package/dist/dropdown-menu-TyNLCLML.js +0 -223
  617. package/dist/features/actions.css +0 -11
  618. package/dist/features/activities.css +0 -25
  619. package/dist/features/ai-chat.css +0 -14
  620. package/dist/features/async-preview.css +0 -10
  621. package/dist/features/combobox.css +0 -12
  622. package/dist/features/comments.css +0 -24
  623. package/dist/features/data-view.css +0 -31
  624. package/dist/features/event-calendar.css +0 -17
  625. package/dist/features/filters.css +0 -24
  626. package/dist/features/global-search.css +0 -19
  627. package/dist/features/kanban.css +0 -7
  628. package/dist/features/map.css +0 -15
  629. package/dist/features/media-library.css +0 -27
  630. package/dist/features/mentions.css +0 -17
  631. package/dist/features/overlays.css +0 -11
  632. package/dist/features/products.css +0 -29
  633. package/dist/features/resource-assignment.css +0 -14
  634. package/dist/features/resource.css +0 -15
  635. package/dist/features/rich-text-editor.css +0 -8
  636. package/dist/features/schema-form.css +0 -22
  637. package/dist/features/sync.css +0 -11
  638. package/dist/features/table.css +0 -20
  639. package/dist/features/theme-tweaker.css +0 -27
  640. package/dist/feedback-DRerHGuV.js +0 -469
  641. package/dist/forms-CPrGGif_.js +0 -242
  642. package/dist/forms-numeric-CPVsL7Vf.js +0 -569
  643. package/dist/index.css +0 -3
  644. package/dist/input-group-BYe0rhoB.js +0 -126
  645. package/dist/item-B3yQ26as.js +0 -146
  646. package/dist/layout/app-shell.css +0 -13
  647. package/dist/layout/auth.css +0 -14
  648. package/dist/layout/containers.css +0 -2
  649. package/dist/layout/header.css +0 -20
  650. package/dist/layout/navigation.css +0 -11
  651. package/dist/layout/page.css +0 -15
  652. package/dist/layout/settings.css +0 -16
  653. package/dist/layout/sidebar.css +0 -16
  654. package/dist/layout/workspace.css +0 -15
  655. package/dist/navigation-CsqTA16F.js +0 -614
  656. package/dist/navigation-DzxzPuwg.js +0 -202
  657. package/dist/overlay-WQOsLd69.js +0 -345
  658. package/dist/patterns/analytics.css +0 -15
  659. package/dist/patterns/onboarding.css +0 -11
  660. package/dist/patterns/timelines.css +0 -11
  661. package/dist/popover-DriLnIFc.js +0 -123
  662. package/dist/popover-menu-C2UCMAe7.js +0 -189
  663. package/dist/primitives.css +0 -3
  664. package/dist/repeaters-DuP1N0nw.js +0 -438
  665. package/dist/rich-text-editor-BQXFe9oN.js +0 -595
  666. package/dist/sidebar-D0N6ckJL.js +0 -412
  667. package/dist/skeleton-DGR9df28.js +0 -172
  668. package/dist/spinner-CUAVFecI.js +0 -52
  669. package/dist/styles/FACTORS.md +0 -36
  670. package/dist/styles/SCOPES.md +0 -86
  671. package/dist/styles/themes/default.css +0 -164
  672. package/dist/styles/theming/animation.css +0 -143
  673. package/dist/styles/theming/colors.css +0 -97
  674. package/dist/styles/theming/feedback.css +0 -17
  675. package/dist/styles/theming/field.css +0 -21
  676. package/dist/styles/theming/focus.css +0 -88
  677. package/dist/styles/theming/layers.css +0 -13
  678. package/dist/styles/theming/layout.css +0 -21
  679. package/dist/styles/theming/motion.css +0 -42
  680. package/dist/styles/theming/overlay.css +0 -52
  681. package/dist/styles/theming/sizing.css +0 -118
  682. package/dist/styles/theming/text.css +0 -30
  683. package/dist/styles/theming/typography.css +0 -26
  684. package/dist/styles/tokens/components.css +0 -22
  685. package/dist/styles/tokens/foundation.css +0 -80
  686. package/dist/styles/tokens/layout.css +0 -19
  687. package/dist/styles/tokens/palette.css +0 -88
  688. package/dist/styles/tokens/primitives.css +0 -18
  689. package/dist/styles/tokens/states.css +0 -77
  690. package/dist/table-BC4qqsUb.js +0 -180
  691. package/dist/table-BHDpjajL.js +0 -982
  692. package/dist/text-inputs-DF_lD7pA.js +0 -385
  693. package/dist/theming-D6KRU7hO.js +0 -104
  694. package/dist/toolbar-DWRywF0R.js +0 -68
  695. package/dist/tooltip-t1VQQ2tZ.js +0 -73
  696. package/dist/upload-B38YZeFJ.js +0 -938
  697. package/dist/value-inputs-Q4ymjXlV.js +0 -716
  698. package/src/styles/FACTORS.md +0 -36
  699. package/src/styles/SCOPES.md +0 -86
  700. /package/dist/components/{admin/patterns → blocks/admin}/access/admin.strings.d.ts +0 -0
  701. /package/dist/components/{admin/patterns → blocks/admin}/access/credential-list.d.ts +0 -0
  702. /package/dist/components/{admin/patterns → blocks/admin}/access/index.d.ts +0 -0
  703. /package/dist/components/{admin/patterns → blocks/admin}/access/role-permissions.d.ts +0 -0
  704. /package/dist/components/{admin/patterns → blocks/admin}/access/sensitive-action.d.ts +0 -0
  705. /package/dist/components/{admin/patterns → blocks/admin}/commerce/account.d.ts +0 -0
  706. /package/dist/components/{admin/patterns → blocks/admin}/commerce/address-lines.d.ts +0 -0
  707. /package/dist/components/{admin/patterns → blocks/admin}/commerce/booking.d.ts +0 -0
  708. /package/dist/components/{admin/patterns → blocks/admin}/commerce/cart.d.ts +0 -0
  709. /package/dist/components/{admin/patterns → blocks/admin}/commerce/commerce.strings.d.ts +0 -0
  710. /package/dist/components/{admin/patterns → blocks/admin}/commerce/commerce.types.d.ts +0 -0
  711. /package/dist/components/{admin/patterns → blocks/admin}/commerce/format-amount.d.ts +0 -0
  712. /package/dist/components/{admin/patterns → blocks/admin}/commerce/index.d.ts +0 -0
  713. /package/dist/components/{admin/patterns → blocks/admin}/commerce/inventory-section.d.ts +0 -0
  714. /package/dist/components/{admin/patterns → blocks/admin}/commerce/invoice.d.ts +0 -0
  715. /package/dist/components/{admin/patterns → blocks/admin}/commerce/loyalty.d.ts +0 -0
  716. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-customer.d.ts +0 -0
  717. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-detail.d.ts +0 -0
  718. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-line-item.d.ts +0 -0
  719. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order-transactions.d.ts +0 -0
  720. /package/dist/components/{admin/patterns → blocks/admin}/commerce/order.d.ts +0 -0
  721. /package/dist/components/{admin/patterns → blocks/admin}/commerce/seo-listing.d.ts +0 -0
  722. /package/dist/components/{admin/patterns → blocks/admin}/commerce/seo-score.d.ts +0 -0
  723. /package/dist/components/{admin/patterns → blocks/admin}/commerce/summary-panel.d.ts +0 -0
  724. /package/dist/components/{patterns → blocks}/analytics/activity-heatmap.d.ts +0 -0
  725. /package/dist/components/{patterns → blocks}/analytics/analytics.types.d.ts +0 -0
  726. /package/dist/components/{patterns → blocks}/analytics/chart-card.d.ts +0 -0
  727. /package/dist/components/{patterns → blocks}/analytics/format-metric-value.d.ts +0 -0
  728. /package/dist/components/{patterns → blocks}/analytics/index.d.ts +0 -0
  729. /package/dist/components/{patterns → blocks}/analytics/metric-bar.d.ts +0 -0
  730. /package/dist/components/{patterns → blocks}/analytics/metric-comparison.d.ts +0 -0
  731. /package/dist/components/{patterns → blocks}/analytics/metric-gradient.d.ts +0 -0
  732. /package/dist/components/{patterns → blocks}/analytics/metric-grid.d.ts +0 -0
  733. /package/dist/components/{patterns → blocks}/analytics/metric-micro-grid.d.ts +0 -0
  734. /package/dist/components/{patterns → blocks}/analytics/metric-skeleton.d.ts +0 -0
  735. /package/dist/components/{patterns → blocks}/analytics/metric-trend-chip.d.ts +0 -0
  736. /package/dist/components/{patterns → blocks}/analytics/metric.d.ts +0 -0
  737. /package/dist/components/{patterns → blocks}/analytics/time-ruler.d.ts +0 -0
  738. /package/dist/components/{patterns → blocks}/onboarding/checklist.d.ts +0 -0
  739. /package/dist/components/{patterns → blocks}/onboarding/index.d.ts +0 -0
  740. /package/dist/components/{patterns → blocks}/onboarding/onboarding.strings.d.ts +0 -0
  741. /package/dist/components/{patterns → blocks}/timelines/changelog-timeline.d.ts +0 -0
  742. /package/dist/components/{patterns → blocks}/timelines/index.d.ts +0 -0
  743. /package/dist/components/{patterns → blocks}/timelines/milestones-timeline.d.ts +0 -0
  744. /package/dist/components/{patterns → blocks}/timelines/steps.d.ts +0 -0
  745. /package/dist/components/{patterns → blocks}/timelines/timelines.strings.d.ts +0 -0
  746. /package/dist/styles/{theming/breakpoints.css → breakpoints.css} +0 -0
@@ -3,13 +3,16 @@
3
3
  * Rewrites a consumer's source for a themelia-ui upgrade, from the migration maps shipped in
4
4
  * docs/generated/. Preview with --dry-run, then apply (in this repo: `npm run codemod`):
5
5
  * node node_modules/themelia-ui/scripts/consumer/codemod.mjs [--dry-run] src/
6
- * Rewrites moved subpaths, removed-barrel imports, renamed tokens and utility classes.
6
+ * Rewrites moved subpaths, removed-barrel imports, renamed tokens and utility classes, and
7
+ * removes obsolete kit stylesheet imports, which components now bring themselves.
7
8
  * Reports without editing: removed tokens, overrides where old names merged (so one rule
8
- * may now set --radius twice), utilities whose meaning changed, ambiguous symbols.
9
+ * may now set --radius twice), utilities whose meaning changed, ambiguous symbols, and kit
10
+ * stylesheet references requiring manual review.
9
11
  */
10
12
  import { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from 'node:fs'
11
- import { dirname, join, relative, resolve } from 'node:path'
13
+ import { dirname, join, resolve } from 'node:path'
12
14
  import { fileURLToPath } from 'node:url'
15
+ import { loadMigrationMaps } from './contract-reader.mjs'
13
16
 
14
17
  const HERE = dirname(fileURLToPath(import.meta.url))
15
18
  const GENERATED = resolve(HERE, '..', '..', 'docs', 'generated')
@@ -21,33 +24,7 @@ const MARKUP = /\.(?:html|vue|svelte|astro|mdx)$/
21
24
  const escape = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
22
25
 
23
26
  /** The two published maps, indexed for the rewrites below. */
24
- export function loadMaps(dir = GENERATED) {
25
- const read = (file) => {
26
- const path = resolve(dir, file)
27
- if (!existsSync(path)) throw new Error(`the packaged migration map is missing at ${path}`)
28
- return JSON.parse(readFileSync(path, 'utf8'))
29
- }
30
- const codemod = read('migration-codemod.json')
31
- const broad = read('migration-broad-imports.json')
32
- const pkg = JSON.parse(readFileSync(resolve(dir, '..', '..', 'package.json'), 'utf8'))
33
- /* A moved family's stylesheet moves with it, where the new one is published. */
34
- const sheets = new Map()
35
- for (const [from, to] of Object.entries(codemod.moves ?? {})) {
36
- const subpath = `.${to.slice(pkg.name.length)}.css`
37
- if (from.startsWith(`${pkg.name}/`) && pkg.exports?.[subpath]) sheets.set(`${from}.css`, `${to}.css`)
38
- }
39
- return {
40
- /* Where a reader finds the rest, as a path from wherever the codemod was run. */
41
- doc: relative(process.cwd(), resolve(dir, 'migration.md')),
42
- moves: new Map([...Object.entries(codemod.moves ?? {}), ...sheets]),
43
- tokens: new Map(Object.entries(codemod.tokens ?? {})),
44
- classes: new Map(Object.entries(codemod.classes ?? {})),
45
- reviewClasses: new Map(Object.entries(codemod.reviewClasses ?? {})),
46
- broad: new Set([...(broad.removedSubpaths ?? [])]),
47
- owner: broad.symbols ?? {},
48
- ambiguous: new Set(Object.keys(broad.ambiguous ?? {})),
49
- }
50
- }
27
+ export const loadMaps = (dir = GENERATED) => loadMigrationMaps(dir)
51
28
 
52
29
  /*
53
30
  * A whole property name: the lookbehind keeps `i--` and `a--b` out; greedy, so a name
@@ -100,6 +77,38 @@ export function rewriteSource(text, file, maps) {
100
77
  }
101
78
  }
102
79
 
80
+ /*
81
+ * Components bring their own CSS in a bundler. Side-effect script imports go; module CSS
82
+ * paths are no longer published, so plain CSS @imports go too. A directly linked page uses
83
+ * style.css instead. Complex references are reported for manual review.
84
+ */
85
+ const sheet = `${escape(maps.name)}/(?!core\\.css["']|tailwind\\.css["'])[^"']+\\.css`
86
+ const moduleSheet = `${escape(maps.name)}/(?:primitives|(?:base|layout|features|blocks|patterns|admin)/[^"']+)\\.css`
87
+ if (isScript) {
88
+ next = next.replace(new RegExp(`^[ \\t]*import\\s*(["'])(${sheet})\\1;?[ \\t]*\\r?\\n?`, 'gm'), (line, quote, specifier) => {
89
+ changes.push(`stylesheet ${file} removed ${specifier} — components bring their own CSS`)
90
+ return ''
91
+ })
92
+ for (const match of next.matchAll(new RegExp(`(["'])(${moduleSheet})\\1`, 'g'))) {
93
+ notes.push(`stylesheet ${file} ${match[2]} — this module stylesheet is no longer published; remove the import`)
94
+ }
95
+ }
96
+ if (isStyle) {
97
+ next = next.replace(new RegExp(`^[ \\t]*@import\\s*(["'])(${moduleSheet})\\1\\s*;?[ \\t]*(?:\\r?\\n|$)`, 'gm'), (line, quote, specifier) => {
98
+ changes.push(`stylesheet ${file} removed ${specifier} — module CSS is no longer published`)
99
+ notes.push(`stylesheet ${file} if this page has no bundler, link ${maps.name}/style.css instead`)
100
+ return ''
101
+ })
102
+ }
103
+ if (isStyle || isMarkup) {
104
+ for (const match of next.matchAll(new RegExp(`(["'])(${sheet})\\1`, 'g'))) {
105
+ notes.push(`stylesheet ${file} ${match[2]} — in a bundled app this loads CSS twice; direct links without a bundler use ${maps.name}/style.css`)
106
+ }
107
+ }
108
+ if (isStyle && new RegExp(`@import\\s*(["'])${escape(maps.name)}/core\\.css\\1`).test(next)) {
109
+ notes.push(`stylesheet ${file} ${maps.name}/core.css — the components import core.css themselves; an @import here inlines a second copy`)
110
+ }
111
+
103
112
  if (isScript) {
104
113
  /* A named import from a removed barrel becomes one import per owning subpath. */
105
114
  next = next.replace(
@@ -215,7 +224,11 @@ export function runCodemod(argv = process.argv.slice(2), { maps = loadMaps(), lo
215
224
 
216
225
  const changes = []
217
226
  const notes = []
218
- for (const file of targets.flatMap((target) => walk(target))) {
227
+ /* A listed path the project does not have is reported, so one command can cover several layouts. */
228
+ const found = targets.filter((target) => existsSync(target))
229
+ for (const target of targets.filter((target) => !existsSync(target))) log(` not found ${target} — skipped`)
230
+ if (!found.length) return 1
231
+ for (const file of found.flatMap((target) => walk(target))) {
219
232
  const original = readFileSync(file, 'utf8')
220
233
  const result = rewriteSource(original, file, maps)
221
234
  changes.push(...result.changes)
@@ -226,10 +239,15 @@ export function runCodemod(argv = process.argv.slice(2), { maps = loadMaps(), lo
226
239
  const uniqueNotes = [...new Set(notes)].sort()
227
240
  for (const line of changes.sort()) log(` ${line}`)
228
241
  for (const line of uniqueNotes) log(` ${line}`)
242
+ const removedSheets = changes.some((line) => line.startsWith('stylesheet'))
229
243
  log(
230
244
  `\n${dryRun ? 'would apply' : 'applied'} ${changes.length} rewrite(s)` +
231
245
  (uniqueNotes.length ? `, left ${uniqueNotes.length} for you` : '') +
232
- `.\n\nNot attempted: \`asChild\` → \`render\`, the provider changes, and the CSS split. See\n${maps.doc}.`,
246
+ `.\n\nNot attempted: \`asChild\` → \`render\` and the provider changes. See\n${maps.doc}.` +
247
+ (removedSheets
248
+ ? '\n\nComponents now bring their own CSS. If the app renders on the server with Vite (Astro, React Router,\n' +
249
+ 'TanStack Start, Vike), add themelia-ui to `ssr.noExternal`, or the server render has no kit CSS.'
250
+ : ''),
233
251
  )
234
252
  return 0
235
253
  }
@@ -0,0 +1,42 @@
1
+ import { existsSync, readFileSync } from 'node:fs'
2
+ import { relative, resolve } from 'node:path'
3
+
4
+ export function loadMigrationMaps(dir) {
5
+ const read = (file) => {
6
+ const path = resolve(dir, file)
7
+ if (!existsSync(path)) throw new Error(`the packaged migration map is missing at ${path}`)
8
+ return JSON.parse(readFileSync(path, 'utf8'))
9
+ }
10
+ const codemod = read('migration-codemod.json')
11
+ const broad = read('migration-broad-imports.json')
12
+ const root = resolve(dir, '..', '..')
13
+ const pkg = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8'))
14
+ return {
15
+ /* Where a reader finds the rest, as a path from wherever the codemod was run. */
16
+ doc: relative(process.cwd(), resolve(dir, 'migration.md')),
17
+ name: pkg.name,
18
+ moves: new Map(Object.entries(codemod.moves ?? {})),
19
+ tokens: new Map(Object.entries(codemod.tokens ?? {})),
20
+ classes: new Map(Object.entries(codemod.classes ?? {})),
21
+ reviewClasses: new Map(Object.entries(codemod.reviewClasses ?? {})),
22
+ broad: new Set([...(broad.removedSubpaths ?? [])]),
23
+ owner: broad.symbols ?? {},
24
+ ambiguous: new Set(Object.keys(broad.ambiguous ?? {})),
25
+ }
26
+ }
27
+
28
+
29
+ /** Read generated package facts; absent or incompatible metadata is an incomplete analysis. */
30
+ export function loadConsumerContract(packageRoot) {
31
+ const pkg=JSON.parse(readFileSync(resolve(packageRoot,'package.json'),'utf8'))
32
+ const metadata=resolve(packageRoot,'docs/generated/consumer-contract.json')
33
+ if(!existsSync(metadata)) throw new Error(`consumer contract is missing at ${metadata}`)
34
+ const contract=JSON.parse(readFileSync(metadata,'utf8'))
35
+ if(contract.schemaVersion!==1 || !contract.publicExports || !contract.privateStyleNames || !Array.isArray(contract.privateStyleNames.variables) || !Array.isArray(contract.privateStyleNames.classes)) throw new Error('unsupported consumer contract schema')
36
+ if(contract.packageVersion!==pkg.version) throw new Error('consumer contract version differs from installed package')
37
+ for(const [specifier,entry] of Object.entries(contract.publicExports)) {
38
+ if(!(specifier===pkg.name||specifier.startsWith(`${pkg.name}/`)) || !['javascript','stylesheet','json'].includes(entry.kind) || !Array.isArray(entry.symbols)) throw new Error('invalid public export metadata')
39
+ if(entry.targets?.some(target=>!target.startsWith('./')||target.split('/').includes('..')||!existsSync(resolve(packageRoot,target)))) throw new Error(`installed package export target is missing: ${specifier}`)
40
+ }
41
+ return {...contract,name:pkg.name,packageRoot,migration:loadMigrationMaps(resolve(packageRoot,'docs/generated'))}
42
+ }
@@ -0,0 +1,51 @@
1
+ /** Bounded plain-CSS observations. Unsupported input is explicit, never a regex pass. */
2
+ const decodeEscapes = value => value
3
+ .replace(/\\(?:\r\n|[\n\r\f])/g, '')
4
+ .replace(/\\([0-9a-fA-F]{1,6})(?:\r\n|[ \n\r\t\f])?|\\(.)/g, (_, hex, char) => {
5
+ if (!hex) return char
6
+ const point = parseInt(hex, 16)
7
+ return point === 0 || point > 0x10ffff || (point >= 0xd800 && point <= 0xdfff) ? '\uFFFD' : String.fromCodePoint(point)
8
+ })
9
+ export function scanCss(source, file = 'input.css') {
10
+ const classes = [], variables = [], imports = [], unsupported = []
11
+ const locate = at => { const before=source.slice(0,at); return { line:before.split('\n').length,column:at-(before.lastIndexOf('\n')+1)+1 } }
12
+ if (!file.endsWith('.css')) return { classes, variables, imports, unsupported:[{...locate(0),reason:'Only plain CSS is supported'}] }
13
+ const chars=source.split('')
14
+ for(let i=0;i<source.length;i++) {
15
+ if(source.slice(i,i+2)==='/*') {
16
+ const end=source.indexOf('*/',i+2)
17
+ if(end<0) { unsupported.push({...locate(i),reason:'Unclosed comment'}); break }
18
+ for(let j=i;j<end+2;j++) if(chars[j]!=='\n') chars[j]=' '
19
+ i=end+1
20
+ } else if(source[i]==='"'||source[i]==="'") {
21
+ const start=i, quote=source[i]; let closed=false
22
+ for(i++;i<source.length;i++) { if(source[i]==='\\') {i++;continue} if(source[i]===quote) {closed=true;break} }
23
+ if(!closed) unsupported.push({...locate(start),reason:'Unclosed string'})
24
+ const value=source.slice(start+1,i)
25
+ if(/@import\s+(?:url\(\s*)?$/i.test(chars.slice(0,start).join(''))) imports.push({specifier:decodeEscapes(value),...locate(start)})
26
+ for(let j=start;j<=i && j<chars.length;j++) if(chars[j]!=='\n') chars[j]=' '
27
+ }
28
+ }
29
+ const clean=chars.join(''); let from=0, depth=0
30
+ for (const hit of clean.matchAll(/@import\s+url\(\s*([^\s)][^)]*?)\s*\)/gi)) {
31
+ const value=decodeEscapes(hit[1])
32
+ imports.push({specifier:value,...locate(hit.index)})
33
+ }
34
+ for(let i=0;i<clean.length;i++) {
35
+ if(clean[i]==='{') {
36
+ const prelude=clean.slice(from,i)
37
+ for(const hit of prelude.matchAll(/\.((?:\\[0-9a-fA-F]{1,6}\s?|\\.|[\w-])+)/g)) {
38
+ const name=decodeEscapes(hit[1])
39
+ classes.push({name,...locate(from+hit.index)})
40
+ }
41
+ depth++;from=i+1
42
+ } else if(clean[i]===';'||clean[i]==='}') { if(clean[i]==='}') depth--;from=i+1 }
43
+ }
44
+ if(depth!==0) unsupported.push({...locate(source.length),reason:'Unbalanced CSS blocks'})
45
+ for(const hit of clean.matchAll(/--[A-Za-z_][\w-]*/g)) {
46
+ const after=clean.slice(hit.index+hit[0].length), before=clean.slice(0,hit.index)
47
+ if(/^\s*:/.test(after)||/var\(\s*$/.test(before)) variables.push({name:hit[0],kind:/^\s*:/.test(after)?'declaration':'read',...locate(hit.index)})
48
+ }
49
+ if(/(?:^|[;{}])\s*\$|@(?:mixin|include|extend)\b/.test(clean)) unsupported.push({...locate(0),reason:'Preprocessor syntax is unsupported'})
50
+ return { classes, variables, imports, unsupported }
51
+ }
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+ /** Read-only observations of explicit consumer files against the installed package. */
3
+ import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync } from 'node:fs'
4
+ import { createRequire } from 'node:module'
5
+ import { dirname, relative, resolve } from 'node:path'
6
+ import { fileURLToPath } from 'node:url'
7
+ import { loadConsumerContract } from './contract-reader.mjs'
8
+ import { scanCss } from './css-scan.mjs'
9
+ import { checkSkill } from './install-skill.mjs'
10
+
11
+ const DOC='node_modules/themelia-ui/docs/learn/'
12
+ const SCRIPT=/\.(?:[cm]?[jt]sx?)$/
13
+ const EXCLUDED=new Set(['node_modules','.git','dist','build'])
14
+ const inside=(root,path)=>{const rel=relative(root,path);return rel!== '..'&&!rel.startsWith('../')&&!rel.startsWith('..\\')}
15
+ export async function diagnoseProject({project='.',paths=[],contract,checkSkills=true}={}) {
16
+ const root=realpathSync(resolve(project)), require=createRequire(resolve(root,'package.json'))
17
+ const report={schemaVersion:1,packageVersion:null,checkedRules:[],skippedChecks:[],checkedFiles:[],skippedFiles:[],findings:[]}
18
+ const skip=(ruleId,reason)=>report.skippedChecks.push({ruleId,reason})
19
+ if(!contract) {
20
+ try {contract=loadConsumerContract(dirname(require.resolve('themelia-ui/package.json')))}
21
+ catch(error) {skip('package-contract',error.message);return {...report,exitCode:2}}
22
+ }
23
+ report.packageVersion=contract.packageVersion
24
+ const files=new Set()
25
+ const skipped=(file,reason)=>report.skippedFiles.push({file:relative(root,file),reason})
26
+ const walk=path=>{
27
+ if(!inside(root,path)||relative(root,path).split(/[\\/]/).some(part=>EXCLUDED.has(part))) {skipped(path,'Outside explicit project source boundary');return}
28
+ if(!existsSync(path)) {skipped(path,'Missing path');return}
29
+ if(!inside(root,realpathSync(path))) {skipped(path,'Resolved path escapes the project through a symlink');return}
30
+ const stat=lstatSync(path)
31
+ if(stat.isSymbolicLink()) {skipped(path,'Symlinks are not followed');return}
32
+ if(stat.isDirectory()) {for(const entry of readdirSync(path).sort()) if(!EXCLUDED.has(entry)) walk(resolve(path,entry));return}
33
+ if(SCRIPT.test(path)||/\.(?:css|scss|sass|less|vue|svelte|astro|mdx)$/.test(path)) files.add(path)
34
+ else skipped(path,'Unsupported source format')
35
+ }
36
+ if(!paths.length) skip('explicit-paths','Supply explicit source paths to analyze')
37
+ for(const path of paths) walk(resolve(root,path))
38
+ const scripts=[...files].filter(path=>SCRIPT.test(path))
39
+ let ts, program, checker
40
+ if(scripts.length) {
41
+ try {ts=require('typescript');program=ts.createProgram(scripts,{noResolve:true,noLib:true,types:[],target:ts.ScriptTarget.Latest,jsx:ts.JsxEmit.Preserve});checker=program.getTypeChecker()}
42
+ catch(error) {skip('script-parser',`Install TypeScript in this consumer project: ${error.message}`)}
43
+ }
44
+ const finding=(ruleId,severity,file,location,evidence,explanation,documentation='troubleshooting.md')=>report.findings.push({ruleId,severity,file:relative(root,file),line:location.line,column:location.column,evidence,explanation,documentation:DOC+documentation})
45
+ const exportEntry=specifier=>contract.publicExports[specifier]
46
+ const imports=(specifier,names,file,loc)=>{
47
+ if(!(specifier===contract.name||specifier.startsWith(`${contract.name}/`))) return
48
+ const entry=exportEntry(specifier)
49
+ if(!entry) {
50
+ const moved=contract.migration?.moves?.get(specifier)
51
+ const alternatives=names.map(name=>contract.migration?.owner?.[name]).filter(Boolean)
52
+ finding('unpublished-import','error',file,loc,specifier,`This exact import is not published.${moved?` Use ${moved}.`:alternatives.length?` Use ${[...new Set(alternatives)].join(', ')}.`:/\.css$/.test(specifier)?' Components bring their own CSS; remove obsolete module stylesheet imports.':' Consult the exact import catalogue.'}`,'composition.md');return
53
+ }
54
+ if(entry.kind==='javascript') for(const name of names) if(!entry.symbols.includes(name)) finding('missing-symbol','error',file,loc,`${specifier}: ${name}`,'This symbol is absent from the installed public declaration; consult the module API.','composition.md')
55
+ }
56
+ if(ts) report.checkedRules.push('unpublished-import','missing-symbol','duplicate-owner','nested-surface')
57
+ for(const file of scripts) {
58
+ if(!ts) {skipped(file,'TypeScript parser unavailable');continue}
59
+ const source=program.getSourceFile(file)
60
+ if(!source || source.parseDiagnostics.length) {skipped(file,'Source parse failed');continue}
61
+ report.checkedFiles.push(relative(root,file));const bindings=new Map(), namespaces=new Map()
62
+ const loc=node=>{const p=source.getLineAndCharacterOfPosition(node.getStart(source));return {line:p.line+1,column:p.character+1}}
63
+ const bind=(node,symbol,specifier)=>{const identity=checker.getSymbolAtLocation(node);if(identity) bindings.set(identity,{symbol,specifier})}
64
+ for(const node of source.statements) {
65
+ if(ts.isImportDeclaration(node)&&ts.isStringLiteral(node.moduleSpecifier)) {
66
+ const specifier=node.moduleSpecifier.text, clause=node.importClause, names=[]
67
+ if(clause?.name) {names.push('default');bind(clause.name,'default',specifier)}
68
+ const named=clause?.namedBindings
69
+ if(named&&ts.isNamedImports(named)) for(const element of named.elements) {const name=element.propertyName?.text??element.name.text;names.push(name);bind(element.name,name,specifier)}
70
+ if(named&&ts.isNamespaceImport(named)) namespaces.set(checker.getSymbolAtLocation(named.name),specifier)
71
+ imports(specifier,names,file,loc(node.moduleSpecifier))
72
+ } else if(ts.isExportDeclaration(node)&&node.moduleSpecifier&&ts.isStringLiteral(node.moduleSpecifier)) imports(node.moduleSpecifier.text,node.exportClause&&ts.isNamedExports(node.exportClause)?node.exportClause.elements.map(item=>item.propertyName?.text??item.name.text):[],file,loc(node.moduleSpecifier))
73
+ }
74
+ const owner=tag=>{
75
+ if(ts.isIdentifier(tag)) return bindings.get(checker.getSymbolAtLocation(tag))
76
+ if(ts.isPropertyAccessExpression(tag)) {const specifier=namespaces.get(checker.getSymbolAtLocation(tag.expression));if(specifier) return {specifier,symbol:tag.name.text}}
77
+ }
78
+ const native=tag=>{const value=owner(tag.tagName);return value&&exportEntry(value.specifier)?.symbols.includes(value.symbol)?value.symbol:null}
79
+ const title=tag=>{const attr=tag.attributes.properties.find(item=>ts.isJsxAttribute(item)&&['title','label'].includes(item.name.getText(source)));return attr?.initializer&&ts.isStringLiteral(attr.initializer)?attr.initializer.text:undefined}
80
+ const visit=node=>{
81
+ if(ts.isCallExpression(node)&&node.arguments[0]&&ts.isStringLiteral(node.arguments[0])&&(node.expression.kind===ts.SyntaxKind.ImportKeyword||(ts.isIdentifier(node.expression)&&node.expression.text==='require'&&!checker.getSymbolAtLocation(node.expression)))) imports(node.arguments[0].text,[],file,loc(node.arguments[0]))
82
+ const member=ts.isPropertyAccessExpression(node)?{base:node.expression,name:node.name.text}
83
+ :ts.isQualifiedName(node)?{base:node.left,name:node.right.text}
84
+ :ts.isElementAccessExpression(node)&&node.argumentExpression&&(ts.isStringLiteral(node.argumentExpression)||ts.isNoSubstitutionTemplateLiteral(node.argumentExpression))?{base:node.expression,name:node.argumentExpression.text}:null
85
+ if(member) {
86
+ const specifier=namespaces.get(checker.getSymbolAtLocation(member.base))
87
+ if(specifier) imports(specifier,[member.name],file,loc(node))
88
+ }
89
+ const tag=ts.isJsxElement(node)?node.openingElement:ts.isJsxSelfClosingElement(node)?node:null
90
+ if(tag) {
91
+ const symbol=native(tag)
92
+ if(symbol) for(let ancestor=node.parent;ancestor;ancestor=ancestor.parent) {
93
+ if(!ts.isJsxElement(ancestor)) continue
94
+ const parent=native(ancestor.openingElement);if(!parent) continue
95
+ if(title(tag)&&title(tag)===title(ancestor.openingElement)) finding('duplicate-owner','warning',file,loc(tag),`${parent} / ${symbol}: ${title(tag)}`,'Repeated literal names may duplicate a subject or field owner. Confirm distinct subjects and accessible names.','composition.md')
96
+ if(symbol==='Card'&&parent==='Card') finding('nested-surface','warning',file,loc(tag),'Card inside Card','Confirm the child is an independent subject. ContentBlock or flat FormSection may express an existing-surface region.','composition.md')
97
+ break
98
+ }
99
+ }
100
+ ts.forEachChild(node,visit)
101
+ };visit(source)
102
+ }
103
+ report.checkedRules.push('private-variable','private-selector','migration-token','stylesheet-import')
104
+ for(const file of [...files].filter(path=>!SCRIPT.test(path))) {
105
+ const observations=scanCss(readFileSync(file,'utf8'),file)
106
+ if(observations.unsupported.length) {skipped(file,observations.unsupported.map(item=>item.reason).join('; '));continue}
107
+ report.checkedFiles.push(relative(root,file))
108
+ for(const item of observations.imports) imports(item.specifier,[],file,item)
109
+ for(const item of observations.classes) if(contract.privateStyleNames.classes.includes(item.name)) finding('private-selector','warning',file,item,item.name,'This selector matches a verified CSS Module hash in this package build. Use documented hooks or public tokens.')
110
+ for(const item of observations.variables) {
111
+ if(contract.privateStyleNames.variables.includes(item.name)) finding('private-variable','warning',file,item,item.name,'This package-private variable is not a supported override. Use a documented public token.')
112
+ if(contract.migration?.tokens?.has(item.name)) finding('migration-token','warning',file,item,item.name,`Historical token; ${contract.migration.tokens.get(item.name)?`review ${contract.migration.tokens.get(item.name)}`:'no successor is declared'}.`,'migration.md')
113
+ }
114
+ }
115
+ if(checkSkills) {
116
+ if(!contract.packageRoot) skip('skill-freshness','Installed package root unavailable')
117
+ else {
118
+ const freshness=checkSkill({project:root,source:resolve(contract.packageRoot,'.agents/skills/themelia-ui')})
119
+ if(freshness.exitCode===2) skip('skill-freshness',freshness.error)
120
+ else {report.checkedRules.push('skill-freshness');for(const target of freshness.targets) if(target.status!=='current') finding('skill-freshness','warning',resolve(root,`.${target.target==='agents'?'agents':'claude'}/skills/themelia-ui/SKILL.md`),{line:1,column:1},`${target.target}: ${target.status}; installed ${target.installedVersion??'unknown'}, expected ${freshness.packageVersion}`,`Review modified content and preserve application policy. Run install-skill.mjs --check --json, then reinstall only the generated copy you intend to replace. Unmanaged skills are never overwritten.`,'verification.md')}
121
+ }
122
+ }
123
+ const incomplete=report.skippedChecks.length||report.skippedFiles.length
124
+ return {...report,exitCode:incomplete?2:report.findings.some(item=>item.severity==='error')?1:0}
125
+ }
126
+
127
+ export async function runDiagnoseCli(args=process.argv.slice(2),io=console) {
128
+ let project='.',json=false;const paths=[]
129
+ for(const arg of args) {if(arg==='--json') json=true;else if(arg.startsWith('--project=')) project=arg.slice(10);else if(arg.startsWith('--')) {io.error('usage: diagnose.mjs --project=<directory> [--json] <paths...>');return 2}else paths.push(arg)}
130
+ let result
131
+ try {result=await diagnoseProject({project,paths})} catch(error) {io.error(`Incomplete diagnosis: ${error.message}`);return 2}
132
+ if(json) io.log(JSON.stringify(result,null,2))
133
+ else {io.log(`themelia-ui ${result.packageVersion??'unknown'}: ${result.checkedFiles.length} files, ${result.findings.length} findings`);for(const item of result.findings) io.log(`${item.severity} ${item.file}:${item.line}:${item.column} ${item.ruleId}: ${item.explanation}`);for(const item of [...result.skippedChecks,...result.skippedFiles]) io.log(`incomplete ${item.ruleId??item.file}: ${item.reason}`)}
134
+ return result.exitCode
135
+ }
136
+ if(process.argv[1]&&realpathSync(process.argv[1])===realpathSync(fileURLToPath(import.meta.url))) process.exitCode=await runDiagnoseCli()
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /*
3
- * Finds which themelia-ui component to use, with its exact JS and CSS imports, from the
3
+ * Finds which themelia-ui component to use, with its exact import, from the
4
4
  * catalogue shipped in this package (offline). `--help` lists the filters.
5
5
  * node node_modules/themelia-ui/scripts/consumer/find-component.mjs "bulk selection"
6
6
  * node node_modules/themelia-ui/scripts/consumer/find-component.mjs --tier=base --json
@@ -11,6 +11,7 @@ import { fileURLToPath } from 'node:url'
11
11
 
12
12
  const HERE = dirname(fileURLToPath(import.meta.url))
13
13
  export const INDEX_PATH = resolve(HERE, '..', '..', 'docs/generated/component-index.json')
14
+ export const CONTEXTS = ['existing-surface', 'editable', 'read-only', 'server-collection', 'nested-overlay', 'changing-scope']
14
15
 
15
16
  /** One catalogue entry in the shape the finder searches and `--json` prints. */
16
17
  const toRecord = (entry) => ({
@@ -19,7 +20,6 @@ const toRecord = (entry) => ({
19
20
  profile: entry.profile,
20
21
  status: entry.status,
21
22
  publicImport: entry.import,
22
- cssImport: entry.css,
23
23
  publicSymbols: entry.symbols,
24
24
  components: entry.components,
25
25
  componentGuidance: entry.componentGuidance,
@@ -37,7 +37,9 @@ const toRecord = (entry) => ({
37
37
 
38
38
  export function loadIndex(path = INDEX_PATH) {
39
39
  if (!existsSync(path)) throw new Error(`the packaged component index is missing at ${path}`)
40
- return Object.values(JSON.parse(readFileSync(path, 'utf8')).modules).map(toRecord)
40
+ const index = JSON.parse(readFileSync(path, 'utf8'))
41
+ if (!Number.isInteger(index.schemaVersion) || index.schemaVersion < 1 || index.schemaVersion > 4 || !index.modules) throw new Error('unsupported component index schema; use the finder shipped with the installed package')
42
+ return Object.values(index.modules).map(toRecord)
41
43
  }
42
44
 
43
45
  const text = (value) => (Array.isArray(value) ? value.join(' ') : String(value ?? ''))
@@ -88,9 +90,11 @@ const STOPWORDS = new Set([
88
90
  * which beats positive guidance and recipes. `avoidWhen` text never counts as a match.
89
91
  */
90
92
  export function findComponents(modules, query, filters = {}) {
93
+ const contexts = filters.context ?? []
94
+ if (!Array.isArray(contexts) || contexts.some(value => !CONTEXTS.includes(value))) throw new Error(`unknown context; expected ${CONTEXTS.join(', ')}`)
91
95
  const needle = query.trim().toLowerCase()
92
96
  const hasFilter = ['tier', 'profile', 'status', 'module', 'peer', 'route', 'symbol']
93
- .some((name) => Boolean(filters[name]))
97
+ .some((name) => Boolean(filters[name])) || contexts.length > 0
94
98
  if (!needle && !hasFilter) return []
95
99
 
96
100
  const scored = []
@@ -105,7 +109,7 @@ export function findComponents(modules, query, filters = {}) {
105
109
  const symbols = (record.publicSymbols ?? []).map((s) => String(s).toLowerCase())
106
110
  if (filters.symbol && !symbols.includes(filters.symbol.toLowerCase())) continue
107
111
 
108
- if (!needle) {
112
+ if (!needle && !contexts.length) {
109
113
  scored.push({ record, score: 0 })
110
114
  continue
111
115
  }
@@ -124,8 +128,8 @@ export function findComponents(modules, query, filters = {}) {
124
128
  )
125
129
  if (normalizedSymbols.includes(phrase)) score = 100
126
130
  else if (normalizedModule === phrase) score = 90
127
- else if (normalizedSymbols.some((symbol) => symbol.includes(phrase))) score = 75
128
- else if (normalizedModule.includes(phrase)) score = 70
131
+ else if (phrase && normalizedSymbols.some((symbol) => symbol.includes(phrase))) score = 75
132
+ else if (phrase && normalizedModule.includes(phrase)) score = 70
129
133
  else if (queryTerms.length > 1 && identityWholeMatch) score = 65
130
134
  else {
131
135
  const positive = [
@@ -152,16 +156,17 @@ export function findComponents(modules, query, filters = {}) {
152
156
  }
153
157
  for (const entry of record.componentGuidance ?? []) {
154
158
  const curated = entry.guidanceSource === 'component'
155
- const corpus = [entry.symbol, entry.description, curated ? entry.chooseWhen : '', ...(entry.capabilities ?? [])].join(' ')
159
+ const matchedContexts = contexts.filter(value => entry.contexts?.includes(value))
160
+ const corpus = [entry.symbol, entry.description, curated ? entry.chooseWhen : '', ...(entry.capabilities ?? []), ...matchedContexts].join(' ')
156
161
  const hits = termHits(queryTerms, corpus)
157
162
  const exact = normalizedWords(entry.symbol).join(' ') === phrase
158
- if (exact || (queryTerms.length && hits * 2 >= queryTerms.length)) {
159
- const componentScore = exact ? 100 : Math.min(curated ? 64 : 34, (curated ? 39 : 10) + Math.round(25 * hits / queryTerms.length))
160
- componentMatches.push({ ...entry, score: componentScore, matchedTerms: queryTerms.filter((term) => termHits([term], corpus)) })
163
+ if (exact || (queryTerms.length && hits * 2 >= queryTerms.length) || (!needle && matchedContexts.length)) {
164
+ const componentScore = exact ? 100 : Math.min(curated ? 74 : 34, (curated ? 39 : 10) + (queryTerms.length ? Math.round(25 * hits / queryTerms.length) : 0) + matchedContexts.length * 5)
165
+ componentMatches.push({ ...entry, score: componentScore, matchedContexts, contextCoverage: entry.contexts ? 'curated' : 'unknown', matchedTerms: queryTerms.filter((term) => termHits([term], corpus)) })
161
166
  score = Math.max(score, componentScore)
162
167
  }
163
168
  }
164
- if (score > 0) scored.push({ record: filters.explain ? { ...record, match: { score, components: componentMatches.sort((a, b) => b.score - a.score), reason: componentMatches.length ? 'Public component name, description or positive usage guidance' : 'Module identity, positive guidance or attributed recipe' } } : record, score })
169
+ if (score > 0 || !needle) scored.push({ record: filters.explain ? { ...record, match: { score, contexts, contextCoverage: (record.componentGuidance ?? []).some(entry => entry.contexts) ? 'curated' : 'unknown', components: componentMatches.sort((a, b) => b.score - a.score), reason: componentMatches.length ? 'Public component name, description, positive usage guidance or applicable context' : 'Module identity, positive guidance or attributed recipe; uncurated contexts remain unknown' } } : record, score })
165
170
  }
166
171
 
167
172
  return scored
@@ -181,6 +186,7 @@ Options:
181
186
  --symbol=<Name> exact public export name
182
187
  --peer=<package> modules that require this optional peer
183
188
  --route=</path> modules represented on this live preview route
189
+ --context=<context> repeatable: ${CONTEXTS.join(', ')}
184
190
  --limit=<N> return at most N matches (default 8)
185
191
  --explain include matched components, reasons and API anchors
186
192
  --json emit complete machine-readable records
@@ -188,7 +194,7 @@ Options:
188
194
 
189
195
  A text query is optional when at least one catalogue filter is present.`
190
196
 
191
- const VALUE_FLAGS = new Set(['tier', 'profile', 'status', 'module', 'symbol', 'peer', 'route', 'limit'])
197
+ const VALUE_FLAGS = new Set(['tier', 'profile', 'status', 'module', 'symbol', 'peer', 'route', 'limit', 'context'])
192
198
  const BOOLEAN_FLAGS = new Set(['json', 'help', 'explain'])
193
199
 
194
200
  export function parseFinderArgs(args) {
@@ -208,7 +214,10 @@ export function parseFinderArgs(args) {
208
214
  if (!VALUE_FLAGS.has(rawName)) throw new Error(`unknown option --${rawName}`)
209
215
  const value = rest.join('=')
210
216
  if (!value) throw new Error(`--${rawName} requires a value written as --${rawName}=...`)
211
- options[rawName] = value
217
+ if (rawName === 'context') {
218
+ if (!CONTEXTS.includes(value)) throw new Error(`unknown context ${value}; expected ${CONTEXTS.join(', ')}`)
219
+ options.context = [...(options.context ?? []), value]
220
+ } else options[rawName] = value
212
221
  }
213
222
  const limit = options.limit === undefined ? 8 : Number(options.limit)
214
223
  if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
@@ -230,7 +239,7 @@ export function runFinderCli(args = process.argv.slice(2), io = console) {
230
239
  return 0
231
240
  }
232
241
  const filters = Object.fromEntries(
233
- ['tier', 'profile', 'status', 'module', 'symbol', 'peer', 'route']
242
+ ['tier', 'profile', 'status', 'module', 'symbol', 'peer', 'route', 'context']
234
243
  .filter((name) => parsed.options[name])
235
244
  .map((name) => [name, parsed.options[name]]),
236
245
  )
@@ -257,16 +266,20 @@ export function renderMatch(record) {
257
266
  `${record.module} (${record.tier} · ${record.profile}${record.status ? ` · ${record.status}` : ''})`,
258
267
  ` import ${record.publicImport}`,
259
268
  ]
260
- if (record.cssImport ?? record.css) lines.push(` css ${record.cssImport ?? record.css}`)
261
269
  if (record.apiDoc) lines.push(` api node_modules/themelia-ui/docs/generated/${record.apiDoc}`)
262
270
  if (record.chooseWhen) lines.push(` choose ${text(record.chooseWhen)}`)
263
271
  if (record.avoidWhen) lines.push(` avoid ${text(record.avoidWhen)}`)
264
- if (record.composeWith?.length) lines.push(` with ${text(record.composeWith)} — import its JS and CSS too`)
272
+ if (record.composeWith?.length) lines.push(` with ${text(record.composeWith)} — import it too`)
265
273
  if (record.alternatives?.length) lines.push(` instead ${text(record.alternatives)}`)
266
274
  if (record.match) {
267
275
  lines.push(` match ${record.match.reason}`)
268
276
  for (const entry of record.match.components.slice(0, 3)) {
269
277
  lines.push(` ${entry.symbol} — ${entry.chooseWhen}`, ` api ${entry.apiDoc}`, ` compose ${entry.composition}`)
278
+ lines.push(` guidance ${entry.guidanceSource === 'component' ? 'component' : 'module fallback'}`)
279
+ lines.push(` context ${entry.contextCoverage ?? 'unknown'}${entry.matchedContexts?.length ? `: ${entry.matchedContexts.join(', ')}` : ''}`)
280
+ const unmatched = (record.match.contexts ?? []).filter(context => !entry.matchedContexts?.includes(context))
281
+ if (unmatched.length) lines.push(` unmatched ${unmatched.join(', ')}`)
282
+ for (const workflow of entry.workflows ?? []) lines.push(` source node_modules/themelia-ui/docs/generated/${workflow.source}`)
270
283
  }
271
284
  }
272
285
  return lines.join('\n')