Skip to content
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

DSD-1877: Filtering Style Guide #1712

Open
wants to merge 11 commits into
base: development
Choose a base branch
from
Next Next commit
initial pages and structure
  • Loading branch information
bigfishdesign13 committed Dec 4, 2024
commit 799c3af45945503967bcd5ab0d2eded3fdae8e0a
28 changes: 28 additions & 0 deletions src/components/StyleGuide/FilteringGeneral.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Meta } from "@storybook/blocks";

import Link from "../Link/Link";

<Meta title="Style Guide/Filtering/General" />

# UX Recommendations for Filtering

## General Information

Categorization and filtering is a key part of NYPL's business. Across our
websites, various methods are provided for users to find what they are looking
for, often in the context of a filtered search. UX recommendations and patterns
for filtering based on the Reservoir Design System will help bring visual and
functional uniformity and consistency to all NYPL websites.

## Table of Contents

- {<Link href="/?path=/docs/style-guide-filtering-page-composition--docs">Page composition</Link>}
- {<Link href="#applying-filters" target="_self">Applying filters</Link>}
- {<Link href="#clearing-filters" target="_self">Clearing filters</Link>}
- {<Link href="#general-recommendations" target="_self">General recommendations</Link>}
- {<Link href="#development-recommendations" target="_self">Development recommendations</Link>}
- {<Link href="#additional-ux-considerations" target="_self">Additional UX considerations</Link>}
- {<Link href="#accessibility" target="_self">Accessibility</Link>}
- {<Link href="#js-disabled-feature" target="_self">JS-disabled feature</Link>}
- {<Link href="#design-examples" target="_self">Design examples</Link>}
- {<Link href="#functional-examples" target="_self">Functional examples</Link>}
296 changes: 296 additions & 0 deletions src/components/StyleGuide/FilteringPageComposition.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
import { Meta, Source } from "@storybook/blocks";

import Link from "../Link/Link";

<Meta title="Style Guide/Filtering/Page Composition" />

# Filtering Page Composition

## Table of Contents

- {<Link href="#page-elements" target="_self">Page elements</Link>}
- {<Link href="#text-search-field" target="_self">Text search field</Link>}
- {<Link href="#filter-bar" target="_self">Filter bar</Link>}
- {<Link href="#active-filters-list" target="_self">Active filters list</Link>}
- {<Link href="#total-results-heading" target="_self">Total results heading</Link>}
- {<Link href="#sorting-menu" target="_self">Sorting menu</Link>}
- {<Link href="#results-list" target="_self">Results list</Link>}
- {<Link href="#pagination-menu" target="_self">Pagination menu</Link>}
- {<Link href="#resources" target="_self">Resources</Link>}

## Page elements

The UX for searching and filtering should incorporate the following UI elements:

- Text search field (SearchBar or TextInput component)
- Filter bar (FilterBarInline and FilterBarPopup components)
- Active filters list (`TagSet` component)
- Sorting menu (Menu component)
- Total results heading (Heading component)
- Results list
- Pagination menu (Pagination component)

## Text search field

The `text search` field provides a way for users to enter a text string to
search and retrieve related information from a defined data set. It is not
considered a filter.

While the `text search` field is not required in a filtering scenario, more
often than not, filtering is used to narrow a results set that was initially
produced with a text search.

The `text search` field should be rendered using the DS `SearchBar` or
`TextInput` component.

The `text search` field should be positioned above the `filter bar` and `active filters` list.

The `text search` field should not be considered when using <Link href="/?path=/docs/style-guide-filtering-applying-filters--docs">live filtering</Link>.
Rather, a text search term should be applied using a submit button.

## Filter bar

The `filter bar` is a wrapper for individual form input elements, including the
following DS components: `CheckboxGroup`, `MultiSelectGroup`, `RadioGroup`,
`Checkbox`, `DatePicker`, `MultiSelect`, `Radio`, `Select`, `Slider`,
`TextInput`, and `Toggle`.

### Layout

The `filter bar` element should be rendered using the DS `FilterBarInline` and
`FilterBarPopup` components.

#### Desktop and tablet

For tablet and desktop viewports, the `FilterBarInline` component should be used
to render the `filter bar` element using one of two layouts: column (vertical)
or row (horizontal).

##### Column (vertical)

- The `filter bar` element should be placed in a sidebar on either the left or
right side of the main content area.
- This configuration allows users to easily make selections across multiple
facets.
- This configuration is recommended:
- for filters that are non-contextual and apply to the entirety of the main
content area
- when there are a large number of filter facets
- Using the `MultiSelect` component:
- The `MultiSelect` component is the most common input element used for
applying filter options
- `MultiSelect` components should be configured to allow multiple
`MultiSelect` components to be opened at the same time
- `MultiSelect` components should be configured to use the `"expand"` overflow
functionality
- When `MultiSelect` components are used, at least one `MultiSelect` component
should be opened by default to make the options visible to users; other
`MultiSelect` components in the `filter bar` may remain collapsed

##### Row (horizontal)

- The `filter bar` should be placed above the area of the page that is pertinent
to the filters.
- The filters that compose the `filter bar` should render in one row for desktop
viewports (approx. five filter facets)
- For specific use cases that need more than five filter facets, the filters
should render on a maximum of two rows for desktop viewports
- Filters should be contextual and only apply to certain sections of the main
content area (such as the items table of the Research Catalog bib page)
- Using the `MultiSelect` component:
- `MultiSelect` components should be configured so that only one `MultiSelect`
component can be opened at any given time. (i.e. When a `MultiSelect`
component is opened, all other `MultiSelect` components will close.)
- NOTE: This configuration requires users to make selections in only one
opened dropdown at a time, making it slightly more difficult to quickly
make selections across multiple facets.
- `MultiSelect` components should be configured to use the `"scroll"` overflow
functionality

#### Mobile

For mobile viewports, the `FilterBarPopup` component should be used to render
the filter bar element. The `filter bar` element will not be visible when the
page first loads and users will need to click a "Show filters" button to open
the `filter bar` in a modal overlay.

The filter input fields will be presented in a column layout.

Using the `MultiSelect` component:

- `MultiSelect` components should be configured to allow multiple `MultiSelect`
components to be opened at the same time

### Filter option labeling

The label text for filter options should include the number of items associated
with each filter option. For example, `English (5)` or `Offsite (11)`. The
number of associated items included in the label text should be updated as
filter options are applied. This treatment is applicable for the labels of the
`Checkbox`, `Radio`, and `Toggle` components, and the labels of the checkbox
options within a `MultiSelect` component, as well as the options within a
`Select` component.

### Filter option status

If the number of items associated with a filter option is zero (0), that filter
option should be set to disabled. Please note that this does not mean that a
filter option should be hidden. This treatment is applicable for the labels of
the `Checkbox`, `Radio`, and `Toggle` components, and the labels of the checkbox
options within a `MultiSelect` component.

### Action buttons

#### Desktop and tablet

For desktop and tablet viewports, the `filter bar` can display optional "Apply
filters" and "Clear all filters" buttons.

The "Apply filters" button must be rendered when the <Link href="/?path=/docs/style-guide-filtering-applying-filters--docs">batch filtering</Link> method is
being used. The "Apply filters" button should never be rendered when the <Link href="/?path=/docs/style-guide-filtering-applying-filters--docs">live filtering</Link> method is being used.

Clicking the "Apply filters" button should:

- update the `TagSet` component to add tags for each filter option that has been
selected
- update the `results` list to reflect the filter options that have been
selected
- update the `total results` heading to reflect the number of items in the
updated `results` list

The "Clear all filters" button should be rendered in use cases where the
`TagSet` component is not used as part of the overall searching and filtering
UX.

Clicking the "Clear all filters" button should:

- reset all form input elements within the `filter bar`
- remove all tags from the `TagSet` component
- update the `results` list to an unfiltered state
- update the `total results` heading to reflect the number of items in the
updated `results` list

#### Mobile

For mobile viewports, the filter bar will display a "Show result" button and can
display an optional "Clear all filters" button.

The "Show results" button will always be rendered at the bottom of the modal
popup regardless of the filtering method being used. It is recommended that the
label for the "Show results" button also include the current number of items in
the results list. For example, "Show 72 results." The number value should update
as filter options are selected. Clicking the "Show results" button will close
the modal overlay.

