themelia-react-ui 1.0.0 → 1.0.2

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 (507) hide show
  1. package/CHANGELOG.md +190 -1
  2. package/README.md +92 -13
  3. package/dist/{accordion-BRWh3BM1.js → accordion-BRTcsp8J.js} +8 -8
  4. package/dist/accordion-BRTcsp8J.js.map +1 -0
  5. package/dist/{action-menu-Cx3SdfbN.js → action-menu-Drxw_vJk.js} +36 -36
  6. package/dist/action-menu-Drxw_vJk.js.map +1 -0
  7. package/dist/affordance-geometry.generated-CL84ZN9A.js +63 -0
  8. package/dist/affordance-geometry.generated-CL84ZN9A.js.map +1 -0
  9. package/dist/{ai-artifact-DkOArd3-.js → ai-artifact-DLVdK0Py.js} +151 -155
  10. package/dist/ai-artifact-DLVdK0Py.js.map +1 -0
  11. package/dist/{app-shell-BH_bGcE2.js → app-shell-C_fKpljx.js} +11 -10
  12. package/dist/app-shell-C_fKpljx.js.map +1 -0
  13. package/dist/{attachment-DsLgNHXt.js → attachment-DbjUWsP0.js} +12 -12
  14. package/dist/{attachment-DsLgNHXt.js.map → attachment-DbjUWsP0.js.map} +1 -1
  15. package/dist/auth-CAQcasMV.js +723 -0
  16. package/dist/auth-CAQcasMV.js.map +1 -0
  17. package/dist/{avatar-CsnWaYmt.js → avatar-Bu2HhitA.js} +76 -71
  18. package/dist/avatar-Bu2HhitA.js.map +1 -0
  19. package/dist/{badge-BZXZT9wd.js → badge-CzId1Wlm.js} +4 -4
  20. package/dist/{badge-BZXZT9wd.js.map → badge-CzId1Wlm.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/buttons.js +3 -2
  27. package/dist/base/cards.js +3 -3
  28. package/dist/base/carousel.js +25 -27
  29. package/dist/base/carousel.js.map +1 -1
  30. package/dist/base/cascader.js +150 -148
  31. package/dist/base/cascader.js.map +1 -1
  32. package/dist/base/chart.js +1 -1
  33. package/dist/base/choice-inputs.js +3 -2
  34. package/dist/base/code-block.js +1 -1
  35. package/dist/base/combobox.js +1 -1
  36. package/dist/base/command.js +1 -1
  37. package/dist/base/copyable.js +1 -1
  38. package/dist/base/date-pickers.js +3 -3
  39. package/dist/base/display.js +7 -7
  40. package/dist/base/feedback.js +4 -3
  41. package/dist/base/forms-numeric.js +1 -1
  42. package/dist/base/forms.js +2 -2
  43. package/dist/base/inline-edit.js +233 -0
  44. package/dist/base/inline-edit.js.map +1 -0
  45. package/dist/base/item.js +1 -1
  46. package/dist/base/media-gallery.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 +33 -33
  52. package/dist/base/repeaters.js.map +1 -1
  53. package/dist/base/sheet.js +1 -1
  54. package/dist/base/sidebar.js +1 -1
  55. package/dist/base/signature-pad.js +83 -81
  56. package/dist/base/signature-pad.js.map +1 -1
  57. package/dist/base/skeleton.js +1 -1
  58. package/dist/base/spinner.js +1 -1
  59. package/dist/base/structure.js +1 -1
  60. package/dist/base/table.js +1 -1
  61. package/dist/base/text-inputs.js +2 -2
  62. package/dist/base/toaster.js +6 -6
  63. package/dist/base/toaster.js.map +1 -1
  64. package/dist/base/tree.js +1 -1
  65. package/dist/base/upload-queue.js +1 -1
  66. package/dist/base/upload.js +3 -3
  67. package/dist/base/value-inputs.js +1 -1
  68. package/dist/blocks/admin.js +134 -134
  69. package/dist/blocks/admin.js.map +1 -1
  70. package/dist/blocks/ai.js +120 -117
  71. package/dist/blocks/ai.js.map +1 -1
  72. package/dist/blocks/analytics/usage-card.js +3 -0
  73. package/dist/blocks/analytics.js +530 -491
  74. package/dist/blocks/analytics.js.map +1 -1
  75. package/dist/blocks/collaboration.js +2 -2
  76. package/dist/blocks/commerce/receipt.js +1 -1
  77. package/dist/blocks/commerce.js +395 -383
  78. package/dist/blocks/commerce.js.map +1 -1
  79. package/dist/blocks/data-display.js +1 -1
  80. package/dist/blocks/onboarding.js +6 -6
  81. package/dist/blocks/onboarding.js.map +1 -1
  82. package/dist/blocks/planning.js +311 -0
  83. package/dist/blocks/planning.js.map +1 -0
  84. package/dist/blocks/timelines.js +1 -1
  85. package/dist/{breadcrumbs-DdQ_I5ra.js → breadcrumbs-BuYz5SDU.js} +9 -8
  86. package/dist/breadcrumbs-BuYz5SDU.js.map +1 -0
  87. package/dist/button-BZDasD04.js +651 -0
  88. package/dist/button-BZDasD04.js.map +1 -0
  89. package/dist/{button-BS6l5JUw.js → button-BZyfTvwm.js} +3 -3
  90. package/dist/button-BZyfTvwm.js.map +1 -0
  91. package/dist/buttons-D_6KJvEE.js +99 -0
  92. package/dist/buttons-D_6KJvEE.js.map +1 -0
  93. package/dist/{cards-BMB0laLG.js → cards-qGSErLw_.js} +12 -12
  94. package/dist/{cards-BMB0laLG.js.map → cards-qGSErLw_.js.map} +1 -1
  95. package/dist/chart-Bsc5BICK.js +150 -0
  96. package/dist/chart-Bsc5BICK.js.map +1 -0
  97. package/dist/checkbox-BQNDjUCh.js +34 -0
  98. package/dist/checkbox-BQNDjUCh.js.map +1 -0
  99. package/dist/choice-inputs-Mk3iWbhr.js +725 -0
  100. package/dist/choice-inputs-Mk3iWbhr.js.map +1 -0
  101. package/dist/{code-block-DIlqzoiD.js → code-block-DzHKRybS.js} +23 -23
  102. package/dist/code-block-DzHKRybS.js.map +1 -0
  103. package/dist/{collapsible-DsnktFNv.js → collapsible-ClvC7Bj3.js} +3 -3
  104. package/dist/{collapsible-DsnktFNv.js.map → collapsible-ClvC7Bj3.js.map} +1 -1
  105. package/dist/{collection-content-C4fthJV_.js → collection-content-D6S8cv_n.js} +3 -3
  106. package/dist/{collection-content-C4fthJV_.js.map → collection-content-D6S8cv_n.js.map} +1 -1
  107. package/dist/{combobox-HDftpzxt.js → combobox-BFnbJJp3.js} +18 -18
  108. package/dist/combobox-BFnbJJp3.js.map +1 -0
  109. package/dist/{combobox-CHD750do.js → combobox-hozNwUcc.js} +313 -316
  110. package/dist/combobox-hozNwUcc.js.map +1 -0
  111. package/dist/{command-D0kWBZfd.js → command-BnmSchli.js} +9 -9
  112. package/dist/command-BnmSchli.js.map +1 -0
  113. package/dist/comments-u5L0OGip.js +1156 -0
  114. package/dist/comments-u5L0OGip.js.map +1 -0
  115. package/dist/components/base/buttons/button-group.recipes.d.ts +1 -1
  116. package/dist/components/base/buttons/button.recipes.d.ts +10 -19
  117. package/dist/components/base/buttons/use-pending-button-focus.d.ts +3 -0
  118. package/dist/components/base/cards/card.recipes.d.ts +13 -5
  119. package/dist/components/base/cards/partials/card-primitives.d.ts +9 -4
  120. package/dist/components/base/cards/smart-card.types.d.ts +3 -1
  121. package/dist/components/base/date-pickers/date-picker.recipes.d.ts +5 -18
  122. package/dist/components/base/date-pickers/datepicker.types.d.ts +3 -0
  123. package/dist/components/base/forms/form-field.d.ts +1 -0
  124. package/dist/components/base/forms/form-sizing.d.ts +3 -3
  125. package/dist/components/base/inline-edit/index.d.ts +2 -0
  126. package/dist/components/base/inline-edit/inline-edit.d.ts +81 -0
  127. package/dist/components/base/inline-edit/inline-edit.recipes.d.ts +6 -0
  128. package/dist/components/base/navigation/tabs.d.ts +3 -5
  129. package/dist/components/base/popover/popover.recipes.d.ts +3 -3
  130. package/dist/components/base/structure/structure.recipes.d.ts +6 -0
  131. package/dist/components/base/table/index.d.ts +1 -1
  132. package/dist/components/base/text-inputs/clear-native-field.d.ts +2 -0
  133. package/dist/components/base/text-inputs/input-trailing-action.d.ts +3 -0
  134. package/dist/components/blocks/analytics/index.d.ts +1 -0
  135. package/dist/components/blocks/analytics/types.d.ts +1 -1
  136. package/dist/components/blocks/analytics/usage-card/index.d.ts +3 -0
  137. package/dist/components/blocks/analytics/usage-card/types.d.ts +52 -0
  138. package/dist/components/blocks/analytics/usage-card/usage-card.d.ts +6 -0
  139. package/dist/components/blocks/analytics/usage-card/usage-card.data.d.ts +19 -0
  140. package/dist/components/blocks/analytics/usage-card/usage-card.strings.d.ts +22 -0
  141. package/dist/components/blocks/collaboration/message/message.recipes.d.ts +12 -0
  142. package/dist/components/blocks/data-display/empty-state/partials/illustrations/document-stack.d.ts +1 -4
  143. package/dist/components/blocks/data-display/empty-state/partials/illustrations/inbox-clean.d.ts +1 -4
  144. package/dist/components/blocks/data-display/empty-state/partials/illustrations/index.d.ts +3 -3
  145. package/dist/components/blocks/data-display/empty-state/partials/illustrations/stacked-cards.d.ts +1 -6
  146. package/dist/components/blocks/planning/index.d.ts +3 -0
  147. package/dist/components/blocks/planning/task-card.d.ts +3 -0
  148. package/dist/components/blocks/planning/task-card.strings.d.ts +15 -0
  149. package/dist/components/blocks/planning/task-card.types.d.ts +66 -0
  150. package/dist/components/features/combobox/components/error-message.d.ts +1 -1
  151. package/dist/components/features/comments/hooks/use-attachment-upload.d.ts +5 -0
  152. package/dist/components/features/filters/facets/search-facet.d.ts +0 -12
  153. package/dist/components/features/filters/facets/tags-facet.d.ts +1 -1
  154. package/dist/components/features/media-library/media-library.d.ts +1 -1
  155. package/dist/components/features/media-library/media-library.types.d.ts +9 -1
  156. package/dist/components/features/media-library/partials/media-library-partials.d.ts +1 -1
  157. package/dist/components/features/overlays/hooks/use-pending-overlay-focus.d.ts +2 -0
  158. package/dist/components/features/overlays/overlays.types.d.ts +5 -4
  159. package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +2 -1
  160. package/dist/components/features/table/data-table.d.ts +1 -1
  161. package/dist/components/features/table/table.types.d.ts +1 -1
  162. package/dist/components/features/theme-tweaker/theme-provider-settings.d.ts +3 -1
  163. package/dist/components/layout/auth/auth.types.d.ts +1 -0
  164. package/dist/components/layout/page/page.d.ts +0 -1
  165. package/dist/components/layout/page/page.types.d.ts +9 -3
  166. package/dist/components/layout/sidebar/sidebar.context.d.ts +1 -1
  167. package/dist/components/layout/sidebar/sidebar.types.d.ts +4 -0
  168. package/dist/components/layout/workspace/workspace.types.d.ts +3 -0
  169. package/dist/components/typography/heading.d.ts +5 -2
  170. package/dist/components/typography/index.d.ts +1 -1
  171. package/dist/components/typography/text.styles.d.ts +10 -0
  172. package/dist/components/ui/popover.d.ts +1 -1
  173. package/dist/components/ui/sidebar.d.ts +1 -1
  174. package/dist/components/ui/table.d.ts +2 -1
  175. package/dist/container.recipes-D9t8MHR3.js +27 -0
  176. package/dist/container.recipes-D9t8MHR3.js.map +1 -0
  177. package/dist/{containers-CPNyNo1_.js → containers-DqB-bSYE.js} +34 -56
  178. package/dist/containers-DqB-bSYE.js.map +1 -0
  179. package/dist/control-group-recipes-DBXmfh2E.js +21 -0
  180. package/dist/control-group-recipes-DBXmfh2E.js.map +1 -0
  181. package/dist/{copyable-B7SBXJMr.js → copyable-BTSByfmq.js} +6 -6
  182. package/dist/{copyable-B7SBXJMr.js.map → copyable-BTSByfmq.js.map} +1 -1
  183. package/dist/{data-display-b3d1TfL4.js → data-display-Bihs9Ven.js} +542 -329
  184. package/dist/data-display-Bihs9Ven.js.map +1 -0
  185. package/dist/{date-BFNMnrS5.js → date-DOKhJPu7.js} +4 -4
  186. package/dist/{date-BFNMnrS5.js.map → date-DOKhJPu7.js.map} +1 -1
  187. package/dist/{date-picker-DI6kPNof.js → date-picker-DzP5HQq7.js} +492 -472
  188. package/dist/date-picker-DzP5HQq7.js.map +1 -0
  189. package/dist/date-pickers-BpgGz7S-.js +196 -0
  190. package/dist/date-pickers-BpgGz7S-.js.map +1 -0
  191. package/dist/{display-ByI5tkqy.js → display-CS6Hbk18.js} +8 -8
  192. package/dist/{display-ByI5tkqy.js.map → display-CS6Hbk18.js.map} +1 -1
  193. package/dist/{dropdown-menu-BlnyHr-9.js → dropdown-menu-D-boNgGO.js} +7 -7
  194. package/dist/{dropdown-menu-BlnyHr-9.js.map → dropdown-menu-D-boNgGO.js.map} +1 -1
  195. package/dist/features/activities.js +152 -141
  196. package/dist/features/activities.js.map +1 -1
  197. package/dist/features/ai-chat.js +182 -179
  198. package/dist/features/ai-chat.js.map +1 -1
  199. package/dist/features/async-preview.js +9 -9
  200. package/dist/features/async-preview.js.map +1 -1
  201. package/dist/features/combobox.js +1 -1
  202. package/dist/features/comments.js +1 -1
  203. package/dist/features/data-view.js +25 -23
  204. package/dist/features/data-view.js.map +1 -1
  205. package/dist/features/email-composer/engine.js +1 -1
  206. package/dist/features/email-composer.js +103 -104
  207. package/dist/features/email-composer.js.map +1 -1
  208. package/dist/features/event-calendar.js +375 -373
  209. package/dist/features/event-calendar.js.map +1 -1
  210. package/dist/features/filters.js +1 -1
  211. package/dist/features/global-search.js +222 -224
  212. package/dist/features/global-search.js.map +1 -1
  213. package/dist/features/kanban.js +29 -29
  214. package/dist/features/kanban.js.map +1 -1
  215. package/dist/features/map.js +59 -58
  216. package/dist/features/map.js.map +1 -1
  217. package/dist/features/media-library.js +856 -855
  218. package/dist/features/media-library.js.map +1 -1
  219. package/dist/features/mentions.js +1 -1
  220. package/dist/features/overlays.js +1 -1
  221. package/dist/features/products.js +1210 -1209
  222. package/dist/features/products.js.map +1 -1
  223. package/dist/features/questionnaire.js +133 -132
  224. package/dist/features/questionnaire.js.map +1 -1
  225. package/dist/features/resource-assignment.js +29 -31
  226. package/dist/features/resource-assignment.js.map +1 -1
  227. package/dist/features/resource.js +13 -13
  228. package/dist/features/resource.js.map +1 -1
  229. package/dist/features/rich-text-editor.js +2 -2
  230. package/dist/features/schema-form.js +82 -82
  231. package/dist/features/schema-form.js.map +1 -1
  232. package/dist/features/suggestions.js +3 -3
  233. package/dist/features/sync.js +4 -4
  234. package/dist/features/sync.js.map +1 -1
  235. package/dist/features/table.js +1 -1
  236. package/dist/features/theme-tweaker.js +456 -450
  237. package/dist/features/theme-tweaker.js.map +1 -1
  238. package/dist/feedback-CJkUAapr.js +233 -0
  239. package/dist/feedback-CJkUAapr.js.map +1 -0
  240. package/dist/field-affordance-recipes-uKY4MsZ_.js +25 -0
  241. package/dist/field-affordance-recipes-uKY4MsZ_.js.map +1 -0
  242. package/dist/{field-state-recipes-CBTRt9Bt.js → field-state-recipes-DQQpiLWC.js} +3 -3
  243. package/dist/field-state-recipes-DQQpiLWC.js.map +1 -0
  244. package/dist/{filters-qtrcv1hf.js → filters-D6FF8L6s.js} +715 -720
  245. package/dist/filters-D6FF8L6s.js.map +1 -0
  246. package/dist/{form-field-C6W-y2hR.js → form-field-CZwrkP7m.js} +17 -9
  247. package/dist/form-field-CZwrkP7m.js.map +1 -0
  248. package/dist/{form-sizing-39NohSqn.js → form-sizing-QP8aIRaW.js} +10 -6
  249. package/dist/form-sizing-QP8aIRaW.js.map +1 -0
  250. package/dist/{forms-BF-HSbff.js → forms-B5NCbkSC.js} +35 -35
  251. package/dist/{forms-BF-HSbff.js.map → forms-B5NCbkSC.js.map} +1 -1
  252. package/dist/forms-numeric-Crrm80Lm.js +867 -0
  253. package/dist/forms-numeric-Crrm80Lm.js.map +1 -0
  254. package/dist/{header-B8ex54cY.js → header-kxruN3RM.js} +53 -49
  255. package/dist/header-kxruN3RM.js.map +1 -0
  256. package/dist/{hooks-D6UBVzf2.js → hooks-BrlnCwQd.js} +2 -2
  257. package/dist/{hooks-D6UBVzf2.js.map → hooks-BrlnCwQd.js.map} +1 -1
  258. package/dist/{http-CLTVJc5I.js → http-CdEIHyQf.js} +2 -2
  259. package/dist/http-CdEIHyQf.js.map +1 -0
  260. package/dist/{icon-badge-Dv0RYQwj.js → icon-badge-Btc6pQrp.js} +4 -4
  261. package/dist/{icon-badge-Dv0RYQwj.js.map → icon-badge-Btc6pQrp.js.map} +1 -1
  262. package/dist/index.js +2 -2
  263. package/dist/input-SX9V0AL3.js +255 -0
  264. package/dist/input-SX9V0AL3.js.map +1 -0
  265. package/dist/input-vxcaNCYC.js +20 -0
  266. package/dist/input-vxcaNCYC.js.map +1 -0
  267. package/dist/{item-pJ0GsOiJ.js → item-DE4YnuJx.js} +18 -17
  268. package/dist/item-DE4YnuJx.js.map +1 -0
  269. package/dist/layout/app-shell.js +1 -1
  270. package/dist/layout/auth.js +1 -1
  271. package/dist/layout/containers.js +1 -1
  272. package/dist/layout/header.js +1 -1
  273. package/dist/layout/hooks.js +1 -1
  274. package/dist/layout/navigation.js +1 -1
  275. package/dist/layout/page.js +1 -1
  276. package/dist/layout/settings.js +1 -1
  277. package/dist/layout/sidebar.js +2 -2
  278. package/dist/layout/workspace.js +1 -1
  279. package/dist/layout.js +10 -10
  280. package/dist/lib/affordance-geometry.generated.d.ts +44 -4
  281. package/dist/lib/control-group-recipes.d.ts +22 -0
  282. package/dist/lib/field-affordance-recipes.d.ts +35 -2
  283. package/dist/lib/field-state-recipes.d.ts +2 -2
  284. package/dist/lib/navigation-row-recipes.d.ts +3 -2
  285. package/dist/lib/overlay-anatomy-recipes.d.ts +1 -1
  286. package/dist/lib/surface-recipes.d.ts +5 -2
  287. package/dist/lib/token-merge.generated.d.ts +144 -2
  288. package/dist/lib/ui-provider/types.d.ts +4 -2
  289. package/dist/lib/use-prefers-reduced-motion.d.ts +2 -0
  290. package/dist/lib/utils.js +1 -1
  291. package/dist/{media-gallery-Ca4YmvBi.js → media-gallery-DLp3HAz0.js} +75 -74
  292. package/dist/media-gallery-DLp3HAz0.js.map +1 -0
  293. package/dist/{mentions-CRio8mTm.js → mentions-Cl0Kt_Pd.js} +52 -50
  294. package/dist/{mentions-CRio8mTm.js.map → mentions-Cl0Kt_Pd.js.map} +1 -1
  295. package/dist/message-SZUNB1eX.js +127 -0
  296. package/dist/message-SZUNB1eX.js.map +1 -0
  297. package/dist/{navigation-BTrEb5u4.js → navigation-DnQSNMT0.js} +64 -55
  298. package/dist/navigation-DnQSNMT0.js.map +1 -0
  299. package/dist/{navigation-DqEITuD2.js → navigation-DyytsLRB.js} +37 -37
  300. package/dist/navigation-DyytsLRB.js.map +1 -0
  301. package/dist/{navigation-row-recipes-BFpvGPGE.js → navigation-row-recipes-DQEXQcqY.js} +3 -3
  302. package/dist/navigation-row-recipes-DQEXQcqY.js.map +1 -0
  303. package/dist/{number-BNT_BIzJ.js → number-DasMFWEG.js} +4 -4
  304. package/dist/{number-BNT_BIzJ.js.map → number-DasMFWEG.js.map} +1 -1
  305. package/dist/overlays-DUbs1KEi.js +1011 -0
  306. package/dist/overlays-DUbs1KEi.js.map +1 -0
  307. package/dist/{page-BMBGjJY8.js → page-hGmT4nWK.js} +75 -64
  308. package/dist/page-hGmT4nWK.js.map +1 -0
  309. package/dist/{page-header-BH41wCyY.js → page-header-D8nERkn5.js} +9 -9
  310. package/dist/page-header-D8nERkn5.js.map +1 -0
  311. package/dist/{pagination-C29vvt3I.js → pagination-NLGqRirf.js} +20 -20
  312. package/dist/pagination-NLGqRirf.js.map +1 -0
  313. package/dist/{popover-TInGXsjg.js → popover-CghIYdQf.js} +23 -22
  314. package/dist/popover-CghIYdQf.js.map +1 -0
  315. package/dist/{popover-menu-BzqXqE72.js → popover-menu-B4PoWhRl.js} +6 -6
  316. package/dist/{popover-menu-BzqXqE72.js.map → popover-menu-B4PoWhRl.js.map} +1 -1
  317. package/dist/{popover.recipes-zgBhMlUu.js → popover.recipes-QlD4JenO.js} +5 -5
  318. package/dist/popover.recipes-QlD4JenO.js.map +1 -0
  319. package/dist/{primitives-DKPOGVpj.js → primitives-C7ff0QaI.js} +120 -113
  320. package/dist/primitives-C7ff0QaI.js.map +1 -0
  321. package/dist/primitives.js +3 -3
  322. package/dist/progress-BroqrAyV.js +169 -0
  323. package/dist/progress-BroqrAyV.js.map +1 -0
  324. package/dist/{receipt-DYWTQGEc.js → receipt-BuJynLgf.js} +8 -8
  325. package/dist/{receipt-DYWTQGEc.js.map → receipt-BuJynLgf.js.map} +1 -1
  326. package/dist/{rich-text-B7sBAdDG.js → rich-text-DlxDOtf4.js} +4 -4
  327. package/dist/{rich-text-B7sBAdDG.js.map → rich-text-DlxDOtf4.js.map} +1 -1
  328. package/dist/rich-text-editor-BKyG7rWz.js +574 -0
  329. package/dist/rich-text-editor-BKyG7rWz.js.map +1 -0
  330. package/dist/{rich-text-editor.recipes-DxvOE0Lp.js → rich-text-editor.recipes-B72Nfuze.js} +35 -26
  331. package/dist/rich-text-editor.recipes-B72Nfuze.js.map +1 -0
  332. package/dist/{scroll-area-BheMQ270.js → scroll-area-D-pIhEKl.js} +3 -3
  333. package/dist/scroll-area-D-pIhEKl.js.map +1 -0
  334. package/dist/{separator-Gk_WXH-l.js → separator-BNIgG3au.js} +3 -3
  335. package/dist/{separator-Gk_WXH-l.js.map → separator-BNIgG3au.js.map} +1 -1
  336. package/dist/{separator-DO0EbCEm.js → separator-BhtFyo4x.js} +2 -2
  337. package/dist/{separator-DO0EbCEm.js.map → separator-BhtFyo4x.js.map} +1 -1
  338. package/dist/services/actions.js +1 -1
  339. package/dist/{settings-D9f_wdIC.js → settings-DOTOzeZ2.js} +10 -9
  340. package/dist/{settings-D9f_wdIC.js.map → settings-DOTOzeZ2.js.map} +1 -1
  341. package/dist/{sheet-vOUloJ4O.js → sheet-BFhrNehm.js} +11 -11
  342. package/dist/sheet-BFhrNehm.js.map +1 -0
  343. package/dist/{sidebar-CNBKFDRW.js → sidebar-CyR4XKwR.js} +219 -200
  344. package/dist/sidebar-CyR4XKwR.js.map +1 -0
  345. package/dist/{sidebar-C3UKkbC5.js → sidebar-SvGJ0Zwi.js} +63 -58
  346. package/dist/sidebar-SvGJ0Zwi.js.map +1 -0
  347. package/dist/{skeleton-BvRhK8y-.js → skeleton-3F0uhYn3.js} +4 -4
  348. package/dist/{skeleton-BvRhK8y-.js.map → skeleton-3F0uhYn3.js.map} +1 -1
  349. package/dist/{smart-card-B5FcKODh.js → smart-card-DjGVV2xr.js} +206 -199
  350. package/dist/smart-card-DjGVV2xr.js.map +1 -0
  351. package/dist/{spinner-JtlFJ7Nc.js → spinner-Cpf7oRkF.js} +5 -5
  352. package/dist/{spinner-JtlFJ7Nc.js.map → spinner-Cpf7oRkF.js.map} +1 -1
  353. package/dist/{structure-BvW4vG4H.js → structure-CRdqVawd.js} +14 -14
  354. package/dist/{structure-BvW4vG4H.js.map → structure-CRdqVawd.js.map} +1 -1
  355. package/dist/{structure.recipes-DjqnBpwz.js → structure.recipes-Bqhf9oIh.js} +2 -2
  356. package/dist/structure.recipes-Bqhf9oIh.js.map +1 -0
  357. package/dist/style.css +1 -1
  358. package/dist/{surface-recipes-CQfRr-VL.js → surface-recipes-Dd__PD-w.js} +4 -3
  359. package/dist/surface-recipes-Dd__PD-w.js.map +1 -0
  360. package/dist/{table-DnlAJ-xR.js → table-CLtJTxoR.js} +17 -16
  361. package/dist/table-CLtJTxoR.js.map +1 -0
  362. package/dist/table-CcRDZiLP.js +1444 -0
  363. package/dist/table-CcRDZiLP.js.map +1 -0
  364. package/dist/tabs-BNgu7g0u.js +188 -0
  365. package/dist/tabs-BNgu7g0u.js.map +1 -0
  366. package/dist/text-inputs-DsR56TR-.js +330 -0
  367. package/dist/text-inputs-DsR56TR-.js.map +1 -0
  368. package/dist/{text.styles-BwB7vAF2.js → text.styles-Q4sGAIgA.js} +18 -10
  369. package/dist/text.styles-Q4sGAIgA.js.map +1 -0
  370. package/dist/theme.css +77 -115
  371. package/dist/{timelines-CnZ2S_Gr.js → timelines-D1pkt3se.js} +84 -78
  372. package/dist/timelines-D1pkt3se.js.map +1 -0
  373. package/dist/{tree-COD9BGdU.js → tree-BtmYyMZV.js} +8 -8
  374. package/dist/{tree-COD9BGdU.js.map → tree-BtmYyMZV.js.map} +1 -1
  375. package/dist/typography/rich-text.js +1 -1
  376. package/dist/typography-BxQgiZyw.js +96 -0
  377. package/dist/typography-BxQgiZyw.js.map +1 -0
  378. package/dist/typography.js +1 -1
  379. package/dist/{ui-provider-CftIB6TY.js → ui-provider-DRPn3qNl.js} +3 -2
  380. package/dist/ui-provider-DRPn3qNl.js.map +1 -0
  381. package/dist/ui-provider.js +1 -1
  382. package/dist/{upload-DIzw1dx1.js → upload-CDbYw1WN.js} +326 -323
  383. package/dist/upload-CDbYw1WN.js.map +1 -0
  384. package/dist/{upload-queue-xRJ3qDmd.js → upload-queue-CNd_hH_a.js} +25 -25
  385. package/dist/upload-queue-CNd_hH_a.js.map +1 -0
  386. package/dist/usage-card-VyJLUwRr.js +457 -0
  387. package/dist/usage-card-VyJLUwRr.js.map +1 -0
  388. package/dist/utils-BvH9PSmq.js +4275 -0
  389. package/dist/utils-BvH9PSmq.js.map +1 -0
  390. package/dist/value-inputs-D0KCrfVC.js +840 -0
  391. package/dist/value-inputs-D0KCrfVC.js.map +1 -0
  392. package/dist/{workspace-Cbqz4FzN.js → workspace-CcR8r-Nt.js} +115 -122
  393. package/dist/workspace-CcR8r-Nt.js.map +1 -0
  394. package/docs/consumer-skill/SKILL.md +112 -18
  395. package/docs/consumer-skill/examples/analytics.tsx +34 -0
  396. package/docs/consumer-skill/examples/app-layout.tsx +42 -12
  397. package/docs/consumer-skill/examples/detail.tsx +24 -9
  398. package/docs/consumer-skill/examples/manifest.json +27 -1
  399. package/docs/consumer-skill/examples/planning-usage-edit.tsx +29 -0
  400. package/docs/consumer-skill/examples/scoped-directory.tsx +77 -0
  401. package/docs/consumer-skill/examples/website.tsx +56 -0
  402. package/docs/consumer-skill/references/analytics.md +70 -0
  403. package/docs/consumer-skill/references/composition.md +219 -2
  404. package/docs/consumer-skill/references/design-contract.md +37 -10
  405. package/docs/consumer-skill/references/discovery.md +93 -5
  406. package/docs/consumer-skill/references/installation.md +20 -3
  407. package/docs/consumer-skill/references/integration.md +26 -0
  408. package/docs/consumer-skill/references/public-api.json +2416 -388
  409. package/docs/consumer-skill/references/review.md +126 -0
  410. package/docs/consumer-skill/references/theming.md +52 -7
  411. package/docs/consumer-skill/references/tokens.json +177 -9
  412. package/docs/consumer-skill/references/workflows.md +129 -1
  413. package/docs/consumer-skill/scripts/check-composition.mjs +31 -0
  414. package/docs/consumer-skill/scripts/composition-policy.mjs +317 -0
  415. package/docs/consumer-skill/scripts/discovery.mjs +65 -8
  416. package/docs/consumer-skill/scripts/surface-policy.mjs +66 -0
  417. package/package.json +30 -6
  418. package/dist/accordion-BRWh3BM1.js.map +0 -1
  419. package/dist/action-menu-Cx3SdfbN.js.map +0 -1
  420. package/dist/affordance-geometry.generated-DXl-Zb3Z.js +0 -23
  421. package/dist/affordance-geometry.generated-DXl-Zb3Z.js.map +0 -1
  422. package/dist/ai-artifact-DkOArd3-.js.map +0 -1
  423. package/dist/app-shell-BH_bGcE2.js.map +0 -1
  424. package/dist/auth-BDB1V_2q.js +0 -704
  425. package/dist/auth-BDB1V_2q.js.map +0 -1
  426. package/dist/avatar-CsnWaYmt.js.map +0 -1
  427. package/dist/breadcrumbs-DdQ_I5ra.js.map +0 -1
  428. package/dist/button-BS6l5JUw.js.map +0 -1
  429. package/dist/buttons-Co6GavvM.js +0 -674
  430. package/dist/buttons-Co6GavvM.js.map +0 -1
  431. package/dist/chart-DVfcwQu6.js +0 -149
  432. package/dist/chart-DVfcwQu6.js.map +0 -1
  433. package/dist/choice-inputs-CavA-SGV.js +0 -644
  434. package/dist/choice-inputs-CavA-SGV.js.map +0 -1
  435. package/dist/code-block-DIlqzoiD.js.map +0 -1
  436. package/dist/combobox-CHD750do.js.map +0 -1
  437. package/dist/combobox-HDftpzxt.js.map +0 -1
  438. package/dist/command-D0kWBZfd.js.map +0 -1
  439. package/dist/comments-CvYeglMS.js +0 -1132
  440. package/dist/comments-CvYeglMS.js.map +0 -1
  441. package/dist/containers-CPNyNo1_.js.map +0 -1
  442. package/dist/data-display-b3d1TfL4.js.map +0 -1
  443. package/dist/date-picker-DI6kPNof.js.map +0 -1
  444. package/dist/date-pickers-ByP6Cv2z.js +0 -224
  445. package/dist/date-pickers-ByP6Cv2z.js.map +0 -1
  446. package/dist/feedback-a9j9J-9A.js +0 -391
  447. package/dist/feedback-a9j9J-9A.js.map +0 -1
  448. package/dist/field-affordance-recipes-CHdUtn2Z.js +0 -17
  449. package/dist/field-affordance-recipes-CHdUtn2Z.js.map +0 -1
  450. package/dist/field-state-recipes-CBTRt9Bt.js.map +0 -1
  451. package/dist/filters-qtrcv1hf.js.map +0 -1
  452. package/dist/form-field-C6W-y2hR.js.map +0 -1
  453. package/dist/form-sizing-39NohSqn.js.map +0 -1
  454. package/dist/forms-numeric-Y15Bg5Nr.js +0 -867
  455. package/dist/forms-numeric-Y15Bg5Nr.js.map +0 -1
  456. package/dist/header-B8ex54cY.js.map +0 -1
  457. package/dist/http-CLTVJc5I.js.map +0 -1
  458. package/dist/input-DMorJiTI.js +0 -202
  459. package/dist/input-DMorJiTI.js.map +0 -1
  460. package/dist/input-ci9fIgFH.js +0 -20
  461. package/dist/input-ci9fIgFH.js.map +0 -1
  462. package/dist/item-pJ0GsOiJ.js.map +0 -1
  463. package/dist/media-gallery-Ca4YmvBi.js.map +0 -1
  464. package/dist/message-B5-6LeYl.js +0 -108
  465. package/dist/message-B5-6LeYl.js.map +0 -1
  466. package/dist/navigation-BTrEb5u4.js.map +0 -1
  467. package/dist/navigation-DqEITuD2.js.map +0 -1
  468. package/dist/navigation-row-recipes-BFpvGPGE.js.map +0 -1
  469. package/dist/overlays-DBqV0J_V.js +0 -982
  470. package/dist/overlays-DBqV0J_V.js.map +0 -1
  471. package/dist/page-BMBGjJY8.js.map +0 -1
  472. package/dist/page-header-BH41wCyY.js.map +0 -1
  473. package/dist/pagination-C29vvt3I.js.map +0 -1
  474. package/dist/popover-TInGXsjg.js.map +0 -1
  475. package/dist/popover.recipes-zgBhMlUu.js.map +0 -1
  476. package/dist/primitives-DKPOGVpj.js.map +0 -1
  477. package/dist/rich-text-editor-BZSJchAF.js +0 -575
  478. package/dist/rich-text-editor-BZSJchAF.js.map +0 -1
  479. package/dist/rich-text-editor.recipes-DxvOE0Lp.js.map +0 -1
  480. package/dist/scroll-area-BheMQ270.js.map +0 -1
  481. package/dist/select-B2mb-qN2.js +0 -108
  482. package/dist/select-B2mb-qN2.js.map +0 -1
  483. package/dist/sheet-vOUloJ4O.js.map +0 -1
  484. package/dist/sidebar-C3UKkbC5.js.map +0 -1
  485. package/dist/sidebar-CNBKFDRW.js.map +0 -1
  486. package/dist/smart-card-B5FcKODh.js.map +0 -1
  487. package/dist/structure.recipes-DjqnBpwz.js.map +0 -1
  488. package/dist/surface-recipes-CQfRr-VL.js.map +0 -1
  489. package/dist/table-DnlAJ-xR.js.map +0 -1
  490. package/dist/table-ghtAQ-JJ.js +0 -1424
  491. package/dist/table-ghtAQ-JJ.js.map +0 -1
  492. package/dist/tabs-DY09eoZg.js +0 -187
  493. package/dist/tabs-DY09eoZg.js.map +0 -1
  494. package/dist/text-inputs-BhOcedTo.js +0 -331
  495. package/dist/text-inputs-BhOcedTo.js.map +0 -1
  496. package/dist/text.styles-BwB7vAF2.js.map +0 -1
  497. package/dist/timelines-CnZ2S_Gr.js.map +0 -1
  498. package/dist/typography-Cv8MT-82.js +0 -96
  499. package/dist/typography-Cv8MT-82.js.map +0 -1
  500. package/dist/ui-provider-CftIB6TY.js.map +0 -1
  501. package/dist/upload-DIzw1dx1.js.map +0 -1
  502. package/dist/upload-queue-xRJ3qDmd.js.map +0 -1
  503. package/dist/utils-C2EKeIw3.js +0 -72
  504. package/dist/utils-C2EKeIw3.js.map +0 -1
  505. package/dist/value-inputs-Co1fu-xv.js +0 -824
  506. package/dist/value-inputs-Co1fu-xv.js.map +0 -1
  507. package/dist/workspace-Cbqz4FzN.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-kxruN3RM.js","names":["React","_Fragment","React","_Fragment","Text","Button","Stack","DropdownMenuItem","DropdownMenuSeparator","DropdownMenuTrigger","DropdownMenuGroup","DropdownMenuLabel","DropdownMenuContent","DropdownMenuLinkItem","DropdownMenu","ActionMenu","formatInitials","AvatarFallback","Avatar","AvatarImage","Badge","Separator","PopoverTrigger","Popover","PopoverContent","Breadcrumbs","SidebarTrigger","useLayoutLinkRenderer","useCommandShortcut","React$1","Fragment$1","HeaderBreadcrumbs","resolvedRenderLink","items","out","homeBreadcrumb","breadcrumbs","showCrumbs","cn","className","showSidebarTrigger","triggerSlot","Header","forwardRef","props","contentClassName","slots","showBreadcrumbs","breadcrumbsClassName","leftClassName","centerClassName","rightClassName","defaultHeaderNotificationsStrings","defaultHeaderSearchStrings","defaultHeaderUserMenuStrings","detectMac","ua","HeaderSearch","stringsProp","strings","useStrings","detectedMac","setDetectedMac","useState","shortcutModifier","isMetaShortcut","enableShortcut","onOpen","shortcutTitle","shortcut","shortcutSlot","Search","iconClassName","HeaderGlobalSearchTrigger","onOpenChange","HeaderToolButton","Icon","label","active","badge","HeaderToolPopover","open","triggerClassName","HeaderUserMenu","initials","user","actions","onProfile","User","onSettings","Settings","onLogout","LogOut","trigger","renderTrigger","showEmail","ChevronsUpDown","contentClasses","customContent","NOTIFICATION_TONE_CLASSNAMES","HeaderNotifications","badgeText","unreadCount","Bell","DisplayLabel","onMarkAllRead","notifications","NotificationRow","onNotificationClick","notification","onViewAll","viewAllHref","renderNotification","content","onClick","renderLink"],"sources":["../src/components/layout/header/partials/header-breadcrumbs.tsx","../src/components/layout/header/header.tsx","../src/components/layout/header/header.types.ts","../src/components/layout/header/partials/header-search.tsx","../src/components/layout/header/partials/header-global-search-trigger.tsx","../src/components/layout/header/partials/header-tool-button.tsx","../src/components/layout/header/partials/header-tool-popover.tsx","../src/components/layout/header/partials/header-user-menu.tsx","../src/components/layout/header/partials/header-notifications.tsx"],"sourcesContent":["/** HeaderBreadcrumbs — breadcrumbs trail with optional sidebar trigger. */\nimport * as React from 'react';\n\nimport { Separator } from '../../../base/display/separator';\nimport { Breadcrumbs } from '../../../base/navigation/breadcrumbs';\nimport { SidebarTrigger } from '../../../base/sidebar';\nimport { cn } from '../../../../lib/utils';\n\nimport { useLayoutLinkRenderer } from '../../hooks';\nimport type { BreadcrumbItem } from '../../layout.types';\nimport type { HeaderBreadcrumbsProps } from '../header.types';\n\nexport function HeaderBreadcrumbs({\n\tbreadcrumbs = [],\n\thomeBreadcrumb = null,\n\tshowSidebarTrigger = true,\n\ttriggerSlot,\n\trenderLink,\n\tclassName,\n}: HeaderBreadcrumbsProps) {\n\tconst resolvedRenderLink = useLayoutLinkRenderer({ renderLink });\n\tconst items = React.useMemo<BreadcrumbItem[]>(() => {\n\t\tconst out: BreadcrumbItem[] = [];\n\t\tif (homeBreadcrumb) out.push(homeBreadcrumb);\n\t\tout.push(...breadcrumbs);\n\t\treturn out;\n\t}, [homeBreadcrumb, breadcrumbs]);\n\n\tconst showCrumbs = items.length > 0;\n\n\treturn (\n\t\t<div className={cn('relative flex min-h-action min-w-0 items-center gap-space-lg', className)}>\n\t\t\t{!!showSidebarTrigger && (\n\t\t\t\t<div className=\"relative flex min-h-action shrink-0 items-center justify-center\">\n\t\t\t\t\t{triggerSlot ?? <SidebarTrigger className=\"size-action-xs [&_svg]:size-icon\" />}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{!!showCrumbs && (\n\t\t\t\t<>\n\t\t\t\t\t{!!showSidebarTrigger && <Separator orientation=\"vertical\" className=\"h-icon shrink-0\" />}\n\t\t\t\t\t<div className=\"flex min-w-0 flex-1 items-center overflow-hidden\">\n\t\t\t\t\t\t<Breadcrumbs\n\t\t\t\t\t\t\tbreadcrumbs={items}\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\trenderLink={resolvedRenderLink}\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t'min-w-0 overflow-hidden',\n\t\t\t\t\t\t\t\t'[&_[data-slot=breadcrumb-list]]:flex-nowrap [&_[data-slot=breadcrumb-list]]:overflow-hidden [&_[data-slot=breadcrumb-list]]:break-normal',\n\t\t\t\t\t\t\t\t'[&_[data-slot=breadcrumb-item]]:min-w-0 [&_[data-slot=breadcrumb-item]]:shrink',\n\t\t\t\t\t\t\t\t'[&_[data-slot=breadcrumb-link]]:truncate [&_[data-slot=breadcrumb-page]]:truncate',\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","/** Header — sticky top bar with breadcrumbs and slot-driven content regions. */\nimport { forwardRef } from 'react';\n\nimport { Stack } from '../../base/structure';\nimport { cn } from '../../../lib/utils';\n\nimport { useLayoutLinkRenderer } from '../hooks';\nimport { HeaderBreadcrumbs } from './partials/header-breadcrumbs';\nimport type { HeaderProps } from './header.types';\n\nexport const Header = forwardRef<HTMLElement, HeaderProps>(function Header({\n\tshowBreadcrumbs = true,\n\tbreadcrumbs = [],\n\thomeBreadcrumb = null,\n\tshowSidebarTrigger = true,\n\tslots,\n\trenderLink,\n\tclassName,\n\tcontentClassName,\n\tleftClassName,\n\tcenterClassName,\n\trightClassName,\n\tbreadcrumbsClassName,\n\t...props\n}, ref) {\n\tconst resolvedRenderLink = useLayoutLinkRenderer({ renderLink });\n\n\treturn (\n\t\t<header\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t'header--component @container/app-header sticky top-0 z-40 flex min-w-0 min-h-shell-header items-center border-b border-border bg-background px-surface py-space-sm transition-[width,height] ease-linear',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<Stack direction=\"horizontal\" gap=\"xl\" align=\"center\" wrap className={cn('min-w-0 min-h-action flex-1', contentClassName)}>\n\t\t\t\t{!!slots?.brand && (\n\t\t\t\t\t<div className=\"hidden min-w-0 shrink-0 items-center @2xl/app-header:flex\">\n\t\t\t\t\t\t{slots.brand}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{!!showBreadcrumbs && (\n\t\t\t\t\t<div className=\"min-w-0 flex-1 basis-32\">\n\t\t\t\t\t\t{slots?.breadcrumbs ?? (\n\t\t\t\t\t\t<HeaderBreadcrumbs\n\t\t\t\t\t\t\tbreadcrumbs={breadcrumbs}\n\t\t\t\t\t\t\thomeBreadcrumb={homeBreadcrumb}\n\t\t\t\t\t\t\tshowSidebarTrigger={showSidebarTrigger}\n\t\t\t\t\t\t\trenderLink={resolvedRenderLink}\n\t\t\t\t\t\t\tclassName={breadcrumbsClassName}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{!!slots?.left && (\n\t\t\t\t\t<div className={cn('flex min-w-0 items-center', leftClassName)}>\n\t\t\t\t\t\t{slots.left}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{!!slots?.center && (\n\t\t\t\t\t/* Search narrows within its region before navigation or account controls lose space. */\n\t\t\t\t\t<div className={cn('hidden min-w-0 flex-1 basis-64 items-center justify-center @3xl/app-header:flex [&>*]:min-w-0 [&>*]:max-w-full', centerClassName)}>\n\t\t\t\t\t\t{slots.center}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{!!slots?.right && (\n\t\t\t\t\t<div className={cn('ms-auto flex min-w-0 max-w-full flex-wrap items-center justify-end gap-space-md [&>*]:max-w-full', rightClassName)}>\n\t\t\t\t\t\t{slots.right}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</Stack>\n\t\t</header>\n\t);\n});\n\nHeader.displayName = 'Header';\n","/**\n * Header layout and partial types.\n *\n * This layer is intentionally framework-neutral: links and route state enter\n * through `renderLink`, and app-specific content enters through slots.\n */\nimport type { ComponentType, HTMLAttributes, ReactNode } from 'react';\n\nimport type { StringsProp } from '../../../lib/strings';\nimport type { SemanticTone } from '../../../lib/component-vocabulary';\n\nimport type {\n\tBreadcrumbItem,\n\tLayoutNavigationAdapter,\n\tLayoutUser,\n} from '../layout.types';\n\nexport interface HeaderBreadcrumbsProps extends LayoutNavigationAdapter {\n\t/** Trail entries, root first. */\n\tbreadcrumbs?: BreadcrumbItem[];\n\t/** Root entry prepended to the trail. */\n\thomeBreadcrumb?: BreadcrumbItem | null;\n\t/** Renders the sidebar collapse control. */\n\tshowSidebarTrigger?: boolean;\n\ttriggerSlot?: ReactNode;\n\tclassName?: string;\n}\n\nexport type NotificationTone = Extract<\n\tSemanticTone,\n\t'info' | 'success' | 'warning' | 'destructive'\n>;\n\nexport interface HeaderNotification {\n\tid: string | number;\n\t/** Surface title. */\n\ttitle: ReactNode;\n\t/** Supporting copy under the title. */\n\tdescription?: ReactNode;\n\ttime?: ReactNode;\n\tread?: boolean;\n\ttone?: NotificationTone;\n\t/** Destination for the entry, when it navigates. */\n\thref?: string;\n}\n\nexport interface HeaderNotificationsStrings {\n\ttriggerLabel: string;\n\theading: string;\n\tmarkAllRead: string;\n\tempty: string;\n\tviewAll: string;\n}\n\nexport const defaultHeaderNotificationsStrings: HeaderNotificationsStrings = {\n\ttriggerLabel: 'Notifications',\n\theading: 'Notifications',\n\tmarkAllRead: 'Mark all as read',\n\tempty: 'No new notifications',\n\tviewAll: 'View all notifications',\n};\n\nexport interface HeaderNotificationsProps extends LayoutNavigationAdapter {\n\t/** Notifications to list, newest first. */\n\tnotifications?: HeaderNotification[];\n\t/** Unread total shown on the trigger. */\n\tunreadCount?: number;\n\tonNotificationClick?: (notification: HeaderNotification) => void;\n\tonMarkAllRead?: () => void;\n\tonViewAll?: () => void;\n\t/** Destination for the view-all link. */\n\tviewAllHref?: string;\n\t/** Alignment of the shell's content. */\n\talign?: 'start' | 'center' | 'end';\n\t/** Which side of the trigger the surface opens on. */\n\tside?: 'top' | 'right' | 'bottom' | 'left';\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<HeaderNotificationsStrings>;\n\tclassName?: string;\n\t/** Merged onto the content region. */\n\tcontentClassName?: string;\n\t/** Replaces the default notification row. */\n\trenderNotification?: (notification: HeaderNotification) => ReactNode;\n}\n\nexport interface HeaderSearchStrings {\n\tplaceholder: string;\n\tshortcutMac: string;\n\tshortcutPc: string;\n}\n\nexport const defaultHeaderSearchStrings: HeaderSearchStrings = {\n\tplaceholder: 'Search...',\n\tshortcutMac: '⌘K',\n\tshortcutPc: 'Ctrl+K',\n};\n\nexport interface HeaderSearchProps {\n\tonOpen?: () => void;\n\t/** Modifier shown in the shortcut hint. Auto-detected when omitted. */\n\tshortcutModifier?: 'meta' | 'control';\n\t/** Binds the keyboard shortcut that opens search. */\n\tenableShortcut?: boolean;\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<HeaderSearchStrings>;\n\tclassName?: string;\n\t/** Merged onto the icon. */\n\ticonClassName?: string;\n\t/** Replaces the shortcut hint shown in the trigger. */\n\tshortcutSlot?: ReactNode;\n}\n\nexport interface HeaderGlobalSearchTriggerProps extends HeaderSearchProps {\n\t/** Whether the surface is showing. Controlled. */\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n}\n\nexport interface HeaderToolButtonProps {\n\t/** Display label. */\n\tlabel: string;\n\t/** Leading glyph. */\n\ticon: ComponentType<{ className?: string }>;\n\t/** Marks the control as currently engaged. */\n\tactive?: boolean;\n\t/** Disables the control. */\n\tdisabled?: boolean;\n\t/** Chip rendered beside the label. */\n\tbadge?: ReactNode;\n\tonClick?: () => void;\n\tclassName?: string;\n\t/** Merged onto the icon. */\n\ticonClassName?: string;\n}\n\nexport interface HeaderToolPopoverProps {\n\t/** Display label. */\n\tlabel: string;\n\t/** Leading glyph. */\n\ticon: ComponentType<{ className?: string }>;\n\t/** Whether the surface is showing. Controlled. */\n\topen?: boolean;\n\t/** Whether the surface starts open, for uncontrolled use. */\n\tdefaultOpen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\t/** Marks the control as currently engaged. */\n\tactive?: boolean;\n\t/** Disables the control. */\n\tdisabled?: boolean;\n\t/** Chip rendered beside the label. */\n\tbadge?: ReactNode;\n\t/** Alignment of the shell's content. */\n\talign?: 'start' | 'center' | 'end';\n\t/** Which side of the trigger the surface opens on. */\n\tside?: 'top' | 'right' | 'bottom' | 'left';\n\tsideOffset?: number;\n\tclassName?: string;\n\t/** Merged onto the trigger. */\n\ttriggerClassName?: string;\n\t/** Merged onto the content region. */\n\tcontentClassName?: string;\n\tchildren?: ReactNode;\n}\n\nexport interface HeaderUserMenuProps {\n\t/** The signed-in user shown in the menu. */\n\tuser: LayoutUser;\n\t/** Shows the signed-in email under the name. */\n\tshowEmail?: boolean;\n\t/** Extra content appended inside the menu. */\n\tcustomContent?: ReactNode;\n\tonProfile?: () => void;\n\tonSettings?: () => void;\n\tonLogout?: () => void;\n\t/** Alignment of the shell's content. */\n\talign?: 'start' | 'center' | 'end';\n\t/** Which side of the trigger the surface opens on. */\n\tside?: 'top' | 'right' | 'bottom' | 'left';\n\t/** Overrides this surface's own copy. */\n\tstrings?: StringsProp<HeaderUserMenuStrings>;\n\t/** Merged onto the trigger. */\n\ttriggerClassName?: string;\n\t/** Merged onto the content region. */\n\tcontentClassName?: string;\n\t/** Replaces the default trigger element. */\n\trenderTrigger?: (user: LayoutUser) => ReactNode;\n}\n\nexport interface HeaderUserMenuStrings {\n\tprofile: string;\n\tsettings: string;\n\tlogout: string;\n}\n\nexport const defaultHeaderUserMenuStrings: HeaderUserMenuStrings = {\n\tprofile: 'Profile',\n\tsettings: 'Settings',\n\tlogout: 'Log out',\n};\n\nexport interface HeaderSlots {\n\t/** Leading brand/logo region before breadcrumbs. */\n\tbrand?: ReactNode;\n\t/** Replaces the breadcrumb/sidebar-trigger region. */\n\tbreadcrumbs?: ReactNode;\n\t/** Leading content after breadcrumbs. */\n\tleft?: ReactNode;\n\t/** Center content, usually search or a scope switcher. */\n\tcenter?: ReactNode;\n\t/** Trailing content, usually notifications/user menu/actions. */\n\tright?: ReactNode;\n}\n\nexport interface HeaderProps extends LayoutNavigationAdapter, HTMLAttributes<HTMLElement> {\n\t/** Renders the breadcrumb trail. */\n\tshowBreadcrumbs?: boolean;\n\t/** Trail entries, root first. */\n\tbreadcrumbs?: BreadcrumbItem[];\n\t/** Root entry prepended to the trail. */\n\thomeBreadcrumb?: BreadcrumbItem | null;\n\t/** Renders the sidebar collapse control. */\n\tshowSidebarTrigger?: boolean;\n\t/** Replaces individual regions of the shell. */\n\tslots?: HeaderSlots;\n\tclassName?: string;\n\t/** Merged onto the content region. */\n\tcontentClassName?: string;\n\t/** Merged onto the leading region. */\n\tleftClassName?: string;\n\t/** Merged onto the centre region. */\n\tcenterClassName?: string;\n\trightClassName?: string;\n\tbreadcrumbsClassName?: string;\n}\n","/** HeaderSearch — framework-neutral search trigger with optional Cmd/Ctrl+K. */\nimport { useEffect, useState } from 'react';\nimport { Search } from 'lucide-react';\n\nimport { Button } from '../../../base/buttons';\nimport { Text } from '../../../typography';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport { useCommandShortcut } from '../../hooks';\nimport {\n\tdefaultHeaderSearchStrings,\n\ttype HeaderSearchProps,\n} from '../header.types';\n\nfunction detectMac(): boolean {\n\tif (typeof navigator === 'undefined') return false;\n\tconst ua = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData;\n\tif (ua?.platform) return ua.platform === 'macOS';\n\treturn /Mac|iPhone|iPad/.test(navigator.platform);\n}\n\nexport function HeaderSearch({\n\tonOpen,\n\tshortcutModifier,\n\tenableShortcut = true,\n\tstrings: stringsProp,\n\tclassName,\n\ticonClassName,\n\tshortcutSlot,\n}: HeaderSearchProps) {\n\tconst strings = useStrings(defaultHeaderSearchStrings, stringsProp);\n\tconst [detectedMac, setDetectedMac] = useState(false);\n\tuseEffect(() => {\n\t\tif (shortcutModifier === undefined) setDetectedMac(detectMac());\n\t}, [shortcutModifier]);\n\tconst resolvedModifier = shortcutModifier ?? (detectedMac ? 'meta' : 'control');\n\tconst isMetaShortcut = resolvedModifier === 'meta';\n\tuseCommandShortcut({ key: 'k', enabled: enableShortcut, onTrigger: onOpen });\n\n\tconst shortcutTitle = isMetaShortcut ? strings.shortcutMac : strings.shortcutPc;\n\tconst shortcut = shortcutSlot ?? (\n\t\t<kbd className=\"header-search--shortcut hidden h-5 shrink-0 items-center gap-space-sm rounded-inner border border-border/70 bg-background/60 px-space-sm font-mono text-xs text-muted-foreground lg:inline-flex\">\n\t\t\t<Text tag=\"span\" size=\"xs\" type=\"secondary\">\n\t\t\t\t{isMetaShortcut ? strings.shortcutMac : strings.shortcutPc}\n\t\t\t</Text>\n\t\t</kbd>\n\t);\n\n\treturn (\n\t\t<Button\n\t\t\tdata-component=\"header-search\"\n\t\t\tdata-slot=\"header-search-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-label={strings.placeholder}\n\t\t\ttone=\"secondary\"\n\t\t\tbuttonStyle=\"outline\"\n\t\t\tonClick={onOpen}\n\t\t\tclassName={cn(\n\t\t\t\t'header-search--component header-search--trigger h-action-sm w-full min-w-0 justify-start gap-space-md rounded-inner border-border/80 bg-muted/40 px-control-sm text-foreground shadow-none transition-[background-color,border-color,color,box-shadow] hover:border-border hover:bg-muted/60 hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background dark:border-border/80 dark:bg-muted dark:hover:bg-muted/60 dark:hover:text-foreground',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\ttitle={shortcutTitle}\n\t\t>\n\t\t\t<Search data-slot=\"header-search-icon\" className={cn('header-search--icon size-icon shrink-0 text-muted-foreground', iconClassName)} aria-hidden=\"true\" />\n\t\t\t<Text tag=\"span\" size=\"inherit\" type=\"secondary\" data-slot=\"header-search-placeholder\" className=\"header-search--placeholder min-w-0 flex-1 truncate text-left\">\n\t\t\t\t{strings.placeholder}\n\t\t\t</Text>\n\t\t\t{shortcut}\n\t\t</Button>\n\t);\n}\n","/** HeaderGlobalSearchTrigger — header search trigger with controlled open callback. */\nimport { HeaderSearch } from './header-search';\nimport type { HeaderGlobalSearchTriggerProps } from '../header.types';\n\nexport function HeaderGlobalSearchTrigger({\n\tonOpen,\n\tonOpenChange,\n\t...props\n}: HeaderGlobalSearchTriggerProps) {\n\treturn (\n\t\t<HeaderSearch\n\t\t\t{...props}\n\t\t\tonOpen={() => {\n\t\t\t\tonOpen?.();\n\t\t\t\tonOpenChange?.(true);\n\t\t\t}}\n\t\t/>\n\t);\n}\n","/** HeaderToolButton — icon control for dense app headers. */\nimport * as React from 'react';\n\nimport { Button } from '../../../base/buttons';\nimport { Text } from '../../../typography';\nimport { cn } from '../../../../lib/utils';\n\nimport type { HeaderToolButtonProps } from '../header.types';\n\nexport const HeaderToolButton = React.forwardRef<\n\tHTMLButtonElement,\n\tHeaderToolButtonProps\n>((\n\t{\n\t\tlabel,\n\t\ticon: Icon,\n\t\tactive = false,\n\t\tdisabled = false,\n\t\tbadge,\n\t\tonClick,\n\t\tclassName,\n\t\ticonClassName,\n\t},\n\tref,\n) => (\n\t<Button\n\t\tref={ref}\n\t\tdata-component=\"header-tool-button\"\n\t\tdata-slot=\"header-tool-button\"\n\t\ttype=\"button\"\n\t\ttone=\"secondary\"\n\t\tbuttonStyle=\"ghost\"\n\t\tsize=\"sm\" iconOnly\n\t\taria-label={label}\n\t\taria-pressed={active || undefined}\n\t\ttitle={label}\n\t\tdisabled={disabled}\n\t\tonClick={onClick}\n\t\tclassName={cn(\n\t\t\t'header-tool-button--component header-tool-button--trigger relative size-action-sm rounded-inner text-foreground transition-[background-color,color,box-shadow] hover:bg-accent hover:text-accent-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background',\n\t\t\tactive && 'bg-accent text-accent-foreground',\n\t\t\tclassName,\n\t\t)}\n\t>\n\t\t<Icon\n\t\t\tdata-slot=\"header-tool-icon\"\n\t\t\tclassName={cn('header-tool-button--icon size-icon', iconClassName)}\n\t\t\taria-hidden=\"true\"\n\t\t/>\n\t\t{!!badge && (\n\t\t\t<Text tag=\"span\" size=\"xs\" weight=\"medium\" lineHeight=\"none\" data-slot=\"header-tool-badge\" className=\"header-tool-button--badge absolute right-space-xs top-space-xs flex min-h-space-lg min-w-space-lg items-center justify-center rounded-full bg-destructive px-space-2xs text-destructive-foreground\">\n\t\t\t\t{badge}\n\t\t\t</Text>\n\t\t)}\n\t\t<Text tag=\"span\" size=\"inherit\" className=\"sr-only\">{label}</Text>\n\t</Button>\n));\n\nHeaderToolButton.displayName = 'HeaderToolButton';\n","/** HeaderToolPopover — controlled header icon trigger plus popover content. */\nimport {\n\tPopover,\n\tPopoverContent,\n\tPopoverTrigger,\n} from '../../../base/popover';\nimport { cn } from '../../../../lib/utils';\n\nimport type { HeaderToolPopoverProps } from '../header.types';\nimport { HeaderToolButton } from './header-tool-button';\n\nexport function HeaderToolPopover({\n\tlabel,\n\ticon,\n\topen,\n\tdefaultOpen,\n\tonOpenChange,\n\tactive,\n\tdisabled,\n\tbadge,\n\talign = 'end',\n\tside = 'bottom',\n\tsideOffset = 8,\n\tclassName,\n\ttriggerClassName,\n\tcontentClassName,\n\tchildren,\n}: HeaderToolPopoverProps) {\n\treturn (\n\t\t<Popover\n\t\t\topen={open}\n\t\t\tdefaultOpen={defaultOpen}\n\t\t\tonOpenChange={onOpenChange}\n\t\t>\n\t\t\t<PopoverTrigger asChild>\n\t\t\t\t<HeaderToolButton\n\t\t\t\t\tlabel={label}\n\t\t\t\t\ticon={icon}\n\t\t\t\t\tactive={active ?? open}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tbadge={badge}\n\t\t\t\t\tclassName={triggerClassName}\n\t\t\t\t/>\n\t\t\t</PopoverTrigger>\n\t\t\t<PopoverContent\n\t\t\t\tdata-component=\"header-tool-popover\"\n\t\t\t\tdata-slot=\"header-tool-popover-content\"\n\t\t\t\talign={align}\n\t\t\t\tside={side}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'header-tool-popover--component w-80 max-w-[calc(100vw-2rem)]',\n\t\t\t\t\tclassName,\n\t\t\t\t\tcontentClassName,\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</PopoverContent>\n\t\t</Popover>\n\t);\n}\n","/** HeaderUserMenu — avatar/name trigger with consumer-wired menu callbacks. */\nimport type { ReactElement } from 'react';\n\nimport { ChevronsUpDown, LogOut, Settings, User } from 'lucide-react';\n\nimport { ActionMenu, type ActionMenuAction } from '../../../base/action-menu';\nimport { Avatar, AvatarFallback, AvatarImage } from '../../../base/avatar';\nimport { Button } from '../../../base/buttons';\nimport { formatInitials } from '../../../primitives/initials-format';\nimport { Text } from '../../../typography';\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuTrigger,\n} from '../../../base/navigation/dropdown-menu';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport {\n\tdefaultHeaderUserMenuStrings,\n\ttype HeaderUserMenuProps,\n} from '../header.types';\n\nexport function HeaderUserMenu({\n\tuser,\n\tshowEmail = true,\n\tcustomContent,\n\tonProfile,\n\tonSettings,\n\tonLogout,\n\talign = 'end',\n\tside = 'bottom',\n\tstrings: stringsProp,\n\ttriggerClassName,\n\tcontentClassName,\n\trenderTrigger,\n}: HeaderUserMenuProps) {\n\tconst strings = useStrings(defaultHeaderUserMenuStrings, stringsProp);\n\tconst initials = formatInitials(user.name, { strategy: 'first-words' });\n\n\t// Profile and settings sit together; sign-out is held apart by a rule with\n\t// no caption, which is what `group: true` is for.\n\tconst actions: ActionMenuAction[] = [\n\t\t...(onProfile ? [{ id: 'profile', label: strings.profile, icon: User, onClick: onProfile }] : []),\n\t\t...(onSettings ? [{ id: 'settings', label: strings.settings, icon: Settings, onClick: onSettings }] : []),\n\t\t...(onLogout\n\t\t\t? [{\n\t\t\t\tid: 'logout',\n\t\t\t\tlabel: strings.logout,\n\t\t\t\ticon: LogOut,\n\t\t\t\tonClick: onLogout,\n\t\t\t\t...(onProfile || onSettings ? { group: true as const } : null),\n\t\t\t}]\n\t\t\t: []),\n\t];\n\n\tconst trigger = renderTrigger?.(user) ?? (\n\t\t<Button\n\t\t\tdata-component=\"header-user-menu\"\n\t\t\tdata-slot=\"header-user-menu-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-label={user.name}\n\t\t\ttone=\"secondary\"\n\t\t\tbuttonStyle=\"ghost\"\n\t\t\tsize=\"lg\"\n\t\t\tclassName={cn(\n\t\t\t\t'header-user-menu--component header-user-menu--trigger group min-w-0 max-w-56 justify-start gap-space-md text-foreground shadow-none hover:bg-accent hover:text-accent-foreground data-[state=open]:bg-accent max-sm:size-action-lg max-sm:justify-center max-sm:p-0 max-sm:[&_.header-user-menu--identity]:hidden max-sm:[&_.header-user-menu--chevron]:hidden',\n\t\t\t\ttriggerClassName,\n\t\t\t)}\n\t\t>\n\t\t\t<Avatar data-slot=\"header-user-avatar\" className=\"header-user-menu--avatar size-avatar-sm overflow-hidden rounded-full ring-1 ring-border\">\n\t\t\t\t{!!user.avatar && <AvatarImage src={user.avatar} alt={user.name} />}\n\t\t\t\t<AvatarFallback className=\"rounded-full bg-muted text-xs font-semibold text-muted-foreground\">\n\t\t\t\t\t{initials}\n\t\t\t\t</AvatarFallback>\n\t\t\t</Avatar>\n\t\t\t<div data-slot=\"header-user-identity\" className=\"header-user-menu--identity grid min-w-0 flex-1 gap-dense text-start leading-none\">\n\t\t\t\t<Text weight=\"medium\" lineHeight=\"tight\" className=\"truncate\">{user.name}</Text>\n\t\t\t\t{!!showEmail && !!user.email && (\n\t\t\t\t\t<Text size=\"xs\" type=\"secondary\" lineHeight=\"tight\" className=\"truncate\">{user.email}</Text>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<ChevronsUpDown className=\"header-user-menu--chevron size-icon-sm shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n\t\t</Button>\n\t);\n\n\tconst contentClasses = cn(\n\t\t'header-user-menu--content w-(--anchor-width) min-w-56 rounded-radius',\n\t\tcontentClassName,\n\t);\n\n\t// `customContent` replaces the menu body wholesale, which is a plain\n\t// dropdown rather than a list of commands — ActionMenu is deliberately not\n\t// that, so this path stays on the primitive it actually needs.\n\tif (customContent) {\n\t\treturn (\n\t\t\t<DropdownMenu>\n\t\t\t\t<DropdownMenuTrigger render={trigger as ReactElement} />\n\t\t\t\t<DropdownMenuContent\n\t\t\t\t\tdata-component=\"header-user-menu-content\"\n\t\t\t\t\tdata-slot=\"header-user-menu-content\"\n\t\t\t\t\tclassName={contentClasses}\n\t\t\t\t\talign={align}\n\t\t\t\t\tside={side}\n\t\t\t\t>\n\t\t\t\t\t{customContent}\n\t\t\t\t</DropdownMenuContent>\n\t\t\t</DropdownMenu>\n\t\t);\n\t}\n\n\treturn (\n\t\t<ActionMenu\n\t\t\tactions={actions}\n\t\t\talign={align}\n\t\t\tside={side}\n\t\t\tcontentClassName={contentClasses}\n\t\t\twidth=\"w-auto\"\n\t\t\tcloseOnSelect\n\t\t\trenderTrigger={trigger as ReactElement}\n\t\t/>\n\t);\n}\n","/** HeaderNotifications — bell dropdown for consumer-supplied notifications. */\nimport type { ReactElement } from 'react';\n\nimport { Bell } from 'lucide-react';\n\nimport { Badge } from '../../../base/badge';\nimport { Button } from '../../../base/buttons';\nimport { Stack } from '../../../base/structure';\nimport { DisplayLabel, Text } from '../../../typography';\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuGroup,\n\tDropdownMenuItem,\n\tDropdownMenuLabel,\n\tDropdownMenuLinkItem,\n\tDropdownMenuSeparator,\n\tDropdownMenuTrigger,\n} from '../../../base/navigation/dropdown-menu';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport { useLayoutLinkRenderer } from '../../hooks';\nimport {\n\tdefaultHeaderNotificationsStrings,\n\ttype HeaderNotification,\n\ttype HeaderNotificationsProps,\n\ttype NotificationTone,\n} from '../header.types';\n\nconst NOTIFICATION_TONE_CLASSNAMES: Record<NotificationTone, string> = {\n\tinfo: 'bg-info',\n\tsuccess: 'bg-success',\n\twarning: 'bg-warning',\n\tdestructive: 'bg-destructive',\n};\n\nexport function HeaderNotifications({\n\tnotifications = [],\n\tunreadCount = 0,\n\tonNotificationClick,\n\tonMarkAllRead,\n\tonViewAll,\n\tviewAllHref,\n\trenderLink,\n\talign = 'end',\n\tside = 'bottom',\n\tstrings: stringsProp,\n\tclassName,\n\tcontentClassName,\n\trenderNotification,\n}: HeaderNotificationsProps) {\n\tconst strings = useStrings(defaultHeaderNotificationsStrings, stringsProp);\n\tconst resolvedRenderLink = useLayoutLinkRenderer({ renderLink });\n\tconst badgeText = unreadCount > 99 ? '99+' : String(unreadCount);\n\n\treturn (\n\t\t<DropdownMenu>\n\t\t\t<DropdownMenuTrigger\n\t\t\t\trender={\n\t\t\t\t\t<Button\n\t\t\t\t\t\tdata-component=\"header-notifications\"\n\t\t\t\t\t\tdata-slot=\"header-notifications-trigger\"\n\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\tsize=\"sm\" iconOnly\n\t\t\t\t\t\taria-label={strings.triggerLabel}\n\t\t\t\t\t\tclassName={cn('header-notifications--component header-notifications--trigger relative', className)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Bell className=\"size-icon\" aria-hidden=\"true\" />\n\t\t\t\t\t\t{unreadCount > 0 && (\n\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\ttone=\"destructive\"\n\t\t\t\t\t\t\t\tclassName=\"absolute -right-1 -top-1 flex h-4.5 min-w-4.5 items-center justify-center px-space-xs py-0\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{badgeText}\n\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Button>\n\t\t\t\t}\n\t\t\t/>\n\t\t\t<DropdownMenuContent\n\t\t\t\tdata-component=\"header-notifications-content\"\n\t\t\t\tdata-slot=\"header-notifications-content\"\n\t\t\t\tclassName={cn('header-notifications--content w-80 max-w-[calc(100vw-2rem)]', contentClassName)}\n\t\t\t\talign={align}\n\t\t\t\tside={side}\n\t\t\t>\n\t\t\t\t<DropdownMenuGroup>\n\t\t\t\t\t<DropdownMenuLabel aria-hidden={false} className=\"header-notifications--label flex items-center justify-between gap-space-lg\">\n\t\t\t\t\t\t<DisplayLabel>{strings.heading}</DisplayLabel>\n\t\t\t\t\t\t{unreadCount > 0 && !!onMarkAllRead && (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\ttone=\"secondary\"\n\t\t\t\t\t\t\t\tbuttonStyle=\"ghost\"\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tonClick={onMarkAllRead}\n\t\t\t\t\t\t\t\tclassName=\"shrink-0\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{strings.markAllRead}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</DropdownMenuLabel>\n\t\t\t\t\t<DropdownMenuSeparator />\n\n\t\t\t\t\t{notifications.length === 0 ? (\n\t\t\t\t\t\t<div className=\"header-notifications--empty p-surface text-center\">\n\t\t\t\t\t\t\t<Text type=\"secondary\">{strings.empty}</Text>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Stack gap=\"xs\" className=\"header-notifications--list\">\n\t\t\t\t\t\t\t{notifications.map((notification) => (\n\t\t\t\t\t\t\t\t<NotificationRow\n\t\t\t\t\t\t\t\t\tkey={notification.id}\n\t\t\t\t\t\t\t\t\tnotification={notification}\n\t\t\t\t\t\t\t\t\tonClick={onNotificationClick}\n\t\t\t\t\t\t\t\t\trenderLink={resolvedRenderLink}\n\t\t\t\t\t\t\t\t\trenderNotification={renderNotification}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t)}\n\t\t\t\t</DropdownMenuGroup>\n\n\t\t\t\t{!!(onViewAll || viewAllHref) && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<DropdownMenuSeparator />\n\t\t\t\t\t\t{viewAllHref ? (\n\t\t\t\t\t\t\t<DropdownMenuLinkItem\n\t\t\t\t\t\t\t\thref={viewAllHref}\n\t\t\t\t\t\t\t\trender={(props) =>\n\t\t\t\t\t\t\t\t\tresolvedRenderLink({\n\t\t\t\t\t\t\t\t\t\t...props,\n\t\t\t\t\t\t\t\t\t\thref: viewAllHref,\n\t\t\t\t\t\t\t\t\t\tchildren: props.children,\n\t\t\t\t\t\t\t\t\t}) as ReactElement\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{strings.viewAll}\n\t\t\t\t\t\t\t</DropdownMenuLinkItem>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<DropdownMenuItem onClick={onViewAll}>{strings.viewAll}</DropdownMenuItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</DropdownMenuContent>\n\t\t</DropdownMenu>\n\t);\n}\n\nfunction NotificationRow({\n\tnotification,\n\tonClick,\n\trenderLink,\n\trenderNotification,\n}: {\n\tnotification: HeaderNotification;\n\tonClick?: (n: HeaderNotification) => void;\n\trenderLink: NonNullable<HeaderNotificationsProps['renderLink']>;\n\t/** Replaces the default notification row. */\n\trenderNotification?: HeaderNotificationsProps['renderNotification'];\n}) {\n\tif (renderNotification) return renderNotification(notification);\n\n\tconst content = (\n\t\t<Stack direction=\"horizontal\" align=\"start\" wrap={false} gap=\"sm\" className=\"header-notifications--item-content\">\n\t\t\t{!!notification.tone && (\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tdata-tone={notification.tone}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'header-notifications--tone mt-space-sm size-2 shrink-0 rounded-full',\n\t\t\t\t\t\tNOTIFICATION_TONE_CLASSNAMES[notification.tone],\n\t\t\t\t\t)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<Stack gap=\"dense\" className=\"min-w-0\">\n\t\t\t\t<Text weight=\"medium\">{notification.title}</Text>\n\t\t\t\t{!!notification.description && <Text size=\"xs\" type=\"secondary\">{notification.description}</Text>}\n\t\t\t\t{!!notification.time && <Text size=\"xs\" type=\"secondary\">{notification.time}</Text>}\n\t\t\t</Stack>\n\t\t</Stack>\n\t);\n\n\tconst className = cn(\n\t\t'header-notifications--item items-start',\n\t\t!notification.read && 'bg-muted text-muted-foreground',\n\t);\n\n\tif (notification.href) {\n\t\treturn (\n\t\t\t<DropdownMenuLinkItem\n\t\t\t\thref={notification.href}\n\t\t\t\tclassName={className}\n\t\t\t\tonClick={() => onClick?.(notification)}\n\t\t\t\trender={(props) =>\n\t\t\t\t\trenderLink({\n\t\t\t\t\t\t...props,\n\t\t\t\t\t\thref: notification.href,\n\t\t\t\t\t\tchildren: props.children,\n\t\t\t\t\t}) as ReactElement\n\t\t\t\t}\n\t\t\t>\n\t\t\t\t{content}\n\t\t\t</DropdownMenuLinkItem>\n\t\t);\n\t}\n\n\treturn (\n\t\t<DropdownMenuItem onClick={() => onClick?.(notification)} className={className}>\n\t\t\t{content}\n\t\t</DropdownMenuItem>\n\t);\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { p as e } from "./sidebar-CNBKFDRW.js";
2
+ import { p as e } from "./sidebar-CyR4XKwR.js";
3
3
  import { n as t } from "./layout.types-Cn7aUzJp.js";
4
4
  import { useCallback as n, useEffect as r, useMemo as i } from "react";
5
5
  import { jsx as a } from "react/jsx-runtime";
@@ -85,4 +85,4 @@ function g({ key: e, enabled: t = !0, onTrigger: n, preventDefault: i = !0 }) {
85
85
  //#endregion
86
86
  export { u as a, m as c, o as d, d as i, f as l, h as n, l as o, p as r, c as s, g as t, s as u };
87
87
 
88
- //# sourceMappingURL=hooks-D6UBVzf2.js.map
88
+ //# sourceMappingURL=hooks-BrlnCwQd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-D6UBVzf2.js","names":["IconComponent","SidebarMenuBadge","resolveLayoutLinkRenderer","useLayoutLinkRenderer","useMemo","renderLink","toPath","href","isPathMatch","currentPath","currentUrl","path","getNavLabel","item","getNavKey","label","fallbackIndex","NavBadge","value","resolveNavBadge","handle","liveBadges","itemBadge","DynamicIcon","props","icon","IconComponent","iconMap","size","renderSidebarLink","useActivePath","useCallback","useCommandShortcut","enabled","onTrigger","handler","event","key","preventDefault"],"sources":["../src/components/layout/hooks/use-layout-link.tsx","../src/components/layout/sidebar/sidebar.utils.tsx","../src/components/layout/hooks/use-active-path.ts","../src/components/layout/hooks/use-command-shortcut.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport {\n\tresolveLayoutLinkRenderer,\n\ttype LayoutLinkRenderer,\n\ttype LayoutNavigationAdapter,\n} from '../layout.types';\n\nexport function useLayoutLinkRenderer({\n\trenderLink,\n}: LayoutNavigationAdapter = {}): LayoutLinkRenderer {\n\treturn useMemo(\n\t\t() => resolveLayoutLinkRenderer({ renderLink }),\n\t\t[renderLink],\n\t);\n}\n"," \n/** Sidebar utilities — pure path helpers, labels, icon rendering, badge pill. */\nimport * as React from 'react';\n\nimport { SidebarMenuBadge } from '../../base/sidebar';\n\nimport type { LayoutIconSource, LayoutLinkRenderer } from '../layout.types';\nimport type { SidebarNavItem } from './sidebar.types';\nimport type { ComponentScale } from '../../../lib/component-vocabulary';\n\nexport function toPath(href: string): string {\n\tif (href.startsWith('#/')) {\n\t\treturn href.slice(1).split('?')[0]?.split('#')[0] || '/';\n\t}\n\n\ttry {\n\t\treturn new URL(href, 'http://local.invalid').pathname;\n\t} catch {\n\t\treturn href;\n\t}\n}\n\nexport function isPathMatch(currentUrl: string, path: string): boolean {\n\tconst currentPath = toPath(currentUrl);\n\treturn currentPath === path || currentPath.startsWith(path + '/') || currentPath.startsWith(path + '?');\n}\n\nexport function getNavLabel(item: Pick<SidebarNavItem, 'label'>): React.ReactNode {\n\treturn item.label;\n}\n\nexport function getNavKey(item: SidebarNavItem, fallbackIndex?: number): React.Key {\n\tconst label = getNavLabel(item);\n\treturn item.handle ?? item.href ?? (typeof label === 'string' || typeof label === 'number' ? label : `nav-${fallbackIndex ?? 0}`);\n}\n\nexport function NavBadge({\n\tvalue,\n\tsize = 'md',\n}: {\n\t/** Current value. Controlled. */\n\tvalue: string | number;\n\t/** Size preset. */\n\tsize?: ComponentScale;\n}) {\n\treturn (\n\t\t<SidebarMenuBadge inline size={size}>\n\t\t\t{value}\n\t\t</SidebarMenuBadge>\n\t);\n}\n\nexport function resolveNavBadge(\n\thandle: string | undefined,\n\titemBadge: string | number | undefined,\n\tliveBadges: Record<string, string | number> | undefined,\n): string | number | undefined {\n\tif (handle && liveBadges && liveBadges[handle] != null) {\n\t\treturn liveBadges[handle];\n\t}\n\treturn itemBadge;\n}\n\nexport interface DynamicIconProps extends React.SVGProps<SVGSVGElement> {\n\t/** Leading glyph. */\n\ticon: LayoutIconSource;\n\t/** Resolves an item's icon name to a component, keeping navigation data serialisable. */\n\ticonMap?: Record<string, React.ComponentType<{ className?: string }>>;\n\t/** Size preset. */\n\tsize?: number;\n\tclassName?: string;\n}\n\nexport function DynamicIcon({\n\ticon,\n\ticonMap = {},\n\tsize = 20,\n\tclassName = 'size-icon',\n\t...props\n}: DynamicIconProps) {\n\tif (!icon) return null;\n\n\tif (typeof icon === 'string') {\n\t\tconst IconComponent = iconMap[icon];\n\t\treturn IconComponent ? <IconComponent className={className} /> : null;\n\t}\n\n\tif (\n\t\ttypeof icon === 'function'\n\t\t|| (typeof icon === 'object' && icon !== null && '$$typeof' in icon)\n\t) {\n\t\tconst IconComponent = icon as React.ElementType<React.SVGProps<SVGSVGElement>>;\n\t\treturn <IconComponent className={className} width={size} height={size} {...props} />;\n\t}\n\n\treturn null;\n}\n\nexport function renderSidebarLink(\n\trenderLink: LayoutLinkRenderer,\n\titem: SidebarNavItem,\n\tchildren: React.ReactNode,\n\tclassName?: string,\n\tactive?: boolean,\n) {\n\treturn renderLink({\n\t\thref: item.href,\n\t\tchildren,\n\t\tclassName,\n\t\tactive,\n\t\tdisabled: item.disabled || !item.href,\n\t\texternal: item.external,\n\t});\n}\n","import { useCallback } from 'react';\n\nimport { isPathMatch, toPath } from '../sidebar/sidebar.utils';\n\nexport function useActivePath(currentUrl = '/') {\n\treturn useCallback(\n\t\t(href?: string) => !!href && isPathMatch(currentUrl, toPath(href)),\n\t\t[currentUrl],\n\t);\n}\n","import { useEffect } from 'react';\n\nexport interface UseCommandShortcutOptions {\n\tkey: string;\n\tenabled?: boolean;\n\tonTrigger?: () => void;\n\tpreventDefault?: boolean;\n}\n\nexport function useCommandShortcut({\n\tkey,\n\tenabled = true,\n\tonTrigger,\n\tpreventDefault = true,\n}: UseCommandShortcutOptions) {\n\tuseEffect(() => {\n\t\tif (!enabled || !onTrigger || typeof document === 'undefined') return;\n\n\t\tconst handler = (event: KeyboardEvent) => {\n\t\t\tif (!(event.metaKey || event.ctrlKey)) return;\n\t\t\tif (event.key.toLowerCase() !== key.toLowerCase()) return;\n\t\t\tif (preventDefault) event.preventDefault();\n\t\t\tonTrigger();\n\t\t};\n\n\t\tdocument.addEventListener('keydown', handler);\n\t\treturn () => document.removeEventListener('keydown', handler);\n\t}, [enabled, key, onTrigger, preventDefault]);\n}\n"],"mappings":";;;;;;AAQA,SAAgBG,EAAsB,EACrC,kBAC4B,CAAC,GAAuB;CACpD,OAAOC,QACAF,EAA0B,EAAE,cAAW,CAAC,GAC9C,CAACG,CAAU,CACZ;AACD;;;ACLA,SAAgBC,EAAO,GAAsB;CAC5C,IAAIC,EAAK,WAAW,IAAI,GACvB,OAAOA,EAAK,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM;CAGtD,IAAI;EACH,OAAO,IAAI,IAAIA,GAAM,sBAAsB,CAAC,CAAC;CAC9C,QAAQ;EACP,OAAOA;CACR;AACD;AAEA,SAAgBC,EAAY,GAAoB,GAAuB;CACtE,IAAMC,IAAcH,EAAOI,CAAU;CACrC,OAAOD,MAAgBE,KAAQF,EAAY,WAAWE,IAAO,GAAG,KAAKF,EAAY,WAAWE,IAAO,GAAG;AACvG;AAEA,SAAgBC,EAAY,GAAsD;CACjF,OAAOC,EAAK;AACb;AAEA,SAAgBC,EAAU,GAAsB,GAAmC;CAClF,IAAMC,IAAQH,EAAYC,CAAI;CAC9B,OAAOA,EAAK,UAAUA,EAAK,SAAS,OAAOE,KAAU,YAAY,OAAOA,KAAU,WAAWA,IAAQ,OAAOC,KAAiB;AAC9H;AAEA,SAAgBC,EAAS,EACxB,UACA,UAAO,QAML;CACF,OACC,kBAAChB,GAAD;EAAkB,QAAA;EAAa;EAC7B,UAAAiB;CACgB,CAAA;AAEpB;AAEA,SAAgBC,EACf,GACA,GACA,GAC8B;CAI9B,OAHIC,KAAUC,KAAcA,EAAWD,MAAW,OAC1CC,EAAWD,KAEZE;AACR;AAYA,SAAgBC,EAAY,EAC3B,SACA,aAAU,CAAC,GACX,UAAO,IACP,eAAY,aACZ,GAAGC,KACiB;CACpB,IAAI,CAACC,GAAM,OAAO;CAElB,IAAI,OAAOA,KAAS,UAAU;EAC7B,IAAMC,IAAgBC,EAAQF;EAC9B,OAAOC,IAAgB,kBAACA,GAAD,EAA0B,aAAY,CAAA,IAAI;CAClE;CAUA,OAPC,OAAOD,KAAS,cACZ,OAAOA,KAAS,YAAYA,KAAiB,cAAcA,IAGxD,kBAACzB,GAAD;EAA0B;EAAW,OAAO4B;EAAM,QAAQA;EAAM,GAAIJ;CAAQ,CAAA,IAG7E;AACR;AAEA,SAAgBK,EACf,GACA,GACA,GACA,GACA,GACC;CACD,OAAOxB,EAAW;EACjB,MAAMQ,EAAK;EACX;EACA;EACA;EACA,UAAUA,EAAK,YAAY,CAACA,EAAK;EACjC,UAAUA,EAAK;CAChB,CAAC;AACF;;;AC7GA,SAAgBiB,EAAc,IAAa,KAAK;CAC/C,OAAOC,GACL,MAAkB,CAAC,CAACxB,KAAQC,EAAYE,GAAYJ,EAAOC,CAAI,CAAC,GACjE,CAACG,CAAU,CACZ;AACD;;;ACAA,SAAgBsB,EAAmB,EAClC,QACA,aAAU,IACV,cACA,oBAAiB,MACY;CAC7B,QAAgB;EACf,IAAI,CAACC,KAAW,CAACC,KAAa,OAAO,WAAa,KAAa;EAE/D,IAAMC,KAAW,MAAyB;GACzC,CAAMC,EAAM,WAAWA,EAAM,YACzBA,EAAM,IAAI,YAAY,MAAMC,EAAI,YAAY,MAC5CC,KAAgBF,EAAM,eAAe,GACzCF,EAAU;EACX;EAGA,OADA,SAAS,iBAAiB,WAAWC,CAAO,SAC/B,SAAS,oBAAoB,WAAWA,CAAO;CAC7D,GAAG;EAACF;EAASI;EAAKH;EAAWI;CAAc,CAAC;AAC7C"}
1
+ {"version":3,"file":"hooks-BrlnCwQd.js","names":["IconComponent","SidebarMenuBadge","resolveLayoutLinkRenderer","useLayoutLinkRenderer","useMemo","renderLink","toPath","href","isPathMatch","currentPath","currentUrl","path","getNavLabel","item","getNavKey","label","fallbackIndex","NavBadge","value","resolveNavBadge","handle","liveBadges","itemBadge","DynamicIcon","props","icon","IconComponent","iconMap","size","renderSidebarLink","useActivePath","useCallback","useCommandShortcut","enabled","onTrigger","handler","event","key","preventDefault"],"sources":["../src/components/layout/hooks/use-layout-link.tsx","../src/components/layout/sidebar/sidebar.utils.tsx","../src/components/layout/hooks/use-active-path.ts","../src/components/layout/hooks/use-command-shortcut.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport {\n\tresolveLayoutLinkRenderer,\n\ttype LayoutLinkRenderer,\n\ttype LayoutNavigationAdapter,\n} from '../layout.types';\n\nexport function useLayoutLinkRenderer({\n\trenderLink,\n}: LayoutNavigationAdapter = {}): LayoutLinkRenderer {\n\treturn useMemo(\n\t\t() => resolveLayoutLinkRenderer({ renderLink }),\n\t\t[renderLink],\n\t);\n}\n"," \n/** Sidebar utilities — pure path helpers, labels, icon rendering, badge pill. */\nimport * as React from 'react';\n\nimport { SidebarMenuBadge } from '../../base/sidebar';\n\nimport type { LayoutIconSource, LayoutLinkRenderer } from '../layout.types';\nimport type { SidebarNavItem } from './sidebar.types';\nimport type { ComponentScale } from '../../../lib/component-vocabulary';\n\nexport function toPath(href: string): string {\n\tif (href.startsWith('#/')) {\n\t\treturn href.slice(1).split('?')[0]?.split('#')[0] || '/';\n\t}\n\n\ttry {\n\t\treturn new URL(href, 'http://local.invalid').pathname;\n\t} catch {\n\t\treturn href;\n\t}\n}\n\nexport function isPathMatch(currentUrl: string, path: string): boolean {\n\tconst currentPath = toPath(currentUrl);\n\treturn currentPath === path || currentPath.startsWith(path + '/') || currentPath.startsWith(path + '?');\n}\n\nexport function getNavLabel(item: Pick<SidebarNavItem, 'label'>): React.ReactNode {\n\treturn item.label;\n}\n\nexport function getNavKey(item: SidebarNavItem, fallbackIndex?: number): React.Key {\n\tconst label = getNavLabel(item);\n\treturn item.handle ?? item.href ?? (typeof label === 'string' || typeof label === 'number' ? label : `nav-${fallbackIndex ?? 0}`);\n}\n\nexport function NavBadge({\n\tvalue,\n\tsize = 'md',\n}: {\n\t/** Current value. Controlled. */\n\tvalue: string | number;\n\t/** Size preset. */\n\tsize?: ComponentScale;\n}) {\n\treturn (\n\t\t<SidebarMenuBadge inline size={size}>\n\t\t\t{value}\n\t\t</SidebarMenuBadge>\n\t);\n}\n\nexport function resolveNavBadge(\n\thandle: string | undefined,\n\titemBadge: string | number | undefined,\n\tliveBadges: Record<string, string | number> | undefined,\n): string | number | undefined {\n\tif (handle && liveBadges && liveBadges[handle] != null) {\n\t\treturn liveBadges[handle];\n\t}\n\treturn itemBadge;\n}\n\nexport interface DynamicIconProps extends React.SVGProps<SVGSVGElement> {\n\t/** Leading glyph. */\n\ticon: LayoutIconSource;\n\t/** Resolves an item's icon name to a component, keeping navigation data serialisable. */\n\ticonMap?: Record<string, React.ComponentType<{ className?: string }>>;\n\t/** Size preset. */\n\tsize?: number;\n\tclassName?: string;\n}\n\nexport function DynamicIcon({\n\ticon,\n\ticonMap = {},\n\tsize = 20,\n\tclassName = 'size-icon',\n\t...props\n}: DynamicIconProps) {\n\tif (!icon) return null;\n\n\tif (typeof icon === 'string') {\n\t\tconst IconComponent = iconMap[icon];\n\t\treturn IconComponent ? <IconComponent className={className} /> : null;\n\t}\n\n\tif (\n\t\ttypeof icon === 'function'\n\t\t|| (typeof icon === 'object' && icon !== null && '$$typeof' in icon)\n\t) {\n\t\tconst IconComponent = icon as React.ElementType<React.SVGProps<SVGSVGElement>>;\n\t\treturn <IconComponent className={className} width={size} height={size} {...props} />;\n\t}\n\n\treturn null;\n}\n\nexport function renderSidebarLink(\n\trenderLink: LayoutLinkRenderer,\n\titem: SidebarNavItem,\n\tchildren: React.ReactNode,\n\tclassName?: string,\n\tactive?: boolean,\n) {\n\treturn renderLink({\n\t\thref: item.href,\n\t\tchildren,\n\t\tclassName,\n\t\tactive,\n\t\tdisabled: item.disabled || !item.href,\n\t\texternal: item.external,\n\t});\n}\n","import { useCallback } from 'react';\n\nimport { isPathMatch, toPath } from '../sidebar/sidebar.utils';\n\nexport function useActivePath(currentUrl = '/') {\n\treturn useCallback(\n\t\t(href?: string) => !!href && isPathMatch(currentUrl, toPath(href)),\n\t\t[currentUrl],\n\t);\n}\n","import { useEffect } from 'react';\n\nexport interface UseCommandShortcutOptions {\n\tkey: string;\n\tenabled?: boolean;\n\tonTrigger?: () => void;\n\tpreventDefault?: boolean;\n}\n\nexport function useCommandShortcut({\n\tkey,\n\tenabled = true,\n\tonTrigger,\n\tpreventDefault = true,\n}: UseCommandShortcutOptions) {\n\tuseEffect(() => {\n\t\tif (!enabled || !onTrigger || typeof document === 'undefined') return;\n\n\t\tconst handler = (event: KeyboardEvent) => {\n\t\t\tif (!(event.metaKey || event.ctrlKey)) return;\n\t\t\tif (event.key.toLowerCase() !== key.toLowerCase()) return;\n\t\t\tif (preventDefault) event.preventDefault();\n\t\t\tonTrigger();\n\t\t};\n\n\t\tdocument.addEventListener('keydown', handler);\n\t\treturn () => document.removeEventListener('keydown', handler);\n\t}, [enabled, key, onTrigger, preventDefault]);\n}\n"],"mappings":";;;;;;AAQA,SAAgBG,EAAsB,EACrC,kBAC4B,CAAC,GAAuB;CACpD,OAAOC,QACAF,EAA0B,EAAE,cAAW,CAAC,GAC9C,CAACG,CAAU,CACZ;AACD;;;ACLA,SAAgBC,EAAO,GAAsB;CAC5C,IAAIC,EAAK,WAAW,IAAI,GACvB,OAAOA,EAAK,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM;CAGtD,IAAI;EACH,OAAO,IAAI,IAAIA,GAAM,sBAAsB,CAAC,CAAC;CAC9C,QAAQ;EACP,OAAOA;CACR;AACD;AAEA,SAAgBC,EAAY,GAAoB,GAAuB;CACtE,IAAMC,IAAcH,EAAOI,CAAU;CACrC,OAAOD,MAAgBE,KAAQF,EAAY,WAAWE,IAAO,GAAG,KAAKF,EAAY,WAAWE,IAAO,GAAG;AACvG;AAEA,SAAgBC,EAAY,GAAsD;CACjF,OAAOC,EAAK;AACb;AAEA,SAAgBC,EAAU,GAAsB,GAAmC;CAClF,IAAMC,IAAQH,EAAYC,CAAI;CAC9B,OAAOA,EAAK,UAAUA,EAAK,SAAS,OAAOE,KAAU,YAAY,OAAOA,KAAU,WAAWA,IAAQ,OAAOC,KAAiB;AAC9H;AAEA,SAAgBC,EAAS,EACxB,UACA,UAAO,QAML;CACF,OACC,kBAAChB,GAAD;EAAkB,QAAA;EAAa;EAC7B,UAAAiB;CACgB,CAAA;AAEpB;AAEA,SAAgBC,EACf,GACA,GACA,GAC8B;CAI9B,OAHIC,KAAUC,KAAcA,EAAWD,MAAW,OAC1CC,EAAWD,KAEZE;AACR;AAYA,SAAgBC,EAAY,EAC3B,SACA,aAAU,CAAC,GACX,UAAO,IACP,eAAY,aACZ,GAAGC,KACiB;CACpB,IAAI,CAACC,GAAM,OAAO;CAElB,IAAI,OAAOA,KAAS,UAAU;EAC7B,IAAMC,IAAgBC,EAAQF;EAC9B,OAAOC,IAAgB,kBAACA,GAAD,EAA0B,aAAY,CAAA,IAAI;CAClE;CAUA,OAPC,OAAOD,KAAS,cACZ,OAAOA,KAAS,YAAYA,KAAiB,cAAcA,IAGxD,kBAACzB,GAAD;EAA0B;EAAW,OAAO4B;EAAM,QAAQA;EAAM,GAAIJ;CAAQ,CAAA,IAG7E;AACR;AAEA,SAAgBK,EACf,GACA,GACA,GACA,GACA,GACC;CACD,OAAOxB,EAAW;EACjB,MAAMQ,EAAK;EACX;EACA;EACA;EACA,UAAUA,EAAK,YAAY,CAACA,EAAK;EACjC,UAAUA,EAAK;CAChB,CAAC;AACF;;;AC7GA,SAAgBiB,EAAc,IAAa,KAAK;CAC/C,OAAOC,GACL,MAAkB,CAAC,CAACxB,KAAQC,EAAYE,GAAYJ,EAAOC,CAAI,CAAC,GACjE,CAACG,CAAU,CACZ;AACD;;;ACAA,SAAgBsB,EAAmB,EAClC,QACA,aAAU,IACV,cACA,oBAAiB,MACY;CAC7B,QAAgB;EACf,IAAI,CAACC,KAAW,CAACC,KAAa,OAAO,WAAa,KAAa;EAE/D,IAAMC,KAAW,MAAyB;GACzC,CAAMC,EAAM,WAAWA,EAAM,YACzBA,EAAM,IAAI,YAAY,MAAMC,EAAI,YAAY,MAC5CC,KAAgBF,EAAM,eAAe,GACzCF,EAAU;EACX;EAGA,OADA,SAAS,iBAAiB,WAAWC,CAAO,SAC/B,SAAS,oBAAoB,WAAWA,CAAO;CAC7D,GAAG;EAACF;EAASI;EAAKH;EAAWI;CAAc,CAAC;AAC7C"}
@@ -59,7 +59,7 @@ function o(e) {
59
59
  let t = e.properties.style;
60
60
  typeof t == "string" && (e.properties.style = t.split(";").flatMap((e) => {
61
61
  let t = e.indexOf(":"), n = e.slice(0, t).trim().toLowerCase(), r = e.slice(t + 1).trim();
62
- return t > 0 && a.has(n) && r && /^[\w\s#%.,()'"+\/-]+$/.test(r) && !/url\s*\(|expression|@|javascript|var\s*\(/i.test(r) ? [`${n}:${r}`] : [];
62
+ return t > 0 && a.has(n) && r && /^[\w\s#%.,()'"+/-]+$/.test(r) && !/url\s*\(|expression|@|javascript|var\s*\(/i.test(r) ? [`${n}:${r}`] : [];
63
63
  }).join(";"), e.properties.style || delete e.properties.style);
64
64
  }
65
65
  (e.type === "root" || e.type === "element") && e.children.forEach(o);
@@ -328,4 +328,4 @@ function w(e, t = {}) {
328
328
  //#endregion
329
329
  export { y as a, h as c, S as i, f as l, b as n, v as o, C as r, x as s, w as t, d as u };
330
330
 
331
- //# sourceMappingURL=http-CLTVJc5I.js.map
331
+ //# sourceMappingURL=http-CdEIHyQf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-CdEIHyQf.js","names":["defaultRichTextEditorStrings","schema","styleProperties","cleanProperties","node","key","value","style","split","declaration","name","parseEmailHtml","fromHtml","html","sanitizeEmailTree","cleaned","sanitize","tree","sanitizeEmailHtml","toHtml","emailHtmlText","defaultEmailComposerStrings","field","index","email","label","keys","id","emptyDocument","escapeEmailHtml","char","documentHtml","content","child","strings","text","mark","tags","level","bodyHtml","bodyMarkup","body","tokens","resolveValues","values","definitions","override","draft","context","template","renderEmail","unresolved","get","subject","visit","clean","inspectDraft","issues","rendered","renderError","r","result","issue","error","validate","recipientLabel","recipient","parseRecipient","match","createHttpSender","response","endpoint","options","message"],"sources":["../src/components/features/email-composer/email-html.ts","../src/components/features/email-composer/strings.ts","../src/components/features/email-composer/document.ts","../src/components/features/email-composer/engine.ts","../src/components/features/email-composer/http.ts"],"sourcesContent":["import { fromHtml } from 'hast-util-from-html';\nimport { sanitize, type Schema } from 'hast-util-sanitize';\nimport { toHtml } from 'hast-util-to-html';\nimport type { Root, RootContent } from 'hast';\nconst tags = ['a', 'b', 'blockquote', 'br', 'code', 'del', 'div', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'mark', 'ol', 'p', 'pre', 's', 'span', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'th', 'thead', 'tfoot', 'tr', 'u', 'ul'];\nconst schema: Schema = {\n\ttagNames: tags, attributes: { '*': ['style', 'align', 'width', 'height'], a: ['href', 'title'], img: ['src', 'alt', 'title'], span: ['dataPlaceholder'], ol: ['start'], td: ['colSpan', 'rowSpan'], th: ['colSpan', 'rowSpan'], table: ['cellPadding', 'cellSpacing', 'border'] },\n\tprotocols: { href: ['https', 'http', 'mailto'], src: ['https'] },\n\tstrip: ['script', 'style', 'iframe', 'object', 'embed', 'svg', 'math', 'template', 'form', 'input', 'button'],\n};\n// Email content has its own small allowlist; admin UI theme styles never enter it.\nconst styleProperties = new Set(['color', 'background', 'background-color', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-color', 'border-width', 'border-style', 'border-collapse', 'border-spacing', 'border-radius', 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'width', 'max-width', 'min-width', 'height', 'font-family', 'font-size', 'font-weight', 'font-style', 'line-height', 'text-align', 'text-decoration', 'vertical-align', 'white-space']);\nfunction cleanProperties(node: Root | RootContent): void {\n\tif (node.type === 'element') {\n\t\tfor (const key of ['href', 'src']) {\n\t\t\tconst value = node.properties[key];\n\t\t\tif (typeof value === 'string' && (value.trimStart().startsWith('//') || (key === 'src' && !/^https:\\/\\//i.test(value))))\n\t\t\t\tdelete node.properties[key];\n\t\t}\n\t\tconst style = node.properties.style;\n\t\tif (typeof style === 'string') {\n\t\t\tnode.properties.style = style.split(';').flatMap(declaration => {\n\t\t\t\tconst split = declaration.indexOf(':');\n\t\t\t\tconst name = declaration.slice(0, split).trim().toLowerCase();\n\t\t\t\tconst value = declaration.slice(split + 1).trim();\n\t\t\t\treturn split > 0 && styleProperties.has(name) && value && /^[\\w\\s#%.,()'\"+/-]+$/.test(value) && !/url\\s*\\(|expression|@|javascript|var\\s*\\(/i.test(value) ? [`${name}:${value}`] : [];\n\t\t\t}).join(';');\n\t\t\tif (!node.properties.style)\n\t\t\t\tdelete node.properties.style;\n\t\t}\n\t}\n\tif (node.type === 'root' || node.type === 'element')\n\t\tnode.children.forEach(cleanProperties);\n}\nexport function parseEmailHtml(html: string): Root { return fromHtml(html, { fragment: true }); }\nexport function sanitizeEmailTree(tree: Root): Root {\n\tconst cleaned = sanitize(tree, schema);\n\tif (cleaned.type !== 'root')\n\t\tthrow new Error('Expected an HTML document fragment.');\n\tcleanProperties(cleaned);\n\treturn cleaned;\n}\nexport function sanitizeEmailHtml(html: string): string { return toHtml(sanitizeEmailTree(parseEmailHtml(html))); }\nexport function emailHtmlText(tree: Root | RootContent): string {\n\tif (tree.type === 'text')\n\t\treturn tree.value;\n\tif (tree.type !== 'root' && tree.type !== 'element')\n\t\treturn '';\n\tif (tree.type === 'element' && tree.tagName === 'br')\n\t\treturn '\\n';\n\tconst text = tree.children.map(emailHtmlText).join('');\n\treturn text + (tree.type === 'element' && /^(p|div|li|h[1-6]|tr|blockquote|pre)$/.test(tree.tagName) ? '\\n' : '');\n}\n","import { defaultRichTextEditorStrings } from '../rich-text-editor/rich-text-editor.strings';\nexport const defaultEmailComposerStrings = {\n\ttoolbar: defaultRichTextEditorStrings.toolbar,\n\ttitle: 'New message', to: 'To', cc: 'Cc', bcc: 'Bcc', subject: 'Subject', body: 'Message body',\n\trecipientPlaceholder: 'Name <email@example.com>', addRecipient: (field: string) => `Add ${field} recipient`,\n\trecipientLabel: (field: string, index: number) => `${field} recipient ${index + 1}`,\n\tremoveRecipient: (email: string) => `Remove ${email}`, newRecipient: (field: string) => `New ${field} recipient`,\n\ttemplates: 'Templates', searchTemplates: 'Search templates…', noTemplates: 'No templates found.', importTemplate: 'Import template',\n\ttemplatesUnavailable: 'Templates are unavailable. Wait for loading to finish or retry.', loadingTemplates: 'Loading templates…', loadingVariables: 'Loading variables…', loadingRecipients: (field: string) => `Loading ${field} recipients…`, retry: 'Retry', dataUnavailable: 'Wait for required recipient and variable data to finish loading, or retry the failed request.',\n\tvariables: 'Variables', variablesDescription: 'Insert a variable into the message, or override its live value for this draft.', insertVariable: (label: string) => `Insert ${label}`, reset: 'Reset', dynamic: 'Dynamic value', overridden: 'Manual override',\n\tchoose: 'Choose…', editor: 'Editor', preview: 'Preview', previewLabel: 'Email body preview',\n\tsend: 'Send email', discard: 'Discard', working: 'Working…', sent: 'Email sent successfully.', discarded: 'Draft discarded.', close: 'Close composer', more: 'More actions',\n\tlink: 'Add or edit link', linkTitle: 'Message link', linkUrl: 'Link URL', closeLink: 'Close link editor', closeConversion: 'Close conversion confirmation', apply: 'Apply', cancel: 'Cancel',\n\tinvalidLink: 'Use an https://, http://, or mailto: URL.', convert: 'Convert to editable rich text',\n\tconvertTitle: 'Convert HTML layout?', convertDescription: 'Unsupported layout elements and styling may be lost when converting to rich text.',\n\tmissingRecipient: 'Add at least one recipient.', invalidRecipients: (field: string) => `Check ${field} addresses.`,\n\tinvalidSubject: 'Enter a single-line subject.', invalidResolvedSubject: 'Resolved subject must be a nonempty single line.', emptyBody: 'Enter a message.',\n\tmissingVariables: (keys: readonly string[]) => `Set values for: ${keys.join(', ')}.`,\n\tattributeVariables: 'Placeholders in HTML attributes are unsupported. Put placeholders in visible text.',\n\tunknownVariable: (key: string) => `Unknown placeholder: ${key}`, duplicateVariable: (key: string) => `Duplicate placeholder: ${key}`,\n\tunknownTemplate: (id: string) => `Unknown template: ${id}`, duplicateTemplate: 'Template IDs must be unique.',\n\teditableRequired: 'Use editable rich text for this operation.', editorNotReady: 'Editor is not ready.',\n\tunsupportedNode: (node: string) => `Unsupported document node: ${node}`, renderError: 'Unable to render the message.',\n\terrorTitle: 'Message could not be completed',\n};\nexport type EmailComposerStrings = typeof defaultEmailComposerStrings;\n","import type { JSONContent } from '@tiptap/react';\nimport type { EmailBody } from './types';\nimport { sanitizeEmailHtml } from './email-html';\nimport { defaultEmailComposerStrings, type EmailComposerStrings } from './strings';\nexport const emptyDocument: JSONContent = { type: 'doc', content: [{ type: 'paragraph' }] };\nexport const escapeEmailHtml = (value: string): string => value.replace(/[&<>\"']/g, char => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' })[char]!);\nexport function documentHtml(node: JSONContent, strings: EmailComposerStrings = defaultEmailComposerStrings): string {\n\tconst content = () => (node.content ?? []).map(child => documentHtml(child, strings)).join('');\n\tif (node.type === 'text' || node.type === 'placeholderToken') {\n\t\tconst key = escapeEmailHtml(String(node.attrs?.key ?? ''));\n\t\tlet text = node.type === 'text' ? escapeEmailHtml(node.text ?? '') : `<span data-placeholder=\"${key}\">{{${key}}}</span>`;\n\t\tfor (const mark of node.marks ?? []) {\n\t\t\tconst tags: Record<string, string> = { bold: 'strong', italic: 'em', strike: 's', underline: 'u', code: 'code' };\n\t\t\tif (tags[mark.type])\n\t\t\t\ttext = `<${tags[mark.type]}>${text}</${tags[mark.type]}>`;\n\t\t\telse if (mark.type === 'link')\n\t\t\t\ttext = `<a href=\"${escapeEmailHtml(String(mark.attrs?.href ?? ''))}\">${text}</a>`;\n\t\t\telse\n\t\t\t\tthrow new Error(strings.unsupportedNode(mark.type));\n\t\t}\n\t\treturn text;\n\t}\n\tif (node.type === 'doc')\n\t\treturn content();\n\tif (node.type === 'hardBreak')\n\t\treturn '<br>';\n\tif (node.type === 'horizontalRule')\n\t\treturn '<hr>';\n\tif (node.type === 'heading') {\n\t\tconst level = Math.min(6, Math.max(1, Number(node.attrs?.level) || 2));\n\t\treturn `<h${level}>${content()}</h${level}>`;\n\t}\n\tif (node.type === 'codeBlock')\n\t\treturn `<pre><code>${content()}</code></pre>`;\n\tif (node.type === 'orderedList')\n\t\treturn `<ol start=\"${Math.max(1, Math.trunc(Number(node.attrs?.start) || 1))}\">${content()}</ol>`;\n\tconst tags: Record<string, string> = { paragraph: 'p', blockquote: 'blockquote', bulletList: 'ul', orderedList: 'ol', listItem: 'li' };\n\tif (!node.type || !tags[node.type])\n\t\tthrow new Error(strings.unsupportedNode(node.type ?? 'unknown'));\n\treturn `<${tags[node.type]}>${content()}</${tags[node.type]}>`;\n}\nexport function bodyHtml(body: EmailBody, strings: EmailComposerStrings = defaultEmailComposerStrings): string {\n\treturn sanitizeEmailHtml(bodyMarkup(body, strings));\n}\nexport function bodyMarkup(body: EmailBody, strings: EmailComposerStrings): string {\n\treturn body.kind === 'html' ? body.html : body.kind === 'text' ? `<p>${escapeEmailHtml(body.text).replace(/\\n/g, '<br>')}</p>` : documentHtml(body.document, strings);\n}\n","import { toHtml } from 'hast-util-to-html';\nimport type { Root, RootContent } from 'hast';\nimport { bodyMarkup } from './document';\nimport { parseEmailHtml, sanitizeEmailTree, emailHtmlText } from './email-html';\nimport { defaultEmailComposerStrings, type EmailComposerStrings } from './strings';\nimport type { ComposerDraft, ComposerIssue, EmailTemplate, PlaceholderDefinition, PlaceholderValue, PreparedEmail, Recipient } from './types';\nconst tokens = /\\{\\{([a-zA-Z0-9_.-]+)\\}\\}/g;\nexport function resolveValues<C, K extends string>(draft: ComposerDraft<K>, context: C, definitions: Partial<Record<K, PlaceholderDefinition<C>>>, template?: EmailTemplate<K>): Partial<Record<K, PlaceholderValue>> {\n\tconst values: Partial<Record<K, PlaceholderValue>> = Object.create(null);\n\tfor (const key of Object.keys(definitions) as K[]) {\n\t\tconst override = Object.hasOwn(draft.placeholderOverrides, key) ? draft.placeholderOverrides[key] : undefined;\n\t\tvalues[key] = override !== undefined ? override : definitions[key]!.resolve(context) ?? template?.defaults?.[key] ?? definitions[key]!.fallback ?? null;\n\t}\n\treturn values;\n}\nexport function renderEmail<C, K extends string>(draft: ComposerDraft<K>, context: C, definitions: Partial<Record<K, PlaceholderDefinition<C>>>, template?: EmailTemplate<K>, strings: EmailComposerStrings = defaultEmailComposerStrings): {\n\temail: PreparedEmail<K>;\n\tunresolved: string[];\n} {\n\tconst values = resolveValues(draft, context, definitions, template);\n\tconst unresolved = new Set<string>();\n\tconst get = (key: string) => {\n\t\tconst value = Object.hasOwn(values, key) ? values[key as K] : null;\n\t\tif (value == null || value === '') {\n\t\t\tunresolved.add(key);\n\t\t\treturn `{{${key}}}`;\n\t\t}\n\t\treturn String(value);\n\t};\n\tconst subject = draft.subject.replace(tokens, (_, key: string) => get(key));\n\tconst tree = parseEmailHtml(bodyMarkup(draft.body, strings));\n\tfunction visit(node: Root | RootContent): void {\n\t\tif (node.type === 'element') {\n\t\t\tfor (const [key, value] of Object.entries(node.properties))\n\t\t\t\tif (key !== 'dataPlaceholder' && typeof value === 'string' && value.includes('{{'))\n\t\t\t\t\tthrow new Error(strings.attributeVariables);\n\t\t}\n\t\tif (node.type === 'root' || node.type === 'element')\n\t\t\tnode.children = node.children.map(child => {\n\t\t\t\tif (child.type === 'element' && child.properties.dataPlaceholder !== undefined)\n\t\t\t\t\treturn { type: 'text', value: get(String(child.properties.dataPlaceholder)) };\n\t\t\t\tif (child.type === 'text')\n\t\t\t\t\treturn { ...child, value: child.value.replace(tokens, (_, key: string) => get(key)) };\n\t\t\t\tvisit(child);\n\t\t\t\treturn child;\n\t\t\t});\n\t}\n\tvisit(tree);\n\tfor (const key of Object.keys(definitions) as K[])\n\t\tif (definitions[key]?.required && (values[key] == null || values[key] === ''))\n\t\t\tunresolved.add(key);\n\tfor (const key of template?.requiredPlaceholders ?? [])\n\t\tif (values[key] == null || values[key] === '')\n\t\t\tunresolved.add(key);\n\tconst clean = sanitizeEmailTree(tree);\n\treturn { email: { to: structuredClone(draft.to), cc: structuredClone(draft.cc), bcc: structuredClone(draft.bcc), subject, html: toHtml(clean), text: emailHtmlText(clean).trim(), templateId: draft.templateId, resolvedPlaceholders: values }, unresolved: [...unresolved] };\n}\nexport function inspectDraft<C, K extends string>(draft: ComposerDraft<K>, context: C, definitions: Partial<Record<K, PlaceholderDefinition<C>>>, template?: EmailTemplate<K>, strings: EmailComposerStrings = defaultEmailComposerStrings) {\n\tconst issues: ComposerIssue[] = [];\n\tlet rendered: ReturnType<typeof renderEmail<C, K>> | undefined;\n\tlet renderError = '';\n\tif (!draft.to.length)\n\t\tissues.push({ field: 'to', message: strings.missingRecipient });\n\tfor (const field of ['to', 'cc', 'bcc'] as const)\n\t\tif (draft[field].some(r => !/^[^\\s@<>]+@[^\\s@<>]+\\.[^\\s@<>]+$/.test(r.email) || /[\\r\\n]/.test(r.name ?? '')))\n\t\t\tissues.push({ field, message: strings.invalidRecipients(strings[field]) });\n\tif (!draft.subject.trim() || /[\\r\\n]/.test(draft.subject))\n\t\tissues.push({ field: 'subject', message: strings.invalidSubject });\n\ttry {\n\t\tconst result = renderEmail(draft, context, definitions, template, strings);\n\t\trendered = result;\n\t\tif (!result.email.text.trim())\n\t\t\tissues.push({ field: 'body', message: strings.emptyBody });\n\t\tif (result.unresolved.length)\n\t\t\tissues.push({ field: 'placeholders', message: strings.missingVariables(result.unresolved) });\n\t\tif ((!result.email.subject.trim() || /[\\r\\n]/.test(result.email.subject)) && !issues.some(issue => issue.field === 'subject'))\n\t\t\tissues.push({ field: 'subject', message: strings.invalidResolvedSubject });\n\t}\n\tcatch (error) {\n\t\trenderError = error instanceof Error ? error.message : strings.renderError;\n\t\tissues.push({ field: 'body', message: renderError });\n\t}\n\treturn { rendered, renderError, issues };\n}\nexport function validate<C, K extends string>(draft: ComposerDraft<K>, context: C, definitions: Partial<Record<K, PlaceholderDefinition<C>>>, template?: EmailTemplate<K>, strings: EmailComposerStrings = defaultEmailComposerStrings): ComposerIssue[] {\n\treturn inspectDraft(draft, context, definitions, template, strings).issues;\n}\nexport function recipientLabel(recipient: Recipient): string { return recipient.name ? `${recipient.name} <${recipient.email}>` : recipient.email; }\nexport function parseRecipient(value: string): Recipient {\n\tconst match = value.trim().match(/^(.*?)\\s*<([^<>]+)>$/);\n\treturn match ? { name: match[1].trim(), email: match[2].trim() } : { email: value.trim() };\n}\n","import type { PreparedEmail } from './types';\n/** Optional sender adapter. The consuming application owns the endpoint and delivery. */\nexport function createHttpSender(endpoint: string, options: {\n\theaders?: Record<string, string>;\n\ttimeoutMs?: number;\n} = {}) {\n\treturn async <K extends string>(email: PreparedEmail<K>): Promise<void> => {\n\t\tconst response = await fetch(endpoint, { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', ...options.headers }, body: JSON.stringify(email), signal: AbortSignal.timeout(options.timeoutMs ?? 30000) });\n\t\tif (!response.ok) {\n\t\t\tlet message = `Email request failed (${response.status}).`;\n\t\t\ttry {\n\t\t\t\tconst result: unknown = await response.json();\n\t\t\t\tif (result && typeof result === 'object' && 'message' in result && typeof result.message === 'string')\n\t\t\t\t\tmessage = result.message;\n\t\t\t}\n\t\t\tcatch { /* Response bodies are optional. */ }\n\t\t\tthrow new Error(message);\n\t\t}\n\t};\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { _ as e, s as t } from "./ui-provider-CftIB6TY.js";
3
- import { t as n } from "./utils-C2EKeIw3.js";
2
+ import { _ as e, s as t } from "./ui-provider-DRPn3qNl.js";
3
+ import { t as n } from "./utils-BvH9PSmq.js";
4
4
  import { createElement as r } from "react";
5
5
  import { jsx as i } from "react/jsx-runtime";
6
6
  //#region src/components/base/display/icon-badge/icon-badge.tsx
@@ -41,7 +41,7 @@ function c({ icon: c, children: l, size: u, shape: d = "circle", tone: f = "prim
41
41
  "aria-hidden": _ ?? (!w || void 0),
42
42
  "aria-label": v,
43
43
  "aria-labelledby": y,
44
- className: n("icon-badge--component", "inline-flex shrink-0 items-center justify-center", d === "circle" ? "rounded-full" : "rounded-radius-md", S.box, C, m && "border border-border/60", h),
44
+ className: n("icon-badge--component", "box-border inline-flex shrink-0 items-center justify-center", d === "circle" ? "rounded-full" : "rounded-radius", S.box, C, m && "border border-border/60", h),
45
45
  ...b,
46
46
  children: c ? r(c, { className: S.icon }) : l
47
47
  });
@@ -50,4 +50,4 @@ c.displayName = "IconBadge";
50
50
  //#endregion
51
51
  export { c as t };
52
52
 
53
- //# sourceMappingURL=icon-badge-Dv0RYQwj.js.map
53
+ //# sourceMappingURL=icon-badge-Btc6pQrp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"icon-badge-Dv0RYQwj.js","names":["resolveComponentScale","useDensityConfig","cn","SIZE_MAP","TONE_TINT","TONE_SOLID","IconBadge","Icon","sizeProp","ariaHidden","ariaLabel","ariaLabelledBy","props","sizes","defaultScale","tones","solid","tone","hasAccessibleName","role","shape","bordered","className","createElement","children"],"sources":["../src/components/base/display/icon-badge/icon-badge.tsx"],"sourcesContent":["/**\n * IconBadge — circular or square icon container with a tinted background.\n * Workhorse for \"row leading icon\" and \"feature illustration\" patterns —\n * coupon checks, conversation initials, search-result tones, AI-bot avatars.\n *\n * Tones reuse the shadcn semantic tokens, with the foreground colour picked\n * to read against a 10–15% background tint (e.g. `bg-success/15 text-success`).\n * For a fully-saturated mark (primary fill, inverse foreground), use\n * `tone=\"primary\"` and pass `solid`.\n *\n * Warning takes `--warning-accent` rather than `--warning-foreground`: the\n * latter is the colour for text on a SOLID warning fill and stays near-black\n * in both themes, so on a 20% tint it vanished in dark (1.87 contrast). Amber\n * is intrinsically light, so — as with `--primary-accent` — the tone needs a\n * separate foreground token that darkens in light and brightens in dark.\n */\nimport type { ComponentProps, ElementType, ReactNode } from 'react';\nimport { createElement } from 'react';\n\nimport { useDensityConfig, type ComponentScale } from '../../../../lib/ui-provider';\nimport { resolveComponentScale } from '../../../../lib/ui-provider/scale';\nimport { cn } from '../../../../lib/utils';\nimport type { SemanticTone } from '../../../../lib/component-vocabulary';\n\nexport type IconBadgeSize = ComponentScale;\nexport type IconBadgeShape = 'circle' | 'square';\nexport type IconBadgeTone = SemanticTone;\n\nexport interface IconBadgeProps extends Omit<ComponentProps<'span'>, 'children'> {\n\t/** Leading glyph. */\n\ticon?: ElementType;\n\tchildren?: ReactNode;\n\t/** Size preset. */\n\tsize?: IconBadgeSize;\n\tshape?: IconBadgeShape;\n\t/** Semantic tone driving the entry's colour. */\n\ttone?: IconBadgeTone;\n\t/** When true, fills the badge with the tone color and inverts the icon. */\n\tsolid?: boolean;\n\t/**\n\t * When true, renders a hairline `border-border/60` around the badge.\n\t * Useful for compact \"secret list\" / \"key list\" rows where the icon\n\t * needs a subtle outline against the surrounding card surface\n\t * (see `blocks/admin/api-key-list`).\n\t */\n\tbordered?: boolean;\n}\n\nconst SIZE_MAP: Record<IconBadgeSize, { box: string; icon: string }> = {\n\tsm: { box: 'size-avatar-sm', icon: 'size-icon-sm' },\n\tmd: { box: 'size-avatar', icon: 'size-icon' },\n\tlg: { box: 'size-avatar-lg', icon: 'size-icon-lg' },\n};\n\nconst TONE_TINT: Record<IconBadgeTone, string> = {\n\tneutral: 'bg-muted text-muted-foreground',\n\tprimary: 'bg-primary/15 text-primary-accent',\n\tsecondary: 'bg-foreground/8 text-muted-foreground',\n\tsuccess: 'bg-success/15 text-success',\n\twarning: 'bg-warning/20 text-warning-accent',\n\tdestructive: 'bg-destructive/12 text-destructive',\n\tinfo: 'bg-info/15 text-info',\n};\n\nconst TONE_SOLID: Record<IconBadgeTone, string> = {\n\tneutral: 'bg-foreground/70 text-background',\n\tprimary: 'bg-primary text-primary-foreground',\n\tsecondary: 'bg-secondary text-secondary-foreground',\n\tsuccess: 'bg-success text-success-foreground',\n\twarning: 'bg-warning text-warning-foreground',\n\tdestructive: 'bg-destructive text-destructive-foreground',\n\tinfo: 'bg-info text-info-foreground',\n};\n\nexport function IconBadge({\n\ticon: Icon,\n\tchildren,\n\tsize: sizeProp,\n\tshape = 'circle',\n\ttone = 'primary',\n\tsolid = false,\n\tbordered = false,\n\tclassName,\n\trole,\n\t'aria-hidden': ariaHidden,\n\t'aria-label': ariaLabel,\n\t'aria-labelledby': ariaLabelledBy,\n\t...props\n}: IconBadgeProps) {\n\tconst { defaultScale } = useDensityConfig();\n\tconst size = resolveComponentScale(sizeProp, defaultScale);\n\tconst sizes = SIZE_MAP[size];\n\tconst tones = solid ? TONE_SOLID[tone] : TONE_TINT[tone];\n\tconst hasAccessibleName = Boolean(ariaLabel || ariaLabelledBy);\n\n\treturn (\n\t\t<span\n\t\t\trole={role ?? (hasAccessibleName ? 'img' : undefined)}\n\t\t\taria-hidden={ariaHidden ?? (hasAccessibleName ? undefined : true)}\n\t\t\taria-label={ariaLabel}\n\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\tclassName={cn('icon-badge--component', \n\t\t\t\t'inline-flex shrink-0 items-center justify-center',\n\t\t\t\tshape === 'circle' ? 'rounded-full' : 'rounded-radius-md',\n\t\t\t\tsizes.box,\n\t\t\t\ttones,\n\t\t\t\tbordered && 'border border-border/60',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{Icon ? createElement(Icon, { className: sizes.icon }) : children}\n\t\t</span>\n\t);\n}\n\nIconBadge.displayName = 'IconBadge';\n"],"mappings":";;;;;;AAgDA,IAAMG,IAAiE;CACtE,IAAI;EAAE,KAAK;EAAkB,MAAM;CAAe;CAClD,IAAI;EAAE,KAAK;EAAe,MAAM;CAAY;CAC5C,IAAI;EAAE,KAAK;EAAkB,MAAM;CAAe;AACnD,GAEMC,IAA2C;CAChD,SAAS;CACT,SAAS;CACT,WAAW;CACX,SAAS;CACT,SAAS;CACT,aAAa;CACb,MAAM;AACP,GAEMC,IAA4C;CACjD,SAAS;CACT,SAAS;CACT,WAAW;CACX,SAAS;CACT,SAAS;CACT,aAAa;CACb,MAAM;AACP;AAEA,SAAgBC,EAAU,EACzB,MAAMC,GACN,aACA,MAAMC,GACN,WAAQ,UACR,UAAO,WACP,WAAQ,IACR,cAAW,IACX,cACA,SACA,eAAeC,GACf,cAAcC,GACd,mBAAmBC,GACnB,GAAGC,KACe;CAClB,IAAM,EAAE,oBAAiBX,EAAiB,GAEpCY,IAAQV,EADDH,EAAsBQ,GAAUM,CACtB,IACjBC,IAAQC,IAAQX,EAAWY,KAAQb,EAAUa,IAC7CC,IAAoB,GAAQR,KAAaC;CAE/C,OACC,kBAAC,QAAD;EACC,MAAMQ,MAASD,IAAoB,QAAQ,KAAA;EAC3C,eAAaT,MAAe,MAAoB,KAAA;EAChD,cAAYC;EACZ,mBAAiBC;EACjB,WAAWT,EAAG,yBACb,oDACAkB,MAAU,WAAW,iBAAiB,qBACtCP,EAAM,KACNE,GACAM,KAAY,2BACZC,CACD;EACA,GAAIV;EAEH,UAAAL,IAAOgB,EAAchB,GAAM,EAAE,WAAWM,EAAM,KAAK,CAAC,IAAIW;CACpD,CAAA;AAER;AAEA,EAAU,cAAc"}
1
+ {"version":3,"file":"icon-badge-Btc6pQrp.js","names":["resolveComponentScale","useDensityConfig","cn","SIZE_MAP","TONE_TINT","TONE_SOLID","IconBadge","Icon","sizeProp","ariaHidden","ariaLabel","ariaLabelledBy","props","sizes","defaultScale","tones","solid","tone","hasAccessibleName","role","shape","bordered","className","createElement","children"],"sources":["../src/components/base/display/icon-badge/icon-badge.tsx"],"sourcesContent":["/**\n * IconBadge — circular or square icon container with a tinted background.\n * Workhorse for \"row leading icon\" and \"feature illustration\" patterns —\n * coupon checks, conversation initials, search-result tones, AI-bot avatars.\n *\n * Tones reuse the shadcn semantic tokens, with the foreground colour picked\n * to read against a 10–15% background tint (e.g. `bg-success/15 text-success`).\n * For a fully-saturated mark (primary fill, inverse foreground), use\n * `tone=\"primary\"` and pass `solid`.\n *\n * Warning takes `--warning-accent` rather than `--warning-foreground`: the\n * latter is the colour for text on a SOLID warning fill and stays near-black\n * in both themes, so on a 20% tint it vanished in dark (1.87 contrast). Amber\n * is intrinsically light, so — as with `--primary-accent` — the tone needs a\n * separate foreground token that darkens in light and brightens in dark.\n */\nimport type { ComponentProps, ElementType, ReactNode } from 'react';\nimport { createElement } from 'react';\n\nimport { useDensityConfig, type ComponentScale } from '../../../../lib/ui-provider';\nimport { resolveComponentScale } from '../../../../lib/ui-provider/scale';\nimport { cn } from '../../../../lib/utils';\nimport type { SemanticTone } from '../../../../lib/component-vocabulary';\n\nexport type IconBadgeSize = ComponentScale;\nexport type IconBadgeShape = 'circle' | 'square';\nexport type IconBadgeTone = SemanticTone;\n\nexport interface IconBadgeProps extends Omit<ComponentProps<'span'>, 'children'> {\n\t/** Leading glyph. */\n\ticon?: ElementType;\n\tchildren?: ReactNode;\n\t/** Size preset. */\n\tsize?: IconBadgeSize;\n\tshape?: IconBadgeShape;\n\t/** Semantic tone driving the entry's colour. */\n\ttone?: IconBadgeTone;\n\t/** When true, fills the badge with the tone color and inverts the icon. */\n\tsolid?: boolean;\n\t/**\n\t * When true, renders a hairline `border-border/60` around the badge.\n\t * Useful for compact \"secret list\" / \"key list\" rows where the icon\n\t * needs a subtle outline against the surrounding card surface\n\t * (see `blocks/admin/api-key-list`).\n\t */\n\tbordered?: boolean;\n}\n\nconst SIZE_MAP: Record<IconBadgeSize, { box: string; icon: string }> = {\n\tsm: { box: 'size-avatar-sm', icon: 'size-icon-sm' },\n\tmd: { box: 'size-avatar', icon: 'size-icon' },\n\tlg: { box: 'size-avatar-lg', icon: 'size-icon-lg' },\n};\n\nconst TONE_TINT: Record<IconBadgeTone, string> = {\n\tneutral: 'bg-muted text-muted-foreground',\n\tprimary: 'bg-primary/15 text-primary-accent',\n\tsecondary: 'bg-foreground/8 text-muted-foreground',\n\tsuccess: 'bg-success/15 text-success',\n\twarning: 'bg-warning/20 text-warning-accent',\n\tdestructive: 'bg-destructive/12 text-destructive',\n\tinfo: 'bg-info/15 text-info',\n};\n\nconst TONE_SOLID: Record<IconBadgeTone, string> = {\n\tneutral: 'bg-foreground/70 text-background',\n\tprimary: 'bg-primary text-primary-foreground',\n\tsecondary: 'bg-secondary text-secondary-foreground',\n\tsuccess: 'bg-success text-success-foreground',\n\twarning: 'bg-warning text-warning-foreground',\n\tdestructive: 'bg-destructive text-destructive-foreground',\n\tinfo: 'bg-info text-info-foreground',\n};\n\nexport function IconBadge({\n\ticon: Icon,\n\tchildren,\n\tsize: sizeProp,\n\tshape = 'circle',\n\ttone = 'primary',\n\tsolid = false,\n\tbordered = false,\n\tclassName,\n\trole,\n\t'aria-hidden': ariaHidden,\n\t'aria-label': ariaLabel,\n\t'aria-labelledby': ariaLabelledBy,\n\t...props\n}: IconBadgeProps) {\n\tconst { defaultScale } = useDensityConfig();\n\tconst size = resolveComponentScale(sizeProp, defaultScale);\n\tconst sizes = SIZE_MAP[size];\n\tconst tones = solid ? TONE_SOLID[tone] : TONE_TINT[tone];\n\tconst hasAccessibleName = Boolean(ariaLabel || ariaLabelledBy);\n\n\treturn (\n\t\t<span\n\t\t\trole={role ?? (hasAccessibleName ? 'img' : undefined)}\n\t\t\taria-hidden={ariaHidden ?? (hasAccessibleName ? undefined : true)}\n\t\t\taria-label={ariaLabel}\n\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\tclassName={cn('icon-badge--component', \n\t\t\t\t'box-border inline-flex shrink-0 items-center justify-center',\n\t\t\t\tshape === 'circle' ? 'rounded-full' : 'rounded-radius',\n\t\t\t\tsizes.box,\n\t\t\t\ttones,\n\t\t\t\tbordered && 'border border-border/60',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{Icon ? createElement(Icon, { className: sizes.icon }) : children}\n\t\t</span>\n\t);\n}\n\nIconBadge.displayName = 'IconBadge';\n"],"mappings":";;;;;;AAgDA,IAAMG,IAAiE;CACtE,IAAI;EAAE,KAAK;EAAkB,MAAM;CAAe;CAClD,IAAI;EAAE,KAAK;EAAe,MAAM;CAAY;CAC5C,IAAI;EAAE,KAAK;EAAkB,MAAM;CAAe;AACnD,GAEMC,IAA2C;CAChD,SAAS;CACT,SAAS;CACT,WAAW;CACX,SAAS;CACT,SAAS;CACT,aAAa;CACb,MAAM;AACP,GAEMC,IAA4C;CACjD,SAAS;CACT,SAAS;CACT,WAAW;CACX,SAAS;CACT,SAAS;CACT,aAAa;CACb,MAAM;AACP;AAEA,SAAgBC,EAAU,EACzB,MAAMC,GACN,aACA,MAAMC,GACN,WAAQ,UACR,UAAO,WACP,WAAQ,IACR,cAAW,IACX,cACA,SACA,eAAeC,GACf,cAAcC,GACd,mBAAmBC,GACnB,GAAGC,KACe;CAClB,IAAM,EAAE,oBAAiBX,EAAiB,GAEpCY,IAAQV,EADDH,EAAsBQ,GAAUM,CACtB,IACjBC,IAAQC,IAAQX,EAAWY,KAAQb,EAAUa,IAC7CC,IAAoB,GAAQR,KAAaC;CAE/C,OACC,kBAAC,QAAD;EACC,MAAMQ,MAASD,IAAoB,QAAQ,KAAA;EAC3C,eAAaT,MAAe,MAAoB,KAAA;EAChD,cAAYC;EACZ,mBAAiBC;EACjB,WAAWT,EAAG,yBACb,+DACAkB,MAAU,WAAW,iBAAiB,kBACtCP,EAAM,KACNE,GACAM,KAAY,2BACZC,CACD;EACA,GAAIV;EAEH,UAAAL,IAAOgB,EAAchB,GAAM,EAAE,WAAWM,EAAM,KAAK,CAAC,IAAIW;CACpD,CAAA;AAER;AAEA,EAAU,cAAc"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { _ as e, a as t, c as n, d as r, f as i, g as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h, v as g } from "./ui-provider-CftIB6TY.js";
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h, v as g } from "./ui-provider-DRPn3qNl.js";
2
2
  import { CARD_SURFACES as _, COMPONENT_SCALES as v, DISCLOSURE_SURFACES as y, SEMANTIC_TONES as b } from "./component-vocabulary.js";
3
3
  import { t as x } from "./theme-scope-kStaAer0.js";
4
4
  import { ACTION_BUTTON_STYLES as S } from "./action-presentation.js";
5
5
  import { interpolateString as C, mergeStrings as w, useStrings as T } from "./lib/strings.js";
6
- import { t as E } from "./utils-C2EKeIw3.js";
6
+ import { t as E } from "./utils-BvH9PSmq.js";
7
7
  export { S as ACTION_BUTTON_STYLES, _ as CARD_SURFACES, v as COMPONENT_SCALES, g as DEFAULT_UI_CONFIG, y as DISCLOSURE_SURFACES, m as DirectionProvider, b as SEMANTIC_TONES, x as ThemeScope, c as UIProvider, E as cn, C as interpolateString, a as isComponentScale, w as mergeStrings, e as resolveComponentScale, l as useBadgeConfig, f as useButtonConfig, o as useCardConfig, t as useCommentsConfig, u as useDatesConfig, p as useDensityConfig, n as useFormattingConfig, s as useItemConfig, h as useMoneyConfig, r as useSpinnerConfig, T as useStrings, i as useToastConfig, d as useTypographyConfig };
@@ -0,0 +1,255 @@
1
+ "use client";
2
+ import { s as e } from "./ui-provider-DRPn3qNl.js";
3
+ import { useStrings as t } from "./lib/strings.js";
4
+ import { t as n } from "./utils-BvH9PSmq.js";
5
+ import { a as r } from "./typography-BxQgiZyw.js";
6
+ import { t as i } from "./field-state-recipes-DQQpiLWC.js";
7
+ import { t as a } from "./field-affordance-recipes-uKY4MsZ_.js";
8
+ import { t as o } from "./editable-text-recipe-Bkm6wKHp.js";
9
+ import { i as s, l as c, n as ee, o as l, p as u, r as d, s as f, t as p, u as m } from "./form-sizing-QP8aIRaW.js";
10
+ import * as h from "react";
11
+ import { createContext as g, memo as _, useCallback as v, useId as y, useMemo as b, useRef as x, useState as S } from "react";
12
+ import { jsx as C, jsxs as w } from "react/jsx-runtime";
13
+ import { CircleXIcon as te, Loader2Icon as ne } from "lucide-react";
14
+ //#region src/components/base/text-inputs/hooks/use-form-field-state.ts
15
+ function T({ controlledValue: e, defaultValue: t, maxLength: n, showCharacterCount: r, providedId: i, idPrefix: a = "field", hasOnChange: o }) {
16
+ let s = y(), c = i || `${a}${s}`, [ee, l] = S(t || ""), u = e !== void 0, d = (u ? e : ee) ?? "", f = !(!o || u || t), p = d.length, m = n !== void 0, h = r !== !1 && !!(r || m), g = d !== "", _ = v((e) => m && e.length > n, [m, n]), x = v((e) => !_(e) && (u || l(e), !0), [u, _]), C = v(() => {
17
+ u || l("");
18
+ }, [u]);
19
+ return b(() => ({
20
+ id: c,
21
+ value: d,
22
+ isControlled: u,
23
+ isReactHookForm: f,
24
+ characterCount: p,
25
+ hasCharacterLimit: m,
26
+ showCount: h,
27
+ hasValue: g,
28
+ updateValue: x,
29
+ clearValue: C,
30
+ wouldExceedLimit: _
31
+ }), [
32
+ c,
33
+ d,
34
+ u,
35
+ f,
36
+ p,
37
+ m,
38
+ h,
39
+ g,
40
+ x,
41
+ C,
42
+ _
43
+ ]);
44
+ }
45
+ //#endregion
46
+ //#region src/components/base/text-inputs/clear-native-field.ts
47
+ function E(e) {
48
+ let t = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(e), "value")?.set;
49
+ e.type === "file" ? e.value = "" : t?.call(e, ""), e.dispatchEvent(new Event("change", { bubbles: !0 }));
50
+ }
51
+ //#endregion
52
+ //#region src/components/base/text-inputs/input-trailing-action.ts
53
+ var D = g(null), O = { clear: "Clear input" }, re = (e, t, n) => {
54
+ let r = e || "";
55
+ return t && r && (r = t + r), n && r && (r += n), r;
56
+ };
57
+ function k({ className: g, type: _ = "text", startIcon: y, endIcon: S, startAddon: k, endAddon: A, maxLength: j, showCharacterCount: ie, clearable: ae, onClear: oe, loading: M = !1, returnValueWithAddons: N, invalid: se, size: ce, onChange: P, value: le, defaultValue: ue, id: de, strings: fe, ...F }, I) {
58
+ let L = x(null), R = h.useContext(D), z = x(null), B = x(null), [V, H] = h.useState(), [U, W] = h.useState(), pe = t(O, fe), { defaultScale: me } = e(), G = u(ce, me), he = v((e) => {
59
+ typeof I == "function" ? I(e) : I && (I.current = e), L.current = e;
60
+ }, [I]), { id: ge, value: _e, isReactHookForm: ve, characterCount: ye, hasCharacterLimit: be, showCount: K, hasValue: xe, updateValue: Se, clearValue: q, wouldExceedLimit: Ce } = T({
61
+ controlledValue: le,
62
+ defaultValue: ue,
63
+ maxLength: j,
64
+ showCharacterCount: ie,
65
+ providedId: de,
66
+ idPrefix: "input",
67
+ hasOnChange: P !== void 0
68
+ }), we = !!ae, J = M, Te = !!S, Ee = !!A, De = _ === "file", Y = !!se, X = we && xe && !K && !J, Z = J && !K, Q = Te && !X && !K && !J, $ = Ee && !X && !K && !J;
69
+ h.useLayoutEffect(() => {
70
+ let e = z.current, t = B.current, n = () => {
71
+ if (e) {
72
+ let t = e.getBoundingClientRect().width;
73
+ t > 0 && H(t);
74
+ } else H(void 0);
75
+ if (t) {
76
+ let e = t.getBoundingClientRect().width;
77
+ e > 0 && W(e);
78
+ } else W(void 0);
79
+ };
80
+ if (n(), !e && !t) return;
81
+ let r = typeof ResizeObserver > "u" ? void 0 : new ResizeObserver(n);
82
+ return e && r?.observe(e), t && r?.observe(t), window.addEventListener("resize", n), () => {
83
+ r?.disconnect(), window.removeEventListener("resize", n);
84
+ };
85
+ }, [
86
+ G,
87
+ ye,
88
+ j,
89
+ k,
90
+ A,
91
+ Q,
92
+ $,
93
+ X,
94
+ K,
95
+ Z,
96
+ R
97
+ ]);
98
+ let Oe = b(() => {
99
+ let e = G === "sm" ? "ps-control-sm" : "ps-control", t = G === "sm" ? "pe-control-sm" : "pe-control";
100
+ return y && (e = f[G]), k && (e = p[G]), k && U !== void 0 && (e = a.measuredStartPadding[G]), Q && (t = s[G]), $ && (t = d[G]), J && (t = s[G]), X && (t = a.clearPadding[G]), K && (t = ee[G]), R && (t = K ? a.pairedCountPadding[G] : X ? a.pairedClearPadding[G] : $ ? a.pairedAddonPadding[G] : Q || Z ? a.pairedIconPadding[G] : a.clearPadding[G]), V !== void 0 && (t = a.measuredPadding[G]), `${e} ${t}`;
101
+ }, [
102
+ y,
103
+ k,
104
+ Q,
105
+ $,
106
+ X,
107
+ Z,
108
+ J,
109
+ K,
110
+ R,
111
+ V,
112
+ U,
113
+ G
114
+ ]), ke = v((e) => {
115
+ let t = e.target.value;
116
+ if (!Ce(t) && (Se(t), P)) {
117
+ if (N && t) {
118
+ let n = re(t, k, A);
119
+ P({
120
+ ...e,
121
+ target: {
122
+ ...e.target,
123
+ value: n
124
+ },
125
+ currentTarget: {
126
+ ...e.currentTarget,
127
+ value: n
128
+ }
129
+ });
130
+ } else P(e);
131
+ }
132
+ }, [
133
+ P,
134
+ N,
135
+ k,
136
+ A,
137
+ Se,
138
+ Ce
139
+ ]), Ae = v(() => {
140
+ if (F.disabled || F.readOnly || M) return;
141
+ let e = L.current;
142
+ if (e?.type === "color" || e?.type === "range") {
143
+ q();
144
+ let t = {
145
+ value: "",
146
+ name: e.name,
147
+ id: e.id,
148
+ type: e.type
149
+ };
150
+ P?.({
151
+ target: t,
152
+ currentTarget: t
153
+ });
154
+ } else e && E(e);
155
+ oe?.(), L.current?.focus();
156
+ }, [
157
+ F.disabled,
158
+ F.readOnly,
159
+ M,
160
+ q,
161
+ P,
162
+ oe
163
+ ]);
164
+ return /* @__PURE__ */ w("div", {
165
+ className: n("input--component", "relative h-fit w-full min-w-0"),
166
+ style: V === void 0 && U === void 0 ? void 0 : {
167
+ "--field-trailing-width": V === void 0 ? void 0 : `${V}px`,
168
+ "--field-leading-width": U === void 0 ? void 0 : `${U}px`
169
+ },
170
+ children: [
171
+ /* @__PURE__ */ C("input", {
172
+ ref: he,
173
+ id: ge,
174
+ type: _,
175
+ ...!ve && { value: _e },
176
+ onChange: ke,
177
+ maxLength: j,
178
+ "aria-invalid": Y || void 0,
179
+ className: n("file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground", "border-input box-border flex w-full min-w-0 rounded-inner border", "transition-[color,box-shadow] outline-none", "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", m[G], o[G], c[G], "file:inline-flex file:h-control-file file:border file:bg-transparent file:px-control file:font-medium", "file:text-pxs", De ? "cursor-pointer bg-background text-foreground file:cursor-pointer file:rounded-inner file:border-input file:bg-background file:text-foreground" : "bg-transparent", i.focus, i.invalid, De ? "read-only:bg-background" : "read-only:bg-muted", Oe, g),
180
+ ...F,
181
+ disabled: F.disabled || M
182
+ }),
183
+ !!y && /* @__PURE__ */ C("div", {
184
+ className: n("pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center", G === "sm" ? "ps-control-sm" : "ps-control", F.disabled && "opacity-50", Y ? "text-destructive" : "text-muted-foreground/80"),
185
+ children: /* @__PURE__ */ C(y, {
186
+ className: l[G],
187
+ "aria-hidden": "true"
188
+ })
189
+ }),
190
+ !!k && /* @__PURE__ */ C("span", {
191
+ className: n("pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center", G === "sm" ? "ps-control-sm" : "ps-control", F.disabled && "opacity-50"),
192
+ children: /* @__PURE__ */ C(r, {
193
+ ref: B,
194
+ tag: "span",
195
+ size: G === "sm" ? "pxs" : "sm",
196
+ type: Y ? "error" : "secondary",
197
+ lineHeight: "tight",
198
+ className: "input--start-addon",
199
+ children: k
200
+ })
201
+ }),
202
+ (Q || $ || K || Z || X || R) && /* @__PURE__ */ w("div", {
203
+ ref: z,
204
+ className: n("input--trailing absolute inset-y-0 flex items-center gap-space-sm whitespace-nowrap", a.clearEnd[G]),
205
+ children: [
206
+ Q && S && /* @__PURE__ */ C(S, {
207
+ className: n("pointer-events-none", l[G], Y ? "text-destructive" : "text-muted-foreground"),
208
+ "aria-hidden": "true"
209
+ }),
210
+ $ && /* @__PURE__ */ C(r, {
211
+ tag: "span",
212
+ size: G === "sm" ? "pxs" : "sm",
213
+ type: Y ? "error" : "secondary",
214
+ lineHeight: "tight",
215
+ className: "input--end-addon pointer-events-none",
216
+ children: A
217
+ }),
218
+ K && /* @__PURE__ */ C("div", {
219
+ role: "status",
220
+ "aria-live": "polite",
221
+ className: "pointer-events-none tabular-nums",
222
+ children: /* @__PURE__ */ w(r, {
223
+ tag: "span",
224
+ size: G === "sm" ? "xxs" : "xs",
225
+ type: Y ? "error" : "secondary",
226
+ children: [ye, be ? `/${j}` : ""]
227
+ })
228
+ }),
229
+ Z && /* @__PURE__ */ C(ne, {
230
+ className: n(l[G], "pointer-events-none animate-spin", Y ? "text-destructive" : "text-muted-foreground"),
231
+ "aria-hidden": "true"
232
+ }),
233
+ X && /* @__PURE__ */ C("button", {
234
+ type: "button",
235
+ className: n(a.target, a.focus, a.clear),
236
+ "aria-label": pe.clear,
237
+ onClick: Ae,
238
+ disabled: F.disabled || F.readOnly || M,
239
+ children: /* @__PURE__ */ C(te, {
240
+ className: a.icon,
241
+ "aria-hidden": "true"
242
+ })
243
+ }),
244
+ R
245
+ ]
246
+ })
247
+ ]
248
+ });
249
+ }
250
+ var A = _(h.forwardRef(k));
251
+ A.displayName = "Input";
252
+ //#endregion
253
+ export { T as a, E as i, O as n, D as r, A as t };
254
+
255
+ //# sourceMappingURL=input-SX9V0AL3.js.map