Skip to content

Commit

Permalink
Add Facets Level Css Support for FilterGroup
Browse files Browse the repository at this point in the history
This change allows users to provide css classes for FilterGroup on the Facets level.
If same css classes are provided on the singular facet level, the latter will be used.

J=BACK-2306
TEST=auto,manual

Added a test for this.
Also manually confirmed the behavior.
  • Loading branch information
EmilyZhang777 committed May 26, 2023
1 parent 0041b9d commit 7d61986
Show file tree
Hide file tree
Showing 17 changed files with 131 additions and 48 deletions.
5 changes: 3 additions & 2 deletions docs/search-ui-react.facetscssclasses.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

## FacetsCssClasses interface

The CSS class interface for [Facets()](./search-ui-react.facets.md)<!-- -->.
The CSS class interface for [Facets()](./search-ui-react.facets.md)<!-- -->. Any [FilterGroupCssClasses](./search-ui-react.filtergroupcssclasses.md) props will be overridden by the same props from customCssClasses on [StandardFacetProps](./search-ui-react.standardfacetprops.md)<!-- -->, [NumericalFacetProps](./search-ui-react.numericalfacetprops.md)<!-- -->, or [HierarchicalFacetProps](./search-ui-react.hierarchicalfacetprops.md)<!-- -->.

<b>Signature:</b>

```typescript
export interface FacetsCssClasses
export interface FacetsCssClasses extends FilterGroupCssClasses
```
<b>Extends:</b> [FilterGroupCssClasses](./search-ui-react.filtergroupcssclasses.md)
## Properties
Expand Down
2 changes: 1 addition & 1 deletion docs/search-ui-react.hierarchicalfacets.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

> Warning: This API is now obsolete.
>
> Use [Facets()](./search-ui-react.facets.md) instead.
> Use [HierarchicalFacet()](./search-ui-react.hierarchicalfacet.md) with [Facets()](./search-ui-react.facets.md) instead.
>
A component that displays hierarchical facets, in a tree level structure, applicable to the current vertical search.
Expand Down
5 changes: 5 additions & 0 deletions docs/search-ui-react.hierarchicalfacetsprops.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

## HierarchicalFacetsProps interface

> Warning: This API is now obsolete.
>
> Use [HierarchicalFacet()](./search-ui-react.hierarchicalfacet.md) with [Facets()](./search-ui-react.facets.md) instead.
>
Props for the [HierarchicalFacets()](./search-ui-react.hierarchicalfacets.md) component.

<b>Signature:</b>
Expand Down
2 changes: 1 addition & 1 deletion docs/search-ui-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
| [CtaData](./search-ui-react.ctadata.md) | The shape of a StandardCard CTA field's data. |
| [DirectAnswerCssClasses](./search-ui-react.directanswercssclasses.md) | The CSS class interface for [DirectAnswer()](./search-ui-react.directanswer.md)<!-- -->. |
| [DirectAnswerProps](./search-ui-react.directanswerprops.md) | Props for [DirectAnswer()](./search-ui-react.directanswer.md)<!-- -->. |
| [FacetsCssClasses](./search-ui-react.facetscssclasses.md) | The CSS class interface for [Facets()](./search-ui-react.facets.md)<!-- -->. |
| [FacetsCssClasses](./search-ui-react.facetscssclasses.md) | The CSS class interface for [Facets()](./search-ui-react.facets.md)<!-- -->. Any [FilterGroupCssClasses](./search-ui-react.filtergroupcssclasses.md) props will be overridden by the same props from customCssClasses on [StandardFacetProps](./search-ui-react.standardfacetprops.md)<!-- -->, [NumericalFacetProps](./search-ui-react.numericalfacetprops.md)<!-- -->, or [HierarchicalFacetProps](./search-ui-react.hierarchicalfacetprops.md)<!-- -->. |
| [FacetsProps](./search-ui-react.facetsprops.md) | Props for the [Facets()](./search-ui-react.facets.md) component. |
| [FilterGroupCssClasses](./search-ui-react.filtergroupcssclasses.md) | The CSS class interface for FilterGroup. |
| [FilterGroupProps](./search-ui-react.filtergroupprops.md) | Props for the FilterGroup component. |
Expand Down
2 changes: 1 addition & 1 deletion docs/search-ui-react.numericalfacets.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

