Improve DragDrop visuals

This commit is contained in:
Eric NGUYEN 2023-02-24 09:59:39 +01:00
parent 1aedcf6ef4
commit e1592f56e7
2 changed files with 42 additions and 8 deletions

View file

@ -22,6 +22,11 @@ function HandleDragStart(event: React.DragEvent<HTMLButtonElement>): void {
const element = event.target as HTMLButtonElement;
event.dataTransfer.setData('type', element.id);
event.dataTransfer.setDragImage(element, 0, 0);
window.dispatchEvent(new Event('componentDragStart'));
}
function HandleDragEnd(): void {
window.dispatchEvent(new Event('componentDragEnd'));
}
interface SidebarCategory {
@ -85,7 +90,8 @@ export function Components(props: IComponentsProps): JSX.Element {
title={componentOption.Type}
onClick={() => { props.buttonOnClick(componentOption.Type); }}
draggable={true}
onDragStart={(event) => { HandleDragStart(event); }}
onDragStart={HandleDragStart}
onDragEnd={HandleDragEnd}
disabled={disabled}
>
{TruncateString(componentOption.DisplayedText ?? componentOption.Type, 25)}

View file

@ -34,8 +34,7 @@ function RemoveBorderClasses(target: HTMLElement, exception: string = ''): void
function HandleDragLeave(event: React.DragEvent): void {
let target: HTMLButtonElement = event.target as HTMLButtonElement;
if (target.classList.contains('list-vertical-bar')) {
if ((target.parentElement?.classList.contains('elements-sidebar-row')) ?? false) {
target = target.parentElement as HTMLButtonElement;
}
@ -49,7 +48,7 @@ function HandleDragOver(
event.preventDefault();
let target = event.target as HTMLElement;
if (target.classList.contains('list-vertical-bar')) {
if ((target.parentElement?.classList.contains('elements-sidebar-row')) ?? false) {
target = target.parentElement as HTMLButtonElement;
}
@ -83,7 +82,7 @@ function HandleOnDrop(
const type = event.dataTransfer.getData('type');
let target: HTMLButtonElement = event.target as HTMLButtonElement;
if (target.classList.contains('list-vertical-bar')) {
if ((target.parentElement?.classList.contains('elements-sidebar-row')) ?? false) {
target = target.parentElement as HTMLButtonElement;
}
@ -141,11 +140,34 @@ function HandleOnDrop(
}
}
function useDragComponentsListener(
setDragActive: (isActive: boolean) => void
): void {
React.useEffect(() => {
function HandleComponentDragStart(): void {
setDragActive(true);
}
function HandleComponentDragEnd(): void {
setDragActive(false);
}
window.addEventListener('componentDragStart', HandleComponentDragStart);
window.addEventListener('componentDragEnd', HandleComponentDragEnd);
return () => {
window.removeEventListener('componentDragStart', HandleComponentDragStart);
window.addEventListener('componentDragEnd', HandleComponentDragEnd);
};
});
}
export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
// States
const divRef = React.useRef<HTMLDivElement>(null);
const [isDragActive, setDragActive] = React.useState<boolean>(false);
const [,height] = useSize(divRef);
// Hooks
useDragComponentsListener(setDragActive);
// Render
const it = MakeRecursionDFSIterator(props.mainContainer, props.containers, 0, [0, 0], true);
const containers = [...it];
@ -176,6 +198,7 @@ export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
text,
props.containers,
props.mainContainer,
isDragActive,
props.addContainer,
props.selectContainer
)
@ -209,7 +232,7 @@ export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
</div>
<List
itemCount={containers.length}
itemSize={40}
itemSize={42}
height={height}
width={'100%'}
>
@ -230,6 +253,7 @@ function ElementsListRow(
text: string,
containers: Map<string, IContainerModel>,
mainContainer: IContainerModel,
isDragActive: boolean,
addContainer: (index: number, type: string, parent: string) => void,
selectContainer: (containerId: string) => void
): JSX.Element {
@ -259,7 +283,9 @@ function ElementsListRow(
return <div style={style}>
<button type="button"
className={`transition-all h-[38px]
className={`transition-all ${isDragActive
? 'h-[38px]'
: 'h-[42px]'}
hover:shadow-lg elements-sidebar-row whitespace-pre
text-left text-sm font-medium flex items-center align-middle group
${container.properties.type} ${buttonClass}`}
@ -278,6 +304,8 @@ function ElementsListRow(
{container.properties.warning.length > 0 &&
<ExclamationTriangleIcon className='pl-2 w-7' />}
</button>
<hr className='border-t-2 h-[2px] border-t-slate-500'></hr>
{isDragActive &&
<hr className='border-t-4 h-[4px] border-t-red-500 transition-all animate-pulse'></hr>
}
</div>;
}