@prolibu-suite/cobalt-core 0.1.2 → 0.3.0

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 (682) hide show
  1. package/custom-elements.json +21351 -7087
  2. package/dist/cjs/co-accordion.cjs.entry.js +19 -4
  3. package/dist/cjs/co-app-shell.cjs.entry.js +4 -4
  4. package/dist/cjs/co-autocomplete.cjs.entry.js +54 -6
  5. package/dist/cjs/co-avatar-group.cjs.entry.js +77 -0
  6. package/dist/cjs/co-avatar.cjs.entry.js +42 -7
  7. package/dist/cjs/co-badge.cjs.entry.js +2 -2
  8. package/dist/cjs/co-bottom-sheet.cjs.entry.js +325 -0
  9. package/dist/cjs/co-button-group.cjs.entry.js +3 -3
  10. package/dist/cjs/co-button.cjs.entry.js +12 -7
  11. package/dist/cjs/co-calendar-month.cjs.entry.js +381 -0
  12. package/dist/cjs/co-calendar_3.cjs.entry.js +692 -0
  13. package/dist/cjs/co-card.cjs.entry.js +21 -4
  14. package/dist/cjs/co-checkbox-group.cjs.entry.js +7 -5
  15. package/dist/cjs/co-checkbox.cjs.entry.js +5 -5
  16. package/dist/cjs/co-chip.cjs.entry.js +11 -8
  17. package/dist/cjs/co-color-picker.cjs.entry.js +111 -0
  18. package/dist/cjs/co-column-picker.cjs.entry.js +443 -0
  19. package/dist/cjs/co-combobox.cjs.entry.js +51 -15
  20. package/dist/cjs/co-command-search.cjs.entry.js +159 -13
  21. package/dist/cjs/co-data-table-pagination.cjs.entry.js +5 -5
  22. package/dist/cjs/co-data-table.cjs.entry.js +38 -12
  23. package/dist/cjs/co-date-picker.cjs.entry.js +177 -0
  24. package/dist/cjs/co-date-range-picker.cjs.entry.js +378 -0
  25. package/dist/cjs/co-date-range.cjs.entry.js +13 -259
  26. package/dist/cjs/co-empty-state.cjs.entry.js +2 -2
  27. package/dist/cjs/co-event-calendar.cjs.entry.js +318 -0
  28. package/dist/cjs/co-fab.cjs.entry.js +3 -3
  29. package/dist/cjs/co-file-field.cjs.entry.js +498 -0
  30. package/dist/cjs/co-helper-text.cjs.entry.js +3 -3
  31. package/dist/cjs/co-icon-button.cjs.entry.js +6 -6
  32. package/dist/cjs/co-icon.cjs.entry.js +36 -25
  33. package/dist/cjs/co-input.cjs.entry.js +13 -8
  34. package/dist/cjs/co-json-field.cjs.entry.js +113 -0
  35. package/dist/cjs/co-lightbox.cjs.entry.js +344 -0
  36. package/dist/cjs/co-list-footer.cjs.entry.js +25 -0
  37. package/dist/cjs/co-list-item.cjs.entry.js +70 -4
  38. package/dist/cjs/co-loader_2.cjs.entry.js +293 -0
  39. package/dist/cjs/co-menu-divider.cjs.entry.js +2 -2
  40. package/dist/cjs/co-menu-item.cjs.entry.js +17 -10
  41. package/dist/cjs/co-menu.cjs.entry.js +2 -2
  42. package/dist/cjs/co-modal.cjs.entry.js +25 -3
  43. package/dist/cjs/co-navbar.cjs.entry.js +4 -4
  44. package/dist/cjs/co-number-field.cjs.entry.js +60 -12
  45. package/dist/cjs/co-page-header.cjs.entry.js +2 -2
  46. package/dist/cjs/co-phone-field.cjs.entry.js +378 -0
  47. package/dist/cjs/co-popover.cjs.entry.js +46 -15
  48. package/dist/cjs/co-progress-bar.cjs.entry.js +8 -4
  49. package/dist/cjs/co-progress-circle.cjs.entry.js +38 -0
  50. package/dist/cjs/co-radio-group.cjs.entry.js +7 -5
  51. package/dist/cjs/co-radio.cjs.entry.js +4 -4
  52. package/dist/cjs/co-rating.cjs.entry.js +4 -4
  53. package/dist/cjs/co-ref-field.cjs.entry.js +214 -21
  54. package/dist/cjs/co-rich-text-editor.cjs.entry.js +2081 -0
  55. package/dist/cjs/co-rich-text-toolbar.cjs.entry.js +1108 -0
  56. package/dist/cjs/co-rich-text-viewer.cjs.entry.js +118 -0
  57. package/dist/cjs/co-row.cjs.entry.js +3 -3
  58. package/dist/cjs/co-select.cjs.entry.js +119 -18
  59. package/dist/cjs/co-separator.cjs.entry.js +2 -2
  60. package/dist/cjs/co-sidebar-nav.cjs.entry.js +55 -10
  61. package/dist/cjs/co-sidebar.cjs.entry.js +3 -3
  62. package/dist/cjs/co-skeleton.cjs.entry.js +26 -0
  63. package/dist/cjs/co-slider.cjs.entry.js +3 -3
  64. package/dist/cjs/co-switch.cjs.entry.js +9 -6
  65. package/dist/cjs/co-tab-group.cjs.entry.js +2 -2
  66. package/dist/cjs/co-tab.cjs.entry.js +3 -3
  67. package/dist/cjs/co-tags-field.cjs.entry.js +211 -0
  68. package/dist/cjs/co-textarea.cjs.entry.js +96 -0
  69. package/dist/cjs/co-toast.cjs.entry.js +2 -2
  70. package/dist/cjs/co-toggle-button-group.cjs.entry.js +7 -4
  71. package/dist/cjs/co-toggle-button.cjs.entry.js +4 -4
  72. package/dist/cjs/co-tooltip.cjs.entry.js +56 -15
  73. package/dist/cjs/co-transfer-list.cjs.entry.js +20 -6
  74. package/dist/cjs/co-video.cjs.entry.js +839 -0
  75. package/dist/cjs/cobalt.cjs.js +2 -2
  76. package/dist/cjs/dateI18n-BdiNAl0_.js +106 -0
  77. package/dist/cjs/dates-D8D-aS5d.js +432 -0
  78. package/dist/cjs/fieldChip-CDIMz_Y6.js +7 -0
  79. package/dist/cjs/index-5NdsiFjZ.js +35405 -0
  80. package/dist/cjs/{index-BEovErzl.js → index-BumlM92r.js} +115 -23
  81. package/dist/cjs/loader.cjs.js +2 -2
  82. package/dist/cjs/normalizeText-B-v-XPKf.js +96 -0
  83. package/dist/cjs/overlayAfterClose-BdeXrhVY.js +12 -0
  84. package/dist/cjs/overlayScroll-ifzDNeyb.js +25 -0
  85. package/dist/cjs/overlayscrollbars-BlBHo2Xx.js +2842 -0
  86. package/dist/cjs/{positioning-DozpXyBd.js → positioning-DwHW399W.js} +40 -25
  87. package/dist/cjs/purify.es-DX41ZWS2.js +1776 -0
  88. package/dist/cjs/requiredMark-CqMGt1H1.js +16 -0
  89. package/dist/cjs/richTextI18n-B7ktXg3M.js +382 -0
  90. package/dist/cjs/toolbar-config-3PlT-3zm.js +216 -0
  91. package/dist/cjs/tz-Dgom0W69.js +127 -0
  92. package/dist/cobalt/cobalt.css +1 -1
  93. package/dist/cobalt/cobalt.esm.js +1 -1
  94. package/dist/cobalt/p-0a506c9d.entry.js +1 -0
  95. package/dist/cobalt/p-0bb55163.entry.js +1 -0
  96. package/dist/cobalt/{p-fb047df8.entry.js → p-0e8c0d87.entry.js} +1 -1
  97. package/dist/cobalt/p-12e2c2c4.entry.js +1 -0
  98. package/dist/cobalt/p-136ad468.entry.js +1 -0
  99. package/dist/cobalt/p-14b59277.entry.js +1 -0
  100. package/dist/cobalt/p-1531d3c9.entry.js +1 -0
  101. package/dist/cobalt/p-1774d211.entry.js +1 -0
  102. package/dist/cobalt/{p-c7517f86.entry.js → p-180e1106.entry.js} +1 -1
  103. package/dist/cobalt/p-1a07c23c.entry.js +1 -0
  104. package/dist/cobalt/p-1dc9c49e.entry.js +1 -0
  105. package/dist/cobalt/p-1f747e45.entry.js +1 -0
  106. package/dist/cobalt/{p-d29c77cb.entry.js → p-201eaf35.entry.js} +1 -1
  107. package/dist/cobalt/p-260101ab.entry.js +1 -0
  108. package/dist/cobalt/p-279bf91c.entry.js +1 -0
  109. package/dist/cobalt/p-29be61a9.entry.js +1 -0
  110. package/dist/cobalt/p-2d2ce434.entry.js +1 -0
  111. package/dist/cobalt/{p-416bb5ae.entry.js → p-2f86e1e0.entry.js} +1 -1
  112. package/dist/cobalt/{p-4cf6d1f4.entry.js → p-31ab9a46.entry.js} +1 -1
  113. package/dist/cobalt/{p-319937c3.entry.js → p-37595103.entry.js} +1 -1
  114. package/dist/cobalt/p-377c2ccc.entry.js +1 -0
  115. package/dist/cobalt/p-3863ea91.entry.js +1 -0
  116. package/dist/cobalt/p-3a257cb0.entry.js +1 -0
  117. package/dist/cobalt/p-3e187456.entry.js +1 -0
  118. package/dist/cobalt/p-4431faac.entry.js +1 -0
  119. package/dist/cobalt/{p-4d8ff00a.entry.js → p-4504f7b0.entry.js} +1 -1
  120. package/dist/cobalt/p-456fa86f.entry.js +1 -0
  121. package/dist/cobalt/p-4871690e.entry.js +1 -0
  122. package/dist/cobalt/p-4c01d984.entry.js +1 -0
  123. package/dist/cobalt/p-51a53177.entry.js +1 -0
  124. package/dist/cobalt/p-52de17da.entry.js +1 -0
  125. package/dist/cobalt/p-5890e4d1.entry.js +1 -0
  126. package/dist/cobalt/{p-e50c4c6f.entry.js → p-58a53421.entry.js} +1 -1
  127. package/dist/cobalt/p-62274eba.entry.js +1 -0
  128. package/dist/cobalt/p-635b03d5.entry.js +1 -0
  129. package/dist/cobalt/p-64ddee92.entry.js +1 -0
  130. package/dist/cobalt/p-65af5017.entry.js +1 -0
  131. package/dist/cobalt/p-69d4c0c8.entry.js +1 -0
  132. package/dist/cobalt/p-6c480916.entry.js +1 -0
  133. package/dist/cobalt/p-6d1217c3.entry.js +1 -0
  134. package/dist/cobalt/p-6e808b3a.entry.js +1 -0
  135. package/dist/cobalt/{p-697df797.entry.js → p-70b14b05.entry.js} +1 -1
  136. package/dist/cobalt/{p-1d7da33f.entry.js → p-790d384e.entry.js} +1 -1
  137. package/dist/cobalt/p-8012e152.entry.js +1 -0
  138. package/dist/cobalt/p-80b27203.entry.js +1 -0
  139. package/dist/cobalt/p-867c1465.entry.js +1 -0
  140. package/dist/cobalt/p-86a143d7.entry.js +1 -0
  141. package/dist/cobalt/{p-3b2f7959.entry.js → p-8d59f5ad.entry.js} +1 -1
  142. package/dist/cobalt/p-8d7fdb9d.entry.js +1 -0
  143. package/dist/cobalt/p-8dc1dab8.entry.js +1 -0
  144. package/dist/cobalt/p-8e1dc062.entry.js +1 -0
  145. package/dist/cobalt/p-929e647f.entry.js +1 -0
  146. package/dist/cobalt/p-92bd9b29.entry.js +1 -0
  147. package/dist/cobalt/p-93046365.entry.js +1 -0
  148. package/dist/cobalt/p-98ab5f3f.entry.js +1 -0
  149. package/dist/cobalt/p-9a04ca90.entry.js +1 -0
  150. package/dist/cobalt/{p-ebd1555e.entry.js → p-9a088515.entry.js} +1 -1
  151. package/dist/cobalt/p-9abbd436.entry.js +1 -0
  152. package/dist/cobalt/p-9d69c067.entry.js +1 -0
  153. package/dist/cobalt/p-B-ckjCUA.js +1 -0
  154. package/dist/cobalt/p-B2QLgWrz.js +2 -0
  155. package/dist/cobalt/p-B6JZk8fL.js +1 -0
  156. package/dist/cobalt/p-BZJ7NCm5.js +1 -0
  157. package/dist/cobalt/p-C1DCLOEl.js +1 -0
  158. package/dist/cobalt/p-C2mZ7x_Y.js +1 -0
  159. package/dist/cobalt/p-CQY6Ul7q.js +1 -0
  160. package/dist/cobalt/p-CYsftTKf.js +2 -0
  161. package/dist/cobalt/p-CegCk7FL.js +1 -0
  162. package/dist/cobalt/p-Ch1jfwZ2.js +1 -0
  163. package/dist/cobalt/p-ChibIpZv.js +1 -0
  164. package/dist/cobalt/p-DqyWGweA.js +1 -0
  165. package/dist/cobalt/p-afb7e19e.entry.js +1 -0
  166. package/dist/cobalt/p-b6f20268.entry.js +1 -0
  167. package/dist/cobalt/p-ba90e871.entry.js +1 -0
  168. package/dist/cobalt/p-c10697e1.entry.js +1 -0
  169. package/dist/cobalt/p-c4f59532.entry.js +1 -0
  170. package/dist/cobalt/{p-1b5c723a.entry.js → p-cb235aa7.entry.js} +1 -1
  171. package/dist/cobalt/p-cfb36943.entry.js +1 -0
  172. package/dist/cobalt/p-d809bd44.entry.js +1 -0
  173. package/dist/cobalt/p-e53861e4.entry.js +1 -0
  174. package/dist/cobalt/p-e54dd404.entry.js +1 -0
  175. package/dist/cobalt/{p-1021f612.entry.js → p-eb18fdbf.entry.js} +1 -1
  176. package/dist/cobalt/{p-a7fa4484.entry.js → p-eb73052a.entry.js} +1 -1
  177. package/dist/cobalt/p-ef7d4ae3.entry.js +1 -0
  178. package/dist/cobalt/p-f4063c41.entry.js +1 -0
  179. package/dist/cobalt/p-oImf-7fN.js +1 -0
  180. package/dist/cobalt/p-ox7HzCZn.js +10 -0
  181. package/dist/cobalt/p-tPYikBRJ.js +1 -0
  182. package/dist/collection/collection-manifest.json +27 -4
  183. package/dist/collection/components/co-accordion/co-accordion.css +19 -1
  184. package/dist/collection/components/co-accordion/co-accordion.js +46 -4
  185. package/dist/collection/components/co-app-shell/co-app-shell.css +79 -6
  186. package/dist/collection/components/co-app-shell/co-app-shell.js +2 -2
  187. package/dist/collection/components/co-autocomplete/co-autocomplete.css +753 -8
  188. package/dist/collection/components/co-autocomplete/co-autocomplete.js +111 -4
  189. package/dist/collection/components/co-avatar/co-avatar.css +45 -1
  190. package/dist/collection/components/co-avatar/co-avatar.js +56 -6
  191. package/dist/collection/components/co-avatar-group/co-avatar-group.css +86 -0
  192. package/dist/collection/components/co-avatar-group/co-avatar-group.js +224 -0
  193. package/dist/collection/components/co-badge/co-badge.js +1 -1
  194. package/dist/collection/components/co-bottom-sheet/co-bottom-sheet.css +136 -0
  195. package/dist/collection/components/co-bottom-sheet/co-bottom-sheet.js +507 -0
  196. package/dist/collection/components/co-button/co-button.css +48 -12
  197. package/dist/collection/components/co-button/co-button.js +70 -8
  198. package/dist/collection/components/co-button-group/co-button-group.js +2 -2
  199. package/dist/collection/components/co-calendar/co-calendar.css +236 -0
  200. package/dist/collection/components/co-calendar/co-calendar.js +728 -0
  201. package/dist/collection/components/co-calendar-month/co-calendar-month.css +231 -0
  202. package/dist/collection/components/co-calendar-month/co-calendar-month.js +594 -0
  203. package/dist/collection/components/co-card/co-card.css +28 -5
  204. package/dist/collection/components/co-card/co-card.js +47 -4
  205. package/dist/collection/components/co-checkbox/co-checkbox.css +7 -1
  206. package/dist/collection/components/co-checkbox/co-checkbox.js +3 -3
  207. package/dist/collection/components/co-checkbox-group/co-checkbox-group.css +33 -1
  208. package/dist/collection/components/co-checkbox-group/co-checkbox-group.js +25 -3
  209. package/dist/collection/components/co-chip/co-chip.css +27 -7
  210. package/dist/collection/components/co-chip/co-chip.js +52 -10
  211. package/dist/collection/components/co-color-picker/co-color-picker.css +258 -0
  212. package/dist/collection/components/co-color-picker/co-color-picker.js +355 -0
  213. package/dist/collection/components/co-color-picker/presets.js +19 -0
  214. package/dist/collection/components/co-column-picker/co-column-picker.css +490 -0
  215. package/dist/collection/components/co-column-picker/co-column-picker.js +675 -0
  216. package/dist/collection/components/co-column-picker/column-picker-node.js +34 -0
  217. package/dist/collection/components/co-column-picker/utils/column-picker-tree.js +221 -0
  218. package/dist/collection/components/co-combobox/co-combobox.css +778 -51
  219. package/dist/collection/components/co-combobox/co-combobox.js +130 -15
  220. package/dist/collection/components/co-command-search/co-command-search.css +167 -1
  221. package/dist/collection/components/co-command-search/co-command-search.js +362 -14
  222. package/dist/collection/components/co-command-search/commandSearchGroup.js +17 -0
  223. package/dist/collection/components/co-command-search/commandSearchLogic.js +27 -0
  224. package/dist/collection/components/co-data-table/co-data-table.css +37 -1
  225. package/dist/collection/components/co-data-table/co-data-table.js +38 -12
  226. package/dist/collection/components/co-data-table-pagination/co-data-table-pagination.js +4 -4
  227. package/dist/collection/components/co-date-field/co-date-field.css +245 -0
  228. package/dist/collection/components/co-date-field/co-date-field.js +746 -0
  229. package/dist/collection/components/co-date-picker/co-date-picker.css +112 -0
  230. package/dist/collection/components/co-date-picker/co-date-picker.js +801 -0
  231. package/dist/collection/components/co-date-range/co-date-range.css +3 -254
  232. package/dist/collection/components/co-date-range/co-date-range.js +29 -433
  233. package/dist/collection/components/co-date-range-picker/co-date-range-picker.css +257 -0
  234. package/dist/collection/components/co-date-range-picker/co-date-range-picker.js +1142 -0
  235. package/dist/collection/components/co-drawer/co-drawer.css +20 -0
  236. package/dist/collection/components/co-drawer/co-drawer.js +46 -2
  237. package/dist/collection/components/co-empty-state/co-empty-state.js +1 -1
  238. package/dist/collection/components/co-event-calendar/co-event-calendar.css +146 -0
  239. package/dist/collection/components/co-event-calendar/co-event-calendar.js +620 -0
  240. package/dist/collection/components/co-fab/co-fab.js +2 -2
  241. package/dist/collection/components/co-file-field/co-file-field.css +395 -0
  242. package/dist/collection/components/co-file-field/co-file-field.js +841 -0
  243. package/dist/collection/components/co-file-field/co-file-field.utils.js +47 -0
  244. package/dist/collection/components/co-helper-text/co-helper-text.js +2 -2
  245. package/dist/collection/components/co-icon/co-icon.js +7 -34
  246. package/dist/collection/components/co-icon/iconLoader.js +39 -0
  247. package/dist/collection/components/co-icon-button/co-icon-button.css +27 -6
  248. package/dist/collection/components/co-icon-button/co-icon-button.js +26 -7
  249. package/dist/collection/components/co-input/co-input.css +63 -11
  250. package/dist/collection/components/co-input/co-input.js +34 -9
  251. package/dist/collection/components/co-json-field/co-json-field.css +193 -0
  252. package/dist/collection/components/co-json-field/co-json-field.js +477 -0
  253. package/dist/collection/components/co-lightbox/co-lightbox.css +164 -0
  254. package/dist/collection/components/co-lightbox/co-lightbox.js +451 -0
  255. package/dist/collection/components/co-list-footer/co-list-footer.css +50 -0
  256. package/dist/collection/components/co-list-footer/co-list-footer.js +149 -0
  257. package/dist/collection/components/co-list-item/co-list-item.css +12 -0
  258. package/dist/collection/components/co-list-item/co-list-item.js +75 -2
  259. package/dist/collection/components/co-loader/co-loader.css +9 -0
  260. package/dist/collection/components/co-menu/co-menu.js +1 -1
  261. package/dist/collection/components/co-menu-divider/co-menu-divider.js +1 -1
  262. package/dist/collection/components/co-menu-item/co-menu-item.css +18 -0
  263. package/dist/collection/components/co-menu-item/co-menu-item.js +15 -8
  264. package/dist/collection/components/co-modal/co-modal.css +59 -5
  265. package/dist/collection/components/co-modal/co-modal.js +91 -1
  266. package/dist/collection/components/co-navbar/co-navbar.css +1 -1
  267. package/dist/collection/components/co-navbar/co-navbar.js +2 -2
  268. package/dist/collection/components/co-number-field/co-number-field.css +89 -1
  269. package/dist/collection/components/co-number-field/co-number-field.js +175 -14
  270. package/dist/collection/components/co-overlay/co-overlay.css +15 -1
  271. package/dist/collection/components/co-overlay/co-overlay.js +266 -1
  272. package/dist/collection/components/co-overlay/focusTrap.js +53 -0
  273. package/dist/collection/components/co-overlay/overlayAfterClose.js +8 -0
  274. package/dist/collection/components/co-page-header/co-page-header.js +1 -1
  275. package/dist/collection/components/co-phone-field/co-phone-field.css +293 -0
  276. package/dist/collection/components/co-phone-field/co-phone-field.js +414 -0
  277. package/dist/collection/components/co-phone-field/dial-codes.js +208 -0
  278. package/dist/collection/components/co-popover/co-popover.css +9 -0
  279. package/dist/collection/components/co-popover/co-popover.js +43 -12
  280. package/dist/collection/components/co-progress-bar/co-progress-bar.css +22 -0
  281. package/dist/collection/components/co-progress-bar/co-progress-bar.js +26 -2
  282. package/dist/collection/components/co-progress-circle/co-progress-circle.css +50 -0
  283. package/dist/collection/components/co-progress-circle/co-progress-circle.js +148 -0
  284. package/dist/collection/components/co-radio/co-radio.js +3 -3
  285. package/dist/collection/components/co-radio-group/co-radio-group.css +26 -0
  286. package/dist/collection/components/co-radio-group/co-radio-group.js +25 -3
  287. package/dist/collection/components/co-rating/co-rating.js +3 -3
  288. package/dist/collection/components/co-ref-field/co-ref-field.css +876 -56
  289. package/dist/collection/components/co-ref-field/co-ref-field.js +0 -0
  290. package/dist/collection/components/co-rich-text-editor/co-rich-text-editor.css +1322 -0
  291. package/dist/collection/components/co-rich-text-editor/co-rich-text-editor.js +2823 -0
  292. package/dist/collection/components/co-rich-text-toolbar/co-rich-text-toolbar.css +837 -0
  293. package/dist/collection/components/co-rich-text-toolbar/co-rich-text-toolbar.js +1289 -0
  294. package/dist/collection/components/co-rich-text-viewer/co-rich-text-viewer.css +156 -0
  295. package/dist/collection/components/co-rich-text-viewer/co-rich-text-viewer.js +237 -0
  296. package/dist/collection/components/co-row/co-row.js +2 -2
  297. package/dist/collection/components/co-select/co-select.css +852 -8
  298. package/dist/collection/components/co-select/co-select.js +240 -17
  299. package/dist/collection/components/co-separator/co-separator.js +1 -1
  300. package/dist/collection/components/co-sidebar/co-sidebar.js +2 -2
  301. package/dist/collection/components/co-sidebar-nav/co-sidebar-nav.css +99 -12
  302. package/dist/collection/components/co-sidebar-nav/co-sidebar-nav.js +54 -9
  303. package/dist/collection/components/co-skeleton/co-skeleton.css +28 -0
  304. package/dist/collection/components/co-skeleton/co-skeleton.js +97 -0
  305. package/dist/collection/components/co-slider/co-slider.js +2 -2
  306. package/dist/collection/components/co-switch/co-switch.css +26 -1
  307. package/dist/collection/components/co-switch/co-switch.js +27 -4
  308. package/dist/collection/components/co-tab/co-tab.js +2 -2
  309. package/dist/collection/components/co-tab-group/co-tab-group.js +1 -1
  310. package/dist/collection/components/co-tags-field/co-tags-field.css +310 -0
  311. package/dist/collection/components/co-tags-field/co-tags-field.js +616 -0
  312. package/dist/collection/components/co-textarea/co-textarea.css +286 -0
  313. package/dist/collection/components/co-textarea/co-textarea.js +508 -0
  314. package/dist/collection/components/co-toast/co-toast.js +1 -1
  315. package/dist/collection/components/co-toggle-button/co-toggle-button.css +30 -6
  316. package/dist/collection/components/co-toggle-button/co-toggle-button.js +3 -3
  317. package/dist/collection/components/co-toggle-button-group/co-toggle-button-group.css +32 -12
  318. package/dist/collection/components/co-toggle-button-group/co-toggle-button-group.js +25 -2
  319. package/dist/collection/components/co-tooltip/co-tooltip.css +24 -0
  320. package/dist/collection/components/co-tooltip/co-tooltip.js +73 -12
  321. package/dist/collection/components/co-transfer-list/co-transfer-list.css +683 -7
  322. package/dist/collection/components/co-transfer-list/co-transfer-list.js +17 -4
  323. package/dist/collection/components/co-video/co-video.css +497 -0
  324. package/dist/collection/components/co-video/co-video.js +1772 -0
  325. package/dist/collection/utils/dateI18n.js +101 -0
  326. package/dist/collection/utils/fieldChip.js +2 -0
  327. package/dist/collection/utils/fileI18n.js +76 -0
  328. package/dist/collection/utils/icon-config.js +34 -0
  329. package/dist/collection/utils/lightboxI18n.js +42 -0
  330. package/dist/collection/utils/normalizeText.js +94 -0
  331. package/dist/collection/utils/overlayScroll.js +20 -0
  332. package/dist/collection/utils/positioning.js +40 -25
  333. package/dist/collection/utils/requiredMark.js +11 -0
  334. package/dist/collection/utils/richTextI18n.js +378 -0
  335. package/dist/collection/utils/sheetGesture.js +53 -0
  336. package/dist/components/co-accordion.js +1 -1
  337. package/dist/components/co-app-shell.js +1 -1
  338. package/dist/components/co-autocomplete.js +1 -1
  339. package/dist/components/co-avatar-group.d.ts +11 -0
  340. package/dist/components/co-avatar-group.js +1 -0
  341. package/dist/components/co-avatar.js +1 -1
  342. package/dist/components/co-badge.js +1 -1
  343. package/dist/components/co-bottom-sheet.d.ts +11 -0
  344. package/dist/components/co-bottom-sheet.js +1 -0
  345. package/dist/components/co-button-group.js +1 -1
  346. package/dist/components/co-button.js +1 -1
  347. package/dist/components/co-calendar-month.d.ts +11 -0
  348. package/dist/components/co-calendar-month.js +1 -0
  349. package/dist/components/co-calendar.d.ts +11 -0
  350. package/dist/components/co-calendar.js +1 -0
  351. package/dist/components/co-card.js +1 -1
  352. package/dist/components/co-checkbox-group.js +1 -1
  353. package/dist/components/co-checkbox.js +1 -1
  354. package/dist/components/co-chip.js +1 -1
  355. package/dist/components/co-color-picker.d.ts +11 -0
  356. package/dist/components/co-color-picker.js +1 -0
  357. package/dist/components/co-column-picker.d.ts +11 -0
  358. package/dist/components/co-column-picker.js +1 -0
  359. package/dist/components/co-combobox.js +1 -1
  360. package/dist/components/co-command-search.js +1 -1
  361. package/dist/components/co-data-table-pagination.js +1 -1
  362. package/dist/components/co-data-table.js +1 -1
  363. package/dist/components/co-date-field.d.ts +11 -0
  364. package/dist/components/co-date-field.js +1 -0
  365. package/dist/components/co-date-picker.d.ts +11 -0
  366. package/dist/components/co-date-picker.js +1 -0
  367. package/dist/components/co-date-range-picker.d.ts +11 -0
  368. package/dist/components/co-date-range-picker.js +1 -0
  369. package/dist/components/co-date-range.js +1 -1
  370. package/dist/components/co-drawer.js +1 -1
  371. package/dist/components/co-empty-state.js +1 -1
  372. package/dist/components/co-event-calendar.d.ts +11 -0
  373. package/dist/components/co-event-calendar.js +1 -0
  374. package/dist/components/co-fab.js +1 -1
  375. package/dist/components/co-file-field.d.ts +11 -0
  376. package/dist/components/co-file-field.js +1 -0
  377. package/dist/components/co-helper-text.js +1 -1
  378. package/dist/components/co-icon-button.js +1 -1
  379. package/dist/components/co-icon.js +1 -1
  380. package/dist/components/co-input.js +1 -1
  381. package/dist/components/co-json-field.d.ts +11 -0
  382. package/dist/components/co-json-field.js +1 -0
  383. package/dist/components/co-lightbox.d.ts +11 -0
  384. package/dist/components/co-lightbox.js +1 -0
  385. package/dist/components/co-list-footer.d.ts +11 -0
  386. package/dist/components/co-list-footer.js +1 -0
  387. package/dist/components/co-list-item.js +1 -1
  388. package/dist/components/co-loader.js +1 -1
  389. package/dist/components/co-menu-divider.js +1 -1
  390. package/dist/components/co-menu-item.js +1 -1
  391. package/dist/components/co-menu.js +1 -1
  392. package/dist/components/co-modal.js +1 -1
  393. package/dist/components/co-navbar.js +1 -1
  394. package/dist/components/co-number-field.js +1 -1
  395. package/dist/components/co-overlay.js +1 -1
  396. package/dist/components/co-page-header.js +1 -1
  397. package/dist/components/co-phone-field.d.ts +11 -0
  398. package/dist/components/co-phone-field.js +1 -0
  399. package/dist/components/co-popover.js +1 -1
  400. package/dist/components/co-progress-bar.js +1 -1
  401. package/dist/components/co-progress-circle.d.ts +11 -0
  402. package/dist/components/co-progress-circle.js +1 -0
  403. package/dist/components/co-radio-group.js +1 -1
  404. package/dist/components/co-radio.js +1 -1
  405. package/dist/components/co-rating.js +1 -1
  406. package/dist/components/co-ref-field.js +1 -1
  407. package/dist/components/co-rich-text-editor.d.ts +11 -0
  408. package/dist/components/co-rich-text-editor.js +1 -0
  409. package/dist/components/co-rich-text-toolbar.d.ts +11 -0
  410. package/dist/components/co-rich-text-toolbar.js +1 -0
  411. package/dist/components/co-rich-text-viewer.d.ts +11 -0
  412. package/dist/components/co-rich-text-viewer.js +1 -0
  413. package/dist/components/co-row.js +1 -1
  414. package/dist/components/co-select.js +1 -1
  415. package/dist/components/co-separator.js +1 -1
  416. package/dist/components/co-sidebar-nav.js +1 -1
  417. package/dist/components/co-sidebar.js +1 -1
  418. package/dist/components/co-skeleton.d.ts +11 -0
  419. package/dist/components/co-skeleton.js +1 -0
  420. package/dist/components/co-slider.js +1 -1
  421. package/dist/components/co-switch.js +1 -1
  422. package/dist/components/co-tab-group.js +1 -1
  423. package/dist/components/co-tab.js +1 -1
  424. package/dist/components/co-tags-field.d.ts +11 -0
  425. package/dist/components/co-tags-field.js +1 -0
  426. package/dist/components/co-textarea.d.ts +11 -0
  427. package/dist/components/co-textarea.js +1 -0
  428. package/dist/components/co-toast.js +1 -1
  429. package/dist/components/co-toggle-button-group.js +1 -1
  430. package/dist/components/co-toggle-button.js +1 -1
  431. package/dist/components/co-tooltip.js +1 -1
  432. package/dist/components/co-transfer-list.js +1 -1
  433. package/dist/components/co-video.d.ts +11 -0
  434. package/dist/components/co-video.js +1 -0
  435. package/dist/components/index.js +1 -1
  436. package/dist/components/p-B2QLgWrz.js +2 -0
  437. package/dist/components/p-B7vGYFbO.js +1 -0
  438. package/dist/components/p-BB2OaYKF.js +1 -0
  439. package/dist/components/p-BFeE_fiq.js +1 -0
  440. package/dist/components/p-BNKz39GA.js +1 -0
  441. package/dist/components/p-Ba4v1NXo.js +1 -0
  442. package/dist/components/p-C1DCLOEl.js +1 -0
  443. package/dist/components/p-C2mZ7x_Y.js +1 -0
  444. package/dist/components/p-CQY6Ul7q.js +1 -0
  445. package/dist/components/p-CWneqh4n.js +1 -0
  446. package/dist/components/p-C_ULDaks.js +1 -0
  447. package/dist/components/p-CegCk7FL.js +1 -0
  448. package/dist/components/p-ChibIpZv.js +1 -0
  449. package/dist/components/p-CyYF8IJE.js +1 -0
  450. package/dist/components/p-D3Y_ti3Q.js +1 -0
  451. package/dist/components/p-DKh8ZK4U.js +1 -0
  452. package/dist/components/p-DeZxp9vb.js +1 -0
  453. package/dist/components/p-DqyWGweA.js +1 -0
  454. package/dist/components/p-DvhR3H61.js +1 -0
  455. package/dist/components/p-DxCFMMfY.js +1 -0
  456. package/dist/components/{p-OGpfa9Yd.js → p-DzoNGEDU.js} +1 -1
  457. package/dist/components/p-EPZfLt5l.js +1 -0
  458. package/dist/components/p-FMnqPWcM.js +1 -0
  459. package/dist/components/p-Hzh9U2cM.js +1 -0
  460. package/dist/components/p-WZ06pT2Y.js +1 -0
  461. package/dist/components/p-ox7HzCZn.js +10 -0
  462. package/dist/components/p-tloAgDin.js +1 -0
  463. package/dist/esm/co-accordion.entry.js +19 -4
  464. package/dist/esm/co-app-shell.entry.js +4 -4
  465. package/dist/esm/co-autocomplete.entry.js +54 -6
  466. package/dist/esm/co-avatar-group.entry.js +75 -0
  467. package/dist/esm/co-avatar.entry.js +41 -6
  468. package/dist/esm/co-badge.entry.js +2 -2
  469. package/dist/esm/co-bottom-sheet.entry.js +323 -0
  470. package/dist/esm/co-button-group.entry.js +3 -3
  471. package/dist/esm/co-button.entry.js +12 -7
  472. package/dist/esm/co-calendar-month.entry.js +379 -0
  473. package/dist/esm/co-calendar_3.entry.js +688 -0
  474. package/dist/esm/co-card.entry.js +21 -4
  475. package/dist/esm/co-checkbox-group.entry.js +7 -5
  476. package/dist/esm/co-checkbox.entry.js +5 -5
  477. package/dist/esm/co-chip.entry.js +11 -8
  478. package/dist/esm/co-color-picker.entry.js +109 -0
  479. package/dist/esm/co-column-picker.entry.js +441 -0
  480. package/dist/esm/co-combobox.entry.js +51 -15
  481. package/dist/esm/co-command-search.entry.js +159 -13
  482. package/dist/esm/co-data-table-pagination.entry.js +5 -5
  483. package/dist/esm/co-data-table.entry.js +38 -12
  484. package/dist/esm/co-date-picker.entry.js +175 -0
  485. package/dist/esm/co-date-range-picker.entry.js +376 -0
  486. package/dist/esm/co-date-range.entry.js +13 -259
  487. package/dist/esm/co-empty-state.entry.js +2 -2
  488. package/dist/esm/co-event-calendar.entry.js +316 -0
  489. package/dist/esm/co-fab.entry.js +3 -3
  490. package/dist/esm/co-file-field.entry.js +496 -0
  491. package/dist/esm/co-helper-text.entry.js +3 -3
  492. package/dist/esm/co-icon-button.entry.js +6 -6
  493. package/dist/esm/co-icon.entry.js +36 -25
  494. package/dist/esm/co-input.entry.js +13 -8
  495. package/dist/esm/co-json-field.entry.js +111 -0
  496. package/dist/esm/co-lightbox.entry.js +342 -0
  497. package/dist/esm/co-list-footer.entry.js +23 -0
  498. package/dist/esm/co-list-item.entry.js +70 -4
  499. package/dist/esm/co-loader_2.entry.js +290 -0
  500. package/dist/esm/co-menu-divider.entry.js +2 -2
  501. package/dist/esm/co-menu-item.entry.js +17 -10
  502. package/dist/esm/co-menu.entry.js +2 -2
  503. package/dist/esm/co-modal.entry.js +25 -3
  504. package/dist/esm/co-navbar.entry.js +4 -4
  505. package/dist/esm/co-number-field.entry.js +60 -12
  506. package/dist/esm/co-page-header.entry.js +2 -2
  507. package/dist/esm/co-phone-field.entry.js +376 -0
  508. package/dist/esm/co-popover.entry.js +46 -15
  509. package/dist/esm/co-progress-bar.entry.js +8 -4
  510. package/dist/esm/co-progress-circle.entry.js +36 -0
  511. package/dist/esm/co-radio-group.entry.js +7 -5
  512. package/dist/esm/co-radio.entry.js +4 -4
  513. package/dist/esm/co-rating.entry.js +4 -4
  514. package/dist/esm/co-ref-field.entry.js +214 -21
  515. package/dist/esm/co-rich-text-editor.entry.js +2079 -0
  516. package/dist/esm/co-rich-text-toolbar.entry.js +1106 -0
  517. package/dist/esm/co-rich-text-viewer.entry.js +116 -0
  518. package/dist/esm/co-row.entry.js +3 -3
  519. package/dist/esm/co-select.entry.js +119 -18
  520. package/dist/esm/co-separator.entry.js +2 -2
  521. package/dist/esm/co-sidebar-nav.entry.js +55 -10
  522. package/dist/esm/co-sidebar.entry.js +3 -3
  523. package/dist/esm/co-skeleton.entry.js +24 -0
  524. package/dist/esm/co-slider.entry.js +3 -3
  525. package/dist/esm/co-switch.entry.js +9 -6
  526. package/dist/esm/co-tab-group.entry.js +2 -2
  527. package/dist/esm/co-tab.entry.js +3 -3
  528. package/dist/esm/co-tags-field.entry.js +209 -0
  529. package/dist/esm/co-textarea.entry.js +94 -0
  530. package/dist/esm/co-toast.entry.js +2 -2
  531. package/dist/esm/co-toggle-button-group.entry.js +7 -4
  532. package/dist/esm/co-toggle-button.entry.js +4 -4
  533. package/dist/esm/co-tooltip.entry.js +56 -15
  534. package/dist/esm/co-transfer-list.entry.js +20 -6
  535. package/dist/esm/co-video.entry.js +837 -0
  536. package/dist/esm/cobalt.js +3 -3
  537. package/dist/esm/dateI18n-C1DCLOEl.js +103 -0
  538. package/dist/esm/dates-tPYikBRJ.js +416 -0
  539. package/dist/esm/fieldChip-GPikjpYw.js +5 -0
  540. package/dist/esm/{index-B0lqrhFo.js → index-CYsftTKf.js} +115 -23
  541. package/dist/esm/index-w_Wxgclf.js +35403 -0
  542. package/dist/esm/loader.js +3 -3
  543. package/dist/esm/normalizeText-CQY6Ul7q.js +92 -0
  544. package/dist/esm/overlayAfterClose-Ch1jfwZ2.js +10 -0
  545. package/dist/esm/overlayScroll-Bpv882_z.js +23 -0
  546. package/dist/esm/overlayscrollbars-ox7HzCZn.js +2840 -0
  547. package/dist/esm/{positioning-Am-OlB8h.js → positioning-C2mZ7x_Y.js} +40 -25
  548. package/dist/esm/purify.es-B2QLgWrz.js +1774 -0
  549. package/dist/esm/requiredMark-CEbXKHcU.js +14 -0
  550. package/dist/esm/richTextI18n-B-ckjCUA.js +380 -0
  551. package/dist/esm/toolbar-config-ChibIpZv.js +212 -0
  552. package/dist/esm/tz-B6JZk8fL.js +119 -0
  553. package/dist/types/components/co-accordion/co-accordion.d.ts +12 -2
  554. package/dist/types/components/co-autocomplete/co-autocomplete.d.ts +13 -0
  555. package/dist/types/components/co-avatar/co-avatar.d.ts +8 -2
  556. package/dist/types/components/co-avatar-group/co-avatar-group.d.ts +33 -0
  557. package/dist/types/components/co-bottom-sheet/co-bottom-sheet.d.ts +81 -0
  558. package/dist/types/components/co-button/co-button.d.ts +7 -1
  559. package/dist/types/components/co-calendar/co-calendar.d.ts +108 -0
  560. package/dist/types/components/co-calendar-month/co-calendar-month.d.ts +83 -0
  561. package/dist/types/components/co-card/co-card.d.ts +10 -2
  562. package/dist/types/components/co-checkbox-group/co-checkbox-group.d.ts +2 -0
  563. package/dist/types/components/co-chip/co-chip.d.ts +7 -2
  564. package/dist/types/components/co-color-picker/co-color-picker.d.ts +50 -0
  565. package/dist/types/components/co-color-picker/presets.d.ts +10 -0
  566. package/dist/types/components/co-column-picker/co-column-picker.d.ts +60 -0
  567. package/dist/types/components/co-column-picker/column-picker-node.d.ts +18 -0
  568. package/dist/types/components/co-column-picker/utils/column-picker-tree.d.ts +37 -0
  569. package/dist/types/components/co-combobox/co-combobox.d.ts +14 -1
  570. package/dist/types/components/co-command-search/co-command-search.d.ts +41 -6
  571. package/dist/types/components/co-command-search/commandSearchGroup.d.ts +20 -0
  572. package/dist/types/components/co-command-search/commandSearchLogic.d.ts +17 -0
  573. package/dist/types/components/co-data-table/co-data-table.d.ts +3 -1
  574. package/dist/types/components/co-date-field/co-date-field.d.ts +96 -0
  575. package/dist/types/components/co-date-picker/co-date-picker.d.ts +92 -0
  576. package/dist/types/components/co-date-range/co-date-range.d.ts +12 -50
  577. package/dist/types/components/co-date-range-picker/co-date-range-picker.d.ts +112 -0
  578. package/dist/types/components/co-drawer/co-drawer.d.ts +4 -0
  579. package/dist/types/components/co-event-calendar/co-event-calendar.d.ts +110 -0
  580. package/dist/types/components/co-file-field/co-file-field.d.ts +146 -0
  581. package/dist/types/components/co-file-field/co-file-field.utils.d.ts +18 -0
  582. package/dist/types/components/co-icon/co-icon.d.ts +1 -1
  583. package/dist/types/components/co-icon/iconLoader.d.ts +6 -0
  584. package/dist/types/components/co-icon-button/co-icon-button.d.ts +3 -1
  585. package/dist/types/components/co-input/co-input.d.ts +4 -1
  586. package/dist/types/components/co-json-field/co-json-field.d.ts +69 -0
  587. package/dist/types/components/co-lightbox/co-lightbox.d.ts +95 -0
  588. package/dist/types/components/co-list-footer/co-list-footer.d.ts +26 -0
  589. package/dist/types/components/co-list-item/co-list-item.d.ts +12 -0
  590. package/dist/types/components/co-modal/co-modal.d.ts +10 -0
  591. package/dist/types/components/co-number-field/co-number-field.d.ts +29 -2
  592. package/dist/types/components/co-overlay/co-overlay.d.ts +45 -0
  593. package/dist/types/components/co-overlay/focusTrap.d.ts +20 -0
  594. package/dist/types/components/co-overlay/overlayAfterClose.d.ts +5 -0
  595. package/dist/types/components/co-phone-field/co-phone-field.d.ts +58 -0
  596. package/dist/types/components/co-phone-field/dial-codes.d.ts +14 -0
  597. package/dist/types/components/co-popover/co-popover.d.ts +9 -0
  598. package/dist/types/components/co-progress-bar/co-progress-bar.d.ts +2 -0
  599. package/dist/types/components/co-progress-circle/co-progress-circle.d.ts +16 -0
  600. package/dist/types/components/co-radio-group/co-radio-group.d.ts +2 -0
  601. package/dist/types/components/co-ref-field/co-ref-field.d.ts +69 -1
  602. package/dist/types/components/co-rich-text-editor/co-rich-text-editor.d.ts +246 -0
  603. package/dist/types/components/co-rich-text-toolbar/co-rich-text-toolbar.d.ts +148 -0
  604. package/dist/types/components/co-rich-text-viewer/co-rich-text-viewer.d.ts +19 -0
  605. package/dist/types/components/co-select/co-select.d.ts +31 -1
  606. package/dist/types/components/co-skeleton/co-skeleton.d.ts +13 -0
  607. package/dist/types/components/co-switch/co-switch.d.ts +2 -0
  608. package/dist/types/components/co-tags-field/co-tags-field.d.ts +84 -0
  609. package/dist/types/components/co-textarea/co-textarea.d.ts +68 -0
  610. package/dist/types/components/co-toggle-button-group/co-toggle-button-group.d.ts +2 -0
  611. package/dist/types/components/co-tooltip/co-tooltip.d.ts +12 -0
  612. package/dist/types/components/co-transfer-list/co-transfer-list.d.ts +4 -0
  613. package/dist/types/components/co-video/co-video.d.ts +203 -0
  614. package/dist/types/components.d.ts +5422 -391
  615. package/dist/types/utils/dateI18n.d.ts +39 -0
  616. package/dist/types/utils/fieldChip.d.ts +37 -0
  617. package/dist/types/utils/fileI18n.d.ts +34 -0
  618. package/dist/types/utils/icon-config.d.ts +31 -0
  619. package/dist/types/utils/lightboxI18n.d.ts +12 -0
  620. package/dist/types/utils/normalizeText.d.ts +41 -0
  621. package/dist/types/utils/overlayScroll.d.ts +17 -0
  622. package/dist/types/utils/positioning.d.ts +7 -14
  623. package/dist/types/utils/requiredMark.d.ts +13 -0
  624. package/dist/types/utils/richTextI18n.d.ts +130 -0
  625. package/dist/types/utils/sheetGesture.d.ts +31 -0
  626. package/package.json +10 -1
  627. package/dist/cjs/co-drawer.cjs.entry.js +0 -75
  628. package/dist/cjs/co-loader.cjs.entry.js +0 -34
  629. package/dist/cjs/co-overlay.cjs.entry.js +0 -23
  630. package/dist/cjs/color-YhUkm10t.js +0 -32
  631. package/dist/cobalt/p-08afdc51.entry.js +0 -1
  632. package/dist/cobalt/p-1b7d6808.entry.js +0 -1
  633. package/dist/cobalt/p-1d3338b6.entry.js +0 -1
  634. package/dist/cobalt/p-1d91ec93.entry.js +0 -1
  635. package/dist/cobalt/p-230a23f3.entry.js +0 -1
  636. package/dist/cobalt/p-31bc842d.entry.js +0 -1
  637. package/dist/cobalt/p-37c1f700.entry.js +0 -1
  638. package/dist/cobalt/p-4905b51d.entry.js +0 -1
  639. package/dist/cobalt/p-4dd7499c.entry.js +0 -1
  640. package/dist/cobalt/p-4e7ce8ee.entry.js +0 -1
  641. package/dist/cobalt/p-4ffba5a3.entry.js +0 -1
  642. package/dist/cobalt/p-5a13e3a0.entry.js +0 -1
  643. package/dist/cobalt/p-6793c51e.entry.js +0 -1
  644. package/dist/cobalt/p-689e38b3.entry.js +0 -1
  645. package/dist/cobalt/p-7028880b.entry.js +0 -1
  646. package/dist/cobalt/p-72113ec2.entry.js +0 -1
  647. package/dist/cobalt/p-8e54e74d.entry.js +0 -1
  648. package/dist/cobalt/p-92c39eed.entry.js +0 -1
  649. package/dist/cobalt/p-9887b828.entry.js +0 -1
  650. package/dist/cobalt/p-9a5c6600.entry.js +0 -1
  651. package/dist/cobalt/p-Am-OlB8h.js +0 -1
  652. package/dist/cobalt/p-B0lqrhFo.js +0 -2
  653. package/dist/cobalt/p-BG4WRR22.js +0 -1
  654. package/dist/cobalt/p-a1b248ad.entry.js +0 -1
  655. package/dist/cobalt/p-a470b764.entry.js +0 -1
  656. package/dist/cobalt/p-a4d55b1a.entry.js +0 -1
  657. package/dist/cobalt/p-b6840df4.entry.js +0 -1
  658. package/dist/cobalt/p-b89d54d9.entry.js +0 -1
  659. package/dist/cobalt/p-ba84631a.entry.js +0 -1
  660. package/dist/cobalt/p-c9b0e73f.entry.js +0 -1
  661. package/dist/cobalt/p-ca41eec2.entry.js +0 -1
  662. package/dist/cobalt/p-cc93ab05.entry.js +0 -1
  663. package/dist/cobalt/p-d9d8b10e.entry.js +0 -1
  664. package/dist/cobalt/p-da55678f.entry.js +0 -1
  665. package/dist/cobalt/p-dc5598d1.entry.js +0 -1
  666. package/dist/cobalt/p-e2c9cb00.entry.js +0 -1
  667. package/dist/cobalt/p-e808916c.entry.js +0 -1
  668. package/dist/cobalt/p-ebd68f56.entry.js +0 -1
  669. package/dist/cobalt/p-f051f44d.entry.js +0 -1
  670. package/dist/cobalt/p-fe1447a3.entry.js +0 -1
  671. package/dist/cobalt/p-ff6a647c.entry.js +0 -1
  672. package/dist/components/p-Am-OlB8h.js +0 -1
  673. package/dist/components/p-B18FTYLq.js +0 -1
  674. package/dist/components/p-BG4WRR22.js +0 -1
  675. package/dist/components/p-Cr8Yc0zj.js +0 -1
  676. package/dist/components/p-FBICWTuN.js +0 -1
  677. package/dist/components/p-cpdUXBiS.js +0 -1
  678. package/dist/components/p-wwWquAtm.js +0 -1
  679. package/dist/esm/co-drawer.entry.js +0 -73
  680. package/dist/esm/co-loader.entry.js +0 -32
  681. package/dist/esm/co-overlay.entry.js +0 -21
  682. package/dist/esm/color-BG4WRR22.js +0 -30
