@ekz/lexical-list 0.40.0

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.
@@ -0,0 +1,11 @@
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
+
9
+ 'use strict'
10
+ const EkzLexicalList = process.env.NODE_ENV !== 'production' ? require('./EkzLexicalList.dev.js') : require('./EkzLexicalList.prod.js');
11
+ module.exports = EkzLexicalList;
@@ -0,0 +1,33 @@
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
+
9
+ import * as modDev from './EkzLexicalList.dev.mjs';
10
+ import * as modProd from './EkzLexicalList.prod.mjs';
11
+ const mod = process.env.NODE_ENV !== 'production' ? modDev : modProd;
12
+ export const $createListItemNode = mod.$createListItemNode;
13
+ export const $createListNode = mod.$createListNode;
14
+ export const $getListDepth = mod.$getListDepth;
15
+ export const $handleListInsertParagraph = mod.$handleListInsertParagraph;
16
+ export const $insertList = mod.$insertList;
17
+ export const $isListItemNode = mod.$isListItemNode;
18
+ export const $isListNode = mod.$isListNode;
19
+ export const $removeList = mod.$removeList;
20
+ export const CheckListExtension = mod.CheckListExtension;
21
+ export const INSERT_CHECK_LIST_COMMAND = mod.INSERT_CHECK_LIST_COMMAND;
22
+ export const INSERT_ORDERED_LIST_COMMAND = mod.INSERT_ORDERED_LIST_COMMAND;
23
+ export const INSERT_UNORDERED_LIST_COMMAND = mod.INSERT_UNORDERED_LIST_COMMAND;
24
+ export const ListExtension = mod.ListExtension;
25
+ export const ListItemNode = mod.ListItemNode;
26
+ export const ListNode = mod.ListNode;
27
+ export const REMOVE_LIST_COMMAND = mod.REMOVE_LIST_COMMAND;
28
+ export const UPDATE_LIST_START_COMMAND = mod.UPDATE_LIST_START_COMMAND;
29
+ export const insertList = mod.insertList;
30
+ export const registerCheckList = mod.registerCheckList;
31
+ export const registerList = mod.registerList;
32
+ export const registerListStrictIndentTransform = mod.registerListStrictIndentTransform;
33
+ export const removeList = mod.removeList;
@@ -0,0 +1,31 @@
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
+
9
+ const mod = await (process.env.NODE_ENV !== 'production' ? import('./EkzLexicalList.dev.mjs') : import('./EkzLexicalList.prod.mjs'));
10
+ export const $createListItemNode = mod.$createListItemNode;
11
+ export const $createListNode = mod.$createListNode;
12
+ export const $getListDepth = mod.$getListDepth;
13
+ export const $handleListInsertParagraph = mod.$handleListInsertParagraph;
14
+ export const $insertList = mod.$insertList;
15
+ export const $isListItemNode = mod.$isListItemNode;
16
+ export const $isListNode = mod.$isListNode;
17
+ export const $removeList = mod.$removeList;
18
+ export const CheckListExtension = mod.CheckListExtension;
19
+ export const INSERT_CHECK_LIST_COMMAND = mod.INSERT_CHECK_LIST_COMMAND;
20
+ export const INSERT_ORDERED_LIST_COMMAND = mod.INSERT_ORDERED_LIST_COMMAND;
21
+ export const INSERT_UNORDERED_LIST_COMMAND = mod.INSERT_UNORDERED_LIST_COMMAND;
22
+ export const ListExtension = mod.ListExtension;
23
+ export const ListItemNode = mod.ListItemNode;
24
+ export const ListNode = mod.ListNode;
25
+ export const REMOVE_LIST_COMMAND = mod.REMOVE_LIST_COMMAND;
26
+ export const UPDATE_LIST_START_COMMAND = mod.UPDATE_LIST_START_COMMAND;
27
+ export const insertList = mod.insertList;
28
+ export const registerCheckList = mod.registerCheckList;
29
+ export const registerList = mod.registerList;
30
+ export const registerListStrictIndentTransform = mod.registerListStrictIndentTransform;
31
+ export const removeList = mod.removeList;
@@ -0,0 +1,9 @@
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
+
9
+ "use strict";var e=require("@ekz/lexical-extension"),t=require("@ekz/lexical-utils"),n=require("@ekz/lexical"),r=require("@ekz/lexical-selection");function s(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function i(e){let t=1,n=e.getParent();for(;null!=n;){if(O(n)){const e=n.getParent();if(A(e)){t++,n=e.getParent();continue}s(40)}return t}return t}function o(e){let t=e.getParent();A(t)||s(40);let n=t;for(;null!==n;)n=n.getParent(),A(n)&&(t=n);return t}function l(e){let t=[];const n=e.getChildren().filter(O);for(let e=0;e<n.length;e++){const r=n[e],s=r.getFirstChild();A(s)?t=t.concat(l(s)):t.push(r)}return t}function c(e){return O(e)&&A(e.getFirstChild())}function a(e){return x().append(e)}function g(e,t){return O(e)&&(0===t.length||1===t.length&&e.is(t[0])&&0===e.getChildrenSize())}function d(e){const t=n.$getSelection();if(null!==t){let r=t.getNodes();if(n.$isRangeSelection(t)){const i=t.getStartEndPoints();null===i&&s(143);const[o]=i,l=o.getNode(),c=l.getParent();if(n.$isRootOrShadowRoot(l)){const e=l.getFirstChild();if(e)r=e.selectStart().getNodes();else{const e=n.$createParagraphNode();l.append(e),r=e.select().getNodes()}}else if(g(l,r)){const t=P(e);if(n.$isRootOrShadowRoot(c)){l.replace(t);const e=x();n.$isElementNode(l)&&(e.setFormat(l.getFormatType()),e.setIndent(l.getIndent())),t.append(e)}else if(O(l)){const e=l.getParentOrThrow();u(t,e.getChildren()),e.replace(t)}return}}const i=new Set;for(let t=0;t<r.length;t++){const s=r[t];if(n.$isElementNode(s)&&s.isEmpty()&&!O(s)&&!i.has(s.getKey())){h(s,e);continue}let o=n.$isLeafNode(s)?s.getParent():O(s)&&s.isEmpty()?s:null;for(;null!=o;){const t=o.getKey();if(A(o)){if(!i.has(t)){const n=P(e);u(n,o.getChildren()),o.replace(n),i.add(t)}break}{const r=o.getParent();if(n.$isRootOrShadowRoot(r)&&!i.has(t)){i.add(t),h(o,e);break}o=r}}}}}function u(e,t){e.splice(e.getChildrenSize(),0,t)}function h(e,t){if(A(e))return e;const r=e.getPreviousSibling(),s=e.getNextSibling(),i=x();let o;if(u(i,e.getChildren()),A(r)&&t===r.getListType())r.append(i),A(s)&&t===s.getListType()&&(u(r,s.getChildren()),s.remove()),o=r;else if(A(s)&&t===s.getListType())s.getFirstChildOrThrow().insertBefore(i),o=s;else{const n=P(t);n.append(i),e.replace(n),o=n}i.setFormat(e.getFormatType()),i.setIndent(e.getIndent());const l=n.$getSelection();return n.$isRangeSelection(l)&&(o.getKey()===l.anchor.key&&l.anchor.set(i.getKey(),l.anchor.offset,"element"),o.getKey()===l.focus.key&&l.focus.set(i.getKey(),l.focus.offset,"element")),e.remove(),o}function f(e,t){const n=e.getLastChild(),r=t.getFirstChild();n&&r&&c(n)&&c(r)&&(f(n.getFirstChild(),r.getFirstChild()),r.remove());const s=t.getChildren();s.length>0&&e.append(...s),t.remove()}function p(){const e=n.$getSelection();if(n.$isRangeSelection(e)){const r=new Set,s=e.getNodes(),i=e.anchor.getNode();if(g(i,s))r.add(o(i));else for(let e=0;e<s.length;e++){const i=s[e];if(n.$isLeafNode(i)){const e=t.$getNearestNodeOfType(i,T);null!=e&&r.add(o(e))}}for(const t of r){let r=t;const s=l(t);for(const t of s){const s=n.$createParagraphNode().setTextStyle(e.style).setTextFormat(e.format);u(s,t.getChildren()),r.insertAfter(s),r=s,t.__key===e.anchor.key&&n.$setPointFromCaret(e.anchor,n.$normalizeCaret(n.$getChildCaret(s,"next"))),t.__key===e.focus.key&&n.$setPointFromCaret(e.focus,n.$normalizeCaret(n.$getChildCaret(s,"next"))),t.remove()}t.remove()}}}function m(e){const t="check"!==e.getListType();let n=e.getStart();for(const r of e.getChildren())O(r)&&(r.getValue()!==n&&r.setValue(n),t&&null!=r.getLatest().__checked&&r.setChecked(void 0),A(r.getFirstChild())||n++)}function _(e){const t=new Set;if(c(e)||t.has(e.getKey()))return;const n=e.getParent(),r=e.getNextSibling(),s=e.getPreviousSibling();if(c(r)&&c(s)){const n=s.getFirstChild();if(A(n)){n.append(e);const s=r.getFirstChild();if(A(s)){u(n,s.getChildren()),r.remove(),t.add(r.getKey())}}}else if(c(r)){const t=r.getFirstChild();if(A(t)){const n=t.getFirstChild();null!==n&&n.insertBefore(e)}}else if(c(s)){const t=s.getFirstChild();A(t)&&t.append(e)}else if(A(n)){const t=x().setTextFormat(e.getTextFormat()).setTextStyle(e.getTextStyle()),i=P(n.getListType()).setTextFormat(n.getTextFormat()).setTextStyle(n.getTextStyle());t.append(i),i.append(e),s?s.insertAfter(t):r?r.insertBefore(t):n.append(t)}}function C(e){if(c(e))return;const t=e.getParent(),n=t?t.getParent():void 0;if(A(n?n.getParent():void 0)&&O(n)&&A(t)){const r=t?t.getFirstChild():void 0,s=t?t.getLastChild():void 0;if(e.is(r))n.insertBefore(e),t.isEmpty()&&n.remove();else if(e.is(s))n.insertAfter(e),t.isEmpty()&&n.remove();else{const r=t.getListType(),s=x(),i=P(r);s.append(i),e.getPreviousSiblings().forEach(e=>i.append(e));const o=x(),l=P(r);o.append(l),u(l,e.getNextSiblings()),n.insertBefore(s),n.insertAfter(o),n.replace(e)}}}function N(){const e=n.$getSelection();if(!n.$isRangeSelection(e)||!e.isCollapsed())return!1;const t=e.anchor.getNode();let r=null;if(O(t)&&0===t.getChildrenSize())r=t;else if(n.$isTextNode(t)){const e=t.getParent();O(e)&&e.getChildren().every(e=>n.$isTextNode(e)&&""===e.getTextContent().trim())&&(r=e)}if(null===r)return!1;const i=o(r),l=r.getParent();A(l)||s(40);const c=l.getParent();let a;if(n.$isRootOrShadowRoot(c))a=n.$createParagraphNode(),i.insertAfter(a);else{if(!O(c))return!1;a=x(),c.insertAfter(a)}a.setTextStyle(e.style).setTextFormat(e.format).select();const g=r.getNextSiblings();if(g.length>0){const e=P(l.getListType());if(O(a)){const t=x();t.append(e),a.insertAfter(t)}else a.insertAfter(e);e.append(...g)}return function(e){let t=e;for(;null==t.getNextSibling()&&null==t.getPreviousSibling();){const e=t.getParent();if(null==e||!O(e)&&!A(e))break;t=e}t.remove()}(r),!0}class T extends n.ElementNode{__value;__checked;$config(){return this.config("listitem",{$transform:e=>{if(null==e.__checked)return;const t=e.getParent();A(t)&&"check"!==t.getListType()&&null!=e.getChecked()&&e.setChecked(void 0)},extends:n.ElementNode,importDOM:n.buildImportMap({li:()=>({conversion:S,priority:0})})})}constructor(e=1,t=void 0,n){super(n),this.__value=void 0===e?1:e,this.__checked=t}afterCloneFrom(e){super.afterCloneFrom(e),this.__value=e.__value,this.__checked=e.__checked}createDOM(e){const t=document.createElement("li");return this.updateListItemDOM(null,t,e),t}updateListItemDOM(e,s,i){!function(e,t,n){const r=t.getParent();!A(r)||"check"!==r.getListType()||A(t.getFirstChild())?(e.removeAttribute("role"),e.removeAttribute("tabIndex"),e.removeAttribute("aria-checked")):(e.setAttribute("role","checkbox"),e.setAttribute("tabIndex","-1"),n&&t.__checked===n.__checked||e.setAttribute("aria-checked",t.getChecked()?"true":"false"))}(s,this,e),s.value=this.__value,function(e,r,s){const i=[],o=[],l=r.list,c=l?l.listitem:void 0;let a;l&&l.nested&&(a=l.nested.listitem);void 0!==c&&i.push(...n.normalizeClassNames(c));if(l){const e=s.getParent(),t=A(e)&&"check"===e.getListType(),n=s.getChecked();t&&!n||o.push(l.listitemUnchecked),t&&n||o.push(l.listitemChecked),t&&i.push(n?l.listitemChecked:l.listitemUnchecked)}if(void 0!==a){const e=n.normalizeClassNames(a);s.getChildren().some(e=>A(e))?i.push(...e):o.push(...e)}o.length>0&&t.removeClassNamesFromElement(e,...o);i.length>0&&t.addClassNamesToElement(e,...i)}(s,i.theme,this);const o=e?e.__style:"",l=this.__style;o!==l&&(""===l?s.removeAttribute("style"):s.style.cssText=l),function(e,t,n){const s=r.getStyleObjectFromCSS(t.__textStyle);for(const t in s)e.style.setProperty(`--listitem-marker-${t}`,s[t]);if(n)for(const t in r.getStyleObjectFromCSS(n.__textStyle))t in s||e.style.removeProperty(`--listitem-marker-${t}`)}(s,this,e)}updateDOM(e,t,n){const r=t;return this.updateListItemDOM(e,r,n),!1}updateFromJSON(e){return super.updateFromJSON(e).setValue(e.value).setChecked(e.checked)}exportDOM(e){const t=this.createDOM(e._config),n=this.getFormatType();n&&(t.style.textAlign=n);const r=this.getDirection();return r&&(t.dir=r),{element:t}}exportJSON(){return{...super.exportJSON(),checked:this.getChecked(),value:this.getValue()}}append(...e){for(let t=0;t<e.length;t++){const r=e[t];if(n.$isElementNode(r)&&this.canMergeWith(r)){const e=r.getChildren();this.append(...e),r.remove()}else super.append(r)}return this}replace(e,t){if(O(e))return super.replace(e);this.setIndent(0);const r=this.getParentOrThrow();if(!A(r))return e;if(r.__first===this.getKey())r.insertBefore(e);else if(r.__last===this.getKey())r.insertAfter(e);else{const t=P(r.getListType());let n=this.getNextSibling();for(;n;){const e=n;n=n.getNextSibling(),t.append(e)}r.insertAfter(e),e.insertAfter(t)}return t&&(n.$isElementNode(e)||s(139),this.getChildren().forEach(t=>{e.append(t)})),this.remove(),0===r.getChildrenSize()&&r.remove(),e}insertAfter(e,t=!0){const n=this.getParentOrThrow();if(A(n)||s(39),O(e))return super.insertAfter(e,t);const r=this.getNextSiblings();if(n.insertAfter(e,t),0!==r.length){const s=P(n.getListType());r.forEach(e=>s.append(e)),e.insertAfter(s,t)}return e}remove(e){const t=this.getPreviousSibling(),n=this.getNextSibling();super.remove(e),t&&n&&c(t)&&c(n)&&(f(t.getFirstChild(),n.getFirstChild()),n.remove())}insertNewAfter(e,t=!0){const n=x().updateFromJSON(this.exportJSON()).setChecked(!this.getChecked()&&void 0);return this.insertAfter(n,t),n}collapseAtStart(e){const t=n.$createParagraphNode();this.getChildren().forEach(e=>t.append(e));const r=this.getParentOrThrow(),s=r.getParentOrThrow(),i=O(s);if(1===r.getChildrenSize())if(i)r.remove(),s.select();else{r.insertBefore(t),r.remove();const n=e.anchor,s=e.focus,i=t.getKey();"element"===n.type&&n.getNode().is(this)&&n.set(i,n.offset,"element"),"element"===s.type&&s.getNode().is(this)&&s.set(i,s.offset,"element")}else r.insertBefore(t),this.remove();return!0}getValue(){return this.getLatest().__value}setValue(e){const t=this.getWritable();return t.__value=e,t}getChecked(){const e=this.getLatest();let t;const n=this.getParent();return A(n)&&(t=n.getListType()),"check"===t?Boolean(e.__checked):void 0}setChecked(e){const t=this.getWritable();return t.__checked=e,t}toggleChecked(){const e=this.getWritable();return e.setChecked(!e.__checked)}getIndent(){const e=this.getParent();if(null===e||!this.isAttached())return this.getLatest().__indent;let t=e.getParentOrThrow(),n=0;for(;O(t);)t=t.getParentOrThrow().getParentOrThrow(),n++;return n}setIndent(e){"number"!=typeof e&&s(117),(e=Math.floor(e))>=0||s(199);let t=this.getIndent();for(;t!==e;)t<e?(_(this),t++):(C(this),t--);return this}canInsertAfter(e){return O(e)}canReplaceWith(e){return O(e)}canMergeWith(e){return O(e)||n.$isParagraphNode(e)}extractWithChild(e,t){if(!n.$isRangeSelection(t))return!1;const r=t.anchor.getNode(),s=t.focus.getNode();return this.isParentOf(r)&&this.isParentOf(s)&&this.getTextContent().length===t.getTextContent().length}isParentRequired(){return!0}createParentElementNode(){return P("bullet")}canMergeWhenEmpty(){return!0}}function S(e){if(e.classList.contains("task-list-item"))for(const t of e.children)if("INPUT"===t.tagName)return y(t);if(e.classList.contains("joplin-checkbox"))for(const t of e.children)if(t.classList.contains("checkbox-wrapper")&&t.children.length>0&&"INPUT"===t.children[0].tagName)return y(t.children[0]);const t=e.getAttribute("aria-checked");return{node:x("true"===t||"false"!==t&&void 0)}}function y(e){if(!("checkbox"===e.getAttribute("type")))return{node:null};return{node:x(e.hasAttribute("checked"))}}function x(e){return n.$applyNodeReplacement(new T(void 0,e))}function O(e){return e instanceof T}class L extends n.ElementNode{__tag;__start;__listType;$config(){return this.config("list",{$transform:e=>{!function(e){const t=e.getNextSibling();A(t)&&e.getListType()===t.getListType()&&f(e,t)}(e),m(e)},extends:n.ElementNode,importDOM:n.buildImportMap({ol:()=>({conversion:E,priority:0}),ul:()=>({conversion:E,priority:0})})})}constructor(e="number",t=1,n){super(n);const r=k[e]||e;this.__listType=r,this.__tag="number"===r?"ol":"ul",this.__start=t}afterCloneFrom(e){super.afterCloneFrom(e),this.__listType=e.__listType,this.__tag=e.__tag,this.__start=e.__start}getTag(){return this.getLatest().__tag}setListType(e){const t=this.getWritable();return t.__listType=e,t.__tag="number"===e?"ol":"ul",t}getListType(){return this.getLatest().__listType}getStart(){return this.getLatest().__start}setStart(e){const t=this.getWritable();return t.__start=e,t}createDOM(e,t){const n=this.__tag,r=document.createElement(n);return 1!==this.__start&&r.setAttribute("start",String(this.__start)),r.__lexicalListType=this.__listType,v(r,e.theme,this),r}updateDOM(e,t,n){return e.__tag!==this.__tag||e.__listType!==this.__listType||(v(t,n.theme,this),!1)}updateFromJSON(e){return super.updateFromJSON(e).setListType(e.listType).setStart(e.start)}exportDOM(e){const n=this.createDOM(e._config,e);return t.isHTMLElement(n)&&(1!==this.__start&&n.setAttribute("start",String(this.__start)),"check"===this.__listType&&n.setAttribute("__lexicalListType","check")),{element:n}}exportJSON(){return{...super.exportJSON(),listType:this.getListType(),start:this.getStart(),tag:this.getTag()}}canBeEmpty(){return!1}canIndent(){return!1}splice(e,t,r){let s=r;for(let e=0;e<r.length;e++){const t=r[e];O(t)||(s===r&&(s=[...r]),s[e]=x().append(!n.$isElementNode(t)||A(t)||t.isInline()?t:n.$createTextNode(t.getTextContent())))}return super.splice(e,t,s)}extractWithChild(e){return O(e)}}function v(e,r,s){const o=[],l=[],c=r.list;if(void 0!==c){const e=c[`${s.__tag}Depth`]||[],t=i(s)-1,r=t%e.length,a=e[r],g=c[s.__tag];let d;const u=c.nested,h=c.checklist;if(void 0!==u&&u.list&&(d=u.list),void 0!==g&&o.push(g),void 0!==h&&"check"===s.__listType&&o.push(h),void 0!==a){o.push(...n.normalizeClassNames(a));for(let t=0;t<e.length;t++)t!==r&&l.push(s.__tag+t)}if(void 0!==d){const e=n.normalizeClassNames(d);t>1?o.push(...e):l.push(...e)}}l.length>0&&t.removeClassNamesFromElement(e,...l),o.length>0&&t.addClassNamesToElement(e,...o)}function M(e){const t=[];for(let n=0;n<e.length;n++){const r=e[n];if(O(r)){t.push(r);const e=r.getChildren();e.length>1&&e.forEach(e=>{A(e)&&t.push(a(e))})}else t.push(a(r))}return t}function E(e){const n=e.nodeName.toLowerCase();let r=null;if("ol"===n){r=P("number",e.start)}else"ul"===n&&(r=function(e){if("check"===e.getAttribute("__lexicallisttype")||e.classList.contains("contains-task-list")||"1"===e.getAttribute("data-is-checklist"))return!0;for(const n of e.childNodes)if(t.isHTMLElement(n)&&n.hasAttribute("aria-checked"))return!0;return!1}(e)?P("check"):P("bullet"));return{after:M,node:r}}const k={ol:"number",ul:"bullet"};function P(e="number",t=1){return n.$applyNodeReplacement(new L(e,t))}function A(e){return e instanceof L}const R=n.createCommand("INSERT_CHECK_LIST_COMMAND");function b(e){return t.mergeRegister(e.registerCommand(R,()=>(d("check"),!0),n.COMMAND_PRIORITY_LOW),e.registerCommand(n.KEY_ARROW_DOWN_COMMAND,t=>w(t,e,!1),n.COMMAND_PRIORITY_LOW),e.registerCommand(n.KEY_ARROW_UP_COMMAND,t=>w(t,e,!0),n.COMMAND_PRIORITY_LOW),e.registerCommand(n.KEY_ESCAPE_COMMAND,()=>{if(null!=D()){const t=e.getRootElement();return null!=t&&t.focus(),!0}return!1},n.COMMAND_PRIORITY_LOW),e.registerCommand(n.KEY_SPACE_COMMAND,t=>{const r=D();return!(null==r||!e.isEditable())&&(e.update(()=>{const e=n.$getNearestNodeFromDOMNode(r);O(e)&&(t.preventDefault(),e.toggleChecked())}),!0)},n.COMMAND_PRIORITY_LOW),e.registerCommand(n.KEY_ARROW_LEFT_COMMAND,r=>e.getEditorState().read(()=>{const s=n.$getSelection();if(n.$isRangeSelection(s)&&s.isCollapsed()){const{anchor:i}=s,o="element"===i.type;if(o||0===i.offset){const s=i.getNode(),l=t.$findMatchingParent(s,e=>n.$isElementNode(e)&&!e.isInline());if(O(l)){const t=l.getParent();if(A(t)&&"check"===t.getListType()&&(o||l.getFirstDescendant()===s)){const t=e.getElementByKey(l.__key);if(null!=t&&document.activeElement!==t)return t.focus(),r.preventDefault(),!0}}}}return!1}),n.COMMAND_PRIORITY_LOW),e.registerRootListener((e,t)=>{null!==e&&(e.addEventListener("click",F),e.addEventListener("pointerdown",$)),null!==t&&(t.removeEventListener("click",F),t.removeEventListener("pointerdown",$))}))}function I(e,n){const r=e.target;if(!t.isHTMLElement(r))return;const s=r.firstChild;if(t.isHTMLElement(s)&&("UL"===s.tagName||"OL"===s.tagName))return;const i=r.parentNode;if(!i||"check"!==i.__lexicalListType)return;const o=r.getBoundingClientRect(),l=t.calculateZoomLevel(r),c=e.clientX/l,a=window.getComputedStyle?window.getComputedStyle(r,"::before"):{width:"0px"},g=parseFloat(a.width),d="touch"===e.pointerType?32:0;("rtl"===r.dir?c<o.right+d&&c>o.right-g-d:c>o.left-d&&c<o.left+g+d)&&n()}function F(e){I(e,()=>{if(t.isHTMLElement(e.target)){const t=e.target,r=n.getNearestEditorFromDOMNode(t);null!=r&&r.isEditable()&&r.update(()=>{const e=n.$getNearestNodeFromDOMNode(t);O(e)&&(t.focus(),e.toggleChecked())})}})}function $(e){I(e,()=>{e.preventDefault()})}function D(){const e=document.activeElement;return t.isHTMLElement(e)&&"LI"===e.tagName&&null!=e.parentNode&&"check"===e.parentNode.__lexicalListType?e:null}function w(e,t,r){const s=D();return null!=s&&t.update(()=>{const i=n.$getNearestNodeFromDOMNode(s);if(!O(i))return;const o=function(e,t){let n=t?e.getPreviousSibling():e.getNextSibling(),r=e;for(;null==n&&O(r);)r=r.getParentOrThrow().getParent(),null!=r&&(n=t?r.getPreviousSibling():r.getNextSibling());for(;O(n);){const e=t?n.getLastChild():n.getFirstChild();if(!A(e))return n;n=t?e.getLastChild():e.getFirstChild()}return null}(i,r);if(null!=o){o.selectStart();const n=t.getElementByKey(o.__key);null!=n&&(e.preventDefault(),setTimeout(()=>{n.focus()},0))}}),!1}const W=n.createCommand("UPDATE_LIST_START_COMMAND"),K=n.createCommand("INSERT_UNORDERED_LIST_COMMAND"),z=n.createCommand("INSERT_ORDERED_LIST_COMMAND"),Y=n.createCommand("REMOVE_LIST_COMMAND");function B(e){return t.mergeRegister(e.registerCommand(z,()=>(d("number"),!0),n.COMMAND_PRIORITY_LOW),e.registerCommand(W,e=>{const{listNodeKey:t,newStart:r}=e,s=n.$getNodeByKey(t);return!!A(s)&&("number"===s.getListType()&&(s.setStart(r),m(s)),!0)},n.COMMAND_PRIORITY_LOW),e.registerCommand(K,()=>(d("bullet"),!0),n.COMMAND_PRIORITY_LOW),e.registerCommand(Y,()=>(p(),!0),n.COMMAND_PRIORITY_LOW),e.registerCommand(n.INSERT_PARAGRAPH_COMMAND,()=>N(),n.COMMAND_PRIORITY_LOW),e.registerNodeTransform(T,e=>{const t=e.getFirstChild();if(t){if(n.$isTextNode(t)){const n=t.getStyle(),r=t.getFormat();e.getTextStyle()!==n&&e.setTextStyle(n),e.getTextFormat()!==r&&e.setTextFormat(r)}}else{const t=n.$getSelection();n.$isRangeSelection(t)&&(t.style!==e.getTextStyle()||t.format!==e.getTextFormat())&&t.isCollapsed()&&e.is(t.anchor.getNode())&&e.setTextStyle(t.style).setTextFormat(t.format)}}),e.registerNodeTransform(n.TextNode,e=>{const t=e.getParent();if(O(t)&&e.is(t.getFirstChild())){const n=e.getStyle(),r=e.getFormat();n===t.getTextStyle()&&r===t.getTextFormat()||t.setTextStyle(n).setTextFormat(r)}}))}function U(e){const n=e=>{const n=e.getParent();if(A(e.getFirstChild())||!A(n))return;const r=t.$findMatchingParent(e,e=>O(e)&&A(e.getParent())&&O(e.getPreviousSibling()));if(null===r&&e.getIndent()>0)e.setIndent(0);else if(O(r)){const t=r.getPreviousSibling();if(O(t)){const r=function(e){let t=e,n=t.getFirstChild();for(;A(n);){const e=n.getLastChild();if(!O(e))break;t=e,n=t.getFirstChild()}return t}(t),s=r.getParent();if(A(s)){const t=i(s);t+1<i(n)&&e.setIndent(t)}}}};return e.registerNodeTransform(L,e=>{const t=[e];for(;t.length>0;){const e=t.shift();if(A(e))for(const r of e.getChildren())if(O(r)){n(r);const e=r.getFirstChild();A(e)&&t.push(e)}}})}const J=n.defineExtension({build:(t,n,r)=>e.namedSignals(n),config:n.safeCast({hasStrictIndent:!1}),name:"@ekz/lexical-list/List",nodes:()=>[L,T],register(n,r,s){const i=s.getOutput();return t.mergeRegister(B(n),e.effect(()=>i.hasStrictIndent.value?U(n):void 0))}}),H=n.defineExtension({dependencies:[J],name:"@ekz/lexical-list/CheckList",register:b});exports.$createListItemNode=x,exports.$createListNode=P,exports.$getListDepth=i,exports.$handleListInsertParagraph=N,exports.$insertList=d,exports.$isListItemNode=O,exports.$isListNode=A,exports.$removeList=p,exports.CheckListExtension=H,exports.INSERT_CHECK_LIST_COMMAND=R,exports.INSERT_ORDERED_LIST_COMMAND=z,exports.INSERT_UNORDERED_LIST_COMMAND=K,exports.ListExtension=J,exports.ListItemNode=T,exports.ListNode=L,exports.REMOVE_LIST_COMMAND=Y,exports.UPDATE_LIST_START_COMMAND=W,exports.insertList=function(e,t){e.update(()=>d(t))},exports.registerCheckList=b,exports.registerList=B,exports.registerListStrictIndentTransform=U,exports.removeList=function(e){e.update(()=>p())};
@@ -0,0 +1,9 @@
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
+
9
+ import{effect as e,namedSignals as t}from"@ekz/lexical-extension";import{$getNearestNodeOfType as n,removeClassNamesFromElement as r,addClassNamesToElement as i,isHTMLElement as s,mergeRegister as o,$findMatchingParent as l,calculateZoomLevel as c}from"@ekz/lexical-utils";import{$getSelection as a,$isRangeSelection as g,$isRootOrShadowRoot as u,$createParagraphNode as h,$isElementNode as d,$isLeafNode as f,$setPointFromCaret as p,$normalizeCaret as m,$getChildCaret as _,$isTextNode as y,ElementNode as C,buildImportMap as T,$isParagraphNode as v,$applyNodeReplacement as S,normalizeClassNames as k,$createTextNode as x,createCommand as b,COMMAND_PRIORITY_LOW as L,KEY_ARROW_DOWN_COMMAND as N,KEY_ARROW_UP_COMMAND as P,KEY_ESCAPE_COMMAND as F,KEY_SPACE_COMMAND as O,$getNearestNodeFromDOMNode as A,KEY_ARROW_LEFT_COMMAND as E,getNearestEditorFromDOMNode as I,defineExtension as w,safeCast as D,$getNodeByKey as M,INSERT_PARAGRAPH_COMMAND as R,TextNode as K}from"@ekz/lexical";import{getStyleObjectFromCSS as B}from"@ekz/lexical-selection";function z(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function W(e){let t=1,n=e.getParent();for(;null!=n;){if(oe(n)){const e=n.getParent();if(de(e)){t++,n=e.getParent();continue}z(40)}return t}return t}function J(e){let t=e.getParent();de(t)||z(40);let n=t;for(;null!==n;)n=n.getParent(),de(n)&&(t=n);return t}function U(e){let t=[];const n=e.getChildren().filter(oe);for(let e=0;e<n.length;e++){const r=n[e],i=r.getFirstChild();de(i)?t=t.concat(U(i)):t.push(r)}return t}function $(e){return oe(e)&&de(e.getFirstChild())}function V(e){return se().append(e)}function j(e,t){return oe(e)&&(0===t.length||1===t.length&&e.is(t[0])&&0===e.getChildrenSize())}function q(e){const t=a();if(null!==t){let n=t.getNodes();if(g(t)){const r=t.getStartEndPoints();null===r&&z(143);const[i]=r,s=i.getNode(),o=s.getParent();if(u(s)){const e=s.getFirstChild();if(e)n=e.selectStart().getNodes();else{const e=h();s.append(e),n=e.select().getNodes()}}else if(j(s,n)){const t=he(e);if(u(o)){s.replace(t);const e=se();d(s)&&(e.setFormat(s.getFormatType()),e.setIndent(s.getIndent())),t.append(e)}else if(oe(s)){const e=s.getParentOrThrow();H(t,e.getChildren()),e.replace(t)}return}}const r=new Set;for(let t=0;t<n.length;t++){const i=n[t];if(d(i)&&i.isEmpty()&&!oe(i)&&!r.has(i.getKey())){X(i,e);continue}let s=f(i)?i.getParent():oe(i)&&i.isEmpty()?i:null;for(;null!=s;){const t=s.getKey();if(de(s)){if(!r.has(t)){const n=he(e);H(n,s.getChildren()),s.replace(n),r.add(t)}break}{const n=s.getParent();if(u(n)&&!r.has(t)){r.add(t),X(s,e);break}s=n}}}}}function H(e,t){e.splice(e.getChildrenSize(),0,t)}function X(e,t){if(de(e))return e;const n=e.getPreviousSibling(),r=e.getNextSibling(),i=se();let s;if(H(i,e.getChildren()),de(n)&&t===n.getListType())n.append(i),de(r)&&t===r.getListType()&&(H(n,r.getChildren()),r.remove()),s=n;else if(de(r)&&t===r.getListType())r.getFirstChildOrThrow().insertBefore(i),s=r;else{const n=he(t);n.append(i),e.replace(n),s=n}i.setFormat(e.getFormatType()),i.setIndent(e.getIndent());const o=a();return g(o)&&(s.getKey()===o.anchor.key&&o.anchor.set(i.getKey(),o.anchor.offset,"element"),s.getKey()===o.focus.key&&o.focus.set(i.getKey(),o.focus.offset,"element")),e.remove(),s}function G(e,t){const n=e.getLastChild(),r=t.getFirstChild();n&&r&&$(n)&&$(r)&&(G(n.getFirstChild(),r.getFirstChild()),r.remove());const i=t.getChildren();i.length>0&&e.append(...i),t.remove()}function Q(){const e=a();if(g(e)){const t=new Set,r=e.getNodes(),i=e.anchor.getNode();if(j(i,r))t.add(J(i));else for(let e=0;e<r.length;e++){const i=r[e];if(f(i)){const e=n(i,ne);null!=e&&t.add(J(e))}}for(const n of t){let t=n;const r=U(n);for(const n of r){const r=h().setTextStyle(e.style).setTextFormat(e.format);H(r,n.getChildren()),t.insertAfter(r),t=r,n.__key===e.anchor.key&&p(e.anchor,m(_(r,"next"))),n.__key===e.focus.key&&p(e.focus,m(_(r,"next"))),n.remove()}n.remove()}}}function Y(e){const t="check"!==e.getListType();let n=e.getStart();for(const r of e.getChildren())oe(r)&&(r.getValue()!==n&&r.setValue(n),t&&null!=r.getLatest().__checked&&r.setChecked(void 0),de(r.getFirstChild())||n++)}function Z(e){const t=new Set;if($(e)||t.has(e.getKey()))return;const n=e.getParent(),r=e.getNextSibling(),i=e.getPreviousSibling();if($(r)&&$(i)){const n=i.getFirstChild();if(de(n)){n.append(e);const i=r.getFirstChild();if(de(i)){H(n,i.getChildren()),r.remove(),t.add(r.getKey())}}}else if($(r)){const t=r.getFirstChild();if(de(t)){const n=t.getFirstChild();null!==n&&n.insertBefore(e)}}else if($(i)){const t=i.getFirstChild();de(t)&&t.append(e)}else if(de(n)){const t=se().setTextFormat(e.getTextFormat()).setTextStyle(e.getTextStyle()),s=he(n.getListType()).setTextFormat(n.getTextFormat()).setTextStyle(n.getTextStyle());t.append(s),s.append(e),i?i.insertAfter(t):r?r.insertBefore(t):n.append(t)}}function ee(e){if($(e))return;const t=e.getParent(),n=t?t.getParent():void 0;if(de(n?n.getParent():void 0)&&oe(n)&&de(t)){const r=t?t.getFirstChild():void 0,i=t?t.getLastChild():void 0;if(e.is(r))n.insertBefore(e),t.isEmpty()&&n.remove();else if(e.is(i))n.insertAfter(e),t.isEmpty()&&n.remove();else{const r=t.getListType(),i=se(),s=he(r);i.append(s),e.getPreviousSiblings().forEach(e=>s.append(e));const o=se(),l=he(r);o.append(l),H(l,e.getNextSiblings()),n.insertBefore(i),n.insertAfter(o),n.replace(e)}}}function te(){const e=a();if(!g(e)||!e.isCollapsed())return!1;const t=e.anchor.getNode();let n=null;if(oe(t)&&0===t.getChildrenSize())n=t;else if(y(t)){const e=t.getParent();oe(e)&&e.getChildren().every(e=>y(e)&&""===e.getTextContent().trim())&&(n=e)}if(null===n)return!1;const r=J(n),i=n.getParent();de(i)||z(40);const s=i.getParent();let o;if(u(s))o=h(),r.insertAfter(o);else{if(!oe(s))return!1;o=se(),s.insertAfter(o)}o.setTextStyle(e.style).setTextFormat(e.format).select();const l=n.getNextSiblings();if(l.length>0){const e=he(i.getListType());if(oe(o)){const t=se();t.append(e),o.insertAfter(t)}else o.insertAfter(e);e.append(...l)}return function(e){let t=e;for(;null==t.getNextSibling()&&null==t.getPreviousSibling();){const e=t.getParent();if(null==e||!oe(e)&&!de(e))break;t=e}t.remove()}(n),!0}class ne extends C{__value;__checked;$config(){return this.config("listitem",{$transform:e=>{if(null==e.__checked)return;const t=e.getParent();de(t)&&"check"!==t.getListType()&&null!=e.getChecked()&&e.setChecked(void 0)},extends:C,importDOM:T({li:()=>({conversion:re,priority:0})})})}constructor(e=1,t=void 0,n){super(n),this.__value=void 0===e?1:e,this.__checked=t}afterCloneFrom(e){super.afterCloneFrom(e),this.__value=e.__value,this.__checked=e.__checked}createDOM(e){const t=document.createElement("li");return this.updateListItemDOM(null,t,e),t}updateListItemDOM(e,t,n){!function(e,t,n){const r=t.getParent();!de(r)||"check"!==r.getListType()||de(t.getFirstChild())?(e.removeAttribute("role"),e.removeAttribute("tabIndex"),e.removeAttribute("aria-checked")):(e.setAttribute("role","checkbox"),e.setAttribute("tabIndex","-1"),n&&t.__checked===n.__checked||e.setAttribute("aria-checked",t.getChecked()?"true":"false"))}(t,this,e),t.value=this.__value,function(e,t,n){const s=[],o=[],l=t.list,c=l?l.listitem:void 0;let a;l&&l.nested&&(a=l.nested.listitem);void 0!==c&&s.push(...k(c));if(l){const e=n.getParent(),t=de(e)&&"check"===e.getListType(),r=n.getChecked();t&&!r||o.push(l.listitemUnchecked),t&&r||o.push(l.listitemChecked),t&&s.push(r?l.listitemChecked:l.listitemUnchecked)}if(void 0!==a){const e=k(a);n.getChildren().some(e=>de(e))?s.push(...e):o.push(...e)}o.length>0&&r(e,...o);s.length>0&&i(e,...s)}(t,n.theme,this);const s=e?e.__style:"",o=this.__style;s!==o&&(""===o?t.removeAttribute("style"):t.style.cssText=o),function(e,t,n){const r=B(t.__textStyle);for(const t in r)e.style.setProperty(`--listitem-marker-${t}`,r[t]);if(n)for(const t in B(n.__textStyle))t in r||e.style.removeProperty(`--listitem-marker-${t}`)}(t,this,e)}updateDOM(e,t,n){const r=t;return this.updateListItemDOM(e,r,n),!1}updateFromJSON(e){return super.updateFromJSON(e).setValue(e.value).setChecked(e.checked)}exportDOM(e){const t=this.createDOM(e._config),n=this.getFormatType();n&&(t.style.textAlign=n);const r=this.getDirection();return r&&(t.dir=r),{element:t}}exportJSON(){return{...super.exportJSON(),checked:this.getChecked(),value:this.getValue()}}append(...e){for(let t=0;t<e.length;t++){const n=e[t];if(d(n)&&this.canMergeWith(n)){const e=n.getChildren();this.append(...e),n.remove()}else super.append(n)}return this}replace(e,t){if(oe(e))return super.replace(e);this.setIndent(0);const n=this.getParentOrThrow();if(!de(n))return e;if(n.__first===this.getKey())n.insertBefore(e);else if(n.__last===this.getKey())n.insertAfter(e);else{const t=he(n.getListType());let r=this.getNextSibling();for(;r;){const e=r;r=r.getNextSibling(),t.append(e)}n.insertAfter(e),e.insertAfter(t)}return t&&(d(e)||z(139),this.getChildren().forEach(t=>{e.append(t)})),this.remove(),0===n.getChildrenSize()&&n.remove(),e}insertAfter(e,t=!0){const n=this.getParentOrThrow();if(de(n)||z(39),oe(e))return super.insertAfter(e,t);const r=this.getNextSiblings();if(n.insertAfter(e,t),0!==r.length){const i=he(n.getListType());r.forEach(e=>i.append(e)),e.insertAfter(i,t)}return e}remove(e){const t=this.getPreviousSibling(),n=this.getNextSibling();super.remove(e),t&&n&&$(t)&&$(n)&&(G(t.getFirstChild(),n.getFirstChild()),n.remove())}insertNewAfter(e,t=!0){const n=se().updateFromJSON(this.exportJSON()).setChecked(!this.getChecked()&&void 0);return this.insertAfter(n,t),n}collapseAtStart(e){const t=h();this.getChildren().forEach(e=>t.append(e));const n=this.getParentOrThrow(),r=n.getParentOrThrow(),i=oe(r);if(1===n.getChildrenSize())if(i)n.remove(),r.select();else{n.insertBefore(t),n.remove();const r=e.anchor,i=e.focus,s=t.getKey();"element"===r.type&&r.getNode().is(this)&&r.set(s,r.offset,"element"),"element"===i.type&&i.getNode().is(this)&&i.set(s,i.offset,"element")}else n.insertBefore(t),this.remove();return!0}getValue(){return this.getLatest().__value}setValue(e){const t=this.getWritable();return t.__value=e,t}getChecked(){const e=this.getLatest();let t;const n=this.getParent();return de(n)&&(t=n.getListType()),"check"===t?Boolean(e.__checked):void 0}setChecked(e){const t=this.getWritable();return t.__checked=e,t}toggleChecked(){const e=this.getWritable();return e.setChecked(!e.__checked)}getIndent(){const e=this.getParent();if(null===e||!this.isAttached())return this.getLatest().__indent;let t=e.getParentOrThrow(),n=0;for(;oe(t);)t=t.getParentOrThrow().getParentOrThrow(),n++;return n}setIndent(e){"number"!=typeof e&&z(117),(e=Math.floor(e))>=0||z(199);let t=this.getIndent();for(;t!==e;)t<e?(Z(this),t++):(ee(this),t--);return this}canInsertAfter(e){return oe(e)}canReplaceWith(e){return oe(e)}canMergeWith(e){return oe(e)||v(e)}extractWithChild(e,t){if(!g(t))return!1;const n=t.anchor.getNode(),r=t.focus.getNode();return this.isParentOf(n)&&this.isParentOf(r)&&this.getTextContent().length===t.getTextContent().length}isParentRequired(){return!0}createParentElementNode(){return he("bullet")}canMergeWhenEmpty(){return!0}}function re(e){if(e.classList.contains("task-list-item"))for(const t of e.children)if("INPUT"===t.tagName)return ie(t);if(e.classList.contains("joplin-checkbox"))for(const t of e.children)if(t.classList.contains("checkbox-wrapper")&&t.children.length>0&&"INPUT"===t.children[0].tagName)return ie(t.children[0]);const t=e.getAttribute("aria-checked");return{node:se("true"===t||"false"!==t&&void 0)}}function ie(e){if(!("checkbox"===e.getAttribute("type")))return{node:null};return{node:se(e.hasAttribute("checked"))}}function se(e){return S(new ne(void 0,e))}function oe(e){return e instanceof ne}class le extends C{__tag;__start;__listType;$config(){return this.config("list",{$transform:e=>{!function(e){const t=e.getNextSibling();de(t)&&e.getListType()===t.getListType()&&G(e,t)}(e),Y(e)},extends:C,importDOM:T({ol:()=>({conversion:ge,priority:0}),ul:()=>({conversion:ge,priority:0})})})}constructor(e="number",t=1,n){super(n);const r=ue[e]||e;this.__listType=r,this.__tag="number"===r?"ol":"ul",this.__start=t}afterCloneFrom(e){super.afterCloneFrom(e),this.__listType=e.__listType,this.__tag=e.__tag,this.__start=e.__start}getTag(){return this.getLatest().__tag}setListType(e){const t=this.getWritable();return t.__listType=e,t.__tag="number"===e?"ol":"ul",t}getListType(){return this.getLatest().__listType}getStart(){return this.getLatest().__start}setStart(e){const t=this.getWritable();return t.__start=e,t}createDOM(e,t){const n=this.__tag,r=document.createElement(n);return 1!==this.__start&&r.setAttribute("start",String(this.__start)),r.__lexicalListType=this.__listType,ce(r,e.theme,this),r}updateDOM(e,t,n){return e.__tag!==this.__tag||e.__listType!==this.__listType||(ce(t,n.theme,this),!1)}updateFromJSON(e){return super.updateFromJSON(e).setListType(e.listType).setStart(e.start)}exportDOM(e){const t=this.createDOM(e._config,e);return s(t)&&(1!==this.__start&&t.setAttribute("start",String(this.__start)),"check"===this.__listType&&t.setAttribute("__lexicalListType","check")),{element:t}}exportJSON(){return{...super.exportJSON(),listType:this.getListType(),start:this.getStart(),tag:this.getTag()}}canBeEmpty(){return!1}canIndent(){return!1}splice(e,t,n){let r=n;for(let e=0;e<n.length;e++){const t=n[e];oe(t)||(r===n&&(r=[...n]),r[e]=se().append(!d(t)||de(t)||t.isInline()?t:x(t.getTextContent())))}return super.splice(e,t,r)}extractWithChild(e){return oe(e)}}function ce(e,t,n){const s=[],o=[],l=t.list;if(void 0!==l){const e=l[`${n.__tag}Depth`]||[],t=W(n)-1,r=t%e.length,i=e[r],c=l[n.__tag];let a;const g=l.nested,u=l.checklist;if(void 0!==g&&g.list&&(a=g.list),void 0!==c&&s.push(c),void 0!==u&&"check"===n.__listType&&s.push(u),void 0!==i){s.push(...k(i));for(let t=0;t<e.length;t++)t!==r&&o.push(n.__tag+t)}if(void 0!==a){const e=k(a);t>1?s.push(...e):o.push(...e)}}o.length>0&&r(e,...o),s.length>0&&i(e,...s)}function ae(e){const t=[];for(let n=0;n<e.length;n++){const r=e[n];if(oe(r)){t.push(r);const e=r.getChildren();e.length>1&&e.forEach(e=>{de(e)&&t.push(V(e))})}else t.push(V(r))}return t}function ge(e){const t=e.nodeName.toLowerCase();let n=null;if("ol"===t){n=he("number",e.start)}else"ul"===t&&(n=function(e){if("check"===e.getAttribute("__lexicallisttype")||e.classList.contains("contains-task-list")||"1"===e.getAttribute("data-is-checklist"))return!0;for(const t of e.childNodes)if(s(t)&&t.hasAttribute("aria-checked"))return!0;return!1}(e)?he("check"):he("bullet"));return{after:ae,node:n}}const ue={ol:"number",ul:"bullet"};function he(e="number",t=1){return S(new le(e,t))}function de(e){return e instanceof le}const fe=b("INSERT_CHECK_LIST_COMMAND");function pe(e){return o(e.registerCommand(fe,()=>(q("check"),!0),L),e.registerCommand(N,t=>Te(t,e,!1),L),e.registerCommand(P,t=>Te(t,e,!0),L),e.registerCommand(F,()=>{if(null!=Ce()){const t=e.getRootElement();return null!=t&&t.focus(),!0}return!1},L),e.registerCommand(O,t=>{const n=Ce();return!(null==n||!e.isEditable())&&(e.update(()=>{const e=A(n);oe(e)&&(t.preventDefault(),e.toggleChecked())}),!0)},L),e.registerCommand(E,t=>e.getEditorState().read(()=>{const n=a();if(g(n)&&n.isCollapsed()){const{anchor:r}=n,i="element"===r.type;if(i||0===r.offset){const n=r.getNode(),s=l(n,e=>d(e)&&!e.isInline());if(oe(s)){const r=s.getParent();if(de(r)&&"check"===r.getListType()&&(i||s.getFirstDescendant()===n)){const n=e.getElementByKey(s.__key);if(null!=n&&document.activeElement!==n)return n.focus(),t.preventDefault(),!0}}}}return!1}),L),e.registerRootListener((e,t)=>{null!==e&&(e.addEventListener("click",_e),e.addEventListener("pointerdown",ye)),null!==t&&(t.removeEventListener("click",_e),t.removeEventListener("pointerdown",ye))}))}function me(e,t){const n=e.target;if(!s(n))return;const r=n.firstChild;if(s(r)&&("UL"===r.tagName||"OL"===r.tagName))return;const i=n.parentNode;if(!i||"check"!==i.__lexicalListType)return;const o=n.getBoundingClientRect(),l=c(n),a=e.clientX/l,g=window.getComputedStyle?window.getComputedStyle(n,"::before"):{width:"0px"},u=parseFloat(g.width),h="touch"===e.pointerType?32:0;("rtl"===n.dir?a<o.right+h&&a>o.right-u-h:a>o.left-h&&a<o.left+u+h)&&t()}function _e(e){me(e,()=>{if(s(e.target)){const t=e.target,n=I(t);null!=n&&n.isEditable()&&n.update(()=>{const e=A(t);oe(e)&&(t.focus(),e.toggleChecked())})}})}function ye(e){me(e,()=>{e.preventDefault()})}function Ce(){const e=document.activeElement;return s(e)&&"LI"===e.tagName&&null!=e.parentNode&&"check"===e.parentNode.__lexicalListType?e:null}function Te(e,t,n){const r=Ce();return null!=r&&t.update(()=>{const i=A(r);if(!oe(i))return;const s=function(e,t){let n=t?e.getPreviousSibling():e.getNextSibling(),r=e;for(;null==n&&oe(r);)r=r.getParentOrThrow().getParent(),null!=r&&(n=t?r.getPreviousSibling():r.getNextSibling());for(;oe(n);){const e=t?n.getLastChild():n.getFirstChild();if(!de(e))return n;n=t?e.getLastChild():e.getFirstChild()}return null}(i,n);if(null!=s){s.selectStart();const n=t.getElementByKey(s.__key);null!=n&&(e.preventDefault(),setTimeout(()=>{n.focus()},0))}}),!1}const ve=b("UPDATE_LIST_START_COMMAND"),Se=b("INSERT_UNORDERED_LIST_COMMAND"),ke=b("INSERT_ORDERED_LIST_COMMAND"),xe=b("REMOVE_LIST_COMMAND");function be(e){return o(e.registerCommand(ke,()=>(q("number"),!0),L),e.registerCommand(ve,e=>{const{listNodeKey:t,newStart:n}=e,r=M(t);return!!de(r)&&("number"===r.getListType()&&(r.setStart(n),Y(r)),!0)},L),e.registerCommand(Se,()=>(q("bullet"),!0),L),e.registerCommand(xe,()=>(Q(),!0),L),e.registerCommand(R,()=>te(),L),e.registerNodeTransform(ne,e=>{const t=e.getFirstChild();if(t){if(y(t)){const n=t.getStyle(),r=t.getFormat();e.getTextStyle()!==n&&e.setTextStyle(n),e.getTextFormat()!==r&&e.setTextFormat(r)}}else{const t=a();g(t)&&(t.style!==e.getTextStyle()||t.format!==e.getTextFormat())&&t.isCollapsed()&&e.is(t.anchor.getNode())&&e.setTextStyle(t.style).setTextFormat(t.format)}}),e.registerNodeTransform(K,e=>{const t=e.getParent();if(oe(t)&&e.is(t.getFirstChild())){const n=e.getStyle(),r=e.getFormat();n===t.getTextStyle()&&r===t.getTextFormat()||t.setTextStyle(n).setTextFormat(r)}}))}function Le(e){const t=e=>{const t=e.getParent();if(de(e.getFirstChild())||!de(t))return;const n=l(e,e=>oe(e)&&de(e.getParent())&&oe(e.getPreviousSibling()));if(null===n&&e.getIndent()>0)e.setIndent(0);else if(oe(n)){const r=n.getPreviousSibling();if(oe(r)){const n=function(e){let t=e,n=t.getFirstChild();for(;de(n);){const e=n.getLastChild();if(!oe(e))break;t=e,n=t.getFirstChild()}return t}(r),i=n.getParent();if(de(i)){const n=W(i);n+1<W(t)&&e.setIndent(n)}}}};return e.registerNodeTransform(le,e=>{const n=[e];for(;n.length>0;){const e=n.shift();if(de(e))for(const r of e.getChildren())if(oe(r)){t(r);const e=r.getFirstChild();de(e)&&n.push(e)}}})}function Ne(e,t){e.update(()=>q(t))}function Pe(e){e.update(()=>Q())}const Fe=w({build:(e,n,r)=>t(n),config:D({hasStrictIndent:!1}),name:"@ekz/lexical-list/List",nodes:()=>[le,ne],register(t,n,r){const i=r.getOutput();return o(be(t),e(()=>i.hasStrictIndent.value?Le(t):void 0))}}),Oe=w({dependencies:[Fe],name:"@ekz/lexical-list/CheckList",register:pe});export{se as $createListItemNode,he as $createListNode,W as $getListDepth,te as $handleListInsertParagraph,q as $insertList,oe as $isListItemNode,de as $isListNode,Q as $removeList,Oe as CheckListExtension,fe as INSERT_CHECK_LIST_COMMAND,ke as INSERT_ORDERED_LIST_COMMAND,Se as INSERT_UNORDERED_LIST_COMMAND,Fe as ListExtension,ne as ListItemNode,le as ListNode,xe as REMOVE_LIST_COMMAND,ve as UPDATE_LIST_START_COMMAND,Ne as insertList,pe as registerCheckList,be as registerList,Le as registerListStrictIndentTransform,Pe as removeList};
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Meta Platforms, Inc. and affiliates.
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.
@@ -0,0 +1,118 @@
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
+ * @flow strict
8
+ */
9
+
10
+ import type {
11
+ NodeKey,
12
+ LexicalNode,
13
+ LexicalEditor,
14
+ ParagraphNode,
15
+ RangeSelection,
16
+ LexicalCommand,
17
+ SerializedElementNode,
18
+ LexicalExtension,
19
+ ExtensionConfigBase,
20
+ } from '@ekz/lexical';
21
+ import type {NamedSignalsOutput} from '@ekz/lexical-extension';
22
+ import {ElementNode} from '@ekz/lexical';
23
+
24
+ export type ListNodeTagType = 'ul' | 'ol';
25
+ export type ListType = 'number' | 'bullet' | 'check';
26
+ declare export function $createListItemNode(
27
+ checked?: boolean | void,
28
+ ): ListItemNode;
29
+ declare export function $createListNode(
30
+ listType: ListType,
31
+ start?: number,
32
+ ): ListNode;
33
+ declare export function $getListDepth(listNode: ListNode): number;
34
+ declare export function $handleListInsertParagraph(): boolean;
35
+ declare export function $isListItemNode(
36
+ node: ?LexicalNode,
37
+ ): node is ListItemNode;
38
+ declare export function $isListNode(
39
+ node: ?LexicalNode,
40
+ ): node is ListNode;
41
+ declare export function indentList(): void;
42
+ declare export function $insertList(
43
+ listType: ListType,
44
+ ): void;
45
+ /** @deprecated use {@link $insertList} from an update or command listener */
46
+ declare export function insertList(
47
+ editor: LexicalEditor,
48
+ listType: ListType,
49
+ ): void;
50
+ declare export class ListItemNode extends ElementNode {
51
+ append(...nodes: LexicalNode[]): this;
52
+ replace<N: LexicalNode>(replaceWithNode: N): N;
53
+ insertAfter(node: LexicalNode, restoreSelection?: boolean): LexicalNode;
54
+ insertNewAfter(
55
+ selection: RangeSelection,
56
+ restoreSelection?: boolean,
57
+ ): ListItemNode | ParagraphNode;
58
+ collapseAtStart(selection: RangeSelection): true;
59
+ getIndent(): number;
60
+ setIndent(indent: number): this;
61
+ insertBefore(nodeToInsert: LexicalNode): LexicalNode;
62
+ canInsertAfter(node: LexicalNode): boolean;
63
+ canReplaceWith(replacement: LexicalNode): boolean;
64
+ canMergeWith(node: LexicalNode): boolean;
65
+ getValue(): number;
66
+ setValue(value: number): void;
67
+ getChecked(): boolean | void;
68
+ setChecked(boolean): this;
69
+ toggleChecked(): void;
70
+ static importJSON(serializedNode: SerializedListItemNode): ListItemNode;
71
+ }
72
+ declare export class ListNode extends ElementNode {
73
+ __tag: ListNodeTagType;
74
+ __start: number;
75
+ canBeEmpty(): false;
76
+ append(...nodesToAppend: LexicalNode[]): this;
77
+ getTag(): ListNodeTagType;
78
+ getStart(): number;
79
+ getListType(): ListType;
80
+ static importJSON(serializedNode: SerializedListNode): ListNode;
81
+ }
82
+ declare export function outdentList(): void;
83
+ /** @deprecated use {@link $removeList} from an update or command listener */
84
+ declare export function removeList(editor: LexicalEditor): void;
85
+ declare export function $removeList(): void;
86
+
87
+ declare export var INSERT_UNORDERED_LIST_COMMAND: LexicalCommand<void>;
88
+ declare export var INSERT_ORDERED_LIST_COMMAND: LexicalCommand<void>;
89
+ declare export var INSERT_CHECK_LIST_COMMAND: LexicalCommand<void>;
90
+ declare export var REMOVE_LIST_COMMAND: LexicalCommand<void>;
91
+
92
+ export type SerializedListItemNode = SerializedElementNode & {
93
+ checked: boolean | void,
94
+ value: number,
95
+ };
96
+
97
+ export type SerializedListNode = SerializedElementNode & {
98
+ listType: ListType,
99
+ start: number,
100
+ tag: ListNodeTagType,
101
+ };
102
+
103
+ declare export function registerListStrictIndentTransform(
104
+ editor: LexicalEditor,
105
+ ): () => void;
106
+
107
+ declare export function registerCheckList(editor: LexicalEditor): () => void;
108
+
109
+ declare export var UPDATE_LIST_START_COMMAND: LexicalCommand<{
110
+ listNodeKey: NodeKey;
111
+ newStart: number;
112
+ }>
113
+
114
+ export type ListConfig = {
115
+ hasStrictIndent: boolean;
116
+ };
117
+ declare export var ListExtension: LexicalExtension<ListConfig, "@ekz/lexical-list/List", NamedSignalsOutput<ListConfig>, void>;
118
+ declare export var CheckListExtension: LexicalExtension<ExtensionConfigBase, "@ekz/lexical-list/CheckList", void, void>;
@@ -0,0 +1,68 @@
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 type { BaseSelection, DOMExportOutput, EditorConfig, LexicalNode, LexicalUpdateJSON, NodeKey, ParagraphNode, RangeSelection, SerializedElementNode, Spread } from '@ekz/lexical';
9
+ import { ElementNode, LexicalEditor } from '@ekz/lexical';
10
+ export type SerializedListItemNode = Spread<{
11
+ checked: boolean | undefined;
12
+ value: number;
13
+ }, SerializedElementNode>;
14
+ /** @noInheritDoc */
15
+ export declare class ListItemNode extends ElementNode {
16
+ /** @internal */
17
+ __value: number;
18
+ /** @internal */
19
+ __checked?: boolean;
20
+ /** @internal */
21
+ $config(): import("@ekz/lexical").StaticNodeConfigRecord<"listitem", {
22
+ $transform: (node: ListItemNode) => void;
23
+ extends: typeof ElementNode;
24
+ importDOM: import("@ekz/lexical").DOMConversionMap<HTMLElement>;
25
+ }>;
26
+ constructor(value?: number, checked?: undefined | boolean, key?: NodeKey);
27
+ afterCloneFrom(prevNode: this): void;
28
+ createDOM(config: EditorConfig): HTMLElement;
29
+ updateListItemDOM(prevNode: ListItemNode | null, dom: HTMLLIElement, config: EditorConfig): void;
30
+ updateDOM(prevNode: ListItemNode, dom: HTMLElement, config: EditorConfig): boolean;
31
+ updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedListItemNode>): this;
32
+ exportDOM(editor: LexicalEditor): DOMExportOutput;
33
+ exportJSON(): SerializedListItemNode;
34
+ append(...nodes: LexicalNode[]): this;
35
+ replace<N extends LexicalNode>(replaceWithNode: N, includeChildren?: boolean): N;
36
+ insertAfter(node: LexicalNode, restoreSelection?: boolean): LexicalNode;
37
+ remove(preserveEmptyParent?: boolean): void;
38
+ insertNewAfter(_: RangeSelection, restoreSelection?: boolean): ListItemNode | ParagraphNode;
39
+ collapseAtStart(selection: RangeSelection): true;
40
+ getValue(): number;
41
+ setValue(value: number): this;
42
+ getChecked(): boolean | undefined;
43
+ setChecked(checked?: boolean): this;
44
+ toggleChecked(): this;
45
+ getIndent(): number;
46
+ setIndent(indent: number): this;
47
+ /** @deprecated @internal */
48
+ canInsertAfter(node: LexicalNode): boolean;
49
+ /** @deprecated @internal */
50
+ canReplaceWith(replacement: LexicalNode): boolean;
51
+ canMergeWith(node: LexicalNode): boolean;
52
+ extractWithChild(child: LexicalNode, selection: BaseSelection): boolean;
53
+ isParentRequired(): true;
54
+ createParentElementNode(): ElementNode;
55
+ canMergeWhenEmpty(): true;
56
+ }
57
+ /**
58
+ * Creates a new List Item node, passing true/false will convert it to a checkbox input.
59
+ * @param checked - Is the List Item a checkbox and, if so, is it checked? undefined/null: not a checkbox, true/false is a checkbox and checked/unchecked, respectively.
60
+ * @returns The new List Item.
61
+ */
62
+ export declare function $createListItemNode(checked?: boolean): ListItemNode;
63
+ /**
64
+ * Checks to see if the node is a ListItemNode.
65
+ * @param node - The node to be checked.
66
+ * @returns true if the node is a ListItemNode, false otherwise.
67
+ */
68
+ export declare function $isListItemNode(node: LexicalNode | null | undefined): node is ListItemNode;
@@ -0,0 +1,59 @@
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 { DOMExportOutput, EditorConfig, ElementNode, LexicalEditor, LexicalNode, LexicalUpdateJSON, NodeKey, SerializedElementNode, Spread } from '@ekz/lexical';
9
+ export type SerializedListNode = Spread<{
10
+ listType: ListType;
11
+ start: number;
12
+ tag: ListNodeTagType;
13
+ }, SerializedElementNode>;
14
+ export type ListType = 'number' | 'bullet' | 'check';
15
+ export type ListNodeTagType = 'ul' | 'ol';
16
+ /** @noInheritDoc */
17
+ export declare class ListNode extends ElementNode {
18
+ /** @internal */
19
+ __tag: ListNodeTagType;
20
+ /** @internal */
21
+ __start: number;
22
+ /** @internal */
23
+ __listType: ListType;
24
+ /** @internal */
25
+ $config(): import("@ekz/lexical").StaticNodeConfigRecord<"list", {
26
+ $transform: (node: ListNode) => void;
27
+ extends: typeof ElementNode;
28
+ importDOM: import("@ekz/lexical").DOMConversionMap<HTMLElement>;
29
+ }>;
30
+ constructor(listType?: ListType, start?: number, key?: NodeKey);
31
+ afterCloneFrom(prevNode: this): void;
32
+ getTag(): ListNodeTagType;
33
+ setListType(type: ListType): this;
34
+ getListType(): ListType;
35
+ getStart(): number;
36
+ setStart(start: number): this;
37
+ createDOM(config: EditorConfig, _editor?: LexicalEditor): HTMLElement;
38
+ updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean;
39
+ updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedListNode>): this;
40
+ exportDOM(editor: LexicalEditor): DOMExportOutput;
41
+ exportJSON(): SerializedListNode;
42
+ canBeEmpty(): false;
43
+ canIndent(): false;
44
+ splice(start: number, deleteCount: number, nodesToInsert: LexicalNode[]): this;
45
+ extractWithChild(child: LexicalNode): boolean;
46
+ }
47
+ /**
48
+ * Creates a ListNode of listType.
49
+ * @param listType - The type of list to be created. Can be 'number', 'bullet', or 'check'.
50
+ * @param start - Where an ordered list starts its count, start = 1 if left undefined.
51
+ * @returns The new ListNode
52
+ */
53
+ export declare function $createListNode(listType?: ListType, start?: number): ListNode;
54
+ /**
55
+ * Checks to see if the node is a ListNode.
56
+ * @param node - The node to be checked.
57
+ * @returns true if the node is a ListNode, false otherwise.
58
+ */
59
+ export declare function $isListNode(node: LexicalNode | null | undefined): node is ListNode;
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # `@lexical/list`
2
+
3
+ [![See API Documentation](https://lexical.dev/img/see-api-documentation.svg)](https://lexical.dev/docs/api/modules/lexical_list)
4
+
5
+ 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
6
+ 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.
7
+
8
+ 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:
9
+
10
+ ## Functions
11
+
12
+ ### $insertList
13
+
14
+ 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
15
+ 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.
16
+
17
+ ### $removeList
18
+
19
+ 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.
20
+
21
+ ## Nodes
22
+
23
+ ### ListNode
24
+
25
+ ### ListItemNode
26
+
27
+ ## Commands
28
+
29
+ For convenience, we provide a set of commands that can be used to connect a plugin to trigger typical list manipulation functionality:
30
+
31
+ ### INSERT_UNORDERED_LIST_COMMAND
32
+
33
+ ### INSERT_ORDERED_LIST_COMMAND
34
+
35
+ ### INSERT_CHECK_LIST_COMMAND
36
+
37
+ ### REMOVE_LIST_COMMAND
38
+
39
+ 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:
40
+
41
+
42
+ ```ts
43
+ // MyListPlugin.ts
44
+
45
+ editor.registerCommand(INSERT_UNORDERED_LIST_COMMAND, () => {
46
+ $insertList(editor, 'bullet');
47
+ return true;
48
+ }, COMMAND_PRIORITY_LOW);
49
+
50
+ // MyInsertListToolbarButton.ts
51
+
52
+ function onButtonClick(e: MouseEvent) {
53
+ editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);
54
+ }
55
+
56
+ ```
57
+
58
+ ## Theming
59
+
60
+ Lists can be styled using the following properties in the EditorTheme passed to the editor in the initial config (the values are classes that will be applied in the denoted contexts):
61
+
62
+ ```ts
63
+ {
64
+ list?: {
65
+ // Applies to all lists of type "bullet"
66
+ ul?: EditorThemeClassName;
67
+ // Used to apply specific styling to nested levels of bullet lists
68
+ // e.g., [ 'bullet-list-level-one', 'bullet-list-level-two' ]
69
+ ulDepth?: Array<EditorThemeClassName>;
70
+ // Applies to all lists of type "number"
71
+ ol?: EditorThemeClassName;
72
+ // Used to apply specific styling to nested levels of number lists
73
+ // e.g., [ 'number-list-level-one', 'number-list-level-two' ]
74
+ olDepth?: Array<EditorThemeClassName>;
75
+ // Applies to all list items
76
+ listitem?: EditorThemeClassName;
77
+ // Applies to all list items with checked property set to "true"
78
+ listitemChecked?: EditorThemeClassName;
79
+ // Applies to all list items with checked property set to "false"
80
+ listitemUnchecked?: EditorThemeClassName;
81
+ // Applies only to list and list items that are not at the top level.
82
+ nested?: {
83
+ list?: EditorThemeClassName;
84
+ listitem?: EditorThemeClassName;
85
+ };
86
+ };
87
+ }
88
+ ```
package/checkList.d.ts ADDED
@@ -0,0 +1,10 @@
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 type { LexicalCommand, LexicalEditor } from '@ekz/lexical';
9
+ export declare const INSERT_CHECK_LIST_COMMAND: LexicalCommand<void>;
10
+ export declare function registerCheckList(editor: LexicalEditor): () => void;
@@ -0,0 +1,70 @@
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 { ListItemNode, ListNode } from './';
9
+ import { ListType } from './LexicalListNode';
10
+ /**
11
+ * Inserts a new ListNode. If the selection's anchor node is an empty ListItemNode and is a child of
12
+ * the root/shadow root, it will replace the ListItemNode with a ListNode and the old ListItemNode.
13
+ * Otherwise it will replace its parent with a new ListNode and re-insert the ListItemNode and any previous children.
14
+ * If the selection's anchor node is not an empty ListItemNode, it will add a new ListNode or merge an existing ListNode,
15
+ * unless the the node is a leaf node, in which case it will attempt to find a ListNode up the branch and replace it with
16
+ * a new ListNode, or create a new ListNode at the nearest root/shadow root.
17
+ * @param listType - The type of list, "number" | "bullet" | "check".
18
+ */
19
+ export declare function $insertList(listType: ListType): void;
20
+ /**
21
+ * A recursive function that goes through each list and their children, including nested lists,
22
+ * appending list2 children after list1 children and updating ListItemNode values.
23
+ * @param list1 - The first list to be merged.
24
+ * @param list2 - The second list to be merged.
25
+ */
26
+ export declare function mergeLists(list1: ListNode, list2: ListNode): void;
27
+ /**
28
+ * Searches for the nearest ancestral ListNode and removes it. If selection is an empty ListItemNode
29
+ * it will remove the whole list, including the ListItemNode. For each ListItemNode in the ListNode,
30
+ * removeList will also generate new ParagraphNodes in the removed ListNode's place. Any child node
31
+ * inside a ListItemNode will be appended to the new ParagraphNodes.
32
+ */
33
+ export declare function $removeList(): void;
34
+ /**
35
+ * Takes the value of a child ListItemNode and makes it the value the ListItemNode
36
+ * should be if it isn't already. Also ensures that checked is undefined if the
37
+ * parent does not have a list type of 'check'.
38
+ * @param list - The list whose children are updated.
39
+ */
40
+ export declare function updateChildrenListItemValue(list: ListNode): void;
41
+ /**
42
+ * Merge the next sibling list if same type.
43
+ * <ul> will merge with <ul>, but NOT <ul> with <ol>.
44
+ * @param list - The list whose next sibling should be potentially merged
45
+ */
46
+ export declare function mergeNextSiblingListIfSameType(list: ListNode): void;
47
+ /**
48
+ * Adds an empty ListNode/ListItemNode chain at listItemNode, so as to
49
+ * create an indent effect. Won't indent ListItemNodes that have a ListNode as
50
+ * a child, but does merge sibling ListItemNodes if one has a nested ListNode.
51
+ * @param listItemNode - The ListItemNode to be indented.
52
+ */
53
+ export declare function $handleIndent(listItemNode: ListItemNode): void;
54
+ /**
55
+ * Removes an indent by removing an empty ListNode/ListItemNode chain. An indented ListItemNode
56
+ * has a great grandparent node of type ListNode, which is where the ListItemNode will reside
57
+ * within as a child.
58
+ * @param listItemNode - The ListItemNode to remove the indent (outdent).
59
+ */
60
+ export declare function $handleOutdent(listItemNode: ListItemNode): void;
61
+ /**
62
+ * Attempts to insert a ParagraphNode at selection and selects the new node. The selection must contain a ListItemNode
63
+ * or a node that does not already contain text. If its grandparent is the root/shadow root, it will get the ListNode
64
+ * (which should be the parent node) and insert the ParagraphNode as a sibling to the ListNode. If the ListNode is
65
+ * nested in a ListItemNode instead, it will add the ParagraphNode after the grandparent ListItemNode.
66
+ * Throws an invariant if the selection is not a child of a ListNode.
67
+ * @returns true if a ParagraphNode was inserted successfully, false if there is no selection
68
+ * or the selection does not contain a ListItemNode or the node already holds text.
69
+ */
70
+ export declare function $handleListInsertParagraph(): boolean;