@haklex/rich-plugin-mention 0.0.39
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/LICENSE +28 -0
- package/dist/MentionMenuItem.d.ts +20 -0
- package/dist/MentionMenuItem.d.ts.map +1 -0
- package/dist/MentionMenuList.d.ts +11 -0
- package/dist/MentionMenuList.d.ts.map +1 -0
- package/dist/MentionMenuPlugin.d.ts +6 -0
- package/dist/MentionMenuPlugin.d.ts.map +1 -0
- package/dist/MentionPlatformRegistry.d.ts +10 -0
- package/dist/MentionPlatformRegistry.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +231 -0
- package/dist/rich-plugin-mention.css +1 -0
- package/dist/styles.css.d.ts +13 -0
- package/dist/styles.css.d.ts.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Innei
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
Additional Terms and Conditions
|
|
25
|
+
|
|
26
|
+
----------------
|
|
27
|
+
|
|
28
|
+
Use of this software is governed by the terms of MIT and, in addition, by the terms and conditions described in the additional file (ADDITIONAL_TERMS.md). By using this software, you agree to abide by these additional terms and conditions.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { MenuOption } from '@lexical/react/LexicalTypeaheadMenuPlugin';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
export type MentionMenuItemType = 'platform' | 'confirm';
|
|
4
|
+
export declare class MentionMenuItem extends MenuOption {
|
|
5
|
+
type: MentionMenuItemType;
|
|
6
|
+
platformKey: string;
|
|
7
|
+
icon: ReactNode;
|
|
8
|
+
label: string;
|
|
9
|
+
description: string;
|
|
10
|
+
handleText: string;
|
|
11
|
+
constructor(options: {
|
|
12
|
+
type: MentionMenuItemType;
|
|
13
|
+
platformKey: string;
|
|
14
|
+
icon?: ReactNode;
|
|
15
|
+
label: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
handleText?: string;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=MentionMenuItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionMenuItem.d.ts","sourceRoot":"","sources":["../src/MentionMenuItem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,2CAA2C,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,SAAS,CAAA;AAExD,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,IAAI,EAAE,mBAAmB,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;gBAEN,OAAO,EAAE;QACnB,IAAI,EAAE,mBAAmB,CAAA;QACzB,WAAW,EAAE,MAAM,CAAA;QACnB,IAAI,CAAC,EAAE,SAAS,CAAA;QAChB,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB;CASF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MentionMenuItem } from './MentionMenuItem';
|
|
2
|
+
interface MentionMenuListProps {
|
|
3
|
+
options: MentionMenuItem[];
|
|
4
|
+
selectedIndex: number | null;
|
|
5
|
+
selectOptionAndCleanUp: (option: MentionMenuItem) => void;
|
|
6
|
+
setHighlightedIndex: (index: number) => void;
|
|
7
|
+
phase: 1 | 2;
|
|
8
|
+
}
|
|
9
|
+
export declare function MentionMenuList({ options, selectedIndex, selectOptionAndCleanUp, setHighlightedIndex, phase, }: MentionMenuListProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=MentionMenuList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionMenuList.d.ts","sourceRoot":"","sources":["../src/MentionMenuList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAGxD,UAAU,oBAAoB;IAC5B,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,sBAAsB,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAA;IACzD,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5C,KAAK,EAAE,CAAC,GAAG,CAAC,CAAA;CACb;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,GACN,EAAE,oBAAoB,kDA+EtB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MentionPlatformDef } from './MentionPlatformRegistry';
|
|
2
|
+
export interface MentionMenuPluginProps {
|
|
3
|
+
extraPlatforms?: MentionPlatformDef[];
|
|
4
|
+
}
|
|
5
|
+
export declare function MentionMenuPlugin({ extraPlatforms, }?: MentionMenuPluginProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=MentionMenuPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionMenuPlugin.d.ts","sourceRoot":"","sources":["../src/MentionMenuPlugin.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAGnE,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,kBAAkB,EAAE,CAAA;CACtC;AAqDD,wBAAgB,iBAAiB,CAAC,EAChC,cAAc,GACf,GAAE,sBAA2B,2CAgF7B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface MentionPlatformDef {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
icon: ReactNode;
|
|
6
|
+
getUrl: (handle: string) => string;
|
|
7
|
+
}
|
|
8
|
+
export declare const builtinPlatforms: MentionPlatformDef[];
|
|
9
|
+
export declare function getAllPlatforms(extra?: MentionPlatformDef[]): MentionPlatformDef[];
|
|
10
|
+
//# sourceMappingURL=MentionPlatformRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionPlatformRegistry.d.ts","sourceRoot":"","sources":["../src/MentionPlatformRegistry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAA;CACnC;AAED,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAO9C,CAAA;AAEH,wBAAgB,eAAe,CAC7B,KAAK,CAAC,EAAE,kBAAkB,EAAE,GAC3B,kBAAkB,EAAE,CAOtB"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { MentionMenuItem } from './MentionMenuItem';
|
|
2
|
+
export type { MentionMenuPluginProps } from './MentionMenuPlugin';
|
|
3
|
+
export { MentionMenuPlugin } from './MentionMenuPlugin';
|
|
4
|
+
export type { MentionPlatformDef } from './MentionPlatformRegistry';
|
|
5
|
+
export { builtinPlatforms, getAllPlatforms } from './MentionPlatformRegistry';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { MenuOption, useBasicTypeaheadTriggerMatch, LexicalTypeaheadMenuPlugin } from "@lexical/react/LexicalTypeaheadMenuPlugin";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { $createMentionNode } from "@haklex/rich-editor";
|
|
7
|
+
import { PortalThemeWrapper } from "@haklex/rich-style-token";
|
|
8
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
9
|
+
import { $createTextNode } from "lexical";
|
|
10
|
+
import { useState, useMemo, useCallback } from "react";
|
|
11
|
+
import { createPortal } from "react-dom";
|
|
12
|
+
import { platformMetaMap } from "@haklex/rich-renderer-mention";
|
|
13
|
+
class MentionMenuItem extends MenuOption {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
super(options.platformKey + (options.handleText ?? ""));
|
|
16
|
+
__publicField(this, "type");
|
|
17
|
+
__publicField(this, "platformKey");
|
|
18
|
+
__publicField(this, "icon");
|
|
19
|
+
__publicField(this, "label");
|
|
20
|
+
__publicField(this, "description");
|
|
21
|
+
__publicField(this, "handleText");
|
|
22
|
+
this.type = options.type;
|
|
23
|
+
this.platformKey = options.platformKey;
|
|
24
|
+
this.icon = options.icon ?? "";
|
|
25
|
+
this.label = options.label;
|
|
26
|
+
this.description = options.description ?? "";
|
|
27
|
+
this.handleText = options.handleText ?? "";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
var mentionMenu = "_1t6e5is0";
|
|
31
|
+
var mentionMenuItem = "_1t6e5is1";
|
|
32
|
+
var mentionMenuItemIcon = "_1t6e5is2";
|
|
33
|
+
var mentionMenuItemText = "_1t6e5is3";
|
|
34
|
+
var mentionMenuItemTitle = "_1t6e5is4";
|
|
35
|
+
var mentionMenuItemDescription = "_1t6e5is5";
|
|
36
|
+
var mentionMenuHint = "_1t6e5is6";
|
|
37
|
+
var phase2Container = "_1t6e5is7";
|
|
38
|
+
var platformTag = "_1t6e5is8";
|
|
39
|
+
var platformTagIcon = "_1t6e5is9";
|
|
40
|
+
var phase2Hint = "_1t6e5isa";
|
|
41
|
+
function MentionMenuList({
|
|
42
|
+
options,
|
|
43
|
+
selectedIndex,
|
|
44
|
+
selectOptionAndCleanUp,
|
|
45
|
+
setHighlightedIndex,
|
|
46
|
+
phase
|
|
47
|
+
}) {
|
|
48
|
+
if (phase === 2) {
|
|
49
|
+
const item = options[0];
|
|
50
|
+
if (!item) return null;
|
|
51
|
+
return /* @__PURE__ */ jsx("div", { className: mentionMenu, children: /* @__PURE__ */ jsxs("div", { className: phase2Container, children: [
|
|
52
|
+
/* @__PURE__ */ jsxs("div", { className: platformTag, children: [
|
|
53
|
+
/* @__PURE__ */ jsx("span", { className: platformTagIcon, children: item.icon }),
|
|
54
|
+
item.description.split(" — ")[0]
|
|
55
|
+
] }),
|
|
56
|
+
item.handleText ? /* @__PURE__ */ jsx(
|
|
57
|
+
"ul",
|
|
58
|
+
{
|
|
59
|
+
style: { listStyle: "none", margin: 0, padding: 0 },
|
|
60
|
+
role: "listbox",
|
|
61
|
+
children: /* @__PURE__ */ jsx(
|
|
62
|
+
"li",
|
|
63
|
+
{
|
|
64
|
+
className: mentionMenuItem,
|
|
65
|
+
role: "option",
|
|
66
|
+
"aria-selected": selectedIndex === 0,
|
|
67
|
+
onClick: () => selectOptionAndCleanUp(item),
|
|
68
|
+
onMouseEnter: () => setHighlightedIndex(0),
|
|
69
|
+
ref: item.setRefElement,
|
|
70
|
+
tabIndex: -1,
|
|
71
|
+
style: { margin: 0 },
|
|
72
|
+
children: /* @__PURE__ */ jsxs("span", { className: mentionMenuItemText, children: [
|
|
73
|
+
/* @__PURE__ */ jsxs("span", { className: mentionMenuItemTitle, children: [
|
|
74
|
+
"@",
|
|
75
|
+
item.handleText
|
|
76
|
+
] }),
|
|
77
|
+
/* @__PURE__ */ jsx("span", { className: mentionMenuItemDescription, children: "Enter to confirm" })
|
|
78
|
+
] })
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
) : /* @__PURE__ */ jsx("div", { className: phase2Hint, children: "Type username, Enter to confirm" })
|
|
83
|
+
] }) });
|
|
84
|
+
}
|
|
85
|
+
if (options.length === 0) {
|
|
86
|
+
return /* @__PURE__ */ jsx("div", { className: mentionMenu, children: /* @__PURE__ */ jsx("div", { className: mentionMenuHint, children: "No matching platforms" }) });
|
|
87
|
+
}
|
|
88
|
+
return /* @__PURE__ */ jsx("ul", { className: mentionMenu, role: "listbox", children: options.map((item, index) => /* @__PURE__ */ jsxs(
|
|
89
|
+
"li",
|
|
90
|
+
{
|
|
91
|
+
className: mentionMenuItem,
|
|
92
|
+
role: "option",
|
|
93
|
+
"aria-selected": index === selectedIndex,
|
|
94
|
+
onClick: () => selectOptionAndCleanUp(item),
|
|
95
|
+
onMouseEnter: () => setHighlightedIndex(index),
|
|
96
|
+
ref: item.setRefElement,
|
|
97
|
+
tabIndex: -1,
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsx("span", { className: mentionMenuItemIcon, children: item.icon }),
|
|
100
|
+
/* @__PURE__ */ jsxs("span", { className: mentionMenuItemText, children: [
|
|
101
|
+
/* @__PURE__ */ jsx("span", { className: mentionMenuItemTitle, children: item.label }),
|
|
102
|
+
/* @__PURE__ */ jsx("span", { className: mentionMenuItemDescription, children: item.description })
|
|
103
|
+
] })
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
item.key
|
|
107
|
+
)) });
|
|
108
|
+
}
|
|
109
|
+
const builtinPlatforms = Object.entries(
|
|
110
|
+
platformMetaMap
|
|
111
|
+
).map(([key, meta]) => ({
|
|
112
|
+
key,
|
|
113
|
+
label: meta.label,
|
|
114
|
+
icon: meta.icon,
|
|
115
|
+
getUrl: meta.getUrl
|
|
116
|
+
}));
|
|
117
|
+
function getAllPlatforms(extra) {
|
|
118
|
+
if (!extra) return builtinPlatforms;
|
|
119
|
+
const map = /* @__PURE__ */ new Map();
|
|
120
|
+
for (const p of builtinPlatforms) map.set(p.key.toUpperCase(), p);
|
|
121
|
+
for (const p of extra)
|
|
122
|
+
map.set(p.key.toUpperCase(), { ...p, key: p.key.toUpperCase() });
|
|
123
|
+
return [...map.values()];
|
|
124
|
+
}
|
|
125
|
+
const MENTION_PUNCTUATION = `\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'"~=<>_;`;
|
|
126
|
+
function parseQueryPhase(query, platforms) {
|
|
127
|
+
const colonIdx = query.indexOf(":");
|
|
128
|
+
if (colonIdx !== -1) {
|
|
129
|
+
const platformKey = query.slice(0, colonIdx).toUpperCase();
|
|
130
|
+
const handle = query.slice(colonIdx + 1);
|
|
131
|
+
const platform = platforms.find((p) => p.key === platformKey);
|
|
132
|
+
if (platform) {
|
|
133
|
+
const confirmItem = new MentionMenuItem({
|
|
134
|
+
type: "confirm",
|
|
135
|
+
platformKey,
|
|
136
|
+
icon: platform.icon,
|
|
137
|
+
label: handle ? `@${handle}` : "Type username...",
|
|
138
|
+
description: `${platform.label} — Enter to confirm`,
|
|
139
|
+
handleText: handle
|
|
140
|
+
});
|
|
141
|
+
return { phase: 2, options: [confirmItem] };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const lower = query.toLowerCase();
|
|
145
|
+
const filtered = platforms.filter(
|
|
146
|
+
(p) => !query || p.key.toLowerCase().includes(lower) || p.label.toLowerCase().includes(lower)
|
|
147
|
+
).map(
|
|
148
|
+
(p) => new MentionMenuItem({
|
|
149
|
+
type: "platform",
|
|
150
|
+
platformKey: p.key,
|
|
151
|
+
icon: p.icon,
|
|
152
|
+
label: p.label,
|
|
153
|
+
description: `@${p.key}:username`
|
|
154
|
+
})
|
|
155
|
+
);
|
|
156
|
+
return { phase: 1, options: filtered };
|
|
157
|
+
}
|
|
158
|
+
function MentionMenuPlugin({
|
|
159
|
+
extraPlatforms
|
|
160
|
+
} = {}) {
|
|
161
|
+
const [editor] = useLexicalComposerContext();
|
|
162
|
+
const [queryString, setQueryString] = useState(null);
|
|
163
|
+
const platforms = useMemo(
|
|
164
|
+
() => getAllPlatforms(extraPlatforms),
|
|
165
|
+
[extraPlatforms]
|
|
166
|
+
);
|
|
167
|
+
const { phase, options } = useMemo(
|
|
168
|
+
() => parseQueryPhase(queryString ?? "", platforms),
|
|
169
|
+
[queryString, platforms]
|
|
170
|
+
);
|
|
171
|
+
const checkForTriggerMatch = useBasicTypeaheadTriggerMatch("@", {
|
|
172
|
+
minLength: 0,
|
|
173
|
+
punctuation: MENTION_PUNCTUATION
|
|
174
|
+
});
|
|
175
|
+
const onSelectOption = useCallback(
|
|
176
|
+
(option, textNodeContainingQuery, closeMenu) => {
|
|
177
|
+
if (option.type === "platform") {
|
|
178
|
+
if (textNodeContainingQuery) {
|
|
179
|
+
const text = `@${option.platformKey}:`;
|
|
180
|
+
const newTextNode = $createTextNode(text);
|
|
181
|
+
textNodeContainingQuery.replace(newTextNode);
|
|
182
|
+
newTextNode.select(text.length, text.length);
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
const handle = option.handleText.trim();
|
|
186
|
+
if (!handle) return;
|
|
187
|
+
const mentionNode = $createMentionNode(option.platformKey, handle);
|
|
188
|
+
if (textNodeContainingQuery) {
|
|
189
|
+
textNodeContainingQuery.replace(mentionNode);
|
|
190
|
+
}
|
|
191
|
+
const spaceNode = $createTextNode(" ");
|
|
192
|
+
mentionNode.insertAfter(spaceNode);
|
|
193
|
+
spaceNode.select(0, 0);
|
|
194
|
+
closeMenu();
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
[editor]
|
|
198
|
+
);
|
|
199
|
+
return /* @__PURE__ */ jsx(
|
|
200
|
+
LexicalTypeaheadMenuPlugin,
|
|
201
|
+
{
|
|
202
|
+
onQueryChange: setQueryString,
|
|
203
|
+
onSelectOption,
|
|
204
|
+
triggerFn: checkForTriggerMatch,
|
|
205
|
+
options,
|
|
206
|
+
menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => {
|
|
207
|
+
if (!anchorElementRef.current) return null;
|
|
208
|
+
if (phase === 1 && options.length === 0) return null;
|
|
209
|
+
return createPortal(
|
|
210
|
+
/* @__PURE__ */ jsx(PortalThemeWrapper, { children: /* @__PURE__ */ jsx(
|
|
211
|
+
MentionMenuList,
|
|
212
|
+
{
|
|
213
|
+
options,
|
|
214
|
+
selectedIndex,
|
|
215
|
+
selectOptionAndCleanUp,
|
|
216
|
+
setHighlightedIndex,
|
|
217
|
+
phase
|
|
218
|
+
}
|
|
219
|
+
) }),
|
|
220
|
+
anchorElementRef.current
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
export {
|
|
227
|
+
MentionMenuItem,
|
|
228
|
+
MentionMenuPlugin,
|
|
229
|
+
builtinPlatforms,
|
|
230
|
+
getAllPlatforms
|
|
231
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}:root.dark{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._16vg1w00{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._16vg1w01{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.8;--rc-line-height-tight: 1.4;--rc-font-family: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._16vg1w02{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #a1a1aa;--rc-quote-bg: #fafafa;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: none;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 2px;--rc-space-sm: 4px;--rc-space-md: 10px;--rc-space-lg: 16px;--rc-space-xl: 20px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 14px;--rc-font-size-small: 12px;--rc-line-height: 1.5;--rc-line-height-tight: 1.3;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 3px;--rc-radius-md: 6px;--rc-radius-lg: 8px}.dark ._16vg1w00,[data-theme=dark] ._16vg1w00,.dark._16vg1w00,[data-theme=dark]._16vg1w00,.dark ._16vg1w01,[data-theme=dark] ._16vg1w01,.dark._16vg1w01,[data-theme=dark]._16vg1w01,.dark ._16vg1w02,[data-theme=dark] ._16vg1w02,.dark._16vg1w02,[data-theme=dark]._16vg1w02{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4)}._1t6e5is0{position:absolute;top:0;left:0;width:280px;max-height:300px;overflow-y:auto;overflow-x:hidden;font-family:var(--rc-font-family);background:var(--rc-bg);border:1px solid var(--rc-border);border-radius:10px;box-shadow:var(--rc-shadow-menu);padding:6px 0;list-style:none;margin:0}._1t6e5is0::-webkit-scrollbar{width:6px}._1t6e5is0::-webkit-scrollbar-thumb{background:#0000001a;border-radius:3px}._1t6e5is1{display:flex;align-items:center;gap:10px;padding:6px 10px;margin:0 6px;border-radius:8px;cursor:pointer;transition:background .1s ease}._1t6e5is1:hover,._1t6e5is1[aria-selected=true]{background:var(--rc-bg-secondary)}._1t6e5is2{width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;border-radius:6px;background:var(--rc-bg-secondary);border:1px solid var(--rc-border);color:var(--rc-text-secondary);line-height:1}._1t6e5is3{display:flex;flex-direction:column;min-width:0;gap:1px}._1t6e5is4{font-size:14px;font-weight:500;line-height:1.3;color:var(--rc-text)}._1t6e5is5{font-size:12px;line-height:1.3;color:var(--rc-text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._1t6e5is6{padding:8px 14px;font-size:12px;color:var(--rc-text-secondary);user-select:none}._1t6e5is7{padding:8px 10px;margin:0 6px}._1t6e5is8{display:inline-flex;align-items:center;gap:5px;padding:3px 8px;border-radius:6px;font-size:12px;font-weight:500;line-height:1.3;background:var(--rc-bg-secondary);border:1px solid var(--rc-border);color:var(--rc-text);margin-bottom:6px}._1t6e5is9{display:flex;align-items:center;font-size:14px}._1t6e5isa{font-size:12px;color:var(--rc-text-secondary);margin-top:2px}._1t6e5isb{font-size:14px;font-weight:500;color:var(--rc-text);margin-top:4px}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const mentionMenu: string;
|
|
2
|
+
export declare const mentionMenuItem: string;
|
|
3
|
+
export declare const mentionMenuItemIcon: string;
|
|
4
|
+
export declare const mentionMenuItemText: string;
|
|
5
|
+
export declare const mentionMenuItemTitle: string;
|
|
6
|
+
export declare const mentionMenuItemDescription: string;
|
|
7
|
+
export declare const mentionMenuHint: string;
|
|
8
|
+
export declare const phase2Container: string;
|
|
9
|
+
export declare const platformTag: string;
|
|
10
|
+
export declare const platformTagIcon: string;
|
|
11
|
+
export declare const phase2Hint: string;
|
|
12
|
+
export declare const phase2Handle: string;
|
|
13
|
+
//# sourceMappingURL=styles.css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,QAgBtB,CAAA;AAWF,eAAO,MAAM,eAAe,QAS1B,CAAA;AASF,eAAO,MAAM,mBAAmB,QAa9B,CAAA;AAEF,eAAO,MAAM,mBAAmB,QAK9B,CAAA;AAEF,eAAO,MAAM,oBAAoB,QAK/B,CAAA;AAEF,eAAO,MAAM,0BAA0B,QAOrC,CAAA;AAEF,eAAO,MAAM,eAAe,QAK1B,CAAA;AAGF,eAAO,MAAM,eAAe,QAG1B,CAAA;AAEF,eAAO,MAAM,WAAW,QAatB,CAAA;AAEF,eAAO,MAAM,eAAe,QAI1B,CAAA;AAEF,eAAO,MAAM,UAAU,QAIrB,CAAA;AAEF,eAAO,MAAM,YAAY,QAKvB,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@haklex/rich-plugin-mention",
|
|
3
|
+
"version": "0.0.39",
|
|
4
|
+
"description": "Mention typeahead plugin with platform selection",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./style.css": "./dist/rich-plugin-mention.css"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.mjs",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@haklex/rich-renderer-mention": "0.0.39",
|
|
20
|
+
"@haklex/rich-editor": "0.0.39",
|
|
21
|
+
"@haklex/rich-style-token": "0.0.39"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@lexical/react": "^0.41.0",
|
|
25
|
+
"@types/react": "^19.2.14",
|
|
26
|
+
"@types/react-dom": "^19.2.3",
|
|
27
|
+
"@vanilla-extract/css": "^1.18.0",
|
|
28
|
+
"@vanilla-extract/vite-plugin": "^4.0.20",
|
|
29
|
+
"lexical": "^0.41.0",
|
|
30
|
+
"react": "19.2.4",
|
|
31
|
+
"react-dom": "19.2.4",
|
|
32
|
+
"typescript": "^5.9.3",
|
|
33
|
+
"vite": "^7.3.1",
|
|
34
|
+
"vite-plugin-dts": "^4.5.4"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@lexical/react": "^0.41.0",
|
|
38
|
+
"lexical": "^0.41.0",
|
|
39
|
+
"react": ">=19",
|
|
40
|
+
"react-dom": ">=19"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "vite build",
|
|
47
|
+
"dev:build": "vite build --watch"
|
|
48
|
+
},
|
|
49
|
+
"types": "./dist/index.d.ts"
|
|
50
|
+
}
|