Fix CYS assembler hub UI issues (#41036)

* Set default logo size to 60px and max to 200px

* Hide homepage template label

* Scroll to position when selecting a pattern

* Fix preview opacity issue

* Update sidebar scrollbar style

* Fix onboarding tour resize handle

* Add changelog
This commit is contained in:
Chi-Hsuan Huang 2023-10-26 18:15:30 +08:00 committed by GitHub
parent b108e19a93
commit 7b00687a38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 162 additions and 99 deletions

View File

@ -15,7 +15,7 @@ import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
// @ts-ignore No types for this exist yet.
import useSiteEditorSettings from '@wordpress/edit-site/build-module/components/block-editor/use-site-editor-settings';
import { useQuery } from '@woocommerce/navigation';
import { useContext, useCallback } from '@wordpress/element';
import { useContext, useCallback, useMemo } from '@wordpress/element';
/**
* Internal dependencies
@ -24,6 +24,7 @@ import BlockPreview from './block-preview';
import { useEditorBlocks } from './hooks/use-editor-blocks';
import { useScrollOpacity } from './hooks/use-scroll-opacity';
import { CustomizeStoreContext } from './';
import { HighlightedBlockContext } from './context/highlighted-block-context';
const { useHistory } = unlock( routerPrivateApis );
@ -118,13 +119,45 @@ export const BlockEditor = ( {} ) => {
[ history, urlParams, pages ]
);
const [ , , onChange ] = useEditorBlocks();
const { highlightedBlockIndex } = useContext( HighlightedBlockContext );
const isHighlighting = highlightedBlockIndex !== -1;
const additionalStyles = isHighlighting
? `
.wp-block.preview-opacity {
opacity: ${ previewOpacity };
}
`
: '';
const renderedBlocks = useMemo(
() =>
blocks.map( ( block, i ) => {
if ( ! isHighlighting || i === highlightedBlockIndex ) {
return block;
}
return {
...block,
attributes: {
...block.attributes,
className:
block.attributes.className + ' preview-opacity',
},
};
} ),
[ blocks, highlightedBlockIndex, isHighlighting ]
);
return (
<div className="woocommerce-customize-store__block-editor">
<div className={ 'woocommerce-block-preview-container' }>
<BlockPreview
blocks={ blocks }
blocks={ renderedBlocks }
onChange={ isHighlighting ? undefined : onChange }
settings={ settings }
additionalStyles={ '' }
additionalStyles={ additionalStyles }
isNavigable={ false }
isScrollable={ currentState !== 'transitionalScreen' }
onClickNavigationItem={ onClickNavigationItem }

View File

@ -7,7 +7,7 @@
*/
// @ts-ignore No types for this exist yet.
import { BlockEditorProvider } from '@wordpress/block-editor';
import { memo, useContext, useMemo } from '@wordpress/element';
import { memo, useMemo } from '@wordpress/element';
import { BlockInstance } from '@wordpress/blocks';
/**
* Internal dependencies
@ -16,63 +16,38 @@ import {
AutoHeightBlockPreview,
ScaledBlockPreviewProps,
} from './auto-block-preview';
import { HighlightedBlockContext } from './context/highlighted-block-context';
import { useEditorBlocks } from './hooks/use-editor-blocks';
import { ChangeHandler } from './hooks/use-editor-blocks';
export const BlockPreview = ( {
blocks,
settings,
useSubRegistry = true,
additionalStyles,
previewOpacity = 0.5,
onChange,
...props
}: {
blocks: BlockInstance | BlockInstance[];
settings: Record< string, unknown >;
onChange?: ChangeHandler | undefined;
useSubRegistry?: boolean;
previewOpacity?: number;
} & Omit< ScaledBlockPreviewProps, 'containerWidth' > ) => {
const [ , , onChange ] = useEditorBlocks();
const { highlightedBlockIndex } = useContext( HighlightedBlockContext );
const renderedBlocks = useMemo( () => {
const _blocks = Array.isArray( blocks ) ? blocks : [ blocks ];
return _blocks.map( ( block, i ) => {
if ( i === highlightedBlockIndex ) {
return block;
}
return {
...block,
attributes: {
...block.attributes,
className: block.attributes.className + ' preview-opacity',
},
};
} );
}, [ blocks, highlightedBlockIndex ] );
const opacityStyles =
highlightedBlockIndex === -1
? ''
: `
.wp-block.preview-opacity {
opacity: ${ previewOpacity };
}
`;
return _blocks;
}, [ blocks ] );
return (
<BlockEditorProvider
value={ renderedBlocks }
settings={ settings }
// We need to set onChange for logo to work, but we don't want to trigger the onChange callback when highlighting blocks in the preview. It would persist the highlighted block and cause the opacity to be applied to block permanently.
onChange={ opacityStyles ? undefined : onChange }
onChange={ onChange }
useSubRegistry={ useSubRegistry }
>
<AutoHeightBlockPreview
settings={ settings }
additionalStyles={ `${ opacityStyles } ${ additionalStyles }` }
additionalStyles={ additionalStyles }
{ ...props }
/>
</BlockEditorProvider>

View File

@ -12,7 +12,7 @@ import { store as editSiteStore } from '@wordpress/edit-site/build-module/store'
import { useSelect } from '@wordpress/data';
import { BlockInstance } from '@wordpress/blocks';
type ChangeHandler = (
export type ChangeHandler = (
blocks: BlockInstance[],
options: Record< string, unknown >
) => void;

View File

@ -6,7 +6,7 @@
*/
// @ts-ignore No types for this exist yet.
import { useIsSiteEditorLoading } from '@wordpress/edit-site/build-module/components/layout/hooks';
import { useEffect } from '@wordpress/element';
import { useCallback, useEffect } from '@wordpress/element';
export const useEditorScroll = ( {
editorSelector,
@ -17,21 +17,29 @@ export const useEditorScroll = ( {
} ) => {
const isEditorLoading = useIsSiteEditorLoading();
useEffect( () => {
// Scroll to the bottom of the preview when the editor is done loading.
if ( isEditorLoading ) {
return;
}
const scroll = useCallback( () => {
const previewContainer =
document.querySelector< HTMLIFrameElement >( editorSelector );
if ( previewContainer ) {
previewContainer.contentWindow?.scrollTo(
0,
scrollDirection === 'bottom'
? previewContainer.contentDocument?.body.scrollHeight || 0
: 0
);
previewContainer.contentWindow?.scrollTo( {
left: 0,
top:
scrollDirection === 'bottom'
? previewContainer.contentDocument?.body.scrollHeight ||
0
: 0,
} );
}
}, [ isEditorLoading, editorSelector, scrollDirection ] );
}, [ scrollDirection, editorSelector ] );
useEffect( () => {
// Scroll to the bottom of the preview when the editor is done loading.
if ( ! isEditorLoading ) {
scroll();
}
}, [ isEditorLoading, scroll ] );
return {
scroll,
};
};

View File

@ -36,10 +36,14 @@ export const useScrollOpacity = (
? ( targetElement as Document ).documentElement
: ( targetElement as Element );
const _sensitivity =
// Set sensitivity to a small threshold for mobile devices because they have a small viewport to ensure the effect is visible.
contentElement.clientWidth > 480 ? sensitivity : 0.05;
const maxScrollHeight =
contentElement.scrollHeight - contentElement.clientHeight;
const currentScrollPosition = contentElement.scrollTop;
const maxEffectScroll = maxScrollHeight * sensitivity;
const maxEffectScroll = maxScrollHeight * _sensitivity;
let calculatedOpacity;
if ( direction === 'bottomUp' ) {

View File

@ -56,7 +56,8 @@ export const Layout = () => {
const [ logoBlockIds, setLogoBlockIds ] = useState< Array< string > >( [] );
// This ensures the edited entity id and type are initialized properly.
useInitEditedEntityFromURL();
const { shouldTourBeShown, ...onboardingTourProps } = useOnboardingTour();
const { shouldTourBeShown, isResizeHandleVisible, ...onboardingTourProps } =
useOnboardingTour();
const isMobileViewport = useViewportMatch( 'medium', '<' );
const disableMotion = useReducedMotion();
@ -179,9 +180,9 @@ export const Layout = () => {
isReady={
! isEditorLoading
}
duringGuideTour={
shouldTourBeShown &&
! onboardingTourProps.showWelcomeTour
isHandleVisibleByDefault={
! onboardingTourProps.showWelcomeTour &&
isResizeHandleVisible
}
isFullWidth={ false }
defaultSize={ {
@ -211,7 +212,7 @@ export const Layout = () => {
) }
</div>
</div>
{ shouldTourBeShown && (
{ ! isEditorLoading && shouldTourBeShown && (
<OnboardingTour { ...onboardingTourProps } />
) }
</EntityProvider>

View File

@ -11,12 +11,14 @@ type OnboardingTourProps = {
onClose: () => void;
showWelcomeTour: boolean;
setShowWelcomeTour: ( show: boolean ) => void;
setIsResizeHandleVisible: ( isVisible: boolean ) => void;
};
export const OnboardingTour = ( {
onClose,
setShowWelcomeTour,
showWelcomeTour,
setIsResizeHandleVisible,
}: OnboardingTourProps ) => {
const [ placement, setPlacement ] =
useState< TourKitTypes.WooConfig[ 'placement' ] >( 'left' );
@ -127,9 +129,11 @@ export const OnboardingTour = ( {
callbacks: {
onPreviousStep: () => {
setPlacement( 'left' );
setIsResizeHandleVisible( true );
},
onNextStep: () => {
setPlacement( 'right-start' );
setIsResizeHandleVisible( false );
},
},
popperModifiers: [

View File

@ -16,6 +16,7 @@ describe( 'OnboardingTour', () => {
onClose: jest.Mock;
setShowWelcomeTour: jest.Mock;
showWelcomeTour: boolean;
setIsResizeHandleVisible: ( isVisible: boolean ) => void;
};
beforeEach( () => {
@ -23,6 +24,7 @@ describe( 'OnboardingTour', () => {
onClose: jest.fn(),
setShowWelcomeTour: jest.fn(),
showWelcomeTour: true,
setIsResizeHandleVisible: jest.fn(),
};
} );

View File

@ -10,6 +10,8 @@ export const CUSTOMIZE_STORE_ONBOARDING_TOUR_HIDDEN =
export const useOnboardingTour = () => {
const [ showWelcomeTour, setShowWelcomeTour ] = useState( true );
const [ isResizeHandleVisible, setIsResizeHandleVisible ] =
useState( true );
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
const { shouldTourBeShown } = useSelect( ( select ) => {
@ -38,5 +40,7 @@ export const useOnboardingTour = () => {
shouldTourBeShown,
showWelcomeTour,
setShowWelcomeTour,
setIsResizeHandleVisible,
isResizeHandleVisible,
};
};

View File

@ -75,7 +75,7 @@ function ResizableFrame( {
/** The default (unresized) width/height of the frame, based on the space availalbe in the viewport. */
defaultSize,
innerContentStyle,
duringGuideTour = false,
isHandleVisibleByDefault = false,
} ) {
const [ frameSize, setFrameSize ] = useState( INITIAL_FRAME_SIZE );
// The width of the resizable frame when a new resize gesture starts.
@ -192,7 +192,9 @@ function ResizableFrame( {
if ( isResizing ) {
return 'active';
}
return shouldShowHandle || duringGuideTour ? 'visible' : 'hidden';
return shouldShowHandle || isHandleVisibleByDefault
? 'visible'
: 'hidden';
} )();
const resizeHandler = (
@ -220,10 +222,10 @@ function ResizableFrame( {
whileFocus="active"
whileHover="active"
children={
duringGuideTour &&
isHandleVisibleByDefault &&
! hasHandlerDragged && (
<Popover
className="components-tooltip"
className="woocommerce-assembler-hub__resizable-frame__drag-handler"
position="middle right"
>
{ __( 'Drag to resize', 'woocommerce' ) }
@ -273,7 +275,7 @@ function ResizableFrame( {
handleComponent={ {
left: (
<>
{ duringGuideTour ? (
{ isHandleVisibleByDefault ? (
<div>{ resizeHandler }</div>
) : (
<Tooltip

View File

@ -37,7 +37,7 @@ const SUPPORTED_FOOTER_PATTERNS = [
];
export const SidebarNavigationScreenFooter = () => {
useEditorScroll( {
const { scroll } = useEditorScroll( {
editorSelector: '.woocommerce-customize-store__block-editor iframe',
scrollDirection: 'bottom',
} );
@ -81,7 +81,6 @@ export const SidebarNavigationScreenFooter = () => {
blocks[ blocks.length - 1 ]
);
setSelectedPattern( currentSelectedPattern );
// eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want to re-run this effect when currentSelectedPattern changes
}, [ blocks, footerPatterns ] );
@ -91,8 +90,9 @@ export const SidebarNavigationScreenFooter = () => {
onChange( [ ...blocks.slice( 0, -1 ), selectedBlocks[ 0 ] ], {
selection: {},
} );
scroll();
},
[ blocks, onChange, setSelectedPattern ]
[ blocks, onChange, setSelectedPattern, scroll ]
);
return (

View File

@ -37,7 +37,7 @@ const SUPPORTED_HEADER_PATTERNS = [
];
export const SidebarNavigationScreenHeader = () => {
useEditorScroll( {
const { scroll } = useEditorScroll( {
editorSelector: '.woocommerce-customize-store__block-editor iframe',
scrollDirection: 'top',
} );
@ -78,6 +78,7 @@ export const SidebarNavigationScreenHeader = () => {
blocks[ 0 ]
);
setSelectedPattern( currentSelectedPattern );
// eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want to re-run this effect when currentSelectedPattern changes
}, [ blocks, headerPatterns ] );
@ -87,8 +88,9 @@ export const SidebarNavigationScreenHeader = () => {
onChange( [ selectedBlocks[ 0 ], ...blocks.slice( 1 ) ], {
selection: {},
} );
scroll();
},
[ blocks, onChange, setSelectedPattern ]
[ blocks, onChange, setSelectedPattern, scroll ]
);
return (

View File

@ -26,8 +26,13 @@ import { useEditorBlocks } from '../hooks/use-editor-blocks';
import { useHomeTemplates } from '../hooks/use-home-templates';
import { BlockInstance } from '@wordpress/blocks';
import { useSelectedPattern } from '../hooks/use-selected-pattern';
import { useEditorScroll } from '../hooks/use-editor-scroll';
export const SidebarNavigationScreenHomepage = () => {
const { scroll } = useEditorScroll( {
editorSelector: '.woocommerce-customize-store__block-editor iframe',
scrollDirection: 'top',
} );
const { isLoading, homeTemplates } = useHomeTemplates();
// eslint-disable-next-line react-hooks/exhaustive-deps
const { selectedPattern, setSelectedPattern } = useSelectedPattern();
@ -40,8 +45,9 @@ export const SidebarNavigationScreenHomepage = () => {
[ blocks[ 0 ], ...selectedBlocks, blocks[ blocks.length - 1 ] ],
{ selection: {} }
);
scroll();
},
[ blocks, onChange, setSelectedPattern ]
[ blocks, onChange, setSelectedPattern, scroll ]
);
const homePatterns = useMemo( () => {
@ -82,6 +88,7 @@ export const SidebarNavigationScreenHomepage = () => {
} );
setSelectedPattern( _currentSelectedPattern );
// eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want to re-run this effect when currentSelectedPattern changes
}, [ blocks, homePatterns ] );
@ -130,7 +137,7 @@ export const SidebarNavigationScreenHomepage = () => {
orientation="vertical"
category={ 'homepage' }
isDraggable={ false }
showTitlesAsTooltip={ true }
showTitlesAsTooltip={ false }
/>
) }
</div>

View File

@ -176,17 +176,11 @@ const LogoSettings = ( {
const isWideAligned = [ 'wide', 'full' ].includes( align );
const isResizable = ! isWideAligned && isLargeViewport;
const { maxWidth } = useSelect( ( select ) => {
// @ts-ignore No types for this exist yet.
const settings = select( blockEditorStore ).getSettings();
return {
maxWidth: settings.maxWidth,
};
}, [] );
const maxWidth = 200;
// Set the default width to a responsible size.
// Note that this width is also set in the attached frontend CSS file.
const defaultWidth = 120;
const defaultWidth = 60;
const currentWidth = width || defaultWidth;
const ratio = naturalWidth / naturalHeight;
@ -218,7 +212,7 @@ const LogoSettings = ( {
setAttributes( { width: newWidth } )
}
min={ minWidth }
max={ maxWidthBuffer }
max={ maxWidth }
initialPosition={ Math.min( defaultWidth, maxWidthBuffer ) }
value={ currentWidth }
disabled={ ! isResizable }

View File

@ -148,6 +148,20 @@
padding: 0 16px;
overflow-x: hidden;
flex: 1;
&::-webkit-scrollbar-thumb {
background-color: #c1c1c1;
}
&::-webkit-scrollbar-track-piece:start {
background: transparent;
margin-top: 250px;
}
&::-webkit-scrollbar-track-piece:end {
background: transparent;
margin-bottom: 400px;
}
}
}
@ -361,6 +375,10 @@
}
}
.block-editor-block-patterns-list__item-title {
display: none;
}
/* Color sidebar */
.woocommerce-customize-store__color-panel-container {
@ -487,27 +505,7 @@
.edit-site-resizable-frame__handle {
background: var(--wp-admin-theme-color);
.components-popover {
display: inline-flex;
padding: 0 10px;
align-items: flex-start;
gap: 10px;
background: var(--wp-admin-theme-color-background-25);
left: 5px !important;
border-radius: 4px;
height: 20px;
.components-popover__content {
color: var(--wp-admin-theme-color-darker-20);
font-size: 0.75rem;
font-style: normal;
font-weight: 500;
line-height: 20px; /* 166.667% */
background: inherit;
padding: 0;
}
}
cursor: ew-resize;
}
.edit-site-layout__canvas .components-resizable-box__container {
@ -667,3 +665,28 @@
stroke: rgba($black, 0.3);
}
}
.woocommerce-assembler-hub__resizable-frame__drag-handler {
display: inline-flex;
padding: 0 10px;
align-items: flex-start;
gap: 10px;
background: var(--wp-admin-theme-color-background-25);
left: 5px !important;
border-radius: 4px;
height: 20px;
.components-popover__content {
color: var(--wp-admin-theme-color-darker-20);
font-size: 0.75rem;
font-style: normal;
font-weight: 500;
line-height: 20px; /* 166.667% */
background: inherit;
padding: 0;
margin-left: 10px;
width: max-content;
box-shadow: none;
}
}

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix CYS assembler hub UI issues