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