All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
package.src.components.Label.LabelGroup.tsx Maven / Gradle / Ivy
Go to download
This library provides a set of common React components for use with the PatternFly reference implementation.
import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/Label/label-group';
import labelStyles from '@patternfly/react-styles/css/components/Label/label';
import { css } from '@patternfly/react-styles';
import { Button } from '../Button';
import { Label } from './Label';
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';
export interface LabelGroupProps extends React.HTMLProps {
/** Content rendered inside the label group. Should be elements. */
children?: React.ReactNode;
/** Additional classes added to the label item */
className?: string;
/** Flag for having the label group default to expanded */
defaultIsOpen?: boolean;
/** Customizable "Show Less" text string */
expandedText?: string;
/** Customizeable template string. Use variable "${remaining}" for the overflow label count. */
collapsedText?: string;
/** Category name text for the label group category. If this prop is supplied the label group with have a label and category styling applied */
categoryName?: string;
/** Aria label for label group that does not have a category name */
'aria-label'?: string;
/** Set number of labels to show before overflow */
numLabels?: number;
/** Flag if label group can be closed */
isClosable?: boolean;
/** Flag indicating the labels in the group are compact */
isCompact?: boolean;
/** Aria label for close button */
closeBtnAriaLabel?: string;
/** Function that is called when clicking on the label group close button */
onClick?: (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';
/** Flag to implement a vertical layout */
isVertical?: boolean;
/** Flag indicating contained labels are editable. Allows spacing for a text input after the labels. */
isEditable?: boolean;
/** Flag indicating the editable label group should be appended with a textarea. */
hasEditableTextArea?: boolean;
/** Additional props passed to the editable textarea. */
editableTextAreaProps?: any;
/** Control for adding new labels */
addLabelControl?: React.ReactNode;
}
interface LabelGroupState {
isOpen: boolean;
isTooltipVisible: boolean;
}
class LabelGroup extends React.Component {
static displayName = 'LabelGroup';
constructor(props: LabelGroupProps) {
super(props);
this.state = {
isOpen: this.props.defaultIsOpen,
isTooltipVisible: false
};
}
private headingRef = React.createRef();
static defaultProps: LabelGroupProps = {
expandedText: 'Show Less',
collapsedText: '${remaining} more',
categoryName: '',
defaultIsOpen: false,
numLabels: 3,
isClosable: false,
isCompact: false,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onClick: (_e: React.MouseEvent) => undefined as any,
closeBtnAriaLabel: 'Close label group',
tooltipPosition: 'top',
'aria-label': 'Label group category',
isVertical: false,
isEditable: false,
hasEditableTextArea: false
};
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,
isCompact,
closeBtnAriaLabel,
'aria-label': ariaLabel,
onClick,
numLabels,
expandedText,
collapsedText,
/* eslint-disable @typescript-eslint/no-unused-vars */
defaultIsOpen,
tooltipPosition,
isVertical,
isEditable,
hasEditableTextArea,
editableTextAreaProps,
addLabelControl,
/* eslint-enable @typescript-eslint/no-unused-vars */
...rest
} = this.props;
const { isOpen } = this.state;
const renderedChildren = React.Children.toArray(children);
const numChildren = renderedChildren.length;
const collapsedTextResult = fillTemplate(collapsedText as string, {
remaining: numChildren - numLabels
});
const renderLabelGroup = (id: string) => {
const labelArray = !isOpen ? renderedChildren.slice(0, numLabels) : renderedChildren;
const content = (
{categoryName && this.renderLabel(id)}
{labelArray.map((child, i) => (
{child}
))}
{numChildren > numLabels && (
{isOpen ? expandedText : collapsedTextResult}
)}
{addLabelControl && {addLabelControl} }
{isEditable && hasEditableTextArea && (
)}
);
const close = (
);
return (
{
{content}
}
{isClosable && close}
);
};
return numChildren === 0 && addLabelControl === undefined ? null : (
{(randomId) => renderLabelGroup(this.props.id || randomId)}
);
}
}
export { LabelGroup };