@lexical/list 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.
@@ -809,7 +809,7 @@ class ListItemNode extends lexical.ElementNode {
809
809
  } // Attempt to merge if the list is of the same type.
810
810
 
811
811
 
812
- if ($isListNode(node) && node.getListType() === listNode.getListType()) {
812
+ if ($isListNode(node)) {
813
813
  let child = node;
814
814
  const children = node.getChildren();
815
815
 
@@ -1138,6 +1138,12 @@ class ListNode extends lexical.ElementNode {
1138
1138
  return this.__tag;
1139
1139
  }
1140
1140
 
1141
+ setListType(type) {
1142
+ const writable = this.getWritable();
1143
+ writable.__listType = type;
1144
+ writable.__tag = type === 'number' ? 'ol' : 'ul';
1145
+ }
1146
+
1141
1147
  getListType() {
1142
1148
  return this.__listType;
1143
1149
  }
@@ -13,17 +13,17 @@ function G(a){if(!u(a)){var b=a.getParent(),c=b?b.getParent():void 0,d=c?c.getPa
13
13
  class H extends h.ElementNode{static getType(){return"listitem"}static clone(a){return new H(a.__value,a.__checked,a.__key)}constructor(a,b,c){super(c);this.__value=void 0===a?1:a;this.__checked=b}createDOM(a){let b=document.createElement("li"),c=this.getParent();q(c)&&"check"===c.getListType()&&I(b,this,null);b.value=this.__value;J(b,a.theme,this);return b}updateDOM(a,b,c){let d=this.getParent();q(d)&&"check"===d.getListType()&&I(b,this,a);b.value=this.__value;J(b,c.theme,this);return!1}static transform(){return a=>
14
14
  {let b=a.getParent();q(b)&&(E(b),"check"!==b.getListType()&&null!=a.getChecked()&&a.setChecked(void 0))}}static importDOM(){return{li:()=>({conversion:K,priority:0})}}static importJSON(a){let b=new H(a.value,a.checked);b.setFormat(a.format);b.setDirection(a.direction);return b}exportJSON(){return{...super.exportJSON(),checked:this.getChecked(),type:"listitem",value:this.getValue(),version:1}}append(...a){for(let b=0;b<a.length;b++){let c=a[b];if(h.$isElementNode(c)&&this.canMergeWith(c)){let d=c.getChildren();
15
15
  this.append(...d);c.remove()}else super.append(c)}return this}replace(a,b){if(p(a))return super.replace(a);this.setIndent(0);let c=this.getParentOrThrow();if(!q(c))return a;if(c.__first===this.getKey())c.insertBefore(a);else if(c.__last===this.getKey())c.insertAfter(a);else{let d=D(c.getListType()),e=this.getNextSibling();for(;e;){let f=e;e=e.getNextSibling();d.append(f)}c.insertAfter(a);a.insertAfter(d)}b&&this.getChildren().forEach(d=>{a.append(d)});this.remove();0===c.getChildrenSize()&&c.remove();
16
- return a}insertAfter(a,b=!0){var c=this.getParentOrThrow();q(c)||m(39);var d=this.getNextSiblings();if(p(a))return b=super.insertAfter(a,b),a=a.getParentOrThrow(),q(a)&&E(a),b;if(q(a)&&a.getListType()===c.getListType()){c=a;a=a.getChildren();for(d=a.length-1;0<=d;d--)c=a[d],this.insertAfter(c,b);return c}c.insertAfter(a,b);if(0!==d.length){let e=D(c.getListType());d.forEach(f=>e.append(f));a.insertAfter(e,b)}return a}remove(a){let b=this.getPreviousSibling(),c=this.getNextSibling();super.remove(a);
17
- b&&c&&u(b)&&u(c)?(F(b.getFirstChild(),c.getFirstChild()),c.remove()):c&&(a=c.getParent(),q(a)&&E(a))}insertNewAfter(a,b=!0){a=y(null==this.__checked?void 0:!1);this.insertAfter(a,b);return a}collapseAtStart(a){let b=h.$createParagraphNode();this.getChildren().forEach(f=>b.append(f));var c=this.getParentOrThrow(),d=c.getParentOrThrow();let e=p(d);1===c.getChildrenSize()?e?(c.remove(),d.select()):(c.insertBefore(b),c.remove(),c=a.anchor,a=a.focus,d=b.getKey(),"element"===c.type&&c.getNode().is(this)&&
18
- c.set(d,c.offset,"element"),"element"===a.type&&a.getNode().is(this)&&a.set(d,a.offset,"element")):(c.insertBefore(b),this.remove());return!0}getValue(){return this.getLatest().__value}setValue(a){this.getWritable().__value=a}getChecked(){return this.getLatest().__checked}setChecked(a){this.getWritable().__checked=a}toggleChecked(){this.setChecked(!this.__checked)}getIndent(){var a=this.getParent();if(null===a)return this.getLatest().__indent;a=a.getParentOrThrow();let b=0;for(;p(a);)a=a.getParentOrThrow().getParentOrThrow(),
19
- b++;return b}setIndent(a){"number"===typeof a&&-1<a||m(117);let b=this.getIndent();for(;b!==a;)if(b<a){a:{var c=new Set;if(u(this)||c.has(this.getKey()))break a;let g=this.getParent();var d=this.getNextSibling(),e=this.getPreviousSibling();if(u(d)&&u(e)){if(e=e.getFirstChild(),q(e)){e.append(this);var f=d.getFirstChild();q(f)&&(f=f.getChildren(),B(e,f),d.remove(),c.add(d.getKey()));E(e)}}else u(d)?(d=d.getFirstChild(),q(d)&&(c=d.getFirstChild(),null!==c&&c.insertBefore(this),E(d))):u(e)?(d=e.getFirstChild(),
20
- q(d)&&(d.append(this),E(d))):q(g)&&(c=y(),f=D(g.getListType()),c.append(f),f.append(this),e?e.insertAfter(c):d?d.insertBefore(c):g.append(c),E(f));q(g)&&E(g)}b++}else G(this),b--;return this}insertBefore(a){if(p(a)){let b=this.getParentOrThrow();if(q(b)){let c=this.getNextSiblings();E(b,c)}}return super.insertBefore(a)}canInsertAfter(a){return p(a)}canReplaceWith(a){return p(a)}canMergeWith(a){return h.$isParagraphNode(a)||p(a)}extractWithChild(a,b){if(!h.$isRangeSelection(b))return!1;a=b.anchor.getNode();
21
- let c=b.focus.getNode();return this.isParentOf(a)&&this.isParentOf(c)&&this.getTextContent().length===b.getTextContent().length}isParentRequired(){return!0}createParentElementNode(){return D("bullet")}}
16
+ return a}insertAfter(a,b=!0){var c=this.getParentOrThrow();q(c)||m(39);var d=this.getNextSiblings();if(p(a))return b=super.insertAfter(a,b),a=a.getParentOrThrow(),q(a)&&E(a),b;if(q(a)){c=a;a=a.getChildren();for(d=a.length-1;0<=d;d--)c=a[d],this.insertAfter(c,b);return c}c.insertAfter(a,b);if(0!==d.length){let e=D(c.getListType());d.forEach(f=>e.append(f));a.insertAfter(e,b)}return a}remove(a){let b=this.getPreviousSibling(),c=this.getNextSibling();super.remove(a);b&&c&&u(b)&&u(c)?(F(b.getFirstChild(),
17
+ c.getFirstChild()),c.remove()):c&&(a=c.getParent(),q(a)&&E(a))}insertNewAfter(a,b=!0){a=y(null==this.__checked?void 0:!1);this.insertAfter(a,b);return a}collapseAtStart(a){let b=h.$createParagraphNode();this.getChildren().forEach(f=>b.append(f));var c=this.getParentOrThrow(),d=c.getParentOrThrow();let e=p(d);1===c.getChildrenSize()?e?(c.remove(),d.select()):(c.insertBefore(b),c.remove(),c=a.anchor,a=a.focus,d=b.getKey(),"element"===c.type&&c.getNode().is(this)&&c.set(d,c.offset,"element"),"element"===
18
+ a.type&&a.getNode().is(this)&&a.set(d,a.offset,"element")):(c.insertBefore(b),this.remove());return!0}getValue(){return this.getLatest().__value}setValue(a){this.getWritable().__value=a}getChecked(){return this.getLatest().__checked}setChecked(a){this.getWritable().__checked=a}toggleChecked(){this.setChecked(!this.__checked)}getIndent(){var a=this.getParent();if(null===a)return this.getLatest().__indent;a=a.getParentOrThrow();let b=0;for(;p(a);)a=a.getParentOrThrow().getParentOrThrow(),b++;return b}setIndent(a){"number"===
19
+ typeof a&&-1<a||m(117);let b=this.getIndent();for(;b!==a;)if(b<a){a:{var c=new Set;if(u(this)||c.has(this.getKey()))break a;let g=this.getParent();var d=this.getNextSibling(),e=this.getPreviousSibling();if(u(d)&&u(e)){if(e=e.getFirstChild(),q(e)){e.append(this);var f=d.getFirstChild();q(f)&&(f=f.getChildren(),B(e,f),d.remove(),c.add(d.getKey()));E(e)}}else u(d)?(d=d.getFirstChild(),q(d)&&(c=d.getFirstChild(),null!==c&&c.insertBefore(this),E(d))):u(e)?(d=e.getFirstChild(),q(d)&&(d.append(this),E(d))):
20
+ q(g)&&(c=y(),f=D(g.getListType()),c.append(f),f.append(this),e?e.insertAfter(c):d?d.insertBefore(c):g.append(c),E(f));q(g)&&E(g)}b++}else G(this),b--;return this}insertBefore(a){if(p(a)){let b=this.getParentOrThrow();if(q(b)){let c=this.getNextSiblings();E(b,c)}}return super.insertBefore(a)}canInsertAfter(a){return p(a)}canReplaceWith(a){return p(a)}canMergeWith(a){return h.$isParagraphNode(a)||p(a)}extractWithChild(a,b){if(!h.$isRangeSelection(b))return!1;a=b.anchor.getNode();let c=b.focus.getNode();
21
+ return this.isParentOf(a)&&this.isParentOf(c)&&this.getTextContent().length===b.getTextContent().length}isParentRequired(){return!0}createParentElementNode(){return D("bullet")}}
22
22
  function J(a,b,c){let d=[],e=[];var f=(b=b.list)?b.listitem:void 0;if(b&&b.nested)var g=b.nested.listitem;void 0!==f&&(f=f.split(" "),d.push(...f));if(b){f=c.getParent();f=q(f)&&"check"===f.getListType();let l=c.getChecked();f&&!l||e.push(b.listitemUnchecked);f&&l||e.push(b.listitemChecked);f&&d.push(l?b.listitemChecked:b.listitemUnchecked)}void 0!==g&&(g=g.split(" "),c.getChildren().some(l=>q(l))?d.push(...g):e.push(...g));0<e.length&&k.removeClassNamesFromElement(a,...e);0<d.length&&k.addClassNamesToElement(a,
23
23
  ...d)}function I(a,b,c){q(b.getFirstChild())?(a.removeAttribute("role"),a.removeAttribute("tabIndex"),a.removeAttribute("aria-checked")):(a.setAttribute("role","checkbox"),a.setAttribute("tabIndex","-1"),c&&b.__checked===c.__checked||a.setAttribute("aria-checked",b.getChecked()?"true":"false"))}function K(a){a=k.isHTMLElement(a)&&"true"===a.getAttribute("aria-checked");return{node:y(a)}}function y(a){return h.$applyNodeReplacement(new H(void 0,a))}function p(a){return a instanceof H}
24
- class L extends h.ElementNode{static getType(){return"list"}static clone(a){return new L(a.__listType||N[a.__tag],a.__start,a.__key)}constructor(a,b,c){super(c);this.__listType=a=N[a]||a;this.__tag="number"===a?"ol":"ul";this.__start=b}getTag(){return this.__tag}getListType(){return this.__listType}getStart(){return this.__start}createDOM(a){let b=document.createElement(this.__tag);1!==this.__start&&b.setAttribute("start",String(this.__start));b.__lexicalListType=this.__listType;O(b,a.theme,this);
25
- return b}updateDOM(a,b,c){if(a.__tag!==this.__tag)return!0;O(b,c.theme,this);return!1}static importDOM(){return{ol:()=>({conversion:P,priority:0}),ul:()=>({conversion:P,priority:0})}}static importJSON(a){let b=D(a.listType,a.start);b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}exportDOM(a){({element:a}=super.exportDOM(a));a&&(1!==this.__start&&a.setAttribute("start",String(this.__start)),"check"===this.__listType&&a.setAttribute("__lexicalListType","check"));return{element:a}}exportJSON(){return{...super.exportJSON(),
26
- listType:this.getListType(),start:this.getStart(),tag:this.getTag(),type:"list",version:1}}canBeEmpty(){return!1}canIndent(){return!1}append(...a){for(let c=0;c<a.length;c++){var b=a[c];if(p(b))super.append(b);else{let d=y();q(b)?d.append(b):h.$isElementNode(b)?(b=h.$createTextNode(b.getTextContent()),d.append(b)):d.append(b);super.append(d)}}E(this);return this}extractWithChild(a){return p(a)}}
24
+ class L extends h.ElementNode{static getType(){return"list"}static clone(a){return new L(a.__listType||N[a.__tag],a.__start,a.__key)}constructor(a,b,c){super(c);this.__listType=a=N[a]||a;this.__tag="number"===a?"ol":"ul";this.__start=b}getTag(){return this.__tag}setListType(a){let b=this.getWritable();b.__listType=a;b.__tag="number"===a?"ol":"ul"}getListType(){return this.__listType}getStart(){return this.__start}createDOM(a){let b=document.createElement(this.__tag);1!==this.__start&&b.setAttribute("start",
25
+ String(this.__start));b.__lexicalListType=this.__listType;O(b,a.theme,this);return b}updateDOM(a,b,c){if(a.__tag!==this.__tag)return!0;O(b,c.theme,this);return!1}static importDOM(){return{ol:()=>({conversion:P,priority:0}),ul:()=>({conversion:P,priority:0})}}static importJSON(a){let b=D(a.listType,a.start);b.setFormat(a.format);b.setIndent(a.indent);b.setDirection(a.direction);return b}exportDOM(a){({element:a}=super.exportDOM(a));a&&(1!==this.__start&&a.setAttribute("start",String(this.__start)),
26
+ "check"===this.__listType&&a.setAttribute("__lexicalListType","check"));return{element:a}}exportJSON(){return{...super.exportJSON(),listType:this.getListType(),start:this.getStart(),tag:this.getTag(),type:"list",version:1}}canBeEmpty(){return!1}canIndent(){return!1}append(...a){for(let c=0;c<a.length;c++){var b=a[c];if(p(b))super.append(b);else{let d=y();q(b)?d.append(b):h.$isElementNode(b)?(b=h.$createTextNode(b.getTextContent()),d.append(b)):d.append(b);super.append(d)}}E(this);return this}extractWithChild(a){return p(a)}}
27
27
  function O(a,b,c){let d=[],e=[];var f=b.list;if(void 0!==f){let l=f[`${c.__tag}Depth`]||[];b=n(c)-1;let x=b%l.length;var g=l[x];let M=f[c.__tag],A;f=f.nested;void 0!==f&&f.list&&(A=f.list);void 0!==M&&d.push(M);if(void 0!==g)for(g=g.split(" "),d.push(...g),g=0;g<l.length;g++)g!==x&&e.push(c.__tag+g);void 0!==A&&(c=A.split(" "),1<b?d.push(...c):e.push(...c))}0<e.length&&k.removeClassNamesFromElement(a,...e);0<d.length&&k.addClassNamesToElement(a,...d)}
28
28
  function Q(a){let b=[];for(let d=0;d<a.length;d++){var c=a[d];p(c)?(b.push(c),c=c.getChildren(),1<c.length&&c.forEach(e=>{q(e)&&b.push(w(e))})):b.push(w(c))}return b}function P(a){let b=a.nodeName.toLowerCase(),c=null;"ol"===b?c=D("number",a.start):"ul"===b&&(c=k.isHTMLElement(a)&&"check"===a.getAttribute("__lexicallisttype")?D("check"):D("bullet"));return{after:Q,node:c}}let N={ol:"number",ul:"bullet"};function D(a,b=1){return h.$applyNodeReplacement(new L(a,b))}
29
29
  function q(a){return a instanceof L}let R=h.createCommand("INSERT_UNORDERED_LIST_COMMAND"),S=h.createCommand("INSERT_ORDERED_LIST_COMMAND"),T=h.createCommand("INSERT_CHECK_LIST_COMMAND"),U=h.createCommand("REMOVE_LIST_COMMAND");exports.$createListItemNode=y;exports.$createListNode=D;exports.$getListDepth=n;
@@ -25,6 +25,7 @@ export declare class ListNode extends ElementNode {
25
25
  static clone(node: ListNode): ListNode;
26
26
  constructor(listType: ListType, start: number, key?: NodeKey);
27
27
  getTag(): ListNodeTagType;
28
+ setListType(type: ListType): void;
28
29
  getListType(): ListType;
29
30
  getStart(): number;
30
31
  createDOM(config: EditorConfig, _editor?: LexicalEditor): HTMLElement;
package/README.md CHANGED
@@ -1,3 +1,86 @@
1
- # `@lexical/list`
1
+ `@lexical/list`
2
2
 
3
- This package contains the functionality for the List feature of Lexical.
3
+ This package exposes the primitives for implementing lists in Lexical. If you're trying to implement conventional lists with React, take a look at the ListPlugin exposed
4
+ by [@lexical/react](https://lexical.dev/docs/packages/lexical-react), which wraps these primitives into a neat component that you can drop into any LexicalComposer.
5
+
6
+ The API of @lexical/list primarily consists of Lexical Nodes that encapsulate list behaviors and a set of functions that can be called to trigger typical list manipulation functionality:
7
+
8
+ ## Functions
9
+
10
+ ### insertList
11
+
12
+ As the name suggests, this inserts a list of the provided type according to an algorithm that tries to determine the best way to do that based on
13
+ the current Selection. For instance, if some text is selected, insertList may try to move it into the first item in the list. See the API documentation for more detail.
14
+
15
+ ### removeList
16
+
17
+ Attempts to remove lists inside the current selection based on a set of opinionated heuristics that implement conventional editor behaviors. For instance, it converts empty ListItemNodes into empty ParagraphNodes.
18
+
19
+ ## Nodes
20
+
21
+ ### ListNode
22
+
23
+ ### ListItemNode
24
+
25
+ ## Commands
26
+
27
+ For convenience, we provide a set of commands that can be used to connect a plugin to trigger typical list manipulation functionality:
28
+
29
+ ### INSERT_UNORDERED_LIST_COMMAND
30
+
31
+ ### INSERT_ORDERED_LIST_COMMAND
32
+
33
+ ### INSERT_CHECK_LIST_COMMAND
34
+
35
+ ### REMOVE_LIST_COMMAND
36
+
37
+ It's important to note that these commands don't have any functionality on their own. They are just for convenience and require you to register a handler for them in order to actually change the editor state when they are dispatched, as below:
38
+
39
+
40
+ ```ts
41
+ // MyListPlugin.ts
42
+
43
+ editor.registerCommand(INSERT_UNORDERED_LIST_COMMAND, () => {
44
+ insertList(editor, 'bullet');
45
+ return true;
46
+ }, COMMAND_PRIORITY_LOW);
47
+
48
+ // MyInsertListToolbarButton.ts
49
+
50
+ function onButtonClick(e: MouseEvent) {
51
+ editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);
52
+ }
53
+
54
+ ```
55
+
56
+ ## Theming
57
+
58
+ Lists can be styled using the following properties in the EditorTheme passed to the editor in the initial config (the values are classses that will be applied in the denoted contexts):
59
+
60
+ ```ts
61
+ {
62
+ list?: {
63
+ // Applies to all lists of type "bullet"
64
+ ul?: EditorThemeClassName;
65
+ // Used to apply specific styling to nested levels of bullet lists
66
+ // e.g., [ 'bullet-list-level-one', 'bullet-list-level-two' ]
67
+ ulDepth?: Array<EditorThemeClassName>;
68
+ // Applies to all lists of type "number"
69
+ ol?: EditorThemeClassName;
70
+ // Used to apply specific styling to nested levels of number lists
71
+ // e.g., [ 'number-list-level-one', 'number-list-level-two' ]
72
+ olDepth?: Array<EditorThemeClassName>;
73
+ // Applies to all list items
74
+ listitem?: EditorThemeClassName;
75
+ // Applies to all list items with checked property set to "true"
76
+ listitemChecked?: EditorThemeClassName;
77
+ // Applies to all list items with checked property set to "false"
78
+ listitemUnchecked?: EditorThemeClassName;
79
+ // Applies only to list and list items that are not at the top level.
80
+ nested?: {
81
+ list?: EditorThemeClassName;
82
+ listitem?: EditorThemeClassName;
83
+ };
84
+ };
85
+ }
86
+ ```
package/package.json CHANGED
@@ -8,13 +8,13 @@
8
8
  "list"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.10.0",
11
+ "version": "0.11.1",
12
12
  "main": "LexicalList.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.10.0"
14
+ "lexical": "0.11.1"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/utils": "0.10.0"
17
+ "@lexical/utils": "0.11.1"
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",