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
21 changes: 21 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,27 @@ const parameters = {
"Chakra UI",
"Development Guide",
"Style Guide",
[
"*",
[
"Overview",
"Page Composition",
[
"Outline",
"Text search field",
"Filter bar",
"Active filters list",
"Total results heading",
"Sorting menu",
"Results list",
"Pagination menu",
],
"Applying & Clearing Filters",
"Accessibility",
"JS-disabled",
],
"*",
],
"Accessibility Guide",
"Components",
"Hooks",
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Currently, this repo is in Prerelease. When it is released, this project will ad

## Prerelease

### Adds

- Adds the `Filtering` page to the `Style Guide`.

## 3.5.0 (December 5, 2024)

### Adds
Expand Down
78 changes: 78 additions & 0 deletions src/components/StyleGuide/FilteringAccessibility.mdx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a Filtering subfolder in StyleGuide for all these files? Then you don't have to repeat the prefix for every file.

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Meta } from "@storybook/blocks";

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

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

# Filtering accessibility

The following accessibility recommendations are applicable for real-time UI
updates resulting from user actions. If UI updates will be applied after a full
page refresh, then no additional accommodations need to be applied.

## Table of contents

- {<Link href="#aria-live" target="_self">Using aria-live</Link>}
- {<Link href="#focus-management" target="_self">Focus management</Link>}
- {<Link href="#applying-search-terms" target="_self">Applying search terms</Link>}
- {<Link href="#applying-filters" target="_self">Applying filters</Link>}
- {<Link href="#clearing-filters" target="_self">Clearing filters</Link>}
- {<Link href="#pagination" target="_self">Pagination</Link>}
- {<Link href="#sorting" target="_self">Sorting</Link>}
- {<Link href="#modal-overlay" target="_self">Modal overlay</Link>}

## Using aria-live

The parent element housing the `total results` heading should include the
`aria-live="polite"` attribute. This will ensure that real-time updates made to
the heading text are announced to screen reader users.

## Focus management

### Applying search terms
Comment on lines +30 to +32
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We’ll eventually need to build a custom filtering modal (we’re currently using an Ionic component) for the Reader, and this will be a great reference for accessibility!


When a search term is applied using the `text search` field, focus should be moved
to the `total results` heading.

### Applying filters

#### Live filtering

For live filtering, as a user makes changes to filtering options, focus should
be maintained on the filter the user is interacting with.

#### Batch filtering

For batch filtering, focus should be moved to the `total results` heading after
the "Apply filters" button has been clicked.

### Clearing filters

When filters are cleared using the methods available in the `active filters`
list or by clicking the "Clear all filters" button in the `filter bar`, focus
should be moved to the `total results` heading.

When clearing a filter by manually resetting an individual form input element,
focus should be maintained on the filter the user is interacting with.

### Pagination

When using the `pagination` menu to update the `results` list, focus should be moved
to the `total results` heading.

### Sorting

After selecting an option in the `sorting` menu, focus should be maintained on
the `sorting` menu.

### Modal overlay

When the modal overlay that is generated as part of the `FilterBarPopup`
component is closed by clicking the close X in the UI, by clicking outside the
modal overlay, or by pressing ESC on the keyboard, focus should be moved to the
button that was initially clicked to launch the modal overlay. This is the
default behavior of the modal overlay.

When the modal overlay that is generated as part of the `FilterBarPopup`
component is closed by clicking the "Show results" button in the UI, focus
should be moved to the `total results` heading
106 changes: 106 additions & 0 deletions src/components/StyleGuide/FilteringApplyingClearing.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Meta } from "@storybook/blocks";

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

<Meta title="Style Guide/Filtering/Applying & Clearing Filters" />

# Applying and clearing filters

## Table of contents

- {<Link href="#methods" target="_self">Methods</Link>}
- {<Link href="#applying-filters" target="_self">Applying filters</Link>}
- {<Link href="#clearing-filters" target="_self">Clearing filters</Link>}
- {<Link href="#populating-results" target="_self">Populating results</Link>}