> Warning: This API is now obsolete.
>
> Use [Facets()](./search-ui-react.facets.md) instead.
> Use [NumericalFacet()](./search-ui-react.numericalfacet.md) with [Facets()](./search-ui-react.facets.md) instead.
>
A component that displays numerical facets applicable to the current vertical search.
Expand Down
5 changes: 5 additions & 0 deletions docs/search-ui-react.numericalfacetsprops.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

## NumericalFacetsProps interface

> Warning: This API is now obsolete.
>
> Use [NumericalFacet()](./search-ui-react.numericalfacet.md) with [Facets()](./search-ui-react.facets.md) instead.
>
Props for the [NumericalFacets()](./search-ui-react.numericalfacets.md) component.

<b>Signature:</b>
Expand Down
2 changes: 1 addition & 1 deletion docs/search-ui-react.standardfacetscssclasses.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

> Warning: This API is now obsolete.
>
> Use [Facets()](./search-ui-react.facets.md) instead.
> Use [StandardFacet()](./search-ui-react.standardfacet.md) with [Facets()](./search-ui-react.facets.md) instead.
>
The CSS class interface for [StandardFacets()](./search-ui-react.standardfacets.md)<!-- -->.
Expand Down
2 changes: 1 addition & 1 deletion docs/search-ui-react.standardfacetsprops.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

> Warning: This API is now obsolete.
>
> Use [Facets()](./search-ui-react.facets.md) instead.
> Use [StandardFacet()](./search-ui-react.standardfacet.md) with [Facets()](./search-ui-react.facets.md) instead.
>
Props for the [StandardFacets()](./search-ui-react.standardfacets.md) component.
Expand Down
6 changes: 3 additions & 3 deletions etc/search-ui-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export type FacetProps = StandardFacetProps | NumericalFacetProps | Hierarchical
export function Facets(props: FacetsProps): JSX.Element;

