Add hotkeys to modals (#1305)
* Add hotkeys to modals * fix * fix * remove unnecessary type * restore type * add handleEnter * rename event props
This commit is contained in:
@ -60,10 +60,10 @@ export function ConfirmationModal({
|
||||
|
||||
const handleInputConfimrationValueChange = (value: string) => {
|
||||
setInputConfirmationValue(value);
|
||||
isValueMatchingUserEmail(confirmationValue, value);
|
||||
isValueMatchingInput(confirmationValue, value);
|
||||
};
|
||||
|
||||
const isValueMatchingUserEmail = debounce(
|
||||
const isValueMatchingInput = debounce(
|
||||
(value?: string, inputValue?: string) => {
|
||||
setIsValidValue(Boolean(value && inputValue && value === inputValue));
|
||||
},
|
||||
@ -75,11 +75,12 @@ export function ConfirmationModal({
|
||||
<LayoutGroup>
|
||||
<StyledConfirmationModal
|
||||
isOpen={isOpen}
|
||||
onOutsideClick={() => {
|
||||
onClose={() => {
|
||||
if (isOpen) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
}}
|
||||
onEnter={onConfirmClick}
|
||||
>
|
||||
<H1Title title={title} fontColor={H1TitleFontColor.Primary} />
|
||||
<Section
|
||||
@ -95,7 +96,7 @@ export function ConfirmationModal({
|
||||
onChange={handleInputConfimrationValueChange}
|
||||
placeholder={confirmationPlaceholder}
|
||||
fullWidth
|
||||
key={'email-' + confirmationValue}
|
||||
key={'input-' + confirmationValue}
|
||||
/>
|
||||
</Section>
|
||||
)}
|
||||
|
||||
@ -1,12 +1,17 @@
|
||||
import React, { useRef } from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import {
|
||||
ClickOutsideMode,
|
||||
useListenClickOutside,
|
||||
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
|
||||
import { ModalHotkeyScope } from './types/ModalHotkeyScope';
|
||||
|
||||
const StyledModalDiv = styled(motion.div)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -83,7 +88,9 @@ function ModalFooter({ children, ...restProps }: ModalFooterProps) {
|
||||
type ModalProps = React.PropsWithChildren &
|
||||
React.ComponentProps<'div'> & {
|
||||
isOpen?: boolean;
|
||||
onOutsideClick?: () => void;
|
||||
onClose?: () => void;
|
||||
hotkeyScope?: ModalHotkeyScope;
|
||||
onEnter?: () => void;
|
||||
};
|
||||
|
||||
const modalVariants = {
|
||||
@ -95,22 +102,55 @@ const modalVariants = {
|
||||
export function Modal({
|
||||
isOpen = false,
|
||||
children,
|
||||
onOutsideClick,
|
||||
onClose,
|
||||
hotkeyScope = ModalHotkeyScope.Default,
|
||||
onEnter,
|
||||
...restProps
|
||||
}: ModalProps) {
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [modalRef],
|
||||
callback: () => onOutsideClick?.(),
|
||||
callback: () => onClose?.(),
|
||||
mode: ClickOutsideMode.absolute,
|
||||
});
|
||||
|
||||
if (!isOpen) {
|
||||
return null;
|
||||
}
|
||||
const {
|
||||
goBackToPreviousHotkeyScope,
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
} = usePreviousHotkeyScope();
|
||||
|
||||
return (
|
||||
useScopedHotkeys(
|
||||
[Key.Escape],
|
||||
() => {
|
||||
onClose?.();
|
||||
},
|
||||
hotkeyScope,
|
||||
[onClose],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
[Key.Enter],
|
||||
() => {
|
||||
onEnter?.();
|
||||
},
|
||||
hotkeyScope,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setHotkeyScopeAndMemorizePreviousScope(hotkeyScope);
|
||||
} else {
|
||||
goBackToPreviousHotkeyScope();
|
||||
}
|
||||
}, [
|
||||
goBackToPreviousHotkeyScope,
|
||||
hotkeyScope,
|
||||
isOpen,
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
]);
|
||||
|
||||
return isOpen ? (
|
||||
<StyledBackDrop>
|
||||
<StyledModalDiv
|
||||
// framer-motion seems to have typing problems with refs
|
||||
@ -127,6 +167,8 @@ export function Modal({
|
||||
{children}
|
||||
</StyledModalDiv>
|
||||
</StyledBackDrop>
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
export enum ModalHotkeyScope {
|
||||
Default = 'default',
|
||||
}
|
||||
Reference in New Issue
Block a user