## Methods

Filters should be applied and cleared using one of two methods: live filtering or batch filtering.

### Live filtering

- Data is updated in real-time as the user selects filtering options.
- This is the recommended method for applying filters because:
- Users tend to expect and are familiar with real-time filtering due to its
prevalence in e-commerce and elsewhere.
- We have observed in previous research that users tend to miss `Apply`
buttons, particularly when they sit out of sight on the page.
- Batch filtering comes at the risk of returning zero results after which
users have to engage in a trial-and-error process to get useful results.

### Batch filtering

- The user selects multiple filtering options and the data is updated after the
user takes the additional action of clicking the "Apply filters" button
included in the `filter bar`.
- This method is recommended for:
- very heavy data sets
- low performing apps

## Applying filters

When filters are applied, the following should be addressed:

- update the `active filters` list based on the filter options that have been
selected
- update the `results` list based on the filter options that have been selected
- update the `total results` heading to reflect the number of items in the
updated `results` list

## Clearing filters

Filters can be cleared using various methods within the page structure,
including global methods as well as methods for clearing individual filters.
Comment on lines +50 to +53
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious: If a user searches for a term and applies some filters, but then continues typing in the search box without clearing the filters, should the filters be reset? Not sure if this is a accessibility question or a product question.


When filters are cleared, the following should be addressed:

- if a global "clear filters" button is clicked, reset all the form input
elements within the `filter bar`
- update the `active filters` list to remove all filter options
- update the `results` list to an unfiltered state
- update the `total results` heading to reflect the number of items in the
updated `results` list

### Filter bar

- Click the "Clear all filters" button in the `filter bar` (if available) to
remove all filters that have been applied

### Active filters list

- Click an "active filter" tag rendered in the `active filters` list to remove a
specific filter that has been applied
- Click the "Clear filters" button in the `active filters` list to remove all
filters that have been applied

### Form input components

Many form input components can be reset manually. Examples include, but may not
be limited to, the following methods:

- **DatePicker component**
- Deleting a date that has been entered into the input field
- Clicking the clear X
- **MultiSelect component**
- Unchecking a checkbox to remove that single selected option (or set of
options in case of nested filters)
- Clicking the "total options selected" pill button next to the heading to
remove all selected options
- **TextInput component**
- Deleting text that has been entered into the input field
- Clicking the clear X
- **Toggle component**
- Clicking the component to return the toggle to its initial state

## Populating results

`OR` logic should be used within a filtering facet.

- Ex: selecting `English (5)` and `Spanish (2)` from a `Languages` filter should
yield 7 results in total

`AND` logic should be used between categories.

- Ex: selecting `Spanish (2)` from a `Languages` filter should cause other
filters to update their options, adjusting the number of associated items for
each option and disabling options with 0 associated items
65 changes: 65 additions & 0 deletions src/components/StyleGuide/FilteringCompositionActiveFilters.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Meta } from "@storybook/blocks";

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

import imageFilteringActiveFiltersList from "../../../static/filteringStyleGuide/filteringActiveFiltersList.png";
import { exampleWrapperStyles } from "./FilteringOverview.mdx";

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

# Active filters list

The `active filters` list is used to display filters that have been applied.

<Image
alt="Example of active filters list"
src={imageFilteringActiveFiltersList}
{...exampleWrapperStyles}
/>

## Table of Contents

- {<Link href="#rendering" target="_self">Rendering</Link>}
- {<Link href="#positioning" target="_self">Positioning</Link>}
- {<Link href="#visibility" target="_self">Visibility</Link>}
- {<Link href="#labeling" target="_self">Labeling</Link>}
- {<Link href="#adding-filters" target="_self">Adding filters</Link>}
- {<Link href="#clearing-filters" target="_self">Clearing filters</Link>}

## Rendering

The `active filters` list should be rendered using the DS
[TagSet](./?path=/docs/components-content-display-tagset--docs) component.

## Positioning

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

## Visibility

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

## Labeling

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

## Adding filters

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.

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.

## Clearing filters

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
Loading
Loading