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
@@ -0,0 +1,153 @@
1
+ # View craft
2
+
3
+ Themelia already sets type, colour, spacing and surfaces. Craft is what remains:
4
+ deciding what a view shows, how much emphasis each part gets and how the parts
5
+ are arranged, so the user understands the screen at a glance. Each rule below is
6
+ a decision you can explain and check on the rendered result. Most improvements
7
+ remove something.
8
+
9
+ Start from the [data brief](data-reading.md#write-the-data-brief). Owner
10
+ selection, surfaces and inset ownership follow
11
+ [screen decisions](screen-decisions.md); this reference does not restate them.
12
+
13
+ ## One focal point
14
+
15
+ Each view, and each region in it, has one thing the eye reaches first: the
16
+ figure that answers the question, the subject's identity and state, or the queue
17
+ of records that need action. Choose it from the brief. When two things compete,
18
+ demote one: a smaller text role, secondary tone, or a supporting region.
19
+
20
+ Check it by looking at a reduced screenshot: the focal point is still the
21
+ strongest mass. It sits in the first viewport at both 390 and 1440 wide.
22
+
23
+ ## Spend emphasis on purpose
24
+
25
+ Emphasis works only by contrast, so it is a budget:
26
+
27
+ - **Commands.** One solid primary command per page or surface. Other commands
28
+ are outline or ghost, or sit in the same scope's overflow menu.
29
+ - **Text.** At most three levels in a region: title (`Heading`), body and values
30
+ (`Text`), supporting copy (`Text` secondary, smaller size). A fourth level
31
+ signals a hierarchy problem, not a missing style.
32
+ - **Tone.** `success`, `warning`, `destructive` and `info` mark a status that
33
+ changes what the user does. Kinds, categories and counts stay neutral. When
34
+ everything is coloured, nothing reads as status.
35
+ - **Size.** One hero figure size per region; peer figures share one size.
36
+
37
+ Adding emphasis in one place means removing it from another.
38
+
39
+ ## Choose the encoding from the fact
40
+
41
+ | The fact | Encoding | Owner family (confirm with the finder and inspector) |
42
+ | --- | --- | --- |
43
+ | A figure the user must judge | Figure with its baseline delta; a sparkline when the path matters | `Metric`, `MetricTrendChip`, `MetricSparkline`; `MetricComparison` for current versus previous |
44
+ | Several peer figures for one period | One strip, not a grid of identical cards | `MetricBar`; `MetricGrid` with a quiet variant inside one surface |
45
+ | A series whose shape is the message | Chart with one emphasised series and minimal axes | `ChartCard` with Recharts children |
46
+ | Part of a whole, or use against a limit | Bar with the figure as its label | `Progress`, `UsageCard` |
47
+ | Facts about one record | Label and value list; one inline line for two to four short facts | `MetadataList` (inline or stacked), `InlineStat` |
48
+ | A lifecycle with a current stage | Steps with only the current stage emphasised | `StepsHorizontal`, `Timeline` |
49
+ | Events and history | Newest first, grouped by day | `Timeline`, `features/activities` |
50
+ | Many records compared on shared columns | Table whose columns are what users compare or sort | `DataTable`, `DataView` |
51
+ | Records that differ in shape | List rows: identity, one line of context, state, action | `Item`, `ItemGroup` |
52
+ | A money ledger | Right-aligned amounts, one rule above the grand total | `SummaryPanel` with `AmountRow`, `OrderSummary` |
53
+ | Nothing to show yet | What is missing and the next action | `EmptyState` |
54
+
55
+ Read [metrics and statistics](analytics.md) for the exact metric owner. A chart
56
+ must answer a question you can write in one sentence; otherwise show the figure.
57
+ Do not chart three values. Prefer a sparkline in a strip to a large chart that
58
+ repeats what the figures already say.
59
+
60
+ ## Spend words carefully
61
+
62
+ - Label a value only when it is ambiguous. A ledger amount needs "Total"; an
63
+ order number in a header does not need "Order number".
64
+ - Do not repeat a column header inside its cells or a section title in each row.
65
+ - State a unit once, in the header or the value.
66
+ - A sentence fragment often reads better than three label and value pairs:
67
+ "2 of 3 shipped · 1 reserved at Plovdiv".
68
+ - Omit zero and not-applicable counters, or collapse them into one "Nothing
69
+ outstanding" line.
70
+ - Do not explain the interface on the page. A description states scope or
71
+ as-of time, not instructions.
72
+
73
+ ## Density follows the audience
74
+
75
+ - **Queues** for operators: compact rows, more records per screen, identity,
76
+ state and amount; detail on open.
77
+ - **Overviews**: fewer, larger figures with room around them, each answering a
78
+ question.
79
+ - **Records**: the subject leads; evidence and history follow.
80
+
81
+ Change global density through the provider and density roots described in
82
+ [theming](theming.md). Do not shrink text roles to fit more data; remove
83
+ low-value content first.
84
+
85
+ ## Rhythm groups content
86
+
87
+ - Gaps grow outward: within a group, between groups, between sections. Equal
88
+ gaps everywhere mean nothing groups. Use `Stack` and `Grid` gap roles.
89
+ - Few edges: peer regions share content start edges; numbers right-align on one
90
+ axis; labels share one axis.
91
+ - Few frames: one `Card` per independent subject. Continuous sections of one
92
+ subject share one surface and are separated by space, not rules or nested
93
+ boxes.
94
+ - Narrow widths keep the decision content first in reading order. Only data
95
+ tables that own horizontal scrolling may scroll sideways.
96
+
97
+ ## Numbers and copy
98
+
99
+ - Numbers use tabular figures through the value primitives (`Money`, `Number`,
100
+ `Percent`, `Date`, `RelativeTime`) with one precision per column.
101
+ - Recency reads as relative time with the exact date available; documents show
102
+ absolute dates.
103
+ - A delta states direction and baseline: "↓ 0.9% vs September".
104
+ - Sentence case everywhere. Buttons are a verb and an object ("Record payment").
105
+ Empty states say what is missing and what to do. Errors say what happened and
106
+ how to recover.
107
+
108
+ ## Modern patterns and their owners
109
+
110
+ - **Overview.** A header with the period control, one figure strip (three to
111
+ five figures with deltas or sparklines), one chart answering the main
112
+ question, and a "needs attention" list that links to records. Not a wall of
113
+ identical cards.
114
+ - **Index.** Search plus the work queues users actually work; rows lead with
115
+ identity and the deciding column; bulk actions appear with a selection;
116
+ export states how many rows match.
117
+ - **Record.** The page header carries identity, status badges in `titleSuffix`,
118
+ one metadata line (date · channel · customer) and the primary command. The
119
+ main column holds the subject's working content, an aside holds context
120
+ (customer, payment, notes) and history comes last.
121
+ - **Editing.** `InlineEdit` for one field; `ActionDrawer` for a focused
122
+ multi-field edit that keeps the record visible; `ActionDialog` for short
123
+ creation; `ConfirmDialog` for destructive commands.
124
+ - **Progressive disclosure.** `Collapsible` or `Accordion` for evidence and
125
+ technical detail; overflow menus for rare commands.
126
+ - **Loading.** Owners' loading states and `Skeleton` shaped like the content,
127
+ not spinners in empty boxes.
128
+
129
+ Inspect each owner's declaration before using it; a pattern names a direction,
130
+ not a prop list.
131
+
132
+ ## Anti-patterns seen in trials
133
+
134
+ - A grid of identical metric cards whose figures have no baseline.
135
+ - A facts card that repeats the header's identifier, status and date.
136
+ - Every lifecycle counter on every line, zeros included.
137
+ - Column headers repeated in cells; units on every value.
138
+ - Filler cards added to balance a column's whitespace.
139
+ - Decorative icons on titles, rows or badges; tinted icon tiles.
140
+ - Status tones on kinds or categories; three badges on one row saying related
141
+ things.
142
+ - A storefront hero image inside an operational editor.
143
+ - A framed box inside a card for sub-content that is not a distinct object.
144
+ - A chart of three values, or a chart whose question cannot be stated.
145
+ - Prose explaining what the screen does.
146
+
147
+ ## When an owner limits the view
148
+
149
+ When an owner cannot express the hierarchy the data needs, compose its public
150
+ parts or app markup with token-backed utilities
151
+ ([domain structures](domain-structures.md)) and report the gap by owner and
152
+ prop. Never override anatomy classes, add colours or add tokens to make a view
153
+ look designed.
@@ -0,0 +1,73 @@
1
+ # View spec
2
+
3
+ Write this before JSX for a new view or a substantial redesign. Keep it short
4
+ enough to read in a minute; it is a working note, not an approval document. Every
5
+ line should change a later decision. Save it beside the app's other design notes
6
+ so a reviewer can compare the result with the intent.
7
+
8
+ ```md
9
+ # <View name> (<route>)
10
+
11
+ ## Decision
12
+ <who> decides <what>, <how often>. Success: <what they can do faster or with more confidence>.
13
+
14
+ ## Data brief
15
+ <the data brief from data-reading.md>
16
+
17
+ ## Ranked information
18
+ - Must (first viewport at 390 and 1440): …
19
+ - Should (visible without interaction): …
20
+ - Could (behind disclosure, overflow or a detail view): …
21
+ - Omit: … (why: zero, not applicable, duplicated elsewhere, not used for this decision)
22
+
23
+ ## Focal point
24
+ <the one element the eye reaches first, and why>
25
+
26
+ ## Wireframes
27
+ 1440:
28
+ ┌──────────────────────────────────────────────┐
29
+ │ Title · status [secondary] [Primary]│
30
+ │ meta · meta · meta │
31
+ ├──────────────────────────────┬───────────────┤
32
+ │ main subject │ context │
33
+ │ … │ … │
34
+ └──────────────────────────────┴───────────────┘
35
+
36
+ 390:
37
+ ┌────────────────────┐
38
+ │ Title · status │
39
+ │ [Primary] [⋯] │
40
+ │ main subject │
41
+ │ context │
42
+ └────────────────────┘
43
+
44
+ ## Encodings
45
+ | Fact | Encoding | Why |
46
+ | --- | --- | --- |
47
+
48
+ ## Owners
49
+ | Region | Owner | Exact import | Verified with |
50
+ | --- | --- | --- | --- |
51
+ (found with find-components.mjs and map-composition.mjs; props checked with inspect-component.mjs)
52
+
53
+ ## Commands
54
+ <command: scope, emphasis (primary, secondary, overflow), eligibility and disabled reason>
55
+
56
+ ## States
57
+ Loading: … Empty: … Error and retry: … Accepted: … Long text and narrow parent: …
58
+
59
+ ## Open questions and data gaps
60
+ …
61
+ ```
62
+
63
+ ## Notes
64
+
65
+ - Draw wireframes in text so they survive any editor and diff. Boxes show
66
+ regions and order, not pixel sizes.
67
+ - The ranked list is where most quality comes from. If "must" has more than
68
+ five items, the decision is not specific enough yet.
69
+ - Fill "Owners" only after running the finder and inspector. An owner that does
70
+ not fit is recorded with the reason, and the region becomes app markup over
71
+ public parts.
72
+ - After building, score the result with the [critique rubric](critique-rubric.md)
73
+ and note any departure from this spec with its reason.
@@ -122,8 +122,15 @@ definitions; the app then chooses appropriate destination focus.
122
122
  Use `Page` from `themelia-react-ui/layout/page` for the record route's identity,
123
123
  back navigation, content bounds, commands and section tabs. Pass the record's
124
124
  main command as `header.primaryAction`, supporting commands as
125
- `header.secondaryActions` and sections as `header.tabs`; one status badge goes in
126
- `header.titleBadges`. `PageHeader` serves a custom shell; `PageActions` is
125
+ `header.secondaryActions` and separately selected/routed sections as `header.tabs`;
126
+ continuous sections can stay in the body. One status badge goes in
127
+ `header.slots.titleSuffix` as a composed Badge. Place supporting facts in
128
+ `header.slots.afterDescription` as a MetadataList when useful. The four header
129
+ slots (`beforeTitle`, `titleSuffix`, `afterDescription`, `actions`) accept content
130
+ or a callback receiving `{ renderLink, defaultContent }`; an actions callback
131
+ can wrap or return `defaultContent` to retain responsive commands. A replacement
132
+ owns its behavior. Below 40rem of actual header width, all commands, including
133
+ primary, share one More actions trigger. `PageHeader` serves a custom shell; `PageActions` is
127
134
  deprecated. The [layout recipe](../examples/app-layout.tsx) demonstrates that
128
135
  route boundary; the [detail recipe](../examples/detail.tsx) demonstrates the
129
136
  record route and an independently framed subject with MetadataList and value
@@ -184,6 +184,25 @@ export function analyzeComposition(text, { filename, index, ts }) {
184
184
  if (ts.isJsxElement(element.parent)) element.parent.children.forEach(collect);
185
185
  return found;
186
186
  };
187
+ // Static region children only: inspect known passive wrappers and providers,
188
+ // never assume an opaque app component renders its lexical children.
189
+ const regionElements = (opening, deep = false) => {
190
+ const found = [];
191
+ const collect = (child, scope = opening, subject) => {
192
+ if (ts.isJsxFragment(child)) { child.children.forEach(item => collect(item, scope, subject)); return; }
193
+ if (ts.isJsxExpression(child)) { const value = resolve(child.expression); if (value) collect(value, scope, subject); return; }
194
+ const node = ts.isJsxElement(child) ? child.openingElement : ts.isJsxSelfClosingElement(child) ? child : undefined;
195
+ if (!node) return;
196
+ const owner = ownerFor(node.tagName);
197
+ found.push({node, owner, tag: node.tagName.getText(source), scope, subject});
198
+ const provider = isOwner(owner, 'features/filters', ['FilterProvider']);
199
+ const card = isOwner(owner, 'base/cards', ['Card', 'SmartCard']);
200
+ // Cards delimit independent subjects; providers delimit query state.
201
+ if (deep && ts.isJsxElement(child) && (/^(div|section|form)$/.test(node.tagName.getText(source)) || isOwner(owner, 'base/structure', ['Stack', 'Grid', 'AdaptiveGrid', 'GridCell']) || card || provider)) child.children.forEach(item => collect(item, provider ? node : scope, card ? node : subject));
202
+ };
203
+ if (ts.isJsxElement(opening.parent)) opening.parent.children.forEach(child => collect(child));
204
+ return found;
205
+ };
187
206
  const renderedText = element => ts.isJsxElement(element) ? element.children.map(child => ts.isJsxText(child) ? child.text : ts.isJsxExpression(child) ? literal(child.expression) ?? '' : '').join(' ').trim() : '';
188
207
  const slotBadge = expression => {
189
208
  const node = resolve(expression);
@@ -342,7 +361,7 @@ export function analyzeComposition(text, { filename, index, ts }) {
342
361
  if (modalRole || scrim) add(node, 'raw-overlay-primitive', 'warning', `A hand-rolled ${modalRole ? 'dialog' : 'full-screen layer'} must own focus, dismissal, pending state and theming itself. ${overlayRemedy}`);
343
362
  if (/^(?:input|textarea)$/.test(node.tagName.getText(source))) {
344
363
  const props = new Map(attributes(node));
345
- if (props.has('className') && classStrings(props.get('className')).flatMap(value=>value.split(/\s+/)).some(value=>replacesSharedRadius(value,'inner'))) add(node,'shared-radius','error','Native editable controls follow bounded rounded-inner; change the global theme root, not per-field corners.');
364
+ if (props.has('className') && classStrings(props.get('className')).flatMap(value=>value.split(/\s+/)).some(value=>replacesSharedRadius(value,'radius'))) add(node,'shared-radius','error','Native editable controls follow bounded rounded-radius; change the global theme root, not per-field corners.');
346
365
  if (props.has('style') && properties(props.get('style')).some(([name])=>radiusProperty.test(name))) add(node,'shared-radius','error','Native editable corners belong to the global radius root, not inline styles.');
347
366
  }
348
367
  if (nativeDisplayNames.test(node.tagName.getText(source))) {
@@ -375,7 +394,7 @@ export function analyzeComposition(text, { filename, index, ts }) {
375
394
  const focusDrift = focusRingDrift(tokens);
376
395
  if ((anatomy || forwarder && name === 'contentClassName') && classes.some(value => paddingClass.test(value))) add(node, 'surface-padding', 'error', `${owner.symbol}: use inset/type/density and public regions; padding overrides replace owned anatomy.`);
377
396
  if (control && name === 'className' && classes.some(value => fixedControlClass.test(value))) add(node, 'control-anatomy', 'error', `${owner.symbol}: use its size/variant props; preserve shared control height, inset, corners and typography.`);
378
- if ((name === 'className' && (control || sharedCorners) || name === 'contentClassName' && forwarder) && classes.some(value=>replacesSharedRadius(value, control && name === 'className' ? 'inner' : cornerRole(family,owner.symbol)))) add(node,'shared-radius','error',`${owner.symbol}: outer shells use rounded-radius; controls and collection rows use bounded rounded-inner. Preserve the owning role and joined-edge resets.`);
397
+ if ((name === 'className' && (control || sharedCorners) || name === 'contentClassName' && forwarder) && classes.some(value=>replacesSharedRadius(value, control && name === 'className' ? 'radius' : cornerRole(family,owner.symbol)))) add(node,'shared-radius','error',`${owner.symbol}: outer shells use rounded-surface; controls and collection rows use bounded rounded-radius. Preserve the owning role and joined-edge resets.`);
379
398
  if (display && classes.some(addsCopyMargin)) add(node,'copy-margin','error',`${owner.symbol}: typography is margin-free; use textGap on the headed owner or gap on Stack/Grid.`);
380
399
  if (textContent && name === 'className' && tokens.some(token=>fadedText(token)||textOpacityDrift(token))) add(node,'faded-text','error',`${owner.symbol}: use its semantic type instead of adding an opacity tier to the text. Presence endpoints and shared disabled state remain valid.`);
381
400
  if ((control || family === 'buttons' && owner.symbol === 'TextButton') && name === 'className' && focusDrift.length) add(node, 'focus-ring-recipe', 'error', `${owner.symbol}: keep the shared focus indicator (a ring-3 halo of ring-ring/50 around a full-strength ring edge); ${[...new Set(focusDrift)].join(', ')} redraws it.`);
@@ -404,6 +423,23 @@ export function analyzeComposition(text, { filename, index, ts }) {
404
423
  }
405
424
  if (isOwner(owner, 'base/feedback', ['Empty'])) add(node, 'reinvented-empty-state', 'warning', 'Empty exposes lower-level anatomy. Compare EmptyState from blocks/data-display for a routine no-data/no-results region; keep Empty when custom anatomy is required.');
406
425
  if (isOwner(owner, 'base/sheet', ['Sheet', 'SheetContent']) || isOwner(owner, 'base/display', ['Dialog', 'DialogContent', 'AlertDialog', 'AlertDialogContent'])) add(node, 'raw-overlay-primitive', 'warning', 'This lower-level modal needs application lifecycle coordination. Prefer ActionDialog, ConfirmDialog or ActionDrawer from features/overlays when their workflow fits.');
426
+ if (isOwner(owner, 'features/table', ['DataTable'])) {
427
+ const parent = parents.at(-1);
428
+ let ancestor = ts.isJsxOpeningElement(node) ? node.parent.parent : node.parent;
429
+ while (ancestor && !ts.isJsxElement(ancestor)) ancestor = ancestor.parent;
430
+ const directOwner = ancestor && ownerFor(ancestor.openingElement.tagName);
431
+ if (isOwner(directOwner, 'base/cards', ['Card', 'SmartCard']) && isOwner(parent?.owner, 'base/cards', ['Card', 'SmartCard']) && literal(parent.props.get('padding')) !== 'none' && !parent.unknownProps) add(node, 'uncontained-table-in-card', 'warning', 'DataTable owns its surface, topbar and edge-to-edge header band. Render it directly in Page or a layout region; a deliberate Card host must use padding="none".');
432
+ }
433
+ const routeOwner = isOwner(owner, 'layout/page', ['Page']) || isOwner(owner, 'layout', ['Page']);
434
+ if (routeOwner) {
435
+ const children = regionElements(node);
436
+ const contents = regionElements(node, true);
437
+ const tables = contents.filter(child => isOwner(child.owner, 'features/table', ['DataTable']));
438
+ for (const child of contents) if (isOwner(child.owner, 'features/filters', ['FilterLayout']) && tables.some(table => table.scope === child.scope && (!child.subject || table.subject === child.subject))) add(child.node, 'detached-filter-layout', 'warning', 'Pass FilterLayout into DataTable topbarContent with variant="compact", or use DataView so filters and table chrome share one surface.');
439
+ const hasAsideSlot = properties(props.get('slots'), false).some(([name]) => name === 'aside');
440
+ const onlyForms = children.length > 0 && children.every(child => child.tag === 'form' || isOwner(child.owner, 'base/forms', ['FormSection']));
441
+ if (onlyForms && !unknownProps && !['narrow', 'maxWidth', 'aside'].some(name => props.has(name)) && !hasAsideSlot) add(node, 'wide-single-column-form', 'warning', 'A single-column form should use Page narrow (48rem centered), an explicit maxWidth, or a supporting aside so fields do not stretch across the default route measure.');
442
+ }
407
443
  if (owner.symbol === 'Page' && literal(props.get('gutter')) === 'none' && !parents.some(parent => parent.framed)) add(node, 'page-gutter', 'warning', 'Page gutter="none" delegates inline padding to a real parent. PageViewport owns scrolling, not padding; verify the parent inset.');
408
444
  if (owner.symbol === 'Card' && framed && literal(props.get('padding')) === 'sm' && !parents.some(parent => parent.framed)) add(node, 'compact-card', 'warning', 'Standalone Card padding="sm" halves the normal inset. Omit padding for ordinary subjects; retain sm only for an intentional compact composition.');
409
445
  const peers = parents.findLast(parent => parent.structure);
@@ -432,7 +468,7 @@ export function analyzeComposition(text, { filename, index, ts }) {
432
468
  const title = literal(props.get('title')) ?? literal(new Map(header).get('title'));
433
469
  if (title && parents.some(parent => parent.title === title)) add(node, 'duplicate-heading', 'warning', `The heading "${title}" repeats its ancestor. Keep one route/subject title unless a distinct task warrants repetition.`);
434
470
  const structure = owner.import === `${index.package}/base/structure` && Object.hasOwn(structureDefaults, owner.symbol);
435
- return { framed, title, structure, cards: structure ? peerCards(node) : new Set(), smallGap: structure ? smallGap(props, owner.symbol, unknownProps) : false };
471
+ return { owner, props, unknownProps, framed, title, structure, cards: structure ? peerCards(node) : new Set(), smallGap: structure ? smallGap(props, owner.symbol, unknownProps) : false };
436
472
  }
437
473
  visit(source);
438
474
  return { findings, unresolved };
@@ -0,0 +1,2 @@
1
+ /** Pure metadata validator shared by the preview and dependency-free consumer tools. */
2
+ export function validateMappings(value: unknown): unknown[];
@@ -0,0 +1,32 @@
1
+ const record = value => value !== null && typeof value === 'object' && !Array.isArray(value) && [Object.prototype, null].includes(Object.getPrototypeOf(value));
2
+ const fail = (condition, message) => { if (!condition) throw new Error(`Invalid composition mapping: ${message}`); };
3
+ const name = value => typeof value === 'string' && /^[A-Za-z][A-Za-z0-9]*$/.test(value);
4
+ const uniqueList = (value, valid, maximum) => Array.isArray(value) && value.length <= maximum && value.every(valid) && new Set(value).size === value.length;
5
+ const scalar = value => value === null || typeof value === 'boolean' || (typeof value === 'string' && value.length <= 500) || (typeof value === 'number' && Number.isFinite(value));
6
+ const kinds = ['shell', 'page', 'layout', 'surface', 'content', 'workflow'];
7
+ const placements = ['region', 'toolbar', 'cell', 'overlay'];
8
+ const surfaces = ['none', 'parent', 'self', 'variant'];
9
+
10
+ /** One literal metadata shape shared by authored catalogue and copied tools. */
11
+ export function validateMappings(mappings) {
12
+ fail(Array.isArray(mappings) && mappings.length <= 64, 'expected an array of at most 64 mappings');
13
+ for (const mapping of mappings) {
14
+ fail(record(mapping), 'expected a plain mapping object');
15
+ fail(Object.keys(mapping).every(key => ['symbol', 'roles', 'kind', 'placement', 'surface', 'slots', 'props', 'routeSlot'].includes(key)), 'unknown mapping field');
16
+ fail(typeof mapping.symbol === 'string' && /^[A-Z][A-Za-z0-9]*$/.test(mapping.symbol), 'symbol must be an exact public component name');
17
+ fail(uniqueList(mapping.roles, value => typeof value === 'string' && /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(value), 8) && mapping.roles.length > 0, `${mapping.symbol}: use 1..8 distinct kebab-case roles`);
18
+ fail(kinds.includes(mapping.kind), `${mapping.symbol}: invalid kind`);
19
+ fail(placements.includes(mapping.placement), `${mapping.symbol}: invalid placement`);
20
+ fail(surfaces.includes(mapping.surface), `${mapping.symbol}: invalid surface`);
21
+ if (mapping.slots !== undefined) fail(uniqueList(mapping.slots, name, 16), `${mapping.symbol}: invalid or duplicate slots`);
22
+ if (mapping.routeSlot !== undefined) fail(mapping.kind === 'shell' && name(mapping.routeSlot) && (mapping.slots ?? []).includes(mapping.routeSlot), `${mapping.symbol}: routeSlot must name a mapped shell insertion slot`);
23
+ if (mapping.props !== undefined) {
24
+ fail(record(mapping.props) && Object.keys(mapping.props).length <= 16, `${mapping.symbol}: props must be a small literal object`);
25
+ for (const [key, value] of Object.entries(mapping.props)) {
26
+ fail(/^[A-Za-z][\w-]*$/.test(key) && !['__proto__', 'constructor', 'prototype'].includes(key) && scalar(value), `${mapping.symbol}: invalid literal prop ${key}`);
27
+ fail(!(mapping.slots ?? []).includes(key), `${mapping.symbol}: ${key} cannot be both an insertion slot and a fixed prop`);
28
+ }
29
+ }
30
+ }
31
+ return mappings;
32
+ }
@@ -0,0 +1,254 @@
1
+ import {validateIndex} from './discovery.mjs';
2
+ import {validateComponentContracts} from './inspection.mjs';
3
+ import {validateMappings} from './composition-schema.mjs';
4
+
5
+ const fail = (condition, message) => { if (!condition) throw new Error(message); };
6
+ const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
7
+ const unique = values => [...new Set(values)].sort(compare);
8
+ const patterns = ['record-detail', 'collection', 'edit', 'analytics', 'embedded'];
9
+ const roleKey = value => value.trim().toLowerCase().replace(/\s+/g, '-');
10
+ const identity = mapping => `${mapping.import}#${mapping.symbol}`;
11
+ const stopWords = new Set(['and', 'for', 'the', 'with', 'from', 'into', 'show', 'list', 'page']);
12
+ const roleTokens = value => value.toLowerCase().split(/[^a-z0-9]+/).filter(token => token.length > 2 && !stopWords.has(token)).map(token => token.length > 3 && token.endsWith('s') ? token.slice(0, -1) : token);
13
+
14
+ /** Nearby mapped roles for a phrase that matched none. Hints only: the need stays unresolved. */
15
+ function suggestRoles(mappings, request, limit = 5) {
16
+ if (/^[A-Z][A-Za-z0-9]*$/.test(request) || /[\/#]/.test(request)) return [];
17
+ const wanted = new Set(roleTokens(request));
18
+ return unique(mappings.flatMap(mapping => mapping.roles))
19
+ .map(role => ({role, shared: roleTokens(role).filter(token => wanted.has(token)).length}))
20
+ .filter(candidate => candidate.shared > 0)
21
+ .sort((a, b) => b.shared - a.shared || a.role.length - b.role.length || compare(a.role, b.role))
22
+ .slice(0, limit).map(candidate => candidate.role);
23
+ }
24
+
25
+ function publicProps(contract, contracts) {
26
+ const inherited = contracts.nativeProfiles[contract.inheritedProfile] ?? {};
27
+ return Object.assign(Object.create(null), Object.fromEntries(Object.entries(inherited).map(([key, value]) => [key, typeof value === 'string' ? contracts.nativeProperties[value] : value])), contract.props);
28
+ }
29
+
30
+ /** Resolve authored rows against the same qualified contracts as API inspection. */
31
+ export function validateCompositionMappings(index, contracts) {
32
+ validateIndex(index);
33
+ validateComponentContracts(contracts, index);
34
+ const byContract = new Map(contracts.contracts.map(contract => [identity(contract), contract]));
35
+ const seen = new Set();
36
+ const mappings = [];
37
+ for (const family of index.families) for (const guidance of family.guidance) {
38
+ for (const mapping of validateMappings(guidance.composition?.mappings ?? [])) {
39
+ const key = `${family.import}#${mapping.symbol}`;
40
+ fail(!seen.has(key), `Duplicate composition mapping: ${key}`); seen.add(key);
41
+ fail(family.symbols.includes(mapping.symbol), `Composition mapping is not a public export: ${key}`);
42
+ fail(!Object.hasOwn(family.deprecated ?? {}, mapping.symbol), `Composition mapping uses a deprecated export: ${key}`);
43
+ const contract = byContract.get(key);
44
+ fail(contract, `Composition mapping has no callable component contract: ${key}`);
45
+ const props = publicProps(contract, contracts);
46
+ for (const slot of mapping.slots ?? []) {
47
+ fail(props[slot], `Unknown composition slot ${slot} on ${key}`);
48
+ fail(/\b(?:ReactNode|ReactElement)\b|JSX\.Element/.test(props[slot].type), `Composition slot ${slot} on ${key} is not a documented React insertion prop`);
49
+ }
50
+ for (const prop of Object.keys(mapping.props ?? {})) fail(props[prop], `Unknown composition prop ${prop} on ${key}`);
51
+ const recipes = (family.recipes ?? []).filter(recipe => recipe.symbols.includes(mapping.symbol));
52
+ mappings.push({...mapping, import: family.import, declaration: family.declaration, optionalPeers: family.optionalPeers,
53
+ guidance, nextReads: {declaration: family.declaration,
54
+ inspect: `node scripts/inspect-component.mjs ${mapping.symbol} --import ${family.import}`,
55
+ references: unique([...(family.references ?? []), ...recipes.flatMap(recipe => recipe.references)]),
56
+ examples: recipes.map(({file, exports, optionalPeers = []}) => ({file, exports, optionalPeers})),
57
+ }});
58
+ }
59
+ }
60
+ return mappings.sort((a, b) => compare(identity(a), identity(b)));
61
+ }
62
+
63
+ function validateOptions(options) {
64
+ const value = {...options, main: options.main ?? [], aside: options.aside ?? [], limit: options.limit ?? 3};
65
+ fail(Number.isInteger(value.limit) && value.limit >= 1 && value.limit <= 10, 'Invalid limit: use 1..10');
66
+ fail(Number(value.roles === true) + Number(value.role !== undefined) + Number(value.pattern !== undefined) === 1, 'Choose one mode: --roles, --role or --pattern');
67
+ for (const region of ['main', 'aside']) fail(Array.isArray(value[region]) && value[region].length <= 24 && value[region].every(need => typeof need === 'string' && need.trim().length > 0 && need.length <= 300), `Invalid ${region} needs; use up to 24 explicit role tags or qualified selectors`);
68
+ if (value.pattern !== undefined) {
69
+ fail(patterns.includes(value.pattern), `Invalid pattern: choose ${patterns.join(', ')}`);
70
+ fail(value.main.length + value.aside.length > 0, 'A plan needs at least one --main or --aside requirement');
71
+ } else {
72
+ fail(value.main.length + value.aside.length === 0, 'Main/aside needs require --pattern');
73
+ if (value.role !== undefined) fail(typeof value.role === 'string' && value.role.trim().length > 0, 'A nonempty role is required');
74
+ }
75
+ if (value.parent !== undefined) fail(value.pattern === 'embedded' && typeof value.parent === 'string' && /^[A-Z][A-Za-z0-9]*$/.test(value.parent), '--parent must be an exact component name with --pattern embedded');
76
+ if (value.publicImport !== undefined) fail(value.parent !== undefined && typeof value.publicImport === 'string' && value.publicImport.length > 0, '--import qualifies an explicit embedded --parent');
77
+ return value;
78
+ }
79
+
80
+ export function parseCompositionArguments(args) {
81
+ const options = {main: [], aside: [], limit: 3};
82
+ const seen = new Set();
83
+ for (let index = 0; index < args.length; index++) {
84
+ const arg = args[index];
85
+ fail(['--roles', '--role', '--pattern', '--main', '--aside', '--parent', '--import', '--limit'].includes(arg), `Unknown argument: ${arg}`);
86
+ fail(['--main', '--aside'].includes(arg) || !seen.has(arg), `Duplicate argument: ${arg}`); seen.add(arg);
87
+ if (arg === '--roles') { options.roles = true; continue; }
88
+ const value = args[++index];
89
+ fail(typeof value === 'string' && value.trim() && !value.startsWith('--'), `Missing value for ${arg}`);
90
+ if (arg === '--main' || arg === '--aside') options[arg.slice(2)].push(value.trim());
91
+ else if (arg === '--limit') { fail(/^[1-9]\d*$/.test(value), 'Invalid limit: use 1..10'); options.limit = Number(value); }
92
+ else options[arg === '--import' ? 'publicImport' : arg.slice(2)] = value.trim();
93
+ }
94
+ validateOptions(options);
95
+ return options;
96
+ }
97
+
98
+ function candidate(mapping) {
99
+ return {import: mapping.import, symbol: mapping.symbol, roles: mapping.roles, kind: mapping.kind,
100
+ placement: mapping.placement, surface: mapping.surface, slots: mapping.slots ?? [], props: mapping.props ?? {},
101
+ ...(mapping.routeSlot ? {routeSlot: mapping.routeSlot} : {}),
102
+ optionalPeers: mapping.optionalPeers, applicationOwns: mapping.guidance.appOwned,
103
+ chooseWhen: mapping.guidance.chooseWhen, avoidWhen: mapping.guidance.avoidWhen, nextReads: mapping.nextReads};
104
+ }
105
+
106
+ /** Exact roles and explicit regions yield an advisory structure, never guessed APIs. */
107
+ export function mapComposition(index, contracts, rawOptions) {
108
+ const options = validateOptions(rawOptions);
109
+ const mappings = validateCompositionMappings(index, contracts);
110
+ const base = {package: index.package, version: index.version, advisory: true,
111
+ baselinePeers: unique((index.peers ?? []).filter(peer => !peer.optional).map(peer => peer.name)),
112
+ peerScope: 'requiredPeers covers selected-family optional peers; baselinePeers apply to every consumer'};
113
+ const matches = request => request.includes('#')
114
+ ? mappings.filter(mapping => identity(mapping) === request)
115
+ : /^[A-Z][A-Za-z0-9]*$/.test(request) || /[\/#]/.test(request) ? []
116
+ : mappings.filter(mapping => mapping.roles.includes(roleKey(request)));
117
+ if (options.roles) {
118
+ const roles = unique(mappings.flatMap(mapping => mapping.roles)).map(role => ({role, owners: mappings.filter(mapping => mapping.roles.includes(role)).length}));
119
+ return {...base, mode: 'roles', total: roles.length, roles};
120
+ }
121
+ if (options.role !== undefined) {
122
+ const found = matches(options.role);
123
+ const suggestions = found.length ? [] : suggestRoles(mappings, options.role);
124
+ return {...base, mode: 'lookup', status: found.length ? 'mapped' : 'unresolved', query: options.role, total: found.length,
125
+ results: found.slice(0, options.limit).map(candidate), omittedResults: Math.max(0, found.length - options.limit),
126
+ ...(suggestions.length ? {suggestedRoles: suggestions} : {})};
127
+ }
128
+
129
+ const unresolved = [], warnings = [], selected = [];
130
+ const node = (mapping, decision = 'none') => {
131
+ selected.push(mapping);
132
+ return {import: mapping.import, symbol: mapping.symbol, kind: mapping.kind, surface: mapping.surface,
133
+ surfaceDecision: decision, props: {...mapping.props}, slots: {}};
134
+ };
135
+ const issue = (request, region, reason, found = [], suggest = false) => {
136
+ // Only a phrase that matched no role gets hints; structural failures of a
137
+ // mapped role already name their candidates.
138
+ const suggestions = suggest ? suggestRoles(mappings, request) : [];
139
+ unresolved.push({request, region, reason, totalCandidates: found.length, candidates: found.slice(0, options.limit).map(candidate), ...(suggestions.length ? {suggestedRoles: suggestions} : {})});
140
+ };
141
+ const resolve = (request, region, found = matches(request)) => {
142
+ if (found.length !== 1) { issue(request, region, found.length ? 'Role is ambiguous; select an exact import#symbol or a more specific mapped role.' : 'No exact mapping covers this requirement. Retry with one of suggestedRoles when it names the same job, or use --roles or the component finder; do not infer an API.', found, !found.length); return null; }
143
+ return found[0];
144
+ };
145
+ const insertion = (mapping, slot, request, region) => {
146
+ if (!(mapping.slots ?? []).includes(slot)) { issue(request, region, `${mapping.symbol} has no mapped ${slot} insertion slot. Inspect its API rather than nesting into an invented prop.`, [mapping]); return false; }
147
+ return true;
148
+ };
149
+ const structure = (role, kind, slots, region = 'structure') => {
150
+ const mapping = resolve(role, region);
151
+ if (!mapping) return null;
152
+ if (mapping.kind !== kind || mapping.placement !== 'region' || (kind === 'surface' && mapping.surface !== 'self')) {
153
+ issue(role, region, `The ${role} mapping does not establish the required ${kind} boundary. Inspect the authored mapping.`, [mapping]); return null;
154
+ }
155
+ if (!slots.every(slot => insertion(mapping, slot, role, region))) return null;
156
+ return mapping;
157
+ };
158
+ let rootMapping = null, root = null, host = null, mainSlot = 'main', asideSlot = 'aside';
159
+ if (options.pattern === 'embedded') {
160
+ if (options.parent) {
161
+ rootMapping = resolve(options.parent, 'structure', mappings.filter(mapping => mapping.symbol === options.parent && (!options.publicImport || mapping.import === options.publicImport)));
162
+ if (rootMapping && rootMapping.placement !== 'region') { issue(options.parent, 'structure', 'This parent belongs to a renderer or overlay boundary, not a subject region.', [rootMapping]); rootMapping = null; }
163
+ if (rootMapping) {
164
+ root = host = node(rootMapping, rootMapping.surface === 'self' ? 'existing-surface' : rootMapping.surface === 'variant' ? 'inspect-variant-host' : 'existing-host');
165
+ mainSlot = (rootMapping.slots ?? []).includes('children') ? 'children' : 'main';
166
+ if (rootMapping.surface === 'variant') warnings.push({code: 'variant-host-surface', message: `${rootMapping.symbol} may already provide framing in its current variant or state. Inspect its contract and existing ancestors before composing another surface.`});
167
+ }
168
+ } else warnings.push({code: 'host-ownership-unverified', message: 'Embedded requirements retain the caller\'s host. Confirm its insertion slot, framing, padding and gaps; no Page or new surface was added.'});
169
+ } else {
170
+ rootMapping = structure('route', 'page', ['children']);
171
+ if (rootMapping) {
172
+ root = host = node(rootMapping);
173
+ if (!options.aside.length && ['edit', 'record-detail'].includes(options.pattern)) {
174
+ const contract = contracts.contracts.find(contract => identity(contract) === identity(rootMapping));
175
+ if (publicProps(contract, contracts).narrow) root.props.narrow = true;
176
+ }
177
+ }
178
+ mainSlot = 'children';
179
+ if (rootMapping && options.aside.length && !(rootMapping.slots ?? []).includes('aside')) {
180
+ const layout = structure('main-support-layout', 'layout', ['main', 'aside']);
181
+ if (layout && insertion(rootMapping, 'children', 'main-support-layout', 'structure')) {
182
+ host = node(layout); root.slots.children = [host]; rootMapping = layout; mainSlot = 'main';
183
+ } else host = null;
184
+ }
185
+ }
186
+
187
+ let resolved = 0;
188
+ const regions = {main: [], aside: []};
189
+ const toolbars = [], placements = [], contextualized = new Set();
190
+ for (const region of ['main', 'aside']) for (const request of options[region]) {
191
+ const mapping = resolve(request, region);
192
+ if (!mapping) continue;
193
+ if (mapping.placement === 'toolbar') { toolbars.push({mapping, request, region}); continue; }
194
+ if (mapping.placement !== 'region') { issue(request, region, mapping.placement === 'cell' ? 'This owner belongs in a table/collection renderer, not directly in a subject region.' : 'This owner belongs at the app/feature overlay boundary; open it through callbacks.', [mapping]); continue; }
195
+ const slot = region === 'main' ? mainSlot : asideSlot;
196
+ if (['page', 'shell'].includes(mapping.kind) && !(options.pattern === 'embedded' && rootMapping?.routeSlot === slot && mapping.kind === 'page')) { issue(request, region, 'A page or shell is not an independent content subject. Only an explicit route-host slot may receive a Page; keep one route title/gutter owner.', [mapping]); continue; }
197
+ if ((!host && options.pattern !== 'embedded') || (!host && options.parent)) { issue(request, region, 'The structural owner is unresolved, so this requirement has not been placed.', [mapping]); continue; }
198
+ if (host && !insertion(rootMapping, slot, request, region)) continue;
199
+ let child;
200
+ const insideSurface = rootMapping?.surface === 'self';
201
+ if (mapping.surface === 'parent' && host && !insideSurface && options.pattern !== 'embedded') {
202
+ const frame = structure('subject-surface', 'surface', ['children'], region);
203
+ if (!frame) continue;
204
+ child = node(frame, 'recommended-frame');
205
+ child.slots.children = [node(mapping, 'uses-parent')];
206
+ } else {
207
+ child = node(mapping, mapping.surface === 'self' ? 'owns-surface' : mapping.surface === 'parent' ? insideSurface ? 'uses-parent' : 'caller-surface-unverified' : mapping.surface === 'variant' ? 'inspect-variant' : 'none');
208
+ }
209
+ if (mapping.surface === 'variant') warnings.push({code: 'variant-surface', request, region, message: `${mapping.symbol} owns framing only in some variants or states. Inspect its contract before adding a surface.`});
210
+ if (mapping.surface === 'parent' && options.pattern === 'embedded' && host && !insideSurface) warnings.push({code: 'host-surface-unverified', request, region, message: 'The explicit host does not establish a known surface boundary. Confirm its ancestors before adding framing; no extra Card was added.'});
211
+ if (insideSurface && mapping.surface === 'self') warnings.push({code: 'nested-surface-review', request, region, message: `${mapping.symbol} already owns a surface. Review its supported embedded variant or use an unframed host; no props were guessed.`});
212
+ else if (rootMapping?.surface === 'variant' && mapping.surface === 'self') warnings.push({code: 'nested-surface-review', request, region, message: `${mapping.symbol} owns a surface and its host may also frame it. Inspect both variants before keeping nested surfaces; no embedded props were guessed.`});
213
+ placements.push({mapping, child, region, slot});
214
+ regions[region].push(child);
215
+ if (host) (host.slots[slot] ??= []).push(child);
216
+ resolved++;
217
+ }
218
+ // Toolbars are placed after subjects so request order cannot affect the tree.
219
+ // FilterLayout's context and the table seam are both authored, validated APIs.
220
+ for (const {mapping, request, region} of toolbars) {
221
+ const targets = placements.filter(item => item.region === region && item.mapping.roles.includes('comparison-table') && (item.mapping.slots ?? []).includes('topbarContent'));
222
+ if (targets.length !== 1) { issue(request, region, 'A toolbar needs exactly one mapped comparison table with a topbarContent slot in this region.', targets.map(item => item.mapping)); continue; }
223
+ const target = targets[0];
224
+ let provider;
225
+ if (mapping.symbol === 'FilterLayout') {
226
+ const contexts = mappings.filter(row => row.import === mapping.import && row.symbol === 'FilterProvider' && row.roles.includes('filter-context'));
227
+ if (contexts.length !== 1 || contexts[0].kind !== 'layout' || contexts[0].placement !== 'region' || !(contexts[0].slots ?? []).includes('children')) {
228
+ issue(request, region, 'FilterLayout needs its mapped FilterProvider context with a children insertion contract.', contexts); continue;
229
+ }
230
+ provider = contexts[0];
231
+ }
232
+ const toolbar = node(mapping, 'uses-parent');
233
+ (target.child.slots.topbarContent ??= []).push(toolbar);
234
+ if (provider && !contextualized.has(target.child)) {
235
+ contextualized.add(target.child);
236
+ const wrapped = node(provider, 'context-provider');
237
+ wrapped.slots.children = [target.child];
238
+ const replace = children => { const position = children.indexOf(target.child); if (position >= 0) children[position] = wrapped; };
239
+ replace(regions[region]);
240
+ if (host) replace(host.slots[target.slot] ?? []);
241
+ // Keep subsequent toolbar insertion addressed to the table, not its context.
242
+ }
243
+ resolved++;
244
+ }
245
+ const requested = options.main.length + options.aside.length;
246
+ const selectedMappings = [...new Map(selected.map(mapping => [identity(mapping), mapping])).values()];
247
+ if (options.pattern === 'edit') warnings.push({code: 'native-form-required', message: 'Provide the application-owned native form, validation and awaited submit/save/discard lifecycle. This structural plan does not create form state or transport.'});
248
+ return {...base, mode: 'plan', status: unresolved.length ? resolved ? 'partial' : 'unresolved' : 'mapped', pattern: options.pattern, patternScope: 'structural-context-only',
249
+ tree: root, ...(root ? {} : {regions}), coverage: {requested, resolved, unresolved: requested - resolved}, unresolved,
250
+ requiredPeers: unique(selectedMappings.flatMap(mapping => mapping.optionalPeers)),
251
+ applicationOwns: unique(selectedMappings.flatMap(mapping => mapping.guidance.appOwned)), warnings,
252
+ nextReads: selectedMappings.map(mapping => ({import: mapping.import, symbol: mapping.symbol, ...mapping.nextReads})),
253
+ limits: 'This is an advisory role/slot map. Supply application data, state, callbacks and content; inspect APIs and execute visual/interaction checks before delivery.'};
254
+ }