@vonage/vivid 5.25.0 → 5.28.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 (747) hide show
  1. package/accordion/index.cjs +1 -1
  2. package/accordion/index.js +8 -8
  3. package/accordion-item/index.cjs +1 -1
  4. package/action-group/index.cjs +3 -3
  5. package/action-group/index.js +10 -5
  6. package/alert/index.cjs +7 -7
  7. package/alert/index.js +47 -35
  8. package/audio-player/index.cjs +18 -18
  9. package/audio-player/index.js +15 -11
  10. package/avatar/index.cjs +9 -9
  11. package/avatar/index.js +27 -18
  12. package/badge/index.cjs +1 -1
  13. package/banner/index.cjs +5 -5
  14. package/banner/index.js +33 -27
  15. package/breadcrumb/index.cjs +1 -1
  16. package/breadcrumb/index.js +5 -1
  17. package/breadcrumb-item/index.cjs +1 -1
  18. package/breadcrumb-item/index.js +6 -6
  19. package/bundled/affix.cjs +3 -3
  20. package/bundled/affix.js +1 -1
  21. package/bundled/anchored.cjs +2 -2
  22. package/bundled/anchored.js +13 -1
  23. package/bundled/aria-binding-directive.cjs +1 -1
  24. package/bundled/aria-binding-directive.js +2 -2
  25. package/bundled/aria.cjs +1 -1
  26. package/bundled/base-color-picker.cjs +2 -2
  27. package/bundled/base-color-picker.js +1 -1
  28. package/bundled/base-progress.cjs +1 -1
  29. package/bundled/breadcrumb-item.cjs +1 -1
  30. package/bundled/button.cjs +1 -1
  31. package/bundled/calendar-event.cjs +1 -1
  32. package/bundled/calendar-event.js +17 -4
  33. package/bundled/calendar-picker.template.cjs +5 -5
  34. package/bundled/calendar-picker.template.js +56 -58
  35. package/bundled/char-count.cjs +2 -2
  36. package/bundled/children.cjs +1 -1
  37. package/bundled/children.js +1 -1
  38. package/bundled/class-names.cjs +1 -1
  39. package/bundled/component-enum.cjs +1 -0
  40. package/bundled/component-enum.js +9 -0
  41. package/bundled/data-grid.options.cjs +1 -1
  42. package/bundled/data-grid.options.js +7 -6
  43. package/bundled/decorate.cjs +1 -1
  44. package/bundled/decorate.js +1 -1
  45. package/bundled/definition.cjs +1 -1
  46. package/bundled/definition10.cjs +12 -18
  47. package/bundled/definition10.js +24 -69
  48. package/bundled/definition11.cjs +74 -10
  49. package/bundled/definition11.js +194 -24
  50. package/bundled/definition12.cjs +18 -70
  51. package/bundled/definition12.js +48 -186
  52. package/bundled/definition13.cjs +5 -22
  53. package/bundled/definition13.js +9 -58
  54. package/bundled/definition14.cjs +1 -5
  55. package/bundled/definition14.js +9 -9
  56. package/bundled/definition15.cjs +3 -3
  57. package/bundled/definition15.js +18 -18
  58. package/bundled/definition16.cjs +3 -3
  59. package/bundled/definition16.js +23 -17
  60. package/bundled/definition17.cjs +6 -6
  61. package/bundled/definition17.js +8 -8
  62. package/bundled/definition18.cjs +2 -2
  63. package/bundled/definition19.cjs +21 -21
  64. package/bundled/definition19.js +66 -61
  65. package/bundled/definition2.cjs +13 -1
  66. package/bundled/definition2.js +22 -185
  67. package/bundled/definition20.cjs +3 -3
  68. package/bundled/definition20.js +6 -7
  69. package/bundled/definition21.cjs +7 -7
  70. package/bundled/definition21.js +22 -23
  71. package/bundled/definition22.cjs +3 -3
  72. package/bundled/definition22.js +25 -25
  73. package/bundled/definition23.cjs +8 -4
  74. package/bundled/definition23.js +31 -9
  75. package/bundled/definition24.cjs +2 -2
  76. package/bundled/definition24.js +1 -1
  77. package/bundled/definition25.cjs +5 -5
  78. package/bundled/definition25.js +16 -11
  79. package/bundled/definition3.cjs +25 -12
  80. package/bundled/definition3.js +90 -21
  81. package/bundled/definition4.cjs +29 -25
  82. package/bundled/definition4.js +50 -89
  83. package/bundled/definition5.cjs +28 -29
  84. package/bundled/definition5.js +144 -45
  85. package/bundled/definition6.cjs +6 -29
  86. package/bundled/definition6.js +20 -130
  87. package/bundled/definition7.cjs +14 -6
  88. package/bundled/definition7.js +159 -20
  89. package/bundled/definition8.cjs +24 -14
  90. package/bundled/definition8.js +90 -144
  91. package/bundled/definition9.cjs +20 -22
  92. package/bundled/definition9.js +54 -80
  93. package/bundled/delegates-aria.cjs +1 -1
  94. package/bundled/delegates-aria.js +3 -2
  95. package/bundled/dialog.cjs +1 -1
  96. package/bundled/dialog.js +1 -1
  97. package/bundled/divider.cjs +1 -1
  98. package/bundled/divider.js +9 -9
  99. package/bundled/dom.cjs +1 -1
  100. package/bundled/enums.cjs +1 -1
  101. package/bundled/extractOptions.cjs +1 -1
  102. package/bundled/feedback-message.cjs +8 -0
  103. package/bundled/feedback-message.js +41 -0
  104. package/bundled/floating-ui.dom.cjs +1 -1
  105. package/bundled/floating-ui.dom.js +163 -197
  106. package/bundled/form-associated.cjs +1 -1
  107. package/bundled/form-associated.js +3 -4
  108. package/bundled/form-element.cjs +1 -1
  109. package/bundled/host-semantics.cjs +1 -1
  110. package/bundled/icon.cjs +1 -1
  111. package/bundled/kbd-shortcut.cjs +1 -1
  112. package/bundled/key-codes.cjs +1 -1
  113. package/bundled/linkable.cjs +2 -2
  114. package/bundled/listbox.cjs +1 -1
  115. package/bundled/listbox.js +3 -5
  116. package/bundled/localized.cjs +1 -1
  117. package/bundled/localized.js +45 -32
  118. package/bundled/mixins.cjs +9 -16
  119. package/bundled/mixins.js +23 -57
  120. package/bundled/numberConverter.cjs +2 -2
  121. package/bundled/numberConverter.js +1 -1
  122. package/bundled/numbers.cjs +1 -1
  123. package/bundled/optgroup.cjs +1 -1
  124. package/bundled/option.cjs +1 -1
  125. package/bundled/option.js +9 -7
  126. package/bundled/picker-field.template.cjs +2 -2
  127. package/bundled/picker-field.template.js +8 -8
  128. package/bundled/platform.cjs +1 -1
  129. package/bundled/playbackRates.cjs +1 -1
  130. package/bundled/ref.cjs +1 -1
  131. package/bundled/ref.js +1 -1
  132. package/bundled/render-in-light-dom.cjs +1 -1
  133. package/bundled/render-in-light-dom.js +4 -4
  134. package/bundled/repeat.cjs +1 -1
  135. package/bundled/repeat.js +16 -15
  136. package/bundled/scrollIntoView.cjs +1 -1
  137. package/bundled/scrollIntoView.js +1 -3
  138. package/bundled/single-date-picker.cjs +1 -1
  139. package/bundled/single-value-picker.cjs +1 -1
  140. package/bundled/single-value-picker.js +1 -1
  141. package/bundled/slider.template.cjs +12 -12
  142. package/bundled/slider.template.js +209 -32
  143. package/bundled/slottable-request.cjs +3 -3
  144. package/bundled/slottable-request.js +26 -17
  145. package/bundled/slotted.cjs +1 -1
  146. package/bundled/slotted.js +1 -1
  147. package/bundled/text-field.cjs +1 -1
  148. package/bundled/text-field.js +1 -1
  149. package/bundled/time-selection-picker.template.cjs +4 -4
  150. package/bundled/time-selection-picker.template.js +10 -7
  151. package/bundled/trapped-focus.cjs +1 -1
  152. package/bundled/utils.cjs +1 -1
  153. package/bundled/vivid-element.cjs +3 -3
  154. package/bundled/vivid-element.js +397 -358
  155. package/bundled/when.cjs +1 -1
  156. package/bundled/when.js +1 -1
  157. package/bundled/with-contextual-help.cjs +1 -1
  158. package/bundled/with-contextual-help.js +1 -1
  159. package/bundled/with-error-text.cjs +1 -1
  160. package/bundled/with-success-text.cjs +1 -1
  161. package/button/index.cjs +1 -1
  162. package/button/index.js +1 -1
  163. package/calendar/index.cjs +1 -1
  164. package/calendar/index.js +7 -7
  165. package/calendar-event/index.cjs +2 -2
  166. package/calendar-event/index.js +10 -8
  167. package/card/index.cjs +4 -2
  168. package/card/index.js +12 -7
  169. package/checkbox/index.cjs +1 -1
  170. package/color-picker/index.cjs +17 -17
  171. package/color-picker/index.js +19 -17
  172. package/combobox/index.cjs +9 -9
  173. package/combobox/index.js +46 -44
  174. package/contextual-help/index.cjs +1 -1
  175. package/contextual-help/index.js +1 -1
  176. package/country/index.cjs +1 -1
  177. package/country-group/index.cjs +1 -1
  178. package/country-group/index.js +8 -4
  179. package/custom-elements.json +9302 -9180
  180. package/data-grid/index.cjs +6 -6
  181. package/data-grid/index.js +92 -99
  182. package/date-picker/index.cjs +1 -1
  183. package/date-picker/index.js +10 -6
  184. package/date-range-picker/index.cjs +1 -1
  185. package/date-range-picker/index.js +13 -9
  186. package/date-time-picker/index.cjs +1 -1
  187. package/date-time-picker/index.js +11 -7
  188. package/dial-pad/index.cjs +4 -3
  189. package/dial-pad/index.js +14 -9
  190. package/dialog/index.cjs +1 -1
  191. package/dialog/index.js +9 -6
  192. package/divider/index.cjs +1 -1
  193. package/elevation/definition.cjs +1 -0
  194. package/elevation/definition.js +2 -2
  195. package/elevation/index.cjs +1 -1
  196. package/elevation/index.js +1 -1
  197. package/empty-state/index.cjs +3 -3
  198. package/empty-state/index.js +18 -6
  199. package/fab/index.cjs +3 -3
  200. package/fab/index.js +14 -6
  201. package/file-picker/index.cjs +8 -10
  202. package/file-picker/index.js +25 -22
  203. package/flag/index.cjs +1 -1
  204. package/flag/index.js +7 -3
  205. package/form-field/definition.cjs +5 -0
  206. package/form-field/definition.js +2 -0
  207. package/form-field/index.cjs +29 -0
  208. package/form-field/index.js +57 -0
  209. package/header/definition.cjs +1 -1
  210. package/header/definition.js +1 -1
  211. package/header/index.cjs +1 -1
  212. package/header/index.js +9 -5
  213. package/icon/index.cjs +1 -1
  214. package/icon/index.js +1 -1
  215. package/index.cjs +159 -154
  216. package/index.js +42 -40
  217. package/kbd-key/definition.cjs +1 -1
  218. package/kbd-key/definition.js +1 -1
  219. package/kbd-key/index.cjs +3 -3
  220. package/kbd-key/index.js +22 -13
  221. package/kbd-shortcut/definition.cjs +1 -1
  222. package/kbd-shortcut/definition.js +1 -1
  223. package/kbd-shortcut/index.cjs +1 -1
  224. package/kbd-shortcut/index.js +6 -6
  225. package/layout/definition.cjs +1 -1
  226. package/layout/definition.js +1 -1
  227. package/layout/index.cjs +1 -1
  228. package/layout/index.js +7 -3
  229. package/lib/accordion-item/accordion-item.d.ts +11 -6
  230. package/lib/action-group/action-group.d.ts +10 -5
  231. package/lib/alert/alert.d.ts +15 -18
  232. package/lib/avatar/avatar.d.ts +16 -7
  233. package/lib/badge/badge.d.ts +18 -7
  234. package/lib/badge/badge.template.d.ts +2 -1
  235. package/lib/banner/banner.d.ts +18 -20
  236. package/lib/button/button.d.ts +25 -16
  237. package/lib/calendar-event/calendar-event.d.ts +14 -7
  238. package/lib/checkbox/checkbox.d.ts +31 -28
  239. package/lib/combobox/combobox.d.ts +37 -32
  240. package/lib/components.d.ts +1 -0
  241. package/lib/data-grid/data-grid.options.d.ts +6 -1
  242. package/lib/dial-pad/locale.d.ts +1 -0
  243. package/lib/divider/divider.d.ts +9 -6
  244. package/lib/elevation/definition.d.ts +2 -0
  245. package/lib/empty-state/empty-state.d.ts +7 -2
  246. package/lib/fab/fab.d.ts +3 -2
  247. package/lib/form-field/definition.d.ts +4 -0
  248. package/lib/form-field/form-field.d.ts +6 -0
  249. package/lib/form-field/form-field.template.d.ts +3 -0
  250. package/lib/icon/icon.d.ts +1 -1
  251. package/lib/kbd-key/kbd-key.d.ts +7 -2
  252. package/lib/listbox/listbox.d.ts +1 -0
  253. package/lib/menu-item/menu-item.d.ts +17 -14
  254. package/lib/nav-disclosure/nav-disclosure.d.ts +18 -11
  255. package/lib/nav-item/nav-item.d.ts +19 -12
  256. package/lib/note/note.d.ts +10 -6
  257. package/lib/number-field/number-field.d.ts +45 -40
  258. package/lib/option/option.d.ts +13 -10
  259. package/lib/popover/popover.d.ts +2 -1
  260. package/lib/popup/definition.d.ts +2 -0
  261. package/lib/progress/progress.d.ts +10 -5
  262. package/lib/progress-ring/progress-ring.d.ts +10 -6
  263. package/lib/radio/radio.d.ts +18 -15
  264. package/lib/range-slider/range-slider.d.ts +19 -15
  265. package/lib/rich-text-editor/rich-text-editor.d.ts +436 -5
  266. package/lib/rich-text-editor/rte/__tests__/async-generator.d.ts +1 -0
  267. package/lib/rich-text-editor/rte/features/atom.d.ts +6 -2
  268. package/lib/rich-text-editor/rte/instance.d.ts +2 -1
  269. package/lib/rich-text-editor/rte/utils/ui.d.ts +2 -1
  270. package/lib/searchable-select/option-tag.d.ts +12 -7
  271. package/lib/searchable-select/searchable-select.d.ts +7 -2
  272. package/lib/select/select.d.ts +45 -40
  273. package/lib/selectable-box/selectable-box.d.ts +9 -5
  274. package/lib/slider/slider.d.ts +18 -14
  275. package/lib/split-button/split-button.d.ts +24 -15
  276. package/lib/status/status.d.ts +10 -7
  277. package/lib/switch/switch.d.ts +13 -9
  278. package/lib/tab/tab.d.ts +19 -14
  279. package/lib/table/locale.d.ts +10 -0
  280. package/lib/table/table-sorting-button.d.ts +425 -0
  281. package/lib/tabs/tabs.d.ts +6 -3
  282. package/lib/tag/tag.d.ts +24 -15
  283. package/lib/tag-name-map.d.ts +2 -1
  284. package/lib/text-field/text-field.d.ts +46 -41
  285. package/lib/video-player/__tests__/video-fixtures.d.ts +3 -0
  286. package/listbox/definition.cjs +1 -1
  287. package/listbox/definition.js +1 -1
  288. package/listbox/index.cjs +7 -5
  289. package/listbox/index.js +24 -10
  290. package/locales/de-DE.cjs +46 -33
  291. package/locales/de-DE.js +46 -33
  292. package/locales/en-GB.cjs +46 -33
  293. package/locales/en-GB.js +46 -33
  294. package/locales/ja-JP.cjs +47 -33
  295. package/locales/ja-JP.js +47 -33
  296. package/locales/zh-CN.cjs +46 -33
  297. package/locales/zh-CN.js +46 -33
  298. package/menu/index.cjs +1 -1
  299. package/menu-item/index.cjs +1 -1
  300. package/nav/definition.cjs +1 -1
  301. package/nav/definition.js +1 -1
  302. package/nav/index.cjs +1 -1
  303. package/nav/index.js +6 -4
  304. package/nav-disclosure/definition.cjs +1 -1
  305. package/nav-disclosure/definition.js +1 -1
  306. package/nav-disclosure/index.cjs +3 -3
  307. package/nav-disclosure/index.js +13 -8
  308. package/nav-item/definition.cjs +1 -1
  309. package/nav-item/definition.js +1 -1
  310. package/nav-item/index.cjs +2 -2
  311. package/nav-item/index.js +15 -10
  312. package/note/definition.cjs +1 -1
  313. package/note/definition.js +1 -1
  314. package/note/index.cjs +6 -4
  315. package/note/index.js +22 -9
  316. package/number-field/definition.cjs +1 -1
  317. package/number-field/definition.js +1 -1
  318. package/number-field/index.cjs +11 -11
  319. package/number-field/index.js +41 -36
  320. package/optgroup/index.cjs +1 -1
  321. package/option/index.cjs +1 -1
  322. package/package.json +29 -36
  323. package/pagination/definition.cjs +1 -1
  324. package/pagination/definition.js +1 -1
  325. package/pagination/index.cjs +1 -1
  326. package/pagination/index.js +9 -9
  327. package/platform-switch/definition.cjs +1 -1
  328. package/platform-switch/definition.js +1 -1
  329. package/platform-switch/index.cjs +1 -1
  330. package/platform-switch/index.js +6 -2
  331. package/popover/definition.cjs +1 -1
  332. package/popover/definition.js +1 -1
  333. package/popover/index.cjs +2 -2
  334. package/popover/index.js +82 -41
  335. package/popup/definition.cjs +1 -0
  336. package/popup/definition.js +2 -2
  337. package/popup/index.cjs +1 -1
  338. package/popup/index.js +1 -1
  339. package/progress/definition.cjs +1 -1
  340. package/progress/definition.js +1 -1
  341. package/progress/index.cjs +7 -7
  342. package/progress/index.js +21 -11
  343. package/progress-ring/index.cjs +1 -1
  344. package/progress-ring/index.js +1 -1
  345. package/radio/definition.cjs +1 -1
  346. package/radio/definition.js +1 -1
  347. package/radio/index.cjs +1 -1
  348. package/radio-group/definition.cjs +1 -1
  349. package/radio-group/definition.js +1 -1
  350. package/radio-group/index.cjs +2 -2
  351. package/radio-group/index.js +14 -9
  352. package/range-slider/definition.cjs +1 -1
  353. package/range-slider/definition.js +1 -1
  354. package/range-slider/index.cjs +8 -8
  355. package/range-slider/index.js +31 -32
  356. package/rich-text-editor/definition.cjs +1 -1
  357. package/rich-text-editor/definition.js +1 -1
  358. package/rich-text-editor/index.cjs +25 -16
  359. package/rich-text-editor/index.js +2450 -2154
  360. package/rich-text-view/definition.cjs +1 -1
  361. package/rich-text-view/definition.js +1 -1
  362. package/rich-text-view/index.cjs +1 -1
  363. package/rich-text-view/index.js +6 -4
  364. package/searchable-select/definition.cjs +1 -1
  365. package/searchable-select/definition.js +1 -1
  366. package/searchable-select/index.cjs +22 -22
  367. package/searchable-select/index.js +97 -93
  368. package/select/definition.cjs +1 -1
  369. package/select/definition.js +1 -1
  370. package/select/index.cjs +1 -1
  371. package/selectable-box/definition.cjs +1 -1
  372. package/selectable-box/definition.js +1 -1
  373. package/selectable-box/index.cjs +8 -8
  374. package/selectable-box/index.js +24 -20
  375. package/shared/localization/Locale.d.ts +2 -0
  376. package/shared/patterns/anchored.d.ts +2 -0
  377. package/shared/styles/appearance.d.ts +2 -0
  378. package/shared/styles/connotation.d.ts +2 -0
  379. package/shared/styles/connotationOverrides.d.ts +1 -0
  380. package/shared/utils/component-enum.d.ts +7 -0
  381. package/side-drawer/definition.cjs +1 -1
  382. package/side-drawer/definition.js +1 -1
  383. package/side-drawer/index.cjs +1 -1
  384. package/side-drawer/index.js +10 -7
  385. package/simple-color-picker/definition.cjs +1 -1
  386. package/simple-color-picker/definition.js +1 -1
  387. package/simple-color-picker/index.cjs +2 -2
  388. package/simple-color-picker/index.js +20 -20
  389. package/slider/definition.cjs +2 -1
  390. package/slider/definition.js +2 -1
  391. package/slider/index.cjs +1 -1
  392. package/slider/index.js +1 -1
  393. package/split-button/definition.cjs +1 -1
  394. package/split-button/definition.js +1 -1
  395. package/split-button/index.cjs +9 -7
  396. package/split-button/index.js +58 -37
  397. package/status/definition.cjs +1 -1
  398. package/status/definition.js +1 -1
  399. package/status/index.cjs +5 -5
  400. package/status/index.js +22 -13
  401. package/switch/definition.cjs +1 -1
  402. package/switch/definition.js +1 -1
  403. package/switch/index.cjs +3 -3
  404. package/switch/index.js +22 -11
  405. package/tab/definition.cjs +1 -1
  406. package/tab/definition.js +1 -1
  407. package/tab/index.cjs +1 -1
  408. package/tab/index.js +1 -1
  409. package/tab-panel/definition.cjs +1 -1
  410. package/tab-panel/definition.js +1 -1
  411. package/tab-panel/index.cjs +1 -1
  412. package/tab-panel/index.js +1 -1
  413. package/table/definition.cjs +1 -1
  414. package/table/definition.js +1 -1
  415. package/table/index.cjs +20 -18
  416. package/table/index.js +54 -42
  417. package/tabs/definition.cjs +1 -1
  418. package/tabs/definition.js +1 -1
  419. package/tabs/index.cjs +4 -4
  420. package/tabs/index.js +32 -30
  421. package/tag/definition.cjs +1 -1
  422. package/tag/definition.js +1 -1
  423. package/tag/index.cjs +6 -6
  424. package/tag/index.js +28 -12
  425. package/tag-group/definition.cjs +1 -1
  426. package/tag-group/definition.js +1 -1
  427. package/tag-group/index.cjs +1 -1
  428. package/tag-group/index.js +6 -4
  429. package/text-area/definition.cjs +1 -1
  430. package/text-area/definition.js +1 -1
  431. package/text-area/index.cjs +5 -5
  432. package/text-area/index.js +18 -15
  433. package/text-field/index.cjs +1 -1
  434. package/text-field/index.js +1 -1
  435. package/time-picker/definition.cjs +1 -1
  436. package/time-picker/definition.js +1 -1
  437. package/time-picker/index.cjs +1 -1
  438. package/time-picker/index.js +9 -6
  439. package/toggletip/index.cjs +1 -1
  440. package/toggletip/index.js +1 -1
  441. package/tooltip/index.cjs +1 -1
  442. package/tooltip/index.js +1 -1
  443. package/tree-item/definition.cjs +1 -1
  444. package/tree-item/definition.js +1 -1
  445. package/tree-item/index.cjs +1 -1
  446. package/tree-item/index.js +1 -1
  447. package/tree-view/definition.cjs +1 -1
  448. package/tree-view/definition.js +1 -1
  449. package/tree-view/index.cjs +1 -1
  450. package/tree-view/index.js +7 -5
  451. package/unbundled/affix.cjs +0 -1
  452. package/unbundled/anchored.cjs +39 -1
  453. package/unbundled/anchored.js +28 -1
  454. package/unbundled/aria-binding-directive.cjs +2 -2
  455. package/unbundled/aria-binding-directive.js +2 -1
  456. package/unbundled/base-color-picker.cjs +0 -1
  457. package/unbundled/base-progress.cjs +0 -1
  458. package/unbundled/breadcrumb-item.cjs +0 -1
  459. package/unbundled/button.cjs +0 -1
  460. package/unbundled/calendar-event.cjs +29 -1
  461. package/unbundled/calendar-event.js +18 -1
  462. package/unbundled/calendar-picker.template.cjs +109 -91
  463. package/unbundled/calendar-picker.template.js +109 -90
  464. package/unbundled/char-count.cjs +0 -1
  465. package/unbundled/component-enum.cjs +18 -0
  466. package/unbundled/component-enum.js +13 -0
  467. package/unbundled/data-grid.options.cjs +8 -0
  468. package/unbundled/data-grid.options.js +3 -1
  469. package/unbundled/decorate.cjs +1 -1
  470. package/unbundled/decorate.js +1 -1
  471. package/unbundled/definition.cjs +1 -2
  472. package/unbundled/definition.js +1 -1
  473. package/unbundled/definition10.cjs +2 -343
  474. package/unbundled/definition10.js +4 -338
  475. package/unbundled/definition11.cjs +6 -7
  476. package/unbundled/definition11.js +6 -6
  477. package/unbundled/definition12.cjs +4 -4
  478. package/unbundled/definition12.js +5 -4
  479. package/unbundled/definition13.cjs +2 -2
  480. package/unbundled/definition13.js +2 -1
  481. package/unbundled/definition14.cjs +12 -4
  482. package/unbundled/definition14.js +12 -3
  483. package/unbundled/definition15.cjs +32 -6
  484. package/unbundled/definition15.js +32 -5
  485. package/unbundled/definition16.cjs +20 -14
  486. package/unbundled/definition16.js +20 -13
  487. package/unbundled/definition17.cjs +0 -1
  488. package/unbundled/definition18.cjs +4 -3
  489. package/unbundled/definition18.js +4 -2
  490. package/unbundled/definition19.cjs +2 -3
  491. package/unbundled/definition19.js +9 -8
  492. package/unbundled/definition2.cjs +9 -4
  493. package/unbundled/definition2.js +9 -3
  494. package/unbundled/definition20.cjs +1 -2
  495. package/unbundled/definition20.js +7 -6
  496. package/unbundled/definition21.cjs +4 -3
  497. package/unbundled/definition21.js +4 -2
  498. package/unbundled/definition22.cjs +0 -1
  499. package/unbundled/definition23.cjs +12 -6
  500. package/unbundled/definition23.js +11 -4
  501. package/unbundled/definition24.cjs +8 -8
  502. package/unbundled/definition24.js +9 -8
  503. package/unbundled/definition25.cjs +7 -4
  504. package/unbundled/definition25.js +7 -3
  505. package/unbundled/definition26.cjs +6 -4
  506. package/unbundled/definition26.js +5 -2
  507. package/unbundled/definition27.cjs +10 -7
  508. package/unbundled/definition27.js +10 -6
  509. package/unbundled/definition28.cjs +3 -3
  510. package/unbundled/definition28.js +2 -1
  511. package/unbundled/definition29.cjs +2 -3
  512. package/unbundled/definition29.js +3 -3
  513. package/unbundled/definition3.cjs +5 -6
  514. package/unbundled/definition3.js +5 -5
  515. package/unbundled/definition30.cjs +0 -1
  516. package/unbundled/definition31.cjs +15 -13
  517. package/unbundled/definition31.js +14 -11
  518. package/unbundled/definition32.cjs +0 -1
  519. package/unbundled/definition33.cjs +0 -1
  520. package/unbundled/definition34.cjs +0 -1
  521. package/unbundled/definition35.cjs +39 -51
  522. package/unbundled/definition35.js +40 -51
  523. package/unbundled/definition36.cjs +2 -3
  524. package/unbundled/definition36.js +9 -8
  525. package/unbundled/definition37.cjs +0 -1
  526. package/unbundled/definition38.cjs +0 -1
  527. package/unbundled/definition39.cjs +0 -1
  528. package/unbundled/definition4.cjs +4 -3
  529. package/unbundled/definition4.js +11 -6
  530. package/unbundled/definition40.cjs +5 -4
  531. package/unbundled/definition40.js +5 -3
  532. package/unbundled/definition41.cjs +0 -1
  533. package/unbundled/definition42.cjs +11 -3
  534. package/unbundled/definition42.js +11 -2
  535. package/unbundled/definition43.cjs +7 -3
  536. package/unbundled/definition43.js +7 -2
  537. package/unbundled/definition44.cjs +12 -11
  538. package/unbundled/definition44.js +11 -9
  539. package/unbundled/definition45.cjs +73 -52
  540. package/unbundled/definition45.js +69 -47
  541. package/unbundled/definition46.cjs +53 -46
  542. package/unbundled/definition46.js +49 -41
  543. package/unbundled/definition47.cjs +40 -165
  544. package/unbundled/definition47.js +36 -160
  545. package/unbundled/definition48.cjs +177 -32
  546. package/unbundled/definition48.js +174 -22
  547. package/unbundled/definition49.cjs +32 -596
  548. package/unbundled/definition49.js +29 -591
  549. package/unbundled/definition5.cjs +9 -3
  550. package/unbundled/definition5.js +15 -7
  551. package/unbundled/definition50.cjs +609 -78
  552. package/unbundled/definition50.js +605 -75
  553. package/unbundled/definition51.cjs +74 -34
  554. package/unbundled/definition51.js +70 -29
  555. package/unbundled/definition52.cjs +59 -24
  556. package/unbundled/definition52.js +57 -18
  557. package/unbundled/definition53.cjs +23 -40
  558. package/unbundled/definition53.js +19 -35
  559. package/unbundled/definition54.cjs +40 -316
  560. package/unbundled/definition54.js +38 -313
  561. package/unbundled/definition55.cjs +305 -196
  562. package/unbundled/definition55.js +301 -191
  563. package/unbundled/definition56.cjs +210 -41
  564. package/unbundled/definition56.js +206 -36
  565. package/unbundled/definition57.cjs +42 -271
  566. package/unbundled/definition57.js +38 -266
  567. package/unbundled/definition58.cjs +351 -51
  568. package/unbundled/definition58.js +348 -46
  569. package/unbundled/definition59.cjs +58 -147
  570. package/unbundled/definition59.js +59 -144
  571. package/unbundled/definition6.cjs +22 -7
  572. package/unbundled/definition6.js +22 -6
  573. package/unbundled/definition60.cjs +129 -226
  574. package/unbundled/definition60.js +126 -222
  575. package/unbundled/definition61.cjs +200 -420
  576. package/unbundled/definition61.js +197 -416
  577. package/unbundled/definition62.cjs +442 -3743
  578. package/unbundled/definition62.js +433 -3570
  579. package/unbundled/definition63.cjs +3788 -729
  580. package/unbundled/definition63.js +3617 -721
  581. package/unbundled/definition64.cjs +784 -98
  582. package/unbundled/definition64.js +781 -94
  583. package/unbundled/definition65.cjs +100 -1003
  584. package/unbundled/definition65.js +98 -997
  585. package/unbundled/definition66.cjs +996 -94
  586. package/unbundled/definition66.js +992 -89
  587. package/unbundled/definition67.cjs +111 -74
  588. package/unbundled/definition67.js +107 -63
  589. package/unbundled/definition68.cjs +69 -157
  590. package/unbundled/definition68.js +65 -152
  591. package/unbundled/definition69.cjs +156 -120
  592. package/unbundled/definition69.js +152 -115
  593. package/unbundled/definition7.cjs +0 -1
  594. package/unbundled/definition7.js +10 -4
  595. package/unbundled/definition70.cjs +154 -50
  596. package/unbundled/definition70.js +150 -45
  597. package/unbundled/definition71.cjs +58 -86
  598. package/unbundled/definition71.js +57 -81
  599. package/unbundled/definition72.cjs +99 -20
  600. package/unbundled/definition72.js +98 -15
  601. package/unbundled/definition73.cjs +20 -89
  602. package/unbundled/definition73.js +16 -84
  603. package/unbundled/definition74.cjs +79 -296
  604. package/unbundled/definition74.js +73 -217
  605. package/unbundled/definition75.cjs +304 -312
  606. package/unbundled/definition75.js +232 -304
  607. package/unbundled/definition76.cjs +328 -27
  608. package/unbundled/definition76.js +320 -23
  609. package/unbundled/definition77.cjs +27 -125
  610. package/unbundled/definition77.js +23 -120
  611. package/unbundled/definition78.cjs +120 -233
  612. package/unbundled/definition78.js +116 -228
  613. package/unbundled/definition79.cjs +258 -26
  614. package/unbundled/definition79.js +249 -23
  615. package/unbundled/definition8.cjs +19 -12
  616. package/unbundled/definition8.js +19 -11
  617. package/unbundled/definition80.cjs +29 -149
  618. package/unbundled/definition80.js +27 -134
  619. package/unbundled/definition81.cjs +118 -174
  620. package/unbundled/definition81.js +109 -169
  621. package/unbundled/definition82.cjs +180 -477
  622. package/unbundled/definition82.js +178 -472
  623. package/unbundled/definition83.cjs +517 -0
  624. package/unbundled/definition83.js +498 -0
  625. package/unbundled/definition9.cjs +4 -3
  626. package/unbundled/definition9.js +4 -2
  627. package/unbundled/delegates-aria.cjs +4 -2
  628. package/unbundled/delegates-aria.js +4 -2
  629. package/unbundled/divider.cjs +8 -3
  630. package/unbundled/divider.js +3 -3
  631. package/unbundled/en-US.cjs +46 -33
  632. package/unbundled/en-US.js +46 -33
  633. package/unbundled/feedback-message.cjs +59 -0
  634. package/unbundled/feedback-message.js +48 -0
  635. package/unbundled/form-associated.cjs +1 -4
  636. package/unbundled/form-associated.js +1 -3
  637. package/unbundled/form-element.cjs +0 -1
  638. package/unbundled/icon.cjs +0 -1
  639. package/unbundled/kbd-shortcut.cjs +0 -1
  640. package/unbundled/linkable.cjs +1 -2
  641. package/unbundled/linkable.js +1 -1
  642. package/unbundled/listbox.cjs +0 -2
  643. package/unbundled/listbox.js +0 -1
  644. package/unbundled/localized.cjs +0 -1
  645. package/unbundled/mixins.cjs +3 -54
  646. package/unbundled/mixins.js +3 -47
  647. package/unbundled/numberConverter.cjs +8 -3
  648. package/unbundled/numberConverter.js +8 -3
  649. package/unbundled/optgroup.cjs +0 -1
  650. package/unbundled/option.cjs +8 -1
  651. package/unbundled/option.js +3 -1
  652. package/unbundled/picker-field.template.cjs +1 -2
  653. package/unbundled/picker-field.template.js +1 -1
  654. package/unbundled/randomId.cjs +0 -1
  655. package/unbundled/{chunk.cjs → rolldown-runtime.cjs} +1 -1
  656. package/unbundled/scrollIntoView.cjs +0 -1
  657. package/unbundled/scrollIntoView.js +0 -1
  658. package/unbundled/slider.template.cjs +340 -2
  659. package/unbundled/slider.template.js +338 -5
  660. package/unbundled/text-field.cjs +1 -1
  661. package/unbundled/text-field.js +1 -1
  662. package/unbundled/time-selection-picker.template.cjs +2 -3
  663. package/unbundled/time-selection-picker.template.js +2 -2
  664. package/unbundled/vivid-element.cjs +63 -4
  665. package/unbundled/vivid-element.js +63 -3
  666. package/unbundled/with-contextual-help.cjs +0 -1
  667. package/unbundled/with-error-text.cjs +0 -1
  668. package/unbundled/with-success-text.cjs +0 -1
  669. package/video-player/definition.cjs +1 -1
  670. package/video-player/definition.js +1 -1
  671. package/video-player/index.cjs +31 -31
  672. package/video-player/index.js +2094 -2085
  673. package/visually-hidden/index.cjs +1 -1
  674. package/vivid.api.json +509 -1125
  675. package/lib/accordion/variations.browser-spec.d.ts +0 -1
  676. package/lib/action-group/variations.browser-spec.d.ts +0 -1
  677. package/lib/alert/variations.browser-spec.d.ts +0 -1
  678. package/lib/audio-player/variations.browser-spec.d.ts +0 -1
  679. package/lib/avatar/variations.browser-spec.d.ts +0 -1
  680. package/lib/badge/variations.browser-spec.d.ts +0 -1
  681. package/lib/banner/variations.browser-spec.d.ts +0 -1
  682. package/lib/breadcrumb-item/variations.browser-spec.d.ts +0 -1
  683. package/lib/button/variations.browser-spec.d.ts +0 -1
  684. package/lib/calendar/variations.browser-spec.d.ts +0 -1
  685. package/lib/calendar-event/variations.browser-spec.d.ts +0 -1
  686. package/lib/card/variations.browser-spec.d.ts +0 -1
  687. package/lib/checkbox/variations.browser-spec.d.ts +0 -1
  688. package/lib/color-picker/variations.browser-spec.d.ts +0 -1
  689. package/lib/combobox/variations.browser-spec.d.ts +0 -1
  690. package/lib/contextual-help/variations.browser-spec.d.ts +0 -1
  691. package/lib/country/variations.browser-spec.d.ts +0 -1
  692. package/lib/data-grid/variations.browser-spec.d.ts +0 -1
  693. package/lib/date-picker/variations.browser-spec.d.ts +0 -1
  694. package/lib/date-range-picker/variations.browser-spec.d.ts +0 -1
  695. package/lib/date-time-picker/variations.browser-spec.d.ts +0 -1
  696. package/lib/dial-pad/variations.browser-spec.d.ts +0 -1
  697. package/lib/dialog/variations.browser-spec.d.ts +0 -1
  698. package/lib/divider/variations.browser-spec.d.ts +0 -1
  699. package/lib/empty-state/variations.browser-spec.d.ts +0 -1
  700. package/lib/fab/variations.browser-spec.d.ts +0 -1
  701. package/lib/file-picker/variations.browser-spec.d.ts +0 -1
  702. package/lib/flag/variations.browser-spec.d.ts +0 -1
  703. package/lib/header/variations.browser-spec.d.ts +0 -1
  704. package/lib/icon/variations.browser-spec.d.ts +0 -1
  705. package/lib/kbd-key/variations.browser-spec.d.ts +0 -1
  706. package/lib/kbd-shortcut/variations.browser-spec.d.ts +0 -1
  707. package/lib/layout/variations.browser-spec.d.ts +0 -1
  708. package/lib/listbox/variations.browser-spec.d.ts +0 -1
  709. package/lib/menu/variations.browser-spec.d.ts +0 -1
  710. package/lib/menu-item/variations.browser-spec.d.ts +0 -1
  711. package/lib/nav/variations.browser-spec.d.ts +0 -1
  712. package/lib/nav-disclosure/variations.browser-spec.d.ts +0 -1
  713. package/lib/nav-item/variations.browser-spec.d.ts +0 -1
  714. package/lib/note/variations.browser-spec.d.ts +0 -1
  715. package/lib/number-field/variations.browser-spec.d.ts +0 -1
  716. package/lib/optgroup/variations.browser-spec.d.ts +0 -1
  717. package/lib/option/variations.browser-spec.d.ts +0 -1
  718. package/lib/pagination/variations.browser-spec.d.ts +0 -1
  719. package/lib/popover/variations.browser-spec.d.ts +0 -1
  720. package/lib/progress/variations.browser-spec.d.ts +0 -1
  721. package/lib/progress-ring/variations.browser-spec.d.ts +0 -1
  722. package/lib/radio/variations.browser-spec.d.ts +0 -1
  723. package/lib/radio-group/variations.browser-spec.d.ts +0 -1
  724. package/lib/range-slider/variations.browser-spec.d.ts +0 -1
  725. package/lib/rich-text-editor/variations.browser-spec.d.ts +0 -1
  726. package/lib/rich-text-view/variations.browser-spec.d.ts +0 -1
  727. package/lib/searchable-select/variations.browser-spec.d.ts +0 -1
  728. package/lib/select/variations.browser-spec.d.ts +0 -1
  729. package/lib/selectable-box/variations.browser-spec.d.ts +0 -1
  730. package/lib/side-drawer/variations.browser-spec.d.ts +0 -1
  731. package/lib/simple-color-picker/variations.browser-spec.d.ts +0 -1
  732. package/lib/slider/variations.browser-spec.d.ts +0 -1
  733. package/lib/split-button/variations.browser-spec.d.ts +0 -1
  734. package/lib/status/variations.browser-spec.d.ts +0 -1
  735. package/lib/switch/variations.browser-spec.d.ts +0 -1
  736. package/lib/table/variations.browser-spec.d.ts +0 -1
  737. package/lib/tabs/variations.browser-spec.d.ts +0 -1
  738. package/lib/tag/variations.browser-spec.d.ts +0 -1
  739. package/lib/text-area/variations.browser-spec.d.ts +0 -1
  740. package/lib/text-field/variations.browser-spec.d.ts +0 -1
  741. package/lib/time-picker/variations.browser-spec.d.ts +0 -1
  742. package/lib/toggletip/variations.browser-spec.d.ts +0 -1
  743. package/lib/tooltip/variations.browser-spec.d.ts +0 -1
  744. package/lib/tree-item/variations.browser-spec.d.ts +0 -1
  745. package/lib/video-player/variations.browser-spec.d.ts +0 -1
  746. /package/lib/{accordion-item/variations.browser-spec.d.ts → form-field/index.d.ts} +0 -0
  747. /package/unbundled/{chunk.js → rolldown-runtime.js} +0 -0
