-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
358 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
249 changes: 249 additions & 0 deletions
249
packages/components/src/Filter/FilterBar/_docs/FilterBar.spec.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
import React, { useState } from "react" | ||
import { Meta, StoryObj } from "@storybook/react" | ||
import { expect, userEvent, waitFor, within, fn } from "@storybook/test" | ||
import { FilterMultiSelect } from "~components/Filter/FilterMultiSelect" | ||
import { DateRange } from "~components/index" | ||
import { FilterBar, Filters } from "../index" | ||
|
||
const meta = { | ||
title: "Components/FilterBar/FilterBar Tests", | ||
component: FilterBar, | ||
argTypes: { | ||
filters: { control: false }, | ||
values: { control: false }, | ||
onValuesChange: { control: false }, | ||
}, | ||
args: { | ||
filters: [], // Defined in stories | ||
values: {}, // Defined in stories | ||
onValuesChange: fn(), | ||
}, | ||
} satisfies Meta<typeof FilterBar> | ||
|
||
export default meta | ||
|
||
type Story = StoryObj<typeof meta> | ||
|
||
type Values = { | ||
flavour: string | ||
deliveryDates: DateRange | ||
toppings: string[] | ||
drank: Date | ||
} | ||
|
||
const filters = [ | ||
{ | ||
id: "flavour", | ||
name: "Flavour", | ||
Component: ( | ||
<FilterBar.Select | ||
items={[ | ||
{ value: "jasmine-milk-tea", label: "Jasmine Milk Tea" }, | ||
{ value: "honey-milk-tea", label: "Honey Milk Tea" }, | ||
{ value: "lychee-green-tea", label: "Lychee Green Tea" }, | ||
]} | ||
/> | ||
), | ||
}, | ||
{ | ||
id: "deliveryDates", | ||
name: "Delivery Dates", | ||
Component: <FilterBar.DateRangePicker />, | ||
}, | ||
{ | ||
id: "toppings", | ||
name: "Toppings", | ||
Component: ( | ||
<FilterBar.MultiSelect | ||
items={[ | ||
{ value: "none", label: "None" }, | ||
{ value: "pearls", label: "Pearls" }, | ||
{ value: "fruit-jelly", label: "Fruit Jelly" }, | ||
{ value: "peanuts", label: "Peanuts" }, | ||
{ value: "coconut", label: "Coconut" }, | ||
{ value: "aloe", label: "Aloe Vera" }, | ||
{ value: "mochi", label: "Mini Mochi" }, | ||
{ value: "popping-pearls", label: "Popping Pearls" }, | ||
]} | ||
> | ||
{(): JSX.Element => ( | ||
<> | ||
<FilterMultiSelect.SearchInput /> | ||
<FilterMultiSelect.ListBox> | ||
{({ allItems }): JSX.Element | JSX.Element[] => | ||
allItems.map(item => ( | ||
<FilterMultiSelect.Option key={item.key} item={item} /> | ||
)) | ||
} | ||
</FilterMultiSelect.ListBox> | ||
<FilterMultiSelect.MenuFooter> | ||
<FilterMultiSelect.SelectAllButton /> | ||
<FilterMultiSelect.ClearButton /> | ||
</FilterMultiSelect.MenuFooter> | ||
</> | ||
)} | ||
</FilterBar.MultiSelect> | ||
), | ||
isRemovable: true, | ||
}, | ||
{ | ||
id: "drank", | ||
name: "Drank", | ||
Component: <FilterBar.DatePicker />, | ||
isRemovable: true, | ||
}, | ||
] satisfies Filters<Values> | ||
|
||
export const ClearAllFromValue: Story = { | ||
render: args => { | ||
const [activeValues, onActiveValuesChange] = useState<Partial<Values>>({}) | ||
return ( | ||
<FilterBar<Values> | ||
{...args} | ||
filters={filters} | ||
values={activeValues} | ||
onValuesChange={onActiveValuesChange} | ||
/> | ||
) | ||
}, | ||
play: async ({ canvasElement, step }) => { | ||
const canvas = within(canvasElement.parentElement!) | ||
|
||
await step( | ||
"Clear all button hidden by default given no values", | ||
async () => { | ||
expect( | ||
canvas.queryByRole("button", { | ||
name: "Clear all filters", | ||
}) | ||
).not.toBeInTheDocument() | ||
} | ||
) | ||
|
||
await step("filter value is added", async () => { | ||
await userEvent.click(canvas.getByRole("button", { name: "Flavour" })) | ||
await userEvent.click( | ||
canvas.getByRole("option", { name: "Jasmine Milk Tea" }) | ||
) | ||
expect( | ||
canvas.getByRole("button", { name: "Flavour: Jasmine Milk Tea" }) | ||
).toBeInTheDocument() | ||
}) | ||
|
||
await step( | ||
"'Clear all' press removes the value and hides itself", | ||
async () => { | ||
const clearAllButton = canvas.getByRole("button", { | ||
name: "Clear all filters", | ||
}) | ||
userEvent.click(clearAllButton) | ||
|
||
waitFor(() => | ||
expect( | ||
canvas.getByRole("button", { name: "Flavour" }) | ||
).toBeInTheDocument() | ||
) | ||
|
||
waitFor(() => | ||
expect( | ||
canvas.queryByRole("button", { | ||
name: "Clear all filters", | ||
}) | ||
).not.toBeInTheDocument() | ||
) | ||
} | ||
) | ||
}, | ||
} | ||
|
||
export const ClearAllFromRemovable: Story = { | ||
render: args => { | ||
const [activeValues, onActiveValuesChange] = useState<Partial<Values>>({}) | ||
return ( | ||
<FilterBar<Values> | ||
{...args} | ||
filters={filters} | ||
values={activeValues} | ||
onValuesChange={onActiveValuesChange} | ||
/> | ||
) | ||
}, | ||
play: async ({ canvasElement, step }) => { | ||
const canvas = within(canvasElement.parentElement!) | ||
|
||
await step("removable filter is added with no value", async () => { | ||
await waitFor(() => { | ||
userEvent.click(canvas.getByRole("button", { name: "Add Filters" })) | ||
}) | ||
|
||
await waitFor(() => { | ||
userEvent.click(canvas.getByRole("button", { name: "Toppings" })) | ||
}) | ||
}) | ||
|
||
await step("'Clear all' press removes removable filter", async () => { | ||
await waitFor(() => { | ||
userEvent.click( | ||
canvas.getByRole("button", { | ||
name: "Clear all filters", | ||
}) | ||
) | ||
}) | ||
|
||
waitFor(() => | ||
expect( | ||
canvas.queryByRole("button", { name: "Toppings" }) | ||
).not.toBeInTheDocument() | ||
) | ||
|
||
waitFor(() => | ||
expect( | ||
canvas.queryByRole("button", { | ||
name: "Clear all filters", | ||
}) | ||
).not.toBeInTheDocument() | ||
) | ||
}) | ||
}, | ||
} | ||
|
||
export const ClearAllRemovesItself: Story = { | ||
render: args => { | ||
const [activeValues, onActiveValuesChange] = useState<Partial<Values>>({}) | ||
return ( | ||
<FilterBar<Values> | ||
{...args} | ||
filters={filters} | ||
values={activeValues} | ||
onValuesChange={onActiveValuesChange} | ||
/> | ||
) | ||
}, | ||
play: async ({ canvasElement, step }) => { | ||
const canvas = within(canvasElement.parentElement!) | ||
|
||
await step("removable filter is added with no value", async () => { | ||
await waitFor(() => | ||
userEvent.click(canvas.getByRole("button", { name: "Add Filters" })) | ||
) | ||
await userEvent.click(canvas.getByRole("button", { name: "Drank" })) | ||
}) | ||
|
||
await step( | ||
"Clear all button hides by itself after removing filter", | ||
async () => { | ||
await userEvent.click( | ||
canvas.getByRole("button", { name: "Remove filter - Drank" }) | ||
) | ||
} | ||
) | ||
|
||
waitFor(() => | ||
expect( | ||
canvas.queryByRole("button", { | ||
name: "Clear all filters", | ||
}) | ||
).not.toBeInTheDocument() | ||
) | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.