@mekari/pixel3-rich-text-editor 0.0.18-dev.2 → 0.1.0-dev.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 (67) hide show
  1. package/dist/{chunk-FZPMIQTC.mjs → chunk-2LGSTJSZ.mjs} +2 -1
  2. package/dist/chunk-4KJOYLJI.mjs +168 -0
  3. package/dist/chunk-4TUA5VF4.mjs +173 -0
  4. package/dist/{chunk-2OCRJNTJ.mjs → chunk-7RMCTPMN.mjs} +2 -2
  5. package/dist/{chunk-ES3FCTTF.mjs → chunk-E3MEVHFO.mjs} +27 -6
  6. package/dist/{chunk-WBMECFO3.mjs → chunk-MCGJK3E4.mjs} +18 -46
  7. package/dist/{chunk-73N5SLQ5.mjs → chunk-MUYPED2X.mjs} +82 -25
  8. package/dist/{chunk-V52XUOVW.mjs → chunk-O33DDWRB.mjs} +10 -2
  9. package/dist/{chunk-RNQQ7LGC.mjs → chunk-PQRMWB4A.mjs} +73 -1
  10. package/dist/{chunk-JAKI6TU2.mjs → chunk-QG3GEBVL.mjs} +8 -22
  11. package/dist/{chunk-GVMGRBDI.mjs → chunk-TNDDXUVW.mjs} +5 -1
  12. package/dist/{chunk-VK7QDWXR.mjs → chunk-YCSNVWMP.mjs} +18 -5
  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 +17 -6
  58. package/dist/rich-text-editor.d.ts +17 -6
  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 +19 -15
@@ -34,8 +34,8 @@ __export(rich_text_editor_exports, {
34
34
  MpRichTextEditor: () => MpRichTextEditor
35
35
  });
36
36
  module.exports = __toCommonJS(rich_text_editor_exports);
37
- var import_vue18 = require("vue");
38
- var import_vue19 = require("vue");
37
+ var import_vue20 = require("vue");
38
+ var import_vue21 = require("vue");
39
39
  var import_pixel3_utils4 = require("@mekari/pixel3-utils");
40
40
 
41
41
  // src/modules/rich-text-editor.props.ts
@@ -67,6 +67,10 @@ var richTextEditorProps = {
67
67
  hasBorder: {
68
68
  type: Boolean,
69
69
  default: true
70
+ },
71
+ suggestions: {
72
+ type: Array,
73
+ default: () => []
70
74
  }
71
75
  };
72
76
  var RTEStyleProviderProps = {
@@ -74,7 +78,7 @@ var RTEStyleProviderProps = {
74
78
  type: String
75
79
  }
76
80
  };
77
- var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus"]);
81
+ var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus", "action", "paste"]);
78
82
 
79
83
  // src/modules/rich-text-editor.hooks.ts
80
84
  var import_vue = require("vue");
@@ -89,6 +93,7 @@ function richTextEditorConnect(state, classes) {
89
93
  placeholder,
90
94
  maxlength,
91
95
  options,
96
+ suggestions,
92
97
  hasBorder,
93
98
  isInvalid,
94
99
  isDisabled
@@ -100,6 +105,7 @@ function richTextEditorConnect(state, classes) {
100
105
  placeholder,
101
106
  maxlength,
102
107
  options,
108
+ suggestions,
103
109
  isInvalid,
104
110
  isDisabled,
105
111
  rootProps: {
@@ -151,13 +157,14 @@ var useRTEStyleProvider = /* @__PURE__ */ __name((props) => {
151
157
  }, "useRTEStyleProvider");
152
158
 
153
159
  // src/rich-text-editor.tsx
154
- var import_vue_3 = require("@tiptap/vue-3");
160
+ var import_vue_32 = require("@tiptap/vue-3");
155
161
  var import_starter_kit = __toESM(require("@tiptap/starter-kit"));
156
162
  var import_extension_underline = __toESM(require("@tiptap/extension-underline"));
157
163
  var import_extension_text_align = __toESM(require("@tiptap/extension-text-align"));
158
164
  var import_extension_text_style = __toESM(require("@tiptap/extension-text-style"));
159
165
  var import_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"));
160
166
  var import_extension_character_count = __toESM(require("@tiptap/extension-character-count"));
167
+ var import_extension_mention = __toESM(require("@tiptap/extension-mention"));
161
168
  var import_extension_color = require("@tiptap/extension-color");
162
169
  var import_extension_link = __toESM(require("@tiptap/extension-link"));
163
170
  var import_extension_highlight = __toESM(require("@tiptap/extension-highlight"));
@@ -167,6 +174,9 @@ var import_pixel3_form_control = require("@mekari/pixel3-form-control");
167
174
  // src/editor-toolbar.tsx
168
175
  var import_vue14 = require("vue");
169
176
  var import_vue15 = require("vue");
177
+ var import_css5 = require("@mekari/pixel3-styled-system/css");
178
+ var import_pixel3_divider = require("@mekari/pixel3-divider");
179
+ var import_pixel3_scrollbar = require("@mekari/pixel3-scrollbar");
170
180
 
171
181
  // src/extensions/heading-extension.tsx
172
182
  var import_vue4 = require("vue");
@@ -496,6 +506,74 @@ var CaretIcon = (0, import_vue3.defineComponent)({
496
506
  }, null)]);
497
507
  }
498
508
  });
