@lexical/react 0.10.0 → 0.11.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/LexicalAutoEmbedPlugin.d.ts +2 -2
- package/LexicalAutoEmbedPlugin.dev.js +4 -4
- package/LexicalAutoEmbedPlugin.js.flow +2 -2
- package/LexicalAutoEmbedPlugin.prod.js +2 -2
- package/LexicalCharacterLimitPlugin.dev.js +4 -3
- package/LexicalCharacterLimitPlugin.prod.js +6 -6
- package/LexicalClickableLinkPlugin.dev.js +12 -9
- package/LexicalClickableLinkPlugin.prod.js +3 -4
- package/LexicalCollaborationPlugin.d.ts +2 -1
- package/LexicalCollaborationPlugin.dev.js +11 -10
- package/LexicalCollaborationPlugin.js.flow +13 -3
- package/LexicalCollaborationPlugin.prod.js +9 -9
- package/LexicalContentEditable.d.ts +1 -1
- package/LexicalContentEditable.dev.js +21 -10
- package/LexicalContentEditable.prod.js +3 -3
- package/LexicalContextMenuPlugin.d.ts +29 -0
- package/LexicalContextMenuPlugin.dev.js +508 -0
- package/LexicalContextMenuPlugin.js +9 -0
- package/LexicalContextMenuPlugin.prod.js +21 -0
- package/LexicalDecoratorBlockNode.d.ts +1 -0
- package/LexicalDecoratorBlockNode.dev.js +4 -0
- package/LexicalDecoratorBlockNode.prod.js +1 -1
- package/LexicalNodeEventPlugin.d.ts +1 -1
- package/LexicalNodeEventPlugin.dev.js +26 -33
- package/LexicalNodeEventPlugin.prod.js +2 -2
- package/LexicalNodeMenuPlugin.d.ts +22 -0
- package/LexicalNodeMenuPlugin.dev.js +521 -0
- package/LexicalNodeMenuPlugin.js +9 -0
- package/LexicalNodeMenuPlugin.js.flow +64 -0
- package/LexicalNodeMenuPlugin.prod.js +21 -0
- package/LexicalPlainTextPlugin.dev.js +1 -1
- package/LexicalPlainTextPlugin.prod.js +4 -4
- package/LexicalRichTextPlugin.dev.js +1 -1
- package/LexicalRichTextPlugin.prod.js +4 -4
- package/LexicalTabIndentationPlugin.d.ts +2 -0
- package/LexicalTabIndentationPlugin.dev.js +69 -10
- package/LexicalTabIndentationPlugin.js.flow +6 -0
- package/LexicalTabIndentationPlugin.prod.js +3 -1
- package/LexicalTypeaheadMenuPlugin.d.ts +10 -40
- package/LexicalTypeaheadMenuPlugin.dev.js +237 -210
- package/LexicalTypeaheadMenuPlugin.js.flow +7 -26
- package/LexicalTypeaheadMenuPlugin.prod.js +20 -20
- package/package.json +19 -19
- package/shared/LexicalMenu.d.ts +49 -0
- package/shared/useYjsCollaboration.d.ts +2 -2
|
@@ -4,23 +4,23 @@
|
|
|
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
|
-
'use strict';var k=require("@lexical/react/LexicalComposerContext"),n=require("
|
|
8
|
-
let B=
|
|
9
|
-
function
|
|
10
|
-
function
|
|
11
|
-
function
|
|
12
|
-
|
|
13
|
-
function
|
|
14
|
-
m)}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
a.
|
|
18
|
-
m
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
exports.
|
|
26
|
-
|
|
7
|
+
'use strict';var k=require("@lexical/react/LexicalComposerContext"),n=require("lexical"),x=require("react"),y=require("@lexical/utils"),z="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?x.useLayoutEffect:x.useEffect;class A{constructor(b){this.key=b;this.ref={current:null};this.setRefElement=this.setRefElement.bind(this)}setRefElement(b){this.ref={current:b}}}
|
|
8
|
+
let B=b=>{const a=document.getElementById("typeahead-menu");if(a){var c=a.getBoundingClientRect();c.top+c.height>window.innerHeight&&a.scrollIntoView({block:"center"});0>c.top&&a.scrollIntoView({block:"center"});b.scrollIntoView({block:"nearest"})}};
|
|
9
|
+
function C(b){var a=n.$getSelection();if(!n.$isRangeSelection(a)||!a.isCollapsed())return null;var c=a.anchor;if("text"!==c.type)return null;a=c.getNode();if(!a.isSimpleText())return null;c=c.offset;let e=a.getTextContent().slice(0,c);var f=b.matchingString;b=b.replaceableString.length;for(let t=b;t<=f.length;t++)e.substr(-t)===f.substr(0,t)&&(b=t);b=c-b;if(0>b)return null;let r;0===b?[r]=a.splitText(c):[,r]=a.splitText(b,c);return r}
|
|
10
|
+
function D(b,a){let c=getComputedStyle(b),e="absolute"===c.position;a=a?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===c.position)return document.body;for(;b=b.parentElement;)if(c=getComputedStyle(b),(!e||"static"!==c.position)&&a.test(c.overflow+c.overflowY+c.overflowX))return b;return document.body}function F(b,a){b=b.getBoundingClientRect();a=a.getBoundingClientRect();return b.top>a.top&&b.top<a.bottom}
|
|
11
|
+
function G(b,a,c,e){let [f]=k.useLexicalComposerContext();x.useEffect(()=>{if(null!=a&&null!=b){let r=f.getRootElement(),t=null!=r?D(r,!1):document.body,l=!1,d=F(a,t),h=function(){l||(window.requestAnimationFrame(function(){c();l=!1}),l=!0);const m=F(a,t);m!==d&&(d=m,null!=e&&e(m))},q=new ResizeObserver(c);window.addEventListener("resize",c);document.addEventListener("scroll",h,{capture:!0,passive:!0});q.observe(a);return()=>{q.unobserve(a);window.removeEventListener("resize",c);document.removeEventListener("scroll",
|
|
12
|
+
h)}}},[a,f,e,c,b])}let H=n.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");
|
|
13
|
+
function I({close:b,editor:a,anchorElementRef:c,resolution:e,options:f,menuRenderFn:r,onSelectOption:t,shouldSplitNodeWithQuery:l=!1}){let [d,h]=x.useState(null);x.useEffect(()=>{h(0)},[e.match&&e.match.matchingString]);let q=x.useCallback(g=>{a.update(()=>{const p=null!=e.match&&l?C(e.match):null;t(g,p,b,e.match?e.match.matchingString:"")})},[a,l,e.match,t,b]),m=x.useCallback(g=>{const p=a.getRootElement();null!==p&&(p.setAttribute("aria-activedescendant","typeahead-item-"+g),h(g))},[a]);x.useEffect(()=>
|
|
14
|
+
()=>{let g=a.getRootElement();null!==g&&g.removeAttribute("aria-activedescendant")},[a]);z(()=>{null===f?h(null):null===d&&m(0)},[f,d,m]);x.useEffect(()=>y.mergeRegister(a.registerCommand(H,({option:g})=>g.ref&&null!=g.ref.current?(B(g.ref.current),!0):!1,n.COMMAND_PRIORITY_LOW)),[a,m]);x.useEffect(()=>y.mergeRegister(a.registerCommand(n.KEY_ARROW_DOWN_COMMAND,g=>{if(null!==f&&f.length&&null!==d){let p=d!==f.length-1?d+1:0;m(p);let u=f[p];null!=u.ref&&u.ref.current&&a.dispatchCommand(H,{index:p,option:u});
|
|
15
|
+
g.preventDefault();g.stopImmediatePropagation()}return!0},n.COMMAND_PRIORITY_LOW),a.registerCommand(n.KEY_ARROW_UP_COMMAND,g=>{if(null!==f&&f.length&&null!==d){var p=0!==d?d-1:f.length-1;m(p);p=f[p];null!=p.ref&&p.ref.current&&B(p.ref.current);g.preventDefault();g.stopImmediatePropagation()}return!0},n.COMMAND_PRIORITY_LOW),a.registerCommand(n.KEY_ESCAPE_COMMAND,g=>{g.preventDefault();g.stopImmediatePropagation();b();return!0},n.COMMAND_PRIORITY_LOW),a.registerCommand(n.KEY_TAB_COMMAND,g=>{if(null===
|
|
16
|
+
f||null===d||null==f[d])return!1;g.preventDefault();g.stopImmediatePropagation();q(f[d]);return!0},n.COMMAND_PRIORITY_LOW),a.registerCommand(n.KEY_ENTER_COMMAND,g=>{if(null===f||null===d||null==f[d])return!1;null!==g&&(g.preventDefault(),g.stopImmediatePropagation());q(f[d]);return!0},n.COMMAND_PRIORITY_LOW)),[q,b,a,f,d,m]);let v=x.useMemo(()=>({options:f,selectOptionAndCleanUp:q,selectedIndex:d,setHighlightedIndex:h}),[q,d,f]);return r(c,v,e.match?e.match.matchingString:"")}
|
|
17
|
+
function J(b,a,c){let [e]=k.useLexicalComposerContext(),f=x.useRef(document.createElement("div")),r=x.useCallback(()=>{const l=e.getRootElement(),d=f.current;var h=d.firstChild;if(null!==l&&null!==b){const {left:m,top:v,width:g,height:p}=b.getRect();d.style.top=`${v+window.pageYOffset}px`;d.style.left=`${m+window.pageXOffset}px`;d.style.height=`${p}px`;d.style.width=`${g}px`;if(null!==h){var q=h.getBoundingClientRect();h=q.height;q=q.width;const u=l.getBoundingClientRect();m+q>u.right&&(d.style.left=
|
|
18
|
+
`${m-q+window.pageXOffset}px`);(v+h>window.innerHeight||v+h>u.bottom)&&v-u.top>h&&(d.style.top=`${v-h+window.pageYOffset-(p+10)}px`)}d.isConnected||(null!=c&&(d.className=c),d.setAttribute("aria-label","Typeahead menu"),d.setAttribute("id","typeahead-menu"),d.setAttribute("role","listbox"),d.style.display="block",d.style.position="absolute",document.body.append(d));f.current=d;l.setAttribute("aria-controls","typeahead-menu")}},[e,b,c]);x.useEffect(()=>{let l=e.getRootElement();if(null!==b)return r(),
|
|
19
|
+
()=>{null!==l&&l.removeAttribute("aria-controls");let d=f.current;null!==d&&d.isConnected&&d.remove()}},[e,r,b]);let t=x.useCallback(l=>{null!==b&&(l||a(null))},[b,a]);G(b,f.current,r,t);return f}function K(b,a){var c=window.getSelection();if(null===c||!c.isCollapsed)return!1;let e=c.anchorNode;c=c.anchorOffset;if(null==e||null==c)return!1;try{a.setStart(e,b),a.setEnd(e,c)}catch(f){return!1}return!0}
|
|
20
|
+
function L(b){let a=null;b.getEditorState().read(()=>{var c=n.$getSelection();if(n.$isRangeSelection(c)){var e=c.anchor;"text"!==e.type?a=null:(c=e.getNode(),c.isSimpleText()?(e=e.offset,a=c.getTextContent().slice(0,e)):a=null)}});return a}function M(b,a){return 0!==a?!1:b.getEditorState().read(()=>{var c=n.$getSelection();return n.$isRangeSelection(c)?(c=c.anchor.getNode().getPreviousSibling(),n.$isTextNode(c)&&c.isTextEntity()):!1})}function N(b){x.startTransition?x.startTransition(b):b()}
|
|
21
|
+
function O(b,a){let c=getComputedStyle(b),e="absolute"===c.position;a=a?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===c.position)return document.body;for(;b=b.parentElement;)if(c=getComputedStyle(b),(!e||"static"!==c.position)&&a.test(c.overflow+c.overflowY+c.overflowX))return b;return document.body}function P(b,a){b=b.getBoundingClientRect();a=a.getBoundingClientRect();return b.top>a.top&&b.top<a.bottom}let Q=n.createCommand("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");
|
|
22
|
+
exports.LexicalTypeaheadMenuPlugin=function({options:b,onQueryChange:a,onSelectOption:c,onOpen:e,onClose:f,menuRenderFn:r,triggerFn:t,anchorClassName:l}){let [d]=k.useLexicalComposerContext(),[h,q]=x.useState(null);l=J(h,q,l);let m=x.useCallback(()=>{q(null);null!=f&&null!==h&&f()},[f,h]),v=x.useCallback(g=>{q(g);null!=e&&null===h&&e(g)},[e,h]);x.useEffect(()=>{let g=d.registerUpdateListener(()=>{d.getEditorState().read(()=>{const p=document.createRange(),u=n.$getSelection(),E=L(d);if(n.$isRangeSelection(u)&&
|
|
23
|
+
u.isCollapsed()&&null!==E&&null!==p){var w=t(E,d);a(w?w.matchingString:null);null===w||M(d,w.leadOffset)||null===K(w.leadOffset,p)?m():N(()=>v({getRect:()=>p.getBoundingClientRect(),match:w}))}else m()})});return()=>{g()}},[d,t,a,h,m,v]);return null===h||null===d?null:x.createElement(I,{close:m,resolution:h,editor:d,anchorElementRef:l,options:b,menuRenderFn:r,shouldSplitNodeWithQuery:!0,onSelectOption:c})};exports.MenuOption=A;exports.PUNCTUATION="\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;";
|
|
24
|
+
exports.SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND=Q;exports.getScrollParent=O;exports.useBasicTypeaheadTriggerMatch=function(b,{minLength:a=1,maxLength:c=75}){return x.useCallback(e=>{e=(new RegExp("(^|\\s|\\()(["+b+"]((?:[^"+(b+"\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;\\s]){0,")+c+"}))$")).exec(e);if(null!==e){let f=e[1],r=e[3];if(r.length>=a)return{leadOffset:e.index+f.length,matchingString:r,replaceableString:e[2]}}return null},[c,a,b])};
|
|
25
|
+
exports.useDynamicPositioning=function(b,a,c,e){let [f]=k.useLexicalComposerContext();x.useEffect(()=>{if(null!=a&&null!=b){let r=f.getRootElement(),t=null!=r?O(r,!1):document.body,l=!1,d=P(a,t),h=function(){l||(window.requestAnimationFrame(function(){c();l=!1}),l=!0);const m=P(a,t);m!==d&&(d=m,null!=e&&e(m))},q=new ResizeObserver(c);window.addEventListener("resize",c);document.addEventListener("scroll",h,{capture:!0,passive:!0});q.observe(a);return()=>{q.unobserve(a);window.removeEventListener("resize",
|
|
26
|
+
c);document.removeEventListener("scroll",h)}}},[a,f,e,c,b])}
|
package/package.json
CHANGED
|
@@ -8,29 +8,29 @@
|
|
|
8
8
|
"rich-text"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.11.1",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@lexical/clipboard": "0.
|
|
14
|
-
"@lexical/code": "0.
|
|
15
|
-
"@lexical/dragon": "0.
|
|
16
|
-
"@lexical/hashtag": "0.
|
|
17
|
-
"@lexical/history": "0.
|
|
18
|
-
"@lexical/link": "0.
|
|
19
|
-
"@lexical/list": "0.
|
|
20
|
-
"@lexical/mark": "0.
|
|
21
|
-
"@lexical/markdown": "0.
|
|
22
|
-
"@lexical/overflow": "0.
|
|
23
|
-
"@lexical/plain-text": "0.
|
|
24
|
-
"@lexical/rich-text": "0.
|
|
25
|
-
"@lexical/selection": "0.
|
|
26
|
-
"@lexical/table": "0.
|
|
27
|
-
"@lexical/text": "0.
|
|
28
|
-
"@lexical/utils": "0.
|
|
29
|
-
"@lexical/yjs": "0.
|
|
13
|
+
"@lexical/clipboard": "0.11.1",
|
|
14
|
+
"@lexical/code": "0.11.1",
|
|
15
|
+
"@lexical/dragon": "0.11.1",
|
|
16
|
+
"@lexical/hashtag": "0.11.1",
|
|
17
|
+
"@lexical/history": "0.11.1",
|
|
18
|
+
"@lexical/link": "0.11.1",
|
|
19
|
+
"@lexical/list": "0.11.1",
|
|
20
|
+
"@lexical/mark": "0.11.1",
|
|
21
|
+
"@lexical/markdown": "0.11.1",
|
|
22
|
+
"@lexical/overflow": "0.11.1",
|
|
23
|
+
"@lexical/plain-text": "0.11.1",
|
|
24
|
+
"@lexical/rich-text": "0.11.1",
|
|
25
|
+
"@lexical/selection": "0.11.1",
|
|
26
|
+
"@lexical/table": "0.11.1",
|
|
27
|
+
"@lexical/text": "0.11.1",
|
|
28
|
+
"@lexical/utils": "0.11.1",
|
|
29
|
+
"@lexical/yjs": "0.11.1",
|
|
30
30
|
"react-error-boundary": "^3.1.4"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"lexical": "0.
|
|
33
|
+
"lexical": "0.11.1",
|
|
34
34
|
"react": ">=17.x",
|
|
35
35
|
"react-dom": ">=17.x"
|
|
36
36
|
},
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
import { LexicalCommand, LexicalEditor, TextNode } from 'lexical';
|
|
9
|
+
import { MutableRefObject, ReactPortal } from 'react';
|
|
10
|
+
export declare type MenuTextMatch = {
|
|
11
|
+
leadOffset: number;
|
|
12
|
+
matchingString: string;
|
|
13
|
+
replaceableString: string;
|
|
14
|
+
};
|
|
15
|
+
export declare type MenuResolution = {
|
|
16
|
+
match?: MenuTextMatch;
|
|
17
|
+
getRect: () => DOMRect;
|
|
18
|
+
};
|
|
19
|
+
export declare const PUNCTUATION = "\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;";
|
|
20
|
+
export declare class MenuOption {
|
|
21
|
+
key: string;
|
|
22
|
+
ref?: MutableRefObject<HTMLElement | null>;
|
|
23
|
+
constructor(key: string);
|
|
24
|
+
setRefElement(element: HTMLElement | null): void;
|
|
25
|
+
}
|
|
26
|
+
export declare type MenuRenderFn<TOption extends MenuOption> = (anchorElementRef: MutableRefObject<HTMLElement | null>, itemProps: {
|
|
27
|
+
selectedIndex: number | null;
|
|
28
|
+
selectOptionAndCleanUp: (option: TOption) => void;
|
|
29
|
+
setHighlightedIndex: (index: number) => void;
|
|
30
|
+
options: Array<TOption>;
|
|
31
|
+
}, matchingString: string | null) => ReactPortal | JSX.Element | null;
|
|
32
|
+
export declare function getScrollParent(element: HTMLElement, includeHidden: boolean): HTMLElement | HTMLBodyElement;
|
|
33
|
+
export declare function useDynamicPositioning(resolution: MenuResolution | null, targetElement: HTMLElement | null, onReposition: () => void, onVisibilityChange?: (isInView: boolean) => void): void;
|
|
34
|
+
export declare const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND: LexicalCommand<{
|
|
35
|
+
index: number;
|
|
36
|
+
option: MenuOption;
|
|
37
|
+
}>;
|
|
38
|
+
export declare function LexicalMenu<TOption extends MenuOption>({ close, editor, anchorElementRef, resolution, options, menuRenderFn, onSelectOption, shouldSplitNodeWithQuery, }: {
|
|
39
|
+
close: () => void;
|
|
40
|
+
editor: LexicalEditor;
|
|
41
|
+
anchorElementRef: MutableRefObject<HTMLElement>;
|
|
42
|
+
resolution: MenuResolution;
|
|
43
|
+
options: Array<TOption>;
|
|
44
|
+
shouldSplitNodeWithQuery?: boolean;
|
|
45
|
+
menuRenderFn: MenuRenderFn<TOption>;
|
|
46
|
+
onSelectOption: (option: TOption, textNodeContainingQuery: TextNode | null, closeMenu: () => void, matchingString: string) => void;
|
|
47
|
+
}): JSX.Element | null;
|
|
48
|
+
export declare function useMenuAnchorRef(resolution: MenuResolution | null, setResolution: (r: MenuResolution | null) => void, className?: string): MutableRefObject<HTMLElement>;
|
|
49
|
+
export declare type TriggerFn = (text: string, editor: LexicalEditor) => MenuTextMatch | null;
|
|
@@ -11,6 +11,6 @@ import * as React from 'react';
|
|
|
11
11
|
import { Doc } from 'yjs';
|
|
12
12
|
import { InitialEditorStateType } from '../LexicalComposer';
|
|
13
13
|
export declare type CursorsContainerRef = React.MutableRefObject<HTMLElement | null>;
|
|
14
|
-
export declare function useYjsCollaboration(editor: LexicalEditor, id: string, provider: Provider, docMap: Map<string, Doc>, name: string, color: string, shouldBootstrap: boolean, cursorsContainerRef?: CursorsContainerRef, initialEditorState?: InitialEditorStateType, excludedProperties?: ExcludedProperties): [JSX.Element, Binding];
|
|
15
|
-
export declare function useYjsFocusTracking(editor: LexicalEditor, provider: Provider, name: string, color: string): void;
|
|
14
|
+
export declare function useYjsCollaboration(editor: LexicalEditor, id: string, provider: Provider, docMap: Map<string, Doc>, name: string, color: string, shouldBootstrap: boolean, cursorsContainerRef?: CursorsContainerRef, initialEditorState?: InitialEditorStateType, excludedProperties?: ExcludedProperties, awarenessData?: object): [JSX.Element, Binding];
|
|
15
|
+
export declare function useYjsFocusTracking(editor: LexicalEditor, provider: Provider, name: string, color: string, awarenessData?: object): void;
|
|
16
16
|
export declare function useYjsHistory(editor: LexicalEditor, binding: Binding): () => void;
|