mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
fix: ESC for back in SharePopover not working (#11662)
* fix: ESC for back in SharePopover not working closes #11656 * Normalize prevent default callbacks
This commit is contained in:
@@ -3,6 +3,7 @@ import { actionToMenuItem } from "~/actions";
|
||||
import useActionContext from "~/hooks/useActionContext";
|
||||
import useMobile from "~/hooks/useMobile";
|
||||
import type { ActionVariant, ActionWithChildren } from "~/types";
|
||||
import { preventDefault } from "~/utils/events";
|
||||
import { toMenuItems } from "./transformer";
|
||||
import { observer } from "mobx-react";
|
||||
import { useComputed } from "~/hooks/useComputed";
|
||||
@@ -61,11 +62,6 @@ export const ContextMenu = observer(
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleCloseAutoFocus = React.useCallback(
|
||||
(e: Event) => e.preventDefault(),
|
||||
[]
|
||||
);
|
||||
|
||||
if (isMobile || !action || menuItems.length === 0) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
@@ -80,7 +76,7 @@ export const ContextMenu = observer(
|
||||
aria-label={ariaLabel}
|
||||
onAnimationStart={disablePointerEvents}
|
||||
onAnimationEnd={enablePointerEvents}
|
||||
onCloseAutoFocus={handleCloseAutoFocus}
|
||||
onCloseAutoFocus={preventDefault}
|
||||
>
|
||||
{content}
|
||||
</MenuContent>
|
||||
|
||||
@@ -13,6 +13,7 @@ import { MenuProvider } from "~/components/primitives/Menu/MenuContext";
|
||||
import { actionToMenuItem } from "~/actions";
|
||||
import useActionContext from "~/hooks/useActionContext";
|
||||
import useMobile from "~/hooks/useMobile";
|
||||
import { preventDefault } from "~/utils/events";
|
||||
import type {
|
||||
ActionVariant,
|
||||
ActionWithChildren,
|
||||
@@ -98,11 +99,6 @@ export const DropdownMenu = observer(
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleCloseAutoFocus = React.useCallback(
|
||||
(e: Event) => e.preventDefault(),
|
||||
[]
|
||||
);
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
<MobileDropdown
|
||||
@@ -129,7 +125,7 @@ export const DropdownMenu = observer(
|
||||
aria-label={ariaLabel}
|
||||
onAnimationStart={disablePointerEvents}
|
||||
onAnimationEnd={enablePointerEvents}
|
||||
onCloseAutoFocus={handleCloseAutoFocus}
|
||||
onCloseAutoFocus={preventDefault}
|
||||
>
|
||||
{content}
|
||||
{append}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import { id as bodyContentId } from "~/components/SkipNavContent";
|
||||
import useKeyDown from "~/hooks/useKeyDown";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import { preventDefault } from "~/utils/events";
|
||||
import type { SearchResult } from "~/types";
|
||||
import SearchListItem from "./SearchListItem";
|
||||
|
||||
@@ -230,7 +231,7 @@ function SearchPopover({ shareId, className }: Props) {
|
||||
align="start"
|
||||
shrink
|
||||
onEscapeKeyDown={handleEscapeList}
|
||||
onOpenAutoFocus={(e) => e.preventDefault()}
|
||||
onOpenAutoFocus={preventDefault}
|
||||
onInteractOutside={(event) => {
|
||||
const target = event.target as Element | null;
|
||||
if (target === searchInputRef.current) {
|
||||
|
||||
@@ -63,9 +63,14 @@ window.addEventListener("keydown", (event) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Track whether defaultPrevented was already set by an external handler (e.g.
|
||||
// Radix UI's DismissableLayer) so we only break on preventDefault calls made
|
||||
// by our own callbacks.
|
||||
const wasDefaultPrevented = event.defaultPrevented;
|
||||
|
||||
// reverse so that the last registered callbacks get executed first
|
||||
for (const registered of callbacks.reverse()) {
|
||||
if (event.defaultPrevented === true) {
|
||||
for (const registered of [...callbacks].reverse()) {
|
||||
if (!wasDefaultPrevented && event.defaultPrevented) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import useCurrentTeam from "~/hooks/useCurrentTeam";
|
||||
import useMobile from "~/hooks/useMobile";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import { preventDefault } from "~/utils/events";
|
||||
import lazyWithRetry from "~/utils/lazyWithRetry";
|
||||
|
||||
const SharePopover = lazyWithRetry(
|
||||
@@ -64,6 +65,7 @@ function ShareButton({ collection }: Props) {
|
||||
minHeight={175}
|
||||
side="bottom"
|
||||
align="end"
|
||||
onEscapeKeyDown={preventDefault}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<SharePopover
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from "~/components/primitives/Popover";
|
||||
import useMobile from "~/hooks/useMobile";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import { preventDefault } from "~/utils/events";
|
||||
import lazyWithRetry from "~/utils/lazyWithRetry";
|
||||
|
||||
const SharePopover = lazyWithRetry(
|
||||
@@ -58,6 +59,7 @@ function ShareButton({ document }: Props) {
|
||||
minHeight={175}
|
||||
side="bottom"
|
||||
align="end"
|
||||
onEscapeKeyDown={preventDefault}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<SharePopover
|
||||
|
||||
@@ -28,6 +28,7 @@ import usePaginatedRequest from "~/hooks/usePaginatedRequest";
|
||||
import useQuery from "~/hooks/useQuery";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import type { PaginationParams, SearchResult } from "~/types";
|
||||
import { preventDefault } from "~/utils/events";
|
||||
import { searchPath } from "~/utils/routeHelpers";
|
||||
import { decodeURIComponentSafe } from "~/utils/urls";
|
||||
import CollectionFilter from "./components/CollectionFilter";
|
||||
@@ -251,11 +252,7 @@ function Search() {
|
||||
<RegisterKeyDown trigger="Escape" handler={history.goBack} />
|
||||
{loading && <LoadingIndicator />}
|
||||
<ResultsWrapper column auto>
|
||||
<form
|
||||
method="GET"
|
||||
action={searchPath()}
|
||||
onSubmit={(ev) => ev.preventDefault()}
|
||||
>
|
||||
<form method="GET" action={searchPath()} onSubmit={preventDefault}>
|
||||
<SearchInput
|
||||
name="query"
|
||||
key={query ? "search" : "recent"}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Calls preventDefault on the event. Useful as a stable callback reference.
|
||||
*
|
||||
* @param event the event to prevent default on.
|
||||
*/
|
||||
export const preventDefault = (event: { preventDefault: () => void }) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
Reference in New Issue
Block a user