Skip to content

Commit

Permalink
Merge pull request #835 from equinor/fix/filter-issue
Browse files Browse the repository at this point in the history
🩹 Fix 2 x's showing in search, Fix search not being cleared when hitting clear all
  • Loading branch information
mariush2 authored Oct 25, 2024
2 parents 630653c + d5bbbd3 commit 21707bd
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 66 deletions.
197 changes: 136 additions & 61 deletions src/organisms/Filter/Filter.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,139 @@
import { FC } from 'react';
import { FC, useMemo, useState } from 'react';

import { DatePicker } from '@equinor/eds-core-react';
import { car, car_wash } from '@equinor/eds-icons';
import { gear, van } from '@equinor/eds-icons';
import { Meta, StoryObj } from '@storybook/react';

import { Filter, FilterProps } from './Filter';
import { formatDate } from 'src/atoms';
import { SingleSelect } from 'src/molecules';

const Wrapper: FC<FilterProps> = (props) => (
<Filter {...props}>
<DatePicker label="Created date" />
<div
style={{
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '1rem',
}}
import { SelectOptionRequired, SingleSelect } from 'src/molecules';

const CAR_SIZE = [
{ value: 'size', label: 'Sports car' },
{ value: 'size', label: 'Kei car' },
{ value: 'size', label: 'Family van' },
];
const MANUFACTURER = [
{ value: 'toyota', label: 'トヨタ (Toyota)' },
{ value: 'mazda', label: 'マツダ (Mazda)' },
{ value: 'created-by', label: '鈴木 (Suzuki)' },
];

type FilterStoryProps = FilterProps & { withIcons?: boolean };

const Wrapper: FC<FilterStoryProps> = (props) => {
const [carSize, setCarSize] = useState<SelectOptionRequired | undefined>(
undefined
);
const [manufacturer, setManufacturer] = useState<
SelectOptionRequired | undefined
>(
props.values?.find((value) =>
MANUFACTURER.some((manufacturer) => manufacturer.value === value.value)
)
);
const [manufacturerDate, setManufacturerDate] = useState<Date | undefined>(
undefined
);

const values = useMemo(() => {
const all: FilterProps['values'] = [];

if (carSize) {
if (props.withIcons) {
all.push({ ...carSize, icon: van });
} else {
all.push(carSize);
}
}

if (manufacturer) {
if (props.withIcons) {
all.push({ ...manufacturer, icon: gear });
} else {
all.push(manufacturer);
}
}

if (manufacturerDate) {
all.push({
value: 'manufacturer-date',
label: `Manufactured: ${formatDate(manufacturerDate, {
format: 'DD. month YYYY',
})}`,
});
}

return all;
}, [carSize, manufacturer, manufacturerDate, props.withIcons]);

const handleOnSelectEnvironment = (
value: SelectOptionRequired | undefined
) => {
setCarSize(value);
};

const handleOnSelectCreatedBy = (value: SelectOptionRequired | undefined) => {
setManufacturer(value);
};

const handleOnChangManufacturerDate = (value: Date | null) => {
setManufacturerDate(value || undefined);
};

const handleOnClearFilter = (value: string) => {
if (MANUFACTURER.some((manufacturer) => manufacturer.value === value)) {
setManufacturer(undefined);
} else if (CAR_SIZE.some((size) => size.value === value)) {
setCarSize(undefined);
} else if (value === 'manufacturer-date') {
setManufacturerDate(undefined);
}
};

const handleOnClearAllFilters = () => {
setCarSize(undefined);
setManufacturer(undefined);
setManufacturerDate(undefined);
};

return (
<Filter
{...props}
values={values}
onClearFilter={handleOnClearFilter}
onClearAllFilters={handleOnClearAllFilters}
>
<SingleSelect
value={undefined}
label="Environment"
onSelect={(value) => console.log(value)}
items={[
{ value: 'development', label: 'Development' },
{ value: 'staging', label: 'Staging' },
{ value: 'production', label: 'Production' },
]}
/>
<SingleSelect
value={undefined}
label="Environment"
onSelect={(value) => console.log(value)}
items={[
{ value: 'development', label: 'Development' },
{ value: 'staging', label: 'Staging' },
{ value: 'production', label: 'Production' },
]}
<DatePicker
label="Manufacturer date"
value={manufacturerDate}
onChange={handleOnChangManufacturerDate}
/>
</div>
</Filter>
);
<div
style={{
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '1rem',
}}
>
<SingleSelect
value={carSize}
label="Car size"
onSelect={handleOnSelectEnvironment}
items={CAR_SIZE}
/>
<SingleSelect
value={manufacturer}
label="Created by"
onSelect={handleOnSelectCreatedBy}
items={MANUFACTURER}
/>
</div>
</Filter>
);
};

