Skip to content

Commit

Permalink
CYS: Override header and footer template parts (#45196)
Browse files Browse the repository at this point in the history
* CYS: Override the header and footer

* fix unit test

* fix lint error

* Add changefile(s) from automation for the following project(s): woocommerce

* fix opacity

---------

Co-authored-by: github-actions <github-actions@github.com>
  • Loading branch information
2 people authored and Konamiman committed Mar 13, 2024
1 parent a250ebf commit 0eea7ce
Show file tree
Hide file tree
Showing 12 changed files with 245 additions and 104 deletions.
Expand Up @@ -6,8 +6,8 @@
// @ts-ignore No types for this exist yet.
import { store as blockEditorStore } from '@wordpress/block-editor';
// @ts-ignore No types for this exist yet.
import { useEntityRecords } from '@wordpress/core-data';
import { select } from '@wordpress/data';
import { useEntityRecords, store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
// @ts-ignore No types for this exist yet.
import { privateApis as routerPrivateApis } from '@wordpress/router';
// @ts-ignore No types for this exist yet.
Expand Down Expand Up @@ -67,7 +67,19 @@ const MAX_PAGE_COUNT = 100;
export const BlockEditor = ( {} ) => {
const history = useHistory();
const settings = useSiteEditorSettings();
const [ blocks, , onChange ] = useEditorBlocks();

const currentTemplate = useSelect(
( select ) =>
// @ts-expect-error No types for this exist yet.
select( coreStore ).__experimentalGetTemplateForLink( '/' ),
[]
);

const [ blocks, , onChange ] = useEditorBlocks(
'wp_template',
currentTemplate.id
);

const urlParams = useQuery();
const { currentState } = useContext( CustomizeStoreContext );

Expand Down Expand Up @@ -120,8 +132,8 @@ export const BlockEditor = ( {} ) => {
[ history, urlParams, pages ]
);

const { highlightedBlockIndex } = useContext( HighlightedBlockContext );
const isHighlighting = highlightedBlockIndex !== -1;
const { highlightedBlockClientId } = useContext( HighlightedBlockContext );
const isHighlighting = highlightedBlockClientId !== null;
const additionalStyles = isHighlighting
? `
.wp-block.preview-opacity {
Expand All @@ -130,23 +142,37 @@ export const BlockEditor = ( {} ) => {
`
: '';

const opacityClass = 'preview-opacity';

const renderedBlocks = useMemo(
() =>
blocks.map( ( block, i ) => {
if ( ! isHighlighting || i === highlightedBlockIndex ) {
return block;
blocks.map( ( block ) => {
if (
! isHighlighting ||
block.clientId === highlightedBlockClientId
) {
return {
...block,
attributes: {
...block.attributes,
className: block.attributes.className?.replace(
opacityClass,
''
),
},
};
}

return {
...block,
attributes: {
...block.attributes,
className:
block.attributes.className + ' preview-opacity',
block.attributes.className + ` ${ opacityClass }`,
},
};
} ),
[ blocks, highlightedBlockIndex, isHighlighting ]
[ blocks, highlightedBlockClientId, isHighlighting ]
);

return (
Expand Down
Expand Up @@ -4,13 +4,17 @@
import React, { createContext, useState } from '@wordpress/element';
import type { ReactNode } from 'react';

export const HighlightedBlockContext = createContext( {
highlightedBlockIndex: -1,
export const HighlightedBlockContext = createContext< {
highlightedBlockClientId: string | null;
setHighlightedBlockClientId: ( clientId: string | null ) => void;
resetHighlightedBlockClientId: () => void;
} >( {
highlightedBlockClientId: null,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
setHighlightedBlockIndex: ( index: number ) => {
setHighlightedBlockClientId: ( clientId: string | null ) => {
// No op by default.
},
resetHighlightedBlockIndex: () => {
resetHighlightedBlockClientId: () => {
// No op by default.
},
} );
Expand All @@ -23,18 +27,20 @@ export const HighlightedBlockContextProvider = ( {
children: ReactNode;
} ) => {
// Create some state
const [ highlightedBlockIndex, setHighlightedBlockIndex ] = useState( -1 );
const [ highlightedBlockClientId, setHighlightedBlockClientId ] = useState<
string | null
>( null );

const resetHighlightedBlockIndex = () => {
setHighlightedBlockIndex( -1 );
const resetHighlightedBlockClientId = () => {
setHighlightedBlockClientId( null );
};

return (
<HighlightedBlockContext.Provider
value={ {
highlightedBlockIndex,
setHighlightedBlockIndex,
resetHighlightedBlockIndex,
highlightedBlockClientId,
setHighlightedBlockClientId,
resetHighlightedBlockClientId,
} }
>
{ children }
Expand Down
Expand Up @@ -13,19 +13,17 @@ import { usePatterns } from '../use-patterns';
jest.mock( '../use-patterns' );
jest.mock( '~/customize-store/data/homepageTemplates', () => ( {
HOMEPAGE_TEMPLATES: {
template1: { blocks: [ 'header', 'content1', 'content2', 'footer' ] },
template2: { blocks: [ 'header', 'content3', 'footer' ] },
template1: { blocks: [ 'content1', 'content2' ] },
template2: { blocks: [ 'content3' ] },
},
} ) );

const mockUsePatterns = usePatterns;

const mockPatternsByName = {
header: { name: 'header', content: '<div>Header</div>' },
content1: { name: 'content1', content: '<div>Content1</div>' },
content2: { name: 'content2', content: '<div>Content2</div>' },
content3: { name: 'content3', content: '<div>Content3</div>' },
footer: { name: 'footer', content: '<div>Footer</div>' },
};

describe( 'useHomeTemplates', () => {
Expand Down
Expand Up @@ -5,11 +5,6 @@
*/
// @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';

export type ChangeHandler = (
Expand All @@ -19,25 +14,18 @@ export type ChangeHandler = (

// 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(),
};
}, [] );

export const useEditorBlocks = (
templateType: 'wp_template' | 'wp_template_part',
templateId: string
): [ BlockInstance[], ChangeHandler, ChangeHandler ] => {
// @ts-ignore Types are not up to date.
const [ blocks, onInput, onChange ]: [
BlockInstance[] | undefined,
ChangeHandler,
ChangeHandler
] = useEntityBlockEditor( 'postType', templateType );
] = useEntityBlockEditor( 'postType', templateType, {
id: templateId,
} );

return [ blocks ?? [], onInput, onChange ];
};
Expand Up @@ -61,7 +61,7 @@ export const useHomeTemplates = () => {
) => {
if ( templateName in recommendedTemplates ) {
acc[ templateName ] = getTemplatePatterns(
template.blocks.slice( 1, -1 ),
template.blocks,
patternsByName
);
}
Expand Down
Expand Up @@ -52,7 +52,7 @@ export const SaveHub = () => {
const { sendEvent } = useContext( CustomizeStoreContext );
const [ isResolving, setIsResolving ] = useState< boolean >( false );
const navigator = useNavigator();
const { resetHighlightedBlockIndex } = useContext(
const { resetHighlightedBlockClientId } = useContext(
HighlightedBlockContext
);
const isEditorLoading = useIsSiteEditorLoading();
Expand Down Expand Up @@ -164,7 +164,7 @@ export const SaveHub = () => {

try {
await save();
resetHighlightedBlockIndex();
resetHighlightedBlockClientId();
navigator.goToParent();
} catch ( error ) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand Down
Expand Up @@ -14,6 +14,8 @@ import {
import { Link } from '@woocommerce/components';
import { recordEvent } from '@woocommerce/tracks';
import { Spinner } from '@wordpress/components';
// @ts-expect-error No types for this exist yet.
import { store as coreStore } from '@wordpress/core-data';

/**
* Internal dependencies
Expand All @@ -29,6 +31,8 @@ import { findPatternByBlock } from './utils';
import BlockPatternList from '../block-pattern-list';
import { CustomizeStoreContext } from '~/customize-store/assembler-hub';
import { FlowType } from '~/customize-store/types';
import { footerTemplateId } from '~/customize-store/data/homepageTemplates';
import { useSelect } from '@wordpress/data';

const SUPPORTED_FOOTER_PATTERNS = [
'woocommerce-blocks/footer-simple-menu',
Expand All @@ -43,18 +47,41 @@ export const SidebarNavigationScreenFooter = () => {
} );

const { isLoading, patterns } = usePatternsByCategory( 'woo-commerce' );
const [ blocks, , onChange ] = useEditorBlocks();
const { setHighlightedBlockIndex, resetHighlightedBlockIndex } = useContext(
HighlightedBlockContext

const currentTemplate = useSelect(
( select ) =>
// @ts-expect-error No types for this exist yet.
select( coreStore ).__experimentalGetTemplateForLink( '/' ),
[]
);

const [ mainTemplateBlocks ] = useEditorBlocks(
'wp_template',
currentTemplate.id
);

const [ blocks, , onChange ] = useEditorBlocks(
'wp_template_part',
footerTemplateId
);

const footerTemplatePartBlockClientId = mainTemplateBlocks.find(
( block ) => block.attributes.slug === 'footer'
);

const { setHighlightedBlockClientId, resetHighlightedBlockClientId } =
useContext( HighlightedBlockContext );
// eslint-disable-next-line react-hooks/exhaustive-deps
const { selectedPattern, setSelectedPattern } = useSelectedPattern();

useEffect( () => {
if ( blocks && blocks.length ) {
setHighlightedBlockIndex( blocks.length - 1 );
}
}, [ setHighlightedBlockIndex, blocks ] );
setHighlightedBlockClientId(
footerTemplatePartBlockClientId?.clientId ?? null
);
}, [
footerTemplatePartBlockClientId?.clientId,
setHighlightedBlockClientId,
] );

const footerPatterns = useMemo(
() =>
Expand Down Expand Up @@ -115,7 +142,7 @@ export const SidebarNavigationScreenFooter = () => {
return (
<SidebarNavigationScreen
title={ title }
onNavigateBackClick={ resetHighlightedBlockIndex }
onNavigateBackClick={ resetHighlightedBlockClientId }
description={ createInterpolateElement( description, {
EditorLink: (
<Link
Expand Down
Expand Up @@ -14,6 +14,9 @@ import {
import { Link } from '@woocommerce/components';
import { recordEvent } from '@woocommerce/tracks';
import { Spinner } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
// @ts-expect-error No types for this exist yet.
import { store as coreStore } from '@wordpress/core-data';

/**
* Internal dependencies
Expand All @@ -29,6 +32,7 @@ import { findPatternByBlock } from './utils';
import BlockPatternList from '../block-pattern-list';
import { CustomizeStoreContext } from '~/customize-store/assembler-hub';
import { FlowType } from '~/customize-store/types';
import { headerTemplateId } from '~/customize-store/data/homepageTemplates';

const SUPPORTED_HEADER_PATTERNS = [
'woocommerce-blocks/header-essential',
Expand All @@ -44,17 +48,38 @@ export const SidebarNavigationScreenHeader = () => {
} );

const { isLoading, patterns } = usePatternsByCategory( 'woo-commerce' );
const [ blocks, , onChange ] = useEditorBlocks();
const { setHighlightedBlockIndex, resetHighlightedBlockIndex } = useContext(
HighlightedBlockContext

const currentTemplate = useSelect(
( select ) =>
// @ts-expect-error No types for this exist yet.
select( coreStore ).__experimentalGetTemplateForLink( '/' ),
[]
);

const [ mainTemplateBlocks ] = useEditorBlocks(
'wp_template',
currentTemplate.id
);

const [ blocks, , onChange ] = useEditorBlocks(
'wp_template_part',
headerTemplateId
);

const headerTemplatePartBlock = mainTemplateBlocks.find(
( block ) => block.attributes.slug === 'header'
);

const { setHighlightedBlockClientId, resetHighlightedBlockClientId } =
useContext( HighlightedBlockContext );
// eslint-disable-next-line react-hooks/exhaustive-deps
const { selectedPattern, setSelectedPattern } = useSelectedPattern();

useEffect( () => {
setHighlightedBlockIndex( 0 );
}, [ setHighlightedBlockIndex ] );

setHighlightedBlockClientId(
headerTemplatePartBlock?.clientId ?? null
);
}, [ headerTemplatePartBlock?.clientId, setHighlightedBlockClientId ] );
const headerPatterns = useMemo(
() =>
patterns
Expand Down Expand Up @@ -103,7 +128,7 @@ export const SidebarNavigationScreenHeader = () => {
return (
<SidebarNavigationScreen
title={ title }
onNavigateBackClick={ resetHighlightedBlockIndex }
onNavigateBackClick={ resetHighlightedBlockClientId }
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>.",
Expand Down

0 comments on commit 0eea7ce

Please sign in to comment.