@mekari/pixel3-rich-text-editor 0.0.18 → 0.1.0-dev.1

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 (67) hide show
  1. package/dist/chunk-4KJOYLJI.mjs +168 -0
  2. package/dist/{chunk-JAKI6TU2.mjs → chunk-4SN6MBXS.mjs} +8 -22
  3. package/dist/chunk-4TUA5VF4.mjs +173 -0
  4. package/dist/{chunk-2OCRJNTJ.mjs → chunk-7RMCTPMN.mjs} +2 -2
  5. package/dist/{chunk-RNQQ7LGC.mjs → chunk-C7IUW3FX.mjs} +73 -1
  6. package/dist/{chunk-ES3FCTTF.mjs → chunk-JE7IG7UU.mjs} +27 -6
  7. package/dist/{chunk-73N5SLQ5.mjs → chunk-MGNW6NK2.mjs} +82 -25
  8. package/dist/{chunk-FZPMIQTC.mjs → chunk-OZGNQAK5.mjs} +2 -1
  9. package/dist/{chunk-VK7QDWXR.mjs → chunk-PTKS3BYW.mjs} +18 -5
  10. package/dist/{chunk-V52XUOVW.mjs → chunk-SBD2AUDA.mjs} +10 -2
  11. package/dist/{chunk-GVMGRBDI.mjs → chunk-TNDDXUVW.mjs} +5 -1
  12. package/dist/{chunk-WBMECFO3.mjs → chunk-X25J3BAC.mjs} +18 -46
  13. package/dist/{chunk-HF36L4GZ.mjs → chunk-ZAXJ3BEP.mjs} +2 -0
  14. package/dist/{chunk-5IPS4HT7.mjs → chunk-ZRAXSVO5.mjs} +1 -1
  15. package/dist/editor-toolbar.d.mts +9 -5
  16. package/dist/editor-toolbar.d.ts +9 -5
  17. package/dist/editor-toolbar.js +193 -92
  18. package/dist/editor-toolbar.mjs +7 -7
  19. package/dist/extensions/align-extension.js +75 -21
  20. package/dist/extensions/align-extension.mjs +2 -2
  21. package/dist/extensions/color-extension.js +69 -0
  22. package/dist/extensions/color-extension.mjs +2 -2
  23. package/dist/extensions/heading-extension.js +85 -45
  24. package/dist/extensions/heading-extension.mjs +2 -2
  25. package/dist/extensions/icons.d.mts +5 -1
  26. package/dist/extensions/icons.d.ts +5 -1
  27. package/dist/extensions/icons.js +76 -0
  28. package/dist/extensions/icons.mjs +9 -1
  29. package/dist/extensions/index.js +115 -71
  30. package/dist/extensions/index.mjs +6 -6
  31. package/dist/extensions/link-extension.js +85 -4
  32. package/dist/extensions/link-extension.mjs +2 -2
  33. package/dist/extensions/mention-list-extension.d.mts +33 -0
  34. package/dist/extensions/mention-list-extension.d.ts +33 -0
  35. package/dist/extensions/mention-list-extension.js +194 -0
  36. package/dist/extensions/mention-list-extension.mjs +7 -0
  37. package/dist/extensions/single-extension.d.mts +1 -1
  38. package/dist/extensions/single-extension.d.ts +1 -1
  39. package/dist/extensions/single-extension.js +73 -1
  40. package/dist/extensions/single-extension.mjs +2 -2
  41. package/dist/index.d.mts +1 -1
  42. package/dist/index.d.ts +1 -1
  43. package/dist/index.js +552 -104
  44. package/dist/index.mjs +14 -12
  45. package/dist/metafile-cjs.json +1 -1
  46. package/dist/metafile-esm.json +1 -1
  47. package/dist/modules/rich-text-editor.connects.js +2 -0
  48. package/dist/modules/rich-text-editor.connects.mjs +1 -1
  49. package/dist/modules/rich-text-editor.hooks.js +2 -0
  50. package/dist/modules/rich-text-editor.hooks.mjs +2 -2
  51. package/dist/modules/rich-text-editor.props.d.mts +7 -3
  52. package/dist/modules/rich-text-editor.props.d.ts +7 -3
  53. package/dist/modules/rich-text-editor.props.js +5 -1
  54. package/dist/modules/rich-text-editor.props.mjs +1 -1
  55. package/dist/modules/rich-text-editor.types.d.mts +18 -4
  56. package/dist/modules/rich-text-editor.types.d.ts +18 -4
  57. package/dist/rich-text-editor.d.mts +15 -4
  58. package/dist/rich-text-editor.d.ts +15 -4
  59. package/dist/rich-text-editor.js +552 -104
  60. package/dist/rich-text-editor.mjs +14 -12
  61. package/dist/rte-style-provider.js +1 -1
  62. package/dist/rte-style-provider.mjs +4 -4
  63. package/dist/rte-suggestion.d.mts +7 -0
  64. package/dist/rte-suggestion.d.ts +7 -0
  65. package/dist/rte-suggestion.js +354 -0
  66. package/dist/rte-suggestion.mjs +8 -0
  67. package/package.json +15 -11
package/dist/index.js CHANGED
@@ -37,8 +37,8 @@ __export(src_exports, {
37
37
  module.exports = __toCommonJS(src_exports);
38
38
 
39
39
  // src/rich-text-editor.tsx
40
- var import_vue18 = require("vue");
41
- var import_vue19 = require("vue");
40
+ var import_vue20 = require("vue");
41
+ var import_vue21 = require("vue");
42
42
  var import_pixel3_utils4 = require("@mekari/pixel3-utils");
43
43
 
44
44
  // src/modules/rich-text-editor.props.ts
@@ -70,6 +70,10 @@ var richTextEditorProps = {
70
70
  hasBorder: {
71
71
  type: Boolean,
72
72
  default: true
73
+ },
74
+ suggestions: {
75
+ type: Array,
76
+ default: () => []
73
77
  }
74
78
  };
75
79
  var RTEStyleProviderProps = {
@@ -77,7 +81,7 @@ var RTEStyleProviderProps = {
77
81
  type: String
78
82
  }
79
83
  };
80
- var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus"]);
84
+ var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus", "action", "paste"]);
81
85
 
82
86
  // src/modules/rich-text-editor.hooks.ts
83
87
  var import_vue = require("vue");
@@ -92,6 +96,7 @@ function richTextEditorConnect(state, classes) {
92
96
  placeholder,
93
97
  maxlength,
94
98
  options,
99
+ suggestions,
95
100
  hasBorder,
96
101
  isInvalid,
97
102
  isDisabled
@@ -103,6 +108,7 @@ function richTextEditorConnect(state, classes) {
103
108
  placeholder,
104
109
  maxlength,
105
110
  options,
111
+ suggestions,
106
112
  isInvalid,
107
113
  isDisabled,
108
114
  rootProps: {
@@ -154,13 +160,14 @@ var useRTEStyleProvider = /* @__PURE__ */ __name((props) => {
154
160
  }, "useRTEStyleProvider");
155
161
 
156
162
  // src/rich-text-editor.tsx
157
- var import_vue_3 = require("@tiptap/vue-3");
163
+ var import_vue_32 = require("@tiptap/vue-3");
158
164
  var import_starter_kit = __toESM(require("@tiptap/starter-kit"));
159
165
  var import_extension_underline = __toESM(require("@tiptap/extension-underline"));
160
166
  var import_extension_text_align = __toESM(require("@tiptap/extension-text-align"));
161
167
  var import_extension_text_style = __toESM(require("@tiptap/extension-text-style"));
162
168
  var import_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"));
163
169
  var import_extension_character_count = __toESM(require("@tiptap/extension-character-count"));
170
+ var import_extension_mention = __toESM(require("@tiptap/extension-mention"));
164
171
  var import_extension_color = require("@tiptap/extension-color");
165
172
  var import_extension_link = __toESM(require("@tiptap/extension-link"));
166
173
  var import_extension_highlight = __toESM(require("@tiptap/extension-highlight"));
@@ -170,6 +177,9 @@ var import_pixel3_form_control = require("@mekari/pixel3-form-control");
170
177
  // src/editor-toolbar.tsx
171
178
  var import_vue14 = require("vue");
172
179
  var import_vue15 = require("vue");
180
+ var import_css5 = require("@mekari/pixel3-styled-system/css");
181
+ var import_pixel3_divider = require("@mekari/pixel3-divider");
182
+ var import_pixel3_scrollbar = require("@mekari/pixel3-scrollbar");
173
183
 
174
184
  // src/extensions/heading-extension.tsx
175
185
  var import_vue4 = require("vue");
@@ -499,6 +509,74 @@ var CaretIcon = (0, import_vue3.defineComponent)({
499
509
  }, null)]);
500
510
  }
501
511
  });