@@ -1,814 +1,3873 @@
1
- require("./chunk.cjs");
1
+ const require_rolldown_runtime = require("./rolldown-runtime.cjs");
2
2
  const require_vivid_element = require("./vivid-element.cjs");
3
- const require_definition = require("./definition.cjs");
4
3
  const require_decorate = require("./decorate.cjs");
5
- const require_affix = require("./affix.cjs");
6
- const require_form_associated = require("./form-associated.cjs");
4
+ const require_delegates_aria = require("./delegates-aria.cjs");
5
+ const require_definition = require("./definition5.cjs");
7
6
  const require_localized = require("./localized.cjs");
8
7
  const require_definition$1 = require("./definition6.cjs");
9
- const require_dialog = require("./dialog.cjs");
10
8
  const require_definition$2 = require("./definition9.cjs");
11
- const require_host_semantics = require("./host-semantics.cjs");
12
- const require_mixins = require("./mixins.cjs");
13
- const require_form_element = require("./form-element.cjs");
14
- const require_with_error_text = require("./with-error-text.cjs");
15
- const require_with_success_text = require("./with-success-text.cjs");
16
- const require_with_contextual_help = require("./with-contextual-help.cjs");
9
+ const require_definition$3 = require("./definition11.cjs");
10
+ const require_definition$4 = require("./definition12.cjs");
11
+ const require_divider = require("./divider.cjs");
12
+ const require_randomId = require("./randomId.cjs");
13
+ const require_definition$5 = require("./definition26.cjs");
14
+ const require_definition$6 = require("./definition27.cjs");
17
15
  const require_option = require("./option.cjs");
18
- const require_definition$3 = require("./definition29.cjs");
19
- const require_definition$4 = require("./definition30.cjs");
20
- const require_listbox = require("./listbox.cjs");
16
+ const require_definition$7 = require("./definition29.cjs");
17
+ const require_definition$8 = require("./definition36.cjs");
18
+ const require_slottable_request = require("./slottable-request.cjs");
19
+ const require_definition$9 = require("./definition64.cjs");
21
20
  let _microsoft_fast_element = require("@microsoft/fast-element");
22
21
  let _microsoft_fast_web_utilities = require("@microsoft/fast-web-utilities");
23
- //#region src/lib/select/select.scss?inline
24
- var select_default = ".label-wrapper{align-items:center;gap:var(--label-wrapper-gap,4px);flex-direction:row;display:flex}.label-wrapper[hidden]{display:none}.label:not(slot),.label::slotted(label){flex:0 auto}.chevron{font:var(--vvd-typography-base-extended);flex-shrink:0;display:flex;transform:rotate(0)}@media (prefers-reduced-motion:no-preference){.chevron{transition:transform .2s}}:host([data-expanded=true]) .chevron,:host([open]) .chevron{transform:rotate(180deg)}:host(:focus-visible){outline:none}:host{--_low-ink-color:var(--vvd-color-neutral-600);--focus-stroke-gap-color:transparent;flex-direction:column;gap:4px;display:inline-flex}:host([disabled]){--_low-ink-color:var(--vvd-color-neutral-600);cursor:not-allowed}.label{color:var(--vvd-color-canvas-text);font:var(--vvd-typography-base)}.control{--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-canvas);--_appearance-color-outline:var(--vvd-color-neutral-500)}.control.appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}@media (hover:hover){.control:hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-canvas);--_appearance-color-outline:var(--vvd-color-neutral-700)}.control:hover:where(:not(.disabled,:disabled,.readonly)).appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:var(--_connotation-color-faint);--_appearance-color-outline:transparent}}.control.hover:where(:not(.disabled,:disabled,.readonly)){--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-canvas);--_appearance-color-outline:var(--vvd-color-neutral-700)}.control.hover:where(:not(.disabled,:disabled,.readonly)).appearance-ghost{--_appearance-color-text:var(--_connotation-color-firm);--_appearance-color-fill:var(--_connotation-color-faint);--_appearance-color-outline:transparent}.control:disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.control:disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.disabled{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:var(--vvd-color-neutral-100);--_appearance-color-outline:var(--vvd-color-neutral-300)}.control.disabled.appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-300);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.readonly:where(:not(.disabled,:disabled)){--_appearance-color-text:var(--vvd-color-canvas-text);--_appearance-color-fill:var(--vvd-color-neutral-200);--_appearance-color-outline:var(--vvd-color-neutral-400)}.control.readonly:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:var(--vvd-color-neutral-600);--_appearance-color-fill:transparent;--_appearance-color-outline:transparent}.control.error:where(:not(.disabled,:disabled)){--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-alert-50);--_appearance-color-outline:var(--vvd-color-alert-500)}.control.error:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-alert-50);--_appearance-color-outline:transparent}.control.success:where(:not(.disabled,:disabled)){--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-success-50);--_appearance-color-outline:var(--vvd-color-success-500)}.control.success:where(:not(.disabled,:disabled)).appearance-ghost{--_appearance-color-text:notset;--_appearance-color-fill:var(--vvd-color-success-50);--_appearance-color-outline:transparent}.control{--_connotation-color-primary:var(--vvd-select-accent-primary,var(--vvd-color-canvas-text));--_connotation-color-primary-text:var(--vvd-select-accent-primary-text,var(--vvd-color-canvas));--_connotation-color-primary-increment:var(--vvd-select-accent-primary-increment,var(--vvd-color-neutral-800));--_connotation-color-intermediate:var(--vvd-select-accent-intermediate,var(--vvd-color-neutral-500));--_connotation-color-faint:var(--vvd-select-accent-faint,var(--vvd-color-neutral-50));--_connotation-color-soft:var(--vvd-select-accent-soft,var(--vvd-color-neutral-100));--_connotation-color-firm:var(--vvd-select-accent-firm,var(--vvd-color-canvas-text));--_connotation-color-fierce:var(--vvd-select-accent-fierce,var(--vvd-color-neutral-700));border-radius:var(--_select-control-border-radius);block-size:var(--_select-block-size);padding-inline:var(--_select-padding-inline);--_select-icon-size:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2);--_select-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2)));--_select-padding-inline:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2.5);background-color:var(--_appearance-color-fill);box-shadow:inset 0 0 0 1px var(--_appearance-color-outline);color:var(--_appearance-color-text);font:var(--vvd-typography-base);justify-content:space-between;align-items:center;gap:8px;transition:box-shadow .2s,background-color .2s;display:flex}.control.size-condensed{--_select-icon-size:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2))) / 2.5);--_select-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 8));--_select-padding-inline:calc(calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 16)) / 2)}.control.size-condensed:not(.shape-pill){--_select-control-border-radius:4px}.control-wrapper{position:relative}.control:not(.disabled){cursor:pointer}.control.disabled{pointer-events:none}.control:not(.shape-pill){--_select-control-border-radius:8px}.control.shape-pill{--_select-control-border-radius:24px}.listbox{max-height:var(--select-height,408px);flex-direction:column;gap:2px;padding:4px;display:flex;overflow-y:auto}:host([multiple]:focus-visible) .listbox{box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));border-radius:8px}.selected-value{white-space:nowrap;flex-grow:1;align-items:center;column-gap:12px;display:flex;overflow:hidden}.selected-value .text{text-overflow:ellipsis;max-inline-size:100%;overflow:hidden}.control.shows-placeholder .selected-value .text{color:var(--vvd-color-neutral-600)}.selected-value slot[name=icon]{flex:0 0 var(--_select-icon-size);font-size:var(--_select-icon-size);line-height:1}.control.has-meta .selected-value{padding-inline-end:8px}.feedback-wrapper{display:contents}::part(popup-base){inline-size:max-content;min-inline-size:var(--_select-fixed-width,100%)}:host([multiple]) ::part(popup-base){position:static}@supports selector(:has(*)){:host(:focus-within) .control:not(.has-activedescendant,:has(.clear-button:focus)){--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px))}}@supports not selector(:has(*)){:host(:focus-within) .control:not(.has-activedescendant){--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px))}}:host(:not(:focus-visible)){--_suppressable-focus-shadow:none;--_suppressable-focus-outline:none;--_suppressable-focus-outline-offset:0}:host([multiple]) .clear-button{margin-inline-start:auto}:host([multiple][clearable]) .label-wrapper{min-block-size:calc(1px * (40 + 4 * clamp(-1, var(--vvd-size-density,0), 2) - 16))}";
22
+ let prosemirror_model = require("prosemirror-model");
23
+ let prosemirror_state = require("prosemirror-state");
24
+ let prosemirror_view = require("prosemirror-view");
25
+ let prosemirror_keymap = require("prosemirror-keymap");
26
+ let prosemirror_commands = require("prosemirror-commands");
27
+ let prosemirror_dropcursor = require("prosemirror-dropcursor");
28
+ let prosemirror_gapcursor = require("prosemirror-gapcursor");
29
+ let dompurify = require("dompurify");
30
+ dompurify = require_rolldown_runtime.__toESM(dompurify, 1);
31
+ let prosemirror_history = require("prosemirror-history");
32
+ let prosemirror_inputrules = require("prosemirror-inputrules");
33
+ let prosemirror_transform = require("prosemirror-transform");
34
+ let prosemirror_schema_basic = require("prosemirror-schema-basic");
35
+ //#region src/lib/rich-text-editor/rich-text-editor.scss?inline
36
+ var rich_text_editor_default = ":host{display:block}.rte{--editor-padding-inline:var(--rich-text-editor-padding-inline,16px);--editor-padding-block:var(--rich-text-editor-padding-block,8px);block-size:100%;max-block-size:inherit;min-block-size:inherit;flex-direction:column;display:flex}.rte.appearance-fieldset{background-color:var(--_appearance-color-fill);outline:1px solid var(--_appearance-color-outline);outline-offset:-1px;border-radius:8px;transition:outline-color .2s,background-color .2s}.rte.appearance-fieldset:focus-within{--focus-stroke-gap-color:transparent;box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px))}.rte.appearance-fieldset .editor-viewport{border-start-start-radius:inherit;border-start-end-radius:inherit}.rte.appearance-fieldset .editor-scroll-area{background:0 0}.rte.appearance-fieldset .toolbar{border-end-end-radius:inherit;border-end-start-radius:inherit}.editor{display:contents}.editor-viewport{contain:layout;flex-direction:column;flex:1;min-block-size:0;display:flex;position:relative;overflow:hidden}.editor-scroll-area{background-color:var(--vvd-color-canvas);color:var(--vvd-color-canvas-text);font:var(--vvd-typography-base);--scrollbar-track-color:transparent;--scrollbar-thumb-color:color-mix(in sRGB, var(--vvd-color-neutral-950), transparent 70%);scrollbar-color:var(--scrollbar-thumb-color) var(--scrollbar-track-color);scrollbar-width:thin;flex-direction:column;flex:1;min-block-size:0;display:flex;overflow-y:auto}.editor-scroll-area ::-webkit-scrollbar{width:4px}.editor-scroll-area ::-webkit-scrollbar-track{background:var(--scrollbar-track-color)}.editor-scroll-area ::-webkit-scrollbar-thumb{background-color:var(--scrollbar-fallback-track-color,var(--scrollbar-thumb-color));border:0;border-radius:4px}.popovers--disabled>*{display:none!important}";
25
37
  //#endregion
26
- //#region src/lib/select/select.ts
38
+ //#region src/lib/rich-text-editor/rich-text-editor.ts
27
39
  /**
28
40
  * @public
29
- * @component select
30
- * @slot - Default slot.
31
- * @slot icon - The preferred way to add an icon to the select control.
32
- * @slot meta - Slot to add meta content to the select control.
33
- * @slot helper-text - Describes how to use the select. Alternative to the `helper-text` attribute.
34
- * @event {CustomEvent<undefined>} input - Fires a custom 'input' event when the value updates
35
- * @event {CustomEvent<HTMLElement>} change - Fires a custom 'change' event when the value updates
36
- * @vueModel modelValue value input,@lazy:change `event.currentTarget.value`
37
- * @testAction selectOptionByValue selectOptionByValue
38
- * @testAction selectOptionByText selectOptionByText
41
+ * @component rich-text-editor
42
+ * @slot editor-before - Displayed before the scrollable editor area.
43
+ * @slot editor-start - Displayed at the start of the scrollable editor area.
44
+ * @slot editor-end - Displayed at the end of the scrollable editor area.
45
+ * @slot editor-after - Displayed after the scrollable editor area.
46
+ * @slot status - Displayed between the editor viewport and the toolbar.
47
+ * @slot text-color-picker - Color picker for the RteTextColorFeature.
48
+ * @dynamicSlot `{ url: string }` inline-image-placeholder - Placeholder content for inline images.
49
+ * @dynamicSlot `{ id: string }` suggestions-empty - Empty state if no suggestions are found.
39
50
  */