// @public
export interface FacetsCssClasses {
export interface FacetsCssClasses extends FilterGroupCssClasses {
// (undocumented)
divider?: string;
// (undocumented)
Expand Down Expand Up @@ -378,7 +378,7 @@ export interface HierarchicalFacetsCssClasses extends HierarchicalFacetDisplayCs
hierarchicalFacetsContainer?: string;
}

// @public
// @public @deprecated
export interface HierarchicalFacetsProps extends Omit<StandardFacetsProps, 'excludedFieldIds'> {
customCssClasses?: HierarchicalFacetsCssClasses;
delimiter?: string;
Expand Down Expand Up @@ -454,7 +454,7 @@ export interface NumericalFacetsCssClasses extends FilterGroupCssClasses, RangeI
numericalFacetsContainer?: string;
}

// @public
// @public @deprecated
export interface NumericalFacetsProps extends Omit<StandardFacetsProps, 'excludedFieldIds'> {
customCssClasses?: NumericalFacetsCssClasses;
getFilterDisplayName?: (value: NumberRangeValue) => string;
Expand Down
6 changes: 4 additions & 2 deletions src/components/FacetProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { NumberRangeValue } from '@yext/search-headless-react';
import { HierarchicalFacetDisplayCssClasses, RangeInputCssClasses } from './Filters';

/**
* The CSS class interface for {@link Facets}.
* The CSS class interface for {@link Facets}. Any {@link FilterGroupCssClasses} props will be
* overridden by the same props from customCssClasses on {@link StandardFacetProps},
* {@link NumericalFacetProps}, or {@link HierarchicalFacetProps}.
*
* @public
*/
export interface FacetsCssClasses {
export interface FacetsCssClasses extends FilterGroupCssClasses {
facetsContainer?: string,
divider?: string
}
Expand Down
88 changes: 58 additions & 30 deletions src/components/Facets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,39 +79,15 @@ export function Facets(props: FacetsProps) {
&& (!onlyRenderChildren || fieldIdToCustomFacetProps.has(fieldId)))
.map((fieldId, i) => {
const facet: DisplayableFacet = fieldIdToFacet.get(fieldId);
let facetType: FacetType = FacetType.STANDARD;
let facetProps: FacetProps = {
fieldId: facet.fieldId,
label: facet.displayName,
};
if (fieldIdToCustomFacetProps.has(facet.fieldId)) {
const customFacetElement: ReactElement =
fieldIdToCustomFacetProps.get(facet.fieldId);
facetProps = { ...facetProps, ...customFacetElement.props };
facetType = getFacetTypeFromReactElementType(
(typeof customFacetElement.type === 'function')
? customFacetElement.type.name : '');
} else {
facetType = getFacetTypeFromFacet(facet, hierarchicalFieldIds);
}

let facetComponent: ReactElement;
switch (facetType) {
case FacetType.NUMERICAL:
facetComponent = (<NumericalFacetContent facet={facet} {...facetProps}/>);
break;
case FacetType.HIERARCHICAL:
facetComponent = (<HierarchicalFacetContent facet={facet} {...facetProps}/>);
break;
case FacetType.STANDARD:
// fall through
default:
facetComponent = (<StandardFacetContent facet={facet} {...facetProps}/>);
}

return (
<Fragment key={facet.fieldId}>
{facetComponent}
<Facet
facet={facet}
facetsCustomCssClasses={customCssClasses}
fieldIdToCustomFacetProps={fieldIdToCustomFacetProps}
hierarchicalFieldIds={hierarchicalFieldIds}
/>
{(i < facets.length - 1)
&& <FilterDivider className={customCssClasses?.divider}/>}
</Fragment>
Expand Down Expand Up @@ -155,6 +131,58 @@ export function NumericalFacet(props: NumericalFacetProps) { return null; }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function HierarchicalFacet(props: HierarchicalFacetProps) { return null; }

/**
* A component that represents a single facet.
*
* @param facet - {@link DisplayableFacet}
* @param facetsCustomCssClasses - {@link FacetsCssClasses}
* @param fieldIdToCustomFacetProps - a map of fieldId to facet props
* @param hierarchicalFieldIds - a list of hierarchical field ids
* @returns {@link ReactElement}
*
* @internal
*/
export function Facet({
facet,
facetsCustomCssClasses,
fieldIdToCustomFacetProps,
hierarchicalFieldIds,
}) {
let facetType: FacetType;
let facetProps: FacetProps = {
fieldId: facet.fieldId,
label: facet.displayName,
};
if (fieldIdToCustomFacetProps.has(facet.fieldId)) {
const customFacetElement: ReactElement = fieldIdToCustomFacetProps.get(facet.fieldId);
facetProps = { ...facetProps, ...customFacetElement.props };
facetType = getFacetTypeFromReactElementType(
(typeof customFacetElement.type === 'function')
? customFacetElement.type.name : '');
} else {
facetType = getFacetTypeFromFacet(facet, hierarchicalFieldIds);
}

facetProps = {
...facetProps,
customCssClasses: {
...facetsCustomCssClasses,
...facetProps.customCssClasses,
},
};

switch (facetType) {
case FacetType.NUMERICAL:
return (<NumericalFacetContent facet={facet} {...facetProps}/>);
case FacetType.HIERARCHICAL:
return (<HierarchicalFacetContent facet={facet} {...facetProps}/>);
case FacetType.STANDARD:
// fall through
default:
return (<StandardFacetContent facet={facet} {...facetProps}/>);
}
}

/**
* Returns the type of the facet based on the props.
* @param elementType - string
Expand Down
3 changes: 2 additions & 1 deletion src/components/HierarchicalFacets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface HierarchicalFacetsCssClasses extends HierarchicalFacetDisplayCs
/**
* Props for the {@link HierarchicalFacets} component.
*
* @deprecated Use {@link HierarchicalFacet} with {@link Facets} instead.
* @public
*/
export interface HierarchicalFacetsProps extends Omit<StandardFacetsProps, 'excludedFieldIds'> {
Expand All @@ -43,7 +44,7 @@ export interface HierarchicalFacetsProps extends Omit<StandardFacetsProps, 'excl
* @param props - {@link HierarchicalFacetsProps}
* @returns A React component for facets
*
* @deprecated Use {@link Facets} instead.
* @deprecated Use {@link HierarchicalFacet} with {@link Facets} instead.
* @public
*/
export function HierarchicalFacets({
Expand Down
3 changes: 2 additions & 1 deletion src/components/NumericalFacets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface NumericalFacetsCssClasses extends FilterGroupCssClasses, RangeI
/**
* Props for the {@link NumericalFacets} component.
*
* @deprecated Use {@link NumericalFacet} with {@link Facets} instead.
* @public
*/
export interface NumericalFacetsProps extends Omit<StandardFacetsProps, 'excludedFieldIds'> {
Expand Down Expand Up @@ -49,7 +50,7 @@ const DEFAULT_RANGE_INPUT_PREFIX = <>$</>;
* @param props - {@link NumericalFacetsProps}
* @returns A React component for facets
*
* @deprecated Use {@link Facets} instead.
* @deprecated Use {@link NumericalFacet} with {@link Facets} instead.
* @public
*/
export function NumericalFacets({
Expand Down
4 changes: 2 additions & 2 deletions src/components/StandardFacets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { isStringFacet } from '../utils/filterutils';
/**
* The CSS class interface for {@link StandardFacets}.
*
* @deprecated Use {@link Facets} instead.
* @deprecated Use {@link StandardFacet} with {@link Facets} instead.
* @public
*/
export interface StandardFacetsCssClasses extends FilterGroupCssClasses {
Expand All @@ -18,7 +18,7 @@ export interface StandardFacetsCssClasses extends FilterGroupCssClasses {
/**
* Props for the {@link StandardFacets} component.
*
* @deprecated Use {@link Facets} instead.
* @deprecated Use {@link StandardFacet} with {@link Facets} instead.
* @public
*/
export interface StandardFacetsProps {
Expand Down
1 change: 0 additions & 1 deletion src/utils/filterutils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NearFilterValue, FieldValueFilter, NumberRangeValue, Matcher, SearchAct
import { isEqual } from 'lodash';
import { isNumberRangeFilter } from '../models/NumberRangeFilter';
import { SelectableFieldValueFilter } from '../models/SelectableFieldValueFilter';
import { DEFAULT_HIERARCHICAL_DELIMITER } from '../components/Filters/HierarchicalFacetDisplay';

/**
* Check if the object follows NearFilterValue interface.
Expand Down
42 changes: 42 additions & 0 deletions tests/components/Facets.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,4 +236,46 @@ describe('Facets', () => {
expect(screen.queryByText(DisplayableFacets[1].displayName)).toBeNull();
expect(screen.queryByText(DisplayableFacets[2].displayName)).toBeNull();
});

it('Use FilterGroupCssClasses provided on the Facets level if not provided on the singular facet',
() => {
const overrideFieldId = 'products';
const overrideLabel = 'My Products';
const facetsTitleLabelClass = 'facets-title-label-class';
const props: StandardFacetProps = {
fieldId: overrideFieldId,
label: overrideLabel,
};

render(
<Facets customCssClasses={{ titleLabel: facetsTitleLabelClass }}>
<StandardFacet {...props}/>
</Facets>);

expect(screen.getByText(overrideLabel)).toBeDefined();
expect(screen.getByText(overrideLabel)).toHaveClass(facetsTitleLabelClass);
expect(screen.getByText(DisplayableFacets[1].displayName)).toBeDefined();
expect(screen.getByText(DisplayableFacets[1].displayName)).toHaveClass(facetsTitleLabelClass);
});

it('Use FilterGroupCssClasses provided on the singular facet level if provided',
() => {
const overrideFieldId = 'products';
const overrideLabel = 'My Products';
const facetsTitleLabelClass = 'facets-title-label-class';
const standardFacetTitleLabelClass = 'standard-facet-title-label-class';
const props: StandardFacetProps = {
fieldId: overrideFieldId,
label: overrideLabel,
customCssClasses: { titleLabel: standardFacetTitleLabelClass },
};

render(
<Facets onlyRenderChildren={true} customCssClasses={{ titleLabel: facetsTitleLabelClass }}>
<StandardFacet {...props}/>
</Facets>);

expect(screen.getByText(overrideLabel)).toBeDefined();
expect(screen.getByText(overrideLabel)).toHaveClass(standardFacetTitleLabelClass);
});
});
1 change: 0 additions & 1 deletion tests/components/StandardFacet.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { SearchHeadlessContext, State } from '@yext/search-headless-react';
import { generateMockedHeadless } from '../__fixtures__/search-headless';
import { RecursivePartial } from '../__utils__/mocks';
import { DisplayableFacets } from '../__fixtures__/data/filters';
import { createHierarchicalFacet } from '../__utils__/hierarchicalfacets';

const meta: ComponentMeta<typeof Facets> = {
title: 'Facets',
Expand Down

0 comments on commit 7d61986

Please sign in to comment.