diff --git a/packages/block-library/src/site-logo/block.json b/packages/block-library/src/site-logo/block.json index 3bdbdc1b809ab1..07855aaa8dc2fb 100644 --- a/packages/block-library/src/site-logo/block.json +++ b/packages/block-library/src/site-logo/block.json @@ -33,6 +33,13 @@ "html": false, "align": true, "alignWide": false, + "__experimentalBorder": { + "color": true, + "radius": true, + "width": true, + "style": true, + "__experimentalSkipSerialization": true + }, "color": { "__experimentalDuotone": "img, .components-placeholder__illustration, .components-placeholder::before", "text": false, @@ -50,6 +57,9 @@ "clientNavigation": true } }, + "selectors": { + "border": ".wp-block-site-logo img, .wp-block-site-logo .components-placeholder, .wp-block-site-logo .wp-block-image__crop-area" + }, "styles": [ { "name": "default", diff --git a/packages/block-library/src/site-logo/edit.js b/packages/block-library/src/site-logo/edit.js index b7e47ec542d1e9..ca092a5390d10d 100644 --- a/packages/block-library/src/site-logo/edit.js +++ b/packages/block-library/src/site-logo/edit.js @@ -40,6 +40,7 @@ import { useBlockProps, store as blockEditorStore, __experimentalImageEditor as ImageEditor, + __experimentalUseBorderProps as useBorderProps, } from '@wordpress/block-editor'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; @@ -54,9 +55,37 @@ import { MIN_SIZE } from '../image/constants'; const ALLOWED_MEDIA_TYPES = [ 'image' ]; const ACCEPT_MEDIA_STRING = 'image/*'; +// If the logo is linked, wrap in an tag to trigger any inherited link element styles. +const ImageWrapper = ( { isLink, href, title, children } ) => { + if ( ! isLink ) { + return children; + } + return ( + event.preventDefault() } + aria-disabled + style={ { + // When the site logo block is linked, + // it's wrapped with a disabled tag. + // Restore cursor style so it doesn't appear 'clickable' + // and remove pointer events. Safari needs the display property. + pointerEvents: 'none', + cursor: 'default', + display: 'inline', + } } + > + { children } + + ); +}; + const SiteLogo = ( { alt, - attributes: { align, width, height, isLink, linkTarget, shouldSyncIcon }, + attributes, isSelected, setAttributes, setLogo, @@ -67,12 +96,16 @@ const SiteLogo = ( { setIcon, canUserEdit, } ) => { + const { align, width, height, isLink, linkTarget, shouldSyncIcon } = + attributes; const isLargeViewport = useViewportMatch( 'medium' ); const isWideAligned = [ 'wide', 'full' ].includes( align ); const isResizable = ! isWideAligned && isLargeViewport; const [ { naturalWidth, naturalHeight }, setNaturalSize ] = useState( {} ); const [ isEditingImage, setIsEditingImage ] = useState( false ); const { toggleSelection } = useDispatch( blockEditorStore ); + const borderProps = useBorderProps( attributes ); + const { imageEditing, maxWidth, title } = useSelect( ( select ) => { const settings = select( blockEditorStore ).getSettings(); const siteEntities = select( coreStore ).getEntityRecord( @@ -93,7 +126,7 @@ const SiteLogo = ( { if ( shouldSyncIcon && logoId !== iconId ) { setAttributes( { shouldSyncIcon: false } ); } - }, [] ); + }, [ iconId, logoId, setAttributes, shouldSyncIcon ] ); useEffect( () => { if ( ! isSelected ) { @@ -112,7 +145,7 @@ const SiteLogo = ( { const img = ( <> { { @@ -121,33 +154,24 @@ const SiteLogo = ( { naturalHeight: event.target.naturalHeight, } ); } } + style={ borderProps.style } /> { isBlobURL( logoUrl ) && } ); - let imgWrapper = img; - - // Disable reason: Image itself is not meant to be interactive, but - // should direct focus to block. - if ( isLink ) { - imgWrapper = ( - /* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */ - event.preventDefault() } - > - { img } - - /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events */ - ); - } - if ( ! isResizable || ! naturalWidth || ! naturalHeight ) { - return
{ imgWrapper }
; + return ( +
+ + { img } + +
+ ); } // Set the default width to a responsible size. @@ -207,20 +231,23 @@ const SiteLogo = ( { const imgEdit = canEditImage && isEditingImage ? ( - { - setLogo( imageAttributes.id ); - } } - onFinishEditing={ () => { - setIsEditingImage( false ); - } } - /> + + { + setLogo( imageAttributes.id ); + } } + onFinishEditing={ () => { + setIsEditingImage( false ); + } } + borderProps={ borderProps } + /> + ) : ( - { imgWrapper } + + { img } + ); @@ -407,6 +440,7 @@ export default function LogoEdit( { isSelected, } ) { const { width, shouldSyncIcon } = attributes; + const borderProps = useBorderProps( attributes ); const { siteLogoId, canUserEdit, @@ -590,9 +624,7 @@ export default function LogoEdit( { className={ placeholderClassName } preview={ logoImage } withIllustration - style={ { - width, - } } + style={ ( width, borderProps.style ) } > { content } @@ -602,6 +634,10 @@ export default function LogoEdit( { const classes = clsx( className, { 'is-default-size': ! width, 'is-transient': temporaryURL, + 'has-custom-border': + !! borderProps.className || + ( borderProps.style && + Object.keys( borderProps.style ).length > 0 ), } ); const blockProps = useBlockProps( { className: classes } ); diff --git a/packages/block-library/src/site-logo/editor.scss b/packages/block-library/src/site-logo/editor.scss index 2f9d1917079bec..521fcaafd771d9 100644 --- a/packages/block-library/src/site-logo/editor.scss +++ b/packages/block-library/src/site-logo/editor.scss @@ -6,11 +6,6 @@ } .wp-block-site-logo { - // Make the block selectable. - a { - pointer-events: none; - } - .custom-logo-link { cursor: inherit; @@ -21,8 +16,10 @@ img { display: block; - height: auto; - max-width: 100%; + } + + .wp-block-image__crop-area { + pointer-events: auto; } &.is-transient { @@ -52,11 +49,13 @@ width: 60px; } + /** // Inherit radius. > div, // A 60px width div shown only in the editor on mobile. .components-resizable-box__container { border-radius: inherit; } + */ // Style the placeholder. .components-placeholder { @@ -64,7 +63,6 @@ justify-content: center; align-items: center; padding: 0; - border-radius: inherit; // Provide a minimum size for the placeholder, for when the logo is resized. // @todo resizing is currently only possible by adding an image, resizing, @@ -108,6 +106,18 @@ } } +// Reduced specificity for the placeholder border radius, +// so that border-radius from global styles can be applied. +:root :where(.wp-block-site-logo .components-placeholder) { + border-radius: inherit; +} + +// Reset the box-sizing for the placeholder to prevent the border +// from covering the logo upload button. +.wp-block-site-logo .components-placeholder.components-placeholder { + box-sizing: initial; +} + .block-library-site-logo__inspector-upload-container { position: relative; // Since there is no option to skip rendering the drag'n'drop icon in drop @@ -165,3 +175,21 @@ height: $grid-unit-50; } } + +// This is necessary for the editor resize handles to accurately work on a non-floated, non-resized logo. +.wp-block-site-logo .components-resizable-box__container { + // Using "display: table" because: + // - it visually hides empty white space in between elements + // - it allows the element to be as wide as its contents (instead of 100% width, as it would be with `display: block`) + display: table; + img { + display: block; + width: inherit; + } +} + +.wp-block-site-logo.has-custom-border { + .wp-block-image__crop-area { + box-sizing: border-box; + } +} diff --git a/packages/block-library/src/site-logo/index.php b/packages/block-library/src/site-logo/index.php index 915563461e30ce..1acc91bd8540aa 100644 --- a/packages/block-library/src/site-logo/index.php +++ b/packages/block-library/src/site-logo/index.php @@ -51,6 +51,22 @@ function render_block_core_site_logo( $attributes ) { } $classnames = array(); + + $border_attributes = block_core_site_logo_get_border_attributes( $attributes ); + if ( $border_attributes ) { + $classnames[] = 'has-custom-border'; + + $processor = new WP_HTML_Tag_Processor( $custom_logo ); + $processor->next_tag( 'img' ); + if ( ! empty( $border_attributes['class'] ) ) { + $processor->add_class( $border_attributes['class'] ); + } + if ( ! empty( $border_attributes['style'] ) ) { + $processor->set_attribute( 'style', $border_attributes['style'] ); + } + $custom_logo = $processor->get_updated_html(); + } + if ( empty( $attributes['width'] ) ) { $classnames[] = 'is-default-size'; } @@ -60,6 +76,49 @@ function render_block_core_site_logo( $attributes ) { return $html; } +/** + * Generates class names and styles to apply the border support styles for + * the site logo block. + * + * @since 6.7.0 + * + * @param array $attributes The block attributes. + * @return array The border-related classnames and styles for the block. + */ +function block_core_site_logo_get_border_attributes( $attributes ) { + $sides = array( 'top', 'right', 'bottom', 'left' ); + $border_styles = array( + 'radius' => $attributes['style']['border']['radius'] ?? null, + 'style' => $attributes['style']['border']['style'] ?? null, + 'width' => $attributes['style']['border']['width'] ?? null, + ); + + // Border color. + $preset_color = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null; + $custom_color = $attributes['style']['border']['color'] ?? null; + $border_styles['color'] = $preset_color ?? $custom_color; + + // Individual border styles e.g. top, left etc. + foreach ( $sides as $side ) { + $border = $attributes['style']['border'][ $side ] ?? null; + $border_styles[ $side ] = array( + 'color' => $border['color'] ?? null, + 'style' => $border['style'] ?? null, + 'width' => $border['width'] ?? null, + ); + } + + $styles = wp_style_engine_get_styles( array( 'border' => $border_styles ) ); + $attributes = array(); + if ( ! empty( $styles['classnames'] ) ) { + $attributes['class'] = $styles['classnames']; + } + if ( ! empty( $styles['css'] ) ) { + $attributes['style'] = $styles['css']; + } + return $attributes; +} + /** * Register a core site setting for a site logo * diff --git a/packages/block-library/src/site-logo/style.scss b/packages/block-library/src/site-logo/style.scss index 020b7aab5370b3..b66d8bf612951d 100644 --- a/packages/block-library/src/site-logo/style.scss +++ b/packages/block-library/src/site-logo/style.scss @@ -18,12 +18,7 @@ img { height: auto; max-width: 100%; - } - - // Inherit border radius from style variations. - a, - img { - border-radius: inherit; + box-sizing: border-box; } &.aligncenter {