Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d7dae8a
Site Editor: Disable the revision button if there is no clickable men…
t-hamano Jun 25, 2023
362d148
Improve LinkControl Edit UI (#51712)
richtabor Jun 26, 2023
132f8b9
Update colors (#51856)
jameskoster Jun 26, 2023
844a804
Library: Fix misalignment of description in custom template parts (#5…
t-hamano Jun 26, 2023
9ee0bfd
Backport adding the distraction free mode to the site editor (#51173)…
priethor Jun 27, 2023
ac3de89
Fix toolbar overlap in site editor (#51810)
draganescu Jun 23, 2023
fb8efb9
Page Content Focus: Switch to Page panel when deselecting a block (#5…
noisysocks Jun 26, 2023
553fbed
Don't show 'Back to page' notification when navigating away from page…
noisysocks Jun 27, 2023
bef847d
Add top margin to page details (#51858)
jameskoster Jun 26, 2023
d1a6d07
Keep framer-motion from updating minor version (#51894)
tellthemachines Jun 27, 2023
e58fb9d
useBlockSync(): Reset inner blocks when component unmounts (#51783)
noisysocks Jun 27, 2023
1472d94
BlockLockModal: restore focus on fallback toolbar button when origina…
ciampo Jun 26, 2023
ce38b89
Fix missing MenuGroup in header more menu (#51860)
richtabor Jun 26, 2023
b734da6
Add `manage all custom patterns` command (#51845)
ntsekouras Jun 26, 2023
340833e
Command center: Add another batch of commands to the site editor (#51…
youknowriad Jun 25, 2023
64ed918
Fix delete shortcut incorrectly bound to non-user patterns (#51830)
talldan Jun 23, 2023
60e8c8e
`ConfirmDialog`: Fix affirmative action being triggered an extra time…
talldan Jun 23, 2023
3ead31a
Ensure there is always a Navigation available in the browse mode side…
getdave Jun 23, 2023
d04f19f
Add image block aspect ratio control (#51545)
ajlende Jun 23, 2023
0a92405
Site Editor: Make string to add Template parts & Patterns consistent …
t-hamano Jun 23, 2023
d5014db
Site Editor Sidebar: improvements to buttons (#51762)
ciampo Jun 23, 2023
f315a17
Fix more icons for high resolution devices (#51768)
richtabor Jun 23, 2023
8e544a4
Hide block toolbar using CSS when it is empty (#51779)
noisysocks Jun 23, 2023
62bdc0a
Update the add template modal design (#51806)
jameskoster Jun 23, 2023
bd97387
Buttons Block: Fix for orientation-based block movers (#51831)
t-hamano Jun 23, 2023
a7c4b8f
Button: Introduce `size` prop (#51842)
mirka Jun 23, 2023
000fc8b
Color (#51847)
jameskoster Jun 23, 2023
b64aabb
Only show Page Content Focus commands when in edit mode (#51888)
noisysocks Jun 26, 2023
da17fa8
Add UI commands to the post editor (#51900)
youknowriad Jun 26, 2023
4f0d57f
ZStack: fix component bounding box to match children (#51836)
ciampo Jun 26, 2023
9292d09
Add view patterns plural label. (#51850)
afercia Jun 25, 2023
c3283d6
Fix css styles in block.jsons. (#51866)
spacedmonkey Jun 24, 2023
1a140db
Update active item appearance in Library (#51848)
jameskoster Jun 23, 2023
bd853d5
Fix Rename in Navigation on Browse Mode (#51791)
getdave Jun 23, 2023
be4546d
Fix ability to click through to Template Parts in Library (#51838)
getdave Jun 23, 2023
b909d90
ItemGroup: Update button focus styles to use `:focus-visible` (#51787)
mikachan Jun 23, 2023
a1477d0
Merge branch 'release/16.1' into add/latest-bugfixes-16-1-rc2
tellthemachines Jun 27, 2023
c65eced
Update package-lock
tellthemachines Jun 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ConfirmDialog: Fix affirmative action being triggered an extra time…
… when selecting a button via keyboard (#51730)

* Ensure the confirm dialog cannnot be submitted using enter when the cancel button is focused

* Add test case

* Add CHANGELOG entry

* Add PR number to changelog

* Also prevent double submission of Confirm button

* Use actions in storybook example rather than outputting to a heading
  • Loading branch information
talldan authored and tellthemachines committed Jun 27, 2023
commit 60e8c8e149fab00a93bf649f81790dafa76cd154
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
14 changes: 12 additions & 2 deletions packages/components/src/confirm-dialog/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 >();
Expand Down Expand Up @@ -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 );
}
},
Expand All @@ -96,12 +104,14 @@ function ConfirmDialog(
<Text>{ children }</Text>
<Flex direction="row" justify="flex-end">
<Button
ref={ cancelButtonRef }
variant="tertiary"
onClick={ handleEvent( onCancel ) }
>
{ cancelLabel }
</Button>
<Button
ref={ confirmButtonRef }
variant="primary"
onClick={ handleEvent( onConfirm ) }
>
Expand Down
23 changes: 8 additions & 15 deletions packages/components/src/confirm-dialog/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { useState } from '@wordpress/element';
* Internal dependencies
*/
import Button from '../../button';
import { Heading } from '../../heading';
import { ConfirmDialog } from '..';

const meta = {
Expand All @@ -26,12 +25,8 @@ const meta = {
isOpen: {
control: { type: null },
},
onConfirm: {
control: { type: null },
},
onCancel: {
control: { type: null },
},
onConfirm: { action: 'onConfirm' },
onCancel: { action: 'onCancel' },
},
args: {
children: 'Would you like to privately publish the post now?',
Expand All @@ -43,19 +38,19 @@ const meta = {

export default meta;

const Template = ( args ) => {
const Template = ( { onConfirm, onCancel, ...args } ) => {
const [ isOpen, setIsOpen ] = useState( false );
const [ confirmVal, setConfirmVal ] = useState( '' );

const handleConfirm = () => {
setConfirmVal( 'Confirmed!' );
const handleConfirm = ( ...confirmArgs ) => {
onConfirm( ...confirmArgs );
setIsOpen( false );
};

const handleCancel = () => {
setConfirmVal( 'Cancelled' );
const handleCancel = ( ...cancelArgs ) => {
onCancel( ...cancelArgs );
setIsOpen( false );
};

return (
<>
<Button variant="primary" onClick={ () => setIsOpen( true ) }>
Expand All @@ -70,8 +65,6 @@ const Template = ( args ) => {
>
{ args.children }
</ConfirmDialog>

<Heading level={ 1 }>{ confirmVal }</Heading>
</>
);
};
Expand Down
42 changes: 42 additions & 0 deletions packages/components/src/confirm-dialog/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,48 @@ describe( 'Confirm', () => {
expect( confirmDialog ).not.toBeInTheDocument();
expect( onConfirm ).toHaveBeenCalled();
} );

it( 'calls only the `onCancel` callback and not the `onConfirm` callback when the cancel button is submitted using the keyboard', async () => {
const user = userEvent.setup();

const onConfirm = jest.fn().mockName( 'onConfirm()' );
const onCancel = jest.fn().mockName( 'onCancel()' );

render(
<ConfirmDialog
onConfirm={ onConfirm }
onCancel={ onCancel }
>
Are you sure?
</ConfirmDialog>
);

await user.keyboard( '[Tab][Enter]' );

expect( onConfirm ).not.toHaveBeenCalled();
expect( onCancel ).toHaveBeenCalledTimes( 1 );
} );

it( 'calls only the `onConfirm` callback when the confirm button is submitted using the keyboard', async () => {
const user = userEvent.setup();

const onConfirm = jest.fn().mockName( 'onConfirm()' );
const onCancel = jest.fn().mockName( 'onCancel()' );

render(
<ConfirmDialog
onConfirm={ onConfirm }
onCancel={ onCancel }
>
Are you sure?
</ConfirmDialog>
);

await user.keyboard( '[Tab][Tab][Enter]' );

expect( onConfirm ).toHaveBeenCalledTimes( 1 );
expect( onCancel ).not.toHaveBeenCalled();
} );
} );
} );

Expand Down