All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.src.components.Chip.ChipGroup.tsx Maven / Gradle / Ivy

Go to download

This library provides a set of common React components for use with the PatternFly reference implementation.

The newest version!
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)} ); } } export { ChipGroup };




© 2015 - 2024 Weber Informatics LLC | Privacy Policy