Skip to content

Commit

Permalink
Add goal centric filter groups in design picker
Browse files Browse the repository at this point in the history
  • Loading branch information
madhusudhand committed Dec 6, 2024
1 parent ba68889 commit 6279914
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface Props {
categories: Category[];
selectedSlugs: string[];
isMultiSelection?: boolean;
forceSwipe?: boolean;
onSelect: ( selectedSlug: string ) => void;
}

Expand All @@ -16,6 +17,7 @@ export default function DesignPickerCategoryFilter( {
categories,
selectedSlugs,
isMultiSelection,
forceSwipe,
onSelect,
}: Props ) {
const onClick = ( index: number ) => {
Expand All @@ -40,6 +42,7 @@ export default function DesignPickerCategoryFilter( {
initialActiveIndex={ initialActiveIndex !== -1 ? initialActiveIndex : 0 }
initialActiveIndexes={ initialActiveIndexes }
isMultiSelection={ isMultiSelection }
forceSwipe={ forceSwipe }
onClick={ onClick }
>
{ categories.map( ( category ) => (
Expand Down
32 changes: 26 additions & 6 deletions packages/design-picker/src/components/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,36 @@
gap: 10px;
margin-bottom: 24px;

@include break-small {
flex-direction: row;
align-items: flex-end;
gap: 30px;
}

.design-picker__category-group {
display: flex;
flex-direction: column;
&.grow {
flex-grow: 1;
}
}

.design-picker__category-group-label {
text-transform: uppercase;
font-size: rem(13px);
font-weight: 500;
}

.design-picker__design-your-own-button {
flex-shrink: 0;
height: 32px;
line-height: 14px;
margin-top: 9px;
margin-left: 10px;
margin-top: 8px;
margin-bottom: 8px;
}

.design-picker__tier-filter {
height: 48px; // match button height
}

.design-picker__design-your-own-button-without-categories {
Expand All @@ -50,10 +74,6 @@
justify-content: flex-start;
}
}

@include break-small {
flex-direction: row;
}
}

.design-picker__grid,
Expand Down
100 changes: 79 additions & 21 deletions packages/design-picker/src/components/unified-design-picker.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';
import { Button } from '@automattic/components';
import clsx from 'clsx';
import { useCallback, useRef, useState } from 'react';
import { useTranslate } from 'i18n-calypso';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useInView } from 'react-intersection-observer';
import { SHOW_ALL_SLUG } from '../constants';
import { useFilteredDesigns } from '../hooks/use-filtered-designs';
Expand All @@ -14,7 +15,7 @@ import NoResults from './no-results';
import PatternAssemblerCta, { usePatternAssemblerCtaData } from './pattern-assembler-cta';
import ThemeCard from './theme-card';
import type { Categorization } from '../hooks/use-categorization';
import type { Design, StyleVariation } from '../types';
import type { Category, Design, StyleVariation } from '../types';
import type { RefCallback } from 'react';
import './style.scss';

Expand Down Expand Up @@ -168,6 +169,25 @@ const DesignCard: React.FC< DesignCardProps > = ( {
);
};

interface DesignPickerFilterGroupProps {
title?: string;
grow?: boolean;
children: React.ReactNode;
}

const DesignPickerFilterGroup: React.FC< DesignPickerFilterGroupProps > = ( {
title,
grow,
children,
} ) => {
return (
<div className={ clsx( 'design-picker__category-group', { grow } ) }>
<div className="design-picker__category-group-label">{ title }</div>
{ children }
</div>
);
};

interface DesignPickerProps {
locale: string;
onDesignYourOwn: ( design: Design ) => void;
Expand Down Expand Up @@ -207,34 +227,72 @@ const DesignPicker: React.FC< DesignPickerProps > = ( {
} ) => {
const hasCategories = !! Object.keys( categorization?.categories || {} ).length;
const filteredDesigns = useFilteredDesigns( designs, categorization );

// Pick design
const features = [ 'blog', 'magazine', 'portfolio', 'podcast', 'store' ];
const [ featureCategories, setFeatureCategories ] = useState< Category[] >( [] );
const [ subjectCategories, setSubjectCategories ] = useState< Category[] >( [] );

const assemblerCtaData = usePatternAssemblerCtaData();

const translate = useTranslate();

useEffect( () => {
if ( ! categorization?.categories?.length ) {
return;
}
setFeatureCategories(
categorization.categories.filter( ( { slug } ) => features.includes( slug ) )
);
setSubjectCategories(
categorization.categories.filter( ( { slug } ) => ! features.includes( slug ) )
);
}, [ categorization?.categories ] );

return (
<div>
<div className="design-picker__filters">
{ categorization && hasCategories && (
<DesignPickerCategoryFilter
className="design-picker__category-filter"
categories={ categorization.categories }
onSelect={ categorization.onSelect }
selectedSlugs={ categorization.selections }
isMultiSelection={ isMultiFilterEnabled }
/>
{ categorization && featureCategories.length && isMultiFilterEnabled && (
<DesignPickerFilterGroup title={ translate( 'Features' ) }>
<DesignPickerCategoryFilter
className="design-picker__category-filter"
categories={ featureCategories }
onSelect={ categorization.onSelect }
selectedSlugs={ categorization.selections }
isMultiSelection={ isMultiFilterEnabled }
forceSwipe
/>
</DesignPickerFilterGroup>
) }
{ assemblerCtaData.shouldGoToAssemblerStep && isSiteAssemblerEnabled && (
<Button
className={ clsx( 'design-picker__design-your-own-button', {
'design-picker__design-your-own-button-without-categories': ! hasCategories,
} ) }
onClick={ () => onClickDesignYourOwnTopButton( getAssemblerDesign() ) }
{ categorization && subjectCategories.length && (
<DesignPickerFilterGroup
title={ isMultiFilterEnabled ? translate( 'Subjects' ) : '' }
grow
>
{ assemblerCtaData.title }
</Button>
<DesignPickerCategoryFilter
className="design-picker__category-filter"
categories={ isMultiFilterEnabled ? subjectCategories : categorization.categories }
onSelect={ categorization.onSelect }
selectedSlugs={ categorization.selections }
isMultiSelection={ isMultiFilterEnabled }
/>
</DesignPickerFilterGroup>
) }
{ assemblerCtaData.shouldGoToAssemblerStep && isSiteAssemblerEnabled && (
<DesignPickerFilterGroup>
<Button
className={ clsx( 'design-picker__design-your-own-button', {
'design-picker__design-your-own-button-without-categories': ! hasCategories,
} ) }
onClick={ () => onClickDesignYourOwnTopButton( getAssemblerDesign() ) }
>
{ assemblerCtaData.title }
</Button>
</DesignPickerFilterGroup>
) }
{ isTierFilterEnabled && (
<DesignPickerFilterGroup>
<DesignPickerTierFilter />
</DesignPickerFilterGroup>
) }
{ isTierFilterEnabled && <DesignPickerTierFilter /> }
</div>

<div className="design-picker__grid">
Expand Down

0 comments on commit 6279914

Please sign in to comment.