Customize your store header (#40107)
This closes #39718 by loading header patterns in the header customization menu of the assembler.
This commit is contained in:
parent
473a53d542
commit
36c644a1c4
|
@ -4,23 +4,21 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { useEntityRecords, useEntityBlockEditor } from '@wordpress/core-data';
|
||||
import { useEntityRecords } from '@wordpress/core-data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { privateApis as routerPrivateApis } from '@wordpress/router';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { store as editSiteStore } from '@wordpress/edit-site/build-module/store';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
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 { BlockInstance } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import BlockPreview from './block-preview';
|
||||
import { useCallback } from '@wordpress/element';
|
||||
import { useEditorBlocks } from './hooks/use-editor-blocks';
|
||||
|
||||
const { useHistory, useLocation } = unlock( routerPrivateApis );
|
||||
|
||||
|
@ -38,19 +36,7 @@ export const BlockEditor = ( {} ) => {
|
|||
const history = useHistory();
|
||||
const location = useLocation();
|
||||
const settings = useSiteEditorSettings();
|
||||
|
||||
const { templateType } = useSelect( ( select ) => {
|
||||
const { getEditedPostType } = unlock( select( editSiteStore ) );
|
||||
|
||||
return {
|
||||
templateType: getEditedPostType(),
|
||||
};
|
||||
}, [] );
|
||||
|
||||
const [ blocks ]: [ BlockInstance[] ] = useEntityBlockEditor(
|
||||
'postType',
|
||||
templateType
|
||||
);
|
||||
const [ blocks ] = useEditorBlocks();
|
||||
|
||||
// // See packages/block-library/src/page-list/edit.js.
|
||||
const { records: pages } = useEntityRecords( 'postType', 'page', {
|
||||
|
@ -145,6 +131,7 @@ export const BlockEditor = ( {} ) => {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="woocommerce-customize-store__block-editor">
|
||||
<div className={ 'woocommerce-block-preview-container' }>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { BlockEditorProvider } from '@wordpress/block-editor';
|
||||
import { memo, useMemo } from '@wordpress/element';
|
||||
import { memo, useContext, useMemo } from '@wordpress/element';
|
||||
import { BlockInstance } from '@wordpress/blocks';
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -16,11 +16,14 @@ import {
|
|||
AutoHeightBlockPreview,
|
||||
ScaledBlockPreviewProps,
|
||||
} from './auto-block-preview';
|
||||
import { HighlightedBlockContext } from './context/highlighted-block-context';
|
||||
import { useScrollOpacity } from './hooks/use-scroll-opacity';
|
||||
|
||||
export const BlockPreview = ( {
|
||||
blocks,
|
||||
settings,
|
||||
useSubRegistry = true,
|
||||
additionalStyles,
|
||||
...props
|
||||
}: {
|
||||
blocks: BlockInstance | BlockInstance[];
|
||||
|
@ -32,13 +35,45 @@ export const BlockPreview = ( {
|
|||
[ blocks ]
|
||||
);
|
||||
|
||||
const { highlightedBlockIndex } = useContext( HighlightedBlockContext );
|
||||
const previewOpacity = useScrollOpacity(
|
||||
'.interface-navigable-region.interface-interface-skeleton__content',
|
||||
'topDown'
|
||||
);
|
||||
|
||||
const opacityStyles =
|
||||
highlightedBlockIndex === -1
|
||||
? ''
|
||||
: `
|
||||
.wp-block.preview-opacity {
|
||||
opacity: ${ previewOpacity };
|
||||
}
|
||||
`;
|
||||
|
||||
return (
|
||||
<BlockEditorProvider
|
||||
value={ renderedBlocks }
|
||||
value={ renderedBlocks.map( ( block, i ) => {
|
||||
if ( i === highlightedBlockIndex ) {
|
||||
return block;
|
||||
}
|
||||
|
||||
return {
|
||||
...block,
|
||||
attributes: {
|
||||
...block.attributes,
|
||||
className:
|
||||
block.attributes.className + ' preview-opacity',
|
||||
},
|
||||
};
|
||||
} ) }
|
||||
settings={ settings }
|
||||
useSubRegistry={ useSubRegistry }
|
||||
>
|
||||
<AutoHeightBlockPreview settings={ settings } { ...props } />
|
||||
<AutoHeightBlockPreview
|
||||
settings={ settings }
|
||||
additionalStyles={ `${ opacityStyles } ${ additionalStyles }` }
|
||||
{ ...props }
|
||||
/>
|
||||
</BlockEditorProvider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React, { createContext, useState } from '@wordpress/element';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
export const HighlightedBlockContext = createContext( {
|
||||
highlightedBlockIndex: -1,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
setHighlightedBlockIndex: ( index: number ) => {
|
||||
// No op by default.
|
||||
},
|
||||
resetHighlightedBlockIndex: () => {
|
||||
// No op by default.
|
||||
},
|
||||
} );
|
||||
|
||||
// A Provider that keeps track of which block is "focussed" in the Assembler Hub.
|
||||
// This is used to highlight the block in the BlockEditor currently.
|
||||
export const HighlightedBlockContextProvider = ( {
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
} ) => {
|
||||
// Create some state
|
||||
const [ highlightedBlockIndex, setHighlightedBlockIndex ] = useState( -1 );
|
||||
|
||||
const resetHighlightedBlockIndex = () => {
|
||||
setHighlightedBlockIndex( -1 );
|
||||
};
|
||||
|
||||
return (
|
||||
<HighlightedBlockContext.Provider
|
||||
value={ {
|
||||
highlightedBlockIndex,
|
||||
setHighlightedBlockIndex,
|
||||
resetHighlightedBlockIndex,
|
||||
} }
|
||||
>
|
||||
{ children }
|
||||
</HighlightedBlockContext.Provider>
|
||||
);
|
||||
};
|
|
@ -7,8 +7,6 @@
|
|||
import classnames from 'classnames';
|
||||
import { useMemo } from '@wordpress/element';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { EntityProvider } from '@wordpress/core-data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { InterfaceSkeleton } from '@wordpress/interface';
|
||||
import { useSelect, useDispatch } from '@wordpress/data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
|
@ -18,8 +16,6 @@ import { store as editSiteStore } from '@wordpress/edit-site/build-module/store'
|
|||
// @ts-ignore No types for this exist yet.
|
||||
import CanvasSpinner from '@wordpress/edit-site/build-module/components/canvas-spinner';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import useEditedEntityRecord from '@wordpress/edit-site/build-module/components/use-edited-entity-record';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { GlobalStylesRenderer } from '@wordpress/edit-site/build-module/components/global-styles-renderer';
|
||||
|
@ -30,8 +26,6 @@ import { GlobalStylesRenderer } from '@wordpress/edit-site/build-module/componen
|
|||
import { BlockEditor } from './block-editor';
|
||||
|
||||
export const Editor = ( { isLoading }: { isLoading: boolean } ) => {
|
||||
const { record: template } = useEditedEntityRecord();
|
||||
const { id: templateId, type: templateType } = template;
|
||||
const { context, hasPageContentFocus } = useSelect( ( select ) => {
|
||||
const {
|
||||
getEditedPostContext,
|
||||
|
@ -68,12 +62,7 @@ export const Editor = ( { isLoading }: { isLoading: boolean } ) => {
|
|||
return (
|
||||
<>
|
||||
{ isLoading ? <CanvasSpinner /> : null }
|
||||
<EntityProvider kind="root" type="site">
|
||||
<EntityProvider
|
||||
kind="postType"
|
||||
type={ templateType }
|
||||
id={ templateId }
|
||||
>
|
||||
|
||||
<BlockContextProvider value={ blockContext }>
|
||||
<InterfaceSkeleton
|
||||
enableRegionNavigation={ false }
|
||||
|
@ -93,8 +82,6 @@ export const Editor = ( { isLoading }: { isLoading: boolean } ) => {
|
|||
}
|
||||
/>
|
||||
</BlockContextProvider>
|
||||
</EntityProvider>
|
||||
</EntityProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* eslint-disable @woocommerce/dependency-group */
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { useEntityBlockEditor } from '@wordpress/core-data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { store as editSiteStore } from '@wordpress/edit-site/build-module/store';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { BlockInstance } from '@wordpress/blocks';
|
||||
|
||||
type ChangeHandler = (
|
||||
blocks: BlockInstance[],
|
||||
options: Record< string, unknown >
|
||||
) => void;
|
||||
|
||||
// Note, must be used within BlockEditorProvider. This allows shared access of blocks currently
|
||||
// being edited in the BlockEditor.
|
||||
export const useEditorBlocks = (): [
|
||||
BlockInstance[],
|
||||
ChangeHandler,
|
||||
ChangeHandler
|
||||
] => {
|
||||
const { templateType } = useSelect( ( select ) => {
|
||||
const { getEditedPostType } = unlock( select( editSiteStore ) );
|
||||
|
||||
return {
|
||||
templateType: getEditedPostType(),
|
||||
};
|
||||
}, [] );
|
||||
|
||||
// @ts-ignore Types are not up to date.
|
||||
const [ blocks, onInput, onChange ]: [
|
||||
BlockInstance[],
|
||||
ChangeHandler,
|
||||
ChangeHandler
|
||||
] = useEntityBlockEditor( 'postType', templateType );
|
||||
|
||||
return [ blocks, onInput, onChange ];
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
/* eslint-disable @woocommerce/dependency-group */
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useSelect } from '@wordpress/data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { store as coreStore } from '@wordpress/core-data';
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import { BlockInstance, parse } from '@wordpress/blocks';
|
||||
|
||||
type Pattern = {
|
||||
blockTypes: string[];
|
||||
categories: string[];
|
||||
content: string;
|
||||
name: string;
|
||||
source: string;
|
||||
title: string;
|
||||
};
|
||||
|
||||
type PatternWithBlocks = Pattern & {
|
||||
blocks: BlockInstance[];
|
||||
};
|
||||
|
||||
export const usePatternsByCategory = ( category: string ) => {
|
||||
const { blockPatterns, isLoading } = useSelect(
|
||||
( select ) => ( {
|
||||
// @ts-ignore - This is valid.
|
||||
blockPatterns: select( coreStore ).getBlockPatterns(),
|
||||
isLoading:
|
||||
// @ts-ignore - This is valid.
|
||||
! select( coreStore ).hasFinishedResolution(
|
||||
'getBlockPatterns'
|
||||
),
|
||||
} ),
|
||||
[]
|
||||
);
|
||||
|
||||
const patternsByCategory: PatternWithBlocks[] = useMemo( () => {
|
||||
return ( blockPatterns || [] )
|
||||
.filter( ( pattern: Pattern ) =>
|
||||
pattern.categories?.includes( category )
|
||||
)
|
||||
.map( ( pattern: Pattern ) => {
|
||||
return {
|
||||
...pattern,
|
||||
// @ts-ignore - Passing options is valid, but not in the type.
|
||||
blocks: parse( pattern.content, {
|
||||
__unstableSkipMigrationLogs: true,
|
||||
} ),
|
||||
};
|
||||
} );
|
||||
}, [ blockPatterns, category ] );
|
||||
|
||||
return { isLoading, patterns: patternsByCategory };
|
||||
};
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useEffect, useState } from '@wordpress/element';
|
||||
|
||||
type ScrollDirection = 'topDown' | 'bottomUp';
|
||||
|
||||
export const useScrollOpacity = (
|
||||
selector: string,
|
||||
direction: ScrollDirection = 'topDown',
|
||||
sensitivity = 0.2
|
||||
) => {
|
||||
const [ opacity, setOpacity ] = useState( 0.05 );
|
||||
|
||||
useEffect( () => {
|
||||
const targetElement = document.querySelector( selector );
|
||||
|
||||
const handleScroll = () => {
|
||||
if ( targetElement ) {
|
||||
const maxScrollHeight =
|
||||
targetElement.scrollHeight - targetElement.clientHeight;
|
||||
const currentScrollPosition = targetElement.scrollTop;
|
||||
const maxEffectScroll = maxScrollHeight * sensitivity;
|
||||
|
||||
let calculatedOpacity;
|
||||
if ( direction === 'bottomUp' ) {
|
||||
calculatedOpacity =
|
||||
1 - currentScrollPosition / maxEffectScroll;
|
||||
} else {
|
||||
calculatedOpacity = currentScrollPosition / maxEffectScroll;
|
||||
}
|
||||
|
||||
calculatedOpacity = 0.1 + 0.9 * calculatedOpacity;
|
||||
|
||||
// Clamp opacity between 0.1 and 1
|
||||
calculatedOpacity = Math.max(
|
||||
0.1,
|
||||
Math.min( calculatedOpacity, 1 )
|
||||
);
|
||||
|
||||
setOpacity( calculatedOpacity );
|
||||
}
|
||||
};
|
||||
|
||||
if ( targetElement ) {
|
||||
targetElement.addEventListener( 'scroll', handleScroll );
|
||||
}
|
||||
|
||||
return () => {
|
||||
if ( targetElement ) {
|
||||
targetElement.removeEventListener( 'scroll', handleScroll );
|
||||
}
|
||||
};
|
||||
}, [ selector, direction, sensitivity ] );
|
||||
|
||||
return opacity;
|
||||
};
|
|
@ -30,6 +30,10 @@ import ErrorBoundary from '@wordpress/edit-site/build-module/components/error-bo
|
|||
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { NavigableRegion } from '@wordpress/interface';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { EntityProvider } from '@wordpress/core-data';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import useEditedEntityRecord from '@wordpress/edit-site/build-module/components/use-edited-entity-record';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -40,6 +44,7 @@ import { SiteHub } from './site-hub';
|
|||
import { LogoBlockContext } from './logo-block-context';
|
||||
import ResizableFrame from './resizable-frame';
|
||||
import { OnboardingTour, useOnboardingTour } from './onboarding-tour';
|
||||
import { HighlightedBlockContextProvider } from './context/highlighted-block-context';
|
||||
|
||||
const { useGlobalStyle } = unlock( blockEditorPrivateApis );
|
||||
|
||||
|
@ -66,12 +71,22 @@ export const Layout = () => {
|
|||
const [ backgroundColor ] = useGlobalStyle( 'color.background' );
|
||||
const [ gradientValue ] = useGlobalStyle( 'color.gradient' );
|
||||
|
||||
const { record: template } = useEditedEntityRecord();
|
||||
const { id: templateId, type: templateType } = template;
|
||||
|
||||
return (
|
||||
<LogoBlockContext.Provider
|
||||
value={ {
|
||||
logoBlock,
|
||||
setLogoBlock,
|
||||
} }
|
||||
>
|
||||
<HighlightedBlockContextProvider>
|
||||
<EntityProvider kind="root" type="site">
|
||||
<EntityProvider
|
||||
kind="postType"
|
||||
type={ templateType }
|
||||
id={ templateId }
|
||||
>
|
||||
<div className={ classnames( 'edit-site-layout' ) }>
|
||||
<motion.div
|
||||
|
@ -90,7 +105,10 @@ export const Layout = () => {
|
|||
|
||||
<div className="edit-site-layout__content">
|
||||
<NavigableRegion
|
||||
ariaLabel={ __( 'Navigation', 'woocommerce' ) }
|
||||
ariaLabel={ __(
|
||||
'Navigation',
|
||||
'woocommerce'
|
||||
) }
|
||||
className="edit-site-layout__sidebar-region"
|
||||
>
|
||||
<motion.div
|
||||
|
@ -99,7 +117,8 @@ export const Layout = () => {
|
|||
type: 'tween',
|
||||
duration:
|
||||
// Disable transitiont in mobile to emulate a full page transition.
|
||||
disableMotion || isMobileViewport
|
||||
disableMotion ||
|
||||
isMobileViewport
|
||||
? 0
|
||||
: ANIMATION_DURATION,
|
||||
ease: 'easeOut',
|
||||
|
@ -122,7 +141,9 @@ export const Layout = () => {
|
|||
whileHover={ {
|
||||
scale: 1.005,
|
||||
transition: {
|
||||
duration: disableMotion ? 0 : 0.5,
|
||||
duration: disableMotion
|
||||
? 0
|
||||
: 0.5,
|
||||
ease: 'easeOut',
|
||||
},
|
||||
} }
|
||||
|
@ -141,7 +162,9 @@ export const Layout = () => {
|
|||
>
|
||||
<ErrorBoundary>
|
||||
<ResizableFrame
|
||||
isReady={ ! isEditorLoading }
|
||||
isReady={
|
||||
! isEditorLoading
|
||||
}
|
||||
duringGuideTour={
|
||||
shouldTourBeShown &&
|
||||
! onboardingTourProps.showWelcomeTour
|
||||
|
@ -166,7 +189,9 @@ export const Layout = () => {
|
|||
} }
|
||||
>
|
||||
<Editor
|
||||
isLoading={ isEditorLoading }
|
||||
isLoading={
|
||||
isEditorLoading
|
||||
}
|
||||
/>
|
||||
</ResizableFrame>
|
||||
</ErrorBoundary>
|
||||
|
@ -179,6 +204,9 @@ export const Layout = () => {
|
|||
{ shouldTourBeShown && (
|
||||
<OnboardingTour { ...onboardingTourProps } />
|
||||
) }
|
||||
</EntityProvider>
|
||||
</EntityProvider>
|
||||
</HighlightedBlockContextProvider>
|
||||
</LogoBlockContext.Provider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,19 +1,64 @@
|
|||
/* eslint-disable @woocommerce/dependency-group */
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { createInterpolateElement } from '@wordpress/element';
|
||||
import {
|
||||
useCallback,
|
||||
createInterpolateElement,
|
||||
useContext,
|
||||
useEffect,
|
||||
} from '@wordpress/element';
|
||||
import { Link } from '@woocommerce/components';
|
||||
import { Spinner } from '@wordpress/components';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { __experimentalBlockPatternsList as BlockPatternList } from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { SidebarNavigationScreen } from './sidebar-navigation-screen';
|
||||
import { ADMIN_URL } from '~/utils/admin-settings';
|
||||
import { usePatternsByCategory } from '../hooks/use-patterns';
|
||||
import { useEditorBlocks } from '../hooks/use-editor-blocks';
|
||||
import { HighlightedBlockContext } from '../context/highlighted-block-context';
|
||||
|
||||
const SUPPORTED_HEADER_PATTERNS = [
|
||||
'woocommerce-blocks/header-centered-menu-with-search',
|
||||
'woocommerce-blocks/header-essential',
|
||||
'woocommerce-blocks/header-large',
|
||||
'woocommerce-blocks/header-minimal',
|
||||
];
|
||||
|
||||
export const SidebarNavigationScreenHeader = () => {
|
||||
const { isLoading, patterns } = usePatternsByCategory( 'woo-commerce' );
|
||||
const [ blocks, , onChange ] = useEditorBlocks();
|
||||
const { setHighlightedBlockIndex, resetHighlightedBlockIndex } = useContext(
|
||||
HighlightedBlockContext
|
||||
);
|
||||
|
||||
useEffect( () => {
|
||||
setHighlightedBlockIndex( 0 );
|
||||
}, [ setHighlightedBlockIndex ] );
|
||||
|
||||
const headerPatterns = patterns.filter( ( pattern ) =>
|
||||
SUPPORTED_HEADER_PATTERNS.includes( pattern.name )
|
||||
);
|
||||
|
||||
const onClickHeaderPattern = useCallback(
|
||||
( _pattern, selectedBlocks ) => {
|
||||
onChange( [ selectedBlocks[ 0 ], ...blocks.slice( 1 ) ], {
|
||||
selection: {},
|
||||
} );
|
||||
},
|
||||
[ blocks, onChange ]
|
||||
);
|
||||
|
||||
return (
|
||||
<SidebarNavigationScreen
|
||||
title={ __( 'Change your header', 'woocommerce' ) }
|
||||
onNavigateBackClick={ resetHighlightedBlockIndex }
|
||||
description={ createInterpolateElement(
|
||||
__(
|
||||
"Select a new header from the options below. Your header includes your site's navigation and will be added to every page. You can continue customizing this via the <EditorLink>Editor</EditorLink>.",
|
||||
|
@ -30,7 +75,26 @@ export const SidebarNavigationScreenHeader = () => {
|
|||
) }
|
||||
content={
|
||||
<>
|
||||
<div className="edit-site-sidebar-navigation-screen-patterns__group-header"></div>
|
||||
<div className="edit-site-sidebar-navigation-screen-patterns__group-header">
|
||||
{ isLoading && (
|
||||
<span className="components-placeholder__preview">
|
||||
<Spinner />
|
||||
</span>
|
||||
) }
|
||||
|
||||
{ ! isLoading && (
|
||||
<BlockPatternList
|
||||
shownPatterns={ headerPatterns }
|
||||
blockPatterns={ headerPatterns }
|
||||
onClickPattern={ onClickHeaderPattern }
|
||||
label={ 'Headers' }
|
||||
orientation="vertical"
|
||||
category={ 'header' }
|
||||
isDraggable={ false }
|
||||
showTitlesAsTooltip={ true }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -40,6 +40,7 @@ export const SidebarNavigationScreen = ( {
|
|||
footer,
|
||||
description,
|
||||
backPath: backPathProp,
|
||||
onNavigateBackClick,
|
||||
}: {
|
||||
isRoot?: boolean;
|
||||
title: string;
|
||||
|
@ -49,6 +50,7 @@ export const SidebarNavigationScreen = ( {
|
|||
footer?: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
backPath?: string;
|
||||
onNavigateBackClick?: () => void;
|
||||
} ) => {
|
||||
const { sendEvent } = useContext( CustomizeStoreContext );
|
||||
const location = useLocation();
|
||||
|
@ -75,6 +77,7 @@ export const SidebarNavigationScreen = ( {
|
|||
{ ! isRoot && (
|
||||
<SidebarButton
|
||||
onClick={ () => {
|
||||
onNavigateBackClick?.();
|
||||
const backPath =
|
||||
backPathProp ?? location.state?.backPath;
|
||||
if ( backPath ) {
|
||||
|
@ -93,6 +96,7 @@ export const SidebarNavigationScreen = ( {
|
|||
{ isRoot && (
|
||||
<SidebarButton
|
||||
onClick={ () => {
|
||||
onNavigateBackClick?.();
|
||||
sendEvent( 'GO_BACK_TO_DESIGN_WITH_AI' );
|
||||
} }
|
||||
icon={ icon }
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add header customization to the Assembler Hub
|
693
pnpm-lock.yaml
693
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue