-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create Facets component #360
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [Facets](./search-ui-react.facets.md) | ||
|
||
## Facets() function | ||
|
||
A component that displays all facets applicable to the current vertical search. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
export declare function Facets(props: FacetsProps): JSX.Element; | ||
``` | ||
|
||
## Parameters | ||
|
||
| Parameter | Type | Description | | ||
| --- | --- | --- | | ||
| props | [FacetsProps](./search-ui-react.facetsprops.md) | [FacetsProps](./search-ui-react.facetsprops.md) | | ||
|
||
<b>Returns:</b> | ||
|
||
JSX.Element | ||
|
||
A React component for facets | ||
|
||
## Remarks | ||
|
||
This component is a quick way of getting facets on the page, and it will render standard facets, numerical facets, and hierarchical facets. The [StandardFacets()](./search-ui-react.standardfacets.md)<!-- -->, [NumericalFacets()](./search-ui-react.numericalfacets.md)<!-- -->, and [HierarchicalFacets()](./search-ui-react.hierarchicalfacets.md) components can be used instead for more control over facet configuration. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [FacetsCssClasses](./search-ui-react.facetscssclasses.md) > [facetsContainer](./search-ui-react.facetscssclasses.facetscontainer.md) | ||
|
||
## FacetsCssClasses.facetsContainer property | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
facetsContainer?: string; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [FacetsCssClasses](./search-ui-react.facetscssclasses.md) | ||
|
||
## FacetsCssClasses interface | ||
|
||
The CSS class interface for [Facets()](./search-ui-react.facets.md)<!-- -->. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
export interface FacetsCssClasses | ||
``` | ||
|
||
## Properties | ||
|
||
| Property | Type | Description | | ||
| --- | --- | --- | | ||
| [facetsContainer?](./search-ui-react.facetscssclasses.facetscontainer.md) | string | <i>(Optional)</i> | | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [FacetsProps](./search-ui-react.facetsprops.md) > [customCssClasses](./search-ui-react.facetsprops.customcssclasses.md) | ||
|
||
## FacetsProps.customCssClasses property | ||
|
||
CSS classes for customizing the component styling. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
customCssClasses?: FacetsCssClasses; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [@yext/search-ui-react](./search-ui-react.md) > [FacetsProps](./search-ui-react.facetsprops.md) | ||
|
||
## FacetsProps interface | ||
|
||
Props for the [Facets()](./search-ui-react.facets.md) component. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
export interface FacetsProps | ||
``` | ||
|
||
## Properties | ||
|
||
| Property | Type | Description | | ||
| --- | --- | --- | | ||
| [customCssClasses?](./search-ui-react.facetsprops.customcssclasses.md) | [FacetsCssClasses](./search-ui-react.facetscssclasses.md) | <i>(Optional)</i> CSS classes for customizing the component styling. | | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { StandardFacets } from './StandardFacets'; | ||
import { NumericalFacets } from './NumericalFacets'; | ||
|
||
/** | ||
* The CSS class interface for {@link Facets}. | ||
* | ||
* @public | ||
*/ | ||
export interface FacetsCssClasses { | ||
facetsContainer?: string | ||
} | ||
|
||
/** | ||
* Props for the {@link Facets} component. | ||
* | ||
* @public | ||
*/ | ||
export interface FacetsProps { | ||
/** CSS classes for customizing the component styling. */ | ||
customCssClasses?: FacetsCssClasses | ||
} | ||
|
||
/** | ||
* A component that displays all facets applicable to the current vertical search. | ||
* | ||
* @remarks | ||
* This component is a quick way of getting facets on the page, and it will render standard facets, | ||
* numerical facets, and hierarchical facets. The {@link StandardFacets}, {@link NumericalFacets}, | ||
* and {@link HierarchicalFacets} components can be used instead for more control over facet | ||
* configuration. | ||
* | ||
* @param props - {@link FacetsProps} | ||
* @returns A React component for facets | ||
* | ||
* @public | ||
*/ | ||
export function Facets(props: FacetsProps) { | ||
const { customCssClasses = {} } = props; | ||
return ( | ||
<div className={customCssClasses.facetsContainer}> | ||
<StandardFacets/> | ||
<NumericalFacets /> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,11 +55,13 @@ export function PeoplePage() { | |
title='Static Employee Department' | ||
filterOptions={employeeFilterConfigs} | ||
/> | ||
<FilterDivider /> | ||
<StaticFilters | ||
fieldId='c_hierarchicalFacet' | ||
title='Static Hierarchical Facets' | ||
filterOptions={hierarchicalFilterConfigs} | ||
/> | ||
<FilterDivider /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this only wrapping StaticFilters and br tag is used on line 73? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These aren't wrapping StaticFilters and are instead standalone filter dividers. The facets dynamically include dividers where needed, but static filters do not |
||
<NumericalFacets /> | ||
<StandardFacets | ||
excludedFieldIds={hierarchicalFacetFieldIds} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { DisplayableFacetOption } from '@yext/search-headless-react'; | ||
|
||
export function getOptionLabelText(option: DisplayableFacetOption) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add a an example of what this is trying to match? |
||
return `${option.displayName} (${option.count})`; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { ComponentMeta, Story } from '@storybook/react'; | ||
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 { Facets, FacetsProps } from '../../src'; | ||
|
||
const meta: ComponentMeta<typeof Facets> = { | ||
title: 'Facets', | ||
component: Facets | ||
}; | ||
export default meta; | ||
|
||
const mockedHeadlessState: RecursivePartial<State> = { | ||
filters: { | ||
facets: DisplayableFacets | ||
} | ||
}; | ||
|
||
export const Primary: Story<FacetsProps> = (args) => { | ||
return ( | ||
<SearchHeadlessContext.Provider value={generateMockedHeadless(mockedHeadlessState)}> | ||
<Facets {...args} /> | ||
</SearchHeadlessContext.Provider> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { render, screen } from '@testing-library/react'; | ||
import { | ||
Source, | ||
State | ||
} from '@yext/search-headless-react'; | ||
import { mockAnswersHooks, mockAnswersState } from '../__utils__/mocks'; | ||
import { DisplayableFacets } from '../__fixtures__/data/filters'; | ||
import { Facets } from '../../src'; | ||
import { getOptionLabelText } from '../__utils__/facets'; | ||
|
||
const mockedState: Partial<State> = { | ||
filters: { | ||
static: [], | ||
facets: DisplayableFacets | ||
}, | ||
vertical: { | ||
verticalKey: 'vertical', | ||
results: [{ | ||
source: Source.KnowledgeManager, | ||
rawData: {} | ||
}], | ||
appliedQueryFilters: [] | ||
}, | ||
searchStatus: { | ||
isLoading: false | ||
}, | ||
meta: { | ||
searchType: 'vertical' | ||
} | ||
}; | ||
|
||
const mockedActions = { | ||
state: mockedState, | ||
setOffset: jest.fn(), | ||
setFacetOption: jest.fn(), | ||
executeVerticalQuery: jest.fn() | ||
}; | ||
|
||
const mockedUtils = { | ||
isCloseMatch: () => true | ||
}; | ||
|
||
jest.mock('@yext/search-headless-react'); | ||
|
||
describe('Facets', () => { | ||
beforeEach(() => { | ||
mockAnswersHooks({ mockedState, mockedActions, mockedUtils }); | ||
}); | ||
it('Properly renders standard facets if present', () => { | ||
render(<Facets/>); | ||
const regularFilter = DisplayableFacets[0]; | ||
|
||
expect(screen.getByText(regularFilter.displayName)).toBeDefined(); | ||
regularFilter.options.forEach(o => { | ||
expect(screen.getByText(getOptionLabelText(o))).toBeDefined(); | ||
}); | ||
}); | ||
|
||
it('Properly renders numerical facets if present', () => { | ||
render(<Facets/>); | ||
const numericalFilter = DisplayableFacets[1]; | ||
|
||
expect(screen.getByText(numericalFilter.displayName)).toBeDefined(); | ||
numericalFilter.options.forEach(o => { | ||
expect(screen.getByText(o.displayName)).toBeDefined(); | ||
}); | ||
}); | ||
|
||
it('Does not render filters if no facets are present', () => { | ||
mockAnswersState({ | ||
...mockedState, | ||
filters: { | ||
static: [], | ||
facets: [] | ||
} | ||
}); | ||
render(<Facets/>); | ||
const regularFilter = DisplayableFacets[0]; | ||
const numericalFilter = DisplayableFacets[1]; | ||
|
||
expect(screen.queryByText(numericalFilter.displayName)).toBeNull(); | ||
numericalFilter.options.forEach(o => { | ||
expect(screen.queryByText(o.displayName)).toBeNull(); | ||
}); | ||
|
||
expect(screen.queryByText(regularFilter.displayName)).toBeNull(); | ||
regularFilter.options.forEach(o => { | ||
expect(screen.queryByText(`${o.displayName} (${o.count})}`)).toBeNull(); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it won't currently use hierarchical facets right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will render them but as standard facets