Improve DragDrop visuals
This commit is contained in:
parent
1aedcf6ef4
commit
e1592f56e7
2 changed files with 42 additions and 8 deletions
|
@ -22,6 +22,11 @@ function HandleDragStart(event: React.DragEvent<HTMLButtonElement>): void {
|
||||||
const element = event.target as HTMLButtonElement;
|
const element = event.target as HTMLButtonElement;
|
||||||
event.dataTransfer.setData('type', element.id);
|
event.dataTransfer.setData('type', element.id);
|
||||||
event.dataTransfer.setDragImage(element, 0, 0);
|
event.dataTransfer.setDragImage(element, 0, 0);
|
||||||
|
window.dispatchEvent(new Event('componentDragStart'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function HandleDragEnd(): void {
|
||||||
|
window.dispatchEvent(new Event('componentDragEnd'));
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SidebarCategory {
|
interface SidebarCategory {
|
||||||
|
@ -85,7 +90,8 @@ export function Components(props: IComponentsProps): JSX.Element {
|
||||||
title={componentOption.Type}
|
title={componentOption.Type}
|
||||||
onClick={() => { props.buttonOnClick(componentOption.Type); }}
|
onClick={() => { props.buttonOnClick(componentOption.Type); }}
|
||||||
draggable={true}
|
draggable={true}
|
||||||
onDragStart={(event) => { HandleDragStart(event); }}
|
onDragStart={HandleDragStart}
|
||||||
|
onDragEnd={HandleDragEnd}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{TruncateString(componentOption.DisplayedText ?? componentOption.Type, 25)}
|
{TruncateString(componentOption.DisplayedText ?? componentOption.Type, 25)}
|
||||||
|
|
|
@ -34,8 +34,7 @@ function RemoveBorderClasses(target: HTMLElement, exception: string = ''): void
|
||||||
|
|
||||||
function HandleDragLeave(event: React.DragEvent): void {
|
function HandleDragLeave(event: React.DragEvent): void {
|
||||||
let target: HTMLButtonElement = event.target as HTMLButtonElement;
|
let target: HTMLButtonElement = event.target as HTMLButtonElement;
|
||||||
|
if ((target.parentElement?.classList.contains('elements-sidebar-row')) ?? false) {
|
||||||
if (target.classList.contains('list-vertical-bar')) {
|
|
||||||
target = target.parentElement as HTMLButtonElement;
|
target = target.parentElement as HTMLButtonElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ function HandleDragOver(
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let target = event.target as HTMLElement;
|
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;
|
target = target.parentElement as HTMLButtonElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +82,7 @@ function HandleOnDrop(
|
||||||
const type = event.dataTransfer.getData('type');
|
const type = event.dataTransfer.getData('type');
|
||||||
let target: HTMLButtonElement = event.target as HTMLButtonElement;
|
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;
|
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 {
|
export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
|
||||||
// States
|
// States
|
||||||
const divRef = React.useRef<HTMLDivElement>(null);
|
const divRef = React.useRef<HTMLDivElement>(null);
|
||||||
|
const [isDragActive, setDragActive] = React.useState<boolean>(false);
|
||||||
const [,height] = useSize(divRef);
|
const [,height] = useSize(divRef);
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
useDragComponentsListener(setDragActive);
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
const it = MakeRecursionDFSIterator(props.mainContainer, props.containers, 0, [0, 0], true);
|
const it = MakeRecursionDFSIterator(props.mainContainer, props.containers, 0, [0, 0], true);
|
||||||
const containers = [...it];
|
const containers = [...it];
|
||||||
|
@ -176,6 +198,7 @@ export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
|
||||||
text,
|
text,
|
||||||
props.containers,
|
props.containers,
|
||||||
props.mainContainer,
|
props.mainContainer,
|
||||||
|
isDragActive,
|
||||||
props.addContainer,
|
props.addContainer,
|
||||||
props.selectContainer
|
props.selectContainer
|
||||||
)
|
)
|
||||||
|
@ -209,7 +232,7 @@ export function ElementsSidebar(props: IElementsSidebarProps): JSX.Element {
|
||||||
</div>
|
</div>
|
||||||
<List
|
<List
|
||||||
itemCount={containers.length}
|
itemCount={containers.length}
|
||||||
itemSize={40}
|
itemSize={42}
|
||||||
height={height}
|
height={height}
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
>
|
>
|
||||||
|
@ -230,6 +253,7 @@ function ElementsListRow(
|
||||||
text: string,
|
text: string,
|
||||||
containers: Map<string, IContainerModel>,
|
containers: Map<string, IContainerModel>,
|
||||||
mainContainer: IContainerModel,
|
mainContainer: IContainerModel,
|
||||||
|
isDragActive: boolean,
|
||||||
addContainer: (index: number, type: string, parent: string) => void,
|
addContainer: (index: number, type: string, parent: string) => void,
|
||||||
selectContainer: (containerId: string) => void
|
selectContainer: (containerId: string) => void
|
||||||
): JSX.Element {
|
): JSX.Element {
|
||||||
|
@ -259,7 +283,9 @@ function ElementsListRow(
|
||||||
|
|
||||||
return <div style={style}>
|
return <div style={style}>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
className={`transition-all h-[38px]
|
className={`transition-all ${isDragActive
|
||||||
|
? 'h-[38px]'
|
||||||
|
: 'h-[42px]'}
|
||||||
hover:shadow-lg elements-sidebar-row whitespace-pre
|
hover:shadow-lg elements-sidebar-row whitespace-pre
|
||||||
text-left text-sm font-medium flex items-center align-middle group
|
text-left text-sm font-medium flex items-center align-middle group
|
||||||
${container.properties.type} ${buttonClass}`}
|
${container.properties.type} ${buttonClass}`}
|
||||||
|
@ -278,6 +304,8 @@ function ElementsListRow(
|
||||||
{container.properties.warning.length > 0 &&
|
{container.properties.warning.length > 0 &&
|
||||||
<ExclamationTriangleIcon className='pl-2 w-7' />}
|
<ExclamationTriangleIcon className='pl-2 w-7' />}
|
||||||
</button>
|
</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>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue