Skip to content

Commit

Permalink
Merge pull request #31154 from ishpaul777/fix/close-popover-on-drag
Browse files Browse the repository at this point in the history
fix: close popover when dragging over
  • Loading branch information
Joel Bettner authored Dec 4, 2023
2 parents 5bd6d8c + 4a8478e commit bd31861
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/components/DragAndDrop/Provider/index.native.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import type {DragAndDropContextParams, DragAndDropProviderProps} from './types';

const DragAndDropContext: DragAndDropContextParams = {};
const DragAndDropContext = React.createContext<DragAndDropContextParams>({});

function DragAndDropProvider({children}: DragAndDropProviderProps) {
return children;
Expand Down
22 changes: 15 additions & 7 deletions src/hooks/useDragAndDrop.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {useIsFocused} from '@react-navigation/native';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import React, {useCallback, useContext, useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
import {PopoverContext} from '@components/PopoverProvider';

const COPY_DROP_EFFECT = 'copy';
const NONE_DROP_EFFECT = 'none';
Expand All @@ -27,6 +28,7 @@ type DragAndDropOptions = {
export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllowDrop = true, isDisabled = false, shouldAcceptDrop = () => true}: DragAndDropParams): DragAndDropOptions {
const isFocused = useIsFocused();
const [isDraggingOver, setIsDraggingOver] = useState(false);
const {close: closePopover} = useContext(PopoverContext);

// This solution is borrowed from this SO: https://stackoverflow.com/questions/7110353/html5-dragleave-fired-when-hovering-a-child-element
// This is necessary because dragging over children will cause dragleave to execute on the parent.
Expand All @@ -43,9 +45,15 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow
setIsDraggingOver(false);
}, [isFocused, isDisabled]);

const setDropEffect = useCallback(
const handleDragEvent = useCallback(
(event: DragEvent) => {
const effect = shouldAllowDrop && shouldAcceptDrop(event) ? COPY_DROP_EFFECT : NONE_DROP_EFFECT;
const shouldAcceptThisDrop = shouldAllowDrop && shouldAcceptDrop(event);

if (shouldAcceptThisDrop && event.type === DRAG_ENTER_EVENT) {
closePopover();
}

const effect = shouldAcceptThisDrop ? COPY_DROP_EFFECT : NONE_DROP_EFFECT;

if (event.dataTransfer) {
// eslint-disable-next-line no-param-reassign
Expand All @@ -54,7 +62,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow
event.dataTransfer.effectAllowed = effect;
}
},
[shouldAllowDrop, shouldAcceptDrop],
[shouldAllowDrop, shouldAcceptDrop, closePopover],
);

/**
Expand All @@ -71,11 +79,11 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow

switch (event.type) {
case DRAG_OVER_EVENT:
setDropEffect(event);
handleDragEvent(event);
break;
case DRAG_ENTER_EVENT:
dragCounter.current++;
setDropEffect(event);
handleDragEvent(event);
if (isDraggingOver) {
return;
}
Expand All @@ -98,7 +106,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow
break;
}
},
[isFocused, isDisabled, shouldAcceptDrop, setDropEffect, isDraggingOver, onDrop],
[isFocused, isDisabled, shouldAcceptDrop, isDraggingOver, onDrop, handleDragEvent],
);

useEffect(() => {
Expand Down
6 changes: 3 additions & 3 deletions src/pages/home/report/ReportActionCompose/SuggestionEmoji.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function SuggestionEmoji({
}) {
const [suggestionValues, setSuggestionValues] = useState(defaultSuggestionsValues);

const isEmojiSuggestionsMenuVisible = !_.isEmpty(suggestionValues.suggestedEmojis) && suggestionValues.shouldShowEmojiSuggestionMenu;
const isEmojiSuggestionsMenuVisible = !_.isEmpty(suggestionValues.suggestedEmojis) && suggestionValues.shouldShowSuggestionMenu;

const [highlightedEmojiIndex, setHighlightedEmojiIndex] = useArrowKeyFocusManager({
isActive: isEmojiSuggestionsMenuVisible,
Expand Down Expand Up @@ -166,13 +166,13 @@ function SuggestionEmoji({
const nextState = {
suggestedEmojis: [],
colonIndex,
shouldShowEmojiSuggestionMenu: false,
shouldShowSuggestionMenu: false,
};
const newSuggestedEmojis = EmojiUtils.suggestEmojis(leftString, preferredLocale);

if (newSuggestedEmojis.length && isCurrentlyShowingEmojiSuggestion) {
nextState.suggestedEmojis = newSuggestedEmojis;
nextState.shouldShowEmojiSuggestionMenu = !_.isEmpty(newSuggestedEmojis);
nextState.shouldShowSuggestionMenu = !_.isEmpty(newSuggestedEmojis);
}

setSuggestionValues((prevState) => ({...prevState, ...nextState}));
Expand Down
13 changes: 12 additions & 1 deletion src/pages/home/report/ReportActionCompose/Suggestions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import PropTypes from 'prop-types';
import React, {useCallback, useImperativeHandle, useRef} from 'react';
import React, {useCallback, useContext, useEffect, useImperativeHandle, useRef} from 'react';
import {View} from 'react-native';
import {DragAndDropContext} from '@components/DragAndDrop/Provider';
import usePrevious from '@hooks/usePrevious';
import SuggestionEmoji from './SuggestionEmoji';
import SuggestionMention from './SuggestionMention';
import * as SuggestionProps from './suggestionProps';
Expand Down Expand Up @@ -45,6 +47,8 @@ function Suggestions({
}) {
const suggestionEmojiRef = useRef(null);
const suggestionMentionRef = useRef(null);
const {isDraggingOver} = useContext(DragAndDropContext);
const prevIsDraggingOver = usePrevious(isDraggingOver);

const getSuggestions = useCallback(() => {
if (suggestionEmojiRef.current && suggestionEmojiRef.current.getSuggestions) {
Expand Down Expand Up @@ -111,6 +115,13 @@ function Suggestions({
[onSelectionChange, resetSuggestions, setShouldBlockSuggestionCalc, triggerHotkeyActions, updateShouldShowSuggestionMenuToFalse, getSuggestions],
);

useEffect(() => {
if (!(!prevIsDraggingOver && isDraggingOver)) {
return;
}
updateShouldShowSuggestionMenuToFalse();
}, [isDraggingOver, prevIsDraggingOver, updateShouldShowSuggestionMenuToFalse]);

const baseProps = {
value,
setValue,
Expand Down

0 comments on commit bd31861

Please sign in to comment.