From 8ebab4b40b1a7b00ebda8d9a74e8ec7b50066ee1 Mon Sep 17 00:00:00 2001 From: Stephen Haberman Date: Fri, 30 Aug 2024 17:50:25 -0500 Subject: [PATCH] feat: Add TextField.onEscapeBubble. --- src/inputs/TextField.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/inputs/TextField.tsx b/src/inputs/TextField.tsx index 8c1d5566a..159981feb 100644 --- a/src/inputs/TextField.tsx +++ b/src/inputs/TextField.tsx @@ -12,6 +12,16 @@ export interface TextFieldProps extends BeamTextFieldProps { clearable?: boolean; api?: MutableRefObject; onEnter?: VoidFunction; + /** + * Allows a TextField to opt-in to bubbling up the escape key event to its parent. + * + * Usually this is a bad idea, because escape-in-a-modal might lose the user's WIP (without + * sufficient "are you sure" checking), and so instead we let callers opt-in to this. + * + * Note that react-aria's `useSearchField` / `useComboBox` seems to have this built-in: + * https://github.com/adobe/react-spectrum/issues/5480 + */ + onEscapeBubble?: boolean; endAdornment?: ReactNode; startAdornment?: ReactNode; hideErrorMessage?: boolean; @@ -28,6 +38,7 @@ export function TextField>(props: TextFieldProps onFocus, api, onEnter, + onEscapeBubble, hideErrorMessage, ...otherProps } = props; @@ -50,6 +61,9 @@ export function TextField>(props: TextFieldProps if (e.key === "Enter") { maybeCall(onEnter); inputRef.current?.blur(); + } else if (e.key === "Escape" && onEscapeBubble) { + // Allow closing modals from within text fields... + e.continuePropagation(); } }, },