@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.
Files changed (45) hide show
  1. package/LexicalAutoEmbedPlugin.d.ts +2 -2
  2. package/LexicalAutoEmbedPlugin.dev.js +4 -4
  3. package/LexicalAutoEmbedPlugin.js.flow +2 -2
  4. package/LexicalAutoEmbedPlugin.prod.js +2 -2
  5. package/LexicalCharacterLimitPlugin.dev.js +4 -3
  6. package/LexicalCharacterLimitPlugin.prod.js +6 -6
  7. package/LexicalClickableLinkPlugin.dev.js +12 -9
  8. package/LexicalClickableLinkPlugin.prod.js +3 -4
  9. package/LexicalCollaborationPlugin.d.ts +2 -1
  10. package/LexicalCollaborationPlugin.dev.js +11 -10
  11. package/LexicalCollaborationPlugin.js.flow +13 -3
  12. package/LexicalCollaborationPlugin.prod.js +9 -9
  13. package/LexicalContentEditable.d.ts +1 -1
  14. package/LexicalContentEditable.dev.js +21 -10
  15. package/LexicalContentEditable.prod.js +3 -3
  16. package/LexicalContextMenuPlugin.d.ts +29 -0
  17. package/LexicalContextMenuPlugin.dev.js +508 -0
  18. package/LexicalContextMenuPlugin.js +9 -0
  19. package/LexicalContextMenuPlugin.prod.js +21 -0
  20. package/LexicalDecoratorBlockNode.d.ts +1 -0
  21. package/LexicalDecoratorBlockNode.dev.js +4 -0
  22. package/LexicalDecoratorBlockNode.prod.js +1 -1
  23. package/LexicalNodeEventPlugin.d.ts +1 -1
  24. package/LexicalNodeEventPlugin.dev.js +26 -33
  25. package/LexicalNodeEventPlugin.prod.js +2 -2
  26. package/LexicalNodeMenuPlugin.d.ts +22 -0
  27. package/LexicalNodeMenuPlugin.dev.js +521 -0
  28. package/LexicalNodeMenuPlugin.js +9 -0
  29. package/LexicalNodeMenuPlugin.js.flow +64 -0
  30. package/LexicalNodeMenuPlugin.prod.js +21 -0
  31. package/LexicalPlainTextPlugin.dev.js +1 -1
  32. package/LexicalPlainTextPlugin.prod.js +4 -4
  33. package/LexicalRichTextPlugin.dev.js +1 -1
  34. package/LexicalRichTextPlugin.prod.js +4 -4
  35. package/LexicalTabIndentationPlugin.d.ts +2 -0
  36. package/LexicalTabIndentationPlugin.dev.js +69 -10
  37. package/LexicalTabIndentationPlugin.js.flow +6 -0
  38. package/LexicalTabIndentationPlugin.prod.js +3 -1
  39. package/LexicalTypeaheadMenuPlugin.d.ts +10 -40
  40. package/LexicalTypeaheadMenuPlugin.dev.js +237 -210
  41. package/LexicalTypeaheadMenuPlugin.js.flow +7 -26
  42. package/LexicalTypeaheadMenuPlugin.prod.js +20 -20
  43. package/package.json +19 -19
  44. package/shared/LexicalMenu.d.ts +49 -0
  45. package/shared/useYjsCollaboration.d.ts +2 -2
