From 6279914f3cc53038674ec85ce1516ec2a59d74b9 Mon Sep 17 00:00:00 2001 From: madhusudhand Date: Thu, 5 Dec 2024 17:18:00 +0530 Subject: [PATCH] Add goal centric filter groups in design picker --- .../design-picker-category-filter/index.tsx | 3 + .../design-picker/src/components/style.scss | 32 ++++-- .../src/components/unified-design-picker.tsx | 100 ++++++++++++++---- 3 files changed, 108 insertions(+), 27 deletions(-) diff --git a/packages/design-picker/src/components/design-picker-category-filter/index.tsx b/packages/design-picker/src/components/design-picker-category-filter/index.tsx index c8b8ac90460432..f3a1ba0b0aa665 100644 --- a/packages/design-picker/src/components/design-picker-category-filter/index.tsx +++ b/packages/design-picker/src/components/design-picker-category-filter/index.tsx @@ -8,6 +8,7 @@ interface Props { categories: Category[]; selectedSlugs: string[]; isMultiSelection?: boolean; + forceSwipe?: boolean; onSelect: ( selectedSlug: string ) => void; } @@ -16,6 +17,7 @@ export default function DesignPickerCategoryFilter( { categories, selectedSlugs, isMultiSelection, + forceSwipe, onSelect, }: Props ) { const onClick = ( index: number ) => { @@ -40,6 +42,7 @@ export default function DesignPickerCategoryFilter( { initialActiveIndex={ initialActiveIndex !== -1 ? initialActiveIndex : 0 } initialActiveIndexes={ initialActiveIndexes } isMultiSelection={ isMultiSelection } + forceSwipe={ forceSwipe } onClick={ onClick } > { categories.map( ( category ) => ( diff --git a/packages/design-picker/src/components/style.scss b/packages/design-picker/src/components/style.scss index 97a655cd295c9b..3518c002defcce 100644 --- a/packages/design-picker/src/components/style.scss +++ b/packages/design-picker/src/components/style.scss @@ -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 { @@ -50,10 +74,6 @@ justify-content: flex-start; } } - - @include break-small { - flex-direction: row; - } } .design-picker__grid, diff --git a/packages/design-picker/src/components/unified-design-picker.tsx b/packages/design-picker/src/components/unified-design-picker.tsx index ab3c5fe489abd0..b24572f01b2514 100644 --- a/packages/design-picker/src/components/unified-design-picker.tsx +++ b/packages/design-picker/src/components/unified-design-picker.tsx @@ -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'; @@ -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'; @@ -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 ( +
+
{ title }
+ { children } +
+ ); +}; + interface DesignPickerProps { locale: string; onDesignYourOwn: ( design: Design ) => void; @@ -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 (
- { categorization && hasCategories && ( - + { categorization && featureCategories.length && isMultiFilterEnabled && ( + + + ) } - { assemblerCtaData.shouldGoToAssemblerStep && isSiteAssemblerEnabled && ( - + + + ) } + { assemblerCtaData.shouldGoToAssemblerStep && isSiteAssemblerEnabled && ( + + + + ) } + { isTierFilterEnabled && ( + + + ) } - { isTierFilterEnabled && }