diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/auto-block-preview.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/auto-block-preview.tsx index 739d86c8df8..b438be89852 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/auto-block-preview.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/auto-block-preview.tsx @@ -6,7 +6,7 @@ * External dependencies */ import { useResizeObserver, pure, useRefEffect } from '@wordpress/compose'; -import { useContext } from '@wordpress/element'; +import { useContext, useMemo, useState } from '@wordpress/element'; import { Disabled } from '@wordpress/components'; import { __unstableEditorStyles as EditorStyles, @@ -36,6 +36,7 @@ const { Provider: DisabledProvider } = Disabled.Context; let MemoizedBlockList: typeof BlockList | undefined; const { useGlobalSetting } = unlock( blockEditorPrivateApis ); +const MAX_HEIGHT = 2000; export type ScaledBlockPreviewProps = { viewportWidth?: number; @@ -49,6 +50,8 @@ export type ScaledBlockPreviewProps = { onClickNavigationItem: ( event: MouseEvent ) => void; isNavigable?: boolean; isScrollable?: boolean; + autoScale?: boolean; + setLogoBlockContext?: boolean; }; function ScaledBlockPreview( { @@ -59,12 +62,16 @@ function ScaledBlockPreview( { onClickNavigationItem, isNavigable = false, isScrollable = true, + autoScale = true, + setLogoBlockContext = false, }: ScaledBlockPreviewProps ) { + const [ contentHeight, setContentHeight ] = useState< number | null >( + null + ); const { setLogoBlockIds } = useContext( LogoBlockContext ); const [ fontFamilies ] = useGlobalSetting( 'typography.fontFamilies.theme' ) as [ FontFamily[] ]; - const externalFontFamilies = fontFamilies.filter( ( { slug } ) => slug !== SYSTEM_FONT_SLUG ); @@ -73,163 +80,213 @@ function ScaledBlockPreview( { viewportWidth = containerWidth; } + // Avoid scrollbars for pattern previews. + const editorStyles = useMemo( () => { + if ( ! isScrollable && settings.styles ) { + return [ + ...settings.styles, + { + css: 'body{height:auto;overflow:hidden;border:none;padding:0;}', + __unstableType: 'presets', + }, + ]; + } + + return settings.styles; + }, [ settings.styles, isScrollable ] ); + + const scale = containerWidth / viewportWidth; + const aspectRatio = contentHeight + ? containerWidth / ( contentHeight * scale ) + : 0; // Initialize on render instead of module top level, to avoid circular dependency issues. MemoizedBlockList = MemoizedBlockList || pure( BlockList ); + const updateIframeContent = ( bodyElement: HTMLBodyElement ) => { + let navigationContainers: NodeListOf< HTMLDivElement >; + let siteTitles: NodeListOf< HTMLAnchorElement >; + + const onMouseMove = ( event: MouseEvent ) => { + event.stopImmediatePropagation(); + }; + + const onClickNavigation = ( event: MouseEvent ) => { + event.preventDefault(); + onClickNavigationItem( event ); + }; + + const possiblyRemoveAllListeners = () => { + bodyElement.removeEventListener( 'mousemove', onMouseMove, false ); + if ( navigationContainers ) { + navigationContainers.forEach( ( element ) => { + element.removeEventListener( 'click', onClickNavigation ); + } ); + } + + if ( siteTitles ) { + siteTitles.forEach( ( element ) => { + element.removeEventListener( 'click', onClickNavigation ); + } ); + } + }; + + const enableNavigation = () => { + // Remove contenteditable and inert attributes from editable elements so that users can click on navigation links. + bodyElement + .querySelectorAll( + '.block-editor-rich-text__editable[contenteditable="true"]' + ) + .forEach( ( element ) => { + element.removeAttribute( 'contenteditable' ); + } ); + + bodyElement + .querySelectorAll( '*[inert="true"]' ) + .forEach( ( element ) => { + element.removeAttribute( 'inert' ); + } ); + + possiblyRemoveAllListeners(); + navigationContainers = bodyElement.querySelectorAll( + '.wp-block-navigation__container' + ); + navigationContainers.forEach( ( element ) => { + element.addEventListener( 'click', onClickNavigation, true ); + } ); + + siteTitles = bodyElement.querySelectorAll( + '.wp-block-site-title a' + ); + siteTitles.forEach( ( element ) => { + element.addEventListener( 'click', onClickNavigation, true ); + } ); + }; + + const findAndSetLogoBlock = () => { + // Get the current logo block client ID from DOM and set it in the logo block context. This is used for the logo settings. See: ./sidebar/sidebar-navigation-screen-logo.tsx + // Ideally, we should be able to get the logo block client ID from the block editor store but it is not available. + // We should update this code once the there is a selector in the block editor store that can be used to get the logo block client ID. + const siteLogos = bodyElement.querySelectorAll( + '.wp-block-site-logo' + ); + + const logoBlockIds = Array.from( siteLogos ) + .map( ( siteLogo ) => { + return siteLogo.getAttribute( 'data-block' ); + } ) + .filter( Boolean ) as string[]; + setLogoBlockIds( logoBlockIds ); + }; + + const onChange = () => { + if ( autoScale ) { + const rootContainer = + bodyElement.querySelector( '.is-root-container' ); + + setContentHeight( + rootContainer ? rootContainer.clientHeight : null + ); + } + + if ( isNavigable ) { + enableNavigation(); + } + + if ( setLogoBlockContext ) { + findAndSetLogoBlock(); + } + }; + + // Stop mousemove event listener to disable block tool insertion feature. + bodyElement.addEventListener( 'mousemove', onMouseMove, true ); + + const observer = new window.MutationObserver( onChange ); + observer.observe( bodyElement, { + attributes: true, + characterData: false, + subtree: true, + childList: true, + } ); + + return () => { + observer.disconnect(); + possiblyRemoveAllListeners(); + + if ( setLogoBlockContext ) { + setLogoBlockIds( [] ); + } + }; + }; + return ( - + + + + + ); } diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-editor.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-editor.tsx index 6607fba9e72..6763dbb9781 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-editor.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-editor.tsx @@ -66,7 +66,7 @@ const MAX_PAGE_COUNT = 100; export const BlockEditor = ( {} ) => { const history = useHistory(); const settings = useSiteEditorSettings(); - const [ blocks ] = useEditorBlocks(); + const [ blocks, onChange ] = useEditorBlocks(); const urlParams = useQuery(); const { currentState } = useContext( CustomizeStoreContext ); @@ -119,8 +119,6 @@ export const BlockEditor = ( {} ) => { [ history, urlParams, pages ] ); - const [ , , onChange ] = useEditorBlocks(); - const { highlightedBlockIndex } = useContext( HighlightedBlockContext ); const isHighlighting = highlightedBlockIndex !== -1; const additionalStyles = isHighlighting @@ -163,7 +161,8 @@ export const BlockEditor = ( {} ) => { onClickNavigationItem={ onClickNavigationItem } // Don't use sub registry so that we can get the logo block from the main registry on the logo sidebar navigation screen component. useSubRegistry={ false } - previewOpacity={ previewOpacity } + autoScale={ false } + setLogoBlockContext={ true } /> diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-pattern-list.jsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-pattern-list.jsx new file mode 100644 index 00000000000..502a7f6f6fe --- /dev/null +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-pattern-list.jsx @@ -0,0 +1,139 @@ +// Reference: https://github.com/WordPress/gutenberg/blob/94ff2ba55379d9ad7f6bed743b20b85ff26cf56d/packages/block-editor/src/components/block-patterns-list/index.js#L1 +/* eslint-disable @woocommerce/dependency-group */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +/** + * External dependencies + */ +import { + VisuallyHidden, + __unstableComposite as Composite, + __unstableUseCompositeState as useCompositeState, + __unstableCompositeItem as CompositeItem, + Tooltip, +} from '@wordpress/components'; +import { useInstanceId } from '@wordpress/compose'; +import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { useMemo } from '@wordpress/element'; +import { store as blockEditorStore } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import BlockPreview from './block-preview'; + +const WithToolTip = ( { showTooltip, title, children } ) => { + if ( showTooltip ) { + return { children }; + } + return <>{ children }; +}; + +function BlockPattern( { pattern, onClick, onHover, composite, showTooltip } ) { + const { blocks, viewportWidth } = pattern; + const instanceId = useInstanceId( BlockPattern ); + const descriptionId = `block-editor-block-patterns-list__item-description-${ instanceId }`; + const originalSettings = useSelect( + ( select ) => select( blockEditorStore ).getSettings(), + [] + ); + const settings = useMemo( + () => ( { ...originalSettings, __unstableIsPreviewMode: true } ), + [ originalSettings ] + ); + return ( +
+
+ + { + onClick( pattern, blocks ); + onHover?.( null ); + } } + onMouseEnter={ () => { + onHover?.( pattern ); + } } + onMouseLeave={ () => onHover?.( null ) } + aria-label={ pattern.title } + aria-describedby={ + pattern.description ? descriptionId : undefined + } + > + + { ! showTooltip && ( +
+ { pattern.title } +
+ ) } + { !! pattern.description && ( + + { pattern.description } + + ) } +
+
+
+
+ ); +} + +function BlockPatternPlaceholder() { + return ( +
+ ); +} + +function BlockPatternList( { + isDraggable, + blockPatterns, + shownPatterns, + onHover, + onClickPattern, + orientation, + label = __( 'Block Patterns', 'woocommerce' ), + showTitlesAsTooltip, +} ) { + const composite = useCompositeState( { orientation } ); + return ( + + { blockPatterns.map( ( pattern ) => { + const isShown = shownPatterns.includes( pattern ); + return isShown ? ( + + ) : ( + + ); + } ) } + + ); +} + +export default BlockPatternList; diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-preview.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-preview.tsx index e0aea3e1c16..ab29db18a67 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-preview.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/block-preview.tsx @@ -22,7 +22,6 @@ export const BlockPreview = ( { blocks, settings, useSubRegistry = true, - additionalStyles, onChange, ...props }: { @@ -30,7 +29,6 @@ export const BlockPreview = ( { settings: Record< string, unknown >; onChange?: ChangeHandler | undefined; useSubRegistry?: boolean; - previewOpacity?: number; } & Omit< ScaledBlockPreviewProps, 'containerWidth' > ) => { const renderedBlocks = useMemo( () => { const _blocks = Array.isArray( blocks ) ? blocks : [ blocks ]; @@ -45,11 +43,7 @@ export const BlockPreview = ( { onChange={ onChange } useSubRegistry={ useSubRegistry } > - + ); }; diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-footer.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-footer.tsx index 7914bb33fa0..49698cc01bd 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-footer.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-footer.tsx @@ -14,8 +14,6 @@ import { import { Link } from '@woocommerce/components'; import { recordEvent } from '@woocommerce/tracks'; import { Spinner } from '@wordpress/components'; -// @ts-expect-error Missing type in core-data. -import { __experimentalBlockPatternsList as BlockPatternList } from '@wordpress/block-editor'; /** * Internal dependencies @@ -28,6 +26,7 @@ import { HighlightedBlockContext } from '../context/highlighted-block-context'; import { useEditorScroll } from '../hooks/use-editor-scroll'; import { useSelectedPattern } from '../hooks/use-selected-pattern'; import { findPatternByBlock } from './utils'; +import BlockPatternList from '../block-pattern-list'; const SUPPORTED_FOOTER_PATTERNS = [ 'woocommerce-blocks/footer-simple-menu-and-cart', @@ -140,8 +139,8 @@ export const SidebarNavigationScreenFooter = () => { onClickPattern={ onClickFooterPattern } label={ 'Footers' } orientation="vertical" - category={ 'footer' } isDraggable={ false } + onHover={ () => {} } showTitlesAsTooltip={ true } /> ) } diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-header.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-header.tsx index e82daca552a..8a954d542f3 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-header.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/sidebar-navigation-screen-header.tsx @@ -14,8 +14,6 @@ import { import { Link } from '@woocommerce/components'; import { recordEvent } from '@woocommerce/tracks'; import { Spinner } from '@wordpress/components'; -// @ts-ignore No types for this exist yet. -import { __experimentalBlockPatternsList as BlockPatternList } from '@wordpress/block-editor'; /** * Internal dependencies @@ -28,6 +26,7 @@ import { useEditorBlocks } from '../hooks/use-editor-blocks'; import { HighlightedBlockContext } from '../context/highlighted-block-context'; import { useEditorScroll } from '../hooks/use-editor-scroll'; import { findPatternByBlock } from './utils'; +import BlockPatternList from '../block-pattern-list'; const SUPPORTED_HEADER_PATTERNS = [ 'woocommerce-blocks/header-essential', @@ -138,8 +137,8 @@ export const SidebarNavigationScreenHeader = () => { onClickPattern={ onClickHeaderPattern } label={ 'Headers' } orientation="vertical" - category={ 'header' } isDraggable={ false } + onHover={ () => {} } showTitlesAsTooltip={ true } /> ) } diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/style.scss b/plugins/woocommerce-admin/client/customize-store/assembler-hub/style.scss index dece2c879cb..af2903e8877 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/style.scss +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/style.scss @@ -472,23 +472,44 @@ /* Layout sidebar */ .block-editor-block-patterns-list__item { - .block-editor-block-preview__container { + .auto-block-preview__container { border-radius: 4px; border: 1.5px solid transparent; + align-items: center; + display: flex; + overflow: hidden; } &.is-selected, &:hover, &:focus { - .block-editor-block-preview__container { + .auto-block-preview__container { box-shadow: none; border-color: var(--wp-admin-theme-color); } } } - .edit-site-sidebar-navigation-screen__content .block-editor-block-patterns-list { - width: 324px; + .block-editor-block-preview__content { + height: 100%; + width: 100%; + } + + .edit-site-sidebar-navigation-screen__content { + .block-editor-block-preview__content { + left: 0; + margin: 0; + min-height: auto; + overflow: visible; + text-align: initial; + top: 0; + transform-origin: top left; + position: relative; + } + + .block-editor-block-patterns-list { + width: 324px; + } } .woocommerce-customize-store__sidebar-homepage-content { diff --git a/plugins/woocommerce/changelog/fix-thumbnail-size b/plugins/woocommerce/changelog/fix-thumbnail-size new file mode 100644 index 00000000000..101cbdde975 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-thumbnail-size @@ -0,0 +1,4 @@ +Significance: patch +Type: fix + +Fix cys pattern thumbnail size