const meta: Meta<typeof Filter> = {
const meta: Meta<FilterStoryProps> = {
title: 'Organisms/Filter',
component: Wrapper,
parameters: {
Expand Down Expand Up @@ -80,41 +171,23 @@ const meta: Meta<typeof Filter> = {
},
},
args: {
values: [
{
value: 'development',
label: 'Development',
},
],
placeholder: 'Search for a car...',
},
};

export default meta;
type Story = StoryObj<typeof Filter>;
type Story = StoryObj<FilterStoryProps>;

export const Default: Story = {
args: {},
args: {
values: [MANUFACTURER[1]],
},
};

export const ValuesWithIcons: Story = {
args: {
placeholder: 'Search for a car...',
values: [
{
value: 'car',
label: 'Toyota',
icon: car,
},
{
value: 'purchase-date',
label: `Purchased: ${formatDate(new Date(), { format: 'DD. month YYYY' })}`,
},
{
value: 'state',
label: 'Newly washed',
icon: car_wash,
},
],
values: [MANUFACTURER[1]],
withIcons: true,
},
};

Expand All @@ -126,12 +199,14 @@ export const WithEmptyValues: Story = {

export const InitialOpen: Story = {
args: {
values: [MANUFACTURER[1]],
initialOpen: true,
},
};

export const WithoutClearButton: Story = {
args: {
values: [MANUFACTURER[1]],
initialOpen: true,
showClearFiltersButton: false,
},
Expand Down
5 changes: 5 additions & 0 deletions src/organisms/Filter/Filter.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ export const SearchField = styled.input`
opacity: 1;
color: ${colors.text.static_icons__tertiary.rgba};
}
&::-webkit-search-cancel-button,
&::-webkit-search-results-button,
&::-webkit-search-results-decoration {
display: none;
}
`;

interface ContentProps {
Expand Down
9 changes: 7 additions & 2 deletions src/organisms/Filter/Filter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ test('onClearFilter is called when clicking X', async () => {
expect(props.onClearFilter).toHaveBeenCalledWith(randomValue.value);
});

test('onClearAllFilters is called when clicking clear all', async () => {
test('onClearAllFilters is called when clicking clear all and search is cleared', async () => {
const props = fakeProps();
render(
<Filter {...props}>
Expand All @@ -138,11 +138,16 @@ test('onClearAllFilters is called when clicking clear all', async () => {
);
const user = userEvent.setup();

const clearAllButton = screen.getAllByRole('button').at(-2)!;
const searchBox = screen.getByRole('searchbox');

await user.type(searchBox, faker.lorem.word());

const clearAllButton = screen.getByTestId('clear-all-x');

await user.click(clearAllButton);

expect(props.onClearAllFilters).toHaveBeenCalledTimes(1);
expect(searchBox).toHaveValue('');
});

test('initialOpen works as expected', async () => {
Expand Down
16 changes: 13 additions & 3 deletions src/organisms/Filter/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,16 @@ export const Filter: FC<FilterProps> = ({
}
};

const handleOnClearAll = () => {
setSearch('');
onClearAllFilters();
};

return (
<Wrapper>
<Container $open={open}>
<Icon
onClick={handleOnToggleOpen}
data={filter_list}
color={colors.interactive.primary__resting.rgba}
/>
Expand All @@ -126,7 +132,11 @@ export const Filter: FC<FilterProps> = ({
/>
</section>
{values.length > 0 && (
<Button variant="ghost_icon" onClick={onClearAllFilters}>
<Button
variant="ghost_icon"
onClick={handleOnClearAll}
data-testid="clear-all-x"
>
<Icon
data={clear}
size={16}
Expand Down Expand Up @@ -157,7 +167,7 @@ export const Filter: FC<FilterProps> = ({
{child}
{index === children.length - 1 &&
showClearFiltersButton && (
<Button variant="outlined" onClick={onClearAllFilters}>
<Button variant="outlined" onClick={handleOnClearAll}>
Clear filters
</Button>
)}
Expand All @@ -167,7 +177,7 @@ export const Filter: FC<FilterProps> = ({
<div>
{children}
{showClearFiltersButton && (
<Button variant="outlined" onClick={onClearAllFilters}>
<Button variant="outlined" onClick={handleOnClearAll}>
Clear filters
</Button>
)}
Expand Down

0 comments on commit 21707bd

Please sign in to comment.