509
+ var ImageIcon = (0, import_vue3.defineComponent)({
510
+ name: "ImageIcon",
511
+ setup() {
512
+ return () => (0, import_vue2.createVNode)("svg", {
513
+ "xmlns": "http://www.w3.org/2000/svg",
514
+ "width": "20",
515
+ "height": "20",
516
+ "viewBox": "0 0 20 20",
517
+ "fill": "none"
518
+ }, [(0, import_vue2.createVNode)("path", {
519
+ "fill-rule": "evenodd",
520
+ "clip-rule": "evenodd",
521
+ "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",
522
+ "fill": "#758195"
523
+ }, null)]);
524
+ }
525
+ });
526
+ var FileIcon = (0, import_vue3.defineComponent)({
527
+ name: "FileIcon",
528
+ setup() {
529
+ return () => (0, import_vue2.createVNode)("svg", {
530
+ "xmlns": "http://www.w3.org/2000/svg",
531
+ "width": "18",
532
+ "height": "17",
533
+ "viewBox": "0 0 18 17",
534
+ "fill": "none"
535
+ }, [(0, import_vue2.createVNode)("path", {
536
+ "fill-rule": "evenodd",
537
+ "clip-rule": "evenodd",
538
+ "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",
539
+ "fill": "#758195"
540
+ }, null)]);
541
+ }
542
+ });
543
+ var AudioIcon = (0, import_vue3.defineComponent)({
544
+ name: "AudioIcon",
545
+ setup() {
546
+ return () => (0, import_vue2.createVNode)("svg", {
547
+ "xmlns": "http://www.w3.org/2000/svg",
548
+ "width": "20",
549
+ "height": "20",
550
+ "viewBox": "0 0 20 20",
551
+ "fill": "none"
552
+ }, [(0, import_vue2.createVNode)("path", {
553
+ "fill-rule": "evenodd",
554
+ "clip-rule": "evenodd",
555
+ "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",
556
+ "fill": "#758195"
557
+ }, null)]);
558
+ }
559
+ });
560
+ var MentionIcon = (0, import_vue3.defineComponent)({
561
+ name: "MentionIcon",
562
+ setup() {
563
+ return () => (0, import_vue2.createVNode)("svg", {
564
+ "xmlns": "http://www.w3.org/2000/svg",
565
+ "width": "18",
566
+ "height": "18",
567
+ "viewBox": "0 0 18 18",
568
+ "fill": "none"
569
+ }, [(0, import_vue2.createVNode)("path", {
570
+ "fill-rule": "evenodd",
571
+ "clip-rule": "evenodd",
572
+ "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",
573
+ "fill": "#758195"
574
+ }, null)]);
575
+ }
576
+ });
499
577
 
500
578
  // src/extensions/heading-extension.tsx
