Add support for basic tab navigation when selecting template

MAILPOET-6331
This commit is contained in:
Oluwaseun Olorunsola
2024-12-03 17:08:37 +01:00
committed by Oluwaseun Olorunsola
parent 5743ccbc5f
commit cb091e0dc6
4 changed files with 143 additions and 97 deletions

View File

@ -1,4 +1,4 @@
import { useState } from '@wordpress/element';
import { store as editorStore } from '@wordpress/editor'; import { store as editorStore } from '@wordpress/editor';
import { dispatch } from '@wordpress/data'; import { dispatch } from '@wordpress/data';
import { import {
@ -15,12 +15,39 @@ import { TemplateCategoriesListSidebar } from './template-categories-list-sideba
const BLANK_TEMPLATE = 'email-general'; const BLANK_TEMPLATE = 'email-general';
export function SelectTemplateModal( { function SelectTemplateBody( {
onSelectCallback, initialCategory,
closeCallback = null, templateCategories,
previewContent = '', templates,
handleTemplateSelection,
} ) { } ) {
const [ templates ] = usePreviewTemplates( previewContent ); const [ selectedCategory, setSelectedCategory ] = useState(
initialCategory?.name
);
return (
<div className="block-editor-block-patterns-explorer">
<TemplateCategoriesListSidebar
templateCategories={ templateCategories }
selectedCategory={ selectedCategory }
onClickCategory={ setSelectedCategory }
/>
<TemplateList
templates={ templates }
onTemplateSelection={ handleTemplateSelection }
selectedCategory={ selectedCategory }
/>
</div>
);
}
export function SelectTemplateModal( {
onSelectCallback,
closeCallback = null,
previewContent = '',
} ) {
const [ templates ] = usePreviewTemplates( previewContent );
const hasTemplates = templates?.length > 0; const hasTemplates = templates?.length > 0;
@ -49,44 +76,43 @@ export function SelectTemplateModal( {
handleTemplateSelection( blankTemplate ); handleTemplateSelection( blankTemplate );
}; };
const dummyTemplateCategories = [ const dummyTemplateCategories = [
{ {
name: 'recent', name: 'recent',
label: 'Recent' label: 'Recent',
}, },
{ {
name: 'basic', name: 'basic',
label: 'Basic' label: 'Basic',
} },
]; ];
const onClickCategory = () => {}
return ( return (
<Modal <Modal
title="Select a template" title={ __( 'Select a template', 'mailpoet' ) }
onRequestClose={ () => onRequestClose={ () =>
closeCallback ? closeCallback() : handleCloseWithoutSelection() closeCallback ? closeCallback() : handleCloseWithoutSelection()
} }
isFullScreen isFullScreen
> >
<div className="block-editor-block-patterns-explorer"> <SelectTemplateBody
<TemplateCategoriesListSidebar templateCategories={dummyTemplateCategories} selectedCategory={dummyTemplateCategories[0].name} onClickCategory={onClickCategory} /> initialCategory={ dummyTemplateCategories[ 0 ] }
templateCategories={ dummyTemplateCategories }
templates={ templates }
handleTemplateSelection={ handleTemplateSelection }
/>
<TemplateList templates={templates} onTemplateSelection={ handleTemplateSelection} /> <Flex justify="flex-end">
<FlexItem>
<Flex justify="flex-end"> <Button
<FlexItem> variant="tertiary"
<Button onClick={ () => handleCloseWithoutSelection() }
variant="tertiary" isBusy={ ! hasTemplates }
onClick={ () => handleCloseWithoutSelection() } >
isBusy={ ! hasTemplates } { __( 'Start from scratch', 'mailpoet' ) }
> </Button>
{ __( 'Start from scratch', 'mailpoet' ) } </FlexItem>
</Button> </Flex>
</FlexItem>
</Flex>
</div>
</Modal> </Modal>
); );
} }

View File

@ -1,67 +1,83 @@
import { useMemo } from '@wordpress/element';
// @ts-expect-error No types available for this component // @ts-expect-error No types available for this component
import { BlockPreview } from '@wordpress/block-editor'; import { BlockPreview } from '@wordpress/block-editor';
import { import {
__experimentalHStack as HStack, // eslint-disable-line __experimentalHStack as HStack, // eslint-disable-line
} from '@wordpress/components'; } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { Async } from './async'; import { Async } from './async';
export function TemplateList({templates, onTemplateSelection}) { function TemplateListBox( { templates, onTemplateSelection } ) {
return (
<div className="block-editor-block-patterns-list" role="listbox">
{ templates.map( ( template ) => (
<div
key={ template.slug }
className="block-editor-block-patterns-list__list-item"
>
<div
className="block-editor-block-patterns-list__item"
role="button"
tabIndex={ 0 }
onClick={ () => {
onTemplateSelection( template );
} }
onKeyPress={ ( event ) => {
if ( event.key === 'Enter' || event.key === ' ' ) {
onTemplateSelection( template );
}
} }
>
<Async
placeholder={
<p>
{ __( 'rendering template', 'mailpoet' ) }
</p>
}
>
<BlockPreview
blocks={ template.previewContentParsed }
viewportWidth={ 900 }
minHeight={ 300 }
additionalStyles={ [
{
css: template.template.email_theme_css,
},
] }
/>
return ( <HStack className="block-editor-patterns__pattern-details">
<div className="block-editor-block-patterns-explorer__list"> <div className="block-editor-block-patterns-list__item-title">
<div { template.template.title.rendered }
className="block-editor-block-patterns-list" </div>
role="listbox" </HStack>
> </Async>
{templates.map((template) => ( </div>
<div </div>
key={template.slug} ) ) }
className="block-editor-block-patterns-list__list-item" </div>
> );
<div }
className="block-editor-block-patterns-list__item"
role="button" export function TemplateList( {
tabIndex={0} templates,
onClick={() => { onTemplateSelection,
onTemplateSelection(template); selectedCategory,
}} } ) {
onKeyPress={(event) => { const filteredTemplates = useMemo(
if ( () =>
event.key === 'Enter' || templates.filter(
event.key === ' ' ( template ) => template.category === selectedCategory
) { ),
onTemplateSelection(template); [ selectedCategory, templates ]
} );
}}
> return (
<Async <div className="block-editor-block-patterns-explorer__list">
placeholder={ <TemplateListBox
<p>rendering template</p> templates={ filteredTemplates }
} onTemplateSelection={ onTemplateSelection }
> />
<BlockPreview </div>
blocks={template.previewContentParsed} );
viewportWidth={900}
minHeight={300}
additionalStyles={[
{
css: template.template.email_theme_css,
},
]}
/>
<HStack className="block-editor-patterns__pattern-details">
<div className="block-editor-block-patterns-list__item-title">
{
template.template.title.rendered
}
</div>
</HStack>
</Async>
</div>
</div>
))}
</div>
</div>
);
} }

View File

@ -103,6 +103,7 @@ export function usePreviewTemplates(
? contentPatternBlocksGeneral ? contentPatternBlocksGeneral
: contentPatternBlocks, : contentPatternBlocks,
template, template,
category: 'basic', // TODO: This will be updated once template category is implemented
}; };
} ), } ),
]; ];

View File

@ -228,8 +228,11 @@ export type TemplatePreview = {
previewContentParsed: BlockInstance[]; previewContentParsed: BlockInstance[];
emailParsed: BlockInstance[]; emailParsed: BlockInstance[];
template: EmailTemplatePreview; template: EmailTemplatePreview;
category?: TemplateCategory;
}; };
export type TemplateCategory = 'recent' | 'basic';
export type Feature = export type Feature =
| 'fullscreenMode' | 'fullscreenMode'
| 'showIconLabels' | 'showIconLabels'