Skip to content

Commit

Permalink
Update BlockStyles control
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Jan 11, 2024
1 parent a77a3ee commit 4299abf
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
Button,
ColorIndicator,
Dropdown,
Flex,
FlexItem,
Icon,
MenuGroup,
MenuItem,
__experimentalHStack as HStack,
__experimentalZStack as ZStack,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { check } from '@wordpress/icons';

const checkIcon = <Icon icon={ check } size={ 24 } />;
const noop = () => undefined;

function BlockStyleColorIndicator( { blockStyle } ) {
const { background, gradient, text } = blockStyle?.styles?.color || {};
const label = blockStyle?.label || blockStyle?.name;

return (
<HStack justify="flex-start">
<ZStack isLayered={ false } offset={ -8 }>
<Flex expanded={ false }>
<ColorIndicator colorValue={ gradient ?? background } />
</Flex>
<Flex expanded={ false }>
<ColorIndicator colorValue={ text } />
</Flex>
</ZStack>
<FlexItem title={ label }>{ label }</FlexItem>
</HStack>
);
}

function BlockStylesDropdownToggle( { onToggle, isOpen, blockStyle } ) {
const toggleProps = {
onClick: onToggle,
className: classnames( 'block-editor-block-styles__dropdown-toggle', {
'is-open': isOpen,
} ),
'aria-expanded': isOpen,
'aria-label': __( 'Block style options' ),
};

return (
<Button __next40pxDefaultSize { ...toggleProps }>
<BlockStyleColorIndicator blockStyle={ blockStyle } />
</Button>
);
}

function BlockStylesDropdownContent( {
activeStyle,
handlePreview,
onSelect,
styles,
} ) {
return (
<MenuGroup
className="block-editor-block-styles__dropdown-group"
label={ __( 'Block styles' ) }
>
{ styles.map( ( style ) => {
const isSelected = activeStyle?.name === style.name;

return (
<MenuItem
isSelected={ isSelected }
key={ style.name }
onBlur={ () => handlePreview( null ) }
onClick={ () => onSelect( style ) }
onFocus={ () => handlePreview( style ) }
onMouseEnter={ () => handlePreview( style ) }
onMouseLeave={ () => handlePreview( null ) }
role="menuitemradio"
suffix={ isSelected ? checkIcon : undefined }
>
<BlockStyleColorIndicator blockStyle={ style } />
</MenuItem>
);
} ) }
</MenuGroup>
);
}

export default function BlockStylesDropdown( {
className,
handlePreview = noop,
onSelect = noop,
styles,
value,
...props
} ) {
if ( ! styles?.length ) {
return null;
}

const classes = classnames(
className,
'block-editor-block-styles__dropdown'
);

return (
<Dropdown
{ ...props }
label={ __( 'Block styles' ) }
className={ classes }
renderToggle={ ( toggleProps ) => (
<BlockStylesDropdownToggle
{ ...toggleProps }
blockStyle={ value }
/>
) }
renderContent={ ( contentProps ) => (
<BlockStylesDropdownContent
{ ...contentProps }
activeStyle={ value }
handlePreview={ handlePreview }
onSelect={ onSelect }
styles={ styles }
/>
) }
/>
);
}
52 changes: 8 additions & 44 deletions packages/block-editor/src/components/block-styles/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { debounce, useViewportMatch } from '@wordpress/compose';
import {
Button,
__experimentalTruncate as Truncate,
Popover,
} from '@wordpress/components';
import { Popover } from '@wordpress/components';

/**
* Internal dependencies
*/
import BlockStylesDropdown from './block-styles-dropdown';
import BlockStylesPreviewPanel from './preview-panel';
import useStylesForBlocks from './use-styles-for-block';

Expand Down Expand Up @@ -61,40 +53,12 @@ function BlockStyles( { clientId, onSwitch = noop, onHoverClassName = noop } ) {

return (
<div className="block-editor-block-styles">
<div className="block-editor-block-styles__variants">
{ stylesToRender.map( ( style ) => {
const buttonText = style.label || style.name;

return (
<Button
__next40pxDefaultSize
className={ classnames(
'block-editor-block-styles__item',
{
'is-active':
activeStyle.name === style.name,
}
) }
key={ style.name }
variant="secondary"
label={ buttonText }
onMouseEnter={ () => styleItemHandler( style ) }
onFocus={ () => styleItemHandler( style ) }
onMouseLeave={ () => styleItemHandler( null ) }
onBlur={ () => styleItemHandler( null ) }
onClick={ () => onSelectStylePreview( style ) }
aria-current={ activeStyle.name === style.name }
>
<Truncate
numberOfLines={ 1 }
className="block-editor-block-styles__item-text"
>
{ buttonText }
</Truncate>
</Button>
);
} ) }
</div>
<BlockStylesDropdown
handlePreview={ styleItemHandler }
onSelect={ onSelectStylePreview }
styles={ stylesToRender }
value={ activeStyle }
/>
{ hoveredStyle && ! isMobileViewport && (
<Popover
placement="left-start"
Expand Down
49 changes: 6 additions & 43 deletions packages/block-editor/src/components/block-styles/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,12 @@
}
}

.block-editor-block-styles__variants {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: $grid-unit-10;

button.components-button.block-editor-block-styles__item {
color: $gray-900;
box-shadow: inset 0 0 0 $border-width $gray-300;
display: inline-block;
width: calc(50% - #{$grid-unit-05});

&:hover {
color: var(--wp-admin-theme-color);
box-shadow: inset 0 0 0 $border-width $gray-300;
}

&.is-active,
&.is-active:hover {
background-color: $gray-900;
box-shadow: none;
}

&.is-active .block-editor-block-styles__item-text,
&.is-active:hover .block-editor-block-styles__item-text {
color: $white;
}

&:focus,
&.is-active:focus {
@include block-toolbar-button-style__focus();
}
}

.block-editor-block-styles__item-text {
word-break: break-all;
// The Button component is white-space: nowrap, and that won't work with line-clamp.
white-space: normal;

// Without this, the ellipsis can sometimes be partially hidden by the Button padding.
text-align: start;
text-align-last: center;
}
.block-editor-block-styles__dropdown {
width: 100%;
}
.block-editor-block-styles__dropdown-toggle {
box-shadow: inset 0 0 0 $border-width $gray-300;
width: 100%;
}

// To prevent overflow in the preview container,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,35 @@ function useGenericPreviewBlock( block, type ) {
*/
export default function useStylesForBlocks( { clientId, onSwitch } ) {
const selector = ( select ) => {
const { getBlock } = select( blockEditorStore );
const { getBlock, getSettings } = select( blockEditorStore );
const block = getBlock( clientId );

if ( ! block ) {
return {};
}
const blockType = getBlockType( block.name );
const { getBlockStyles } = select( blocksStore );
const styles = getBlockStyles( block.name );

// Add theme.json styles for each block style if available.
// These will be used to customize the block style control
// For example, by displaying color swatches.
const variations =
getSettings().__experimentalStyles?.blocks?.[ block.name ]
?.variations ?? {};

if ( variations ) {
styles?.forEach( ( style, index ) => {
if ( variations[ style.name ] ) {
styles[ index ].styles = variations[ style.name ];
}
} );
}

return {
block,
blockType,
styles: getBlockStyles( block.name ),
styles,
className: block.attributes.className || '',
};
};
Expand Down

0 comments on commit 4299abf

Please sign in to comment.