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