@mekari/pixel3-rich-text-editor 0.1.3 → 0.2.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 (35) hide show
  1. package/dist/{chunk-6O4HSL2C.mjs → chunk-B5BN5T5O.mjs} +6 -2
  2. package/dist/{chunk-4ZCPCZD2.mjs → chunk-E4R6ETA7.mjs} +16 -9
  3. package/dist/{chunk-4TUA5VF4.mjs → chunk-ELFAGDKG.mjs} +17 -3
  4. package/dist/{chunk-4KJOYLJI.mjs → chunk-RTEK53TL.mjs} +47 -15
  5. package/dist/{chunk-BA5A7DIS.mjs → chunk-RVXAG7LK.mjs} +3 -3
  6. package/dist/editor-toolbar.mjs +4 -4
  7. package/dist/extensions/index.mjs +9 -9
  8. package/dist/extensions/mention-list-extension.d.mts +9 -0
  9. package/dist/extensions/mention-list-extension.d.ts +9 -0
  10. package/dist/extensions/mention-list-extension.js +16 -2
  11. package/dist/extensions/mention-list-extension.mjs +1 -1
  12. package/dist/index.d.mts +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +79 -22
  15. package/dist/index.mjs +13 -13
  16. package/dist/metafile-cjs.json +1 -1
  17. package/dist/metafile-esm.json +1 -1
  18. package/dist/modules/rich-text-editor.props.d.mts +7 -3
  19. package/dist/modules/rich-text-editor.props.d.ts +7 -3
  20. package/dist/modules/rich-text-editor.props.js +6 -2
  21. package/dist/modules/rich-text-editor.props.mjs +1 -1
  22. package/dist/modules/rich-text-editor.types.d.mts +12 -3
  23. package/dist/modules/rich-text-editor.types.d.ts +12 -3
  24. package/dist/rich-text-editor.d.mts +15 -5
  25. package/dist/rich-text-editor.d.ts +15 -5
  26. package/dist/rich-text-editor.js +79 -22
  27. package/dist/rich-text-editor.mjs +12 -12
  28. package/dist/rte-style-provider.js +1 -1
  29. package/dist/rte-style-provider.mjs +2 -2
  30. package/dist/rte-suggestion.d.mts +7 -3
  31. package/dist/rte-suggestion.d.ts +7 -3
  32. package/dist/rte-suggestion.js +62 -16
  33. package/dist/rte-suggestion.mjs +2 -2
  34. package/package.json +13 -12
  35. package/dist/{chunk-G4CGNV6P.mjs → chunk-RX7ZEE2M.mjs} +6 -6
@@ -1,4 +1,4 @@
1
- import { ToolbarOption, MentionSuggestionItem, VariableSuggestionItem } from './rich-text-editor.types.mjs';
1
+ import { ToolbarOption, MentionSuggestionSource, VariableSuggestionItem } from './rich-text-editor.types.mjs';
2
2
  import { PropType } from 'vue';
3
3
  import '@mekari/pixel3-utils';
4
4
 
@@ -31,9 +31,13 @@ declare const richTextEditorProps: {
31
31
  default: boolean;
32
32
  };
33
33
  suggestions: {
34
- type: PropType<MentionSuggestionItem[] | undefined>;
34
+ type: PropType<MentionSuggestionSource | undefined>;
35
35
  default: () => never[];
36
36
  };
37
+ maxSuggestions: {
38
+ type: PropType<number | undefined>;
39
+ default: number;
40
+ };
37
41
  variables: {
38
42
  type: PropType<VariableSuggestionItem[] | undefined>;
39
43
  default: () => never[];
@@ -53,6 +57,6 @@ declare const RTEStyleProviderProps: {
53
57
  type: PropType<string | undefined>;
54
58
  };
55
59
  };
56
- declare const richTextEditorEmits: ("change" | "blur" | "focus" | "action" | "paste")[];
60
+ declare const richTextEditorEmits: ("change" | "blur" | "focus" | "action" | "paste" | "suggestionsChange")[];
57
61
 
58
62
  export { RTEStyleProviderProps, richTextEditorEmits, richTextEditorProps };
@@ -1,4 +1,4 @@
1
- import { ToolbarOption, MentionSuggestionItem, VariableSuggestionItem } from './rich-text-editor.types.js';
1
+ import { ToolbarOption, MentionSuggestionSource, VariableSuggestionItem } from './rich-text-editor.types.js';
2
2
  import { PropType } from 'vue';
3
3
  import '@mekari/pixel3-utils';
4
4
 
@@ -31,9 +31,13 @@ declare const richTextEditorProps: {
31
31
  default: boolean;
32
32
  };
