@thebuoyant-tsdev/mui-ts-library 3.13.0 → 3.14.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.
- package/README.de.md +7 -0
- package/README.md +7 -0
- package/dist/components/color-picker/ColorPicker.js +1 -2
- package/dist/components/rich-text-editor/RichTextEditor.d.ts +1 -1
- package/dist/components/rich-text-editor/RichTextEditor.js +95 -68
- package/dist/components/rich-text-editor/RichTextEditor.types.d.ts +24 -0
- package/dist/components/rich-text-editor/RichTextEditor.types.js +2 -1
- package/dist/components/rich-text-editor/RichTextEditorMentionList.d.ts +11 -0
- package/dist/components/rich-text-editor/RichTextEditorMentionList.js +54 -0
- package/dist/components/rich-text-editor/RichTextEditorMentionSuggestion.d.ts +9 -0
- package/dist/components/rich-text-editor/RichTextEditorMentionSuggestion.js +45 -0
- package/dist/index.cjs +2 -2
- package/package.json +2 -1
package/README.de.md
CHANGED
|
@@ -434,6 +434,13 @@ Dieses Projekt folgt [Semantic Versioning](https://semver.org/). In der Praxis b
|
|
|
434
434
|
|
|
435
435
|
## Changelog
|
|
436
436
|
|
|
437
|
+
### [3.14.0] — 2026-07-02
|
|
438
|
+
|
|
439
|
+
**Hinzugefügt**
|
|
440
|
+
- RichTextEditor: `@`-Mention-Autocomplete (`mentionItems`, `onMentionSearch`, `mentionTriggerChar`, `translation.mentionNoResults`). Dropdown am Cursor verankert, Tastaturnavigation (↑/↓/Enter/Escape), im HTML-Output als `<span data-type="mention" data-id="…">` serialisiert. Neuer Export: `MentionItem`. Neue Peer-Abhängigkeit: `@tiptap/extension-mention`. Siehe [Vollständiger Changelog](https://github.com/thebuoyant/mui-ts-library/blob/main/CHANGELOG.md) für Details.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
437
444
|
### [3.13.0] — 2026-06-29
|
|
438
445
|
|
|
439
446
|
**Hinzugefügt**
|
package/README.md
CHANGED
|
@@ -434,6 +434,13 @@ This project follows [Semantic Versioning](https://semver.org/). In practice:
|
|
|
434
434
|
|
|
435
435
|
## Changelog
|
|
436
436
|
|
|
437
|
+
### [3.14.0] — 2026-07-02
|
|
438
|
+
|
|
439
|
+
**Added**
|
|
440
|
+
- RichTextEditor: `@`-mention autocomplete (`mentionItems`, `onMentionSearch`, `mentionTriggerChar`, `translation.mentionNoResults`). Dropdown anchored to the cursor, keyboard navigation (↑/↓/Enter/Escape), serialised as `<span data-type="mention" data-id="…">` in HTML output. New export: `MentionItem`. New peer dependency: `@tiptap/extension-mention`. See [Full Changelog](https://github.com/thebuoyant/mui-ts-library/blob/main/CHANGELOG.md) for details.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
437
444
|
### [3.13.0] — 2026-06-29
|
|
438
445
|
|
|
439
446
|
**Added**
|
|
@@ -303,8 +303,7 @@ function x({ value: o, onChange: x, onChangeCommitted: S, defaultFormat: ae = "h
|
|
|
303
303
|
disabled: T,
|
|
304
304
|
onChange: (e) => ye(e.target.value),
|
|
305
305
|
sx: {
|
|
306
|
-
minWidth:
|
|
307
|
-
fontSize: "0.75rem",
|
|
306
|
+
minWidth: 80,
|
|
308
307
|
flexShrink: 0
|
|
309
308
|
},
|
|
310
309
|
children: [
|
|
@@ -5,4 +5,4 @@ declare module "@tiptap/core" {
|
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
import { type RichTextEditorProps } from "./RichTextEditor.types";
|
|
8
|
-
export declare function RichTextEditor({ disabled, error, height, helperText, maxCharacters, name, placeholder, readonly, showCharacterCount, showToolbar, showWordCount, toolbarConfig, translation, value, width, onBlur, onChange, onFocus, onMarkdownChange, }: RichTextEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function RichTextEditor({ disabled, error, height, helperText, maxCharacters, mentionItems, mentionTriggerChar, name, onMentionSearch, placeholder, readonly, showCharacterCount, showToolbar, showWordCount, toolbarConfig, translation, value, width, onBlur, onChange, onFocus, onMarkdownChange, }: RichTextEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,56 +1,83 @@
|
|
|
1
1
|
import { normalizeSize as e } from "../shared/normalizeSize.js";
|
|
2
2
|
import { DEFAULT_RICH_TEXT_EDITOR_TOOLBAR_CONFIG as t, DEFAULT_RICH_TEXT_EDITOR_TRANSLATION as n } from "./RichTextEditor.types.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
3
|
+
import { buildMentionSuggestion as r } from "./RichTextEditorMentionSuggestion.js";
|
|
4
|
+
import { RichTextEditorContent as i } from "./RichTextEditorContent.js";
|
|
5
|
+
import { RichTextEditorToolbar as a } from "./RichTextEditorToolbar.js";
|
|
6
|
+
import { RichTextEditorFooter as ee } from "./RichTextEditorFooter.js";
|
|
7
|
+
import { useEffect as o, useMemo as te, useRef as s, useState as c } from "react";
|
|
8
|
+
import { Box as l, Divider as u, Paper as ne } from "@mui/material";
|
|
9
|
+
import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
10
|
+
import { useEditor as re } from "@tiptap/react";
|
|
11
|
+
import { Mention as m } from "@tiptap/extension-mention";
|
|
12
|
+
import { StarterKit as h } from "@tiptap/starter-kit";
|
|
13
|
+
import { TextStyle as ie } from "@tiptap/extension-text-style";
|
|
14
|
+
import { Color as g } from "@tiptap/extension-color";
|
|
15
|
+
import { Highlight as _ } from "@tiptap/extension-highlight";
|
|
16
|
+
import { Placeholder as ae } from "@tiptap/extension-placeholder";
|
|
17
|
+
import { CharacterCount as v } from "@tiptap/extension-character-count";
|
|
18
|
+
import { TableKit as oe } from "@tiptap/extension-table";
|
|
19
|
+
import { Image as y } from "@tiptap/extension-image";
|
|
20
|
+
import { Markdown as b } from "tiptap-markdown";
|
|
19
21
|
//#region src/components/rich-text-editor/RichTextEditor.tsx
|
|
20
|
-
function
|
|
22
|
+
function x({ disabled: x = !1, error: S = !1, height: se, helperText: C, maxCharacters: w, mentionItems: T, mentionTriggerChar: E = "@", name: D, onMentionSearch: O, placeholder: k, readonly: A = !1, showCharacterCount: j = !1, showToolbar: M = !0, showWordCount: N = !1, toolbarConfig: P, translation: F, value: I, width: L, onBlur: R, onChange: z, onFocus: B, onMarkdownChange: V }) {
|
|
21
23
|
let H = {
|
|
22
24
|
...n,
|
|
23
|
-
...
|
|
25
|
+
...F
|
|
24
26
|
}, U = {
|
|
25
27
|
...t,
|
|
26
|
-
...
|
|
27
|
-
}, [W, G] = c(!1), [K,
|
|
28
|
+
...P
|
|
29
|
+
}, [W, G] = c(!1), [K, ce] = c(!1), q = s(K), J = s(T ?? []);
|
|
28
30
|
o(() => {
|
|
29
|
-
J.current =
|
|
31
|
+
J.current = T ?? [];
|
|
32
|
+
}, [T]), o(() => {
|
|
33
|
+
q.current = K;
|
|
30
34
|
}, [K]);
|
|
31
|
-
let Y = e(
|
|
35
|
+
let Y = e(se), le = e(L), X = Y === "auto", ue = X ? void 0 : Y ?? 200, Z = T !== void 0 || O !== void 0, Q = te(() => Z ? m.configure({
|
|
36
|
+
HTMLAttributes: { class: "rte-mention" },
|
|
37
|
+
renderHTML({ options: e, node: t }) {
|
|
38
|
+
return [
|
|
39
|
+
"span",
|
|
40
|
+
{
|
|
41
|
+
...e.HTMLAttributes,
|
|
42
|
+
"data-id": t.attrs.id,
|
|
43
|
+
"data-label": t.attrs.label
|
|
44
|
+
},
|
|
45
|
+
`${E}${t.attrs.label}`
|
|
46
|
+
];
|
|
47
|
+
},
|
|
48
|
+
suggestion: r({
|
|
49
|
+
getItems: () => J.current,
|
|
50
|
+
onMentionSearch: O,
|
|
51
|
+
noResultsLabel: H.mentionNoResults ?? "No results"
|
|
52
|
+
})
|
|
53
|
+
}) : null, [
|
|
54
|
+
Z,
|
|
55
|
+
E,
|
|
56
|
+
O
|
|
57
|
+
]), de = w !== void 0 && w > 0 || j || N, $ = re({
|
|
32
58
|
shouldRerenderOnTransaction: !0,
|
|
33
59
|
extensions: [
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
60
|
+
h.configure({ link: { openOnClick: !1 } }),
|
|
61
|
+
ie,
|
|
62
|
+
g,
|
|
63
|
+
_.configure({ multicolor: !0 }),
|
|
64
|
+
b.configure({
|
|
39
65
|
transformPastedText: !0,
|
|
40
66
|
transformCopiedText: !1
|
|
41
67
|
}),
|
|
42
|
-
|
|
43
|
-
...U.showTableButton ? [
|
|
44
|
-
...U.showImageButton ? [
|
|
68
|
+
ae.configure({ placeholder: k ?? "" }),
|
|
69
|
+
...U.showTableButton ? [oe] : [],
|
|
70
|
+
...U.showImageButton ? [y.configure({
|
|
45
71
|
inline: !1,
|
|
46
72
|
allowBase64: !0
|
|
47
73
|
})] : [],
|
|
48
|
-
...
|
|
74
|
+
...Q ? [Q] : [],
|
|
75
|
+
...de ? w !== void 0 && w > 0 ? [v.configure({ limit: w })] : [v] : []
|
|
49
76
|
],
|
|
50
|
-
content:
|
|
51
|
-
editable: !
|
|
77
|
+
content: I ?? "",
|
|
78
|
+
editable: !x && !A,
|
|
52
79
|
editorProps: { handlePaste(e, t) {
|
|
53
|
-
if (!
|
|
80
|
+
if (!q.current) return !1;
|
|
54
81
|
let n = t.clipboardData?.getData("text/plain");
|
|
55
82
|
if (!n) return !1;
|
|
56
83
|
t.preventDefault();
|
|
@@ -58,26 +85,26 @@ function w({ disabled: w = !1, error: T = !1, height: E, helperText: D, maxChara
|
|
|
58
85
|
return e.dispatch(r.tr.insertText(n, r.selection.from, r.selection.to)), !0;
|
|
59
86
|
} },
|
|
60
87
|
onUpdate({ editor: e }) {
|
|
61
|
-
|
|
88
|
+
z?.(e.getHTML()), V?.(e.storage.markdown.getMarkdown());
|
|
62
89
|
},
|
|
63
90
|
onBlur() {
|
|
64
|
-
|
|
91
|
+
R?.();
|
|
65
92
|
},
|
|
66
93
|
onFocus() {
|
|
67
|
-
|
|
94
|
+
B?.();
|
|
68
95
|
}
|
|
69
96
|
});
|
|
70
97
|
o(() => {
|
|
71
|
-
!$ ||
|
|
72
|
-
}, [$,
|
|
73
|
-
$ && $.setEditable(!
|
|
98
|
+
!$ || I === void 0 || $.getHTML() !== I && $.commands.setContent(I, { emitUpdate: !1 });
|
|
99
|
+
}, [$, I]), o(() => {
|
|
100
|
+
$ && $.setEditable(!x && !A);
|
|
74
101
|
}, [
|
|
75
102
|
$,
|
|
76
|
-
|
|
77
|
-
|
|
103
|
+
x,
|
|
104
|
+
A
|
|
78
105
|
]);
|
|
79
|
-
let
|
|
80
|
-
return /* @__PURE__ */
|
|
106
|
+
let fe = $?.storage.characterCount?.characters?.() ?? 0, pe = $?.storage.characterCount?.words?.() ?? 0, me = j || w !== void 0 && w > 0 || N || !!C;
|
|
107
|
+
return /* @__PURE__ */ p(l, {
|
|
81
108
|
sx: W ? {
|
|
82
109
|
position: "fixed",
|
|
83
110
|
top: 0,
|
|
@@ -90,60 +117,60 @@ function w({ disabled: w = !1, error: T = !1, height: E, helperText: D, maxChara
|
|
|
90
117
|
bgcolor: "background.default",
|
|
91
118
|
p: 1
|
|
92
119
|
} : {
|
|
93
|
-
width:
|
|
94
|
-
...
|
|
120
|
+
width: le ?? "100%",
|
|
121
|
+
...X ? {
|
|
95
122
|
display: "flex",
|
|
96
123
|
flexDirection: "column",
|
|
97
124
|
flex: 1
|
|
98
125
|
} : {}
|
|
99
126
|
},
|
|
100
127
|
children: [
|
|
101
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ p(ne, {
|
|
102
129
|
variant: "outlined",
|
|
103
130
|
sx: {
|
|
104
131
|
display: "flex",
|
|
105
132
|
flexDirection: "column",
|
|
106
133
|
overflow: "hidden",
|
|
107
|
-
...W ||
|
|
108
|
-
borderColor:
|
|
134
|
+
...W || X ? { flex: 1 } : { height: ue },
|
|
135
|
+
borderColor: S ? "error.main" : void 0,
|
|
109
136
|
"&:focus-within": {
|
|
110
|
-
borderColor:
|
|
137
|
+
borderColor: S ? "error.main" : "primary.main",
|
|
111
138
|
borderWidth: 2
|
|
112
139
|
}
|
|
113
140
|
},
|
|
114
|
-
children: [
|
|
141
|
+
children: [M && !A && /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(a, {
|
|
115
142
|
editor: $,
|
|
116
143
|
toolbarConfig: U,
|
|
117
144
|
translation: H,
|
|
118
|
-
disabled:
|
|
145
|
+
disabled: x,
|
|
119
146
|
isFullscreen: W,
|
|
120
147
|
onToggleFullscreen: () => G((e) => !e),
|
|
121
148
|
pasteAsPlainText: K,
|
|
122
|
-
onTogglePasteAsPlainText: () =>
|
|
123
|
-
}), /* @__PURE__ */
|
|
149
|
+
onTogglePasteAsPlainText: () => ce((e) => !e)
|
|
150
|
+
}), /* @__PURE__ */ f(u, {})] }), /* @__PURE__ */ f(i, {
|
|
124
151
|
editor: $,
|
|
125
|
-
error:
|
|
126
|
-
disabled:
|
|
127
|
-
readonly:
|
|
152
|
+
error: S,
|
|
153
|
+
disabled: x,
|
|
154
|
+
readonly: A
|
|
128
155
|
})]
|
|
129
156
|
}),
|
|
130
|
-
|
|
131
|
-
helperText:
|
|
132
|
-
error:
|
|
133
|
-
showCharacterCount:
|
|
134
|
-
charCount:
|
|
135
|
-
maxCharacters:
|
|
136
|
-
showWordCount:
|
|
137
|
-
wordCount:
|
|
157
|
+
me && /* @__PURE__ */ f(ee, {
|
|
158
|
+
helperText: C,
|
|
159
|
+
error: S,
|
|
160
|
+
showCharacterCount: j || w !== void 0 && w > 0,
|
|
161
|
+
charCount: fe,
|
|
162
|
+
maxCharacters: w && w > 0 ? w : void 0,
|
|
163
|
+
showWordCount: N,
|
|
164
|
+
wordCount: pe,
|
|
138
165
|
translation: H
|
|
139
166
|
}),
|
|
140
|
-
|
|
167
|
+
D && /* @__PURE__ */ f("input", {
|
|
141
168
|
type: "hidden",
|
|
142
|
-
name:
|
|
169
|
+
name: D,
|
|
143
170
|
value: $ ? $.getHTML() : ""
|
|
144
171
|
})
|
|
145
172
|
]
|
|
146
173
|
});
|
|
147
174
|
}
|
|
148
175
|
//#endregion
|
|
149
|
-
export {
|
|
176
|
+
export { x as RichTextEditor };
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export type MentionItem = {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
};
|
|
1
5
|
export type RichTextEditorToolbarConfig = {
|
|
2
6
|
showBold?: boolean;
|
|
3
7
|
showItalic?: boolean;
|
|
@@ -99,6 +103,8 @@ export type RichTextEditorTranslation = {
|
|
|
99
103
|
markdownDialogCopy?: string;
|
|
100
104
|
/** @since 3.8.0 */
|
|
101
105
|
markdownDialogCopied?: string;
|
|
106
|
+
/** Text shown in mention dropdown when no items match the query @since 3.14.0 */
|
|
107
|
+
mentionNoResults?: string;
|
|
102
108
|
};
|
|
103
109
|
export declare const DEFAULT_RICH_TEXT_EDITOR_TRANSLATION: Required<RichTextEditorTranslation>;
|
|
104
110
|
export type RichTextEditorProps = {
|
|
@@ -121,6 +127,24 @@ export type RichTextEditorProps = {
|
|
|
121
127
|
value?: string;
|
|
122
128
|
/** Breite des Editors. Zahlen → px. "auto" oder leer → 100% des Elternelements. */
|
|
123
129
|
width?: number | string;
|
|
130
|
+
/**
|
|
131
|
+
* List of items for @-mention autocomplete. The Mention extension is only active when this prop is provided.
|
|
132
|
+
* Used for client-side filtering when `onMentionSearch` is not provided.
|
|
133
|
+
* @since 3.14.0
|
|
134
|
+
*/
|
|
135
|
+
mentionItems?: MentionItem[];
|
|
136
|
+
/**
|
|
137
|
+
* Custom search/filter function called on each keystroke after @.
|
|
138
|
+
* When provided, `mentionItems` is ignored for filtering — return the relevant subset.
|
|
139
|
+
* Supports async for server-side search.
|
|
140
|
+
* @since 3.14.0
|
|
141
|
+
*/
|
|
142
|
+
onMentionSearch?: (query: string) => MentionItem[] | Promise<MentionItem[]>;
|
|
143
|
+
/**
|
|
144
|
+
* Character that triggers the mention autocomplete popup. Default: "@"
|
|
145
|
+
* @since 3.14.0
|
|
146
|
+
*/
|
|
147
|
+
mentionTriggerChar?: string;
|
|
124
148
|
onBlur?: () => void;
|
|
125
149
|
onChange?: (value: string) => void;
|
|
126
150
|
onFocus?: () => void;
|
|
@@ -79,7 +79,8 @@ var e = {
|
|
|
79
79
|
markdownDialogApply: "Apply",
|
|
80
80
|
markdownDialogCancel: "Cancel",
|
|
81
81
|
markdownDialogCopy: "Copy",
|
|
82
|
-
markdownDialogCopied: "Copied!"
|
|
82
|
+
markdownDialogCopied: "Copied!",
|
|
83
|
+
mentionNoResults: "No results"
|
|
83
84
|
};
|
|
84
85
|
//#endregion
|
|
85
86
|
export { e as DEFAULT_RICH_TEXT_EDITOR_TOOLBAR_CONFIG, t as DEFAULT_RICH_TEXT_EDITOR_TRANSLATION };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MentionItem } from "./RichTextEditor.types";
|
|
2
|
+
export type MentionListProps = {
|
|
3
|
+
items: MentionItem[];
|
|
4
|
+
noResultsLabel: string;
|
|
5
|
+
clientRect: (() => DOMRect | null) | null;
|
|
6
|
+
onSelect: (item: MentionItem) => void;
|
|
7
|
+
};
|
|
8
|
+
export type MentionListRef = {
|
|
9
|
+
onKeyDown: (event: KeyboardEvent) => boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const RichTextEditorMentionList: import("react").ForwardRefExoticComponent<MentionListProps & import("react").RefAttributes<MentionListRef>>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { forwardRef as e, useEffect as t, useImperativeHandle as n, useRef as r, useState as i } from "react";
|
|
2
|
+
import { List as a, ListItemButton as o, Paper as s, Popper as c, Typography as l } from "@mui/material";
|
|
3
|
+
import { jsx as u } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/rich-text-editor/RichTextEditorMentionList.tsx
|
|
5
|
+
var d = e(function({ items: e, noResultsLabel: d, clientRect: f, onSelect: p }, m) {
|
|
6
|
+
let [h, g] = i(0), [_, v] = i(e), y = r(null);
|
|
7
|
+
e !== _ && (v(e), g(0)), t(() => {
|
|
8
|
+
(y.current?.children[h])?.scrollIntoView({ block: "nearest" });
|
|
9
|
+
}, [h]), n(m, () => ({ onKeyDown(t) {
|
|
10
|
+
return t.key === "ArrowUp" ? (g((t) => (t - 1 + e.length) % e.length), !0) : t.key === "ArrowDown" ? (g((t) => (t + 1) % e.length), !0) : t.key === "Enter" ? (e[h] && p(e[h]), !0) : !1;
|
|
11
|
+
} }));
|
|
12
|
+
let b = f ? { getBoundingClientRect: f } : null;
|
|
13
|
+
return /* @__PURE__ */ u(c, {
|
|
14
|
+
open: !!b,
|
|
15
|
+
anchorEl: b,
|
|
16
|
+
placement: "bottom-start",
|
|
17
|
+
modifiers: [{
|
|
18
|
+
name: "offset",
|
|
19
|
+
options: { offset: [0, 4] }
|
|
20
|
+
}],
|
|
21
|
+
style: { zIndex: 1400 },
|
|
22
|
+
children: /* @__PURE__ */ u(s, {
|
|
23
|
+
elevation: 4,
|
|
24
|
+
sx: {
|
|
25
|
+
maxHeight: 240,
|
|
26
|
+
overflow: "auto",
|
|
27
|
+
minWidth: 180
|
|
28
|
+
},
|
|
29
|
+
children: e.length === 0 ? /* @__PURE__ */ u(l, {
|
|
30
|
+
variant: "body2",
|
|
31
|
+
sx: {
|
|
32
|
+
px: 2,
|
|
33
|
+
py: 1,
|
|
34
|
+
color: "text.secondary"
|
|
35
|
+
},
|
|
36
|
+
children: d
|
|
37
|
+
}) : /* @__PURE__ */ u(a, {
|
|
38
|
+
ref: y,
|
|
39
|
+
dense: !0,
|
|
40
|
+
disablePadding: !0,
|
|
41
|
+
children: e.map((e, t) => /* @__PURE__ */ u(o, {
|
|
42
|
+
selected: t === h,
|
|
43
|
+
onMouseDown: (t) => {
|
|
44
|
+
t.preventDefault(), p(e);
|
|
45
|
+
},
|
|
46
|
+
onMouseEnter: () => g(t),
|
|
47
|
+
children: e.label
|
|
48
|
+
}, e.id))
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//#endregion
|
|
54
|
+
export { d as RichTextEditorMentionList };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SuggestionOptions } from "@tiptap/suggestion";
|
|
2
|
+
import type { MentionItem } from "./RichTextEditor.types";
|
|
3
|
+
type BuildSuggestionOptions = {
|
|
4
|
+
getItems: () => MentionItem[];
|
|
5
|
+
onMentionSearch?: (query: string) => MentionItem[] | Promise<MentionItem[]>;
|
|
6
|
+
noResultsLabel: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function buildMentionSuggestion({ getItems, onMentionSearch, noResultsLabel, }: BuildSuggestionOptions): Partial<SuggestionOptions<MentionItem>>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { RichTextEditorMentionList as e } from "./RichTextEditorMentionList.js";
|
|
2
|
+
import { ReactRenderer as t } from "@tiptap/react";
|
|
3
|
+
//#region src/components/rich-text-editor/RichTextEditorMentionSuggestion.ts
|
|
4
|
+
function n({ getItems: n, onMentionSearch: r, noResultsLabel: i }) {
|
|
5
|
+
return {
|
|
6
|
+
items: async ({ query: e }) => {
|
|
7
|
+
if (r) return r(e);
|
|
8
|
+
let t = n(), i = e.toLowerCase();
|
|
9
|
+
return t.filter((e) => e.label.toLowerCase().includes(i));
|
|
10
|
+
},
|
|
11
|
+
render() {
|
|
12
|
+
let n = null;
|
|
13
|
+
return {
|
|
14
|
+
onStart(r) {
|
|
15
|
+
n = new t(e, {
|
|
16
|
+
props: {
|
|
17
|
+
items: r.items,
|
|
18
|
+
noResultsLabel: i,
|
|
19
|
+
clientRect: r.clientRect,
|
|
20
|
+
onSelect: (e) => r.command({
|
|
21
|
+
id: e.id,
|
|
22
|
+
label: e.label
|
|
23
|
+
})
|
|
24
|
+
},
|
|
25
|
+
editor: r.editor
|
|
26
|
+
}), document.body.appendChild(n.element);
|
|
27
|
+
},
|
|
28
|
+
onUpdate(e) {
|
|
29
|
+
n?.updateProps({
|
|
30
|
+
items: e.items,
|
|
31
|
+
clientRect: e.clientRect
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
onKeyDown(e) {
|
|
35
|
+
return e.event.key === "Escape" ? (n?.destroy(), n = null, !0) : n?.ref?.onKeyDown(e.event) ?? !1;
|
|
36
|
+
},
|
|
37
|
+
onExit() {
|
|
38
|
+
n?.element.remove(), n?.destroy(), n = null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { n as buildMentionSuggestion };
|