40
- var Select = class extends require_mixins.WithLightDOMFeedback(require_with_contextual_help.WithContextualHelp(require_with_error_text.WithErrorText(require_with_success_text.WithSuccessText(require_localized.Localized(require_form_element.FormElement(require_host_semantics.HostSemantics(require_affix.AffixIconWithTrailing(require_form_associated.FormAssociated(require_listbox.Listbox))))))))) {
51
+ var RichTextEditor = class extends require_delegates_aria.DelegatesAria(require_localized.WithObservableLocale(require_vivid_element.VividElement)) {
41
52
  constructor(..._args) {
42
53
  super(..._args);
43
- this.proxy = document.createElement("select");
44
- this.activeIndex = -1;
45
- this.rangeStartIndex = -1;
46
- this.open = false;
47
- this.listboxId = (0, _microsoft_fast_web_utilities.uniqueId)("listbox-");
48
- this.maxHeight = 0;
49
- this.fixedDropdown = false;
50
- this._feedbackWrapper = null;
51
- this._isResetting = false;
52
- this.clearable = false;
53
- this._isClearButtonFocused = false;
54
+ this._disabled = false;
54
55
  }
55
- /**
56
- * Returns the last checked option.
57
- *
58
- * @internal
59
- */
60
- get activeOption() {
61
- return this.options[this.activeIndex];
56
+ /** @internal */
57
+ instanceChanged(prevInstance) {
58
+ prevInstance?.[require_slottable_request.impl].destroyViewIfNeeded();
59
+ if (prevInstance) prevInstance[require_slottable_request.impl].onDisabledChanged = null;
60
+ this._disabled = false;
61
+ this._initViewIfNeeded();
62
+ prevInstance?.[require_slottable_request.impl].styles.removeStylesFrom(this.shadowRoot);
63
+ this.instance?.[require_slottable_request.impl].styles.addStylesTo(this.shadowRoot);
62
64
  }
63
- /**
64
- * Returns the list of checked options.
65
- *
66
- * @internal
67
- */
68
- get checkedOptions() {
69
- return this.options.filter((o) => o.checked);
65
+ _initViewIfNeeded() {
66
+ const instance = this.instance?.[require_slottable_request.impl];
67
+ if (instance && this.$fastController.isConnected && !instance.view) {
68
+ this._syncStateIfNeeded();
69
+ instance.onDisabledChanged = (disabled) => {
70
+ this._disabled = disabled;
71
+ };
72
+ instance.createView(this._editableEl);
73
+ }
70
74
  }
71
- /**
72
- * Returns the index of the first selected option.
73
- *
74
- * @internal
75
- */
76
- get firstSelectedOptionIndex() {
77
- return this.options.indexOf(this.firstSelectedOption);
75
+ _destroyViewIfNeeded() {
76
+ this.instance?.[require_slottable_request.impl].destroyViewIfNeeded();
78
77
  }
79
- /**
80
- * Updates the `ariaActiveDescendant` property when the active index changes.
81
- *
82
- * @internal
83
- */
84
- activeIndexChanged(_, next) {
85
- this._activeDescendant = this.options[next]?.id ?? "";
86
- this.focusAndScrollOptionIntoView();
78
+ connectedCallback() {
79
+ super.connectedCallback();
80
+ this._initViewIfNeeded();
87
81
  }
88
- /**
89
- * Toggles the checked state for the currently active option.
90
- *
91
- * @remarks
92
- * Multiple-selection mode only.
93
- *
94
- * @internal
95
- */
96
- checkActiveIndex() {
97
- const activeItem = this.activeOption;
98
- /* v8 ignore else -- @preserve */
99
- if (activeItem) activeItem.checked = true;
82
+ disconnectedCallback() {
83
+ super.disconnectedCallback();
84
+ this._destroyViewIfNeeded();
85
+ if (this.instance) this.instance[require_slottable_request.impl].onDisabledChanged = null;
100
86
  }
101
- /**
102
- * Sets the active index to the first option and marks it as checked.
103
- *
104
- * @remarks
105
- * Multi-selection mode only.
106
- *
107
- * @param preserveChecked - mark all options unchecked before changing the active index
108
- *
109
- * @internal
110
- */
111
- checkFirstOption(preserveChecked) {
112
- const firstSelectableIndex = this.getNextSelectableIndex(0);
113
- if (firstSelectableIndex === -1) return;
114
- if (preserveChecked) {
115
- if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
116
- this.options.forEach((o, i) => {
117
- o.checked = (0, _microsoft_fast_web_utilities.inRange)(i, firstSelectableIndex, this.rangeStartIndex + 1) && !o.disabled;
118
- });
119
- } else this.uncheckAllOptions();
120
- this.activeIndex = firstSelectableIndex;
121
- this.checkActiveIndex();
87
+ /** @internal */
88
+ localeChanged() {
89
+ this._syncStateIfNeeded();
122
90
  }
123
- /**
124
- * Decrements the active index and sets the matching option as checked.
125
- *
126
- * @remarks
127
- * Multi-selection mode only.
128
- *
129
- * @param preserveChecked - mark all options unchecked before changing the active index
130
- *
131
- * @internal
132
- */
133
- checkLastOption(preserveChecked) {
134
- const lastSelectableIndex = this.getPreviousSelectableIndex(this.length - 1);
135
- if (lastSelectableIndex === -1) return;
136
- if (preserveChecked) {
137
- if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
138
- this.options.forEach((o, i) => {
139
- o.checked = (0, _microsoft_fast_web_utilities.inRange)(i, this.rangeStartIndex, lastSelectableIndex + 1) && !o.disabled;
140
- });
141
- } else this.uncheckAllOptions();
142
- this.activeIndex = lastSelectableIndex;
143
- this.checkActiveIndex();
91
+ _syncStateIfNeeded() {
92
+ this.instance?.[require_slottable_request.impl].updateHostState({
93
+ locale: this.locale,
94
+ ctx: this._ctx
95
+ });
144
96
  }
145
- /**
146
- * Increments the active index and marks the matching option as checked.
147
- *
148
- * @remarks
149
- * Multiple-selection mode only.
150
- *
151
- * @param preserveChecked - mark all options unchecked before changing the active index
152
- *
153
- * @internal
154
- */
155
- checkNextOption(preserveChecked) {
156
- const nextIndex = this.getNextSelectableIndex(this.activeIndex + 1);
157
- if (nextIndex === -1) return;
158
- if (preserveChecked) {
159
- if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
160
- this.options.forEach((o, i) => {
161
- o.checked = (0, _microsoft_fast_web_utilities.inRange)(i, this.rangeStartIndex, nextIndex + 1) && !o.disabled;
162
- });
163
- } else this.uncheckAllOptions();
164
- this.activeIndex = nextIndex;
165
- this.checkActiveIndex();
97
+ /** @internal */
98
+ focus(options) {
99
+ const view = this.instance?.[require_slottable_request.impl].view;
100
+ if (view && view.editable) {
101
+ this._editableEl.focus(options);
102
+ view.focus();
103
+ } else super.focus(options);
166
104
  }
167
- /**
168
- * Decrements the active index and marks the matching option as checked.
169
- *
170
- * @remarks
171
- * Multiple-selection mode only.
172
- *
173
- * @param preserveChecked - mark all options unchecked before changing the active index
174
- *
175
- * @internal
176
- */
177
- checkPreviousOption(preserveChecked) {
178
- const previousIndex = this.getPreviousSelectableIndex(this.activeIndex - 1);
179
- if (previousIndex === -1) return;
180
- if (preserveChecked) {
181
- if (this.rangeStartIndex === -1) this.rangeStartIndex = this.activeIndex;
182
- if (this.checkedOptions.length === 1) this.rangeStartIndex += 1;
183
- this.options.forEach((o, i) => {
184
- o.checked = (0, _microsoft_fast_web_utilities.inRange)(i, previousIndex, this.rangeStartIndex + 1) && !o.disabled;
185
- });
186
- } else this.uncheckAllOptions();
187
- this.activeIndex = previousIndex;
188
- this.checkActiveIndex();
105
+ };
106
+ require_decorate.__decorate([_microsoft_fast_element.observable], RichTextEditor.prototype, "instance", void 0);
107
+ require_decorate.__decorate([_microsoft_fast_element.attr], RichTextEditor.prototype, "appearance", void 0);
108
+ require_decorate.__decorate([_microsoft_fast_element.attr], RichTextEditor.prototype, "state", void 0);
109
+ require_decorate.__decorate([_microsoft_fast_element.observable], RichTextEditor.prototype, "_disabled", void 0);
110
+ //#endregion
111
+ //#region src/lib/rich-text-editor/rich-text-editor.template.ts
112
+ var RichTextEditorTemplate = (ctx) => {
113
+ return _microsoft_fast_element.html`<template :_ctx="${() => ctx}">
114
+ <div
115
+ class="${(x) => (0, _microsoft_fast_web_utilities.classNames)("rte", `connotation-accent`, "with-idle", "with-hover", "with-disabled", "with-error", "with-success", ["disabled", x._disabled], [`appearance-${x.appearance}`, Boolean(x.appearance)], ["error", x.state === "error"], ["success", x.state === "success"])}"
116
+ >
117
+ <slot name="editor-before"></slot>
118
+ <div
119
+ class="editor-viewport"
120
+ part="editor-viewport"
121
+ ${(0, _microsoft_fast_element.ref)("editorViewportElement")}
122
+ >
123
+ <div class="editor-scroll-area" part="editor-scrollable-area">
124
+ <slot name="editor-start"></slot>
125
+ <div class="editor rich-text">
126
+ <div part="editor" ${require_delegates_aria.delegateAria()} ${(0, _microsoft_fast_element.ref)("_editableEl")}></div>
127
+ </div>
128
+ <div class="popovers"></div>
129
+ <slot name="editor-end"></slot>
130
+ </div>
131
+ </div>
132
+ <slot name="editor-after"></slot>
133
+ <slot name="status"></slot>
134
+ <div class="toolbar"></div>
135
+ </div>
136
+ </template>`;
137
+ };
138
+ //#endregion
139
+ //#region src/lib/rich-text-editor/popover.ts
140
+ var Kind = {
141
+ default: {
142
+ placement: void 0,
143
+ placementStrategy: require_definition$2.PlacementStrategy.AutoPlacementHorizontal,
144
+ shiftCrossAxis: false,
145
+ strategy: "fixed"
146
+ },
147
+ autocomplete: {
148
+ placement: "bottom-start",
149
+ placementStrategy: require_definition$2.PlacementStrategy.Flip,
150
+ shiftCrossAxis: false,
151
+ strategy: "fixed"
152
+ },
153
+ imageOptions: {
154
+ placement: "bottom",
155
+ placementStrategy: require_definition$2.PlacementStrategy.Flip,
156
+ shiftCrossAxis: true,
157
+ strategy: "absolute"
189
158
  }
190
- /** @internal */
191
- focusAndScrollOptionIntoView() {
192
- super.focusAndScrollOptionIntoView(this.activeOption);
159
+ };
160
+ var popoverTemplate = (context) => {
161
+ const popup = context.tagFor(require_definition$2.Popup);
162
+ return _microsoft_fast_element.html`<${popup}
163
+ :anchor="${(x) => x.anchorEl}"
164
+ :placement="${(x) => Kind[x.kind].placement}"
165
+ :placementStrategy="${(x) => Kind[x.kind].placementStrategy}"
166
+ :shiftCrossAxis="${(x) => Kind[x.kind].shiftCrossAxis}"
167
+ :open="${(x) => x.open}"
168
+ :offset="${(x) => x.offset}"
169
+ :strategy="${(x) => Kind[x.kind].strategy}"
170
+ exportparts="vvd-theme-alternate"
171
+ >
172
+ <slot></slot>
173
+ </${popup}>`;
174
+ };
175
+ var Popover = class extends require_vivid_element.VividElement {
176
+ constructor(..._args) {
177
+ super(..._args);
178
+ this.kind = "default";
179
+ this.anchorBlocksPopover = false;
180
+ this.onAnchorBlockPopoverChanged = () => {
181
+ this.anchorBlocksPopover = this.anchorEl?.dataset.blockPopover === "true" || false;
182
+ };
183
+ this.requestedOpenState = false;
193
184
  }
194
- /**
195
- * In multiple-selection mode:
196
- * If any options are selected, the first selected option is checked when
197
- * the listbox receives focus. If no options are selected, the first
198
- * selectable option is checked.
199
- *
200
- * @internal
201
- */
202
- focusinHandler(e) {
203
- if (!this.multiple) {
204
- super.focusinHandler(e);
205
- return;
206
- }
207
- /* v8 ignore else -- @preserve */
208
- if (!this.shouldSkipFocus && e.target === e.currentTarget) {
209
- this.uncheckAllOptions();
210
- if (this.activeIndex === -1) this.activeIndex = this.firstSelectedOptionIndex !== -1 ? this.firstSelectedOptionIndex : 0;
211
- this.checkActiveIndex();
212
- this.setSelectedOptions();
213
- this.focusAndScrollOptionIntoView();
214
- }
215
- this.shouldSkipFocus = false;
185
+ static setBlockPopover(onElement, block) {
186
+ onElement.dataset.blockPopover = block ? "true" : "false";
187
+ const event = new CustomEvent("block-popover-changed", {
188
+ bubbles: false,
189
+ composed: false
190
+ });
191
+ onElement.dispatchEvent(event);
192
+ }
193
+ /** Closes the popover. It reopens when anchorEl changes to a new element that does not block it. */
194
+ dismiss() {
195
+ this.anchorBlocksPopover = true;
196
+ }
197
+ anchorElChanged(prev, next) {
198
+ prev?.removeEventListener("block-popover-changed", this.onAnchorBlockPopoverChanged);
199
+ next?.addEventListener("block-popover-changed", this.onAnchorBlockPopoverChanged);
200
+ this.onAnchorBlockPopoverChanged();
201
+ }
202
+ anchorIdChanged() {
203
+ this.updateAnchor();
204
+ }
205
+ updateAnchor() {
206
+ if (this.anchorId && this.isConnected) this.anchorEl = this.getRootNode().getElementById(this.anchorId) || void 0;
207
+ else this.anchorEl = void 0;
208
+ }
209
+ requestOpenState(open) {
210
+ this.requestedOpenState = open;
211
+ }
212
+ get open() {
213
+ return this.requestedOpenState && !!this.anchorEl && !this.anchorBlocksPopover;
214
+ }
215
+ #observer;
216
+ connectedCallback() {
217
+ super.connectedCallback();
218
+ this.updateAnchor();
219
+ this.#observer = new MutationObserver((records) => {
220
+ if (records.some((r) => Array.from(r.addedNodes).some((n) => n instanceof HTMLElement && n.id === this.anchorId))) this.updateAnchor();
221
+ });
222
+ this.#observer.observe(this.getRootNode(), {
223
+ childList: true,
224
+ subtree: true
225
+ });
226
+ }
227
+ disconnectedCallback() {
228
+ super.disconnectedCallback();
229
+ this.#observer.disconnect();
230
+ }
231
+ };
232
+ require_decorate.__decorate([_microsoft_fast_element.observable], Popover.prototype, "kind", void 0);
233
+ require_decorate.__decorate([_microsoft_fast_element.observable], Popover.prototype, "offset", void 0);
234
+ require_decorate.__decorate([_microsoft_fast_element.observable], Popover.prototype, "anchorBlocksPopover", void 0);
235
+ require_decorate.__decorate([_microsoft_fast_element.observable], Popover.prototype, "anchorEl", void 0);
236
+ require_decorate.__decorate([_microsoft_fast_element.observable], Popover.prototype, "anchorId", void 0);
237
+ require_decorate.__decorate([_microsoft_fast_element.observable], Popover.prototype, "requestedOpenState", void 0);
238
+ require_decorate.__decorate([_microsoft_fast_element.volatile], Popover.prototype, "open", null);
239
+ var popoverDefinition = require_vivid_element.defineVividComponent("rich-text-editor-popover", Popover, popoverTemplate, [require_definition$2.popupDefinition], {});
240
+ //#endregion
241
+ //#region ../../node_modules/.pnpm/prosemirror-view@1.41.8/node_modules/prosemirror-view/style/prosemirror.css?inline
242
+ var prosemirror_default = ".ProseMirror{word-wrap:break-word;white-space:pre-wrap;white-space:break-spaces;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-feature-settings:\"liga\" 0;position:relative}.ProseMirror pre{white-space:pre-wrap}.ProseMirror li{position:relative}.ProseMirror-hideselection ::selection{background:0 0}.ProseMirror-hideselection ::selection{background:0 0}.ProseMirror-hideselection{caret-color:#0000}.ProseMirror [draggable][contenteditable=false]{user-select:text}.ProseMirror-selectednode{outline:2px solid #8cf}li.ProseMirror-selectednode{outline:none}li.ProseMirror-selectednode:after{content:\"\";pointer-events:none;border:2px solid #8cf;position:absolute;inset:-2px -2px -2px -32px}img.ProseMirror-separator{border:none!important;margin:0!important;display:inline!important}";
243
+ //#endregion
244
+ //#region src/lib/rich-text-editor/rte/utils/default-textblock.ts
245
+ function defaultTextblockForMatch(match) {
246
+ for (let i = 0; i < match.edgeCount; i++) {
247
+ const { type } = match.edge(i);
248
+ /* v8 ignore if -- @preserve It's currently not possible to exercise this code in our RTE */
249
+ if (type.isTextblock && !type.hasRequiredAttrs()) return type;
250
+ }
251
+ }
252
+ //#endregion
253
+ //#region src/lib/rich-text-editor/rte/utils/ui.style.scss?inline
254
+ var ui_style_default = "[data-class=ui-select]{min-inline-size:120px;margin-block:-4px}.ui-divider{block-size:20px}.ui-button-group{gap:4px;display:flex}.ui-tooltip,.ui-menu{--_popup-display:contents;display:contents}.ui-tooltip-wrapper{display:contents}";
255
+ //#endregion
256
+ //#region src/lib/rich-text-editor/rte/utils/feature-state.ts
257
+ var FeatureState = class {
258
+ constructor(initialValue) {
259
+ this.plugin = new prosemirror_state.Plugin({ state: {
260
+ init: () => initialValue,
261
+ apply: (tr, value) => {
262
+ const meta = tr.getMeta(this.plugin);
263
+ return meta !== void 0 ? meta : value;
264
+ }
265
+ } });
266
+ }
267
+ getValue(rte) {
268
+ return this.plugin.getState(rte.state);
269
+ }
270
+ setValue(rte, newValue) {
271
+ rte.dispatchTransaction(rte.tr.setMeta(this.plugin, newValue));
272
+ }
273
+ };
274
+ //#endregion
275
+ //#region src/lib/rich-text-editor/rte/features/internal/core.style.scss?inline
276
+ var core_style_default = ".ProseMirror{box-sizing:border-box;padding:var(--editor-padding-block) var(--editor-padding-inline);outline:none;flex:1 0 0}.ProseMirror-selectednode{--focus-stroke-gap-color:transparent;--focus-border-radius:2px;outline:none;position:relative}.ProseMirror-selectednode:after{box-shadow:0 0 0 4px color-mix(in sRGB, var(--focus-stroke-color,var(--vvd-color-cta-500)), transparent 85%), inset 0 0 0 3px var(--focus-stroke-gap-color,currentColor);outline:1px solid var(--focus-stroke-color,var(--vvd-color-cta-500));outline-offset:calc(-1px - var(--focus-inset,0px));border-radius:var(--focus-border-radius,inherit);block-size:calc(100% + var(--focus-block-size-addition,4px));content:\"\";inline-size:calc(100% + var(--focus-block-size-addition,4px));display:block;position:absolute;inset-block-start:50%;inset-inline-start:50%;transform:translate(-50%,-50%)}.editor--disabled .ProseMirror{color:var(--_appearance-color-text,var(--vvd-color-neutral-300));cursor:not-allowed}";
277
+ //#endregion
278
+ //#region src/lib/rich-text-editor/rte/features/internal/foreign-html.ts
279
+ var RteForeignHtmlFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
280
+ constructor(..._args) {
281
+ super(..._args);
282
+ this.name = "RteForeignHtmlFeature";
216
283
  }
217
- /** Sets an option as selected and gives it focus. */
218
- setSelectedOptions() {
219
- if (!this.multiple) {
220
- super.setSelectedOptions();
221
- return;
284
+ getPlugins(rte) {
285
+ return [this.contribution(new prosemirror_state.Plugin({ props: {
286
+ transformPastedHTML: (html) => rte.foreignHtmlParser[require_slottable_request.impl].transform(html),
287
+ clipboardParser: rte.foreignHtmlParser[require_slottable_request.impl].parser,
288
+ clipboardSerializer: rte.foreignHtmlSerializer[require_slottable_request.impl].serializer
289
+ } }))];
290
+ }
291
+ };
292
+ //#endregion
293
+ //#region src/lib/rich-text-editor/rte/features/internal/cursor-fix.ts
294
+ /**
295
+ * When the cursor is positioned after an inline atom node at the end of a line,
296
+ * browsers may display the cursor inside the atom.
297
+ */
298
+ var atomCursorFix = ($cursor) => {
299
+ if (!($cursor.parentOffset === $cursor.parent.content.size)) return null;
300
+ const nodeBefore = $cursor.nodeBefore;
301
+ if (nodeBefore && nodeBefore.isInline && nodeBefore.isAtom && !nodeBefore.isText) return {};
302
+ return null;
303
+ };
304
+ /**
305
+ * When the cursor is positioned directly before an inline atom node (e.g. an image)
306
+ * that wraps to the next line, browsers may display the cursor on the next line even
307
+ * though typing inserts text on the previous line. A ZWSP between cursor and atom will be
308
+ * layouted to the previous line and therefore fix the cursor position.
309
+ */
310
+ var beforeAtomCursorFix = ($cursor) => {
311
+ const nodeAfter = $cursor.nodeAfter;
312
+ if (nodeAfter && nodeAfter.isInline && nodeAfter.isAtom && !nodeAfter.isText) return { afterCursor: true };
313
+ return null;
314
+ };
315
+ function createZwspWidget(style) {
316
+ const span = document.createElement("span");
317
+ span.textContent = "​";
318
+ for (const [prop, value] of Object.entries(style)) span.style.setProperty(prop, value);
319
+ return span;
320
+ }
321
+ var RteCursorFixFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
322
+ constructor(..._args) {
323
+ super(..._args);
324
+ this.name = "RteCursorFix";
325
+ }
326
+ getPlugins(rte) {
327
+ const cursorFixes = [atomCursorFix, beforeAtomCursorFix];
328
+ for (const markType of Object.values(rte.schema.marks)) {
329
+ const spec = markType.spec;
330
+ if (spec.cursorFix) cursorFixes.push(spec.cursorFix);
222
331
  }
223
- /* v8 ignore else -- @preserve */
224
- if (this.$fastController.isConnected && this.options) {
225
- this.selectedOptions = this.options.filter((o) => o.selected);
226
- this.focusAndScrollOptionIntoView();
332
+ return [this.contribution(new prosemirror_state.Plugin({ props: { decorations: (state) => {
333
+ const { $cursor } = state.selection;
334
+ if (!$cursor) return null;
335
+ const decorations = [];
336
+ const cursorFixStyles = {};
337
+ let before = false;
338
+ let after = false;
339
+ for (const fn of cursorFixes) {
340
+ const result = fn($cursor, state);
341
+ if (!result) continue;
342
+ if (result.style) Object.assign(cursorFixStyles, result.style);
343
+ if (result.afterCursor) after = true;
344
+ else before = true;
345
+ }
346
+ if (before) decorations.push(prosemirror_view.Decoration.widget($cursor.pos, () => createZwspWidget(cursorFixStyles), { side: -1 }));
347
+ if (after) decorations.push(prosemirror_view.Decoration.widget($cursor.pos, () => createZwspWidget(cursorFixStyles), { side: 1 }));
348
+ if (decorations.length === 0) return null;
349
+ return prosemirror_view.DecorationSet.create(state.doc, decorations);
350
+ } } }))];
351
+ }
352
+ };
353
+ require_slottable_request.featureFacade(RteCursorFixFeatureImpl);
354
+ //#endregion
355
+ //#region src/lib/rich-text-editor/rte/features/internal/core.ts
356
+ /** Plugin to bring state from the host web component into ProseMirror. */
357
+ var hostBridgePlugin = new prosemirror_state.Plugin({ state: {
358
+ init() {
359
+ return null;
360
+ },
361
+ apply(tr, value) {
362
+ const meta = tr.getMeta(hostBridgePlugin);
363
+ if (meta) return meta;
364
+ else return value;
365
+ }
366
+ } });
367
+ var RteCoreImpl = class extends require_slottable_request.RteFeatureImpl {
368
+ constructor(..._args) {
369
+ super(..._args);
370
+ this.name = "RteCore";
371
+ this.disabled = new FeatureState(false);
372
+ this.scrollThreshold = void 0;
373
+ this.scrollMargin = void 0;
374
+ }
375
+ getStyles() {
376
+ return [
377
+ this.contribution(prosemirror_default),
378
+ this.contribution(core_style_default),
379
+ this.contribution(ui_style_default)
380
+ ];
381
+ }
382
+ getPlugins(rte) {
383
+ const splitFn = (0, prosemirror_commands.splitBlockAs)((node, atEnd, $from) => {
384
+ if (!atEnd) return {
385
+ type: node.type,
386
+ attrs: node.attrs
387
+ };
388
+ const defaultTextblock = defaultTextblockForMatch($from.node($from.depth - 1).contentMatchAt($from.indexAfter($from.depth - 1)));
389
+ if (!defaultTextblock) return null;
390
+ return {
391
+ type: defaultTextblock,
392
+ attrs: rte.textblockAttrs.extractFromNode(node)
393
+ };
394
+ });
395
+ const splitFnKeepMarks = (state, dispatch) => splitFn(state, dispatch && ((tr) => {
396
+ const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks();
397
+ if (marks) tr.ensureMarks(marks);
398
+ dispatch(tr);
399
+ }));
400
+ const enterKeyChainCommands = (0, prosemirror_commands.chainCommands)(prosemirror_commands.newlineInCode, prosemirror_commands.createParagraphNear, prosemirror_commands.liftEmptyBlock, splitFnKeepMarks);
401
+ return [
402
+ this.contribution(this.disabled.plugin),
403
+ this.contribution(new prosemirror_state.Plugin({
404
+ props: {
405
+ editable: () => !this.disabled.getValue(rte),
406
+ handleDOMEvents: { click: (_view, event) => {
407
+ if (this.disabled.getValue(rte)) {
408
+ event.preventDefault();
409
+ return true;
410
+ }
411
+ return false;
412
+ } }
413
+ },
414
+ view: (view) => {
415
+ const popovers = view.dom.getRootNode().querySelector(".popovers");
416
+ const updateDisabled = () => {
417
+ const disabled = this.disabled.getValue(rte);
418
+ popovers.classList.toggle("popovers--disabled", disabled);
419
+ view.dom.parentElement.classList.toggle("editor--disabled", disabled);
420
+ rte.onDisabledChanged?.(disabled);
421
+ };
422
+ updateDisabled();
423
+ return { update: () => {
424
+ updateDisabled();
425
+ } };
426
+ }
427
+ })),
428
+ this.contribution((0, prosemirror_keymap.keymap)({
429
+ ...prosemirror_commands.baseKeymap,
430
+ Enter: enterKeyChainCommands,
431
+ "Shift-Enter": enterKeyChainCommands
432
+ })),
433
+ this.contribution((0, prosemirror_dropcursor.dropCursor)()),
434
+ this.contribution((0, prosemirror_gapcursor.gapCursor)()),
435
+ this.contribution(hostBridgePlugin)
436
+ ];
437
+ }
438
+ getFeatures() {
439
+ return [
440
+ this,
441
+ new RteForeignHtmlFeatureImpl(),
442
+ new RteCursorFixFeatureImpl()
443
+ ];
444
+ }
445
+ };
446
+ require_slottable_request.featureFacade(RteCoreImpl);
447
+ //#endregion
448
+ //#region src/lib/rich-text-editor/rte/utils/sanitization.ts
449
+ var DEFAULT_ALLOWED_URI_REGEXP = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
450
+ var ALLOWED_URI_REGEXP_WITH_BLOB = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|blob):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i;
451
+ var ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
452
+ var domPurifyConfig = { ALLOWED_URI_REGEXP: ALLOWED_URI_REGEXP_WITH_BLOB };
453
+ /**
454
+ * Sanitize potentially dangerous URLs, like "javascript:", in anchor href attributes.
455
+ * Returns empty string if the URL is unsafe.
456
+ */
457
+ var sanitizeLinkHref = (url) => {
458
+ if (!DEFAULT_ALLOWED_URI_REGEXP.test(url.replace(ATTR_WHITESPACE, ""))) return "";
459
+ const anchor = document.createElement("a");
460
+ anchor.setAttribute("href", url);
461
+ /* v8 ignore next -- since href is already validated it's probably always present @preserve */
462
+ return dompurify.default.sanitize(anchor, {
463
+ RETURN_DOM: true,
464
+ ...domPurifyConfig
465
+ }).querySelector("a").getAttribute("href") ?? "";
466
+ };
467
+ /**
468
+ * Sanitize potentially dangerous URLs, like "javascript:", in image src attributes.
469
+ * Returns empty string if the URL is unsafe.
470
+ */
471
+ var sanitizeImageSrc = (url) => {
472
+ const img = document.createElement("img");
473
+ img.setAttribute("src", url);
474
+ return dompurify.default.sanitize(img, {
475
+ RETURN_DOM: true,
476
+ ...domPurifyConfig
477
+ }).querySelector("img").getAttribute("src") ?? "";
478
+ };
479
+ /**
480
+ * Escapes a CSS value for insertion into style attribute.
481
+ * E.g. "15px; background: red" => "15px"
482
+ */
483
+ var escapeCssProperty = (value) => value.replace(/[;!].*/, "");
484
+ //#endregion
485
+ //#region src/lib/rich-text-editor/rte/html-parser.ts
486
+ var copy = (obj) => ({ ...obj });
487
+ var parseRulesFromSchema = (schema) => ({
488
+ nodes: Object.fromEntries(Object.keys(schema.nodes).map((name) => [name, (schema.nodes[name].spec.parseDOM ?? []).map(copy)])),
489
+ marks: Object.fromEntries(Object.keys(schema.marks).map((name) => [name, (schema.marks[name].spec.parseDOM ?? []).map(copy)]))
490
+ });
491
+ var RteHtmlParser = class {
492
+ constructor(config, options) {
493
+ this[require_slottable_request.impl] = new RteHtmlParserImpl(config[require_slottable_request.impl], options);
494
+ }
495
+ /** Converts an HTML string to an RteDocument. */
496
+ parseDocument(html, options) {
497
+ return this[require_slottable_request.impl].parser.parse(this.parseHtml(html, options), { preserveWhitespace: true }).toJSON();
498
+ }
499
+ /** Converts an HTML string to an RteFragment. */
500
+ parseFragment(html, options) {
501
+ return this[require_slottable_request.impl].parser.parseSlice(this.parseHtml(html, options), { preserveWhitespace: true }).content.toJSON() ?? [];
502
+ }
503
+ parseHtml(html, options) {
504
+ const dom = dompurify.default.sanitize(html, {
505
+ RETURN_DOM: true,
506
+ ...domPurifyConfig
507
+ });
508
+ const container = document.createDocumentFragment();
509
+ container.appendChild(dom);
510
+ options?.modifyDom?.(container);
511
+ return container;
512
+ }
513
+ };
514
+ var RteHtmlParserImpl = class {
515
+ constructor(config, options) {
516
+ const rules = parseRulesFromSchema(config.schema);
517
+ options?.modifyParseRules?.(rules);
518
+ this.parser = buildDomParser(config.schema, rules);
519
+ }
520
+ /** Used by the editor when foreign HTML is pasted or dropped */
521
+ transform(html) {
522
+ return dompurify.default.sanitize(html);
523
+ }
524
+ };
525
+ var buildDomParser = (schema, { marks, nodes }) => {
526
+ const parserRules = [];
527
+ const priority = (rule) => rule.priority ?? 50;
528
+ function insert(rule) {
529
+ let i = 0;
530
+ for (; i < parserRules.length; i++) {
531
+ const next = parserRules[i];
532
+ if (priority(next) < priority(rule)) break;
227
533
  }
534
+ parserRules.splice(i, 0, rule);
228
535
  }
229
- /**
230
- * Toggles the selected state of the provided options. If any provided items
231
- * are in an unselected state, all items are set to selected. If every
232
- * provided item is selected, they are all unselected.
233
- *
234
- * @internal
235
- */
236
- toggleSelectedForAllCheckedOptions() {
237
- const enabledCheckedOptions = this.checkedOptions.filter((o) => !o.disabled);
238
- const force = !enabledCheckedOptions.every((o) => o.selected);
239
- enabledCheckedOptions.forEach((o) => o.selected = force);
240
- this.selectedIndex = this.options.indexOf(enabledCheckedOptions[enabledCheckedOptions.length - 1]);
241
- this.setSelectedOptions();
242
- this.updateValue(true);
536
+ for (const name in marks) marks[name]?.forEach((rule) => {
537
+ insert(rule = copy(rule));
538
+ if (!(rule.mark || rule.ignore || rule.clearMark)) rule.mark = name;
539
+ });
540
+ for (const name in nodes) nodes[name]?.forEach((rule) => {
541
+ insert(rule = copy(rule));
542
+ if (!(rule.node || rule.ignore || rule.mark)) rule.node = name;
543
+ });
544
+ parserRules.push({
545
+ tag: "br",
546
+ closeParent: true
547
+ });
548
+ return new prosemirror_model.DOMParser(schema, parserRules);
549
+ };
550
+ //#endregion
551
+ //#region src/lib/rich-text-editor/rte/html-serializer.ts
552
+ var RteHtmlSerializer = class {
553
+ constructor(config, options) {
554
+ this[require_slottable_request.impl] = new RteHtmlSerializerImpl(config[require_slottable_request.impl], options);
243
555
  }
244
- /** @internal */
245
- typeaheadBufferChanged(prev, next) {
246
- if (!this.multiple) {
247
- super.typeaheadBufferChanged(prev, next);
248
- return;
556
+ /** Converts an RteDocument to an HTML string. */
557
+ serializeDocument(doc, options) {
558
+ return this[require_slottable_request.impl].serializeFragment(doc.content, options);
559
+ }
560
+ /** Converts an RteFragment to an HTML string. */
561
+ serializeFragment(fragment, options) {
562
+ return this[require_slottable_request.impl].serializeFragment(fragment, options);
563
+ }
564
+ };
565
+ var RteHtmlSerializerImpl = class RteHtmlSerializerImpl {
566
+ constructor(config, options) {
567
+ this.config = config;
568
+ const serializers = RteHtmlSerializerImpl.domSerializersFromSchema(config.schema);
569
+ Object.assign(serializers.nodes, options?.serializers?.nodes ?? {});
570
+ Object.assign(serializers.marks, options?.serializers?.marks ?? {});
571
+ this.serializer = new prosemirror_model.DOMSerializer(serializers.nodes, serializers.marks);
572
+ }
573
+ static domSerializersFromSchema(schema) {
574
+ const result = {
575
+ nodes: {},
576
+ marks: {}
577
+ };
578
+ for (const name in schema.marks) {
579
+ const toDOM = schema.marks[name].spec.toDOM;
580
+ if (toDOM) result.marks[name] = toDOM;
249
581
  }
250
- /* v8 ignore if -- @preserve */
251
- if (this.$fastController.isConnected) {
252
- const typeaheadMatches = this.getTypeaheadMatches();
253
- const activeIndex = this.options.indexOf(typeaheadMatches[0]);
254
- if (activeIndex > -1) {
255
- this.activeIndex = activeIndex;
256
- this.uncheckAllOptions();
257
- this.checkActiveIndex();
258
- }
259
- this.typeaheadExpired = false;
582
+ for (const name in schema.nodes) {
583
+ const toDOM = schema.nodes[name].spec.serializeToDOM ?? schema.nodes[name].spec.toDOM;
584
+ if (toDOM) result.nodes[name] = toDOM;
260
585
  }
586
+ result.nodes.text = (node) => document.createTextNode(node.text);
587
+ return result;
261
588
  }
262
- /**
263
- * Unchecks all options.
264
- *
265
- * @remarks
266
- * Multiple-selection mode only.
267
- *
268
- * @param preserveChecked - reset the rangeStartIndex
269
- *
270
- * @internal
271
- */
272
- uncheckAllOptions(preserveChecked = false) {
273
- this.options.forEach((o) => o.checked = false);
274
- /* v8 ignore else -- @preserve */
275
- if (!preserveChecked) this.rangeStartIndex = -1;
589
+ serializeFragment(fragment, options) {
590
+ const parsedFragment = prosemirror_model.Fragment.fromJSON(this.config.schema, fragment);
591
+ const serializedFragment = this.serializer.serializeFragment(parsedFragment);
592
+ const container = document.createDocumentFragment();
593
+ container.appendChild(serializedFragment);
594
+ options?.modifyDom?.(container);
595
+ const output = document.createElement("div");
596
+ output.appendChild(container);
597
+ return output.innerHTML;
276
598
  }
277
- /**
278
- * Sets focus when the open property changes.
279
- *
280
- * @internal
281
- */
282
- openChanged(prev, next) {
283
- if (!this.collapsible) return;
284
- if (this.open) {
285
- this.focusAndScrollOptionIntoView();
286
- this.indexWhenOpened = this.selectedIndex;
287
- _microsoft_fast_element.Updates.enqueue(() => this.focus());
288
- return;
289
- }
290
- const didClose = prev && !next;
291
- const selectionChangedWhileOpen = this.indexWhenOpened !== this.selectedIndex;
292
- if (didClose && selectionChangedWhileOpen) this.updateValue(true);
599
+ };
600
+ //#endregion
601
+ //#region src/lib/rich-text-editor/rte/instance.ts
602
+ var parseDocument = (schema, doc) => {
603
+ const node = schema.topNodeType.createAndFill(null, doc ? prosemirror_model.Fragment.fromJSON(schema, doc.content) : null);
604
+ if (!node) throw new Error("Document could not be parsed");
605
+ node.check();
606
+ return node;
607
+ };
608
+ var RteInstance = class {
609
+ constructor(config, options) {
610
+ this.options = options;
611
+ this.feature = (Feature, featureId) => {
612
+ return this[require_slottable_request.impl].getPublicInterface(Feature, featureId);
613
+ };
614
+ this[require_slottable_request.impl] = new RteInstanceImpl(this, config, options);
293
615
  }
294
- /**
295
- * The component is collapsible when in single-selection mode.
296
- *
297
- * @internal
298
- */
299
- get collapsible() {
300
- return !this.multiple;
616
+ /** Returns the current document state. */
617
+ getDocument() {
618
+ return this[require_slottable_request.impl].state.doc.toJSON();
301
619
  }
302
- /** @internal */
303
- valueChanged(prev, next) {
304
- const nextSelectedIndex = this.options.findIndex((el) => el.value === next);
305
- const validNextSelectedIndex = this._validSelectedIndex(nextSelectedIndex);
306
- const nextValue = this.options[validNextSelectedIndex]?.value ?? "";
307
- if (this.selectedIndex !== validNextSelectedIndex) this.selectedIndex = validNextSelectedIndex;
308
- if (next !== nextValue) return;
309
- super.valueChanged(prev, next);
310
- this.updateDisplayValue();
620
+ /** Reset the editor to its initial state. Optionally, an initial document can be provided. */
621
+ reset(initialDocument) {
622
+ this[require_slottable_request.impl].reset(initialDocument);
311
623
  }
312
624
  /**
313
- * Sets the value and display value to match the first selected option.
314
- *
315
- * @param shouldEmit - if true, the input and change events will be emitted
316
- *
317
- * @internal
625
+ * Replaces the current selection with the given content.
626
+ * If no text is selected, this inserts the content at the cursor position.
318
627
  */
319
- updateValue(shouldEmit) {
320
- if (this.$fastController.isConnected) this.value = this.firstSelectedOption?.value ?? "";
321
- if (shouldEmit) {
322
- this.$emit("input");
323
- this.$emit("change", this, {
324
- bubbles: true,
325
- composed: void 0
326
- });
327
- }
628
+ replaceSelection(content, options) {
629
+ const { state, tr, schema, dispatchTransaction } = this[require_slottable_request.impl];
630
+ tr.replaceSelection(new prosemirror_model.Slice(prosemirror_model.Fragment.fromJSON(schema, content), 0, 0));
631
+ tr.doc.check();
632
+ const $from = tr.doc.resolve(tr.mapping.map(state.selection.from));
633
+ const $to = tr.doc.resolve(tr.selection.to);
634
+ const [$head, $anchor] = options?.cursorPlacement === "start" ? [$from, $to] : [$to, $from];
635
+ if (options?.selectContent) tr.setSelection(state.selection instanceof prosemirror_state.AllSelection ? new prosemirror_state.AllSelection(tr.doc) : prosemirror_state.TextSelection.between($anchor, $head));
636
+ else tr.setSelection(prosemirror_state.TextSelection.between($head, $head));
637
+ dispatchTransaction(tr);
328
638
  }
329
639
  /**
330
- * Updates the proxy value when the selected index changes.
331
- *
332
- * @param prev - the previous selected index
333
- * @param next - the next selected index
334
- *
335
- * @internal
640
+ * Replaces the entire document with the given new document.
641
+ * Unlike reset, this preserves the rest of the editor state. The undo history is preserved, so the user can undo the replacement.
336
642
  */
337
- selectedIndexChanged(prev, next) {
338
- super.selectedIndexChanged(prev, next);
339
- this.updateValue();
643
+ replaceDocument(newDocument, options) {
644
+ const { state, tr, schema, dispatchTransaction } = this[require_slottable_request.impl];
645
+ tr.replaceWith(0, state.doc.content.size, parseDocument(schema, newDocument));
646
+ if (options?.selectContent) tr.setSelection(new prosemirror_state.AllSelection(tr.doc));
647
+ else if (options?.cursorPlacement === "end") tr.setSelection(prosemirror_state.TextSelection.atEnd(tr.doc));
648
+ else tr.setSelection(prosemirror_state.TextSelection.atStart(tr.doc));
649
+ dispatchTransaction(tr);
340
650
  }
341
651
  /**
342
- * Handle opening and closing the listbox when the select is clicked.
343
- *
344
- * @param e - the mouse event
345
- * @internal
652
+ * Scrolls the cursor into view.
653
+ * Has no effect if the editor is not currently mounted.
346
654
  */
347
- clickHandler(e) {
348
- if (this.disabled || this._isFromContextualHelp(e)) return;
349
- const clickedOption = e.target.closest(`option,[role=option],[data-vvd-component=option]`);
350
- if (clickedOption && clickedOption.disabled) return;
351
- if (this.multiple) {
352
- this.uncheckAllOptions();
353
- this.activeIndex = this.options.indexOf(clickedOption);
354
- this.checkActiveIndex();
355
- this.toggleSelectedForAllCheckedOptions();
356
- } else super.clickHandler(e);
357
- if (this.collapsible) this.open = !this.open;
358
- return true;
655
+ scrollIntoView() {
656
+ const instance = this[require_slottable_request.impl];
657
+ if (!instance.view) return;
658
+ instance.dispatchTransaction(instance.tr.scrollIntoView());
359
659
  }
360
- /**
361
- * Handles focus state when the element or its children lose focus.
362
- *
363
- * @param e - The focus event
364
- * @internal
365
- */
366
- focusoutHandler(e) {
367
- if (this.multiple) this.uncheckAllOptions();
368
- if (!this.open) return true;
369
- const focusTarget = e.relatedTarget;
370
- if (this.isSameNode(focusTarget)) {
371
- this.focus();
372
- return;
373
- }
374
- /* v8 ignore else -- @preserve */
375
- if (!this.options.includes(focusTarget)) {
376
- this.open = false;
377
- if (this.indexWhenOpened !== this.selectedIndex) this.updateValue(true);
378
- }
660
+ };
661
+ var RteInstanceImpl = class {
662
+ getFeature(name) {
663
+ const f = this.config.featureMap.get(name);
664
+ if (!f) throw new Error(`Feature not found: ${name}`);
665
+ return f;
379
666
  }
380
- /**
381
- * Updates the value when an option's value changes.
382
- *
383
- * @param source - the source object
384
- * @param propertyName - the property to evaluate
385
- *
386
- * @internal
387
- */
388
- handleChange(source, propertyName) {
389
- super.handleChange(source, propertyName);
390
- if (propertyName === "value") this.updateValue();
667
+ getPublicInterface(Feature, featureId) {
668
+ const instances = this.config.featureFacadesMap.get(Feature);
669
+ if (!instances || instances.length === 0) throw new Error(`Feature not found`);
670
+ if (instances[0].featureId !== void 0) {
671
+ if (featureId === void 0) throw new Error(`No featureId provided for multi-instance feature.`);
672
+ const instance = instances.find((f) => f.featureId === featureId);
673
+ if (!instance) throw new Error(`Feature with id "${featureId}" not found`);
674
+ return instance.getPublicInterface(this);
675
+ }
676
+ if (featureId !== void 0) throw new Error(`Feature does not support featureId`);
677
+ return instances[0].getPublicInterface(this);
391
678
  }
392
- /**
393
- * Prevents focus when a scrollbar is clicked.
394
- *
395
- * @param e - the mouse event object
396
- *
397
- * @internal
398
- */
399
- mousedownHandler(e) {
400
- if (e.offsetX >= 0 && e.offsetX <= this.listbox.scrollWidth) return super.mousedownHandler(e);
401
- return this.collapsible;
679
+ constructor(instanceFacade, configFacade, options) {
680
+ this.options = options;
681
+ this.view = null;
682
+ this.onDisabledChanged = null;
683
+ this.dispatchTransaction = (tr) => {
684
+ const prevState = this.state;
685
+ this.state = this.state.apply(tr);
686
+ this.view?.updateState(this.state);
687
+ if (prevState.doc !== this.state.doc) this.options?.onChange?.();
688
+ return this.state;
689
+ };
690
+ this.facade = instanceFacade;
691
+ const config = configFacade[require_slottable_request.impl];
692
+ this.config = config;
693
+ this.schema = config.schema;
694
+ this.textblockAttrs = config.textblockAttrs;
695
+ this.features = config.features;
696
+ this.foreignHtmlParser = options?.foreignHtmlParser ?? new RteHtmlParser(configFacade);
697
+ this.foreignHtmlSerializer = options?.foreignHtmlSerializer ?? new RteHtmlSerializer(configFacade);
698
+ this.styles = new _microsoft_fast_element.ElementStyles(require_slottable_request.sortedContributions(config.features.flatMap((f) => f.getStyles())));
699
+ this.initState(options?.initialDocument);
402
700
  }
403
- /** @internal */
404
- multipleChanged(_, next) {
405
- this.options.forEach((o) => {
406
- o.checked = next ? false : void 0;
701
+ initState(initialDoc) {
702
+ this.state = prosemirror_state.EditorState.create({
703
+ doc: parseDocument(this.schema, initialDoc),
704
+ schema: this.config.schema,
705
+ plugins: require_slottable_request.sortedContributions(this.config.features.flatMap((feature) => feature.getPlugins(this)))
407
706
  });
408
- this.setSelectedOptions();
409
- /* v8 ignore if -- @preserve */
410
- if (this.proxy) this.proxy.multiple = next;
411
707
  }
412
- /**
413
- * Updates the selectedness of each option when the list of selected options changes.
414
- *
415
- * @param prev - the previous list of selected options
416
- * @param next - the current list of selected options
417
- *
418
- * @internal
419
- */
420
- selectedOptionsChanged(prev, next) {
421
- super.selectedOptionsChanged(prev, next);
422
- this.options.forEach((o, i) => {
423
- const proxyOption = this.proxy.options.item(i);
424
- if (proxyOption) proxyOption.selected = o.selected;
708
+ reset(initialDocument) {
709
+ const currentHostState = hostBridgePlugin.getState(this.state);
710
+ this.initState(initialDocument);
711
+ this.updateHostState(currentHostState);
712
+ this.view?.updateState(this.state);
713
+ }
714
+ createView(mountTarget) {
715
+ const core = this.config.featureMap.get("RteCore");
716
+ this.view = new prosemirror_view.EditorView({ mount: mountTarget }, {
717
+ state: this.state,
718
+ dispatchTransaction: this.dispatchTransaction,
719
+ ...core?.scrollThreshold !== void 0 && { scrollThreshold: core.scrollThreshold },
720
+ ...core?.scrollMargin !== void 0 && { scrollMargin: core.scrollMargin }
425
721
  });
426
722
  }
427
- /**
428
- * Resets and fills the proxy to match the component's options.
429
- *
430
- * @internal
431
- */
432
- setProxyOptions() {
433
- /* v8 ignore else -- @preserve */
434
- if (this.proxy instanceof HTMLSelectElement && this.options) {
435
- this.proxy.length = 0;
436
- this.options.forEach((option) => {
437
- const proxyOption = option.proxy || (option instanceof HTMLOptionElement ? option.cloneNode() : null);
438
- if (proxyOption) this.proxy.options.add(proxyOption);
439
- });
723
+ destroyViewIfNeeded() {
724
+ if (this.view) {
725
+ this.view.destroy();
726
+ this.view = null;
440
727
  }
441
728
  }
442
- /**
443
- * Handles keydown actions when the select is in multiple selection mode.
444
- *
445
- * @internal
446
- */
447
- multipleKeydownHandler(e) {
448
- if (this.disabled) return;
449
- const { key, shiftKey } = e;
450
- this.shouldSkipFocus = false;
451
- switch (key) {
452
- case _microsoft_fast_web_utilities.keyHome:
453
- this.checkFirstOption(shiftKey);
454
- return;
455
- case _microsoft_fast_web_utilities.keyArrowDown:
456
- this.checkNextOption(shiftKey);
457
- return;
458
- case _microsoft_fast_web_utilities.keyArrowUp:
459
- this.checkPreviousOption(shiftKey);
460
- return;
461
- case _microsoft_fast_web_utilities.keyEnd:
462
- this.checkLastOption(shiftKey);
463
- return;
464
- case _microsoft_fast_web_utilities.keyTab:
465
- this.focusAndScrollOptionIntoView();
466
- return;
467
- case _microsoft_fast_web_utilities.keyEscape:
468
- this.uncheckAllOptions();
469
- this.checkActiveIndex();
470
- return;
471
- case _microsoft_fast_web_utilities.keySpace:
472
- e.preventDefault();
473
- /* v8 ignore else -- @preserve */
474
- if (this.typeaheadExpired) {
475
- this.toggleSelectedForAllCheckedOptions();
476
- return;
477
- }
478
- default:
479
- /* v8 ignore else -- @preserve */
480
- if (key.length === 1) this.handleTypeAhead(key);
481
- return;
482
- }
729
+ createComponent(type) {
730
+ return document.createElement(this.hostState().ctx.tagFor(type, true));
483
731
  }
484
- /**
485
- * Handle keyboard interaction for the select.
486
- *
487
- * @param e - the keyboard event
488
- * @internal
489
- */
490
- keydownHandler(e) {
491
- const selectedIndexBefore = this.selectedIndex;
492
- if (this.multiple) this.multipleKeydownHandler(e);
493
- else super.keydownHandler(e);
494
- switch (e.key) {
495
- case _microsoft_fast_web_utilities.keySpace:
496
- e.preventDefault();
497
- if (this.collapsible && this.typeaheadExpired) this.open = !this.open;
498
- break;
499
- case _microsoft_fast_web_utilities.keyHome:
500
- case _microsoft_fast_web_utilities.keyEnd:
501
- e.preventDefault();
502
- break;
503
- case _microsoft_fast_web_utilities.keyEnter:
504
- e.preventDefault();
505
- this.open = !this.open;
506
- break;
507
- case _microsoft_fast_web_utilities.keyEscape:
508
- if (this.collapsible && this.open) {
509
- e.preventDefault();
510
- this.open = false;
511
- }
512
- break;
513
- case _microsoft_fast_web_utilities.keyTab:
514
- if (this.collapsible && this.open) {
515
- e.preventDefault();
516
- this.open = false;
517
- }
518
- return true;
519
- }
520
- if (this.collapsible && !this.open && this.selectedIndex !== selectedIndexBefore) this.updateValue(true);
521
- return !(e.key === _microsoft_fast_web_utilities.keyArrowDown || e.key === _microsoft_fast_web_utilities.keyArrowUp);
732
+ getLocale() {
733
+ return this.hostState().locale;
522
734
  }
523
- connectedCallback() {
524
- super.connectedCallback();
525
- this.addEventListener("focusout", this.focusoutHandler);
526
- this.addEventListener("contentchange", this.updateDisplayValue);
735
+ get tr() {
736
+ return this.state.tr;
527
737
  }
528
- disconnectedCallback() {
529
- this.removeEventListener("focusout", this.focusoutHandler);
530
- this.removeEventListener("contentchange", this.updateDisplayValue);
531
- super.disconnectedCallback();
738
+ hostState() {
739
+ const state = hostBridgePlugin.getState(this.state);
740
+ if (!state) throw new Error("No host state available");
741
+ return state;
532
742
  }
533
- /** @internal */
534
- updateDisplayValue() {
535
- if (this.collapsible) _microsoft_fast_element.Observable.notify(this, "displayValue");
536
- }
537
- get displayValue() {
538
- _microsoft_fast_element.Observable.track(this, "displayValue");
539
- return this.firstSelectedOption?.getAttribute("label") ?? this.firstSelectedOption?.text ?? this.placeholder ?? "";
540
- }
541
- _newDefaultSelectedIndex(prev, next, currentSelectIndex) {
542
- const defaultSelectedIndex = super._newDefaultSelectedIndex(prev, next, currentSelectIndex);
543
- if (defaultSelectedIndex === null && currentSelectIndex === -1 && !this.placeholder) {
544
- const firstSelectableIndex = this.getNextSelectableIndex(0);
545
- if (firstSelectableIndex !== -1) return firstSelectableIndex;
546
- }
547
- return defaultSelectedIndex;
743
+ updateHostState(hostState) {
744
+ this.dispatchTransaction(this.tr.setMeta(hostBridgePlugin, hostState));
548
745
  }
549
- _isDefaultSelected(option) {
550
- return super._isDefaultSelected(option) || option.value === this.initialValue || !this._isResetting && option.value === this.value;
746
+ };
747
+ //#endregion
748
+ //#region src/lib/rich-text-editor/rte/utils/textblock-attrs.ts
749
+ var TextblockAttrs = class {
750
+ constructor(specs) {
751
+ this.specs = specs;
752
+ this.attrs = {};
753
+ for (const spec of specs) this.attrs[spec.name] = { default: spec.default };
551
754
  }
552
- slottedOptionsChanged(prev, next) {
553
- this.options.forEach((o) => {
554
- _microsoft_fast_element.Observable.getNotifier(o).unsubscribe(this, "value");
555
- });
556
- super.slottedOptionsChanged(prev, next);
557
- this.options.forEach((o) => {
558
- _microsoft_fast_element.Observable.getNotifier(o).subscribe(this, "value");
559
- });
560
- this.setProxyOptions();
561
- this.updateValue();
562
- const scale = this.getAttribute("scale") || this.scale;
563
- next.forEach((element) => {
564
- if (scale) {
565
- element.setAttribute("scale", scale);
566
- element.scale = scale;
567
- }
568
- });
569
- this.proxy.value = this.value;
570
- this.validate();
755
+ fromDOM(dom) {
756
+ return Object.assign({}, ...this.specs.map((s) => ({ [s.name]: s.fromDOM(dom) })));
571
757
  }
572
- formResetCallback() {
573
- this.setProxyOptions();
574
- this._isResetting = true;
575
- this.selectedIndex = this._newDefaultSelectedIndex([], this.options, -1) ?? -1;
576
- this._isResetting = false;
758
+ getStyle(node) {
759
+ return this.specs.flatMap((s) => s.toStyles(node)).join("; ");
577
760
  }
578
- /** @internal */
579
- get _shouldShowClearButton() {
580
- if (!this.clearable) return false;
581
- if (this.multiple) return this.selectedOptions?.length > 0;
582
- return this.value !== "";
761
+ getDOMAttrsProperties(node) {
762
+ if (!this.specs.length) return {};
763
+ return { style: this.getStyle(node) };
583
764
  }
584
- /** @internal */
585
- _onClearButtonFocus() {
586
- this._isClearButtonFocused = true;
587
- this.activeIndex = -1;
588
- this.uncheckAllOptions();
765
+ getDOMAttrs(node) {
766
+ if (!this.specs.length) return [];
767
+ return [this.getDOMAttrsProperties(node)];
589
768
  }
590
- /** @internal */
591
- _onClearButtonBlur() {
592
- this._isClearButtonFocused = false;
769
+ extractFromNode(node) {
770
+ return Object.assign({}, ...Object.keys(this.attrs).map((attr) => ({ [attr]: node.attrs[attr] })));
593
771
  }
594
- /** @internal */
595
- get _shouldShowLabelWrapper() {
596
- return Boolean(this.label || this._hasContextualHelp || this.multiple && this._shouldShowClearButton);
772
+ };
773
+ //#endregion
774
+ //#region src/lib/rich-text-editor/rte/utils/textblock-marks.ts
775
+ var TextblockMarks = class {
776
+ constructor(specs) {
777
+ this.specs = specs;
597
778
  }
598
- /** @internal */
599
- _onClearButtonClick() {
600
- if (this.multiple) this.selectedOptions.forEach((o) => {
601
- /* v8 ignore else -- @preserve */
602
- if (!o.disabled) o.selected = false;
603
- });
604
- else this.selectedIndex = -1;
605
- this.updateValue(true);
606
- }
607
- };
608
- require_decorate.__decorate([_microsoft_fast_element.observable], Select.prototype, "activeIndex", void 0);
609
- require_decorate.__decorate([(0, _microsoft_fast_element.attr)({ mode: "boolean" })], Select.prototype, "multiple", void 0);
610
- require_decorate.__decorate([(0, _microsoft_fast_element.attr)({
611
- attribute: "open",
612
- mode: "boolean"
613
- })], Select.prototype, "open", void 0);
614
- require_decorate.__decorate([_microsoft_fast_element.volatile], Select.prototype, "collapsible", null);
615
- require_decorate.__decorate([_microsoft_fast_element.observable], Select.prototype, "control", void 0);
616
- require_decorate.__decorate([_microsoft_fast_element.observable], Select.prototype, "maxHeight", void 0);
617
- require_decorate.__decorate([_microsoft_fast_element.observable], Select.prototype, "_anchor", void 0);
618
- require_decorate.__decorate([(0, _microsoft_fast_element.attr)()], Select.prototype, "scale", void 0);
619
- require_decorate.__decorate([_microsoft_fast_element.attr], Select.prototype, "appearance", void 0);
620
- require_decorate.__decorate([_microsoft_fast_element.attr], Select.prototype, "shape", void 0);
621
- require_decorate.__decorate([(0, _microsoft_fast_element.attr)({
622
- mode: "boolean",
623
- attribute: "fixed-dropdown"
624
- })], Select.prototype, "fixedDropdown", void 0);
625
- require_decorate.__decorate([_microsoft_fast_element.attr], Select.prototype, "placeholder", void 0);
626
- require_decorate.__decorate([_microsoft_fast_element.observable], Select.prototype, "_feedbackWrapper", void 0);
627
- require_decorate.__decorate([_microsoft_fast_element.observable], Select.prototype, "metaSlottedContent", void 0);
628
- require_decorate.__decorate([(0, _microsoft_fast_element.attr)({ mode: "boolean" })], Select.prototype, "clearable", void 0);
629
- require_decorate.__decorate([_microsoft_fast_element.observable], Select.prototype, "_isClearButtonFocused", void 0);
630
- //#endregion
631
- //#region src/lib/select/select.template.ts
632
- function renderLabel() {
633
- return _microsoft_fast_element.html` <label
634
- for="${(x) => x.multiple ? null : "control"}"
635
- class="label"
636
- id="label"
637
- >
638
- ${(x) => x.label}
639
- </label>`;
640
- }
641
- function renderPlaceholder(context) {
642
- const optionTag = context.tagFor(require_option.ListboxOption);
643
- return _microsoft_fast_element.html`
644
- <${optionTag} text="${(x) => x.placeholder}" hidden disabled>
645
- </${optionTag}>`;
646
- }
647
- function renderClearButton(context) {
648
- const buttonTag = context.tagFor(require_definition$1.Button);
649
- return _microsoft_fast_element.html`
650
- <${buttonTag}
651
- aria-label="${(x) => x.locale.select.clearButtonLabel}"
652
- aria-hidden="${(x) => x._isClearButtonFocused ? "false" : "true"}"
653
- @click="${(x, c) => {
654
- x._onClearButtonClick();
655
- c.event.stopPropagation();
656
- }}"
657
- @mousedown="${() => false}"
658
- @keydown="${(x, c) => {
659
- /* v8 ignore next -- @preserve */
660
- if (c.event.key === "Tab") x._onClearButtonBlur();
661
- c.event.stopPropagation();
779
+ getAllowedMarksForNode(nodeName) {
780
+ return this.specs.filter((spec) => !spec.onNodeName || spec.onNodeName === nodeName).map((spec) => spec.markName);
781
+ }
782
+ getReferencedNodeNames() {
783
+ return new Set(this.specs.map((spec) => spec.onNodeName).filter(Boolean));
784
+ }
785
+ };
786
+ //#endregion
787
+ //#region src/lib/rich-text-editor/rte/view.ts
788
+ /**
789
+ * Converts an RteDocument to an RteView tree for rendering outside the editor.
790
+ * The logic is adapted from ProseMirror's DOM serialization to ensure the resulting structure
791
+ * matches the editor's HTML structure.
792
+ */
793
+ var convertToView = (doc, ctx) => {
794
+ const schema = ctx.config[require_slottable_request.impl].schema;
795
+ const getMarkRank = (mark) => schema.marks[mark.type].rank;
796
+ const marksEqual = (a, b) => {
797
+ if (a.type !== b.type) return false;
798
+ const attrsA = a.attrs;
799
+ const attrsB = b.attrs;
800
+ if (attrsA === attrsB) return true;
801
+ /* v8 ignore next -- not currently reachable since all attrs are required @preserve */
802
+ if (!attrsA || !attrsB) return false;
803
+ const keysA = Object.keys(attrsA);
804
+ const keysB = Object.keys(attrsB);
805
+ /* v8 ignore next -- not currently reachable since all attrs are required @preserve */
806
+ if (keysA.length !== keysB.length) return false;
807
+ for (const key of keysA) if (attrsA[key] !== attrsB[key]) return false;
662
808
  return true;
663
- }}"
664
- @focusin="${(x, c) => {
665
- c.event.stopPropagation();
666
- x._onClearButtonFocus();
667
- }}"
668
- @focusout="${(x) => x._onClearButtonBlur()}"
669
- ?disabled="${(x) => x.disabled}"
670
- :shape="${(x) => x.shape}"
671
- size="super-condensed"
672
- icon="close-line"
673
- appearance="ghost-light"
674
- class="clear-button"
675
- tabindex="0"
676
- ></${buttonTag}>
677
- `;
678
- }
679
- function selectValue(context) {
680
- const affixIconTemplate = require_affix.affixIconTemplateFactory(context);
681
- const chevronTemplate = require_definition$1.chevronTemplateFactory(context);
682
- return _microsoft_fast_element.html` <div
683
- class="control ${(x) => (0, _microsoft_fast_web_utilities.classNames)(["has-activedescendant", Boolean(x._activeDescendant) && x.open], ["disabled", x.disabled], [`appearance-${x.appearance}`, Boolean(x.appearance)], [`shape-${x.shape}`, Boolean(x.shape)], ["has-meta", Boolean(x.metaSlottedContent?.length)], ["error", Boolean(x.errorValidationMessage)], ["success", !!x.successText], ["shows-placeholder", Boolean(x.placeholder) && !x.value], [`size-${x.scale}`, Boolean(x.scale)])}"
684
- ${(0, _microsoft_fast_element.ref)("_anchor")}
685
- id="control"
686
- ?disabled="${(x) => x.disabled}"
687
- >
688
- <div class="selected-value">
689
- ${(x) => affixIconTemplate(x.icon, require_affix.IconWrapper.Slot)}
690
- <span class="text">${(x) => x.displayValue}</span>
691
- <slot name="meta" ${(0, _microsoft_fast_element.slotted)("metaSlottedContent")}></slot>
692
- </div>
693
- ${(0, _microsoft_fast_element.when)((x) => x._shouldShowClearButton, renderClearButton(context))}
694
- ${chevronTemplate}
695
- </div>`;
696
- }
697
- function setFixedDropdownVarWidth(x) {
698
- return x.open && x.fixedDropdown ? `--_select-fixed-width: ${Math.round(x.getBoundingClientRect().width)}px` : null;
699
- }
700
- /** @param context - element definition context */
701
- function renderControl(context) {
702
- const popupTag = context.tagFor(require_definition$2.Popup);
703
- return _microsoft_fast_element.html`
704
- <div class="label-wrapper" ?hidden=${(x) => !x._shouldShowLabelWrapper}>
705
- ${(0, _microsoft_fast_element.when)((x) => x.label, renderLabel())}
706
- ${(0, _microsoft_fast_element.when)((x) => x.multiple && x._shouldShowClearButton, renderClearButton(context))}
707
- <slot name="contextual-help" ${(0, _microsoft_fast_element.slotted)("_contextualHelpSlottedContent")}></slot>
708
- </div>
709
- <div class="control-wrapper">
710
- ${(0, _microsoft_fast_element.when)((x) => !x.multiple, selectValue(context))}
711
- <${popupTag} class="popup"
712
- style="${setFixedDropdownVarWidth}"
713
- ?open="${(x) => x.collapsible ? x.open : true}"
714
- :anchor="${(x) => x._anchor}"
715
- placement="bottom-start"
716
- strategy="${(x) => x.fixedDropdown ? null : "absolute"}">
717
- <div class="listbox"
718
- id="${(x) => x.listboxId}"
719
- role="listbox"
720
- aria-multiselectable="${(x) => x.multiple}"
721
- aria-label="${(x) => x.multiple && !x.label && x.ariaLabel ? x.ariaLabel : null}"
722
- aria-labelledby="${(x) => x.multiple && x.label ? "label" : null}"
723
- ?disabled="${(x) => x.disabled}"
724
- ?hidden="${(x) => x.collapsible ? !x.open : false}"
725
- ${(0, _microsoft_fast_element.ref)("listbox")}>
726
- ${(0, _microsoft_fast_element.when)((x) => x.placeholder, renderPlaceholder(context))}
727
- <slot
728
- ${(0, _microsoft_fast_element.slotted)({
729
- filter: require_listbox.Listbox.slottedOptionFilter,
730
- flatten: true,
731
- property: "slottedOptions"
732
- })}>
733
- </slot>
734
- </div>
735
- </${popupTag}>
736
- </div>
737
- `;
738
- }
739
- /** Ignore events that originate from feedback, e.g. a click on link */
740
- function ifNotFromFeedback(handler) {
741
- return (x, c) => {
742
- if (!c.event.composedPath().includes(x._feedbackWrapper)) {
743
- handler(x, c.event);
744
- return;
809
+ };
810
+ const convertFragment = (nodes) => {
811
+ const result = [];
812
+ const active = [];
813
+ const activeContents = [result];
814
+ for (const node of nodes) {
815
+ const nodeMarks = [...node.marks ?? []].sort((a, b) => getMarkRank(a) - getMarkRank(b));
816
+ let keep = 0;
817
+ let rendered = 0;
818
+ while (keep < active.length && rendered < nodeMarks.length) {
819
+ if (!marksEqual(active[keep], nodeMarks[rendered])) break;
820
+ keep++;
821
+ rendered++;
822
+ }
823
+ while (active.length > keep) {
824
+ active.pop();
825
+ activeContents.pop();
826
+ }
827
+ while (rendered < nodeMarks.length) {
828
+ const mark = nodeMarks[rendered];
829
+ const markContent = [];
830
+ activeContents[activeContents.length - 1].push({
831
+ type: "mark",
832
+ mark,
833
+ children: {
834
+ type: "fragment",
835
+ content: markContent,
836
+ [require_slottable_request.impl]: ctx
837
+ },
838
+ [require_slottable_request.impl]: ctx
839
+ });
840
+ active.push(mark);
841
+ activeContents.push(markContent);
842
+ rendered++;
843
+ }
844
+ activeContents[activeContents.length - 1].push({
845
+ type: "node",
846
+ node,
847
+ children: convertFragment(node.content ?? []),
848
+ [require_slottable_request.impl]: ctx
849
+ });
745
850
  }
746
- return true;
851
+ return {
852
+ type: "fragment",
853
+ content: result,
854
+ [require_slottable_request.impl]: ctx
855
+ };
856
+ };
857
+ return {
858
+ type: "node",
859
+ node: doc,
860
+ children: convertFragment(doc.content),
861
+ [require_slottable_request.impl]: ctx
747
862
  };
748
- }
749
- var SelectTemplate = (context) => {
750
- return _microsoft_fast_element.html`
751
- <template
752
- ${require_host_semantics.applyHostSemantics({
753
- role: "combobox",
754
- ariaLabel: (x) => x.ariaLabel ?? x.label,
755
- ariaHasPopup: (x) => x.collapsible ? "listbox" : "false",
756
- ariaExpanded: (x) => x.open,
757
- ariaDisabled: (x) => x.disabled
758
- })}
759
- aria-controls="${(x) => x.listboxId}"
760
- aria-activedescendant="${(x) => x.open ? x._activeDescendant : null}"
761
- aria-describedby="${(x) => x._feedbackDescribedBy}"
762
- tabindex="${(x) => !x.disabled ? "0" : null}"
763
- @click="${ifNotFromFeedback((x, e) => x.clickHandler(e))}"
764
- @focusin="${ifNotFromFeedback((x, e) => x.focusinHandler(e))}"
765
- @focusout="${ifNotFromFeedback((x, e) => x.focusoutHandler(e))}"
766
- @keydown="${ifNotFromFeedback((x, e) => {
767
- if (x.open) require_dialog.handleEscapeKeyAndStopPropogation(e);
768
- return x.keydownHandler(e);
769
- })}"
770
- @mousedown="${ifNotFromFeedback((x, e) => x.mousedownHandler(e))}"
771
- >
772
- ${renderControl(context)}
773
- <div class="feedback-wrapper" ${(0, _microsoft_fast_element.ref)("_feedbackWrapper")}>
774
- ${(x) => x._getFeedbackTemplate(context)}
775
- </div>
776
- </template>
777
- `;
778
863
  };
779
864
  //#endregion
780
- //#region src/lib/select/definition.ts
781
- /** @internal */
782
- var selectDefinition = require_vivid_element.defineVividComponent("select", Select, SelectTemplate, [
783
- require_definition$2.popupDefinition,
784
- require_definition.iconDefinition,
785
- require_definition$3.listboxOptionDefinition,
786
- require_definition$4.optgroupDefinition,
787
- require_definition$1.buttonDefinition,
788
- require_mixins.feedbackMessageDefinition
789
- ], { styles: select_default });
790
- /**
791
- * Registers the select elements with the design system.
792
- *
793
- * @param prefix - the prefix to use for the component name
794
- */
795
- var registerSelect = require_vivid_element.createRegisterFunction(selectDefinition);
865
+ //#region src/lib/rich-text-editor/rte/config.ts
866
+ var RteConfig = class {
867
+ constructor(features) {
868
+ this[require_slottable_request.impl] = new RteConfigImpl(features);
869
+ }
870
+ instantiateEditor(options) {
871
+ return new RteInstance(this, options);
872
+ }
873
+ instantiateView(document, options) {
874
+ return convertToView(document, {
875
+ config: this,
876
+ options: { ...options }
877
+ });
878
+ }
879
+ };
880
+ var RteConfigImpl = class {
881
+ constructor(featuresFacades) {
882
+ const resolveFeatures = (features) => features.flatMap((f) => f.getFeatures().flatMap((subFeature) => subFeature === f ? f : resolveFeatures([subFeature])));
883
+ this.features = resolveFeatures(featuresFacades.map(require_slottable_request.getFeatureImpl));
884
+ this.featureMap = /* @__PURE__ */ new Map();
885
+ for (const f of this.features) {
886
+ if (this.featureMap.has(f.name)) throw new Error(`Duplicate feature: ${f.name}`);
887
+ this.featureMap.set(f.name, f);
888
+ }
889
+ this.featureFacadesMap = /* @__PURE__ */ new Map();
890
+ for (const facade of featuresFacades) {
891
+ const FacadeClass = facade.constructor;
892
+ const feature = require_slottable_request.getFeatureImpl(facade);
893
+ const instances = this.featureFacadesMap.get(FacadeClass);
894
+ if (instances) instances.push(feature);
895
+ else this.featureFacadesMap.set(FacadeClass, [feature]);
896
+ }
897
+ if (!this.featureMap.has("RteBase")) throw new Error("RteBase feature is required");
898
+ if (this.featureMap.has("RteLinkFeature") && !this.featureMap.has("RteToolbarFeature")) throw new Error("RteToolbarFeature is required for RteLinkFeature");
899
+ this.textblockAttrs = new TextblockAttrs(require_slottable_request.sortedContributions(this.features.flatMap((f) => f.getTextblockAttrs())));
900
+ this.textblockMarks = new TextblockMarks(require_slottable_request.sortedContributions(this.features.flatMap((f) => f.getTextblockMarks())));
901
+ const schemaContributions = require_slottable_request.sortedContributions(this.features.flatMap((f) => f.getSchema(this.textblockAttrs, this.textblockMarks)));
902
+ const schemaSpec = {
903
+ nodes: {},
904
+ marks: {}
905
+ };
906
+ for (const schema of schemaContributions) {
907
+ Object.assign(schemaSpec.nodes, schema.nodes ?? {});
908
+ Object.assign(schemaSpec.marks, schema.marks ?? {});
909
+ }
910
+ for (const referencedNodeName of this.textblockMarks.getReferencedNodeNames()) if (!(referencedNodeName in schemaSpec.nodes)) throw new Error(`Unknown node "${referencedNodeName}"`);
911
+ this.schema = new prosemirror_model.Schema(schemaSpec);
912
+ }
913
+ };
796
914
  //#endregion
797
- Object.defineProperty(exports, "Select", {
915
+ //#region src/lib/rich-text-editor/rte/utils/ui.ts
916
+ var isPropBinding = (prop) => typeof prop === "function";
917
+ var on = (event, prop, handler) => [
918
+ event,
919
+ prop,
920
+ handler
921
+ ];
922
+ var UiCtx = class {
923
+ constructor(view, rte, props) {
924
+ this.view = view;
925
+ this.rte = rte;
926
+ this.props = props;
927
+ this.bindings = [];
928
+ }
929
+ /** Evaluates a prop, returning its current value. */
930
+ evalProp(prop) {
931
+ return isPropBinding(prop) ? prop(this) : prop;
932
+ }
933
+ /** On every state change, prop is re-evaluated and passed to bindFn. */
934
+ bindProp(prop, bindFn) {
935
+ if (prop === void 0) return;
936
+ else if (isPropBinding(prop)) {
937
+ const binding = () => bindFn(prop(this));
938
+ this.bindings.push(binding);
939
+ binding();
940
+ } else bindFn(prop);
941
+ }
942
+ /** To be called on each state update to refresh all bindings. */
943
+ updateBindings() {
944
+ for (const binding of this.bindings) binding();
945
+ }
946
+ /** Whether to return focus to the editor after a toolbar action */
947
+ shouldReturnFocusToEditor() {
948
+ return this.evalProp(this.props.shouldReturnFocusToEditor);
949
+ }
950
+ /** Utility to more conveniently bind props to elements */
951
+ bindToEl(target, props = {}, events = [], children = []) {
952
+ for (const name in props) this.bindProp(props[name], (value) => {
953
+ target[name] = value;
954
+ });
955
+ for (const [name, value, bindFn] of events) if (value) target.addEventListener(name, bindFn(value));
956
+ for (const child of children) target.appendChild(child);
957
+ }
958
+ };
959
+ var createDiv = (ctx, props) => {
960
+ const div = document.createElement("div");
961
+ ctx.bindToEl(div, {
962
+ className: props.className,
963
+ slot: props.slot
964
+ }, [], props.children);
965
+ return div;
966
+ };
967
+ var createAnchor = (ctx, props) => {
968
+ const anchor = document.createElement("a");
969
+ ctx.bindToEl(anchor, {
970
+ href: props.href,
971
+ target: props.target,
972
+ rel: props.rel,
973
+ className: props.className
974
+ }, [], props.children);
975
+ return anchor;
976
+ };
977
+ var wrapperTargets = /* @__PURE__ */ new WeakMap();
978
+ var createOptionalTooltip = (ctx, props) => {
979
+ const tooltip = ctx.rte.createComponent(require_definition$6.Tooltip);
980
+ tooltip.setAttribute("exportparts", "vvd-theme-alternate");
981
+ ctx.bindToEl(tooltip, {
982
+ className: "ui-tooltip",
983
+ text: props.label,
984
+ placement: ctx.props.popupPlacement
985
+ });
986
+ ctx.bindProp(props.enabled, (enabled) => {
987
+ if (!enabled) tooltip.open = false;
988
+ tooltip.anchor = enabled ? props.anchor : void 0;
989
+ });
990
+ const wrapper = createDiv(ctx, {
991
+ className: "ui-tooltip-wrapper",
992
+ slot: props.slot,
993
+ children: [props.anchor, tooltip]
994
+ });
995
+ wrapperTargets.set(wrapper, props.anchor);
996
+ return wrapper;
997
+ };
998
+ var createButton = (ctx, props) => {
999
+ const variant = () => ctx.evalProp(props.variant) ?? "toolbar";
1000
+ const size = () => variant() === "toolbar" ? "super-condensed" : "condensed";
1001
+ const appearanceInactive = () => variant() === "popover-primary" ? "outlined" : "ghost-light";
1002
+ const appearanceActive = () => variant() === "toolbar-menu" || variant() === "popover" ? "filled" : appearanceInactive();
1003
+ const appearance = () => ctx.evalProp(props.active) ? appearanceActive() : appearanceInactive();
1004
+ const connotation = () => ctx.evalProp(props.connotation) ?? (variant() === "toolbar-menu" && ctx.evalProp(props.active) ? "cta" : void 0);
1005
+ const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
1006
+ const hasIcon = Boolean(props.icon ?? props.dynamicIcon);
1007
+ const icon = () => {
1008
+ const dynamicIcon = ctx.evalProp(props.dynamicIcon);
1009
+ if (dynamicIcon !== void 0) return `${dynamicIcon}-${ctx.evalProp(props.active) ? "solid" : "line"}`;
1010
+ return ctx.evalProp(props.icon);
1011
+ };
1012
+ const button = ctx.rte.createComponent(require_definition$1.Button);
1013
+ ctx.bindToEl(button, {
1014
+ size,
1015
+ appearance,
1016
+ disabled,
1017
+ icon,
1018
+ autofocus: props.autofocus,
1019
+ connotation,
1020
+ [hasIcon ? "ariaLabel" : "label"]: props.label,
1021
+ pressed: () => Boolean(ctx.evalProp(props.active)),
1022
+ ariaPressed: props.active !== void 0 ? () => ctx.evalProp(props.active) ? "true" : "false" : void 0
1023
+ }, [on("click", props.onClick, (onClick) => () => {
1024
+ if (!onClick() && ctx.shouldReturnFocusToEditor()) ctx.view.focus();
1025
+ })]);
1026
+ return createOptionalTooltip(ctx, {
1027
+ enabled: () => hasIcon && !ctx.evalProp(props.noTooltip) && !disabled(),
1028
+ label: props.label,
1029
+ anchor: button,
1030
+ slot: props.slot
1031
+ });
1032
+ };
1033
+ var createMenu = (ctx, props) => {
1034
+ const menu = ctx.rte.createComponent(require_definition$4.Menu);
1035
+ ctx.bindToEl(menu, {
1036
+ className: "ui-menu",
1037
+ autoDismiss: true,
1038
+ ariaLabel: props.label,
1039
+ anchor: wrapperTargets.get(props.trigger) ?? props.trigger,
1040
+ placement: ctx.props.popupPlacement,
1041
+ offset: () => ctx.evalProp(ctx.props.menuOffset) ?? null
1042
+ }, [], props.children);
1043
+ const fragment = document.createDocumentFragment();
1044
+ fragment.appendChild(props.trigger);
1045
+ fragment.appendChild(menu);
1046
+ return fragment;
1047
+ };
1048
+ var createMenuItem = (ctx, props) => {
1049
+ const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
1050
+ const item = ctx.rte.createComponent(require_definition$3.MenuItem);
1051
+ ctx.bindToEl(item, {
1052
+ text: props.text,
1053
+ checked: props.checked,
1054
+ disabled,
1055
+ controlType: "radio",
1056
+ checkedAppearance: "tick-only"
1057
+ }, [on("change", props.onSelect, (onSelect) => () => {
1058
+ if (item.checked && !item.disabled) {
1059
+ if (ctx.evalProp(props.checked) !== item.checked) {
1060
+ onSelect();
1061
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
1062
+ }
1063
+ }
1064
+ })]);
1065
+ return item;
1066
+ };
1067
+ var createButtonGroup = (ctx, props) => createDiv(ctx, {
1068
+ slot: props.slot,
1069
+ className: "ui-button-group",
1070
+ children: props.children
1071
+ });
1072
+ function markActive(state, type) {
1073
+ const { from, $from, to, empty } = state.selection;
1074
+ if (empty) return !!type.isInSet(state.storedMarks || $from.marks());
1075
+ else return state.doc.rangeHasMark(from, to, type);
1076
+ }
1077
+ var createMarkToggle = (ctx, props) => createButton(ctx, {
1078
+ label: props.label,
1079
+ dynamicIcon: props.dynamicIcon,
1080
+ active: () => markActive(ctx.view.state, props.markType),
1081
+ disabled: () => !(0, prosemirror_commands.toggleMark)(props.markType)(ctx.view.state),
1082
+ onClick: () => {
1083
+ (0, prosemirror_commands.toggleMark)(props.markType)(ctx.view.state, ctx.view.dispatch);
1084
+ }
1085
+ });
1086
+ var createOption = (ctx, props) => {
1087
+ const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled) || ctx.evalProp(props.disabled));
1088
+ const option = ctx.rte.createComponent(require_option.ListboxOption);
1089
+ ctx.bindToEl(option, {
1090
+ value: props.value,
1091
+ text: props.text,
1092
+ disabled
1093
+ });
1094
+ return option;
1095
+ };
1096
+ var createSelect = (ctx, props) => {
1097
+ const disabled = () => Boolean(ctx.evalProp(ctx.props.disabled));
1098
+ const select = ctx.rte.createComponent(require_definition$9.Select);
1099
+ select.setAttribute("data-class", "ui-select");
1100
+ ctx.bindToEl(select, {
1101
+ placeholder: " ",
1102
+ ariaLabel: props.label,
1103
+ appearance: "ghost",
1104
+ disabled
1105
+ }, [on("change", props.onSelect, (onSelect) => () => {
1106
+ const value = select.value;
1107
+ if (value) {
1108
+ onSelect(value);
1109
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
1110
+ }
1111
+ })], props.children);
1112
+ queueMicrotask(() => {
1113
+ ctx.bindProp(props.value, (value) => select.value = value);
1114
+ });
1115
+ let hideTooltip = false;
1116
+ select.addEventListener("vwc-popup:open", () => {
1117
+ hideTooltip = true;
1118
+ ctx.updateBindings();
1119
+ });
1120
+ select.addEventListener("vwc-popup:close", () => {
1121
+ hideTooltip = false;
1122
+ ctx.updateBindings();
1123
+ });
1124
+ return createOptionalTooltip(ctx, {
1125
+ enabled: () => !hideTooltip && !disabled(),
1126
+ label: props.label,
1127
+ anchor: select
1128
+ });
1129
+ };
1130
+ var createDivider = (ctx) => {
1131
+ const divider = ctx.rte.createComponent(require_divider.Divider);
1132
+ ctx.bindToEl(divider, {
1133
+ className: "ui-divider",
1134
+ orientation: "vertical"
1135
+ });
1136
+ return divider;
1137
+ };
1138
+ var createTextField = (ctx, props) => {
1139
+ const textField = ctx.rte.createComponent(require_definition$5.TextField);
1140
+ ctx.bindToEl(textField, {
1141
+ label: props.label,
1142
+ value: props.value,
1143
+ placeholder: props.placeholder,
1144
+ slot: props.slot,
1145
+ autofocus: props.autofocus,
1146
+ type: props.type,
1147
+ helperText: props.helperText
1148
+ }, [on("input", props.onInput, (onInput) => () => {
1149
+ onInput(textField.value);
1150
+ })]);
1151
+ return textField;
1152
+ };
1153
+ var createText = (ctx, props) => {
1154
+ const textNode = document.createTextNode("");
1155
+ ctx.bindToEl(textNode, { textContent: props.text });
1156
+ return textNode;
1157
+ };
1158
+ var createSingleSlot = (ctx, props) => {
1159
+ const slot = document.createElement("slot");
1160
+ slot.name = props.name;
1161
+ let currentEl = null;
1162
+ const listeners = [];
1163
+ function cleanup() {
1164
+ for (const { el, type, handler } of listeners) el.removeEventListener(type, handler);
1165
+ listeners.length = 0;
1166
+ currentEl = null;
1167
+ }
1168
+ for (const [key, prop] of Object.entries(props.assignedProps)) ctx.bindProp(prop, (value) => {
1169
+ if (currentEl) currentEl[key] = value;
1170
+ });
1171
+ function applyPropsAndEvents(el) {
1172
+ for (const [key, prop] of Object.entries(props.assignedProps)) el[key] = ctx.evalProp(prop);
1173
+ for (const [type, handler] of Object.entries(props.assignedEvents)) {
1174
+ const listener = (e) => {
1175
+ handler(e);
1176
+ if (ctx.shouldReturnFocusToEditor()) ctx.view.focus();
1177
+ };
1178
+ el.addEventListener(type, listener);
1179
+ listeners.push({
1180
+ el,
1181
+ type,
1182
+ handler: listener
1183
+ });
1184
+ }
1185
+ }
1186
+ const processSlot = () => {
1187
+ const first = slot.assignedElements({ flatten: true })[0];
1188
+ if (first === currentEl) return;
1189
+ cleanup();
1190
+ if (first) {
1191
+ currentEl = first;
1192
+ applyPropsAndEvents(first);
1193
+ }
1194
+ };
1195
+ slot.addEventListener("slotchange", processSlot);
1196
+ queueMicrotask(processSlot);
1197
+ return slot;
1198
+ };
1199
+ //#endregion
1200
+ //#region src/lib/rich-text-editor/rte/features/internal/history.ts
1201
+ var RteHistoryFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1202
+ constructor(config) {
1203
+ super();
1204
+ this.config = config;
1205
+ this.name = "RteHistoryFeature";
1206
+ }
1207
+ getPlugins() {
1208
+ return [this.contribution((0, prosemirror_history.history)()), this.contribution((0, prosemirror_keymap.keymap)({
1209
+ "Mod-z": prosemirror_history.undo,
1210
+ "Ctrl-y": prosemirror_history.redo,
1211
+ "Cmd-Z": prosemirror_history.redo
1212
+ }))];
1213
+ }
1214
+ getToolbarItems() {
1215
+ if (!this.config.showToolbarButtons) return [];
1216
+ return [this.contribution({
1217
+ section: "history",
1218
+ render: (ctx) => createButton(ctx, {
1219
+ label: (ctx) => ctx.rte.getLocale().richTextEditor.undo,
1220
+ icon: "undo-line",
1221
+ disabled: (ctx) => !(0, prosemirror_history.undo)(ctx.view.state),
1222
+ onClick: () => {
1223
+ const { state, dispatch } = ctx.view;
1224
+ (0, prosemirror_history.undo)(state, dispatch);
1225
+ }
1226
+ })
1227
+ }, 1), this.contribution({
1228
+ section: "history",
1229
+ render: (ctx) => createButton(ctx, {
1230
+ label: (ctx) => ctx.rte.getLocale().richTextEditor.redo,
1231
+ icon: "redo-line",
1232
+ disabled: (ctx) => !(0, prosemirror_history.redo)(ctx.view.state),
1233
+ onClick: () => {
1234
+ const { state, dispatch } = ctx.view;
1235
+ (0, prosemirror_history.redo)(state, dispatch);
1236
+ }
1237
+ })
1238
+ }, 2)];
1239
+ }
1240
+ };
1241
+ //#endregion
1242
+ //#region src/lib/rich-text-editor/rte/features/internal/basic-text-blocks.style.scss?inline
1243
+ var basic_text_blocks_style_default = "h1,h2,h3,p{all:unset;display:block}h1:first-child,h2:first-child,h3:first-child,p:first-child{margin-block-start:0}h1:last-child,h2:last-child,h3:last-child,p:last-child{margin-block-end:0}p{font:var(--vvd-typography-base);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:16px;line-height:20px}.heading-step-1{font:var(--vvd-typography-heading-4);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:24px 12px;line-height:28px}.heading-step-2{font:var(--vvd-typography-heading-3);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:24px 12px;line-height:36px}.heading-step-3{font:var(--vvd-typography-heading-2);font-variant-ligatures:unset;font-feature-settings:unset;margin-block:32px 16px;line-height:42px}";
1244
+ //#endregion
1245
+ //#region src/lib/rich-text-editor/rte/features/internal/basic-text-blocks.ts
1246
+ var RteBasicTextBlocksImpl = class extends require_slottable_request.RteFeatureImpl {
1247
+ constructor(enabledBlocks) {
1248
+ super();
1249
+ this.enabledBlocks = enabledBlocks;
1250
+ this.name = "RteBasicTextBlocks";
1251
+ }
1252
+ getStyles() {
1253
+ return [this.contribution(basic_text_blocks_style_default)];
1254
+ }
1255
+ getSchema(textblockAttrs, textblockMarks) {
1256
+ const nodes = {};
1257
+ if (this.enabledBlocks.paragraph) nodes["paragraph"] = {
1258
+ group: "block",
1259
+ content: "inline*",
1260
+ attrs: { ...textblockAttrs.attrs },
1261
+ parseDOM: [{
1262
+ tag: "p",
1263
+ getAttrs: (dom) => textblockAttrs.fromDOM(dom)
1264
+ }],
1265
+ marks: textblockMarks.getAllowedMarksForNode("paragraph").join(" "),
1266
+ toDOM(node) {
1267
+ return [
1268
+ "p",
1269
+ {
1270
+ part: `node--paragraph`,
1271
+ ...textblockAttrs.getDOMAttrsProperties(node)
1272
+ },
1273
+ 0
1274
+ ];
1275
+ },
1276
+ serializeToDOM(node) {
1277
+ return [
1278
+ "p",
1279
+ ...textblockAttrs.getDOMAttrs(node),
1280
+ 0
1281
+ ];
1282
+ }
1283
+ };
1284
+ let headingCount = 0;
1285
+ for (const level of [
1286
+ 3,
1287
+ 2,
1288
+ 1
1289
+ ]) {
1290
+ const nodeName = `heading${level}`;
1291
+ const tag = `h${level}`;
1292
+ if (!this.enabledBlocks[nodeName]) continue;
1293
+ headingCount++;
1294
+ const visualLevel = headingCount;
1295
+ nodes[nodeName] = {
1296
+ group: "block",
1297
+ content: "inline*",
1298
+ attrs: { ...textblockAttrs.attrs },
1299
+ parseDOM: [{
1300
+ tag,
1301
+ getAttrs: (dom) => textblockAttrs.fromDOM(dom)
1302
+ }],
1303
+ marks: textblockMarks.getAllowedMarksForNode(nodeName).join(" "),
1304
+ defining: true,
1305
+ toDOM(node) {
1306
+ return [
1307
+ tag,
1308
+ {
1309
+ class: `heading-step-${visualLevel}`,
1310
+ part: `node--${nodeName}`,
1311
+ ...textblockAttrs.getDOMAttrsProperties(node)
1312
+ },
1313
+ 0
1314
+ ];
1315
+ },
1316
+ serializeToDOM(node) {
1317
+ return [
1318
+ tag,
1319
+ ...textblockAttrs.getDOMAttrs(node),
1320
+ 0
1321
+ ];
1322
+ }
1323
+ };
1324
+ }
1325
+ return [this.contribution({ nodes })];
1326
+ }
1327
+ getPlugins(rte) {
1328
+ const keyBindings = {};
1329
+ if (this.enabledBlocks.paragraph) keyBindings["Mod-Alt-0"] = this.setBlockType(rte, "paragraph");
1330
+ for (const level of [
1331
+ 1,
1332
+ 2,
1333
+ 3
1334
+ ]) {
1335
+ const nodeName = `heading${level}`;
1336
+ if (this.enabledBlocks[nodeName]) keyBindings[`Mod-Alt-${level}`] = this.setBlockType(rte, nodeName);
1337
+ }
1338
+ return [this.contribution((0, prosemirror_keymap.keymap)(keyBindings))];
1339
+ }
1340
+ getCurrentBlockType(state) {
1341
+ const { $from, $to } = state.selection;
1342
+ const fromTopBlock = $from.depth === 0 ? state.doc.childAfter($from.pos).node : $from.node(1);
1343
+ if (fromTopBlock !== ($to.depth === 0 ? state.doc.childBefore($to.pos).node : $to.node(1))) return null;
1344
+ if (!(fromTopBlock.type.name in this.enabledBlocks)) return null;
1345
+ return fromTopBlock.type.name;
1346
+ }
1347
+ setBlockType(rte, name) {
1348
+ return (state, dispatch) => {
1349
+ const { from, to } = state.selection;
1350
+ const tr = state.tr;
1351
+ let supportedNodeFound = false;
1352
+ state.doc.nodesBetween(from, to, (node, pos) => {
1353
+ if (node.type.name in this.enabledBlocks) {
1354
+ supportedNodeFound = true;
1355
+ tr.setBlockType(pos, pos + node.nodeSize, state.schema.nodes[name], (oldNode) => rte.textblockAttrs.extractFromNode(oldNode));
1356
+ }
1357
+ return false;
1358
+ });
1359
+ if (!supportedNodeFound) return false;
1360
+ dispatch?.(tr);
1361
+ return true;
1362
+ };
1363
+ }
1364
+ };
1365
+ //#endregion
1366
+ //#region src/lib/rich-text-editor/rte/utils/text-before-cursor.ts
1367
+ /** Get the text content before the cursor position in the current text block. */
1368
+ var textBeforeCursor = ($cursor) => $cursor.parent.textBetween(0, $cursor.parentOffset, void 0, "");
1369
+ //#endregion
1370
+ //#region src/lib/rich-text-editor/rte/features/internal/input-rules.ts
1371
+ /** Aggregates all input rules from other features. */
1372
+ var RteInputRulesFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1373
+ constructor(..._args) {
1374
+ super(..._args);
1375
+ this.name = "RteInputRulesFeature";
1376
+ }
1377
+ getPlugins(rte) {
1378
+ const ruleSpecs = require_slottable_request.sortedContributions(rte.config.features.flatMap((f) => f.getInputRules(rte)));
1379
+ if (ruleSpecs.length === 0) return [];
1380
+ const plugins = [];
1381
+ const rules = ruleSpecs.map((spec) => spec.rule);
1382
+ plugins.push(this.contribution((0, prosemirror_inputrules.inputRules)({ rules })));
1383
+ plugins.push(this.contribution((0, prosemirror_keymap.keymap)({ Backspace: prosemirror_inputrules.undoInputRule }), require_slottable_request.contributionPriority.high));
1384
+ const enterHandlers = ruleSpecs.filter((spec) => spec.enterHandler).map((spec) => spec.enterHandler);
1385
+ if (enterHandlers.length > 0) plugins.push(this.contribution((0, prosemirror_keymap.keymap)({ Enter: (state, dispatch) => {
1386
+ const { $cursor } = state.selection;
1387
+ if (!$cursor) return false;
1388
+ const textBefore = textBeforeCursor($cursor);
1389
+ for (const { regex, handler } of enterHandlers) {
1390
+ const match = regex.exec(textBefore);
1391
+ if (!match) continue;
1392
+ const matchStart = $cursor.pos - $cursor.parentOffset + match.index;
1393
+ const tr = handler(state, match, matchStart, matchStart + match[0].length);
1394
+ if (tr) dispatch?.(tr);
1395
+ break;
1396
+ }
1397
+ return false;
1398
+ } }), require_slottable_request.contributionPriority.highest));
1399
+ return plugins;
1400
+ }
1401
+ };
1402
+ //#endregion
1403
+ //#region src/lib/rich-text-editor/rte/features/base.ts
1404
+ var RteBaseImpl = class extends require_slottable_request.RteFeatureImpl {
1405
+ constructor(config) {
1406
+ super();
1407
+ this.config = config;
1408
+ this.name = "RteBase";
1409
+ }
1410
+ getSchema() {
1411
+ return [this.contribution({ nodes: {
1412
+ doc: { content: this.config?.singleBlock ? "block" : "block+" },
1413
+ text: { group: "inline" }
1414
+ } })];
1415
+ }
1416
+ getFeatures() {
1417
+ return [
1418
+ this,
1419
+ new RteCoreImpl(),
1420
+ new RteHistoryFeatureImpl({ showToolbarButtons: this.config?.historyToolbarButtons ?? true }),
1421
+ new RteBasicTextBlocksImpl({
1422
+ heading1: this.config?.heading1 ?? false,
1423
+ heading2: this.config?.heading2 ?? false,
1424
+ heading3: this.config?.heading3 ?? false,
1425
+ paragraph: this.config?.paragraph ?? true
1426
+ }),
1427
+ new RteInputRulesFeatureImpl()
1428
+ ];
1429
+ }
1430
+ getPublicInterface(rte) {
1431
+ const core = rte.getFeature("RteCore");
1432
+ return {
1433
+ get disabled() {
1434
+ return core.disabled.getValue(rte);
1435
+ },
1436
+ set disabled(value) {
1437
+ core.disabled.setValue(rte, value);
1438
+ },
1439
+ get scrollThreshold() {
1440
+ return core.scrollThreshold;
1441
+ },
1442
+ set scrollThreshold(value) {
1443
+ core.scrollThreshold = value;
1444
+ rte.view?.setProps({ scrollThreshold: value });
1445
+ },
1446
+ get scrollMargin() {
1447
+ return core.scrollMargin;
1448
+ },
1449
+ set scrollMargin(value) {
1450
+ core.scrollMargin = value;
1451
+ rte.view?.setProps({ scrollMargin: value });
1452
+ }
1453
+ };
1454
+ }
1455
+ };
1456
+ var RteBase = require_slottable_request.featureFacade(RteBaseImpl);
1457
+ //#endregion
1458
+ //#region src/lib/rich-text-editor/rte/features/text-block-picker.ts
1459
+ var RteTextBlockPickerFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1460
+ constructor(config) {
1461
+ super();
1462
+ this.config = config;
1463
+ this.name = "RteTextBlockPickerFeature";
1464
+ }
1465
+ getToolbarItems(rte) {
1466
+ const blocks = rte.getFeature("RteBasicTextBlocks");
1467
+ return [this.contribution({
1468
+ section: "font",
1469
+ render: (ctx) => {
1470
+ return createSelect(ctx, {
1471
+ label: () => ctx.rte.getLocale().richTextEditor.paragraphStyles,
1472
+ value: (ctx) => blocks.getCurrentBlockType(ctx.view.state) ?? "",
1473
+ onSelect: (value) => {
1474
+ const { state, dispatch } = ctx.view;
1475
+ blocks.setBlockType(rte, value)(state, dispatch);
1476
+ },
1477
+ children: this.config.options.map((opt) => createOption(ctx, {
1478
+ text: opt.label,
1479
+ value: opt.node,
1480
+ disabled: () => !blocks.setBlockType(rte, opt.node)(ctx.view.state)
1481
+ }))
1482
+ });
1483
+ }
1484
+ }, 1)];
1485
+ }
1486
+ };
1487
+ var RteTextBlockPickerFeature = require_slottable_request.featureFacade(RteTextBlockPickerFeatureImpl);
1488
+ //#endregion
1489
+ //#region src/lib/rich-text-editor/rte/features/toolbar.style.scss?inline
1490
+ var toolbar_style_default = ".toolbar{background-color:var(--vvd-color-neutral-50);flex-wrap:wrap;align-items:center;gap:8px;padding:4px;display:flex}.toolbar--hidden{display:none}";
1491
+ //#endregion
1492
+ //#region src/lib/rich-text-editor/rte/features/toolbar.ts
1493
+ var RteToolbarFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1494
+ constructor(config) {
1495
+ super();
1496
+ this.config = config;
1497
+ this.name = "RteToolbarFeature";
1498
+ this.hidden = new FeatureState(false);
1499
+ }
1500
+ getStyles() {
1501
+ return [this.contribution(toolbar_style_default)];
1502
+ }
1503
+ getPlugins(rte) {
1504
+ const sections = [
1505
+ "history",
1506
+ "font",
1507
+ "text-style",
1508
+ "textblock",
1509
+ "insert"
1510
+ ];
1511
+ const itemsBySection = new Map(sections.map((section) => [section, []]));
1512
+ for (const toolbarItem of require_slottable_request.sortedContributions(rte.features.flatMap((f) => f.getToolbarItems(rte)))) itemsBySection.get(toolbarItem.section).push(toolbarItem);
1513
+ const core = rte.getFeature("RteCore");
1514
+ return [this.contribution(this.hidden.plugin), this.contribution(new prosemirror_state.Plugin({ view: (view) => {
1515
+ let focusCameFromEditorWithMouse = false;
1516
+ const ctx = new UiCtx(view, rte, {
1517
+ popupPlacement: this.config?.popupDirection === "outward" ? "bottom" : "top",
1518
+ menuOffset: 8,
1519
+ disabled: () => core.disabled.getValue(rte),
1520
+ shouldReturnFocusToEditor: () => focusCameFromEditorWithMouse
1521
+ });
1522
+ const toolbar = view.dom.getRootNode().querySelector(".toolbar");
1523
+ let mouseDownTime = -Infinity;
1524
+ const onMouseDown = () => {
1525
+ if (view.hasFocus()) focusCameFromEditorWithMouse = true;
1526
+ mouseDownTime = Date.now();
1527
+ };
1528
+ const onFocusIn = () => {
1529
+ if (Date.now() - mouseDownTime > 250) focusCameFromEditorWithMouse = false;
1530
+ };
1531
+ const onFocusOut = (e) => {
1532
+ if (!toolbar.contains(e.relatedTarget)) focusCameFromEditorWithMouse = false;
1533
+ };
1534
+ toolbar.addEventListener("mousedown", onMouseDown, { capture: true });
1535
+ toolbar.addEventListener("focusin", onFocusIn);
1536
+ toolbar.addEventListener("focusout", onFocusOut);
1537
+ ctx.bindProp(() => this.hidden.getValue(rte), (hidden) => {
1538
+ toolbar.classList.toggle("toolbar--hidden", hidden);
1539
+ });
1540
+ let openSection = false;
1541
+ for (const section of sections) {
1542
+ const items = itemsBySection.get(section);
1543
+ if (items.length && openSection) {
1544
+ toolbar.appendChild(createDivider(ctx));
1545
+ openSection = false;
1546
+ }
1547
+ for (const toolbarItemSpec of items) {
1548
+ toolbar.appendChild(toolbarItemSpec.render(ctx));
1549
+ openSection = true;
1550
+ }
1551
+ }
1552
+ return {
1553
+ update() {
1554
+ ctx.updateBindings();
1555
+ },
1556
+ destroy() {
1557
+ toolbar.innerHTML = "";
1558
+ toolbar.removeEventListener("mousedown", onMouseDown, { capture: true });
1559
+ toolbar.removeEventListener("focusin", onFocusIn);
1560
+ toolbar.removeEventListener("focusout", onFocusOut);
1561
+ focusCameFromEditorWithMouse = false;
1562
+ }
1563
+ };
1564
+ } }))];
1565
+ }
1566
+ getPublicInterface(rte) {
1567
+ const hidden = this.hidden;
1568
+ return {
1569
+ get hidden() {
1570
+ return hidden.getValue(rte);
1571
+ },
1572
+ set hidden(value) {
1573
+ hidden.setValue(rte, value);
1574
+ }
1575
+ };
1576
+ }
1577
+ };
1578
+ var RteToolbarFeature = require_slottable_request.featureFacade(RteToolbarFeatureImpl);
1579
+ //#endregion
1580
+ //#region src/lib/rich-text-editor/rte/features/placeholder.style.scss?inline
1581
+ var placeholder_style_default = ".placeholder{display:contents}.placeholder:before{color:var(--vvd-color-neutral-600);content:attr(data-placeholder);font-size:var(--placeholder-font-size,inherit);inset-inline:var(--editor-padding-inline);line-height:inherit;pointer-events:none;position:absolute}.editor--disabled .placeholder:before{color:var(--vvd-color-neutral-300)}";
1582
+ //#endregion
1583
+ //#region src/lib/rich-text-editor/rte/features/placeholder.ts
1584
+ var RtePlaceholderFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1585
+ constructor(config) {
1586
+ super();
1587
+ this.config = config;
1588
+ this.name = "RtePlaceholderFeature";
1589
+ }
1590
+ getStyles() {
1591
+ return [this.contribution(placeholder_style_default)];
1592
+ }
1593
+ getPlugins() {
1594
+ const placeholderPlugin = new prosemirror_state.Plugin({ props: { decorations: (state) => {
1595
+ if (state.doc.nodeSize === 4) {
1596
+ const storedSize = state.schema.marks.fontSize?.isInSet(state.storedMarks ?? [])?.attrs.size;
1597
+ return prosemirror_view.DecorationSet.create(state.doc, [prosemirror_view.Decoration.widget(1, () => {
1598
+ const placeholder = document.createElement("span");
1599
+ placeholder.className = "placeholder";
1600
+ placeholder.dataset.placeholder = this.config.text;
1601
+ if (storedSize) placeholder.style.setProperty("--placeholder-font-size", storedSize);
1602
+ return placeholder;
1603
+ })]);
1604
+ }
1605
+ return null;
1606
+ } } });
1607
+ return [this.contribution(placeholderPlugin)];
1608
+ }
1609
+ };
1610
+ var RtePlaceholderFeature = require_slottable_request.featureFacade(RtePlaceholderFeatureImpl);
1611
+ //#endregion
1612
+ //#region src/lib/rich-text-editor/rte/features/hard-break.ts
1613
+ var RteHardBreakFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1614
+ constructor(..._args) {
1615
+ super(..._args);
1616
+ this.name = "RteHardBreakFeature";
1617
+ }
1618
+ getSchema() {
1619
+ return [this.contribution({ nodes: { hardBreak: {
1620
+ inline: true,
1621
+ group: "inline",
1622
+ selectable: false,
1623
+ parseDOM: [{ tag: "br" }],
1624
+ toDOM() {
1625
+ return ["br"];
1626
+ }
1627
+ } } })];
1628
+ }
1629
+ getPlugins(_rte) {
1630
+ const forceBreak = (state, dispatch) => {
1631
+ const marks = state.storedMarks || state.selection.$from.marks();
1632
+ const tr = state.tr.replaceSelectionWith(state.schema.nodes.hardBreak.create(), true).scrollIntoView();
1633
+ if (marks.length) tr.setStoredMarks(marks);
1634
+ dispatch?.(tr);
1635
+ return true;
1636
+ };
1637
+ const keyBindings = { "Shift-Enter": forceBreak };
1638
+ return [this.contribution((0, prosemirror_keymap.keymap)(keyBindings), require_slottable_request.contributionPriority.high)];
1639
+ }
1640
+ };
1641
+ var RteHardBreakFeature = require_slottable_request.featureFacade(RteHardBreakFeatureImpl);
1642
+ //#endregion
1643
+ //#region src/lib/rich-text-editor/rte/features/font-size-picker.ts
1644
+ var mixedFontSize = Symbol("mixedFontSize");
1645
+ var RteFontSizePickerFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1646
+ constructor(config) {
1647
+ super();
1648
+ this.config = config;
1649
+ this.name = "RteFontSizePickerFeature";
1650
+ this.fontSizes = config.options;
1651
+ if (config.onBlocks) {
1652
+ this.defaultFontSizeForNode = {};
1653
+ for (const block of config.onBlocks) this.defaultFontSizeForNode[block.node] = block.defaultSize ?? null;
1654
+ }
1655
+ }
1656
+ getTextblockMarks() {
1657
+ if (this.config?.onBlocks) return this.config.onBlocks.map((block) => this.contribution({
1658
+ markName: "fontSize",
1659
+ onNodeName: block.node
1660
+ }));
1661
+ return [this.contribution({ markName: "fontSize" })];
1662
+ }
1663
+ getSchema() {
1664
+ return [this.contribution({ marks: { fontSize: {
1665
+ attrs: { size: { validate: "string" } },
1666
+ parseDOM: [{
1667
+ tag: "span[style*='font-size']",
1668
+ getAttrs: (node) => {
1669
+ const size = node.getAttribute("style").match(/font-size:\s*([^;]+)/)?.[1]?.trim();
1670
+ if (size) return { size };
1671
+ return false;
1672
+ }
1673
+ }],
1674
+ toDOM: (mark) => {
1675
+ return [
1676
+ "span",
1677
+ { style: `font-size: ${escapeCssProperty(mark.attrs.size)};` },
1678
+ 0
1679
+ ];
1680
+ },
1681
+ cursorFix: ($cursor, state) => {
1682
+ const storedMarks = state.storedMarks;
1683
+ if (!storedMarks) return null;
1684
+ const fontSizeMark = storedMarks.find((m) => m.type.name === "fontSize");
1685
+ if (fontSizeMark) return { style: { "font-size": fontSizeMark.attrs.size } };
1686
+ if (storedMarks.length === 0) {
1687
+ const defaultSize = this.defaultFontSizeForNode?.[$cursor.parent.type.name];
1688
+ if (defaultSize) return { style: { "font-size": defaultSize } };
1689
+ }
1690
+ return null;
1691
+ }
1692
+ } } })];
1693
+ }
1694
+ getPlugins() {
1695
+ return [this.contribution((0, prosemirror_keymap.keymap)({
1696
+ "Mod-Shift-.": this.adjustFontSize(-1),
1697
+ "Mod-Shift-,": this.adjustFontSize(1)
1698
+ }))];
1699
+ }
1700
+ getToolbarItems(rte) {
1701
+ return [this.contribution({
1702
+ section: "font",
1703
+ render: (ctx) => createMenu(ctx, {
1704
+ label: () => rte.getLocale().richTextEditor.textSize,
1705
+ trigger: createButton(ctx, {
1706
+ label: () => rte.getLocale().richTextEditor.textSize,
1707
+ icon: "text-size-line"
1708
+ }),
1709
+ children: this.fontSizes.map((fs) => createMenuItem(ctx, {
1710
+ text: fs.label,
1711
+ checked: () => this.getFontSizeFromSelection(ctx.view.state) === fs.size,
1712
+ disabled: () => !this.setFontSize(fs.size)(ctx.view.state),
1713
+ onSelect: () => {
1714
+ const { state, dispatch } = ctx.view;
1715
+ this.setFontSize(fs.size)(state, dispatch);
1716
+ }
1717
+ }))
1718
+ })
1719
+ }, 2)];
1720
+ }
1721
+ getFontSizeFromSelection(state) {
1722
+ const { from, to, $from, empty } = state.selection;
1723
+ const { fontSize } = state.schema.marks;
1724
+ if (empty) {
1725
+ const defaultSize = this.defaultFontSizeForNode?.[$from.parent.type.name] ?? null;
1726
+ return fontSize.isInSet(state.storedMarks || $from.marks())?.attrs.size ?? defaultSize;
1727
+ }
1728
+ let size = null;
1729
+ const observeSize = (observedSize) => {
1730
+ if (size === null) size = observedSize ?? null;
1731
+ else if (observedSize !== size) size = mixedFontSize;
1732
+ };
1733
+ state.doc.nodesBetween(from, to, (node, _, parent) => {
1734
+ if (size === mixedFontSize) return false;
1735
+ if (!node.isLeaf) {
1736
+ if (node.type.allowsMarkType(fontSize) && node.childCount === 0) observeSize(this.defaultFontSizeForNode?.[node.type.name]);
1737
+ return true;
1738
+ }
1739
+ observeSize(fontSize.isInSet(node.marks)?.attrs.size ?? (parent && this.defaultFontSizeForNode?.[parent.type.name]));
1740
+ return true;
1741
+ });
1742
+ return size;
1743
+ }
1744
+ setFontSize(size) {
1745
+ return (state, dispatch) => {
1746
+ const { from, to, empty, $from } = state.selection;
1747
+ const { fontSize } = state.schema.marks;
1748
+ if (!(0, prosemirror_commands.toggleMark)(fontSize, { size })(state)) return false;
1749
+ const tr = state.tr;
1750
+ if (empty) {
1751
+ const newStoredMarks = (state.storedMarks || []).filter((m) => m.type !== fontSize);
1752
+ if (size !== this.defaultFontSizeForNode?.[$from.parent.type.name]) newStoredMarks.push(fontSize.create({ size }));
1753
+ tr.setStoredMarks(newStoredMarks);
1754
+ } else {
1755
+ tr.addMark(from, to, fontSize.create({ size }));
1756
+ tr.doc.nodesBetween(from, to, (node, pos, parent) => {
1757
+ if (!node.isInline) return;
1758
+ const mark = fontSize.isInSet(node.marks);
1759
+ const defaultSize = this.defaultFontSizeForNode?.[parent.type.name];
1760
+ if (mark && mark.attrs.size === defaultSize) tr.step(new prosemirror_transform.RemoveMarkStep(pos, pos + node.nodeSize, mark));
1761
+ });
1762
+ }
1763
+ dispatch?.(tr.scrollIntoView());
1764
+ return true;
1765
+ };
1766
+ }
1767
+ adjustFontSize(adjustment) {
1768
+ return (state, dispatch) => {
1769
+ const currentSize = this.getFontSizeFromSelection(state);
1770
+ if (currentSize === null || currentSize === mixedFontSize) return false;
1771
+ const nextIndex = this.fontSizes.findIndex((fs) => fs.size === currentSize) + adjustment;
1772
+ if (nextIndex < 0 || nextIndex >= this.fontSizes.length) return false;
1773
+ return this.setFontSize(this.fontSizes[nextIndex].size)(state, dispatch);
1774
+ };
1775
+ }
1776
+ };
1777
+ var RteFontSizePickerFeature = require_slottable_request.featureFacade(RteFontSizePickerFeatureImpl);
1778
+ //#endregion
1779
+ //#region src/lib/rich-text-editor/rte/features/internal/text-style.ts
1780
+ var RteTextStyleFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1781
+ constructor(config) {
1782
+ super();
1783
+ this.config = config;
1784
+ }
1785
+ getTextblockMarks() {
1786
+ if (this.config?.onBlocks) return this.config.onBlocks.map((block) => this.contribution({
1787
+ markName: this.markName,
1788
+ onNodeName: block.node
1789
+ }));
1790
+ return [this.contribution({ markName: this.markName })];
1791
+ }
1792
+ };
1793
+ //#endregion
1794
+ //#region src/lib/rich-text-editor/rte/features/bold.ts
1795
+ var RteBoldFeatureImpl = class extends RteTextStyleFeatureImpl {
1796
+ constructor(..._args) {
1797
+ super(..._args);
1798
+ this.name = "RteBoldFeature";
1799
+ this.markName = "bold";
1800
+ }
1801
+ getSchema() {
1802
+ return [this.contribution({ marks: { bold: prosemirror_schema_basic.marks.strong } })];
1803
+ }
1804
+ getPlugins(rte) {
1805
+ return [this.contribution((0, prosemirror_keymap.keymap)({ "Mod-b": (0, prosemirror_commands.toggleMark)(rte.schema.marks.bold) }))];
1806
+ }
1807
+ getToolbarItems(rte) {
1808
+ return [this.contribution({
1809
+ section: "text-style",
1810
+ render: (ctx) => createMarkToggle(ctx, {
1811
+ label: () => ctx.rte.getLocale().richTextEditor.bold,
1812
+ dynamicIcon: "bold",
1813
+ markType: rte.schema.marks.bold
1814
+ })
1815
+ }, 1)];
1816
+ }
1817
+ };
1818
+ var RteBoldFeature = require_slottable_request.featureFacade(RteBoldFeatureImpl);
1819
+ //#endregion
1820
+ //#region src/lib/rich-text-editor/rte/features/italic.ts
1821
+ var RteItalicFeatureImpl = class extends RteTextStyleFeatureImpl {
1822
+ constructor(..._args) {
1823
+ super(..._args);
1824
+ this.name = "RteItalicFeature";
1825
+ this.markName = "italic";
1826
+ }
1827
+ getSchema() {
1828
+ return [this.contribution({ marks: { italic: prosemirror_schema_basic.marks.em } })];
1829
+ }
1830
+ getPlugins(rte) {
1831
+ return [this.contribution((0, prosemirror_keymap.keymap)({ "Mod-i": (0, prosemirror_commands.toggleMark)(rte.schema.marks.italic) }))];
1832
+ }
1833
+ getToolbarItems(rte) {
1834
+ return [this.contribution({
1835
+ section: "text-style",
1836
+ render: (ctx) => createMarkToggle(ctx, {
1837
+ label: () => ctx.rte.getLocale().richTextEditor.italic,
1838
+ dynamicIcon: "italic",
1839
+ markType: rte.schema.marks.italic
1840
+ })
1841
+ }, 2)];
1842
+ }
1843
+ };
1844
+ var RteItalicFeature = require_slottable_request.featureFacade(RteItalicFeatureImpl);
1845
+ //#endregion
1846
+ //#region src/lib/rich-text-editor/rte/features/underline.ts
1847
+ var RteUnderlineFeatureImpl = class extends RteTextStyleFeatureImpl {
1848
+ constructor(..._args) {
1849
+ super(..._args);
1850
+ this.name = "RteUnderlineFeature";
1851
+ this.markName = "underline";
1852
+ }
1853
+ getSchema() {
1854
+ return [this.contribution({ marks: { underline: {
1855
+ parseDOM: [{ tag: "u" }],
1856
+ toDOM() {
1857
+ return ["u", 0];
1858
+ }
1859
+ } } })];
1860
+ }
1861
+ getPlugins(rte) {
1862
+ return [this.contribution((0, prosemirror_keymap.keymap)({ "Mod-u": (0, prosemirror_commands.toggleMark)(rte.schema.marks.underline) }))];
1863
+ }
1864
+ getToolbarItems(rte) {
1865
+ return [this.contribution({
1866
+ section: "text-style",
1867
+ render: (ctx) => createMarkToggle(ctx, {
1868
+ label: () => ctx.rte.getLocale().richTextEditor.underline,
1869
+ dynamicIcon: "underline",
1870
+ markType: rte.schema.marks.underline
1871
+ })
1872
+ }, 3)];
1873
+ }
1874
+ };
1875
+ var RteUnderlineFeature = require_slottable_request.featureFacade(RteUnderlineFeatureImpl);
1876
+ //#endregion
1877
+ //#region src/lib/rich-text-editor/rte/features/strikethrough.ts
1878
+ var RteStrikethroughFeatureImpl = class extends RteTextStyleFeatureImpl {
1879
+ constructor(..._args) {
1880
+ super(..._args);
1881
+ this.name = "RteStrikethroughFeature";
1882
+ this.markName = "strikethrough";
1883
+ }
1884
+ getSchema() {
1885
+ return [this.contribution({ marks: { strikethrough: {
1886
+ parseDOM: [{ tag: "s" }, { tag: "del" }],
1887
+ toDOM() {
1888
+ return ["s", 0];
1889
+ }
1890
+ } } })];
1891
+ }
1892
+ getPlugins(rte) {
1893
+ return [this.contribution((0, prosemirror_keymap.keymap)({
1894
+ "Alt-Shift-5": (0, prosemirror_commands.toggleMark)(rte.schema.marks.strikethrough),
1895
+ "Cmd-Shift-X": (0, prosemirror_commands.toggleMark)(rte.schema.marks.strikethrough)
1896
+ }))];
1897
+ }
1898
+ getToolbarItems(rte) {
1899
+ return [this.contribution({
1900
+ section: "text-style",
1901
+ render: (ctx) => createMarkToggle(ctx, {
1902
+ label: () => ctx.rte.getLocale().richTextEditor.strikethrough,
1903
+ dynamicIcon: "strikethrough",
1904
+ markType: rte.schema.marks.strikethrough
1905
+ })
1906
+ }, 4)];
1907
+ }
1908
+ };
1909
+ var RteStrikethroughFeature = require_slottable_request.featureFacade(RteStrikethroughFeatureImpl);
1910
+ //#endregion
1911
+ //#region src/lib/rich-text-editor/rte/features/monospace.style.scss?inline
1912
+ var monospace_style_default = "tt{font:var(--vvd-typography-base-code);font-variant-ligatures:unset;font-feature-settings:unset;font-size:unset;font-weight:unset;line-height:unset}";
1913
+ //#endregion
1914
+ //#region src/lib/rich-text-editor/rte/features/monospace.ts
1915
+ var RteMonospaceFeatureImpl = class extends RteTextStyleFeatureImpl {
1916
+ constructor(..._args) {
1917
+ super(..._args);
1918
+ this.name = "RteMonospaceFeature";
1919
+ this.markName = "monospace";
1920
+ }
1921
+ getStyles() {
1922
+ return [this.contribution(monospace_style_default)];
1923
+ }
1924
+ getSchema() {
1925
+ return [this.contribution({ marks: { monospace: {
1926
+ parseDOM: [{ tag: "tt" }, { tag: "code" }],
1927
+ toDOM() {
1928
+ return ["tt", 0];
1929
+ }
1930
+ } } })];
1931
+ }
1932
+ getPlugins(rte) {
1933
+ return [this.contribution((0, prosemirror_keymap.keymap)({ "Mod-M": (0, prosemirror_commands.toggleMark)(rte.schema.marks.monospace) }))];
1934
+ }
1935
+ getToolbarItems(rte) {
1936
+ return [this.contribution({
1937
+ section: "text-style",
1938
+ render: (ctx) => createMarkToggle(ctx, {
1939
+ label: () => ctx.rte.getLocale().richTextEditor.monospace,
1940
+ dynamicIcon: "monospace",
1941
+ markType: rte.schema.marks.monospace
1942
+ })
1943
+ }, 5)];
1944
+ }
1945
+ };
1946
+ var RteMonospaceFeature = require_slottable_request.featureFacade(RteMonospaceFeatureImpl);
1947
+ //#endregion
1948
+ //#region src/lib/rich-text-editor/rte/features/text-color-picker.ts
1949
+ function markApplies(doc, ranges, type) {
1950
+ for (let i = 0; i < ranges.length; i++) {
1951
+ const { $from, $to } = ranges[i];
1952
+ let can = $from.depth == 0 ? doc.type.allowsMarkType(type) : false;
1953
+ doc.nodesBetween($from.pos, $to.pos, (node) => {
1954
+ if (can) return false;
1955
+ can = node.inlineContent && node.type.allowsMarkType(type);
1956
+ return true;
1957
+ });
1958
+ if (can) return true;
1959
+ }
1960
+ return false;
1961
+ }
1962
+ var mixedColor = Symbol("mixedColor");
1963
+ var RteTextColorPickerFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
1964
+ constructor(config) {
1965
+ super();
1966
+ this.config = config;
1967
+ this.name = "RteTextColorPicker";
1968
+ if (config?.onBlocks) {
1969
+ this.defaultColorForNode = {};
1970
+ for (const block of config.onBlocks) this.defaultColorForNode[block.node] = block.defaultColor ?? null;
1971
+ }
1972
+ }
1973
+ getTextblockMarks() {
1974
+ if (this.config?.onBlocks) return this.config.onBlocks.map((block) => this.contribution({
1975
+ markName: "textColor",
1976
+ onNodeName: block.node
1977
+ }));
1978
+ return [this.contribution({ markName: "textColor" })];
1979
+ }
1980
+ getSchema() {
1981
+ return [this.contribution({ marks: { textColor: {
1982
+ attrs: { color: { validate: "string" } },
1983
+ parseDOM: [{
1984
+ tag: "span[data-text-color]",
1985
+ getAttrs: (dom) => {
1986
+ return { color: dom.getAttribute("data-text-color") };
1987
+ }
1988
+ }, {
1989
+ style: "color",
1990
+ getAttrs: (value) => {
1991
+ return { color: value };
1992
+ }
1993
+ }],
1994
+ toDOM(node) {
1995
+ const { color } = node.attrs;
1996
+ return [
1997
+ "span",
1998
+ {
1999
+ style: `color: ${escapeCssProperty(color)};`,
2000
+ "data-text-color": color
2001
+ },
2002
+ 0
2003
+ ];
2004
+ },
2005
+ inclusive: true
2006
+ } } })];
2007
+ }
2008
+ getToolbarItems() {
2009
+ return [this.contribution({
2010
+ section: "text-style",
2011
+ render: (ctx) => {
2012
+ const tooltipButton = createButton(ctx, {
2013
+ label: () => ctx.rte.getLocale().richTextEditor.textColor,
2014
+ disabled: () => !this.setColor("any")(ctx.view.state),
2015
+ icon: "textcolor-line"
2016
+ });
2017
+ const button = tooltipButton.firstElementChild;
2018
+ return createDiv(ctx, { children: [tooltipButton, createSingleSlot(ctx, {
2019
+ name: "text-color-picker",
2020
+ assignedProps: {
2021
+ anchor: button,
2022
+ value: () => this.getSelectionColor(ctx.view.state) || ""
2023
+ },
2024
+ assignedEvents: { change: (e) => {
2025
+ const value = e.currentTarget.value;
2026
+ this.setColor(value)(ctx.view.state, ctx.view.dispatch);
2027
+ } }
2028
+ })] });
2029
+ }
2030
+ }, 6)];
2031
+ }
2032
+ /** Determine the color of the current selection or null if colors are mixed */
2033
+ getSelectionColor(state) {
2034
+ const { selection } = state;
2035
+ const { textColor } = state.schema.marks;
2036
+ const { from, to, $from, empty } = selection;
2037
+ if (empty) {
2038
+ const defaultColor = this.defaultColorForNode?.[$from.parent.type.name] ?? null;
2039
+ return textColor.isInSet(state.storedMarks || $from.marks())?.attrs.color ?? defaultColor;
2040
+ }
2041
+ let selectionColor = null;
2042
+ const observeColor = (observedColor) => {
2043
+ if (selectionColor === null) selectionColor = observedColor ?? null;
2044
+ else if (observedColor !== selectionColor) selectionColor = mixedColor;
2045
+ };
2046
+ state.doc.nodesBetween(from, to, (node, _pos, parent) => {
2047
+ if (selectionColor === mixedColor) return false;
2048
+ if (!node.isLeaf) {
2049
+ if (node.type.allowsMarkType(textColor) && node.childCount === 0) observeColor(this.defaultColorForNode?.[node.type.name]);
2050
+ return true;
2051
+ }
2052
+ observeColor(textColor.isInSet(node.marks)?.attrs.color ?? (parent && this.defaultColorForNode?.[parent.type.name]));
2053
+ return true;
2054
+ });
2055
+ return selectionColor === mixedColor ? null : selectionColor;
2056
+ }
2057
+ setColor(color) {
2058
+ return (state, dispatch) => {
2059
+ const { textColor } = state.schema.marks;
2060
+ const { from, to, empty, $from } = state.selection;
2061
+ if (!markApplies(state.doc, state.selection.ranges, textColor)) return false;
2062
+ const tr = state.tr;
2063
+ if (empty) {
2064
+ const newStoredMarks = (state.storedMarks || []).filter((m) => m.type !== textColor);
2065
+ if (color !== this.defaultColorForNode?.[$from.parent.type.name]) newStoredMarks.push(textColor.create({ color }));
2066
+ tr.setStoredMarks(newStoredMarks);
2067
+ } else {
2068
+ tr.addMark(from, to, textColor.create({ color }));
2069
+ tr.doc.nodesBetween(from, to, (node, pos, parent) => {
2070
+ if (!node.isInline) return;
2071
+ const mark = textColor.isInSet(node.marks);
2072
+ const defaultColor = this.defaultColorForNode?.[parent.type.name];
2073
+ if (mark && mark.attrs.color === defaultColor) tr.step(new prosemirror_transform.RemoveMarkStep(pos, pos + node.nodeSize, mark));
2074
+ });
2075
+ }
2076
+ dispatch?.(tr.scrollIntoView());
2077
+ return true;
2078
+ };
2079
+ }
2080
+ };
2081
+ var RteTextColorPickerFeature = require_slottable_request.featureFacade(RteTextColorPickerFeatureImpl);
2082
+ //#endregion
2083
+ //#region src/lib/rich-text-editor/rte/features/list.style.scss?inline
2084
+ var list_style_default = ".rich-text ul,.rich-text ol{padding-inline-start:1.5em}.rich-text li{list-style-position:inside}";
2085
+ //#endregion
2086
+ //#region src/lib/rich-text-editor/rte/features/list.ts
2087
+ var atStartOfNode = ($cursor) => $cursor.parentOffset === 0;
2088
+ var isEmpty = (node) => node.nodeSize === 2;
2089
+ var listDepth = ($li) => $li.depth - 1;
2090
+ var outOfListDepth = ($li) => $li.depth - 2;
2091
+ var getLi = ($li) => $li.parent;
2092
+ var getList = ($li) => $li.node(listDepth($li));
2093
+ var isNested = ($li) => $li.depth > 2;
2094
+ var isFirstChild = ($pos, depth) => $pos.index(depth) === 0;
2095
+ var isLastChild = ($pos, depth) => $pos.index(depth) === $pos.node(depth).childCount - 1;
2096
+ var prevSibling = ($pos, depth) => {
2097
+ const parent = $pos.node(depth);
2098
+ const index = $pos.index(depth);
2099
+ return parent.maybeChild(index - 1);
2100
+ };
2101
+ var nextSibling = ($pos, depth) => {
2102
+ const parent = $pos.node(depth);
2103
+ const index = $pos.index(depth);
2104
+ return parent.maybeChild(index + 1);
2105
+ };
2106
+ var asTextSelection = (selection) => {
2107
+ let { $from, $to } = selection;
2108
+ if (selection instanceof prosemirror_state.AllSelection) {
2109
+ const textSelection = prosemirror_state.TextSelection.between(selection.$from, selection.$to);
2110
+ $from = textSelection.$from;
2111
+ $to = textSelection.$to;
2112
+ }
2113
+ return {
2114
+ $from,
2115
+ $to
2116
+ };
2117
+ };
2118
+ var getSharedAncestor = ($from, $to) => $from.sameParent($to) ? $from.node(-1) : $from.node($from.sharedDepth($to.pos));
2119
+ var cursorInListItem = (state) => {
2120
+ const { $cursor } = state.selection;
2121
+ if ($cursor?.parent.type === state.schema.nodes.listItem) return $cursor;
2122
+ return null;
2123
+ };
2124
+ var allListItemsAreOfType = (state, $from, $to, type) => {
2125
+ let currentListType;
2126
+ let allLisAreOurType = true;
2127
+ state.doc.nodesBetween($from.pos, $to.pos, (node) => {
2128
+ if (node.type.isInGroup("list")) currentListType = node.type;
2129
+ if (node.type === state.schema.nodes.listItem && currentListType !== type) allLisAreOurType = false;
2130
+ });
2131
+ return allLisAreOurType;
2132
+ };
2133
+ var lift = (rte, $li, tr) => {
2134
+ if (isNested($li)) {
2135
+ liftToOuterList($li, tr);
2136
+ return true;
2137
+ }
2138
+ return liftOutOfList(rte, $li, tr);
2139
+ };
2140
+ var liftToOuterList = ($li, tr) => {
2141
+ const liRange = new prosemirror_model.NodeRange($li.doc.resolve($li.before()), $li.doc.resolve($li.after()), $li.depth - 1);
2142
+ tr.lift(liRange, $li.depth - 2);
2143
+ };
2144
+ var liftOutOfList = (rte, $li, tr) => {
2145
+ const list = getList($li);
2146
+ const listIndex = $li.index(outOfListDepth($li));
2147
+ const defaultTextblock = defaultTextblockForMatch($li.node(outOfListDepth($li)).contentMatchAt(listIndex + 1));
2148
+ if (!defaultTextblock) return false;
2149
+ const atStart = isFirstChild($li, listDepth($li));
2150
+ const atEnd = isLastChild($li, listDepth($li));
2151
+ tr.step(new prosemirror_transform.ReplaceAroundStep($li.before() - (atStart ? 1 : 0), $li.after() + (atEnd ? 1 : 0), $li.start(), $li.end(), new prosemirror_model.Slice((atStart ? prosemirror_model.Fragment.empty : prosemirror_model.Fragment.from(list.copy(prosemirror_model.Fragment.empty))).append(prosemirror_model.Fragment.from(defaultTextblock.create(rte.textblockAttrs.extractFromNode(getLi($li))))).append(atEnd ? prosemirror_model.Fragment.empty : prosemirror_model.Fragment.from(list.copy(prosemirror_model.Fragment.empty))), atStart ? 0 : 1, atEnd ? 0 : 1), (atStart ? 0 : 1) + 1));
2152
+ return true;
2153
+ };
2154
+ var sink = (rte, listType, $node, tr) => {
2155
+ if ($node.parent.type === rte.schema.nodes.listItem) sinkLi(listType, $node, tr);
2156
+ else sinkNode(rte, listType, $node, tr);
2157
+ };
2158
+ var sinkLi = (listType, $li, tr) => {
2159
+ const canJoinWithPrev = prevSibling($li, listDepth($li))?.type === listType;
2160
+ const canJoinWithNext = nextSibling($li, listDepth($li))?.type === listType;
2161
+ const openStart = canJoinWithPrev ? 1 : 0;
2162
+ const openEnd = canJoinWithNext ? 1 : 0;
2163
+ tr.step(new prosemirror_transform.ReplaceAroundStep($li.before() - (canJoinWithPrev ? 1 : 0), $li.after() + (canJoinWithNext ? 1 : 0), $li.before(), $li.after(), new prosemirror_model.Slice(prosemirror_model.Fragment.from(listType.create(null, [])), openStart, openEnd), 1 - openStart));
2164
+ };
2165
+ var sinkNode = (rte, listType, $node, tr) => {
2166
+ tr.step(new prosemirror_transform.ReplaceAroundStep($node.before(), $node.after(), $node.start(), $node.end(), new prosemirror_model.Slice(prosemirror_model.Fragment.from(listType.create(null, [rte.schema.nodes.listItem.create(rte.textblockAttrs.extractFromNode($node.parent))])), 0, 0), 2));
2167
+ };
2168
+ var RteListFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
2169
+ constructor(config) {
2170
+ super();
2171
+ this.config = config;
2172
+ this.name = "RteListFeature";
2173
+ if (!config.bulletList && !config.numberedList) throw new Error("RteListFeature requires at least one of bulletList or numberedList to be enabled");
2174
+ }
2175
+ getStyles() {
2176
+ return [this.contribution(list_style_default)];
2177
+ }
2178
+ getSchema(textblockAttrs) {
2179
+ return [this.contribution({ nodes: {
2180
+ listItem: {
2181
+ content: "inline*",
2182
+ attrs: textblockAttrs.attrs,
2183
+ defining: true,
2184
+ parseDOM: [{
2185
+ tag: "li",
2186
+ getAttrs: (dom) => textblockAttrs.fromDOM(dom)
2187
+ }],
2188
+ toDOM(node) {
2189
+ return [
2190
+ "li",
2191
+ ...textblockAttrs.getDOMAttrs(node),
2192
+ 0
2193
+ ];
2194
+ }
2195
+ },
2196
+ ...this.config.bulletList ? { bulletList: {
2197
+ group: "block list",
2198
+ content: "(listItem | list)+",
2199
+ parseDOM: [{ tag: "ul" }],
2200
+ toDOM() {
2201
+ return ["ul", 0];
2202
+ }
2203
+ } } : {},
2204
+ ...this.config.numberedList ? { numberedList: {
2205
+ group: "block list",
2206
+ content: "(listItem | list)+",
2207
+ parseDOM: [{ tag: "ol" }],
2208
+ toDOM() {
2209
+ return ["ol", 0];
2210
+ }
2211
+ } } : {}
2212
+ } })];
2213
+ }
2214
+ getPlugins(rte) {
2215
+ this.rte = rte;
2216
+ const tabCommand = (state, dispatch) => {
2217
+ const $liCursor = cursorInListItem(state);
2218
+ if ($liCursor && atStartOfNode($liCursor)) {
2219
+ const tr = state.tr;
2220
+ sinkLi(getList($liCursor).type, $liCursor, tr);
2221
+ dispatch?.(tr.scrollIntoView());
2222
+ return true;
2223
+ }
2224
+ return false;
2225
+ };
2226
+ const shiftTabCommand = (state, dispatch) => {
2227
+ const $liCursor = cursorInListItem(state);
2228
+ if ($liCursor && atStartOfNode($liCursor) && isNested($liCursor)) {
2229
+ const tr = state.tr;
2230
+ liftToOuterList($liCursor, tr);
2231
+ dispatch?.(tr.scrollIntoView());
2232
+ return true;
2233
+ }
2234
+ return false;
2235
+ };
2236
+ const enterCommand = (state, dispatch) => {
2237
+ const $liCursor = cursorInListItem(state);
2238
+ if ($liCursor && isEmpty(getLi($liCursor))) {
2239
+ const tr = state.tr;
2240
+ if (!lift(this.rte, $liCursor, tr)) return false;
2241
+ dispatch?.(tr.scrollIntoView());
2242
+ return true;
2243
+ }
2244
+ return false;
2245
+ };
2246
+ const backspaceCommand = (state, dispatch) => {
2247
+ const $liCursor = cursorInListItem(state);
2248
+ if ($liCursor && atStartOfNode($liCursor)) {
2249
+ if (isFirstChild($liCursor, listDepth($liCursor)) && prevSibling($liCursor, outOfListDepth($liCursor))?.type === getList($liCursor).type) return false;
2250
+ const tr = state.tr;
2251
+ if (!lift(this.rte, $liCursor, tr)) return false;
2252
+ dispatch?.(tr.scrollIntoView());
2253
+ return true;
2254
+ }
2255
+ return false;
2256
+ };
2257
+ return [this.contribution((0, prosemirror_keymap.keymap)({
2258
+ Enter: enterCommand,
2259
+ Backspace: backspaceCommand,
2260
+ Tab: tabCommand,
2261
+ "Shift-Tab": shiftTabCommand,
2262
+ ...this.config.bulletList ? { "Mod-Shift-8": this.toggleList(rte.schema.nodes.bulletList) } : {},
2263
+ ...this.config.numberedList ? { "Mod-Shift-7": this.toggleList(rte.schema.nodes.numberedList) } : {}
2264
+ }), require_slottable_request.contributionPriority.high)];
2265
+ }
2266
+ getToolbarItems(rte) {
2267
+ const toolbarItems = [];
2268
+ if (this.config.bulletList) toolbarItems.push(this.contribution({
2269
+ section: "textblock",
2270
+ render: (ctx) => createButton(ctx, {
2271
+ label: () => ctx.rte.getLocale().richTextEditor.bulletList,
2272
+ dynamicIcon: "bullet-list-2",
2273
+ active: () => this.isSelectionInList(rte.schema.nodes.bulletList, ctx.rte.state),
2274
+ onClick: () => {
2275
+ const { state, dispatch } = ctx.view;
2276
+ this.toggleList(rte.schema.nodes.bulletList)(state, dispatch);
2277
+ }
2278
+ })
2279
+ }, 1));
2280
+ if (this.config.numberedList) toolbarItems.push(this.contribution({
2281
+ section: "textblock",
2282
+ render: (ctx) => createButton(ctx, {
2283
+ label: () => ctx.rte.getLocale().richTextEditor.numberedList,
2284
+ dynamicIcon: "list-numbered",
2285
+ active: () => this.isSelectionInList(rte.schema.nodes.numberedList, ctx.rte.state),
2286
+ onClick: () => {
2287
+ const { state, dispatch } = ctx.view;
2288
+ this.toggleList(rte.schema.nodes.numberedList)(state, dispatch);
2289
+ }
2290
+ })
2291
+ }, 2));
2292
+ return toolbarItems;
2293
+ }
2294
+ toggleList(type) {
2295
+ return (0, prosemirror_commands.autoJoin)((state, dispatch) => {
2296
+ const { $from, $to } = asTextSelection(state.selection);
2297
+ if (getSharedAncestor($from, $to).type.isInGroup("list")) {
2298
+ if (allListItemsAreOfType(state, $from, $to, type)) {
2299
+ const tr = state.tr;
2300
+ state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
2301
+ if (node.type === state.schema.nodes.listItem) {
2302
+ const $li = tr.doc.resolve(tr.mapping.map(pos + 1));
2303
+ lift(this.rte, $li, tr);
2304
+ }
2305
+ });
2306
+ dispatch?.(tr.scrollIntoView());
2307
+ return true;
2308
+ } else {
2309
+ const tr = state.tr;
2310
+ state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
2311
+ if (node.type.isInGroup("list") && node.type !== type) tr.setNodeMarkup(pos, type, node.attrs);
2312
+ });
2313
+ dispatch?.(tr.scrollIntoView());
2314
+ return true;
2315
+ }
2316
+ } else {
2317
+ const tr = state.tr;
2318
+ state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => {
2319
+ if (!node.isTextblock) return;
2320
+ const $node = tr.doc.resolve(tr.mapping.map(pos + 1));
2321
+ sink(this.rte, type, $node, tr);
2322
+ });
2323
+ dispatch?.(tr.scrollIntoView());
2324
+ return true;
2325
+ }
2326
+ }, (before, after) => before.type === type && after.type === type);
2327
+ }
2328
+ isSelectionInList(type, state) {
2329
+ const { $from, $to } = asTextSelection(state.selection);
2330
+ if (getSharedAncestor($from, $to).type.isInGroup("list")) return allListItemsAreOfType(state, $from, $to, type);
2331
+ else return false;
2332
+ }
2333
+ };
2334
+ var RteListFeature = require_slottable_request.featureFacade(RteListFeatureImpl);
2335
+ //#endregion
2336
+ //#region src/lib/rich-text-editor/rte/features/alignment.ts
2337
+ var alignments = [
2338
+ {
2339
+ value: "left",
2340
+ icon: "align-left",
2341
+ label: "left"
2342
+ },
2343
+ {
2344
+ value: "center",
2345
+ icon: "align-center",
2346
+ label: "center"
2347
+ },
2348
+ {
2349
+ value: "right",
2350
+ icon: "align-right",
2351
+ label: "right"
2352
+ }
2353
+ ];
2354
+ var validTextAlign = (value) => alignments.find((a) => a.value === value)?.value ?? "left";
2355
+ var RteAlignmentFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
2356
+ constructor(..._args) {
2357
+ super(..._args);
2358
+ this.name = "RteAlignmentFeature";
2359
+ }
2360
+ getTextblockAttrs() {
2361
+ return [this.contribution({
2362
+ name: "textAlign",
2363
+ default: "left",
2364
+ fromDOM(dom) {
2365
+ return validTextAlign(dom.style.textAlign);
2366
+ },
2367
+ toStyles(node) {
2368
+ return [`text-align: ${validTextAlign(node.attrs.textAlign)}`];
2369
+ }
2370
+ })];
2371
+ }
2372
+ getPlugins() {
2373
+ return [this.contribution((0, prosemirror_keymap.keymap)({
2374
+ "Mod-L": this.setAlignment("left"),
2375
+ "Mod-E": this.setAlignment("center"),
2376
+ "Mod-R": this.setAlignment("right")
2377
+ }))];
2378
+ }
2379
+ getToolbarItems() {
2380
+ return [this.contribution({
2381
+ section: "textblock",
2382
+ render: (ctx) => createMenu(ctx, {
2383
+ label: () => ctx.rte.getLocale().richTextEditor.alignment,
2384
+ trigger: createButton(ctx, {
2385
+ label: () => ctx.rte.getLocale().richTextEditor.alignment,
2386
+ icon: () => {
2387
+ const currentAlign = this.getAlignmentFromSelection(ctx.view.state);
2388
+ return `${alignments.find((a) => a.value === currentAlign)?.icon ?? "align-left"}-line`;
2389
+ }
2390
+ }),
2391
+ children: [createButtonGroup(ctx, {
2392
+ slot: "header",
2393
+ children: alignments.map((align, index) => createButton(ctx, {
2394
+ dynamicIcon: align.icon,
2395
+ label: () => ctx.rte.getLocale().richTextEditor.alignments[align.label],
2396
+ noTooltip: true,
2397
+ variant: "toolbar-menu",
2398
+ autofocus: () => {
2399
+ const currentAlign = this.getAlignmentFromSelection(ctx.view.state);
2400
+ if ((currentAlign === "mixed" || currentAlign === null) && index === 0) return true;
2401
+ return align.value === currentAlign;
2402
+ },
2403
+ active: () => this.getAlignmentFromSelection(ctx.view.state) === align.value,
2404
+ disabled: () => this.getAlignmentFromSelection(ctx.view.state) === null,
2405
+ onClick: () => {
2406
+ const { state, dispatch } = ctx.view;
2407
+ this.setAlignment(align.value)(state, dispatch);
2408
+ }
2409
+ }))
2410
+ })]
2411
+ })
2412
+ }, 3)];
2413
+ }
2414
+ getAlignmentFromSelection(state) {
2415
+ const { selection } = state;
2416
+ const { from, to } = selection;
2417
+ let align = null;
2418
+ state.doc.nodesBetween(from, to, (node) => {
2419
+ if (align === "mixed") return;
2420
+ if (node.type.isTextblock) {
2421
+ if (!align) align = node.attrs.textAlign;
2422
+ else if (align !== node.attrs.textAlign) align = "mixed";
2423
+ }
2424
+ });
2425
+ return align;
2426
+ }
2427
+ setAlignment(align) {
2428
+ return (state, dispatch) => {
2429
+ const { tr, selection } = state;
2430
+ const { from, to } = selection;
2431
+ state.doc.nodesBetween(from, to, (node, pos) => {
2432
+ if (node.type.isTextblock) tr.setNodeMarkup(pos, node.type, {
2433
+ ...node.attrs,
2434
+ textAlign: align
2435
+ });
2436
+ });
2437
+ dispatch?.(tr.scrollIntoView());
2438
+ return true;
2439
+ };
2440
+ }
2441
+ };
2442
+ var RteAlignmentFeature = require_slottable_request.featureFacade(RteAlignmentFeatureImpl);
2443
+ //#endregion
2444
+ //#region src/lib/rich-text-editor/rte/features/link.style.scss?inline
2445
+ var link_style_default = ".link-popover{flex-direction:column;gap:8px;inline-size:450px;padding:16px;display:flex}.link-popover-header{justify-content:space-between;align-items:center;display:flex}.link-popover-label{color:var(--vvd-color-neutral-600);font:var(--vvd-typography-base-condensed)}.link-popover-content{flex-direction:column;gap:16px;display:flex}.link,.rich-text a[href],.link:visited,.rich-text a[href]:visited{color:var(--vvd-color-cta-600)}.link:hover,.rich-text a[href]:hover{color:var(--vvd-color-cta-500)}.link:active,.rich-text a[href]:active{color:var(--vvd-color-cta-400)}.link-action-bar{justify-content:end;gap:8px;display:flex}.link-toolbar-menu{flex-direction:column;gap:16px;inline-size:368px;padding:8px;display:flex}";
2446
+ //#endregion
2447
+ //#region src/lib/rich-text-editor/rte/features/link.ts
2448
+ var linkPattern = "(?:https?://|www\\.)[^\\s<]+";
2449
+ function convertToLink(state, matchedText, start, end) {
2450
+ if (state.doc.rangeHasMark(start, start + 1, state.schema.marks.link)) return null;
2451
+ const link = matchedText.replace(/[.,;:!?) ]+$/, "");
2452
+ const href = link.startsWith("www.") ? `https://${link}` : link;
2453
+ const linkMark = state.schema.marks.link.create({ href });
2454
+ const linkEnd = start + link.length;
2455
+ const trailingChars = matchedText.slice(link.length);
2456
+ const tr = state.tr.addMark(start, linkEnd, linkMark);
2457
+ if (trailingChars) tr.replaceWith(linkEnd, end, state.schema.text(trailingChars));
2458
+ return tr;
2459
+ }
2460
+ var RteLinkFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
2461
+ constructor(..._args) {
2462
+ super(..._args);
2463
+ this.name = "RteLinkFeature";
2464
+ this.removeLink = (state, dispatch) => {
2465
+ const tr = state.tr;
2466
+ const existingLink = this.getCurrentLink(state);
2467
+ tr.removeMark(existingLink.start, existingLink.end, state.schema.marks.link);
2468
+ dispatch?.(tr.scrollIntoView());
2469
+ return true;
2470
+ };
2471
+ }
2472
+ getStyles() {
2473
+ return [this.contribution(link_style_default)];
2474
+ }
2475
+ getSchema() {
2476
+ return [this.contribution({ marks: { link: {
2477
+ attrs: { href: { validate: "string" } },
2478
+ inclusive: false,
2479
+ parseDOM: [{
2480
+ tag: "a[href]",
2481
+ getAttrs(dom) {
2482
+ return { href: dom.getAttribute("href") };
2483
+ }
2484
+ }],
2485
+ toDOM(node) {
2486
+ const { href } = node.attrs;
2487
+ return [
2488
+ "a",
2489
+ { href: sanitizeLinkHref(href) },
2490
+ 0
2491
+ ];
2492
+ }
2493
+ } } }, require_slottable_request.contributionPriority.high)];
2494
+ }
2495
+ getTextblockMarks() {
2496
+ return [this.contribution({ markName: "link" })];
2497
+ }
2498
+ getInputRules() {
2499
+ const linkRegex = new RegExp(`${linkPattern}$`);
2500
+ return [this.contribution({
2501
+ rule: new prosemirror_inputrules.InputRule(new RegExp(`${linkPattern} $`), (state, match, start, end) => convertToLink(state, match[0], start, end)),
2502
+ enterHandler: {
2503
+ regex: linkRegex,
2504
+ handler: (state, match, start, end) => convertToLink(state, match[0], start, end)
2505
+ }
2506
+ })];
2507
+ }
2508
+ getPlugins(rte) {
2509
+ const insertLinkCommand = () => {
2510
+ this.toolbarMenu.open = true;
2511
+ return true;
2512
+ };
2513
+ let popup;
2514
+ return [this.contribution(new prosemirror_state.Plugin({
2515
+ props: { decorations: (state) => {
2516
+ const link = this.getCurrentLink(state);
2517
+ if (link) {
2518
+ const deco = prosemirror_view.Decoration.inline(link.start, link.end, { id: "current-link" });
2519
+ return prosemirror_view.DecorationSet.create(state.doc, [deco]);
2520
+ }
2521
+ return null;
2522
+ } },
2523
+ view: (view) => {
2524
+ const ctx = new UiCtx(view, rte, {
2525
+ popupPlacement: "bottom",
2526
+ shouldReturnFocusToEditor: true
2527
+ });
2528
+ popup = rte.createComponent(Popover);
2529
+ popup.anchorId = "current-link";
2530
+ const content = createDiv(ctx, {
2531
+ className: "link-popover",
2532
+ children: [createDiv(ctx, {
2533
+ className: "link-popover-header",
2534
+ children: [createDiv(ctx, {
2535
+ className: "link-popover-label",
2536
+ children: [createText(ctx, { text: () => this.getCurrentLink(ctx.view.state)?.text || "" })]
2537
+ }), createButton(ctx, {
2538
+ icon: "close-line",
2539
+ label: () => ctx.rte.getLocale().richTextEditor.close,
2540
+ noTooltip: true,
2541
+ onClick: () => {
2542
+ popup.dismiss();
2543
+ }
2544
+ })]
2545
+ }), createDiv(ctx, {
2546
+ className: "link-popover-content",
2547
+ children: [createAnchor(ctx, {
2548
+ className: "link",
2549
+ href: () => this.getCurrentLink(ctx.view.state)?.href || "",
2550
+ target: "_blank",
2551
+ rel: "noopener",
2552
+ children: [createText(ctx, { text: () => this.getCurrentLink(ctx.view.state)?.href || "" })]
2553
+ }), createDiv(ctx, {
2554
+ className: "link-action-bar",
2555
+ children: [createButton(ctx, {
2556
+ icon: "delete-line",
2557
+ label: () => ctx.rte.getLocale().richTextEditor.delete,
2558
+ connotation: "alert",
2559
+ variant: "popover",
2560
+ noTooltip: true,
2561
+ onClick: () => {
2562
+ const { state, dispatch } = ctx.view;
2563
+ this.removeLink(state, dispatch);
2564
+ }
2565
+ }), createButton(ctx, {
2566
+ icon: "edit-line",
2567
+ label: () => ctx.rte.getLocale().richTextEditor.edit,
2568
+ variant: "popover",
2569
+ noTooltip: true,
2570
+ onClick: () => {
2571
+ this.toolbarMenu.open = true;
2572
+ popup.requestOpenState(false);
2573
+ return true;
2574
+ }
2575
+ })]
2576
+ })]
2577
+ })]
2578
+ });
2579
+ popup.appendChild(content);
2580
+ view.dom.getRootNode().querySelector(".popovers").appendChild(popup);
2581
+ return {
2582
+ update: (view) => {
2583
+ const state = view.state;
2584
+ ctx.updateBindings();
2585
+ const link = this.getCurrentLink(state);
2586
+ popup.requestOpenState(Boolean(link));
2587
+ },
2588
+ destroy: () => {
2589
+ popup.remove();
2590
+ }
2591
+ };
2592
+ }
2593
+ })), this.contribution((0, prosemirror_keymap.keymap)({
2594
+ Escape: (state) => {
2595
+ if (this.getCurrentLink(state)) {
2596
+ popup?.dismiss();
2597
+ return true;
2598
+ }
2599
+ return false;
2600
+ },
2601
+ "Mod-k": insertLinkCommand
2602
+ }))];
2603
+ }
2604
+ getToolbarItems(rte) {
2605
+ const getSelectionText = (state) => {
2606
+ const { from, to } = state.selection;
2607
+ if (from === to) return "";
2608
+ return state.doc.textBetween(from, to, " ");
2609
+ };
2610
+ const isValidUrl = (url) => {
2611
+ try {
2612
+ new URL(url);
2613
+ return true;
2614
+ } catch {
2615
+ return false;
2616
+ }
2617
+ };
2618
+ return [this.contribution({
2619
+ section: "insert",
2620
+ render: (ctx) => {
2621
+ const textField = createTextField(ctx, {
2622
+ label: () => ctx.rte.getLocale().richTextEditor.linkText,
2623
+ placeholder: () => ctx.rte.getLocale().richTextEditor.linkTextPlaceholder,
2624
+ slot: "header",
2625
+ autofocus: true,
2626
+ value: () => this.getCurrentLink(ctx.view.state)?.text || getSelectionText(ctx.view.state) || "",
2627
+ onInput: () => {
2628
+ updateValidation();
2629
+ }
2630
+ });
2631
+ const urlField = createTextField(ctx, {
2632
+ label: () => ctx.rte.getLocale().richTextEditor.linkUrl,
2633
+ type: "url",
2634
+ placeholder: () => ctx.rte.getLocale().richTextEditor.linkUrlPlaceholder,
2635
+ helperText: () => ctx.rte.getLocale().richTextEditor.linkUrlHelperText,
2636
+ slot: "header",
2637
+ value: () => this.getCurrentLink(ctx.view.state)?.href || "",
2638
+ onInput: () => {
2639
+ updateValidation();
2640
+ }
2641
+ });
2642
+ const applyButton = createButton(ctx, {
2643
+ label: () => ctx.rte.getLocale().richTextEditor.apply,
2644
+ variant: "popover-primary",
2645
+ disabled: () => {
2646
+ const link = this.getCurrentLink(ctx.view.state);
2647
+ return !(link && link.text.length && isValidUrl(link.href));
2648
+ },
2649
+ onClick: () => {
2650
+ const { state, dispatch } = ctx.view;
2651
+ this.insertLink(rte, urlField.value, textField.value)(state, dispatch);
2652
+ this.toolbarMenu.open = false;
2653
+ }
2654
+ });
2655
+ const updateValidation = () => {
2656
+ applyButton.querySelector("[data-vvd-component=\"button\"]").disabled = !(textField.value.length && isValidUrl(urlField.value));
2657
+ };
2658
+ const menu = createMenu(ctx, {
2659
+ label: () => ctx.rte.getLocale().richTextEditor.hyperlink,
2660
+ trigger: createButton(ctx, {
2661
+ label: () => ctx.rte.getLocale().richTextEditor.hyperlink,
2662
+ icon: "link-line"
2663
+ }),
2664
+ children: [createDiv(ctx, {
2665
+ className: "link-toolbar-menu",
2666
+ slot: "header",
2667
+ children: [
2668
+ textField,
2669
+ urlField,
2670
+ createDiv(ctx, {
2671
+ className: "link-action-bar",
2672
+ slot: "header",
2673
+ children: [createButton(ctx, {
2674
+ label: () => ctx.rte.getLocale().richTextEditor.cancel,
2675
+ variant: "popover",
2676
+ onClick: () => {
2677
+ this.toolbarMenu.open = false;
2678
+ }
2679
+ }), applyButton]
2680
+ })
2681
+ ]
2682
+ })]
2683
+ });
2684
+ this.toolbarMenu = menu.lastElementChild;
2685
+ return menu;
2686
+ }
2687
+ }, 1)];
2688
+ }
2689
+ getCurrentLink(state) {
2690
+ const selection = state.selection;
2691
+ if (!(selection instanceof prosemirror_state.TextSelection)) return null;
2692
+ const linkMark = state.schema.marks.link;
2693
+ const { $from, $to } = selection;
2694
+ const selectionStartMarks = state.selection.empty ? $from.marks() : $from.nodeAfter?.marks ?? [];
2695
+ const targetHref = linkMark.isInSet(selectionStartMarks)?.attrs.href;
2696
+ if (!targetHref) return null;
2697
+ const isTargetLink = (node) => linkMark.isInSet(node.marks)?.attrs.href === targetHref;
2698
+ let currentRun = null;
2699
+ const runs = [];
2700
+ state.doc.nodesBetween($from.start(), $to.end(), (node, pos) => {
2701
+ if (!node.isText) return true;
2702
+ const nodeEnd = pos + node.nodeSize;
2703
+ if (isTargetLink(node)) {
2704
+ if (!currentRun) {
2705
+ currentRun = {
2706
+ start: pos,
2707
+ end: nodeEnd
2708
+ };
2709
+ runs.push(currentRun);
2710
+ } else currentRun.end = nodeEnd;
2711
+ } else currentRun = null;
2712
+ return false;
2713
+ });
2714
+ const selectionRun = runs.find((run) => run.start <= selection.from && run.end >= selection.to);
2715
+ if (!selectionRun) return null;
2716
+ return {
2717
+ text: state.doc.textBetween(selectionRun.start, selectionRun.end, " "),
2718
+ href: targetHref,
2719
+ start: selectionRun.start,
2720
+ end: selectionRun.end
2721
+ };
2722
+ }
2723
+ insertLink(rte, href, text) {
2724
+ return (state, dispatch) => {
2725
+ let { from, to } = state.selection;
2726
+ const tr = state.tr;
2727
+ const existingLink = this.getCurrentLink(state);
2728
+ if (existingLink) {
2729
+ from = existingLink.start;
2730
+ to = existingLink.end;
2731
+ }
2732
+ tr.insertText(text, from, to);
2733
+ tr.addMark(from, from + text.length, rte.schema.marks.link.create({ href }));
2734
+ dispatch?.(tr.scrollIntoView());
2735
+ return true;
2736
+ };
2737
+ }
2738
+ };
2739
+ var RteLinkFeature = require_slottable_request.featureFacade(RteLinkFeatureImpl);
2740
+ //#endregion
2741
+ //#region src/lib/rich-text-editor/rte/features/inline-image.style.scss?inline
2742
+ var inline_image_style_default = ".inline-image-wrapper{vertical-align:text-bottom;display:inline-block}.inline-image{block-size:auto;display:block}.inline-image-popover{align-items:center;gap:4px;padding:8px;display:flex}.inline-image-placeholder{color:var(--vvd-color-canvas-text);font:var(--vvd-typography-base);font-feature-settings:normal;font-variant-ligatures:normal;overflow-wrap:normal;pointer-events:none;white-space:normal}";
2743
+ //#endregion
2744
+ //#region src/lib/rich-text-editor/rte/features/inline-image.ts
2745
+ var isGenerator$1 = (value) => value !== null && Boolean(value["next"]);
2746
+ var uniqueId = 1;
2747
+ var generateUniqueId = () => uniqueId++;
2748
+ var InlineImageView = class {
2749
+ constructor(node, view, getPos, config) {
2750
+ this.view = view;
2751
+ this.getPos = getPos;
2752
+ this.config = config;
2753
+ this.content = null;
2754
+ this.dom = document.createElement("div");
2755
+ this.dom.className = "inline-image-wrapper";
2756
+ this.imageUrl = node.attrs.imageUrl;
2757
+ this.img = document.createElement("img");
2758
+ this.initializeImg(node);
2759
+ const resolveResult = this.config.resolveUrl ? this.config.resolveUrl(this.imageUrl) : this.imageUrl;
2760
+ const initialResolvedUrl = isGenerator$1(resolveResult) ? null : resolveResult;
2761
+ this.handleResolvedUrl(initialResolvedUrl);
2762
+ if (isGenerator$1(resolveResult)) this.handleResolvedUrlGenerator(resolveResult);
2763
+ }
2764
+ setContent(content, { onDestroy, allowPopover } = {}) {
2765
+ this.content?.remove();
2766
+ this.onContentDestroy?.();
2767
+ this.content = content;
2768
+ if (content) {
2769
+ this.onContentDestroy = onDestroy;
2770
+ this.dom.appendChild(content);
2771
+ }
2772
+ Popover.setBlockPopover(this.dom, !allowPopover);
2773
+ }
2774
+ async handleResolvedUrlGenerator(generator) {
2775
+ const iterator = generator[Symbol.asyncIterator]();
2776
+ let result;
2777
+ do {
2778
+ result = await iterator.next();
2779
+ this.handleResolvedUrl(result.value);
2780
+ } while (!result.done);
2781
+ }
2782
+ handleResolvedUrl(result) {
2783
+ if (typeof result === "string") this.renderImg(result);
2784
+ else if (result?.type === "placeholder") {
2785
+ const slotName = `inline-image-placeholder-${generateUniqueId()}`;
2786
+ const slot = document.createElement("slot");
2787
+ slot.className = "inline-image-placeholder";
2788
+ slot.name = slotName;
2789
+ const onDestroy = result.create?.(slotName);
2790
+ const host = this.view.dom.getRootNode().host;
2791
+ require_slottable_request.dispatchSlottableRequest(host, "inline-image-placeholder", slotName, { url: this.imageUrl });
2792
+ this.setContent(slot, { onDestroy: () => {
2793
+ require_slottable_request.dispatchSlottableRequest(host, "inline-image-placeholder", slotName, require_slottable_request.removeSymbol);
2794
+ onDestroy?.();
2795
+ } });
2796
+ } else this.setContent(null);
2797
+ }
2798
+ initializeImg(node) {
2799
+ this.img.className = "inline-image";
2800
+ this.update(node);
2801
+ this.img.addEventListener("load", () => {
2802
+ const pos = this.getPos();
2803
+ if (pos) {
2804
+ const { state, dispatch } = this.view;
2805
+ const currentNode = state.doc.nodeAt(pos);
2806
+ if (!currentNode || currentNode.attrs.naturalWidth === this.img.naturalWidth && currentNode.attrs.naturalHeight === this.img.naturalHeight) return;
2807
+ const tr = state.tr;
2808
+ tr.setNodeAttribute(pos, "naturalWidth", this.img.naturalWidth);
2809
+ tr.setNodeAttribute(pos, "naturalHeight", this.img.naturalHeight);
2810
+ tr.setMeta("addToHistory", false);
2811
+ dispatch(tr);
2812
+ }
2813
+ });
2814
+ }
2815
+ renderImg(src) {
2816
+ this.img.src = sanitizeImageSrc(src);
2817
+ this.setContent(this.img, { allowPopover: true });
2818
+ }
2819
+ update(node) {
2820
+ this.img.alt = node.attrs.alt;
2821
+ this.img.width = node.attrs.naturalWidth;
2822
+ this.img.height = node.attrs.naturalHeight;
2823
+ this.img.style.maxWidth = node.attrs.size;
2824
+ return true;
2825
+ }
2826
+ destroy() {
2827
+ this.setContent(null);
2828
+ }
2829
+ };
2830
+ var RteInlineImageFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
2831
+ constructor(config = {}) {
2832
+ super();
2833
+ this.config = config;
2834
+ this.name = "RteInlineImageFeature";
2835
+ }
2836
+ getStyles() {
2837
+ return [this.contribution(inline_image_style_default)];
2838
+ }
2839
+ getSchema() {
2840
+ return [this.contribution({ nodes: { inlineImage: {
2841
+ inline: true,
2842
+ group: "inline",
2843
+ selectable: true,
2844
+ atom: true,
2845
+ attrs: {
2846
+ imageUrl: { validate: "string" },
2847
+ alt: {
2848
+ validate: "string",
2849
+ default: ""
2850
+ },
2851
+ size: {
2852
+ validate: "string|null",
2853
+ default: null
2854
+ },
2855
+ naturalWidth: {
2856
+ validate: "number|null",
2857
+ default: null
2858
+ },
2859
+ naturalHeight: {
2860
+ validate: "number|null",
2861
+ default: null
2862
+ }
2863
+ },
2864
+ parseDOM: [{
2865
+ tag: "img[src],img[data-src]",
2866
+ getAttrs: (dom) => {
2867
+ const parseDimension = (dim) => {
2868
+ const value = parseInt(dim ?? "", 10);
2869
+ return isNaN(value) ? null : value;
2870
+ };
2871
+ const srcAttr = dom.getAttribute("data-src") ?? dom.getAttribute("src");
2872
+ const imageUrl = this.config.parseUrlFromHtml ? this.config.parseUrlFromHtml(srcAttr) : srcAttr;
2873
+ if (imageUrl === null) return false;
2874
+ return {
2875
+ imageUrl,
2876
+ alt: dom.getAttribute("alt") || "",
2877
+ size: dom.style.maxWidth || null,
2878
+ naturalWidth: parseDimension(dom.getAttribute("width")),
2879
+ naturalHeight: parseDimension(dom.getAttribute("height"))
2880
+ };
2881
+ }
2882
+ }],
2883
+ /** Since we use a NodeView, this is only used for HTML serialization */
2884
+ toDOM: (node) => {
2885
+ const { imageUrl, alt, size, naturalWidth, naturalHeight } = node.attrs;
2886
+ const resolvedUrl = this.config.serializeUrlToHtml ? this.config.serializeUrlToHtml(imageUrl) : imageUrl;
2887
+ if (resolvedUrl === null) return document.createTextNode("");
2888
+ const attrs = {
2889
+ src: sanitizeImageSrc(resolvedUrl),
2890
+ "data-src": resolvedUrl,
2891
+ alt
2892
+ };
2893
+ if (size) attrs.style = `max-width: ${escapeCssProperty(size)}; height: auto;`;
2894
+ if (naturalWidth) attrs.width = naturalWidth;
2895
+ if (naturalHeight) attrs.height = naturalHeight;
2896
+ return ["img", attrs];
2897
+ }
2898
+ } } })];
2899
+ }
2900
+ getPlugins(rte) {
2901
+ let popover;
2902
+ return [this.contribution(new prosemirror_state.Plugin({
2903
+ props: { nodeViews: { inlineImage: (node, view, getPos) => new InlineImageView(node, view, getPos, this.config) } },
2904
+ view: (view) => {
2905
+ const ctx = new UiCtx(view, rte, {
2906
+ popupPlacement: "bottom",
2907
+ shouldReturnFocusToEditor: true
2908
+ });
2909
+ popover = rte.createComponent(Popover);
2910
+ popover.kind = "imageOptions";
2911
+ popover.offset = 4;
2912
+ const content = createDiv(ctx, {
2913
+ className: "inline-image-popover",
2914
+ children: [
2915
+ createButton(ctx, {
2916
+ label: () => ctx.rte.getLocale().richTextEditor.imageSizes.small,
2917
+ variant: "popover",
2918
+ active: () => this.getSelectedImageSize(ctx.view.state) === "small",
2919
+ onClick: () => {
2920
+ this.setSelectedImageSize("small")(ctx.view.state, ctx.view.dispatch);
2921
+ }
2922
+ }),
2923
+ createDivider(ctx),
2924
+ createButton(ctx, {
2925
+ label: () => ctx.rte.getLocale().richTextEditor.imageSizes.fit,
2926
+ variant: "popover",
2927
+ active: () => this.getSelectedImageSize(ctx.view.state) === "fit",
2928
+ onClick: () => {
2929
+ this.setSelectedImageSize("fit")(ctx.view.state, ctx.view.dispatch);
2930
+ }
2931
+ }),
2932
+ createDivider(ctx),
2933
+ createButton(ctx, {
2934
+ label: () => ctx.rte.getLocale().richTextEditor.imageSizes.original,
2935
+ variant: "popover",
2936
+ active: () => this.getSelectedImageSize(ctx.view.state) === "original",
2937
+ onClick: () => {
2938
+ this.setSelectedImageSize("original")(ctx.view.state, ctx.view.dispatch);
2939
+ }
2940
+ })
2941
+ ]
2942
+ });
2943
+ popover.appendChild(content);
2944
+ view.dom.getRootNode().querySelector(".popovers").appendChild(popover);
2945
+ return {
2946
+ update: (view) => {
2947
+ ctx.updateBindings();
2948
+ const selectedImage = this.getSelectedInlineImage(view.state);
2949
+ if (selectedImage) {
2950
+ popover.anchorEl = view.nodeDOM(selectedImage.pos);
2951
+ popover.requestOpenState(true);
2952
+ } else {
2953
+ popover.anchorEl = void 0;
2954
+ popover.requestOpenState(false);
2955
+ }
2956
+ },
2957
+ destroy: () => {
2958
+ popover.remove();
2959
+ }
2960
+ };
2961
+ }
2962
+ })), this.contribution((0, prosemirror_keymap.keymap)({ Escape: (state) => {
2963
+ if (this.getSelectedInlineImage(state)) {
2964
+ popover?.dismiss();
2965
+ return true;
2966
+ }
2967
+ return false;
2968
+ } }))];
2969
+ }
2970
+ calculateSmallWidth(naturalWidth) {
2971
+ return `${Math.min(300, naturalWidth / 2)}px`;
2972
+ }
2973
+ getSelectedInlineImage(state) {
2974
+ const sel = state.selection;
2975
+ if (sel instanceof prosemirror_state.NodeSelection && sel.node.type === state.schema.nodes.inlineImage) return {
2976
+ pos: sel.from,
2977
+ node: sel.node
2978
+ };
2979
+ return null;
2980
+ }
2981
+ setSelectedImageSize(size) {
2982
+ return (state, dispatch) => {
2983
+ const selectedImage = this.getSelectedInlineImage(state);
2984
+ if (!selectedImage) return false;
2985
+ const { naturalWidth } = selectedImage.node.attrs;
2986
+ if (size === "small" && naturalWidth === null) return false;
2987
+ const tr = state.tr;
2988
+ tr.setNodeAttribute(selectedImage.pos, "size", size === "small" ? this.calculateSmallWidth(naturalWidth) : size === "fit" ? "100%" : null);
2989
+ dispatch?.(tr.scrollIntoView());
2990
+ return true;
2991
+ };
2992
+ }
2993
+ getSelectedImageSize(state) {
2994
+ const selectedImage = this.getSelectedInlineImage(state);
2995
+ if (!selectedImage) return null;
2996
+ const { size, naturalWidth } = selectedImage.node.attrs;
2997
+ if (naturalWidth !== null && size === this.calculateSmallWidth(naturalWidth)) return "small";
2998
+ if (size === "100%") return "fit";
2999
+ if (size === null) return "original";
3000
+ return null;
3001
+ }
3002
+ };
3003
+ var RteInlineImageFeature = require_slottable_request.featureFacade(RteInlineImageFeatureImpl);
3004
+ //#endregion
3005
+ //#region src/shared/utils/promise.ts
3006
+ var resolvePromise = async (promise) => {
3007
+ try {
3008
+ return {
3009
+ type: "ok",
3010
+ result: await promise
3011
+ };
3012
+ } catch (e) {
3013
+ return {
3014
+ type: "error",
3015
+ error: e
3016
+ };
3017
+ }
3018
+ };
3019
+ //#endregion
3020
+ //#region src/lib/rich-text-editor/rte/features/file-handler.ts
3021
+ var RteFileHandlerFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3022
+ constructor(config) {
3023
+ super();
3024
+ this.config = config;
3025
+ this.name = "RteFileHandlerFeature";
3026
+ }
3027
+ getPlugins(rte) {
3028
+ const insertPointPlaceholderPlugin = new prosemirror_state.Plugin({
3029
+ state: {
3030
+ init() {
3031
+ return prosemirror_view.DecorationSet.empty;
3032
+ },
3033
+ apply(tr, set) {
3034
+ set = set.map(tr.mapping, tr.doc);
3035
+ const action = tr.getMeta(insertPointPlaceholderPlugin);
3036
+ if (action && action.add) {
3037
+ const placeholder = document.createElement("placeholder");
3038
+ const deco = prosemirror_view.Decoration.widget(action.add.pos, placeholder, {
3039
+ id: action.add.id,
3040
+ relaxedSide: true
3041
+ });
3042
+ set = set.add(tr.doc, [deco]);
3043
+ } else if (action && action.remove) set = set.remove(set.find(void 0, void 0, (spec) => spec.id == action.remove.id));
3044
+ return set;
3045
+ }
3046
+ },
3047
+ props: { decorations(state) {
3048
+ return this.getState(state);
3049
+ } }
3050
+ });
3051
+ const createInsertPointPlaceholder = (tr, pos) => {
3052
+ const id = require_randomId.generateRandomId();
3053
+ tr.setMeta(insertPointPlaceholderPlugin, { add: {
3054
+ id,
3055
+ pos
3056
+ } });
3057
+ return {
3058
+ getPos: (state) => {
3059
+ const found = insertPointPlaceholderPlugin.getState(state).find(void 0, void 0, (spec) => spec.id == id);
3060
+ return found.length ? found[0].from : null;
3061
+ },
3062
+ remove: (tr) => {
3063
+ tr.setMeta(insertPointPlaceholderPlugin, { remove: { id } });
3064
+ }
3065
+ };
3066
+ };
3067
+ const insertFragment = (tr, fragment, insertPoint) => {
3068
+ if (insertPoint.type === "selection") {
3069
+ const parsed = prosemirror_model.Slice.fromJSON(rte.schema, { content: fragment });
3070
+ tr.replaceSelection(parsed);
3071
+ } else {
3072
+ const parsed = prosemirror_model.Fragment.fromJSON(rte.schema, fragment);
3073
+ tr.insert(insertPoint.pos, parsed);
3074
+ }
3075
+ };
3076
+ const handleFiles = (files, insertPoint) => {
3077
+ const result = this.config.handleFiles(files);
3078
+ if (result === null) return;
3079
+ else if (result instanceof Promise) handleAsyncResult(result, insertPoint);
3080
+ else handleSyncResult(result, insertPoint);
3081
+ };
3082
+ const handleSyncResult = (result, insertPoint) => {
3083
+ const tr = rte.state.tr;
3084
+ insertFragment(tr, result, insertPoint);
3085
+ rte.dispatchTransaction(tr);
3086
+ };
3087
+ const handleAsyncResult = async (promise, insertPoint) => {
3088
+ const tr = rte.state.tr;
3089
+ if (insertPoint.type === "selection" && !tr.selection.empty) tr.deleteSelection();
3090
+ const pos = insertPoint.type === "selection" ? tr.selection.from : insertPoint.pos;
3091
+ const placeholder = createInsertPointPlaceholder(tr, pos);
3092
+ rte.dispatchTransaction(tr);
3093
+ const resolved = await resolvePromise(promise);
3094
+ const updatedPos = placeholder.getPos(rte.state);
3095
+ const insertTr = rte.state.tr;
3096
+ placeholder.remove(insertTr);
3097
+ if (updatedPos !== null && resolved.type === "ok") insertFragment(insertTr, resolved.result, {
3098
+ type: "pos",
3099
+ pos: updatedPos
3100
+ });
3101
+ rte.dispatchTransaction(insertTr);
3102
+ if (resolved.type === "error") console.error("Error in handleFiles handler:", resolved.error);
3103
+ };
3104
+ return [this.contribution(insertPointPlaceholderPlugin), this.contribution(new prosemirror_state.Plugin({ props: {
3105
+ handlePaste: (_view, event) => {
3106
+ const files = Array.from(event.clipboardData.files);
3107
+ if (!files.length) return false;
3108
+ handleFiles(files, { type: "selection" });
3109
+ return true;
3110
+ },
3111
+ handleDrop: (view, event) => {
3112
+ const files = Array.from(event.dataTransfer.files);
3113
+ if (!files.length) return false;
3114
+ let target = view.posAtCoords({
3115
+ left: event.clientX,
3116
+ top: event.clientY
3117
+ }).pos;
3118
+ if (view.dragging && view.dragging.slice) {
3119
+ const point = (0, prosemirror_transform.dropPoint)(view.state.doc, target, view.dragging.slice);
3120
+ if (point != null) target = point;
3121
+ }
3122
+ handleFiles(files, {
3123
+ type: "pos",
3124
+ pos: target
3125
+ });
3126
+ return true;
3127
+ }
3128
+ } }))];
3129
+ }
3130
+ };
3131
+ var RteFileHandlerFeature = require_slottable_request.featureFacade(RteFileHandlerFeatureImpl);
3132
+ //#endregion
3133
+ //#region src/lib/rich-text-editor/rte/features/drop-handler.ts
3134
+ var RteDropHandlerFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3135
+ constructor(config) {
3136
+ super();
3137
+ this.config = config;
3138
+ this.name = "RteDebugFeature";
3139
+ }
3140
+ getPlugins() {
3141
+ const dragOverResults = /* @__PURE__ */ new WeakMap();
3142
+ let lastResult = false;
3143
+ const onDragOver = (event) => {
3144
+ if (dragOverResults.get(event) !== void 0) return;
3145
+ lastResult = this.config.onViewportDragOver?.(event) ?? false;
3146
+ };
3147
+ const onDrop = (event) => {
3148
+ this.config.onViewportDrop?.(event);
3149
+ this.config.onViewportDragFinish?.();
3150
+ };
3151
+ const onDragEnd = () => {
3152
+ this.config.onViewportDragFinish?.();
3153
+ };
3154
+ let isEntering = false;
3155
+ const onDragEnter = () => {
3156
+ isEntering = true;
3157
+ window.setTimeout(() => isEntering = false, 0);
3158
+ };
3159
+ const onDragLeave = () => {
3160
+ if (isEntering) return;
3161
+ this.config.onViewportDragFinish?.();
3162
+ };
3163
+ return [this.contribution(new prosemirror_state.Plugin({ view: (view) => {
3164
+ const viewport = view.root.host.editorViewportElement;
3165
+ viewport.addEventListener("dragover", onDragOver);
3166
+ viewport.addEventListener("drop", onDrop);
3167
+ viewport.addEventListener("dragend", onDragEnd);
3168
+ viewport.addEventListener("dragenter", onDragEnter);
3169
+ viewport.addEventListener("dragleave", onDragLeave);
3170
+ return { destroy() {
3171
+ viewport.removeEventListener("dragover", onDragOver);
3172
+ viewport.removeEventListener("drop", onDrop);
3173
+ viewport.removeEventListener("dragend", onDragEnd);
3174
+ viewport.removeEventListener("dragenter", onDragEnter);
3175
+ viewport.removeEventListener("dragleave", onDragLeave);
3176
+ } };
3177
+ } })), this.contribution(new prosemirror_state.Plugin({ props: { handleDOMEvents: {
3178
+ dragover: (_view, event) => {
3179
+ const result = this.config.onViewportDragOver?.(event) ?? false;
3180
+ dragOverResults.set(event, result);
3181
+ lastResult = result;
3182
+ if (result) {
3183
+ event.stopImmediatePropagation();
3184
+ event.preventDefault();
3185
+ return true;
3186
+ }
3187
+ return false;
3188
+ },
3189
+ drop: () => {
3190
+ return lastResult;
3191
+ }
3192
+ } } }), require_slottable_request.contributionPriority.high)];
3193
+ }
3194
+ };
3195
+ var RteDropHandlerFeature = require_slottable_request.featureFacade(RteDropHandlerFeatureImpl);
3196
+ //#endregion
3197
+ //#region src/lib/rich-text-editor/rte/features/toolbar-button.ts
3198
+ var RteToolbarButtonFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3199
+ constructor(featureId, options) {
3200
+ super();
3201
+ this.featureId = featureId;
3202
+ this.options = options;
3203
+ this.name = `RteToolbarButtonFeature[${featureId}]`;
3204
+ }
3205
+ getToolbarItems() {
3206
+ return [this.contribution({
3207
+ section: "insert",
3208
+ render: (ctx) => createButton(ctx, {
3209
+ label: this.options.label,
3210
+ icon: this.options.icon,
3211
+ onClick: () => {
3212
+ this.executeAction(ctx);
3213
+ }
3214
+ })
3215
+ }, 2 + (this.options.order ?? 0) / Number.MAX_SAFE_INTEGER)];
3216
+ }
3217
+ executeAction(ctx) {
3218
+ const { action } = this.options;
3219
+ switch (action.type) {
3220
+ case "insert-text": {
3221
+ const { state, dispatch } = ctx.view;
3222
+ const { from, to } = state.selection;
3223
+ dispatch(state.tr.insertText(action.text, from, to));
3224
+ break;
3225
+ }
3226
+ }
3227
+ }
3228
+ };
3229
+ var RteToolbarButtonFeature = require_slottable_request.featureFacade(RteToolbarButtonFeatureImpl);
3230
+ //#endregion
3231
+ //#region src/lib/rich-text-editor/rte/features/atom.ts
3232
+ var isGenerator = (value) => value !== null && typeof value === "object" && "next" in value;
3233
+ var VALID_VARIANT = /^[a-zA-Z0-9-]+$/;
3234
+ var normalizeResolvedValue = (value) => {
3235
+ if (value == null) return {
3236
+ text: "",
3237
+ variant: []
3238
+ };
3239
+ if (typeof value === "string") return {
3240
+ text: value,
3241
+ variant: []
3242
+ };
3243
+ return {
3244
+ text: value.text,
3245
+ variant: (value.variant ?? []).filter((v) => {
3246
+ if (!VALID_VARIANT.test(v)) {
3247
+ console.warn(`[rich-text-editor] Ignoring invalid atom variant "${v}".`);
3248
+ return false;
3249
+ }
3250
+ return true;
3251
+ })
3252
+ };
3253
+ };
3254
+ var partsFor = (atomName, variant) => [`node--${atomName}`, ...variant.map((v) => `atom-variant--${v}`)].join(" ");
3255
+ var AtomView = class {
3256
+ constructor(node, config, atomName) {
3257
+ this.atomName = atomName;
3258
+ this.dom = document.createElement("span");
3259
+ this.dom.className = "atom-wrapper";
3260
+ const result = config.resolveValue ? config.resolveValue(node.attrs.value) : node.attrs.value;
3261
+ if (isGenerator(result)) {
3262
+ this.render(null);
3263
+ this.handleResolvedGenerator(result);
3264
+ } else this.render(result);
3265
+ }
3266
+ render(value) {
3267
+ const { text, variant } = normalizeResolvedValue(value);
3268
+ if (this.dom.textContent !== text) this.dom.textContent = text;
3269
+ const parts = partsFor(this.atomName, variant);
3270
+ if (this.dom.getAttribute("part") !== parts) this.dom.setAttribute("part", parts);
3271
+ }
3272
+ async handleResolvedGenerator(generator) {
3273
+ const iterator = generator[Symbol.asyncIterator]();
3274
+ try {
3275
+ let result;
3276
+ do {
3277
+ result = await iterator.next();
3278
+ this.render(result.value ?? null);
3279
+ } while (!result.done);
3280
+ } catch (error) {
3281
+ this.render(null);
3282
+ console.warn("[rich-text-editor] Error while resolving atom value:", error);
3283
+ }
3284
+ }
3285
+ };
3286
+ var RteAtomFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3287
+ constructor(atomName, config = {}) {
3288
+ super();
3289
+ this.atomName = atomName;
3290
+ this.config = config;
3291
+ this.name = `RteAtomFeature[${atomName}]`;
3292
+ }
3293
+ getSchema() {
3294
+ const atomSpec = {
3295
+ inline: true,
3296
+ group: "inline",
3297
+ selectable: true,
3298
+ atom: true,
3299
+ attrs: { value: { validate: "string" } },
3300
+ parseDOM: [{
3301
+ tag: `span[data-atom-type="${this.atomName}"][data-value]`,
3302
+ getAttrs: (dom) => ({ value: dom.getAttribute("data-value") })
3303
+ }],
3304
+ /** Since we use a NodeView, toDOM is only used for Rich Text View */
3305
+ toDOM: (node) => {
3306
+ const serializedValue = this.config.serializeValueToHtml ? this.config.serializeValueToHtml(node.attrs.value) : node.attrs.value;
3307
+ if (serializedValue === null) return document.createDocumentFragment();
3308
+ return [
3309
+ "span",
3310
+ { part: partsFor(this.atomName, []) },
3311
+ serializedValue
3312
+ ];
3313
+ },
3314
+ serializeToDOM: (node) => {
3315
+ const serializedValue = this.config.serializeValueToHtml ? this.config.serializeValueToHtml(node.attrs.value) : node.attrs.value;
3316
+ if (serializedValue === null) return document.createTextNode("");
3317
+ return [
3318
+ "span",
3319
+ {
3320
+ "data-atom-type": this.atomName,
3321
+ "data-value": node.attrs.value
3322
+ },
3323
+ serializedValue
3324
+ ];
3325
+ }
3326
+ };
3327
+ return [this.contribution({ nodes: { [this.atomName]: atomSpec } })];
3328
+ }
3329
+ getPlugins(_rte) {
3330
+ return [this.contribution(new prosemirror_state.Plugin({ props: { nodeViews: { [this.atomName]: (node) => new AtomView(node, this.config, this.atomName) } } }))];
3331
+ }
3332
+ };
3333
+ var RteAtomFeature = require_slottable_request.featureFacade(RteAtomFeatureImpl);
3334
+ //#endregion
3335
+ //#region src/lib/rich-text-editor/rte/features/input-rule.ts
3336
+ var RteInputRuleFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3337
+ constructor(featureId, options) {
3338
+ super();
3339
+ this.featureId = featureId;
3340
+ this.options = options;
3341
+ this.name = `RteInputRuleFeature[${featureId}]`;
3342
+ }
3343
+ getInputRules(rte) {
3344
+ const basePattern = `(?:${this.options.pattern.source})`;
3345
+ const handler = (state, match, start, end) => {
3346
+ const fragment = this.options.handler(match);
3347
+ if (!fragment) return null;
3348
+ return state.tr.replaceWith(start, end, prosemirror_model.Fragment.fromJSON(rte.schema, fragment));
3349
+ };
3350
+ const regex = this.options.matchAfterWhitespace ? new RegExp(`${basePattern} $`) : new RegExp(`${basePattern}$`);
3351
+ const spec = { rule: new prosemirror_inputrules.InputRule(regex, handler) };
3352
+ if (this.options.matchAfterWhitespace) spec.enterHandler = {
3353
+ regex: new RegExp(`${basePattern}$`),
3354
+ handler
3355
+ };
3356
+ return [this.contribution(spec)];
3357
+ }
3358
+ };
3359
+ var RteInputRuleFeature = require_slottable_request.featureFacade(RteInputRuleFeatureImpl);
3360
+ //#endregion
3361
+ //#region src/lib/rich-text-editor/rte/features/keyboard-shortcuts.ts
3362
+ function toCommand(handler, rteInstance) {
3363
+ return (_state, _dispatch) => handler(rteInstance);
3364
+ }
3365
+ var RteKeyboardShortcutsFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3366
+ constructor(featureId, options) {
3367
+ super();
3368
+ this.featureId = featureId;
3369
+ this.options = options;
3370
+ this.name = `RteKeyboardShortcutsFeature[${featureId}]`;
3371
+ }
3372
+ getPlugins(rte) {
3373
+ const bindings = {};
3374
+ for (const [key, handler] of Object.entries(this.options.shortcuts)) bindings[key] = toCommand(handler, rte.facade);
3375
+ return [this.contribution((0, prosemirror_keymap.keymap)(bindings), require_slottable_request.contributionPriority.high)];
3376
+ }
3377
+ };
3378
+ var RteKeyboardShortcutsFeature = require_slottable_request.featureFacade(RteKeyboardShortcutsFeatureImpl);
3379
+ //#endregion
3380
+ //#region src/lib/rich-text-editor/rte/features/suggest.style.scss?inline
3381
+ var suggest_style_default = ".suggest-popover{flex-direction:column;gap:2px;max-block-size:408px;min-inline-size:128px;max-inline-size:248px;padding:4px;display:flex}.suggest-loading-widget{vertical-align:middle;white-space:normal;align-items:center;margin-inline-start:2px;display:inline-flex}.suggest-empty-message{color:var(--vvd-color-neutral-300);font:var(--vvd-typography-base);text-align:center;justify-content:center;align-items:center;min-block-size:40px;display:flex}";
3382
+ //#endregion
3383
+ //#region src/lib/rich-text-editor/rte/features/suggest.ts
3384
+ var isPopoverOpen = (state) => Boolean(state?.suggestions && !state.dismissed);
3385
+ var popoverShowsResults = (state) => isPopoverOpen(state) && state.suggestions.items.length > 0;
3386
+ function findMatch(state, regex) {
3387
+ const { $cursor } = state.selection;
3388
+ if (!$cursor) return null;
3389
+ const textBefore = textBeforeCursor($cursor);
3390
+ const match = regex.exec(textBefore);
3391
+ if (!match) return null;
3392
+ const blockStart = $cursor.pos - $cursor.parentOffset;
3393
+ return {
3394
+ text: match[0],
3395
+ groups: [...match],
3396
+ start: blockStart + match.index,
3397
+ end: blockStart + match.index + match[0].length
3398
+ };
3399
+ }
3400
+ var replaceMatch = (view, match, fragment) => {
3401
+ const { state } = view;
3402
+ view.dispatch((0, prosemirror_history.closeHistory)(state.tr));
3403
+ const tr = view.state.tr;
3404
+ tr.replaceWith(match.start, match.end, prosemirror_model.Fragment.fromJSON(view.state.schema, fragment));
3405
+ const newPos = tr.mapping.map(match.end);
3406
+ tr.setSelection(prosemirror_state.TextSelection.create(tr.doc, newPos));
3407
+ view.dispatch(tr.scrollIntoView());
3408
+ };
3409
+ var RteSuggestFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3410
+ selectSuggestion(view, suggestState, suggestion) {
3411
+ const fragment = this.options.select(suggestion);
3412
+ replaceMatch(view, suggestState.match, fragment);
3413
+ view.focus();
3414
+ }
3415
+ async startLoadingSuggestions(match, dispatch) {
3416
+ const gen = ++this.loadGeneration;
3417
+ const suggestions = await this.options.load(match);
3418
+ if (gen !== this.loadGeneration) return;
3419
+ dispatch({
3420
+ type: "load",
3421
+ generation: gen,
3422
+ suggestions
3423
+ });
3424
+ }
3425
+ constructor(featureId, options) {
3426
+ super();
3427
+ this.featureId = featureId;
3428
+ this.options = options;
3429
+ this.pluginKey = new prosemirror_state.PluginKey("suggest");
3430
+ this.loadGeneration = 0;
3431
+ this.name = `RteSuggestFeature[${featureId}]`;
3432
+ }
3433
+ getStyles() {
3434
+ return [this.contribution(suggest_style_default)];
3435
+ }
3436
+ getPlugins(rte) {
3437
+ const createSuggestActionTr = (action) => rte.state.tr.setMeta(this.pluginKey, action);
3438
+ const dispatchSuggestAction = (action) => rte.dispatchTransaction(createSuggestActionTr(action));
3439
+ const suggestPlugin = new prosemirror_state.Plugin({
3440
+ key: this.pluginKey,
3441
+ state: {
3442
+ init: () => null,
3443
+ apply: (tr, prevState, _prevEditor, newEditor) => {
3444
+ const match = findMatch(newEditor, this.options.pattern);
3445
+ if (!match) return null;
3446
+ if (!prevState && !tr.docChanged) return null;
3447
+ if (prevState?.dismissed) return prevState;
3448
+ const loadingDecoration = (isLoading) => {
3449
+ if (!isLoading) return prosemirror_view.DecorationSet.empty;
3450
+ return Boolean(prevState?.loadingDecoration.find().length ?? 0) ? prevState.loadingDecoration.map(tr.mapping, tr.doc) : prosemirror_view.DecorationSet.create(tr.doc, [prosemirror_view.Decoration.widget(match.end, () => {
3451
+ const wrapper = document.createElement("span");
3452
+ wrapper.className = "suggest-loading-widget";
3453
+ const spinner = rte.createComponent(require_definition.ProgressRing);
3454
+ spinner.size = -6;
3455
+ wrapper.appendChild(spinner);
3456
+ return wrapper;
3457
+ }, {
3458
+ ignoreSelection: true,
3459
+ side: 1
3460
+ })]);
3461
+ };
3462
+ const action = tr.getMeta(this.pluginKey);
3463
+ if (prevState && action) switch (action.type) {
3464
+ case "load": return {
3465
+ ...prevState,
3466
+ suggestions: {
3467
+ generation: action.generation,
3468
+ items: action.suggestions,
3469
+ selectedIndex: 0,
3470
+ visibleFocus: false
3471
+ },
3472
+ loadingDecoration: loadingDecoration(false)
3473
+ };
3474
+ case "navigate": {
3475
+ /* v8 ignore next 3 -- defensive: navigate is only dispatched after results are loaded @preserve */
3476
+ if (!prevState.suggestions?.items.length) return prevState;
3477
+ if (!prevState.suggestions.visibleFocus) return {
3478
+ ...prevState,
3479
+ suggestions: {
3480
+ ...prevState.suggestions,
3481
+ visibleFocus: true
3482
+ }
3483
+ };
3484
+ const newIndex = Math.max(0, Math.min(prevState.suggestions.items.length - 1, prevState.suggestions.selectedIndex + (action.action === "up" ? -1 : 1)));
3485
+ return {
3486
+ ...prevState,
3487
+ suggestions: {
3488
+ ...prevState.suggestions,
3489
+ selectedIndex: newIndex
3490
+ }
3491
+ };
3492
+ }
3493
+ case "dismiss": return {
3494
+ ...prevState,
3495
+ dismissed: true,
3496
+ loadingDecoration: prosemirror_view.DecorationSet.empty
3497
+ };
3498
+ }
3499
+ if (!prevState) {
3500
+ this.startLoadingSuggestions(match.groups, dispatchSuggestAction);
3501
+ return {
3502
+ match,
3503
+ loadingDecoration: loadingDecoration(true)
3504
+ };
3505
+ }
3506
+ const matchChanged = match.groups[0] !== prevState.match.groups[0];
3507
+ if (matchChanged) this.startLoadingSuggestions(match.groups, dispatchSuggestAction);
3508
+ return {
3509
+ ...prevState,
3510
+ match,
3511
+ suggestions: prevState.suggestions ? {
3512
+ ...prevState.suggestions,
3513
+ visibleFocus: false
3514
+ } : void 0,
3515
+ loadingDecoration: loadingDecoration(matchChanged)
3516
+ };
3517
+ }
3518
+ },
3519
+ props: { decorations: (state) => {
3520
+ const suggestState = this.pluginKey.getState(state);
3521
+ if (!suggestState) return null;
3522
+ return suggestState.loadingDecoration.add(state.doc, [prosemirror_view.Decoration.inline(suggestState.match.start, suggestState.match.end, { id: `suggest-anchor-${this.featureId}` })]);
3523
+ } },
3524
+ view: (view) => {
3525
+ const ctx = new UiCtx(view, rte, {
3526
+ popupPlacement: "bottom",
3527
+ shouldReturnFocusToEditor: true
3528
+ });
3529
+ const popover = rte.createComponent(Popover);
3530
+ popover.anchorId = `suggest-anchor-${this.featureId}`;
3531
+ popover.kind = "autocomplete";
3532
+ popover.offset = 4;
3533
+ const content = createDiv(ctx, {
3534
+ className: "suggest-popover",
3535
+ children: []
3536
+ });
3537
+ popover.appendChild(content);
3538
+ view.dom.getRootNode().querySelector(".popovers").appendChild(popover);
3539
+ const emptySlotName = `${this.featureId}-suggestions-empty`;
3540
+ const host = view.dom.getRootNode().host;
3541
+ let emptySlotShowing = false;
3542
+ const updateEmptySlotShowing = (showing) => {
3543
+ if (!emptySlotShowing && showing) require_slottable_request.dispatchSlottableRequest(host, "suggestions-empty-state", emptySlotName, { id: this.featureId });
3544
+ if (emptySlotShowing && !showing) require_slottable_request.dispatchSlottableRequest(host, "suggestions-empty-state", emptySlotName, require_slottable_request.removeSymbol);
3545
+ emptySlotShowing = showing;
3546
+ };
3547
+ const updatePopoverContent = (suggestState) => {
3548
+ content.innerHTML = "";
3549
+ const suggestions = suggestState.suggestions;
3550
+ const showEmptyState = suggestions.items.length === 0;
3551
+ updateEmptySlotShowing(showEmptyState);
3552
+ if (showEmptyState) {
3553
+ const emptySlot = document.createElement("slot");
3554
+ emptySlot.name = emptySlotName;
3555
+ emptySlot.textContent = rte.getLocale().richTextEditor.suggestNoResults;
3556
+ content.appendChild(createDiv(ctx, {
3557
+ className: "suggest-empty-message",
3558
+ children: [emptySlot]
3559
+ }));
3560
+ return;
3561
+ }
3562
+ for (const [index, suggestion] of suggestions.items.entries()) {
3563
+ const item = rte.createComponent(require_option.ListboxOption);
3564
+ item.text = suggestion.text;
3565
+ item.textSecondary = suggestion.textSecondary;
3566
+ if (index === suggestions.selectedIndex) {
3567
+ item.selected = true;
3568
+ if (suggestions.visibleFocus) item._highlighted = true;
3569
+ queueMicrotask(() => {
3570
+ item.scrollIntoView({ block: "nearest" });
3571
+ });
3572
+ }
3573
+ item.addEventListener("click", (e) => {
3574
+ e.preventDefault();
3575
+ e.stopPropagation();
3576
+ this.selectSuggestion(view, suggestState, suggestion);
3577
+ });
3578
+ content.appendChild(item);
3579
+ }
3580
+ };
3581
+ return {
3582
+ update: (view) => {
3583
+ ctx.updateBindings();
3584
+ const suggestState = this.pluginKey.getState(view.state);
3585
+ const showPopover = isPopoverOpen(suggestState);
3586
+ popover.requestOpenState(showPopover);
3587
+ if (showPopover) updatePopoverContent(suggestState);
3588
+ else updateEmptySlotShowing(false);
3589
+ },
3590
+ destroy: () => {
3591
+ updateEmptySlotShowing(false);
3592
+ popover.remove();
3593
+ }
3594
+ };
3595
+ }
3596
+ });
3597
+ return [this.contribution(suggestPlugin), this.contribution((0, prosemirror_keymap.keymap)({
3598
+ ArrowUp: (state, dispatch) => {
3599
+ if (!popoverShowsResults(this.pluginKey.getState(state))) return false;
3600
+ dispatch?.(createSuggestActionTr({
3601
+ type: "navigate",
3602
+ action: "up"
3603
+ }));
3604
+ return true;
3605
+ },
3606
+ ArrowDown: (state, dispatch) => {
3607
+ if (!popoverShowsResults(this.pluginKey.getState(state))) return false;
3608
+ dispatch?.(createSuggestActionTr({
3609
+ type: "navigate",
3610
+ action: "down"
3611
+ }));
3612
+ return true;
3613
+ },
3614
+ Enter: (state, _dispatch, view) => {
3615
+ const suggestState = this.pluginKey.getState(state);
3616
+ if (!popoverShowsResults(suggestState)) return false;
3617
+ const suggestion = suggestState.suggestions.items[suggestState.suggestions.selectedIndex];
3618
+ /* v8 ignore next 3 -- defensive: view is always passed by keymap @preserve */
3619
+ if (view) this.selectSuggestion(view, suggestState, suggestion);
3620
+ return true;
3621
+ },
3622
+ Escape: (state, dispatch) => {
3623
+ if (!isPopoverOpen(this.pluginKey.getState(state))) return false;
3624
+ dispatch?.(createSuggestActionTr({ type: "dismiss" }));
3625
+ return true;
3626
+ }
3627
+ }), require_slottable_request.contributionPriority.high)];
3628
+ }
3629
+ };
3630
+ var RteSuggestFeature = require_slottable_request.featureFacade(RteSuggestFeatureImpl);
3631
+ //#endregion
3632
+ //#region src/lib/rich-text-editor/rte/features/character-count.ts
3633
+ var countCharacters = (doc) => doc.textBetween(0, doc.content.size, void 0, " ").length;
3634
+ var RteCharacterCountFeatureImpl = class extends require_slottable_request.RteFeatureImpl {
3635
+ constructor(config) {
3636
+ super();
3637
+ this.config = config;
3638
+ this.name = "RteCharacterCountFeature";
3639
+ }
3640
+ getPlugins() {
3641
+ const limit = this.config?.limit;
3642
+ if (limit === void 0) return [];
3643
+ return [this.contribution(new prosemirror_state.Plugin({ filterTransaction: (transaction, state) => {
3644
+ if (!transaction.docChanged) return true;
3645
+ const oldSize = countCharacters(state.doc);
3646
+ const newSize = countCharacters(transaction.doc);
3647
+ if (newSize <= limit) return true;
3648
+ if (oldSize > limit) return newSize <= oldSize;
3649
+ if (!transaction.getMeta("paste")) return false;
3650
+ const pos = transaction.selection.$head.pos;
3651
+ const from = pos - (newSize - limit);
3652
+ const to = pos;
3653
+ transaction.deleteRange(from, to);
3654
+ return countCharacters(transaction.doc) <= limit;
3655
+ } }))];
3656
+ }
3657
+ getPublicInterface(rte) {
3658
+ const limit = this.config?.limit;
3659
+ return {
3660
+ get characters() {
3661
+ return countCharacters(rte.state.doc);
3662
+ },
3663
+ get limit() {
3664
+ return limit;
3665
+ }
3666
+ };
3667
+ }
3668
+ };
3669
+ var RteCharacterCountFeature = require_slottable_request.featureFacade(RteCharacterCountFeatureImpl);
3670
+ //#endregion
3671
+ //#region src/lib/rich-text-editor/definition.ts
3672
+ var richTextEditorDefinition = require_vivid_element.defineVividComponent("rich-text-editor", RichTextEditor, RichTextEditorTemplate, [
3673
+ require_definition$8.dividerDefinition,
3674
+ require_definition$9.selectDefinition,
3675
+ require_definition$7.listboxOptionDefinition,
3676
+ require_definition$1.buttonDefinition,
3677
+ require_definition$6.tooltipDefinition,
3678
+ require_definition$4.menuDefinition,
3679
+ require_definition$3.menuItemDefinition,
3680
+ require_definition$5.textFieldDefinition,
3681
+ popoverDefinition,
3682
+ require_definition.progressRingDefinition
3683
+ ], {
3684
+ styles: rich_text_editor_default,
3685
+ shadowOptions: { delegatesFocus: true }
3686
+ });
3687
+ /**
3688
+ * Registers the rich-text-editor element with the design system.
3689
+ *
3690
+ * @param prefix - the prefix to use for the component name
3691
+ */
3692
+ var registerRichTextEditor = require_vivid_element.createRegisterFunction(richTextEditorDefinition);
3693
+ //#endregion
3694
+ Object.defineProperty(exports, "RichTextEditor", {
3695
+ enumerable: true,
3696
+ get: function() {
3697
+ return RichTextEditor;
3698
+ }
3699
+ });
3700
+ Object.defineProperty(exports, "RteAlignmentFeature", {
3701
+ enumerable: true,
3702
+ get: function() {
3703
+ return RteAlignmentFeature;
3704
+ }
3705
+ });
3706
+ Object.defineProperty(exports, "RteAtomFeature", {
3707
+ enumerable: true,
3708
+ get: function() {
3709
+ return RteAtomFeature;
3710
+ }
3711
+ });
3712
+ Object.defineProperty(exports, "RteBase", {
3713
+ enumerable: true,
3714
+ get: function() {
3715
+ return RteBase;
3716
+ }
3717
+ });
3718
+ Object.defineProperty(exports, "RteBoldFeature", {
3719
+ enumerable: true,
3720
+ get: function() {
3721
+ return RteBoldFeature;
3722
+ }
3723
+ });
3724
+ Object.defineProperty(exports, "RteCharacterCountFeature", {
3725
+ enumerable: true,
3726
+ get: function() {
3727
+ return RteCharacterCountFeature;
3728
+ }
3729
+ });
3730
+ Object.defineProperty(exports, "RteConfig", {
3731
+ enumerable: true,
3732
+ get: function() {
3733
+ return RteConfig;
3734
+ }
3735
+ });
3736
+ Object.defineProperty(exports, "RteDropHandlerFeature", {
3737
+ enumerable: true,
3738
+ get: function() {
3739
+ return RteDropHandlerFeature;
3740
+ }
3741
+ });
3742
+ Object.defineProperty(exports, "RteFileHandlerFeature", {
3743
+ enumerable: true,
3744
+ get: function() {
3745
+ return RteFileHandlerFeature;
3746
+ }
3747
+ });
3748
+ Object.defineProperty(exports, "RteFontSizePickerFeature", {
3749
+ enumerable: true,
3750
+ get: function() {
3751
+ return RteFontSizePickerFeature;
3752
+ }
3753
+ });
3754
+ Object.defineProperty(exports, "RteHardBreakFeature", {
3755
+ enumerable: true,
3756
+ get: function() {
3757
+ return RteHardBreakFeature;
3758
+ }
3759
+ });
3760
+ Object.defineProperty(exports, "RteHtmlParser", {
3761
+ enumerable: true,
3762
+ get: function() {
3763
+ return RteHtmlParser;
3764
+ }
3765
+ });
3766
+ Object.defineProperty(exports, "RteHtmlSerializer", {
3767
+ enumerable: true,
3768
+ get: function() {
3769
+ return RteHtmlSerializer;
3770
+ }
3771
+ });
3772
+ Object.defineProperty(exports, "RteInlineImageFeature", {
3773
+ enumerable: true,
3774
+ get: function() {
3775
+ return RteInlineImageFeature;
3776
+ }
3777
+ });
3778
+ Object.defineProperty(exports, "RteInputRuleFeature", {
3779
+ enumerable: true,
3780
+ get: function() {
3781
+ return RteInputRuleFeature;
3782
+ }
3783
+ });
3784
+ Object.defineProperty(exports, "RteItalicFeature", {
3785
+ enumerable: true,
3786
+ get: function() {
3787
+ return RteItalicFeature;
3788
+ }
3789
+ });
3790
+ Object.defineProperty(exports, "RteKeyboardShortcutsFeature", {
3791
+ enumerable: true,
3792
+ get: function() {
3793
+ return RteKeyboardShortcutsFeature;
3794
+ }
3795
+ });
3796
+ Object.defineProperty(exports, "RteLinkFeature", {
3797
+ enumerable: true,
3798
+ get: function() {
3799
+ return RteLinkFeature;
3800
+ }
3801
+ });
3802
+ Object.defineProperty(exports, "RteListFeature", {
3803
+ enumerable: true,
3804
+ get: function() {
3805
+ return RteListFeature;
3806
+ }
3807
+ });
3808
+ Object.defineProperty(exports, "RteMonospaceFeature", {
3809
+ enumerable: true,
3810
+ get: function() {
3811
+ return RteMonospaceFeature;
3812
+ }
3813
+ });
3814
+ Object.defineProperty(exports, "RtePlaceholderFeature", {
3815
+ enumerable: true,
3816
+ get: function() {
3817
+ return RtePlaceholderFeature;
3818
+ }
3819
+ });
3820
+ Object.defineProperty(exports, "RteStrikethroughFeature", {
3821
+ enumerable: true,
3822
+ get: function() {
3823
+ return RteStrikethroughFeature;
3824
+ }
3825
+ });
3826
+ Object.defineProperty(exports, "RteSuggestFeature", {
3827
+ enumerable: true,
3828
+ get: function() {
3829
+ return RteSuggestFeature;
3830
+ }
3831
+ });
3832
+ Object.defineProperty(exports, "RteTextBlockPickerFeature", {
3833
+ enumerable: true,
3834
+ get: function() {
3835
+ return RteTextBlockPickerFeature;
3836
+ }
3837
+ });
3838
+ Object.defineProperty(exports, "RteTextColorPickerFeature", {
3839
+ enumerable: true,
3840
+ get: function() {
3841
+ return RteTextColorPickerFeature;
3842
+ }
3843
+ });
3844
+ Object.defineProperty(exports, "RteToolbarButtonFeature", {
3845
+ enumerable: true,
3846
+ get: function() {
3847
+ return RteToolbarButtonFeature;
3848
+ }
3849
+ });
3850
+ Object.defineProperty(exports, "RteToolbarFeature", {
3851
+ enumerable: true,
3852
+ get: function() {
3853
+ return RteToolbarFeature;
3854
+ }
3855
+ });
3856
+ Object.defineProperty(exports, "RteUnderlineFeature", {
798
3857
  enumerable: true,
799
3858
  get: function() {
800
- return Select;
3859
+ return RteUnderlineFeature;
801
3860
  }
802
3861
  });
803
- Object.defineProperty(exports, "registerSelect", {
3862
+ Object.defineProperty(exports, "registerRichTextEditor", {
804
3863
  enumerable: true,
805
3864
  get: function() {
806
- return registerSelect;
3865
+ return registerRichTextEditor;
807
3866
  }
808
3867
  });
809
- Object.defineProperty(exports, "selectDefinition", {
3868
+ Object.defineProperty(exports, "richTextEditorDefinition", {
810
3869
  enumerable: true,
811
3870
  get: function() {
812
- return selectDefinition;
3871
+ return richTextEditorDefinition;
813
3872
  }
814
3873
  });