-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Update the popover component to rely on useDialog #27675
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3da1da0
d12f92f
f111ad8
651f31c
fc7ffdd
1012fa4
8382ca9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,17 +13,12 @@ import { | |
| forwardRef, | ||
| } from '@wordpress/element'; | ||
| import { getRectangleFromRange } from '@wordpress/dom'; | ||
| import { ESCAPE } from '@wordpress/keycodes'; | ||
| import deprecated from '@wordpress/deprecated'; | ||
| import { | ||
| useViewportMatch, | ||
| useResizeObserver, | ||
| useFocusOnMount, | ||
| __experimentalUseFocusOutside as useFocusOutside, | ||
| useConstrainedTabbing, | ||
| useFocusReturn, | ||
| useMergeRefs, | ||
| useRefEffect, | ||
| __experimentalUseDialog as useDialog, | ||
| } from '@wordpress/compose'; | ||
| import { close } from '@wordpress/icons'; | ||
|
|
||
|
|
@@ -485,97 +480,37 @@ const Popover = ( | |
| __unstableBoundaryParent, | ||
| ] ); | ||
|
|
||
| // Event handlers for closing the popover. | ||
| const closeEventRef = useRefEffect( | ||
| ( node ) => { | ||
| function maybeClose( event ) { | ||
| // Close on escape. | ||
| if ( event.keyCode === ESCAPE && onClose ) { | ||
| event.stopPropagation(); | ||
| onClose(); | ||
| } | ||
| } | ||
|
|
||
| node.addEventListener( 'keydown', maybeClose ); | ||
|
|
||
| return () => { | ||
| node.removeEventListener( 'keydown', maybeClose ); | ||
| }; | ||
| }, | ||
| [ onClose ] | ||
| ); | ||
|
|
||
| const constrainedTabbingRef = useConstrainedTabbing(); | ||
| const focusReturnRef = useFocusReturn(); | ||
| const focusOnMountRef = useFocusOnMount( focusOnMount ); | ||
| const focusOutsideProps = useFocusOutside( handleOnFocusOutside ); | ||
| const mergedRefs = useMergeRefs( [ | ||
| ref, | ||
| containerRef, | ||
| // Don't register the event at all if there's no onClose callback. | ||
| onClose ? closeEventRef : null, | ||
| focusOnMount ? constrainedTabbingRef : null, | ||
| focusOnMount ? focusReturnRef : null, | ||
| focusOnMount ? focusOnMountRef : null, | ||
| ] ); | ||
|
|
||
| /** | ||
| * Shims an onFocusOutside callback to be compatible with a deprecated | ||
| * onClickOutside prop function, if provided. | ||
| * | ||
| * @param {FocusEvent} event Focus event from onFocusOutside. | ||
| */ | ||
| function handleOnFocusOutside( event ) { | ||
| // Defer to given `onFocusOutside` if specified. Call `onClose` only if | ||
| // both `onFocusOutside` and `onClickOutside` are unspecified. Doing so | ||
| // assures backwards-compatibility for prior `onClickOutside` default. | ||
| if ( onFocusOutside ) { | ||
| const onDialogClose = ( type, event ) => { | ||
| // Ideally the popover should have just a single onClose prop and | ||
| // not three props that potentially do the same thing. | ||
| if ( type === 'focus-outside' && onFocusOutside ) { | ||
| onFocusOutside( event ); | ||
| return; | ||
| } else if ( ! onClickOutside ) { | ||
| if ( onClose ) { | ||
| onClose(); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| // Simulate MouseEvent using FocusEvent#relatedTarget as emulated click | ||
| // target. MouseEvent constructor is unsupported in Internet Explorer. | ||
| let clickEvent; | ||
| try { | ||
| clickEvent = new window.MouseEvent( 'click' ); | ||
| } catch ( error ) { | ||
| clickEvent = document.createEvent( 'MouseEvent' ); | ||
| clickEvent.initMouseEvent( | ||
| 'click', | ||
| true, | ||
| true, | ||
| window, | ||
| 0, | ||
| 0, | ||
| 0, | ||
| 0, | ||
| 0, | ||
| false, | ||
| false, | ||
| false, | ||
| false, | ||
| 0, | ||
| null | ||
| ); | ||
| } else if ( type === 'focus-outside' && onClickOutside ) { | ||
| // Simulate MouseEvent using FocusEvent#relatedTarget as emulated click target. | ||
| const clickEvent = new window.MouseEvent( 'click' ); | ||
|
|
||
| Object.defineProperty( clickEvent, 'target', { | ||
| get: () => event.relatedTarget, | ||
| } ); | ||
|
|
||
| deprecated( 'Popover onClickOutside prop', { | ||
| since: '5.3', | ||
| alternative: 'onFocusOutside', | ||
| } ); | ||
|
|
||
| onClickOutside( clickEvent ); | ||
| } else if ( onClose ) { | ||
| onClose(); | ||
| } | ||
| }; | ||
|
|
||
| Object.defineProperty( clickEvent, 'target', { | ||
| get: () => event.relatedTarget, | ||
| } ); | ||
| const [ dialogRef, dialogProps ] = useDialog( { | ||
| focusOnMount, | ||
| __unstableOnClose: onDialogClose, | ||
| onClose: onDialogClose, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the difference between these two?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also mean: do we need to set both here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally we should remove |
||
| } ); | ||
|
|
||
| deprecated( 'Popover onClickOutside prop', { | ||
| since: '5.3', | ||
| alternative: 'onFocusOutside', | ||
| } ); | ||
|
|
||
| onClickOutside( clickEvent ); | ||
| } | ||
| const mergedRefs = useMergeRefs( [ containerRef, dialogRef, ref ] ); | ||
|
|
||
| /** @type {false | string} */ | ||
| const animateClassName = | ||
|
|
@@ -603,8 +538,8 @@ const Popover = ( | |
| } | ||
| ) } | ||
| { ...contentProps } | ||
| { ...focusOutsideProps } | ||
| ref={ mergedRefs } | ||
| { ...dialogProps } | ||
| tabIndex="-1" | ||
| > | ||
| { isExpanded && <ScrollLock /> } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we deprecate this in the future as well, in favour of onClose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like something we could try, I'm not certain yet of the impact.