@@ -4,7 +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
- 'use strict';var b=require("@lexical/react/LexicalComposerContext"),h=require("@lexical/react/useLexicalEditable"),l=require("react"),m=require("@lexical/text"),n=require("@lexical/utils"),p=require("react-dom"),r=require("@lexical/dragon"),t=require("@lexical/rich-text"),u="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?l.useLayoutEffect:l.useEffect;
8
- function v(a){return a.getEditorState().read(m.$canShowPlaceholderCurry(a.isComposing()))}function w(a){let [d,c]=l.useState(()=>v(a));u(()=>{function e(){let f=v(a);c(f)}e();return n.mergeRegister(a.registerUpdateListener(()=>{e()}),a.registerEditableListener(()=>{e()}))},[a]);return d}
9
- function x(a,d){let [c,e]=l.useState(()=>a.getDecorators());u(()=>a.registerDecoratorListener(f=>{p.flushSync(()=>{e(f)})}),[a]);l.useEffect(()=>{e(a.getDecorators())},[a]);return l.useMemo(()=>{let f=[],q=Object.keys(c);for(let k=0;k<q.length;k++){var g=q[k];let z=l.createElement(d,{onError:y=>a._onError(y)},l.createElement(l.Suspense,{fallback:null},c[g]));g=a.getElementByKey(g);null!==g&&f.push(p.createPortal(z,g))}return f},[d,c,a])}
10
- function A(a){u(()=>n.mergeRegister(t.registerRichText(a),r.registerDragonSupport(a)),[a])}function B({content:a}){var [d]=b.useLexicalComposerContext();d=w(d);let c=h();return d?"function"===typeof a?a(c):a:null}exports.RichTextPlugin=function({contentEditable:a,placeholder:d,ErrorBoundary:c}){let [e]=b.useLexicalComposerContext();c=x(e,c);A(e);return l.createElement(l.Fragment,null,a,l.createElement(B,{content:d}),c)}
7
+ 'use strict';var b=require("@lexical/react/LexicalComposerContext"),g=require("@lexical/react/useLexicalEditable"),l=require("react"),m=require("@lexical/text"),n=require("@lexical/utils"),p=require("react-dom"),t=require("@lexical/dragon"),u=require("@lexical/rich-text"),v="undefined"!==typeof window&&"undefined"!==typeof window.document&&"undefined"!==typeof window.document.createElement?l.useLayoutEffect:l.useEffect;
8
+ function w(a){return a.getEditorState().read(m.$canShowPlaceholderCurry(a.isComposing()))}function x(a){let [d,c]=l.useState(()=>w(a));v(()=>{function e(){let f=w(a);c(f)}e();return n.mergeRegister(a.registerUpdateListener(()=>{e()}),a.registerEditableListener(()=>{e()}))},[a]);return d}
9
+ function y(a,d){let [c,e]=l.useState(()=>a.getDecorators());v(()=>a.registerDecoratorListener(f=>{p.flushSync(()=>{e(f)})}),[a]);l.useEffect(()=>{e(a.getDecorators())},[a]);return l.useMemo(()=>{let f=[],q=Object.keys(c);for(let h=0;h<q.length;h++){let k=q[h],A=l.createElement(d,{onError:z=>a._onError(z)},l.createElement(l.Suspense,{fallback:null},c[k])),r=a.getElementByKey(k);null!==r&&f.push(p.createPortal(A,r,k))}return f},[d,c,a])}
10
+ function B(a){v(()=>n.mergeRegister(u.registerRichText(a),t.registerDragonSupport(a)),[a])}function C({content:a}){var [d]=b.useLexicalComposerContext();d=x(d);let c=g();return d?"function"===typeof a?a(c):a:null}exports.RichTextPlugin=function({contentEditable:a,placeholder:d,ErrorBoundary:c}){let [e]=b.useLexicalComposerContext();c=y(e,c);B(e);return l.createElement(l.Fragment,null,a,l.createElement(C,{content:d}),c)}
@@ -5,6 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
+ import type { LexicalEditor } from 'lexical';
9
+ export declare function registerTabIndentation(editor: LexicalEditor): () => void;
8
10
  /**
9
11
  * This plugin adds the ability to indent content using the tab key. Generally, we don't
10
12
  * recommend using this plugin as it could negatively affect acessibility for keyboard
@@ -7,6 +7,7 @@
7
7
  'use strict';
8
8
 
9
9
  var LexicalComposerContext = require('@lexical/react/LexicalComposerContext');
10
+ var utils = require('@lexical/utils');
10
11
  var lexical = require('lexical');
11
12
  var react = require('react');
12
13
 
@@ -17,6 +18,72 @@ var react = require('react');
17
18
  * LICENSE file in the root directory of this source tree.
18
19
  *
19
20
  */
