diff --git a/packages/react-interactions/events/src/dom/Focus.js b/packages/react-interactions/events/src/dom/Focus.js index 434ac2370fa3b..8ce9921e5d906 100644 --- a/packages/react-interactions/events/src/dom/Focus.js +++ b/packages/react-interactions/events/src/dom/Focus.js @@ -49,6 +49,7 @@ type FocusEventType = 'focus' | 'blur' | 'focuschange' | 'focusvisiblechange'; type FocusWithinProps = { disabled?: boolean, + onFocusWithin?: (e: FocusEvent) => void, onBlurWithin?: (e: FocusEvent) => void, onFocusWithinChange?: boolean => void, onFocusWithinVisibleChange?: boolean => void, @@ -57,7 +58,8 @@ type FocusWithinProps = { type FocusWithinEventType = | 'focuswithinvisiblechange' | 'focuswithinchange' - | 'blurwithin'; + | 'blurwithin' + | 'focuswithin'; /** * Shared between Focus and FocusWithin @@ -239,6 +241,26 @@ function dispatchBlurEvents( } } +function dispatchFocusWithinEvents( + context: ReactDOMResponderContext, + event: ReactDOMResponderEvent, + props: FocusWithinProps, + state: FocusState, +) { + const pointerType = state.pointerType; + const target = ((state.focusTarget: any): Element | Document) || event.target; + const onFocusWithin = (props.onFocusWithin: any); + if (isFunction(onFocusWithin)) { + const syntheticEvent = createFocusEvent( + context, + 'focuswithin', + target, + pointerType, + ); + context.dispatchEvent(syntheticEvent, onFocusWithin, DiscreteEvent); + } +} + function dispatchBlurWithinEvents( context: ReactDOMResponderContext, event: ReactDOMResponderEvent, @@ -474,6 +496,7 @@ const focusWithinResponderImpl = { state.isFocusVisible = isGlobalFocusVisible; dispatchFocusWithinVisibleChangeEvent(context, props, state, true); } + dispatchFocusWithinEvents(context, event, props, state); break; } case 'blur': {