33
33
  suggestions: {
34
- type: PropType<MentionSuggestionItem[] | undefined>;
34
+ type: PropType<MentionSuggestionSource | undefined>;
35
35
  default: () => never[];
36
36
  };
37
+ maxSuggestions: {
38
+ type: PropType<number | undefined>;
39
+ default: number;
40
+ };
37
41
  variables: {
38
42
  type: PropType<VariableSuggestionItem[] | undefined>;
39
43
  default: () => never[];
@@ -53,6 +57,6 @@ declare const RTEStyleProviderProps: {
53
57
  type: PropType<string | undefined>;
54
58
  };
55
59
  };
56
- declare const richTextEditorEmits: ("change" | "blur" | "focus" | "action" | "paste")[];
60
+ declare const richTextEditorEmits: ("change" | "blur" | "focus" | "action" | "paste" | "suggestionsChange")[];
57
61
 
58
62
  export { RTEStyleProviderProps, richTextEditorEmits, richTextEditorProps };
@@ -55,9 +55,13 @@ var richTextEditorProps = {
55
55
  default: true
56
56
  },
57
57
  suggestions: {
58
- type: Array,
58
+ type: [Array, Function],
59
59
  default: () => []
60
60
  },
61
+ maxSuggestions: {
62
+ type: Number,
63
+ default: 50
64
+ },
61
65
  variables: {
62
66
  type: Array,
63
67
  default: () => []
@@ -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", "action", "paste"]);
81
+ var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus", "action", "paste", "suggestionsChange"]);
78
82
  // Annotate the CommonJS export names for ESM import in node:
79
83
  0 && (module.exports = {
80
84
  RTEStyleProviderProps,
@@ -2,7 +2,7 @@ import {
2
2
  RTEStyleProviderProps,
3
3
  richTextEditorEmits,
4
4
  richTextEditorProps
5
- } from "../chunk-6O4HSL2C.mjs";
5
+ } from "../chunk-B5BN5T5O.mjs";
6
6
  import "../chunk-QZ7VFGWC.mjs";
7
7
  export {
8
8
  RTEStyleProviderProps,
@@ -10,6 +10,13 @@ interface MentionSuggestionItem {
10
10
  description?: string;
11
11
  avatar?: string;
12
12
  }
13
+ /**
14
+ * Mention suggestions can be a static array (filtered internally by the
15
+ * editor) or a resolver function that receives the current mention query and
16
+ * returns the items to show — synchronously or as a Promise (e.g. from an API
17
+ * call). With the function form, filtering is fully delegated to the resolver.
18
+ */
19
+ type MentionSuggestionSource = MentionSuggestionItem[] | ((query: string) => MentionSuggestionItem[] | Promise<MentionSuggestionItem[]>);
13
20
  interface VariableSuggestionItem {
14
21
  id: string;
15
22
  name: string;
@@ -21,7 +28,8 @@ interface RichTextEditorProps {
21
28
  placeholder?: string;
22
29
  maxlength?: number;
23
30
  options?: ToolbarOption[][];
24
- suggestions?: MentionSuggestionItem[];
31
+ suggestions?: MentionSuggestionSource;
32
+ maxSuggestions?: number;
25
33
  variables?: VariableSuggestionItem[];
26
34
  isInvalid: boolean;
27
35
  isDisabled: boolean;
@@ -45,7 +53,8 @@ interface RichTextEditorApiMachine<T extends PropTypes = PropTypes> {
45
53
  placeholder?: string;
46
54
  maxlength?: number;
47
55
  options?: ToolbarOption[][];
48
- suggestions?: MentionSuggestionItem[];
56
+ suggestions?: MentionSuggestionSource;
57
+ maxSuggestions?: number;
49
58
  variables?: VariableSuggestionItem[];
50
59
  isInvalid?: boolean;
51
60
  isDisabled?: boolean;
@@ -82,4 +91,4 @@ interface ItemOptions {
82
91
  }
83
92
  type ActionTypes = 'image' | 'file' | 'audio' | 'mention' | 'variable' | 'location';
84
93
 
85
- export { ActionTypes, ItemOptions, Items, MentionSuggestionItem, RTEStyleProviderApiMachine, RTEStyleProviderClasses, RTEStyleProviderDefinedContext, RTEStyleProviderState, RichTextEditorApiMachine, RichTextEditorClasses, RichTextEditorDefinedContext, RichTextEditorProps, RichTextEditorState, RteStyleProviderProps, ToolbarOption, ToolbarOptionObject, VariableSuggestionItem };
94
+ export { ActionTypes, ItemOptions, Items, MentionSuggestionItem, MentionSuggestionSource, RTEStyleProviderApiMachine, RTEStyleProviderClasses, RTEStyleProviderDefinedContext, RTEStyleProviderState, RichTextEditorApiMachine, RichTextEditorClasses, RichTextEditorDefinedContext, RichTextEditorProps, RichTextEditorState, RteStyleProviderProps, ToolbarOption, ToolbarOptionObject, VariableSuggestionItem };
@@ -10,6 +10,13 @@ interface MentionSuggestionItem {
10
10
  description?: string;
11
11
  avatar?: string;
12
12
  }
13
+ /**
14
+ * Mention suggestions can be a static array (filtered internally by the
15
+ * editor) or a resolver function that receives the current mention query and
16
+ * returns the items to show — synchronously or as a Promise (e.g. from an API
17
+ * call). With the function form, filtering is fully delegated to the resolver.
18
+ */
19
+ type MentionSuggestionSource = MentionSuggestionItem[] | ((query: string) => MentionSuggestionItem[] | Promise<MentionSuggestionItem[]>);
13
20
  interface VariableSuggestionItem {
14
21
  id: string;
15
22
  name: string;
@@ -21,7 +28,8 @@ interface RichTextEditorProps {
21
28
  placeholder?: string;
22
29
  maxlength?: number;
23
30
  options?: ToolbarOption[][];
24
- suggestions?: MentionSuggestionItem[];
31
+ suggestions?: MentionSuggestionSource;
32
+ maxSuggestions?: number;
25
33
  variables?: VariableSuggestionItem[];
26
34
  isInvalid: boolean;
27
35
  isDisabled: boolean;
@@ -45,7 +53,8 @@ interface RichTextEditorApiMachine<T extends PropTypes = PropTypes> {
45
53
  placeholder?: string;
46
54
  maxlength?: number;
47
55
  options?: ToolbarOption[][];
48
- suggestions?: MentionSuggestionItem[];
56
+ suggestions?: MentionSuggestionSource;
57
+ maxSuggestions?: number;
49
58
  variables?: VariableSuggestionItem[];
50
59
  isInvalid?: boolean;
51
60
  isDisabled?: boolean;
@@ -82,4 +91,4 @@ interface ItemOptions {
82
91
  }
83
92
  type ActionTypes = 'image' | 'file' | 'audio' | 'mention' | 'variable' | 'location';
84
93
 
85
- export { ActionTypes, ItemOptions, Items, MentionSuggestionItem, RTEStyleProviderApiMachine, RTEStyleProviderClasses, RTEStyleProviderDefinedContext, RTEStyleProviderState, RichTextEditorApiMachine, RichTextEditorClasses, RichTextEditorDefinedContext, RichTextEditorProps, RichTextEditorState, RteStyleProviderProps, ToolbarOption, ToolbarOptionObject, VariableSuggestionItem };
94
+ export { ActionTypes, ItemOptions, Items, MentionSuggestionItem, MentionSuggestionSource, RTEStyleProviderApiMachine, RTEStyleProviderClasses, RTEStyleProviderDefinedContext, RTEStyleProviderState, RichTextEditorApiMachine, RichTextEditorClasses, RichTextEditorDefinedContext, RichTextEditorProps, RichTextEditorState, RteStyleProviderProps, ToolbarOption, ToolbarOptionObject, VariableSuggestionItem };
@@ -1,5 +1,5 @@
1
1
  import * as vue_jsx_runtime from 'vue/jsx-runtime';
2
- import { ToolbarOption, MentionSuggestionItem, VariableSuggestionItem } from './modules/rich-text-editor.types.mjs';
2
+ import { ToolbarOption, MentionSuggestionSource, VariableSuggestionItem } from './modules/rich-text-editor.types.mjs';
3
3
  import * as vue from 'vue';
4
4
  import '@mekari/pixel3-utils';
5
5
 
@@ -32,9 +32,13 @@ declare const MpRichTextEditor: vue.DefineComponent<{
32
32
  default: boolean;
33
33
  };
34
34
  suggestions: {
35
- type: vue.PropType<MentionSuggestionItem[] | undefined>;
35
+ type: vue.PropType<MentionSuggestionSource | undefined>;
36
36
  default: () => never[];
37
37
  };
38
+ maxSuggestions: {
39
+ type: vue.PropType<number | undefined>;
40
+ default: number;
41
+ };
38
42
  variables: {
39
43
  type: vue.PropType<VariableSuggestionItem[] | undefined>;
40
44
  default: () => never[];
@@ -48,7 +52,7 @@ declare const MpRichTextEditor: vue.DefineComponent<{
48
52
  transformLink: {
49
53
  type: vue.PropType<((url: string) => string) | undefined>;
50
54
  };
51
- }, () => vue_jsx_runtime.JSX.Element, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("change" | "blur" | "focus" | "action" | "paste")[], "change" | "blur" | "focus" | "action" | "paste", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
55
+ }, () => vue_jsx_runtime.JSX.Element, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("change" | "blur" | "focus" | "action" | "paste" | "suggestionsChange")[], "change" | "blur" | "focus" | "action" | "paste" | "suggestionsChange", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
52
56
  id: {
53
57
  type: vue.PropType<string | undefined>;
54
58
  };
@@ -77,9 +81,13 @@ declare const MpRichTextEditor: vue.DefineComponent<{
77
81
  default: boolean;
78
82
  };
79
83
  suggestions: {
80
- type: vue.PropType<MentionSuggestionItem[] | undefined>;
84
+ type: vue.PropType<MentionSuggestionSource | undefined>;
81
85
  default: () => never[];
82
86
  };
87
+ maxSuggestions: {
88
+ type: vue.PropType<number | undefined>;
89
+ default: number;
90
+ };
83
91
  variables: {
84
92
  type: vue.PropType<VariableSuggestionItem[] | undefined>;
85
93
  default: () => never[];
@@ -99,8 +107,10 @@ declare const MpRichTextEditor: vue.DefineComponent<{
99
107
  onBlur?: ((...args: any[]) => any) | undefined;
100
108
  onChange?: ((...args: any[]) => any) | undefined;
101
109
  onAction?: ((...args: any[]) => any) | undefined;
110
+ onSuggestionsChange?: ((...args: any[]) => any) | undefined;
102
111
  }, {
103
- suggestions: MentionSuggestionItem[] | undefined;
112
+ suggestions: MentionSuggestionSource | undefined;
113
+ maxSuggestions: number | undefined;
104
114
  variables: VariableSuggestionItem[] | undefined;
105
115
  isInvalid: boolean;
106
116
  isDisabled: boolean;
@@ -1,5 +1,5 @@
1
1
  import * as vue_jsx_runtime from 'vue/jsx-runtime';
2
- import { ToolbarOption, MentionSuggestionItem, VariableSuggestionItem } from './modules/rich-text-editor.types.js';
2
+ import { ToolbarOption, MentionSuggestionSource, VariableSuggestionItem } from './modules/rich-text-editor.types.js';
3
3
  import * as vue from 'vue';
4
4
  import '@mekari/pixel3-utils';
5
5
 
@@ -32,9 +32,13 @@ declare const MpRichTextEditor: vue.DefineComponent<{
32
32
  default: boolean;
33
33
  };
34
34
  suggestions: {
35
- type: vue.PropType<MentionSuggestionItem[] | undefined>;
35
+ type: vue.PropType<MentionSuggestionSource | undefined>;
36
36
  default: () => never[];
37
37
  };
38
+ maxSuggestions: {
39
+ type: vue.PropType<number | undefined>;
40
+ default: number;
41
+ };
38
42
  variables: {
39
43
  type: vue.PropType<VariableSuggestionItem[] | undefined>;
40
44
  default: () => never[];
@@ -48,7 +52,7 @@ declare const MpRichTextEditor: vue.DefineComponent<{
48
52
  transformLink: {
49
53
  type: vue.PropType<((url: string) => string) | undefined>;
50
54
  };
51
- }, () => vue_jsx_runtime.JSX.Element, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("change" | "blur" | "focus" | "action" | "paste")[], "change" | "blur" | "focus" | "action" | "paste", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
55
+ }, () => vue_jsx_runtime.JSX.Element, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("change" | "blur" | "focus" | "action" | "paste" | "suggestionsChange")[], "change" | "blur" | "focus" | "action" | "paste" | "suggestionsChange", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
52
56
  id: {
53
57
  type: vue.PropType<string | undefined>;
54
58
  };
@@ -77,9 +81,13 @@ declare const MpRichTextEditor: vue.DefineComponent<{
77
81
  default: boolean;
78
82
  };
79
83
  suggestions: {
80
- type: vue.PropType<MentionSuggestionItem[] | undefined>;
84
+ type: vue.PropType<MentionSuggestionSource | undefined>;
81
85
  default: () => never[];
82
86
  };
87
+ maxSuggestions: {
88
+ type: vue.PropType<number | undefined>;
89
+ default: number;
90
+ };
83
91
  variables: {
84
92
  type: vue.PropType<VariableSuggestionItem[] | undefined>;
85
93
  default: () => never[];
@@ -99,8 +107,10 @@ declare const MpRichTextEditor: vue.DefineComponent<{
99
107
  onBlur?: ((...args: any[]) => any) | undefined;
100
108
  onChange?: ((...args: any[]) => any) | undefined;
101
109
  onAction?: ((...args: any[]) => any) | undefined;
110
+ onSuggestionsChange?: ((...args: any[]) => any) | undefined;
102
111
  }, {
103
- suggestions: MentionSuggestionItem[] | undefined;
112
+ suggestions: MentionSuggestionSource | undefined;
113
+ maxSuggestions: number | undefined;
104
114
  variables: VariableSuggestionItem[] | undefined;
105
115
  isInvalid: boolean;
106
116
  isDisabled: boolean;
@@ -69,9 +69,13 @@ var richTextEditorProps = {
69
69
  default: true
70
70
  },
71
71
  suggestions: {
72
- type: Array,
72
+ type: [Array, Function],
73
73
  default: () => []
74
74
  },
75
+ maxSuggestions: {
76
+ type: Number,
77
+ default: 50
78
+ },
75
79
  variables: {
76
80
  type: Array,
77
81
  default: () => []
@@ -88,7 +92,7 @@ var RTEStyleProviderProps = {
88
92
  type: String
89
93
  }
90
94
  };
91
- var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus", "action", "paste"]);
95
+ var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus", "action", "paste", "suggestionsChange"]);
92
96
 
93
97
  // src/modules/rich-text-editor.hooks.ts
94
98
  var import_vue = require("vue");
@@ -1806,6 +1810,7 @@ var import_css7 = require("@mekari/pixel3-styled-system/css");
1806
1810
  var import_pixel3_avatar = require("@mekari/pixel3-avatar");
1807
1811
  var import_pixel3_popover4 = require("@mekari/pixel3-popover");
1808
1812
  var import_pixel3_text3 = require("@mekari/pixel3-text");
1813
+ var import_pixel3_spinner = require("@mekari/pixel3-spinner");
1809
1814
  var avatarVariantColors = ["violet", "lime", "amber", "sky", "pink", "teal", "rose", "stone"];
1810
1815
  var getAvatarVariantColor = /* @__PURE__ */ __name((index) => {
1811
1816
  return avatarVariantColors[index % avatarVariantColors.length];
@@ -1820,6 +1825,10 @@ var MentionList = (0, import_vue21.defineComponent)({
1820
1825
  command: {
1821
1826
  type: Function,
1822
1827
  required: true
1828
+ },
1829
+ isLoading: {
1830
+ type: Boolean,
1831
+ default: false
1823
1832
  }
1824
1833
  },
1825
1834
  setup(props, {
@@ -1904,7 +1913,16 @@ var MentionList = (0, import_vue21.defineComponent)({
1904
1913
  },
1905
1914
  "data-pixel-rte": true
1906
1915
  }, {
1907
- default: () => [!props.items.length && (0, import_vue20.createVNode)(import_pixel3_text3.MpText, {
1916
+ default: () => [props.isLoading && (0, import_vue20.createVNode)("div", {
1917
+ "class": (0, import_css7.css)({
1918
+ display: "flex",
1919
+ justifyContent: "center",
1920
+ px: "3",
1921
+ py: "3"
1922
+ })
1923
+ }, [(0, import_vue20.createVNode)(import_pixel3_spinner.MpSpinner, {
1924
+ "size": "sm"
1925
+ }, null)]), !props.isLoading && !props.items.length && (0, import_vue20.createVNode)(import_pixel3_text3.MpText, {
1908
1926
  "color": "text.secondary",
1909
1927
  "class": (0, import_css7.css)({
1910
1928
  px: "3",
@@ -1912,7 +1930,7 @@ var MentionList = (0, import_vue21.defineComponent)({
1912
1930
  })
1913
1931
  }, {
1914
1932
  default: () => [(0, import_vue20.createTextVNode)("No result")]
1915
- }), props.items.map((item, index) => {
1933
+ }), !props.isLoading && props.items.map((item, index) => {
1916
1934
  return (0, import_vue20.createVNode)(import_pixel3_popover4.MpPopoverListItem, {
1917
1935
  "key": `${item.id}-${index}`,
1918
1936
  "is-active": selectedIndex.value === index,
@@ -1966,8 +1984,7 @@ var MentionList = (0, import_vue21.defineComponent)({
1966
1984
  });
1967
1985
 
1968
1986
  // src/rte-suggestion.ts
1969
- var MAX_SUGGESTION_ITEMS = 10;
1970
- var getFilteredSuggestionItems = /* @__PURE__ */ __name((items, query) => {
1987
+ var getFilteredSuggestionItems = /* @__PURE__ */ __name((items, query, maxItems) => {
1971
1988
  const normalizedQuery = query.trim().toLowerCase();
1972
1989
  return items.filter((item) => {
1973
1990
  var _a, _b;
@@ -1978,14 +1995,25 @@ var getFilteredSuggestionItems = /* @__PURE__ */ __name((items, query) => {
1978
1995
  const label = ((_a = item.name) != null ? _a : "").toLowerCase();
1979
1996
  const description = ((_b = item.description) != null ? _b : "").toLowerCase();
1980
1997
  return id.includes(normalizedQuery) || label.includes(normalizedQuery) || description.includes(normalizedQuery);
1981
- }).slice(0, MAX_SUGGESTION_ITEMS);
1998
+ }).slice(0, maxItems);
1982
1999
  }, "getFilteredSuggestionItems");
1983
- var createMentionSuggestion = /* @__PURE__ */ __name((getSuggestionItems = () => []) => {
2000
+ var createMentionSuggestion = /* @__PURE__ */ __name((getSuggestionSource = () => [], options = {}) => {
2001
+ var _a;
2002
+ const maxItems = (_a = options.maxItems) != null ? _a : 50;
1984
2003
  return {
1985
- items: ({
2004
+ items: async ({
1986
2005
  query
1987
2006
  }) => {
1988
- return getFilteredSuggestionItems(getSuggestionItems(), query);
2007
+ var _a2, _b, _c;
2008
+ const source = getSuggestionSource();
2009
+ if (typeof source === "function") {
2010
+ const items2 = ((_a2 = await source(query)) != null ? _a2 : []).slice(0, maxItems);
2011
+ (_b = options.onSuggestionsChange) == null ? void 0 : _b.call(options, items2);
2012
+ return items2;
2013
+ }
2014
+ const items = getFilteredSuggestionItems(source != null ? source : [], query, maxItems);
2015
+ (_c = options.onSuggestionsChange) == null ? void 0 : _c.call(options, items);
2016
+ return items;
1989
2017
  },
1990
2018
  render: () => {
1991
2019
  let component = null;
@@ -2046,8 +2074,8 @@ var createMentionSuggestion = /* @__PURE__ */ __name((getSuggestionItems = () =>
2046
2074
  }
2047
2075
  return {
2048
2076
  getBoundingClientRect: () => {
2049
- var _a;
2050
- return (_a = clientRectProvider == null ? void 0 : clientRectProvider()) != null ? _a : new DOMRect();
2077
+ var _a2;
2078
+ return (_a2 = clientRectProvider == null ? void 0 : clientRectProvider()) != null ? _a2 : new DOMRect();
2051
2079
  }
2052
2080
  };
2053
2081
  }, "getVirtualElement");
@@ -2076,14 +2104,18 @@ var createMentionSuggestion = /* @__PURE__ */ __name((getSuggestionItems = () =>
2076
2104
  popperInstance.update();
2077
2105
  }, "updatePopoverPosition");
2078
2106
  return {
2079
- onStart: (props) => {
2107
+ // Fires synchronously before `items()` resolves, so the popover can
2108
+ // mount showing a loading state instead of a blank/"No result" flash
2109
+ // while the (possibly async) suggestion source is fetched.
2110
+ onBeforeStart: (props) => {
2080
2111
  clientRectProvider = props.clientRect;
2081
2112
  editorElement = props.editor.view.dom;
2082
2113
  component = new import_vue_3.VueRenderer(MentionList, {
2083
2114
  editor: props.editor,
2084
2115
  props: {
2085
- items: props.items,
2086
- command: props.command
2116
+ items: [],
2117
+ command: props.command,
2118
+ isLoading: true
2087
2119
  }
2088
2120
  });
2089
2121
  popoverWrapper = document.createElement("div");
@@ -2096,21 +2128,39 @@ var createMentionSuggestion = /* @__PURE__ */ __name((getSuggestionItems = () =>
2096
2128
  setupOutsideListeners();
2097
2129
  updatePopoverPosition();
2098
2130
  },
2131
+ onStart: (props) => {
2132
+ clientRectProvider = props.clientRect;
2133
+ component == null ? void 0 : component.updateProps({
2134
+ items: props.items,
2135
+ command: props.command,
2136
+ isLoading: false
2137
+ });
2138
+ updatePopoverPosition();
2139
+ },
2140
+ // Fires before every re-fetch triggered by a query change — flips
2141
+ // back to the loading state until the new `items()` call resolves.
2142
+ onBeforeUpdate: (props) => {
2143
+ clientRectProvider = props.clientRect;
2144
+ component == null ? void 0 : component.updateProps({
2145
+ isLoading: true
2146
+ });
2147
+ },
2099
2148
  onUpdate: (props) => {
2100
2149
  clientRectProvider = props.clientRect;
2101
2150
  component == null ? void 0 : component.updateProps({
2102
2151
  items: props.items,
2103
- command: props.command
2152
+ command: props.command,
2153
+ isLoading: false
2104
2154
  });
2105
2155
  updatePopoverPosition();
2106
2156
  },
2107
2157
  onKeyDown: (props) => {
2108
- var _a, _b;
2158
+ var _a2, _b;
2109
2159
  if (props.event.key === "Escape") {
2110
2160
  destroyMentionPopover();
2111
2161
  return true;
2112
2162
  }
2113
- return (_b = (_a = component == null ? void 0 : component.ref) == null ? void 0 : _a.onKeyDown(props)) != null ? _b : false;
2163
+ return (_b = (_a2 = component == null ? void 0 : component.ref) == null ? void 0 : _a2.onKeyDown(props)) != null ? _b : false;
2114
2164
  },
2115
2165
  onExit: () => {
2116
2166
  destroyMentionPopover();
@@ -2126,7 +2176,7 @@ var import_vue_32 = require("@tiptap/vue-3");
2126
2176
  var import_core4 = require("@popperjs/core");
2127
2177
  var import_state = require("@tiptap/pm/state");
2128
2178
  var VariablePluginKey = new import_state.PluginKey("variable");
2129
- var MAX_SUGGESTION_ITEMS2 = 50;
2179
+ var MAX_SUGGESTION_ITEMS = 50;
2130
2180
  var getFilteredSuggestionItems2 = /* @__PURE__ */ __name((items, query) => {
2131
2181
  const normalizedQuery = query.trim().toLowerCase();
2132
2182
  return items.filter((item) => {
@@ -2138,7 +2188,7 @@ var getFilteredSuggestionItems2 = /* @__PURE__ */ __name((items, query) => {
2138
2188
  const name = ((_a = item.name) != null ? _a : "").toLowerCase();
2139
2189
  const category = ((_b = item.category) != null ? _b : "").toLowerCase();
2140
2190
  return id.includes(normalizedQuery) || name.includes(normalizedQuery) || category.includes(normalizedQuery);
2141
- }).slice(0, MAX_SUGGESTION_ITEMS2);
2191
+ }).slice(0, MAX_SUGGESTION_ITEMS);
2142
2192
  }, "getFilteredSuggestionItems");
2143
2193
  var createVariableSuggestion = /* @__PURE__ */ __name((getSuggestionItems = () => []) => {
2144
2194
  return {
@@ -2365,8 +2415,15 @@ var MpRichTextEditor = (0, import_vue23.defineComponent)({
2365
2415
  import_extension_character_count.default.configure({
2366
2416
  limit: api.value.maxlength
2367
2417
  }),
2368
- ...props.suggestions && props.suggestions.length > 0 ? [import_extension_mention.default.configure({
2369
- suggestion: createMentionSuggestion(() => props.suggestions || [])
2418
+ // Extensions are registered once at mount, so the array-length check
2419
+ // here can't be reactive. A resolver function always registers the
2420
+ // extension — use that form when suggestions are loaded dynamically
2421
+ // (e.g. fetched from an API after mount).
2422
+ ...typeof props.suggestions === "function" || props.suggestions && props.suggestions.length > 0 ? [import_extension_mention.default.configure({
2423
+ suggestion: createMentionSuggestion(() => props.suggestions, {
2424
+ maxItems: props.maxSuggestions,
2425
+ onSuggestionsChange: (items) => emit("suggestionsChange", items)
2426
+ })
2370
2427
  })] : [],
2371
2428
  ...props.variables && props.variables.length > 0 ? [Variable.configure({
2372
2429
  suggestion: createVariableSuggestion(() => props.variables || [])
@@ -1,23 +1,23 @@
1
1
  import {
2
2
  MpRichTextEditor
3
- } from "./chunk-4ZCPCZD2.mjs";
4
- import "./chunk-G4CGNV6P.mjs";
3
+ } from "./chunk-E4R6ETA7.mjs";
4
+ import "./chunk-RX7ZEE2M.mjs";
5
5
  import "./chunk-HIHIKPNN.mjs";
6
+ import "./chunk-X2CB42A3.mjs";
7
+ import "./chunk-COZ45QUD.mjs";
6
8
  import "./chunk-FCLBNBXD.mjs";
7
9
  import "./chunk-ENKUUZPM.mjs";
10
+ import "./chunk-RVXAG7LK.mjs";
11
+ import "./chunk-ZRAXSVO5.mjs";
12
+ import "./chunk-ZAXJ3BEP.mjs";
13
+ import "./chunk-B5BN5T5O.mjs";
14
+ import "./chunk-RTEK53TL.mjs";
15
+ import "./chunk-ELFAGDKG.mjs";
16
+ import "./chunk-BWRU2WZN.mjs";
17
+ import "./chunk-76GEEOAG.mjs";
8
18
  import "./chunk-YWVVMJGP.mjs";
9
19
  import "./chunk-Y6UPQ6EU.mjs";
10
- import "./chunk-X2CB42A3.mjs";
11
- import "./chunk-COZ45QUD.mjs";
12
20
  import "./chunk-IFRJVX2K.mjs";
13
- import "./chunk-BA5A7DIS.mjs";
14
- import "./chunk-6O4HSL2C.mjs";
15
- import "./chunk-4KJOYLJI.mjs";
16
- import "./chunk-4TUA5VF4.mjs";
17
- import "./chunk-BWRU2WZN.mjs";
18
- import "./chunk-76GEEOAG.mjs";
19
- import "./chunk-ZRAXSVO5.mjs";
20
- import "./chunk-ZAXJ3BEP.mjs";
21
21
  import "./chunk-QZ7VFGWC.mjs";
22
22
  export {
23
23
  MpRichTextEditor
@@ -34,7 +34,7 @@ var RTEStyleProviderProps = {
34
34
  type: String
35
35
  }
36
36
  };
37
- var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus", "action", "paste"]);
37
+ var richTextEditorEmits = (0, import_pixel3_utils.declareEmit)(["change", "blur", "focus", "action", "paste", "suggestionsChange"]);
38
38
 
39
39
  // src/modules/rich-text-editor.hooks.ts
40
40
  var import_vue = require("vue");
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  MpRTEStyleProvider
3
- } from "./chunk-BA5A7DIS.mjs";
4
- import "./chunk-6O4HSL2C.mjs";
3
+ } from "./chunk-RVXAG7LK.mjs";
5
4
  import "./chunk-ZRAXSVO5.mjs";
6
5
  import "./chunk-ZAXJ3BEP.mjs";
6
+ import "./chunk-B5BN5T5O.mjs";
7
7
  import "./chunk-QZ7VFGWC.mjs";
8
8
  export {
9
9
  MpRTEStyleProvider
@@ -1,7 +1,11 @@
1
1
  import { MentionOptions } from '@tiptap/extension-mention';
2
- import { MentionSuggestionItem } from './modules/rich-text-editor.types.mjs';
2
+ import { MentionSuggestionItem, MentionSuggestionSource } from './modules/rich-text-editor.types.mjs';
3
3
  import '@mekari/pixel3-utils';
4
4
 
5
- declare const createMentionSuggestion: (getSuggestionItems?: () => MentionSuggestionItem[]) => MentionOptions['suggestion'];
5
+ interface CreateMentionSuggestionOptions {
6
+ maxItems?: number;
7
+ onSuggestionsChange?: (items: MentionSuggestionItem[]) => void;
8
+ }
9
+ declare const createMentionSuggestion: (getSuggestionSource?: () => MentionSuggestionSource | undefined, options?: CreateMentionSuggestionOptions) => MentionOptions['suggestion'];
6
10
 
7
- export { createMentionSuggestion };
11
+ export { CreateMentionSuggestionOptions, createMentionSuggestion };
@@ -1,7 +1,11 @@
1
1
  import { MentionOptions } from '@tiptap/extension-mention';
2
- import { MentionSuggestionItem } from './modules/rich-text-editor.types.js';
2
+ import { MentionSuggestionItem, MentionSuggestionSource } from './modules/rich-text-editor.types.js';
3
3
  import '@mekari/pixel3-utils';
4
4
 
5
- declare const createMentionSuggestion: (getSuggestionItems?: () => MentionSuggestionItem[]) => MentionOptions['suggestion'];
5
+ interface CreateMentionSuggestionOptions {
6
+ maxItems?: number;
7
+ onSuggestionsChange?: (items: MentionSuggestionItem[]) => void;
8
+ }
9
+ declare const createMentionSuggestion: (getSuggestionSource?: () => MentionSuggestionSource | undefined, options?: CreateMentionSuggestionOptions) => MentionOptions['suggestion'];
6
10
 
7
- export { createMentionSuggestion };
11
+ export { CreateMentionSuggestionOptions, createMentionSuggestion };