21
+
22
+ function $filter(nodes, filterFn) {
23
+ const result = [];
24
+
25
+ for (let i = 0; i < nodes.length; i++) {
26
+ const node = filterFn(nodes[i]);
27
+
28
+ if (node !== null) {
29
+ result.push(node);
30
+ }
31
+ }
32
+
33
+ return result;
34
+ }
35
+
36
+ function indentOverTab(selection) {
37
+ // const handled = new Set();
38
+ const nodes = selection.getNodes();
39
+ const canIndentBlockNodes = $filter(nodes, node => {
40
+ if (lexical.$isBlockElementNode(node) && node.canIndent()) {
41
+ return node;
42
+ }
43
+
44
+ return null;
45
+ }); // 1. If selection spans across canIndent block nodes: indent
46
+
47
+ if (canIndentBlockNodes.length > 0) {
48
+ return true;
49
+ } // 2. If first (anchor/focus) is at block start: indent
50
+
51
+
52
+ const anchor = selection.anchor;
53
+ const focus = selection.focus;
54
+ const first = focus.isBefore(anchor) ? focus : anchor;
55
+ const firstNode = first.getNode();
56
+ const firstBlock = utils.$getNearestBlockElementAncestorOrThrow(firstNode);
57
+
58
+ if (firstBlock.canIndent()) {
59
+ const firstBlockKey = firstBlock.getKey();
60
+ let selectionAtStart = lexical.$createRangeSelection();
61
+ selectionAtStart.anchor.set(firstBlockKey, 0, 'element');
62
+ selectionAtStart.focus.set(firstBlockKey, 0, 'element');
63
+ selectionAtStart = lexical.$normalizeSelection__EXPERIMENTAL(selectionAtStart);
64
+
65
+ if (selectionAtStart.anchor.is(first)) {
66
+ return true;
67
+ }
68
+ } // 3. Else: tab
69
+
70
+
71
+ return false;
72
+ }
73
+
74
+ function registerTabIndentation(editor) {
75
+ return editor.registerCommand(lexical.KEY_TAB_COMMAND, event => {
76
+ const selection = lexical.$getSelection();
77
+
78
+ if (!lexical.$isRangeSelection(selection)) {
79
+ return false;
80
+ }
81
+
82
+ event.preventDefault();
83
+ const command = indentOverTab(selection) ? event.shiftKey ? lexical.OUTDENT_CONTENT_COMMAND : lexical.INDENT_CONTENT_COMMAND : lexical.INSERT_TAB_COMMAND;
84
+ return editor.dispatchCommand(command, undefined);
85
+ }, lexical.COMMAND_PRIORITY_EDITOR);
86
+ }
20
87
  /**
21
88
  * This plugin adds the ability to indent content using the tab key. Generally, we don't
22
89
  * recommend using this plugin as it could negatively affect acessibility for keyboard
@@ -26,18 +93,10 @@ var react = require('react');
26
93
  function TabIndentationPlugin() {
27
94
  const [editor] = LexicalComposerContext.useLexicalComposerContext();
28
95
  react.useEffect(() => {
29
- return editor.registerCommand(lexical.KEY_TAB_COMMAND, event => {
30
- const selection = lexical.$getSelection();
31
-
32
- if (!lexical.$isRangeSelection(selection)) {
33
- return false;
34
- }
35
-
36
- event.preventDefault();
37
- return editor.dispatchCommand(event.shiftKey ? lexical.OUTDENT_CONTENT_COMMAND : lexical.INDENT_CONTENT_COMMAND, undefined);
38
- }, lexical.COMMAND_PRIORITY_EDITOR);
96
+ return registerTabIndentation(editor);
39
97
  });
40
98
  return null;
41
99
  }
42
100
 
43
101
  exports.TabIndentationPlugin = TabIndentationPlugin;
102
+ exports.registerTabIndentation = registerTabIndentation;
@@ -7,4 +7,10 @@
7
7
  * @flow strict
8
8
  */
9
9
 
10
+ import type {LexicalEditor} from 'lexical';
11
+
12
+ declare export function registerTabIndentation(
13
+ editor: LexicalEditor,
14
+ ): () => void;
15
+
10
16
  declare export function TabIndentationPlugin(): null;
@@ -4,4 +4,6 @@
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 a=require("@lexical/react/LexicalComposerContext"),d=require("lexical"),e=require("react");exports.TabIndentationPlugin=function(){let [b]=a.useLexicalComposerContext();e.useEffect(()=>b.registerCommand(d.KEY_TAB_COMMAND,c=>{let f=d.$getSelection();if(!d.$isRangeSelection(f))return!1;c.preventDefault();return b.dispatchCommand(c.shiftKey?d.OUTDENT_CONTENT_COMMAND:d.INDENT_CONTENT_COMMAND,void 0)},d.COMMAND_PRIORITY_EDITOR));return null}
7
+ 'use strict';var d=require("@lexical/react/LexicalComposerContext"),g=require("@lexical/utils"),h=require("lexical"),k=require("react");function l(b,a){let c=[];for(let e=0;e<b.length;e++){let f=a(b[e]);null!==f&&c.push(f)}return c}
8
+ function m(b){var a=b.getNodes();if(0<l(a,c=>h.$isBlockElementNode(c)&&c.canIndent()?c:null).length)return!0;a=b.anchor;b=b.focus;b=b.isBefore(a)?b:a;a=b.getNode();a=g.$getNearestBlockElementAncestorOrThrow(a);if(a.canIndent()){a=a.getKey();let c=h.$createRangeSelection();c.anchor.set(a,0,"element");c.focus.set(a,0,"element");c=h.$normalizeSelection__EXPERIMENTAL(c);if(c.anchor.is(b))return!0}return!1}
9
+ function n(b){return b.registerCommand(h.KEY_TAB_COMMAND,a=>{let c=h.$getSelection();if(!h.$isRangeSelection(c))return!1;a.preventDefault();a=m(c)?a.shiftKey?h.OUTDENT_CONTENT_COMMAND:h.INDENT_CONTENT_COMMAND:h.INSERT_TAB_COMMAND;return b.dispatchCommand(a,void 0)},h.COMMAND_PRIORITY_EDITOR)}exports.TabIndentationPlugin=function(){let [b]=d.useLexicalComposerContext();k.useEffect(()=>n(b));return null};exports.registerTabIndentation=n
@@ -5,60 +5,30 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import { LexicalCommand, LexicalEditor, NodeKey, TextNode } from 'lexical';
9
- import { MutableRefObject, ReactPortal } from 'react';
10
- export declare type QueryMatch = {
11
- leadOffset: number;
12
- matchingString: string;
13
- replaceableString: string;
14
- };
15
- export declare type Resolution = {
16
- match: QueryMatch;
17
- getRect: () => DOMRect;
18
- };
8
+ /// <reference types="react" />
9
+ import type { MenuRenderFn, MenuResolution, MenuTextMatch, TriggerFn } from './shared/LexicalMenu';
10
+ import { LexicalCommand, TextNode } from 'lexical';
11
+ import { MenuOption } from './shared/LexicalMenu';
19
12
  export declare const PUNCTUATION = "\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'\"~=<>_:;";
