Issue
I have an input element of type file that can be clicked or have files dragged onto it. When the file is dragged, it uses drag events to change the text of the label that is displayed for the input.
To make sure the text changes properly, it needs to have the pointer set to none. But I want the pointer to stay a pointer when the mouse is over the button and not dragging a file, so I change it back using an onMouseOver event.
The problem is that when I use the onMouseOver event, the input stops working when I click it. If have the onMouseOver event set the pointer to none, it works. Set it to pointer, it can no longer be clicked.
const [labelText, setLabelText] = React.useState<string>(hoverLabel);
const [pointer, setPointer] = React.useState<string>('none');
const stopDefaults = (e: React.DragEvent) => {
e.stopPropagation();
e.preventDefault();
};
const dragEvents = {
onDragEnter: (e: React.DragEvent) => {
stopDefaults(e);
setLabelText(dropLabel);
setPointer('none');
},
onMouseOver: () => {
setPointer('pointer');
},
onDragLeave: (e: React.DragEvent) => {
stopDefaults(e);
setLabelText(hoverLabel);
setPointer('none');
},
onDragOver: stopDefaults,
onDrop: (e: React.DragEvent<HTMLElement>) => {
stopDefaults(e);
setLabelText(hoverLabel);
onDrop(e);
},
};
return (
<>
<input
onChange={handleChange}
style={{display: 'none'}}
id="fileUploader"
type="file"
/>
<label
htmlFor="file-upload"
{...dragEvents}
>
<Box
width={width}
height={height}
sx={{ pointerEvents: pointer }}
>
<Button sx={{ height: height, width: width}}>
<Typography>{labelText}</Typography>
</Button>
</Box>
</label>
</>
);
Solution
The interaction of the pointerEvents property and the clickability of the input could be causing this. You can try to handle the pointer events directly on the label element without relying on the pointerEvents property. You can dynamically set the cursor property of the label based on whether a file is being dragged or not. the label should remain clickable even when the pointer is set to 'none' during dragging. Try something like this and see if it works,
...
const [isDragging, setIsDragging] = React.useState<boolean>(false);
...
const dragEvents = {
onDragEnter: (e: React.DragEvent) => {
...
setIsDragging(true);
},
onDragLeave: (e: React.DragEvent) => {
...
setIsDragging(false);
},
onDragOver: stopDefaults,
onDrop: (e: React.DragEvent<HTMLElement>) => {
...
setIsDragging(false);
onDrop(e);
},
};
const labelStyle: React.CSSProperties = {
cursor: isDragging ? 'none' : 'pointer',
};
return (
<>
<input
...
/>
<label
htmlFor="file-upload"
{...dragEvents}
style={labelStyle}
>
<Box width={width} height={height}>
<Button sx={{ height: height, width: width }}>
<Typography>{labelText}</Typography>
</Button>
</Box>
</label>
</>
);
Answered By - Nazrul Chowdhury
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.