512
+ var ImageIcon = (0, import_vue3.defineComponent)({
513
+ name: "ImageIcon",
514
+ setup() {
515
+ return () => (0, import_vue2.createVNode)("svg", {
516
+ "xmlns": "http://www.w3.org/2000/svg",
517
+ "width": "20",
518
+ "height": "20",
519
+ "viewBox": "0 0 20 20",
520
+ "fill": "none"
521
+ }, [(0, import_vue2.createVNode)("path", {
522
+ "fill-rule": "evenodd",
523
+ "clip-rule": "evenodd",
524
+ "d": "M9.13948 1.25H10.8605C12.3328 1.24998 13.5133 1.24997 14.4405 1.37376C15.4002 1.50189 16.2001 1.77481 16.8347 2.4051C17.4701 3.03609 17.7459 3.83259 17.8753 4.78811C18 5.70986 18 6.88312 18 8.34439V11.6556C18 13.1169 18 14.2901 17.8753 15.2119C17.7459 16.1674 17.4701 16.9639 16.8347 17.5949C16.2001 18.2252 15.4002 18.4981 14.4405 18.6262C13.5133 18.75 12.3328 18.75 10.8605 18.75H9.13947C7.66718 18.75 6.48666 18.75 5.55953 18.6262C4.59985 18.4981 3.79994 18.2252 3.16528 17.5949C2.58896 17.0226 2.30764 16.313 2.16398 15.4695C1.99993 14.5064 1.99996 13.2565 2 11.6731L2 8.34442C1.99998 6.88313 1.99997 5.70987 2.12475 4.78811C2.25411 3.83259 2.5299 3.03609 3.16528 2.4051C3.79994 1.77481 4.59985 1.50189 5.55953 1.37376C6.48666 1.24997 7.66719 1.24998 9.13948 1.25ZM5.75805 2.86056C4.96282 2.96674 4.53137 3.16245 4.22226 3.46942C3.91387 3.77568 3.71778 4.20206 3.61119 4.98935C3.50162 5.79875 3.5 6.87016 3.5 8.4V11.6C3.5 12.5721 3.50087 13.3576 3.52902 14.0064L6.03954 12.2878C6.94782 11.6827 8.2354 11.7423 9.0689 12.4535L9.07527 12.4589L9.33734 12.6877C9.68567 12.9822 10.2858 12.9815 10.6328 12.6855L13.984 9.82945C14.6747 9.24036 15.6655 9.09888 16.5 9.40545V8.4C16.5 6.87016 16.4984 5.79875 16.3888 4.98935C16.2822 4.20206 16.0861 3.77568 15.7777 3.46942C15.4686 3.16245 15.0372 2.96674 14.242 2.86056C13.4257 2.75157 12.3456 2.75 10.8056 2.75H9.19445C7.65442 2.75 6.57433 2.75157 5.75805 2.86056ZM16.2474 10.9638L16.5 11.1945V11.6C16.5 13.1298 16.4984 14.2013 16.3888 15.0107C16.2822 15.7979 16.0861 16.2243 15.7777 16.5306C15.4686 16.8376 15.0372 17.0333 14.242 17.1394C13.4257 17.2484 12.3456 17.25 10.8056 17.25H9.19445C7.65442 17.25 6.57433 17.2484 5.75805 17.1394C4.96282 17.0333 4.53137 16.8376 4.22226 16.5306C4.01416 16.3239 3.85786 16.0633 3.74539 15.6761L6.87456 13.534C7.23802 13.2943 7.78269 13.3303 8.09262 13.5923L8.35477 13.8211L8.36118 13.8266C9.26993 14.6019 10.6976 14.6019 11.6063 13.8266L14.9572 10.9709C15.3024 10.6764 15.8983 10.6739 16.2474 10.9638ZM5.22222 6.8C5.22222 5.49725 6.28423 4.45 7.58334 4.45C8.88244 4.45 9.94445 5.49725 9.94445 6.8C9.94445 8.10276 8.88244 9.15 7.58334 9.15C6.28423 9.15 5.22222 8.10276 5.22222 6.8Z",
525
+ "fill": "currentColor"
526
+ }, null)]);
527
+ }
528
+ });
529
+ var FileIcon = (0, import_vue3.defineComponent)({
530
+ name: "FileIcon",
531
+ setup() {
532
+ return () => (0, import_vue2.createVNode)("svg", {
533
+ "xmlns": "http://www.w3.org/2000/svg",
534
+ "width": "18",
535
+ "height": "17",
536
+ "viewBox": "0 0 18 17",
537
+ "fill": "none"
538
+ }, [(0, import_vue2.createVNode)("path", {
539
+ "fill-rule": "evenodd",
540
+ "clip-rule": "evenodd",
541
+ "d": "M11.6901 2.47169C10.3906 1.1761 8.28282 1.1761 6.98332 2.47169L3.07076 6.37248C0.976415 8.46053 0.976415 11.845 3.07076 13.933C5.16636 16.0223 8.56492 16.0223 10.6605 13.933L16.2205 8.3898C16.5138 8.09734 16.9887 8.09806 17.2811 8.39139C17.5736 8.68473 17.5729 9.1596 17.2795 9.45205L11.7196 14.9953C9.03856 17.6682 4.69271 17.6682 2.0117 14.9953C-0.670564 12.3211 -0.670564 7.98442 2.0117 5.31022L5.92426 1.40943C7.80917 -0.469814 10.8643 -0.469812 12.7492 1.40943C14.6354 3.28992 14.6354 6.33973 12.7492 8.22022L8.83664 12.121C7.74783 13.2066 5.98345 13.2066 4.89464 12.121C3.80458 11.0342 3.80458 9.27127 4.89464 8.18449L8.8072 4.2837C9.10053 3.99125 9.5754 3.99196 9.86786 4.2853C10.1603 4.57863 10.1596 5.0535 9.86626 5.34596L5.9537 9.24675C5.45156 9.74738 5.45156 10.5581 5.9537 11.0588C6.45709 11.5606 7.27419 11.5606 7.77758 11.0588L11.6901 7.15797C12.9884 5.86363 12.9884 3.76603 11.6901 2.47169Z",
542
+ "fill": "currentColor"
543
+ }, null)]);
544
+ }
545
+ });
546
+ var AudioIcon = (0, import_vue3.defineComponent)({
547
+ name: "AudioIcon",
548
+ setup() {
549
+ return () => (0, import_vue2.createVNode)("svg", {
550
+ "xmlns": "http://www.w3.org/2000/svg",
551
+ "width": "20",
552
+ "height": "20",
553
+ "viewBox": "0 0 20 20",
554
+ "fill": "none"
555
+ }, [(0, import_vue2.createVNode)("path", {
556
+ "fill-rule": "evenodd",
557
+ "clip-rule": "evenodd",
558
+ "d": "M6.32334 4.94737C6.32334 2.91036 7.96446 1.25 10 1.25C12.0355 1.25 13.6767 2.91036 13.6767 4.94737V10C13.6767 12.037 12.0355 13.6974 10 13.6974C7.96446 13.6974 6.32334 12.037 6.32334 10V4.94737ZM10 2.75C8.80284 2.75 7.82334 3.7288 7.82334 4.94737V10C7.82334 11.2186 8.80284 12.1974 10 12.1974C11.1972 12.1974 12.1767 11.2186 12.1767 10V4.94737C12.1767 3.7288 11.1972 2.75 10 2.75ZM14.9948 9.67107C15.409 9.66825 15.7471 10.0017 15.7499 10.4159C15.7686 13.1719 13.4277 15.3958 10.75 15.7526L10.75 17.25H11.6724C12.0866 17.25 12.4224 17.5858 12.4224 18C12.4224 18.4142 12.0866 18.75 11.6724 18.75H8.3276C7.91339 18.75 7.5776 18.4142 7.5776 18C7.5776 17.5858 7.91339 17.25 8.3276 17.25H9.24997L9.24996 15.7526C6.57163 15.3957 4.25 13.1696 4.25 10.4211C4.25 10.0068 4.58579 9.67105 5 9.67105C5.41421 9.67105 5.75 10.0068 5.75 10.4211C5.75 12.4712 7.71926 14.3026 9.99995 14.3026C12.2856 14.3026 14.2638 12.4679 14.2499 10.4262C14.2471 10.012 14.5806 9.67389 14.9948 9.67107Z",
559
+ "fill": "currentColor"
560
+ }, null)]);
561
+ }
562
+ });
563
+ var MentionIcon = (0, import_vue3.defineComponent)({
564
+ name: "MentionIcon",
565
+ setup() {
566
+ return () => (0, import_vue2.createVNode)("svg", {
567
+ "xmlns": "http://www.w3.org/2000/svg",
568
+ "width": "18",
569
+ "height": "18",
570
+ "viewBox": "0 0 18 18",
571
+ "fill": "none"
572
+ }, [(0, import_vue2.createVNode)("path", {
573
+ "fill-rule": "evenodd",
574
+ "clip-rule": "evenodd",
575
+ "d": "M5.04155 0.82474C6.82687 -0.0106618 8.84196 -0.218789 10.7603 0.234079C12.6787 0.686946 14.388 1.77428 15.6112 3.3199C16.8345 4.86553 17.5 6.7789 17.5 8.75V9.55C17.5 10.3854 17.1681 11.1866 16.5774 11.7774C15.9866 12.3681 15.1854 12.7 14.35 12.7C13.5146 12.7 12.7134 12.3681 12.1226 11.7774C11.9824 11.6371 11.8567 11.485 11.7466 11.3234C11.0222 12.1662 9.94841 12.7 8.74991 12.7C6.56839 12.7 4.79991 10.9315 4.79991 8.74999C4.79991 6.56847 6.56839 4.79999 8.74991 4.79999C9.67546 4.79999 10.5267 5.11833 11.2 5.65148V5.55C11.2 5.13579 11.5358 4.8 11.95 4.8C12.3642 4.8 12.7 5.13579 12.7 5.55V9.55C12.7 9.98761 12.8738 10.4073 13.1833 10.7167C13.4927 11.0262 13.9124 11.2 14.35 11.2C14.7876 11.2 15.2073 11.0262 15.5167 10.7167C15.8262 10.4073 16 9.98761 16 9.55V8.75C16 7.1168 15.4486 5.53144 14.435 4.25078C13.4215 2.97012 12.0052 2.06919 10.4157 1.69395C8.8262 1.31872 7.15655 1.49117 5.67729 2.18336C4.19802 2.87555 2.9958 4.04692 2.26541 5.50771C1.53502 6.96849 1.31925 8.63309 1.65306 10.2318C1.98687 11.8305 2.85069 13.2697 4.10459 14.3162C5.35848 15.3627 6.92898 15.9551 8.56164 15.9976C10.1943 16.04 11.7934 15.5299 13.1 14.55C13.4314 14.3015 13.9015 14.3686 14.15 14.7C14.3985 15.0314 14.3314 15.5015 14 15.75C12.4231 16.9327 10.4931 17.5483 8.52266 17.497C6.55222 17.4458 4.65679 16.7308 3.14347 15.4678C1.63015 14.2048 0.587595 12.4679 0.184723 10.5384C-0.218148 8.6089 0.0422661 6.5999 0.923772 4.83689C1.80528 3.07387 3.25623 1.66014 5.04155 0.82474ZM8.74991 6.29999C7.39682 6.29999 6.29991 7.3969 6.29991 8.74999C6.29991 10.1031 7.39682 11.2 8.74991 11.2C10.103 11.2 11.1999 10.1031 11.1999 8.74999C11.1999 7.3969 10.103 6.29999 8.74991 6.29999Z",
576
+ "fill": "currentColor"
577
+ }, null)]);
578
+ }
579
+ });
502
580
 
