themelia-react-ui 2.0.3 → 2.0.5

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 (648) hide show
  1. package/CHANGELOG.md +185 -0
  2. package/README.md +168 -36
  3. package/dist/{accordion-Cjb6sx0G.js → accordion-B9MHG0cT.js} +11 -11
  4. package/dist/accordion-B9MHG0cT.js.map +1 -0
  5. package/dist/action-menu-Dr8K-ghE.js +284 -0
  6. package/dist/action-menu-Dr8K-ghE.js.map +1 -0
  7. package/dist/{affordance-geometry.generated-tF36bREk.js → affordance-geometry.generated-P-aVJisu.js} +42 -36
  8. package/dist/affordance-geometry.generated-P-aVJisu.js.map +1 -0
  9. package/dist/{ai-artifact-DvTwDVyL.js → ai-artifact-C58tQcBy.js} +387 -350
  10. package/dist/ai-artifact-C58tQcBy.js.map +1 -0
  11. package/dist/app-shell-B_IuNWOo.js +321 -0
  12. package/dist/app-shell-B_IuNWOo.js.map +1 -0
  13. package/dist/{attachment-BxDfL2mw.js → attachment-Dg_69lPS.js} +9 -9
  14. package/dist/{attachment-BxDfL2mw.js.map → attachment-Dg_69lPS.js.map} +1 -1
  15. package/dist/{auth-BGua8ouh.js → auth-DTkkshS8.js} +44 -47
  16. package/dist/auth-DTkkshS8.js.map +1 -0
  17. package/dist/{avatar-DAPlDvhJ.js → avatar-CeZaFmNH.js} +8 -8
  18. package/dist/avatar-CeZaFmNH.js.map +1 -0
  19. package/dist/{badge-HpFqoqSY.js → badge-xIiV_E7f.js} +5 -5
  20. package/dist/{badge-HpFqoqSY.js.map → badge-xIiV_E7f.js.map} +1 -1
  21. package/dist/base/accordion.js +1 -1
  22. package/dist/base/action-menu.js +1 -1
  23. package/dist/base/attachment.js +1 -1
  24. package/dist/base/avatar.js +1 -1
  25. package/dist/base/badge.js +1 -1
  26. package/dist/base/batch-action-bar.js +1 -1
  27. package/dist/base/buttons.js +1 -1
  28. package/dist/base/cards.js +2 -2
  29. package/dist/base/carousel.js +3 -3
  30. package/dist/base/cascader.js +2 -372
  31. package/dist/base/chart.js +1 -1
  32. package/dist/base/choice-inputs.js +2 -2
  33. package/dist/base/code-block.js +1 -1
  34. package/dist/base/combobox.js +2 -2
  35. package/dist/base/command.js +1 -1
  36. package/dist/base/copyable.js +1 -1
  37. package/dist/base/date-pickers.js +2 -2
  38. package/dist/base/display.js +6 -6
  39. package/dist/base/feedback.js +3 -3
  40. package/dist/base/forms-numeric.js +1 -1
  41. package/dist/base/forms.js +3 -3
  42. package/dist/base/inline-edit.js +10 -10
  43. package/dist/base/item.js +1 -1
  44. package/dist/base/media-gallery.js +1 -1
  45. package/dist/base/metadata-list.js +1 -1
  46. package/dist/base/navigation.js +7 -7
  47. package/dist/base/popover-menu.js +1 -1
  48. package/dist/base/popover.js +1 -1
  49. package/dist/base/qr-code.js +1 -1
  50. package/dist/base/repeaters.js +12 -12
  51. package/dist/base/repeaters.js.map +1 -1
  52. package/dist/base/sheet.js +1 -1
  53. package/dist/base/sidebar.js +2 -2
  54. package/dist/base/signature-pad.js +7 -7
  55. package/dist/base/signature-pad.js.map +1 -1
  56. package/dist/base/skeleton.js +1 -1
  57. package/dist/base/spinner.js +4 -4
  58. package/dist/base/structure.js +1 -1
  59. package/dist/base/table.js +1 -1
  60. package/dist/base/text-inputs.js +2 -2
  61. package/dist/base/toaster.js +36 -36
  62. package/dist/base/toaster.js.map +1 -1
  63. package/dist/base/tree.js +1 -1
  64. package/dist/base/upload-queue.js +1 -1
  65. package/dist/base/upload.js +3 -3
  66. package/dist/base/value-inputs.js +1 -1
  67. package/dist/{batch-action-bar-DnUJ21NQ.js → batch-action-bar-Cb8cuvyy.js} +6 -6
  68. package/dist/batch-action-bar-Cb8cuvyy.js.map +1 -0
  69. package/dist/blocks/admin.js +23 -23
  70. package/dist/blocks/admin.js.map +1 -1
  71. package/dist/blocks/ai.js +230 -216
  72. package/dist/blocks/ai.js.map +1 -1
  73. package/dist/blocks/analytics/usage-card.js +1 -1
  74. package/dist/blocks/analytics.js +326 -307
  75. package/dist/blocks/analytics.js.map +1 -1
  76. package/dist/blocks/collaboration.js +1 -1
  77. package/dist/blocks/commerce/receipt.js +1 -1
  78. package/dist/blocks/commerce.js +1247 -1169
  79. package/dist/blocks/commerce.js.map +1 -1
  80. package/dist/blocks/data-display.js +2 -2
  81. package/dist/blocks/onboarding.js +6 -6
  82. package/dist/blocks/onboarding.js.map +1 -1
  83. package/dist/blocks/planning.js +11 -11
  84. package/dist/blocks/timelines.js +1 -1
  85. package/dist/{breadcrumbs-C-oqs1sQ.js → breadcrumbs-J-K2kl4c.js} +6 -6
  86. package/dist/{breadcrumbs-C-oqs1sQ.js.map → breadcrumbs-J-K2kl4c.js.map} +1 -1
  87. package/dist/{button-DVzspB_G.js → button-S2Cubiiz.js} +3 -3
  88. package/dist/button-S2Cubiiz.js.map +1 -0
  89. package/dist/{buttons-DPZekJFu.js → buttons-BedGfygC.js} +16 -16
  90. package/dist/buttons-BedGfygC.js.map +1 -0
  91. package/dist/cards-rNX1M4Xn.js +69 -0
  92. package/dist/cards-rNX1M4Xn.js.map +1 -0
  93. package/dist/cascader-B1MiqkBq.js +439 -0
  94. package/dist/cascader-B1MiqkBq.js.map +1 -0
  95. package/dist/chart-Darg_0Kv.js +162 -0
  96. package/dist/chart-Darg_0Kv.js.map +1 -0
  97. package/dist/{checkbox-AWIhNhmo.js → checkbox-fflqmODR.js} +9 -5
  98. package/dist/checkbox-fflqmODR.js.map +1 -0
  99. package/dist/choice-inputs-zUgBZfE4.js +777 -0
  100. package/dist/choice-inputs-zUgBZfE4.js.map +1 -0
  101. package/dist/{code-block-DeneBJR_.js → code-block-BzmM9Eig.js} +9 -9
  102. package/dist/code-block-BzmM9Eig.js.map +1 -0
  103. package/dist/{collapsible-C-_l4hpy.js → collapsible-BkAI_XD4.js} +5 -5
  104. package/dist/{collapsible-C-_l4hpy.js.map → collapsible-BkAI_XD4.js.map} +1 -1
  105. package/dist/{collection-content-By56pLog.js → collection-content-gDh1v6O4.js} +3 -3
  106. package/dist/{collection-content-By56pLog.js.map → collection-content-gDh1v6O4.js.map} +1 -1
  107. package/dist/combobox-BEx0vJgF.js +362 -0
  108. package/dist/combobox-BEx0vJgF.js.map +1 -0
  109. package/dist/{combobox-Dxo2fAYQ.js → combobox-BwzoXFSG.js} +254 -247
  110. package/dist/combobox-BwzoXFSG.js.map +1 -0
  111. package/dist/{command-C25VMRII.js → command-CrlPIL6m.js} +12 -12
  112. package/dist/command-CrlPIL6m.js.map +1 -0
  113. package/dist/{comments-DD0DUPwJ.js → comments-Dmpp0YIc.js} +380 -379
  114. package/dist/comments-Dmpp0YIc.js.map +1 -0
  115. package/dist/components/base/action-menu/action-menu.d.ts +9 -1
  116. package/dist/components/base/buttons/button-group.recipes.d.ts +2 -2
  117. package/dist/components/base/cards/card.recipes.d.ts +16 -7
  118. package/dist/components/base/cards/partials/card-primitives.d.ts +9 -2
  119. package/dist/components/base/cards/partials/smart-card-header-row.d.ts +3 -1
  120. package/dist/components/base/cards/smart-card.types.d.ts +11 -7
  121. package/dist/components/base/cascader/cascader-panel.d.ts +76 -0
  122. package/dist/components/base/chart/chart.d.ts +6 -1
  123. package/dist/components/base/choice-inputs/checkbox.d.ts +7 -2
  124. package/dist/components/base/choice-inputs/choice-types.d.ts +1 -1
  125. package/dist/components/base/choice-inputs/switch-card.d.ts +7 -0
  126. package/dist/components/base/choice-inputs/toggle-field.d.ts +7 -0
  127. package/dist/components/base/combobox/index.d.ts +4 -2
  128. package/dist/components/base/date-pickers/datepicker.types.d.ts +7 -0
  129. package/dist/components/base/feedback/alert.d.ts +1 -1
  130. package/dist/components/base/forms/controlled-form-field.d.ts +6 -6
  131. package/dist/components/base/forms/form-field.d.ts +5 -3
  132. package/dist/components/base/forms/form-sizing.d.ts +7 -7
  133. package/dist/components/base/forms/index.d.ts +1 -0
  134. package/dist/components/base/forms/server-errors.d.ts +16 -0
  135. package/dist/components/base/forms/workflow.d.ts +11 -2
  136. package/dist/components/base/forms-numeric/coordinates-input.d.ts +4 -0
  137. package/dist/components/base/metadata-list/metadata-list.d.ts +3 -1
  138. package/dist/components/base/navigation/dropdown-menu.d.ts +1 -1
  139. package/dist/components/base/navigation/page-header/page-header-commands.d.ts +14 -7
  140. package/dist/components/base/navigation/page-header/page-header.d.ts +13 -4
  141. package/dist/components/base/popover/popover.d.ts +3 -3
  142. package/dist/components/base/popover/popover.recipes.d.ts +10 -6
  143. package/dist/components/base/sheet/sheet.d.ts +2 -0
  144. package/dist/components/base/sidebar/index.d.ts +1 -1
  145. package/dist/components/base/sidebar/sidebar.d.ts +27 -5
  146. package/dist/components/base/structure/composition.recipes.d.ts +17 -0
  147. package/dist/components/base/text-inputs/hooks/use-form-field-state.d.ts +7 -2
  148. package/dist/components/base/text-inputs/input.d.ts +4 -2
  149. package/dist/components/base/text-inputs/textarea.d.ts +4 -2
  150. package/dist/components/base/toaster/index.d.ts +1 -0
  151. package/dist/components/base/value-inputs/date-time-input.d.ts +2 -1
  152. package/dist/components/base/value-inputs/slider.d.ts +5 -1
  153. package/dist/components/base/value-inputs/tags-input.d.ts +5 -1
  154. package/dist/components/blocks/ai/ai-file-tree/types.d.ts +1 -1
  155. package/dist/components/blocks/ai/ai-tool-call/types.d.ts +3 -1
  156. package/dist/components/blocks/ai/ai.strings.d.ts +2 -0
  157. package/dist/components/blocks/analytics/metric-comparison/metric-comparison.d.ts +2 -0
  158. package/dist/components/blocks/analytics/usage-card/usage-card.strings.d.ts +2 -0
  159. package/dist/components/blocks/commerce/cart-summary/cart-summary.d.ts +1 -1
  160. package/dist/components/blocks/commerce/cart-summary/types.d.ts +3 -1
  161. package/dist/components/blocks/commerce/discount-stack/discount-stack.d.ts +1 -1
  162. package/dist/components/blocks/commerce/discount-stack/types.d.ts +3 -1
  163. package/dist/components/blocks/commerce/fulfillment-group/fulfillment-group.d.ts +1 -1
  164. package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +11 -2
  165. package/dist/components/blocks/commerce/index.d.ts +7 -6
  166. package/dist/components/blocks/commerce/inventory-section/inventory-section.d.ts +1 -1
  167. package/dist/components/blocks/commerce/inventory-section/types.d.ts +7 -2
  168. package/dist/components/blocks/commerce/invoice-header/index.d.ts +2 -1
  169. package/dist/components/blocks/commerce/invoice-header/invoice-header.d.ts +1 -1
  170. package/dist/components/blocks/commerce/invoice-header/types.d.ts +20 -6
  171. package/dist/components/blocks/commerce/invoice-line-items/invoice-line-items.d.ts +1 -1
  172. package/dist/components/blocks/commerce/invoice-line-items/types.d.ts +24 -7
  173. package/dist/components/blocks/commerce/invoice-mini/index.d.ts +2 -1
  174. package/dist/components/blocks/commerce/invoice-mini/types.d.ts +7 -1
  175. package/dist/components/blocks/commerce/order-customer/order-customer.d.ts +1 -1
  176. package/dist/components/blocks/commerce/order-customer/types.d.ts +9 -1
  177. package/dist/components/blocks/commerce/refund-status/refund-status.d.ts +1 -1
  178. package/dist/components/blocks/commerce/refund-status/types.d.ts +3 -1
  179. package/dist/components/blocks/commerce/shipment-tracking/shipment-tracking.d.ts +1 -1
  180. package/dist/components/blocks/commerce/shipment-tracking/types.d.ts +3 -1
  181. package/dist/components/blocks/commerce/tax-breakdown/tax-breakdown.d.ts +1 -1
  182. package/dist/components/blocks/commerce/tax-breakdown/types.d.ts +3 -1
  183. package/dist/components/features/activities/activities.types.d.ts +8 -2
  184. package/dist/components/features/activities/partials/activity-marker.d.ts +7 -3
  185. package/dist/components/features/activities/partials/activity-row.d.ts +24 -0
  186. package/dist/components/features/event-calendar/colors.d.ts +2 -2
  187. package/dist/components/features/event-calendar/event-calendar.types.d.ts +4 -0
  188. package/dist/components/features/filters/facets/select-facet.d.ts +2 -1
  189. package/dist/components/features/filters/filters.strings.d.ts +4 -0
  190. package/dist/components/features/filters/filters.types.d.ts +3 -0
  191. package/dist/components/features/filters/partials/filter-editor-header.d.ts +16 -0
  192. package/dist/components/features/filters/partials/filter-popover-content.d.ts +1 -1
  193. package/dist/components/features/filters/partials/nested-filter-options.d.ts +21 -0
  194. package/dist/components/features/filters/partials/regular-filter-content.d.ts +2 -1
  195. package/dist/components/features/filters/utils/filter-utils.d.ts +21 -3
  196. package/dist/components/features/global-search/global-search.types.d.ts +2 -0
  197. package/dist/components/features/global-search/partials/global-search-input.d.ts +10 -0
  198. package/dist/components/features/global-search/partials/global-search-result-row.d.ts +7 -1
  199. package/dist/components/features/media-library/media-library.strings.d.ts +2 -0
  200. package/dist/components/features/media-library/media-library.types.d.ts +14 -4
  201. package/dist/components/features/media-library/partials/media-library-partials.d.ts +1 -1
  202. package/dist/components/features/products/components/product-options-matrix.d.ts +1 -1
  203. package/dist/components/features/products/components/product-variant-editor.d.ts +1 -1
  204. package/dist/components/features/products/components/product-variants-manager.d.ts +1 -1
  205. package/dist/components/features/products/products.strings.d.ts +9 -1
  206. package/dist/components/features/products/products.types.d.ts +43 -6
  207. package/dist/components/features/resource/resource.d.ts +5 -1
  208. package/dist/components/features/resource/resource.types.d.ts +12 -1
  209. package/dist/components/features/rich-text-editor/partials/image-uploads.d.ts +1 -1
  210. package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +12 -2
  211. package/dist/components/features/table/partials/resource-cell.d.ts +22 -5
  212. package/dist/components/features/table/table.types.d.ts +1 -1
  213. package/dist/components/layout/app-shell/app-shell.types.d.ts +35 -6
  214. package/dist/components/layout/app-shell/index.d.ts +1 -1
  215. package/dist/components/layout/app-shell/shell-regions.d.ts +27 -0
  216. package/dist/components/layout/app-shell/sidebar-inset-layout.d.ts +1 -1
  217. package/dist/components/layout/app-shell/stacked-layout.d.ts +1 -1
  218. package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +1 -1
  219. package/dist/components/layout/containers/two-column-layout.d.ts +2 -0
  220. package/dist/components/layout/header/header.recipes.d.ts +6 -0
  221. package/dist/components/layout/header/header.types.d.ts +6 -6
  222. package/dist/components/layout/navigation/section-nav/section-nav.d.ts +5 -0
  223. package/dist/components/layout/page/index.d.ts +2 -1
  224. package/dist/components/layout/page/page.d.ts +1 -0
  225. package/dist/components/layout/page/page.strings.d.ts +11 -0
  226. package/dist/components/layout/page/page.types.d.ts +69 -17
  227. package/dist/components/layout/page/partials/page-header.d.ts +1 -1
  228. package/dist/components/layout/settings/settings.d.ts +9 -2
  229. package/dist/components/layout/sidebar/app-sidebar.d.ts +1 -1
  230. package/dist/components/layout/sidebar/components/sidebar-grouped-navigation.d.ts +1 -1
  231. package/dist/components/layout/sidebar/components/sidebar-navigation.d.ts +1 -1
  232. package/dist/components/layout/sidebar/index.d.ts +2 -1
  233. package/dist/components/layout/sidebar/sidebar-navigation-rail.d.ts +36 -0
  234. package/dist/components/layout/sidebar/sidebar.context.d.ts +5 -7
  235. package/dist/components/layout/sidebar/sidebar.types.d.ts +48 -10
  236. package/dist/components/layout/sidebar/sidebar.utils.d.ts +9 -1
  237. package/dist/components/layout/workspace/workspace.types.d.ts +8 -1
  238. package/dist/components/typography/text.styles.d.ts +26 -1
  239. package/dist/components/ui/alert-dialog.d.ts +2 -2
  240. package/dist/components/ui/combobox.d.ts +1 -1
  241. package/dist/components/ui/dialog.d.ts +2 -2
  242. package/dist/components/ui/overlay-layer.d.ts +18 -0
  243. package/dist/components/ui/sheet.d.ts +5 -1
  244. package/dist/components/ui/sidebar-state.d.ts +82 -0
  245. package/dist/components/ui/sidebar.d.ts +5 -17
  246. package/dist/composition.recipes-COdiFhxB.js +19 -0
  247. package/dist/composition.recipes-COdiFhxB.js.map +1 -0
  248. package/dist/containers-CIxwbZt5.js +112 -0
  249. package/dist/containers-CIxwbZt5.js.map +1 -0
  250. package/dist/{control-group-recipes-DBXmfh2E.js → control-group-recipes-fMuFo0H7.js} +6 -6
  251. package/dist/control-group-recipes-fMuFo0H7.js.map +1 -0
  252. package/dist/{copyable-ClBuk_UK.js → copyable-DIznBqiT.js} +7 -7
  253. package/dist/{copyable-ClBuk_UK.js.map → copyable-DIznBqiT.js.map} +1 -1
  254. package/dist/{data-display-DT_khPl_.js → data-display-BdgCAw8T.js} +277 -285
  255. package/dist/data-display-BdgCAw8T.js.map +1 -0
  256. package/dist/{date-DCrsDTZc.js → date-Cq8ioE4o.js} +5 -5
  257. package/dist/{date-DCrsDTZc.js.map → date-Cq8ioE4o.js.map} +1 -1
  258. package/dist/{date-picker-B2K3ucWn.js → date-picker-RlIzKom_.js} +501 -480
  259. package/dist/date-picker-RlIzKom_.js.map +1 -0
  260. package/dist/date-pickers-DY-CpXS1.js +179 -0
  261. package/dist/date-pickers-DY-CpXS1.js.map +1 -0
  262. package/dist/{display-hAc1HjpI.js → display-KsZLw9Ov.js} +9 -9
  263. package/dist/{display-hAc1HjpI.js.map → display-KsZLw9Ov.js.map} +1 -1
  264. package/dist/dropdown-menu-CLs8Lihj.js +194 -0
  265. package/dist/dropdown-menu-CLs8Lihj.js.map +1 -0
  266. package/dist/features/activities.js +302 -253
  267. package/dist/features/activities.js.map +1 -1
  268. package/dist/features/ai-chat.js +15 -14
  269. package/dist/features/ai-chat.js.map +1 -1
  270. package/dist/features/appointment-calendar.js +222 -220
  271. package/dist/features/appointment-calendar.js.map +1 -1
  272. package/dist/features/async-preview.js +11 -10
  273. package/dist/features/async-preview.js.map +1 -1
  274. package/dist/features/combobox.js +1 -1
  275. package/dist/features/comments.js +1 -1
  276. package/dist/features/data-view.js +13 -13
  277. package/dist/features/data-view.js.map +1 -1
  278. package/dist/features/email-composer.js +249 -249
  279. package/dist/features/email-composer.js.map +1 -1
  280. package/dist/features/event-calendar.js +264 -269
  281. package/dist/features/event-calendar.js.map +1 -1
  282. package/dist/features/filters.js +1 -1
  283. package/dist/features/global-search.js +167 -138
  284. package/dist/features/global-search.js.map +1 -1
  285. package/dist/features/kanban.js +6 -7
  286. package/dist/features/kanban.js.map +1 -1
  287. package/dist/features/map.js +269 -260
  288. package/dist/features/map.js.map +1 -1
  289. package/dist/features/media-library.js +827 -777
  290. package/dist/features/media-library.js.map +1 -1
  291. package/dist/features/mentions.js +1 -1
  292. package/dist/features/overlays.js +1 -1
  293. package/dist/features/products.js +1246 -1169
  294. package/dist/features/products.js.map +1 -1
  295. package/dist/features/questionnaire.js +13 -13
  296. package/dist/features/questionnaire.js.map +1 -1
  297. package/dist/features/resource-assignment.js +8 -8
  298. package/dist/features/resource.js +127 -123
  299. package/dist/features/resource.js.map +1 -1
  300. package/dist/features/rich-text-editor.js +2 -2
  301. package/dist/features/schema-form.js +254 -253
  302. package/dist/features/schema-form.js.map +1 -1
  303. package/dist/features/suggestions.js +3 -3
  304. package/dist/features/sync.js +3 -3
  305. package/dist/features/table.js +1 -1
  306. package/dist/features/theme-tweaker.js +95 -96
  307. package/dist/features/theme-tweaker.js.map +1 -1
  308. package/dist/{feedback-BYIhtitP.js → feedback-Dm4izqFn.js} +81 -80
  309. package/dist/feedback-Dm4izqFn.js.map +1 -0
  310. package/dist/{field-affordance-recipes-DZhnIL_Y.js → field-affordance-recipes-DWcNcOjh.js} +4 -4
  311. package/dist/field-affordance-recipes-DWcNcOjh.js.map +1 -0
  312. package/dist/{filters-DJVAveHA.js → filters-DzgSJpMK.js} +693 -645
  313. package/dist/filters-DzgSJpMK.js.map +1 -0
  314. package/dist/{form-field-CwH9y77i.js → form-field-BriWAXyg.js} +14 -8
  315. package/dist/form-field-BriWAXyg.js.map +1 -0
  316. package/dist/{form-sizing-BdP_Mf5p.js → form-sizing-Bs2qFUeE.js} +4 -4
  317. package/dist/form-sizing-Bs2qFUeE.js.map +1 -0
  318. package/dist/forms-C0RGnJTe.js +216 -0
  319. package/dist/forms-C0RGnJTe.js.map +1 -0
  320. package/dist/{forms-numeric-B_jraJaQ.js → forms-numeric-DIhghX1Q.js} +295 -291
  321. package/dist/forms-numeric-DIhghX1Q.js.map +1 -0
  322. package/dist/{header-BSfIEWbI.js → header-DMMxG__r.js} +67 -63
  323. package/dist/header-DMMxG__r.js.map +1 -0
  324. package/dist/header.recipes-BigdJjw1.js +6 -0
  325. package/dist/header.recipes-BigdJjw1.js.map +1 -0
  326. package/dist/hooks/useFormErrors.d.ts +1 -1
  327. package/dist/{hooks-ClH9thn4.js → hooks-DB6CJ4MR.js} +26 -14
  328. package/dist/hooks-DB6CJ4MR.js.map +1 -0
  329. package/dist/{icon-badge-DYKIwvOV.js → icon-badge-DZF-YjQp.js} +4 -4
  330. package/dist/{icon-badge-DYKIwvOV.js.map → icon-badge-DZF-YjQp.js.map} +1 -1
  331. package/dist/index.js +4 -5
  332. package/dist/input-CvyDQlY7.js +289 -0
  333. package/dist/input-CvyDQlY7.js.map +1 -0
  334. package/dist/input-DMBwAZmr.js +21 -0
  335. package/dist/input-DMBwAZmr.js.map +1 -0
  336. package/dist/item-DjCcM18E.js +277 -0
  337. package/dist/item-DjCcM18E.js.map +1 -0
  338. package/dist/layout/app-shell.js +1 -1
  339. package/dist/layout/auth.js +1 -1
  340. package/dist/layout/containers.js +1 -1
  341. package/dist/layout/header.js +1 -1
  342. package/dist/layout/hooks.js +1 -1
  343. package/dist/layout/navigation.js +1 -1
  344. package/dist/layout/page.js +2 -2
  345. package/dist/layout/settings.js +1 -1
  346. package/dist/layout/sidebar.js +3 -3
  347. package/dist/layout/workspace.js +1 -1
  348. package/dist/layout.js +11 -11
  349. package/dist/lib/affordance-geometry.generated.d.ts +41 -35
  350. package/dist/lib/control-group-recipes.d.ts +5 -5
  351. package/dist/lib/field-affordance-recipes.d.ts +2 -2
  352. package/dist/lib/motion-recipes.d.ts +3 -0
  353. package/dist/lib/navigation-row-recipes.d.ts +7 -7
  354. package/dist/lib/overlay-anatomy-recipes.d.ts +3 -3
  355. package/dist/lib/portal-recipes.d.ts +3 -0
  356. package/dist/lib/token-merge.generated.d.ts +13 -10
  357. package/dist/lib/ui-provider/types.d.ts +1 -1
  358. package/dist/lib/utils.js +1 -1
  359. package/dist/map-demo-tile.svg +1 -1
  360. package/dist/{media-gallery-3zIVLMWH.js → media-gallery-C-vChPmE.js} +6 -6
  361. package/dist/{media-gallery-3zIVLMWH.js.map → media-gallery-C-vChPmE.js.map} +1 -1
  362. package/dist/{mentions-CGlEJ15c.js → mentions-0_4nWuI-.js} +10 -10
  363. package/dist/{mentions-CGlEJ15c.js.map → mentions-0_4nWuI-.js.map} +1 -1
  364. package/dist/{message-DZ_ruyUV.js → message-g8p7eVtN.js} +7 -7
  365. package/dist/message-g8p7eVtN.js.map +1 -0
  366. package/dist/metadata-list-C3MkU-Om.js +443 -0
  367. package/dist/metadata-list-C3MkU-Om.js.map +1 -0
  368. package/dist/{motion-recipes-ChBg4HBq.js → motion-recipes-DitYv6P2.js} +10 -2
  369. package/dist/motion-recipes-DitYv6P2.js.map +1 -0
  370. package/dist/navigation-C90-oQFq.js +255 -0
  371. package/dist/navigation-C90-oQFq.js.map +1 -0
  372. package/dist/{navigation-BzhHI3lo.js → navigation-DaRjthVk.js} +101 -82
  373. package/dist/navigation-DaRjthVk.js.map +1 -0
  374. package/dist/{navigation-row-recipes-BFLCk_Aq.js → navigation-row-recipes-BGVLvU_O.js} +9 -9
  375. package/dist/navigation-row-recipes-BGVLvU_O.js.map +1 -0
  376. package/dist/{number-DbV1Dija.js → number-CRU3kGuk.js} +5 -5
  377. package/dist/{number-DbV1Dija.js.map → number-CRU3kGuk.js.map} +1 -1
  378. package/dist/overflow-tab-bar-IVFVQFV6.js +172 -0
  379. package/dist/overflow-tab-bar-IVFVQFV6.js.map +1 -0
  380. package/dist/overlays-BSgCtM2v.js +1013 -0
  381. package/dist/overlays-BSgCtM2v.js.map +1 -0
  382. package/dist/page-DUUKDAjo.js +331 -0
  383. package/dist/page-DUUKDAjo.js.map +1 -0
  384. package/dist/page-header-commands-7P3sfE9u.js +193 -0
  385. package/dist/page-header-commands-7P3sfE9u.js.map +1 -0
  386. package/dist/{pagination-BL25hu2s.js → pagination-CgCjElfu.js} +7 -7
  387. package/dist/{pagination-BL25hu2s.js.map → pagination-CgCjElfu.js.map} +1 -1
  388. package/dist/popover-B85RenIl.js +201 -0
  389. package/dist/popover-B85RenIl.js.map +1 -0
  390. package/dist/{popover-menu-Cn9rUkdc.js → popover-menu-DlnQ2zlR.js} +7 -7
  391. package/dist/{popover-menu-Cn9rUkdc.js.map → popover-menu-DlnQ2zlR.js.map} +1 -1
  392. package/dist/{popover.recipes-D3j8R8Yp.js → popover.recipes-DdiEp0rd.js} +18 -11
  393. package/dist/popover.recipes-DdiEp0rd.js.map +1 -0
  394. package/dist/portal-recipes-BpsV_iRw.js +9 -0
  395. package/dist/portal-recipes-BpsV_iRw.js.map +1 -0
  396. package/dist/{primitives-BFK08r9M.js → primitives-ByWgGUgt.js} +6 -6
  397. package/dist/{primitives-BFK08r9M.js.map → primitives-ByWgGUgt.js.map} +1 -1
  398. package/dist/primitives.js +4 -4
  399. package/dist/{progress-B1VnCT0K.js → progress-BJhQP9WX.js} +9 -9
  400. package/dist/{progress-B1VnCT0K.js.map → progress-BJhQP9WX.js.map} +1 -1
  401. package/dist/{receipt-BVSOH3Xo.js → receipt-tOc7B3hw.js} +7 -7
  402. package/dist/receipt-tOc7B3hw.js.map +1 -0
  403. package/dist/{rich-text-GOUyKQ-s.js → rich-text-Dth5E882.js} +4 -4
  404. package/dist/{rich-text-GOUyKQ-s.js.map → rich-text-Dth5E882.js.map} +1 -1
  405. package/dist/{rich-text-editor-cRLC-eBK.js → rich-text-editor-C1fOjBTd.js} +429 -430
  406. package/dist/rich-text-editor-C1fOjBTd.js.map +1 -0
  407. package/dist/{rich-text-editor-toolbar-DfXg0-VC.js → rich-text-editor-toolbar-laT3tpBT.js} +33 -29
  408. package/dist/rich-text-editor-toolbar-laT3tpBT.js.map +1 -0
  409. package/dist/{scroll-area-DcI-M1UT.js → scroll-area-B0dB2cBi.js} +2 -2
  410. package/dist/{scroll-area-DcI-M1UT.js.map → scroll-area-B0dB2cBi.js.map} +1 -1
  411. package/dist/{separator-Bom7NsGO.js → separator-Bb17I4pu.js} +2 -2
  412. package/dist/{separator-Bom7NsGO.js.map → separator-Bb17I4pu.js.map} +1 -1
  413. package/dist/{separator-BDV-Y648.js → separator-Ct_WSWTJ.js} +3 -3
  414. package/dist/{separator-BDV-Y648.js.map → separator-Ct_WSWTJ.js.map} +1 -1
  415. package/dist/services/actions.js +1 -1
  416. package/dist/settings-Bar5wiSo.js +167 -0
  417. package/dist/settings-Bar5wiSo.js.map +1 -0
  418. package/dist/sheet-BGPERY55.js +250 -0
  419. package/dist/sheet-BGPERY55.js.map +1 -0
  420. package/dist/sidebar-D-JYMMbY.js +686 -0
  421. package/dist/sidebar-D-JYMMbY.js.map +1 -0
  422. package/dist/sidebar-f9gRWXIR.js +1001 -0
  423. package/dist/sidebar-f9gRWXIR.js.map +1 -0
  424. package/dist/skeleton-BapcJd9C.js +265 -0
  425. package/dist/skeleton-BapcJd9C.js.map +1 -0
  426. package/dist/smart-card-CW0hjetE.js +617 -0
  427. package/dist/smart-card-CW0hjetE.js.map +1 -0
  428. package/dist/{structure-BmisBK-3.js → structure-DuxKl954.js} +3 -3
  429. package/dist/{structure-BmisBK-3.js.map → structure-DuxKl954.js.map} +1 -1
  430. package/dist/{structure.recipes-EPz60cU8.js → structure.recipes-BB4-n58V.js} +2 -2
  431. package/dist/{structure.recipes-EPz60cU8.js.map → structure.recipes-BB4-n58V.js.map} +1 -1
  432. package/dist/style.css +1 -1
  433. package/dist/{table-DsfzoUia.js → table-B4TE7iOV.js} +3 -3
  434. package/dist/{table-DsfzoUia.js.map → table-B4TE7iOV.js.map} +1 -1
  435. package/dist/{table-BweFy_P9.js → table-CFOWY9pQ.js} +394 -388
  436. package/dist/table-CFOWY9pQ.js.map +1 -0
  437. package/dist/{tabs-CDocW5D1.js → tabs-e7ko9S2o.js} +11 -11
  438. package/dist/tabs-e7ko9S2o.js.map +1 -0
  439. package/dist/{text-inputs-f9Ia-aCi.js → text-inputs-B1culiSK.js} +107 -104
  440. package/dist/text-inputs-B1culiSK.js.map +1 -0
  441. package/dist/{text.styles-g4He6UIW.js → text.styles-B64My8RZ.js} +25 -10
  442. package/dist/text.styles-B64My8RZ.js.map +1 -0
  443. package/dist/theme.css +192 -149
  444. package/dist/{timelines-CwM_9IhD.js → timelines-D3Sl9ueq.js} +13 -12
  445. package/dist/timelines-D3Sl9ueq.js.map +1 -0
  446. package/dist/tooltip-8wz5S_Zr.js +113 -0
  447. package/dist/tooltip-8wz5S_Zr.js.map +1 -0
  448. package/dist/{tree-WnKQzwbq.js → tree-CzUJHnFs.js} +9 -9
  449. package/dist/{tree-WnKQzwbq.js.map → tree-CzUJHnFs.js.map} +1 -1
  450. package/dist/typography/rich-text.js +1 -1
  451. package/dist/typography-BQnine1k.js +117 -0
  452. package/dist/typography-BQnine1k.js.map +1 -0
  453. package/dist/typography.js +1 -1
  454. package/dist/ui-provider-C-74NVLc.js +178 -0
  455. package/dist/ui-provider-C-74NVLc.js.map +1 -0
  456. package/dist/ui-provider.js +2 -3
  457. package/dist/{upload-CXyxmQBP.js → upload-BOW6U2tI.js} +25 -24
  458. package/dist/upload-BOW6U2tI.js.map +1 -0
  459. package/dist/{upload-queue-Boscubn9.js → upload-queue-qUXn1ykN.js} +16 -14
  460. package/dist/upload-queue-qUXn1ykN.js.map +1 -0
  461. package/dist/{usage-card-BhO5eqkX.js → usage-card-BeSLY0i0.js} +145 -137
  462. package/dist/usage-card-BeSLY0i0.js.map +1 -0
  463. package/dist/{utils-BRhFDwuU.js → utils-B6kKb8jB.js} +303 -144
  464. package/dist/utils-B6kKb8jB.js.map +1 -0
  465. package/dist/value-inputs-skdVB2zh.js +980 -0
  466. package/dist/value-inputs-skdVB2zh.js.map +1 -0
  467. package/dist/{value-typography-BP8OG6h5.js → value-typography-uAmWUAL1.js} +2 -2
  468. package/dist/{value-typography-BP8OG6h5.js.map → value-typography-uAmWUAL1.js.map} +1 -1
  469. package/dist/workspace-DHeHv0qw.js +411 -0
  470. package/dist/workspace-DHeHv0qw.js.map +1 -0
  471. package/docs/consumer-skill/SKILL.md +15 -129
  472. package/docs/consumer-skill/agents/themelia-ui-designer.md +96 -0
  473. package/docs/consumer-skill/examples/app-layout.tsx +74 -13
  474. package/docs/consumer-skill/examples/authentication.tsx +77 -0
  475. package/docs/consumer-skill/examples/commerce-lines.tsx +271 -0
  476. package/docs/consumer-skill/examples/custom-composition.tsx +21 -0
  477. package/docs/consumer-skill/examples/detail.tsx +5 -4
  478. package/docs/consumer-skill/examples/edit.tsx +30 -38
  479. package/docs/consumer-skill/examples/editable-sections.tsx +38 -0
  480. package/docs/consumer-skill/examples/index-table.tsx +4 -4
  481. package/docs/consumer-skill/examples/manifest.json +88 -1
  482. package/docs/consumer-skill/examples/product-media.tsx +41 -0
  483. package/docs/consumer-skill/examples/product-parts.tsx +81 -0
  484. package/docs/consumer-skill/examples/rhf-bindings.tsx +86 -0
  485. package/docs/consumer-skill/examples/rhf-edit-page.tsx +141 -0
  486. package/docs/consumer-skill/examples/rhf-overlay-form.tsx +105 -0
  487. package/docs/consumer-skill/examples/rhf-transport.tsx +28 -0
  488. package/docs/consumer-skill/examples/token-domain-structure.tsx +68 -0
  489. package/docs/consumer-skill/references/agents-md.md +23 -11
  490. package/docs/consumer-skill/references/analytics.md +18 -1
  491. package/docs/consumer-skill/references/authentication.md +42 -0
  492. package/docs/consumer-skill/references/commerce-composition.md +97 -0
  493. package/docs/consumer-skill/references/component-contracts.json +325201 -0
  494. package/docs/consumer-skill/references/composition-mapping.md +106 -0
  495. package/docs/consumer-skill/references/composition.md +198 -46
  496. package/docs/consumer-skill/references/critique-rubric.md +98 -0
  497. package/docs/consumer-skill/references/custom-composition.md +261 -0
  498. package/docs/consumer-skill/references/data-reading.md +79 -0
  499. package/docs/consumer-skill/references/design-contract.md +43 -9
  500. package/docs/consumer-skill/references/discovery.md +109 -8
  501. package/docs/consumer-skill/references/domain-structures.md +124 -0
  502. package/docs/consumer-skill/references/installation.md +51 -36
  503. package/docs/consumer-skill/references/integration.md +41 -2
  504. package/docs/consumer-skill/references/product-composition.md +94 -0
  505. package/docs/consumer-skill/references/public-api.json +4390 -475
  506. package/docs/consumer-skill/references/review.md +47 -5
  507. package/docs/consumer-skill/references/rhf-workflows.md +93 -0
  508. package/docs/consumer-skill/references/screen-archetypes.md +34 -0
  509. package/docs/consumer-skill/references/screen-decisions.md +126 -0
  510. package/docs/consumer-skill/references/theming.md +25 -27
  511. package/docs/consumer-skill/references/tokens.json +20 -11
  512. package/docs/consumer-skill/references/view-craft.md +153 -0
  513. package/docs/consumer-skill/references/view-spec.md +73 -0
  514. package/docs/consumer-skill/references/workflows.md +9 -2
  515. package/docs/consumer-skill/scripts/composition-policy.mjs +39 -3
  516. package/docs/consumer-skill/scripts/composition-schema.d.mts +2 -0
  517. package/docs/consumer-skill/scripts/composition-schema.mjs +32 -0
  518. package/docs/consumer-skill/scripts/composition.mjs +254 -0
  519. package/docs/consumer-skill/scripts/discovery.mjs +96 -10
  520. package/docs/consumer-skill/scripts/inspect-component.mjs +11 -0
  521. package/docs/consumer-skill/scripts/inspect-tokens.mjs +11 -0
  522. package/docs/consumer-skill/scripts/inspection.mjs +193 -0
  523. package/docs/consumer-skill/scripts/map-composition.mjs +12 -0
  524. package/docs/consumer-skill/scripts/setup-skills.mjs +111 -0
  525. package/docs/consumer-skill/scripts/surface-policy.mjs +5 -5
  526. package/docs/consumer-skills/themelia-components/SKILL.md +31 -0
  527. package/docs/consumer-skills/themelia-composition/SKILL.md +34 -0
  528. package/docs/consumer-skills/themelia-design/SKILL.md +55 -0
  529. package/docs/consumer-skills/themelia-forms/SKILL.md +12 -0
  530. package/docs/consumer-skills/themelia-foundation/SKILL.md +15 -0
  531. package/docs/consumer-skills/themelia-tokenization/SKILL.md +42 -0
  532. package/package.json +4 -2
  533. package/templates/README.md +39 -0
  534. package/templates/admin-shell-template.tsx +382 -0
  535. package/templates/analytics-operations-template.tsx +376 -0
  536. package/templates/customers-template.tsx +509 -0
  537. package/templates/index.ts +29 -0
  538. package/templates/orders-template.tsx +1102 -0
  539. package/templates/products-template.tsx +834 -0
  540. package/templates/user-permissions-template.tsx +450 -0
  541. package/dist/accordion-Cjb6sx0G.js.map +0 -1
  542. package/dist/action-menu-CllU52Mm.js +0 -280
  543. package/dist/action-menu-CllU52Mm.js.map +0 -1
  544. package/dist/affordance-geometry.generated-tF36bREk.js.map +0 -1
  545. package/dist/ai-artifact-DvTwDVyL.js.map +0 -1
  546. package/dist/app-shell-C4FhvCqF.js +0 -236
  547. package/dist/app-shell-C4FhvCqF.js.map +0 -1
  548. package/dist/auth-BGua8ouh.js.map +0 -1
  549. package/dist/avatar-DAPlDvhJ.js.map +0 -1
  550. package/dist/base/cascader.js.map +0 -1
  551. package/dist/batch-action-bar-DnUJ21NQ.js.map +0 -1
  552. package/dist/button-DVzspB_G.js.map +0 -1
  553. package/dist/buttons-DPZekJFu.js.map +0 -1
  554. package/dist/cards-BaBZR-AU.js +0 -68
  555. package/dist/cards-BaBZR-AU.js.map +0 -1
  556. package/dist/chart-ZOYyK2xG.js +0 -155
  557. package/dist/chart-ZOYyK2xG.js.map +0 -1
  558. package/dist/checkbox-AWIhNhmo.js.map +0 -1
  559. package/dist/choice-inputs-CNHvARCJ.js +0 -770
  560. package/dist/choice-inputs-CNHvARCJ.js.map +0 -1
  561. package/dist/code-block-DeneBJR_.js.map +0 -1
  562. package/dist/combobox-DaHESuiL.js +0 -355
  563. package/dist/combobox-DaHESuiL.js.map +0 -1
  564. package/dist/combobox-Dxo2fAYQ.js.map +0 -1
  565. package/dist/command-C25VMRII.js.map +0 -1
  566. package/dist/comments-DD0DUPwJ.js.map +0 -1
  567. package/dist/containers-Mu1LMGV1.js +0 -103
  568. package/dist/containers-Mu1LMGV1.js.map +0 -1
  569. package/dist/control-group-recipes-DBXmfh2E.js.map +0 -1
  570. package/dist/data-display-DT_khPl_.js.map +0 -1
  571. package/dist/date-picker-B2K3ucWn.js.map +0 -1
  572. package/dist/date-pickers-Ds8gLaoP.js +0 -175
  573. package/dist/date-pickers-Ds8gLaoP.js.map +0 -1
  574. package/dist/dropdown-menu-Cl4X7L5S.js +0 -193
  575. package/dist/dropdown-menu-Cl4X7L5S.js.map +0 -1
  576. package/dist/feedback-BYIhtitP.js.map +0 -1
  577. package/dist/field-affordance-recipes-DZhnIL_Y.js.map +0 -1
  578. package/dist/filters-DJVAveHA.js.map +0 -1
  579. package/dist/form-field-CwH9y77i.js.map +0 -1
  580. package/dist/form-sizing-BdP_Mf5p.js.map +0 -1
  581. package/dist/forms-B9G_xwzi.js +0 -194
  582. package/dist/forms-B9G_xwzi.js.map +0 -1
  583. package/dist/forms-numeric-B_jraJaQ.js.map +0 -1
  584. package/dist/header-BSfIEWbI.js.map +0 -1
  585. package/dist/hooks-ClH9thn4.js.map +0 -1
  586. package/dist/input-CZw8iU99.js +0 -21
  587. package/dist/input-CZw8iU99.js.map +0 -1
  588. package/dist/input-DQdEd0YD.js +0 -263
  589. package/dist/input-DQdEd0YD.js.map +0 -1
  590. package/dist/item-K5_ghvze.js +0 -275
  591. package/dist/item-K5_ghvze.js.map +0 -1
  592. package/dist/message-DZ_ruyUV.js.map +0 -1
  593. package/dist/metadata-list-8N16ZMW_.js +0 -405
  594. package/dist/metadata-list-8N16ZMW_.js.map +0 -1
  595. package/dist/motion-recipes-ChBg4HBq.js.map +0 -1
  596. package/dist/navigation-Bnotn4AQ.js +0 -145
  597. package/dist/navigation-Bnotn4AQ.js.map +0 -1
  598. package/dist/navigation-BzhHI3lo.js.map +0 -1
  599. package/dist/navigation-row-recipes-BFLCk_Aq.js.map +0 -1
  600. package/dist/overflow-tab-bar-CWY7Nogn.js +0 -282
  601. package/dist/overflow-tab-bar-CWY7Nogn.js.map +0 -1
  602. package/dist/overlays-tMkF-VAN.js +0 -1003
  603. package/dist/overlays-tMkF-VAN.js.map +0 -1
  604. package/dist/page-CL9YeH_V.js +0 -224
  605. package/dist/page-CL9YeH_V.js.map +0 -1
  606. package/dist/page-header-commands-DOb6WsfD.js +0 -126
  607. package/dist/page-header-commands-DOb6WsfD.js.map +0 -1
  608. package/dist/popover-gnTOhbFM.js +0 -198
  609. package/dist/popover-gnTOhbFM.js.map +0 -1
  610. package/dist/popover.recipes-D3j8R8Yp.js.map +0 -1
  611. package/dist/receipt-BVSOH3Xo.js.map +0 -1
  612. package/dist/rich-text-editor-cRLC-eBK.js.map +0 -1
  613. package/dist/rich-text-editor-toolbar-DfXg0-VC.js.map +0 -1
  614. package/dist/settings-ybnjVwbd.js +0 -171
  615. package/dist/settings-ybnjVwbd.js.map +0 -1
  616. package/dist/sheet-ijlsjq-n.js +0 -213
  617. package/dist/sheet-ijlsjq-n.js.map +0 -1
  618. package/dist/sidebar-Db6gkh3U.js +0 -619
  619. package/dist/sidebar-Db6gkh3U.js.map +0 -1
  620. package/dist/sidebar-DkTO4VTO.js +0 -512
  621. package/dist/sidebar-DkTO4VTO.js.map +0 -1
  622. package/dist/skeleton-Byjnt7qr.js +0 -264
  623. package/dist/skeleton-Byjnt7qr.js.map +0 -1
  624. package/dist/smart-card-DiC5aac3.js +0 -604
  625. package/dist/smart-card-DiC5aac3.js.map +0 -1
  626. package/dist/table-BweFy_P9.js.map +0 -1
  627. package/dist/tabs-CDocW5D1.js.map +0 -1
  628. package/dist/text-inputs-f9Ia-aCi.js.map +0 -1
  629. package/dist/text.styles-g4He6UIW.js.map +0 -1
  630. package/dist/theme-scope-BJ6eE2xt.js +0 -50
  631. package/dist/theme-scope-BJ6eE2xt.js.map +0 -1
  632. package/dist/timelines-CwM_9IhD.js.map +0 -1
  633. package/dist/tooltip-yiRJUFjp.js +0 -111
  634. package/dist/tooltip-yiRJUFjp.js.map +0 -1
  635. package/dist/typography-UTnveOEy.js +0 -117
  636. package/dist/typography-UTnveOEy.js.map +0 -1
  637. package/dist/ui-provider-C_U0Xma4.js +0 -136
  638. package/dist/ui-provider-C_U0Xma4.js.map +0 -1
  639. package/dist/upload-CXyxmQBP.js.map +0 -1
  640. package/dist/upload-queue-Boscubn9.js.map +0 -1
  641. package/dist/usage-card-BhO5eqkX.js.map +0 -1
  642. package/dist/use-mobile-vaLKwgyf.js +0 -15
  643. package/dist/use-mobile-vaLKwgyf.js.map +0 -1
  644. package/dist/utils-BRhFDwuU.js.map +0 -1
  645. package/dist/value-inputs-TaX4OjNk.js +0 -963
  646. package/dist/value-inputs-TaX4OjNk.js.map +0 -1
  647. package/dist/workspace-B-OEm3Kf.js +0 -408
  648. package/dist/workspace-B-OEm3Kf.js.map +0 -1
