Skip to content

Commit

Permalink
feat(filterspopover): add filters popover
Browse files Browse the repository at this point in the history
  • Loading branch information
Jin Lee committed Sep 10, 2022
1 parent 0fb7565 commit 541e226
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 24 deletions.
2 changes: 2 additions & 0 deletions src/components/Filters/Filters.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default {
/>
</Filters.FiltersCheckboxField>
),
variant: 'drawer',
},
decorators: [
(Story) => (
Expand Down Expand Up @@ -141,6 +142,7 @@ const OverflowCheckboxFields = () => {
onClear={onClear}
onClose={onClose}
triggerText={triggerText}
variant="popover"
>
<Filters.FiltersCheckboxField legend="Filters Segment 1">
<Checkbox
Expand Down
78 changes: 56 additions & 22 deletions src/components/Filters/Filters.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { useState } from 'react';
import styles from './Filters.module.css';
import Button from '../Button';
import { FiltersCheckboxField } from '../FiltersCheckboxField/FiltersCheckboxField';
import { FiltersDrawer } from '../FiltersDrawer/FiltersDrawer';
import FiltersCheckboxField from '../FiltersCheckboxField';
import FiltersDrawer from '../FiltersDrawer';
import FiltersPopover from '../FiltersPopover';
import Icon from '../Icon';
import Popover from '../Popover';

export type Props = {
/**
Expand Down Expand Up @@ -31,13 +33,18 @@ export type Props = {
*/
footerButtonGroupClassName?: string;
/**
* Callback called when filters drawer is closed.
* Callback called when filters are closed.
* Currently only works with the 'drawer' variant.
*/
onClose?: () => void;
/**
* Callback called when the apply button is called.
*/
onApply?: () => void;
/**
* Which filters variant to render.
*/
variant: 'drawer' | 'popover';
};

/**
Expand All @@ -58,6 +65,7 @@ export const Filters = ({
onClear,
onClose,
onApply,
variant,
}: Props) => {
/**
* Manages the active state of the filters drawer.
Expand Down Expand Up @@ -88,25 +96,51 @@ export const Filters = ({

return (
<div>
<Button
className={styles['filters__button']}
onClick={() => setIsActive(true)}
status={buttonStatus}
variant={buttonVariant}
>
<Icon name="filter-list" purpose="decorative" size="1.5rem" />
{triggerText}
</Button>
<FiltersDrawer
className={className}
footerButtonGroupClassName={footerButtonGroupClassName}
isActive={isActive}
onApply={onApply ? applyFilters : undefined}
onClear={onClear ? clearFilters : undefined}
onClose={closeFilters}
>
{children}
</FiltersDrawer>
{variant === 'popover' && (
<Popover placement="bottom-start">
<Popover.Button as={React.Fragment}>
<Button
className={styles['filters__button']}
onClick={() => setIsActive(true)}
status={buttonStatus}
variant={buttonVariant}
>
<Icon name="filter-list" purpose="decorative" size="1.5rem" />
{triggerText}
</Button>
</Popover.Button>
<FiltersPopover
className={className}
onApply={onApply ? applyFilters : undefined}
onClear={onClear ? clearFilters : undefined}
>
{children}
</FiltersPopover>
</Popover>
)}
{variant === 'drawer' && (
<>
<Button
className={styles['filters__button']}
onClick={() => setIsActive(true)}
status={buttonStatus}
variant={buttonVariant}
>
<Icon name="filter-list" purpose="decorative" size="1.5rem" />
{triggerText}
</Button>
<FiltersDrawer
className={className}
footerButtonGroupClassName={footerButtonGroupClassName}
isActive={isActive}
onApply={onApply ? applyFilters : undefined}
onClear={onClear ? clearFilters : undefined}
onClose={closeFilters}
>
{children}
</FiltersDrawer>
</>
)}
</div>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/FiltersDrawer/FiltersDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ButtonGroup from '../ButtonGroup';
import Drawer from '../Drawer';
import Heading from '../Heading';

export type Props = {
export type FiltersDrawerProps = {
/**
* Form controls, form fields, or other relevant information that will be displayed in the filters drawer.
*/
Expand Down Expand Up @@ -55,7 +55,7 @@ export const FiltersDrawer = ({
onApply,
onClose,
isActive,
}: Props) => {
}: FiltersDrawerProps) => {
/**
* Manages overflow state.
*/
Expand Down
19 changes: 19 additions & 0 deletions src/components/FiltersPopover/FiltersPopover.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { BADGE } from '@geometricpanda/storybook-addon-badges';
import { StoryObj, Meta } from '@storybook/react';
import React from 'react';

import { FiltersPopover } from './FiltersPopover';

export default {
title: 'PleaseUpdateThisToADifferentFolder/FiltersPopover',
component: FiltersPopover,
parameters: {
badges: [BADGE.BETA],
},
} as Meta<Args>;

type Args = React.ComponentProps<typeof FiltersPopover>;

export const Default: StoryObj<Args> = {
args: {},
};
6 changes: 6 additions & 0 deletions src/components/FiltersPopover/FiltersPopover.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { generateSnapshots } from '@chanzuckerberg/story-utils';
import * as stories from './FiltersPopover.stories';

describe('<FiltersPopover />', () => {
generateSnapshots(stories);
});
76 changes: 76 additions & 0 deletions src/components/FiltersPopover/FiltersPopover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import clsx from 'clsx';
import React from 'react';
import Button from '../Button';
import ButtonGroup from '../ButtonGroup';
import Popover from '../Popover';

export type FiltersPopoverProps = {
/**
* Form controls, form fields, or other relevant information that will be displayed in the filters popover.
*/
children: React.ReactNode;
/**
* CSS class names that can be appended to the component.
*/
className?: string;
/**
* Callback called when the clear button is called.
*/
onClear?: () => void;
/**
* Callback called when filters drawer is closed.
*/
onClose?: () => void;
/**
* Callback called when the apply button is called.
*/
onApply?: () => void;
};

/**
* BETA: This component is still a work in progress and is subject to change.
*
* ```ts
* import {FiltersPopover} from "@chanzuckerberg/eds";
* ```
*
* TODO: update this comment with a description of the component.
*/
export const FiltersPopover = ({
children,
className,
onApply,
onClear,
...other
}: FiltersPopoverProps) => {
const componentClassName = clsx(styles['filters-popover'], className);

return (
<Popover.Content className={componentClassName} {...other}>
<div>{children}</div>
{(onClear || onApply) && (
<div className={styles['filters-popover__footer']}>
<ButtonGroup className={styles['filters-popover__button-group']}>
{onClear && (
<Button
className={styles['footer__button']}
onClick={() => onClear()}
>
Clear All
</Button>
)}
{onApply && (
<Button
className={styles['footer__button']}
onClick={() => onApply()}
variant="primary"
>
Apply
</Button>
)}
</ButtonGroup>
</div>
)}
</Popover.Content>
);
};
1 change: 1 addition & 0 deletions src/components/FiltersPopover/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { FiltersPopover as default } from './FiltersPopover';
2 changes: 2 additions & 0 deletions src/components/PopoverButton/PopoverButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ export const PopoverButton = (props: PopoverButtonProps) => {
const { setReferenceElement } = useContext(PopoverContext);
return <HeadlessPopover.Button {...props} ref={setReferenceElement} />;
};

PopoverButton.displayName = 'PopoverButton';
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export { default as FieldsetLegend } from './components/FieldsetLegend';
export { default as Filters } from './components/Filters';
export { default as FiltersCheckboxField } from './components/FiltersCheckboxField';
export { default as FiltersDrawer } from './components/FiltersDrawer';
export { default as FiltersPopover } from './components/FiltersPopover';
export { default as Grid } from './components/Grid';
export { default as GridItem } from './components/GridItem';
export { default as Heading } from './components/Heading';
Expand Down

0 comments on commit 541e226

Please sign in to comment.