themelia-react-ui 2.0.2 → 2.0.4

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 (435) hide show
  1. package/CHANGELOG.md +67 -7
  2. package/README.md +70 -37
  3. package/THIRD_PARTY_NOTICES.md +6 -12
  4. package/dist/{accordion-Cjb6sx0G.js → accordion-96o0pN62.js} +5 -5
  5. package/dist/{accordion-Cjb6sx0G.js.map → accordion-96o0pN62.js.map} +1 -1
  6. package/dist/action-menu-CHgs8vmj.js +281 -0
  7. package/dist/action-menu-CHgs8vmj.js.map +1 -0
  8. package/dist/{affordance-geometry.generated-tF36bREk.js → affordance-geometry.generated-B8yGOr8-.js} +7 -1
  9. package/dist/affordance-geometry.generated-B8yGOr8-.js.map +1 -0
  10. package/dist/{ai-artifact-DvTwDVyL.js → ai-artifact-BZUGwBq6.js} +277 -276
  11. package/dist/ai-artifact-BZUGwBq6.js.map +1 -0
  12. package/dist/{app-shell-C4FhvCqF.js → app-shell-D63ATkIK.js} +84 -83
  13. package/dist/app-shell-D63ATkIK.js.map +1 -0
  14. package/dist/{attachment-BxDfL2mw.js → attachment-DkoqHPPl.js} +7 -7
  15. package/dist/{attachment-BxDfL2mw.js.map → attachment-DkoqHPPl.js.map} +1 -1
  16. package/dist/{auth-ax2BqjrI.js → auth-D2FVZ1MH.js} +10 -10
  17. package/dist/{auth-ax2BqjrI.js.map → auth-D2FVZ1MH.js.map} +1 -1
  18. package/dist/{avatar-DAPlDvhJ.js → avatar-DWO_HHhB.js} +5 -5
  19. package/dist/{avatar-DAPlDvhJ.js.map → avatar-DWO_HHhB.js.map} +1 -1
  20. package/dist/{badge-HpFqoqSY.js → badge-DErMA7ul.js} +4 -4
  21. package/dist/{badge-HpFqoqSY.js.map → badge-DErMA7ul.js.map} +1 -1
  22. package/dist/base/accordion.js +1 -1
  23. package/dist/base/action-menu.js +1 -1
  24. package/dist/base/attachment.js +1 -1
  25. package/dist/base/avatar.js +1 -1
  26. package/dist/base/badge.js +1 -1
  27. package/dist/base/batch-action-bar.js +1 -1
  28. package/dist/base/buttons.js +1 -1
  29. package/dist/base/cards.js +2 -2
  30. package/dist/base/carousel.js +3 -3
  31. package/dist/base/cascader.js +13 -13
  32. package/dist/base/chart.js +1 -1
  33. package/dist/base/choice-inputs.js +2 -2
  34. package/dist/base/code-block.js +1 -1
  35. package/dist/base/combobox.js +2 -2
  36. package/dist/base/command.js +1 -1
  37. package/dist/base/copyable.js +1 -1
  38. package/dist/base/date-pickers.js +2 -2
  39. package/dist/base/display.js +6 -6
  40. package/dist/base/feedback.js +3 -3
  41. package/dist/base/forms-numeric.js +1 -1
  42. package/dist/base/forms.js +3 -3
  43. package/dist/base/inline-edit.js +10 -10
  44. package/dist/base/item.js +1 -1
  45. package/dist/base/media-gallery.js +1 -1
  46. package/dist/base/metadata-list.js +1 -1
  47. package/dist/base/navigation.js +6 -6
  48. package/dist/base/popover-menu.js +1 -1
  49. package/dist/base/popover.js +1 -1
  50. package/dist/base/qr-code.js +1 -1
  51. package/dist/base/repeaters.js +9 -9
  52. package/dist/base/sheet.js +1 -1
  53. package/dist/base/sidebar.js +1 -1
  54. package/dist/base/signature-pad.js +6 -6
  55. package/dist/base/skeleton.js +1 -1
  56. package/dist/base/spinner.js +4 -4
  57. package/dist/base/structure.js +1 -1
  58. package/dist/base/table.js +1 -1
  59. package/dist/base/text-inputs.js +2 -2
  60. package/dist/base/toaster.js +3 -3
  61. package/dist/base/tree.js +1 -1
  62. package/dist/base/upload-queue.js +1 -1
  63. package/dist/base/upload.js +3 -3
  64. package/dist/base/value-inputs.js +1 -1
  65. package/dist/{batch-action-bar-DnUJ21NQ.js → batch-action-bar-CdfIkCsV.js} +4 -4
  66. package/dist/{batch-action-bar-DnUJ21NQ.js.map → batch-action-bar-CdfIkCsV.js.map} +1 -1
  67. package/dist/blocks/admin.js +20 -20
  68. package/dist/blocks/admin.js.map +1 -1
  69. package/dist/blocks/ai.js +15 -15
  70. package/dist/blocks/analytics/usage-card.js +1 -1
  71. package/dist/blocks/analytics.js +17 -17
  72. package/dist/blocks/analytics.js.map +1 -1
  73. package/dist/blocks/collaboration.js +1 -1
  74. package/dist/blocks/commerce/receipt.js +1 -1
  75. package/dist/blocks/commerce.js +570 -567
  76. package/dist/blocks/commerce.js.map +1 -1
  77. package/dist/blocks/data-display.js +2 -2
  78. package/dist/blocks/onboarding.js +5 -5
  79. package/dist/blocks/planning.js +11 -11
  80. package/dist/blocks/timelines.js +1 -1
  81. package/dist/{breadcrumbs-C-oqs1sQ.js → breadcrumbs-B-WFKecD.js} +4 -4
  82. package/dist/{breadcrumbs-C-oqs1sQ.js.map → breadcrumbs-B-WFKecD.js.map} +1 -1
  83. package/dist/{button-DVzspB_G.js → button-DkmK-z8E.js} +2 -2
  84. package/dist/{button-DVzspB_G.js.map → button-DkmK-z8E.js.map} +1 -1
  85. package/dist/{buttons-DPZekJFu.js → buttons-BbfzgczK.js} +8 -8
  86. package/dist/{buttons-DPZekJFu.js.map → buttons-BbfzgczK.js.map} +1 -1
  87. package/dist/{cards-BaBZR-AU.js → cards-4JTWqvVe.js} +10 -10
  88. package/dist/cards-4JTWqvVe.js.map +1 -0
  89. package/dist/{chart-ZOYyK2xG.js → chart-C19flDQb.js} +4 -4
  90. package/dist/{chart-ZOYyK2xG.js.map → chart-C19flDQb.js.map} +1 -1
  91. package/dist/{checkbox-AWIhNhmo.js → checkbox-CzYUTPeJ.js} +9 -5
  92. package/dist/checkbox-CzYUTPeJ.js.map +1 -0
  93. package/dist/{choice-inputs-CNHvARCJ.js → choice-inputs-JLtij2y4.js} +182 -176
  94. package/dist/choice-inputs-JLtij2y4.js.map +1 -0
  95. package/dist/{code-block-DeneBJR_.js → code-block-CGNaUtAE.js} +7 -7
  96. package/dist/{code-block-DeneBJR_.js.map → code-block-CGNaUtAE.js.map} +1 -1
  97. package/dist/{collapsible-C-_l4hpy.js → collapsible-Do4G0zcC.js} +3 -3
  98. package/dist/{collapsible-C-_l4hpy.js.map → collapsible-Do4G0zcC.js.map} +1 -1
  99. package/dist/{collection-content-By56pLog.js → collection-content-C0e8SsTm.js} +3 -3
  100. package/dist/{collection-content-By56pLog.js.map → collection-content-C0e8SsTm.js.map} +1 -1
  101. package/dist/{combobox-C0EQW6dr.js → combobox-CBJDs6w_.js} +349 -347
  102. package/dist/combobox-CBJDs6w_.js.map +1 -0
  103. package/dist/{combobox-xCQ2RMNE.js → combobox-hbhSS18O.js} +158 -112
  104. package/dist/combobox-hbhSS18O.js.map +1 -0
  105. package/dist/{command-C25VMRII.js → command-D8NrBj-b.js} +7 -7
  106. package/dist/{command-C25VMRII.js.map → command-D8NrBj-b.js.map} +1 -1
  107. package/dist/{comments-BYYlTA8E.js → comments-Di4w0H_S.js} +383 -382
  108. package/dist/comments-Di4w0H_S.js.map +1 -0
  109. package/dist/components/base/action-menu/action-menu.d.ts +2 -0
  110. package/dist/components/base/cards/card.recipes.d.ts +12 -5
  111. package/dist/components/base/cards/smart-card.types.d.ts +12 -7
  112. package/dist/components/base/choice-inputs/checkbox.d.ts +7 -2
  113. package/dist/components/base/choice-inputs/switch-card.d.ts +7 -0
  114. package/dist/components/base/choice-inputs/toggle-field.d.ts +7 -0
  115. package/dist/components/base/combobox/combobox-field.d.ts +16 -0
  116. package/dist/components/base/date-pickers/datepicker.types.d.ts +7 -0
  117. package/dist/components/base/forms/controlled-form-field.d.ts +6 -6
  118. package/dist/components/base/forms/form-field.d.ts +5 -3
  119. package/dist/components/base/forms/index.d.ts +1 -0
  120. package/dist/components/base/forms/server-errors.d.ts +16 -0
  121. package/dist/components/base/forms/workflow.d.ts +5 -2
  122. package/dist/components/base/metadata-list/metadata-list.d.ts +3 -1
  123. package/dist/components/base/navigation/page-header/page-header.d.ts +4 -2
  124. package/dist/components/base/structure/composition.recipes.d.ts +17 -0
  125. package/dist/components/base/text-inputs/hooks/use-form-field-state.d.ts +7 -2
  126. package/dist/components/base/text-inputs/input.d.ts +4 -2
  127. package/dist/components/base/text-inputs/textarea.d.ts +4 -2
  128. package/dist/components/base/value-inputs/date-time-input.d.ts +2 -1
  129. package/dist/components/base/value-inputs/slider.d.ts +5 -1
  130. package/dist/components/base/value-inputs/tags-input.d.ts +5 -1
  131. package/dist/components/typography/text.styles.d.ts +26 -1
  132. package/dist/components/ui/combobox-dismiss.d.ts +16 -0
  133. package/dist/components/ui/combobox.d.ts +11 -6
  134. package/dist/components/ui/dialog.d.ts +1 -1
  135. package/dist/components/ui/popover.d.ts +1 -1
  136. package/dist/components/ui/sheet.d.ts +1 -1
  137. package/dist/composition.recipes-COdiFhxB.js +19 -0
  138. package/dist/composition.recipes-COdiFhxB.js.map +1 -0
  139. package/dist/containers-CRmHf7GP.js +104 -0
  140. package/dist/containers-CRmHf7GP.js.map +1 -0
  141. package/dist/{copyable-ClBuk_UK.js → copyable-CnGCZdX4.js} +4 -4
  142. package/dist/{copyable-ClBuk_UK.js.map → copyable-CnGCZdX4.js.map} +1 -1
  143. package/dist/{data-display-DT_khPl_.js → data-display-D4oujtx0.js} +239 -238
  144. package/dist/data-display-D4oujtx0.js.map +1 -0
  145. package/dist/{date-DCrsDTZc.js → date-Q7jnXxpk.js} +5 -5
  146. package/dist/{date-DCrsDTZc.js.map → date-Q7jnXxpk.js.map} +1 -1
  147. package/dist/{date-picker-ay0Pha_a.js → date-picker-zOt1oNss.js} +102 -90
  148. package/dist/date-picker-zOt1oNss.js.map +1 -0
  149. package/dist/date-pickers-cj8IXbDC.js +179 -0
  150. package/dist/date-pickers-cj8IXbDC.js.map +1 -0
  151. package/dist/{display-hAc1HjpI.js → display-BB4BL_-K.js} +8 -8
  152. package/dist/{display-hAc1HjpI.js.map → display-BB4BL_-K.js.map} +1 -1
  153. package/dist/{dropdown-menu-Cl4X7L5S.js → dropdown-menu-CjY8Vt7W.js} +8 -8
  154. package/dist/{dropdown-menu-Cl4X7L5S.js.map → dropdown-menu-CjY8Vt7W.js.map} +1 -1
  155. package/dist/features/activities.js +11 -11
  156. package/dist/features/ai-chat.js +9 -9
  157. package/dist/features/appointment-calendar.js +222 -220
  158. package/dist/features/appointment-calendar.js.map +1 -1
  159. package/dist/features/async-preview.js +8 -8
  160. package/dist/features/combobox.js +1 -1
  161. package/dist/features/comments.js +1 -1
  162. package/dist/features/data-view.js +10 -10
  163. package/dist/features/email-composer.js +275 -274
  164. package/dist/features/email-composer.js.map +1 -1
  165. package/dist/features/event-calendar.js +199 -198
  166. package/dist/features/event-calendar.js.map +1 -1
  167. package/dist/features/filters.js +1 -1
  168. package/dist/features/global-search.js +12 -12
  169. package/dist/features/kanban.js +4 -4
  170. package/dist/features/map.js +7 -7
  171. package/dist/features/media-library.js +623 -622
  172. package/dist/features/media-library.js.map +1 -1
  173. package/dist/features/mentions.js +1 -1
  174. package/dist/features/overlays.js +1 -1
  175. package/dist/features/products.js +973 -969
  176. package/dist/features/products.js.map +1 -1
  177. package/dist/features/questionnaire.js +12 -12
  178. package/dist/features/resource-assignment.js +8 -8
  179. package/dist/features/resource.js +113 -112
  180. package/dist/features/resource.js.map +1 -1
  181. package/dist/features/rich-text-editor.js +2 -2
  182. package/dist/features/schema-form.js +254 -253
  183. package/dist/features/schema-form.js.map +1 -1
  184. package/dist/features/suggestions.js +3 -3
  185. package/dist/features/sync.js +3 -3
  186. package/dist/features/table.js +1 -1
  187. package/dist/features/theme-tweaker.js +19 -19
  188. package/dist/features/theme-tweaker.js.map +1 -1
  189. package/dist/{feedback-BYIhtitP.js → feedback-DZNL5Lg1.js} +9 -9
  190. package/dist/{feedback-BYIhtitP.js.map → feedback-DZNL5Lg1.js.map} +1 -1
  191. package/dist/{field-affordance-recipes-DZhnIL_Y.js → field-affordance-recipes-DjwGx8eM.js} +2 -2
  192. package/dist/{field-affordance-recipes-DZhnIL_Y.js.map → field-affordance-recipes-DjwGx8eM.js.map} +1 -1
  193. package/dist/{filters-BGfvjP4d.js → filters-BcT-uoFy.js} +19 -19
  194. package/dist/{filters-BGfvjP4d.js.map → filters-BcT-uoFy.js.map} +1 -1
  195. package/dist/{form-field-CwH9y77i.js → form-field-CsgRmdit.js} +14 -8
  196. package/dist/form-field-CsgRmdit.js.map +1 -0
  197. package/dist/{form-sizing-BdP_Mf5p.js → form-sizing-NXgjkmBG.js} +3 -3
  198. package/dist/{form-sizing-BdP_Mf5p.js.map → form-sizing-NXgjkmBG.js.map} +1 -1
  199. package/dist/{forms-B9G_xwzi.js → forms-BV5m5aQF.js} +83 -65
  200. package/dist/forms-BV5m5aQF.js.map +1 -0
  201. package/dist/{forms-numeric-B_jraJaQ.js → forms-numeric-Cd33AKbD.js} +288 -288
  202. package/dist/forms-numeric-Cd33AKbD.js.map +1 -0
  203. package/dist/{header-CGXuhcRm.js → header-BA697l4a.js} +14 -14
  204. package/dist/{header-CGXuhcRm.js.map → header-BA697l4a.js.map} +1 -1
  205. package/dist/hooks/useFormErrors.d.ts +1 -1
  206. package/dist/{hooks-Dkz0K2WT.js → hooks-BQ-L7Uu2.js} +2 -2
  207. package/dist/{hooks-Dkz0K2WT.js.map → hooks-BQ-L7Uu2.js.map} +1 -1
  208. package/dist/{icon-badge-DYKIwvOV.js → icon-badge-COWbCCWu.js} +3 -3
  209. package/dist/{icon-badge-DYKIwvOV.js.map → icon-badge-COWbCCWu.js.map} +1 -1
  210. package/dist/index.js +2 -2
  211. package/dist/input-Cdw4k0fb.js +289 -0
  212. package/dist/input-Cdw4k0fb.js.map +1 -0
  213. package/dist/{input-CZw8iU99.js → input-DOPL5_QE.js} +3 -3
  214. package/dist/{input-CZw8iU99.js.map → input-DOPL5_QE.js.map} +1 -1
  215. package/dist/item-BvZ2DR_x.js +277 -0
  216. package/dist/item-BvZ2DR_x.js.map +1 -0
  217. package/dist/layout/app-shell.js +1 -1
  218. package/dist/layout/auth.js +1 -1
  219. package/dist/layout/containers.js +1 -1
  220. package/dist/layout/header.js +1 -1
  221. package/dist/layout/hooks.js +1 -1
  222. package/dist/layout/navigation.js +1 -1
  223. package/dist/layout/page.js +1 -1
  224. package/dist/layout/settings.js +1 -1
  225. package/dist/layout/sidebar.js +2 -2
  226. package/dist/layout/workspace.js +1 -1
  227. package/dist/layout.js +10 -10
  228. package/dist/lib/affordance-geometry.generated.d.ts +6 -0
  229. package/dist/lib/ui-provider/types.d.ts +1 -1
  230. package/dist/lib/use-popup-focus-recovery.d.ts +8 -0
  231. package/dist/lib/utils.js +1 -1
  232. package/dist/{media-gallery-3zIVLMWH.js → media-gallery-CSl5W1Fy.js} +6 -6
  233. package/dist/{media-gallery-3zIVLMWH.js.map → media-gallery-CSl5W1Fy.js.map} +1 -1
  234. package/dist/{mentions-utuUvH1K.js → mentions-RKOQaaIB.js} +8 -8
  235. package/dist/{mentions-utuUvH1K.js.map → mentions-RKOQaaIB.js.map} +1 -1
  236. package/dist/{message-DZ_ruyUV.js → message-INU2xsxu.js} +4 -4
  237. package/dist/{message-DZ_ruyUV.js.map → message-INU2xsxu.js.map} +1 -1
  238. package/dist/metadata-list-qVV7AVxa.js +443 -0
  239. package/dist/metadata-list-qVV7AVxa.js.map +1 -0
  240. package/dist/{navigation-BzhHI3lo.js → navigation-BQNcg1jT.js} +8 -8
  241. package/dist/{navigation-BzhHI3lo.js.map → navigation-BQNcg1jT.js.map} +1 -1
  242. package/dist/{navigation-Bnotn4AQ.js → navigation-DLF3E1IC.js} +7 -7
  243. package/dist/{navigation-Bnotn4AQ.js.map → navigation-DLF3E1IC.js.map} +1 -1
  244. package/dist/{navigation-row-recipes-BFLCk_Aq.js → navigation-row-recipes-WZEs-hYo.js} +2 -2
  245. package/dist/{navigation-row-recipes-BFLCk_Aq.js.map → navigation-row-recipes-WZEs-hYo.js.map} +1 -1
  246. package/dist/{number-DbV1Dija.js → number-E_OiIfJz.js} +5 -5
  247. package/dist/{number-DbV1Dija.js.map → number-E_OiIfJz.js.map} +1 -1
  248. package/dist/{overflow-tab-bar-CWY7Nogn.js → overflow-tab-bar-CrbqMteP.js} +107 -105
  249. package/dist/overflow-tab-bar-CrbqMteP.js.map +1 -0
  250. package/dist/{overlays-DNWmZrJ4.js → overlays-BlKynmde.js} +322 -319
  251. package/dist/overlays-BlKynmde.js.map +1 -0
  252. package/dist/page-CIwNUtGr.js +227 -0
  253. package/dist/page-CIwNUtGr.js.map +1 -0
  254. package/dist/page-header-commands-DFMlNYzN.js +128 -0
  255. package/dist/page-header-commands-DFMlNYzN.js.map +1 -0
  256. package/dist/{pagination-BL25hu2s.js → pagination-Ch8X_47u.js} +5 -5
  257. package/dist/{pagination-BL25hu2s.js.map → pagination-Ch8X_47u.js.map} +1 -1
  258. package/dist/{popover-menu-B9WWygpa.js → popover-menu-BYaCdFhf.js} +6 -6
  259. package/dist/{popover-menu-B9WWygpa.js.map → popover-menu-BYaCdFhf.js.map} +1 -1
  260. package/dist/{popover-7_m66eYW.js → popover-uwzX2vo7.js} +65 -63
  261. package/dist/popover-uwzX2vo7.js.map +1 -0
  262. package/dist/{primitives-BFK08r9M.js → primitives-Du64iDbb.js} +6 -6
  263. package/dist/{primitives-BFK08r9M.js.map → primitives-Du64iDbb.js.map} +1 -1
  264. package/dist/primitives.js +4 -4
  265. package/dist/{progress-B1VnCT0K.js → progress-BvF2oCdV.js} +5 -5
  266. package/dist/{progress-B1VnCT0K.js.map → progress-BvF2oCdV.js.map} +1 -1
  267. package/dist/{receipt-BVSOH3Xo.js → receipt-D789Jwyy.js} +6 -6
  268. package/dist/{receipt-BVSOH3Xo.js.map → receipt-D789Jwyy.js.map} +1 -1
  269. package/dist/{rich-text-GOUyKQ-s.js → rich-text-CLJEf76s.js} +4 -4
  270. package/dist/{rich-text-GOUyKQ-s.js.map → rich-text-CLJEf76s.js.map} +1 -1
  271. package/dist/{rich-text-editor-cRLC-eBK.js → rich-text-editor-Cm1dpUpQ.js} +10 -10
  272. package/dist/{rich-text-editor-cRLC-eBK.js.map → rich-text-editor-Cm1dpUpQ.js.map} +1 -1
  273. package/dist/{rich-text-editor-toolbar-DfXg0-VC.js → rich-text-editor-toolbar-L__e4x47.js} +4 -4
  274. package/dist/{rich-text-editor-toolbar-DfXg0-VC.js.map → rich-text-editor-toolbar-L__e4x47.js.map} +1 -1
  275. package/dist/{scroll-area-DcI-M1UT.js → scroll-area-La5RXsEk.js} +2 -2
  276. package/dist/{scroll-area-DcI-M1UT.js.map → scroll-area-La5RXsEk.js.map} +1 -1
  277. package/dist/{separator-Bom7NsGO.js → separator-DAEV0w65.js} +2 -2
  278. package/dist/{separator-Bom7NsGO.js.map → separator-DAEV0w65.js.map} +1 -1
  279. package/dist/{separator-BDV-Y648.js → separator-GNfPG-90.js} +3 -3
  280. package/dist/{separator-BDV-Y648.js.map → separator-GNfPG-90.js.map} +1 -1
  281. package/dist/services/actions.js +1 -1
  282. package/dist/settings-BA2iboic.js +174 -0
  283. package/dist/settings-BA2iboic.js.map +1 -0
  284. package/dist/{sheet-CGpB3omz.js → sheet-DoAxTb2J.js} +75 -73
  285. package/dist/sheet-DoAxTb2J.js.map +1 -0
  286. package/dist/{sidebar-A0ElHINE.js → sidebar-ByqKR_W5.js} +13 -13
  287. package/dist/{sidebar-A0ElHINE.js.map → sidebar-ByqKR_W5.js.map} +1 -1
  288. package/dist/{sidebar-CPx_7YBa.js → sidebar-D2iSnGJ7.js} +11 -11
  289. package/dist/{sidebar-CPx_7YBa.js.map → sidebar-D2iSnGJ7.js.map} +1 -1
  290. package/dist/{skeleton-Byjnt7qr.js → skeleton-CUj8O5Bd.js} +3 -3
  291. package/dist/{skeleton-Byjnt7qr.js.map → skeleton-CUj8O5Bd.js.map} +1 -1
  292. package/dist/smart-card-CqkzQsK-.js +614 -0
  293. package/dist/smart-card-CqkzQsK-.js.map +1 -0
  294. package/dist/{structure-BmisBK-3.js → structure-C0V0_Fyf.js} +3 -3
  295. package/dist/{structure-BmisBK-3.js.map → structure-C0V0_Fyf.js.map} +1 -1
  296. package/dist/{structure.recipes-EPz60cU8.js → structure.recipes-BB4-n58V.js} +2 -2
  297. package/dist/{structure.recipes-EPz60cU8.js.map → structure.recipes-BB4-n58V.js.map} +1 -1
  298. package/dist/style.css +1 -1
  299. package/dist/{table-DsfzoUia.js → table-CpvnzJn9.js} +3 -3
  300. package/dist/{table-DsfzoUia.js.map → table-CpvnzJn9.js.map} +1 -1
  301. package/dist/{table-BweFy_P9.js → table-DH7rozUv.js} +19 -19
  302. package/dist/{table-BweFy_P9.js.map → table-DH7rozUv.js.map} +1 -1
  303. package/dist/{tabs-CDocW5D1.js → tabs-eqVsJZWO.js} +7 -7
  304. package/dist/{tabs-CDocW5D1.js.map → tabs-eqVsJZWO.js.map} +1 -1
  305. package/dist/{text-inputs-f9Ia-aCi.js → text-inputs-DXItiR0O.js} +101 -98
  306. package/dist/text-inputs-DXItiR0O.js.map +1 -0
  307. package/dist/{text.styles-g4He6UIW.js → text.styles-B64My8RZ.js} +25 -10
  308. package/dist/text.styles-B64My8RZ.js.map +1 -0
  309. package/dist/theme.css +152 -112
  310. package/dist/{timelines-CwM_9IhD.js → timelines-DmtztAY_.js} +10 -10
  311. package/dist/{timelines-CwM_9IhD.js.map → timelines-DmtztAY_.js.map} +1 -1
  312. package/dist/{tooltip-yiRJUFjp.js → tooltip-B4hjKtoV.js} +3 -3
  313. package/dist/{tooltip-yiRJUFjp.js.map → tooltip-B4hjKtoV.js.map} +1 -1
  314. package/dist/{tree-WnKQzwbq.js → tree-CV11PURP.js} +8 -8
  315. package/dist/{tree-WnKQzwbq.js.map → tree-CV11PURP.js.map} +1 -1
  316. package/dist/typography/rich-text.js +1 -1
  317. package/dist/typography-CSyJrh28.js +117 -0
  318. package/dist/typography-CSyJrh28.js.map +1 -0
  319. package/dist/typography.js +1 -1
  320. package/dist/{ui-provider-C_U0Xma4.js → ui-provider-CQCuCBcy.js} +3 -3
  321. package/dist/ui-provider-CQCuCBcy.js.map +1 -0
  322. package/dist/ui-provider.js +1 -1
  323. package/dist/{upload-CXyxmQBP.js → upload-C9SA0X-8.js} +11 -11
  324. package/dist/{upload-CXyxmQBP.js.map → upload-C9SA0X-8.js.map} +1 -1
  325. package/dist/{upload-queue-Boscubn9.js → upload-queue-DhQJiSRc.js} +9 -9
  326. package/dist/{upload-queue-Boscubn9.js.map → upload-queue-DhQJiSRc.js.map} +1 -1
  327. package/dist/{usage-card-BhO5eqkX.js → usage-card-DVTRDmGz.js} +134 -133
  328. package/dist/usage-card-DVTRDmGz.js.map +1 -0
  329. package/dist/use-popup-focus-recovery-C0QPvgOR.js +36 -0
  330. package/dist/use-popup-focus-recovery-C0QPvgOR.js.map +1 -0
  331. package/dist/{utils-BRhFDwuU.js → utils-CF3c95Io.js} +68 -5
  332. package/dist/utils-CF3c95Io.js.map +1 -0
  333. package/dist/value-inputs-C0o70p-U.js +980 -0
  334. package/dist/value-inputs-C0o70p-U.js.map +1 -0
  335. package/dist/{value-typography-BP8OG6h5.js → value-typography-ClupF0Gz.js} +2 -2
  336. package/dist/{value-typography-BP8OG6h5.js.map → value-typography-ClupF0Gz.js.map} +1 -1
  337. package/dist/workspace-9EFVXUyk.js +410 -0
  338. package/dist/workspace-9EFVXUyk.js.map +1 -0
  339. package/docs/consumer-skill/SKILL.md +14 -129
  340. package/docs/consumer-skill/examples/app-layout.tsx +22 -12
  341. package/docs/consumer-skill/examples/authentication.tsx +77 -0
  342. package/docs/consumer-skill/examples/edit.tsx +30 -38
  343. package/docs/consumer-skill/examples/manifest.json +51 -1
  344. package/docs/consumer-skill/examples/rhf-bindings.tsx +86 -0
  345. package/docs/consumer-skill/examples/rhf-edit-page.tsx +141 -0
  346. package/docs/consumer-skill/examples/rhf-overlay-form.tsx +92 -0
  347. package/docs/consumer-skill/examples/rhf-transport.tsx +28 -0
  348. package/docs/consumer-skill/references/agents-md.md +17 -7
  349. package/docs/consumer-skill/references/authentication.md +42 -0
  350. package/docs/consumer-skill/references/component-contracts.json +319824 -0
  351. package/docs/consumer-skill/references/composition-mapping.md +92 -0
  352. package/docs/consumer-skill/references/composition.md +43 -19
  353. package/docs/consumer-skill/references/design-contract.md +32 -0
  354. package/docs/consumer-skill/references/discovery.md +84 -7
  355. package/docs/consumer-skill/references/installation.md +45 -35
  356. package/docs/consumer-skill/references/integration.md +6 -2
  357. package/docs/consumer-skill/references/public-api.json +1520 -66
  358. package/docs/consumer-skill/references/review.md +9 -4
  359. package/docs/consumer-skill/references/rhf-workflows.md +86 -0
  360. package/docs/consumer-skill/references/screen-archetypes.md +22 -0
  361. package/docs/consumer-skill/references/theming.md +8 -9
  362. package/docs/consumer-skill/references/tokens.json +12 -3
  363. package/docs/consumer-skill/references/workflows.md +7 -5
  364. package/docs/consumer-skill/scripts/composition-schema.d.mts +2 -0
  365. package/docs/consumer-skill/scripts/composition-schema.mjs +32 -0
  366. package/docs/consumer-skill/scripts/composition.mjs +198 -0
  367. package/docs/consumer-skill/scripts/discovery.mjs +42 -10
  368. package/docs/consumer-skill/scripts/inspect-component.mjs +11 -0
  369. package/docs/consumer-skill/scripts/inspect-tokens.mjs +11 -0
  370. package/docs/consumer-skill/scripts/inspection.mjs +138 -0
  371. package/docs/consumer-skill/scripts/map-composition.mjs +12 -0
  372. package/docs/consumer-skill/scripts/setup-skills.mjs +76 -0
  373. package/docs/consumer-skills/themelia-components/SKILL.md +30 -0
  374. package/docs/consumer-skills/themelia-composition/SKILL.md +35 -0
  375. package/docs/consumer-skills/themelia-forms/SKILL.md +12 -0
  376. package/docs/consumer-skills/themelia-foundation/SKILL.md +14 -0
  377. package/docs/consumer-skills/themelia-tokenization/SKILL.md +35 -0
  378. package/package.json +6 -4
  379. package/templates/README.md +39 -0
  380. package/templates/admin-shell-template.tsx +382 -0
  381. package/templates/analytics-operations-template.tsx +376 -0
  382. package/templates/customers-template.tsx +509 -0
  383. package/templates/index.ts +29 -0
  384. package/templates/orders-template.tsx +1102 -0
  385. package/templates/products-template.tsx +834 -0
  386. package/templates/user-permissions-template.tsx +450 -0
  387. package/dist/action-menu-CllU52Mm.js +0 -280
  388. package/dist/action-menu-CllU52Mm.js.map +0 -1
  389. package/dist/affordance-geometry.generated-tF36bREk.js.map +0 -1
  390. package/dist/ai-artifact-DvTwDVyL.js.map +0 -1
  391. package/dist/app-shell-C4FhvCqF.js.map +0 -1
  392. package/dist/cards-BaBZR-AU.js.map +0 -1
  393. package/dist/checkbox-AWIhNhmo.js.map +0 -1
  394. package/dist/choice-inputs-CNHvARCJ.js.map +0 -1
  395. package/dist/combobox-C0EQW6dr.js.map +0 -1
  396. package/dist/combobox-xCQ2RMNE.js.map +0 -1
  397. package/dist/comments-BYYlTA8E.js.map +0 -1
  398. package/dist/containers-Mu1LMGV1.js +0 -103
  399. package/dist/containers-Mu1LMGV1.js.map +0 -1
  400. package/dist/data-display-DT_khPl_.js.map +0 -1
  401. package/dist/date-picker-ay0Pha_a.js.map +0 -1
  402. package/dist/date-pickers-Ccw8DL2b.js +0 -175
  403. package/dist/date-pickers-Ccw8DL2b.js.map +0 -1
  404. package/dist/form-field-CwH9y77i.js.map +0 -1
  405. package/dist/forms-B9G_xwzi.js.map +0 -1
  406. package/dist/forms-numeric-B_jraJaQ.js.map +0 -1
  407. package/dist/input-DQdEd0YD.js +0 -263
  408. package/dist/input-DQdEd0YD.js.map +0 -1
  409. package/dist/item-K5_ghvze.js +0 -275
  410. package/dist/item-K5_ghvze.js.map +0 -1
  411. package/dist/metadata-list-8N16ZMW_.js +0 -405
  412. package/dist/metadata-list-8N16ZMW_.js.map +0 -1
  413. package/dist/overflow-tab-bar-CWY7Nogn.js.map +0 -1
  414. package/dist/overlays-DNWmZrJ4.js.map +0 -1
  415. package/dist/page-Bgl1F560.js +0 -224
  416. package/dist/page-Bgl1F560.js.map +0 -1
  417. package/dist/page-header-commands-DOb6WsfD.js +0 -126
  418. package/dist/page-header-commands-DOb6WsfD.js.map +0 -1
  419. package/dist/popover-7_m66eYW.js.map +0 -1
  420. package/dist/settings-ybnjVwbd.js +0 -171
  421. package/dist/settings-ybnjVwbd.js.map +0 -1
  422. package/dist/sheet-CGpB3omz.js.map +0 -1
  423. package/dist/smart-card-DiC5aac3.js +0 -604
  424. package/dist/smart-card-DiC5aac3.js.map +0 -1
  425. package/dist/text-inputs-f9Ia-aCi.js.map +0 -1
  426. package/dist/text.styles-g4He6UIW.js.map +0 -1
  427. package/dist/typography-UTnveOEy.js +0 -117
  428. package/dist/typography-UTnveOEy.js.map +0 -1
  429. package/dist/ui-provider-C_U0Xma4.js.map +0 -1
  430. package/dist/usage-card-BhO5eqkX.js.map +0 -1
  431. package/dist/utils-BRhFDwuU.js.map +0 -1
  432. package/dist/value-inputs-DXPDjvBU.js +0 -963
  433. package/dist/value-inputs-DXPDjvBU.js.map +0 -1
  434. package/dist/workspace-Cdrg7k9f.js +0 -408
  435. package/dist/workspace-Cdrg7k9f.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,23 @@ 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
