@lexical/react 0.1.16 → 0.1.19
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/DEPRECATED_useLexicalAutoFormatter.dev.js +5 -729
- package/DEPRECATED_useLexicalAutoFormatter.prod.js +1 -19
- package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +1 -1
- package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +1 -1
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +9 -10
- package/DEPRECATED_useLexicalCharacterLimit.prod.js +7 -7
- package/DEPRECATED_useLexicalDecorators.dev.js +1 -1
- package/DEPRECATED_useLexicalDecorators.prod.js +1 -1
- package/DEPRECATED_useLexicalEditorEvents.dev.js +1 -1
- package/DEPRECATED_useLexicalEditorEvents.prod.js +1 -1
- package/DEPRECATED_useLexicalHistory.dev.js +5 -307
- package/DEPRECATED_useLexicalHistory.prod.js +1 -7
- package/DEPRECATED_useLexicalList.dev.js +29 -25
- package/DEPRECATED_useLexicalList.prod.js +3 -1
- package/DEPRECATED_useLexicalPlainText.dev.js +8 -662
- package/DEPRECATED_useLexicalPlainText.prod.js +2 -14
- package/DEPRECATED_useLexicalRichText.dev.js +8 -747
- package/DEPRECATED_useLexicalRichText.prod.js +2 -17
- package/LICENSE +1 -1
- package/{withSubscriptions.prod.js → LexicalAutoFocusPlugin.d.ts} +3 -1
- package/{withSubscriptions.dev.js → LexicalAutoFocusPlugin.dev.js} +10 -5
- package/LexicalAutoFocusPlugin.js +9 -0
- package/{LexicalAutoFormatterPlugin.js.flow → LexicalAutoFocusPlugin.js.flow} +1 -1
- package/LexicalAutoFocusPlugin.prod.js +7 -0
- package/LexicalAutoLinkPlugin.dev.js +12 -15
- package/LexicalAutoLinkPlugin.prod.js +6 -6
- package/LexicalAutoScrollPlugin.d.ts +13 -0
- package/LexicalAutoScrollPlugin.dev.js +82 -0
- package/LexicalAutoScrollPlugin.js +9 -0
- package/{withSubscriptions.d.ts → LexicalAutoScrollPlugin.js.flow} +5 -5
- package/LexicalAutoScrollPlugin.prod.js +8 -0
- package/LexicalCharacterLimitPlugin.dev.js +9 -10
- package/LexicalCharacterLimitPlugin.prod.js +7 -7
- package/LexicalClearEditorPlugin.dev.js +15 -19
- package/LexicalClearEditorPlugin.prod.js +1 -1
- package/LexicalCollaborationPlugin.d.ts +6 -3
- package/LexicalCollaborationPlugin.dev.js +30 -41
- package/LexicalCollaborationPlugin.js.flow +7 -4
- package/LexicalCollaborationPlugin.prod.js +10 -9
- package/LexicalComposer.d.ts +2 -2
- package/LexicalComposer.dev.js +3 -19
- package/LexicalComposer.js.flow +2 -2
- package/LexicalComposer.prod.js +2 -3
- package/LexicalContentEditable.dev.js +3 -1
- package/LexicalContentEditable.prod.js +2 -2
- package/LexicalHashtagPlugin.dev.js +20 -94
- package/LexicalHashtagPlugin.prod.js +4 -7
- package/LexicalHistoryPlugin.dev.js +5 -307
- package/LexicalHistoryPlugin.prod.js +1 -7
- package/LexicalHorizontalRuleNode.d.ts +3 -1
- package/LexicalHorizontalRuleNode.dev.js +2 -0
- package/LexicalHorizontalRuleNode.js.flow +6 -2
- package/LexicalHorizontalRuleNode.prod.js +2 -2
- package/LexicalLinkPlugin.dev.js +19 -20
- package/LexicalLinkPlugin.prod.js +4 -3
- package/LexicalListPlugin.dev.js +29 -25
- package/LexicalListPlugin.prod.js +3 -2
- package/{LexicalAutoFormatterPlugin.d.ts → LexicalMarkdownShortcutPlugin.d.ts} +1 -1
- package/LexicalMarkdownShortcutPlugin.dev.js +42 -0
- package/LexicalMarkdownShortcutPlugin.js +9 -0
- package/{withSubscriptions.js.flow → LexicalMarkdownShortcutPlugin.js.flow} +1 -4
- package/LexicalMarkdownShortcutPlugin.prod.js +7 -0
- package/LexicalNestedComposer.dev.js +20 -15
- package/LexicalNestedComposer.prod.js +3 -3
- package/LexicalOnChangePlugin.dev.js +1 -1
- package/LexicalOnChangePlugin.prod.js +1 -1
- package/LexicalPlainTextPlugin.dev.js +6 -359
- package/LexicalPlainTextPlugin.prod.js +4 -11
- package/LexicalRichTextPlugin.dev.js +6 -444
- package/LexicalRichTextPlugin.prod.js +4 -12
- package/LexicalTablePlugin.dev.js +27 -30
- package/LexicalTablePlugin.prod.js +3 -3
- package/LexicalTreeView.dev.js +1 -1
- package/LexicalTreeView.prod.js +1 -1
- package/package.json +17 -14
- package/useLexicalIsTextContentEmpty.dev.js +1 -1
- package/useLexicalIsTextContentEmpty.prod.js +1 -1
- package/useLexicalNodeSelection.dev.js +1 -1
- package/useLexicalNodeSelection.prod.js +1 -1
- package/useLexicalTextEntity.d.ts +19 -0
- package/useLexicalTextEntity.dev.js +29 -0
- package/{withSubscriptions.js → useLexicalTextEntity.js} +2 -2
- package/useLexicalTextEntity.js.flow +18 -0
- package/useLexicalTextEntity.prod.js +7 -0
- package/LexicalAutoFormatterPlugin.dev.js +0 -766
- package/LexicalAutoFormatterPlugin.js +0 -9
- package/LexicalAutoFormatterPlugin.prod.js +0 -25
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
10
10
|
var React = require('react');
|
|
11
|
+
var utils = require('@lexical/utils');
|
|
11
12
|
var yjs = require('@lexical/yjs');
|
|
12
13
|
var lexical = require('lexical');
|
|
13
14
|
var reactDom = require('react-dom');
|
|
@@ -45,7 +46,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
45
46
|
const onStatus = ({
|
|
46
47
|
status
|
|
47
48
|
}) => {
|
|
48
|
-
editor.
|
|
49
|
+
editor.dispatchCommand(yjs.CONNECTED_COMMAND, status === 'connected');
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
const onSync = isSynced => {
|
|
@@ -80,7 +81,7 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
80
81
|
provider.on('sync', onSync);
|
|
81
82
|
awareness.on('update', onAwarenessUpdate);
|
|
82
83
|
root.getSharedType().observeDeep(onYjsTreeChanges);
|
|
83
|
-
const removeListener = editor.
|
|
84
|
+
const removeListener = editor.registerUpdateListener(({
|
|
84
85
|
prevEditorState,
|
|
85
86
|
editorState,
|
|
86
87
|
dirtyLeaves,
|
|
@@ -116,39 +117,35 @@ function useYjsCollaboration(editor, id, provider, docMap, name, color, shouldBo
|
|
|
116
117
|
}), document.body);
|
|
117
118
|
}, [binding]);
|
|
118
119
|
React.useEffect(() => {
|
|
119
|
-
return editor.
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
disconnect();
|
|
132
|
-
}
|
|
120
|
+
return editor.registerCommand(yjs.TOGGLE_CONNECT_COMMAND, payload => {
|
|
121
|
+
if (connect !== undefined && disconnect !== undefined) {
|
|
122
|
+
const shouldConnect = payload;
|
|
123
|
+
|
|
124
|
+
if (shouldConnect) {
|
|
125
|
+
// eslint-disable-next-line no-console
|
|
126
|
+
console.log('Collaboration connected!');
|
|
127
|
+
connect();
|
|
128
|
+
} else {
|
|
129
|
+
// eslint-disable-next-line no-console
|
|
130
|
+
console.log('Collaboration disconnected!');
|
|
131
|
+
disconnect();
|
|
133
132
|
}
|
|
134
133
|
}
|
|
135
134
|
|
|
136
|
-
return
|
|
135
|
+
return true;
|
|
137
136
|
}, EditorPriority);
|
|
138
137
|
}, [connect, disconnect, editor]);
|
|
139
138
|
return [cursorsContainer, binding];
|
|
140
139
|
}
|
|
141
140
|
function useYjsFocusTracking(editor, provider, name, color) {
|
|
142
141
|
React.useEffect(() => {
|
|
143
|
-
return editor.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return false;
|
|
151
|
-
}, EditorPriority);
|
|
142
|
+
return utils.mergeRegister(editor.registerCommand(lexical.FOCUS_COMMAND, payload => {
|
|
143
|
+
yjs.setLocalStateFocus(provider, name, color, true);
|
|
144
|
+
return true;
|
|
145
|
+
}, EditorPriority), editor.registerCommand(lexical.BLUR_COMMAND, payload => {
|
|
146
|
+
yjs.setLocalStateFocus(provider, name, color, false);
|
|
147
|
+
return true;
|
|
148
|
+
}, EditorPriority));
|
|
152
149
|
}, [color, editor, name, provider]);
|
|
153
150
|
}
|
|
154
151
|
function useYjsHistory(editor, binding) {
|
|
@@ -162,21 +159,13 @@ function useYjsHistory(editor, binding) {
|
|
|
162
159
|
undoManager.redo();
|
|
163
160
|
};
|
|
164
161
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
redo();
|
|
173
|
-
return true;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return false;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
return editor.addListener('command', applyCommand, EditorPriority);
|
|
162
|
+
return utils.mergeRegister(editor.registerCommand(lexical.UNDO_COMMAND, () => {
|
|
163
|
+
undo();
|
|
164
|
+
return true;
|
|
165
|
+
}, EditorPriority), editor.registerCommand(lexical.REDO_COMMAND, () => {
|
|
166
|
+
redo();
|
|
167
|
+
return true;
|
|
168
|
+
}, EditorPriority));
|
|
180
169
|
});
|
|
181
170
|
const clearHistory = React.useCallback(() => {
|
|
182
171
|
undoManager.clear();
|
|
@@ -33,12 +33,12 @@ export interface Provider {
|
|
|
33
33
|
on(type: 'status', cb: ({status: string}) => void): void;
|
|
34
34
|
// $FlowFixMe: temp
|
|
35
35
|
on(type: 'update', cb: (any) => void): void;
|
|
36
|
-
on(type: 'reload', cb: (doc: Doc) => void): void;
|
|
36
|
+
on(type: 'reload', cb: (doc: Doc) => void): void;
|
|
37
37
|
off(type: 'sync', cb: (isSynced: boolean) => void): void;
|
|
38
38
|
// $FlowFixMe: temp
|
|
39
39
|
off(type: 'update', cb: (any) => void): void;
|
|
40
40
|
off(type: 'status', cb: ({status: string}) => void): void;
|
|
41
|
-
off(type: 'reload', cb: (doc: Doc) => void): void;
|
|
41
|
+
off(type: 'reload', cb: (doc: Doc) => void): void;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
type CollaborationContextType = {
|
|
@@ -48,13 +48,16 @@ type CollaborationContextType = {
|
|
|
48
48
|
yjsDocMap: Map<string, Doc>,
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
export type ProviderFactory = (
|
|
51
|
+
export type ProviderFactory = (
|
|
52
|
+
id: string,
|
|
53
|
+
yjsDocMap: Map<string, Doc>,
|
|
54
|
+
) => Provider;
|
|
52
55
|
|
|
53
56
|
declare export function CollaborationPlugin(arg0: {
|
|
54
57
|
id: string,
|
|
55
58
|
providerFactory: ProviderFactory,
|
|
56
59
|
shouldBootstrap: boolean,
|
|
57
|
-
username?: string
|
|
60
|
+
username?: string,
|
|
58
61
|
}): React$Node;
|
|
59
62
|
declare export var CollaborationContext: React$Context<CollaborationContextType>;
|
|
60
63
|
declare export function useCollaborationContext(): CollaborationContextType;
|
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var e=require("@lexical/react/LexicalComposerContext"),
|
|
8
|
-
function
|
|
9
|
-
a,h)};
|
|
10
|
-
|
|
11
|
-
function
|
|
12
|
-
function
|
|
13
|
-
function I(
|
|
14
|
-
const
|
|
15
|
-
|
|
7
|
+
var e=require("@lexical/react/LexicalComposerContext"),g=require("react"),m=require("@lexical/utils"),x=require("@lexical/yjs"),F=require("lexical"),G=require("react-dom");
|
|
8
|
+
function H(b,c,a,d,k,p,q){const n=g.useRef(!1),[r,v]=g.useState(d.get(c)),f=g.useMemo(()=>x.createBinding(b,a,c,r,d),[b,a,c,d,r]),t=g.useCallback(()=>{a.connect()},[a]),u=g.useCallback(()=>{try{a.disconnect()}catch(l){}},[a]);g.useEffect(()=>{const {root:l}=f,{awareness:y}=a,z=({status:h})=>{b.dispatchCommand(x.CONNECTED_COMMAND,"connected"===h)},A=h=>{q&&h&&l.isEmpty()&&0===l._xmlText._length&&!1===n.current&&I(b);n.current=!1},B=()=>{x.syncCursorPositions(f,a)},C=(h,w)=>{w.origin!==f&&x.syncYjsChangesToLexical(f,
|
|
9
|
+
a,h)};x.initLocalState(a,k,p,document.activeElement===b.getRootElement());const D=h=>{J(b,f);v(h);d.set(c,h);n.current=!0};a.on("reload",D);a.on("status",z);a.on("sync",A);y.on("update",B);l.getSharedType().observeDeep(C);const R=b.registerUpdateListener(({prevEditorState:h,editorState:w,dirtyLeaves:O,dirtyElements:P,normalizedNodes:Q,tags:E})=>{!1===E.has("skip-collab")&&x.syncLexicalUpdateToYjs(f,a,h,w,P,O,Q,E)});t();return()=>{!1===n.current&&u();a.off("sync",A);a.off("status",z);a.off("reload",
|
|
10
|
+
D);y.off("update",B);l.getSharedType().unobserveDeep(C);R()}},[f,p,t,u,d,b,c,k,a,q]);const S=g.useMemo(()=>G.createPortal(g.createElement("div",{ref:l=>{f.cursorsContainer=l}}),document.body),[f]);g.useEffect(()=>b.registerCommand(x.TOGGLE_CONNECT_COMMAND,l=>{void 0!==t&&void 0!==u&&(l?(console.log("Collaboration connected!"),t()):(console.log("Collaboration disconnected!"),u()));return!0},0),[t,u,b]);return[S,f]}
|
|
11
|
+
function K(b,c,a,d){g.useEffect(()=>m.mergeRegister(b.registerCommand(F.FOCUS_COMMAND,()=>{x.setLocalStateFocus(c,a,d,!0);return!0},0),b.registerCommand(F.BLUR_COMMAND,()=>{x.setLocalStateFocus(c,a,d,!1);return!0},0)),[d,b,a,c])}
|
|
12
|
+
function L(b,c){const a=g.useMemo(()=>x.createUndoManager(c,c.root.getSharedType()),[c]);g.useEffect(()=>m.mergeRegister(b.registerCommand(F.UNDO_COMMAND,()=>{a.undo();return!0},0),b.registerCommand(F.REDO_COMMAND,()=>{a.redo();return!0},0)));return g.useCallback(()=>{a.clear()},[a])}
|
|
13
|
+
function I(b){b.update(()=>{var c=F.$getRoot();if(null===c.getFirstChild()){const a=F.$createParagraphNode();c.append(a);c=document.activeElement;(null!==F.$getSelection()||null!==c&&c===b.getRootElement())&&a.select()}},{tag:"history-merge"})}
|
|
14
|
+
function J(b,c){b.update(()=>{const d=F.$getRoot();d.clear();d.select()},{tag:"skip-collab"});if(null!=c.cursors&&(b=c.cursorsContainer,null!=b)){c=Array.from(c.cursors.values());for(let d=0;d<c.length;d++){var a=c[d].selection;if(a&&null!=a.selections){a=a.selections;for(let k=0;k<a.length;k++)b.removeChild(a[d])}}}}
|
|
15
|
+
const M=[["Cat","255,165,0"],["Dog","0,200,55"],["Rabbit","160,0,200"],["Frog","0,172,200"],["Fox","197,200,0"],["Hedgehog","31,200,0"],["Pigeon","200,0,0"],["Squirrel","200,0,148"],["Bear","255,235,0"],["Tiger","86,255,0"],["Leopard","0,255,208"],["Zebra","0,243,255"],["Wolf","0,102,255"],["Owl","147,0,255"],["Gull","255,0,153"],["Squid","0,220,255"]],N=M[Math.floor(Math.random()*(M.length-1+1))],T=g.createContext({clientID:0,color:N[1],name:N[0],yjsDocMap:new Map});
|
|
16
|
+
function U(b){const c=g.useContext(T);null!=b&&(c.name=b);return c}exports.CollaborationContext=T;exports.CollaborationPlugin=function({id:b,providerFactory:c,shouldBootstrap:a,username:d}){d=U(d);const {yjsDocMap:k,name:p,color:q}=d,[n]=e.useLexicalComposerContext(),r=g.useMemo(()=>c(b,k),[b,c,k]),[v,f]=H(n,b,r,k,p,q,a);d.clientID=f.clientID;L(n,f);K(n,r,p,q);return v};exports.useCollaborationContext=U;
|
package/LexicalComposer.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ import {Class} from 'utility-types';
|
|
|
10
10
|
import type {EditorThemeClasses, LexicalEditor, LexicalNode} from 'lexical';
|
|
11
11
|
type Props = {
|
|
12
12
|
initialConfig: {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
editor__DEPRECATED?: LexicalEditor | null;
|
|
14
|
+
readOnly?: boolean;
|
|
15
15
|
namespace?: string;
|
|
16
16
|
nodes?: Array<Class<LexicalNode>>;
|
|
17
17
|
theme?: EditorThemeClasses;
|
package/LexicalComposer.dev.js
CHANGED
|
@@ -43,30 +43,15 @@ function LexicalComposer({
|
|
|
43
43
|
initialConfig,
|
|
44
44
|
children
|
|
45
45
|
}) {
|
|
46
|
-
const parentContext = React.useContext(LexicalComposerContext.LexicalComposerContext);
|
|
47
46
|
const composerContext = React.useMemo(() => {
|
|
48
|
-
let composerTheme;
|
|
49
|
-
let parentEditor;
|
|
50
47
|
const {
|
|
51
48
|
theme,
|
|
52
49
|
namespace,
|
|
53
|
-
|
|
50
|
+
editor__DEPRECATED: initialEditor,
|
|
54
51
|
nodes,
|
|
55
52
|
onError
|
|
56
53
|
} = initialConfig;
|
|
57
|
-
|
|
58
|
-
if (theme != null) {
|
|
59
|
-
composerTheme = theme;
|
|
60
|
-
} else if (parentContext != null) {
|
|
61
|
-
parentEditor = parentContext[0];
|
|
62
|
-
const parentTheme = parentContext[1].getTheme();
|
|
63
|
-
|
|
64
|
-
if (parentTheme != null) {
|
|
65
|
-
composerTheme = parentTheme;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const context = LexicalComposerContext.createLexicalComposerContext(parentContext, composerTheme);
|
|
54
|
+
const context = LexicalComposerContext.createLexicalComposerContext(null, theme);
|
|
70
55
|
let editor = initialEditor || null;
|
|
71
56
|
|
|
72
57
|
if (editor === null) {
|
|
@@ -75,9 +60,8 @@ function LexicalComposer({
|
|
|
75
60
|
namespace,
|
|
76
61
|
nodes,
|
|
77
62
|
onError: error => onError(error, newEditor),
|
|
78
|
-
parentEditor,
|
|
79
63
|
readOnly: true,
|
|
80
|
-
theme
|
|
64
|
+
theme
|
|
81
65
|
});
|
|
82
66
|
editor = newEditor;
|
|
83
67
|
}
|
package/LexicalComposer.js.flow
CHANGED
|
@@ -11,8 +11,8 @@ import type {EditorThemeClasses, LexicalEditor, LexicalNode} from 'lexical';
|
|
|
11
11
|
|
|
12
12
|
type Props = {
|
|
13
13
|
initialConfig: $ReadOnly<{
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
editor__DEPRECATED?: LexicalEditor | null,
|
|
15
|
+
readOnly?: boolean,
|
|
16
16
|
namespace?: string,
|
|
17
17
|
nodes?: $ReadOnlyArray<Class<LexicalNode>>,
|
|
18
18
|
theme?: EditorThemeClasses,
|
package/LexicalComposer.prod.js
CHANGED
|
@@ -4,6 +4,5 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var
|
|
8
|
-
module.exports=function({initialConfig:
|
|
9
|
-
!1)},[]);return n.createElement(b.LexicalComposerContext.Provider,{value:m},q)};
|
|
7
|
+
var a=require("@lexical/react/LexicalComposerContext"),e=require("lexical"),l=require("react"),m="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?l.useLayoutEffect:l.useEffect;
|
|
8
|
+
module.exports=function({initialConfig:f,children:n}){const k=l.useMemo(()=>{const {theme:b,namespace:c,editor__DEPRECATED:p,nodes:q,onError:r}=f,g=a.createLexicalComposerContext(null,b);let d=p||null;if(null===d){const h=e.createEditor({context:g,namespace:c,nodes:q,onError:t=>r(t,h),readOnly:!0,theme:b});d=h}return[d,g]},[]);m(()=>{const b=f.readOnly,[c]=k;c.setReadOnly(b||!1)},[]);return l.createElement(a.LexicalComposerContext.Provider,{value:k},n)};
|
|
@@ -53,6 +53,7 @@ function LexicalContentEditable({
|
|
|
53
53
|
autoComplete,
|
|
54
54
|
autoCorrect,
|
|
55
55
|
className,
|
|
56
|
+
id,
|
|
56
57
|
role = 'textbox',
|
|
57
58
|
spellCheck = true,
|
|
58
59
|
style,
|
|
@@ -66,7 +67,7 @@ function LexicalContentEditable({
|
|
|
66
67
|
}, [editor]);
|
|
67
68
|
useLayoutEffect(() => {
|
|
68
69
|
setReadOnly(editor.isReadOnly());
|
|
69
|
-
return editor.
|
|
70
|
+
return editor.registerReadOnlyListener(currentIsReadOnly => {
|
|
70
71
|
setReadOnly(currentIsReadOnly);
|
|
71
72
|
});
|
|
72
73
|
}, [editor]);
|
|
@@ -87,6 +88,7 @@ function LexicalContentEditable({
|
|
|
87
88
|
className: className,
|
|
88
89
|
contentEditable: !isReadOnly,
|
|
89
90
|
"data-testid": testid,
|
|
91
|
+
id: id,
|
|
90
92
|
ref: ref,
|
|
91
93
|
role: isReadOnly ? null : role,
|
|
92
94
|
spellCheck: spellCheck,
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
var b=require("@lexical/react/LexicalComposerContext"),g=require("react"),h="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?g.useLayoutEffect:g.useEffect;
|
|
8
|
-
module.exports=function({ariaActiveDescendantID:k,ariaAutoComplete:l,ariaControls:m,ariaDescribedBy:n,ariaExpanded:p,ariaLabel:q,ariaLabelledBy:r,ariaMultiline:t,ariaOwneeID:u,ariaRequired:v,autoCapitalize:w,autoComplete:x,autoCorrect:y,className:z,role:e="textbox",spellCheck:
|
|
9
|
-
{"aria-activedescendant":a?null:k,"aria-autocomplete":a?null:l,"aria-controls":a?null:m,"aria-describedby":n,"aria-expanded":a?null:"combobox"===e?!!p:null,"aria-label":q,"aria-labelledby":r,"aria-multiline":t,"aria-owns":a?null:u,"aria-required":v,autoCapitalize:w,autoComplete:x,autoCorrect:y,className:z,contentEditable:!a,"data-testid":
|
|
8
|
+
module.exports=function({ariaActiveDescendantID:k,ariaAutoComplete:l,ariaControls:m,ariaDescribedBy:n,ariaExpanded:p,ariaLabel:q,ariaLabelledBy:r,ariaMultiline:t,ariaOwneeID:u,ariaRequired:v,autoCapitalize:w,autoComplete:x,autoCorrect:y,className:z,id:A,role:e="textbox",spellCheck:B=!0,style:C,tabIndex:D,testid:E}){const [c]=b.useLexicalComposerContext(),[a,f]=g.useState(!0),F=g.useCallback(d=>{c.setRootElement(d)},[c]);h(()=>{f(c.isReadOnly());return c.registerReadOnlyListener(d=>{f(d)})},[c]);return g.createElement("div",
|
|
9
|
+
{"aria-activedescendant":a?null:k,"aria-autocomplete":a?null:l,"aria-controls":a?null:m,"aria-describedby":n,"aria-expanded":a?null:"combobox"===e?!!p:null,"aria-label":q,"aria-labelledby":r,"aria-multiline":t,"aria-owns":a?null:u,"aria-required":v,autoCapitalize:w,autoComplete:x,autoCorrect:y,className:z,contentEditable:!a,"data-testid":E,id:A,ref:F,role:a?null:e,spellCheck:B,style:C,tabIndex:D})};
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
var hashtag = require('@lexical/hashtag');
|
|
10
10
|
var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
|
|
11
|
-
var
|
|
12
|
-
var OverflowNode = require('lexical/OverflowNode');
|
|
11
|
+
var useLexicalTextEntity = require('@lexical/react/useLexicalTextEntity');
|
|
13
12
|
var react = require('react');
|
|
14
13
|
|
|
15
14
|
/**
|
|
@@ -104,106 +103,33 @@ function getHashtagRegexString() {
|
|
|
104
103
|
return hashtag;
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
const REGEX = new RegExp(getHashtagRegexString(), '
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
function startsWithValidChar(string) {
|
|
114
|
-
return isValidCharacter(string[0]);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function endsWithValidChar(string) {
|
|
118
|
-
return isValidCharacter(string[string.length - 1]);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function textNodeTransform(node) {
|
|
122
|
-
if (!node.isSimpleText()) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const text = node.getTextContent();
|
|
127
|
-
let currentNode = node;
|
|
128
|
-
let adjustedOffset = 0;
|
|
129
|
-
|
|
130
|
-
while (true) {
|
|
131
|
-
const matchArr = REGEX.exec(text);
|
|
132
|
-
|
|
133
|
-
if (currentNode == null) {
|
|
134
|
-
return;
|
|
106
|
+
const REGEX = new RegExp(getHashtagRegexString(), 'i');
|
|
107
|
+
function HashtagPlugin() {
|
|
108
|
+
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
109
|
+
react.useEffect(() => {
|
|
110
|
+
if (!editor.hasNodes([hashtag.HashtagNode])) {
|
|
111
|
+
throw new Error('HashtagPlugin: HashtagNode not registered on editor');
|
|
135
112
|
}
|
|
136
|
-
|
|
137
|
-
|
|
113
|
+
}, [editor]);
|
|
114
|
+
const createHashtagNode = react.useCallback(textNode => {
|
|
115
|
+
return hashtag.$createHashtagNode(textNode.getTextContent());
|
|
116
|
+
}, []);
|
|
117
|
+
const getHashtagMatch = react.useCallback(text => {
|
|
118
|
+
const matchArr = REGEX.exec(text);
|
|
138
119
|
|
|
139
120
|
if (matchArr === null) {
|
|
140
|
-
|
|
141
|
-
hashtag.$toggleHashtag(nextSibling);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return;
|
|
121
|
+
return null;
|
|
145
122
|
}
|
|
146
123
|
|
|
147
124
|
const hashtagLength = matchArr[3].length + 1;
|
|
148
|
-
const startOffset = matchArr.index + matchArr[1].length
|
|
125
|
+
const startOffset = matchArr.index + matchArr[1].length;
|
|
149
126
|
const endOffset = startOffset + hashtagLength;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (startOffset === 0 && hashtag.$isHashtagNode(currentNode.getPreviousSibling()) || !isValidCharacter(prevChar) || !isValidCharacter(nextChar) || nextChar === '' && lexical.$isTextNode(nextSibling) && !nextSibling.isSimpleText()) {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
let targetNode;
|
|
158
|
-
|
|
159
|
-
if (startOffset === 0) {
|
|
160
|
-
[targetNode, currentNode] = currentNode.splitText(endOffset);
|
|
161
|
-
} else {
|
|
162
|
-
[, targetNode, currentNode] = currentNode.splitText(startOffset, endOffset);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
adjustedOffset += endOffset;
|
|
166
|
-
hashtag.$toggleHashtag(targetNode);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function isPreviousNodeValid(node) {
|
|
171
|
-
const previousNode = node.getPreviousSibling();
|
|
172
|
-
return previousNode === null || lexical.$isLineBreakNode(previousNode) || OverflowNode.$isOverflowNode(previousNode) || lexical.$isTextNode(previousNode) && !hashtag.$isHashtagNode(previousNode) && endsWithValidChar(previousNode.getTextContent());
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function isNextNodeValid(node) {
|
|
176
|
-
const nextNode = node.getNextSibling();
|
|
177
|
-
return nextNode === null || lexical.$isLineBreakNode(nextNode) || OverflowNode.$isOverflowNode(nextNode) || lexical.$isTextNode(nextNode) && !hashtag.$isHashtagNode(nextNode) && startsWithValidChar(nextNode.getTextContent());
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function $hashtagToPlainTextTransform(hashtagNode) {
|
|
181
|
-
// Check neighbors
|
|
182
|
-
if (!isPreviousNodeValid(hashtagNode) || !isNextNodeValid(hashtagNode)) {
|
|
183
|
-
$convertHashtagNodeToPlainTextNode(hashtagNode);
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function $convertHashtagNodeToPlainTextNode(node) {
|
|
189
|
-
const textNode = lexical.$createTextNode(node.getTextContent());
|
|
190
|
-
node.replace(textNode);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function useHashtags(editor) {
|
|
194
|
-
react.useEffect(() => {
|
|
195
|
-
const removePlainTextTransform = editor.addNodeTransform(lexical.TextNode, textNodeTransform);
|
|
196
|
-
const removeHashtagToPlainTextTransform = editor.addNodeTransform(hashtag.HashtagNode, $hashtagToPlainTextTransform);
|
|
197
|
-
return () => {
|
|
198
|
-
removePlainTextTransform();
|
|
199
|
-
removeHashtagToPlainTextTransform();
|
|
127
|
+
return {
|
|
128
|
+
end: endOffset,
|
|
129
|
+
start: startOffset
|
|
200
130
|
};
|
|
201
|
-
}, [
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
function HashtagPlugin() {
|
|
205
|
-
const [editor] = LexicalComposerContext.useLexicalComposerContext();
|
|
206
|
-
useHashtags(editor);
|
|
131
|
+
}, []);
|
|
132
|
+
useLexicalTextEntity(getHashtagMatch, hashtag.HashtagNode, createHashtagNode);
|
|
207
133
|
return null;
|
|
208
134
|
}
|
|
209
135
|
|
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
var
|
|
8
|
-
const
|
|
9
|
-
"-"+
|
|
10
|
-
|
|
11
|
-
function A(a){if(a.isSimpleText())for(var b=a.getTextContent(),c=0;;){var d=y.exec(b);if(null==a)break;const l=a.getNextSibling();if(null===d){!e.$isHashtagNode(l)||z(b[b.length-1])||B(a)||e.$toggleHashtag(l);break}const k=d.index+d[1].length-c;d=k+(d[3].length+1);const C=b[k-1]||"",u=b[d]||"";if(0===k&&e.$isHashtagNode(a.getPreviousSibling())||!z(C)||!z(u)||""===u&&g.$isTextNode(l)&&!l.isSimpleText())continue;let m;0===k?[m,a]=a.splitText(d):[,m,a]=a.splitText(k,d);c+=d;e.$toggleHashtag(m)}}
|
|
12
|
-
function B(a){a=a.getNextSibling();return null===a||g.$isLineBreakNode(a)||h.$isOverflowNode(a)||g.$isTextNode(a)&&!e.$isHashtagNode(a)&&z(a.getTextContent()[0])}function D(a){var b=a.getPreviousSibling(),c;!(c=null===b||g.$isLineBreakNode(b)||h.$isOverflowNode(b))&&(c=g.$isTextNode(b)&&!e.$isHashtagNode(b))&&(b=b.getTextContent(),c=z(b[b.length-1]));c&&B(a)||(b=g.$createTextNode(a.getTextContent()),a.replace(b))}
|
|
13
|
-
function E(a){n.useEffect(()=>{const b=a.addNodeTransform(g.TextNode,A),c=a.addNodeTransform(e.HashtagNode,D);return()=>{b();c()}},[a])}module.exports=function(){const [a]=f.useLexicalComposerContext();E(a);return null};
|
|
7
|
+
var b=require("@lexical/hashtag"),c=require("@lexical/react/LexicalComposerContext"),d=require("@lexical/react/useLexicalTextEntity"),e=require("react"),f=RegExp;
|
|
8
|
+
const g=String.fromCharCode,l="A-Za-z\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u0241\u0250-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ee\u037a\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03ce\u03d0-\u03f5\u03f7-\u0481\u048a-\u04ce\u04d0-\u04f9\u0500-\u050f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0621-\u063a\u0640-\u064a\u066e-\u066f\u0671-\u06d3\u06d5\u06e5-\u06e6\u06ee-\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u076d\u0780-\u07a5\u07b1\u0904-\u0939\u093d\u0950\u0958-\u0961\u097d\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc-\u09dd\u09df-\u09e1\u09f0-\u09f1\u0a05-\u0a0a\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36\u0a38-\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0-\u0ae1\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32-\u0b33\u0b35-\u0b39\u0b3d\u0b5c-\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c60-\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0-\u0ce1\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d28\u0d2a-\u0d39\u0d60-\u0d61\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32-\u0e33\u0e40-\u0e46\u0e81-\u0e82\u0e84\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa-\u0eab\u0ead-\u0eb0\u0eb2-\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edd\u0f00\u0f40-\u0f47\u0f49-\u0f6a\u0f88-\u0f8b\u1000-\u1021\u1023-\u1027\u1029-\u102a\u1050-\u1055\u10a0-\u10c5\u10d0-\u10fa\u10fc\u1100-\u1159\u115f-\u11a2\u11a8-\u11f9\u1200-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u1676\u1681-\u169a\u16a0-\u16ea\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19a9\u19c1-\u19c7\u1a00-\u1a16\u1d00-\u1dbf\u1e00-\u1e9b\u1ea0-\u1ef9\u1f00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u2094\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2131\u2133-\u2139\u213c-\u213f\u2145-\u2149\u2c00-\u2c2e\u2c30-\u2c5e\u2c80-\u2ce4\u2d00-\u2d25\u2d30-\u2d65\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3006\u3031-\u3035\u303b-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312c\u3131-\u318e\u31a0-\u31b7\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fbb\ua000-\ua48c\ua800-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\uac00-\ud7a3\uf900-\ufa2d\ufa30-\ufa6a\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc\u0300-\u036f\u0483-\u0486\u0591-\u05b9\u05bb-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u0615\u064b-\u065e\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u0901-\u0903\u093c\u093e-\u094d\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09bc\u09be-\u09c4\u09c7-\u09c8\u09cb-\u09cd\u09d7\u09e2-\u09e3\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a70-\u0a71\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2-\u0ae3\u0b01-\u0b03\u0b3c\u0b3e-\u0b43\u0b47-\u0b48\u0b4b-\u0b4d\u0b56-\u0b57\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c82-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5-\u0cd6\u0d02-\u0d03\u0d3e-\u0d43\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d82-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2-\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f3e-\u0f3f\u0f71-\u0f84\u0f86-\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102c-\u1032\u1036-\u1039\u1056-\u1059\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b6-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u192b\u1930-\u193b\u19b0-\u19c0\u19c8-\u19c9\u1a17-\u1a1b\u1dc0-\u1dc3\u20d0-\u20dc\u20e1\u20e5-\u20eb\u302a-\u302f\u3099-\u309a\ua802\ua806\ua80b\ua823-\ua827\ufb1e\ufe00-\ufe0f\ufe20-\ufe23\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\u024f\u0253-\u0254\u0256-\u0257\u0259\u025b\u0263\u0268\u026f\u0272\u0289\u028b\u02bb\u0300-\u036f\u1e00-\u1eff\u0400-\u04ff\u0500-\u0527\u2de0-\u2dff\ua640-\ua69f\u0591-\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f4\ufb12-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4f\u0610-\u061a\u0620-\u065f\u066e-\u06d3\u06d5-\u06dc\u06de-\u06e8\u06ea-\u06ef\u06fa-\u06fc\u06ff\u0750-\u077f\u08a0\u08a2-\u08ac\u08e4-\u08fe\ufb50-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\u200c-\u200c\u0e01-\u0e3a\u0e40-\u0e4e\u1100-\u11ff\u3130-\u3185\ua960-\ua97f\uac00-\ud7af\ud7b0-\ud7ff\uffa1-\uffdc\u30a1-\u30fa\u30fc-\u30fe\uff66-\uff9f\uff10-\uff19\uff21-\uff3a\uff41-\uff5a\u3041-\u3096\u3099-\u309e\u3400-\u4dbf\u4e00-\u9fff"+(g(173824)+
|
|
9
|
+
"-"+g(177983)+g(177984)+"-"+g(178207)+g(194560)+"-"+g(195103)+"\u3003\u3005\u303b"),{alpha:m,alphanumeric:n,hashChars:p}={alpha:l,alphanumeric:l+"0-9\u0660-\u0669\u06f0-\u06f9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\uff10-\uff19_",hashChars:"#\\uFF03"},q="["+n+"]",r=new f("(^|$|[^&/"+(n+"])([")+(p+"])(")+q+"*["+(m+"]")+
|
|
10
|
+
q+"*)","i");module.exports=function(){const [h]=c.useLexicalComposerContext();e.useEffect(()=>{if(!h.hasNodes([b.HashtagNode]))throw Error("HashtagPlugin: HashtagNode not registered on editor");},[h]);const t=e.useCallback(a=>b.$createHashtagNode(a.getTextContent()),[]),u=e.useCallback(a=>{a=r.exec(a);if(null===a)return null;const k=a.index+a[1].length;return{end:k+(a[3].length+1),start:k}},[]);d(u,b.HashtagNode,t);return null};
|