Teact: Fix moving element to the end of fast list

This commit is contained in:
Alexander Zinchuk 2023-05-15 10:56:01 +02:00
parent af06317a0f
commit da4e5e543b

View File

@ -83,6 +83,7 @@ function renderWithVirtual<T extends VirtualElement | undefined>(
options: { options: {
skipComponentUpdate?: boolean; skipComponentUpdate?: boolean;
nextSibling?: ChildNode; nextSibling?: ChildNode;
forceMoveToEnd?: boolean;
fragment?: DocumentFragment; fragment?: DocumentFragment;
} = {}, } = {},
): T { ): T {
@ -162,6 +163,7 @@ function renderWithVirtual<T extends VirtualElement | undefined>(
$new as VirtualElementComponent | VirtualElementFragment, $new as VirtualElementComponent | VirtualElementFragment,
parentEl, parentEl,
nextSibling, nextSibling,
options.forceMoveToEnd,
); );
} else { } else {
const $currentAsReal = $current as VirtualElementReal; const $currentAsReal = $current as VirtualElementReal;
@ -176,7 +178,7 @@ function renderWithVirtual<T extends VirtualElement | undefined>(
$newAsTag.props.ref = $current.props.ref; $newAsTag.props.ref = $current.props.ref;
if (nextSibling) { if (nextSibling || options.forceMoveToEnd) {
insertBefore(parentEl, currentTarget, nextSibling); insertBefore(parentEl, currentTarget, nextSibling);
} }
@ -377,7 +379,11 @@ function getNextSibling($current: VirtualElement): ChildNode | undefined {
} }
function renderChildren( function renderChildren(
$current: VirtualElementParent, $new: VirtualElementParent, currentEl: HTMLElement, nextSibling?: ChildNode, $current: VirtualElementParent,
$new: VirtualElementParent,
currentEl: HTMLElement,
nextSibling?: ChildNode,
forceMoveToEnd = false,
) { ) {
if (DEBUG) { if (DEBUG) {
DEBUG_checkKeyUniqueness($new.children); DEBUG_checkKeyUniqueness($new.children);
@ -394,8 +400,8 @@ function renderChildren(
const fragment = newChildrenLength > currentChildrenLength ? document.createDocumentFragment() : undefined; const fragment = newChildrenLength > currentChildrenLength ? document.createDocumentFragment() : undefined;
const lastCurrentChild = $current.children[currentChildrenLength - 1]; const lastCurrentChild = $current.children[currentChildrenLength - 1];
const fragmentNextSibling = nextSibling || ( const fragmentNextSibling = fragment && (
newChildrenLength > currentChildrenLength && lastCurrentChild ? getNextSibling(lastCurrentChild) : undefined nextSibling || lastCurrentChild ? getNextSibling(lastCurrentChild) : undefined
); );
for (let i = 0; i < maxLength; i++) { for (let i = 0; i < maxLength; i++) {
@ -405,7 +411,7 @@ function renderChildren(
$new.children[i], $new.children[i],
$new, $new,
i, i,
i >= currentChildrenLength ? { fragment } : { nextSibling }, i >= currentChildrenLength ? { fragment } : { nextSibling, forceMoveToEnd },
); );
if ($newChild) { if ($newChild) {
@ -519,12 +525,10 @@ function renderFastListChildren($current: VirtualElementParent, $new: VirtualEle
currentPreservedIndex++; currentPreservedIndex++;
} }
newChildren.push( const nextSibling = currentEl.childNodes[isMovingDown ? i + 1 : i];
renderWithVirtual(currentEl, currentChildInfo.$element, $newChild, $new, i, { const options = shouldMoveNode ? (nextSibling ? { nextSibling } : { forceMoveToEnd: true }) : undefined;
// `+ 1` is needed because before moving down the node still takes place above
nextSibling: shouldMoveNode ? currentEl.childNodes[isMovingDown ? i + 1 : i] : undefined, newChildren.push(renderWithVirtual(currentEl, currentChildInfo.$element, $newChild, $new, i, options));
}),
);
}); });
// This appends new children to the bottom // This appends new children to the bottom