503
581
  // src/extensions/heading-extension.tsx
504
582
  var HeadingExtention = (0, import_vue5.defineComponent)({
@@ -516,7 +594,8 @@ var HeadingExtention = (0, import_vue5.defineComponent)({
516
594
  editor
517
595
  }) {
518
596
  return () => (0, import_vue4.createVNode)(import_pixel3_popover.MpPopover, {
519
- "id": "popover-heading-extention"
597
+ "id": "popover-heading-extention",
598
+ "usePortal": true
520
599
  }, {
521
600
  default: () => [(0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverTrigger, null, {
522
601
  default: () => [(0, import_vue4.withDirectives)((0, import_vue4.createVNode)("button", {
@@ -587,84 +666,55 @@ var HeadingExtention = (0, import_vue5.defineComponent)({
587
666
  })
588
667
  }, {
589
668
  default: () => [(0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverList, {
590
- "class": (0, import_css.css)({
591
- gap: "2",
592
- alignItems: "flex-start",
593
- paddingLeft: "3"
594
- })
669
+ "data-pixel-rte": true
595
670
  }, {
596
671
  default: () => [(0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
597
- "class": {
598
- "is-active": editor == null ? void 0 : editor.isActive("heading", {
599
- level: 1
600
- }),
601
- "text-sizing": true
602
- },
672
+ "is-active": editor == null ? void 0 : editor.isActive("heading", {
673
+ level: 1
674
+ }),
603
675
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().toggleHeading({
604
676
  level: 1
605
677
  }).run()
606
678
  }, {
607
679
  default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
608
680
  "as": "h1",
609
- "size": "h1",
610
- "class": (0, import_css.css)({
611
- color: "currentColor"
612
- })
681
+ "size": "h1"
613
682
  }, {
614
683
  default: () => [(0, import_vue4.createTextVNode)("Heading 1")]
615
684
  })]
616
685
  }), (0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
617
- "class": {
618
- "is-active": editor == null ? void 0 : editor.isActive("heading", {
619
- level: 2
620
- }),
621
- "text-sizing": true
622
- },
686
+ "is-active": editor == null ? void 0 : editor.isActive("heading", {
687
+ level: 2
688
+ }),
623
689
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().toggleHeading({
624
690
  level: 2
625
691
  }).run()
626
692
  }, {
627
693
  default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
628
694
  "as": "h2",
629
- "size": "h2",
630
- "class": (0, import_css.css)({
631
- color: "currentColor"
632
- })
695
+ "size": "h2"
633
696
  }, {
634
697
  default: () => [(0, import_vue4.createTextVNode)("Heading 2")]
635
698
  })]
636
699
  }), (0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
637
- "class": {
638
- "is-active": editor == null ? void 0 : editor.isActive("heading", {
639
- level: 3
640
- }),
641
- "text-sizing": true
642
- },
700
+ "is-active": editor == null ? void 0 : editor.isActive("heading", {
701
+ level: 3
702
+ }),
643
703
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().toggleHeading({
644
704
  level: 3
645
705
  }).run()
646
706
  }, {
647
707
  default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
648
708
  "as": "h3",
649
- "size": "h3",
650
- "class": (0, import_css.css)({
651
- color: "currentColor"
652
- })
709
+ "size": "h3"
653
710
  }, {
654
711
  default: () => [(0, import_vue4.createTextVNode)("Heading 3")]
655
712
  })]
656
713
  }), (0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
657
- "class": {
658
- "is-active": editor == null ? void 0 : editor.isActive("paragraph"),
659
- "text-sizing": true
660
- },
714
+ "is-active": editor == null ? void 0 : editor.isActive("paragraph"),
661
715
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setParagraph().run()
662
716
  }, {
663
- default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
664
- "class": (0, import_css.css)({
665
- color: "currentColor"
666
- })
667
- }, {
717
+ default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, null, {
668
718
  default: () => [(0, import_vue4.createTextVNode)("Normal text")]
669
719
  })]
670
720
  })]