@@ -1,3 +1,5 @@
1
+ import {validateMappings} from './composition-schema.mjs';
2
+
1
3
  export const layers = ['foundations', 'base', 'layout', 'blocks', 'features'];
2
4
  const requireFormat = (condition, message) => { if (!condition) throw new Error(`Invalid discovery index: ${message}`); };
3
5
  const stringList = value => Array.isArray(value) && value.every(item => typeof item === 'string');
@@ -9,6 +11,16 @@ const searchable = value => words(value).join(' ');
9
11
  const containsTerms = (value, terms) => { const tokens = new Set(words(value)); return terms.every(term => tokens.has(term)); };
10
12
  const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
11
13
 
14
+ /** The same bounded context shape is used by authored routes and portable indexes. */
15
+ export function validateComposition(composition) {
16
+ requireFormat(composition !== null && typeof composition === 'object' && !Array.isArray(composition), 'invalid composition object');
17
+ requireFormat(Object.keys(composition).every(field => ['owns', 'parentOwns', 'page', 'embedded', 'mappings'].includes(field)), 'unknown composition field');
18
+ for (const field of ['owns', 'parentOwns']) requireFormat(stringList(composition[field]) && composition[field].length <= 3 && composition[field].every(text), `invalid composition ${field}; use at most three nonempty responsibilities`);
19
+ for (const field of ['page', 'embedded']) if (composition[field] !== undefined) requireFormat(text(composition[field]), `invalid composition ${field}`);
20
+ if (composition.mappings !== undefined) validateMappings(composition.mappings);
21
+ return composition;
22
+ }
23
+
12
24
  export function validateIndex(index) {
13
25
  requireFormat(index?.schemaVersion === 1 && index?.discoveryVersion === 1, 'unsupported schema/format; expected schemaVersion 1 and discoveryVersion 1');
14
26
  requireFormat(text(index.package) && text(index.version) && Array.isArray(index.families), 'package, version and families are required');
@@ -40,6 +52,8 @@ export function validateIndex(index) {
40
52
  requireFormat(guide.browse.domain === undefined || typeof guide.browse.domain === 'string', 'invalid guidance browse domain');
41
53
  for (const field of ['chooseWhen', 'avoidWhen', 'appOwned', 'jobs', 'tags', 'aliases', 'alternatives']) requireFormat(stringList(guide[field]), `invalid guidance ${field}`);
42
54
  requireFormat(Array.isArray(guide.sections) && guide.sections.every(section => text(section?.title) && stringList(section.symbols)), 'invalid guidance sections');
55
+ if (guide.composition !== undefined) validateComposition(guide.composition);
56
+ for (const mapping of guide.composition?.mappings ?? []) requireFormat(family.symbols.includes(mapping.symbol) && !Object.hasOwn(family.deprecated ?? {}, mapping.symbol), `invalid composition mapping public symbol: ${family.import}#${mapping.symbol}`);
43
57
  }
44
58
  }