20
- export declare class TypeaheadOption {
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 TypeaheadOption> = (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) => ReactPortal | JSX.Element | null;
32
13
  export declare function getScrollParent(element: HTMLElement, includeHidden: boolean): HTMLElement | HTMLBodyElement;
33
- export declare function useDynamicPositioning(resolution: Resolution | null, targetElement: HTMLElement | null, onReposition: () => void, onVisibilityChange?: (isInView: boolean) => void): void;
14
+ export declare function useDynamicPositioning(resolution: MenuResolution | null, targetElement: HTMLElement | null, onReposition: () => void, onVisibilityChange?: (isInView: boolean) => void): void;
34
15
  export declare const SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND: LexicalCommand<{
35
16
  index: number;
36
- option: TypeaheadOption;
17
+ option: MenuOption;
37
18
  }>;
38
19
  export declare function useBasicTypeaheadTriggerMatch(trigger: string, { minLength, maxLength }: {
39
20
  minLength?: number;
40
21
  maxLength?: number;
41
22
  }): TriggerFn;
42
- export declare type TypeaheadMenuPluginProps<TOption extends TypeaheadOption> = {
23
+ export declare type TypeaheadMenuPluginProps<TOption extends MenuOption> = {
43
24
  onQueryChange: (matchingString: string | null) => void;
44
25
  onSelectOption: (option: TOption, textNodeContainingQuery: TextNode | null, closeMenu: () => void, matchingString: string) => void;
45
26
  options: Array<TOption>;
46
27
  menuRenderFn: MenuRenderFn<TOption>;
47
28
  triggerFn: TriggerFn;
48
- onOpen?: (resolution: Resolution) => void;
29
+ onOpen?: (resolution: MenuResolution) => void;
49
30
  onClose?: () => void;
50
31
  anchorClassName?: string;
51
32
  };
52
- export declare type TriggerFn = (text: string, editor: LexicalEditor) => QueryMatch | null;
53
- export declare function LexicalTypeaheadMenuPlugin<TOption extends TypeaheadOption>({ options, onQueryChange, onSelectOption, onOpen, onClose, menuRenderFn, triggerFn, anchorClassName, }: TypeaheadMenuPluginProps<TOption>): JSX.Element | null;
54
- declare type NodeMenuPluginProps<TOption extends TypeaheadOption> = {
55
- onSelectOption: (option: TOption, textNodeContainingQuery: TextNode | null, closeMenu: () => void, matchingString: string) => void;
56
- options: Array<TOption>;
57
- nodeKey: NodeKey | null;
58
- onClose?: () => void;
59
- onOpen?: (resolution: Resolution) => void;
60
- menuRenderFn: MenuRenderFn<TOption>;
61
- anchorClassName?: string;
62
- };
63
- export declare function LexicalNodeMenuPlugin<TOption extends TypeaheadOption>({ options, nodeKey, onClose, onOpen, onSelectOption, menuRenderFn, anchorClassName, }: NodeMenuPluginProps<TOption>): JSX.Element | null;
64
- export {};
33
+ export declare function LexicalTypeaheadMenuPlugin<TOption extends MenuOption>({ options, onQueryChange, onSelectOption, onOpen, onClose, menuRenderFn, triggerFn, anchorClassName, }: TypeaheadMenuPluginProps<TOption>): JSX.Element | null;
34
+ export { MenuOption, MenuRenderFn, MenuResolution, MenuTextMatch, TriggerFn };