fix: better transition (#4267)

This commit is contained in:
Peng Xiao 2023-09-07 23:20:48 +08:00 committed by GitHub
parent 2813ad36b8
commit 0c4277e5b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 16 deletions

View File

@ -13,6 +13,7 @@ import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import type { ReactElement } from 'react'; import type { ReactElement } from 'react';
import { import {
lazy, lazy,
startTransition,
Suspense, Suspense,
useCallback, useCallback,
useEffect, useEffect,
@ -223,13 +224,14 @@ export const AllWorkspaceModals = (): ReactElement => {
); );
const { jumpToSubPath } = useNavigateHelper(); const { jumpToSubPath } = useNavigateHelper();
const workspaces = useAtomValue(rootWorkspacesMetadataAtom); const workspaces = useAtomValue(rootWorkspacesMetadataAtom, {
delay: 0,
});
const setWorkspaces = useSetAtom(rootWorkspacesMetadataAtom); const setWorkspaces = useSetAtom(rootWorkspacesMetadataAtom);
const [currentWorkspaceId, setCurrentWorkspaceId] = useAtom( const [currentWorkspaceId, setCurrentWorkspaceId] = useAtom(
currentWorkspaceIdAtom currentWorkspaceIdAtom
); );
const setCurrentPageId = useSetAtom(currentPageIdAtom); const setCurrentPageId = useSetAtom(currentPageIdAtom);
const [isPending, startTransition] = useTransition();
const [, startCloseTransition] = useTransition(); const [, startCloseTransition] = useTransition();
const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom); const [, setOpenSettingModalAtom] = useAtom(openSettingModalAtom);
@ -250,7 +252,6 @@ export const AllWorkspaceModals = (): ReactElement => {
<> <>
<Suspense> <Suspense>
<WorkspaceListModal <WorkspaceListModal
disabled={isPending}
workspaces={workspaces} workspaces={workspaces}
currentWorkspaceId={currentWorkspaceId} currentWorkspaceId={currentWorkspaceId}
open={ open={

View File

@ -14,9 +14,9 @@ import {
restrictToParentElement, restrictToParentElement,
restrictToVerticalAxis, restrictToVerticalAxis,
} from '@dnd-kit/modifiers'; } from '@dnd-kit/modifiers';
import { SortableContext, useSortable } from '@dnd-kit/sortable'; import { arrayMove, SortableContext, useSortable } from '@dnd-kit/sortable';
import type { CSSProperties } from 'react'; import type { CSSProperties } from 'react';
import { useMemo } from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react';
import { WorkspaceCard } from '../../components/card/workspace-card'; import { WorkspaceCard } from '../../components/card/workspace-card';
import { workspaceItemStyle } from './index.css'; import { workspaceItemStyle } from './index.css';
@ -35,18 +35,20 @@ interface SortableWorkspaceItemProps extends Omit<WorkspaceListProps, 'items'> {
} }
const SortableWorkspaceItem = (props: SortableWorkspaceItemProps) => { const SortableWorkspaceItem = (props: SortableWorkspaceItemProps) => {
const { setNodeRef, attributes, listeners, transform } = useSortable({ const { setNodeRef, attributes, listeners, transform, transition } =
id: props.item.id, useSortable({
}); id: props.item.id,
});
const style: CSSProperties = useMemo( const style: CSSProperties = useMemo(
() => ({ () => ({
transform: transform transform: transform
? `translate3d(${transform.x}px, ${transform.y}px, 0)` ? `translate3d(${transform.x}px, ${transform.y}px, 0)`
: undefined, : undefined,
transition,
pointerEvents: props.disabled ? 'none' : undefined, pointerEvents: props.disabled ? 'none' : undefined,
opacity: props.disabled ? 0.6 : undefined, opacity: props.disabled ? 0.6 : undefined,
}), }),
[props.disabled, transform] [props.disabled, transform, transition]
); );
return ( return (
<div <div
@ -77,14 +79,33 @@ export const WorkspaceList = (props: WorkspaceListProps) => {
}, },
}) })
); );
const workspaceList = props.items;
const [optimisticList, setOptimisticList] = useState(workspaceList);
useEffect(() => {
setOptimisticList(workspaceList);
}, [workspaceList]);
const onDragEnd = useCallback(
(event: DragEndEvent) => {
const { active, over } = event;
if (active.id !== over?.id) {
setOptimisticList(workspaceList => {
const oldIndex = workspaceList.findIndex(w => w.id === active.id);
const newIndex = workspaceList.findIndex(w => w.id === over?.id);
const newList = arrayMove(workspaceList, oldIndex, newIndex);
return newList;
});
props.onDragEnd(event);
}
},
[props]
);
return ( return (
<DndContext <DndContext sensors={sensors} onDragEnd={onDragEnd} modifiers={modifiers}>
sensors={sensors} <SortableContext items={optimisticList}>
onDragEnd={props.onDragEnd} {optimisticList.map(item => (
modifiers={modifiers}
>
<SortableContext items={props.items}>
{props.items.map(item => (
<SortableWorkspaceItem {...props} item={item} key={item.id} /> <SortableWorkspaceItem {...props} item={item} key={item.id} />
))} ))}
</SortableContext> </SortableContext>