Skip to content

Commit

Permalink
Pattern Library: Add Readymade Templates section (#92023)
Browse files Browse the repository at this point in the history
Introduces a new Pattern Library section to highlight Readymade Templates.
  • Loading branch information
mmtr committed Jun 25, 2024
1 parent b921885 commit 4742267
Show file tree
Hide file tree
Showing 12 changed files with 207 additions and 3 deletions.
4 changes: 2 additions & 2 deletions client/my-sites/patterns/components/copy-paste-info/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ImgStyle from './images/style.svg';

import './style.scss';

export function PatternsCopyPasteInfo() {
export function PatternsCopyPasteInfo( { theme }: { theme?: 'dark' } ) {
const translate = useTranslate();
return (
<PatternsSection
Expand All @@ -20,7 +20,7 @@ export function PatternsCopyPasteInfo() {
textOnly: true,
}
) }
theme="dark"
theme={ theme }
title={ translate( 'Copy, paste, customize—it’s easy like that', {
comment:
'Heading text in a section that contains info about block patterns built by WordPress.com',
Expand Down
16 changes: 15 additions & 1 deletion client/my-sites/patterns/components/pattern-library/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isEnabled } from '@automattic/calypso-config';
import page from '@automattic/calypso-router';
import { Button } from '@automattic/components';
import {
Expand All @@ -22,6 +23,7 @@ import { ViewToggle } from 'calypso/my-sites/patterns/components/view-toggle';
import { usePatternsContext } from 'calypso/my-sites/patterns/context';
import { usePatternCategories } from 'calypso/my-sites/patterns/hooks/use-pattern-categories';
import { usePatterns } from 'calypso/my-sites/patterns/hooks/use-patterns';
import { useReadymadeTemplates } from 'calypso/my-sites/patterns/hooks/use-readymade-templates';
import { useRecordPatternsEvent } from 'calypso/my-sites/patterns/hooks/use-record-patterns-event';
import { filterPatternsByTerm } from 'calypso/my-sites/patterns/lib/filter-patterns-by-term';
import { filterPatternsByType } from 'calypso/my-sites/patterns/lib/filter-patterns-by-type';
Expand All @@ -33,6 +35,7 @@ import {
PatternView,
CategoryGalleryFC,
PatternGalleryFC,
ReadymadeTemplatesFC,
} from 'calypso/my-sites/patterns/types';
import { useSelector } from 'calypso/state';
import { isUserLoggedIn } from 'calypso/state/current-user/selectors';
Expand Down Expand Up @@ -73,11 +76,13 @@ function scrollToPatternView( stickyFiltersElement: HTMLDivElement, onlyIfBelowT
type PatternLibraryProps = {
categoryGallery: CategoryGalleryFC;
patternGallery: PatternGalleryFC;
readymadeTemplates: ReadymadeTemplatesFC;
};

export const PatternLibrary = ( {
categoryGallery: CategoryGallery,
patternGallery: PatternGallery,
readymadeTemplates: ReadymadeTemplates,
}: PatternLibraryProps ) => {
const locale = useLocale();
const translate = useTranslate();
Expand All @@ -94,6 +99,7 @@ export const PatternLibrary = ( {
category,
{ enabled: Boolean( category || searchTerm ) }
);
const { data: readymadeTemplates = [] } = useReadymadeTemplates();

const patterns = searchTerm
? filterPatternsByTerm( rawPatterns, searchTerm )
Expand Down Expand Up @@ -357,7 +363,13 @@ export const PatternLibrary = ( {
</PatternLibraryBody>
) }

{ isHomePage && <PatternsCopyPasteInfo /> }
{ isEnabled( 'readymade-templates/showcase' ) && isHomePage && (
<ReadymadeTemplates readymadeTemplates={ readymadeTemplates } />
) }

{ ! isEnabled( 'readymade-templates/showcase' ) && isHomePage && (
<PatternsCopyPasteInfo theme="dark" />
) }

{ isHomePage && (
<CategoryGallery
Expand All @@ -369,6 +381,8 @@ export const PatternLibrary = ( {
patternTypeFilter={ PatternTypeFilter.PAGES }
/>
) }

{ isEnabled( 'readymade-templates/showcase' ) && isHomePage && <PatternsCopyPasteInfo /> }
</div>

<PatternsGetStarted />
Expand Down
30 changes: 30 additions & 0 deletions client/my-sites/patterns/components/readymade-templates/client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
PatternRenderer,
BlockRendererProvider,
PatternsRendererContext,
} from '@automattic/block-renderer';
import { ReadymadeTemplatesSection } from 'calypso/my-sites/patterns/components/readymade-templates/section';
import { RENDERER_SITE_ID } from 'calypso/my-sites/patterns/constants';
import { useRenderReadymadeTemplate } from 'calypso/my-sites/patterns/hooks/use-render-readymade-template';
import { ReadymadeTemplate, ReadymadeTemplatesFC } from 'calypso/my-sites/patterns/types';

const ReadymadeTemplatePreview = ( readymadeTemplate: ReadymadeTemplate ) => {
const { data: renderedPatterns = {} } = useRenderReadymadeTemplate( readymadeTemplate );

return (
<PatternsRendererContext.Provider value={ { renderedPatterns, shouldShufflePosts: false } }>
{ Object.keys( renderedPatterns ).map( ( pattern ) => (
<PatternRenderer patternId={ pattern } viewportWidth={ 1200 } key={ pattern } />
) ) }
</PatternsRendererContext.Provider>
);
};

export const ReadymadeTemplatesClient: ReadymadeTemplatesFC = ( { readymadeTemplates } ) => (
<BlockRendererProvider siteId={ RENDERER_SITE_ID }>
<ReadymadeTemplatesSection
readymadeTemplates={ readymadeTemplates }
renderPreview={ ReadymadeTemplatePreview }
/>
</BlockRendererProvider>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useTranslate } from 'i18n-calypso';
import { ReactNode } from 'react';
import { PatternsSection } from 'calypso/my-sites/patterns/components/section';
import { ReadymadeTemplate, ReadymadeTemplatesProps } from 'calypso/my-sites/patterns/types';
import './style.scss';

type ReadymadeTemplatesSectionProps = ReadymadeTemplatesProps & {
renderPreview?: ( readymadeTemplate: ReadymadeTemplate ) => ReactNode;
};

export const ReadymadeTemplatesSection = ( {
readymadeTemplates,
renderPreview,
}: ReadymadeTemplatesSectionProps ) => {
const translate = useTranslate();

if ( ! readymadeTemplates.length ) {
return;
}

return (
<PatternsSection
bodyFullWidth
description={ translate(
'Explore a collection of beautiful site layouts made with our patterns.'
) }
theme="dark"
title={ translate( 'Ready-to-use site layouts' ) }
>
<div className="readymade-templates">
{ readymadeTemplates.map( ( readymadeTemplate ) => (
<div className="readymade-template" key={ readymadeTemplate.template_id }>
<div className="readymade-template__content">
{ renderPreview?.( readymadeTemplate ) }
</div>
<div className="readymade-template__title">{ readymadeTemplate.title }</div>
</div>
) ) }
</div>
</PatternsSection>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ReadymadeTemplatesSection } from 'calypso/my-sites/patterns/components/readymade-templates/section';
import { ReadymadeTemplatesFC } from 'calypso/my-sites/patterns/types';

export const ReadymadeTemplatesServer: ReadymadeTemplatesFC = ( { readymadeTemplates } ) => (
<ReadymadeTemplatesSection readymadeTemplates={ readymadeTemplates } />
);
51 changes: 51 additions & 0 deletions client/my-sites/patterns/components/readymade-templates/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
@import "@wordpress/base-styles/breakpoints";

.readymade-templates {
display: flex;
gap: 24px;
padding: 16px 110px 24px;
overflow: auto;
mask-image: linear-gradient(to right, transparent, #fff 110px, #fff calc(100% - 110px), transparent);

@media (max-width: $break-wide) {
padding-left: 24px;
padding-right: 24px;
mask-image: none;
}

@media (max-width: $break-medium) {
padding-top: 0;
padding-bottom: 0;
}
}

.readymade-template__content {
--readymade-template-width: 390px;
width: var(--readymade-template-width);
height: calc(var(--readymade-template-width) * 1.4);
background-color: #fff;
margin-bottom: 24px;
overflow: hidden;
border-radius: 2px;

@media (max-width: $break-huge) {
--readymade-template-width: calc(100vw / 3 - 90px);
}

@media (max-width: $break-wide) {
--readymade-template-width: calc(100vw / 3 - 50px);
}

@media (max-width: $break-medium) {
--readymade-template-width: calc(100vw / 2 - 72px);
}

@media (max-width: $break-small) {
--readymade-template-width: calc(100vw - 170px);
}
}

.readymade-template__title {
font-size: 1.125rem; /* stylelint-disable-line scales/font-sizes */
line-height: 26px;
}
15 changes: 15 additions & 0 deletions client/my-sites/patterns/hooks/use-readymade-templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useQuery } from '@tanstack/react-query';
import wpcom from 'calypso/lib/wp';
import type { ReadymadeTemplate } from 'calypso/my-sites/patterns/types';

export const useReadymadeTemplates = () =>
useQuery< ReadymadeTemplate[] >( {
queryKey: [ 'pattern-library', 'readymade-templates' ],
queryFn() {
return wpcom.req.get( {
path: '/themes/readymade-templates',
apiNamespace: 'wpcom/v2',
} );
},
staleTime: 5 * 60 * 1000,
} );
23 changes: 23 additions & 0 deletions client/my-sites/patterns/hooks/use-render-readymade-template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { RenderedPattern } from '@automattic/block-renderer';
import { useQuery } from '@tanstack/react-query';
import wpcom from 'calypso/lib/wp';
import { RENDERER_SITE_ID } from 'calypso/my-sites/patterns/constants';
import type { ReadymadeTemplate } from 'calypso/my-sites/patterns/types';

export const useRenderReadymadeTemplate = ( readymadeTemplate: ReadymadeTemplate ) =>
useQuery< { [ key: string ]: RenderedPattern } >( {
queryKey: [ 'pattern-library', 'readymade-template', readymadeTemplate.template_id, 'render' ],
queryFn() {
return wpcom.req.get(
{
path: `/sites/${ RENDERER_SITE_ID }/block-renderer/patterns/render`,
apiNamespace: 'wpcom/v2',
},
{
pattern_ids: readymadeTemplate.patterns.map( ( { id } ) => id ).join( ',' ),
site_title: readymadeTemplate.title,
}
);
},
staleTime: 5 * 60 * 1000,
} );
2 changes: 2 additions & 0 deletions client/my-sites/patterns/index.node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { CategoryGalleryServer } from 'calypso/my-sites/patterns/components/category-gallery/server';
import { PatternGalleryServer } from 'calypso/my-sites/patterns/components/pattern-gallery/server';
import { PatternLibrary } from 'calypso/my-sites/patterns/components/pattern-library';
import { ReadymadeTemplatesServer } from 'calypso/my-sites/patterns/components/readymade-templates/server';
import { PatternsContext } from 'calypso/my-sites/patterns/context';
import { getPatternCategoriesQueryOptions } from 'calypso/my-sites/patterns/hooks/use-pattern-categories';
import { getPatternsQueryOptions } from 'calypso/my-sites/patterns/hooks/use-patterns';
Expand Down Expand Up @@ -40,6 +41,7 @@ function renderPatterns( context: RouterContext, next: RouterNext ) {
<PatternLibrary
categoryGallery={ CategoryGalleryServer }
patternGallery={ PatternGalleryServer }
readymadeTemplates={ ReadymadeTemplatesServer }
/>
</PatternsWrapper>
</PatternsContext.Provider>
Expand Down
2 changes: 2 additions & 0 deletions client/my-sites/patterns/index.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { CategoryGalleryClient } from 'calypso/my-sites/patterns/components/cate
import { PatternsCategoryNotFound } from 'calypso/my-sites/patterns/components/category-not-found';
import { PatternGalleryClient } from 'calypso/my-sites/patterns/components/pattern-gallery/client';
import { PatternLibrary } from 'calypso/my-sites/patterns/components/pattern-library';
import { ReadymadeTemplatesClient } from 'calypso/my-sites/patterns/components/readymade-templates/client';
import { PatternsContext } from 'calypso/my-sites/patterns/context';
import { getPatternCategoriesQueryOptions } from 'calypso/my-sites/patterns/hooks/use-pattern-categories';
import { extractPatternIdFromHash } from 'calypso/my-sites/patterns/lib/extract-pattern-id-from-hash';
Expand Down Expand Up @@ -49,6 +50,7 @@ function renderPatterns( context: RouterContext, next: RouterNext ) {
<PatternLibrary
categoryGallery={ CategoryGalleryClient }
patternGallery={ PatternGalleryClient }
readymadeTemplates={ ReadymadeTemplatesClient }
/>
</PatternsWrapper>
</PatternsContext.Provider>
Expand Down
18 changes: 18 additions & 0 deletions client/my-sites/patterns/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,23 @@ export type PatternGalleryProps = {

export type PatternGalleryFC = React.FC< PatternGalleryProps >;

export type ReadymadeTemplatesProps = {
readymadeTemplates: ReadymadeTemplate[];
};
export type ReadymadeTemplatesFC = React.FC< ReadymadeTemplatesProps >;

export type PatternType = 'pattern' | 'page-layout';
export type PatternView = 'grid' | 'list';

type ReadymadeTemplatePattern = {
id: number;
source_site_sid: number;
};

export type ReadymadeTemplate = {
template_id: number;
title: string;
description: string;
content: string;
patterns: ReadymadeTemplatePattern[];
};
1 change: 1 addition & 0 deletions packages/block-renderer/src/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as BlockRendererContainer } from './block-renderer-container';
export { default as BlockRendererProvider } from './block-renderer-provider';
export { default as PatternRenderer } from './pattern-renderer';
export { default as PatternsRendererContext } from './patterns-renderer-context';
export { default as PatternsRendererProvider } from './patterns-renderer-provider';

0 comments on commit 4742267

Please sign in to comment.