45
59
  for (const family of index.families) for (const guide of family.guidance) for (const alternative of guide.alternatives) requireFormat(seen.has(alternative), `unpublished alternative ${alternative}`);
@@ -71,7 +85,9 @@ export function parseArguments(args) {
71
85
  return { query, ...options };
72
86
  }
73
87
 
74
- const guideText = guide => searchable([guide.title, guide.description, ...Object.values(guide.browse), ...guide.jobs, ...guide.tags, ...guide.aliases, ...guide.chooseWhen, ...guide.appOwned, ...guide.sections.flatMap(section => [section.title, ...section.symbols])].join(' '));
88
+ // Owned capabilities recommend this owner. Parent responsibilities and contextual
89
+ // comparisons can name other owners, so they are returned as guidance only.
90
+ const guideText = guide => searchable([guide.title, guide.description, ...Object.values(guide.browse), ...guide.jobs, ...guide.tags, ...guide.aliases, ...guide.chooseWhen, ...guide.appOwned, ...(guide.composition?.owns ?? []), ...guide.sections.flatMap(section => [section.title, ...section.symbols])].join(' '));
75
91
  const guideSymbols = (guide, family) => [...new Set(guide.sections.flatMap(section => section.symbols))].filter(symbol => family.symbols.includes(symbol));