@@ -699,7 +749,8 @@ var AlignExtention = (0, import_vue7.defineComponent)({
699
749
  });
700
750
  }, "isActiveAlignment");
701
751
  return () => (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopover, {
702
- "id": "popover-align-extention"
752
+ "id": "popover-align-extention",
753
+ "usePortal": true
703
754
  }, {
704
755
  default: () => [(0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverTrigger, null, {
705
756
  default: () => [(0, import_vue6.withDirectives)((0, import_vue6.createVNode)("button", {
@@ -721,40 +772,25 @@ var AlignExtention = (0, import_vue7.defineComponent)({
721
772
  })
722
773
  }, {
723
774
  default: () => [(0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverList, {
724
- "class": (0, import_css2.css)({
725
- gap: "2",
726
- alignItems: "center"
727
- })
775
+ "data-pixel-rte": true
728
776
  }, {
729
777
  default: () => [(0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
730
- "class": {
731
- "is-active": isActiveAlignment("left"),
732
- "text-sizing": true
733
- },
778
+ "is-active": isActiveAlignment("left"),
734
779
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("left").run()
735
780
  }, {
736
781
  default: () => [(0, import_vue6.createVNode)(AlignLeftIcon, null, null)]
737
782
  }), (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
738
- "class": {
739
- "is-active": isActiveAlignment("center"),
740
- "text-sizing": true
741
- },
783
+ "is-active": isActiveAlignment("center"),
742
784
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("center").run()
743
785
  }, {
744
786
  default: () => [(0, import_vue6.createVNode)(AlignCenterIcon, null, null)]
745
787
  }), (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
746
- "class": {
747
- "is-active": isActiveAlignment("right"),
748
- "text-sizing": true
749
- },
788
+ "is-active": isActiveAlignment("right"),
750
789
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("right").run()
751
790
  }, {
752
791
  default: () => [(0, import_vue6.createVNode)(AlignRightIcon, null, null)]
753
792
  }), (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
754
- "class": {
755
- "is-active": isActiveAlignment("justify"),
756
- "text-sizing": true
757
- },
793
+ "is-active": isActiveAlignment("justify"),
758
794
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("justify").run()
759
795
  }, {
760
796
  default: () => [(0, import_vue6.createVNode)(AlignJustifyIcon, null, null)]
@@ -800,7 +836,11 @@ var SingleExtention = (0, import_vue9.defineComponent)({
800
836
  orderedList: (0, import_vue8.createVNode)(OrderedListIcon, null, null),
801
837
  undo: (0, import_vue8.createVNode)(UndoIcon, null, null),
802
838
  redo: (0, import_vue8.createVNode)(RedoIcon, null, null),
803
- clear: (0, import_vue8.createVNode)(ClearIcon, null, null)
839
+ clear: (0, import_vue8.createVNode)(ClearIcon, null, null),
840
+ image: (0, import_vue8.createVNode)(ImageIcon, null, null),
841
+ file: (0, import_vue8.createVNode)(FileIcon, null, null),
842
+ audio: (0, import_vue8.createVNode)(AudioIcon, null, null),
843
+ mention: (0, import_vue8.createVNode)(MentionIcon, null, null)
804
844
  };
805
845
  return () => (0, import_vue8.withDirectives)((0, import_vue8.createVNode)("button", {
806
846
  "class": {
@@ -864,6 +904,7 @@ var ColorExtension = (0, import_vue11.defineComponent)({
864
904
  "preset": colorPreset,
865
905
  "variant": "basic",
866
906
  "placement": "bottom-start",
907
+ "usePortal": true,
867
908
  "isShowPreset": true,
868
909
  "isShowInput": false,
869
910
  "class": (0, import_css3.css)({
@@ -928,6 +969,7 @@ var LinkExtension = (0, import_vue13.defineComponent)({
928
969
  popperInstance.destroy();
929
970
  }
930
971
  popperInstance = (0, import_core.createPopper)(target, popoverRef.value, {
972
+ strategy: "fixed",
931
973
  onFirstUpdate: () => {
932
974
  if (popperInstance) {
933
975
  popperInstance.setOptions({
@@ -986,6 +1028,14 @@ var LinkExtension = (0, import_vue13.defineComponent)({
986
1028
  }
987
1029
  onClosePopover();
988
1030
  }, "onSetLink");
1031
+ const onOpenInNewTab = /* @__PURE__ */ __name(() => {
1032
+ const trimmedUrl = url.value.trim();
1033
+ if (!trimmedUrl) {
1034
+ return;
1035
+ }
1036
+ const normalizedUrl = /^(https?:)?\/\//i.test(trimmedUrl) ? trimmedUrl : `https://${trimmedUrl}`;
1037
+ window.open(normalizedUrl, "_blank", "noopener,noreferrer");
1038
+ }, "onOpenInNewTab");
989
1039
  const onClosePopover = /* @__PURE__ */ __name(() => {
990
1040
  isShowPopover.value = false;
991
1041
  editor == null ? void 0 : editor.commands.setTextSelection({
@@ -1029,10 +1079,9 @@ var LinkExtension = (0, import_vue13.defineComponent)({
1029
1079
  default: () => [(0, import_vue12.createVNode)("div", {
1030
1080
  "ref": popoverRef,
1031
1081
  "data-pixel-rte": true,
1032
- "style": {
1033
- position: "absolute",
1034
- zIndex: "var(--mp-z-index-popover)"
1035
- }
1082
+ "class": (0, import_css4.css)({
1083
+ zIndex: "popover"
1084
+ })
1036
1085
  }, [(0, import_vue12.createVNode)("div", {
1037
1086
  "class": (0, import_css4.css)({
1038
1087
  display: "flex",
@@ -1065,6 +1114,11 @@ var LinkExtension = (0, import_vue13.defineComponent)({
1065
1114
  }, null) : (0, import_vue12.createVNode)(import_pixel3_button.MpButton, {
1066
1115
  "leftIcon": "check",
1067
1116
  "onClick": onSetLink
1117
+ }, null), isEditLink.value && (0, import_vue12.createVNode)(import_pixel3_button.MpButton, {
1118
+ "leftIcon": "newtab",
1119
+ "variant": "ghost",
1120
+ "isDisabled": !url.value.trim(),
1121
+ "onClick": onOpenInNewTab
1068
1122
  }, null), isEditLink.value ? (0, import_vue12.createVNode)(import_pixel3_button.MpButton, {
1069
1123
  "leftIcon": "delete",
1070
1124
  "variant": "ghost",
@@ -1079,9 +1133,9 @@ var LinkExtension = (0, import_vue13.defineComponent)({
1079
1133
  });
1080
1134
 
1081
1135
  // src/editor-toolbar.tsx
1082
- var import_pixel3_divider = require("@mekari/pixel3-divider");
1083
1136
  var EditorToolbar = (0, import_vue15.defineComponent)({
1084
1137
  name: "EditorToolbar",
1138
+ emits: ["clickImage", "clickFile", "clickAudio"],
1085
1139
  props: {
1086
1140
  editor: {
1087
1141
  type: Object
@@ -1093,8 +1147,10 @@ var EditorToolbar = (0, import_vue15.defineComponent)({
1093
1147
  setup({
1094
1148
  editor,
1095
1149
  options
1150
+ }, {
1151
+ emit
1096
1152
  }) {
1097
- const items = ["heading", "bold", "italic", "underline", "strike", "blockquote", "bulletList", "orderedList", "textColor", "fillColor", "textLink", "align", "undo", "redo", "clear"];
1153
+ const items = ["heading", "bold", "italic", "underline", "strike", "blockquote", "bulletList", "orderedList", "textColor", "fillColor", "textLink", "align", "undo", "redo", "clear", "image", "file", "audio", "mention"];
1098
1154
  const itemOptions = {
1099
1155
  heading: {
1100
1156
  tooltipLabel: "Text style",
@@ -1157,52 +1213,104 @@ var EditorToolbar = (0, import_vue15.defineComponent)({
1157
1213
  clear: {
1158
1214
  tooltipLabel: "Reset format",
1159
1215
  onClick: () => (editor == null ? void 0 : editor.chain()).focus().unsetAllMarks().run()
1216
+ },
1217
+ image: {
1218
+ tooltipLabel: "Add image",
1219
+ onClick: () => emit("clickImage")
1220
+ },
1221
+ file: {
1222
+ tooltipLabel: "Add file",
1223
+ onClick: () => emit("clickFile")
1224
+ },
1225
+ audio: {
1226
+ tooltipLabel: "Add audio",
1227
+ onClick: () => emit("clickAudio")
1228
+ },
1229
+ mention: {
1230
+ tooltipLabel: "Mention",
1231
+ editor,
1232
+ onClick: () => (editor == null ? void 0 : editor.chain()).focus().insertContent("@").run()
1160
1233
  }
1161
1234
  };
1162
- const renderExtension = /* @__PURE__ */ __name((item) => {
1163
- const options2 = itemOptions[item];
1164
- if (!options2)
1235
+ const getResolvedItem = /* @__PURE__ */ __name((option) => {
1236
+ if (typeof option === "string") {
1237
+ return {
1238
+ item: option
1239
+ };
1240
+ }
1241
+ return {
1242
+ item: option.value,
1243
+ tooltip: option.tooltip
1244
+ };
1245
+ }, "getResolvedItem");
1246
+ const renderExtension = /* @__PURE__ */ __name((option) => {
1247
+ const {
1248
+ item,
1249
+ tooltip
1250
+ } = getResolvedItem(option);
1251
+ if (!items.includes(item))
1252
+ return null;
1253
+ const resolvedItem = item;
1254
+ const resolvedOptions = itemOptions[resolvedItem];
1255
+ if (!resolvedOptions)
1165
1256
  return null;
1166
- switch (item) {
1257
+ const tooltipLabel = tooltip || resolvedOptions.tooltipLabel;
1258
+ switch (resolvedItem) {
1167
1259
  case "heading":
1168
1260
  return (0, import_vue14.createVNode)(HeadingExtention, {
1169
- "tooltipLabel": options2.tooltipLabel,
1261
+ "tooltipLabel": tooltipLabel,
1170
1262
  "editor": editor
1171
1263
  }, null);
1172
1264
  case "align":
1173
1265
  return (0, import_vue14.createVNode)(AlignExtention, {
1174
- "tooltipLabel": options2.tooltipLabel,
1266
+ "tooltipLabel": tooltipLabel,
1175
1267
  "editor": editor
1176
1268
  }, null);
1177
1269
  case "textColor":
1178
1270
  case "fillColor":
1179
1271
  return (0, import_vue14.createVNode)(ColorExtension, {
1180
- "tooltipLabel": options2.tooltipLabel,
1272
+ "tooltipLabel": tooltipLabel,
1181
1273
  "editor": editor,
1182
- "type": options2.type
1274
+ "type": resolvedOptions.type
1183
1275
  }, null);
1184
1276
  case "textLink":
1185
1277
  return (0, import_vue14.createVNode)(LinkExtension, {
1186
- "tooltipLabel": options2.tooltipLabel,
1278
+ "tooltipLabel": tooltipLabel,
1187
1279
  "editor": editor
1188
1280
  }, null);
1189
1281
  default:
1190
1282
  return (0, import_vue14.createVNode)(SingleExtention, {
1191
- "name": item,
1192
- "tooltipLabel": options2.tooltipLabel,
1193
- "onClick": options2.onClick,
1283
+ "name": resolvedItem,
1284
+ "tooltipLabel": tooltipLabel,
1285
+ "onClick": resolvedOptions.onClick,
1194
1286
  "editor": editor
1195
1287
  }, null);
1196
1288
  }
1197
1289
  }, "renderExtension");
1198
- return () => (0, import_vue14.createVNode)("div", null, [options == null ? void 0 : options.map((option, index) => (0, import_vue14.createVNode)(import_vue14.Fragment, null, [option.map((item) => {
1199
- if (items.includes(item)) {
1200
- return renderExtension(item);
1290
+ return () => (0, import_vue14.createVNode)(import_pixel3_scrollbar.MpScrollbar, {
1291
+ "options": {
1292
+ overflow: {
1293
+ y: "hide",
1294
+ x: "scroll"
1295
+ }
1201
1296
  }
1202
- }), index !== (options == null ? void 0 : options.length) - 1 && (0, import_vue14.createVNode)(import_pixel3_divider.MpDivider, {
1203
- "id": "divider-toolbar",
1204
- "orientation": "vertical"
1205
- }, null)]))]);
1297
+ }, {
1298
+ default: () => [(0, import_vue14.createVNode)("div", {
1299
+ "class": (0, import_css5.css)({
1300
+ display: "flex",
1301
+ alignItems: "stretch",
1302
+ gap: "1"
1303
+ })
1304
+ }, [options == null ? void 0 : options.map((option, index) => (0, import_vue14.createVNode)(import_vue14.Fragment, null, [option.map((item) => {
1305
+ const resolvedItem = typeof item === "string" ? item : item.value;
1306
+ if (items.includes(resolvedItem)) {
1307
+ return renderExtension(item);
1308
+ }
1309
+ }), index !== (options == null ? void 0 : options.length) - 1 && (0, import_vue14.createVNode)(import_pixel3_divider.MpDivider, {
1310
+ "id": "divider-toolbar",
1311
+ "orientation": "vertical"
1312
+ }, null)]))])]
1313
+ });
1206
1314
  }
1207
1315
  });
1208
1316
 
@@ -1223,8 +1331,334 @@ var MpRTEStyleProvider = (0, import_vue17.defineComponent)({
1223
1331
  }
1224
1332
  });
1225
1333
 
1334
+ // src/rte-suggestion.ts
1335
+ var import_vue_3 = require("@tiptap/vue-3");
1336
+ var import_core2 = require("@popperjs/core");
1337
+
1338
+ // src/extensions/mention-list-extension.tsx
1339
+ var import_vue18 = require("vue");
1340
+ var import_vue19 = require("vue");
1341
+ var import_css6 = require("@mekari/pixel3-styled-system/css");
1342
+ var import_pixel3_avatar = require("@mekari/pixel3-avatar");
1343
+ var import_pixel3_popover3 = require("@mekari/pixel3-popover");
1344
+ var import_pixel3_text2 = require("@mekari/pixel3-text");
1345
+ var avatarVariantColors = ["violet", "lime", "amber", "sky", "pink", "teal", "rose", "stone"];
1346
+ var getAvatarVariantColor = /* @__PURE__ */ __name((index) => {
1347
+ return avatarVariantColors[index % avatarVariantColors.length];
1348
+ }, "getAvatarVariantColor");
1349
+ var MentionList = (0, import_vue19.defineComponent)({
1350
+ name: "MentionList",
1351
+ props: {
1352
+ items: {
1353
+ type: Array,
1354
+ default: () => []
1355
+ },
1356
+ command: {
1357
+ type: Function,
1358
+ required: true
1359
+ }
1360
+ },
1361
+ setup(props, {
1362
+ expose
1363
+ }) {
1364
+ const selectedIndex = (0, import_vue19.ref)(0);
1365
+ const listRef = (0, import_vue19.ref)(null);
1366
+ const scrollToFocusedItem = /* @__PURE__ */ __name(() => {
1367
+ (0, import_vue19.nextTick)(() => {
1368
+ if (!listRef.value)
1369
+ return;
1370
+ const targetItem = listRef.value.querySelector('[data-active="true"], [data-highlight]');
1371
+ if (targetItem) {
1372
+ targetItem.scrollIntoView({
1373
+ block: "nearest"
1374
+ });
1375
+ }
1376
+ });
1377
+ }, "scrollToFocusedItem");
1378
+ (0, import_vue19.watch)(() => props.items, () => {
1379
+ selectedIndex.value = 0;
1380
+ });
1381
+ const onSelect = /* @__PURE__ */ __name((index) => {
1382
+ const item = props.items[index];
1383
+ if (item) {
1384
+ props.command({
1385
+ ...item,
1386
+ label: item.name
1387
+ });
1388
+ }
1389
+ }, "onSelect");
1390
+ const onKeyDown = /* @__PURE__ */ __name(({
1391
+ event
1392
+ }) => {
1393
+ if (!props.items.length) {
1394
+ return false;
1395
+ }
1396
+ if (event.key === "ArrowUp") {
1397
+ event.preventDefault();
1398
+ const total = props.items.length;
1399
+ selectedIndex.value = (selectedIndex.value + total - 1) % total;
1400
+ scrollToFocusedItem();
1401
+ return true;
1402
+ }
1403
+ if (event.key === "ArrowDown") {
1404
+ event.preventDefault();
1405
+ selectedIndex.value = (selectedIndex.value + 1) % props.items.length;
1406
+ scrollToFocusedItem();
1407
+ return true;
1408
+ }
1409
+ if (event.key === "Enter") {
1410
+ event.preventDefault();
1411
+ onSelect(selectedIndex.value);
1412
+ return true;
1413
+ }
1414
+ return false;
1415
+ }, "onKeyDown");
1416
+ expose({
1417
+ onKeyDown
1418
+ });
1419
+ return () => (0, import_vue18.createVNode)(import_pixel3_popover3.MpPopover, {
1420
+ "id": "popover-rte-mention-list",
1421
+ "is-manual": true,
1422
+ "is-default-open": true,
1423
+ "is-open": true
1424
+ }, {
1425
+ default: () => [(0, import_vue18.createVNode)(import_pixel3_popover3.MpPopoverContent, {
1426
+ "class": (0, import_css6.css)({
1427
+ width: "280px",
1428
+ maxHeight: "284px",
1429
+ overflowY: "auto"
1430
+ })
1431
+ }, {
1432
+ default: () => [(0, import_vue18.createVNode)(import_pixel3_popover3.MpPopoverList, {
1433
+ "ref": (element) => {
1434
+ var _a;
1435
+ if (!element) {
1436
+ listRef.value = null;
1437
+ return;
1438
+ }
1439
+ listRef.value = (_a = element.$el) != null ? _a : element;
1440
+ },
1441
+ "data-pixel-rte": true
1442
+ }, {
1443
+ default: () => [!props.items.length && (0, import_vue18.createVNode)(import_pixel3_text2.MpText, {
1444
+ "color": "text.secondary",
1445
+ "class": (0, import_css6.css)({
1446
+ px: "3",
1447
+ py: "2"
1448
+ })
1449
+ }, {
1450
+ default: () => [(0, import_vue18.createTextVNode)("No result")]
1451
+ }), props.items.map((item, index) => {
1452
+ return (0, import_vue18.createVNode)(import_pixel3_popover3.MpPopoverListItem, {
1453
+ "key": `${item.id}-${index}`,
1454
+ "is-active": selectedIndex.value === index,
1455
+ "onMousedown": (event) => event.preventDefault(),
1456
+ "onMouseenter": () => {
1457
+ selectedIndex.value = index;
1458
+ },
1459
+ "onClick": () => {
1460
+ onSelect(index);
1461
+ }
1462
+ }, {
1463
+ default: () => [(0, import_vue18.createVNode)("div", {
1464
+ "class": (0, import_css6.css)({
1465
+ display: "flex",
1466
+ alignItems: "center",
1467
+ gap: "2",
1468
+ width: "full",
1469
+ minWidth: "0"
1470
+ })
1471
+ }, [item.avatar && (0, import_vue18.createVNode)(import_pixel3_avatar.MpAvatar, {
1472
+ "id": `avatar-rte-mention-${index}`,
1473
+ "name": item.avatar,
1474
+ "size": "lg",
1475
+ "variant-color": getAvatarVariantColor(index)
1476
+ }, null), (0, import_vue18.createVNode)("div", {
1477
+ "class": (0, import_css6.css)({
1478
+ display: "flex",
1479
+ flexDirection: "column",
1480
+ alignItems: "flex-start",
1481
+ minWidth: "0",
1482
+ flex: "1 1 0%"
1483
+ })
1484
+ }, [(0, import_vue18.createVNode)(import_pixel3_text2.MpText, {
1485
+ "size": "label",
1486
+ "is-truncated": true
1487
+ }, {
1488
+ default: () => [item.name || "Unknown"]
1489
+ }), item.description && (0, import_vue18.createVNode)(import_pixel3_text2.MpText, {
1490
+ "size": "label-small",
1491
+ "color": "text.secondary",
1492
+ "is-truncated": true
1493
+ }, {
1494
+ default: () => [item.description]
1495
+ })])])]
1496
+ });
1497
+ })]
1498
+ })]
1499
+ })]
1500
+ });
1501
+ }
1502
+ });
1503
+
1504
+ // src/rte-suggestion.ts
1505
+ var MAX_SUGGESTION_ITEMS = 10;
1506
+ var getFilteredSuggestionItems = /* @__PURE__ */ __name((items, query) => {
1507
+ const normalizedQuery = query.trim().toLowerCase();
1508
+ return items.filter((item) => {
1509
+ var _a, _b;
1510
+ if (!normalizedQuery) {
1511
+ return true;
1512
+ }
1513
+ const id = item.id.toLowerCase();
1514
+ const label = ((_a = item.name) != null ? _a : "").toLowerCase();
1515
+ const description = ((_b = item.description) != null ? _b : "").toLowerCase();
1516
+ return id.includes(normalizedQuery) || label.includes(normalizedQuery) || description.includes(normalizedQuery);
1517
+ }).slice(0, MAX_SUGGESTION_ITEMS);
1518
+ }, "getFilteredSuggestionItems");
1519
+ var createMentionSuggestion = /* @__PURE__ */ __name((getSuggestionItems = () => []) => {
1520
+ return {
1521
+ items: ({
1522
+ query
1523
+ }) => {
1524
+ return getFilteredSuggestionItems(getSuggestionItems(), query);
1525
+ },
1526
+ render: () => {
1527
+ let component = null;
1528
+ let popperInstance = null;
1529
+ let popoverWrapper = null;
1530
+ let clientRectProvider;
1531
+ let editorElement = null;
1532
+ let removeOutsideListeners = null;
1533
+ const destroyMentionPopover = /* @__PURE__ */ __name(() => {
1534
+ removeOutsideListeners == null ? void 0 : removeOutsideListeners();
1535
+ removeOutsideListeners = null;
1536
+ popperInstance == null ? void 0 : popperInstance.destroy();
1537
+ popperInstance = null;
1538
+ popoverWrapper == null ? void 0 : popoverWrapper.remove();
1539
+ popoverWrapper = null;
1540
+ component == null ? void 0 : component.destroy();
1541
+ component = null;
1542
+ }, "destroyMentionPopover");
1543
+ const isWithinMentionContext = /* @__PURE__ */ __name((target) => {
1544
+ if (!(target instanceof Node)) {
1545
+ return false;
1546
+ }
1547
+ return Boolean((editorElement == null ? void 0 : editorElement.contains(target)) || (popoverWrapper == null ? void 0 : popoverWrapper.contains(target)));
1548
+ }, "isWithinMentionContext");
1549
+ const setupOutsideListeners = /* @__PURE__ */ __name(() => {
1550
+ if (!editorElement || removeOutsideListeners) {
1551
+ return;
1552
+ }
1553
+ const handleDocumentFocusIn = /* @__PURE__ */ __name((event) => {
1554
+ if (!isWithinMentionContext(event.target)) {
1555
+ destroyMentionPopover();
1556
+ }
1557
+ }, "handleDocumentFocusIn");
1558
+ const handleDocumentPointerDown = /* @__PURE__ */ __name((event) => {
1559
+ if (!isWithinMentionContext(event.target)) {
1560
+ destroyMentionPopover();
1561
+ }
1562
+ }, "handleDocumentPointerDown");
1563
+ const handleEditorFocusOut = /* @__PURE__ */ __name((event) => {
1564
+ if (!isWithinMentionContext(event.relatedTarget)) {
1565
+ destroyMentionPopover();
1566
+ }
1567
+ }, "handleEditorFocusOut");
1568
+ document.addEventListener("focusin", handleDocumentFocusIn);
1569
+ document.addEventListener("mousedown", handleDocumentPointerDown, true);
1570
+ document.addEventListener("touchstart", handleDocumentPointerDown, true);
1571
+ editorElement.addEventListener("focusout", handleEditorFocusOut);
1572
+ removeOutsideListeners = /* @__PURE__ */ __name(() => {
1573
+ document.removeEventListener("focusin", handleDocumentFocusIn);
1574
+ document.removeEventListener("mousedown", handleDocumentPointerDown, true);
1575
+ document.removeEventListener("touchstart", handleDocumentPointerDown, true);
1576
+ editorElement == null ? void 0 : editorElement.removeEventListener("focusout", handleEditorFocusOut);
1577
+ }, "removeOutsideListeners");
1578
+ }, "setupOutsideListeners");
1579
+ const getVirtualElement = /* @__PURE__ */ __name(() => {
1580
+ if (!clientRectProvider) {
1581
+ return null;
1582
+ }
1583
+ return {
1584
+ getBoundingClientRect: () => {
1585
+ var _a;
1586
+ return (_a = clientRectProvider == null ? void 0 : clientRectProvider()) != null ? _a : new DOMRect();
1587
+ }
1588
+ };
1589
+ }, "getVirtualElement");
1590
+ const updatePopoverPosition = /* @__PURE__ */ __name(() => {
1591
+ const virtualElement = getVirtualElement();
1592
+ if (!virtualElement || !popoverWrapper) {
1593
+ return;
1594
+ }
1595
+ if (!popperInstance) {
1596
+ popperInstance = (0, import_core2.createPopper)(virtualElement, popoverWrapper, {
1597
+ placement: "bottom-start",
1598
+ modifiers: [{
1599
+ name: "offset",
1600
+ options: {
1601
+ offset: [0, 8]
1602
+ }
1603
+ }, {
1604
+ name: "flip",
1605
+ options: {
1606
+ fallbackPlacements: ["top-start"]
1607
+ }
1608
+ }]
1609
+ });
1610
+ return;
1611
+ }
1612
+ popperInstance.update();
1613
+ }, "updatePopoverPosition");
1614
+ return {
1615
+ onStart: (props) => {
1616
+ clientRectProvider = props.clientRect;
1617
+ editorElement = props.editor.view.dom;
1618
+ component = new import_vue_3.VueRenderer(MentionList, {
1619
+ editor: props.editor,
1620
+ props: {
1621
+ items: props.items,
1622
+ command: props.command
1623
+ }
1624
+ });
1625
+ popoverWrapper = document.createElement("div");
1626
+ popoverWrapper.style.position = "absolute";
1627
+ popoverWrapper.style.zIndex = "var(--mp-z-index-popover)";
1628
+ if (component.element) {
1629
+ popoverWrapper.append(component.element);
1630
+ }
1631
+ document.body.append(popoverWrapper);
1632
+ setupOutsideListeners();
1633
+ updatePopoverPosition();
1634
+ },
1635
+ onUpdate: (props) => {
1636
+ clientRectProvider = props.clientRect;
1637
+ component == null ? void 0 : component.updateProps({
1638
+ items: props.items,
1639
+ command: props.command
1640
+ });
1641
+ updatePopoverPosition();
1642
+ },
1643
+ onKeyDown: (props) => {
1644
+ var _a, _b;
1645
+ if (props.event.key === "Escape") {
1646
+ destroyMentionPopover();
1647
+ return true;
1648
+ }
1649
+ return (_b = (_a = component == null ? void 0 : component.ref) == null ? void 0 : _a.onKeyDown(props)) != null ? _b : false;
1650
+ },
1651
+ onExit: () => {
1652
+ destroyMentionPopover();
1653
+ editorElement = null;
1654
+ }
1655
+ };
1656
+ }
1657
+ };
1658
+ }, "createMentionSuggestion");
1659
+
1226
1660
  // src/rich-text-editor.tsx
1227
- var MpRichTextEditor = (0, import_vue19.defineComponent)({
1661
+ var MpRichTextEditor = (0, import_vue21.defineComponent)({
1228
1662
  name: "MpRichTextEditor",
1229
1663
  props: richTextEditorProps,
1230
1664
  emits: richTextEditorEmits,
@@ -1233,14 +1667,19 @@ var MpRichTextEditor = (0, import_vue19.defineComponent)({
1233
1667
  }) {
1234
1668
  const formControlProp = (0, import_pixel3_form_control.useFormControlContext)();
1235
1669
  const api = useRichTextEditor(props);
1236
- console.log(api.value);
1237
- const isFocused = (0, import_vue19.ref)(false);
1670
+ const isFocused = (0, import_vue21.ref)(false);
1238
1671
  const {
1239
1672
  isNextTheme
1240
1673
  } = (0, import_pixel3_utils4.usePixelTheme)();
1241
- const editor = new import_vue_3.Editor({
1674
+ const editor = new import_vue_32.Editor({
1242
1675
  content: api.value.value,
1243
1676
  editable: (formControlProp == null ? void 0 : formControlProp.value.isDisabled) === void 0 ? !api.value.isDisabled : !(formControlProp == null ? void 0 : formControlProp.value.isDisabled),
1677
+ editorProps: {
1678
+ handlePaste(_view, event) {
1679
+ emit("paste", event);
1680
+ return false;
1681
+ }
1682
+ },
1244
1683
  extensions: [import_starter_kit.default.configure({
1245
1684
  heading: {
1246
1685
  levels: [1, 2, 3]
@@ -1257,6 +1696,8 @@ var MpRichTextEditor = (0, import_vue19.defineComponent)({
1257
1696
  placeholder: api.value.placeholder || ""
1258
1697
  }), import_extension_character_count.default.configure({
1259
1698
  limit: api.value.maxlength
1699
+ }), import_extension_mention.default.configure({
1700
+ suggestion: createMentionSuggestion(() => props.suggestions || [])
1260
1701
  })],
1261
1702
  onFocus({
1262
1703
  editor: editor2,
@@ -1278,21 +1719,28 @@ var MpRichTextEditor = (0, import_vue19.defineComponent)({
1278
1719
  emit("change", editor2.getHTML(), editor2);
1279
1720
  }
1280
1721
  });
1722
+ const onClickToolbar = /* @__PURE__ */ __name((name) => {
1723
+ emit("action", name);
1724
+ }, "onClickToolbar");
1281
1725
  return () => {
1282
- return (0, import_vue18.createVNode)("div", (0, import_vue18.mergeProps)(api.value.rootProps, {
1726
+ return (0, import_vue20.createVNode)("div", (0, import_vue20.mergeProps)(api.value.rootProps, {
1283
1727
  "style": {
1284
1728
  "--mp-rich-text-editor--border-color-hover": (formControlProp == null ? void 0 : formControlProp.value.isInvalid) || api.value.isInvalid ? isNextTheme.value ? import_tokens.token.var("colors.border.danger") : import_tokens.token.var("colors.red.400") : isFocused.value ? isNextTheme.value ? import_tokens.token.var("colors.border.focused") : import_tokens.token.var("colors.blue.400") : isNextTheme.value ? import_tokens.token.var("colors.border.form") : import_tokens.token.var("colors.gray.400"),
1285
1729
  "--mp-rich-text-editor--border-color": (formControlProp == null ? void 0 : formControlProp.value.isInvalid) || api.value.isInvalid ? isNextTheme.value ? import_tokens.token.var("colors.border.danger") : import_tokens.token.var("colors.red.400") : isFocused.value ? isNextTheme.value ? import_tokens.token.var("colors.border.focused") : import_tokens.token.var("colors.blue.400") : isNextTheme.value ? import_tokens.token.var("colors.border.form") : import_tokens.token.var("colors.gray.100"),
1286
1730
  "--mp-rich-text-editor--box-shadow": isFocused.value ? isNextTheme.value ? import_tokens.token.var("shadows.focus") : import_tokens.token.var("shadows.outer") : void 0,
1287
1731
  "--mp-rich-text-editor--background-color": (formControlProp == null ? void 0 : formControlProp.value.isDisabled) || api.value.isDisabled ? isNextTheme.value ? import_tokens.token.var("colors.background.disabled") : import_tokens.token.var("colors.gray.50") : isNextTheme.value ? import_tokens.token.var("colors.background.neutral") : import_tokens.token.var("colors.white")
1288
1732
  }
1289
- }), [(0, import_vue18.createVNode)(EditorToolbar, (0, import_vue18.mergeProps)({
1733
+ }), [(0, import_vue20.createVNode)(EditorToolbar, (0, import_vue20.mergeProps)({
1290
1734
  "editor": editor,
1291
1735
  "options": api.value.options
1292
- }, api.value.toolbarProps), null), (0, import_vue18.createVNode)(MpRTEStyleProvider, {
1736
+ }, api.value.toolbarProps, {
1737
+ "onClickImage": () => onClickToolbar("image"),
1738
+ "onClickFile": () => onClickToolbar("file"),
1739
+ "onClickAudio": () => onClickToolbar("audio")
1740
+ }), null), (0, import_vue20.createVNode)(MpRTEStyleProvider, {
1293
1741
  "id": `${api.value.id}-style-provider`
1294
1742
  }, {
1295
- default: () => [(0, import_vue18.createVNode)(import_vue_3.EditorContent, (0, import_vue18.mergeProps)({
1743
+ default: () => [(0, import_vue20.createVNode)(import_vue_32.EditorContent, (0, import_vue20.mergeProps)({
1296
1744
  "editor": editor
1297
1745
  }, api.value.areaProps), null)]
1298
1746
  })]);