fix: better transition (#4267)

This commit is contained in:
Peng Xiao
2023-09-07 23:20:48 +08:00
committed by LongYinan
parent e8e6f0ee95
commit fd05bb3e39
2 changed files with 44 additions and 17 deletions
+10 -4
View File
@@ -8,7 +8,13 @@ import {
} from '@toeverything/infra/atom'; } from '@toeverything/infra/atom';
import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import type { ReactElement } from 'react'; import type { ReactElement } from 'react';
import { lazy, Suspense, useCallback, useTransition } from 'react'; import {
lazy,
startTransition,
Suspense,
useCallback,
useTransition,
} from 'react';
import type { SettingAtom } from '../atoms'; import type { SettingAtom } from '../atoms';
import { import {
@@ -119,13 +125,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);
@@ -146,7 +153,6 @@ export const AllWorkspaceModals = (): ReactElement => {
<> <>
<Suspense> <Suspense>
<WorkspaceListModal <WorkspaceListModal
disabled={isPending}
workspaces={workspaces} workspaces={workspaces}
currentWorkspaceId={currentWorkspaceId} currentWorkspaceId={currentWorkspaceId}
open={ open={
@@ -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>