themelia-react-ui 2.0.4 → 2.0.6

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 (715) hide show
  1. package/CHANGELOG.md +211 -0
  2. package/MIGRATION.md +119 -0
  3. package/README.md +122 -20
  4. package/dist/{accordion-96o0pN62.js → accordion-0tQUZ20r.js} +13 -13
  5. package/dist/accordion-0tQUZ20r.js.map +1 -0
  6. package/dist/{action-menu-CHgs8vmj.js → action-menu-C0gjzLyE.js} +48 -45
  7. package/dist/action-menu-C0gjzLyE.js.map +1 -0
  8. package/dist/{affordance-geometry.generated-B8yGOr8-.js → affordance-geometry.generated-P-aVJisu.js} +36 -36
  9. package/dist/affordance-geometry.generated-P-aVJisu.js.map +1 -0
  10. package/dist/{ai-artifact-BZUGwBq6.js → ai-artifact-CGGpQryR.js} +281 -230
  11. package/dist/ai-artifact-CGGpQryR.js.map +1 -0
  12. package/dist/app-shell-EHuuRDGy.js +321 -0
  13. package/dist/app-shell-EHuuRDGy.js.map +1 -0
  14. package/dist/{attachment-DkoqHPPl.js → attachment-BCpA4e7i.js} +10 -10
  15. package/dist/{attachment-DkoqHPPl.js.map → attachment-BCpA4e7i.js.map} +1 -1
  16. package/dist/{auth-D2FVZ1MH.js → auth-B0girIk_.js} +49 -52
  17. package/dist/auth-B0girIk_.js.map +1 -0
  18. package/dist/{avatar-DWO_HHhB.js → avatar-B9Jnp-T-.js} +8 -8
  19. package/dist/avatar-B9Jnp-T-.js.map +1 -0
  20. package/dist/{badge-DErMA7ul.js → badge-wWauMgAt.js} +5 -5
  21. package/dist/{badge-DErMA7ul.js.map → badge-wWauMgAt.js.map} +1 -1
  22. package/dist/base/accordion.js +1 -1
  23. package/dist/base/action-menu.js +1 -1
  24. package/dist/base/attachment.js +1 -1
  25. package/dist/base/avatar.js +1 -1
  26. package/dist/base/badge.js +1 -1
  27. package/dist/base/batch-action-bar.js +1 -1
  28. package/dist/base/buttons.js +1 -1
  29. package/dist/base/cards.js +2 -2
  30. package/dist/base/carousel.js +3 -3
  31. package/dist/base/cascader.js +2 -372
  32. package/dist/base/chart.js +1 -1
  33. package/dist/base/choice-inputs.js +2 -2
  34. package/dist/base/code-block.js +1 -1
  35. package/dist/base/combobox.js +2 -2
  36. package/dist/base/command.js +1 -1
  37. package/dist/base/copyable.js +1 -1
  38. package/dist/base/date-pickers.js +2 -2
  39. package/dist/base/display.js +6 -6
  40. package/dist/base/feedback.js +4 -4
  41. package/dist/base/forms-numeric.js +1 -1
  42. package/dist/base/forms.js +2 -2
  43. package/dist/base/inline-edit.js +10 -10
  44. package/dist/base/item.js +1 -1
  45. package/dist/base/media-gallery.js +1 -1
  46. package/dist/base/metadata-list.js +1 -1
  47. package/dist/base/navigation.js +7 -7
  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 +200 -193
  52. package/dist/base/repeaters.js.map +1 -1
  53. package/dist/base/sheet.js +1 -1
  54. package/dist/base/sidebar.js +2 -2
  55. package/dist/base/signature-pad.js +8 -8
  56. package/dist/base/signature-pad.js.map +1 -1
  57. package/dist/base/skeleton.js +1 -1
  58. package/dist/base/spinner.js +6 -6
  59. package/dist/base/spinner.js.map +1 -1
  60. package/dist/base/structure.js +1 -1
  61. package/dist/base/table.js +1 -1
  62. package/dist/base/text-inputs.js +2 -2
  63. package/dist/base/toaster.js +36 -36
  64. package/dist/base/toaster.js.map +1 -1
  65. package/dist/base/tree.js +1 -1
  66. package/dist/base/upload-queue.js +1 -1
  67. package/dist/base/upload.js +3 -3
  68. package/dist/base/value-inputs.js +1 -1
  69. package/dist/{batch-action-bar-CdfIkCsV.js → batch-action-bar-BoqWIIpV.js} +7 -7
  70. package/dist/batch-action-bar-BoqWIIpV.js.map +1 -0
  71. package/dist/blocks/admin.js +21 -21
  72. package/dist/blocks/admin.js.map +1 -1
  73. package/dist/blocks/ai.js +267 -247
  74. package/dist/blocks/ai.js.map +1 -1
  75. package/dist/blocks/analytics/usage-card.js +1 -1
  76. package/dist/blocks/analytics.js +537 -543
  77. package/dist/blocks/analytics.js.map +1 -1
  78. package/dist/blocks/collaboration.js +1 -1
  79. package/dist/blocks/commerce/receipt.js +1 -1
  80. package/dist/blocks/commerce.js +1330 -1250
  81. package/dist/blocks/commerce.js.map +1 -1
  82. package/dist/blocks/data-display.js +2 -2
  83. package/dist/blocks/onboarding.js +6 -6
  84. package/dist/blocks/onboarding.js.map +1 -1
  85. package/dist/blocks/planning.js +11 -11
  86. package/dist/blocks/timelines.js +1 -1
  87. package/dist/{breadcrumbs-B-WFKecD.js → breadcrumbs-Bp9Ke7kd.js} +7 -7
  88. package/dist/breadcrumbs-Bp9Ke7kd.js.map +1 -0
  89. package/dist/{button-DkmK-z8E.js → button-ChBovTx0.js} +3 -3
  90. package/dist/button-ChBovTx0.js.map +1 -0
  91. package/dist/{buttons-BbfzgczK.js → buttons-DeW0bQeK.js} +16 -16
  92. package/dist/buttons-DeW0bQeK.js.map +1 -0
  93. package/dist/cards-CNXnmvV5.js +69 -0
  94. package/dist/cards-CNXnmvV5.js.map +1 -0
  95. package/dist/cascader-CrAl9zD5.js +439 -0
  96. package/dist/cascader-CrAl9zD5.js.map +1 -0
  97. package/dist/chart-I7ROnsl8.js +162 -0
  98. package/dist/chart-I7ROnsl8.js.map +1 -0
  99. package/dist/{checkbox-CzYUTPeJ.js → checkbox-MoyHIAPs.js} +3 -3
  100. package/dist/{checkbox-CzYUTPeJ.js.map → checkbox-MoyHIAPs.js.map} +1 -1
  101. package/dist/choice-inputs-DHGtx0QV.js +789 -0
  102. package/dist/choice-inputs-DHGtx0QV.js.map +1 -0
  103. package/dist/{code-block-CGNaUtAE.js → code-block-BSJyq9e-.js} +9 -9
  104. package/dist/code-block-BSJyq9e-.js.map +1 -0
  105. package/dist/{collapsible-Do4G0zcC.js → collapsible-BzJ91LUG.js} +5 -5
  106. package/dist/{collapsible-Do4G0zcC.js.map → collapsible-BzJ91LUG.js.map} +1 -1
  107. package/dist/{collection-content-C0e8SsTm.js → collection-content-CSnwtOTH.js} +3 -3
  108. package/dist/{collection-content-C0e8SsTm.js.map → collection-content-CSnwtOTH.js.map} +1 -1
  109. package/dist/combobox-Bcvu5J8O.js +363 -0
  110. package/dist/combobox-Bcvu5J8O.js.map +1 -0
  111. package/dist/combobox-C2JiSQPc.js +915 -0
  112. package/dist/combobox-C2JiSQPc.js.map +1 -0
  113. package/dist/{command-D8NrBj-b.js → command-9e52NPgK.js} +11 -11
  114. package/dist/command-9e52NPgK.js.map +1 -0
  115. package/dist/{comments-Di4w0H_S.js → comments-BsgErEqd.js} +44 -39
  116. package/dist/comments-BsgErEqd.js.map +1 -0
  117. package/dist/components/base/action-menu/action-menu.d.ts +7 -1
  118. package/dist/components/base/buttons/button-group.recipes.d.ts +2 -2
  119. package/dist/components/base/cards/card.recipes.d.ts +6 -4
  120. package/dist/components/base/cards/partials/card-primitives.d.ts +9 -2
  121. package/dist/components/base/cards/partials/smart-card-header-row.d.ts +3 -1
  122. package/dist/components/base/cards/smart-card.types.d.ts +3 -4
  123. package/dist/components/base/cascader/cascader-panel.d.ts +76 -0
  124. package/dist/components/base/chart/chart.d.ts +6 -1
  125. package/dist/components/base/choice-inputs/choice-types.d.ts +5 -1
  126. package/dist/components/base/choice-inputs/pill-radio-group.d.ts +7 -6
  127. package/dist/components/base/combobox/combobox-field.d.ts +2 -2
  128. package/dist/components/base/combobox/index.d.ts +4 -2
  129. package/dist/components/base/date-pickers/date-picker-internals.d.ts +3 -1
  130. package/dist/components/base/date-pickers/datepicker.types.d.ts +10 -4
  131. package/dist/components/base/date-pickers/time-picker.d.ts +17 -3
  132. package/dist/components/base/feedback/alert.d.ts +1 -1
  133. package/dist/components/base/feedback/state-display.d.ts +5 -1
  134. package/dist/components/base/feedback/state-display.strings.d.ts +9 -0
  135. package/dist/components/base/forms/form-field.d.ts +7 -2
  136. package/dist/components/base/forms/form-sizing.d.ts +7 -7
  137. package/dist/components/base/forms/workflow.d.ts +7 -1
  138. package/dist/components/base/forms-numeric/coordinates-input.d.ts +8 -1
  139. package/dist/components/base/forms-numeric/decimal-input.d.ts +2 -2
  140. package/dist/components/base/forms-numeric/dimensions-input.d.ts +4 -1
  141. package/dist/components/base/forms-numeric/numeric-composite-field.d.ts +12 -0
  142. package/dist/components/base/forms-numeric/weight-input.d.ts +6 -1
  143. package/dist/components/base/metadata-list/metadata-list.d.ts +1 -1
  144. package/dist/components/base/navigation/dropdown-menu.d.ts +1 -1
  145. package/dist/components/base/navigation/language-switcher.d.ts +12 -4
  146. package/dist/components/base/navigation/page-header/page-header-commands.d.ts +14 -7
  147. package/dist/components/base/navigation/page-header/page-header.d.ts +10 -3
  148. package/dist/components/base/popover/popover.d.ts +3 -3
  149. package/dist/components/base/popover/popover.recipes.d.ts +10 -6
  150. package/dist/components/base/repeaters/key-value-editor.d.ts +2 -1
  151. package/dist/components/base/sheet/sheet.d.ts +2 -0
  152. package/dist/components/base/sidebar/index.d.ts +1 -1
  153. package/dist/components/base/sidebar/sidebar.d.ts +29 -5
  154. package/dist/components/base/toaster/index.d.ts +1 -0
  155. package/dist/components/base/upload/avatar-upload.d.ts +2 -1
  156. package/dist/components/base/upload/image-upload.d.ts +2 -1
  157. package/dist/components/blocks/ai/ai-citation/types.d.ts +2 -0
  158. package/dist/components/blocks/ai/ai-file-tree/types.d.ts +1 -1
  159. package/dist/components/blocks/ai/ai-reasoning/types.d.ts +2 -0
  160. package/dist/components/blocks/ai/ai-sources/types.d.ts +2 -0
  161. package/dist/components/blocks/ai/ai-tool-call/types.d.ts +5 -1
  162. package/dist/components/blocks/ai/ai.strings.d.ts +2 -0
  163. package/dist/components/blocks/analytics/metric/metric.d.ts +4 -0
  164. package/dist/components/blocks/analytics/metric-comparison/metric-comparison.d.ts +4 -0
  165. package/dist/components/blocks/analytics/metric-grid/metric-grid.d.ts +4 -5
  166. package/dist/components/blocks/analytics/types.d.ts +2 -2
  167. package/dist/components/blocks/analytics/usage-card/usage-card.strings.d.ts +2 -0
  168. package/dist/components/blocks/commerce/cart-summary/cart-summary.d.ts +1 -1
  169. package/dist/components/blocks/commerce/cart-summary/types.d.ts +3 -1
  170. package/dist/components/blocks/commerce/discount-stack/discount-stack.d.ts +1 -1
  171. package/dist/components/blocks/commerce/discount-stack/types.d.ts +3 -1
  172. package/dist/components/blocks/commerce/fulfillment-group/fulfillment-group.d.ts +1 -1
  173. package/dist/components/blocks/commerce/fulfillment-group/types.d.ts +11 -2
  174. package/dist/components/blocks/commerce/index.d.ts +7 -6
  175. package/dist/components/blocks/commerce/inventory-section/inventory-section.d.ts +1 -1
  176. package/dist/components/blocks/commerce/inventory-section/types.d.ts +7 -2
  177. package/dist/components/blocks/commerce/invoice-header/index.d.ts +2 -1
  178. package/dist/components/blocks/commerce/invoice-header/invoice-header.d.ts +1 -1
  179. package/dist/components/blocks/commerce/invoice-header/types.d.ts +20 -6
  180. package/dist/components/blocks/commerce/invoice-line-items/invoice-line-items.d.ts +1 -1
  181. package/dist/components/blocks/commerce/invoice-line-items/types.d.ts +24 -7
  182. package/dist/components/blocks/commerce/invoice-mini/index.d.ts +2 -1
  183. package/dist/components/blocks/commerce/invoice-mini/types.d.ts +7 -1
  184. package/dist/components/blocks/commerce/order-customer/order-customer.d.ts +1 -1
  185. package/dist/components/blocks/commerce/order-customer/types.d.ts +9 -1
  186. package/dist/components/blocks/commerce/order-status/types.d.ts +4 -0
  187. package/dist/components/blocks/commerce/refund-status/refund-status.d.ts +1 -1
  188. package/dist/components/blocks/commerce/refund-status/types.d.ts +3 -1
  189. package/dist/components/blocks/commerce/shipment-tracking/shipment-tracking.d.ts +1 -1
  190. package/dist/components/blocks/commerce/shipment-tracking/types.d.ts +3 -1
  191. package/dist/components/blocks/commerce/tax-breakdown/tax-breakdown.d.ts +1 -1
  192. package/dist/components/blocks/commerce/tax-breakdown/types.d.ts +3 -1
  193. package/dist/components/blocks/data-display/empty-state/empty-state.types.d.ts +4 -3
  194. package/dist/components/features/activities/activities.types.d.ts +26 -13
  195. package/dist/components/features/activities/hooks/use-activity-resources.d.ts +2 -1
  196. package/dist/components/features/activities/partials/activity-marker.d.ts +7 -3
  197. package/dist/components/features/activities/partials/activity-row.d.ts +24 -0
  198. package/dist/components/features/ai-chat/hooks/use-ai-chat-scroll.d.ts +1 -1
  199. package/dist/components/features/appointment-calendar/appointment-calendar.d.ts +1 -1
  200. package/dist/components/features/appointment-calendar/appointment-calendar.types.d.ts +4 -2
  201. package/dist/components/features/combobox/async-resource-combobox.d.ts +2 -2
  202. package/dist/components/features/combobox/combobox.d.ts +2 -2
  203. package/dist/components/features/combobox/hooks/use-combobox-core.d.ts +2 -1
  204. package/dist/components/features/combobox/hooks/use-combobox-state.d.ts +1 -0
  205. package/dist/components/features/combobox/hooks/use-load-more.d.ts +1 -0
  206. package/dist/components/features/combobox/types.d.ts +37 -8
  207. package/dist/components/features/email-composer/types.d.ts +3 -1
  208. package/dist/components/features/event-calendar/colors.d.ts +2 -2
  209. package/dist/components/features/event-calendar/event-calendar.types.d.ts +4 -0
  210. package/dist/components/features/filters/facets/date-facet.d.ts +4 -2
  211. package/dist/components/features/filters/facets/range-facet.d.ts +12 -0
  212. package/dist/components/features/filters/facets/select-facet.d.ts +2 -1
  213. package/dist/components/features/filters/filters.strings.d.ts +4 -0
  214. package/dist/components/features/filters/filters.types.d.ts +6 -3
  215. package/dist/components/features/filters/partials/date-filter-content.d.ts +3 -2
  216. package/dist/components/features/filters/partials/filter-editor-header.d.ts +16 -0
  217. package/dist/components/features/filters/partials/filter-popover-content.d.ts +5 -3
  218. package/dist/components/features/filters/partials/nested-filter-options.d.ts +21 -0
  219. package/dist/components/features/filters/partials/range-filter-content.d.ts +12 -0
  220. package/dist/components/features/filters/partials/regular-filter-content.d.ts +2 -1
  221. package/dist/components/features/filters/utils/filter-utils.d.ts +25 -3
  222. package/dist/components/features/global-search/global-search.types.d.ts +2 -0
  223. package/dist/components/features/global-search/partials/global-search-input.d.ts +10 -0
  224. package/dist/components/features/global-search/partials/global-search-result-row.d.ts +7 -1
  225. package/dist/components/features/media-library/hooks/use-media-library.d.ts +1 -1
  226. package/dist/components/features/media-library/media-library.d.ts +1 -1
  227. package/dist/components/features/media-library/media-library.strings.d.ts +8 -0
  228. package/dist/components/features/media-library/media-library.types.d.ts +50 -12
  229. package/dist/components/features/media-library/partials/media-library-partials.d.ts +4 -4
  230. package/dist/components/features/mentions/hooks/use-mentions.d.ts +16 -1
  231. package/dist/components/features/mentions/partials/mention-inline-suggestions.d.ts +5 -1
  232. package/dist/components/features/mentions/utils/split-html-by-mentions.d.ts +1 -7
  233. package/dist/components/features/overlays/hooks/use-overlay-visibility.d.ts +2 -2
  234. package/dist/components/features/products/components/product-options-matrix.d.ts +1 -1
  235. package/dist/components/features/products/components/product-variant-editor.d.ts +1 -1
  236. package/dist/components/features/products/components/product-variants-manager.d.ts +1 -1
  237. package/dist/components/features/products/products.strings.d.ts +9 -1
  238. package/dist/components/features/products/products.types.d.ts +45 -8
  239. package/dist/components/features/questionnaire/questionnaire.types.d.ts +3 -0
  240. package/dist/components/features/resource/resource.d.ts +6 -2
  241. package/dist/components/features/resource/resource.types.d.ts +14 -1
  242. package/dist/components/features/rich-text-editor/form-rich-text-editor.d.ts +1 -1
  243. package/dist/components/features/rich-text-editor/partials/caret-helpers.d.ts +1 -1
  244. package/dist/components/features/rich-text-editor/partials/editor-field-aria.d.ts +14 -0
  245. package/dist/components/features/rich-text-editor/partials/image-uploads.d.ts +1 -1
  246. package/dist/components/features/rich-text-editor/partials/rich-text-editor-toolbar.d.ts +3 -1
  247. package/dist/components/features/rich-text-editor/rich-text-editor.recipes.d.ts +12 -2
  248. package/dist/components/features/rich-text-editor/rich-text-editor.types.d.ts +17 -3
  249. package/dist/components/features/schema-form/hooks/use-schema-form.d.ts +5 -1
  250. package/dist/components/features/schema-form/partials/schema-form-field.d.ts +3 -1
  251. package/dist/components/features/schema-form/schema-form.utils.d.ts +1 -1
  252. package/dist/components/features/suggestions/suggestions.types.d.ts +1 -1
  253. package/dist/components/features/table/data-table.d.ts +1 -1
  254. package/dist/components/features/table/index.d.ts +1 -0
  255. package/dist/components/features/table/partials/resource-cell.d.ts +22 -5
  256. package/dist/components/features/table/table-body.d.ts +1 -1
  257. package/dist/components/features/table/table-helpers.d.ts +6 -3
  258. package/dist/components/features/table/table.strings.d.ts +3 -0
  259. package/dist/components/features/table/table.types.d.ts +18 -2
  260. package/dist/components/layout/app-shell/app-shell.types.d.ts +35 -6
  261. package/dist/components/layout/app-shell/index.d.ts +1 -1
  262. package/dist/components/layout/app-shell/shell-regions.d.ts +27 -0
  263. package/dist/components/layout/app-shell/sidebar-inset-layout.d.ts +1 -1
  264. package/dist/components/layout/app-shell/stacked-layout.d.ts +1 -1
  265. package/dist/components/layout/app-shell/topbar-sidebar-layout.d.ts +1 -1
  266. package/dist/components/layout/containers/two-column-layout.d.ts +2 -0
  267. package/dist/components/layout/header/header.recipes.d.ts +6 -0
  268. package/dist/components/layout/header/header.types.d.ts +9 -8
  269. package/dist/components/layout/layout.types.d.ts +5 -3
  270. package/dist/components/layout/navigation/section-nav/section-nav.d.ts +5 -0
  271. package/dist/components/layout/navigation/side-nav.d.ts +3 -2
  272. package/dist/components/layout/normalize-layout-path.d.ts +1 -0
  273. package/dist/components/layout/page/index.d.ts +2 -1
  274. package/dist/components/layout/page/page.d.ts +1 -0
  275. package/dist/components/layout/page/page.strings.d.ts +11 -0
  276. package/dist/components/layout/page/page.types.d.ts +69 -17
  277. package/dist/components/layout/page/partials/page-header.d.ts +1 -1
  278. package/dist/components/layout/settings/settings.d.ts +10 -3
  279. package/dist/components/layout/sidebar/app-sidebar.d.ts +1 -1
  280. package/dist/components/layout/sidebar/components/sidebar-grouped-navigation.d.ts +1 -1
  281. package/dist/components/layout/sidebar/components/sidebar-navigation.d.ts +1 -1
  282. package/dist/components/layout/sidebar/index.d.ts +2 -1
  283. package/dist/components/layout/sidebar/sidebar-navigation-rail.d.ts +38 -0
  284. package/dist/components/layout/sidebar/sidebar.context.d.ts +6 -7
  285. package/dist/components/layout/sidebar/sidebar.types.d.ts +50 -10
  286. package/dist/components/layout/sidebar/sidebar.utils.d.ts +9 -1
  287. package/dist/components/layout/workspace/workspace.types.d.ts +8 -1
  288. package/dist/components/primitives/link.d.ts +3 -2
  289. package/dist/components/primitives/money.d.ts +1 -1
  290. package/dist/components/primitives/number.d.ts +1 -1
  291. package/dist/components/typography/rich-text/rich-text-tree.d.ts +7 -5
  292. package/dist/components/ui/alert-dialog.d.ts +2 -2
  293. package/dist/components/ui/combobox.d.ts +1 -1
  294. package/dist/components/ui/dialog.d.ts +2 -2
  295. package/dist/components/ui/overlay-layer.d.ts +18 -0
  296. package/dist/components/ui/sheet.d.ts +5 -1
  297. package/dist/components/ui/sidebar-state.d.ts +82 -0
  298. package/dist/components/ui/sidebar.d.ts +5 -17
  299. package/dist/{containers-CRmHf7GP.js → containers-CSdc32h9.js} +26 -18
  300. package/dist/containers-CSdc32h9.js.map +1 -0
  301. package/dist/{control-group-recipes-DBXmfh2E.js → control-group-recipes-fMuFo0H7.js} +6 -6
  302. package/dist/control-group-recipes-fMuFo0H7.js.map +1 -0
  303. package/dist/{copyable-CnGCZdX4.js → copyable-3fdHfMR3.js} +7 -7
  304. package/dist/{copyable-CnGCZdX4.js.map → copyable-3fdHfMR3.js.map} +1 -1
  305. package/dist/{data-display-D4oujtx0.js → data-display-Cmj-xZYl.js} +271 -279
  306. package/dist/data-display-Cmj-xZYl.js.map +1 -0
  307. package/dist/{date-Q7jnXxpk.js → date-Br0FicVv.js} +5 -5
  308. package/dist/{date-Q7jnXxpk.js.map → date-Br0FicVv.js.map} +1 -1
  309. package/dist/date-picker-CyQlFYsP.js +1617 -0
  310. package/dist/date-picker-CyQlFYsP.js.map +1 -0
  311. package/dist/date-pickers-tj2MXmXd.js +185 -0
  312. package/dist/date-pickers-tj2MXmXd.js.map +1 -0
  313. package/dist/{display-BB4BL_-K.js → display-CT_N2a3w.js} +9 -9
  314. package/dist/{display-BB4BL_-K.js.map → display-CT_N2a3w.js.map} +1 -1
  315. package/dist/dropdown-menu-C08iIugv.js +194 -0
  316. package/dist/dropdown-menu-C08iIugv.js.map +1 -0
  317. package/dist/features/activities.js +388 -326
  318. package/dist/features/activities.js.map +1 -1
  319. package/dist/features/ai-chat.js +46 -32
  320. package/dist/features/ai-chat.js.map +1 -1
  321. package/dist/features/appointment-calendar.js +130 -130
  322. package/dist/features/appointment-calendar.js.map +1 -1
  323. package/dist/features/async-preview.js +11 -10
  324. package/dist/features/async-preview.js.map +1 -1
  325. package/dist/features/combobox.js +1 -1
  326. package/dist/features/comments.js +1 -1
  327. package/dist/features/data-view.js +13 -13
  328. package/dist/features/data-view.js.map +1 -1
  329. package/dist/features/email-composer.js +243 -239
  330. package/dist/features/email-composer.js.map +1 -1
  331. package/dist/features/event-calendar.js +197 -199
  332. package/dist/features/event-calendar.js.map +1 -1
  333. package/dist/features/filters.js +2 -2
  334. package/dist/features/global-search.js +168 -143
  335. package/dist/features/global-search.js.map +1 -1
  336. package/dist/features/kanban.js +19 -30
  337. package/dist/features/kanban.js.map +1 -1
  338. package/dist/features/map/style.css +15 -0
  339. package/dist/features/map.js +369 -343
  340. package/dist/features/map.js.map +1 -1
  341. package/dist/features/media-library.js +1202 -975
  342. package/dist/features/media-library.js.map +1 -1
  343. package/dist/features/mentions.js +2 -2
  344. package/dist/features/overlays.js +1 -1
  345. package/dist/features/products.js +1270 -1183
  346. package/dist/features/products.js.map +1 -1
  347. package/dist/features/questionnaire.js +160 -153
  348. package/dist/features/questionnaire.js.map +1 -1
  349. package/dist/features/resource-assignment.js +8 -8
  350. package/dist/features/resource.js +119 -113
  351. package/dist/features/resource.js.map +1 -1
  352. package/dist/features/rich-text-editor.js +28 -19
  353. package/dist/features/rich-text-editor.js.map +1 -1
  354. package/dist/features/schema-form.js +297 -256
  355. package/dist/features/schema-form.js.map +1 -1
  356. package/dist/features/suggestions.js +57 -50
  357. package/dist/features/suggestions.js.map +1 -1
  358. package/dist/features/sync.js +3 -3
  359. package/dist/features/table.js +1 -1
  360. package/dist/features/theme-tweaker.js +470 -470
  361. package/dist/features/theme-tweaker.js.map +1 -1
  362. package/dist/feedback-Dzo1xtAU.js +246 -0
  363. package/dist/feedback-Dzo1xtAU.js.map +1 -0
  364. package/dist/{field-affordance-recipes-DjwGx8eM.js → field-affordance-recipes-D6H7tVJi.js} +5 -5
  365. package/dist/field-affordance-recipes-D6H7tVJi.js.map +1 -0
  366. package/dist/field-control-attributes-B6i335wr.js +18 -0
  367. package/dist/field-control-attributes-B6i335wr.js.map +1 -0
  368. package/dist/{field-state-recipes-BVA2CWHo.js → field-state-recipes-7sza8QbC.js} +4 -2
  369. package/dist/{field-state-recipes-BVA2CWHo.js.map → field-state-recipes-7sza8QbC.js.map} +1 -1
  370. package/dist/filters-Dl80yYtN.js +2415 -0
  371. package/dist/filters-Dl80yYtN.js.map +1 -0
  372. package/dist/form-field-CAPdwdnZ.js +74 -0
  373. package/dist/form-field-CAPdwdnZ.js.map +1 -0
  374. package/dist/{form-sizing-NXgjkmBG.js → form-sizing-CgcrUbLU.js} +5 -5
  375. package/dist/form-sizing-CgcrUbLU.js.map +1 -0
  376. package/dist/{forms-BV5m5aQF.js → forms-B3W8CH7-.js} +17 -13
  377. package/dist/forms-B3W8CH7-.js.map +1 -0
  378. package/dist/forms-numeric-CwjQJe-O.js +991 -0
  379. package/dist/forms-numeric-CwjQJe-O.js.map +1 -0
  380. package/dist/{header-BA697l4a.js → header-ZIIsRKxP.js} +145 -141
  381. package/dist/header-ZIIsRKxP.js.map +1 -0
  382. package/dist/header.recipes-BigdJjw1.js +6 -0
  383. package/dist/header.recipes-BigdJjw1.js.map +1 -0
  384. package/dist/hooks/use-files.d.ts +2 -0
  385. package/dist/{hooks-BQ-L7Uu2.js → hooks-BitHSh-Y.js} +27 -15
  386. package/dist/hooks-BitHSh-Y.js.map +1 -0
  387. package/dist/{icon-badge-COWbCCWu.js → icon-badge-npxF1SLX.js} +4 -4
  388. package/dist/{icon-badge-COWbCCWu.js.map → icon-badge-npxF1SLX.js.map} +1 -1
  389. package/dist/index.js +4 -5
  390. package/dist/{input-Cdw4k0fb.js → input-7KAc7XQL.js} +9 -9
  391. package/dist/{input-Cdw4k0fb.js.map → input-7KAc7XQL.js.map} +1 -1
  392. package/dist/input-DIREVYHs.js +21 -0
  393. package/dist/input-DIREVYHs.js.map +1 -0
  394. package/dist/{interaction-recipes-XR9ZpVYL.js → interaction-recipes-4wZ2tvfb.js} +2 -2
  395. package/dist/{interaction-recipes-XR9ZpVYL.js.map → interaction-recipes-4wZ2tvfb.js.map} +1 -1
  396. package/dist/item-FfWnaYST.js +278 -0
  397. package/dist/item-FfWnaYST.js.map +1 -0
  398. package/dist/layout/app-shell.js +1 -1
  399. package/dist/layout/auth.js +1 -1
  400. package/dist/layout/containers.js +1 -1
  401. package/dist/layout/header.js +1 -1
  402. package/dist/layout/hooks.js +1 -1
  403. package/dist/layout/navigation.js +1 -1
  404. package/dist/layout/page.js +2 -2
  405. package/dist/layout/settings.js +1 -1
  406. package/dist/layout/sidebar.js +3 -3
  407. package/dist/layout/workspace.js +1 -1
  408. package/dist/layout.js +12 -12
  409. package/dist/layout.types-E_GAApzO.js +30 -0
  410. package/dist/layout.types-E_GAApzO.js.map +1 -0
  411. package/dist/lib/affordance-geometry.generated.d.ts +35 -35
  412. package/dist/lib/control-group-recipes.d.ts +5 -5
  413. package/dist/lib/field-affordance-recipes.d.ts +2 -2
  414. package/dist/lib/field-control-attributes.d.ts +11 -0
  415. package/dist/lib/field-state-recipes.d.ts +2 -0
  416. package/dist/lib/format.d.ts +1 -0
  417. package/dist/lib/motion-recipes.d.ts +3 -0
  418. package/dist/lib/navigation-row-recipes.d.ts +7 -7
  419. package/dist/lib/overlay-anatomy-recipes.d.ts +3 -3
  420. package/dist/lib/portal-recipes.d.ts +3 -0
  421. package/dist/lib/surface-recipes.d.ts +1 -1
  422. package/dist/lib/token-merge.generated.d.ts +18 -15
  423. package/dist/lib/utils.js +1 -1
  424. package/dist/map-demo-tile.svg +1 -1
  425. package/dist/{media-gallery-CSl5W1Fy.js → media-gallery-C81DAnKI.js} +6 -6
  426. package/dist/{media-gallery-CSl5W1Fy.js.map → media-gallery-C81DAnKI.js.map} +1 -1
  427. package/dist/{mentions-RKOQaaIB.js → mentions-qOnedSt4.js} +237 -168
  428. package/dist/mentions-qOnedSt4.js.map +1 -0
  429. package/dist/message-BJHnn43M.js +135 -0
  430. package/dist/message-BJHnn43M.js.map +1 -0
  431. package/dist/{metadata-list-qVV7AVxa.js → metadata-list-XkqZ_UXH.js} +64 -64
  432. package/dist/metadata-list-XkqZ_UXH.js.map +1 -0
  433. package/dist/{motion-recipes-ChBg4HBq.js → motion-recipes-DitYv6P2.js} +10 -2
  434. package/dist/motion-recipes-DitYv6P2.js.map +1 -0
  435. package/dist/navigation-BgtPJAhi.js +288 -0
  436. package/dist/navigation-BgtPJAhi.js.map +1 -0
  437. package/dist/navigation-Bt-v7rWP.js +261 -0
  438. package/dist/navigation-Bt-v7rWP.js.map +1 -0
  439. package/dist/{navigation-row-recipes-WZEs-hYo.js → navigation-row-recipes-BGVLvU_O.js} +9 -9
  440. package/dist/navigation-row-recipes-BGVLvU_O.js.map +1 -0
  441. package/dist/normalize-layout-path-BmEgg6fu.js +14 -0
  442. package/dist/normalize-layout-path-BmEgg6fu.js.map +1 -0
  443. package/dist/{number-E_OiIfJz.js → number-CYqBcrSj.js} +79 -87
  444. package/dist/number-CYqBcrSj.js.map +1 -0
  445. package/dist/overflow-tab-bar-BQCA2Zn2.js +172 -0
  446. package/dist/overflow-tab-bar-BQCA2Zn2.js.map +1 -0
  447. package/dist/overlays-CC8zI3Du.js +1017 -0
  448. package/dist/overlays-CC8zI3Du.js.map +1 -0
  449. package/dist/page-BoQ1VaFJ.js +331 -0
  450. package/dist/page-BoQ1VaFJ.js.map +1 -0
  451. package/dist/page-header-commands-DIKspJfx.js +193 -0
  452. package/dist/page-header-commands-DIKspJfx.js.map +1 -0
  453. package/dist/{pagination-Ch8X_47u.js → pagination-Br8TdV9A.js} +7 -7
  454. package/dist/{pagination-Ch8X_47u.js.map → pagination-Br8TdV9A.js.map} +1 -1
  455. package/dist/popover-k8TdUcAt.js +201 -0
  456. package/dist/popover-k8TdUcAt.js.map +1 -0
  457. package/dist/{popover-menu-BYaCdFhf.js → popover-menu-yn-o0kyA.js} +7 -7
  458. package/dist/{popover-menu-BYaCdFhf.js.map → popover-menu-yn-o0kyA.js.map} +1 -1
  459. package/dist/{popover.recipes-D3j8R8Yp.js → popover.recipes-DJ0AkUan.js} +19 -12
  460. package/dist/popover.recipes-DJ0AkUan.js.map +1 -0
  461. package/dist/portal-recipes-DyUXqUtD.js +9 -0
  462. package/dist/portal-recipes-DyUXqUtD.js.map +1 -0
  463. package/dist/{primitives-Du64iDbb.js → primitives-BkkQjYl7.js} +23 -18
  464. package/dist/primitives-BkkQjYl7.js.map +1 -0
  465. package/dist/primitives.js +4 -4
  466. package/dist/{progress-BvF2oCdV.js → progress-DZFXXzPs.js} +9 -9
  467. package/dist/{progress-BvF2oCdV.js.map → progress-DZFXXzPs.js.map} +1 -1
  468. package/dist/{receipt-D789Jwyy.js → receipt-C7LhOg7Q.js} +7 -7
  469. package/dist/receipt-C7LhOg7Q.js.map +1 -0
  470. package/dist/rich-text-BnTzZjIo.js +45 -0
  471. package/dist/rich-text-BnTzZjIo.js.map +1 -0
  472. package/dist/{rich-text-editor-Cm1dpUpQ.js → rich-text-editor-CAurDwT5.js} +501 -424
  473. package/dist/rich-text-editor-CAurDwT5.js.map +1 -0
  474. package/dist/rich-text-editor-toolbar-DbXig7Jk.js +99 -0
  475. package/dist/rich-text-editor-toolbar-DbXig7Jk.js.map +1 -0
  476. package/dist/rich-text-tree-BqyQ_7-R.js +66 -0
  477. package/dist/rich-text-tree-BqyQ_7-R.js.map +1 -0
  478. package/dist/{sanitize-html-DsQmI48u.js → sanitize-html-BWkH4dLM.js} +29 -16
  479. package/dist/sanitize-html-BWkH4dLM.js.map +1 -0
  480. package/dist/{scroll-area-La5RXsEk.js → scroll-area-Bj6CRUif.js} +2 -2
  481. package/dist/{scroll-area-La5RXsEk.js.map → scroll-area-Bj6CRUif.js.map} +1 -1
  482. package/dist/{separator-DAEV0w65.js → separator-B9ewiCGO.js} +2 -2
  483. package/dist/{separator-DAEV0w65.js.map → separator-B9ewiCGO.js.map} +1 -1
  484. package/dist/{separator-GNfPG-90.js → separator-DM6gs2vu.js} +3 -3
  485. package/dist/{separator-GNfPG-90.js.map → separator-DM6gs2vu.js.map} +1 -1
  486. package/dist/services/actions.js +1 -1
  487. package/dist/settings-DZPHgpx4.js +155 -0
  488. package/dist/settings-DZPHgpx4.js.map +1 -0
  489. package/dist/sheet-C4DHsgLk.js +250 -0
  490. package/dist/sheet-C4DHsgLk.js.map +1 -0
  491. package/dist/sidebar-C8BnDwTH.js +709 -0
  492. package/dist/sidebar-C8BnDwTH.js.map +1 -0
  493. package/dist/sidebar-CmD6a-HK.js +1004 -0
  494. package/dist/sidebar-CmD6a-HK.js.map +1 -0
  495. package/dist/skeleton-DDgdhmu9.js +265 -0
  496. package/dist/skeleton-DDgdhmu9.js.map +1 -0
  497. package/dist/smart-card-B6vLxqa_.js +617 -0
  498. package/dist/smart-card-B6vLxqa_.js.map +1 -0
  499. package/dist/{structure-C0V0_Fyf.js → structure-DZJ2wbAU.js} +2 -2
  500. package/dist/{structure-C0V0_Fyf.js.map → structure-DZJ2wbAU.js.map} +1 -1
  501. package/dist/style.css +1 -1
  502. package/dist/{surface-recipes-BKRVW8Os.js → surface-recipes-C8mNycaY.js} +2 -2
  503. package/dist/{surface-recipes-BKRVW8Os.js.map → surface-recipes-C8mNycaY.js.map} +1 -1
  504. package/dist/{table-DH7rozUv.js → table-CBonSdTp.js} +573 -519
  505. package/dist/table-CBonSdTp.js.map +1 -0
  506. package/dist/{table-CpvnzJn9.js → table-CXSPHH25.js} +75 -71
  507. package/dist/table-CXSPHH25.js.map +1 -0
  508. package/dist/tabs-C4Kr_hCr.js +192 -0
  509. package/dist/tabs-C4Kr_hCr.js.map +1 -0
  510. package/dist/{text-inputs-DXItiR0O.js → text-inputs-jdkS3ReG.js} +18 -18
  511. package/dist/text-inputs-jdkS3ReG.js.map +1 -0
  512. package/dist/theme.css +40 -37
  513. package/dist/{timelines-DmtztAY_.js → timelines-CoPwdJP0.js} +13 -12
  514. package/dist/timelines-CoPwdJP0.js.map +1 -0
  515. package/dist/tooltip-31NwIpTo.js +113 -0
  516. package/dist/tooltip-31NwIpTo.js.map +1 -0
  517. package/dist/{tree-CV11PURP.js → tree-CeYVzdFE.js} +9 -9
  518. package/dist/{tree-CV11PURP.js.map → tree-CeYVzdFE.js.map} +1 -1
  519. package/dist/typography/rich-text.js +1 -1
  520. package/dist/{typography-CSyJrh28.js → typography-C7-YMW1S.js} +12 -12
  521. package/dist/{typography-CSyJrh28.js.map → typography-C7-YMW1S.js.map} +1 -1
  522. package/dist/typography.js +1 -1
  523. package/dist/ui-provider-C-74NVLc.js +178 -0
  524. package/dist/ui-provider-C-74NVLc.js.map +1 -0
  525. package/dist/ui-provider.js +2 -3
  526. package/dist/{upload-C9SA0X-8.js → upload-Hdm5gObf.js} +309 -296
  527. package/dist/upload-Hdm5gObf.js.map +1 -0
  528. package/dist/{upload-queue-DhQJiSRc.js → upload-queue-D0sYPuqo.js} +16 -14
  529. package/dist/upload-queue-D0sYPuqo.js.map +1 -0
  530. package/dist/{usage-card-DVTRDmGz.js → usage-card-9s8hLDfn.js} +24 -17
  531. package/dist/usage-card-9s8hLDfn.js.map +1 -0
  532. package/dist/{utils-CF3c95Io.js → utils-DhuoqFy4.js} +255 -165
  533. package/dist/utils-DhuoqFy4.js.map +1 -0
  534. package/dist/value-inputs-D3aPgq9H.js +980 -0
  535. package/dist/value-inputs-D3aPgq9H.js.map +1 -0
  536. package/dist/{value-typography-ClupF0Gz.js → value-typography-uSzzG9Gf.js} +32 -26
  537. package/dist/value-typography-uSzzG9Gf.js.map +1 -0
  538. package/dist/{workspace-9EFVXUyk.js → workspace-CC8Vchiu.js} +51 -50
  539. package/dist/workspace-CC8Vchiu.js.map +1 -0
  540. package/docs/consumer-skill/SKILL.md +4 -3
  541. package/docs/consumer-skill/agents/themelia-ui-designer.md +96 -0
  542. package/docs/consumer-skill/examples/app-layout.tsx +52 -1
  543. package/docs/consumer-skill/examples/commerce-lines.tsx +271 -0
  544. package/docs/consumer-skill/examples/custom-composition.tsx +21 -0
  545. package/docs/consumer-skill/examples/detail.tsx +5 -4
  546. package/docs/consumer-skill/examples/edit.tsx +3 -3
  547. package/docs/consumer-skill/examples/editable-sections.tsx +38 -0
  548. package/docs/consumer-skill/examples/index-table.tsx +4 -4
  549. package/docs/consumer-skill/examples/manifest.json +38 -1
  550. package/docs/consumer-skill/examples/product-media.tsx +41 -0
  551. package/docs/consumer-skill/examples/product-parts.tsx +81 -0
  552. package/docs/consumer-skill/examples/rhf-edit-page.tsx +1 -1
  553. package/docs/consumer-skill/examples/rhf-overlay-form.tsx +24 -11
  554. package/docs/consumer-skill/examples/token-domain-structure.tsx +68 -0
  555. package/docs/consumer-skill/references/agents-md.md +21 -19
  556. package/docs/consumer-skill/references/analytics.md +33 -1
  557. package/docs/consumer-skill/references/commerce-composition.md +97 -0
  558. package/docs/consumer-skill/references/component-contracts.json +21249 -14205
  559. package/docs/consumer-skill/references/composition-mapping.md +17 -3
  560. package/docs/consumer-skill/references/composition.md +177 -32
  561. package/docs/consumer-skill/references/critique-rubric.md +98 -0
  562. package/docs/consumer-skill/references/custom-composition.md +261 -0
  563. package/docs/consumer-skill/references/data-reading.md +79 -0
  564. package/docs/consumer-skill/references/design-contract.md +12 -9
  565. package/docs/consumer-skill/references/discovery.md +27 -3
  566. package/docs/consumer-skill/references/domain-structures.md +124 -0
  567. package/docs/consumer-skill/references/installation.md +62 -8
  568. package/docs/consumer-skill/references/integration.md +59 -1
  569. package/docs/consumer-skill/references/product-composition.md +94 -0
  570. package/docs/consumer-skill/references/public-api.json +3044 -445
  571. package/docs/consumer-skill/references/review.md +87 -10
  572. package/docs/consumer-skill/references/rhf-workflows.md +79 -0
  573. package/docs/consumer-skill/references/screen-archetypes.md +19 -7
  574. package/docs/consumer-skill/references/screen-decisions.md +126 -0
  575. package/docs/consumer-skill/references/theming.md +24 -20
  576. package/docs/consumer-skill/references/tokens.json +9 -9
  577. package/docs/consumer-skill/references/view-craft.md +153 -0
  578. package/docs/consumer-skill/references/view-spec.md +73 -0
  579. package/docs/consumer-skill/references/workflows.md +7 -1
  580. package/docs/consumer-skill/scripts/composition-policy.mjs +176 -26
  581. package/docs/consumer-skill/scripts/composition-schema.mjs +1 -1
  582. package/docs/consumer-skill/scripts/composition.mjs +61 -5
  583. package/docs/consumer-skill/scripts/discovery.mjs +54 -0
  584. package/docs/consumer-skill/scripts/inspect-component.mjs +1 -1
  585. package/docs/consumer-skill/scripts/inspection.mjs +73 -18
  586. package/docs/consumer-skill/scripts/setup-skills.mjs +79 -7
  587. package/docs/consumer-skill/scripts/surface-policy.mjs +5 -5
  588. package/docs/consumer-skills/themelia-components/SKILL.md +14 -13
  589. package/docs/consumer-skills/themelia-composition/SKILL.md +16 -17
  590. package/docs/consumer-skills/themelia-design/SKILL.md +55 -0
  591. package/docs/consumer-skills/themelia-foundation/SKILL.md +2 -1
  592. package/docs/consumer-skills/themelia-tokenization/SKILL.md +24 -17
  593. package/package.json +4 -2
  594. package/templates/admin-shell-template.tsx +1 -2
  595. package/templates/customers-template.tsx +18 -16
  596. package/dist/accordion-96o0pN62.js.map +0 -1
  597. package/dist/action-menu-CHgs8vmj.js.map +0 -1
  598. package/dist/affordance-geometry.generated-B8yGOr8-.js.map +0 -1
  599. package/dist/ai-artifact-BZUGwBq6.js.map +0 -1
  600. package/dist/app-shell-D63ATkIK.js +0 -237
  601. package/dist/app-shell-D63ATkIK.js.map +0 -1
  602. package/dist/auth-D2FVZ1MH.js.map +0 -1
  603. package/dist/avatar-DWO_HHhB.js.map +0 -1
  604. package/dist/base/cascader.js.map +0 -1
  605. package/dist/batch-action-bar-CdfIkCsV.js.map +0 -1
  606. package/dist/breadcrumbs-B-WFKecD.js.map +0 -1
  607. package/dist/button-DkmK-z8E.js.map +0 -1
  608. package/dist/buttons-BbfzgczK.js.map +0 -1
  609. package/dist/cards-4JTWqvVe.js +0 -68
  610. package/dist/cards-4JTWqvVe.js.map +0 -1
  611. package/dist/chart-C19flDQb.js +0 -155
  612. package/dist/chart-C19flDQb.js.map +0 -1
  613. package/dist/choice-inputs-JLtij2y4.js +0 -776
  614. package/dist/choice-inputs-JLtij2y4.js.map +0 -1
  615. package/dist/code-block-CGNaUtAE.js.map +0 -1
  616. package/dist/combobox-CBJDs6w_.js +0 -877
  617. package/dist/combobox-CBJDs6w_.js.map +0 -1
  618. package/dist/combobox-hbhSS18O.js +0 -355
  619. package/dist/combobox-hbhSS18O.js.map +0 -1
  620. package/dist/command-D8NrBj-b.js.map +0 -1
  621. package/dist/comments-Di4w0H_S.js.map +0 -1
  622. package/dist/containers-CRmHf7GP.js.map +0 -1
  623. package/dist/control-group-recipes-DBXmfh2E.js.map +0 -1
  624. package/dist/data-display-D4oujtx0.js.map +0 -1
  625. package/dist/date-picker-zOt1oNss.js +0 -1542
  626. package/dist/date-picker-zOt1oNss.js.map +0 -1
  627. package/dist/date-pickers-cj8IXbDC.js +0 -179
  628. package/dist/date-pickers-cj8IXbDC.js.map +0 -1
  629. package/dist/dropdown-menu-CjY8Vt7W.js +0 -193
  630. package/dist/dropdown-menu-CjY8Vt7W.js.map +0 -1
  631. package/dist/feedback-DZNL5Lg1.js +0 -239
  632. package/dist/feedback-DZNL5Lg1.js.map +0 -1
  633. package/dist/field-affordance-recipes-DjwGx8eM.js.map +0 -1
  634. package/dist/filters-BcT-uoFy.js +0 -2209
  635. package/dist/filters-BcT-uoFy.js.map +0 -1
  636. package/dist/form-field-CsgRmdit.js +0 -63
  637. package/dist/form-field-CsgRmdit.js.map +0 -1
  638. package/dist/form-sizing-NXgjkmBG.js.map +0 -1
  639. package/dist/forms-BV5m5aQF.js.map +0 -1
  640. package/dist/forms-numeric-Cd33AKbD.js +0 -906
  641. package/dist/forms-numeric-Cd33AKbD.js.map +0 -1
  642. package/dist/header-BA697l4a.js.map +0 -1
  643. package/dist/hooks-BQ-L7Uu2.js.map +0 -1
  644. package/dist/input-DOPL5_QE.js +0 -21
  645. package/dist/input-DOPL5_QE.js.map +0 -1
  646. package/dist/item-BvZ2DR_x.js +0 -277
  647. package/dist/item-BvZ2DR_x.js.map +0 -1
  648. package/dist/layout.types-Cn7aUzJp.js +0 -20
  649. package/dist/layout.types-Cn7aUzJp.js.map +0 -1
  650. package/dist/mentions-RKOQaaIB.js.map +0 -1
  651. package/dist/message-INU2xsxu.js +0 -128
  652. package/dist/message-INU2xsxu.js.map +0 -1
  653. package/dist/metadata-list-qVV7AVxa.js.map +0 -1
  654. package/dist/motion-recipes-ChBg4HBq.js.map +0 -1
  655. package/dist/navigation-BQNcg1jT.js +0 -269
  656. package/dist/navigation-BQNcg1jT.js.map +0 -1
  657. package/dist/navigation-DLF3E1IC.js +0 -145
  658. package/dist/navigation-DLF3E1IC.js.map +0 -1
  659. package/dist/navigation-row-recipes-WZEs-hYo.js.map +0 -1
  660. package/dist/number-E_OiIfJz.js.map +0 -1
  661. package/dist/overflow-tab-bar-CrbqMteP.js +0 -284
  662. package/dist/overflow-tab-bar-CrbqMteP.js.map +0 -1
  663. package/dist/overlays-BlKynmde.js +0 -1004
  664. package/dist/overlays-BlKynmde.js.map +0 -1
  665. package/dist/page-CIwNUtGr.js +0 -227
  666. package/dist/page-CIwNUtGr.js.map +0 -1
  667. package/dist/page-header-commands-DFMlNYzN.js +0 -128
  668. package/dist/page-header-commands-DFMlNYzN.js.map +0 -1
  669. package/dist/popover-uwzX2vo7.js +0 -198
  670. package/dist/popover-uwzX2vo7.js.map +0 -1
  671. package/dist/popover.recipes-D3j8R8Yp.js.map +0 -1
  672. package/dist/primitives-Du64iDbb.js.map +0 -1
  673. package/dist/receipt-D789Jwyy.js.map +0 -1
  674. package/dist/rich-text-CLJEf76s.js +0 -78
  675. package/dist/rich-text-CLJEf76s.js.map +0 -1
  676. package/dist/rich-text-editor-Cm1dpUpQ.js.map +0 -1
  677. package/dist/rich-text-editor-toolbar-L__e4x47.js +0 -94
  678. package/dist/rich-text-editor-toolbar-L__e4x47.js.map +0 -1
  679. package/dist/safe-image-src-C6kQSMBZ.js +0 -17
  680. package/dist/safe-image-src-C6kQSMBZ.js.map +0 -1
  681. package/dist/sanitize-html-DsQmI48u.js.map +0 -1
  682. package/dist/settings-BA2iboic.js +0 -174
  683. package/dist/settings-BA2iboic.js.map +0 -1
  684. package/dist/sheet-DoAxTb2J.js +0 -213
  685. package/dist/sheet-DoAxTb2J.js.map +0 -1
  686. package/dist/sidebar-ByqKR_W5.js +0 -512
  687. package/dist/sidebar-ByqKR_W5.js.map +0 -1
  688. package/dist/sidebar-D2iSnGJ7.js +0 -619
  689. package/dist/sidebar-D2iSnGJ7.js.map +0 -1
  690. package/dist/skeleton-CUj8O5Bd.js +0 -264
  691. package/dist/skeleton-CUj8O5Bd.js.map +0 -1
  692. package/dist/smart-card-CqkzQsK-.js +0 -614
  693. package/dist/smart-card-CqkzQsK-.js.map +0 -1
  694. package/dist/table-CpvnzJn9.js.map +0 -1
  695. package/dist/table-DH7rozUv.js.map +0 -1
  696. package/dist/tabs-eqVsJZWO.js +0 -191
  697. package/dist/tabs-eqVsJZWO.js.map +0 -1
  698. package/dist/text-inputs-DXItiR0O.js.map +0 -1
  699. package/dist/theme-scope-BJ6eE2xt.js +0 -50
  700. package/dist/theme-scope-BJ6eE2xt.js.map +0 -1
  701. package/dist/timelines-DmtztAY_.js.map +0 -1
  702. package/dist/tooltip-B4hjKtoV.js +0 -111
  703. package/dist/tooltip-B4hjKtoV.js.map +0 -1
  704. package/dist/ui-provider-CQCuCBcy.js +0 -136
  705. package/dist/ui-provider-CQCuCBcy.js.map +0 -1
  706. package/dist/upload-C9SA0X-8.js.map +0 -1
  707. package/dist/upload-queue-DhQJiSRc.js.map +0 -1
  708. package/dist/usage-card-DVTRDmGz.js.map +0 -1
  709. package/dist/use-mobile-vaLKwgyf.js +0 -15
  710. package/dist/use-mobile-vaLKwgyf.js.map +0 -1
  711. package/dist/utils-CF3c95Io.js.map +0 -1
  712. package/dist/value-inputs-C0o70p-U.js +0 -980
  713. package/dist/value-inputs-C0o70p-U.js.map +0 -1
  714. package/dist/value-typography-ClupF0Gz.js.map +0 -1
  715. package/dist/workspace-9EFVXUyk.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"rich-text-CLJEf76s.js","names":["useTypographyConfig","resolveTextClassNames","safeImageSrc","sanitizeHtmlTree","sanitizeHtml","contentTypographyClassName","VOID_ELEMENTS","toNumber","number","value","toReactProps","props","name","element","letter","renderNode","node","src","image","Fragment","renderImage","key","createElement","child","index","renderRichTextTree","tree","RichText","forwardRef","sizeProp","Tag","size","defaultTextSize","allowImages","images","sanitizedHtml","useMemo","html","classNames","cn"],"sources":["../src/components/typography/rich-text/rich-text-tree.tsx","../src/components/typography/rich-text/rich-text.tsx"],"sourcesContent":["import { createElement, Fragment, type ReactNode } from 'react';\nimport type { Element, Root, RootContent } from 'hast';\n\nimport { safeImageSrc } from '../../../lib/safe-image-src';\n\n/** An image in sanitized rich text, as handed to `renderImage`. */\nexport interface RichTextImageAttributes {\n\t/** Source that passed the package image policy (http, https, blob or relative). */\n\tsrc: string;\n\t/** Text alternative; empty for a decorative image. */\n\talt: string;\n\ttitle?: string;\n\twidth?: number;\n\theight?: number;\n}\n\nexport type RenderRichTextImage = (image: RichTextImageAttributes) => ReactNode;\n\nconst VOID_ELEMENTS = new Set(['br', 'img']);\n\nfunction toNumber(value: unknown): number | undefined {\n\tconst number = typeof value === 'number' ? value : Number(value);\n\treturn Number.isFinite(number) && number > 0 ? number : undefined;\n}\n\n/** hast properties are camelCase (`dataRefId`); the DOM attribute is `data-ref-id`. */\nfunction toReactProps(element: Element, key: number) {\n\tconst props: Record<string, unknown> = { key };\n\tfor (const [name, value] of Object.entries(element.properties)) {\n\t\tif (value == null || value === false) continue;\n\t\tif (name === 'className') props.className = Array.isArray(value) ? value.join(' ') : String(value);\n\t\telse if (/^data[A-Z]/.test(name)) props[name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)] = String(value);\n\t\telse props[name] = Array.isArray(value) ? value.join(' ') : value;\n\t}\n\treturn props;\n}\n\nfunction renderNode(node: RootContent, key: number, renderImage: RenderRichTextImage): ReactNode {\n\tif (node.type === 'text') return node.value;\n\tif (node.type !== 'element') return null;\n\tif (node.tagName === 'img') {\n\t\tconst src = safeImageSrc(node.properties.src);\n\t\tif (!src) return null;\n\t\tconst image: RichTextImageAttributes = {\n\t\t\tsrc,\n\t\t\talt: typeof node.properties.alt === 'string' ? node.properties.alt : '',\n\t\t\ttitle: typeof node.properties.title === 'string' ? node.properties.title : undefined,\n\t\t\twidth: toNumber(node.properties.width),\n\t\t\theight: toNumber(node.properties.height),\n\t\t};\n\t\treturn <Fragment key={key}>{renderImage(image)}</Fragment>;\n\t}\n\tconst props = toReactProps(node, key);\n\tif (VOID_ELEMENTS.has(node.tagName)) return createElement(node.tagName, props);\n\treturn createElement(node.tagName, props, ...node.children.map((child, index) => renderNode(child, index, renderImage)));\n}\n\n/**\n * Renders an already sanitized tree as React elements, so each image can be\n * the consumer's own component (a framework image, a lightbox trigger) while\n * the surrounding markup keeps its structure. Server and client output match.\n */\nexport function renderRichTextTree(tree: Root, renderImage: RenderRichTextImage): ReactNode {\n\treturn tree.children.map((child, index) => renderNode(child, index, renderImage));\n}\n","import { forwardRef, useMemo } from 'react';\n\nimport { sanitizeHtml, sanitizeHtmlTree } from '../../../lib/sanitize-html';\nimport { useTypographyConfig } from '../../../lib/ui-provider';\nimport { cn } from '../../../lib/utils';\nimport { contentTypographyClassName } from '../content-typography';\n\nimport type { TextProps } from '../text';\nimport { resolveTextClassNames } from '../text.styles';\nimport { renderRichTextTree, type RenderRichTextImage } from './rich-text-tree';\n\nexport type { RenderRichTextImage, RichTextImageAttributes } from './rich-text-tree';\n\n/** Image rendering for read-only rich text. */\nexport interface RichTextImageRendering {\n\t/**\n\t * Renders each image, for example with a framework image component. It\n\t * receives only sources that passed the package image policy.\n\t */\n\trenderImage?: RenderRichTextImage;\n}\n\nexport interface RichTextProps\n\textends Omit<\n\t\tTextProps,\n\t\t'children' | 'content' | 'dangerouslySetInnerHTML'\n\t> {\n\t/** HTML sanitized through the package allowlist before rendering. */\n\thtml?: string | null;\n\t/**\n\t * Keeps images whose source is a web URL, a `blob:` preview or a relative\n\t * path (script and `data:` sources are removed). Pass `renderImage` to draw\n\t * each image with your own component. Default: images are removed.\n\t */\n\timages?: boolean | RichTextImageRendering;\n}\n\nexport const RichText = forwardRef<HTMLElement, RichTextProps>(\n\tfunction RichText(\n\t\t{\n\t\t\thtml,\n\t\t\ttype = 'main',\n\t\t\tsize: sizeProp,\n\t\t\talign = 'left',\n\t\t\tlineHeight = 'normal',\n\t\t\tweight = 'regular',\n\t\t\tclassName,\n\t\t\tnumeric = false,\n\t\t\ttag: Tag = 'p',\n\t\t\timages = false,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) {\n\t\tconst { defaultTextSize } = useTypographyConfig();\n\t\tconst size = sizeProp ?? defaultTextSize ?? 'sm';\n\t\tconst allowImages = Boolean(images);\n\t\tconst renderImage = typeof images === 'object' ? images.renderImage : undefined;\n\t\tconst sanitizedHtml = useMemo(() => sanitizeHtml(html ?? '', { images: allowImages }), [allowImages, html]);\n\t\t// Consumer image components need React elements; plain images keep the HTML path.\n\t\tconst tree = useMemo(\n\t\t\t() => (renderImage && sanitizedHtml ? renderRichTextTree(sanitizeHtmlTree(html ?? '', { images: true }), renderImage) : null),\n\t\t\t[html, renderImage, sanitizedHtml],\n\t\t);\n\n\t\tif (!sanitizedHtml) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst classNames = cn(contentTypographyClassName, resolveTextClassNames({\n\t\t\ttype,\n\t\t\tsize,\n\t\t\talign,\n\t\t\tlineHeight,\n\t\t\tweight,\n\t\t\tnumeric,\n\t\t\tclassName,\n\t\t}));\n\n\t\tif (tree) {\n\t\t\treturn (\n\t\t\t\t<Tag ref={ref as never} className={classNames} data-typography=\"rich-text\" {...props}>\n\t\t\t\t\t{tree}\n\t\t\t\t</Tag>\n\t\t\t);\n\t\t}\n\n\t\treturn (\n\t\t\t<Tag\n\t\t\t\tref={ref as never}\n\t\t\t\tclassName={classNames}\n\t\t\t\tdata-typography=\"rich-text\"\n\t\t\t\tdangerouslySetInnerHTML={{ __html: sanitizedHtml }}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\n\nRichText.displayName = 'RichText';\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"rich-text-editor-Cm1dpUpQ.js","names":["NumberValue","_Fragment","_Fragment","EditorContent","StarterKit","cn","Button","Text","Stack","safeImageSrc","editableContentClassName","SecondaryValue","Number$1","Input","FormField","richTextEditorRecipes","RichTextEditorToolbar","defaultRichTextEditorStrings","Fragment$1","TiptapReact","StarterKitModule","readCaretContext","sel","range","startNode","startOffset","block","editable","text","cursor","prev","rect","r","replaceBeforeCaret","editor","selection","from","length","html","notifyChange","caret","remaining","take","previousTextNode","fragment","insertHtmlIntoEditable","current","node","CountsFooterText","chars","words","overLimit","maxLength","className","strings","CountsFooter","sourceMode","sourceValue","normalizeHtml","trimmed","value","toEditorContent","normalized","inlineReferenceChipClassName","NODE_NAME","deleteAdjacentReference","state","direction","$from","tr","inlineReferenceNode","getInlineReferenceNode","element","attributes","HTMLAttributes","dom","UPLOAD_ATTRIBUTE","UPLOAD_PLACEHOLDER_CLASS","PLACEHOLDER_PATTERN","stripUploadPlaceholders","acceptsImageFile","type","file","name","accept","entry","altFromFileName","imageFilesFrom","data","uploadSequence","useImageUploadQueue","uploads","setUploads","useState","notice","setNotice","jobs","useRef","job","forget","useCallback","id","upload","run","images","controller","pending","result","src","placed","adapterRef","error","refused","files","reason","message","interpolateString","ImageUploadStatus","failed","AlertCircle","Loader2","onRetry","onRemove","ImageUploadPortals","queue","target","createPortal","useImageInsertControl","inputRef","beforeOpenRef","beforeOpen","enabled","useMemo","ImagePlus","event","onFiles","ImageDetailsBar","inputId","useId","alt","onDismissNotice","onAltChange","positiveNumber","number","imageNode","imageUploadNode","getImageNode","getImageUploadNode","valueHtml","EditorContent$1","useTiptapEditor","StarterKit$1","TiptapRichTextEditor","forwardRef","stringsProp","useStrings","imagesEnabled","queueRef","editorInstanceRef","isFocused","setIsFocused","setSourceMode","setSourceValue","isFocusedRef","externalValueRef","onCaretChangeRef","onCaretChange","disabled","autoFocus","currentEditor","onValueChange","imagesRef","moved","at","view","useEffect","next","handler","useImperativeHandle","ref","emitValue","findNode","found","match","created","image","uploadQueue","imageInsert","toolbarItems","extraToolbarItems","activeImage","setActiveImage","sync","nodeBefore","nodeAfter","bodyMinHeightClassName","bodyHeight","compact","contentStyle","minHeight","maxHeight","toggleSourceMode","handleSourceChange","toolbarButtons","Bold","Italic","Strikethrough","List","ListOrdered","Quote","Undo2","Redo2","countsFooter","showCounts","placeholderText","placeholder","placeholderNode","footerSlot","hasTiptapRuntime","serializeEditable","copy","removeUnsafeImages","imageAtSelection","startContainer","placeCaretAtPoint","doc","x","y","position","FallbackRichTextEditor","editableRef","savedRangeRef","activeAlt","setActiveAlt","setEditableRef","emitEditableChange","saved","syncActiveImage","handleInput","isEmpty","RichTextEditor","props"],"sources":["../src/components/features/rich-text-editor/partials/caret-helpers.ts","../src/components/features/rich-text-editor/partials/counts-footer.tsx","../src/components/features/rich-text-editor/partials/html-helpers.ts","../src/components/features/rich-text-editor/partials/inline-reference-node.ts","../src/components/features/rich-text-editor/partials/image-uploads.tsx","../src/components/features/rich-text-editor/partials/image-nodes.ts","../src/components/features/rich-text-editor/partials/rich-text-editor-tiptap.tsx","../src/components/features/rich-text-editor/partials/rich-text-editor-fallback.tsx","../src/components/features/rich-text-editor/rich-text-editor.tsx"],"sourcesContent":["/**\n * Caret-introspection helpers used by `<RichTextEditor>` to expose the\n * text before the caret and replace a leading run of characters with\n * inline HTML — the building blocks for `@`-mention chips and similar\n * inline triggers.\n */\nimport type { RichTextCaretContext, TiptapEditor } from '../rich-text-editor.types';\n\n/**\n * Read the current selection's caret context.\n *\n * Walks back from the caret through the current text node and any\n * preceding sibling text nodes inside the same block-level container\n * (paragraph / list-item / heading) collecting plain text. Returns the\n * accumulated text plus the caret's bounding rect when available.\n *\n * Returns `null` when there is no live selection or the selection isn't\n * a text caret inside a contenteditable.\n */\nexport function readCaretContext(): RichTextCaretContext | null {\n\tif (typeof window === 'undefined') return null;\n\tconst sel = window.getSelection();\n\tif (!sel || sel.rangeCount === 0) return null;\n\tconst range = sel.getRangeAt(0);\n\tif (!range.collapsed) return null;\n\n\tconst startNode = range.startContainer;\n\tconst startOffset = range.startOffset;\n\n\tlet block: Node | null = startNode;\n\twhile (block && block.nodeType !== Node.ELEMENT_NODE) {\n\t\tblock = block.parentNode;\n\t}\n\tif (!block) return null;\n\tconst editable =\n\t\t(block as Element).closest('[contenteditable=\"true\"]') ??\n\t\t(block as Element).closest('.ProseMirror');\n\tif (!editable) return null;\n\n\tlet text = '';\n\tif (startNode.nodeType === Node.TEXT_NODE) {\n\t\ttext = (startNode.textContent ?? '').slice(0, startOffset);\n\t}\n\n\tlet cursor: Node | null = startNode;\n\twhile (cursor && cursor !== editable && cursor !== block) {\n\t\tlet prev: Node | null = cursor.previousSibling;\n\t\twhile (prev) {\n\t\t\ttext = (prev.textContent ?? '') + text;\n\t\t\tprev = prev.previousSibling;\n\t\t}\n\t\tcursor = cursor.parentNode;\n\t\tif (cursor && (cursor as Element).matches?.('p, li, h1, h2, h3, h4, h5, h6, blockquote')) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlet rect: RichTextCaretContext['rect'];\n\tconst r = range.getBoundingClientRect();\n\tif (r && (r.top || r.left || r.right || r.bottom)) {\n\t\trect = { top: r.top, left: r.left, bottom: r.bottom, right: r.right };\n\t}\n\n\treturn { textBefore: text, rect };\n}\n\n/**\n * Extend the selection backwards by `length` characters, then insert\n * `html`. The selection extension means `editor.insertContent` (or the\n * fallback's `range.deleteContents()` + insert) replaces the trigger\n * range with the chip atomically — no manual text-content mutation, no\n * timing races between \"delete\" and \"insert\".\n */\nexport function replaceBeforeCaret(\n\teditor: TiptapEditor | null,\n\tlength: number,\n\thtml: string,\n\tnotifyChange: (next: string) => void,\n): void {\n\tif (typeof window === 'undefined') return;\n\n\tif (editor) {\n\t\t// ProseMirror owns its selection: focus() restores the stored caret and ignores a DOM range,\n\t\t// so replace the run before that caret in document positions, inside its text block.\n\t\tconst { selection } = editor.state;\n\t\tif (!selection.empty) return;\n\t\tconst from = selection.from - Math.min(length, selection.$from.parentOffset);\n\t\teditor.chain().focus().insertContentAt({ from, to: selection.from }, html).run();\n\t\tnotifyChange(editor.getHTML());\n\t\treturn;\n\t}\n\n\tconst sel = window.getSelection();\n\tif (!sel || sel.rangeCount === 0) return;\n\tconst caret = sel.getRangeAt(0);\n\tif (!caret.collapsed) return;\n\n\tlet remaining = length;\n\tlet startNode: Node = caret.startContainer;\n\tlet startOffset = caret.startOffset;\n\n\twhile (remaining > 0) {\n\t\tif (startNode.nodeType === Node.TEXT_NODE) {\n\t\t\tconst take = Math.min(startOffset, remaining);\n\t\t\tstartOffset -= take;\n\t\t\tremaining -= take;\n\t\t\tif (remaining === 0) break;\n\t\t}\n\t\tconst prev = previousTextNode(startNode);\n\t\tif (!prev) break;\n\t\tstartNode = prev;\n\t\tstartOffset = prev.textContent?.length ?? 0;\n\t}\n\n\tconst range = document.createRange();\n\trange.setStart(startNode, startOffset);\n\trange.setEnd(caret.endContainer, caret.endOffset);\n\tsel.removeAllRanges();\n\tsel.addRange(range);\n\n\trange.deleteContents();\n\tconst fragment = document.createRange().createContextualFragment(html);\n\trange.insertNode(fragment);\n\tsel.collapseToEnd();\n\tconst editable =\n\t\t(startNode as Element | null)?.parentElement?.closest?.('[contenteditable=\"true\"]') ?? null;\n\tif (editable) notifyChange((editable as HTMLElement).innerHTML);\n}\n\nexport function insertHtmlIntoEditable(editable: HTMLElement | null, html: string): void {\n\tif (typeof window === 'undefined' || !editable) return;\n\teditable.focus();\n\n\tconst sel = window.getSelection();\n\tif (!sel || sel.rangeCount === 0) {\n\t\teditable.insertAdjacentHTML('beforeend', html);\n\t\treturn;\n\t}\n\n\tconst range = sel.getRangeAt(0);\n\tif (!editable.contains(range.commonAncestorContainer)) {\n\t\teditable.insertAdjacentHTML('beforeend', html);\n\t\treturn;\n\t}\n\n\trange.deleteContents();\n\tconst fragment = document.createRange().createContextualFragment(html);\n\trange.insertNode(fragment);\n\trange.collapse(false);\n\tsel.removeAllRanges();\n\tsel.addRange(range);\n}\n\nfunction previousTextNode(node: Node): Node | null {\n\tlet current: Node | null = node;\n\twhile (current) {\n\t\tif (current.previousSibling) {\n\t\t\tcurrent = current.previousSibling;\n\t\t\twhile (current && current.lastChild) {\n\t\t\t\tcurrent = current.lastChild;\n\t\t\t}\n\t\t\tif (current && current.nodeType === Node.TEXT_NODE) return current;\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent = current.parentNode;\n\t\tif (!current || (current as Element).matches?.('p, li, h1, h2, h3, h4, h5, h6, blockquote, [contenteditable=\"true\"]')) {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn null;\n}\n","import { Number as NumberValue, SecondaryValue } from '../../../primitives';\nimport { Text } from '../../../typography';\nimport { cn } from '../../../../lib/utils';\n\nimport type { RichTextEditorStrings } from '../rich-text-editor.strings';\nimport type { TiptapEditor } from '../rich-text-editor.types';\n\nexport interface CountsFooterTextProps {\n\t/** Plain-text projection of the document, used for the character count. */\n\ttext: string;\n\t/** Character cap the count is measured against. */\n\tmaxLength?: number;\n\t/** Overrides this surface's own copy. */\n\tstrings: RichTextEditorStrings;\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n}\n\nexport function CountsFooterText({ text, maxLength, strings, className }: CountsFooterTextProps) {\n\tconst chars = text.length;\n\tconst words = text.trim().length > 0 ? text.trim().split(/\\s+/).length : 0;\n\tconst overLimit = typeof maxLength === 'number' && chars > maxLength;\n\n\treturn (\n\t\t<div className={cn('counts-footer-text--component border-border flex items-center justify-end gap-space-lg border-t px-control py-space-sm', className)}>\n\t\t\t<Text\n\t\t\t\ttag=\"span\"\n\t\t\t\tsize=\"xs\"\n\t\t\t\ttype={overLimit ? 'error' : 'secondary'}\n\t\t\t\tweight={overLimit ? 'medium' : 'regular'}\n\t\t\t\tclassName={cn('tabular-nums')}\n\t\t\t>\n\t\t\t\t<NumberValue value={chars} size=\"xs\" type={overLimit ? 'error' : 'secondary'} align=\"left\" />\n\t\t\t\t{typeof maxLength === 'number' && (\n\t\t\t\t\t<> / <NumberValue value={maxLength} size=\"xs\" type={overLimit ? 'error' : 'secondary'} align=\"left\" /></>\n\t\t\t\t)} {strings.counts.characters}\n\t\t\t</Text>\n\t\t\t<SecondaryValue size=\"xs\" className=\"tabular-nums\">\n\t\t\t\t<NumberValue value={words} size=\"xs\" type=\"secondary\" align=\"left\" /> {strings.counts.words}\n\t\t\t</SecondaryValue>\n\t\t</div>\n\t);\n}\n\nCountsFooterText.displayName = 'CountsFooterText';\n\nexport interface CountsFooterProps {\n\t/** The editor instance, for reading counts directly. */\n\teditor: TiptapEditor;\n\t/** Whether the editor is showing HTML source. */\n\tsourceMode: boolean;\n\t/** Raw HTML while in source mode. */\n\tsourceValue: string;\n\t/** Character cap the count is measured against. */\n\tmaxLength?: number;\n\t/** Overrides this surface's own copy. */\n\tstrings: RichTextEditorStrings;\n}\n\nexport function CountsFooter({\n\teditor,\n\tsourceMode,\n\tsourceValue,\n\tmaxLength,\n\tstrings,\n}: CountsFooterProps) {\n\tconst text = sourceMode\n\t\t? sourceValue.replace(/<[^>]*>/g, '')\n\t\t: (editor?.getText() ?? '');\n\n\treturn <CountsFooterText text={text} maxLength={maxLength} strings={strings} />;\n}\n\nCountsFooter.displayName = 'CountsFooter';\n","/**\n * Plain HTML normalization shared by the TipTap and contenteditable\n * fallback editors. Keeping these out of the React tree means the\n * editor partials stay focused on rendering.\n */\n\nexport function normalizeHtml(value: string): string {\n\tconst trimmed = value.trim();\n\n\tif (trimmed === '' || trimmed === '<p></p>' || trimmed === '<p><br></p>') {\n\t\treturn '';\n\t}\n\n\treturn trimmed;\n}\n\nexport function toEditorContent(value: string): string {\n\tconst normalized = normalizeHtml(value);\n\treturn normalized === '' ? '<p></p>' : normalized;\n}\n","import * as TiptapReact from '@tiptap/react';\n\n/**\n * Inline references (`@person`, `#booking`) as one atomic editor token.\n *\n * The serialized HTML is the mentions contract written by `buildMentionHtml`\n * and read by `parseMentionsFromHtml`/`MentionContent`:\n *\n * <span class=\"rsc-mention\" data-ref-id=\"…\" data-ref-kind=\"…\" data-ref-tone=\"…\"\n * contenteditable=\"false\">@Label</span>\n *\n * Without this node the editor schema had no place for that span, so a picked\n * mention collapsed into plain text. Inside the editor the token keeps the\n * `.rsc-mention` hook, so mention-chip.css (the inline Badge utilities and\n * shared tone tints) draws it exactly as it draws serialized chips; it is\n * selectable as a unit, and Backspace/Delete remove it in one keystroke.\n */\n\nexport const inlineReferenceChipClassName = 'rsc-mention inline-reference--chip';\n\nconst NODE_NAME = 'inlineReference';\n\nfunction deleteAdjacentReference(direction: 'backward' | 'forward') {\n\treturn ({ editor }: { editor: TiptapReact.Editor }) => editor.commands.command(({ tr, state }) => {\n\t\tconst { selection } = state;\n\t\tif (!selection.empty) return false;\n\t\tconst { $from } = selection;\n\t\tconst node = direction === 'backward' ? $from.nodeBefore : $from.nodeAfter;\n\t\tif (node?.type.name !== NODE_NAME) return false;\n\t\tconst from = direction === 'backward' ? $from.pos - node.nodeSize : $from.pos;\n\t\ttr.delete(from, from + node.nodeSize);\n\t\treturn true;\n\t});\n}\n\nlet inlineReferenceNode: TiptapReact.Node | null = null;\n\n/** Created on first use, so the optional Tiptap runtime is only touched by the editor that needs it. */\nexport function getInlineReferenceNode(): TiptapReact.Node {\n\tinlineReferenceNode ??= TiptapReact.Node.create({\n\t\tname: NODE_NAME,\n\t\tgroup: 'inline',\n\t\tinline: true,\n\t\tatom: true,\n\t\tselectable: true,\n\t\tdraggable: false,\n\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\tid: { default: null, parseHTML: (element) => element.getAttribute('data-ref-id'), renderHTML: (attributes) => ({ 'data-ref-id': attributes.id }) },\n\t\t\t\tkind: { default: null, parseHTML: (element) => element.getAttribute('data-ref-kind'), renderHTML: (attributes) => (attributes.kind ? { 'data-ref-kind': attributes.kind } : {}) },\n\t\t\t\ttone: { default: null, parseHTML: (element) => element.getAttribute('data-ref-tone'), renderHTML: (attributes) => (attributes.tone ? { 'data-ref-tone': attributes.tone } : {}) },\n\t\t\t\tlabel: { default: '', parseHTML: (element) => element.textContent ?? '', renderHTML: () => ({}) },\n\t\t\t};\n\t\t},\n\n\t\tparseHTML() {\n\t\t\treturn [{ tag: 'span[data-ref-id]' }];\n\t\t},\n\n\t\trenderHTML({ node, HTMLAttributes }) {\n\t\t\treturn ['span', TiptapReact.mergeAttributes({ class: 'rsc-mention', contenteditable: 'false' }, HTMLAttributes), node.attrs.label as string];\n\t\t},\n\n\t\trenderText({ node }) {\n\t\t\treturn node.attrs.label as string;\n\t\t},\n\n\t\taddNodeView() {\n\t\t\treturn ({ node }) => {\n\t\t\t\tconst dom = document.createElement('span');\n\t\t\t\tdom.className = inlineReferenceChipClassName;\n\t\t\t\tdom.setAttribute('contenteditable', 'false');\n\t\t\t\tdom.setAttribute('data-ref-id', String(node.attrs.id ?? ''));\n\t\t\t\tif (node.attrs.kind) dom.setAttribute('data-ref-kind', String(node.attrs.kind));\n\t\t\t\tif (node.attrs.tone) dom.setAttribute('data-ref-tone', String(node.attrs.tone));\n\t\t\t\tdom.textContent = String(node.attrs.label ?? '');\n\t\t\t\treturn { dom };\n\t\t\t};\n\t\t},\n\n\t\taddKeyboardShortcuts() {\n\t\t\treturn {\n\t\t\t\tBackspace: deleteAdjacentReference('backward'),\n\t\t\t\tDelete: deleteAdjacentReference('forward'),\n\t\t\t};\n\t\t},\n\t});\n\treturn inlineReferenceNode;\n}\n","import { AlertCircle, ImagePlus, Loader2 } from 'lucide-react';\nimport { useCallback, useEffect, useId, useMemo, useRef, useState, type RefObject } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { Button } from '../../../base/buttons';\nimport { FormField } from '../../../base/forms';\nimport { Stack } from '../../../base/structure';\nimport { Input } from '../../../base/text-inputs';\nimport { Text } from '../../../typography';\nimport { safeImageSrc } from '../../../../lib/safe-image-src';\nimport { interpolateString } from '../../../../lib/strings';\n\nimport type { RichTextEditorStrings } from '../rich-text-editor.strings';\nimport type { RichTextEditorImages, RichTextEditorToolbarItem, RichTextImage } from '../rich-text-editor.types';\n\nexport const DEFAULT_IMAGE_ACCEPT = 'image/png,image/jpeg,image/gif,image/webp';\n\n/** Marks an upload placeholder in the editing surface; never part of the value. */\nexport const UPLOAD_ATTRIBUTE = 'data-rte-upload';\n\n/** The placeholder occupies a line of its own while its image uploads. */\nexport const UPLOAD_PLACEHOLDER_CLASS = 'rich-text-editor--upload my-space-xs flex min-h-control items-center rounded-inner border border-dashed border-input bg-muted/30 px-row-x py-row-y';\n\nconst PLACEHOLDER_PATTERN = new RegExp(`<span[^>]*\\\\b${UPLOAD_ATTRIBUTE}=\"[^\"]*\"[^>]*>[\\\\s\\\\S]*?</span>`, 'g');\n\n/** Removes upload placeholders from serialized editor HTML. */\nexport function stripUploadPlaceholders(html: string): string {\n\treturn html.includes(UPLOAD_ATTRIBUTE) ? html.replace(PLACEHOLDER_PATTERN, '') : html;\n}\n\nexport function acceptsImageFile(file: File, accept: string): boolean {\n\tconst type = file.type.toLowerCase();\n\tconst name = file.name.toLowerCase();\n\treturn accept.split(',').map((entry) => entry.trim().toLowerCase()).filter(Boolean).some((entry) => {\n\t\tif (entry.startsWith('.')) return name.endsWith(entry);\n\t\tif (entry.endsWith('/*')) return type.startsWith(entry.slice(0, -1));\n\t\treturn type === entry;\n\t});\n}\n\n/** A readable default description from the file name: `team-offsite_2026.jpg` → `team offsite 2026`. */\nexport function altFromFileName(name: string): string {\n\treturn name.replace(/\\.[^.]+$/, '').replace(/[-_]+/g, ' ').trim();\n}\n\n/** Image files carried by a paste or drop. */\nexport function imageFilesFrom(data: DataTransfer | null | undefined): File[] {\n\treturn Array.from(data?.files ?? []).filter((file) => file.type.startsWith('image/'));\n}\n\n/** How each editor engine puts placeholders and images into its document. */\nexport interface ImageUploadAdapter {\n\t/** Inserts an empty placeholder for `id` at the selection (or the drop point). */\n\tinsertPlaceholder: (id: string) => void;\n\t/** Swaps the placeholder for the uploaded image and reports the change. */\n\tresolvePlaceholder: (id: string, image: RichTextImage) => void;\n\t/** Removes the placeholder and reports the change. */\n\tremovePlaceholder: (id: string) => void;\n\t/** The placeholder's element, or null once the user has deleted it. */\n\tfindPlaceholder: (id: string) => HTMLElement | null;\n}\n\nexport interface PendingImageUpload {\n\tid: string;\n\tname: string;\n\tstatus: 'uploading' | 'error';\n}\n\nlet uploadSequence = 0;\n\n/**\n * The engine-agnostic upload lifecycle: validate, insert a placeholder, call\n * the consumer's `upload` with an abort signal, then swap in the image or keep\n * the placeholder in its error state for Retry or Remove.\n */\nexport function useImageUploadQueue(\n\timages: RichTextEditorImages | undefined,\n\tadapterRef: RefObject<ImageUploadAdapter | null>,\n\tstrings: RichTextEditorStrings['images'],\n) {\n\tconst [uploads, setUploads] = useState<PendingImageUpload[]>([]);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\tconst jobs = useRef(new Map<string, { file: File; controller?: AbortController }>());\n\n\tuseEffect(() => () => {\n\t\tfor (const job of jobs.current.values()) job.controller?.abort();\n\t}, []);\n\n\tconst forget = useCallback((id: string) => {\n\t\tjobs.current.get(id)?.controller?.abort();\n\t\tjobs.current.delete(id);\n\t\tsetUploads((current) => current.filter((upload) => upload.id !== id));\n\t}, []);\n\n\tconst run = useCallback(async (id: string) => {\n\t\tconst job = jobs.current.get(id);\n\t\tif (!job || !images) return;\n\t\tjob.controller?.abort();\n\t\tconst controller = new AbortController();\n\t\tjob.controller = controller;\n\t\tconst pending: PendingImageUpload = { id, name: job.file.name, status: 'uploading' };\n\t\tsetUploads((current) => (current.some((upload) => upload.id === id) ? current.map((upload) => (upload.id === id ? pending : upload)) : [...current, pending]));\n\t\ttry {\n\t\t\tconst result = await images.upload(job.file, { signal: controller.signal });\n\t\t\tif (controller.signal.aborted) return;\n\t\t\tconst src = safeImageSrc(result?.src);\n\t\t\tif (!src) throw new Error(`The uploaded image source for ${job.file.name} is not an allowed URL.`);\n\t\t\tconst placed = adapterRef.current?.findPlaceholder(id);\n\t\t\tforget(id);\n\t\t\tif (placed) {\n\t\t\t\tadapterRef.current?.resolvePlaceholder(id, {\n\t\t\t\t\tsrc,\n\t\t\t\t\talt: result.alt ?? altFromFileName(job.file.name),\n\t\t\t\t\twidth: result.width,\n\t\t\t\t\theight: result.height,\n\t\t\t\t});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (controller.signal.aborted) return;\n\t\t\timages.onError?.(error, job.file);\n\t\t\tsetUploads((current) => current.map((upload) => (upload.id === id ? { ...upload, status: 'error' } : upload)));\n\t\t}\n\t}, [adapterRef, forget, images]);\n\n\tconst addFiles = useCallback((files: readonly File[]) => {\n\t\tif (!images) return;\n\t\tconst accept = images.accept ?? DEFAULT_IMAGE_ACCEPT;\n\t\tconst refused: string[] = [];\n\t\tfor (const file of files) {\n\t\t\tconst reason = !acceptsImageFile(file, accept)\n\t\t\t\t? strings.unsupported\n\t\t\t\t: images.maxSize && file.size > images.maxSize ? strings.tooLarge : null;\n\t\t\tif (reason) {\n\t\t\t\tconst message = interpolateString(reason, { name: file.name });\n\t\t\t\trefused.push(message);\n\t\t\t\timages.onError?.(new Error(message), file);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tuploadSequence += 1;\n\t\t\tconst id = `upload-${uploadSequence}`;\n\t\t\tjobs.current.set(id, { file });\n\t\t\tadapterRef.current?.insertPlaceholder(id);\n\t\t\tvoid run(id);\n\t\t}\n\t\tsetNotice(refused.length > 0 ? refused.join(' ') : null);\n\t}, [adapterRef, images, run, strings.tooLarge, strings.unsupported]);\n\n\tconst retry = useCallback((id: string) => { void run(id); }, [run]);\n\n\tconst remove = useCallback((id: string) => {\n\t\tforget(id);\n\t\tadapterRef.current?.removePlaceholder(id);\n\t}, [adapterRef, forget]);\n\n\t/** Forgets uploads whose placeholder the user deleted while editing. */\n\tconst prune = useCallback(() => {\n\t\tfor (const id of Array.from(jobs.current.keys())) {\n\t\t\tif (!adapterRef.current?.findPlaceholder(id)) forget(id);\n\t\t}\n\t}, [adapterRef, forget]);\n\n\treturn { uploads, notice, dismissNotice: () => setNotice(null), addFiles, retry, remove, prune };\n}\n\nexport type ImageUploadQueue = ReturnType<typeof useImageUploadQueue>;\n\n/** Status inside a placeholder: uploading with Cancel, or the failure with Retry and Remove. */\nfunction ImageUploadStatus({ upload, strings, onRetry, onRemove }: {\n\tupload: PendingImageUpload;\n\tstrings: RichTextEditorStrings['images'];\n\tonRetry: () => void;\n\tonRemove: () => void;\n}) {\n\tconst failed = upload.status === 'error';\n\treturn (\n\t\t// The message keeps a readable width; on a narrow editor the actions wrap below it.\n\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\" wrap className=\"rich-text-editor--upload-status w-full min-w-0\" data-status={upload.status}>\n\t\t\t{failed\n\t\t\t\t? <AlertCircle className=\"size-icon shrink-0 text-destructive\" aria-hidden=\"true\" />\n\t\t\t\t: <Loader2 className=\"size-icon shrink-0 animate-spin text-muted-foreground motion-reduce:animate-none\" aria-hidden=\"true\" />}\n\t\t\t<Text tag=\"span\" size=\"xs\" type={failed ? 'error' : 'secondary'} role={failed ? 'alert' : 'status'} className=\"min-w-0 flex-1 basis-40 break-words\">\n\t\t\t\t{interpolateString(failed ? strings.failed : strings.uploading, { name: upload.name })}\n\t\t\t</Text>\n\t\t\t{failed && <Button type=\"button\" size=\"sm\" onClick={onRetry}>{strings.retry}</Button>}\n\t\t\t<Button type=\"button\" size=\"sm\" buttonStyle=\"ghost\" onClick={onRemove}>{failed ? strings.remove : strings.cancel}</Button>\n\t\t</Stack>\n\t);\n}\n\n/** Renders each pending upload's status into its placeholder in the editing surface. */\nexport function ImageUploadPortals({ queue, adapterRef, strings }: {\n\tqueue: ImageUploadQueue;\n\tadapterRef: RefObject<ImageUploadAdapter | null>;\n\tstrings: RichTextEditorStrings['images'];\n}) {\n\treturn (\n\t\t<>\n\t\t\t{queue.uploads.map((upload) => {\n\t\t\t\tconst target = adapterRef.current?.findPlaceholder(upload.id);\n\t\t\t\treturn target ? createPortal(\n\t\t\t\t\t<ImageUploadStatus upload={upload} strings={strings} onRetry={() => queue.retry(upload.id)} onRemove={() => queue.remove(upload.id)} />,\n\t\t\t\t\ttarget,\n\t\t\t\t\tupload.id,\n\t\t\t\t) : null;\n\t\t\t})}\n\t\t</>\n\t);\n}\n\n/** The Insert image toolbar control and its hidden file input. */\nexport function useImageInsertControl(\n\timages: RichTextEditorImages | undefined,\n\tstrings: RichTextEditorStrings['images'],\n\tonFiles: (files: File[]) => void,\n\tbeforeOpen?: () => void,\n) {\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\tconst beforeOpenRef = useRef(beforeOpen);\n\tbeforeOpenRef.current = beforeOpen;\n\tconst enabled = Boolean(images);\n\tconst item = useMemo<RichTextEditorToolbarItem | null>(() => (enabled ? {\n\t\tid: 'insert-image',\n\t\ticon: ImagePlus,\n\t\tlabel: strings.insert,\n\t\ttoggle: false,\n\t\tonClick: () => {\n\t\t\tbeforeOpenRef.current?.();\n\t\t\tinputRef.current?.click();\n\t\t},\n\t} : null), [enabled, strings.insert]);\n\tconst input = images ? (\n\t\t<input\n\t\t\tref={inputRef}\n\t\t\ttype=\"file\"\n\t\t\taccept={images.accept ?? DEFAULT_IMAGE_ACCEPT}\n\t\t\tmultiple\n\t\t\thidden\n\t\t\ttabIndex={-1}\n\t\t\taria-hidden=\"true\"\n\t\t\tonChange={(event) => {\n\t\t\t\tconst files = Array.from(event.target.files ?? []);\n\t\t\t\tevent.target.value = '';\n\t\t\t\tif (files.length > 0) onFiles(files);\n\t\t\t}}\n\t\t/>\n\t) : null;\n\treturn { item, input };\n}\n\n/** The description field for the image at the caret, and refused-file notices. */\nexport function ImageDetailsBar({ alt, onAltChange, onRemove, notice, onDismissNotice, strings }: {\n\talt: string | null;\n\tonAltChange: (alt: string) => void;\n\tonRemove: () => void;\n\tnotice: string | null;\n\tonDismissNotice: () => void;\n\tstrings: RichTextEditorStrings['images'];\n}) {\n\tconst inputId = useId();\n\tif (alt === null && !notice) return null;\n\treturn (\n\t\t<Stack gap=\"sm\" className=\"rich-text-editor--image-details border-t border-border/60 px-control py-space-sm\">\n\t\t\t{!!notice && (\n\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\">\n\t\t\t\t\t<Text tag=\"span\" size=\"xs\" type=\"error\" role=\"alert\" className=\"min-w-0 flex-1\">{notice}</Text>\n\t\t\t\t\t<Button type=\"button\" size=\"sm\" buttonStyle=\"ghost\" onClick={onDismissNotice}>{strings.remove}</Button>\n\t\t\t\t</Stack>\n\t\t\t)}\n\t\t\t{alt !== null && (\n\t\t\t\t// The action sits on the field's own row, so it lines up with the input, not the hint.\n\t\t\t\t<FormField label={strings.descriptionLabel} hint={strings.descriptionHint} htmlFor={inputId}>\n\t\t\t\t\t{/* A compound field: the fragment keeps FormField from labelling the row itself. */}\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Stack direction=\"horizontal\" align=\"center\" gap=\"sm\" wrap={false}>\n\t\t\t\t\t\t\t<Input id={inputId} value={alt} className=\"min-w-0 flex-1\" onChange={(event) => onAltChange(event.target.value)} />\n\t\t\t\t\t\t\t<Button type=\"button\" buttonStyle=\"outline\" onClick={onRemove}>{strings.removeImage}</Button>\n\t\t\t\t\t\t</Stack>\n\t\t\t\t\t</>\n\t\t\t\t</FormField>\n\t\t\t)}\n\t\t</Stack>\n\t);\n}\n","import * as TiptapReact from '@tiptap/react';\n\nimport { safeImageSrc } from '../../../../lib/safe-image-src';\nimport { UPLOAD_ATTRIBUTE, UPLOAD_PLACEHOLDER_CLASS } from './image-uploads';\n\nfunction positiveNumber(value: string | null): number | null {\n\tconst number = Number(value);\n\treturn Number.isFinite(number) && number > 0 ? number : null;\n}\n\nlet imageNode: TiptapReact.Node | null = null;\nlet imageUploadNode: TiptapReact.Node | null = null;\n\n/**\n * An inline image whose source passes the package image policy; any other\n * `<img>` in loaded or pasted content is dropped. Serializes as a plain\n * `<img src alt width height>`, matching the contenteditable engine.\n */\nexport function getImageNode(): TiptapReact.Node {\n\timageNode ??= TiptapReact.Node.create({\n\t\tname: 'image',\n\t\tgroup: 'inline',\n\t\tinline: true,\n\t\tatom: true,\n\t\tselectable: true,\n\t\tdraggable: true,\n\n\t\taddAttributes() {\n\t\t\treturn {\n\t\t\t\tsrc: { default: null, parseHTML: (element) => safeImageSrc(element.getAttribute('src')) ?? null },\n\t\t\t\talt: { default: '', parseHTML: (element) => element.getAttribute('alt') ?? '' },\n\t\t\t\ttitle: { default: null },\n\t\t\t\twidth: { default: null, parseHTML: (element) => positiveNumber(element.getAttribute('width')) },\n\t\t\t\theight: { default: null, parseHTML: (element) => positiveNumber(element.getAttribute('height')) },\n\t\t\t};\n\t\t},\n\n\t\tparseHTML() {\n\t\t\treturn [{ tag: 'img[src]', getAttrs: (element) => (safeImageSrc((element as HTMLElement).getAttribute('src')) ? null : false) }];\n\t\t},\n\n\t\trenderHTML({ HTMLAttributes }) {\n\t\t\tconst src = safeImageSrc(HTMLAttributes.src);\n\t\t\treturn ['img', TiptapReact.mergeAttributes(HTMLAttributes, { src: src ?? null })];\n\t\t},\n\t});\n\treturn imageNode;\n}\n\n/**\n * The placeholder an image occupies while it uploads. It is never parsed from\n * HTML and the editor strips it from its value; the editor renders the\n * upload status into its node view.\n */\nexport function getImageUploadNode(): TiptapReact.Node {\n\timageUploadNode ??= TiptapReact.Node.create({\n\t\tname: 'imageUpload',\n\t\tgroup: 'inline',\n\t\tinline: true,\n\t\tatom: true,\n\t\tselectable: false,\n\n\t\taddAttributes() {\n\t\t\treturn { id: { default: null } };\n\t\t},\n\n\t\tparseHTML() {\n\t\t\treturn [];\n\t\t},\n\n\t\trenderHTML({ node }) {\n\t\t\treturn ['span', { [UPLOAD_ATTRIBUTE]: node.attrs.id as string }];\n\t\t},\n\n\t\taddNodeView() {\n\t\t\treturn ({ node }) => {\n\t\t\t\tconst dom = document.createElement('span');\n\t\t\t\tdom.setAttribute(UPLOAD_ATTRIBUTE, String(node.attrs.id));\n\t\t\t\tdom.setAttribute('contenteditable', 'false');\n\t\t\t\tdom.className = UPLOAD_PLACEHOLDER_CLASS;\n\t\t\t\t// The status UI is a React portal; keep ProseMirror out of it.\n\t\t\t\treturn { dom, ignoreMutation: () => true, stopEvent: () => true };\n\t\t\t};\n\t\t},\n\t});\n\treturn imageUploadNode;\n}\n","import {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport {\n\tBold,\n\tItalic,\n\tList,\n\tListOrdered,\n\tQuote,\n\tRedo2,\n\tStrikethrough,\n\tUndo2,\n} from 'lucide-react';\nimport * as TiptapReact from '@tiptap/react';\nimport * as StarterKitModule from '@tiptap/starter-kit';\n\nimport { richTextEditorRecipes } from '../rich-text-editor.recipes';\nimport { editableContentClassName } from '../../../typography/content-typography';\n\nimport { Text } from '../../../typography';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport { defaultRichTextEditorStrings } from '../rich-text-editor.strings';\nimport type {\n\tRichTextEditorHandle,\n\tRichTextEditorProps,\n\tTiptapEditor,\n\tToolbarButtonConfig,\n} from '../rich-text-editor.types';\nimport { readCaretContext, replaceBeforeCaret } from './caret-helpers';\nimport { CountsFooter } from './counts-footer';\nimport { normalizeHtml, toEditorContent } from './html-helpers';\nimport { RichTextEditorToolbar } from './rich-text-editor-toolbar';\nimport { getInlineReferenceNode } from './inline-reference-node';\nimport { getImageNode, getImageUploadNode } from './image-nodes';\nimport {\n\tImageDetailsBar,\n\tImageUploadPortals,\n\timageFilesFrom,\n\tstripUploadPlaceholders,\n\tuseImageInsertControl,\n\tuseImageUploadQueue,\n\ttype ImageUploadAdapter,\n\ttype ImageUploadQueue,\n} from './image-uploads';\n\ntype ProseNode = { type: { name: string }; attrs: Record<string, unknown>; nodeSize: number };\n\n/** Value HTML: the editor's HTML without upload placeholders. */\nfunction valueHtml(editor: { getHTML: () => string } | null | undefined): string {\n\treturn normalizeHtml(stripUploadPlaceholders(editor?.getHTML() ?? ''));\n}\n\nconst EditorContent = TiptapReact.EditorContent;\nconst useTiptapEditor = TiptapReact.useEditor;\nconst StarterKit =\n\t'default' in StarterKitModule ? StarterKitModule.default : StarterKitModule;\n\nexport const TiptapRichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorProps>(function TiptapRichTextEditor(\n\t{\n\t\tvalue,\n\t\tonValueChange,\n\t\tplaceholder,\n\t\tcompact = false,\n\t\tbodyHeight,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tdisabled = false,\n\t\tshowCounts = false,\n\t\tmaxLength,\n\t\textraToolbarItems,\n\t\ttoolbarTrailing,\n\t\tfooterSlot,\n\t\thideSourceToggle = false,\n\t\tautoFocus = false,\n\t\tclassName,\n\t\tonCaretChange,\n\t\tstrings: stringsProp,\n\t\timages,\n\t},\n\tref,\n) {\n\tconst strings = useStrings(defaultRichTextEditorStrings, stringsProp);\n\tconst imagesEnabled = Boolean(images);\n\tconst queueRef = useRef<ImageUploadQueue | null>(null);\n\tconst editorInstanceRef = useRef<TiptapEditor | null>(null);\n\tconst [isFocused, setIsFocused] = useState(false);\n\tconst [sourceMode, setSourceMode] = useState(false);\n\tconst [sourceValue, setSourceValue] = useState('');\n\tconst isFocusedRef = useRef(false);\n\tconst externalValueRef = useRef<string>(normalizeHtml(value));\n\tconst onCaretChangeRef = useRef(onCaretChange);\n\tonCaretChangeRef.current = onCaretChange;\n\n\tconst extensions = useMemo(\n\t\t() => [StarterKit, getInlineReferenceNode(), ...(imagesEnabled ? [getImageNode(), getImageUploadNode()] : [])],\n\t\t[imagesEnabled],\n\t);\n\tconst editor = useTiptapEditor({\n\t\textensions,\n\t\tcontent: toEditorContent(value),\n\t\teditable: !disabled,\n\t\timmediatelyRender: false,\n\t\tautofocus: autoFocus ? 'end' : false,\n\t\tonFocus: () => {\n\t\t\tisFocusedRef.current = true;\n\t\t\tsetIsFocused(true);\n\t\t},\n\t\tonBlur: () => {\n\t\t\tisFocusedRef.current = false;\n\t\t\tsetIsFocused(false);\n\t\t},\n\t\tonUpdate: ({ editor: currentEditor }: { editor: { getHTML: () => string } }) => {\n\t\t\tqueueRef.current?.prune();\n\t\t\tconst html = valueHtml(currentEditor);\n\t\t\tif (!isFocusedRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (html !== externalValueRef.current) {\n\t\t\t\texternalValueRef.current = html;\n\t\t\t\tonValueChange(html);\n\t\t\t}\n\n\t\t\tonCaretChangeRef.current?.();\n\t\t},\n\t\teditorProps: {\n\t\t\t// Image files from the clipboard or a drop go through the upload lifecycle.\n\t\t\thandlePaste: (_view: unknown, event: ClipboardEvent) => {\n\t\t\t\tconst files = imageFilesFrom(event.clipboardData);\n\t\t\t\tif (!queueRef.current || !imagesRef.current || files.length === 0) return false;\n\t\t\t\tqueueRef.current.addFiles(files);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\thandleDrop: (view: { posAtCoords: (coords: { left: number; top: number }) => { pos: number } | null }, event: DragEvent, _slice: unknown, moved: boolean) => {\n\t\t\t\tconst files = imageFilesFrom(event.dataTransfer);\n\t\t\t\tif (moved || !queueRef.current || !imagesRef.current || files.length === 0) return false;\n\t\t\t\tconst at = view.posAtCoords({ left: event.clientX, top: event.clientY });\n\t\t\t\tif (at) editorInstanceRef.current?.commands.setTextSelection(at.pos);\n\t\t\t\tqueueRef.current.addFiles(files);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\tattributes: {\n\t\t\t\trole: 'textbox',\n\t\t\t\t'aria-label': strings.editorLabel,\n\t\t\t\t'aria-multiline': 'true',\n\t\t\t\tclass: editableContentClassName,\n\t\t\t},\n\t\t},\n\t// Image nodes join the schema only when images are enabled, which needs a new editor.\n\t}, [imagesEnabled]);\n\n\tuseEffect(() => {\n\t\tif (!editor) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = valueHtml(editor);\n\t\tconst next = normalizeHtml(value);\n\t\texternalValueRef.current = next;\n\n\t\tif (current !== next) {\n\t\t\teditor.commands.setContent(toEditorContent(next), { emitUpdate: false });\n\t\t}\n\t}, [editor, value]);\n\n\tuseEffect(() => {\n\t\tif (!editor) {\n\t\t\treturn;\n\t\t}\n\n\t\teditor.setEditable(!disabled);\n\t}, [disabled, editor]);\n\n\tuseEffect(() => {\n\t\tif (typeof document === 'undefined') return;\n\t\tconst handler = () => {\n\t\t\tif (!isFocusedRef.current) return;\n\t\t\tonCaretChangeRef.current?.();\n\t\t};\n\t\tdocument.addEventListener('selectionchange', handler);\n\t\treturn () => document.removeEventListener('selectionchange', handler);\n\t}, []);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\tfocus: () => {\n\t\t\t\teditor?.chain().focus().run();\n\t\t\t},\n\t\t\tgetHTML: () => valueHtml(editor),\n\t\t\tsetHTML: (html: string) => {\n\t\t\t\tconst next = normalizeHtml(html);\n\t\t\t\texternalValueRef.current = next;\n\t\t\t\teditor?.commands.setContent(toEditorContent(next), { emitUpdate: false });\n\t\t\t\tonValueChange(next);\n\t\t\t},\n\t\t\tinsertHTML: (html: string) => {\n\t\t\t\tif (!editor) return;\n\t\t\t\teditor.chain().focus().insertContent(html).run();\n\t\t\t},\n\t\t\tisEmpty: () => valueHtml(editor) === '',\n\t\t\tclear: () => {\n\t\t\t\texternalValueRef.current = '';\n\t\t\t\teditor?.commands.setContent('<p></p>', { emitUpdate: false });\n\t\t\t\tonValueChange('');\n\t\t\t},\n\t\t\tgetCaretContext: () => readCaretContext(),\n\t\t\treplaceBeforeCaret: (length: number, html: string) => {\n\t\t\t\treplaceBeforeCaret(editor, length, html, (next) => {\n\t\t\t\t\texternalValueRef.current = normalizeHtml(next);\n\t\t\t\t\tonValueChange(externalValueRef.current);\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t\t[editor, onValueChange],\n\t);\n\n\teditorInstanceRef.current = editor ?? null;\n\tconst imagesRef = useRef(images);\n\timagesRef.current = images;\n\n\t/** Programmatic changes (an upload landing, a description edit) report the value themselves. */\n\tconst emitValue = useCallback(() => {\n\t\tif (!editor) return;\n\t\tconst html = valueHtml(editor);\n\t\tif (html === externalValueRef.current) return;\n\t\texternalValueRef.current = html;\n\t\tonValueChange(html);\n\t}, [editor, onValueChange]);\n\n\tconst findNode = useCallback((match: (node: ProseNode) => boolean) => {\n\t\tlet found: { pos: number; node: ProseNode } | null = null;\n\t\teditor?.state.doc.descendants((node: ProseNode, pos: number) => {\n\t\t\tif (!found && match(node)) found = { pos, node };\n\t\t\treturn !found;\n\t\t});\n\t\treturn found as { pos: number; node: ProseNode } | null;\n\t}, [editor]);\n\n\tconst adapterRef = useRef<ImageUploadAdapter | null>(null);\n\tadapterRef.current = editor ? {\n\t\tinsertPlaceholder: (id) => {\n\t\t\teditor.chain().focus().insertContent({ type: 'imageUpload', attrs: { id } }).run();\n\t\t},\n\t\tfindPlaceholder: (id) => editor.view.dom.querySelector<HTMLElement>(`[data-rte-upload=\"${id}\"]`),\n\t\tresolvePlaceholder: (id, image) => {\n\t\t\tconst at = findNode((node) => node.type.name === 'imageUpload' && node.attrs.id === id);\n\t\t\tif (!at) return;\n\t\t\tconst created = editor.schema.nodes.image.create({ src: image.src, alt: image.alt ?? '', width: image.width ?? null, height: image.height ?? null });\n\t\t\teditor.view.dispatch(editor.state.tr.replaceWith(at.pos, at.pos + at.node.nodeSize, created));\n\t\t\temitValue();\n\t\t},\n\t\tremovePlaceholder: (id) => {\n\t\t\tconst at = findNode((node) => node.type.name === 'imageUpload' && node.attrs.id === id);\n\t\t\tif (!at) return;\n\t\t\teditor.view.dispatch(editor.state.tr.delete(at.pos, at.pos + at.node.nodeSize));\n\t\t\temitValue();\n\t\t},\n\t} : null;\n\tconst uploadQueue = useImageUploadQueue(images, adapterRef, strings.images);\n\tqueueRef.current = imagesEnabled ? uploadQueue : null;\n\tconst imageInsert = useImageInsertControl(images, strings.images, uploadQueue.addFiles);\n\tconst toolbarItems = useMemo(\n\t\t() => (imageInsert.item ? [imageInsert.item, ...(extraToolbarItems ?? [])] : extraToolbarItems),\n\t\t[extraToolbarItems, imageInsert.item],\n\t);\n\n\t// The image the selection holds, or that sits beside a collapsed caret.\n\tconst [activeImage, setActiveImage] = useState<{ pos: number; alt: string } | null>(null);\n\tuseEffect(() => {\n\t\tif (!editor || !imagesEnabled) return;\n\t\tconst sync = () => {\n\t\t\tconst selection = editor.state.selection as unknown as { node?: ProseNode; empty: boolean; from: number; $from: { nodeBefore: ProseNode | null; nodeAfter: ProseNode | null } };\n\t\t\tlet next: { pos: number; alt: string } | null = null;\n\t\t\tif (selection.node?.type.name === 'image') next = { pos: selection.from, alt: String(selection.node.attrs.alt ?? '') };\n\t\t\telse if (selection.empty) {\n\t\t\t\tconst { nodeBefore, nodeAfter } = selection.$from;\n\t\t\t\tif (nodeBefore?.type.name === 'image') next = { pos: selection.from - nodeBefore.nodeSize, alt: String(nodeBefore.attrs.alt ?? '') };\n\t\t\t\telse if (nodeAfter?.type.name === 'image') next = { pos: selection.from, alt: String(nodeAfter.attrs.alt ?? '') };\n\t\t\t}\n\t\t\tsetActiveImage(next);\n\t\t};\n\t\teditor.on('selectionUpdate', sync);\n\t\teditor.on('update', sync);\n\t\treturn () => {\n\t\t\teditor.off('selectionUpdate', sync);\n\t\t\teditor.off('update', sync);\n\t\t};\n\t}, [editor, imagesEnabled]);\n\n\t// The recipe owns the default body floor; inline style carries only the\n\t// consumer's explicit CSS lengths, which win over that class.\n\tconst bodyMinHeightClassName = richTextEditorRecipes.bodyMinHeight[bodyHeight ?? (compact ? 'control' : 'document')];\n\tconst contentStyle = useMemo(\n\t\t() => ({\n\t\t\t...(minHeight ? { minHeight } : {}),\n\t\t\t...(maxHeight ? { maxHeight, overflowY: 'auto' as const } : {}),\n\t\t}),\n\t\t[maxHeight, minHeight],\n\t);\n\n\tconst toggleSourceMode = useCallback(() => {\n\t\tif (!editor) return;\n\n\t\tif (sourceMode) {\n\t\t\tconst html = toEditorContent(sourceValue);\n\t\t\teditor.commands.setContent(html, { emitUpdate: false });\n\t\t\tconst normalized = normalizeHtml(sourceValue);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tonValueChange(normalized);\n\t\t\tsetSourceMode(false);\n\t\t} else {\n\t\t\tsetSourceValue(editor.getHTML());\n\t\t\tsetSourceMode(true);\n\t\t}\n\t}, [editor, onValueChange, sourceMode, sourceValue]);\n\n\tconst handleSourceChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\t\tconst next = e.target.value;\n\t\t\tsetSourceValue(next);\n\t\t\tconst normalized = normalizeHtml(next);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tonValueChange(normalized);\n\t\t},\n\t\t[onValueChange],\n\t);\n\n\tconst toolbarButtons = useMemo<ToolbarButtonConfig[]>(\n\t\t() => [\n\t\t\t{\n\t\t\t\tid: 'bold',\n\t\t\t\ticon: Bold,\n\t\t\t\tlabel: strings.toolbar.bold,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('bold')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleBold().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'italic',\n\t\t\t\ticon: Italic,\n\t\t\t\tlabel: strings.toolbar.italic,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('italic')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleItalic().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'strike',\n\t\t\t\ticon: Strikethrough,\n\t\t\t\tlabel: strings.toolbar.strike,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('strike')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleStrike().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'bullet-list',\n\t\t\t\ticon: List,\n\t\t\t\tlabel: strings.toolbar.bulletList,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('bulletList')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleBulletList().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'ordered-list',\n\t\t\t\ticon: ListOrdered,\n\t\t\t\tlabel: strings.toolbar.orderedList,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('orderedList')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleOrderedList().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'blockquote',\n\t\t\t\ticon: Quote,\n\t\t\t\tlabel: strings.toolbar.blockquote,\n\t\t\t\tisActive: () => Boolean(editor?.isActive('blockquote')),\n\t\t\t\ttoggle: true,\n\t\t\t\trun: () => editor?.chain().focus().toggleBlockquote().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'undo',\n\t\t\t\ticon: Undo2,\n\t\t\t\tlabel: strings.toolbar.undo,\n\t\t\t\tisActive: () => false,\n\t\t\t\trun: () => editor?.chain().focus().undo().run(),\n\t\t\t\tdisabled: !editor?.can().chain().focus().undo().run(),\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'redo',\n\t\t\t\ticon: Redo2,\n\t\t\t\tlabel: strings.toolbar.redo,\n\t\t\t\tisActive: () => false,\n\t\t\t\trun: () => editor?.chain().focus().redo().run(),\n\t\t\t\tdisabled: !editor?.can().chain().focus().redo().run(),\n\t\t\t},\n\t\t],\n\t\t[editor, strings],\n\t);\n\n\tconst countsFooter =\n\t\tshowCounts && editor ? (\n\t\t\t<CountsFooter\n\t\t\t\teditor={editor}\n\t\t\t\tsourceMode={sourceMode}\n\t\t\t\tsourceValue={sourceValue}\n\t\t\t\tmaxLength={maxLength}\n\t\t\t\tstrings={strings}\n\t\t\t/>\n\t\t) : null;\n\n\tconst placeholderText = typeof placeholder === 'string' ? placeholder : '';\n\tconst showPlaceholder =\n\t\tplaceholderText.length > 0 && !isFocused && Boolean(editor?.isEmpty);\n\tconst placeholderNode = showPlaceholder ? (\n\t\t<Text\n\t\t\ttag=\"span\"\n\t\t\tsize=\"sm\"\n\t\t\ttype=\"secondary\"\n\t\t\tclassName=\"pointer-events-none absolute inset-0 px-control py-control-y-offset\"\n\t\t>\n\t\t\t{placeholderText}\n\t\t</Text>\n\t) : null;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\trichTextEditorRecipes.frame,\n\t\t\t\tdisabled && richTextEditorRecipes.disabled,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<RichTextEditorToolbar\n\t\t\t\tbuttons={toolbarButtons}\n\t\t\t\textraToolbarItems={toolbarItems}\n\t\t\t\thideSourceToggle={hideSourceToggle}\n\t\t\t\tsourceMode={sourceMode}\n\t\t\t\ttoggleSourceMode={toggleSourceMode}\n\t\t\t\tdisabled={disabled}\n\t\t\t\thasEditor={Boolean(editor)}\n\t\t\t\ttoolbarTrailing={toolbarTrailing}\n\t\t\t\tstrings={strings}\n\t\t\t/>\n\n\t\t\t{sourceMode ? (\n\t\t\t\t<textarea\n\t\t\t\t\taria-label={strings.sourceLabel}\n\t\t\t\t\tvalue={sourceValue}\n\t\t\t\t\tonChange={handleSourceChange}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tspellCheck={false}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\trichTextEditorRecipes.source,\n\t\t\t\t\t\tbodyMinHeightClassName,\n\t\t\t\t\t\tdisabled && 'cursor-not-allowed',\n\t\t\t\t\t)}\n\t\t\t\t\tstyle={contentStyle}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<div className={cn('relative', bodyMinHeightClassName)} style={contentStyle}>\n\t\t\t\t\t{placeholderNode}\n\n\t\t\t\t\t<EditorContent\n\t\t\t\t\t\teditor={editor}\n\t\t\t\t\t\tclassName={richTextEditorRecipes.content}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{imagesEnabled && (\n\t\t\t\t<ImageDetailsBar\n\t\t\t\t\talt={activeImage ? activeImage.alt : null}\n\t\t\t\t\tonAltChange={(alt) => {\n\t\t\t\t\t\tif (!editor || !activeImage) return;\n\t\t\t\t\t\tconst node = editor.state.doc.nodeAt(activeImage.pos) as ProseNode | null;\n\t\t\t\t\t\tif (node?.type.name !== 'image') return;\n\t\t\t\t\t\teditor.view.dispatch(editor.state.tr.setNodeMarkup(activeImage.pos, undefined, { ...node.attrs, alt }));\n\t\t\t\t\t\tsetActiveImage({ ...activeImage, alt });\n\t\t\t\t\t\temitValue();\n\t\t\t\t\t}}\n\t\t\t\t\tonRemove={() => {\n\t\t\t\t\t\tif (!editor || !activeImage) return;\n\t\t\t\t\t\tconst node = editor.state.doc.nodeAt(activeImage.pos) as ProseNode | null;\n\t\t\t\t\t\tif (node?.type.name !== 'image') return;\n\t\t\t\t\t\teditor.view.dispatch(editor.state.tr.delete(activeImage.pos, activeImage.pos + node.nodeSize));\n\t\t\t\t\t\tsetActiveImage(null);\n\t\t\t\t\t\temitValue();\n\t\t\t\t\t\teditor.commands.focus();\n\t\t\t\t\t}}\n\t\t\t\t\tnotice={uploadQueue.notice}\n\t\t\t\t\tonDismissNotice={uploadQueue.dismissNotice}\n\t\t\t\t\tstrings={strings.images}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{!!footerSlot && (\n\t\t\t\t<div className=\"px-control pb-space-md pt-space-xs\">{footerSlot}</div>\n\t\t\t)}\n\n\t\t\t{countsFooter}\n\t\t\t{imageInsert.input}\n\t\t\t{imagesEnabled && <ImageUploadPortals queue={uploadQueue} adapterRef={adapterRef} strings={strings.images} />}\n\t\t</div>\n\t);\n});\n\nTiptapRichTextEditor.displayName = 'TiptapRichTextEditor';\n\n// Tiptap 3 exports EditorContent as React.memo (an object), so accept any component type.\nconst isComponentType = (value: unknown) =>\n\ttypeof value === 'function' || (typeof value === 'object' && value !== null && '$$typeof' in value);\n\nexport const hasTiptapRuntime =\n\tisComponentType(EditorContent) &&\n\ttypeof useTiptapEditor === 'function' &&\n\ttypeof StarterKit === 'object' &&\n\tStarterKit !== null;\n","import {\n\tforwardRef,\n\tuseCallback,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from 'react';\nimport {\n\tBold,\n\tItalic,\n\tList,\n\tListOrdered,\n\tQuote,\n\tRedo2,\n\tStrikethrough,\n\tUndo2,\n} from 'lucide-react';\n\nimport { richTextEditorRecipes } from '../rich-text-editor.recipes';\nimport { editableContentClassName } from '../../../typography/content-typography';\n\nimport { Text } from '../../../typography';\nimport { useStrings } from '../../../../lib/strings';\nimport { cn } from '../../../../lib/utils';\n\nimport { defaultRichTextEditorStrings } from '../rich-text-editor.strings';\nimport type {\n\tRichTextEditorHandle,\n\tRichTextEditorProps,\n\tToolbarButtonConfig,\n} from '../rich-text-editor.types';\nimport {\n\tinsertHtmlIntoEditable,\n\treadCaretContext,\n\treplaceBeforeCaret,\n} from './caret-helpers';\nimport { CountsFooterText } from './counts-footer';\nimport { normalizeHtml, toEditorContent } from './html-helpers';\nimport { RichTextEditorToolbar } from './rich-text-editor-toolbar';\nimport {\n\tImageDetailsBar,\n\tImageUploadPortals,\n\tUPLOAD_ATTRIBUTE,\n\tUPLOAD_PLACEHOLDER_CLASS,\n\timageFilesFrom,\n\tuseImageInsertControl,\n\tuseImageUploadQueue,\n\ttype ImageUploadAdapter,\n} from './image-uploads';\nimport { safeImageSrc } from '../../../../lib/safe-image-src';\n\n/** The editable's HTML without upload placeholders, which are never part of the value. */\nfunction serializeEditable(editable: HTMLElement | null): string {\n\tif (!editable) return '';\n\tif (!editable.querySelector(`[${UPLOAD_ATTRIBUTE}]`)) return editable.innerHTML;\n\tconst copy = editable.cloneNode(true) as HTMLElement;\n\tfor (const placeholder of Array.from(copy.querySelectorAll(`[${UPLOAD_ATTRIBUTE}]`))) placeholder.remove();\n\treturn copy.innerHTML;\n}\n\n/** Pasted markup may carry images; keep only those whose source passes the image policy. */\nfunction removeUnsafeImages(editable: HTMLElement): void {\n\tfor (const image of Array.from(editable.querySelectorAll('img'))) {\n\t\tif (!safeImageSrc(image.getAttribute('src'))) image.remove();\n\t}\n}\n\n/** The image the selection touches, or that sits right beside a collapsed caret. */\nfunction imageAtSelection(editable: HTMLElement): HTMLImageElement | null {\n\tconst selection = window.getSelection();\n\tif (!selection || selection.rangeCount === 0) return null;\n\tconst range = selection.getRangeAt(0);\n\tif (!editable.contains(range.commonAncestorContainer)) return null;\n\tfor (const image of Array.from(editable.querySelectorAll('img'))) {\n\t\tif (range.intersectsNode(image) && !range.collapsed) return image;\n\t}\n\tif (!range.collapsed) return null;\n\tconst { startContainer, startOffset } = range;\n\tconst neighbours = startContainer.nodeType === Node.TEXT_NODE\n\t\t? [startOffset === 0 ? startContainer.previousSibling : null, startOffset === (startContainer.textContent?.length ?? 0) ? startContainer.nextSibling : null]\n\t\t: [startContainer.childNodes[startOffset - 1] ?? null, startContainer.childNodes[startOffset] ?? null];\n\treturn (neighbours.find((node) => node instanceof HTMLImageElement) as HTMLImageElement | undefined) ?? null;\n}\n\n/** Places the caret where a drop happened. */\nfunction placeCaretAtPoint(x: number, y: number): void {\n\tconst doc = document as Document & {\n\t\tcaretRangeFromPoint?: (x: number, y: number) => Range | null;\n\t\tcaretPositionFromPoint?: (x: number, y: number) => { offsetNode: Node; offset: number } | null;\n\t};\n\tlet range = doc.caretRangeFromPoint?.(x, y) ?? null;\n\tif (!range) {\n\t\tconst position = doc.caretPositionFromPoint?.(x, y);\n\t\tif (position) {\n\t\t\trange = document.createRange();\n\t\t\trange.setStart(position.offsetNode, position.offset);\n\t\t}\n\t}\n\tif (!range) return;\n\trange.collapse(true);\n\tconst selection = window.getSelection();\n\tselection?.removeAllRanges();\n\tselection?.addRange(range);\n}\n\n/**\n * Fallback editor used when the TipTap runtime is unavailable (e.g. in\n * environments where the package failed to load). Renders a\n * `contenteditable` surface with the same imperative handle so callers\n * never need to care which variant they got.\n */\nexport const FallbackRichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorProps>(function FallbackRichTextEditor(\n\t{\n\t\tvalue,\n\t\tonValueChange,\n\t\tplaceholder,\n\t\tcompact = false,\n\t\tbodyHeight,\n\t\tminHeight,\n\t\tmaxHeight,\n\t\tdisabled = false,\n\t\tshowCounts = false,\n\t\tmaxLength,\n\t\textraToolbarItems,\n\t\ttoolbarTrailing,\n\t\tfooterSlot,\n\t\thideSourceToggle = false,\n\t\tautoFocus = false,\n\t\tclassName,\n\t\tonCaretChange,\n\t\tstrings: stringsProp,\n\t\timages,\n\t},\n\tref,\n) {\n\tconst strings = useStrings(defaultRichTextEditorStrings, stringsProp);\n\tconst editableRef = useRef<HTMLDivElement>(null);\n\tconst savedRangeRef = useRef<Range | null>(null);\n\tconst [activeImage, setActiveImage] = useState<HTMLImageElement | null>(null);\n\tconst [activeAlt, setActiveAlt] = useState('');\n\tconst [isFocused, setIsFocused] = useState(false);\n\tconst [sourceMode, setSourceMode] = useState(false);\n\tconst [sourceValue, setSourceValue] = useState('');\n\tconst externalValueRef = useRef<string>(normalizeHtml(value));\n\tconst onCaretChangeRef = useRef(onCaretChange);\n\tonCaretChangeRef.current = onCaretChange;\n\n\tconst setEditableRef = useCallback((node: HTMLDivElement | null) => {\n\t\teditableRef.current = node;\n\t\tif (node && node.innerHTML === '') {\n\t\t\tnode.innerHTML = toEditorContent(externalValueRef.current);\n\t\t}\n\t}, []);\n\n\tuseEffect(() => {\n\t\tconst editable = editableRef.current;\n\t\tif (!editable || isFocused) return;\n\t\tconst next = toEditorContent(value);\n\t\tif (normalizeHtml(serializeEditable(editable)) !== normalizeHtml(next)) {\n\t\t\teditable.innerHTML = next;\n\t\t}\n\t\texternalValueRef.current = normalizeHtml(value);\n\t}, [isFocused, value]);\n\n\tuseEffect(() => {\n\t\tif (!autoFocus) return;\n\t\teditableRef.current?.focus();\n\t}, [autoFocus]);\n\n\tconst emitEditableChange = useCallback(() => {\n\t\tconst editable = editableRef.current;\n\t\tconst html = normalizeHtml(serializeEditable(editable));\n\t\texternalValueRef.current = html;\n\t\tonValueChange(html);\n\t\tonCaretChangeRef.current?.();\n\t}, [onValueChange]);\n\n\tconst adapterRef = useRef<ImageUploadAdapter | null>(null);\n\tadapterRef.current = {\n\t\tinsertPlaceholder: (id) => {\n\t\t\tconst editable = editableRef.current;\n\t\t\tif (!editable) return;\n\t\t\tconst saved = savedRangeRef.current;\n\t\t\tif (saved && editable.contains(saved.commonAncestorContainer) && !editable.contains(document.activeElement)) {\n\t\t\t\teditable.focus();\n\t\t\t\tconst selection = window.getSelection();\n\t\t\t\tselection?.removeAllRanges();\n\t\t\t\tselection?.addRange(saved);\n\t\t\t}\n\t\t\tinsertHtmlIntoEditable(editable, `<span ${UPLOAD_ATTRIBUTE}=\"${id}\" contenteditable=\"false\" class=\"${UPLOAD_PLACEHOLDER_CLASS}\"></span>`);\n\t\t},\n\t\tfindPlaceholder: (id) => editableRef.current?.querySelector<HTMLElement>(`[${UPLOAD_ATTRIBUTE}=\"${id}\"]`) ?? null,\n\t\tresolvePlaceholder: (id, image) => {\n\t\t\tconst placeholder = editableRef.current?.querySelector(`[${UPLOAD_ATTRIBUTE}=\"${id}\"]`);\n\t\t\tif (!placeholder) return;\n\t\t\tconst element = document.createElement('img');\n\t\t\telement.setAttribute('src', image.src);\n\t\t\telement.setAttribute('alt', image.alt ?? '');\n\t\t\tif (image.width) element.setAttribute('width', String(image.width));\n\t\t\tif (image.height) element.setAttribute('height', String(image.height));\n\t\t\tplaceholder.replaceWith(element);\n\t\t\temitEditableChange();\n\t\t},\n\t\tremovePlaceholder: (id) => {\n\t\t\teditableRef.current?.querySelector(`[${UPLOAD_ATTRIBUTE}=\"${id}\"]`)?.remove();\n\t\t\temitEditableChange();\n\t\t},\n\t};\n\tconst uploadQueue = useImageUploadQueue(images, adapterRef, strings.images);\n\tconst imageInsert = useImageInsertControl(images, strings.images, uploadQueue.addFiles, () => {\n\t\tconst selection = window.getSelection();\n\t\tconst range = selection && selection.rangeCount > 0 ? selection.getRangeAt(0) : null;\n\t\tsavedRangeRef.current = range && editableRef.current?.contains(range.commonAncestorContainer) ? range.cloneRange() : null;\n\t});\n\tconst toolbarItems = useMemo(\n\t\t() => (imageInsert.item ? [imageInsert.item, ...(extraToolbarItems ?? [])] : extraToolbarItems),\n\t\t[extraToolbarItems, imageInsert.item],\n\t);\n\n\tconst syncActiveImage = useCallback(() => {\n\t\tconst editable = editableRef.current;\n\t\tif (!images || !editable) return;\n\t\t// Typing in the description field moves the selection out; keep the image then.\n\t\tconst selection = window.getSelection();\n\t\tif (selection && selection.rangeCount > 0 && !editable.contains(selection.getRangeAt(0).commonAncestorContainer)) return;\n\t\tconst image = imageAtSelection(editable);\n\t\tsetActiveImage(image);\n\t\tsetActiveAlt(image?.getAttribute('alt') ?? '');\n\t}, [images]);\n\n\tuseEffect(() => {\n\t\tif (!images || typeof document === 'undefined') return;\n\t\tdocument.addEventListener('selectionchange', syncActiveImage);\n\t\treturn () => document.removeEventListener('selectionchange', syncActiveImage);\n\t}, [images, syncActiveImage]);\n\n\tconst handleInput = useCallback(() => {\n\t\tconst editable = editableRef.current;\n\t\tif (images && editable) {\n\t\t\tremoveUnsafeImages(editable);\n\t\t\tuploadQueue.prune();\n\t\t\tif (activeImage && !activeImage.isConnected) setActiveImage(null);\n\t\t}\n\t\temitEditableChange();\n\t}, [activeImage, emitEditableChange, images, uploadQueue]);\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\tfocus: () => editableRef.current?.focus(),\n\t\t\tgetHTML: () => normalizeHtml(serializeEditable(editableRef.current)),\n\t\t\tsetHTML: (html: string) => {\n\t\t\t\tconst next = normalizeHtml(html);\n\t\t\t\texternalValueRef.current = next;\n\t\t\t\tif (editableRef.current) {\n\t\t\t\t\teditableRef.current.innerHTML = toEditorContent(next);\n\t\t\t\t}\n\t\t\t\tonValueChange(next);\n\t\t\t},\n\t\t\tinsertHTML: (html: string) => {\n\t\t\t\tinsertHtmlIntoEditable(editableRef.current, html);\n\t\t\t\temitEditableChange();\n\t\t\t},\n\t\t\tisEmpty: () => normalizeHtml(serializeEditable(editableRef.current)) === '',\n\t\t\tclear: () => {\n\t\t\t\texternalValueRef.current = '';\n\t\t\t\tif (editableRef.current) editableRef.current.innerHTML = '<p></p>';\n\t\t\t\tonValueChange('');\n\t\t\t},\n\t\t\tgetCaretContext: () => readCaretContext(),\n\t\t\treplaceBeforeCaret: (length: number, html: string) => {\n\t\t\t\treplaceBeforeCaret(null, length, html, () => emitEditableChange());\n\t\t\t},\n\t\t}),\n\t\t[emitEditableChange, onValueChange],\n\t);\n\n\t// The recipe owns the default body floor; inline style carries only the\n\t// consumer's explicit CSS lengths, which win over that class.\n\tconst bodyMinHeightClassName = richTextEditorRecipes.bodyMinHeight[bodyHeight ?? (compact ? 'control' : 'document')];\n\tconst contentStyle = useMemo(\n\t\t() => ({\n\t\t\t...(minHeight ? { minHeight } : {}),\n\t\t\t...(maxHeight ? { maxHeight, overflowY: 'auto' as const } : {}),\n\t\t}),\n\t\t[maxHeight, minHeight],\n\t);\n\n\tconst toggleSourceMode = useCallback(() => {\n\t\tif (sourceMode) {\n\t\t\tconst normalized = normalizeHtml(sourceValue);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tif (editableRef.current) {\n\t\t\t\teditableRef.current.innerHTML = toEditorContent(normalized);\n\t\t\t}\n\t\t\tonValueChange(normalized);\n\t\t\tsetSourceMode(false);\n\t\t\treturn;\n\t\t}\n\t\tsetSourceValue(editableRef.current?.innerHTML ?? toEditorContent(value));\n\t\tsetSourceMode(true);\n\t}, [onValueChange, sourceMode, sourceValue, value]);\n\n\tconst handleSourceChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLTextAreaElement>) => {\n\t\t\tconst next = e.target.value;\n\t\t\tsetSourceValue(next);\n\t\t\tconst normalized = normalizeHtml(next);\n\t\t\texternalValueRef.current = normalized;\n\t\t\tonValueChange(normalized);\n\t\t},\n\t\t[onValueChange],\n\t);\n\n\tconst placeholderText = typeof placeholder === 'string' ? placeholder : '';\n\tconst isEmpty = normalizeHtml(externalValueRef.current) === '' && uploadQueue.uploads.length === 0;\n\tconst placeholderNode =\n\t\tplaceholderText.length > 0 && !isFocused && isEmpty ? (\n\t\t\t<Text\n\t\t\t\ttag=\"span\"\n\t\t\t\tsize=\"sm\"\n\t\t\t\ttype=\"secondary\"\n\t\t\t\tclassName=\"pointer-events-none absolute inset-0 px-control py-control-y-offset\"\n\t\t\t>\n\t\t\t\t{placeholderText}\n\t\t\t</Text>\n\t\t) : null;\n\n\tconst toolbarButtons = useMemo<ToolbarButtonConfig[]>(\n\t\t() => [\n\t\t\t{ id: 'bold', toggle: true, icon: Bold, label: strings.toolbar.bold, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'italic', toggle: true, icon: Italic, label: strings.toolbar.italic, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'strike', toggle: true, icon: Strikethrough, label: strings.toolbar.strike, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'bullet-list', toggle: true, icon: List, label: strings.toolbar.bulletList, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'ordered-list', toggle: true, icon: ListOrdered, label: strings.toolbar.orderedList, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'blockquote', toggle: true, icon: Quote, label: strings.toolbar.blockquote, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'undo', icon: Undo2, label: strings.toolbar.undo, isActive: () => false, run: () => undefined, disabled: true },\n\t\t\t{ id: 'redo', icon: Redo2, label: strings.toolbar.redo, isActive: () => false, run: () => undefined, disabled: true },\n\t\t],\n\t\t[strings],\n\t);\n\n\tconst text = sourceMode\n\t\t? sourceValue.replace(/<[^>]*>/g, '')\n\t\t: (editableRef.current?.innerText ?? normalizeHtml(value).replace(/<[^>]*>/g, ''));\n\tconst countsFooter =\n\t\tshowCounts ? (\n\t\t\t<CountsFooterText text={text} maxLength={maxLength} strings={strings} />\n\t\t) : null;\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\trichTextEditorRecipes.frame,\n\t\t\t\tdisabled && richTextEditorRecipes.disabled,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<RichTextEditorToolbar\n\t\t\t\tbuttons={toolbarButtons}\n\t\t\t\textraToolbarItems={toolbarItems}\n\t\t\t\thideSourceToggle={hideSourceToggle}\n\t\t\t\tsourceMode={sourceMode}\n\t\t\t\ttoggleSourceMode={toggleSourceMode}\n\t\t\t\tdisabled={disabled}\n\t\t\t\thasEditor\n\t\t\t\ttoolbarTrailing={toolbarTrailing}\n\t\t\t\tstrings={strings}\n\t\t\t/>\n\n\t\t\t{sourceMode ? (\n\t\t\t\t<textarea\n\t\t\t\t\taria-label={strings.sourceLabel}\n\t\t\t\t\tvalue={sourceValue}\n\t\t\t\t\tonChange={handleSourceChange}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tspellCheck={false}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\trichTextEditorRecipes.source,\n\t\t\t\t\t\tbodyMinHeightClassName,\n\t\t\t\t\t\tdisabled && 'cursor-not-allowed',\n\t\t\t\t\t)}\n\t\t\t\t\tstyle={contentStyle}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<div className={cn('relative', bodyMinHeightClassName)} style={contentStyle}>\n\t\t\t\t\t{placeholderNode}\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={setEditableRef}\n\t\t\t\t\t\trole=\"textbox\"\n\t\t\t\t\t\taria-label={strings.editorLabel}\n\t\t\t\t\t\taria-multiline=\"true\"\n\t\t\t\t\t\tcontentEditable={!disabled}\n\t\t\t\t\t\tsuppressContentEditableWarning\n\t\t\t\t\t\tonInput={handleInput}\n\t\t\t\t\t\tonKeyUp={() => onCaretChangeRef.current?.()}\n\t\t\t\t\t\tonMouseUp={() => onCaretChangeRef.current?.()}\n\t\t\t\t\t\tonClick={images ? (event) => {\n\t\t\t\t\t\t\t// A click on an image selects it, so the description field follows.\n\t\t\t\t\t\t\tif (!(event.target instanceof HTMLImageElement)) return;\n\t\t\t\t\t\t\tconst range = document.createRange();\n\t\t\t\t\t\t\trange.selectNode(event.target);\n\t\t\t\t\t\t\tconst selection = window.getSelection();\n\t\t\t\t\t\t\tselection?.removeAllRanges();\n\t\t\t\t\t\t\tselection?.addRange(range);\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonPaste={images ? (event) => {\n\t\t\t\t\t\t\tconst files = imageFilesFrom(event.clipboardData);\n\t\t\t\t\t\t\tif (files.length === 0) return;\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tuploadQueue.addFiles(files);\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonDragOver={images ? (event) => {\n\t\t\t\t\t\t\tif (Array.from(event.dataTransfer.types).includes('Files')) event.preventDefault();\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonDrop={images ? (event) => {\n\t\t\t\t\t\t\tconst files = imageFilesFrom(event.dataTransfer);\n\t\t\t\t\t\t\tif (files.length === 0) return;\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\teditableRef.current?.focus();\n\t\t\t\t\t\t\tplaceCaretAtPoint(event.clientX, event.clientY);\n\t\t\t\t\t\t\tuploadQueue.addFiles(files);\n\t\t\t\t\t\t} : undefined}\n\t\t\t\t\t\tonFocus={() => setIsFocused(true)}\n\t\t\t\t\t\tonBlur={() => setIsFocused(false)}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\teditableContentClassName,\n\t\t\t\t\t\t\t'h-full min-h-full',\n\t\t\t\t\t\t\tdisabled && 'cursor-not-allowed',\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{!!images && (\n\t\t\t\t<ImageDetailsBar\n\t\t\t\t\talt={activeImage ? activeAlt : null}\n\t\t\t\t\tonAltChange={(alt) => {\n\t\t\t\t\t\tsetActiveAlt(alt);\n\t\t\t\t\t\tactiveImage?.setAttribute('alt', alt);\n\t\t\t\t\t\temitEditableChange();\n\t\t\t\t\t}}\n\t\t\t\t\tonRemove={() => {\n\t\t\t\t\t\tactiveImage?.remove();\n\t\t\t\t\t\tsetActiveImage(null);\n\t\t\t\t\t\temitEditableChange();\n\t\t\t\t\t\teditableRef.current?.focus();\n\t\t\t\t\t}}\n\t\t\t\t\tnotice={uploadQueue.notice}\n\t\t\t\t\tonDismissNotice={uploadQueue.dismissNotice}\n\t\t\t\t\tstrings={strings.images}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{!!footerSlot && (\n\t\t\t\t<div className=\"px-control pb-space-md pt-space-xs\">{footerSlot}</div>\n\t\t\t)}\n\n\t\t\t{countsFooter}\n\t\t\t{imageInsert.input}\n\t\t\t<ImageUploadPortals queue={uploadQueue} adapterRef={adapterRef} strings={strings.images} />\n\t\t</div>\n\t);\n});\n\nFallbackRichTextEditor.displayName = 'FallbackRichTextEditor';\n","/**\n * Public `<RichTextEditor>` shell — picks the TipTap-backed editor when\n * the runtime is loaded and falls back to a plain `contenteditable`\n * surface otherwise. Both variants implement the same imperative\n * `RichTextEditorHandle`, so callers don't have to branch.\n *\n * Heavy lifting lives in `partials/`:\n * - `partials/rich-text-editor-tiptap.tsx` — TipTap variant\n * - `partials/rich-text-editor-fallback.tsx` — contenteditable variant\n * - `partials/rich-text-editor-toolbar.tsx` — shared toolbar\n * - `partials/counts-footer.tsx` — char/word counts\n * - `partials/caret-helpers.ts` — caret introspection\n * - `partials/html-helpers.ts` — HTML normalization\n */\nimport { forwardRef } from 'react';\n\nimport {\n\tFallbackRichTextEditor,\n\tTiptapRichTextEditor,\n\thasTiptapRuntime,\n} from './partials';\nimport type {\n\tRichTextEditorHandle,\n\tRichTextEditorProps,\n} from './rich-text-editor.types';\n\nexport const RichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorProps>(function RichTextEditor(\n\tprops,\n\tref,\n) {\n\tif (!hasTiptapRuntime) {\n\t\treturn <FallbackRichTextEditor className=\"rich-text-editor--component\" {...props} ref={ref} />;\n\t}\n\n\treturn <TiptapRichTextEditor {...props} ref={ref} />;\n});\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport type {\n\tRichTextEditorProps,\n\tRichTextEditorHandle,\n\tRichTextEditorToolbarItem,\n\tRichTextCaretContext,\n} from './rich-text-editor.types';\n"],"mappings":"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"}
@@ -1,94 +0,0 @@
1
- "use client";
2
- import { t as e } from "./utils-CF3c95Io.js";
3
- import { n as t } from "./buttons-BbfzgczK.js";
4
- import { i as n } from "./text.styles-B64My8RZ.js";
5
- import { t as r } from "./interaction-recipes-XR9ZpVYL.js";
6
- import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
7
- import { Code2 as s } from "lucide-react";
8
- //#region src/components/features/rich-text-editor/rich-text-editor.recipes.ts
9
- var c = {
10
- source: e("rich-text-editor--source box-border m-0 block min-h-0 w-full resize-y rounded-none border-0 bg-transparent px-control py-control-y-offset outline-none disabled:cursor-not-allowed", n({
11
- type: "main",
12
- size: "xs",
13
- weight: "regular",
14
- align: "left",
15
- lineHeight: "relaxed",
16
- numeric: !0
17
- })),
18
- frame: "min-w-0 overflow-hidden border-input bg-background rounded-inner border",
19
- disabled: "opacity-50",
20
- disabledControl: "disabled:opacity-100 aria-disabled:opacity-100",
21
- content: "h-full [&_.ProseMirror]:h-full [&_.ProseMirror]:min-h-full [&_.ProseMirror]:outline-none",
22
- bodyMinHeight: {
23
- control: "min-h-control-sm",
24
- field: "min-h-textarea-sm",
25
- document: "min-h-48"
26
- }
27
- };
28
- //#endregion
29
- //#region src/components/features/rich-text-editor/partials/rich-text-editor-toolbar.tsx
30
- function l({ buttons: n, extraToolbarItems: l, hideSourceToggle: u = !1, sourceMode: d, toggleSourceMode: f, disabled: p = !1, hasEditor: m = !0, toolbarTrailing: h, strings: g, className: _ }) {
31
- let v = (l?.length ?? 0) > 0;
32
- return /* @__PURE__ */ o("div", {
33
- className: e("rich-text-editor-toolbar--component border-border flex flex-wrap items-center gap-space-xs border-b p-surface-xs", _),
34
- children: [
35
- n.map((n) => {
36
- let i = n.icon, o = n.isActive();
37
- return /* @__PURE__ */ a(t, {
38
- type: "button",
39
- tone: "secondary",
40
- buttonStyle: "ghost",
41
- size: "sm",
42
- iconOnly: !0,
43
- className: e(o ? r.togglePressed : r.toggleHoverButton, p && c.disabledControl),
44
- onClick: n.run,
45
- disabled: p || !m || d || n.disabled,
46
- "aria-pressed": n.toggle ? o : void 0,
47
- "aria-label": n.label,
48
- title: n.label,
49
- children: /* @__PURE__ */ a(i, { className: "size-icon" })
50
- }, n.id);
51
- }),
52
- !u && /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("div", { className: "bg-border mx-space-xs size-icon w-px" }), /* @__PURE__ */ a(t, {
53
- type: "button",
54
- tone: "secondary",
55
- buttonStyle: "ghost",
56
- size: "sm",
57
- iconOnly: !0,
58
- className: e(d ? r.togglePressed : r.toggleHoverButton, p && c.disabledControl),
59
- onClick: f,
60
- disabled: p || !m,
61
- "aria-pressed": d,
62
- "aria-label": g.toolbar.sourceCode,
63
- title: g.toolbar.sourceCode,
64
- children: /* @__PURE__ */ a(s, { className: "size-icon" })
65
- })] }),
66
- v && /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("div", { className: "bg-border mx-space-xs size-icon w-px" }), l?.map((n) => {
67
- let i = n.icon, o = n.isActive?.() ?? !1, s = n.toggle ?? n.isActive !== void 0;
68
- return /* @__PURE__ */ a(t, {
69
- type: "button",
70
- tone: "secondary",
71
- buttonStyle: "ghost",
72
- size: "sm",
73
- iconOnly: !0,
74
- className: e(o ? r.togglePressed : r.toggleHoverButton, p && c.disabledControl),
75
- onClick: n.onClick,
76
- disabled: p || !m || d || n.disabled,
77
- "aria-pressed": s ? o : void 0,
78
- "aria-label": n.label,
79
- title: n.label,
80
- children: /* @__PURE__ */ a(i, { className: "size-icon" })
81
- }, n.id);
82
- })] }),
83
- !!h && /* @__PURE__ */ a("div", {
84
- className: "ml-auto flex items-center gap-space-xs",
85
- children: h
86
- })
87
- ]
88
- });
89
- }
90
- l.displayName = "RichTextEditorToolbar";
91
- //#endregion
92
- export { c as n, l as t };
93
-
94
- //# sourceMappingURL=rich-text-editor-toolbar-L__e4x47.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rich-text-editor-toolbar-L__e4x47.js","names":["_Fragment","cn","Button","resolveTextClassNames","interactionRecipes","richTextEditorRecipes","RichTextEditorToolbar","hasExtras","extraToolbarItems","className","buttons","Icon","button","isActive","disabled","hasEditor","sourceMode","hideSourceToggle","Fragment","toggleSourceMode","strings","Code2","item","toggle","toolbarTrailing"],"sources":["../src/components/features/rich-text-editor/rich-text-editor.recipes.ts","../src/components/features/rich-text-editor/partials/rich-text-editor-toolbar.tsx"],"sourcesContent":["import { resolveTextClassNames } from '../../typography/text.styles';\nimport { cn } from '../../../lib/utils';\n\n/** Shared field anatomy for rich editors, including specialized document schemas. */\nexport const richTextEditorRecipes = {\n source: cn('rich-text-editor--source box-border m-0 block min-h-0 w-full resize-y rounded-none border-0 bg-transparent px-control py-control-y-offset outline-none disabled:cursor-not-allowed', resolveTextClassNames({type: 'main', size: 'xs', weight: 'regular', align: 'left', lineHeight: 'relaxed', numeric: true})),\n frame: 'min-w-0 overflow-hidden border-input bg-background rounded-inner border',\n disabled: 'opacity-50',\n // The frame owns the whole-editor dim; individually unavailable commands\n // keep Button's ordinary disabled treatment while the editor is enabled.\n disabledControl: 'disabled:opacity-100 aria-disabled:opacity-100',\n content: 'h-full [&_.ProseMirror]:h-full [&_.ProseMirror]:min-h-full [&_.ProseMirror]:outline-none',\n // Body floor when the consumer sets no `minHeight`: one small control line, a\n // textarea-sized field (a composer), or a short page (as the email body does).\n bodyMinHeight: { control: 'min-h-control-sm', field: 'min-h-textarea-sm', document: 'min-h-48' },\n} as const;\n","import { Code2 } from 'lucide-react';\nimport type { ReactNode } from 'react';\n\nimport { Button } from '../../../base/buttons/button';\nimport { interactionRecipes } from '../../../../lib/interaction-recipes';\nimport { cn } from '../../../../lib/utils';\n\nimport type { RichTextEditorStrings } from '../rich-text-editor.strings';\nimport { richTextEditorRecipes } from '../rich-text-editor.recipes';\nimport type {\n\tRichTextEditorToolbarItem,\n\tToolbarButtonConfig,\n} from '../rich-text-editor.types';\n\nexport interface RichTextEditorToolbarProps {\n\t/** Formatting controls to show, in order. */\n\tbuttons: ToolbarButtonConfig[];\n\t/** Additional controls appended to the toolbar. */\n\textraToolbarItems?: ReadonlyArray<RichTextEditorToolbarItem>;\n\t/** Hides the control that switches to HTML source. */\n\thideSourceToggle?: boolean;\n\t/** Whether the editor is currently showing HTML source. */\n\tsourceMode: boolean;\n\t/** Switches between rich text and HTML source. */\n\ttoggleSourceMode: () => void;\n\t/** Renders the entry as unselectable. */\n\tdisabled?: boolean;\n\t/**\n\t * The TipTap variant disables built-in buttons until the editor instance\n\t * is ready; the fallback variant simply marks them disabled. This flag\n\t * lets callers force the disabled state without re-deriving it per button.\n\t */\n\thasEditor?: boolean;\n\t/** Content pinned to the end of the toolbar. */\n\ttoolbarTrailing?: ReactNode;\n\t/** Overrides this surface's own copy. */\n\tstrings: RichTextEditorStrings;\n\t/** Merged onto the outermost node. */\n\tclassName?: string;\n}\n\nexport function RichTextEditorToolbar({\n\tbuttons,\n\textraToolbarItems,\n\thideSourceToggle = false,\n\tsourceMode,\n\ttoggleSourceMode,\n\tdisabled = false,\n\thasEditor = true,\n\ttoolbarTrailing,\n\tstrings,\n\tclassName,\n}: RichTextEditorToolbarProps) {\n\tconst hasExtras = (extraToolbarItems?.length ?? 0) > 0;\n\n\treturn (\n\t\t<div className={cn('rich-text-editor-toolbar--component border-border flex flex-wrap items-center gap-space-xs border-b p-surface-xs', className)}>\n\t\t\t{buttons.map((button) => {\n\t\t\t\tconst Icon = button.icon;\n\t\t\t\tconst isActive = button.isActive();\n\n\t\t\t\treturn (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tkey={button.id}\n\t\t\t\t\t\ttype=\"button\"\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\t// A formatting toggle: pressed is the accent fill, hover the lighter muted one.\n\t\t\t\t\t\tclassName={cn(isActive ? interactionRecipes.togglePressed : interactionRecipes.toggleHoverButton, disabled && richTextEditorRecipes.disabledControl)}\n\t\t\t\t\t\tonClick={button.run}\n\t\t\t\t\t\tdisabled={disabled || !hasEditor || sourceMode || button.disabled}\n\t\t\t\t\t\taria-pressed={button.toggle ? isActive : undefined}\n\t\t\t\t\t\taria-label={button.label}\n\t\t\t\t\t\ttitle={button.label}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon className=\"size-icon\" />\n\t\t\t\t\t</Button>\n\t\t\t\t);\n\t\t\t})}\n\n\t\t\t{!hideSourceToggle && (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"bg-border mx-space-xs size-icon w-px\" />\n\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\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\t// Source view is a toggle like the formats: the same pressed fill and state.\n\t\t\t\t\t\tclassName={cn(sourceMode ? interactionRecipes.togglePressed : interactionRecipes.toggleHoverButton, disabled && richTextEditorRecipes.disabledControl)}\n\t\t\t\t\t\tonClick={toggleSourceMode}\n\t\t\t\t\t\tdisabled={disabled || !hasEditor}\n\t\t\t\t\t\taria-pressed={sourceMode}\n\t\t\t\t\t\taria-label={strings.toolbar.sourceCode}\n\t\t\t\t\t\ttitle={strings.toolbar.sourceCode}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Code2 className=\"size-icon\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t{hasExtras && (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"bg-border mx-space-xs size-icon w-px\" />\n\t\t\t\t\t{extraToolbarItems?.map((item) => {\n\t\t\t\t\t\tconst Icon = item.icon;\n\t\t\t\t\t\tconst isActive = item.isActive?.() ?? false;\n\t\t\t\t\t\tconst toggle = item.toggle ?? item.isActive !== undefined;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tkey={item.id}\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\" iconOnly\n\t\t\t\t\t\t\t\tclassName={cn(isActive ? interactionRecipes.togglePressed : interactionRecipes.toggleHoverButton, disabled && richTextEditorRecipes.disabledControl)}\n\t\t\t\t\t\t\t\tonClick={item.onClick}\n\t\t\t\t\t\t\t\tdisabled={disabled || !hasEditor || sourceMode || item.disabled}\n\t\t\t\t\t\t\t\taria-pressed={toggle ? isActive : undefined}\n\t\t\t\t\t\t\t\taria-label={item.label}\n\t\t\t\t\t\t\t\ttitle={item.label}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon className=\"size-icon\" />\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t{!!toolbarTrailing && (\n\t\t\t\t<div className=\"ml-auto flex items-center gap-space-xs\">{toolbarTrailing}</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nRichTextEditorToolbar.displayName = 'RichTextEditorToolbar';\n"],"mappings":";;;;;;;;AAIA,IAAaK,IAAwB;CACpC,QAAQJ,EAAG,sLAAsLE,EAAsB;EAAC,MAAM;EAAQ,MAAM;EAAM,QAAQ;EAAW,OAAO;EAAQ,YAAY;EAAW,SAAS;CAAI,CAAC,CAAC;CAC1T,OAAO;CACP,UAAU;CAGV,iBAAiB;CACjB,SAAS;CAGT,eAAe;EAAE,SAAS;EAAoB,OAAO;EAAqB,UAAU;CAAW;AAChG;;;AC0BA,SAAgBG,EAAsB,EACrC,YACA,sBACA,sBAAmB,IACnB,eACA,qBACA,cAAW,IACX,eAAY,IACZ,oBACA,YACA,gBAC8B;CAC9B,IAAMC,KAAaC,GAAmB,UAAU,KAAK;CAErD,OACC,kBAAC,OAAD;EAAK,WAAWP,EAAG,oHAAoHQ,CAAS;EAAhJ,UAAA;GACEC,EAAQ,KAAK,MAAW;IACxB,IAAMC,IAAOC,EAAO,MACdC,IAAWD,EAAO,SAAS;IAEjC,OACC,kBAACV,GAAD;KAEC,MAAK;KACL,MAAK;KACL,aAAY;KACZ,MAAK;KAAK,UAAA;KAEV,WAAWD,EAAGY,IAAWT,EAAmB,gBAAgBA,EAAmB,mBAAmBU,KAAYT,EAAsB,eAAe;KACnJ,SAASO,EAAO;KAChB,UAAUE,KAAY,CAACC,KAAaC,KAAcJ,EAAO;KACzD,gBAAcA,EAAO,SAASC,IAAW,KAAA;KACzC,cAAYD,EAAO;KACnB,OAAOA,EAAO;KAEd,UAAA,kBAACD,GAAD,EAAM,WAAU,YAAa,CAAA;IACtB,GAdFC,EAAO,EAcL;GAEV,CAAC;GAEA,CAACK,KACD,kBAAAjB,GAAA,EAAA,UAAA,CACC,kBAAC,OAAD,EAAK,WAAU,uCAAwC,CAAA,GAEvD,kBAACE,GAAD;IACC,MAAK;IACL,MAAK;IACL,aAAY;IACZ,MAAK;IAAK,UAAA;IAEV,WAAWD,EAAGe,IAAaZ,EAAmB,gBAAgBA,EAAmB,mBAAmBU,KAAYT,EAAsB,eAAe;IACrJ,SAASc;IACT,UAAUL,KAAY,CAACC;IACvB,gBAAcC;IACd,cAAYI,EAAQ,QAAQ;IAC5B,OAAOA,EAAQ,QAAQ;IAEvB,UAAA,kBAACC,GAAD,EAAO,WAAU,YAAa,CAAA;GACvB,CAAA,CACP,EAAA,CAAA;GAGFd,KACA,kBAAAP,GAAA,EAAA,UAAA,CACC,kBAAC,OAAD,EAAK,WAAU,uCAAwC,CAAA,GACtDQ,GAAmB,KAAK,MAAS;IACjC,IAAMG,IAAOW,EAAK,MACZT,IAAWS,EAAK,WAAW,KAAK,IAChCC,IAASD,EAAK,UAAUA,EAAK,aAAa,KAAA;IAChD,OACC,kBAACpB,GAAD;KAEC,MAAK;KACL,MAAK;KACL,aAAY;KACZ,MAAK;KAAK,UAAA;KACV,WAAWD,EAAGY,IAAWT,EAAmB,gBAAgBA,EAAmB,mBAAmBU,KAAYT,EAAsB,eAAe;KACnJ,SAASiB,EAAK;KACd,UAAUR,KAAY,CAACC,KAAaC,KAAcM,EAAK;KACvD,gBAAcC,IAASV,IAAW,KAAA;KAClC,cAAYS,EAAK;KACjB,OAAOA,EAAK;KAEZ,UAAA,kBAACX,GAAD,EAAM,WAAU,YAAa,CAAA;IACtB,GAbFW,EAAK,EAaH;GAEV,CAAC,CACA,EAAA,CAAA;GAGF,CAAC,CAACE,KACF,kBAAC,OAAD;IAAK,WAAU;IAA0C,UAAAA;GAAqB,CAAA;EAE3E;;AAEP;AAEA,EAAsB,cAAc"}
@@ -1,17 +0,0 @@
1
- //#region src/lib/safe-image-src.ts
2
- var e = [
3
- "http",
4
- "https",
5
- "blob"
6
- ];
7
- function t(t) {
8
- if (typeof t != "string") return;
9
- let n = t.trim();
10
- if (!n || n.startsWith("//") || n.startsWith("\\\\")) return;
11
- let r = n.replace(/[\u0000- \u007F]+/g, ""), i = /^([a-z][a-z0-9+.-]*):/i.exec(r)?.[1]?.toLowerCase();
12
- return i ? e.includes(i) ? n : void 0 : n;
13
- }
14
- //#endregion
15
- export { t as n, e as t };
16
-
17
- //# sourceMappingURL=safe-image-src-C6kQSMBZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"safe-image-src-C6kQSMBZ.js","names":["SAFE_IMAGE_SCHEMES","safeImageSrc","value","src","compact","scheme"],"sources":["../src/lib/safe-image-src.ts"],"sourcesContent":["/** Schemes an image `src` may use: web URLs and same-document `blob:` previews. */\nexport const SAFE_IMAGE_SCHEMES = ['http', 'https', 'blob'] as const;\n\n/**\n * The one image-source policy shared by the editor and read-only rich text.\n * Returns the source when it is a web URL, a `blob:` preview or a relative\n * path, and `undefined` otherwise: script, `data:` and other schemes and\n * protocol-relative (`//host`) URLs are refused. Control characters and\n * whitespace inside a scheme are ignored, so `java\\tscript:` is still refused.\n */\nexport function safeImageSrc(value: unknown): string | undefined {\n\tif (typeof value !== 'string') return undefined;\n\tconst src = value.trim();\n\tif (!src || src.startsWith('//') || src.startsWith('\\\\\\\\')) return undefined;\n\t// eslint-disable-next-line no-control-regex\n\tconst compact = src.replace(/[\\u0000- \\u007F]+/g, '');\n\tconst scheme = /^([a-z][a-z0-9+.-]*):/i.exec(compact)?.[1]?.toLowerCase();\n\tif (!scheme) return src;\n\treturn (SAFE_IMAGE_SCHEMES as readonly string[]).includes(scheme) ? src : undefined;\n}\n"],"mappings":";AACA,IAAaA,IAAqB;CAAC;CAAQ;CAAS;AAAM;AAS1D,SAAgBC,EAAa,GAAoC;CAChE,IAAI,OAAOC,KAAU,UAAU;CAC/B,IAAMC,IAAMD,EAAM,KAAK;CACvB,IAAI,CAACC,KAAOA,EAAI,WAAW,IAAI,KAAKA,EAAI,WAAW,MAAM,GAAG;CAE5D,IAAMC,IAAUD,EAAI,QAAQ,sBAAsB,EAAE,GAC9CE,IAAS,yBAAyB,KAAKD,CAAO,CAAC,GAAG,EAAE,EAAE,YAAY;CAExE,OADKC,IACGL,EAAyC,SAASK,CAAM,IAAIF,IAAM,KAAA,IADtDA;AAErB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"sanitize-html-DsQmI48u.js","names":["safeImageSrc","ALLOWED_TAGS","SANITIZE_SCHEMA","SANITIZE_SCHEMA_WITH_IMAGES","SAFE_IMAGE_SCHEMES","removeUnsafeImages","node","child","removeProtocolRelativeLinks","href","sanitizeHtml","input","toHtml","sanitizeHtmlTree","options","unsafeTree","fromHtml","tree","sanitize"],"sources":["../src/lib/sanitize-html.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';\n\nimport { SAFE_IMAGE_SCHEMES, safeImageSrc } from './safe-image-src';\n\nconst ALLOWED_TAGS = [\n\t'a',\n\t'b',\n\t'blockquote',\n\t'br',\n\t'code',\n\t'del',\n\t'div',\n\t'em',\n\t'h1',\n\t'h2',\n\t'h3',\n\t'h4',\n\t'h5',\n\t'h6',\n\t'i',\n\t'li',\n\t'mark',\n\t'ol',\n\t'p',\n\t'pre',\n\t's',\n\t'span',\n\t'strong',\n\t'sub',\n\t'sup',\n\t'u',\n\t'ul',\n] as const;\n\nconst SANITIZE_SCHEMA = {\n\tallowComments: false,\n\tallowDoctypes: false,\n\ttagNames: [...ALLOWED_TAGS],\n\tattributes: {\n\t\ta: [\n\t\t\t'href',\n\t\t\t'title',\n\t\t\t['target', '_blank', '_self', '_parent', '_top'],\n\t\t\t'rel',\n\t\t\t'dataRefId',\n\t\t\t'dataRefKind',\n\t\t\t'dataRefTone',\n\t\t],\n\t\tspan: ['dataRefId', 'dataRefKind', 'dataRefTone'],\n\t},\n\tprotocols: {\n\t\thref: ['http', 'https', 'mailto', 'tel'],\n\t},\n\tstrip: [\n\t\t'embed',\n\t\t'iframe',\n\t\t'math',\n\t\t'noscript',\n\t\t'object',\n\t\t'script',\n\t\t'style',\n\t\t'svg',\n\t\t'template',\n\t],\n} satisfies Schema;\n\n/** The same vocabulary plus images whose source passes `safeImageSrc`. */\nconst SANITIZE_SCHEMA_WITH_IMAGES = {\n\t...SANITIZE_SCHEMA,\n\ttagNames: [...ALLOWED_TAGS, 'img'],\n\tattributes: {\n\t\t...SANITIZE_SCHEMA.attributes,\n\t\timg: ['src', 'alt', 'title', 'width', 'height'],\n\t},\n\tprotocols: {\n\t\t...SANITIZE_SCHEMA.protocols,\n\t\tsrc: [...SAFE_IMAGE_SCHEMES],\n\t},\n} satisfies Schema;\n\nexport interface SanitizeHtmlOptions {\n\t/**\n\t * Keeps `<img>` with `src`, `alt`, `title`, `width` and `height` when its\n\t * source passes `safeImageSrc`; an image without a safe source is removed.\n\t * Default: `false`, which removes every image.\n\t */\n\timages?: boolean;\n}\n\nfunction removeUnsafeImages(node: Root | RootContent): void {\n\tif (node.type !== 'root' && node.type !== 'element') return;\n\tnode.children = node.children.filter(\n\t\t(child) => child.type !== 'element' || child.tagName !== 'img' || safeImageSrc(child.properties.src) !== undefined,\n\t);\n\tfor (const child of node.children) removeUnsafeImages(child);\n}\n\nfunction removeProtocolRelativeLinks(node: Root | RootContent): void {\n\tif (node.type === 'element') {\n\t\tconst href = node.properties.href;\n\t\tif (typeof href === 'string' && href.trimStart().startsWith('//')) {\n\t\t\tdelete node.properties.href;\n\t\t}\n\t}\n\n\tif (node.type === 'root' || node.type === 'element') {\n\t\tfor (const child of node.children) {\n\t\t\tremoveProtocolRelativeLinks(child);\n\t\t}\n\t}\n}\n\n/**\n * Sanitize package-rendered rich text with an intentionally small HTML\n * vocabulary. Styling, event handlers, embedded media, and protocol-relative\n * URLs are excluded; images only with `options.images` and a safe source.\n * Mention identity attributes remain available so the Mentions feature can\n * replace serialized references with React components.\n */\nexport function sanitizeHtml(input: string, options: SanitizeHtmlOptions = {}): string {\n\tif (!input) return '';\n\treturn toHtml(sanitizeHtmlTree(input, options));\n}\n\n/** The sanitized tree behind `sanitizeHtml`, for renderers that substitute elements. */\nexport function sanitizeHtmlTree(input: string, options: SanitizeHtmlOptions = {}): Root {\n\tconst unsafeTree = fromHtml(input ?? '', { fragment: true });\n\tremoveProtocolRelativeLinks(unsafeTree);\n\tconst tree = sanitize(unsafeTree, options.images ? SANITIZE_SCHEMA_WITH_IMAGES : SANITIZE_SCHEMA) as Root;\n\tif (options.images) removeUnsafeImages(tree);\n\treturn tree;\n}\n\nexport default sanitizeHtml;\n"],"mappings":";;;;;AAOA,IAAMC,IAAe,6HA4BrB,GAEMC,IAAkB;CACvB,eAAe;CACf,eAAe;CACf,UAAU,CAAC,GAAGD,CAAY;CAC1B,YAAY;EACX,GAAG;GACF;GACA;GACA;IAAC;IAAU;IAAU;IAAS;IAAW;GAAM;GAC/C;GACA;GACA;GACA;EACD;EACA,MAAM;GAAC;GAAa;GAAe;EAAa;CACjD;CACA,WAAW,EACV,MAAM;EAAC;EAAQ;EAAS;EAAU;CAAK,EACxC;CACA,OAAO;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD;AACD,GAGME,IAA8B;CACnC,GAAGD;CACH,UAAU,CAAC,GAAGD,GAAc,KAAK;CACjC,YAAY;EACX,GAAGC,EAAgB;EACnB,KAAK;GAAC;GAAO;GAAO;GAAS;GAAS;EAAQ;CAC/C;CACA,WAAW;EACV,GAAGA,EAAgB;EACnB,KAAK,CAAC,GAAGE,CAAkB;CAC5B;AACD;AAWA,SAASC,EAAmB,GAAgC;CAC3D,IAAIC,EAAK,SAAS,UAAUA,EAAK,SAAS,WAC1C;IAAK,WAAWA,EAAK,SAAS,QAC5B,MAAUC,EAAM,SAAS,aAAaA,EAAM,YAAY,SAASP,EAAaO,EAAM,WAAW,GAAG,MAAM,KAAA,CAC1G;EACA,KAAK,IAAMA,KAASD,EAAK,UAAU,EAAmBC,CAAK;CAD3D;AAED;AAEA,SAASC,EAA4B,GAAgC;CACpE,IAAIF,EAAK,SAAS,WAAW;EAC5B,IAAMG,IAAOH,EAAK,WAAW;EAC7B,AAAI,OAAOG,KAAS,YAAYA,EAAK,UAAU,CAAC,CAAC,WAAW,IAAI,KAC/D,OAAOH,EAAK,WAAW;CAEzB;CAEA,IAAIA,EAAK,SAAS,UAAUA,EAAK,SAAS,WACzC,KAAK,IAAMC,KAASD,EAAK,UACxB,EAA4BC,CAAK;AAGpC;AASA,SAAgBG,EAAa,GAAe,IAA+B,CAAC,GAAW;CAEtF,OADKC,IACEC,EAAOC,EAAiBF,GAAOG,CAAO,CAAC,IAD3B;AAEpB;AAGA,SAAgBD,EAAiB,GAAe,IAA+B,CAAC,GAAS;CACxF,IAAME,IAAaC,EAASL,KAAS,IAAI,EAAE,UAAU,GAAK,CAAC;CAC3D,EAA4BI,CAAU;CACtC,IAAME,IAAOC,EAASH,GAAYD,EAAQ,SAASX,IAA8BD,CAAe;CAEhG,OADIY,EAAQ,UAAQT,EAAmBY,CAAI,GACpCA;AACR"}
@@ -1,174 +0,0 @@
1
- "use client";
2
- import { useStrings as e } from "./lib/strings.js";
3
- import { t } from "./utils-CF3c95Io.js";
4
- import { c as n, o as r, s as i } from "./typography-CSyJrh28.js";
5
- import { n as a, t as o } from "./text.styles-B64My8RZ.js";
6
- import { t as s } from "./focus-recipes-B653VaLq.js";
7
- import { t as c } from "./structure-C0V0_Fyf.js";
8
- import { t as l } from "./smart-card-CqkzQsK-.js";
9
- import { n as u, t as d } from "./composition.recipes-COdiFhxB.js";
10
- import { t as f } from "./interaction-recipes-XR9ZpVYL.js";
11
- import { t as p } from "./badge-DErMA7ul.js";
12
- import { n as m, t as h } from "./page-header-commands-DFMlNYzN.js";
13
- import { n as g } from "./layout.types-Cn7aUzJp.js";
14
- import { jsx as _, jsxs as v } from "react/jsx-runtime";
15
- //#region src/components/layout/settings/settings.tsx
16
- var y = { navigationAriaLabel: "Settings navigation" };
17
- function b(e) {
18
- if (!e) return "";
19
- try {
20
- let t = typeof window < "u" ? window.location.origin : "http://localhost", n = new URL(e, t).pathname.replace(/\/+$/, "");
21
- return n.length > 0 ? n : "/";
22
- } catch {
23
- let t = (e.split("?")[0] ?? e).replace(/\/+$/, "");
24
- return t.length > 0 ? t : "/";
25
- }
26
- }
27
- function x(e, t, n) {
28
- if (t) return e.id === t;
29
- if (!n || !e.href) return !1;
30
- let r = b(n), i = b(e.href);
31
- return r === i || r.startsWith(`${i}/`);
32
- }
33
- function S({ title: b, description: S, groups: C, currentId: w, currentPath: T, children: E, aside: D, actions: O, primaryAction: k, secondaryActions: A, moreActionsLabel: j = "More actions", footer: M, className: N, navClassName: P, contentClassName: F, renderLink: I, strings: L }) {
34
- let R = e(y, L), z = g({ renderLink: I }), B = m(k, A);
35
- return /* @__PURE__ */ v("section", {
36
- "data-component": "aside-nav-shell",
37
- "data-slot": "aside-nav-shell",
38
- className: t("aside-nav-shell--component grid min-w-0 lg:grid-cols-[17rem_minmax(0,1fr)]", d.subjects, N),
39
- children: [/* @__PURE__ */ _("aside", {
40
- "data-slot": "aside-nav-shell-aside",
41
- className: "aside-nav-shell--aside min-w-0",
42
- children: /* @__PURE__ */ v(l, {
43
- surface: "card",
44
- className: t("aside-nav-shell--nav-card sticky top-[calc(var(--shell-header-height)_+_1rem*var(--space-scale))]", P),
45
- contentClassName: "grid gap-space-xl",
46
- children: [!!D && /* @__PURE__ */ _("div", {
47
- className: "aside-nav-shell--aside-header",
48
- children: D
49
- }), /* @__PURE__ */ _(c, {
50
- render: /* @__PURE__ */ _("nav", { "aria-label": R.navigationAriaLabel }),
51
- gap: "xl",
52
- children: C.map((e) => /* @__PURE__ */ v(c, {
53
- gap: "sm",
54
- children: [!!e.label && /* @__PURE__ */ _(r, {
55
- className: "px-row-x text-inherit",
56
- children: e.label
57
- }), /* @__PURE__ */ _(c, {
58
- gap: "2xs",
59
- children: e.items.map((e) => {
60
- let r = e.icon, i = x(e, w, T), a = /* @__PURE__ */ v(c, {
61
- direction: "horizontal",
62
- align: "start",
63
- gap: "md",
64
- wrap: !1,
65
- render: /* @__PURE__ */ _("span", {}),
66
- className: "min-w-0 w-full",
67
- children: [
68
- !!r && /* @__PURE__ */ _(r, { className: t("size-icon shrink-0 mt-space-2xs", i ? "text-accent-foreground" : "text-muted-foreground") }),
69
- /* @__PURE__ */ v(c, {
70
- render: /* @__PURE__ */ _("span", {}),
71
- gap: "dense",
72
- className: "min-w-0 flex-1",
73
- children: [/* @__PURE__ */ _(n, {
74
- tag: "span",
75
- type: "inherit",
76
- weight: i ? "semibold" : "medium",
77
- className: "truncate",
78
- children: e.label
79
- }), !!e.description && /* @__PURE__ */ _(n, {
80
- tag: "span",
81
- size: "xs",
82
- type: "secondary",
83
- className: "truncate",
84
- children: e.description
85
- })]
86
- }),
87
- !!e.badge && /* @__PURE__ */ _(p, {
88
- tone: "secondary",
89
- className: "shrink-0",
90
- children: e.badge
91
- })
92
- ]
93
- });
94
- return /* @__PURE__ */ _("div", {
95
- onClick: () => {
96
- e.disabled || e.onSelect?.(e.id);
97
- },
98
- children: z({
99
- href: e.href,
100
- children: a,
101
- active: i,
102
- disabled: e.disabled,
103
- external: e.external,
104
- className: t("aside-nav-shell--item flex min-w-0 rounded-inner px-row-x py-row-y transition-colors", `focus-visible:outline-none ${s.edge}`, i ? f.rowSelected : `text-inherit ${f.rowHover}`, e.disabled && "pointer-events-none opacity-50"),
105
- "aria-label": typeof e.label == "string" ? e.label : void 0
106
- })
107
- }, e.id);
108
- })
109
- })]
110
- }, e.id))
111
- })]
112
- })
113
- }), /* @__PURE__ */ v(c, {
114
- gap: u.subjects,
115
- "data-slot": "aside-nav-shell-main",
116
- className: t("aside-nav-shell--main", F),
117
- children: [
118
- (b || S || O || B) && /* @__PURE__ */ v(c, {
119
- render: /* @__PURE__ */ _("header", {}),
120
- direction: {
121
- base: "vertical",
122
- sm: "horizontal"
123
- },
124
- gap: "lg",
125
- align: { sm: "start" },
126
- justify: { sm: "between" },
127
- className: "aside-nav-shell--header",
128
- children: [/* @__PURE__ */ v(c, {
129
- gap: "normal",
130
- className: "min-w-0 flex-1",
131
- children: [!!b && /* @__PURE__ */ _(i, {
132
- tag: "h2",
133
- size: a.subject,
134
- className: "border-0 pb-0",
135
- children: b
136
- }), !!S && /* @__PURE__ */ _(n, {
137
- ...o.structuralDescription,
138
- className: "max-w-3xl",
139
- children: S
140
- })]
141
- }), !!(O || B) && /* @__PURE__ */ v(c, {
142
- direction: "horizontal",
143
- wrap: !0,
144
- align: "center",
145
- justify: B ? "end" : void 0,
146
- gap: u.commands,
147
- className: "aside-nav-shell--actions shrink-0",
148
- children: [O, B && /* @__PURE__ */ _(h, {
149
- primaryAction: k,
150
- secondaryActions: A,
151
- moreActionsLabel: j,
152
- renderLink: z
153
- })]
154
- })]
155
- }),
156
- /* @__PURE__ */ _("div", {
157
- "data-slot": "aside-nav-shell-content",
158
- className: "aside-nav-shell--content min-w-0",
159
- children: E
160
- }),
161
- !!M && /* @__PURE__ */ _("footer", {
162
- className: "aside-nav-shell--footer",
163
- children: M
164
- })
165
- ]
166
- })]
167
- });
168
- }
169
- var C = S;
170
- S.displayName = "AsideNavShell";
171
- //#endregion
172
- export { C as n, y as r, S as t };
173
-
174
- //# sourceMappingURL=settings-BA2iboic.js.map