import * as React from 'react'; import styles from '@patternfly/react-styles/css/components/Chip/chip-group'; import { css } from '@patternfly/react-styles'; import { Button } from '../Button'; import { Chip } from './Chip'; import { Tooltip, TooltipPosition } from '../Tooltip'; import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon'; import { fillTemplate } from '../../helpers'; import { GenerateId } from '../../helpers/GenerateId/GenerateId'; import { getOUIAProps, OUIAProps } from '../../helpers'; export interface ChipGroupProps extends React.HTMLProps, OUIAProps { /** Content rendered inside the chip group. Should be elements. */ children?: React.ReactNode; /** Additional classes added to the chip item */ className?: string; /** Flag for having the chip group default to expanded */ defaultIsOpen?: boolean; /** Customizable "Show Less" text string */ expandedText?: string; /** Customizeable template string. Use variable "${remaining}" for the overflow chip count. */ collapsedText?: string; /** Category name text for the chip group category. If this prop is supplied the chip group with have a label and category styling applied */ categoryName?: string; /** Aria label for chip group that does not have a category name */ 'aria-label'?: string; /** Set number of chips to show before overflow */ numChips?: number; /** Flag if chip group can be closed*/ isClosable?: boolean; /** Aria label for close button */ closeBtnAriaLabel?: string; /** Function that is called when clicking on the chip group close button */ onClick?: (event: React.MouseEvent) => void; /** Function that is called when clicking on the overflow (expand/collapse) chip button */ onOverflowChipClick?: (event: React.MouseEvent) => void; /** Position of the tooltip which is displayed if the category name text is longer */ tooltipPosition?: | TooltipPosition | 'auto' | 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end'; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; } interface ChipGroupState { isOpen: boolean; isTooltipVisible: boolean; } class ChipGroup extends React.Component { static displayName = 'ChipGroup'; constructor(props: ChipGroupProps) { super(props); this.state = { isOpen: this.props.defaultIsOpen, isTooltipVisible: false }; } private headingRef = React.createRef(); static defaultProps: ChipGroupProps = { expandedText: 'Show Less', collapsedText: '${remaining} more', categoryName: '', defaultIsOpen: false, numChips: 3, isClosable: false, // eslint-disable-next-line @typescript-eslint/no-unused-vars onClick: (_e: React.MouseEvent) => undefined as any, onOverflowChipClick: (_e: React.MouseEvent) => undefined as any, closeBtnAriaLabel: 'Close chip group', tooltipPosition: 'top', 'aria-label': 'Chip group category' }; componentDidMount() { this.setState({ isTooltipVisible: Boolean( this.headingRef.current && this.headingRef.current.offsetWidth < this.headingRef.current.scrollWidth ) }); } toggleCollapse = () => { this.setState((prevState) => ({ isOpen: !prevState.isOpen, isTooltipVisible: Boolean( this.headingRef.current && this.headingRef.current.offsetWidth < this.headingRef.current.scrollWidth ) })); }; renderLabel(id: string) { const { categoryName, tooltipPosition } = this.props; const { isTooltipVisible } = this.state; return isTooltipVisible ? ( {categoryName} ) : ( {categoryName} ); } render() { const { categoryName, children, className, isClosable, closeBtnAriaLabel, 'aria-label': ariaLabel, onClick, onOverflowChipClick, numChips, expandedText, collapsedText, ouiaId, /* eslint-disable @typescript-eslint/no-unused-vars */ defaultIsOpen, tooltipPosition, /* eslint-enable @typescript-eslint/no-unused-vars */ ...rest } = this.props; const { isOpen } = this.state; const numChildren = React.Children.count(children); const collapsedTextResult = fillTemplate(collapsedText as string, { remaining: React.Children.count(children) - numChips }); const renderChipGroup = (id: string) => { const chipArray = !isOpen ? React.Children.toArray(children).slice(0, numChips) : React.Children.toArray(children); return (
{categoryName && this.renderLabel(id)}
    {chipArray.map((child, i) => (
  • {child}
  • ))} {numChildren > numChips && (
  • { this.toggleCollapse(); onOverflowChipClick(event); }} component="button" > {isOpen ? expandedText : collapsedTextResult}
  • )}
{isClosable && (
)}
); }; return numChildren === 0 ? null : ( {(randomId) => renderChipGroup((this.props.id || randomId) as string)} ); } } export { ChipGroup };