feat(ui): more dnd cleanup and tidy

This commit is contained in:
psychedelicious
2024-10-31 07:26:22 +10:00
parent f0c80a8d7a
commit ee8359242c
8 changed files with 75 additions and 55 deletions

View File

@@ -1,3 +1,4 @@
import type { SystemStyleObject } from '@invoke-ai/ui-library';
import { Box, Circle, Flex, Icon, IconButton, Spacer, Tooltip } from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import { DndListDropIndicator } from 'features/dnd/DndListDropIndicator';
@@ -20,6 +21,19 @@ type Props = {
fieldIdentifier: FieldIdentifier;
};
const sx = {
layerStyle: 'second',
alignItems: 'center',
position: 'relative',
borderRadius: 'base',
w: 'full',
p: 2,
'&[data-is-dragging=true]': {
opacity: 0.3,
},
transitionProperty: 'common',
} satisfies SystemStyleObject;
const LinearViewFieldInternal = ({ fieldIdentifier }: Props) => {
const dispatch = useAppDispatch();
const { isValueChanged, onReset } = useFieldOriginalValue(fieldIdentifier.nodeId, fieldIdentifier.fieldName);
@@ -31,7 +45,7 @@ const LinearViewFieldInternal = ({ fieldIdentifier }: Props) => {
}, [dispatch, fieldIdentifier]);
const ref = useRef<HTMLDivElement>(null);
const dndState = useLinearViewFieldDnd(ref, fieldIdentifier);
const [dndListState, isDragging] = useLinearViewFieldDnd(ref, fieldIdentifier);
return (
<Box position="relative" w="full">
@@ -39,14 +53,10 @@ const LinearViewFieldInternal = ({ fieldIdentifier }: Props) => {
ref={ref}
// This is used to trigger the post-move flash animation
data-field-name={fieldIdentifier.fieldName}
data-is-dragging={isDragging}
onMouseEnter={handleMouseOver}
onMouseLeave={handleMouseOut}
layerStyle="second"
alignItems="center"
position="relative"
borderRadius="base"
w="full"
p={2}
sx={sx}
>
<Flex flexDir="column" w="full">
<Flex alignItems="center" gap={2}>
@@ -90,7 +100,7 @@ const LinearViewFieldInternal = ({ fieldIdentifier }: Props) => {
<InputFieldRenderer nodeId={fieldIdentifier.nodeId} fieldName={fieldIdentifier.fieldName} />
</Flex>
</Flex>
<DndListDropIndicator dndState={dndState} />
<DndListDropIndicator dndState={dndListState} />
</Box>
);
};

View File

@@ -13,7 +13,8 @@ import { useEffect, useState } from 'react';
export const singleWorkflowField = buildDndSourceApi<{ fieldIdentifier: FieldIdentifier }>('SingleWorkflowField');
export const useLinearViewFieldDnd = (ref: RefObject<HTMLElement>, fieldIdentifier: FieldIdentifier) => {
const [dndState, setDndState] = useState<DndListState>(idle);
const [dndListState, setListDndState] = useState<DndListState>(idle);
const [isDragging, setIsDragging] = useState(false);
useEffect(() => {
const element = ref.current;
@@ -27,10 +28,12 @@ export const useLinearViewFieldDnd = (ref: RefObject<HTMLElement>, fieldIdentifi
return singleWorkflowField.getData({ fieldIdentifier });
},
onDragStart() {
setDndState({ type: 'is-dragging' });
setListDndState({ type: 'is-dragging' });
setIsDragging(true);
},
onDrop() {
setDndState(idle);
setListDndState(idle);
setIsDragging(false);
},
}),
dropTargetForElements({
@@ -54,14 +57,14 @@ export const useLinearViewFieldDnd = (ref: RefObject<HTMLElement>, fieldIdentifi
},
onDragEnter({ self }) {
const closestEdge = extractClosestEdge(self.data);
setDndState({ type: 'is-dragging-over', closestEdge });
setListDndState({ type: 'is-dragging-over', closestEdge });
},
onDrag({ self }) {
const closestEdge = extractClosestEdge(self.data);
// Only need to update react state if nothing has changed.
// Prevents re-rendering.
setDndState((current) => {
setListDndState((current) => {
if (current.type === 'is-dragging-over' && current.closestEdge === closestEdge) {
return current;
}
@@ -69,14 +72,14 @@ export const useLinearViewFieldDnd = (ref: RefObject<HTMLElement>, fieldIdentifi
});
},
onDragLeave() {
setDndState(idle);
setListDndState(idle);
},
onDrop() {
setDndState(idle);
setListDndState(idle);
},
})
);
}, [fieldIdentifier, ref]);
return dndState;
return [dndListState, isDragging] as const;
};