import React, { useEffect, useState } from 'react' import { FilterMenu, type FilterStatesType } from './FilterMenu' import Button from '../Button/Button' import ButtonGroup from '../Button/ButtonGroup/ButtonGroup' import { type ButtonGroupProps } from '../Button/ButtonGroup/ButtonGroup' import Ellipsis from '../Ellipsis/Ellipsis' import FormFooter from '../Form/FormFooter' import Icon from '../Icons/Icon' import { type IconStringList } from '../Icons/Icon.models' import Pill from '../Pill/Pill' import { SideDrawer } from '../SideDrawer/SideDrawer' import { useMediaQuery } from '../../hooks/responsiveHooks' import styles from './_filter.module.scss' import { c } from '../../translations/LibraryTranslationService' export type FilterProps = { /** Objects with key value pairs about what filter options can render in Filter body */ filterStates: FilterStatesType /** Function to save selected filter options */ filterCallout: (...params: unknown[]) => void /** Function to reset filter options to default */ resetCallout: () => void /** Function to reset date selected from filter options */ resetDate?: (...params: unknown[]) => void /** Display applied filter count if filter options are selected */ appliedFilters?: unknown /** Function to call on change of any filter options */ onChangeCallout?: (...params: unknown[]) => void /** Function to cancel */ cancelCallout: (...params: unknown[]) => void /** Function to open */ openCallout?: (...params: unknown[]) => void /** Anything which you would like to add in addition to Filter options */ children?: (props: { isOpen?: boolean close?: () => void }) => React.ReactNode /** Set boolean for loading state of filter */ loading?: boolean /** Set boolean to enable/disable tab indexing */ noTabIndex?: boolean /** The text that will display at the top of the popover */ headerText?: string /** Enable/disable Filter button based on API status either loading or success */ apiStatus?: string /** Disables the apply button on the filter form */ disabled?: boolean /** Render filter children above other filter elements rather than the default of below */ topChildren?: boolean /** Disables the filters button */ disableFilterButton?: boolean /** Optionally hide the filter button text in mobile */ hideMobileButtonText?: boolean /** Optionally display the Filter Button as a ButtonGroup */ buttonGroupConfig?: Omit /** Optional prop to add a test id to the Filter for QA testing */ qaTestId?: string } const Filter = ({ filterStates = {}, filterCallout, resetCallout, resetDate, appliedFilters, onChangeCallout, cancelCallout, openCallout, children, loading, noTabIndex, headerText, apiStatus, disabled, topChildren, disableFilterButton, hideMobileButtonText = false, buttonGroupConfig, qaTestId = 'filter', }: FilterProps): React.JSX.Element => { const [openFilters, setOpenFilters] = useState(false) const isMobileView = useMediaQuery({ type: 'max', breakpoint: 'md' }) const buttonGroupProps = buttonGroupConfig ? { ...buttonGroupConfig, buttons: [ ...buttonGroupConfig.buttons, { icon: 'filter' as IconStringList, onClick: () => setOpenFilters(true), disabled: loading || disableFilterButton, }, ], } : null useEffect(() => { openFilters && openCallout?.() }, [openFilters, openCallout]) return (
{buttonGroupProps ? (
{appliedFilters ? ( ) : null}
) : ( )} { setOpenFilters(false) if (isOutsideClick) { cancelCallout() } }} headerContent={headerText ?? c('filters')} footerContent={({ close }) => ( resetCallout(), children: c('resetFilters'), }} cancelButtonProps={{ onClick: () => { cancelCallout() close() }, }} saveButtonProps={{ onClick: () => { filterCallout(filterStates) close() }, disabled: apiStatus === 'loading' || disabled, children: c('apply'), }} /> )} > {({ close }) => ( {children} )}
) } export default Filter