import { forwardRef, useEffect, useState, FunctionComponent, Ref, MouseEvent as ReactMouseEvent, CSSProperties } from 'react'; import { Badge } from '@patternfly/react-core/dist/esm/components/Badge'; import { MenuToggle, MenuToggleElement, MenuToggleProps } from '@patternfly/react-core/dist/esm/components/MenuToggle'; import { Select, SelectList, SelectOption, SelectOptionProps, SelectProps } from '@patternfly/react-core/dist/esm/components/Select'; export interface CheckboxSelectOption extends Omit { /** Content of the select option. */ content: React.ReactNode; /** Value of the select option. */ value: string | number; } export interface CheckboxSelectProps extends Omit { /** @hide Forwarded ref */ innerRef?: React.Ref; /** Initial options of the select. */ initialOptions?: CheckboxSelectOption[]; /** Callback triggered on selection. */ onSelect?: (_event: React.MouseEvent, value?: CheckboxSelectOption['value']) => void; /** Callback triggered when the select opens or closes. */ onToggle?: (nextIsOpen: boolean) => void; /** Flag indicating the select should be disabled. */ isDisabled?: boolean; /** Content of the toggle. Defaults to a string with badge count of selected options. */ toggleContent?: React.ReactNode; /** Width of the toggle. */ toggleWidth?: string; /** Additional props passed to the toggle. */ toggleProps?: MenuToggleProps; } const CheckboxSelectBase: FunctionComponent = ({ innerRef, initialOptions, isDisabled, onSelect: passedOnSelect, onToggle, toggleContent, toggleWidth = '200px', toggleProps, ...props }: CheckboxSelectProps) => { const [isOpen, setIsOpen] = useState(false); const [selected, setSelected] = useState([]); useEffect(() => { const selectedOptions = initialOptions?.filter((option) => option.selected); setSelected(selectedOptions?.map((selectedOption) => String(selectedOption.value)) ?? []); }, [initialOptions]); const checkboxSelectOptions = initialOptions?.map((option) => { const { content, value, ...props } = option; const isSelected = selected.includes(`${value}`); return ( {content} ); }); const onToggleClick = () => { onToggle && onToggle(!isOpen); setIsOpen(!isOpen); }; const onSelect = (event: ReactMouseEvent | undefined, value: string | number | undefined) => { const valueString = `${value}`; if (selected.includes(valueString)) { setSelected((prevSelected) => prevSelected.filter((item) => item !== valueString)); } else { setSelected((prevSelected) => [...prevSelected, valueString]); } passedOnSelect && passedOnSelect(event, value); }; const defaultToggleContent = ( <> Filter by status {selected.length > 0 && {selected.length}} ); const toggle = (toggleRef: Ref) => ( {toggleContent || defaultToggleContent} ); return ( ); }; export const CheckboxSelect = forwardRef((props: CheckboxSelectProps, ref: Ref) => ( ));