76
92
 
77
93
  function relevantGuidance(family, needle, terms, matchedSymbols, exactImport) {
@@ -90,10 +106,9 @@ function relevantGuidance(family, needle, terms, matchedSymbols, exactImport) {
90
106
  return (selected.length || !exactImport ? selected : ranked).slice(0, 3).map(item => item.guide);
91
107
  }
92
108
 
93
- export function findComponents(index, { query, layer = null, limit = 5 }) {
94
- validateIndex(index);
109
+ function rankComponents(index, { query, layer = null, limit = 5 }, partial = false) {
95
110
  const needle = normalized(query);
96
- const terms = [...new Set(words(query))];
111
+ const queryTerms = [...new Set(words(query))];
97
112
  const key = symbolKey(query);
98
113
  // Cased API names and explicit imports request a precise contract. Ordinary
99
114
  // nouns such as table/empty remain task searches with richer alternatives.
@@ -105,11 +120,13 @@ export function findComponents(index, { query, layer = null, limit = 5 }) {
105
120
  const exactImport = normalized(family.import) === needle;
106
121
  const matchedSymbols = family.symbols.filter(symbol => symbolKey(symbol) === key);
107
122
  const documented = new Set(family.guidance.flatMap(guide => guideSymbols(guide, family)));
123
+ const capabilities = searchable([family.responsibility, ...documented, ...family.jobs, ...family.tags, ...family.aliases, ...family.sections, ...family.guidance.map(guideText)].join(' '));
124
+ const haystack = searchable([family.import, capabilities].join(' '));
125
+ // Related owners need capability evidence: package/path vocabulary alone
126
+ // cannot recommend them. Strict matching still requires every query term.
127
+ const terms = partial ? queryTerms.filter(term => containsTerms(capabilities, [term])) : queryTerms;
128
+ if ((partial && !terms.length) || (!partial && !exactImport && !matchedSymbols.length && !containsTerms(haystack, terms))) continue;
108
129
  const focusedSymbols = [...documented].filter(symbol => containsTerms(symbol, terms));
109
- const haystack = searchable([family.import, family.responsibility, ...documented, ...family.jobs, ...family.tags, ...family.aliases, ...family.sections, ...family.guidance.map(guideText)].join(' '));
110
- // AND matching prevents a familiar term from inventing results for an
111
- // otherwise unknown query. Avoidance/alternatives do not recommend owners.
112
- if (!exactImport && !matchedSymbols.length && !containsTerms(haystack, terms)) continue;
113
130
  // A dedicated, documented owner precedes an aggregate re-export of the
114
131
  // same symbol. Explicit import queries still select the requested family.
115
132
  const documentedSymbol = matchedSymbols.some(symbol => documented.has(symbol));
@@ -137,8 +154,77 @@ export function findComponents(index, { query, layer = null, limit = 5 }) {
137
154
  references: [...new Set([...(family.references ?? []), ...recipes.flatMap(recipe => recipe.references)])].sort(compare),
138
155
  examples: recipes.map(({ file, exports, symbols, optionalPeers = [] }) => ({ file, exports, symbols: symbols.filter(symbol => relevantSymbols.includes(symbol)), optionalPeers })),
139
156
  };
140
- ranked.push({ score, import: family.import, declaration: family.declaration, layer: family.layer, responsibility: family.responsibility, optionalPeers: family.optionalPeers, match: exactImport ? 'import' : matchedSymbols.length ? 'symbol' : 'intent', matchedSymbols, relevantSymbols, ...(Object.keys(deprecated).length ? { deprecated } : {}), nextReads, guidance });
157
+ ranked.push({ score, import: family.import, declaration: family.declaration, layer: family.layer, responsibility: family.responsibility, optionalPeers: family.optionalPeers, match: partial ? 'partial' : exactImport ? 'import' : matchedSymbols.length ? 'symbol' : 'intent', ...(partial ? { matchedTerms: terms, unmatchedTerms: queryTerms.filter(term => !terms.includes(term)) } : {}), matchedSymbols, relevantSymbols, ...(Object.keys(deprecated).length ? { deprecated } : {}), nextReads, guidance });
141
158
  }
142
- ranked.sort((a, b) => b.score - a.score || compare(a.import, b.import));
159
+ ranked.sort((a, b) => (partial ? b.matchedTerms.length - a.matchedTerms.length : 0) || b.score - a.score || compare(a.import, b.import));
143
160
  return { package: index.package, version: index.version, query, layer, limit, total: ranked.length, results: ranked.slice(0, limit) };
144
161
  }
162
+
163
+ const singularPlural = segment => segment.endsWith('ies') ? [segment.slice(0, -3) + 'y'] : segment.endsWith('s') ? [segment.slice(0, -1)] : [segment + 's', ...(segment.endsWith('y') ? [segment.slice(0, -1) + 'ies'] : [])];
164
+
165
+ // An unpublished import path resolves only through deterministic evidence: the
166
+ // missing package prefix, a catalogue path alias, the family's singular/plural
167
+ // spelling, or a trailing segment that names one exported component. Anything
168
+ // else keeps the precise empty result instead of a guessed owner.
169
+ export function resolveImport(index, query) {
170
+ const requested = query.trim();
171
+ if (!/^[\w@.-]+(?:\/[\w.-]+)+$/.test(requested) || index.families.some(family => family.import === requested)) return null;
172
+ const path = requested.startsWith(`${index.package}/`) ? requested.slice(index.package.length + 1) : requested;
173
+ const byPath = new Map(index.families.map(family => [family.import === index.package ? '' : family.import.slice(index.package.length + 1), family]));
174
+ const segments = path.split('/');
175
+ const key = symbolKey(segments.at(-1));
176
+ const named = family => family.symbols.find(symbol => /^[A-Z]/.test(symbol) && symbolKey(symbol) === key && !Object.hasOwn(family.deprecated ?? {}, symbol));
177
+ const only = (families, reason, symbol) => families.length === 1 ? { requested, import: families[0].import, reason, ...(symbol ? { symbol } : {}) } : null;
178
+ if (byPath.has(path)) return only([byPath.get(path)], 'Public imports include the package name.');
179
+ const aliased = index.families.filter(family => family.aliases.includes(path));
180
+ if (aliased.length) {
181
+ // A route alias ("blocks/commerce/invoice-table") names its documented owner.
182
+ const routeSymbols = aliased.length === 1 ? [...new Set(aliased[0].guidance.filter(guide => guide.aliases.includes(path)).flatMap(guide => guideSymbols(guide, aliased[0])))] : [];
183
+ return only(aliased, 'Catalogue path alias for this family.', aliased.length === 1 ? named(aliased[0]) ?? (routeSymbols.length === 1 ? routeSymbols[0] : undefined) : undefined);
184
+ }
185
+ const parent = segments.slice(0, -1).join('/');
186
+ const spelled = singularPlural(segments.at(-1)).map(segment => byPath.get([...segments.slice(0, -1), segment].join('/'))).filter(Boolean);
187
+ if (spelled.length) return only(spelled, 'Family names keep their published singular or plural spelling.', spelled.length === 1 ? named(spelled[0]) : undefined);
188
+ // "blocks/commerce/order-header" names OrderHeader in blocks/commerce;
189
+ // "features/data-table" names DataTable, exported by one features family.
190
+ // An aggregate such as `layout` re-exports its sub-families, so the most
191
+ // specific exporting family answers, then the one that documents the
192
+ // component. Several equal owners keep ordinary search instead of a guess.
193
+ const within = prefix => index.families.filter(family => family.import === `${index.package}/${prefix}` || family.import.startsWith(`${index.package}/${prefix}/`)).filter(named);
194
+ const exporting = byPath.has(parent) && within(parent).length ? within(parent) : within(segments[0]);
195
+ const owners = exporting.filter(family => !exporting.some(other => other !== family && other.import.startsWith(`${family.import}/`)));
196
+ const documented = owners.filter(family => family.guidance.some(guide => guideSymbols(guide, family).includes(named(family))));
197
+ const chosen = owners.length === 1 ? owners : documented.length === 1 ? documented : [];
198
+ if (chosen.length) return only(chosen, 'The trailing path segment names a component exported by this family.', named(chosen[0]));
199
+ // A deprecated re-export ("blocks/data-display/metadata-value") points to
200
+ // the one family that owns the current export, whatever its layer.
201
+ const parentFamily = byPath.get(parent);
202
+ const retired = parentFamily?.symbols.find(symbol => symbolKey(symbol) === key && Object.hasOwn(parentFamily.deprecated ?? {}, symbol));
203
+ if (!retired) return null;
204
+ const current = index.families.filter(family => family.import !== index.package && named(family) === retired);
205
+ const currentOwners = current.filter(family => !current.some(other => other !== family && other.import.startsWith(`${family.import}/`)));
206
+ return only(currentOwners, `${retired} is deprecated in ${parentFamily.import}; this family owns the current export.`, retired);
207
+ }
208
+
209
+ export function findComponents(index, options) {
210
+ validateIndex(index);
211
+ const resolution = resolveImport(index, options.query);
212
+ if (resolution) {
213
+ // Answer with the canonical owner, keeping the request visible.
214
+ // Rank every owner before bounding the output, so `limit` cannot drop it.
215
+ const canonical = rankComponents(index, { ...options, query: resolution.symbol ?? resolution.import, limit: 100 });
216
+ const results = canonical.results.filter(result => result.import === resolution.import);
217
+ if (results.length) return { ...canonical, query: options.query, limit: options.limit ?? 5, total: results.length, results: results.slice(0, options.limit ?? 5), importResolution: resolution };
218
+ }
219
+ const result = rankComponents(index, options);
220
+ // Only natural-language requests recover automatically. API-like names and
221
+ // explicit paths keep precise failure semantics rather than guessed owners.
222
+ const query = options.query.trim();
223
+ if (result.total || !/\s/.test(query) || /[\\/]|[a-z0-9][A-Z]|[A-Z]{2}/.test(query) || new Set(words(query)).size < 2) return result;
224
+ const related = rankComponents(index, options, true);
225
+ return related.total ? { ...result, related: {
226
+ explanation: 'No family matched every query term. These suggestions cover incomplete context; unmatched terms remain unverified. Read the owner guidance before choosing.',
227
+ total: related.total,
228
+ results: related.results,
229
+ } } : result;
230
+ }
@@ -0,0 +1,11 @@
1
+ import fs from 'node:fs';
2
+ import {inspectComponent, parseComponentArguments} from './inspection.mjs';
3
+
4
+ try {
5
+ const read = name => JSON.parse(fs.readFileSync(new URL(`../references/${name}`, import.meta.url), 'utf8'));
6
+ const result = inspectComponent(read('component-contracts.json'), parseComponentArguments(process.argv.slice(2)), read('public-api.json'));
7
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
8
+ } catch (error) {
9
+ process.stderr.write(`inspect-component: ${error.message}\nUsage: node inspect-component.mjs <ExactSymbol> [--import exact-public-import] [--prop name[,name]]... [--limit 1..100]\n`);
10
+ process.exitCode = 1;
11
+ }
@@ -0,0 +1,11 @@
1
+ import fs from 'node:fs';
2
+ import {inspectTokens, parseTokenArguments} from './inspection.mjs';
3
+
4
+ try {
5
+ const index = JSON.parse(fs.readFileSync(new URL('../references/tokens.json', import.meta.url), 'utf8'));
6
+ const publicIndex = JSON.parse(fs.readFileSync(new URL('../references/public-api.json', import.meta.url), 'utf8'));
7
+ process.stdout.write(JSON.stringify(inspectTokens(index, parseTokenArguments(process.argv.slice(2)), publicIndex), null, 2) + '\n');
8
+ } catch (error) {
9
+ process.stderr.write(`inspect-tokens: ${error.message}\nUsage: node inspect-tokens.mjs <root-or-role-query> [--limit 1..100]\n`);
10
+ process.exitCode = 1;
11
+ }
@@ -0,0 +1,193 @@
1
+ const requireFormat = (condition, message) => {if (!condition) throw new Error(message);};
2
+ const text = value => typeof value === 'string' && value.length > 0;
3
+ const record = value => value !== null && typeof value === 'object' && !Array.isArray(value);
4
+ const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
5
+ const boundedText = (value, limit) => ({text: value.slice(0, limit), complete: value.length <= limit, omittedCharacters: Math.max(0, value.length - limit)});
6
+
7
+ function parse(args, token = false) {
8
+ const options = token ? {query: '', limit: 12} : {symbol: '', publicImport: null, props: [], limit: 12};
9
+ const seen = new Set();
10
+ const allowed = token ? ['--limit'] : ['--import', '--prop', '--limit'];
11
+ for (let index = 0; index < args.length; index++) {
12
+ const arg = args[index];
13
+ if (!allowed.includes(arg)) {
14
+ if (!token && arg.startsWith('-')) throw new Error(`Unknown argument: ${arg}`);
15
+ const key = token ? 'query' : 'symbol';
16
+ requireFormat(!options[key] && text(arg), `Use one exact ${key}; quote a multiword token query`);
17
+ options[key] = arg;
18
+ continue;
19
+ }
20
+ // Several props may be read at once: repeat --prop or separate names with commas.
21
+ requireFormat(arg === '--prop' || !seen.has(arg), `Duplicate argument: ${arg}`); seen.add(arg);
22
+ const value = args[++index];
23
+ requireFormat(text(value) && !value.startsWith('--'), `Missing value for ${arg}`);
24
+ if (arg === '--limit') {
25
+ requireFormat(/^[1-9]\d*$/.test(value) && Number(value) <= 100, 'Invalid limit: use 1..100'); options.limit = Number(value);
26
+ } else if (arg === '--prop') {
27
+ const names = value.split(',').map(name => name.trim());
28
+ requireFormat(names.every(text), `Missing value for ${arg}`);
29
+ for (const name of names) if (!options.props.includes(name)) options.props.push(name);
30
+ } else options.publicImport = value;
31
+ }
32
+ requireFormat(text(options[token ? 'query' : 'symbol']), `A nonempty ${token ? 'token query' : 'exact symbol'} is required`);
33
+ // `prop` keeps the single-prop field earlier programmatic callers read.
34
+ return token ? options : {symbol: options.symbol, publicImport: options.publicImport, prop: options.props[0] ?? null, props: options.props, limit: options.limit};
35
+ }
36
+ export const parseComponentArguments = args => parse(args);
37
+ export const parseTokenArguments = args => parse(args, true);
38
+
39
+ export function validateComponentContracts(index, publicIndex) {
40
+ requireFormat(record(index) && index.schemaVersion === 1, 'Unsupported component contract schema; refresh the complete skill bundle');
41
+ requireFormat(text(index.package) && text(index.version) && Array.isArray(index.contracts) && record(index.nativeProfiles), 'Invalid component contract identity/data');
42
+ requireFormat(index.nativeProperties === undefined || record(index.nativeProperties), 'Invalid native property registry');
43
+ if (publicIndex) requireFormat(index.package === publicIndex.package && index.version === publicIndex.version, 'Component contract package/version identity mismatch; refresh the complete bundle');
44
+ const seen = new Set();
45
+ const validateProp = (name, prop) => {
46
+ requireFormat(record(prop) && prop.name === name && text(prop.type) && typeof prop.required === 'boolean' && typeof prop.description === 'string' && record(prop.default) && ['unknown', 'documented'].includes(prop.default.status), `Invalid prop contract: ${name}`);
47
+ if (prop.variants !== undefined) requireFormat(Array.isArray(prop.variants) && prop.variants.every(variant => Number.isInteger(variant.branch) && Number.isInteger(variant.signature) && typeof variant.required === 'boolean' && text(variant.type) && (variant.discriminants === undefined || record(variant.discriminants))), `Invalid branch contract: ${name}`);
48
+ if (prop.callbackSignatures !== undefined) requireFormat(Array.isArray(prop.callbackSignatures) && prop.callbackSignatures.every(callback => Number.isInteger(callback.branch) && Number.isInteger(callback.signature) && Array.isArray(callback.signatures) && callback.signatures.length > 0 && callback.signatures.every(text) && (callback.discriminants === undefined || record(callback.discriminants))), `Invalid callback contract: ${name}`);
49
+ };
50
+ for (const prop of Object.values(index.nativeProperties ?? {})) validateProp(prop?.name, prop);
51
+ for (const props of Object.values(index.nativeProfiles)) {
52
+ requireFormat(record(props), 'Invalid native profile');
53
+ for (const [name, reference] of Object.entries(props)) {
54
+ if (typeof reference === 'string') requireFormat(Object.hasOwn(index.nativeProperties ?? {}, reference), `Missing native property reference: ${reference}`);
55
+ validateProp(name, typeof reference === 'string' ? index.nativeProperties[reference] : reference);
56
+ }
57
+ }
58
+ for (const contract of index.contracts) {
59
+ requireFormat(record(contract) && text(contract.import) && text(contract.symbol) && /^dist\/[\w./-]+\.d\.ts$/.test(contract.declaration) && !contract.declaration.split('/').includes('..') && Array.isArray(contract.callSignatures) && contract.callSignatures.every(text) && record(contract.props), 'Invalid component contract');
60
+ const identity = `${contract.import}#${contract.symbol}`;
61
+ requireFormat(!seen.has(identity), `Duplicate component contract: ${identity}`); seen.add(identity);
62
+ requireFormat(contract.inheritedProfile === null || Object.hasOwn(index.nativeProfiles, contract.inheritedProfile), `Missing inherited profile for ${identity}`);
63
+ for (const [name, prop] of Object.entries(contract.props)) validateProp(name, prop);
64
+ if (publicIndex) {
65
+ const family = publicIndex.families?.find(family => family.import === contract.import);
66
+ requireFormat(family?.declaration === contract.declaration && family.symbols.includes(contract.symbol), `Contract is absent from matching public index: ${identity}`);
67
+ }
68
+ }
69
+ return index;
70
+ }
71
+
72
+ function displayProp(prop, origin) {
73
+ const type = boundedText(prop.type, 2000);
74
+ const description = boundedText(prop.description, 800);
75
+ const variants = prop.variants?.slice(0, 12).map(variant => {
76
+ const value = boundedText(variant.type, 2000);
77
+ return {...variant, type: value.text, typeComplete: value.complete, omittedTypeCharacters: value.omittedCharacters};
78
+ });
79
+ const callbacks = prop.callbackSignatures?.slice(0, 12).map(callback => ({...callback,
80
+ signatures: callback.signatures.slice(0, 4).map(signature => boundedText(signature, 2000)), omittedSignatures: Math.max(0, callback.signatures.length - 4)}));
81
+ return {...prop, origin, type: type.text, typeComplete: type.complete, omittedTypeCharacters: type.omittedCharacters,
82
+ description: description.text, omittedDescriptionCharacters: description.omittedCharacters,
83
+ ...(variants ? {variants, omittedVariants: prop.variants.length - variants.length} : {}),
84
+ ...(callbacks ? {callbackSignatures: callbacks, omittedCallbackBranches: prop.callbackSignatures.length - callbacks.length} : {})};
85
+ }
86
+
87
+ function displayGuidance(guide) {
88
+ const list = value => (Array.isArray(value) ? value : []).slice(0, 3).map(value => boundedText(value, 600));
89
+ const composition = guide.composition;
90
+ return {title: boundedText(guide.title ?? '', 150), chooseWhen: list(guide.chooseWhen), avoidWhen: list(guide.avoidWhen),
91
+ alternatives: list(guide.alternatives), omittedAlternatives: Math.max(0, (guide.alternatives?.length ?? 0) - 3),
92
+ ...(composition ? {composition: {owns: list(composition.owns), parentOwns: list(composition.parentOwns),
93
+ ...(composition.page ? {page: boundedText(composition.page, 600)} : {}),
94
+ ...(composition.embedded ? {embedded: boundedText(composition.embedded, 600)} : {})}} : {})};
95
+ }
96
+
97
+ /** Exact API inspection is deliberately separate from task/intent discovery. */
98
+ export function inspectComponent(index, {symbol, publicImport = null, prop = null, props = [], limit = 12}, publicIndex) {
99
+ validateComponentContracts(index, publicIndex);
100
+ requireFormat(text(symbol) && Number.isInteger(limit) && limit >= 1 && limit <= 100, 'Use an exact symbol and limit 1..100');
101
+ const requestedProps = [...new Set([...(prop ? [prop] : []), ...props])];
102
+ const owners = index.contracts.filter(contract => contract.symbol === symbol);
103
+ // Hooks, helpers and types are public too, but have no component contract:
104
+ // name the declaration that holds their signature instead of a generic miss.
105
+ const exporters = owners.length ? [] : (publicIndex?.families ?? []).filter(family => family.symbols.includes(symbol) && (!publicImport || family.import === publicImport));
106
+ requireFormat(!exporters.length, `${symbol} is a public ${/^use[A-Z]/.test(symbol) ? 'hook' : 'export'} without a component contract. Read its signature in ${exporters.slice(0, 3).map(family => `${family.declaration} (import from ${family.import})`).join('; ')}${exporters.length > 3 ? `; ${exporters.length - 3} more` : ''}.`);
107
+ const matches = owners.filter(contract => !publicImport || contract.import === publicImport);
108
+ // An exact symbol can recover from a guessed path without fuzzy matching or
109
+ // silently selecting another owner. Bound both recovery and ambiguity output.
110
+ const imports = owners.map(contract => contract.import).sort(compare);
111
+ const ownerChoices = `${imports.slice(0, 3).join(', ')}. Omitted imports: ${Math.max(0, imports.length - 3)}.`;
112
+ requireFormat(matches.length > 0, `No contract for ${symbol}${publicImport ? ` from ${publicImport}` : ''}; ${owners.length ? `Available imports (--import): ${ownerChoices} ` : ''}Use the finder and read the matching published declaration. Coverage: ${index.coverage ?? 'published uppercase callable exports'}`);
113
+ requireFormat(matches.length === 1, `Ambiguous symbol ${symbol}; qualify with --import: ${ownerChoices}`);
114
+ const contract = matches[0];
115
+ const local = Object.values(contract.props);
116
+ const inherited = contract.inheritedProfile ? Object.fromEntries(Object.entries(index.nativeProfiles[contract.inheritedProfile]).map(([name, reference]) => [name, typeof reference === 'string' ? index.nativeProperties[reference] : reference])) : {};
117
+ // Anatomy is the first decision when composing; callbacks remain exactly
118
+ // inspectable without displacing every insertion seam in a large API.
119
+ const anatomy = ['title', 'description', 'header', 'aside', 'toolbar', 'tabs', 'items', 'fields', 'filters', 'activeFilters', 'primaryAction', 'secondaryActions', 'topbarContent', 'topbarEnd', 'rowActions', 'pagination', 'footer', 'footerSlot', 'titleSuffix', 'headerAction', 'surface', 'padding', 'narrow', 'maxWidth', 'loading', 'error', 'empty', 'slots'];
120
+ const ownerAnatomy = {
121
+ Page: ['header', 'aside', 'toolbar', 'narrow', 'maxWidth', 'loading', 'error', 'empty', 'onRetry', 'slots', 'beforeHeader', 'afterHeader'],
122
+ Card: ['title', 'description', 'titleSuffix', 'headerAction', 'footerSlot', 'surface', 'padding', 'children', 'contentGap', 'headerPlacement', 'actions', 'slots'],
123
+ DataTable: ['columns', 'data', 'topbarContent', 'topbarEnd', 'rowActions', 'pagination', 'surface', 'emptyStateMessage', 'emptyStateAction', 'bulkActions', 'loading', 'getRowId'],
124
+ ActionDialog: ['title', 'description', 'children', 'formId', 'loading', 'strings', 'open', 'onOpenChange', 'onAsyncConfirm', 'alertMessage', 'initialFocusRef', 'footer'],
125
+ ActionDrawer: ['title', 'description', 'children', 'formId', 'loading', 'strings', 'open', 'onOpenChange', 'onAsyncConfirm', 'alertMessage', 'initialFocusRef', 'footer'],
126
+ ProductVariantsManager: ['optionGroups', 'variants', 'editingOptionId', 'defaultEditingOptionId', 'onEditingOptionIdChange', 'onSaveEditingOption', 'onCancelEditingOption', 'onError', 'renderValue', 'visibleColumns', 'selectionMode', 'onSelectVariant'],
127
+ MediaResourceGallery: ['items', 'accessors', 'primaryId', 'onPrimaryChange', 'onReorder', 'onRemove', 'onAdd', 'readOnly', 'renderItem', 'layout', 'density', 'maxItems'],
128
+ ProductOptionsMatrix: ['optionGroups', 'editingOptionId', 'defaultEditingOptionId', 'onEditingOptionIdChange', 'onSaveEditingOption', 'onCancelEditingOption', 'onError', 'renderValue', 'renderOptionActions', 'collapsedOptionIds', 'onCollapsedOptionIdsChange', 'onAddValue'],
129
+ ProductVariantEditor: ['value', 'defaultValue', 'onValueChange', 'optionFields', 'statusOptions', 'visibleFields', 'children', 'onSubmit', 'submitting', 'disabled', 'onError', 'onCancel', 'footerSlot', 'strings'],
130
+ ProductVariantDetails: ['variant', 'metadata', 'media', 'optionItems', 'renderMetadata', 'renderOption', 'renderActions', 'onEditVariant', 'onSelectVariant', 'onBack', 'footerSlot', 'empty'],
131
+ }[symbol] ?? [];
132
+ // Upstream control contracts share inherited profiles with HTML attributes.
133
+ // Keep cross-family state, mounting and render seams discoverable without
134
+ // treating every native DOM event as component anatomy.
135
+ const behavior = new Set(['children', 'render', 'value', 'defaultValue', 'checked', 'defaultChecked', 'open', 'defaultOpen', 'expanded', 'defaultExpanded', 'pressed', 'defaultPressed', 'onChange', 'onValueChange', 'onCheckedChange', 'onOpenChange', 'onExpandedChange', 'onPressedChange', 'multiple', 'keepMounted', 'hiddenUntilFound', 'disabled', 'orientation', 'loopFocus', 'modal']);
136
+ const hasProp = name => Object.hasOwn(contract.props, name) || Object.hasOwn(inherited, name);
137
+ const inheritedBehavior = value => behavior.has(value.name)
138
+ // React's HTMLAttributes includes these defaults even on div-like surfaces.
139
+ && (value.name !== 'defaultValue' || hasProp('value'))
140
+ && (value.name !== 'defaultChecked' || hasProp('checked'))
141
+ && (value.name !== 'onChange' || hasProp('value') || hasProp('checked'));
142
+ const priority = value => {
143
+ if (/(?:^className$|ClassName$|^style$|^(?:BottomSlot|TopSlot)$)/.test(value.name) || value.deprecated || /@deprecated|^Deprecated[.: ]/i.test(value.description)) return -100;
144
+ const position = ownerAnatomy.indexOf(value.name);
145
+ return Number(value.required) * 1000 + (position >= 0 ? 300 - position : anatomy.includes(value.name) ? 100 : /^(?:value|defaultValue|checked|defaultChecked|open|defaultOpen)$/.test(value.name) ? 50 : behavior.has(value.name) ? 40 : /^on[A-Z]/.test(value.name) ? 20 : 0);
146
+ };
147
+ const compareProps = (a, b) => priority(b) - priority(a) || compare(a.name, b.name);
148
+ local.sort(compareProps);
149
+ const inheritedValues = Object.values(inherited).sort((a, b) => Number(inheritedBehavior(b)) - Number(inheritedBehavior(a)) || compareProps(a, b));
150
+ let selected;
151
+ if (requestedProps.length) {
152
+ const unknown = requestedProps.filter(name => !(contract.props[name] ?? inherited[name]));
153
+ requireFormat(!unknown.length, `Unknown prop ${unknown.join(', ')} on ${symbol} from ${contract.import}; inspect its declaration or omit --prop for the bounded prop index`);
154
+ selected = requestedProps.map(name => displayProp(contract.props[name] ?? inherited[name], Object.hasOwn(contract.props, name) ? 'local' : 'inherited'));
155
+ } else {
156
+ const candidates = [
157
+ ...local.map(value => ({value, origin: 'local'})),
158
+ ...inheritedValues.filter(value => inheritedBehavior(value) && priority(value) >= 0 && !Object.hasOwn(contract.props, value.name)).map(value => ({value, origin: 'inherited'})),
159
+ ];
160
+ candidates.sort((a, b) => compareProps(a.value, b.value));
161
+ selected = candidates.slice(0, limit).map(({value, origin}) => displayProp(value, origin));
162
+ }
163
+ const description = boundedText(contract.description ?? '', 1000);
164
+ return {package: index.package, version: index.version, import: contract.import, symbol: contract.symbol, declaration: contract.declaration,
165
+ ...(contract.optionalPeers ? {optionalPeers: contract.optionalPeers} : {}),
166
+ description: description.text, omittedDescriptionCharacters: description.omittedCharacters,
167
+ callSignatures: contract.callSignatures.slice(0, 4).map((signature, signatureIndex) => ({index: signatureIndex, ...boundedText(signature, 4000)})),
168
+ props: selected,
169
+ omissions: {localProps: local.length - selected.filter(value => value.origin === 'local').length,
170
+ inheritedProps: Object.keys(inherited).length - selected.filter(value => value.origin === 'inherited').length,
171
+ callSignatures: Math.max(0, contract.callSignatures.length - 4)},
172
+ propNames: {local: local.map(value => value.name).slice(0, 100), omittedLocalNames: Math.max(0, local.length - 100), inherited: inheritedValues.slice(0, 20).map(value => value.name), omittedInheritedNames: Math.max(0, inheritedValues.length - 20)},
173
+ ...(contract.guidance?.length ? {guidance: contract.guidance.slice(0, 1).map(displayGuidance), omittedGuidance: Math.max(0, contract.guidance.length - 1)} : {}),
174
+ next: 'Use --prop <exact-name> (repeat it, or separate names with commas) for local or inherited contracts. Read declaration for full types, omitted overloads or truncated fields. Defaults marked unknown are not inferred.'};
175
+ }
176
+
177
+ export function inspectTokens(index, {query, limit = 12}, publicIndex) {
178
+ requireFormat(record(index) && text(index.package) && text(index.version) && Array.isArray(index.structural) && record(index.radius) && Array.isArray(index.advanced) && record(index.utilities), 'Invalid token metadata; refresh the complete bundle');
179
+ requireFormat(text(query) && Number.isInteger(limit) && limit >= 1 && limit <= 100, 'Use a token query and limit 1..100');
180
+ if (publicIndex) requireFormat(index.package === publicIndex.package && index.version === publicIndex.version, 'Token metadata package/version identity mismatch; refresh the complete bundle');
181
+ const words = value => value.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
182
+ const terms = words(query);
183
+ const values = [
184
+ ...index.structural.map(root => ({...root, default: {status: 'recorded', value: root.default}, kind: 'structural-root', overrideRoot: true})),
185
+ {...index.radius, default: {status: 'recorded', value: index.radius.default}, kind: 'radius-root', overrideRoot: true},
186
+ ...index.advanced.map(name => ({name, kind: 'advanced-root', overrideRoot: true, default: {status: 'not-recorded'}})),
187
+ ...[...new Set(Object.values(index.utilities).flat())].map(name => ({name, kind: 'derived-utility', overrideRoot: false, default: {status: 'not-applicable'}, ...(name === index.radius.surfaceUtility ? {formula: index.radius.surfaceFormula} : {})})),
188
+ ];
189
+ const matches = values.filter(value => terms.every(term => words([value.name, value.purpose ?? ''].join(' ')).some(word => word === term))).sort((a, b) => Number(b.name === query) - Number(a.name === query) || Number(b.overrideRoot) - Number(a.overrideRoot) || compare(a.name, b.name));
190
+ return {package: index.package, version: index.version, query, total: matches.length, results: matches.slice(0, limit), omitted: Math.max(0, matches.length - limit),
191
+ coverage: 'Structural/radius roots, advanced root names and derived utility spellings. Semantic shadcn light/dark color values are not indexed here; read the installed theme stylesheet and theming reference.',
192
+ rule: index.rule, nextReads: ['references/theming.md', 'references/design-contract.md', 'references/tokens.json'], themeStylesheets: publicIndex?.stylesheets ?? []};
193
+ }
@@ -0,0 +1,12 @@
1
+ import fs from 'node:fs';
2
+ import {mapComposition, parseCompositionArguments} from './composition.mjs';
3
+
4
+ try {
5
+ const options = parseCompositionArguments(process.argv.slice(2));
6
+ const read = file => JSON.parse(fs.readFileSync(new URL(`../references/${file}`, import.meta.url), 'utf8'));
7
+ const result = mapComposition(read('public-api.json'), read('component-contracts.json'), options);
8
+ process.stdout.write(JSON.stringify(result, null, 2) + '\n');
9
+ } catch (error) {
10
+ process.stderr.write(`map-composition: ${error.message}\nUsage: node map-composition.mjs --roles | --role <role or import#symbol> | --pattern record-detail|collection|edit|analytics|embedded [--main <need>] [--aside <need>] [--parent <symbol> --import <import>] [--limit 1..10]\n`);
11
+ process.exitCode = 1;
12
+ }
@@ -0,0 +1,111 @@
1
+ import assert from 'node:assert/strict';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ export const focusedSkills = ['themelia-components', 'themelia-tokenization', 'themelia-composition', 'themelia-design'];
7
+ export const sharedSkillName = 'themelia-react-ui-consumer';
8
+ export const agentFiles = ['themelia-ui-designer.md'];
9
+
10
+ /** One metadata/example copy, four small discoverable entrypoints, and real templates. */
11
+ export function consumerBundleFiles(packageRoot, destination) {
12
+ const mappings = [
13
+ ['docs/consumer-skill', sharedSkillName],
14
+ ...focusedSkills.map(name => [`docs/consumer-skills/${name}`, name]),
15
+ ['templates', `${sharedSkillName}/templates`],
16
+ ].map(([source, target]) => ({ source: path.resolve(packageRoot, source), target: path.resolve(destination, target) }));
17
+ function mapped(file) {
18
+ const mapping = mappings.find(item => file === item.source || file.startsWith(item.source + path.sep));
19
+ assert(mapping, `Reference outside shipped consumer bundle: ${file}`);
20
+ return path.join(mapping.target, path.relative(mapping.source, file));
21
+ }
22
+ const files = [];
23
+ function walk(directory) {
24
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
25
+ if (entry.name === '.DS_Store') continue;
26
+ const source = path.join(directory, entry.name);
27
+ assert(!fs.lstatSync(source).isSymbolicLink(), `Symlink in consumer bundle: ${source}`);
28
+ if (entry.isDirectory()) walk(source);
29
+ else {
30
+ const target = mapped(source);
31
+ let content = fs.readFileSync(source);
32
+ if (source.endsWith('.md')) {
33
+ content = Buffer.from(content.toString().replace(/(\]\(|^\s*\[[^\]]+\]:\s*)([^\s)]+)(?=\)|\s|$)/gm, (match, prefix, raw) => {
34
+ if (/^(?:[a-z][a-z\d+.-]*:|#|\/)/i.test(raw)) return match;
35
+ const [link, anchor = ''] = raw.split(/(?=[?#])/);
36
+ const resolved = path.resolve(path.dirname(source), decodeURIComponent(link));
37
+ assert(fs.existsSync(resolved), `Missing consumer bundle reference: ${source} → ${link}`);
38
+ const relative = path.relative(path.dirname(target), mapped(resolved)).split(path.sep).join('/');
39
+ return prefix + relative + anchor;
40
+ }));
41
+ }
42
+ files.push({ source, target, content });
43
+ }
44
+ }
45
+ }
46
+ for (const mapping of mappings) walk(mapping.source);
47
+ return files;
48
+ }
49
+
50
+ export function checkCopiedConsumerBundle({ packageRoot, destination }) {
51
+ const files = consumerBundleFiles(packageRoot, destination);
52
+ for (const { target, content } of files) {
53
+ assert(fs.existsSync(target) && !fs.lstatSync(target).isSymbolicLink(), `Copied consumer bundle is stale: missing or linked asset ${target}`);
54
+ assert(content.equals(fs.readFileSync(target)), `Copied consumer bundle is stale: refresh the whole bundle (${target})`);
55
+ }
56
+ return { skills: [sharedSkillName, ...focusedSkills], assets: files.length };
57
+ }
58
+
59
+ export function copyConsumerBundle({ packageRoot, destination }) {
60
+ const files = consumerBundleFiles(packageRoot, destination);
61
+ for (const name of [sharedSkillName, ...focusedSkills]) assert(!fs.existsSync(path.join(destination, name)), `Destination exists: ${name}. Preserve or move the previous skill before copying.`);
62
+ for (const { target, content } of files) {
63
+ fs.mkdirSync(path.dirname(target), { recursive: true });
64
+ fs.writeFileSync(target, content);
65
+ }
66
+ return checkCopiedConsumerBundle({ packageRoot, destination });
67
+ }
68
+
69
+ /** Agent definitions are single files copied into an agents directory, such as `.claude/agents`. */
70
+ function agentBundleFiles(packageRoot, destination) {
71
+ return agentFiles.map(name => {
72
+ const source = path.resolve(packageRoot, 'docs/consumer-skill/agents', name);
73
+ return { source, target: path.resolve(destination, name), content: fs.readFileSync(source) };
74
+ });
75
+ }
76
+
77
+ export function checkCopiedAgents({ packageRoot, destination }) {
78
+ const files = agentBundleFiles(packageRoot, destination);
79
+ for (const { target, content } of files) {
80
+ assert(fs.existsSync(target) && !fs.lstatSync(target).isSymbolicLink(), `Copied agent is stale: missing or linked ${target}`);
81
+ assert(content.equals(fs.readFileSync(target)), `Copied agent is stale: copy it again (${target})`);
82
+ }
83
+ return { agents: files.map(file => path.basename(file.target, '.md')) };
84
+ }
85
+
86
+ export function copyAgents({ packageRoot, destination }) {
87
+ const files = agentBundleFiles(packageRoot, destination);
88
+ for (const { target } of files) assert(!fs.existsSync(target), `Destination exists: ${path.basename(target)}. Preserve or move the previous agent before copying.`);
89
+ fs.mkdirSync(destination, { recursive: true });
90
+ for (const { target, content } of files) fs.writeFileSync(target, content);
91
+ return checkCopiedAgents({ packageRoot, destination });
92
+ }
93
+
94
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
95
+ try {
96
+ const usage = 'Usage: node setup-skills.mjs --copy|--check [--destination <agent-skills-directory>] [--agents <agent-definitions-directory>]';
97
+ const [mode, ...rest] = process.argv.slice(2);
98
+ const options = {};
99
+ for (let index = 0; index < rest.length; index += 2) {
100
+ assert(['--destination', '--agents'].includes(rest[index]) && rest[index + 1] && !(rest[index] in options), usage);
101
+ options[rest[index]] = path.resolve(rest[index + 1]);
102
+ }
103
+ assert(['--copy', '--check'].includes(mode) && Object.keys(options).length, usage);
104
+ const packageRoot = fileURLToPath(new URL('../../..', import.meta.url));
105
+ const copy = mode === '--copy';
106
+ const result = {};
107
+ if (options['--destination']) Object.assign(result, (copy ? copyConsumerBundle : checkCopiedConsumerBundle)({ packageRoot, destination: options['--destination'] }), { destination: options['--destination'] });
108
+ if (options['--agents']) Object.assign(result, (copy ? copyAgents : checkCopiedAgents)({ packageRoot, destination: options['--agents'] }), { agentsDestination: options['--agents'] });
109
+ console.log(JSON.stringify(result, null, 2));
110
+ } catch (error) { console.error(error.message); process.exitCode = 1; }
111
+ }
@@ -31,11 +31,11 @@ export const marginProperty = /^margin(?:Inline|Block)?(?:Start|End)?$|^margin(?
31
31
  export const radiusProperty = /^border(?:(?:Top|Bottom)(?:Left|Right)|(?:Start|End)(?:Start|End))?Radius$|^border-(?:(?:top|bottom)-(?:left|right)-|(?:start|end)-(?:start|end)-)?radius$/;
32
32
 
33
33
  export function cornerRole(family, symbol) {
34
- if (family === 'item' && symbol === 'Item' || family === 'navigation' && /^(?:TabsList|TabsTrigger)$/.test(symbol)) return 'inner';
35
- return sharedCornerParts[family]?.test(symbol) && /(?:Item|SubTrigger)$/.test(symbol) ? 'inner' : 'radius';
34
+ if (family === 'item' && symbol === 'Item' || family === 'navigation' && /^(?:TabsList|TabsTrigger)$/.test(symbol)) return 'radius';
35
+ return sharedCornerParts[family]?.test(symbol) && /(?:Item|SubTrigger)$/.test(symbol) ? 'radius' : 'surface';
36
36
  }
37
37
 
38
- export function replacesSharedRadius(token, role = 'radius') {
38
+ export function replacesSharedRadius(token, role = 'surface') {
39
39
  const value = utility(token);
40
40
  if (new RegExp(`^rounded(?:-[trblse]{1,2})?-(?:${role}|none)$`).test(value)) return false;
41
41
  return /^rounded(?:-|$)/.test(value) || /^\[border-(?:(?:top|bottom)-(?:left|right)-|(?:start|end)-(?:start|end)-)?radius:/.test(value);
@@ -159,8 +159,8 @@ export function stateMotionDrift(classes) {
159
159
  return resting.filter(token => /^duration-(?!150$|0$)/.test(utility(token)) || /^ease-/.test(utility(token)));
160
160
  }
161
161
 
162
- // Corners take a role derived from --radius: rounded-radius (outer shells) and
163
- // rounded-inner (controls, rows, nested bodies), plus rounded-full, rounded-none
162
+ // Corners take a role derived from --radius: rounded-radius (controls, badges,
163
+ // rows, nested bodies) and rounded-surface (outer shells), plus rounded-full, rounded-none
164
164
  // and the root-derived rounded-radius-* steps. Bare rounded is a fixed 4px that
165
165
  // ignores the theme root, and the t-shirt steps are a second scale.
166
166
  export function radiusRoleDrift(token) {
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: themelia-components
3
+ description: Use when finding or integrating themelia-react-ui components, compound parts, blocks, features or typed forms in React apps; not library maintenance.
4
+ ---
5
+
6
+ # Themelia components
7
+
8
+ Installed types own the API. Resolve package/version and copied-skill freshness through [installation](../../consumer-skill/references/installation.md). Set up CSS, peers and UIProvider when missing. Skills share assets.
9
+
10
+ ## Find and verify
11
+
12
+ Split the task into responsibilities: facts, selection, editing, collection, disclosure or navigation. Search each separately. Empty strict results do not establish missing support; inspect related suggestions and unmatched terms, then shorten the query. See [discovery](../../consumer-skill/references/discovery.md).
13
+
14
+ ```sh
15
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/find-components.mjs "expandable form sections" --limit 3
16
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/inspect-component.mjs AccordionContent --import themelia-react-ui/base/accordion --prop keepMounted
17
+ ```
18
+
19
+ Imports keep each family's published spelling (`base/cards`, `base/buttons`, `base/chart`); a near miss reports `importResolution`. Read choose/avoid, ownership and peers for the exact export. Qualify ambiguous names. Default inspection includes relevant inherited behavior; --prop retrieves exact callbacks/slots, and installed declarations cover omitted types/overloads. Unknown defaults stay unknown. Preserve generic/discriminated contracts and prefer canonical exports over migration names.
20
+
21
+ Search task-specific subjects/workflows as well as controls: options, variant editing and attached media have dedicated owners. Before rebuilding, compare their data contract, controlled/default state, mounting, callbacks, refs and render seams. A missing prop on a convenience wrapper can exist on its public parts. A custom badge/retained field does not establish a disclosure gap. See [capability comparison](../../consumer-skill/references/custom-composition.md).
22
+
23
+ ## Wire the selected owner
24
+
25
+ - Routes use Page from layout/page for title, responsive commands, lifecycle and gutters. Back navigation and tabs are optional; choose them for an actual journey/section need. Use narrow for one column, aside for context; explicit maxWidth wins. Header actions defaultContent retains command behavior. See [composition](../../consumer-skill/references/composition.md).
26
+ - Server indexes use FilterProvider → DataTable, with FilterLayout in topbarContent. DataTable owns its surface. App query transport retains fixed scope, applies criteria and supplies authoritative rows/pagination. See [scoped directory](../../consumer-skill/examples/scoped-directory.tsx).
27
+ - Forms use typed RHF bindings with ControlledFormField and FormSection. Page forms can use FormActionsBar; overlay forms normally use the overlay's formId/loading/strings footer contract. Await transport, retain failed drafts and reset to accepted values. Inertia needs its onFinish bridge. Read [typed workflows](../../consumer-skill/references/rhf-workflows.md) and [recipes](../../consumer-skill/examples/manifest.json).
28
+
29
+ Use a fitting complete feature; otherwise compose public owners. Base controls and blocks already own local interaction/accessibility. Features coordinate a complete workflow. Data, routing, permissions and translations stay app-owned; see [integration](../../consumer-skill/references/integration.md). Dialogs/drawers/confirmations use features/overlays at the app/feature boundary.
30
+
31
+ Use **themelia-composition** for hierarchy and custom composites, **themelia-tokenization** for theme roles and token-backed app geometry, and **themelia-design** for data-led view specs and rendered critique. Run app checks and [review](../../consumer-skill/references/review.md); execute relevant focus, validation and failure/retry paths. Report source, inspected appearance and executed behavior separately.
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: themelia-composition
3
+ description: Use when composing or repairing Themelia screens, shells, public sites, data-led domain components and workflows, including owner selection, hierarchy, responsive regions and compound APIs.
4
+ ---
5
+
6
+ # Themelia composition
7
+
8
+ Start with the user's decision, representative records, related entities and editable state. Use **themelia-components** for installed identity/APIs, **themelia-tokenization** for shared visual roles and app geometry, and **themelia-design** to read records into a view spec and score the rendered view.
9
+
10
+ Before JSX, settle task, reading priority, action scope and inset owners. Read [screen decisions](../../consumer-skill/references/screen-decisions.md) for new screens/repairs. Optional props are capabilities, not reasons to add navigation, cards or commands.
11
+
12
+ ## Let the data shape the subject
13
+
14
+ Discover task-specific owners before choosing custom markup: product options, variant editing and attached media have different owners from generic controls. Compare their data/state/render seams; use a fitting owner or its parts. Custom JSX shapes additional relationships without requiring an API gap. Read [capability comparison and domain coverage](../../consumer-skill/references/custom-composition.md). More data and a new component name do not establish better composition.
15
+
16
+ ## Choose the seam
17
+
18
+ A feature coordinates workflows; blocks present subjects; base owns controls/disclosure/structures; layout owns app/page regions; primitives format values. Each can have local interaction. Combine these owners and compound parts.
19
+
20
+ Inspect an existing owner's behavior before replacing it: a badge or retained field does not establish an API limit. Card owns framing; Accordion owns labeled disclosure; Collapsible supports a custom single disclosure. Rich slot content retains the owner's typography role.
21
+
22
+ Use the [mapper](../../consumer-skill/references/composition-mapping.md) with --roles or a pattern/subject query. Read coverage, unresolved needs and nextReads. Unmapped does not mean unsupported. [Archetypes](../../consumer-skill/references/screen-archetypes.md) are starting responsibilities, not layouts to reproduce; orders and invoices have an [owner map](../../consumer-skill/references/commerce-composition.md).
23
+
24
+ ## Assign geometry once
25
+
26
+ Page narrow centers one-column forms/details at 48rem; aside infers xl/80rem. Explicit TwoColumnLayout needs Page maxWidth="xl". Collections default to lg/64rem. Settings use Page → SettingsShell → FormSection.
27
+
28
+ Explicit maxWidth wins, then narrow, then aside width. Page owns h1, commands, lifecycle, gutters and subject gaps. AuthShell owns auth; Container/Section own sites. Header actions defaultContent preserves responsive commands. Loading precedes error then empty; supply copy/onRetry. Resource shells are migration APIs.
29
+
30
+ Stack/Grid/AdaptiveGrid own peer relationships; Card owns frame/insets. Card flat removes chrome, not padding; use none under an existing inset owner. Blocks stay card-free unless their purpose is a card. Tailwind owns app-specific tracks/queries/overflow; read [domain structures](../../consumer-skill/references/domain-structures.md).
31
+
32
+ Indexes use DataView or FilterProvider → DataTable with FilterLayout in topbarContent; exports in topbarEnd, selection in bulkActions, record commands in rowActions. Table owns its surface. Keep fixed scope distinct from filters. Apps own transport, permissions, routing and translations; read [forms](../../consumer-skill/references/rhf-workflows.md).
33
+
34
+ Rank commands by scope/frequency/consequence; use overflow for secondary item actions when visible buttons compete with identity. Add back navigation only for a real return journey. Preserve narrow DOM priority, not just column stacking. Run app checks and [review](../../consumer-skill/references/review.md); inspect actual narrow/wide appearance and opened/error/accepted states. Valid API usage is not product quality.