introduce drag & drop handlers to search box

without modification, default browser behavior for dropping new text on top of pre-existing text in an input field is to insert the new text in between whatever characters the mouse is pointing to at time of drop.  Instead, by adding handlers, the pre-existing content can be overwritten/replaced.  The primary use-case is for accessing quoted toots, or referenced hashtags or accounts, in the feed by searching for the linked URLs & showing the original/expanded version of them in the search results (as opposed to clicking on the links themselves and having them open in a new tab, on a potentially different mastodon server)
Since the search box is designed to actively process its input for context-clues, after the text has been dropped, an Input event is triggered to bubble up from the search-box's new handleDrop method, that will cause the handleChange method to be invoked.  This strategy was adapted from https://stackoverflow.com/a/47409362
This commit is contained in:
Matt Panaro 2024-12-31 12:27:08 -05:00
parent 7d6da219c0
commit da6a2d3b51

View File

@ -451,6 +451,33 @@ export const Search: React.FC<{
setSelectedOption(-1);
}, [setExpanded, setSelectedOption]);
const handleDragOver = useCallback(
(event: React.DragEvent<HTMLInputElement>) => {
event.preventDefault();
},
[],
);
const handleDrop = useCallback(
(event: React.DragEvent<HTMLInputElement>) => {
event.preventDefault();
handleClear();
const query =
event.dataTransfer.getData('URL') ||
event.dataTransfer.getData('text/plain');
Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
'value',
)?.set?.call(event.target, query);
event.currentTarget.focus();
event.target.dispatchEvent(new Event('change', { bubbles: true }));
},
[handleClear],
);
return (
<form className={classNames('search', { active: expanded })}>
<input
@ -468,6 +495,8 @@ export const Search: React.FC<{
onKeyDown={handleKeyDown}
onFocus={handleFocus}
onBlur={handleBlur}
onDragOver={handleDragOver}
onDrop={handleDrop}
/>
<button type='button' className='search__icon' onClick={handleClear}>