Skip to content
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

Use state for dimensions visualizers #33560

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 19 additions & 2 deletions packages/block-editor/src/hooks/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export function DimensionsPanel( props ) {
const isMarginDisabled = useIsMarginDisabled( props );
const isDisabled = useIsDimensionsDisabled( props );
const isSupported = hasDimensionsSupport( props.name );
const createSetVisualizers = ( key ) => ( next ) => {
const { __experimentalSetVisualizers: setVisualizers } = props;
setVisualizers( ( prev ) => ( {
...prev,
[ key ]: typeof next === 'function' ? next( prev?.[ key ] ) : next,
} ) );
};

if ( isDisabled || ! isSupported ) {
return null;
Expand Down Expand Up @@ -81,7 +88,12 @@ export function DimensionsPanel( props ) {
isShownByDefault={ defaultSpacingControls?.padding }
panelId={ props.clientId }
>
<PaddingEdit { ...props } />
<PaddingEdit
{ ...props }
__experimentalSetVisualizer={ createSetVisualizers(
'padding'
) }
/>
</ToolsPanelItem>
) }
{ ! isMarginDisabled && (
Expand All @@ -93,7 +105,12 @@ export function DimensionsPanel( props ) {
isShownByDefault={ defaultSpacingControls?.margin }
panelId={ props.clientId }
>
<MarginEdit { ...props } />
<MarginEdit
{ ...props }
__experimentalSetVisualizer={ createSetVisualizers(
'margin'
) }
/>
</ToolsPanelItem>
) }
{ ! isGapDisabled && (
Expand Down
16 changes: 2 additions & 14 deletions packages/block-editor/src/hooks/margin.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export function MarginEdit( props ) {
name: blockName,
attributes: { style },
setAttributes,
__experimentalSetVisualizer: setVisualizer,
} = props;

const units = useCustomUnits( {
Expand Down Expand Up @@ -124,26 +125,13 @@ export function MarginEdit( props ) {
} );
};

const onChangeShowVisualizer = ( next ) => {
const newStyle = {
...style,
visualizers: {
margin: next,
},
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just use __unstableMarkNextChangeAsNotPersistent here and __unstableMarkLastChangeAsPersistent before the setAttributes at the onChange function? The second action is because of this: https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/store/reducer.js#L497

All changes are considered persistent except when updating the same block attribute as in the previous action.

Copy link
Contributor Author

@ajlende ajlende Sep 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just use __unstableMarkNextChangeAsNotPersistent here and __unstableMarkLastChangeAsPersistent before the setAttributes at the onChange function?

I wasn't aware of these, but after skimming through the code, if I understand it correctly, it looks like they are basically just a complicated way to toggle between triggering the onInput versus onChange props for the BlockEditor. It doesn't really solve the root-cause of this issue—using attributes to store editor-specific data.

I was wondering if the alternative I propose in the comment could be considered and I'm not sure if it is too hacky 😄 .

Using attributes for anything other than properties needed to render the final block is what I think is the hacky part. As long as we're using attributes for editor data, there are always going to be opportunities for bugs like this one to crop up.

This way we could add BoxControlVisualizer to other blocks that use padding support without any other change needed.

The ideal case would be incorporating BoxControlVisualizer directly into the hook so only the block.json needs to be updated for the support. Maybe someone has an idea for how to do that in the overhaul that @aaronrobertshaw mentioned. The changes for blocks using the hook are pretty minimal with this approach, but you're right, they aren't nothing.

The implementation would be simpler for hooks that don't have nested properties. In that simple case, you could just pass setVisualizers from useState directly to __experimentalSetVisualizers, and that could be documented with BoxControlVisualizer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ideal case would be incorporating BoxControlVisualizer directly into the hook so only the block.json needs to be updated for the support.

Exactly!

Also I wasn't able to reproduce adding extra props in style besides the padding ones. Do I have to do something specific?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I wasn't able to reproduce adding extra props in style besides the padding ones. Do I have to do something specific?

Do you mean attributes.style? If so, #31839, has a screen recording and the steps to reproduce the issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ideal case would be incorporating BoxControlVisualizer directly into the hook so only the block.json needs to be updated for the support. Maybe someone has an idea for how to do that in the overhaul that @aaronrobertshaw mentioned.

This might not be so straightforward when the differences between blocks (and their markup) are taken into account. More complicated again, when both padding and margin wish to be visualized.

With the current visualizer, displaying margins is particularly problematic and can require adding a wrapping element which creates a disjoint between the markup in the editor and the frontend.

One previous suggestion on how the visualizer could work was making it not rely on a parent element and instead maybe use a ref/popover.

For the moment, I'd think being able to handle the visualization on a block by block basis would be best.

setAttributes( {
style: cleanEmptyObject( newStyle ),
} );
};

return Platform.select( {
web: (
<>
<BoxControl
values={ style?.spacing?.margin }
onChange={ onChange }
onChangeShowVisualizer={ onChangeShowVisualizer }
onChangeShowVisualizer={ setVisualizer }
label={ __( 'Margin' ) }
sides={ sides }
units={ units }
Expand Down
16 changes: 2 additions & 14 deletions packages/block-editor/src/hooks/padding.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export function PaddingEdit( props ) {
name: blockName,
attributes: { style },
setAttributes,
__experimentalSetVisualizer: setVisualizer,
} = props;

const units = useCustomUnits( {
Expand Down Expand Up @@ -124,26 +125,13 @@ export function PaddingEdit( props ) {
} );
};

const onChangeShowVisualizer = ( next ) => {
const newStyle = {
...style,
visualizers: {
padding: next,
},
};

setAttributes( {
style: cleanEmptyObject( newStyle ),
} );
};

return Platform.select( {
web: (
<>
<BoxControl
values={ style?.spacing?.padding }
onChange={ onChange }
onChangeShowVisualizer={ onChangeShowVisualizer }
onChangeShowVisualizer={ setVisualizer }
label={ __( 'Padding' ) }
sides={ sides }
units={ units }
Expand Down
22 changes: 19 additions & 3 deletions packages/block-editor/src/hooks/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import { useContext, createPortal } from '@wordpress/element';
import { useState, useContext, createPortal } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
import {
getBlockSupport,
Expand Down Expand Up @@ -259,6 +259,14 @@ export function addEditProps( settings ) {
export const withBlockControls = createHigherOrderComponent(
( BlockEdit ) => ( props ) => {
const shouldDisplayControls = useDisplayBlockControls();
const [ visualizers, setVisualizers ] = useState( null );
const createSetVisualizers = ( key ) => ( next ) => {
setVisualizers( ( prev ) => ( {
...prev,
[ key ]:
typeof next === 'function' ? next( prev?.[ key ] ) : next,
} ) );
};

return (
<>
Expand All @@ -267,10 +275,18 @@ export const withBlockControls = createHigherOrderComponent(
<ColorEdit { ...props } />
<TypographyPanel { ...props } />
<BorderPanel { ...props } />
<DimensionsPanel { ...props } />
<DimensionsPanel
{ ...props }
__experimentalSetVisualizers={ createSetVisualizers(
'dimensions'
) }
/>
</>
) }
<BlockEdit { ...props } />
<BlockEdit
{ ...props }
__experimentalStyleVisualizer={ visualizers }
/>
</>
);
},
Expand Down
3 changes: 2 additions & 1 deletion packages/block-library/src/cover/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ function CoverEdit( {
setOverlayColor,
toggleSelection,
markNextChangeAsNotPersistent,
__experimentalStyleVisualizer: styleVisualizer,
} ) {
const {
contentPosition,
Expand Down Expand Up @@ -704,7 +705,7 @@ function CoverEdit( {
>
<BoxControlVisualizer
values={ styleAttribute?.spacing?.padding }
showValues={ styleAttribute?.visualizers?.padding }
showValues={ styleVisualizer?.dimensions?.padding }
className="block-library-cover__padding-visualizer"
/>
<ResizableCover
Expand Down