Skip to content

Commit

Permalink
fix: prevent unwanted scrolling when dismissing via outside pointerdo…
Browse files Browse the repository at this point in the history
…wn (#1752)
  • Loading branch information
atomiks committed Jun 23, 2022
1 parent 1589c1d commit 0949185
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
25 changes: 22 additions & 3 deletions packages/react-dom-interactions/src/FloatingFocusManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export interface Props<RT extends ReferenceType = ReferenceType> {
* @see https://floating-ui.com/docs/FloatingFocusManager
*/
export function FloatingFocusManager<RT extends ReferenceType = ReferenceType>({
context: {refs, nodeId, onOpenChange, dataRef},
context: {refs, nodeId, onOpenChange, dataRef, events},
children,
order = ['content'],
endGuard = true,
Expand Down Expand Up @@ -230,6 +230,7 @@ export function FloatingFocusManager<RT extends ReferenceType = ReferenceType>({
return;
}

let returnFocusValue = returnFocus;
const floating = refs.floating.current;
const previouslyFocusedElement = activeElement(getDocument(floating));

Expand All @@ -239,12 +240,30 @@ export function FloatingFocusManager<RT extends ReferenceType = ReferenceType>({
focus(initialFocus.current ?? floating);
}

// Dismissing via outside `pointerdown` should always ignore `returnFocus`
// to prevent unwanted scrolling. The `esc` key will continue to focus the
// reference.
function onDismiss() {
returnFocusValue = false;
}

events.on('dismiss', onDismiss);

return () => {
if (returnFocus && isHTMLElement(previouslyFocusedElement)) {
events.off('dismiss', onDismiss);

if (returnFocusValue && isHTMLElement(previouslyFocusedElement)) {
focus(previouslyFocusedElement);
}
};
}, [preventTabbing, getTabbableElements, initialFocus, returnFocus, refs]);
}, [
preventTabbing,
getTabbableElements,
initialFocus,
returnFocus,
refs,
events,
]);

const isTypeableCombobox = () =>
refs.domReference.current?.getAttribute('role') === 'combobox' &&
Expand Down
13 changes: 4 additions & 9 deletions packages/react-dom-interactions/src/hooks/useDismiss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ export const useDismiss = <RT extends ReferenceType = ReferenceType>(
);
}, [refs]);

const focusReference = React.useCallback(() => {
if (isHTMLElement(refs.domReference.current)) {
refs.domReference.current.focus();
}
}, [refs]);

React.useEffect(() => {
if (!open || !enabled) {
return;
Expand All @@ -61,7 +55,10 @@ export const useDismiss = <RT extends ReferenceType = ReferenceType>(

events.emit('dismiss');
onOpenChangeRef.current(false);
focusReference();

if (isHTMLElement(refs.domReference.current)) {
refs.domReference.current.focus();
}
}
}

Expand All @@ -86,7 +83,6 @@ export const useDismiss = <RT extends ReferenceType = ReferenceType>(

events.emit('dismiss');
onOpenChangeRef.current(false);
focusReference();
}

function onScroll() {
Expand Down Expand Up @@ -135,7 +131,6 @@ export const useDismiss = <RT extends ReferenceType = ReferenceType>(
nodeId,
open,
onOpenChangeRef,
focusReference,
ancestorScroll,
enabled,
bubbles,
Expand Down

0 comments on commit 0949185

Please sign in to comment.