import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { ToolbarItem, ToolbarItemProps } from './ToolbarItem'; import { ChipGroup } from '../Chip'; import { Chip } from '../Chip'; import { ToolbarContentContext, ToolbarContext } from './ToolbarUtils'; import { PickOptional } from '../../helpers/typeUtils'; export interface ToolbarChipGroup { /** A unique key to identify this chip group category */ key: string; /** The category name to display for the chip group */ name: string; } export interface ToolbarChip { /** A unique key to identify this chip */ key: string; /** The ReactNode to display in the chip */ node: React.ReactNode; } export interface ToolbarFilterProps extends ToolbarItemProps { /** Flag indicating when toolbar toggle group is expanded for non-managed toolbar toggle groups. */ isExpanded?: boolean; /** An array of strings to be displayed as chips in the expandable content */ chips?: (string | ToolbarChip)[]; /** Callback passed by consumer used to close the entire chip group */ deleteChipGroup?: (category: string | ToolbarChipGroup) => void; /** Callback passed by consumer used to delete a chip from the chips[] */ deleteChip?: (category: string | ToolbarChipGroup, chip: ToolbarChip | string) => void; /** Customizable "Show Less" text string for the chip group */ chipGroupExpandedText?: string; /** Customizeable template string for the chip group. Use variable "${remaining}" for the overflow chip count. */ chipGroupCollapsedText?: string; /** Content to be rendered inside the data toolbar item associated with the chip group */ children: React.ReactNode; /** Unique category name to be used as a label for the chip group */ categoryName: string | ToolbarChipGroup; /** Flag to show the toolbar item */ showToolbarItem?: boolean; /** Reference to a chip container created with a custom expandable content group, for non-managed multiple toolbar toggle groups. */ expandableChipContainerRef?: React.RefObject; } interface ToolbarFilterState { isMounted: boolean; } class ToolbarFilter extends React.Component { static displayName = 'ToolbarFilter'; static contextType = ToolbarContext; context!: React.ContextType; static defaultProps: PickOptional = { chips: [] as (string | ToolbarChip)[], showToolbarItem: true }; constructor(props: ToolbarFilterProps) { super(props); this.state = { isMounted: false }; } componentDidMount() { const { categoryName, chips } = this.props; this.context.updateNumberFilters( typeof categoryName !== 'string' && categoryName.hasOwnProperty('key') ? categoryName.key : categoryName.toString(), chips.length ); this.setState({ isMounted: true }); } componentDidUpdate() { const { categoryName, chips } = this.props; this.context.updateNumberFilters( typeof categoryName !== 'string' && categoryName.hasOwnProperty('key') ? categoryName.key : categoryName.toString(), chips.length ); } render() { const { children, chips, deleteChipGroup, deleteChip, chipGroupExpandedText, chipGroupCollapsedText, categoryName, showToolbarItem, isExpanded, expandableChipContainerRef, ...props } = this.props; const { isExpanded: managedIsExpanded, chipGroupContentRef } = this.context; const _isExpanded = isExpanded !== undefined ? isExpanded : managedIsExpanded; const categoryKey = typeof categoryName !== 'string' && categoryName.hasOwnProperty('key') ? categoryName.key : categoryName.toString(); const chipGroup = chips.length ? ( deleteChipGroup(categoryName)} collapsedText={chipGroupCollapsedText} expandedText={chipGroupExpandedText} > {chips.map((chip) => typeof chip === 'string' ? ( deleteChip(categoryKey, chip)}> {chip} ) : ( deleteChip(categoryKey, chip)}> {chip.node} ) )} ) : null; if (!_isExpanded && this.state.isMounted) { return ( {showToolbarItem && {children}} {ReactDOM.createPortal(chipGroup, chipGroupContentRef.current.firstElementChild)} ); } return ( {({ chipContainerRef }) => ( {showToolbarItem && {children}} {chipContainerRef.current && ReactDOM.createPortal(chipGroup, chipContainerRef.current)} {expandableChipContainerRef && expandableChipContainerRef.current && ReactDOM.createPortal(chipGroup, expandableChipContainerRef.current)} )} ); } } export { ToolbarFilter };