+ export function findComponents(index, options) {
164
+ validateIndex(index);
165
+ const result = rankComponents(index, options);
166
+ // Only natural-language requests recover automatically. API-like names and
167
+ // explicit paths keep precise failure semantics rather than guessed owners.
168
+ const query = options.query.trim();
169
+ if (result.total || !/\s/.test(query) || /[\\/]|[a-z0-9][A-Z]|[A-Z]{2}/.test(query) || new Set(words(query)).size < 2) return result;
170
+ const related = rankComponents(index, options, true);
171
+ return related.total ? { ...result, related: {
172
+ explanation: 'No family matched every query term. These suggestions cover incomplete context; unmatched terms remain unverified. Read the owner guidance before choosing.',
173
+ total: related.total,
174
+ results: related.results,
175
+ } } : result;
176
+ }
@@ -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 exact-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,138 @@
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, prop: null, 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
+ requireFormat(!seen.has(arg), `Duplicate argument: ${arg}`); seen.add(arg);
21
+ const value = args[++index];
22
+ requireFormat(text(value) && !value.startsWith('--'), `Missing value for ${arg}`);
23
+ if (arg === '--limit') {
24
+ requireFormat(/^[1-9]\d*$/.test(value) && Number(value) <= 100, 'Invalid limit: use 1..100'); options.limit = Number(value);
25
+ } else options[arg === '--import' ? 'publicImport' : 'prop'] = value;
26
+ }
27
+ requireFormat(text(options[token ? 'query' : 'symbol']), `A nonempty ${token ? 'token query' : 'exact symbol'} is required`);
28
+ return options;
29
+ }
30
+ export const parseComponentArguments = args => parse(args);
31
+ export const parseTokenArguments = args => parse(args, true);
32
+
33
+ export function validateComponentContracts(index, publicIndex) {
34
+ requireFormat(record(index) && index.schemaVersion === 1, 'Unsupported component contract schema; refresh the complete skill bundle');
35
+ requireFormat(text(index.package) && text(index.version) && Array.isArray(index.contracts) && record(index.nativeProfiles), 'Invalid component contract identity/data');
36
+ requireFormat(index.nativeProperties === undefined || record(index.nativeProperties), 'Invalid native property registry');
37
+ if (publicIndex) requireFormat(index.package === publicIndex.package && index.version === publicIndex.version, 'Component contract package/version identity mismatch; refresh the complete bundle');
38
+ const seen = new Set();
39
+ const validateProp = (name, prop) => {
40
+ 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}`);
41
+ 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}`);
42
+ 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}`);
43
+ };
44
+ for (const prop of Object.values(index.nativeProperties ?? {})) validateProp(prop?.name, prop);
45
+ for (const props of Object.values(index.nativeProfiles)) {
46
+ requireFormat(record(props), 'Invalid native profile');
47
+ for (const [name, reference] of Object.entries(props)) {
48
+ if (typeof reference === 'string') requireFormat(Object.hasOwn(index.nativeProperties ?? {}, reference), `Missing native property reference: ${reference}`);
49
+ validateProp(name, typeof reference === 'string' ? index.nativeProperties[reference] : reference);
50
+ }
51
+ }
52
+ for (const contract of index.contracts) {
53
+ 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');
54
+ const identity = `${contract.import}#${contract.symbol}`;
55
+ requireFormat(!seen.has(identity), `Duplicate component contract: ${identity}`); seen.add(identity);
56
+ requireFormat(contract.inheritedProfile === null || Object.hasOwn(index.nativeProfiles, contract.inheritedProfile), `Missing inherited profile for ${identity}`);
57
+ for (const [name, prop] of Object.entries(contract.props)) validateProp(name, prop);
58
+ if (publicIndex) {
59
+ const family = publicIndex.families?.find(family => family.import === contract.import);
60
+ requireFormat(family?.declaration === contract.declaration && family.symbols.includes(contract.symbol), `Contract is absent from matching public index: ${identity}`);
61
+ }
62
+ }
63
+ return index;
64
+ }
65
+
66
+ function displayProp(prop, origin) {
67
+ const type = boundedText(prop.type, 2000);
68
+ const description = boundedText(prop.description, 800);
69
+ const variants = prop.variants?.slice(0, 12).map(variant => {
70
+ const value = boundedText(variant.type, 2000);
71
+ return {...variant, type: value.text, typeComplete: value.complete, omittedTypeCharacters: value.omittedCharacters};
72
+ });
73
+ const callbacks = prop.callbackSignatures?.slice(0, 12).map(callback => ({...callback,
74
+ signatures: callback.signatures.slice(0, 4).map(signature => boundedText(signature, 2000)), omittedSignatures: Math.max(0, callback.signatures.length - 4)}));
75
+ return {...prop, origin, type: type.text, typeComplete: type.complete, omittedTypeCharacters: type.omittedCharacters,
76
+ description: description.text, omittedDescriptionCharacters: description.omittedCharacters,
77
+ ...(variants ? {variants, omittedVariants: prop.variants.length - variants.length} : {}),
78
+ ...(callbacks ? {callbackSignatures: callbacks, omittedCallbackBranches: prop.callbackSignatures.length - callbacks.length} : {})};
79
+ }
80
+
81
+ function displayGuidance(guide) {
82
+ const list = value => (Array.isArray(value) ? value : []).slice(0, 3).map(value => boundedText(value, 600));
83
+ const composition = guide.composition;
84
+ return {title: boundedText(guide.title ?? '', 150), chooseWhen: list(guide.chooseWhen), avoidWhen: list(guide.avoidWhen),
85
+ ...(composition ? {composition: {owns: list(composition.owns), parentOwns: list(composition.parentOwns),
86
+ ...(composition.page ? {page: boundedText(composition.page, 600)} : {}),
87
+ ...(composition.embedded ? {embedded: boundedText(composition.embedded, 600)} : {})}} : {})};
88
+ }
89
+
90
+ /** Exact API inspection is deliberately separate from task/intent discovery. */
91
+ export function inspectComponent(index, {symbol, publicImport = null, prop = null, limit = 12}, publicIndex) {
92
+ validateComponentContracts(index, publicIndex);
93
+ requireFormat(text(symbol) && Number.isInteger(limit) && limit >= 1 && limit <= 100, 'Use an exact symbol and limit 1..100');
94
+ const matches = index.contracts.filter(contract => contract.symbol === symbol && (!publicImport || contract.import === publicImport));
95
+ requireFormat(matches.length > 0, `No contract for ${symbol}${publicImport ? ` from ${publicImport}` : ''}; use the finder and read the matching published declaration. Coverage: ${index.coverage ?? 'published uppercase callable exports'}`);
96
+ requireFormat(matches.length === 1, `Ambiguous symbol ${symbol}; qualify with --import: ${matches.map(contract => contract.import).join(', ')}`);
97
+ const contract = matches[0];
98
+ const local = Object.values(contract.props);
99
+ const inherited = contract.inheritedProfile ? Object.fromEntries(Object.entries(index.nativeProfiles[contract.inheritedProfile]).map(([name, reference]) => [name, typeof reference === 'string' ? index.nativeProperties[reference] : reference])) : {};
100
+ const priority = value => Number(value.required) * 100 + Number(/^(?:value|defaultValue|checked|defaultChecked|open|defaultOpen|on[A-Z])/.test(value.name)) * 10;
101
+ local.sort((a, b) => priority(b) - priority(a) || compare(a.name, b.name));
102
+ let selected;
103
+ if (prop) {
104
+ const value = contract.props[prop] ?? inherited[prop];
105
+ requireFormat(value, `Unknown prop ${prop} on ${symbol} from ${contract.import}; inspect its declaration or omit --prop for the bounded prop index`);
106
+ selected = [displayProp(value, Object.hasOwn(contract.props, prop) ? 'local' : 'inherited')];
107
+ } else selected = local.slice(0, limit).map(value => displayProp(value, 'local'));
108
+ const description = boundedText(contract.description ?? '', 1000);
109
+ return {package: index.package, version: index.version, import: contract.import, symbol: contract.symbol, declaration: contract.declaration,
110
+ ...(contract.optionalPeers ? {optionalPeers: contract.optionalPeers} : {}),
111
+ description: description.text, omittedDescriptionCharacters: description.omittedCharacters,
112
+ callSignatures: contract.callSignatures.slice(0, 4).map((signature, signatureIndex) => ({index: signatureIndex, ...boundedText(signature, 4000)})),
113
+ props: selected,
114
+ omissions: {localProps: local.length - selected.filter(value => value.origin === 'local').length,
115
+ inheritedProps: Object.keys(inherited).length - selected.filter(value => value.origin === 'inherited').length,
116
+ callSignatures: Math.max(0, contract.callSignatures.length - 4)},
117
+ propNames: {local: local.map(value => value.name).slice(0, 100), omittedLocalNames: Math.max(0, local.length - 100), inherited: Object.keys(inherited).slice(0, 20), omittedInheritedNames: Math.max(0, Object.keys(inherited).length - 20)},
118
+ ...(contract.guidance?.length ? {guidance: contract.guidance.slice(0, 1).map(displayGuidance), omittedGuidance: Math.max(0, contract.guidance.length - 1)} : {}),
119
+ next: 'Use --prop <exact-name> for one local or inherited contract. Read declaration for full types, omitted overloads or truncated fields. Defaults marked unknown are not inferred.'};
120
+ }
121
+
122
+ export function inspectTokens(index, {query, limit = 12}, publicIndex) {
123
+ 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');
124
+ requireFormat(text(query) && Number.isInteger(limit) && limit >= 1 && limit <= 100, 'Use a token query and limit 1..100');
125
+ if (publicIndex) requireFormat(index.package === publicIndex.package && index.version === publicIndex.version, 'Token metadata package/version identity mismatch; refresh the complete bundle');
126
+ const words = value => value.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
127
+ const terms = words(query);
128
+ const values = [
129
+ ...index.structural.map(root => ({...root, default: {status: 'recorded', value: root.default}, kind: 'structural-root', overrideRoot: true})),
130
+ {...index.radius, default: {status: 'recorded', value: index.radius.default}, kind: 'radius-root', overrideRoot: true},
131
+ ...index.advanced.map(name => ({name, kind: 'advanced-root', overrideRoot: true, default: {status: 'not-recorded'}})),
132
+ ...[...new Set(Object.values(index.utilities).flat())].map(name => ({name, kind: 'derived-utility', overrideRoot: false, default: {status: 'not-applicable'}, ...(name === index.radius.innerUtility ? {formula: index.radius.innerFormula} : {})})),
133
+ ];
134
+ 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));
135
+ return {package: index.package, version: index.version, query, total: matches.length, results: matches.slice(0, limit), omitted: Math.max(0, matches.length - limit),
136
+ 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.',
137
+ rule: index.rule, nextReads: ['references/theming.md', 'references/design-contract.md', 'references/tokens.json'], themeStylesheets: publicIndex?.stylesheets ?? []};
138
+ }
@@ -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,76 @@
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'];
7
+ export const sharedSkillName = 'themelia-react-ui-consumer';
8
+
9
+ /** One metadata/example copy, three small discoverable entrypoints, and real templates. */
10
+ export function consumerBundleFiles(packageRoot, destination) {
11
+ const mappings = [
12
+ ['docs/consumer-skill', sharedSkillName],
13
+ ...focusedSkills.map(name => [`docs/consumer-skills/${name}`, name]),
14
+ ['templates', `${sharedSkillName}/templates`],
15
+ ].map(([source, target]) => ({ source: path.resolve(packageRoot, source), target: path.resolve(destination, target) }));
16
+ function mapped(file) {
17
+ const mapping = mappings.find(item => file === item.source || file.startsWith(item.source + path.sep));
18
+ assert(mapping, `Reference outside shipped consumer bundle: ${file}`);
19
+ return path.join(mapping.target, path.relative(mapping.source, file));
20
+ }
21
+ const files = [];
22
+ function walk(directory) {
23
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
24
+ if (entry.name === '.DS_Store') continue;
25
+ const source = path.join(directory, entry.name);
26
+ assert(!fs.lstatSync(source).isSymbolicLink(), `Symlink in consumer bundle: ${source}`);
27
+ if (entry.isDirectory()) walk(source);
28
+ else {
29
+ const target = mapped(source);
30
+ let content = fs.readFileSync(source);
31
+ if (source.endsWith('.md')) {
32
+ content = Buffer.from(content.toString().replace(/(\]\(|^\s*\[[^\]]+\]:\s*)([^\s)]+)(?=\)|\s|$)/gm, (match, prefix, raw) => {
33
+ if (/^(?:[a-z][a-z\d+.-]*:|#|\/)/i.test(raw)) return match;
34
+ const [link, anchor = ''] = raw.split(/(?=[?#])/);
35
+ const resolved = path.resolve(path.dirname(source), decodeURIComponent(link));
36
+ assert(fs.existsSync(resolved), `Missing consumer bundle reference: ${source} → ${link}`);
37
+ const relative = path.relative(path.dirname(target), mapped(resolved)).split(path.sep).join('/');
38
+ return prefix + relative + anchor;
39
+ }));
40
+ }
41
+ files.push({ source, target, content });
42
+ }
43
+ }
44
+ }
45
+ for (const mapping of mappings) walk(mapping.source);
46
+ return files;
47
+ }
48
+
49
+ export function checkCopiedConsumerBundle({ packageRoot, destination }) {
50
+ const files = consumerBundleFiles(packageRoot, destination);
51
+ for (const { target, content } of files) {
52
+ assert(fs.existsSync(target) && !fs.lstatSync(target).isSymbolicLink(), `Copied consumer bundle is stale: missing or linked asset ${target}`);
53
+ assert(content.equals(fs.readFileSync(target)), `Copied consumer bundle is stale: refresh the whole bundle (${target})`);
54
+ }
55
+ return { skills: [sharedSkillName, ...focusedSkills], assets: files.length };
56
+ }
57
+
58
+ export function copyConsumerBundle({ packageRoot, destination }) {
59
+ const files = consumerBundleFiles(packageRoot, destination);
60
+ for (const name of [sharedSkillName, ...focusedSkills]) assert(!fs.existsSync(path.join(destination, name)), `Destination exists: ${name}. Preserve or move the previous skill before copying.`);
61
+ for (const { target, content } of files) {
62
+ fs.mkdirSync(path.dirname(target), { recursive: true });
63
+ fs.writeFileSync(target, content);
64
+ }
65
+ return checkCopiedConsumerBundle({ packageRoot, destination });
66
+ }
67
+
68
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
69
+ try {
70
+ const args = process.argv.slice(2);
71
+ assert(args.length === 3 && ['--copy', '--check'].includes(args[0]) && args[1] === '--destination' && args[2], 'Usage: node setup-skills.mjs --copy|--check --destination <agent-skills-directory>');
72
+ const packageRoot = fileURLToPath(new URL('../../..', import.meta.url));
73
+ const result = (args[0] === '--copy' ? copyConsumerBundle : checkCopiedConsumerBundle)({ packageRoot, destination: path.resolve(args[2]) });
74
+ console.log(JSON.stringify({ ...result, destination: path.resolve(args[2]) }, null, 2));
75
+ } catch (error) { console.error(error.message); process.exitCode = 1; }
76
+ }
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: themelia-components
3
+ description: Discover, inspect and integrate themelia-react-ui controls, value primitives, blocks and complete features in React apps, including typed forms, callbacks and framework adapters; not library internals or visual theme design.
4
+ ---
5
+
6
+ # Themelia components
7
+
8
+ Use the installed package as the API authority. Resolve its root/version with [installation](../../consumer-skill/references/installation.md); verify a copied bundle before using it. Follow that setup only when CSS, required peers or UIProvider are missing. One shared asset bundle serves all three skills; no global CLI or MCP server is required.
9
+
10
+ ## Discover and inspect
11
+
12
+ Split a business request into responsibilities: identity/facts, selection, editing, collection, navigation or a complete workflow. Search each separately. When strict results are empty, inspect related suggestions and their unmatched terms; they cover only part of the request. Shorten to a responsibility, try an exact symbol or remove the layer filter as needed. Read [discovery](../../consumer-skill/references/discovery.md) for query behavior and copied paths.
13
+
14
+ ```sh
15
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/find-components.mjs "record facts" --limit 3
16
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/inspect-component.mjs DataTable --import themelia-react-ui/features/table
17
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/inspect-component.mjs DataTable --import themelia-react-ui/features/table --prop onRowSelectionChange
18
+ ```
19
+
20
+ Read choose/avoid, ownership, peers and the small reading path. Listed peers cover the whole imported family, including type-only exports. Inspect the exact selected export before wiring it. Qualify ambiguous names: basic `ThemeScope` from `ui-provider` and advanced `features/theme-tweaker` scope differ. Inspector omissions and unresolved named types lead to the installed declaration; they are not permission to guess. Preserve discriminated modes, generic row types and overloads. An undocumented default is unknown. Use the canonical owner rather than a deprecated migration name or unrelated aggregate entrypoint.
21
+
22
+ ## Integrate the contract
23
+
24
+ Prefer a complete feature when its state/lifecycle matches the task; otherwise compose public owners into an app-specific component. Check actual value/event types, controlled versus default state, callback timing, native attributes/refs, strings, slots and render composition. Do not rebuild routine menu/listbox/overlay behavior from generic elements or cast mismatched bindings to `any`.
25
+
26
+ For forms read [typed bindings and transport](../../consumer-skill/references/rhf-workflows.md) and the matching [recipe](../../consumer-skill/examples/manifest.json). RHF recipes cover validation, arrays, dirty state and async submission; an existing controller can use supported native/controlled contracts. Checkbox state, input events, dates, selection and arrays differ. Keep drafts on failure, await the complete transport, and accept authoritative saved values before reset. Read [workflows](../../consumer-skill/references/workflows.md) only for the chosen feature.
27
+
28
+ The app supplies data, routing, permission and translation. Use [integration](../../consumer-skill/references/integration.md) for framework adapters and client boundaries. Dialogs, drawers and confirmations use `features/overlays`; open them at the app/feature boundary through callbacks. Never invent a framework-specific package API.
29
+
30
+ Use **themelia-tokenization** for shared visual changes and **themelia-composition** for hierarchy, shells and regions. Finish the component's real loading/empty/error/disabled/async paths and keyboard/focus behavior, then run app checks and [composition review](../../consumer-skill/references/review.md). Report behavior separately from source and inspected appearance.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: themelia-composition
3
+ description: Map responsibilities to exact Themelia components and supported compositions, then build and polish business interfaces, shells, public sites and workflows with verified hierarchy and interactions.
4
+ ---
5
+
6
+ # Themelia composition
7
+
8
+ ## Start from the business task
9
+
10
+ Identify the user, decision/action, essential facts, editable state and supporting history. Prioritize what must be compared together and what can be selected, disclosed or routed. App-specific business components are expected; public owners supply geometry and behavior.
11
+
12
+ Use the [mapper](../../consumer-skill/references/composition-mapping.md) for executable role selection and supported nesting:
13
+
14
+ ```sh
15
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/map-composition.mjs --roles
16
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/map-composition.mjs --pattern record-detail --main invoice-lines --aside facts
17
+ ```
18
+
19
+ Verify installed/copied guidance with **themelia-components** first. Read coverage, unresolved needs, surface warnings, family peers and focused API/recipe reads. Resolve ambiguity with a specific role or qualified import/symbol. The plan is advisory; unmapped components can still be valid. Inspect unfamiliar APIs before wiring them. Use the [archetype matrix](../../consumer-skill/references/screen-archetypes.md) and matching blueprints as evidence. Prefer a complete feature when its lifecycle fits.
20
+
21
+ ## Assign ownership and build
22
+
23
+ Use Page for route identity/commands, AuthShell for authentication, Container/Section for content sites. Shell hosts route children; route owns its Page/h1. Page owns gutters and direct-subject gaps; TwoColumnLayout owns column/subject gaps. Stack/Grid arrange nested groups; Card owns framing/insets; features own interactions. Read [composition](../../consumer-skill/references/composition.md) and page/embedded guidance. Give each space, header and command one owner.
24
+
25
+ Implement the responsibility map with app state. Avoid a Card for every field or automatic KPI rows/tabs/icons. Main/support regions clarify responsibilities. Adapt to parent width, preserve DOM/focus order and constrain scrolling/overflow. Continuous documents are valid; tabs select separate sections.
26
+
27
+ Choose gaps by [shared relationships](../../consumer-skill/references/design-contract.md#semantic-roles), not whichever utility fits one screenshot. Page/subject/copy/action rhythm differs from surface insets and row density. Use Heading/Text and semantic value primitives; title badges use titleSuffix. Reusable content stays card-free until its boundary. Supported flat/none anatomy prevents doubled insets inside a padded host. Use **themelia-tokenization** for coherent theme changes.
28
+
29
+ See [template boundaries](../../../templates/README.md) for domain blueprints and [typed form workflows](../../consumer-skill/references/rhf-workflows.md) for editing. Transport, permissions, routing and translations belong to the app. Dialogs/drawers/confirmations use `features/overlays` at the composing app/feature boundary.
30
+
31
+ ## Inspect, repair and deliver
32
+
33
+ Run the [composition checker](../../consumer-skill/references/review.md) and app type/lint/test checks. Fix errors; judge warnings in context rather than removing valid composition to silence them. Open the actual screen at narrow/wide parent widths and both themes. Inspect hierarchy, wrapping, alignment, corners, control consistency and quiet space; repair the highest-impact weakness at its owner.
34
+
35
+ Execute relevant keyboard/focus, selection, validation, failure/retry, cancellation and accepted-save paths. Report source, inspected appearance and interactions separately. A renderable route or clean checker does not establish a useful screen. For requested publication use the app's actual build/deploy configuration and target; no Themelia publish CLI exists. Library npm release is maintainer work. Hand back the working result and verified limits.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: themelia-forms
3
+ description: Compatibility route for older Themelia form-skill instructions; use themelia-components for exact bindings and themelia-composition for complete edit/create workflows.
4
+ ---
5
+
6
+ # Themelia forms compatibility route
7
+
8
+ Use [themelia-components](../themelia-components/SKILL.md) to inspect actual value/event, callback, ref and controlled-state contracts. Use [themelia-composition](../themelia-composition/SKILL.md) for complete edit pages and overlay workflows.
9
+
10
+ The full [RHF workflows](../../consumer-skill/references/rhf-workflows.md), [typed bindings](../../consumer-skill/examples/rhf-bindings.tsx), [edit page](../../consumer-skill/examples/rhf-edit-page.tsx) and [overlay form](../../consumer-skill/examples/rhf-overlay-form.tsx) remain shared resources. Validation, dirty state, arrays, async transport, failure drafts, accepted-value reset and focus restoration retain their contracts.
11
+
12
+ This package path is retained for existing instructions. Install the complete current bundle through [installation](../../consumer-skill/references/installation.md); separately installed skills are not replaced automatically.
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: themelia-foundation
3
+ description: Compatibility route for older Themelia instructions naming themelia-foundation; use the current components, tokenization and composition capabilities for new work.
4
+ ---
5
+
6
+ # Themelia foundation compatibility route
7
+
8
+ The canonical capability split is now:
9
+
10
+ - [themelia-components](../themelia-components/SKILL.md): installed setup, owner discovery, exact API inspection and framework integration.
11
+ - [themelia-tokenization](../themelia-tokenization/SKILL.md): CSS/theme setup, semantic roots, typography and scoped themes.
12
+ - [themelia-composition](../themelia-composition/SKILL.md): shell/route ownership, screen hierarchy and delivery.
13
+
14
+ Follow the matching capability. [Installation](../../consumer-skill/references/installation.md) explains the complete current bundle. This package path is retained for existing instructions; separately installed skills are not replaced automatically.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: themelia-tokenization
3
+ description: Theme and polish themelia-react-ui apps through semantic colors, typography, structural roots, density and scoped portal themes; inspect supported tokens and correct visual drift without restyling component anatomy.
4
+ ---
5
+
6
+ # Themelia tokenization
7
+
8
+ Translate the intended visual change into a shared responsibility before changing CSS. Use the installed version's [design contract](../../consumer-skill/references/design-contract.md), [theme guide](../../consumer-skill/references/theming.md) and generated token metadata. **themelia-components** owns API integration; **themelia-composition** owns task hierarchy and region placement.
9
+
10
+ ## Inspect the customization surface
11
+
12
+ Resolve package identity and the active CSS path through [installation](../../consumer-skill/references/installation.md). Compiled component CSS and app-authored semantic Tailwind utilities have different setup requirements. Keep overrides in one app stylesheet after package styles, or at a real ThemeScope boundary.
13
+
14
+ ```sh
15
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/inspect-tokens.mjs surface --limit 8
16
+ node node_modules/themelia-react-ui/docs/consumer-skill/scripts/inspect-tokens.mjs radius --limit 5
17
+ ```
18
+
19
+ Lookup distinguishes structural roots, advanced settings and derived utility spellings. Only supported settings are overrides. Generated `--spacing-*`, `--radius-*` or `--container-*` aliases are not public knobs. If a query lacks a semantic color value, read the installed theme and guide; do not invent a root or claim an unreported light/dark default.
20
+
21
+ ## Choose the role
22
+
23
+ - Brand/surface changes use existing shadcn semantic surface/foreground pairs. State uses success/info/warning/destructive pairs; categories and counts stay neutral. Keep input boundaries, dividers and focus distinct.
24
+ - Typography changes use supported text/font roles and provider defaults. Visual size stays separate from heading level. Density does not reduce primary copy to compact metadata.
25
+ - `--space-scale` changes gaps/insets; `--density-scale` changes control/row heights. Action/control sizes, row density, copy gaps and surface insets remain independent. Use the [relationship table](../../consumer-skill/references/design-contract.md#semantic-roles) to select public gaps.
26
+ - Surface insets belong to Card/overlay anatomy; page gutters belong to layout. Change the appropriate owner/root instead of accumulating wrappers or padding resets.
27
+ - The single radius root drives outer shells and height-bounded inner controls. Physical nesting does not choose the role. Icons, avatars and shell dimensions have their own existing roots.
28
+
29
+ Apply the smallest coherent theme change to related owners. Preserve supported variants and app placement; do not compensate for one control with a copied implementation, raw palette, extra opacity scale, local focus treatment or per-component token.
30
+
31
+ ## Verify the effect
32
+
33
+ Check both themes on actual surfaces, including primary/secondary/status text, boundaries and focused/invalid/disabled states. Open a real picker/menu/overlay in a scoped theme and verify its portal shares the scope. Change spacing and density independently with other roots held fixed; inspect adjoining heights, baselines, corners and clipping as well as computed values. A capture before popup presence settles is not open-state proof.
34
+
35
+ Use available browser/contrast tooling and the [review contract](../../consumer-skill/references/review.md); do not invent a Themelia theme-publishing or audit CLI. Run app checks and execute keyboard use. Deliver the stylesheet, affected role explanation, inspected widths/themes and behavior evidence. Report unexercised states as unverified.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "themelia-react-ui",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "A composable React UI library for modern admin applications, built on Base UI and Tailwind with shadcn-compatible themes, shared design tokens, reusable layouts, blocks and workflows.",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -30,6 +30,8 @@
30
30
  "README.md",
31
31
  "CHANGELOG.md",
32
32
  "docs/consumer-skill",
33
+ "docs/consumer-skills",
34
+ "templates",
33
35
  "THIRD_PARTY_NOTICES.md"
34
36
  ],
35
37
  "sideEffects": [
@@ -477,11 +479,11 @@
477
479
  "check:maps": "node scripts/test-client-boundaries.mjs --built",
478
480
  "build:docs": "node scripts/build-static-docs.mjs",
479
481
  "check:static-docs": "node scripts/check-static-docs.mjs",
480
- "check:agent": "node --test scripts/test-consumer-discovery.mjs scripts/test-consumer-composition.mjs scripts/test-consumer-evals.mjs scripts/test-button-codemod.mjs scripts/test-consumer-skill-assets.mjs scripts/test-static-docs.mjs scripts/test-fixture-install.mjs && npm run check:skill",
482
+ "check:agent": "node --test scripts/test-consumer-discovery.mjs scripts/test-consumer-inspection.mjs scripts/test-consumer-mapper.mjs scripts/test-composition-metadata.mjs scripts/test-consumer-composition.mjs scripts/test-consumer-evals.mjs scripts/test-button-codemod.mjs scripts/test-consumer-skill-assets.mjs scripts/test-static-docs.mjs scripts/test-fixture-install.mjs && npm run check:skill",
481
483
  "check:release": "npm run check:all && npm run check:agent && npm run build:docs && npm run check:static-docs"
482
484
  },
483
485
  "peerDependencies": {
484
- "@base-ui/react": "1.8.0-kpo.2",
486
+ "@base-ui/react": "^1.9.0",
485
487
  "@dnd-kit/core": "^6.0.0",
486
488
  "@dnd-kit/sortable": "^10.0.0",
487
489
  "@dnd-kit/utilities": "^3.0.0",
@@ -523,7 +525,7 @@
523
525
  "zustand": "^5.0.12"
524
526
  },
525
527
  "devDependencies": {
526
- "@base-ui/react": "file:./base-ui-react-1.8.0-kpo.2.tgz",
528
+ "@base-ui/react": "^1.9.0",
527
529
  "@dnd-kit/core": "^6.3.1",
528
530
  "@dnd-kit/sortable": "^10.0.0",
529
531
  "@dnd-kit/utilities": "^3.2.2",
@@ -0,0 +1,39 @@
1
+ # Admin composition examples
2
+
3
+ These shipped, copyable application blueprints demonstrate `themelia-react-ui` through its public imports. Open `/?page=templates` after `npm run dev` for the shared shell, or use the individual catalogue pages under Templates. They ship in `node_modules/themelia-react-ui/templates/` as source assets, not additional npm entrypoints. Copy and adapt them into the application.
4
+
5
+ The examples use local, in-memory records. A reload resets them. Connect your app's data loading, persistence, authorization, notification delivery and navigation at the shown callbacks; no backend or authentication service is included. Publishing settings and permissions here describe sample state, not server enforcement.
6
+
7
+ For production create/edit workflows, adapt the [RHF edit page](../docs/consumer-skill/examples/rhf-edit-page.tsx) and [RHF overlay form](../docs/consumer-skill/examples/rhf-overlay-form.tsx) to these domain screens. Replace their local draft state with RHF values, validation, arrays and dirty tracking, and await the app's complete transport before accepting a saved baseline. The [forms workflow guide](../docs/consumer-skill/references/rhf-workflows.md) supplies typed control bindings and Inertia/TanStack integration seams.
8
+
9
+ | File | Export | Composition demonstrated |
10
+ | --- | --- | --- |
11
+ | [admin-shell-template.tsx](admin-shell-template.tsx) | `AdminStarterShell`, `AdminTemplatesShowcase` | UIProvider defaults, all five AppLayout presets, AppSidebar, workspace context, breadcrumbs, notifications and account/settings menus |
12
+ | [orders-template.tsx](orders-template.tsx) | `OrdersAdminTemplate` | Page with a fulfillment primary command, TwoColumnLayout, Card, lifecycle-grouped Item rows, MetadataList, Money, AddressCard, PaymentMethod, ActivityLog and refund/tracking/note dialogs |
13
+ | [products-template.tsx](products-template.tsx) | `ProductsAdminTemplate` | ProductVariantsManager, ProductVariantDetails/Editor, SeoListingCard, publishing/organization forms and variant duplication |
14
+ | [customers-template.tsx](customers-template.tsx) | `CustomersAdminTemplate` | MetricBar, DataTable order history, MetadataList, AddressCard, ActivityLog, contact drafts and validated store-credit submission |
15
+ | [user-permissions-template.tsx](user-permissions-template.tsx) | `UserPermissionsTemplate` | FormField, DirtyStateBanner, role-based Page save and confirmed suspend commands, role presets and editable permission groups with a saved/discard baseline |
16
+ | [analytics-operations-template.tsx](analytics-operations-template.tsx) | `AnalyticsOperationsTemplate` | Numeric MetricBar KPIs, MetricComparison, ActivityHeatmap, UsageCard and an app-owned operations list |
17
+
18
+ For layout selection, read the [owner map](../docs/consumer-skill/references/composition.md#structure-and-spacing) and [typed layout-block recipe](../docs/consumer-skill/examples/layout-blocks.tsx). Use horizontal Stack for rows, Grid/GridCell for prescribed columns and spans, AdaptiveGrid for parent-driven equal tiles, and TwoColumnLayout for a main/support split.
19
+
20
+ ## Boundaries to preserve when adapting
21
+
22
+ - `AdminTemplatesShowcase` supplies UIProvider defaults; embedded preview pages inherit the catalogue's provider. `AdminStarterShell` inherits the application's provider. `defaultDensity` belongs to the standalone showcase.
23
+ - Page owns gutters and the default resource measure, TwoColumnLayout owns the main/aside split, and Stack/Grid own peer gaps. These record and overview routes keep the default measure; only a wide directory or comparison opts into `maxWidth="full"`. Ordinary Cards retain the default padding. Compact control density does not shrink Cards. Peer Card stacks use `gap="2xl"`, matching Page and TwoColumnLayout’s 24px default rhythm in both axes; copy and form groups keep their own gaps.
24
+ - A headed address, payment, SEO or variants panel uses its own `surface="card"`. It delegates to Card's aligned header/body anatomy and inherits provider separators. Do not wrap it in an untitled padded Card. Omitted surface keeps these blocks unframed for embedding; an embedded header does not inherit an unintended Card separator.
25
+ - Put page commands in Page's header as `primaryAction` (one) and ordered
26
+ `secondaryActions`; the header owns their treatment, overflow and narrow-width
27
+ collapse. A destructive command is a `destructive: true` secondary action that
28
+ opens ConfirmDialog. Put subject commands in Card's header. Status/count badges use `titleSuffix`;
29
+ a status shown in the page header is not repeated in a card or fact list. Spacing separates a card's header, body and footer; a body separator is appropriate only between distinct body sections.
30
+ - Metrics use numeric values and formatting hints. Context such as “12 orders” belongs in a subtitle; it is not a directional trend. The analytics period changes the KPI strip; comparisons, heatmap and quota data are separately described monthly/current snapshots.
31
+ - Overlay edits start from a snapshot and update committed display state only on Save. Native forms use `formId` so required fields and submission ownership are preserved. App persistence should use the overlay's async contract with pending/error/retry handling before committing; do not bind a draft editor directly to committed record data.
32
+ - Local sidebar navigation preserves native link modifiers and closes the mobile drawer. Replace the local route map with your router adapter and record-aware destinations. Sample records across these pages are independent; a customer route is not an order's customer resolver.
33
+ - Choose the component that fits the subject. A lifecycle-specific order item group can use Item; editable permission groups can use ToggleField. Do not replace them with an unrelated block merely to increase the component count.
34
+
35
+ ## Checks
36
+
37
+ `npm run typecheck`, `npm run lint` and `npm run check:design-lint` include `templates/`. `npm run check:package` also typechecks these sources against the installed tarball, from the installed tarball, alongside the shipped consumer-skill recipes. `node docs/consumer-skill/scripts/check-composition.mjs templates` is a supplementary static review; unresolved dynamic spreads still need source and interaction review.
38
+
39
+ `tests/browser/templates.spec.ts` covers Card boundaries at desktop/mobile widths in both themes, mobile navigation and contact/credit submission. The dated verification report records the images actually inspected and the checks executed. Static checks and screenshots do not establish backend integration.