diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 7b8e5296c4502..e8df38232306c 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -30,6 +30,7 @@ import PositionControls from '../inspector-controls-tabs/position-controls-panel import useBlockInspectorAnimationSettings from './useBlockInspectorAnimationSettings'; import BlockInfo from '../block-info-slot-fill'; import BlockQuickNavigation from '../block-quick-navigation'; +import { getBorderPanelLabel } from '../../hooks/border'; function BlockInspectorLockedBlocks( { topLevelLockedBlock } ) { const contentClientIds = useSelect( @@ -139,7 +140,9 @@ const BlockInspector = ( { showNoBlockSelectedMessage = true } ) => { /> @@ -248,6 +251,7 @@ const BlockInspectorSingleBlock = ( { clientId, blockName } ) => { [ blockName ] ); const blockInformation = useBlockDisplayInformation( clientId ); + const borderPanelLabel = getBorderPanelLabel( { blockName } ); return (
@@ -300,7 +304,7 @@ const BlockInspectorSingleBlock = ( { clientId, blockName } ) => { /> { label={ __( 'Background' ) } /> -
diff --git a/packages/block-editor/src/components/global-styles/border-panel.js b/packages/block-editor/src/components/global-styles/border-panel.js index a1cbcfd9a01c6..0dee6040c8705 100644 --- a/packages/block-editor/src/components/global-styles/border-panel.js +++ b/packages/block-editor/src/components/global-styles/border-panel.js @@ -7,6 +7,8 @@ import { __experimentalIsDefinedBorder as isDefinedBorder, __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem, + __experimentalItemGroup as ItemGroup, + BaseControl, } from '@wordpress/components'; import { useCallback, useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -17,6 +19,14 @@ import { __ } from '@wordpress/i18n'; import BorderRadiusControl from '../border-radius-control'; import { useColorsPerOrigin } from './hooks'; import { getValueFromVariable, TOOLSPANEL_DROPDOWNMENU_PROPS } from './utils'; +import { mergeOrigins } from '../../store/get-block-settings'; +import { setImmutably } from '../../utils/object'; +import { getBorderPanelLabel } from '../../hooks/border'; +import { ShadowPopover } from './shadow-panel-components'; + +function useHasShadowControl( settings ) { + return !! settings?.shadow; +} export function useHasBorderPanel( settings ) { const controls = [ @@ -24,6 +34,7 @@ export function useHasBorderPanel( settings ) { useHasBorderRadiusControl( settings ), useHasBorderStyleControl( settings ), useHasBorderWidthControl( settings ), + useHasShadowControl( settings ), ]; return controls.some( Boolean ); @@ -51,6 +62,7 @@ function BorderToolsPanel( { value, panelId, children, + label, } ) { const resetAll = () => { const updatedValue = resetAllFilter( value ); @@ -59,7 +71,7 @@ function BorderToolsPanel( { return ( { + const slug = mergedShadowPresets?.find( + ( { shadow: shadowName } ) => shadowName === newValue + )?.slug; + + onChange( + setImmutably( + value, + [ 'shadow' ], + slug ? `var:preset|shadow|${ slug }` : newValue || undefined + ) + ); + }; + const hasShadow = () => !! value?.shadow; + const resetShadow = () => setShadow( undefined ); const resetBorder = () => { if ( hasBorderRadius() ) { @@ -173,18 +210,30 @@ export default function BorderPanel( { return { ...previousValue, border: undefined, + shadow: undefined, }; }, [] ); const showBorderByDefault = defaultControls?.color || defaultControls?.width; + const label = getBorderPanelLabel( { + blockName: name, + hasShadowControl, + hasBorderControl: + showBorderColor || + showBorderStyle || + showBorderWidth || + showBorderRadius, + } ); + return ( { ( showBorderWidth || showBorderColor ) && ( ) } @@ -223,6 +274,26 @@ export default function BorderPanel( { /> ) } + { hasShadowControl && ( + + + { __( 'Shadow' ) } + + + + + + ) } ); } diff --git a/packages/block-editor/src/components/global-styles/effects-panel.js b/packages/block-editor/src/components/global-styles/effects-panel.js deleted file mode 100644 index 4fefed8e3497e..0000000000000 --- a/packages/block-editor/src/components/global-styles/effects-panel.js +++ /dev/null @@ -1,244 +0,0 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - -/** - * WordPress dependencies - */ -import { - __experimentalToolsPanel as ToolsPanel, - __experimentalToolsPanelItem as ToolsPanelItem, - __experimentalItemGroup as ItemGroup, - __experimentalHStack as HStack, - __experimentalVStack as VStack, - __experimentalGrid as Grid, - __experimentalHeading as Heading, - FlexItem, - Dropdown, - __experimentalDropdownContentWrapper as DropdownContentWrapper, - Button, -} from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { useCallback } from '@wordpress/element'; -import { shadow as shadowIcon, Icon, check } from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import { mergeOrigins } from '../../store/get-block-settings'; -import { getValueFromVariable, TOOLSPANEL_DROPDOWNMENU_PROPS } from './utils'; -import { setImmutably } from '../../utils/object'; - -export function useHasEffectsPanel( settings ) { - const hasShadowControl = useHasShadowControl( settings ); - return hasShadowControl; -} - -function useHasShadowControl( settings ) { - return !! settings?.shadow; -} - -function EffectsToolsPanel( { - resetAllFilter, - onChange, - value, - panelId, - children, -} ) { - const resetAll = () => { - const updatedValue = resetAllFilter( value ); - onChange( updatedValue ); - }; - - return ( - - { children } - - ); -} - -const DEFAULT_CONTROLS = { - shadow: true, -}; - -export default function EffectsPanel( { - as: Wrapper = EffectsToolsPanel, - value, - onChange, - inheritedValue = value, - settings, - panelId, - defaultControls = DEFAULT_CONTROLS, -} ) { - const decodeValue = ( rawValue ) => - getValueFromVariable( { settings }, '', rawValue ); - - // Shadow - const hasShadowEnabled = useHasShadowControl( settings ); - const shadow = decodeValue( inheritedValue?.shadow ); - const shadowPresets = settings?.shadow?.presets; - const mergedShadowPresets = shadowPresets - ? mergeOrigins( shadowPresets ) - : []; - const setShadow = ( newValue ) => { - const slug = mergedShadowPresets?.find( - ( { shadow: shadowName } ) => shadowName === newValue - )?.slug; - - onChange( - setImmutably( - value, - [ 'shadow' ], - slug ? `var:preset|shadow|${ slug }` : newValue || undefined - ) - ); - }; - const hasShadow = () => !! value?.shadow; - const resetShadow = () => setShadow( undefined ); - - const resetAllFilter = useCallback( ( previousValue ) => { - return { - ...previousValue, - shadow: undefined, - }; - }, [] ); - - return ( - - { hasShadowEnabled && ( - - - - - - ) } - - ); -} - -const ShadowPopover = ( { shadow, onShadowChange, settings } ) => { - const popoverProps = { - placement: 'left-start', - offset: 36, - shift: true, - }; - - return ( - ( - - - - ) } - /> - ); -}; - -function renderShadowToggle() { - return ( { onToggle, isOpen } ) => { - const toggleProps = { - onClick: onToggle, - className: classnames( { 'is-open': isOpen } ), - 'aria-expanded': isOpen, - }; - - return ( - - ); - }; -} - -function ShadowPopoverContainer( { shadow, onShadowChange, settings } ) { - const defaultShadows = settings?.shadow?.presets?.default; - const themeShadows = settings?.shadow?.presets?.theme; - const defaultPresetsEnabled = settings?.shadow?.defaultPresets; - - const shadows = [ - ...( defaultPresetsEnabled ? defaultShadows : [] ), - ...( themeShadows || [] ), - ]; - - return ( -
- - { __( 'Shadow' ) } - - -
- ); -} - -function ShadowPresets( { presets, activeShadow, onSelect } ) { - return ! presets ? null : ( - - { presets.map( ( { name, slug, shadow } ) => ( - - onSelect( shadow === activeShadow ? undefined : shadow ) - } - shadow={ shadow } - /> - ) ) } - - ); -} - -function ShadowIndicator( { label, isActive, onSelect, shadow } ) { - return ( -
- -
- ); -} diff --git a/packages/block-editor/src/components/global-styles/index.js b/packages/block-editor/src/components/global-styles/index.js index 65392a7636c44..6df4ed512d025 100644 --- a/packages/block-editor/src/components/global-styles/index.js +++ b/packages/block-editor/src/components/global-styles/index.js @@ -21,7 +21,6 @@ export { } from './dimensions-panel'; export { default as BorderPanel, useHasBorderPanel } from './border-panel'; export { default as ColorPanel, useHasColorPanel } from './color-panel'; -export { default as EffectsPanel, useHasEffectsPanel } from './effects-panel'; export { default as FiltersPanel, useHasFiltersPanel } from './filters-panel'; export { default as ImageSettingsPanel, diff --git a/packages/block-editor/src/components/global-styles/shadow-panel-components.js b/packages/block-editor/src/components/global-styles/shadow-panel-components.js new file mode 100644 index 0000000000000..6e4e3a15b184d --- /dev/null +++ b/packages/block-editor/src/components/global-styles/shadow-panel-components.js @@ -0,0 +1,125 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { + __experimentalVStack as VStack, + __experimentalHeading as Heading, + __experimentalGrid as Grid, + __experimentalHStack as HStack, + __experimentalDropdownContentWrapper as DropdownContentWrapper, + Button, + FlexItem, + Dropdown, +} from '@wordpress/components'; +import { shadow as shadowIcon, Icon, check } from '@wordpress/icons'; +/** + * External dependencies + */ +import classNames from 'classnames'; + +export function ShadowPopoverContainer( { shadow, onShadowChange, settings } ) { + const defaultShadows = settings?.shadow?.presets?.default; + const themeShadows = settings?.shadow?.presets?.theme; + const defaultPresetsEnabled = settings?.shadow?.defaultPresets; + + const shadows = [ + ...( defaultPresetsEnabled ? defaultShadows : [] ), + ...( themeShadows || [] ), + ]; + + return ( +
+ + { __( 'Drop shadow' ) } + + +
+ ); +} + +export function ShadowPresets( { presets, activeShadow, onSelect } ) { + return ! presets ? null : ( + + { presets.map( ( { name, slug, shadow } ) => ( + + onSelect( shadow === activeShadow ? undefined : shadow ) + } + shadow={ shadow } + /> + ) ) } + + ); +} + +export function ShadowIndicator( { label, isActive, onSelect, shadow } ) { + return ( +
+ +
+ ); +} + +export function ShadowPopover( { shadow, onShadowChange, settings } ) { + const popoverProps = { + placement: 'left-start', + offset: 36, + shift: true, + }; + + return ( + ( + + + + ) } + /> + ); +} + +function renderShadowToggle() { + return ( { onToggle, isOpen } ) => { + const toggleProps = { + onClick: onToggle, + className: classNames( { 'is-open': isOpen } ), + 'aria-expanded': isOpen, + }; + + return ( + + ); + }; +} diff --git a/packages/block-editor/src/components/global-styles/style.scss b/packages/block-editor/src/components/global-styles/style.scss index 693f1cee762be..010c5faaefff4 100644 --- a/packages/block-editor/src/components/global-styles/style.scss +++ b/packages/block-editor/src/components/global-styles/style.scss @@ -1,13 +1,13 @@ -.block-editor-global-styles-effects-panel__toggle-icon { +.block-editor-global-styles__toggle-icon { fill: currentColor; } -.block-editor-global-styles-effects-panel__shadow-popover-container { +.block-editor-global-styles__shadow-popover-container { width: 230px; } .block-editor-global-styles-filters-panel__dropdown, -.block-editor-global-styles-effects-panel__shadow-dropdown { +.block-editor-global-styles__shadow-dropdown { display: block; padding: 0; @@ -22,7 +22,7 @@ } // wrapper to clip the shadow beyond 6px -.block-editor-global-styles-effects-panel__shadow-indicator-wrapper { +.block-editor-global-styles__shadow-indicator-wrapper { padding: $grid-unit-15 * 0.5; display: flex; align-items: center; @@ -30,7 +30,7 @@ } // These styles are similar to the color palette. -.block-editor-global-styles-effects-panel__shadow-indicator { +.block-editor-global-styles__shadow-indicator { color: $gray-800; border: $gray-200 $border-width solid; border-radius: $radius-block-ui; diff --git a/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js b/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js index 6f24051ea2cfc..6c2556f2378ff 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/styles-tab.js @@ -11,8 +11,11 @@ import { __ } from '@wordpress/i18n'; import BlockStyles from '../block-styles'; import DefaultStylePicker from '../default-style-picker'; import InspectorControls from '../inspector-controls'; +import { getBorderPanelLabel } from '../../hooks/border'; const StylesTab = ( { blockName, clientId, hasBlockStyles } ) => { + const borderPanelLabel = getBorderPanelLabel( { blockName } ); + return ( <> { hasBlockStyles && ( @@ -45,8 +48,7 @@ const StylesTab = ( { blockName, clientId, hasBlockStyles } ) => { group="dimensions" label={ __( 'Dimensions' ) } /> - - + ); diff --git a/packages/block-editor/src/hooks/border.js b/packages/block-editor/src/hooks/border.js index e67105969df81..c743b457fc05c 100644 --- a/packages/block-editor/src/hooks/border.js +++ b/packages/block-editor/src/hooks/border.js @@ -6,7 +6,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { getBlockSupport } from '@wordpress/blocks'; +import { hasBlockSupport, getBlockSupport } from '@wordpress/blocks'; import { __experimentalHasSplitBorders as hasSplitBorders } from '@wordpress/components'; import { Platform, useCallback, useMemo } from '@wordpress/element'; import { addFilter } from '@wordpress/hooks'; @@ -24,8 +24,10 @@ import { BorderPanel as StylesBorderPanel, } from '../components/global-styles'; import { store as blockEditorStore } from '../store'; +import { __ } from '@wordpress/i18n'; export const BORDER_SUPPORT_KEY = '__experimentalBorder'; +export const SHADOW_SUPPORT_KEY = 'shadow'; const getColorByProperty = ( colors, property, value ) => { let matchedColor; @@ -109,7 +111,7 @@ function attributesToStyle( attributes ) { }; } -function BordersInspectorControl( { children, resetAllFilter } ) { +function BordersInspectorControl( { label, children, resetAllFilter } ) { const attributesResetAllFilter = useCallback( ( attributes ) => { const existingStyle = attributesToStyle( attributes ); @@ -126,6 +128,7 @@ function BordersInspectorControl( { children, resetAllFilter } ) { { children } @@ -152,10 +155,16 @@ export function BorderPanel( { clientId, name, setAttributes, settings } ) { return null; } - const defaultControls = getBlockSupport( name, [ - BORDER_SUPPORT_KEY, - '__experimentalDefaultControls', - ] ); + const defaultControls = { + ...getBlockSupport( name, [ + BORDER_SUPPORT_KEY, + '__experimentalDefaultControls', + ] ), + ...getBlockSupport( name, [ + SHADOW_SUPPORT_KEY, + '__experimentalDefaultControls', + ] ), + }; return ( - hasBlockSupport( blockName, key ) - ); -} - -function EffectsInspectorControl( { children, resetAllFilter } ) { - return ( - - { children } - - ); -} -export function EffectsPanel( { clientId, setAttributes, settings } ) { - const isEnabled = useHasEffectsPanel( settings ); - const value = useSelect( - ( select ) => - select( blockEditorStore ).getBlockAttributes( clientId )?.style, - [ clientId ] - ); - - const onChange = ( newStyle ) => { - setAttributes( { style: cleanEmptyObject( newStyle ) } ); - }; - - if ( ! isEnabled ) { - return null; - } - - return ( - - ); -} diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index 42fe431a40b24..dad62bc0594a7 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -15,7 +15,7 @@ import { getCSSRules, compileCSS } from '@wordpress/style-engine'; * Internal dependencies */ import { BACKGROUND_SUPPORT_KEY, BackgroundImagePanel } from './background'; -import { BORDER_SUPPORT_KEY, BorderPanel } from './border'; +import { BORDER_SUPPORT_KEY, BorderPanel, SHADOW_SUPPORT_KEY } from './border'; import { COLOR_SUPPORT_KEY, ColorEdit } from './color'; import { TypographyPanel, @@ -27,11 +27,6 @@ import { SPACING_SUPPORT_KEY, DimensionsPanel, } from './dimensions'; -import { - EFFECTS_SUPPORT_KEYS, - SHADOW_SUPPORT_KEY, - EffectsPanel, -} from './effects'; import { shouldSkipSerialization, useStyleOverride, @@ -42,12 +37,12 @@ import { useBlockEditingMode } from '../components/block-editing-mode'; const styleSupportKeys = [ ...TYPOGRAPHY_SUPPORT_KEYS, - ...EFFECTS_SUPPORT_KEYS, BORDER_SUPPORT_KEY, COLOR_SUPPORT_KEY, DIMENSIONS_SUPPORT_KEY, BACKGROUND_SUPPORT_KEY, SPACING_SUPPORT_KEY, + SHADOW_SUPPORT_KEY, ]; const hasStyleSupport = ( nameOrType ) => @@ -349,7 +344,6 @@ function BlockStyleControls( { - ); } diff --git a/packages/block-editor/src/hooks/test/effects.js b/packages/block-editor/src/hooks/test/effects.js deleted file mode 100644 index b4fe61745744b..0000000000000 --- a/packages/block-editor/src/hooks/test/effects.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Internal dependencies - */ -import { hasEffectsSupport } from '../effects'; - -describe( 'effects', () => { - describe( 'hasEffectsSupport', () => { - it( 'should return false if the block does not support effects', () => { - const settings = { - supports: { - shadow: false, - }, - }; - - expect( hasEffectsSupport( settings ) ).toBe( false ); - } ); - - it( 'should return true if the block supports effects', () => { - const settings = { - supports: { - shadow: true, - }, - }; - - expect( hasEffectsSupport( settings ) ).toBe( true ); - } ); - - it( 'should return true if the block supports effects and other features', () => { - const settings = { - supports: { - shadow: true, - align: true, - }, - }; - - expect( hasEffectsSupport( settings ) ).toBe( true ); - } ); - } ); -} ); diff --git a/packages/edit-site/src/components/global-styles/screen-block.js b/packages/edit-site/src/components/global-styles/screen-block.js index aaeb1a4a833fa..570b465b10eea 100644 --- a/packages/edit-site/src/components/global-styles/screen-block.js +++ b/packages/edit-site/src/components/global-styles/screen-block.js @@ -64,7 +64,6 @@ const { useGlobalSetting, useSettingsForBlockElement, useHasColorPanel, - useHasEffectsPanel, useHasFiltersPanel, useHasImageSettingsPanel, useGlobalStyle, @@ -72,7 +71,6 @@ const { ColorPanel: StylesColorPanel, TypographyPanel: StylesTypographyPanel, DimensionsPanel: StylesDimensionsPanel, - EffectsPanel: StylesEffectsPanel, FiltersPanel: StylesFiltersPanel, ImageSettingsPanel, AdvancedPanel: StylesAdvancedPanel, @@ -124,7 +122,6 @@ function ScreenBlock( { name, variation } ) { const hasColorPanel = useHasColorPanel( settings ); const hasBorderPanel = useHasBorderPanel( settings ); const hasDimensionsPanel = useHasDimensionsPanel( settings ); - const hasEffectsPanel = useHasEffectsPanel( settings ); const hasFiltersPanel = useHasFiltersPanel( settings ); const hasImageSettingsPanel = useHasImageSettingsPanel( name, @@ -279,15 +276,6 @@ function ScreenBlock( { name, variation } ) { settings={ settings } /> ) } - { hasEffectsPanel && ( - - ) } { hasFiltersPanel && ( +