Skip to content

Commit

Permalink
updated denest transform to handle nesting inside lists, removed imag…
Browse files Browse the repository at this point in the history
…e-specific denest in koenig-lexical
  • Loading branch information
kevinansfield committed Oct 18, 2023
1 parent 4a848d7 commit 58b8c51
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 28 deletions.
1 change: 1 addition & 0 deletions packages/kg-default-transforms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"typescript": "5.2.2"
},
"dependencies": {
"@lexical/list": "^0.12.2",
"@lexical/rich-text": "^0.12.2",
"@lexical/utils": "^0.12.2",
"@tryghost/kg-default-nodes": "^0.2.3",
Expand Down
5 changes: 4 additions & 1 deletion packages/kg-default-transforms/src/default-transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {mergeRegister} from '@lexical/utils';
import {$createParagraphNode, ParagraphNode} from 'lexical';
import {$createHeadingNode, $createQuoteNode, HeadingNode, QuoteNode} from '@lexical/rich-text';
import {ExtendedHeadingNode} from '@tryghost/kg-default-nodes';
import {ListItemNode, $createListItemNode, ListNode, $createListNode} from '@lexical/list';

export * from './transforms/denest.js';
export * from './transforms/remove-alignment.js';
Expand All @@ -21,6 +22,8 @@ export function registerDefaultTransforms(editor: LexicalEditor) {
registerDenestTransform(editor, ParagraphNode, () => ($createParagraphNode())),
registerDenestTransform(editor, HeadingNode, node => ($createHeadingNode(node.getTag()))),
registerDenestTransform(editor, ExtendedHeadingNode, node => ($createHeadingNode(node.getTag()))),
registerDenestTransform(editor, QuoteNode, () => ($createQuoteNode()))
registerDenestTransform(editor, QuoteNode, () => ($createQuoteNode())),
registerDenestTransform(editor, ListNode, node => ($createListNode(node.getListType(), node.getStart()))),
registerDenestTransform(editor, ListItemNode, () => ($createListItemNode()))
);
}
18 changes: 13 additions & 5 deletions packages/kg-default-transforms/src/transforms/denest.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {ElementNode, $createParagraphNode, LexicalEditor, LexicalNode, Klass} from 'lexical';
import {$isListItemNode, $isListNode} from '@lexical/list';
import {ElementNode, $createParagraphNode, LexicalEditor, LexicalNode, Klass, $getRoot} from 'lexical';

export type CreateNodeFn<T extends LexicalNode> = (originalNode: T) => T;

export function denestTransform<T extends ElementNode>(node: T, createNode: CreateNodeFn<T>) {
const children = node.getChildren();

const hasInvalidChild = children.some((child: LexicalNode) => {
return child.isInline && !child.isInline();
return !$isListNode(child) && !$isListItemNode(child) && child.isInline && !child.isInline();
});

if (!hasInvalidChild) {
Expand All @@ -26,7 +27,7 @@ export function denestTransform<T extends ElementNode>(node: T, createNode: Crea

// pull out any non-inline children as we don't support nested element nodes
children.forEach((child: LexicalNode) => {
if (child.isInline && !child.isInline()) {
if (!$isListNode(child) && !$isListItemNode(child) && child.isInline && !child.isInline()) {
if (currentElementNode.getChildrenSize() > 0) {
tempParagraph.append(currentElementNode);
currentElementNode = createNode(node);
Expand All @@ -42,10 +43,17 @@ export function denestTransform<T extends ElementNode>(node: T, createNode: Crea
tempParagraph.append(currentElementNode);
}

// find the top-level parent to insert nodes after in case of deeper nesting,
// e.g. images inside lists
let parent = node;
while (parent.getParent() && parent.getParent() !== $getRoot()) {
parent = parent.getParentOrThrow();
}

// reverse because we can only insertAfter the current paragraph
// so we need to insert the first child last to maintain order
// so we need to insert the first child last to maintain order.
tempParagraph.getChildren().reverse().forEach((child) => {
node.insertAfter(child);
parent.insertAfter(child);
});

// remove the original paragraph
Expand Down
22 changes: 0 additions & 22 deletions packages/koenig-lexical/src/plugins/KoenigBehaviourPlugin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1344,28 +1344,6 @@ function useKoenigBehaviour({editor, containerElem, cursorDidExitAtTop, isNested
);
}, [editor]);

// make sure ImageNode is a top-level node
React.useEffect(() => {
if (!editor.hasNodes([ImageNode])) {
return;
}
return mergeRegister(
editor.registerNodeTransform(ImageNode, (node) => {
// return if ImageNode is already a top-level node
if (node.getParent() === $getRoot()) {
return;
}

let parent = node;
while (parent.getParent() !== $getRoot()) {
parent = parent.getParent();
}

parent.insertAfter(node);
})
);
}, [editor]);

// remove alignment formats and denest invalid node nesting
React.useEffect(() => {
return registerDefaultTransforms(editor);
Expand Down

0 comments on commit 58b8c51

Please sign in to comment.