Skip to content

Commit

Permalink
Further simplify pattern overrides flow (#60769)
Browse files Browse the repository at this point in the history
* Adjust allow pattern overrides UX flow

* Minor tweaks

* Fix e2e tests

* Simplify button text

* Use <Text/>

* Update packages/patterns/src/components/allow-overrides-modal.js

Co-authored-by: Aki Hamano <[email protected]>

* Fix tests

---------
Co-authored-by: kevin940726 <[email protected]>
Co-authored-by: richtabor <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Co-authored-by: jameskoster <[email protected]>
Co-authored-by: SaxonF <[email protected]>
  • Loading branch information
7 people authored Apr 17, 2024
1 parent d4ba8f4 commit 41a483d
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 53 deletions.
89 changes: 70 additions & 19 deletions packages/patterns/src/components/allow-overrides-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,36 @@ import {
__experimentalHStack as HStack,
__experimentalVStack as VStack,
Button,
__experimentalText as Text,
TextControl,
Modal,
} from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { useState, useId } from '@wordpress/element';
import { speak } from '@wordpress/a11y';

export default function AllowOverridesModal( {
export function AllowOverridesModal( {
placeholder,
initialName = '',
onClose,
onSave,
} ) {
const [ editedBlockName, setEditedBlockName ] = useState( '' );
const [ editedBlockName, setEditedBlockName ] = useState( initialName );
const descriptionId = useId();

const isNameValid = !! editedBlockName.trim();

const handleSubmit = () => {
const message = sprintf(
/* translators: %s: new name/label for the block */
__( 'Block name changed to: "%s".' ),
editedBlockName
);
if ( editedBlockName !== initialName ) {
const message = sprintf(
/* translators: %s: new name/label for the block */
__( 'Block name changed to: "%s".' ),
editedBlockName
);

// Must be assertive to immediately announce change.
speak( message, 'assertive' );
// Must be assertive to immediately announce change.
speak( message, 'assertive' );
}
onSave( editedBlockName );

// Immediate close avoids ability to hit save multiple times.
Expand All @@ -39,9 +43,8 @@ export default function AllowOverridesModal( {

return (
<Modal
title={ __( 'Allow overrides' ) }
title={ __( 'Enable overrides' ) }
onRequestClose={ onClose }
overlayClassName="block-editor-block-allow-overrides-modal"
focusOnMount="firstContentElement"
aria={ { describedby: descriptionId } }
size="small"
Expand All @@ -57,18 +60,19 @@ export default function AllowOverridesModal( {
handleSubmit();
} }
>
<p id={ descriptionId }>
{ __( 'Enter a custom name for this block.' ) }
</p>
<VStack spacing="3">
<VStack spacing="6">
<Text id={ descriptionId }>
{ __(
'Overrides are changes you make to a block within a synced pattern instance. Use overrides to customize a synced pattern instance to suit its new context. Name this block to specify an override.'
) }
</Text>
<TextControl
__nextHasNoMarginBottom
__next40pxDefaultSize
value={ editedBlockName }
label={ __( 'Block name' ) }
hideLabelFromVision
label={ __( 'Name' ) }
help={ __(
'This name will be used to denote the override wherever the synced pattern is used. The name here will help people understand its purpose. E.g. if you\'re creating a recipe pattern, it can be "Recipe Title", "Recipe Description", etc.'
'For example, if you are creating a recipe pattern, you use "Recipe Title", "Recipe Description", etc.'
) }
placeholder={ placeholder }
onChange={ setEditedBlockName }
Expand All @@ -88,7 +92,54 @@ export default function AllowOverridesModal( {
variant="primary"
type="submit"
>
{ __( 'Save' ) }
{ __( 'Enable' ) }
</Button>
</HStack>
</VStack>
</form>
</Modal>
);
}

export function DisallowOverridesModal( { onClose, onSave } ) {
const descriptionId = useId();

return (
<Modal
title={ __( 'Disable overrides' ) }
onRequestClose={ onClose }
aria={ { describedby: descriptionId } }
size="small"
>
<form
onSubmit={ ( event ) => {
event.preventDefault();
onSave();
onClose();
} }
>
<VStack spacing="6">
<Text id={ descriptionId }>
{ __(
'Are you sure you want to disable overrides? Disabling overrides will revert all applied overrides for this block throughout instances of this pattern.'
) }
</Text>

<HStack justify="right">
<Button
__next40pxDefaultSize
variant="tertiary"
onClick={ onClose }
>
{ __( 'Cancel' ) }
</Button>

<Button
__next40pxDefaultSize
variant="primary"
type="submit"
>
{ __( 'Disable' ) }
</Button>
</HStack>
</VStack>
Expand Down
71 changes: 39 additions & 32 deletions packages/patterns/src/components/pattern-overrides-controls.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* WordPress dependencies
*/
import { useState, useId, useRef, flushSync } from '@wordpress/element';
import { useState, useId } from '@wordpress/element';
import { InspectorControls } from '@wordpress/block-editor';
import { ToggleControl, BaseControl, Button } from '@wordpress/components';
import { BaseControl, Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
Expand All @@ -13,7 +13,10 @@ import {
PARTIAL_SYNCING_SUPPORTED_BLOCKS,
PATTERN_OVERRIDES_BINDING_SOURCE,
} from '../constants';
import AllowOverridesModal from './allow-overrides-modal';
import {
AllowOverridesModal,
DisallowOverridesModal,
} from './allow-overrides-modal';

function removeBindings( bindings, syncedAttributes ) {
let updatedBindings = {};
Expand Down Expand Up @@ -47,9 +50,10 @@ function addBindings( bindings, syncedAttributes ) {

function PatternOverridesControls( { attributes, name, setAttributes } ) {
const controlId = useId();
const toggleRef = useRef();
const [ showAllowOverridesModal, setShowAllowOverridesModal ] =
useState( false );
const [ showDisallowOverridesModal, setShowDisallowOverridesModal ] =
useState( false );

const syncedAttributes = PARTIAL_SYNCING_SUPPORTED_BLOCKS[ name ];
const attributeSources = syncedAttributes.map(
Expand Down Expand Up @@ -83,7 +87,12 @@ function PatternOverridesControls( { attributes, name, setAttributes } ) {
// Avoid overwriting other (e.g. meta) bindings.
if ( isConnectedToOtherSources ) return null;

const hasName = attributes.metadata?.name;
const hasName = !! attributes.metadata?.name;
const allowOverrides =
hasName &&
attributeSources.some(
( source ) => source === PATTERN_OVERRIDES_BINDING_SOURCE
);

return (
<>
Expand All @@ -92,45 +101,43 @@ function PatternOverridesControls( { attributes, name, setAttributes } ) {
id={ controlId }
label={ __( 'Overrides' ) }
help={ __(
'Allow attributes within this block to be overridden by pattern instances.'
'Allow changes to this block throughout instances of this pattern.'
) }
>
{ hasName ? (
<ToggleControl
__nextHasNoMarginBottom
label={ __( 'Allow overrides' ) }
checked={ attributeSources.some(
( source ) =>
source === PATTERN_OVERRIDES_BINDING_SOURCE
) }
onChange={ ( isChecked ) => {
updateBindings( isChecked );
} }
ref={ toggleRef }
/>
) : (
<Button
className="pattern-overrides-control__allow-overrides-button"
variant="secondary"
onClick={ () => setShowAllowOverridesModal( true ) }
>
{ __( 'Allow overrides' ) }
</Button>
) }
<Button
__next40pxDefaultSize
className="pattern-overrides-control__allow-overrides-button"
variant="secondary"
onClick={ () => {
if ( allowOverrides ) {
setShowDisallowOverridesModal( true );
} else {
setShowAllowOverridesModal( true );
}
} }
>
{ allowOverrides
? __( 'Disable overrides' )
: __( 'Enable overrides' ) }
</Button>
</BaseControl>
</InspectorControls>

{ showAllowOverridesModal && (
<AllowOverridesModal
initialName={ attributes.metadata?.name }
onClose={ () => setShowAllowOverridesModal( false ) }
onSave={ ( newName ) => {
flushSync( () => {
updateBindings( true, newName );
} );
toggleRef.current?.focus();
updateBindings( true, newName );
} }
/>
) }
{ showDisallowOverridesModal && (
<DisallowOverridesModal
onClose={ () => setShowDisallowOverridesModal( false ) }
onSave={ () => updateBindings( false ) }
/>
) }
</>
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/patterns/src/components/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@
width: 100%;
justify-content: center;
}

8 changes: 6 additions & 2 deletions test/e2e/specs/editor/various/pattern-overrides.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,12 @@ test.describe( 'Pattern Overrides', () => {
.getByRole( 'button', { name: 'Advanced' } )
.click();
await editorSettings
.getByRole( 'checkbox', { name: 'Allow overrides' } )
.setChecked( true );
.getByRole( 'button', { name: 'Enable overrides' } )
.click();
await page
.getByRole( 'dialog', { name: 'Enable overrides' } )
.getByRole( 'button', { name: 'Enable' } )
.click();

await expect.poll( editor.getBlocks ).toMatchObject( [
{
Expand Down

0 comments on commit 41a483d

Please sign in to comment.