168 lines
4.5 KiB
TypeScript
168 lines
4.5 KiB
TypeScript
|
/**
|
||
|
* External dependencies
|
||
|
*/
|
||
|
import { BlockInstance } from '@wordpress/blocks';
|
||
|
|
||
|
/**
|
||
|
* Internal dependencies
|
||
|
*/
|
||
|
import { Pattern } from '~/customize-store/types/pattern';
|
||
|
import { PATTERN_CATEGORIES } from './categories';
|
||
|
|
||
|
/**
|
||
|
* Adds a 'is-added' CSS class to each pattern preview element in the pattern list that matches a block's pattern name.
|
||
|
* This function iterates through an array of blocks added in the page, extracts the pattern name from each block's metadata,
|
||
|
* and finds the corresponding pattern preview element in the pattern list by its ID. If found, the 'is-added' class is added to the element.
|
||
|
*/
|
||
|
export const addIsAddedClassToPatternPreview = (
|
||
|
patternListEl: HTMLElement,
|
||
|
blocks: BlockInstance[]
|
||
|
) => {
|
||
|
patternListEl.querySelectorAll( '.is-added' ).forEach( ( element ) => {
|
||
|
element.classList.remove( 'is-added' );
|
||
|
} );
|
||
|
|
||
|
blocks.forEach( ( block ) => {
|
||
|
const patterName = block.attributes.metadata?.patternName;
|
||
|
if ( ! patterName ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const element = patternListEl.querySelector( `[id="${ patterName }"]` );
|
||
|
|
||
|
if ( element ) {
|
||
|
element.classList.add( 'is-added' );
|
||
|
}
|
||
|
} );
|
||
|
};
|
||
|
|
||
|
const orderPatternList = {
|
||
|
intro: [
|
||
|
'Intro: Two column with content and image',
|
||
|
'Heading with image and two columns below',
|
||
|
'Fullwidth content with background image',
|
||
|
'Two column with image and content',
|
||
|
'Centered heading with two column text',
|
||
|
'Content with button and fullwidth image',
|
||
|
'Center-aligned content overlaid on an image',
|
||
|
'Left-aligned content overlaid on an image',
|
||
|
'Centered Content',
|
||
|
'Large left-aligned heading',
|
||
|
'Fullwidth image with content and button',
|
||
|
'Pull right with wide image below',
|
||
|
],
|
||
|
about: [
|
||
|
'Content right with image left',
|
||
|
'Content left with image right',
|
||
|
'Heading left and content right',
|
||
|
'Four image grid, content on the left',
|
||
|
'Content with grid of images on right',
|
||
|
'Heading with two media columns',
|
||
|
'Heading with content and large image below',
|
||
|
'Centered heading and button',
|
||
|
'Content left, image right',
|
||
|
'Tall content with image left',
|
||
|
'Fullwidth image, content pull right',
|
||
|
'Right-aligned Content',
|
||
|
'Large heading with content on right',
|
||
|
'Tall content with image right',
|
||
|
'Spread right, heavy text',
|
||
|
'Heading with button and text',
|
||
|
'Left-aligned content',
|
||
|
'Pull left, fullwidth image',
|
||
|
],
|
||
|
services: [
|
||
|
'Three columns with images and content',
|
||
|
'Heading with four text sections',
|
||
|
'Two columns with images',
|
||
|
'Heading with six text sections',
|
||
|
'Headings left, content right',
|
||
|
],
|
||
|
} as Record< string, string[] >;
|
||
|
|
||
|
const orderByPriority = (
|
||
|
aElementTitle: string,
|
||
|
bElementTitle: string,
|
||
|
category: string
|
||
|
) => {
|
||
|
const aIndex = orderPatternList[ category ]?.indexOf( aElementTitle );
|
||
|
const bIndex = orderPatternList[ category ]?.indexOf( bElementTitle );
|
||
|
|
||
|
if ( aIndex === -1 && bIndex === -1 ) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
if ( aIndex > -1 && bIndex > -1 ) {
|
||
|
return aIndex - bIndex;
|
||
|
}
|
||
|
|
||
|
if ( aIndex === -1 && bIndex > -1 ) {
|
||
|
return 1;
|
||
|
}
|
||
|
if ( bIndex === -1 && aIndex > -1 ) {
|
||
|
return -1;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Sorts patterns by category and priority based on the orderPatternList object . For 'intro' and 'about' categories
|
||
|
* prioritized DotCom Patterns. For intro category, it also prioritizes the "centered-content-with-image-below" pattern.
|
||
|
* For other categories, it simply sorts patterns to prioritize Woo Patterns.
|
||
|
*/
|
||
|
export const sortPatternsByCategory = (
|
||
|
patterns: Pattern[],
|
||
|
category: keyof typeof PATTERN_CATEGORIES
|
||
|
) => {
|
||
|
const prefix = 'woocommerce-blocks';
|
||
|
if ( category === 'intro' || category === 'about' ) {
|
||
|
return patterns.sort( ( a, b ) => {
|
||
|
if (
|
||
|
a.name ===
|
||
|
'woocommerce-blocks/centered-content-with-image-below'
|
||
|
) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (
|
||
|
b.name ===
|
||
|
'woocommerce-blocks/centered-content-with-image-below'
|
||
|
) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
const priority = orderByPriority( a.title, b.title, category );
|
||
|
|
||
|
if ( typeof priority === 'number' ) {
|
||
|
return priority;
|
||
|
}
|
||
|
|
||
|
if ( a.name.includes( prefix ) && ! b.name.includes( prefix ) ) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if ( ! a.name.includes( prefix ) && b.name.includes( prefix ) ) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// If neither title is in the list, keep their original order
|
||
|
return 0;
|
||
|
} );
|
||
|
}
|
||
|
|
||
|
return patterns.sort( ( a, b ) => {
|
||
|
const priority = orderByPriority( a.title, b.title, category );
|
||
|
|
||
|
if ( typeof priority === 'number' ) {
|
||
|
return priority;
|
||
|
}
|
||
|
|
||
|
if ( a.name.includes( prefix ) && ! b.name.includes( prefix ) ) {
|
||
|
return -1;
|
||
|
}
|
||
|
if ( ! a.name.includes( prefix ) && b.name.includes( prefix ) ) {
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
} );
|
||
|
};
|