diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index f33d32ed894974..2322d6f48ae73b 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -13,6 +13,7 @@ - `Popover`: Allow legitimate 0 positions to update popover position ([#51320](https://github.com/WordPress/gutenberg/pull/51320)). - `Button`: Remove unnecessary margin from dashicon ([#51395](https://github.com/WordPress/gutenberg/pull/51395)). - `Autocomplete`: Announce how many results are available to screen readers when suggestions list first renders ([#51018](https://github.com/WordPress/gutenberg/pull/51018)). +- `ConfirmDialog`: Ensure onConfirm isn't called an extra time when submitting one of the buttons using the keyboard ([#51730](https://github.com/WordPress/gutenberg/pull/51730)). ### Internal diff --git a/packages/components/src/confirm-dialog/component.tsx b/packages/components/src/confirm-dialog/component.tsx index 92fb3fa08fbb17..b5c6cdf45f99af 100644 --- a/packages/components/src/confirm-dialog/component.tsx +++ b/packages/components/src/confirm-dialog/component.tsx @@ -7,7 +7,7 @@ import type { ForwardedRef, KeyboardEvent } from 'react'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useCallback, useEffect, useState } from '@wordpress/element'; +import { useCallback, useEffect, useRef, useState } from '@wordpress/element'; /** * Internal dependencies @@ -42,6 +42,8 @@ function ConfirmDialog( const cx = useCx(); const wrapperClassName = cx( styles.wrapper ); + const cancelButtonRef = useRef(); + const confirmButtonRef = useRef(); const [ isOpen, setIsOpen ] = useState< boolean >(); const [ shouldSelfClose, setShouldSelfClose ] = useState< boolean >(); @@ -69,7 +71,13 @@ function ConfirmDialog( const handleEnter = useCallback( ( event: KeyboardEvent< HTMLDivElement > ) => { - if ( event.key === 'Enter' ) { + // Avoid triggering the 'confirm' action when a button is focused, + // as this can cause a double submission. + const isConfirmOrCancelButton = + event.target === cancelButtonRef.current || + event.target === confirmButtonRef.current; + + if ( ! isConfirmOrCancelButton && event.key === 'Enter' ) { handleEvent( onConfirm )( event ); } }, @@ -96,12 +104,14 @@ function ConfirmDialog( { children }