From 7eb79266c45917cf81a3b97a097ef75a3b66124e Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Mon, 1 Jan 2024 12:38:20 +1100 Subject: [PATCH] feat(ui): split dnd overlay to separate component This reduces top-level rerenders when zooming in and out on workflow editor --- .../features/dnd/components/AppDndContext.tsx | 58 ++---------------- .../features/dnd/components/DndOverlay.tsx | 60 +++++++++++++++++++ 2 files changed, 65 insertions(+), 53 deletions(-) create mode 100644 invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx diff --git a/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx b/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx index 5e5dfecbd4..0fe069f68a 100644 --- a/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx +++ b/invokeai/frontend/web/src/features/dnd/components/AppDndContext.tsx @@ -1,28 +1,19 @@ -import { - DragOverlay, - MouseSensor, - TouchSensor, - useSensor, - useSensors, -} from '@dnd-kit/core'; +import { MouseSensor, TouchSensor, useSensor, useSensors } from '@dnd-kit/core'; import { logger } from 'app/logging/logger'; import { dndDropped } from 'app/store/middleware/listenerMiddleware/listeners/imageDropped'; import { useAppDispatch } from 'app/store/storeHooks'; import { parseify } from 'common/util/serialize'; -import { useScaledModifer } from 'features/dnd/hooks/useScaledCenteredModifer'; +import DndOverlay from 'features/dnd/components/DndOverlay'; import type { DragEndEvent, DragStartEvent, TypesafeDraggableData, } from 'features/dnd/types'; import { customPointerWithin } from 'features/dnd/util/customPointerWithin'; -import type { AnimationProps } from 'framer-motion'; -import { AnimatePresence, motion } from 'framer-motion'; -import type { CSSProperties, PropsWithChildren } from 'react'; -import { memo, useCallback, useMemo, useState } from 'react'; +import type { PropsWithChildren } from 'react'; +import { memo, useCallback, useState } from 'react'; import { DndContextTypesafe } from './DndContextTypesafe'; -import DragPreview from './DragPreview'; const AppDndContext = (props: PropsWithChildren) => { const [activeDragData, setActiveDragData] = @@ -77,9 +68,6 @@ const AppDndContext = (props: PropsWithChildren) => { const sensors = useSensors(mouseSensor, touchSensor); - const scaledModifier = useScaledModifer(); - const modifiers = useMemo(() => [scaledModifier], [scaledModifier]); - return ( { autoScroll={false} > {props.children} - - - {activeDragData && ( - - - - )} - - + ); }; export default memo(AppDndContext); - -const dragOverlayStyles: CSSProperties = { - width: 'min-content', - height: 'min-content', - cursor: 'grabbing', - userSelect: 'none', - // expand overlay to prevent cursor from going outside it and displaying - padding: '10rem', -}; - -const initial: AnimationProps['initial'] = { - opacity: 0, - scale: 0.7, -}; -const animate: AnimationProps['animate'] = { - opacity: 1, - scale: 1, - transition: { duration: 0.1 }, -}; diff --git a/invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx b/invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx new file mode 100644 index 0000000000..263ebf928c --- /dev/null +++ b/invokeai/frontend/web/src/features/dnd/components/DndOverlay.tsx @@ -0,0 +1,60 @@ +import { DragOverlay } from '@dnd-kit/core'; +import { useScaledModifer } from 'features/dnd/hooks/useScaledCenteredModifer'; +import type { TypesafeDraggableData } from 'features/dnd/types'; +import type { AnimationProps } from 'framer-motion'; +import { AnimatePresence, motion } from 'framer-motion'; +import type { CSSProperties } from 'react'; +import { memo, useMemo } from 'react'; + +import DragPreview from './DragPreview'; + +type DndOverlayProps = { + activeDragData: TypesafeDraggableData | null; +}; + +const DndOverlay = (props: DndOverlayProps) => { + const scaledModifier = useScaledModifer(); + const modifiers = useMemo(() => [scaledModifier], [scaledModifier]); + + return ( + + + {props.activeDragData && ( + + + + )} + + + ); +}; + +export default memo(DndOverlay); + +const dragOverlayStyles: CSSProperties = { + width: 'min-content', + height: 'min-content', + cursor: 'grabbing', + userSelect: 'none', + // expand overlay to prevent cursor from going outside it and displaying + padding: '10rem', +}; + +const initial: AnimationProps['initial'] = { + opacity: 0, + scale: 0.7, +}; +const animate: AnimationProps['animate'] = { + opacity: 1, + scale: 1, + transition: { duration: 0.1 }, +};