@@ -0,0 +1,2079 @@
1
+ import { r as registerInstance, c as createEvent, h, a as getElement } from './index-CYsftTKf.js';
2
+ import { R as RichText } from './index-w_Wxgclf.js';
3
+ import { g as getRichTextStrings } from './richTextI18n-B-ckjCUA.js';
4
+ import './purify.es-B2QLgWrz.js';
5
+ import './toolbar-config-ChibIpZv.js';
6
+
7
+ const coRichTextEditorCss = () => `co-rich-text-editor{display:block;font-family:var(--co-font-family-primary);font-size:var(--co-font-size-14);letter-spacing:var(--co-font-letter-spacing-body)}.co-rich-text-editor{display:flex;flex-direction:column;gap:var(--co-spacing-sm2, 6px)}.co-rich-text-editor__labels{display:flex;align-items:center;justify-content:space-between;padding:0 var(--co-spacing-xs);gap:var(--co-spacing-sm2, 6px)}.co-rich-text-editor__label,.co-rich-text-editor__secondary-label{color:var(--co-semantic-text-secondary);font-size:var(--co-font-size-14);font-weight:400;line-height:1}.co-rich-text-editor__frame{display:flex;flex-direction:column;background:var(--co-semantic-surface-secondary);border:1px solid var(--co-semantic-border-subtle);border-radius:var(--co-border-radius-xs);transition:border-color 0.15s ease, box-shadow 0.15s ease;min-height:0;flex:1;position:relative;overflow:visible}.co-rich-text-editor__box{display:flex;flex-direction:column;min-height:0;flex:1;position:relative;overflow-y:auto;overflow-x:hidden}.co-rich-text-editor--focused .co-rich-text-editor__frame{border-color:var(--co-semantic-border-focus, var(--co-color-base-negro, #1a1a1a));box-shadow:0 0 0 3px var(--co-semantic-border-focus-ring, rgba(37, 99, 235, 0.15))}.co-rich-text-editor--error .co-rich-text-editor__frame{border-color:var(--co-color-status-error)}.co-rich-text-editor--success .co-rich-text-editor__frame{border-color:var(--co-color-status-success)}.co-rich-text-editor--disabled .co-rich-text-editor__frame,.co-rich-text-editor--readonly .co-rich-text-editor__frame{opacity:0.7;cursor:not-allowed}.co-rich-text-editor--loading .co-rte-content{min-height:96px;background:linear-gradient(90deg, var(--co-semantic-surface-secondary) 0%, var(--co-semantic-surface-hover, rgba(0, 0, 0, 0.04)) 50%, var(--co-semantic-surface-secondary) 100%);background-size:200% 100%;animation:co-rte-skeleton 1.2s ease-in-out infinite}@keyframes co-rte-skeleton{0%{background-position:200% 0}100%{background-position:-200% 0}}.co-rich-text-editor__toolbar{position:relative;flex-shrink:0;z-index:60}.co-rte-content{min-height:96px;color:var(--co-semantic-text-default);flex:1 0 auto;display:flex;flex-direction:column}.co-rte-content .ProseMirror{outline:none;flex:1 0 auto;line-height:1.5;padding:var(--co-spacing-md);box-sizing:border-box}.co-rte-content .ProseMirror p{margin:0 0 var(--co-spacing-sm) 0}.co-rte-content .ProseMirror p:last-child{margin-bottom:0}.co-rte-content .ProseMirror>p{margin-bottom:var(--co-spacing-sm) !important}.co-rte-content .ProseMirror>p:last-child{margin-bottom:0 !important}.co-rte-content .ProseMirror [style*="text-align: justify"]{text-align-last:left}.co-rte-content .ProseMirror [style*="text-align: center"]{text-align:center}.co-rte-content .ProseMirror [style*="text-align: right"]{text-align:right}.co-rte-content .ProseMirror h1,.co-rte-content .ProseMirror h2,.co-rte-content .ProseMirror h3,.co-rte-content .ProseMirror h4{margin:var(--co-spacing-md) 0 var(--co-spacing-sm);font-weight:600;line-height:1.3}.co-rte-content .ProseMirror h1{font-size:var(--co-font-size-28, 28px)}.co-rte-content .ProseMirror h2{font-size:var(--co-font-size-20, 20px)}.co-rte-content .ProseMirror h3{font-size:var(--co-font-size-16, 16px)}.co-rte-content .ProseMirror ul,.co-rte-content .ProseMirror ol{padding-left:var(--co-spacing-xl);margin:0 0 var(--co-spacing-sm) 0}.co-rte-content .ProseMirror ul[data-type="taskList"]{list-style:none;padding-left:0;margin:0 0 var(--co-spacing-sm) 0}.co-rte-content .ProseMirror ul[data-type="taskList"] li{display:flex;align-items:flex-start;gap:var(--co-spacing-sm, 8px)}.co-rte-content .ProseMirror ul[data-type="taskList"] li>label{flex:0 0 auto;margin-top:0.15em;user-select:none}.co-rte-content .ProseMirror ul[data-type="taskList"] li>div{flex:1 1 auto;min-width:0}.co-rte-content .ProseMirror ul[data-type="taskList"] li>div>p{margin:0}.co-rte-content .ProseMirror ul[data-type="taskList"] input[type="checkbox"]{width:16px;height:16px;cursor:pointer;accent-color:var(--co-color-base-negro, #1a1a1a)}.co-rte-content .ProseMirror ul[data-type="taskList"][data-variant="strike"] li[data-checked="true"]>div{text-decoration:line-through;color:var(--co-semantic-text-muted, #999)}.co-rte-content .ProseMirror ul[data-type="taskList"][data-variant="plain"] li[data-checked="true"]>div{text-decoration:none}.co-rte-content .ProseMirror blockquote{border-left:3px solid var(--co-semantic-border-default, var(--co-semantic-border-subtle));padding-left:var(--co-spacing-md);margin:0 0 var(--co-spacing-sm) 0;color:var(--co-semantic-text-secondary)}.co-rte-content .ProseMirror a{color:var(--co-color-base-negro, #1a1a1a);text-decoration:underline;text-underline-offset:2px}.co-rte-content .ProseMirror img{max-width:100%;height:auto;border-radius:var(--co-border-radius-xs);margin:var(--co-spacing-sm) 0;cursor:default;-webkit-user-drag:none;user-select:none}.co-rte-content .ProseMirror img.ProseMirror-selectednode{outline:2px solid var(--co-color-base-negro, #1a1a1a)}.co-rte-content [data-resize-container].ProseMirror-selectednode{outline:2px solid var(--co-color-base-negro, #1a1a1a);outline-offset:0px;border-radius:0}.co-rte-content [data-resize-container]{position:relative;display:inline-block;width:fit-content;max-width:100%;margin:var(--co-spacing-sm) 0;line-height:0}.co-rte-content [data-resize-container][data-resize-state="true"]{outline:2px solid var(--co-color-base-negro, #1a1a1a);outline-offset:0px;border-radius:0}.co-rte-content [data-resize-wrapper]{position:relative;display:inline-block;line-height:0}.co-rte-content [data-resize-handle]{width:10px;height:10px;background:var(--co-color-base-negro, #1a1a1a);border:1.5px solid #fff;border-radius:50%;box-shadow:0 0 2px rgba(0, 0, 0, 0.3);z-index:5;opacity:0;pointer-events:none}.co-rte-content [data-resize-container][data-resize-state="true"] [data-resize-handle],.co-rte-content [data-resize-container].ProseMirror-selectednode [data-resize-handle]{opacity:1;pointer-events:auto}.co-rte-content [data-resize-handle="top-left"]{cursor:nw-resize}.co-rte-content [data-resize-handle="top-right"]{cursor:ne-resize}.co-rte-content [data-resize-handle="bottom-left"]{cursor:sw-resize}.co-rte-content [data-resize-handle="bottom-right"]{cursor:se-resize}.co-rte-content [data-resize-handle="top"],.co-rte-content [data-resize-handle="bottom"]{width:30px;height:6px;border-radius:3px;left:50% !important;transform:translateX(-50%)}.co-rte-content [data-resize-handle="top"]{cursor:n-resize}.co-rte-content [data-resize-handle="bottom"]{cursor:s-resize}.co-rte-content [data-resize-handle="left"],.co-rte-content [data-resize-handle="right"]{width:6px;height:30px;border-radius:3px;top:50% !important;transform:translateY(-50%)}.co-rte-content [data-resize-handle="left"]{cursor:w-resize}.co-rte-content [data-resize-handle="right"]{cursor:e-resize}.co-rte-content [data-resize-container] img{max-width:100%;display:block;border-radius:0;margin:0}.co-rte-content .ProseMirror hr{border:none;border-top:1px solid var(--co-semantic-border-default, #e0e0e0);margin:var(--co-spacing-lg) 0}.co-rte-content .ProseMirror code{font-family:var(--co-font-family-mono);font-size:0.9em;background:var(--co-semantic-surface-hover, rgba(0, 0, 0, 0.06));padding:0.1em 0.3em;border-radius:var(--co-border-radius-xxs)}.co-rte-content .ProseMirror pre{font-family:var(--co-font-family-mono);font-size:0.9em;background:var(--co-semantic-surface-hover, rgba(0, 0, 0, 0.06));padding:var(--co-spacing-md);border-radius:var(--co-border-radius-xs);overflow-x:auto;margin:var(--co-spacing-sm) 0}.co-rte-content .ProseMirror pre code{background:none;padding:0;border-radius:0}.co-rte-content .ProseMirror p.is-editor-empty:first-child::before{content:attr(data-placeholder);color:var(--co-semantic-text-muted);float:left;height:0;pointer-events:none}.co-rte-content .co-rte-variable,.co-rte-content .co-rte-mention{display:inline-block;padding:0.05em 0.4em;border-radius:var(--co-border-radius-xxs);background:var(--co-color-base-negro, #1a1a1a);color:var(--co-color-base-blanco, #fff);font-size:0.9em;white-space:nowrap}.co-rte-content .co-rte-mention{background:var(--co-color-primary-verde)}.co-rich-text-editor__footer{display:flex;align-items:center;justify-content:space-between;gap:var(--co-spacing-sm);padding:0 var(--co-spacing-xs);min-height:0}.co-rich-text-editor__helper{display:flex;align-items:center;gap:var(--co-spacing-xs);color:var(--co-semantic-text-secondary);font-size:var(--co-font-size-12, 12px)}.co-rich-text-editor__helper--error{color:var(--co-color-status-error)}.co-rich-text-editor__helper--success{color:var(--co-color-status-success)}.co-rich-text-editor__count{margin-left:auto;color:var(--co-semantic-text-muted);font-size:var(--co-font-size-12, 12px)}.co-rte-bubble.co-rte-bubble--suppressed{display:none !important}.co-rte-bubble{position:absolute;z-index:50;display:flex;flex-direction:row;align-items:center;gap:2px;padding:var(--co-spacing-xs, 4px) var(--co-spacing-sm, 8px);background:var(--co-semantic-surface-secondary, #fff);border:1px solid var(--co-semantic-border-default, #e0e0e0);border-radius:var(--co-border-radius-xs, 8px);box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);user-select:none;white-space:nowrap}.co-rte-bubble__drag-handle{display:flex;align-items:center;justify-content:center;cursor:grab;color:var(--co-semantic-text-muted, #999);width:18px;height:28px;margin:0 2px 0 0;flex-shrink:0}.co-rte-bubble__drag-handle:hover{color:var(--co-semantic-text-secondary, #555)}.co-rte-bubble__drag-handle:active{cursor:grabbing}.co-rte-bubble__row{display:flex;align-items:center;gap:2px;flex-wrap:nowrap}.co-rte-bubble__btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:var(--co-border-radius-xxs, 4px);background:transparent;color:var(--co-semantic-text-default, #333);cursor:pointer}.co-rte-bubble__btn:hover:not(.co-rte-bubble__btn--active){background:var(--co-semantic-surface-hover, rgba(0, 0, 0, 0.06))}.co-rte-bubble__btn--active{background:var(--co-color-base-negro, #1a1a1a);color:var(--co-color-base-blanco, #fff)}.co-rte-bubble__btn--active:hover{background:var(--co-color-base-negro, #333)}.co-rte-bubble__sep{display:inline-block;width:1px;height:18px;margin:0 4px;background:var(--co-semantic-border-default, rgba(0, 0, 0, 0.12));flex-shrink:0}.co-rte-bubble__select{position:relative}.co-rte-bubble__select-trigger{display:flex;align-items:center;gap:2px;height:28px;padding:0 6px;border:1px solid transparent;border-radius:var(--co-border-radius-xxs, 4px);background:transparent;color:var(--co-semantic-text-default, #333);font-family:var(--co-font-family-primary);font-size:11px;cursor:pointer;white-space:nowrap;transition:background 0.12s, border-color 0.12s}.co-rte-bubble__select-trigger:hover{background:var(--co-semantic-surface-hover, #f5f5f5);border-color:var(--co-semantic-border-default, #e0e0e0)}.co-rte-bubble__select-label{max-width:72px;overflow:hidden;text-overflow:ellipsis}.co-rte-bubble__select--font .co-rte-bubble__select-label{max-width:110px}.co-rte-bubble__select-dropdown{position:absolute;bottom:100%;left:0;z-index:120;min-width:100px;max-height:260px;overflow-y:auto;padding:var(--co-spacing-xxs, 2px);background:var(--co-semantic-surface-secondary, #fff);border:1px solid var(--co-semantic-border-default, #e0e0e0);border-radius:var(--co-border-radius-xxs, 4px);box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);margin-bottom:4px;white-space:normal}.co-rte-bubble__select-dropdown[data-position="above"]{bottom:100%;top:auto;margin-bottom:4px;margin-top:0}.co-rte-bubble__select-dropdown[data-position="below"]{top:100%;bottom:auto;margin-top:4px;margin-bottom:0}.co-rte-bubble__select-option{display:block;width:100%;padding:4px 8px;border:none;border-radius:3px;background:transparent;color:var(--co-semantic-text-default, #333);font-family:var(--co-font-family-primary);font-size:12px;text-align:left;cursor:pointer;white-space:nowrap}.co-rte-bubble__select-option:hover{background:var(--co-semantic-surface-hover, #f5f5f5)}.co-rte-bubble__select-dropdown--font{min-width:200px;max-height:320px;overflow:hidden;overflow-y:auto;display:flex;flex-direction:column;white-space:normal}.co-rte-bubble__font-search{padding:6px 6px 4px;flex-shrink:0}.co-rte-bubble__font-search-input{width:100%;padding:4px 8px;border:1px solid var(--co-semantic-border-default, #ccc);border-radius:4px;background:var(--co-semantic-surface-secondary, #fff);color:var(--co-semantic-text-default, #333);font-family:var(--co-font-family-primary);font-size:12px;outline:none;box-sizing:border-box}.co-rte-bubble__font-search-input:focus{border-color:var(--co-color-base-negro, #1a1a1a)}.co-rte-bubble__font-list{max-height:260px;overflow-y:auto;padding:0 var(--co-spacing-xxs, 2px) var(--co-spacing-xxs, 2px)}.co-rte-bubble__font-section-header{padding:6px 8px 2px;font-size:11px;font-weight:600;color:var(--co-semantic-text-muted, #888);text-transform:uppercase;letter-spacing:0.5px}.co-rte-bubble__font-empty{padding:12px 8px;text-align:center;color:var(--co-semantic-text-muted, #888);font-size:12px}.co-rte-bubble__color{position:relative}.co-rte-bubble__color-dropdown{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);z-index:120;width:224px;padding:var(--co-spacing-sm, 8px);background:var(--co-semantic-surface-secondary, #fff);border:1px solid var(--co-semantic-border-default, #e0e0e0);border-radius:var(--co-border-radius-xs, 8px);box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);margin-bottom:4px;white-space:normal;max-width:calc(100vw - 16px)}.co-rte-bubble__color-dropdown[data-position="above"]{bottom:100%;top:auto;margin-bottom:4px;margin-top:0}.co-rte-bubble__color-dropdown[data-position="below"]{top:100%;bottom:auto;margin-top:4px;margin-bottom:0}.co-rte-bubble__color-grid{display:grid;grid-template-columns:repeat(10, 1fr);gap:2px}.co-rte-bubble__color-swatch{width:20px;height:20px;padding:0;border:none;border-radius:3px;cursor:pointer;transition:transform 0.1s, box-shadow 0.1s}.co-rte-bubble__color-swatch:hover{transform:scale(1.2);box-shadow:0 0 0 2px var(--co-color-base-negro, #1a1a1a)}.co-rte-bubble__color-hex{display:flex;align-items:center;gap:4px;margin-top:6px}.co-rte-bubble__color-hex-input{width:100%;padding:3px 6px;border:1px solid var(--co-semantic-border-default, #ccc);border-radius:3px;background:var(--co-semantic-surface-secondary, #fff);color:var(--co-semantic-text-default, #333);font-family:var(--co-font-family-mono, monospace);font-size:11px;outline:none}.co-rte-bubble__color-hex-input:focus{border-color:var(--co-color-base-negro, #1a1a1a)}.co-rte-bubble__color-clear{display:flex;align-items:center;gap:4px;width:100%;padding:3px 6px;margin-top:4px;border:none;background:transparent;color:var(--co-semantic-text-secondary, #666);font-family:var(--co-font-family-primary);font-size:11px;cursor:pointer;border-radius:3px}.co-rte-bubble__color-clear:hover{background:var(--co-semantic-surface-hover, #f5f5f5)}.co-rte-bubble__link-form{display:flex;align-items:center;gap:4px;margin-left:4px}.co-rte-bubble__link-input{width:160px;padding:3px 8px;border:1px solid var(--co-semantic-border-default, #ccc);border-radius:4px;background:var(--co-semantic-surface-secondary, #fff);color:var(--co-semantic-text-default, #333);font-family:var(--co-font-family-primary);font-size:12px;outline:none}.co-rte-bubble__link-input::placeholder{color:var(--co-semantic-text-muted, #999)}.co-rte-bubble__link-input:focus{border-color:var(--co-color-base-negro, #1a1a1a);box-shadow:0 0 0 2px rgba(0, 0, 0, 0.1)}.co-rte-bubble__link-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;border:none;border-radius:4px;background:var(--co-color-base-negro, #1a1a1a);color:#fff;cursor:pointer}.co-rte-bubble__link-btn:hover{opacity:0.9}.co-rte-bubble__link-unlink{background:var(--co-semantic-surface-error, #ef4444)}.co-rte-bubble__panel{position:absolute;z-index:140;width:230px;background:var(--co-semantic-surface-secondary, #fff);border:1px solid var(--co-semantic-border-default, #e0e0e0);border-radius:var(--co-border-radius-xs, 8px);box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);overflow:hidden;user-select:none}.co-rte-bubble__panel-header{display:flex;align-items:center;gap:4px;padding:6px 8px;border-bottom:1px solid var(--co-semantic-border-subtle, #eee)}.co-rte-bubble__panel-drag{cursor:grab;display:flex;align-items:center;justify-content:center;color:var(--co-semantic-text-muted, #999);flex-shrink:0}.co-rte-bubble__panel-drag:active{cursor:grabbing}.co-rte-bubble__panel-title{flex:1;font-size:12px;font-weight:600;color:var(--co-semantic-text-default, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.co-rte-bubble__panel-close{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;border-radius:3px;background:transparent;color:var(--co-semantic-text-muted, #999);cursor:pointer;flex-shrink:0}.co-rte-bubble__panel-close:hover{background:var(--co-semantic-surface-hover, rgba(0, 0, 0, 0.06));color:var(--co-semantic-text-default, #333)}.co-rte-bubble__panel-input-wrap{padding:6px 8px}.co-rte-bubble__panel-input{width:100%;padding:4px 8px;border:1px solid var(--co-semantic-border-default, #e0e0e0);border-radius:4px;font-size:12px;font-family:inherit;outline:none;box-sizing:border-box;background:var(--co-semantic-surface-secondary, #fff);color:var(--co-semantic-text-default, #333)}.co-rte-bubble__panel-input:focus{border-color:var(--co-color-base-negro, #1a1a1a)}.co-rte-bubble__panel-options{max-height:280px;overflow-y:auto;padding:2px 4px 4px}.co-rte-bubble__panel-option{display:block;width:100%;padding:5px 8px;border:none;border-radius:3px;background:transparent;cursor:pointer;text-align:left;font-family:inherit;color:var(--co-semantic-text-default, #333)}.co-rte-bubble__panel-option:hover{background:var(--co-semantic-surface-hover, #f5f5f5)}.co-rte-bubble__panel-sep{height:1px;background:var(--co-semantic-border-subtle, #eee);margin:4px 8px}.co-rte-bubble__panel-opt-row{display:flex;justify-content:space-between;align-items:center;width:100%}.co-rte-bubble__panel-opt-value{color:var(--co-semantic-text-muted, #999);font-size:11px;font-weight:400 !important;min-width:28px;text-align:right}.co-rte-bubble__panel[data-position="above"]{bottom:100%;top:auto;margin-bottom:4px}.co-rte-bubble__panel[data-position="below"]{top:100%;bottom:auto;margin-top:4px}.co-rte-bubble__overflow{position:relative}.co-rte-bubble__overflow-menu{position:absolute;bottom:100%;right:0;z-index:130;min-width:230px;padding:4px;background:var(--co-semantic-surface-secondary, #fff);border:1px solid var(--co-semantic-border-default, #e0e0e0);border-radius:var(--co-border-radius-xs, 8px);box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);margin-bottom:4px}.co-rte-bubble__overflow-menu[data-position="below"]{top:100%;bottom:auto;margin-top:4px;margin-bottom:0}.co-rte-bubble__overflow-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 8px;border:none;border-radius:4px;background:transparent;font-family:inherit;font-size:13px;color:var(--co-semantic-text-default, #333);cursor:pointer;text-align:left;white-space:nowrap}.co-rte-bubble__overflow-item:hover{background:var(--co-semantic-surface-hover, #f5f5f5)}.co-rte-bubble__overflow-item--active{background:var(--co-semantic-surface-hover, rgba(0, 0, 0, 0.06));color:var(--co-color-base-negro, #1a1a1a);font-weight:600}.co-rte-bubble__overflow-value{margin-left:auto;color:var(--co-semantic-text-muted, #999);font-size:11px}.co-rte-bubble__overflow-sep{height:1px;background:var(--co-semantic-border-subtle, #eee);margin:3px 8px}.co-rte-bubble__overflow-section-title{padding:6px 8px 2px;font-size:11px;font-weight:600;color:var(--co-semantic-text-muted, #888);letter-spacing:0.5px}.co-rte-bubble__overflow-item--danger{color:var(--co-color-status-error, #aa2e1b)}.co-rte-bubble__overflow-item--danger:hover{background:rgba(170, 46, 27, 0.06)}.co-rte-bubble__color-indicator{display:flex;flex-direction:column;align-items:center;gap:1px;line-height:1}.co-rte-bubble__color-letter{font-family:var(--co-font-family-primary);font-size:14px;font-weight:700;color:var(--co-semantic-text-default, #333);line-height:1}.co-rte-bubble__color-bar{width:14px;height:3px;border-radius:1px}.co-rte-content .callout{display:flex;gap:0.75rem;padding:1rem;border-radius:var(--co-border-radius-xs, 8px);border:2px solid;margin:1rem 0}.co-rte-content .callout--info{background:#eff6ff;border-color:#bfdbfe}.co-rte-content .callout--warning{background:#fffbeb;border-color:#fde68a}.co-rte-content .callout--success{background:#f0fdf4;border-color:#bbf7d0}.co-rte-content .callout--error{background:#fef2f2;border-color:#fecaca}.co-rte-content .callout__icon{flex-shrink:0;font-size:1.2em}.co-rte-content .callout__content{flex:1}.co-rte-content .callout__content p{margin:0}.co-rte-content table{border-collapse:collapse;table-layout:auto;width:100%;margin:1rem 0;overflow:hidden}.co-rte-content .tableWrapper{overflow-x:auto;max-width:100%}.co-rte-content td,.co-rte-content th{min-width:1em;border:1px solid var(--co-semantic-border-default, #e0e0e0);padding:0.5rem;vertical-align:top;box-sizing:border-box;position:relative}.co-rte-content th{font-weight:600;text-align:left;background-color:#e3e3e3;color:var(--co-semantic-text-default, #333)}.co-rte-content .ProseMirror table th{background-color:#e3e3e3}.co-rte-content .selectedCell{background:rgba(0, 0, 0, 0.06)}.co-rte-content .column-resize-handle{position:absolute;right:-2px;top:0;bottom:0;width:4px;background-color:var(--co-color-base-negro, #1a1a1a);pointer-events:none}.co-rte-content .ProseMirror.resize-cursor,.co-rte-content .ProseMirror.resize-cursor *{cursor:col-resize}.co-rte-content iframe{border-radius:var(--co-border-radius-xs, 8px);max-width:100%;aspect-ratio:16 / 9;width:100%;height:auto;display:block;margin:0}.co-rte-content .co-rte-embed{position:relative;display:block;max-width:100%;margin:1rem 0;line-height:0}.co-rte-content .co-rte-embed::before{content:'';position:absolute;inset:0;z-index:1}.co-rte-content .co-rte-embed.ProseMirror-selectednode,.co-rte-content .co-rte-embed--selected{outline:2px solid var(--co-color-base-negro, #1a1a1a);outline-offset:2px;border-radius:var(--co-border-radius-xs, 8px)}.co-rte-content .co-rte-embed__handle{position:absolute;width:12px;height:12px;background:var(--co-color-base-negro, #1a1a1a);border:1.5px solid #fff;border-radius:50%;box-shadow:0 0 2px rgba(0, 0, 0, 0.3);z-index:3;opacity:0;pointer-events:none}.co-rte-content .co-rte-embed.ProseMirror-selectednode .co-rte-embed__handle,.co-rte-content .co-rte-embed--selected .co-rte-embed__handle{opacity:1;pointer-events:auto}.co-rte-content .co-rte-embed__handle--bottom-right{right:-6px;bottom:-6px;cursor:nwse-resize}.co-rte-content .co-rte-embed__handle--bottom-left{left:-6px;bottom:-6px;cursor:nesw-resize}.co-rte-content .co-rte-embed--resizing{outline:2px dashed var(--co-color-base-negro, #1a1a1a);outline-offset:2px}.co-rich-text-editor--readonly .co-rte-embed::before,.co-rich-text-editor--disabled .co-rte-embed::before{display:none}.co-rich-text-editor--readonly .co-rte-embed.ProseMirror-selectednode,.co-rich-text-editor--readonly .co-rte-embed--selected,.co-rich-text-editor--disabled .co-rte-embed.ProseMirror-selectednode,.co-rich-text-editor--disabled .co-rte-embed--selected{outline:none !important}.co-rte-img-layout{position:absolute;z-index:50;display:flex;align-items:center;gap:2px;padding:4px;background:var(--co-semantic-surface-secondary, #fff);border:1px solid var(--co-semantic-border-default, #e0e0e0);border-radius:var(--co-border-radius-xs, 8px);box-shadow:0 2px 12px rgba(0, 0, 0, 0.12);pointer-events:auto}.co-rte-img-layout__btn{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;padding:0;border:1px solid transparent;border-radius:var(--co-border-radius-xxs, 4px);background:transparent;color:var(--co-semantic-text-default, #333);cursor:pointer;transition:background 0.12s, border-color 0.12s}.co-rte-img-layout__btn:hover{background:var(--co-semantic-surface-hover, rgba(0, 0, 0, 0.06))}.co-rte-img-layout__btn--active{background:var(--co-color-base-negro, #1a1a1a);color:var(--co-color-base-blanco, #fff)}.co-rte-img-layout__btn--active:hover{background:var(--co-color-base-negro, #333)}.co-rte-img-layout__btn[data-tooltip]{position:relative}.co-rte-img-layout__btn[data-tooltip]::after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 6px);left:50%;transform:translateX(-50%);padding:4px 8px;background:var(--co-color-base-negro, #1a1a1a);color:var(--co-color-base-blanco, #fff);font-family:var(--co-font-family-primary);font-size:11px;font-weight:500;line-height:1.3;white-space:nowrap;border-radius:4px;pointer-events:none;opacity:0;transition:opacity 0.12s ease;z-index:100}.co-rte-img-layout__btn[data-tooltip]:hover::after{opacity:1;transition-delay:0.3s}.co-rte-content [data-resize-container][data-image-layout="wrap-left"]{float:left;max-width:50%;margin:4px 16px 8px 0}.co-rte-content [data-resize-container][data-image-layout="wrap-right"]{float:right;max-width:50%;margin:4px 0 8px 16px}.co-rte-content [data-resize-container][data-image-layout="center"]{display:block;margin:12px auto}.co-rte-content [data-resize-container][data-image-layout="full-width"]{display:block;width:100%;margin:12px 0}.co-rte-content [data-resize-container][data-image-layout="full-width"] [data-resize-wrapper],.co-rte-content [data-resize-container][data-image-layout="full-width"] img{width:100%}@media (max-width: 768px){.co-rte-content [data-resize-container][data-image-layout="wrap-left"],.co-rte-content [data-resize-container][data-image-layout="wrap-right"]{float:none;max-width:100%;display:block;margin:12px 0}}.co-rte-content--site .ProseMirror{width:var(--co-rte-content-width, 80%);max-width:100%;margin:0 auto}@media (max-width: 768px){.co-rte-content--site .ProseMirror{width:100%}}.co-rich-text-editor--readonly [data-resize-handle],.co-rich-text-editor--disabled [data-resize-handle]{display:none !important}.co-rich-text-editor--readonly [data-resize-container].ProseMirror-selectednode,.co-rich-text-editor--disabled [data-resize-container].ProseMirror-selectednode,.co-rich-text-editor--readonly img.ProseMirror-selectednode,.co-rich-text-editor--disabled img.ProseMirror-selectednode{outline:none !important}`;
8
+
9
+ const CoRichTextEditor = class {
10
+ constructor(hostRef) {
11
+ registerInstance(this, hostRef);
12
+ this.coInput = createEvent(this, "coInput", 7);
13
+ this.coChange = createEvent(this, "coChange", 7);
14
+ this.coFocus = createEvent(this, "coFocus", 7);
15
+ this.coBlur = createEvent(this, "coBlur", 7);
16
+ this.coClear = createEvent(this, "coClear", 7);
17
+ this.coReady = createEvent(this, "coReady", 7);
18
+ this.coFontPopupShow = createEvent(this, "coFontPopupShow", 7);
19
+ this.coFontPopupHide = createEvent(this, "coFontPopupHide", 7);
20
+ /** ProseMirror document as a JSON string. `null`/empty = empty editor. */
21
+ this.value = null;
22
+ /** Preset controlling allowed nodes/marks, toolbar and sanitization. */
23
+ this.preset = 'task';
24
+ this.placeholder = '';
25
+ this.status = 'default';
26
+ this.disabled = false;
27
+ this.readonly = false;
28
+ this.required = false;
29
+ this.showCharacterCount = false;
30
+ this.autofocus = false;
31
+ /** Toolbar layout. `auto` uses the preset default. */
32
+ this.toolbar = 'auto';
33
+ /** BCP-47 locale for UI strings (e.g. 'en', 'es-CO', 'pt-BR'). Default English. */
34
+ this.locale = 'en';
35
+ this.ready = false;
36
+ this.hasFocus = false;
37
+ /** Character count — updated imperatively to avoid re-renders on every keystroke. */
38
+ this.charCount = 0;
39
+ this.bubbleDragged = false;
40
+ this.bubbleDragOffset = { x: 0, y: 0 };
41
+ this.bubbleDragPos = { x: 0, y: 0 };
42
+ /** Position lock — prevents floating-ui from repositioning the bubble during toolbar interactions. */
43
+ this.bubblePositionLocked = false;
44
+ this.bubbleLockPos = { x: 0, y: 0 };
45
+ this.applyingBubbleLock = false;
46
+ /** Account fonts loaded via fontLoader callback. */
47
+ this._loadedAccountFonts = [];
48
+ this._fontLoaderCalled = false;
49
+ this._fontLoaderLoading = false;
50
+ /** Last emitted JSON string — guards the value Watch against feedback loops. */
51
+ this.lastEmittedJson = null;
52
+ /** Last emitted HTML string — parents often send HTML back via value prop. */
53
+ this.lastEmittedHtml = '';
54
+ /** True while applying an external value (suppresses emit). */
55
+ this.applyingExternal = false;
56
+ this.rt = RichText;
57
+ this.imgLayoutVisible = false;
58
+ this.handleUpdate = (editor) => {
59
+ this.refreshCharCount();
60
+ if (this.applyingExternal)
61
+ return;
62
+ const out = this.buildOutput(editor);
63
+ // Track both JSON and HTML forms to prevent feedback loops.
64
+ // The parent may send back either format via the value prop.
65
+ this.lastEmittedJson = out.json ? JSON.stringify(out.json) : null;
66
+ this.lastEmittedHtml = out.html;
67
+ // Do NOT set this.value here — it triggers unnecessary Stencil re-renders
68
+ // and the Watch cycle. The parent is the source of truth for the value prop.
69
+ this.coInput.emit(out);
70
+ // In readonly mode there's no blur cycle, so commit immediately
71
+ // (e.g. task-list checkbox toggled by onReadOnlyChecked).
72
+ if (this.readonly)
73
+ this.coChange.emit(out);
74
+ };
75
+ this.handleFocus = () => {
76
+ this.hasFocus = true;
77
+ this.coFocus.emit();
78
+ };
79
+ this.handleBlur = () => {
80
+ // Delay blur processing — if the user clicked a toolbar button,
81
+ // chain().focus() will re-focus the editor before this timeout fires.
82
+ clearTimeout(this.blurTimeout);
83
+ this.blurTimeout = setTimeout(() => {
84
+ var _a, _b;
85
+ if ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isFocused)
86
+ return; // Focus was restored (toolbar click)
87
+ // Don't blur if focus moved to an element inside the bubble (e.g. hex input)
88
+ if ((_b = this.bubbleEl) === null || _b === void 0 ? void 0 : _b.contains(document.activeElement))
89
+ return;
90
+ this.hasFocus = false;
91
+ if (this.editor)
92
+ this.coChange.emit(this.buildOutput(this.editor));
93
+ this.coBlur.emit();
94
+ }, 100);
95
+ };
96
+ }
97
+ async componentDidLoad() {
98
+ var _a, _b;
99
+ if (!this.contentEl)
100
+ return;
101
+ // Create bubble element imperatively so Stencil VDOM cannot interfere
102
+ // with BubbleMenu's DOM management (it calls element.remove/appendChild).
103
+ const showToolbar = this.resolvedToolbar !== 'none' && !this.readonly && !this.disabled;
104
+ if (showToolbar) {
105
+ this.bubbleEl = this.createBubbleElement();
106
+ }
107
+ this.editor = this.rt.createEditor({
108
+ preset: this.preset,
109
+ element: this.contentEl,
110
+ content: this.parseValue(this.value),
111
+ editable: !this.disabled && !this.readonly,
112
+ placeholder: this.placeholder,
113
+ maxLength: this.maxLength,
114
+ features: this.parsedFeatures,
115
+ customExtensions: (_a = this.customExtensions) !== null && _a !== void 0 ? _a : [],
116
+ bubbleMenuElement: this.bubbleEl,
117
+ imageUpload: this.imageUpload,
118
+ onUpdate: (editor) => this.handleUpdate(editor),
119
+ onFocus: () => this.handleFocus(),
120
+ onBlur: () => this.handleBlur(),
121
+ });
122
+ // Document / "site" preset: fluid ~80% content width (see editor.css). Marks
123
+ // both editable and readonly so the reader matches the author's measure.
124
+ if (this.preset === 'document') {
125
+ this.contentEl.classList.add('co-rte-content--site');
126
+ }
127
+ // Image layout toolbar — only when actually editable. The layout itself is
128
+ // CSS-driven (keyed on `data-image-layout`); the bar just lets the author
129
+ // pick a reflow mode (inline / wrap-left / wrap-right / center / full-width).
130
+ if (showToolbar && this.imagesEnabled) {
131
+ this.contentEl.style.position = 'relative'; // offset parent for the bar
132
+ this.imgLayoutEl = this.createImageLayoutBar();
133
+ this.contentEl.appendChild(this.imgLayoutEl);
134
+ }
135
+ // Update bubble active states on every transaction
136
+ this.editor.on('transaction', ({ transaction }) => {
137
+ if (this.bubbleEl) {
138
+ this.updateBubbleActiveStates();
139
+ if ((this.bubbleDragged || this.bubblePositionLocked) && this.bubbleEl) {
140
+ this.applyBubbleFixedPosition();
141
+ }
142
+ }
143
+ // Reapply floating-image positions only when the doc changed (skip pure
144
+ // selection/cursor moves to avoid a full descendants walk on every keystroke).
145
+ if (this.imagesEnabled && transaction.docChanged)
146
+ this.syncImageLayouts();
147
+ this.updateImageLayoutBar();
148
+ });
149
+ // Clicking the toolbar closes bubble popups (link form, panels, etc.)
150
+ if (this.bubbleEl && this.toolbarEl) {
151
+ this.toolbarEl.addEventListener('mousedown', () => {
152
+ this.closeBubbleDropdowns();
153
+ });
154
+ // Hide the selection bubble while a toolbar dropdown/popover is open so
155
+ // the two never overlap in the same space (the bubble lives inside the
156
+ // content area, right where toolbar dropdowns expand into).
157
+ this.toolbarEl.addEventListener('coPopoverChange', (e) => {
158
+ var _a;
159
+ const open = (_a = e.detail) === null || _a === void 0 ? void 0 : _a.open;
160
+ this.suppressBubble(!!open);
161
+ });
162
+ }
163
+ this.lastEmittedJson = (_b = this.value) !== null && _b !== void 0 ? _b : null;
164
+ this.ready = true;
165
+ this.refreshCharCount();
166
+ this.syncToolbar();
167
+ this.coReady.emit();
168
+ if (this.autofocus)
169
+ this.editor.commands.focus();
170
+ // Tag every image container with its layout mode so the CSS rules apply.
171
+ // Runs even without the layout toolbar (readonly/disabled viewers).
172
+ requestAnimationFrame(() => this.syncImageLayouts());
173
+ }
174
+ disconnectedCallback() {
175
+ var _a, _b, _c, _d;
176
+ clearTimeout(this.blurTimeout);
177
+ clearTimeout(this.bubbleLockTimer);
178
+ (_a = this.bubbleStyleObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
179
+ if (this.bubbleDragMoveHandler)
180
+ document.removeEventListener('mousemove', this.bubbleDragMoveHandler);
181
+ if (this.bubbleDragEndHandler)
182
+ document.removeEventListener('mouseup', this.bubbleDragEndHandler);
183
+ if (this.bubbleOutsideClickHandler)
184
+ document.removeEventListener('click', this.bubbleOutsideClickHandler, true);
185
+ (_b = this.editor) === null || _b === void 0 ? void 0 : _b.destroy();
186
+ this.editor = undefined;
187
+ (_c = this.bubbleEl) === null || _c === void 0 ? void 0 : _c.remove();
188
+ (_d = this.imgLayoutEl) === null || _d === void 0 ? void 0 : _d.remove();
189
+ }
190
+ componentDidRender() {
191
+ this.syncToolbar();
192
+ }
193
+ onAccountFontsChange() {
194
+ var _a;
195
+ // Re-render the font dropdown list if it's open
196
+ if (this._fontDropdownRenderFn) {
197
+ const filter = ((_a = this._fontDropdownSearchInput) === null || _a === void 0 ? void 0 : _a.value) || '';
198
+ this._fontDropdownRenderFn(filter);
199
+ }
200
+ }
201
+ onValueChange(next) {
202
+ if (!this.editor || this.applyingExternal)
203
+ return;
204
+ const incoming = next !== null && next !== void 0 ? next : null;
205
+ // Skip if this value matches what we last emitted (JSON or HTML form).
206
+ // This prevents the destructive feedback loop where the parent sends
207
+ // back our own output and setContent resets the editor on every keystroke.
208
+ if (incoming === this.lastEmittedJson || incoming === this.lastEmittedHtml)
209
+ return;
210
+ this.applyingExternal = true;
211
+ try {
212
+ if (incoming === '' || incoming === null) {
213
+ this.editor.commands.clearContent(false);
214
+ }
215
+ else {
216
+ this.editor.commands.setContent(this.parseValue(next), { emitUpdate: false });
217
+ }
218
+ }
219
+ finally {
220
+ this.applyingExternal = false;
221
+ this.lastEmittedJson = incoming;
222
+ this.lastEmittedHtml = '';
223
+ this.refreshCharCount();
224
+ }
225
+ }
226
+ onEditableChange() {
227
+ var _a;
228
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.setEditable(!this.disabled && !this.readonly);
229
+ }
230
+ /* ── Public methods (escape hatches + imperative control) ── */
231
+ async getJSON() {
232
+ return this.editor && !this.editor.isEmpty ? this.editor.getJSON() : null;
233
+ }
234
+ async getHtml() {
235
+ return this.editor ? this.sanitizeHtml(this.editor.getHTML()) : '';
236
+ }
237
+ async getText() {
238
+ var _a, _b;
239
+ return (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.getText()) !== null && _b !== void 0 ? _b : '';
240
+ }
241
+ async clear() {
242
+ if (!this.editor)
243
+ return;
244
+ this.editor.commands.clearContent(true);
245
+ this.coClear.emit();
246
+ }
247
+ async focusEditor() {
248
+ var _a;
249
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.commands.focus();
250
+ }
251
+ async setContent(content) {
252
+ var _a;
253
+ (_a = this.editor) === null || _a === void 0 ? void 0 : _a.commands.setContent(content);
254
+ }
255
+ async getEditorInstance() {
256
+ var _a;
257
+ return (_a = this.editor) !== null && _a !== void 0 ? _a : null;
258
+ }
259
+ /* ── internals ── */
260
+ /** Whether the image node is enabled (mirrors presets.ts `wantImage` logic). */
261
+ get imagesEnabled() {
262
+ var _a;
263
+ const f = this.parsedFeatures;
264
+ return (_a = f === null || f === void 0 ? void 0 : f.image) !== null && _a !== void 0 ? _a : this.preset === 'document';
265
+ }
266
+ get parsedFeatures() {
267
+ if (!this.features)
268
+ return undefined;
269
+ if (typeof this.features === 'string') {
270
+ try {
271
+ return JSON.parse(this.features);
272
+ }
273
+ catch (_a) {
274
+ return undefined;
275
+ }
276
+ }
277
+ return this.features;
278
+ }
279
+ parseValue(v) {
280
+ if (!v)
281
+ return '';
282
+ try {
283
+ return JSON.parse(v);
284
+ }
285
+ catch (_a) {
286
+ return v; // tolerate an HTML string
287
+ }
288
+ }
289
+ sanitizeHtml(html) {
290
+ return this.rt.sanitize(html, this.preset);
291
+ }
292
+ buildOutput(editor) {
293
+ const empty = editor.isEmpty;
294
+ return {
295
+ json: empty ? null : editor.getJSON(),
296
+ html: empty ? '' : this.sanitizeHtml(editor.getHTML()),
297
+ text: editor.getText(),
298
+ };
299
+ }
300
+ /** Lock the bubble position so floating-ui doesn't reposition it. */
301
+ lockBubblePosition(durationMs = 1000) {
302
+ if (!this.bubbleEl)
303
+ return;
304
+ const rect = this.bubbleEl.getBoundingClientRect();
305
+ if (rect.width === 0)
306
+ return; // bubble not visible
307
+ this.bubbleLockPos = { x: rect.left, y: rect.top };
308
+ this.bubblePositionLocked = true;
309
+ clearTimeout(this.bubbleLockTimer);
310
+ this.bubbleLockTimer = setTimeout(() => {
311
+ this.bubblePositionLocked = false;
312
+ }, durationMs);
313
+ }
314
+ /** Apply fixed position to the bubble, overriding floating-ui. */
315
+ applyBubbleFixedPosition() {
316
+ if (!this.bubbleEl)
317
+ return;
318
+ const pos = this.bubbleDragged ? this.bubbleDragPos : this.bubbleLockPos;
319
+ this.applyingBubbleLock = true;
320
+ this.bubbleEl.style.position = 'fixed';
321
+ this.bubbleEl.style.top = `${pos.y}px`;
322
+ this.bubbleEl.style.left = `${pos.x}px`;
323
+ this.bubbleEl.style.transform = 'none';
324
+ this.bubbleEl.style.visibility = 'visible';
325
+ requestAnimationFrame(() => { this.applyingBubbleLock = false; });
326
+ }
327
+ /** Watch for floating-ui style changes and override them when locked/dragged. */
328
+ setupBubbleStyleObserver(bubble) {
329
+ // Use BubbleMenu plugin's onHide/onShow callbacks (dispatched as custom
330
+ // events from create-editor) for reliable drag state management.
331
+ // These fire synchronously inside hide()/show(), avoiding microtask races.
332
+ bubble.addEventListener('co-bubble-hide', () => {
333
+ this.bubbleDragged = false;
334
+ this.bubblePositionLocked = false;
335
+ clearTimeout(this.bubbleLockTimer);
336
+ this.closeBubbleDropdowns();
337
+ bubble.style.position = '';
338
+ bubble.style.top = '';
339
+ bubble.style.left = '';
340
+ bubble.style.transform = '';
341
+ });
342
+ bubble.addEventListener('co-bubble-show', () => {
343
+ this.bubbleDragged = false;
344
+ this.bubblePositionLocked = false;
345
+ });
346
+ // MutationObserver only handles overriding floating-ui position
347
+ // while the bubble is actively dragged or position-locked.
348
+ this.bubbleStyleObserver = new MutationObserver(() => {
349
+ if (this.applyingBubbleLock)
350
+ return;
351
+ if (!this.bubblePositionLocked && !this.bubbleDragged)
352
+ return;
353
+ this.applyBubbleFixedPosition();
354
+ });
355
+ this.bubbleStyleObserver.observe(bubble, {
356
+ attributes: true,
357
+ attributeFilter: ['style'],
358
+ });
359
+ }
360
+ /**
361
+ * Hide/show the selection bubble while a toolbar dropdown is open. Uses a
362
+ * class with `!important` so it wins over the BubbleMenu plugin's inline
363
+ * display/visibility writes. When unsuppressed, the plugin's own state
364
+ * (selection still active) reveals it again on the next update.
365
+ */
366
+ suppressBubble(on) {
367
+ if (!this.bubbleEl)
368
+ return;
369
+ this.bubbleEl.classList.toggle('co-rte-bubble--suppressed', on);
370
+ if (on)
371
+ this.closeBubbleDropdowns();
372
+ }
373
+ /** Close all open sub-dropdowns inside the bubble. */
374
+ closeBubbleDropdowns() {
375
+ if (!this.bubbleEl)
376
+ return;
377
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__select-dropdown').forEach(d => {
378
+ d.style.display = 'none';
379
+ });
380
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__color-dropdown').forEach(d => {
381
+ d.style.display = 'none';
382
+ });
383
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__panel').forEach(d => {
384
+ d.style.display = 'none';
385
+ });
386
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__overflow-menu').forEach(d => {
387
+ d.style.display = 'none';
388
+ });
389
+ if (this.bubbleLinkFormEl) {
390
+ this.bubbleLinkFormEl.style.display = 'none';
391
+ }
392
+ }
393
+ refreshCharCount() {
394
+ var _a;
395
+ const storage = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.storage;
396
+ if (storage === null || storage === void 0 ? void 0 : storage.characterCount) {
397
+ this.charCount = storage.characterCount.characters();
398
+ // Update DOM directly to avoid Stencil re-renders on every keystroke
399
+ if (this.charCountEl) {
400
+ this.charCountEl.textContent = this.maxLength != null
401
+ ? `${this.charCount} / ${this.maxLength}`
402
+ : `${this.charCount}`;
403
+ }
404
+ }
405
+ }
406
+ syncToolbar() {
407
+ if (this.toolbarEl && this.editor && this.toolbarEl.editor !== this.editor) {
408
+ this.toolbarEl.editor = this.editor;
409
+ }
410
+ if (this.toolbarEl) {
411
+ this.toolbarEl.imageUpload = this.imageUpload;
412
+ }
413
+ }
414
+ get resolvedToolbar() {
415
+ if (this.toolbar !== 'auto')
416
+ return this.toolbar;
417
+ return this.rt.defaultToolbarForPreset(this.preset);
418
+ }
419
+ get resolvedFontFamilies() {
420
+ if (!this.fontFamilies)
421
+ return CoRichTextEditor.DEFAULT_FONTS;
422
+ if (typeof this.fontFamilies === 'string') {
423
+ try {
424
+ return JSON.parse(this.fontFamilies);
425
+ }
426
+ catch (_a) {
427
+ return CoRichTextEditor.DEFAULT_FONTS;
428
+ }
429
+ }
430
+ return this.fontFamilies;
431
+ }
432
+ get resolvedAccountFonts() {
433
+ // Prefer prop over loaded fonts
434
+ if (this.accountFonts) {
435
+ if (typeof this.accountFonts === 'string') {
436
+ try {
437
+ return JSON.parse(this.accountFonts);
438
+ }
439
+ catch (_a) {
440
+ return [];
441
+ }
442
+ }
443
+ return this.accountFonts;
444
+ }
445
+ return this._loadedAccountFonts;
446
+ }
447
+ registerFontFace(name, url) {
448
+ if (!url || !name || CoRichTextEditor._registeredFonts.has(name))
449
+ return;
450
+ CoRichTextEditor._registeredFonts.add(name);
451
+ try {
452
+ const face = new FontFace(name, `url("${url}")`);
453
+ face.load().then(() => document.fonts.add(face)).catch(() => { });
454
+ }
455
+ catch ( /* ignore */_a) { /* ignore */ }
456
+ }
457
+ /** Load account fonts via the fontLoader callback (called once). */
458
+ async loadFontsViaCallback() {
459
+ var _a, _b, _c;
460
+ if (this._fontLoaderCalled || !this.fontLoader)
461
+ return;
462
+ this._fontLoaderCalled = true;
463
+ this._fontLoaderLoading = true;
464
+ // Re-render to show loading state
465
+ (_a = this._fontDropdownRenderFn) === null || _a === void 0 ? void 0 : _a.call(this, '');
466
+ try {
467
+ const fonts = await this.fontLoader();
468
+ if (Array.isArray(fonts)) {
469
+ this._loadedAccountFonts = fonts.map(f => {
470
+ if (f.url)
471
+ this.registerFontFace(f.label, f.url);
472
+ return { label: f.label, value: f.value };
473
+ });
474
+ }
475
+ }
476
+ catch (e) {
477
+ console.error('[co-rich-text-editor] fontLoader error', e);
478
+ }
479
+ finally {
480
+ this._fontLoaderLoading = false;
481
+ // Re-render with loaded fonts
482
+ const filter = ((_b = this._fontDropdownSearchInput) === null || _b === void 0 ? void 0 : _b.value) || '';
483
+ (_c = this._fontDropdownRenderFn) === null || _c === void 0 ? void 0 : _c.call(this, filter);
484
+ }
485
+ }
486
+ get helperIcon() {
487
+ switch (this.status) {
488
+ case 'error': return 'warning-circle';
489
+ case 'success': return 'check-circle';
490
+ case 'warning': return 'warning-circle';
491
+ default: return 'info';
492
+ }
493
+ }
494
+ /* ── Bubble menu (imperative — outside Stencil VDOM) ── */
495
+ /**
496
+ * Create the bubble menu element imperatively. BubbleMenu v3 manages
497
+ * the element via remove()/appendChild(), which conflicts with Stencil's
498
+ * virtual DOM reconciliation. By creating it outside the VDOM, Stencil
499
+ * won't recreate or interfere with the element.
500
+ */
501
+ createBubbleElement() {
502
+ const bubble = document.createElement('div');
503
+ bubble.className = 'co-rte-bubble';
504
+ // Start hidden and absolutely positioned so it never takes document flow space.
505
+ // BubbleMenu's floating-ui will manage position via inline styles when shown.
506
+ bubble.style.visibility = 'hidden';
507
+ bubble.style.position = 'absolute';
508
+ bubble.style.top = '0';
509
+ bubble.style.left = '0';
510
+ // Prevent any bubble click from stealing editor focus
511
+ // and lock bubble position during any toolbar interaction.
512
+ bubble.addEventListener('mousedown', (e) => {
513
+ if (e.target.tagName !== 'INPUT')
514
+ e.preventDefault();
515
+ this.lockBubblePosition();
516
+ });
517
+ // Close dropdowns/panels when clicking outside the bubble
518
+ this.bubbleOutsideClickHandler = (e) => {
519
+ if (!bubble.contains(e.target)) {
520
+ this.closeBubbleDropdowns();
521
+ }
522
+ };
523
+ document.addEventListener('click', this.bubbleOutsideClickHandler, true);
524
+ // Watch for floating-ui style overrides and restore locked position
525
+ this.setupBubbleStyleObserver(bubble);
526
+ const isDocument = this.preset === 'document';
527
+ /* ── Drag handle (document only) ── */
528
+ if (isDocument) {
529
+ const dragHandle = document.createElement('div');
530
+ dragHandle.className = 'co-rte-bubble__drag-handle';
531
+ dragHandle.innerHTML = `<co-icon name="dots-six-vertical" size="14"></co-icon>`;
532
+ dragHandle.addEventListener('mousedown', (e) => {
533
+ e.preventDefault();
534
+ e.stopPropagation();
535
+ const rect = bubble.getBoundingClientRect();
536
+ this.bubbleDragOffset = { x: e.clientX - rect.left, y: e.clientY - rect.top };
537
+ if (!this.bubbleDragged) {
538
+ this.bubbleDragPos = { x: rect.left, y: rect.top };
539
+ }
540
+ this.bubbleDragged = true;
541
+ this.bubbleDragMoveHandler = (ev) => {
542
+ this.bubbleDragPos.x = ev.clientX - this.bubbleDragOffset.x;
543
+ this.bubbleDragPos.y = ev.clientY - this.bubbleDragOffset.y;
544
+ bubble.style.position = 'fixed';
545
+ bubble.style.top = `${this.bubbleDragPos.y}px`;
546
+ bubble.style.left = `${this.bubbleDragPos.x}px`;
547
+ bubble.style.transform = 'none';
548
+ bubble.style.visibility = 'visible';
549
+ };
550
+ this.bubbleDragEndHandler = () => {
551
+ document.removeEventListener('mousemove', this.bubbleDragMoveHandler);
552
+ document.removeEventListener('mouseup', this.bubbleDragEndHandler);
553
+ };
554
+ document.addEventListener('mousemove', this.bubbleDragMoveHandler);
555
+ document.addEventListener('mouseup', this.bubbleDragEndHandler);
556
+ });
557
+ bubble.appendChild(dragHandle);
558
+ } // end isDocument drag handle
559
+ /* ── Single row: all controls ── */
560
+ const row = document.createElement('div');
561
+ row.className = 'co-rte-bubble__row';
562
+ // --- Advanced controls (document preset only) ---
563
+ // Panels will be appended to bubble root (not inside the row) at the end.
564
+ let fontSizePanel = null;
565
+ let fontWeightPanel = null;
566
+ let lineHeightPanelEl = null;
567
+ let letterSpacingPanelEl = null;
568
+ let bgColorPanelEl = null;
569
+ let overflowResult = null;
570
+ if (isDocument) {
571
+ // --- Font Family select (with search) ---
572
+ const fontFamilyWrap = this.createBubbleFontFamilySelect();
573
+ row.appendChild(fontFamilyWrap);
574
+ // --- Font Size panel (draggable with custom input) ---
575
+ fontSizePanel = this.createBubbleFontSizePanel();
576
+ row.appendChild(fontSizePanel.wrap);
577
+ // --- Font Weight panel (draggable, two-column) ---
578
+ fontWeightPanel = this.createBubbleFontWeightPanel();
579
+ row.appendChild(fontWeightPanel.wrap);
580
+ row.appendChild(this.createSep());
581
+ // --- Text color picker ---
582
+ const colorWrap = this.createBubbleColorPicker('textColor', (color) => {
583
+ if (!this.editor)
584
+ return;
585
+ this.editor.chain().focus().setColor(color).run();
586
+ });
587
+ row.appendChild(colorWrap);
588
+ row.appendChild(this.createSep());
589
+ } // end isDocument advanced controls
590
+ // --- B I U (all presets except comment which disables underline) ---
591
+ const _s = getRichTextStrings(this.locale);
592
+ const formatBtns = [
593
+ { action: 'bold', icon: 'text-b', label: _s.bold, check: 'bold' },
594
+ { action: 'italic', icon: 'text-italic', label: _s.italic, check: 'italic' },
595
+ ];
596
+ // Underline is available on task, email, document (not comment)
597
+ if (this.preset !== 'comment') {
598
+ formatBtns.push({ action: 'underline', icon: 'text-underline', label: _s.underline, check: 'underline' });
599
+ }
600
+ formatBtns.forEach(({ action, icon, label, check }) => {
601
+ const btn = this.createBubbleBtn(icon, label, action, check, () => {
602
+ if (!this.editor)
603
+ return;
604
+ const chain = this.editor.chain().focus();
605
+ switch (action) {
606
+ case 'bold':
607
+ chain.toggleBold().run();
608
+ break;
609
+ case 'italic':
610
+ chain.toggleItalic().run();
611
+ break;
612
+ case 'underline':
613
+ chain.toggleUnderline().run();
614
+ break;
615
+ }
616
+ });
617
+ row.appendChild(btn);
618
+ });
619
+ row.appendChild(this.createSep());
620
+ // --- Alignment buttons (document and email only) ---
621
+ if (isDocument || this.preset === 'email') {
622
+ const alignments = [
623
+ { align: 'left', icon: 'text-align-left', label: _s.alignLeft },
624
+ { align: 'center', icon: 'text-align-center', label: _s.center },
625
+ { align: 'right', icon: 'text-align-right', label: _s.alignRight },
626
+ { align: 'justify', icon: 'text-align-justify', label: _s.justify },
627
+ ];
628
+ alignments.forEach(({ align, icon, label }) => {
629
+ const btn = document.createElement('button');
630
+ btn.type = 'button';
631
+ btn.className = 'co-rte-bubble__btn';
632
+ btn.title = label;
633
+ btn.setAttribute('aria-label', label);
634
+ btn.setAttribute('data-action', 'textAlign');
635
+ btn.setAttribute('data-align', align);
636
+ btn.innerHTML = `<co-icon name="${icon}" size="16"></co-icon>`;
637
+ btn.addEventListener('click', () => {
638
+ if (!this.editor)
639
+ return;
640
+ this.editor.chain().focus().setTextAlign(align).run();
641
+ });
642
+ row.appendChild(btn);
643
+ });
644
+ row.appendChild(this.createSep());
645
+ } // end alignment
646
+ // --- Bullet / Ordered list (task, email — not comment, not document) ---
647
+ // For document preset, lists are moved to the overflow menu.
648
+ if (this.preset !== 'comment' && !isDocument) {
649
+ row.appendChild(this.createBubbleBtn('list-bullets', _s.bulletList, 'bulletList', 'bulletList', () => {
650
+ if (!this.editor)
651
+ return;
652
+ this.editor.chain().focus().toggleBulletList().run();
653
+ }));
654
+ row.appendChild(this.createBubbleBtn('list-numbers', _s.orderedList, 'orderedList', 'orderedList', () => {
655
+ if (!this.editor)
656
+ return;
657
+ this.editor.chain().focus().toggleOrderedList().run();
658
+ }));
659
+ row.appendChild(this.createSep());
660
+ } // end lists (non-document)
661
+ // --- Link (all presets) ---
662
+ const linkBtn = this.createBubbleBtn('link', _s.link, 'link', 'link', () => {
663
+ if (!this.editor)
664
+ return;
665
+ this.toggleBubbleLinkForm(true);
666
+ });
667
+ row.appendChild(linkBtn);
668
+ // --- Overflow menu (document only) ---
669
+ // Superscript, subscript, lists, strikethrough, bg color, line height,
670
+ // letter spacing, horizontal rule, clear formatting — all in overflow.
671
+ if (isDocument) {
672
+ row.appendChild(this.createSep());
673
+ lineHeightPanelEl = this.createBubbleLineHeightPanel();
674
+ letterSpacingPanelEl = this.createBubbleLetterSpacingPanel();
675
+ bgColorPanelEl = this.createBubbleBgColorPanel();
676
+ overflowResult = this.createBubbleOverflowMenu({
677
+ lineHeight: lineHeightPanelEl,
678
+ letterSpacing: letterSpacingPanelEl,
679
+ bgColor: bgColorPanelEl,
680
+ });
681
+ row.appendChild(overflowResult.overflowWrap);
682
+ } // end isDocument overflow
683
+ bubble.appendChild(row);
684
+ // Append floating panels to bubble root (outside the row, so they float freely)
685
+ if (isDocument) {
686
+ if (fontSizePanel)
687
+ bubble.appendChild(fontSizePanel.panelEl);
688
+ if (fontWeightPanel)
689
+ bubble.appendChild(fontWeightPanel.panelEl);
690
+ if (lineHeightPanelEl)
691
+ bubble.appendChild(lineHeightPanelEl);
692
+ if (letterSpacingPanelEl)
693
+ bubble.appendChild(letterSpacingPanelEl);
694
+ if (bgColorPanelEl)
695
+ bubble.appendChild(bgColorPanelEl);
696
+ }
697
+ // Link form (hidden by default)
698
+ const linkForm = document.createElement('div');
699
+ linkForm.className = 'co-rte-bubble__link-form';
700
+ linkForm.style.display = 'none';
701
+ this.bubbleLinkFormEl = linkForm;
702
+ const linkInput = document.createElement('input');
703
+ linkInput.type = 'url';
704
+ linkInput.className = 'co-rte-bubble__link-input';
705
+ linkInput.placeholder = 'https://...';
706
+ this.bubbleLinkInputEl = linkInput;
707
+ linkInput.addEventListener('keydown', (e) => {
708
+ if (e.key === 'Enter')
709
+ this.submitBubbleLinkImperative();
710
+ if (e.key === 'Escape')
711
+ this.toggleBubbleLinkForm(false);
712
+ });
713
+ const linkSubmit = document.createElement('button');
714
+ linkSubmit.type = 'button';
715
+ linkSubmit.className = 'co-rte-bubble__link-btn';
716
+ linkSubmit.innerHTML = `<co-icon name="check" size="14"></co-icon>`;
717
+ linkSubmit.addEventListener('click', () => this.submitBubbleLinkImperative());
718
+ const linkUnlink = document.createElement('button');
719
+ linkUnlink.type = 'button';
720
+ linkUnlink.className = 'co-rte-bubble__link-btn co-rte-bubble__link-unlink';
721
+ linkUnlink.title = _s.unlinkLink;
722
+ linkUnlink.innerHTML = `<co-icon name="link-break" size="14"></co-icon>`;
723
+ linkUnlink.addEventListener('click', () => {
724
+ if (!this.editor)
725
+ return;
726
+ this.editor.chain().focus().unsetLink().run();
727
+ this.toggleBubbleLinkForm(false);
728
+ });
729
+ this.bubbleLinkUnlinkEl = linkUnlink;
730
+ linkForm.appendChild(linkInput);
731
+ linkForm.appendChild(linkSubmit);
732
+ linkForm.appendChild(linkUnlink);
733
+ bubble.appendChild(linkForm);
734
+ return bubble;
735
+ }
736
+ /** Helper: create a separator span */
737
+ createSep() {
738
+ const sep = document.createElement('span');
739
+ sep.className = 'co-rte-bubble__sep';
740
+ return sep;
741
+ }
742
+ /**
743
+ * Position a dropdown above or below the trigger depending on available
744
+ * viewport space. Sets `data-position="above"|"below"` so CSS can flip.
745
+ */
746
+ positionDropdown(trigger, dropdown) {
747
+ const triggerRect = trigger.getBoundingClientRect();
748
+ // The dropdown is already display:block when this is called.
749
+ // Remove any previous position so it can be measured at its natural height.
750
+ dropdown.removeAttribute('data-position');
751
+ dropdown.style.removeProperty('left');
752
+ dropdown.style.removeProperty('transform');
753
+ const dropH = dropdown.offsetHeight || 320;
754
+ const dropW = dropdown.offsetWidth || 224;
755
+ const spaceAbove = triggerRect.top;
756
+ const spaceBelow = window.innerHeight - triggerRect.bottom;
757
+ if (spaceBelow >= dropH || spaceBelow > spaceAbove) {
758
+ dropdown.setAttribute('data-position', 'below');
759
+ }
760
+ else {
761
+ dropdown.setAttribute('data-position', 'above');
762
+ }
763
+ // Clamp horizontal position so the dropdown stays within the viewport.
764
+ // The dropdown is positioned relative to its parent (trigger wrapper).
765
+ // Default CSS uses left:50% + translateX(-50%) to center; we override
766
+ // when centering would push the dropdown outside the viewport.
767
+ const isColorDropdown = dropdown.classList.contains('co-rte-bubble__color-dropdown');
768
+ if (isColorDropdown) {
769
+ const parentRect = (trigger.parentElement || trigger).getBoundingClientRect();
770
+ // Desired center-aligned left edge in viewport coords
771
+ const idealLeft = parentRect.left + parentRect.width / 2 - dropW / 2;
772
+ const idealRight = idealLeft + dropW;
773
+ const viewportPad = 8;
774
+ if (idealLeft < viewportPad) {
775
+ // Would overflow left — align to left edge of trigger
776
+ dropdown.style.left = '0';
777
+ dropdown.style.transform = 'none';
778
+ }
779
+ else if (idealRight > window.innerWidth - viewportPad) {
780
+ // Would overflow right — align to right edge of trigger
781
+ dropdown.style.left = 'auto';
782
+ dropdown.style.right = '0';
783
+ dropdown.style.transform = 'none';
784
+ }
785
+ // else: default centering from CSS is fine
786
+ }
787
+ }
788
+ positionPanelNearBubble(panel) {
789
+ if (!this.bubbleEl)
790
+ return;
791
+ const overflowMenu = this.bubbleEl.querySelector('.co-rte-bubble__overflow-menu');
792
+ const anchorRect = overflowMenu && overflowMenu.style.display !== 'none'
793
+ ? overflowMenu.getBoundingClientRect()
794
+ : this.bubbleEl.getBoundingClientRect();
795
+ const panelH = panel.offsetHeight || 320;
796
+ const panelW = panel.offsetWidth || 230;
797
+ const gap = 4;
798
+ const pad = 8;
799
+ let top = anchorRect.top;
800
+ if (top + panelH > window.innerHeight - pad)
801
+ top = window.innerHeight - pad - panelH;
802
+ if (top < pad)
803
+ top = pad;
804
+ let left = anchorRect.left - panelW - gap;
805
+ if (left < pad)
806
+ left = anchorRect.right + gap;
807
+ if (left + panelW > window.innerWidth - pad)
808
+ left = window.innerWidth - pad - panelW;
809
+ panel.style.position = 'fixed';
810
+ panel.style.top = `${top}px`;
811
+ panel.style.left = `${left}px`;
812
+ panel.style.bottom = 'auto';
813
+ panel.style.right = 'auto';
814
+ panel.style.transform = 'none';
815
+ panel.removeAttribute('data-position');
816
+ }
817
+ /** Helper: create a toggle button for the bubble */
818
+ createBubbleBtn(icon, label, action, check, onClick) {
819
+ const btn = document.createElement('button');
820
+ btn.type = 'button';
821
+ btn.className = 'co-rte-bubble__btn';
822
+ btn.title = label;
823
+ btn.setAttribute('aria-label', label);
824
+ btn.setAttribute('data-action', action);
825
+ btn.setAttribute('data-check', check);
826
+ btn.innerHTML = `<co-icon name="${icon}" size="16"></co-icon>`;
827
+ btn.addEventListener('click', onClick);
828
+ return btn;
829
+ }
830
+ /** Creates the font family dropdown with search for the bubble menu. */
831
+ createBubbleFontFamilySelect() {
832
+ const wrap = document.createElement('div');
833
+ wrap.className = 'co-rte-bubble__select co-rte-bubble__select--font';
834
+ wrap.setAttribute('data-select', 'fontFamily');
835
+ const trigger = document.createElement('button');
836
+ trigger.type = 'button';
837
+ trigger.className = 'co-rte-bubble__select-trigger';
838
+ trigger.innerHTML = `<span class="co-rte-bubble__select-label">Sans-serif</span><co-icon name="caret-down" size="12"></co-icon>`;
839
+ const dropdown = document.createElement('div');
840
+ dropdown.className = 'co-rte-bubble__select-dropdown co-rte-bubble__select-dropdown--font';
841
+ dropdown.style.display = 'none';
842
+ // Search input
843
+ const searchWrap = document.createElement('div');
844
+ searchWrap.className = 'co-rte-bubble__font-search';
845
+ const searchInput = document.createElement('input');
846
+ searchInput.type = 'text';
847
+ searchInput.className = 'co-rte-bubble__font-search-input';
848
+ searchInput.placeholder = getRichTextStrings(this.locale).searchFont;
849
+ searchWrap.appendChild(searchInput);
850
+ dropdown.appendChild(searchWrap);
851
+ // Font list container
852
+ const listEl = document.createElement('div');
853
+ listEl.className = 'co-rte-bubble__font-list';
854
+ dropdown.appendChild(listEl);
855
+ const createFontOption = (label, value) => {
856
+ const opt = document.createElement('button');
857
+ opt.type = 'button';
858
+ opt.className = 'co-rte-bubble__select-option';
859
+ opt.setAttribute('data-value', value);
860
+ opt.textContent = label;
861
+ opt.style.fontFamily = value.includes(',') ? value : `"${value}", sans-serif`;
862
+ opt.addEventListener('click', () => {
863
+ if (!this.editor)
864
+ return;
865
+ this.editor.chain().focus().setFontFamily(value).run();
866
+ dropdown.style.display = 'none';
867
+ const labelEl = trigger.querySelector('.co-rte-bubble__select-label');
868
+ if (labelEl)
869
+ labelEl.textContent = label;
870
+ searchInput.value = '';
871
+ this.coFontPopupHide.emit();
872
+ });
873
+ return opt;
874
+ };
875
+ const renderFonts = (filter) => {
876
+ listEl.innerHTML = '';
877
+ const term = filter.toLowerCase();
878
+ const accountFonts = this.resolvedAccountFonts;
879
+ const systemFonts = this.resolvedFontFamilies;
880
+ const filteredAccount = term ? accountFonts.filter(f => f.label.toLowerCase().includes(term)) : accountFonts;
881
+ const filteredSystem = term ? systemFonts.filter(f => f.label.toLowerCase().includes(term)) : systemFonts;
882
+ if (!filteredAccount.length && !filteredSystem.length) {
883
+ const empty = document.createElement('div');
884
+ empty.className = 'co-rte-bubble__font-empty';
885
+ empty.textContent = getRichTextStrings(this.locale).noResults;
886
+ listEl.appendChild(empty);
887
+ return;
888
+ }
889
+ // Loading indicator
890
+ if ((this.fontsLoading || this._fontLoaderLoading) && !filteredAccount.length) {
891
+ const loading = document.createElement('div');
892
+ loading.className = 'co-rte-bubble__font-empty';
893
+ loading.textContent = getRichTextStrings(this.locale).loadingFonts;
894
+ listEl.appendChild(loading);
895
+ }
896
+ // Imported fonts section
897
+ if (filteredAccount.length) {
898
+ const header = document.createElement('div');
899
+ header.className = 'co-rte-bubble__font-section-header';
900
+ header.textContent = getRichTextStrings(this.locale).importedFonts;
901
+ listEl.appendChild(header);
902
+ filteredAccount.forEach(({ label, value }) => listEl.appendChild(createFontOption(label, value)));
903
+ }
904
+ // System fonts section
905
+ if (filteredSystem.length) {
906
+ const header = document.createElement('div');
907
+ header.className = 'co-rte-bubble__font-section-header';
908
+ header.textContent = getRichTextStrings(this.locale).systemFonts;
909
+ listEl.appendChild(header);
910
+ filteredSystem.forEach(({ label, value }) => listEl.appendChild(createFontOption(label, value)));
911
+ }
912
+ };
913
+ searchInput.addEventListener('input', () => renderFonts(searchInput.value));
914
+ // Re-render fonts when accountFonts prop changes (MutationObserver on the host)
915
+ this._fontDropdownRenderFn = renderFonts;
916
+ this._fontDropdownSearchInput = searchInput;
917
+ trigger.addEventListener('click', () => {
918
+ const parent = wrap.closest('.co-rte-bubble');
919
+ if (parent) {
920
+ parent.querySelectorAll('.co-rte-bubble__select-dropdown').forEach(d => {
921
+ if (d !== dropdown)
922
+ d.style.display = 'none';
923
+ });
924
+ parent.querySelectorAll('.co-rte-bubble__color-dropdown').forEach(d => {
925
+ d.style.display = 'none';
926
+ });
927
+ }
928
+ const isOpen = dropdown.style.display !== 'none';
929
+ dropdown.style.display = isOpen ? 'none' : 'block';
930
+ if (!isOpen) {
931
+ this.coFontPopupShow.emit();
932
+ this.loadFontsViaCallback();
933
+ this.positionDropdown(trigger, dropdown);
934
+ renderFonts('');
935
+ setTimeout(() => searchInput.focus(), 0);
936
+ }
937
+ else {
938
+ this.coFontPopupHide.emit();
939
+ }
940
+ });
941
+ wrap.appendChild(trigger);
942
+ wrap.appendChild(dropdown);
943
+ return wrap;
944
+ }
945
+ /** Creates a compact dropdown-select for the bubble menu. */
946
+ createBubbleSelect(name, options, defaultLabel, onChange) {
947
+ const wrap = document.createElement('div');
948
+ wrap.className = 'co-rte-bubble__select';
949
+ wrap.setAttribute('data-select', name);
950
+ const trigger = document.createElement('button');
951
+ trigger.type = 'button';
952
+ trigger.className = 'co-rte-bubble__select-trigger';
953
+ trigger.innerHTML = `<span class="co-rte-bubble__select-label">${defaultLabel}</span><co-icon name="caret-down" size="12"></co-icon>`;
954
+ const dropdown = document.createElement('div');
955
+ dropdown.className = 'co-rte-bubble__select-dropdown';
956
+ dropdown.style.display = 'none';
957
+ options.forEach(({ label, value }) => {
958
+ const opt = document.createElement('button');
959
+ opt.type = 'button';
960
+ opt.className = 'co-rte-bubble__select-option';
961
+ opt.setAttribute('data-value', value);
962
+ opt.textContent = label;
963
+ // Preview font weight in the option
964
+ if (name === 'fontWeight') {
965
+ opt.style.fontWeight = value;
966
+ }
967
+ opt.addEventListener('click', () => {
968
+ onChange(value);
969
+ dropdown.style.display = 'none';
970
+ const labelEl = trigger.querySelector('.co-rte-bubble__select-label');
971
+ if (labelEl)
972
+ labelEl.textContent = label;
973
+ });
974
+ dropdown.appendChild(opt);
975
+ });
976
+ trigger.addEventListener('click', () => {
977
+ // Close other open dropdowns in the bubble
978
+ const parent = wrap.closest('.co-rte-bubble');
979
+ if (parent) {
980
+ parent.querySelectorAll('.co-rte-bubble__select-dropdown').forEach(d => {
981
+ if (d !== dropdown)
982
+ d.style.display = 'none';
983
+ });
984
+ parent.querySelectorAll('.co-rte-bubble__color-dropdown').forEach(d => {
985
+ d.style.display = 'none';
986
+ });
987
+ }
988
+ const isOpen = dropdown.style.display !== 'none';
989
+ dropdown.style.display = isOpen ? 'none' : 'block';
990
+ if (!isOpen)
991
+ this.positionDropdown(trigger, dropdown);
992
+ });
993
+ wrap.appendChild(trigger);
994
+ wrap.appendChild(dropdown);
995
+ return wrap;
996
+ }
997
+ /** Creates a compact color picker button for the bubble menu. */
998
+ createBubbleColorPicker(name, onChange) {
999
+ const colors = [
1000
+ '#000000', '#434343', '#666666', '#999999', '#b7b7b7', '#cccccc',
1001
+ '#d9d9d9', '#efefef', '#f3f3f3', '#ffffff',
1002
+ '#980000', '#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff',
1003
+ '#4a86e8', '#0000ff', '#9900ff', '#ff00ff',
1004
+ '#e6b8af', '#f4cccc', '#fce5cd', '#fff2cc', '#d9ead3', '#d0e0e3',
1005
+ '#c9daf8', '#cfe2f3', '#d9d2e9', '#ead1dc',
1006
+ ];
1007
+ const wrap = document.createElement('div');
1008
+ wrap.className = 'co-rte-bubble__color';
1009
+ wrap.setAttribute('data-color', name);
1010
+ const iconName = name === 'textColor' ? '' : 'highlighter';
1011
+ const trigger = document.createElement('button');
1012
+ trigger.type = 'button';
1013
+ trigger.className = 'co-rte-bubble__btn';
1014
+ const _cs = getRichTextStrings(this.locale);
1015
+ trigger.title = name === 'textColor' ? _cs.textColor : _cs.backgroundColor;
1016
+ if (name === 'textColor') {
1017
+ trigger.innerHTML = `<span class="co-rte-bubble__color-indicator"><span class="co-rte-bubble__color-letter">A</span><span class="co-rte-bubble__color-bar" style="background:#000000"></span></span>`;
1018
+ }
1019
+ else {
1020
+ trigger.innerHTML = `<co-icon name="${iconName}" size="16"></co-icon>`;
1021
+ }
1022
+ const dropdown = document.createElement('div');
1023
+ dropdown.className = 'co-rte-bubble__color-dropdown';
1024
+ dropdown.style.display = 'none';
1025
+ const colorTitle = name === 'textColor' ? _cs.textColor : _cs.backgroundColor;
1026
+ const { resetDrag: resetColorDrag } = this.addDragHeader(dropdown, colorTitle);
1027
+ // Prevent focus loss
1028
+ dropdown.addEventListener('mousedown', (e) => {
1029
+ if (e.target.tagName !== 'INPUT')
1030
+ e.preventDefault();
1031
+ this.lockBubblePosition();
1032
+ });
1033
+ const grid = document.createElement('div');
1034
+ grid.className = 'co-rte-bubble__color-grid';
1035
+ colors.forEach(color => {
1036
+ const swatch = document.createElement('button');
1037
+ swatch.type = 'button';
1038
+ swatch.className = 'co-rte-bubble__color-swatch';
1039
+ swatch.style.background = color;
1040
+ if (color === '#ffffff') {
1041
+ swatch.style.border = '1px solid #e0e0e0';
1042
+ }
1043
+ swatch.addEventListener('click', () => {
1044
+ onChange(color);
1045
+ dropdown.style.display = 'none';
1046
+ });
1047
+ grid.appendChild(swatch);
1048
+ });
1049
+ // Hex input
1050
+ const hexRow = document.createElement('div');
1051
+ hexRow.className = 'co-rte-bubble__color-hex';
1052
+ const hexInput = document.createElement('input');
1053
+ hexInput.type = 'text';
1054
+ hexInput.className = 'co-rte-bubble__color-hex-input';
1055
+ hexInput.placeholder = '#hex';
1056
+ hexInput.maxLength = 7;
1057
+ hexInput.addEventListener('keydown', (e) => {
1058
+ if (e.key === 'Enter') {
1059
+ const val = hexInput.value.trim();
1060
+ if (/^#[0-9a-fA-F]{3,6}$/.test(val)) {
1061
+ onChange(val);
1062
+ dropdown.style.display = 'none';
1063
+ hexInput.value = '';
1064
+ }
1065
+ }
1066
+ });
1067
+ // Clear color button
1068
+ const clearBtn = document.createElement('button');
1069
+ clearBtn.type = 'button';
1070
+ clearBtn.className = 'co-rte-bubble__color-clear';
1071
+ clearBtn.innerHTML = `<co-icon name="x" size="12"></co-icon> ${_cs.noColor}`;
1072
+ clearBtn.addEventListener('click', () => {
1073
+ if (!this.editor)
1074
+ return;
1075
+ if (name === 'textColor')
1076
+ this.editor.chain().focus().unsetColor().run();
1077
+ else
1078
+ this.editor.chain().focus().unsetHighlight().run();
1079
+ dropdown.style.display = 'none';
1080
+ });
1081
+ dropdown.appendChild(grid);
1082
+ hexRow.appendChild(hexInput);
1083
+ dropdown.appendChild(hexRow);
1084
+ dropdown.appendChild(clearBtn);
1085
+ trigger.addEventListener('click', () => {
1086
+ const parent = wrap.closest('.co-rte-bubble');
1087
+ if (parent) {
1088
+ parent.querySelectorAll('.co-rte-bubble__select-dropdown').forEach(d => {
1089
+ d.style.display = 'none';
1090
+ });
1091
+ parent.querySelectorAll('.co-rte-bubble__color-dropdown').forEach(d => {
1092
+ if (d !== dropdown)
1093
+ d.style.display = 'none';
1094
+ });
1095
+ }
1096
+ const isOpen = dropdown.style.display !== 'none';
1097
+ if (isOpen) {
1098
+ dropdown.style.display = 'none';
1099
+ }
1100
+ else {
1101
+ resetColorDrag();
1102
+ dropdown.style.position = '';
1103
+ dropdown.style.top = '';
1104
+ dropdown.style.left = '';
1105
+ dropdown.style.bottom = '';
1106
+ dropdown.style.right = '';
1107
+ dropdown.style.transform = '';
1108
+ dropdown.style.display = 'block';
1109
+ this.positionDropdown(trigger, dropdown);
1110
+ }
1111
+ });
1112
+ wrap.appendChild(trigger);
1113
+ wrap.appendChild(dropdown);
1114
+ return wrap;
1115
+ }
1116
+ /** Close all bubble popups EXCEPT the given element. */
1117
+ closeAllBubblePopups(...except) {
1118
+ if (!this.bubbleEl)
1119
+ return;
1120
+ const keep = except.filter(Boolean);
1121
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__select-dropdown').forEach(d => {
1122
+ if (!keep.includes(d))
1123
+ d.style.display = 'none';
1124
+ });
1125
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__color-dropdown').forEach(d => {
1126
+ if (!keep.includes(d))
1127
+ d.style.display = 'none';
1128
+ });
1129
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__panel').forEach(d => {
1130
+ if (!keep.includes(d))
1131
+ d.style.display = 'none';
1132
+ });
1133
+ this.bubbleEl.querySelectorAll('.co-rte-bubble__overflow-menu').forEach(d => {
1134
+ if (!keep.includes(d))
1135
+ d.style.display = 'none';
1136
+ });
1137
+ if (this.bubbleLinkFormEl && !keep.includes(this.bubbleLinkFormEl)) {
1138
+ this.bubbleLinkFormEl.style.display = 'none';
1139
+ }
1140
+ }
1141
+ addDragHeader(panel, title) {
1142
+ let dragged = false;
1143
+ let dragPos = { x: 0, y: 0 };
1144
+ let dragOffset = { x: 0, y: 0 };
1145
+ const header = document.createElement('div');
1146
+ header.className = 'co-rte-bubble__panel-header';
1147
+ const dragHandle = document.createElement('div');
1148
+ dragHandle.className = 'co-rte-bubble__panel-drag';
1149
+ dragHandle.innerHTML = `<co-icon name="dots-six" size="14"></co-icon>`;
1150
+ const titleEl = document.createElement('span');
1151
+ titleEl.className = 'co-rte-bubble__panel-title';
1152
+ titleEl.textContent = title;
1153
+ const closeBtn = document.createElement('button');
1154
+ closeBtn.type = 'button';
1155
+ closeBtn.className = 'co-rte-bubble__panel-close';
1156
+ closeBtn.innerHTML = `<co-icon name="x" size="14"></co-icon>`;
1157
+ closeBtn.addEventListener('click', () => { panel.style.display = 'none'; });
1158
+ header.appendChild(dragHandle);
1159
+ header.appendChild(titleEl);
1160
+ header.appendChild(closeBtn);
1161
+ dragHandle.addEventListener('mousedown', (e) => {
1162
+ e.preventDefault();
1163
+ e.stopPropagation();
1164
+ const rect = panel.getBoundingClientRect();
1165
+ dragOffset = { x: e.clientX - rect.left, y: e.clientY - rect.top };
1166
+ if (!dragged)
1167
+ dragPos = { x: rect.left, y: rect.top };
1168
+ dragged = true;
1169
+ const onMove = (ev) => {
1170
+ dragPos.x = ev.clientX - dragOffset.x;
1171
+ dragPos.y = ev.clientY - dragOffset.y;
1172
+ panel.style.position = 'fixed';
1173
+ panel.style.top = `${dragPos.y}px`;
1174
+ panel.style.left = `${dragPos.x}px`;
1175
+ panel.style.bottom = 'auto';
1176
+ panel.style.right = 'auto';
1177
+ panel.style.transform = 'none';
1178
+ panel.removeAttribute('data-position');
1179
+ };
1180
+ const onUp = () => {
1181
+ document.removeEventListener('mousemove', onMove);
1182
+ document.removeEventListener('mouseup', onUp);
1183
+ };
1184
+ document.addEventListener('mousemove', onMove);
1185
+ document.addEventListener('mouseup', onUp);
1186
+ });
1187
+ const resetDrag = () => { dragged = false; };
1188
+ panel.insertBefore(header, panel.firstChild);
1189
+ return { header, resetDrag };
1190
+ }
1191
+ /** Generic draggable panel factory. */
1192
+ createBubblePanel(config) {
1193
+ const wrap = document.createElement('div');
1194
+ wrap.className = 'co-rte-bubble__select';
1195
+ wrap.setAttribute('data-select', config.name);
1196
+ const trigger = document.createElement('button');
1197
+ trigger.type = 'button';
1198
+ trigger.className = 'co-rte-bubble__select-trigger';
1199
+ trigger.innerHTML = `<span class="co-rte-bubble__select-label">${config.triggerLabel}</span><co-icon name="caret-down" size="12"></co-icon>`;
1200
+ const panel = document.createElement('div');
1201
+ panel.className = 'co-rte-bubble__panel';
1202
+ panel.setAttribute('data-panel', config.name);
1203
+ panel.style.display = 'none';
1204
+ // Header
1205
+ const header = document.createElement('div');
1206
+ header.className = 'co-rte-bubble__panel-header';
1207
+ const dragHandle = document.createElement('div');
1208
+ dragHandle.className = 'co-rte-bubble__panel-drag';
1209
+ dragHandle.innerHTML = `<co-icon name="dots-six" size="14"></co-icon>`;
1210
+ const titleEl = document.createElement('span');
1211
+ titleEl.className = 'co-rte-bubble__panel-title';
1212
+ titleEl.textContent = config.title;
1213
+ const closeBtn = document.createElement('button');
1214
+ closeBtn.type = 'button';
1215
+ closeBtn.className = 'co-rte-bubble__panel-close';
1216
+ closeBtn.innerHTML = `<co-icon name="x" size="14"></co-icon>`;
1217
+ closeBtn.addEventListener('click', () => { panel.style.display = 'none'; });
1218
+ header.appendChild(dragHandle);
1219
+ header.appendChild(titleEl);
1220
+ header.appendChild(closeBtn);
1221
+ panel.appendChild(header);
1222
+ // Panel drag
1223
+ let panelDragged = false;
1224
+ let panelDragPos = { x: 0, y: 0 };
1225
+ let panelDragOffset = { x: 0, y: 0 };
1226
+ dragHandle.addEventListener('mousedown', (e) => {
1227
+ e.preventDefault();
1228
+ e.stopPropagation();
1229
+ const rect = panel.getBoundingClientRect();
1230
+ panelDragOffset = { x: e.clientX - rect.left, y: e.clientY - rect.top };
1231
+ if (!panelDragged)
1232
+ panelDragPos = { x: rect.left, y: rect.top };
1233
+ panelDragged = true;
1234
+ const onMove = (ev) => {
1235
+ panelDragPos.x = ev.clientX - panelDragOffset.x;
1236
+ panelDragPos.y = ev.clientY - panelDragOffset.y;
1237
+ panel.style.position = 'fixed';
1238
+ panel.style.top = `${panelDragPos.y}px`;
1239
+ panel.style.left = `${panelDragPos.x}px`;
1240
+ panel.style.bottom = 'auto';
1241
+ panel.style.right = 'auto';
1242
+ panel.style.transform = 'none';
1243
+ panel.removeAttribute('data-position');
1244
+ };
1245
+ const onUp = () => {
1246
+ document.removeEventListener('mousemove', onMove);
1247
+ document.removeEventListener('mouseup', onUp);
1248
+ };
1249
+ document.addEventListener('mousemove', onMove);
1250
+ document.addEventListener('mouseup', onUp);
1251
+ });
1252
+ // Custom input
1253
+ if (config.hasCustomInput) {
1254
+ const inputWrap = document.createElement('div');
1255
+ inputWrap.className = 'co-rte-bubble__panel-input-wrap';
1256
+ const input = document.createElement('input');
1257
+ input.type = config.inputType || 'text';
1258
+ input.className = 'co-rte-bubble__panel-input';
1259
+ input.placeholder = config.inputPlaceholder || '';
1260
+ input.addEventListener('mousedown', (e) => e.stopPropagation());
1261
+ input.addEventListener('keydown', (e) => {
1262
+ if (e.key === 'Enter') {
1263
+ const val = input.value.trim();
1264
+ if (val && config.onCustomInput) {
1265
+ config.onCustomInput(val);
1266
+ input.value = '';
1267
+ }
1268
+ }
1269
+ if (e.key === 'Escape') {
1270
+ panel.style.display = 'none';
1271
+ }
1272
+ });
1273
+ inputWrap.appendChild(input);
1274
+ panel.appendChild(inputWrap);
1275
+ }
1276
+ // Options
1277
+ const optionsWrap = document.createElement('div');
1278
+ optionsWrap.className = 'co-rte-bubble__panel-options';
1279
+ config.options.forEach(opt => {
1280
+ const btn = document.createElement('button');
1281
+ btn.type = 'button';
1282
+ btn.className = 'co-rte-bubble__panel-option';
1283
+ btn.setAttribute('data-value', opt.value);
1284
+ if (config.renderOption) {
1285
+ config.renderOption(opt, btn);
1286
+ }
1287
+ else {
1288
+ btn.textContent = opt.label;
1289
+ }
1290
+ btn.addEventListener('click', () => {
1291
+ config.onSelect(opt.value);
1292
+ panel.style.display = 'none';
1293
+ panelDragged = false;
1294
+ });
1295
+ optionsWrap.appendChild(btn);
1296
+ });
1297
+ panel.appendChild(optionsWrap);
1298
+ // Prevent bubble from losing focus
1299
+ panel.addEventListener('mousedown', (e) => {
1300
+ if (e.target.tagName !== 'INPUT')
1301
+ e.preventDefault();
1302
+ this.lockBubblePosition();
1303
+ });
1304
+ // Toggle logic
1305
+ const togglePanel = () => {
1306
+ this.closeAllBubblePopups(panel);
1307
+ const isOpen = panel.style.display !== 'none';
1308
+ if (isOpen) {
1309
+ panel.style.display = 'none';
1310
+ }
1311
+ else {
1312
+ panelDragged = false;
1313
+ panel.style.position = '';
1314
+ panel.style.top = '';
1315
+ panel.style.left = '';
1316
+ panel.style.bottom = '';
1317
+ panel.style.right = '';
1318
+ panel.style.transform = '';
1319
+ panel.style.display = 'block';
1320
+ this.positionDropdown(trigger, panel);
1321
+ }
1322
+ };
1323
+ trigger.addEventListener('click', togglePanel);
1324
+ wrap.appendChild(trigger);
1325
+ const updateLabel = (text) => {
1326
+ const labelEl = trigger.querySelector('.co-rte-bubble__select-label');
1327
+ if (labelEl)
1328
+ labelEl.textContent = text;
1329
+ };
1330
+ return { wrap, panelEl: panel, updateLabel };
1331
+ }
1332
+ /** Font size panel with visual preview and custom input. */
1333
+ createBubbleFontSizePanel() {
1334
+ const _fs = getRichTextStrings(this.locale);
1335
+ const headings = [
1336
+ { label: _fs.title, value: 'h1' },
1337
+ { label: _fs.heading1, value: 'h2' },
1338
+ { label: _fs.heading2, value: 'h3' },
1339
+ ];
1340
+ const sizes = ['8px', '10px', '12px', '14px', '16px', '18px', '20px', '24px', '28px', '32px', '36px', '48px', '64px', '72px'];
1341
+ const allOptions = [
1342
+ ...headings,
1343
+ { label: '---', value: '---' },
1344
+ ...sizes.map(s => ({ label: s, value: s })),
1345
+ ];
1346
+ return this.createBubblePanel({
1347
+ name: 'fontSize',
1348
+ title: _fs.fontSize,
1349
+ triggerLabel: '16px',
1350
+ hasCustomInput: true,
1351
+ inputType: 'number',
1352
+ inputPlaceholder: _fs.writeSize,
1353
+ options: allOptions,
1354
+ renderOption: (opt, btn) => {
1355
+ if (opt.value === '---') {
1356
+ btn.className = 'co-rte-bubble__panel-sep';
1357
+ btn.disabled = true;
1358
+ btn.style.pointerEvents = 'none';
1359
+ return;
1360
+ }
1361
+ if (opt.value === 'h1') {
1362
+ btn.textContent = opt.label;
1363
+ btn.style.fontSize = '24px';
1364
+ btn.style.fontWeight = '700';
1365
+ btn.style.padding = '6px 8px';
1366
+ }
1367
+ else if (opt.value === 'h2') {
1368
+ btn.textContent = opt.label;
1369
+ btn.style.fontSize = '18px';
1370
+ btn.style.fontWeight = '700';
1371
+ btn.style.padding = '5px 8px';
1372
+ }
1373
+ else if (opt.value === 'h3') {
1374
+ btn.textContent = opt.label;
1375
+ btn.style.fontSize = '15px';
1376
+ btn.style.fontWeight = '700';
1377
+ btn.style.padding = '4px 8px';
1378
+ }
1379
+ else {
1380
+ btn.textContent = opt.label;
1381
+ const px = parseInt(opt.value);
1382
+ btn.style.fontSize = `${Math.min(px, 36)}px`;
1383
+ btn.style.lineHeight = '1.3';
1384
+ }
1385
+ },
1386
+ onSelect: (val) => {
1387
+ if (!this.editor || val === '---')
1388
+ return;
1389
+ const chain = this.editor.chain().focus();
1390
+ if (val === 'h1')
1391
+ chain.toggleHeading({ level: 1 }).run();
1392
+ else if (val === 'h2')
1393
+ chain.toggleHeading({ level: 2 }).run();
1394
+ else if (val === 'h3')
1395
+ chain.toggleHeading({ level: 3 }).run();
1396
+ else
1397
+ chain.setFontSize(val).run();
1398
+ },
1399
+ onCustomInput: (val) => {
1400
+ if (!this.editor)
1401
+ return;
1402
+ const num = parseInt(val);
1403
+ if (num > 0)
1404
+ this.editor.chain().focus().setFontSize(`${num}px`).run();
1405
+ },
1406
+ });
1407
+ }
1408
+ /** Font weight panel with two-column layout and visual preview. */
1409
+ createBubbleFontWeightPanel() {
1410
+ const weights = [
1411
+ { label: 'Thin', value: '100' },
1412
+ { label: 'Extra Light', value: '200' },
1413
+ { label: 'Light', value: '300' },
1414
+ { label: 'Regular', value: '400' },
1415
+ { label: 'Medium', value: '500' },
1416
+ { label: 'Semi Bold', value: '600' },
1417
+ { label: 'Bold', value: '700' },
1418
+ { label: 'Extra Bold', value: '800' },
1419
+ { label: 'Black', value: '900' },
1420
+ ];
1421
+ return this.createBubblePanel({
1422
+ name: 'fontWeight',
1423
+ title: getRichTextStrings(this.locale).fontWeight,
1424
+ triggerLabel: 'Regular',
1425
+ hasCustomInput: false,
1426
+ options: weights,
1427
+ renderOption: (opt, btn) => {
1428
+ btn.style.fontWeight = opt.value;
1429
+ btn.innerHTML = `<span class="co-rte-bubble__panel-opt-row"><span>${opt.label}</span><span class="co-rte-bubble__panel-opt-value">${opt.value}</span></span>`;
1430
+ },
1431
+ onSelect: (val) => {
1432
+ if (!this.editor)
1433
+ return;
1434
+ this.editor.chain().focus().setFontWeight(val).run();
1435
+ },
1436
+ });
1437
+ }
1438
+ /** Line height panel with custom input. */
1439
+ createBubbleLineHeightPanel() {
1440
+ const options = [
1441
+ { label: '0.5', value: '0.5' },
1442
+ { label: '1', value: '1' },
1443
+ { label: '1.15', value: '1.15' },
1444
+ { label: '1.5', value: '1.5' },
1445
+ { label: '1.75', value: '1.75' },
1446
+ { label: '2', value: '2' },
1447
+ { label: '2.5', value: '2.5' },
1448
+ { label: '3', value: '3' },
1449
+ { label: '---', value: '---' },
1450
+ { label: '16px', value: '16px' },
1451
+ { label: '20px', value: '20px' },
1452
+ { label: '24px', value: '24px' },
1453
+ { label: '32px', value: '32px' },
1454
+ { label: '---', value: '---2' },
1455
+ { label: '100%', value: '100%' },
1456
+ { label: '150%', value: '150%' },
1457
+ { label: '200%', value: '200%' },
1458
+ ];
1459
+ const { panelEl } = this.createBubblePanel({
1460
+ name: 'lineHeight',
1461
+ title: getRichTextStrings(this.locale).lineSpacing,
1462
+ triggerLabel: '1.5',
1463
+ hasCustomInput: true,
1464
+ inputPlaceholder: '1.5, 20px, 150%...',
1465
+ options,
1466
+ renderOption: (opt, btn) => {
1467
+ if (opt.value.startsWith('---')) {
1468
+ btn.className = 'co-rte-bubble__panel-sep';
1469
+ btn.disabled = true;
1470
+ btn.style.pointerEvents = 'none';
1471
+ return;
1472
+ }
1473
+ btn.textContent = opt.label;
1474
+ },
1475
+ onSelect: (val) => {
1476
+ if (!this.editor || val.startsWith('---'))
1477
+ return;
1478
+ this.editor.chain().focus().setLineHeight(val).run();
1479
+ },
1480
+ onCustomInput: (val) => {
1481
+ if (!this.editor)
1482
+ return;
1483
+ this.editor.chain().focus().setLineHeight(val).run();
1484
+ },
1485
+ });
1486
+ return panelEl;
1487
+ }
1488
+ /** Letter spacing panel with custom input. */
1489
+ createBubbleLetterSpacingPanel() {
1490
+ const options = [
1491
+ { label: '-0.05em', value: '-0.05em' },
1492
+ { label: 'Normal', value: 'normal' },
1493
+ { label: '0.05em', value: '0.05em' },
1494
+ { label: '0.1em', value: '0.1em' },
1495
+ { label: '0.2em', value: '0.2em' },
1496
+ ];
1497
+ const { panelEl } = this.createBubblePanel({
1498
+ name: 'letterSpacing',
1499
+ title: getRichTextStrings(this.locale).letterSpacing,
1500
+ triggerLabel: getRichTextStrings(this.locale).normal,
1501
+ hasCustomInput: true,
1502
+ inputPlaceholder: 'Custom (em)...',
1503
+ options,
1504
+ onSelect: (val) => {
1505
+ if (!this.editor)
1506
+ return;
1507
+ if (val === 'normal')
1508
+ this.editor.chain().focus().unsetLetterSpacing().run();
1509
+ else
1510
+ this.editor.chain().focus().setLetterSpacing(val).run();
1511
+ },
1512
+ onCustomInput: (val) => {
1513
+ if (!this.editor)
1514
+ return;
1515
+ const v = val.includes('em') || val.includes('px') ? val : `${val}em`;
1516
+ this.editor.chain().focus().setLetterSpacing(v).run();
1517
+ },
1518
+ });
1519
+ return panelEl;
1520
+ }
1521
+ /** Background color panel for overflow menu. */
1522
+ createBubbleBgColorPanel() {
1523
+ const bgColorWrap = this.createBubbleColorPicker('bgColor', (color) => {
1524
+ if (!this.editor)
1525
+ return;
1526
+ this.editor.chain().focus().toggleHighlight({ color }).run();
1527
+ });
1528
+ // Hide the trigger button — bg color is only opened from the overflow menu.
1529
+ const triggerBtn = bgColorWrap.querySelector('.co-rte-bubble__btn');
1530
+ if (triggerBtn)
1531
+ triggerBtn.style.display = 'none';
1532
+ return bgColorWrap;
1533
+ }
1534
+ /** Overflow menu (three-dots ⋮) with dynamic table context section. */
1535
+ createBubbleOverflowMenu(panels) {
1536
+ const wrap = document.createElement('div');
1537
+ wrap.className = 'co-rte-bubble__overflow';
1538
+ const btn = document.createElement('button');
1539
+ btn.type = 'button';
1540
+ btn.className = 'co-rte-bubble__btn';
1541
+ const _os = getRichTextStrings(this.locale);
1542
+ btn.title = _os.moreOptions;
1543
+ btn.setAttribute('aria-label', _os.moreOptions);
1544
+ btn.innerHTML = `<co-icon name="dots-three" size="16"></co-icon>`;
1545
+ const menu = document.createElement('div');
1546
+ menu.className = 'co-rte-bubble__overflow-menu';
1547
+ menu.style.display = 'none';
1548
+ const { resetDrag: resetOverflowDrag } = this.addDragHeader(menu, _os.moreOptions);
1549
+ // Prevent focus loss
1550
+ menu.addEventListener('mousedown', (e) => {
1551
+ if (e.target.tagName !== 'INPUT')
1552
+ e.preventDefault();
1553
+ this.lockBubblePosition();
1554
+ });
1555
+ const items = [
1556
+ { icon: 'text-strikethrough', label: _os.strikethrough, action: 'strike', check: 'strike', type: 'toggle' },
1557
+ { icon: 'highlighter', label: _os.backgroundColor, action: 'bgColor', type: 'panel', panel: panels.bgColor },
1558
+ { icon: 'list-bullets', label: _os.bulletList, action: 'bulletList', check: 'bulletList', type: 'toggle' },
1559
+ { icon: 'list-numbers', label: _os.orderedList, action: 'orderedList', check: 'orderedList', type: 'toggle' },
1560
+ { icon: 'text-superscript', label: _os.superscript, action: 'superscript', check: 'superscript', type: 'toggle' },
1561
+ { icon: 'text-subscript', label: _os.subscript, action: 'subscript', check: 'subscript', type: 'toggle' },
1562
+ { icon: 'line-segments', label: _os.lineSpacing, action: 'lineHeight', type: 'panel', panel: panels.lineHeight, valueAttr: 'lineHeight' },
1563
+ { icon: 'text-aa', label: _os.letterSpacing, action: 'letterSpacing', type: 'panel', panel: panels.letterSpacing, valueAttr: 'letterSpacing' },
1564
+ { icon: 'minus', label: _os.horizontalRule, action: 'horizontalRule', type: 'toggle' },
1565
+ { icon: 'eraser', label: _os.clearFormat, action: 'clearFormat', type: 'toggle' },
1566
+ ];
1567
+ items.forEach((item) => {
1568
+ if (item.action === 'lineHeight' || item.action === 'horizontalRule') {
1569
+ const sep = document.createElement('div');
1570
+ sep.className = 'co-rte-bubble__overflow-sep';
1571
+ menu.appendChild(sep);
1572
+ }
1573
+ const itemBtn = document.createElement('button');
1574
+ itemBtn.type = 'button';
1575
+ itemBtn.className = 'co-rte-bubble__overflow-item';
1576
+ itemBtn.setAttribute('data-overflow-item', item.action);
1577
+ if (item.check)
1578
+ itemBtn.setAttribute('data-check', item.check);
1579
+ let valueSpan = '';
1580
+ if (item.valueAttr) {
1581
+ valueSpan = `<span class="co-rte-bubble__overflow-value" data-overflow-value="${item.valueAttr}"></span>`;
1582
+ }
1583
+ itemBtn.innerHTML = `<co-icon name="${item.icon}" size="16"></co-icon><span>${item.label}</span>${valueSpan}`;
1584
+ itemBtn.addEventListener('click', () => {
1585
+ if (!this.editor)
1586
+ return;
1587
+ if (item.type === 'panel' && item.panel) {
1588
+ if (item.action === 'bgColor') {
1589
+ const dd = item.panel.querySelector('.co-rte-bubble__color-dropdown');
1590
+ if (dd) {
1591
+ const isOpen = dd.style.display !== 'none';
1592
+ this.closeAllBubblePopups(menu, isOpen ? undefined : dd);
1593
+ dd.style.display = isOpen ? 'none' : 'block';
1594
+ if (!isOpen)
1595
+ this.positionPanelNearBubble(dd);
1596
+ }
1597
+ }
1598
+ else {
1599
+ const isOpen = item.panel.style.display !== 'none';
1600
+ this.closeAllBubblePopups(menu, isOpen ? undefined : item.panel);
1601
+ item.panel.style.display = isOpen ? 'none' : 'block';
1602
+ if (!isOpen)
1603
+ this.positionPanelNearBubble(item.panel);
1604
+ }
1605
+ return;
1606
+ }
1607
+ const chain = this.editor.chain().focus();
1608
+ switch (item.action) {
1609
+ case 'strike':
1610
+ chain.toggleStrike().run();
1611
+ break;
1612
+ case 'bulletList':
1613
+ chain.toggleBulletList().run();
1614
+ break;
1615
+ case 'orderedList':
1616
+ chain.toggleOrderedList().run();
1617
+ break;
1618
+ case 'superscript':
1619
+ chain.toggleSuperscript().run();
1620
+ break;
1621
+ case 'subscript':
1622
+ chain.toggleSubscript().run();
1623
+ break;
1624
+ case 'horizontalRule':
1625
+ chain.setHorizontalRule().run();
1626
+ menu.style.display = 'none';
1627
+ break;
1628
+ case 'clearFormat':
1629
+ chain.unsetAllMarks().clearNodes().run();
1630
+ menu.style.display = 'none';
1631
+ break;
1632
+ }
1633
+ });
1634
+ menu.appendChild(itemBtn);
1635
+ });
1636
+ // ── Table context section (hidden by default, shown when cursor is in a table) ──
1637
+ const tableSection = document.createElement('div');
1638
+ tableSection.className = 'co-rte-bubble__overflow-table-section';
1639
+ tableSection.style.display = 'none';
1640
+ const tableSep = document.createElement('div');
1641
+ tableSep.className = 'co-rte-bubble__overflow-sep';
1642
+ tableSection.appendChild(tableSep);
1643
+ const tableHeader = document.createElement('div');
1644
+ tableHeader.className = 'co-rte-bubble__overflow-section-title';
1645
+ tableHeader.textContent = _os.tableOptions;
1646
+ tableSection.appendChild(tableHeader);
1647
+ const tableItems = [
1648
+ { action: 'addColumnBefore', icon: 'columns-plus-left', label: _os.addColumnBefore },
1649
+ { action: 'addColumnAfter', icon: 'columns-plus-right', label: _os.addColumnAfter },
1650
+ { action: 'addRowBefore', icon: 'rows-plus-top', label: _os.addRowAbove },
1651
+ { action: 'addRowAfter', icon: 'rows-plus-bottom', label: _os.addRowBelow },
1652
+ { action: 'mergeCells', icon: 'arrows-merge', label: _os.mergeCells },
1653
+ { action: 'splitCell', icon: 'arrows-split', label: _os.splitCell },
1654
+ { action: 'toggleHeaderRow', icon: 'rows', label: _os.headerRow },
1655
+ ];
1656
+ tableItems.forEach(({ action, icon, label }) => {
1657
+ const tBtn = document.createElement('button');
1658
+ tBtn.type = 'button';
1659
+ tBtn.className = 'co-rte-bubble__overflow-item';
1660
+ tBtn.setAttribute('data-overflow-item', action);
1661
+ if (action === 'toggleHeaderRow')
1662
+ tBtn.setAttribute('data-check', 'toggleHeaderRow');
1663
+ tBtn.innerHTML = `<co-icon name="${icon}" size="16"></co-icon><span>${label}</span>`;
1664
+ tBtn.addEventListener('click', () => {
1665
+ if (!this.editor)
1666
+ return;
1667
+ const chain = this.editor.chain().focus();
1668
+ switch (action) {
1669
+ case 'addColumnAfter':
1670
+ chain.addColumnAfter().run();
1671
+ break;
1672
+ case 'addColumnBefore':
1673
+ chain.addColumnBefore().run();
1674
+ break;
1675
+ case 'addRowAfter':
1676
+ chain.addRowAfter().run();
1677
+ break;
1678
+ case 'addRowBefore':
1679
+ chain.addRowBefore().run();
1680
+ break;
1681
+ case 'mergeCells':
1682
+ chain.mergeCells().run();
1683
+ break;
1684
+ case 'splitCell':
1685
+ chain.splitCell().run();
1686
+ break;
1687
+ case 'toggleHeaderRow':
1688
+ chain.toggleHeaderRow().run();
1689
+ break;
1690
+ }
1691
+ });
1692
+ tableSection.appendChild(tBtn);
1693
+ });
1694
+ // Danger items (delete column, row, table)
1695
+ const dangerSep = document.createElement('div');
1696
+ dangerSep.className = 'co-rte-bubble__overflow-sep';
1697
+ tableSection.appendChild(dangerSep);
1698
+ const dangerItems = [
1699
+ { action: 'deleteColumn', icon: 'minus-square', label: _os.deleteColumn },
1700
+ { action: 'deleteRow', icon: 'x-square', label: _os.deleteRow },
1701
+ { action: 'deleteTable', icon: 'trash', label: _os.deleteTable },
1702
+ ];
1703
+ dangerItems.forEach(({ action, icon, label }) => {
1704
+ const dBtn = document.createElement('button');
1705
+ dBtn.type = 'button';
1706
+ dBtn.className = 'co-rte-bubble__overflow-item co-rte-bubble__overflow-item--danger';
1707
+ dBtn.setAttribute('data-overflow-item', action);
1708
+ dBtn.innerHTML = `<co-icon name="${icon}" size="16"></co-icon><span>${label}</span>`;
1709
+ dBtn.addEventListener('click', () => {
1710
+ if (!this.editor)
1711
+ return;
1712
+ const chain = this.editor.chain().focus();
1713
+ switch (action) {
1714
+ case 'deleteColumn':
1715
+ chain.deleteColumn().run();
1716
+ break;
1717
+ case 'deleteRow':
1718
+ chain.deleteRow().run();
1719
+ break;
1720
+ case 'deleteTable':
1721
+ chain.deleteTable().run();
1722
+ menu.style.display = 'none';
1723
+ break;
1724
+ }
1725
+ });
1726
+ tableSection.appendChild(dBtn);
1727
+ });
1728
+ menu.appendChild(tableSection);
1729
+ btn.addEventListener('click', () => {
1730
+ this.closeAllBubblePopups(menu);
1731
+ const isOpen = menu.style.display !== 'none';
1732
+ if (isOpen) {
1733
+ menu.style.display = 'none';
1734
+ }
1735
+ else {
1736
+ resetOverflowDrag();
1737
+ menu.style.position = '';
1738
+ menu.style.top = '';
1739
+ menu.style.left = '';
1740
+ menu.style.bottom = '';
1741
+ menu.style.right = '';
1742
+ menu.style.transform = '';
1743
+ menu.style.display = 'block';
1744
+ this.positionDropdown(btn, menu);
1745
+ }
1746
+ });
1747
+ wrap.appendChild(btn);
1748
+ wrap.appendChild(menu);
1749
+ return { overflowWrap: wrap, overflowMenu: menu };
1750
+ }
1751
+ toggleBubbleLinkForm(show) {
1752
+ var _a, _b;
1753
+ if (!this.bubbleLinkFormEl || !this.bubbleLinkInputEl)
1754
+ return;
1755
+ this.bubbleLinkFormEl.style.display = show ? 'flex' : 'none';
1756
+ if (show) {
1757
+ const existing = ((_a = this.editor) === null || _a === void 0 ? void 0 : _a.isActive('link'))
1758
+ ? ((_b = this.editor.getAttributes('link')) === null || _b === void 0 ? void 0 : _b.href) || ''
1759
+ : '';
1760
+ this.bubbleLinkInputEl.value = existing;
1761
+ if (this.bubbleLinkUnlinkEl) {
1762
+ this.bubbleLinkUnlinkEl.style.display = existing ? 'flex' : 'none';
1763
+ }
1764
+ setTimeout(() => { var _a; return (_a = this.bubbleLinkInputEl) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
1765
+ }
1766
+ }
1767
+ submitBubbleLinkImperative() {
1768
+ if (!this.editor || !this.bubbleLinkInputEl)
1769
+ return;
1770
+ const url = this.bubbleLinkInputEl.value.trim();
1771
+ if (!url) {
1772
+ this.toggleBubbleLinkForm(false);
1773
+ return;
1774
+ }
1775
+ this.editor.chain().focus().setLink({ href: url }).run();
1776
+ this.toggleBubbleLinkForm(false);
1777
+ }
1778
+ updateBubbleActiveStates() {
1779
+ if (!this.editor || !this.bubbleEl)
1780
+ return;
1781
+ // Toggle buttons (bold, italic, etc.)
1782
+ const btns = this.bubbleEl.querySelectorAll('.co-rte-bubble__btn[data-check]');
1783
+ btns.forEach(btn => {
1784
+ const check = btn.getAttribute('data-check');
1785
+ if (check) {
1786
+ btn.classList.toggle('co-rte-bubble__btn--active', this.editor.isActive(check));
1787
+ }
1788
+ });
1789
+ // Alignment buttons
1790
+ const alignBtns = this.bubbleEl.querySelectorAll('.co-rte-bubble__btn[data-align]');
1791
+ alignBtns.forEach(btn => {
1792
+ const align = btn.getAttribute('data-align');
1793
+ if (align) {
1794
+ btn.classList.toggle('co-rte-bubble__btn--active', this.editor.isActive({ textAlign: align }));
1795
+ }
1796
+ });
1797
+ // Font family label
1798
+ const ffLabel = this.bubbleEl.querySelector('[data-select="fontFamily"] .co-rte-bubble__select-label');
1799
+ if (ffLabel) {
1800
+ const attrs = this.editor.getAttributes('textStyle');
1801
+ const family = (attrs === null || attrs === void 0 ? void 0 : attrs.fontFamily) || '';
1802
+ ffLabel.textContent = family ? family.split(',')[0].replace(/['"]/g, '').trim() : 'Sans-serif';
1803
+ }
1804
+ // Font size label (panel trigger)
1805
+ const fsTrigger = this.bubbleEl.querySelector('[data-select="fontSize"] .co-rte-bubble__select-label');
1806
+ if (fsTrigger) {
1807
+ const attrs = this.editor.getAttributes('textStyle');
1808
+ const _us = getRichTextStrings(this.locale);
1809
+ if (this.editor.isActive('heading', { level: 1 }))
1810
+ fsTrigger.textContent = _us.title;
1811
+ else if (this.editor.isActive('heading', { level: 2 }))
1812
+ fsTrigger.textContent = _us.headingAbbr1;
1813
+ else if (this.editor.isActive('heading', { level: 3 }))
1814
+ fsTrigger.textContent = _us.headingAbbr2;
1815
+ else
1816
+ fsTrigger.textContent = (attrs === null || attrs === void 0 ? void 0 : attrs.fontSize) || '16px';
1817
+ }
1818
+ // Font weight label (panel trigger)
1819
+ const fwTrigger = this.bubbleEl.querySelector('[data-select="fontWeight"] .co-rte-bubble__select-label');
1820
+ if (fwTrigger) {
1821
+ const attrs = this.editor.getAttributes('textStyle');
1822
+ const w = (attrs === null || attrs === void 0 ? void 0 : attrs.fontWeight) || '400';
1823
+ const wMap = { '100': 'Thin', '200': 'Extra Light', '300': 'Light', '400': 'Regular', '500': 'Medium', '600': 'Semi-bold', '700': 'Bold', '800': 'Extra-bold', '900': 'Black' };
1824
+ fwTrigger.textContent = wMap[w] || 'Regular';
1825
+ }
1826
+ // Overflow menu items active states
1827
+ const overflowItems = this.bubbleEl.querySelectorAll('.co-rte-bubble__overflow-item[data-check]');
1828
+ overflowItems.forEach(item => {
1829
+ const check = item.getAttribute('data-check');
1830
+ if (check) {
1831
+ item.classList.toggle('co-rte-bubble__overflow-item--active', this.editor.isActive(check));
1832
+ }
1833
+ });
1834
+ // Line height value in overflow (lineHeight is a block-level attribute on paragraph/heading)
1835
+ const lhValue = this.bubbleEl.querySelector('[data-overflow-value="lineHeight"]');
1836
+ if (lhValue) {
1837
+ const pAttrs = this.editor.getAttributes('paragraph');
1838
+ const hAttrs = this.editor.getAttributes('heading');
1839
+ lhValue.textContent = (pAttrs === null || pAttrs === void 0 ? void 0 : pAttrs.lineHeight) || (hAttrs === null || hAttrs === void 0 ? void 0 : hAttrs.lineHeight) || '';
1840
+ }
1841
+ // Letter spacing value in overflow
1842
+ const lsValue = this.bubbleEl.querySelector('[data-overflow-value="letterSpacing"]');
1843
+ if (lsValue) {
1844
+ const attrs = this.editor.getAttributes('textStyle');
1845
+ lsValue.textContent = (attrs === null || attrs === void 0 ? void 0 : attrs.letterSpacing) || '';
1846
+ }
1847
+ // Text color indicator bar
1848
+ const colorBar = this.bubbleEl.querySelector('.co-rte-bubble__color-bar');
1849
+ if (colorBar) {
1850
+ const attrs = this.editor.getAttributes('textStyle');
1851
+ colorBar.style.background = (attrs === null || attrs === void 0 ? void 0 : attrs.color) || '#000000';
1852
+ }
1853
+ // Table context section — show/hide based on cursor position
1854
+ const tableSection = this.bubbleEl.querySelector('.co-rte-bubble__overflow-table-section');
1855
+ if (tableSection) {
1856
+ const inTable = this.editor.isActive('table');
1857
+ tableSection.style.display = inTable ? 'block' : 'none';
1858
+ // Toggle header row active state
1859
+ if (inTable) {
1860
+ const headerBtn = tableSection.querySelector('[data-overflow-item="toggleHeaderRow"]');
1861
+ if (headerBtn) {
1862
+ const view = this.editor.view;
1863
+ const { $anchor } = this.editor.state.selection;
1864
+ let d = $anchor.depth;
1865
+ let hasHeader = false;
1866
+ while (d > 0) {
1867
+ if ($anchor.node(d).type.name === 'table') {
1868
+ const domEl = view.nodeDOM($anchor.start(d) - 1);
1869
+ if (domEl) {
1870
+ const tbl = domEl.querySelector('table') || domEl;
1871
+ const firstRow = tbl.querySelector('tr');
1872
+ hasHeader = firstRow ? firstRow.querySelector('th') !== null : false;
1873
+ }
1874
+ break;
1875
+ }
1876
+ d--;
1877
+ }
1878
+ headerBtn.classList.toggle('co-rte-bubble__overflow-item--active', hasHeader);
1879
+ }
1880
+ }
1881
+ }
1882
+ }
1883
+ createImageLayoutBar() {
1884
+ const bar = document.createElement('div');
1885
+ bar.className = 'co-rte-img-layout';
1886
+ bar.style.display = 'none';
1887
+ bar.addEventListener('mousedown', (e) => {
1888
+ e.preventDefault();
1889
+ e.stopPropagation();
1890
+ });
1891
+ const s = getRichTextStrings(this.locale);
1892
+ const labels = {
1893
+ 'inline': s.imageLayoutInline,
1894
+ 'wrap-left': s.imageLayoutWrapLeft,
1895
+ 'wrap-right': s.imageLayoutWrapRight,
1896
+ 'center': s.imageLayoutCenter,
1897
+ 'full-width': s.imageLayoutFullWidth,
1898
+ };
1899
+ const keys = ['inline', 'wrap-left', 'wrap-right', 'center', 'full-width'];
1900
+ keys.forEach(key => {
1901
+ const btn = document.createElement('button');
1902
+ btn.type = 'button';
1903
+ btn.className = 'co-rte-img-layout__btn';
1904
+ btn.setAttribute('data-layout', key);
1905
+ // Fast CSS tooltip (avoids the slow native `title` delay).
1906
+ btn.setAttribute('data-tooltip', labels[key] || key);
1907
+ btn.setAttribute('aria-label', labels[key] || key);
1908
+ btn.innerHTML = `<co-icon name="${CoRichTextEditor.IMG_LAYOUT_ICONS[key]}" size="18"></co-icon>`;
1909
+ btn.addEventListener('click', () => this.setImageLayout(key));
1910
+ bar.appendChild(btn);
1911
+ });
1912
+ return bar;
1913
+ }
1914
+ setImageLayout(layout) {
1915
+ if (!this.editor || !this.contentEl)
1916
+ return;
1917
+ const { state } = this.editor;
1918
+ const sel = state.selection;
1919
+ if (sel.constructor.name !== 'NodeSelection')
1920
+ return;
1921
+ const node = sel.node;
1922
+ if ((node === null || node === void 0 ? void 0 : node.type.name) !== 'image')
1923
+ return;
1924
+ const pos = sel.from;
1925
+ const tr = state.tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { imageLayout: layout }));
1926
+ this.editor.view.dispatch(tr);
1927
+ this.editor.commands.setNodeSelection(pos);
1928
+ requestAnimationFrame(() => {
1929
+ this.syncImageLayouts();
1930
+ this.updateImageLayoutBar();
1931
+ });
1932
+ }
1933
+ getSelectedImageInfo() {
1934
+ var _a;
1935
+ if (!this.editor)
1936
+ return null;
1937
+ const { state } = this.editor;
1938
+ const sel = state.selection;
1939
+ if (sel.constructor.name !== 'NodeSelection')
1940
+ return null;
1941
+ const node = sel.node;
1942
+ if ((node === null || node === void 0 ? void 0 : node.type.name) !== 'image')
1943
+ return null;
1944
+ const pos = sel.from;
1945
+ const domNode = this.editor.view.nodeDOM(pos);
1946
+ if (!domNode)
1947
+ return null;
1948
+ const container = (((_a = domNode.closest) === null || _a === void 0 ? void 0 : _a.call(domNode, '[data-resize-container]')) || domNode);
1949
+ return { node, pos, container };
1950
+ }
1951
+ /**
1952
+ * Tag every image container with its layout mode (`data-image-layout`) so the
1953
+ * stylesheet's responsive rules apply, and clear any stray inline positioning
1954
+ * left over from legacy absolute-positioned content. Layout is CSS-only now
1955
+ * (it reflows and collapses on mobile); we only set the attribute here.
1956
+ *
1957
+ * Runs on every transaction. The resize NodeView's `onUpdate` returns `true`,
1958
+ * so ProseMirror never reflects attribute changes to the DOM — we must read
1959
+ * from state and write the attribute imperatively to the container.
1960
+ */
1961
+ syncImageLayouts() {
1962
+ if (!this.editor)
1963
+ return;
1964
+ const view = this.editor.view;
1965
+ this.editor.state.doc.descendants((node, pos) => {
1966
+ var _a;
1967
+ if (node.type.name !== 'image')
1968
+ return true;
1969
+ const dom = view.nodeDOM(pos);
1970
+ const c = (((_a = dom === null || dom === void 0 ? void 0 : dom.closest) === null || _a === void 0 ? void 0 : _a.call(dom, '[data-resize-container]')) || dom);
1971
+ if (!c)
1972
+ return true;
1973
+ c.dataset.imageLayout = node.attrs.imageLayout || 'inline';
1974
+ // Neutralise any absolute positioning baked by the old fixed-page model.
1975
+ c.style.position = '';
1976
+ c.style.left = '';
1977
+ c.style.top = '';
1978
+ c.style.zIndex = '';
1979
+ return true;
1980
+ });
1981
+ }
1982
+ /** Reposition only the layout bar (used during drag for performance). */
1983
+ updateImageLayoutBarPosition() {
1984
+ if (!this.imgLayoutEl || !this.contentEl)
1985
+ return;
1986
+ const info = this.getSelectedImageInfo();
1987
+ if (!info)
1988
+ return;
1989
+ const containerRect = info.container.getBoundingClientRect();
1990
+ const contentRect = this.contentEl.getBoundingClientRect();
1991
+ const barWidth = this.imgLayoutEl.offsetWidth || 194;
1992
+ let leftPos = (containerRect.left + containerRect.width / 2) - contentRect.left + this.contentEl.scrollLeft - barWidth / 2;
1993
+ leftPos = Math.max(4, Math.min(leftPos, contentRect.width - barWidth - 4));
1994
+ const topPos = containerRect.bottom - contentRect.top + this.contentEl.scrollTop + 8;
1995
+ this.imgLayoutEl.style.left = `${leftPos}px`;
1996
+ this.imgLayoutEl.style.top = `${topPos}px`;
1997
+ }
1998
+ updateImageLayoutBar() {
1999
+ if (!this.imgLayoutEl || !this.editor)
2000
+ return;
2001
+ const info = this.getSelectedImageInfo();
2002
+ if (!info) {
2003
+ if (this.imgLayoutVisible) {
2004
+ this.imgLayoutEl.style.display = 'none';
2005
+ this.imgLayoutVisible = false;
2006
+ }
2007
+ return;
2008
+ }
2009
+ this.imgLayoutEl.style.display = 'flex';
2010
+ this.imgLayoutVisible = true;
2011
+ this.updateImageLayoutBarPosition();
2012
+ const currentLayout = info.node.attrs.imageLayout || 'inline';
2013
+ this.imgLayoutEl.querySelectorAll('.co-rte-img-layout__btn').forEach(btn => {
2014
+ btn.classList.toggle('co-rte-img-layout__btn--active', btn.getAttribute('data-layout') === currentLayout);
2015
+ });
2016
+ }
2017
+ render() {
2018
+ const showToolbar = this.resolvedToolbar !== 'none' && !this.readonly && !this.disabled;
2019
+ const showCount = this.showCharacterCount || this.maxLength != null;
2020
+ return (h("div", { key: 'd24b8e5db1151bcd983790ea15f68aaf4838ff43', class: {
2021
+ 'co-rich-text-editor': true,
2022
+ 'co-rich-text-editor--focused': this.hasFocus,
2023
+ 'co-rich-text-editor--disabled': this.disabled,
2024
+ 'co-rich-text-editor--readonly': this.readonly,
2025
+ 'co-rich-text-editor--loading': !this.ready,
2026
+ [`co-rich-text-editor--${this.status}`]: this.status !== 'default',
2027
+ }, part: "wrapper" }, (this.label || this.secondaryLabel) && (h("div", { key: '1622079a94d8ebb190642f91463b715f3456fcf4', class: "co-rich-text-editor__labels" }, this.label && h("label", { key: 'bb5c0754a63d46d45ce8f211ae0f0e8c4ddbc478', class: "co-rich-text-editor__label", part: "label" }, this.label), this.secondaryLabel && (h("span", { key: '1af0a217a38746c3a78693c552be44df6d03b276', class: "co-rich-text-editor__secondary-label" }, this.secondaryLabel)))), h("div", { key: 'e5ad90dd90061be3e40136eece0f485e5cfb89a1', class: "co-rich-text-editor__frame" }, showToolbar && (h("co-rich-text-toolbar", { key: '56f3da29e9259cd37fdf6e7511dc54efb30085ca', class: "co-rich-text-editor__toolbar", part: "toolbar", variant: this.resolvedToolbar, disabled: this.disabled || this.readonly, locale: this.locale, ref: (el) => (this.toolbarEl = el) })), h("div", { key: 'bb0dc27e8625171284cae02b5cae28dcbe638991', class: "co-rich-text-editor__box" }, h("div", { key: '647563e73112023ec546418787dbf61acb58853d', class: "co-rte-content", part: "content", role: "textbox", "aria-multiline": "true", "aria-label": this.label, "aria-required": this.required ? 'true' : undefined, "aria-invalid": this.status === 'error' ? 'true' : undefined, ref: (el) => (this.contentEl = el) }))), h("div", { key: '460dad69fd1781f11d751565d0ca09015013e8ce', class: "co-rich-text-editor__footer" }, this.helperText && (h("div", { key: '69d8fb55797eb8f35885fa10e86cf08e4d0e45ec', class: `co-rich-text-editor__helper co-rich-text-editor__helper--${this.status}`, part: "helper" }, h("co-icon", { key: 'd1c3cc4f06284b865c889dac7492305a4b7d8dfd', name: this.helperIcon, size: 14 }), h("span", { key: '361940f354fcee5a309cd2ef5cff84b73689650e' }, this.helperText))), showCount && (h("span", { key: '2b5a1b6e04ba3d428346034d092bf83978de0124', class: "co-rich-text-editor__count", ref: (el) => (this.charCountEl = el) }, this.charCount, this.maxLength != null ? ` / ${this.maxLength}` : '')))));
2028
+ }
2029
+ get el() { return getElement(this); }
2030
+ static get watchers() { return {
2031
+ "accountFonts": [{
2032
+ "onAccountFontsChange": 0
2033
+ }],
2034
+ "value": [{
2035
+ "onValueChange": 0
2036
+ }],
2037
+ "disabled": [{
2038
+ "onEditableChange": 0
2039
+ }],
2040
+ "readonly": [{
2041
+ "onEditableChange": 0
2042
+ }]
2043
+ }; }
2044
+ };
2045
+ CoRichTextEditor.DEFAULT_FONTS = [
2046
+ { label: 'Arial', value: 'Arial, sans-serif' },
2047
+ { label: 'Calibri', value: 'Calibri, sans-serif' },
2048
+ { label: 'Cambria', value: 'Cambria, serif' },
2049
+ { label: 'Comic Sans MS', value: "'Comic Sans MS', cursive" },
2050
+ { label: 'Courier New', value: "'Courier New', monospace" },
2051
+ { label: 'Georgia', value: 'Georgia, serif' },
2052
+ { label: 'Geist', value: "'Geist', sans-serif" },
2053
+ { label: 'Helvetica', value: 'Helvetica, Arial, sans-serif' },
2054
+ { label: 'Impact', value: 'Impact, sans-serif' },
2055
+ { label: 'Inter', value: "'Inter', sans-serif" },
2056
+ { label: 'Lato', value: "'Lato', sans-serif" },
2057
+ { label: 'Montserrat', value: "'Montserrat', sans-serif" },
2058
+ { label: 'Open Sans', value: "'Open Sans', sans-serif" },
2059
+ { label: 'Poppins', value: "'Poppins', sans-serif" },
2060
+ { label: 'Roboto', value: "'Roboto', sans-serif" },
2061
+ { label: 'Segoe UI', value: "'Segoe UI', sans-serif" },
2062
+ { label: 'Tahoma', value: 'Tahoma, sans-serif' },
2063
+ { label: 'Times New Roman', value: "'Times New Roman', serif" },
2064
+ { label: 'Trebuchet MS', value: "'Trebuchet MS', sans-serif" },
2065
+ { label: 'Verdana', value: 'Verdana, sans-serif' },
2066
+ ];
2067
+ /** Register a font via FontFace API so it can be previewed. */
2068
+ CoRichTextEditor._registeredFonts = new Set();
2069
+ /* ── Image layout bar (Google-Docs-style toolbar below selected image) ── */
2070
+ CoRichTextEditor.IMG_LAYOUT_ICONS = {
2071
+ 'inline': 'image-square',
2072
+ 'wrap-left': 'text-align-left',
2073
+ 'wrap-right': 'text-align-right',
2074
+ 'center': 'text-align-center',
2075
+ 'full-width': 'arrows-horizontal',
2076
+ };
2077
+ CoRichTextEditor.style = coRichTextEditorCss();
2078
+
2079
+ export { CoRichTextEditor as co_rich_text_editor };