Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lexical-list] Revert PR 6912 #6944

Merged
merged 3 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 49 additions & 46 deletions packages/lexical-list/src/LexicalListItemNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@
*/

import type {ListNode, ListType} from './';
import type {
BaseSelection,
DOMConversionMap,
DOMConversionOutput,
DOMExportOutput,
EditorConfig,
EditorThemeClasses,
LexicalNode,
NodeKey,
ParagraphNode,
RangeSelection,
SerializedElementNode,
Spread,
} from 'lexical';

import {
addClassNamesToElement,
Expand All @@ -15,24 +29,11 @@ import {
import {
$applyNodeReplacement,
$createParagraphNode,
$getSelection,
$isElementNode,
$isParagraphNode,
$isRangeSelection,
BaseSelection,
DOMConversionMap,
DOMConversionOutput,
DOMExportOutput,
EditorConfig,
EditorThemeClasses,
ElementNode,
LexicalEditor,
LexicalNode,
NodeKey,
ParagraphNode,
RangeSelection,
SerializedParagraphNode,
Spread,
} from 'lexical';
import invariant from 'shared/invariant';
import normalizeClassNames from 'shared/normalizeClassNames';
Expand All @@ -46,11 +47,11 @@ export type SerializedListItemNode = Spread<
checked: boolean | undefined;
value: number;
},
SerializedParagraphNode
SerializedElementNode
>;

/** @noInheritDoc */
export class ListItemNode extends ParagraphNode {
export class ListItemNode extends ElementNode {
/** @internal */
__value: number;
/** @internal */
Expand Down Expand Up @@ -80,18 +81,20 @@ export class ListItemNode extends ParagraphNode {
$setListItemThemeClassNames(element, config.theme, this);
return element;
}
updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean {
if (super.updateDOM(prevNode, dom, config)) {
return true;
}

updateDOM(
prevNode: ListItemNode,
dom: HTMLElement,
config: EditorConfig,
): boolean {
const parent = this.getParent();
if ($isListNode(parent) && parent.getListType() === 'check') {
updateListItemChecked(dom, this, prevNode, parent);
}
// @ts-expect-error - this is always HTMLListItemElement
dom.value = this.__value;
$setListItemThemeClassNames(dom, config.theme, this);

return false;
}

Expand Down Expand Up @@ -125,12 +128,6 @@ export class ListItemNode extends ParagraphNode {
node.setValue(serializedNode.value);
node.setFormat(serializedNode.format);
node.setDirection(serializedNode.direction);
if (typeof serializedNode.textFormat === 'number') {
node.setTextFormat(serializedNode.textFormat);
}
if (typeof serializedNode.textStyle === 'string') {
node.setTextStyle(serializedNode.textStyle);
}
return node;
}

Expand Down Expand Up @@ -227,11 +224,15 @@ export class ListItemNode extends ParagraphNode {
}

const siblings = this.getNextSiblings();

// Split the lists and insert the node in between them
listNode.insertAfter(node, restoreSelection);

if (siblings.length !== 0) {
const newListNode = $createListNode(listNode.getListType());

siblings.forEach((sibling) => newListNode.append(sibling));

node.insertAfter(newListNode, restoreSelection);
}

Expand All @@ -255,49 +256,51 @@ export class ListItemNode extends ParagraphNode {
}

insertNewAfter(
selection: RangeSelection,
_: RangeSelection,
restoreSelection = true,
): ListItemNode | ParagraphNode {
const newElement = $createListItemNode(
this.__checked == null ? undefined : false,
);

const format = selection.format;
newElement.setTextFormat(format);

newElement.setFormat(this.getFormatType());
this.insertAfter(newElement, restoreSelection);

return newElement;
}

collapseAtStart(): boolean {
const selection = $getSelection();

if (!$isRangeSelection(selection)) {
return false;
}

collapseAtStart(selection: RangeSelection): true {
const paragraph = $createParagraphNode();
const children = this.getChildren();
children.forEach((child) => paragraph.append(child));

const listNode = this.getParentOrThrow();
const listNodeParent = listNode.getParent();

if (!$isListNode(listNode)) {
return false;
}
const listNodeParent = listNode.getParentOrThrow();
const isIndented = $isListItemNode(listNodeParent);

if (listNode.getChildrenSize() === 1) {
if ($isListItemNode(listNodeParent)) {
if (isIndented) {
// if the list node is nested, we just want to remove it,
// effectively unindenting it.
listNode.remove();
listNodeParent.select();
} else {
listNode.insertBefore(paragraph);
listNode.remove();
paragraph.select();
// If we have selection on the list item, we'll need to move it
// to the paragraph
const anchor = selection.anchor;
const focus = selection.focus;
const key = paragraph.getKey();

if (anchor.type === 'element' && anchor.getNode().is(this)) {
anchor.set(key, anchor.offset, 'element');
}

if (focus.type === 'element' && focus.getNode().is(this)) {
focus.set(key, focus.offset, 'element');
}
}
} else {
listNode.insertBefore(paragraph);
this.remove();
}

return true;
Expand Down
10 changes: 6 additions & 4 deletions packages/lexical-list/src/formatList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export function removeList(editor: LexicalEditor): void {

if ($isLeafNode(node)) {
const listItemNode = $getNearestNodeOfType(node, ListItemNode);

if (listItemNode != null) {
listNodes.add($getTopListNode(listItemNode));
}
Expand Down Expand Up @@ -478,13 +479,11 @@ export function $handleListInsertParagraph(): boolean {
return false;
}
// Only run this code on empty list items

const anchor = selection.anchor.getNode();

if (!$isListItemNode(anchor) || anchor.getChildrenSize() !== 0) {
return false;
}

const topListNode = $getTopListNode(anchor);
const parent = anchor.getParent();

Expand All @@ -494,7 +493,8 @@ export function $handleListInsertParagraph(): boolean {
);

const grandparent = parent.getParent();
let replacementNode: ElementNode;

let replacementNode;

if ($isRootOrShadowRoot(grandparent)) {
replacementNode = $createParagraphNode();
Expand All @@ -505,10 +505,10 @@ export function $handleListInsertParagraph(): boolean {
} else {
return false;
}

replacementNode.select();

const nextSiblings = anchor.getNextSiblings();

if (nextSiblings.length > 0) {
const newList = $createListNode(parent.getListType());
if ($isParagraphNode(replacementNode)) {
Expand All @@ -523,7 +523,9 @@ export function $handleListInsertParagraph(): boolean {
newList.append(sibling);
});
}

// Don't leave hanging nested empty lists
$removeHighestEmptyListParent(anchor);

return true;
}
3 changes: 2 additions & 1 deletion packages/lexical-list/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
*
*/

import type {LexicalNode, Spread} from 'lexical';

import {$findMatchingParent} from '@lexical/utils';
import {type LexicalNode, type Spread} from 'lexical';
import invariant from 'shared/invariant';

import {
Expand Down
45 changes: 0 additions & 45 deletions packages/lexical-playground/__tests__/e2e/List.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
redo,
selectAll,
selectCharacters,
toggleBold,
undo,
} from '../keyboardShortcuts/index.mjs';
import {
Expand Down Expand Up @@ -1882,48 +1881,4 @@ test.describe.parallel('Nested List', () => {
});
},
);
test('new list item should preserve format from previous list item even after new list item is indented', async ({
page,
}) => {
await focusEditor(page);
await toggleBulletList(page);
await toggleBold(page);
await page.keyboard.type('MLH Fellowship');
await page.keyboard.press('Enter');
await clickIndentButton(page);
await page.keyboard.type('Fall 2024');
await assertHTML(
page,
html`
<ul class="PlaygroundEditorTheme__ul">
<li
class="PlaygroundEditorTheme__listItem PlaygroundEditorTheme__ltr"
dir="ltr"
value="1">
<strong
class="PlaygroundEditorTheme__textBold"
data-lexical-text="true">
MLH Fellowship
</strong>
</li>
<li
class="PlaygroundEditorTheme__listItem PlaygroundEditorTheme__nestedListItem"
value="2">
<ul class="PlaygroundEditorTheme__ul">
<li
class="PlaygroundEditorTheme__listItem PlaygroundEditorTheme__ltr"
dir="ltr"
value="1">
<strong
class="PlaygroundEditorTheme__textBold"
data-lexical-text="true">
Fall 2024
</strong>
</li>
</ul>
</li>
</ul>
`,
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ describe('LexicalEditor tests', () => {
editable ? 'editable' : 'non-editable'
})`, async () => {
const JSON_EDITOR_STATE =
'{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"123","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"root","version":1}}';
'{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"123","type":"text","version":1}],"direction":null,"format":"","indent":0,"type":"paragraph","version":1,"textStyle":""}],"direction":null,"format":"","indent":0,"type":"root","version":1}}';
init();
const contentEditable = editor.getRootElement();
editor.setEditable(editable);
Expand Down
Loading
Loading