501
579
  var HeadingExtention = (0, import_vue5.defineComponent)({
@@ -513,7 +591,8 @@ var HeadingExtention = (0, import_vue5.defineComponent)({
513
591
  editor
514
592
  }) {
515
593
  return () => (0, import_vue4.createVNode)(import_pixel3_popover.MpPopover, {
516
- "id": "popover-heading-extention"
594
+ "id": "popover-heading-extention",
595
+ "usePortal": true
517
596
  }, {
518
597
  default: () => [(0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverTrigger, null, {
519
598
  default: () => [(0, import_vue4.withDirectives)((0, import_vue4.createVNode)("button", {
@@ -584,84 +663,55 @@ var HeadingExtention = (0, import_vue5.defineComponent)({
584
663
  })
585
664
  }, {
586
665
  default: () => [(0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverList, {
587
- "class": (0, import_css.css)({
588
- gap: "2",
589
- alignItems: "flex-start",
590
- paddingLeft: "3"
591
- })
666
+ "data-pixel-rte": true
592
667
  }, {
593
668
  default: () => [(0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
594
- "class": {
595
- "is-active": editor == null ? void 0 : editor.isActive("heading", {
596
- level: 1
597
- }),
598
- "text-sizing": true
599
- },
669
+ "is-active": editor == null ? void 0 : editor.isActive("heading", {
670
+ level: 1
671
+ }),
600
672
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().toggleHeading({
601
673
  level: 1
602
674
  }).run()
603
675
  }, {
604
676
  default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
605
677
  "as": "h1",
606
- "size": "h1",
607
- "class": (0, import_css.css)({
608
- color: "currentColor"
609
- })
678
+ "size": "h1"
610
679
  }, {
611
680
  default: () => [(0, import_vue4.createTextVNode)("Heading 1")]
612
681
  })]
613
682
  }), (0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
614
- "class": {
615
- "is-active": editor == null ? void 0 : editor.isActive("heading", {
616
- level: 2
617
- }),
618
- "text-sizing": true
619
- },
683
+ "is-active": editor == null ? void 0 : editor.isActive("heading", {
684
+ level: 2
685
+ }),
620
686
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().toggleHeading({
621
687
  level: 2
622
688
  }).run()
623
689
  }, {
624
690
  default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
625
691
  "as": "h2",
626
- "size": "h2",
627
- "class": (0, import_css.css)({
628
- color: "currentColor"
629
- })
692
+ "size": "h2"
630
693
  }, {
631
694
  default: () => [(0, import_vue4.createTextVNode)("Heading 2")]
632
695
  })]
633
696
  }), (0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
634
- "class": {
635
- "is-active": editor == null ? void 0 : editor.isActive("heading", {
636
- level: 3
637
- }),
638
- "text-sizing": true
639
- },
697
+ "is-active": editor == null ? void 0 : editor.isActive("heading", {
698
+ level: 3
699
+ }),
640
700
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().toggleHeading({
641
701
  level: 3
642
702
  }).run()
643
703
  }, {
644
704
  default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
645
705
  "as": "h3",
646
- "size": "h3",
647
- "class": (0, import_css.css)({
648
- color: "currentColor"
649
- })
706
+ "size": "h3"
650
707
  }, {
651
708
  default: () => [(0, import_vue4.createTextVNode)("Heading 3")]
652
709
  })]
653
710
  }), (0, import_vue4.createVNode)(import_pixel3_popover.MpPopoverListItem, {
654
- "class": {
655
- "is-active": editor == null ? void 0 : editor.isActive("paragraph"),
656
- "text-sizing": true
657
- },
711
+ "is-active": editor == null ? void 0 : editor.isActive("paragraph"),
658
712
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setParagraph().run()
659
713
  }, {
660
- default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, {
661
- "class": (0, import_css.css)({
662
- color: "currentColor"
663
- })
664
- }, {
714
+ default: () => [(0, import_vue4.createVNode)(import_pixel3_text.MpText, null, {
665
715
  default: () => [(0, import_vue4.createTextVNode)("Normal text")]
666
716
  })]
667
717
  })]
@@ -696,7 +746,8 @@ var AlignExtention = (0, import_vue7.defineComponent)({
696
746
  });
697
747
  }, "isActiveAlignment");
698
748
  return () => (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopover, {
699
- "id": "popover-align-extention"
749
+ "id": "popover-align-extention",
750
+ "usePortal": true
700
751
  }, {
701
752
  default: () => [(0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverTrigger, null, {
702
753
  default: () => [(0, import_vue6.withDirectives)((0, import_vue6.createVNode)("button", {
@@ -718,40 +769,25 @@ var AlignExtention = (0, import_vue7.defineComponent)({
718
769
  })
719
770
  }, {
720
771
  default: () => [(0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverList, {
721
- "class": (0, import_css2.css)({
722
- gap: "2",
723
- alignItems: "center"
724
- })
772
+ "data-pixel-rte": true
725
773
  }, {
726
774
  default: () => [(0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
727
- "class": {
728
- "is-active": isActiveAlignment("left"),
729
- "text-sizing": true
730
- },
775
+ "is-active": isActiveAlignment("left"),
731
776
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("left").run()
732
777
  }, {
733
778
  default: () => [(0, import_vue6.createVNode)(AlignLeftIcon, null, null)]
734
779
  }), (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
735
- "class": {
736
- "is-active": isActiveAlignment("center"),
737
- "text-sizing": true
738
- },
780
+ "is-active": isActiveAlignment("center"),
739
781
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("center").run()
740
782
  }, {
741
783
  default: () => [(0, import_vue6.createVNode)(AlignCenterIcon, null, null)]
742
784
  }), (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
743
- "class": {
744
- "is-active": isActiveAlignment("right"),
745
- "text-sizing": true
746
- },
785
+ "is-active": isActiveAlignment("right"),
747
786
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("right").run()
748
787
  }, {
749
788
  default: () => [(0, import_vue6.createVNode)(AlignRightIcon, null, null)]
750
789
  }), (0, import_vue6.createVNode)(import_pixel3_popover2.MpPopoverListItem, {
751
- "class": {
752
- "is-active": isActiveAlignment("justify"),
753
- "text-sizing": true
754
- },
790
+ "is-active": isActiveAlignment("justify"),
755
791
  "onClick": () => (editor == null ? void 0 : editor.chain()).focus().setTextAlign("justify").run()
756
792
  }, {
757
793
  default: () => [(0, import_vue6.createVNode)(AlignJustifyIcon, null, null)]
@@ -797,7 +833,11 @@ var SingleExtention = (0, import_vue9.defineComponent)({
797
833
  orderedList: (0, import_vue8.createVNode)(OrderedListIcon, null, null),
798
834
  undo: (0, import_vue8.createVNode)(UndoIcon, null, null),
799
835
  redo: (0, import_vue8.createVNode)(RedoIcon, null, null),
800
- clear: (0, import_vue8.createVNode)(ClearIcon, null, null)
836
+ clear: (0, import_vue8.createVNode)(ClearIcon, null, null),
837
+ image: (0, import_vue8.createVNode)(ImageIcon, null, null),
838
+ file: (0, import_vue8.createVNode)(FileIcon, null, null),
839
+ audio: (0, import_vue8.createVNode)(AudioIcon, null, null),
840
+ mention: (0, import_vue8.createVNode)(MentionIcon, null, null)
801
841
  };
802
842
  return () => (0, import_vue8.withDirectives)((0, import_vue8.createVNode)("button", {
803
843
  "class": {
@@ -861,6 +901,7 @@ var ColorExtension = (0, import_vue11.defineComponent)({
861
901
  "preset": colorPreset,
862
902
  "variant": "basic",
863
903
  "placement": "bottom-start",
904
+ "usePortal": true,
864
905
  "isShowPreset": true,
865
906
  "isShowInput": false,
866
907
  "class": (0, import_css3.css)({
@@ -925,6 +966,7 @@ var LinkExtension = (0, import_vue13.defineComponent)({
925
966
  popperInstance.destroy();
926
967
  }
927
968
  popperInstance = (0, import_core.createPopper)(target, popoverRef.value, {
969
+ strategy: "fixed",
928
970
  onFirstUpdate: () => {
929
971
  if (popperInstance) {
930
972
  popperInstance.setOptions({
@@ -983,6 +1025,14 @@ var LinkExtension = (0, import_vue13.defineComponent)({
983
1025
  }
984
1026
  onClosePopover();
985
1027
  }, "onSetLink");
1028
+ const onOpenInNewTab = /* @__PURE__ */ __name(() => {
1029
+ const trimmedUrl = url.value.trim();
1030
+ if (!trimmedUrl) {
1031
+ return;
1032
+ }
1033
+ const normalizedUrl = /^(https?:)?\/\//i.test(trimmedUrl) ? trimmedUrl : `https://${trimmedUrl}`;
1034
+ window.open(normalizedUrl, "_blank", "noopener,noreferrer");
1035
+ }, "onOpenInNewTab");
986
1036
  const onClosePopover = /* @__PURE__ */ __name(() => {
987
1037
  isShowPopover.value = false;
988
1038
  editor == null ? void 0 : editor.commands.setTextSelection({
@@ -1026,10 +1076,9 @@ var LinkExtension = (0, import_vue13.defineComponent)({
1026
1076
  default: () => [(0, import_vue12.createVNode)("div", {
1027
1077
  "ref": popoverRef,
1028
1078
  "data-pixel-rte": true,
1029
- "style": {
1030
- position: "absolute",
1031
- zIndex: "var(--mp-z-index-popover)"
1032
- }
1079
+ "class": (0, import_css4.css)({
1080
+ zIndex: "popover"
1081
+ })
1033
1082
  }, [(0, import_vue12.createVNode)("div", {
1034
1083
  "class": (0, import_css4.css)({
1035
1084
  display: "flex",
@@ -1062,6 +1111,11 @@ var LinkExtension = (0, import_vue13.defineComponent)({
1062
1111
  }, null) : (0, import_vue12.createVNode)(import_pixel3_button.MpButton, {
1063
1112
  "leftIcon": "check",
1064
1113
  "onClick": onSetLink
1114
+ }, null), isEditLink.value && (0, import_vue12.createVNode)(import_pixel3_button.MpButton, {
1115
+ "leftIcon": "newtab",
1116
+ "variant": "ghost",
1117
+ "isDisabled": !url.value.trim(),
1118
+ "onClick": onOpenInNewTab
1065
1119
  }, null), isEditLink.value ? (0, import_vue12.createVNode)(import_pixel3_button.MpButton, {
1066
1120
  "leftIcon": "delete",
1067
1121
  "variant": "ghost",
@@ -1076,9 +1130,9 @@ var LinkExtension = (0, import_vue13.defineComponent)({
1076
1130
  });
1077
1131
 
1078
1132
  // src/editor-toolbar.tsx
1079
- var import_pixel3_divider = require("@mekari/pixel3-divider");
1080
1133
  var EditorToolbar = (0, import_vue15.defineComponent)({
1081
1134
  name: "EditorToolbar",
1135
+ emits: ["clickImage", "clickFile", "clickAudio"],
1082
1136
  props: {
1083
1137
  editor: {
1084
1138
  type: Object
@@ -1090,8 +1144,10 @@ var EditorToolbar = (0, import_vue15.defineComponent)({
1090
1144
  setup({
1091
1145
  editor,
1092
1146
  options
1147
+ }, {
1148
+ emit
1093
1149
  }) {
1094
- const items = ["heading", "bold", "italic", "underline", "strike", "blockquote", "bulletList", "orderedList", "textColor", "fillColor", "textLink", "align", "undo", "redo", "clear"];
1150
+ const items = ["heading", "bold", "italic", "underline", "strike", "blockquote", "bulletList", "orderedList", "textColor", "fillColor", "textLink", "align", "undo", "redo", "clear", "image", "file", "audio", "mention"];
1095
1151
  const itemOptions = {
1096
1152
  heading: {
1097
1153
  tooltipLabel: "Text style",
@@ -1154,52 +1210,104 @@ var EditorToolbar = (0, import_vue15.defineComponent)({
1154
1210
  clear: {
1155
1211
  tooltipLabel: "Reset format",
1156
1212
  onClick: () => (editor == null ? void 0 : editor.chain()).focus().unsetAllMarks().run()
1213
+ },
1214
+ image: {
1215
+ tooltipLabel: "Add image",
1216
+ onClick: () => emit("clickImage")
1217
+ },
1218
+ file: {
1219
+ tooltipLabel: "Add file",
1220
+ onClick: () => emit("clickFile")
1221
+ },
1222
+ audio: {
1223
+ tooltipLabel: "Add audio",
1224
+ onClick: () => emit("clickAudio")
1225
+ },
1226
+ mention: {
1227
+ tooltipLabel: "Mention",
1228
+ editor,
1229
+ onClick: () => (editor == null ? void 0 : editor.chain()).focus().insertContent("@").run()
1157
1230
  }
1158
1231
  };
1159
- const renderExtension = /* @__PURE__ */ __name((item) => {
1160
- const options2 = itemOptions[item];
1161
- if (!options2)
1232
+ const getResolvedItem = /* @__PURE__ */ __name((option) => {
1233
+ if (typeof option === "string") {
1234
+ return {
1235
+ item: option
1236
+ };
1237
+ }
1238
+ return {
1239
+ item: option.value,
1240
+ tooltip: option.tooltip
1241
+ };
1242
+ }, "getResolvedItem");
1243
+ const renderExtension = /* @__PURE__ */ __name((option) => {
1244
+ const {
1245
+ item,
1246
+ tooltip
1247
+ } = getResolvedItem(option);
1248
+ if (!items.includes(item))
1249
+ return null;
1250
+ const resolvedItem = item;
1251
+ const resolvedOptions = itemOptions[resolvedItem];
1252
+ if (!resolvedOptions)
1162
1253
  return null;
1163
- switch (item) {
1254
+ const tooltipLabel = tooltip || resolvedOptions.tooltipLabel;
1255
+ switch (resolvedItem) {
1164
1256
  case "heading":
1165
1257
  return (0, import_vue14.createVNode)(HeadingExtention, {
1166
- "tooltipLabel": options2.tooltipLabel,
1258
+ "tooltipLabel": tooltipLabel,
1167
1259
  "editor": editor
1168
1260
  }, null);
1169
1261
  case "align":
1170
1262
  return (0, import_vue14.createVNode)(AlignExtention, {
1171
- "tooltipLabel": options2.tooltipLabel,
1263
+ "tooltipLabel": tooltipLabel,
1172
1264
  "editor": editor
1173
1265
  }, null);
1174
1266
  case "textColor":
1175
1267
  case "fillColor":
1176
1268
  return (0, import_vue14.createVNode)(ColorExtension, {
1177
- "tooltipLabel": options2.tooltipLabel,
1269
+ "tooltipLabel": tooltipLabel,
1178
1270
  "editor": editor,
1179
- "type": options2.type
1271
+ "type": resolvedOptions.type
1180
1272
  }, null);
1181
1273
  case "textLink":
1182
1274
  return (0, import_vue14.createVNode)(LinkExtension, {
1183
- "tooltipLabel": options2.tooltipLabel,
1275
+ "tooltipLabel": tooltipLabel,
1184
1276
  "editor": editor
1185
1277
  }, null);
1186
1278
  default:
1187
1279
  return (0, import_vue14.createVNode)(SingleExtention, {
1188
- "name": item,
1189
- "tooltipLabel": options2.tooltipLabel,
1190
- "onClick": options2.onClick,
1280
+ "name": resolvedItem,
1281
+ "tooltipLabel": tooltipLabel,
1282
+ "onClick": resolvedOptions.onClick,
1191
1283
  "editor": editor
1192
1284
  }, null);
1193
1285
  }
1194
1286
  }, "renderExtension");
1195
- 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) => {
1196
- if (items.includes(item)) {
1197
- return renderExtension(item);
1287
+ return () => (0, import_vue14.createVNode)(import_pixel3_scrollbar.MpScrollbar, {
1288
+ "options": {
1289
+ overflow: {
1290
+ y: "hide",
1291
+ x: "scroll"
1292
+ }
1198
1293
  }
1199
- }), index !== (options == null ? void 0 : options.length) - 1 && (0, import_vue14.createVNode)(import_pixel3_divider.MpDivider, {
1200
- "id": "divider-toolbar",
1201
- "orientation": "vertical"
1202
- }, null)]))]);
1294
+ }, {
1295
+ default: () => [(0, import_vue14.createVNode)("div", {
1296
+ "class": (0, import_css5.css)({
1297
+ display: "flex",
1298
+ alignItems: "stretch",
1299
+ gap: "1"
1300
+ })
1301
+ }, [options == null ? void 0 : options.map((option, index) => (0, import_vue14.createVNode)(import_vue14.Fragment, null, [option.map((item) => {
1302
+ const resolvedItem = typeof item === "string" ? item : item.value;
1303
+ if (items.includes(resolvedItem)) {
1304
+ return renderExtension(item);
1305
+ }
1306
+ }), index !== (options == null ? void 0 : options.length) - 1 && (0, import_vue14.createVNode)(import_pixel3_divider.MpDivider, {
1307
+ "id": "divider-toolbar",
1308
+ "orientation": "vertical"
1309
+ }, null)]))])]
1310
+ });
1203
1311
  }
1204
1312
  });
1205
1313
 
@@ -1220,8 +1328,334 @@ var MpRTEStyleProvider = (0, import_vue17.defineComponent)({
1220
1328
  }
1221
1329
  });
1222
1330
 
1331
+ // src/rte-suggestion.ts
1332
+ var import_vue_3 = require("@tiptap/vue-3");
1333
+ var import_core2 = require("@popperjs/core");
1334
+
1335
+ // src/extensions/mention-list-extension.tsx
1336
+ var import_vue18 = require("vue");
1337
+ var import_vue19 = require("vue");
1338
+ var import_css6 = require("@mekari/pixel3-styled-system/css");
1339
+ var import_pixel3_avatar = require("@mekari/pixel3-avatar");
1340
+ var import_pixel3_popover3 = require("@mekari/pixel3-popover");
1341
+ var import_pixel3_text2 = require("@mekari/pixel3-text");
1342
+ var avatarVariantColors = ["violet", "lime", "amber", "sky", "pink", "teal", "rose", "stone"];
1343
+ var getAvatarVariantColor = /* @__PURE__ */ __name((index) => {
1344
+ return avatarVariantColors[index % avatarVariantColors.length];
1345
+ }, "getAvatarVariantColor");
1346
+ var MentionList = (0, import_vue19.defineComponent)({
1347
+ name: "MentionList",
1348
+ props: {
1349
+ items: {
1350
+ type: Array,
1351
+ default: () => []
1352
+ },
1353
+ command: {
1354
+ type: Function,
1355
+ required: true
1356
+ }
1357
+ },
1358
+ setup(props, {
1359
+ expose
1360
+ }) {
1361
+ const selectedIndex = (0, import_vue19.ref)(0);
1362
+ const listRef = (0, import_vue19.ref)(null);
1363
+ const scrollToFocusedItem = /* @__PURE__ */ __name(() => {
1364
+ (0, import_vue19.nextTick)(() => {
1365
+ if (!listRef.value)
1366
+ return;
1367
+ const targetItem = listRef.value.querySelector('[data-active="true"], [data-highlight]');
1368
+ if (targetItem) {
1369
+ targetItem.scrollIntoView({
1370
+ block: "nearest"
1371
+ });
1372
+ }
1373
+ });
1374
+ }, "scrollToFocusedItem");
1375
+ (0, import_vue19.watch)(() => props.items, () => {
1376
+ selectedIndex.value = 0;
1377
+ });
1378
+ const onSelect = /* @__PURE__ */ __name((index) => {
1379
+ const item = props.items[index];
1380
+ if (item) {
1381
+ props.command({
1382
+ ...item,
1383
+ label: item.name
1384
+ });
1385
+ }
1386
+ }, "onSelect");
1387
+ const onKeyDown = /* @__PURE__ */ __name(({
1388
+ event
1389
+ }) => {
1390
+ if (!props.items.length) {
1391
+ return false;
1392
+ }
1393
+ if (event.key === "ArrowUp") {
1394
+ event.preventDefault();
1395
+ const total = props.items.length;
1396
+ selectedIndex.value = (selectedIndex.value + total - 1) % total;
1397
+ scrollToFocusedItem();
1398
+ return true;
1399
+ }
1400
+ if (event.key === "ArrowDown") {
1401
+ event.preventDefault();
1402
+ selectedIndex.value = (selectedIndex.value + 1) % props.items.length;
1403
+ scrollToFocusedItem();
1404
+ return true;
1405
+ }
1406
+ if (event.key === "Enter") {
1407
+ event.preventDefault();
1408
+ onSelect(selectedIndex.value);
1409
+ return true;
1410
+ }
1411
+ return false;
1412
+ }, "onKeyDown");
1413
+ expose({
1414
+ onKeyDown
1415
+ });
1416
+ return () => (0, import_vue18.createVNode)(import_pixel3_popover3.MpPopover, {
1417
+ "id": "popover-rte-mention-list",
1418
+ "is-manual": true,
1419
+ "is-default-open": true,
1420
+ "is-open": true
1421
+ }, {
1422
+ default: () => [(0, import_vue18.createVNode)(import_pixel3_popover3.MpPopoverContent, {
1423
+ "class": (0, import_css6.css)({
1424
+ width: "280px",
1425
+ maxHeight: "284px",
1426
+ overflowY: "auto"
1427
+ })
1428
+ }, {
1429
+ default: () => [(0, import_vue18.createVNode)(import_pixel3_popover3.MpPopoverList, {
1430
+ "ref": (element) => {
1431
+ var _a;
1432
+ if (!element) {
1433
+ listRef.value = null;
1434
+ return;
1435
+ }
1436
+ listRef.value = (_a = element.$el) != null ? _a : element;
1437
+ },
1438
+ "data-pixel-rte": true
1439
+ }, {
1440
+ default: () => [!props.items.length && (0, import_vue18.createVNode)(import_pixel3_text2.MpText, {
1441
+ "color": "text.secondary",
1442
+ "class": (0, import_css6.css)({
1443
+ px: "3",
1444
+ py: "2"
1445
+ })
1446
+ }, {
1447
+ default: () => [(0, import_vue18.createTextVNode)("No result")]
1448
+ }), props.items.map((item, index) => {
1449
+ return (0, import_vue18.createVNode)(import_pixel3_popover3.MpPopoverListItem, {
1450
+ "key": `${item.id}-${index}`,
1451
+ "is-active": selectedIndex.value === index,
1452
+ "onMousedown": (event) => event.preventDefault(),
1453
+ "onMouseenter": () => {
1454
+ selectedIndex.value = index;
1455
+ },
1456
+ "onClick": () => {
1457
+ onSelect(index);
1458
+ }
1459
+ }, {
1460
+ default: () => [(0, import_vue18.createVNode)("div", {
1461
+ "class": (0, import_css6.css)({
1462
+ display: "flex",
1463
+ alignItems: "center",
1464
+ gap: "2",
1465
+ width: "full",
1466
+ minWidth: "0"
1467
+ })
1468
+ }, [item.avatar && (0, import_vue18.createVNode)(import_pixel3_avatar.MpAvatar, {
1469
+ "id": `avatar-rte-mention-${index}`,
1470
+ "name": item.avatar,
1471
+ "size": "lg",
1472
+ "variant-color": getAvatarVariantColor(index)
1473
+ }, null), (0, import_vue18.createVNode)("div", {
1474
+ "class": (0, import_css6.css)({
1475
+ display: "flex",
1476
+ flexDirection: "column",
1477
+ alignItems: "flex-start",
1478
+ minWidth: "0",
1479
+ flex: "1 1 0%"
1480
+ })
1481
+ }, [(0, import_vue18.createVNode)(import_pixel3_text2.MpText, {
1482
+ "size": "label",
1483
+ "is-truncated": true
1484
+ }, {
1485
+ default: () => [item.name || "Unknown"]
1486
+ }), item.description && (0, import_vue18.createVNode)(import_pixel3_text2.MpText, {
1487
+ "size": "label-small",
1488
+ "color": "text.secondary",
1489
+ "is-truncated": true
1490
+ }, {
1491
+ default: () => [item.description]
1492
+ })])])]
1493
+ });
1494
+ })]
1495
+ })]
1496
+ })]
1497
+ });
1498
+ }
1499
+ });
1500
+
1501
+ // src/rte-suggestion.ts
1502
+ var MAX_SUGGESTION_ITEMS = 10;
1503
+ var getFilteredSuggestionItems = /* @__PURE__ */ __name((items, query) => {
1504
+ const normalizedQuery = query.trim().toLowerCase();
1505
+ return items.filter((item) => {
1506
+ var _a, _b;
1507
+ if (!normalizedQuery) {
1508
+ return true;
1509
+ }
1510
+ const id = item.id.toLowerCase();
1511
+ const label = ((_a = item.name) != null ? _a : "").toLowerCase();
1512
+ const description = ((_b = item.description) != null ? _b : "").toLowerCase();
1513
+ return id.includes(normalizedQuery) || label.includes(normalizedQuery) || description.includes(normalizedQuery);
1514
+ }).slice(0, MAX_SUGGESTION_ITEMS);
1515
+ }, "getFilteredSuggestionItems");
1516
+ var createMentionSuggestion = /* @__PURE__ */ __name((getSuggestionItems = () => []) => {
1517
+ return {
1518
+ items: ({
1519
+ query
1520
+ }) => {
1521
+ return getFilteredSuggestionItems(getSuggestionItems(), query);
1522
+ },
1523
+ render: () => {
1524
+ let component = null;
1525
+ let popperInstance = null;
1526
+ let popoverWrapper = null;
1527
+ let clientRectProvider;
1528
+ let editorElement = null;
1529
+ let removeOutsideListeners = null;
1530
+ const destroyMentionPopover = /* @__PURE__ */ __name(() => {
1531
+ removeOutsideListeners == null ? void 0 : removeOutsideListeners();
1532
+ removeOutsideListeners = null;
1533
+ popperInstance == null ? void 0 : popperInstance.destroy();
1534
+ popperInstance = null;
1535
+ popoverWrapper == null ? void 0 : popoverWrapper.remove();
1536
+ popoverWrapper = null;
1537
+ component == null ? void 0 : component.destroy();
1538
+ component = null;
1539
+ }, "destroyMentionPopover");
1540
+ const isWithinMentionContext = /* @__PURE__ */ __name((target) => {
1541
+ if (!(target instanceof Node)) {
1542
+ return false;
1543
+ }
1544
+ return Boolean((editorElement == null ? void 0 : editorElement.contains(target)) || (popoverWrapper == null ? void 0 : popoverWrapper.contains(target)));
1545
+ }, "isWithinMentionContext");
1546
+ const setupOutsideListeners = /* @__PURE__ */ __name(() => {
1547
+ if (!editorElement || removeOutsideListeners) {
1548
+ return;
1549
+ }
1550
+ const handleDocumentFocusIn = /* @__PURE__ */ __name((event) => {
1551
+ if (!isWithinMentionContext(event.target)) {
1552
+ destroyMentionPopover();
1553
+ }
1554
+ }, "handleDocumentFocusIn");
1555
+ const handleDocumentPointerDown = /* @__PURE__ */ __name((event) => {
1556
+ if (!isWithinMentionContext(event.target)) {
1557
+ destroyMentionPopover();
1558
+ }
1559
+ }, "handleDocumentPointerDown");
1560
+ const handleEditorFocusOut = /* @__PURE__ */ __name((event) => {
1561
+ if (!isWithinMentionContext(event.relatedTarget)) {
1562
+ destroyMentionPopover();
1563
+ }
1564
+ }, "handleEditorFocusOut");
1565
+ document.addEventListener("focusin", handleDocumentFocusIn);
1566
+ document.addEventListener("mousedown", handleDocumentPointerDown, true);
1567
+ document.addEventListener("touchstart", handleDocumentPointerDown, true);
1568
+ editorElement.addEventListener("focusout", handleEditorFocusOut);
1569
+ removeOutsideListeners = /* @__PURE__ */ __name(() => {
1570
+ document.removeEventListener("focusin", handleDocumentFocusIn);
1571
+ document.removeEventListener("mousedown", handleDocumentPointerDown, true);
1572
+ document.removeEventListener("touchstart", handleDocumentPointerDown, true);
1573
+ editorElement == null ? void 0 : editorElement.removeEventListener("focusout", handleEditorFocusOut);
1574
+ }, "removeOutsideListeners");
1575
+ }, "setupOutsideListeners");
1576
+ const getVirtualElement = /* @__PURE__ */ __name(() => {
1577
+ if (!clientRectProvider) {
1578
+ return null;
1579
+ }
1580
+ return {
1581
+ getBoundingClientRect: () => {
1582
+ var _a;
1583
+ return (_a = clientRectProvider == null ? void 0 : clientRectProvider()) != null ? _a : new DOMRect();
1584
+ }
1585
+ };
1586
+ }, "getVirtualElement");
1587
+ const updatePopoverPosition = /* @__PURE__ */ __name(() => {
1588
+ const virtualElement = getVirtualElement();
1589
+ if (!virtualElement || !popoverWrapper) {
1590
+ return;
1591
+ }
1592
+ if (!popperInstance) {
1593
+ popperInstance = (0, import_core2.createPopper)(virtualElement, popoverWrapper, {
1594
+ placement: "bottom-start",
1595
+ modifiers: [{
1596
+ name: "offset",
1597
+ options: {
1598
+ offset: [0, 8]
1599
+ }
1600
+ }, {
1601
+ name: "flip",
1602
+ options: {
1603
+ fallbackPlacements: ["top-start"]
1604
+ }
1605
+ }]
1606
+ });
1607
+ return;
1608
+ }
1609
+ popperInstance.update();
1610
+ }, "updatePopoverPosition");
1611
+ return {
1612
+ onStart: (props) => {
1613
+ clientRectProvider = props.clientRect;
1614
+ editorElement = props.editor.view.dom;
1615
+ component = new import_vue_3.VueRenderer(MentionList, {
1616
+ editor: props.editor,
1617
+ props: {
1618
+ items: props.items,
1619
+ command: props.command
1620
+ }
1621
+ });
1622
+ popoverWrapper = document.createElement("div");
1623
+ popoverWrapper.style.position = "absolute";
1624
+ popoverWrapper.style.zIndex = "var(--mp-z-index-popover)";
1625
+ if (component.element) {
1626
+ popoverWrapper.append(component.element);
1627
+ }
1628
+ document.body.append(popoverWrapper);
1629
+ setupOutsideListeners();
1630
+ updatePopoverPosition();
1631
+ },
1632
+ onUpdate: (props) => {
1633
+ clientRectProvider = props.clientRect;
1634
+ component == null ? void 0 : component.updateProps({
1635
+ items: props.items,
1636
+ command: props.command
1637
+ });
1638
+ updatePopoverPosition();
1639
+ },
1640
+ onKeyDown: (props) => {
1641
+ var _a, _b;
1642
+ if (props.event.key === "Escape") {
1643
+ destroyMentionPopover();
1644
+ return true;
1645
+ }
1646
+ return (_b = (_a = component == null ? void 0 : component.ref) == null ? void 0 : _a.onKeyDown(props)) != null ? _b : false;
1647
+ },
1648
+ onExit: () => {
1649
+ destroyMentionPopover();
1650
+ editorElement = null;
1651
+ }
1652
+ };
1653
+ }
1654
+ };
1655
+ }, "createMentionSuggestion");
1656
+
1223
1657
  // src/rich-text-editor.tsx
1224
- var MpRichTextEditor = (0, import_vue19.defineComponent)({
1658
+ var MpRichTextEditor = (0, import_vue21.defineComponent)({
1225
1659
  name: "MpRichTextEditor",
1226
1660
  props: richTextEditorProps,
1227
1661
  emits: richTextEditorEmits,
@@ -1230,14 +1664,19 @@ var MpRichTextEditor = (0, import_vue19.defineComponent)({
1230
1664
  }) {
1231
1665
  const formControlProp = (0, import_pixel3_form_control.useFormControlContext)();
1232
1666
  const api = useRichTextEditor(props);
1233
- console.log(api.value);
1234
- const isFocused = (0, import_vue19.ref)(false);
1667
+ const isFocused = (0, import_vue21.ref)(false);
1235
1668
  const {
1236
1669
  isNextTheme
1237
1670
  } = (0, import_pixel3_utils4.usePixelTheme)();
1238
- const editor = new import_vue_3.Editor({
1671
+ const editor = new import_vue_32.Editor({
1239
1672
  content: api.value.value,
1240
1673
  editable: (formControlProp == null ? void 0 : formControlProp.value.isDisabled) === void 0 ? !api.value.isDisabled : !(formControlProp == null ? void 0 : formControlProp.value.isDisabled),
1674
+ editorProps: {
1675
+ handlePaste(_view, event) {
1676
+ emit("paste", event);
1677
+ return false;
1678
+ }
1679
+ },
1241
1680
  extensions: [import_starter_kit.default.configure({
1242
1681
  heading: {
1243
1682
  levels: [1, 2, 3]
@@ -1254,6 +1693,8 @@ var MpRichTextEditor = (0, import_vue19.defineComponent)({
1254
1693
  placeholder: api.value.placeholder || ""
1255
1694
  }), import_extension_character_count.default.configure({
1256
1695
  limit: api.value.maxlength
1696
+ }), import_extension_mention.default.configure({
1697
+ suggestion: createMentionSuggestion(() => props.suggestions || [])
1257
1698
  })],
1258
1699
  onFocus({
1259
1700
  editor: editor2,
@@ -1275,21 +1716,28 @@ var MpRichTextEditor = (0, import_vue19.defineComponent)({
1275
1716
  emit("change", editor2.getHTML(), editor2);
1276
1717
  }
1277
1718
  });
1719
+ const onClickToolbar = /* @__PURE__ */ __name((name) => {
1720
+ emit("action", name);
1721
+ }, "onClickToolbar");
1278
1722
  return () => {
1279
- return (0, import_vue18.createVNode)("div", (0, import_vue18.mergeProps)(api.value.rootProps, {
1723
+ return (0, import_vue20.createVNode)("div", (0, import_vue20.mergeProps)(api.value.rootProps, {
1280
1724
  "style": {
1281
1725
  "--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"),
1282
1726
  "--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"),
1283
1727
  "--mp-rich-text-editor--box-shadow": isFocused.value ? isNextTheme.value ? import_tokens.token.var("shadows.focus") : import_tokens.token.var("shadows.outer") : void 0,
1284
1728
  "--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")
1285
1729
  }
1286
- }), [(0, import_vue18.createVNode)(EditorToolbar, (0, import_vue18.mergeProps)({
1730
+ }), [(0, import_vue20.createVNode)(EditorToolbar, (0, import_vue20.mergeProps)({
1287
1731
  "editor": editor,
1288
1732
  "options": api.value.options
1289
- }, api.value.toolbarProps), null), (0, import_vue18.createVNode)(MpRTEStyleProvider, {
1733
+ }, api.value.toolbarProps, {
1734
+ "onClickImage": () => onClickToolbar("image"),
1735
+ "onClickFile": () => onClickToolbar("file"),
1736
+ "onClickAudio": () => onClickToolbar("audio")
1737
+ }), null), (0, import_vue20.createVNode)(MpRTEStyleProvider, {
1290
1738
  "id": `${api.value.id}-style-provider`
1291
1739
  }, {
1292
- default: () => [(0, import_vue18.createVNode)(import_vue_3.EditorContent, (0, import_vue18.mergeProps)({
1740
+ default: () => [(0, import_vue20.createVNode)(import_vue_32.EditorContent, (0, import_vue20.mergeProps)({
1293
1741
  "editor": editor
1294
1742
  }, api.value.areaProps), null)]
1295
1743
  })]);