The "Clear all filters" button is optional, but it is recommended to render the
buttons. Clicking the "Clear all filters" button should:

- reset all form input elements within the `filter bar`
- remove all tags from the `TagSet` component
- update the `results` list to an unfiltered state
- update the `total results` heading to reflect the number of items in the
updated `results` list
- update the label for the "Clear all filters" button to reflect the number of
items in the updated `results` list

## Active filters list

The `active filters` list should be rendered using the DS `TagSet` component.

The `active filters` list should be positioned directly above the `results` list.

The `active filters` list should only be visible after at least one filter option
has been applied.

The `active filters` list should include an "Active filters" label.

A new tag should be added to the `TagSet` as each new filter option is applied.
The tags in the `TagSet` should be listed in the order they were selected.

The `TagSet` component will render a "Clear filters" button when more than one
filter option has been applied. Clicking the "Clear filters" button should:

- reset all form input elements within the `filter bar`
- remove all tags from the `TagSet` component
- update the `results` list to an unfiltered state
- update the `total results` heading to reflect the updated `results` list

In use cases where a text search term has been applied to the search results,
the `active filters` list should not include the search term. Rather, the search
term should be incorporated into the `total results` heading.

## Total results heading

The `total results` heading should be rendered using the DS `Heading` component.

The `total results` heading should be positioned below the `active filters` list and
aligned to the left.

The `total results` heading should reflect the current state of a results set.

The `total results` heading should be updated whenever filters are applied.

The `total results` heading should use the following format:

`Displaying 1-24 of 1,234 results`

In use cases where a text search term has been applied to the search results
using the `text search` field, the `total results` heading should use the following
format:

`Displaying 1-24 of 567 results for "{search_term}"`

## Sorting menu

The `sorting menu` should be rendered using the DS `Menu` component.

The `sorting menu` should be positioned below the `active filters` list and aligned
to the right.

The initial text label and `aria-label` value for the sorting menu should be set
to "Sort by." If a sorting option is selected, the `aria-label` value should
remain as "Sort by," but the text label for the sorting menu should be updated
to include the label of the option that was selected.

Label example:

`Sort by: Title A-Z`

## Results list

The `results list` will most commonly be rendered using the DS `Card` component
presented in a list or grid format, but ultimately the items in the `results list`
should be composed as needed by consuming apps.

For results that are presented in either a list or grid format, it is
recommended to show 12, 24, 36, or 48 results on each page in a set of results,
depending on the size and complexity of the individual result items. For
example, simple result items that contain a book title and a short description
should show 36 or 48 items per page, while complex result items that include a
photo, a book title, a long description, an availability indicator, and CTA
buttons might be best limited to 12 or 24 items per page.

The number of items per page should initially be set by the product designer and
the product owner, but the final number should also take into account
limitations imposed by the data architecture and infrastructure of a consuming
app.

## Pagination menu

The `pagination` menu should be rendered using the DS `Pagination` component.

The number of result items displayed per page should be determined as needed by
consuming apps. For more information, refer to the [Results list](#results-list) section.

## Resources

### Design examples

- {<Link href="https://www.figma.com/design/qpllPO7SRpgaXdhk5mG9BH/Example-Page-Design?node-id=1361-11781&t=CVP20UTxu75HE0YX-11" target="_blank" type="external">Row filtering example</Link>}
- {<Link href="https://www.figma.com/design/qpllPO7SRpgaXdhk5mG9BH/Example-Page-Design?node-id=1871-10399&t=CVP20UTxu75HE0YX-11" target="_blank" type="external">Column filtering example</Link>}

### Functional examples

- {<Link href="https://www.mylibrarynyc.org/teacher_set_data?keyword=dogs" target="_blank" type="external">MyLibraryNYC</Link>}
- {<Link href="https://www.nypl.org/research/research-catalog/bib/b21148115" target="_blank" type="external">Research Catalog</Link>}
- {<Link href="https://nypl-ds-test-app.vercel.app/fullPages/search-and-filter#above-header-notification" target="_blank" type="external">Turbine example</Link>} (still in development)