Make ESC key dismiss MediaEditor and TextStoryCreator modals

This commit is contained in:
Alvaro 2022-08-15 13:35:30 -06:00 committed by GitHub
parent 385eb63fd5
commit 95be24e8f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 9 deletions

View file

@ -97,6 +97,8 @@ export const MediaEditor = ({
}: PropsType): JSX.Element | null => {
const [fabricCanvas, setFabricCanvas] = useState<fabric.Canvas | undefined>();
const [image, setImage] = useState<HTMLImageElement>(new Image());
const [isStickerPopperOpen, setIsStickerPopperOpen] =
useState<boolean>(false);
const canvasId = useUniqueId();
@ -147,6 +149,8 @@ export const MediaEditor = ({
};
}, [canvasId, fabricCanvas, imageSrc, onClose, takeSnapshot]);
const [editMode, setEditMode] = useState<EditMode | undefined>();
// Keyboard support
useEffect(() => {
if (!fabricCanvas) {
@ -173,7 +177,19 @@ export const MediaEditor = ({
[
ev => ev.key === 'Escape',
() => {
setEditMode(undefined);
// close window if the user is not in the middle of something
if (editMode === undefined) {
// if the stickers popper is open,
// it will use the escape key to close itself
//
// there's no easy way to prevent an ESC meant for the
// sticker-picker from hitting this handler first
if (!isStickerPopperOpen) {
onClose();
}
} else {
setEditMode(undefined);
}
if (fabricCanvas.getActiveObject()) {
fabricCanvas.discardActiveObject();
@ -307,7 +323,14 @@ export const MediaEditor = ({
return () => {
document.removeEventListener('keydown', handleKeydown);
};
}, [fabricCanvas, redoIfPossible, undoIfPossible]);
}, [
fabricCanvas,
editMode,
isStickerPopperOpen,
onClose,
redoIfPossible,
undoIfPossible,
]);
const [containerWidth, setContainerWidth] = useState(0);
const [containerHeight, setContainerHeight] = useState(0);
@ -349,7 +372,6 @@ export const MediaEditor = ({
const [cropAspectRatioLock, setCropAspectRatioLock] = useState(false);
const [drawTool, setDrawTool] = useState<DrawTool>(DrawTool.Pen);
const [drawWidth, setDrawWidth] = useState<DrawWidth>(DrawWidth.Regular);
const [editMode, setEditMode] = useState<EditMode | undefined>();
const [sliderValue, setSliderValue] = useState<number>(0);
const [textStyle, setTextStyle] = useState<TextStyle>(TextStyle.Regular);
@ -921,6 +943,9 @@ export const MediaEditor = ({
MediaEditor__control: true,
'MediaEditor__control--sticker': true,
})}
onOpenStateChanged={value => {
setIsStickerPopperOpen(value);
}}
clearInstalledStickerPack={noop}
clearShowIntroduction={() => {
// We're using this as a callback for when the sticker button

View file

@ -214,9 +214,19 @@ export const TextStoryCreator = ({
};
const handleEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
setIsColorPickerShowing(false);
event.preventDefault();
event.stopPropagation();
if (
isColorPickerShowing ||
isEditingText ||
isLinkPreviewInputShowing
) {
setIsColorPickerShowing(false);
setIsEditingText(false);
setIsLinkPreviewInputShowing(false);
event.preventDefault();
event.stopPropagation();
} else {
onClose();
}
}
};
@ -227,7 +237,13 @@ export const TextStoryCreator = ({
document.removeEventListener('click', handleOutsideClick);
document.removeEventListener('keydown', handleEscape);
};
}, [isColorPickerShowing, colorPickerPopperButtonRef]);
}, [
isColorPickerShowing,
isEditingText,
isLinkPreviewInputShowing,
colorPickerPopperButtonRef,
onClose,
]);
const sliderColorNumber = getRGBANumber(sliderValue);

View file

@ -26,6 +26,7 @@ export type OwnProps = {
readonly knownPacks: ReadonlyArray<StickerPackType>;
readonly installedPack?: StickerPackType | null;
readonly recentStickers: ReadonlyArray<StickerType>;
readonly onOpenStateChanged?: (isOpen: boolean) => void;
readonly clearInstalledStickerPack: () => unknown;
readonly onClickAddPack?: () => unknown;
readonly onPickSticker: (
@ -51,6 +52,7 @@ export const StickerButton = React.memo(
onClickAddPack,
onPickSticker,
recentStickers,
onOpenStateChanged,
receivedPacks,
installedPack,
installedPacks,
@ -63,7 +65,16 @@ export const StickerButton = React.memo(
position = 'top-end',
theme,
}: Props) => {
const [open, setOpen] = React.useState(false);
const [open, internalSetOpen] = React.useState(false);
const setOpen = React.useCallback(
(value: boolean) => {
internalSetOpen(value);
if (onOpenStateChanged) onOpenStateChanged(value);
},
[internalSetOpen, onOpenStateChanged]
);
const [popperRoot, setPopperRoot] = React.useState<HTMLElement | null>(
null
);
@ -110,7 +121,7 @@ export const StickerButton = React.memo(
clearShowPickerHint();
}
onClickAddPack?.();
}, [onClickAddPack, showPickerHint, clearShowPickerHint]);
}, [onClickAddPack, showPickerHint, setOpen, clearShowPickerHint]);
const handleClearIntroduction = React.useCallback(() => {
clearInstalledStickerPack();