| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- import React, { PureComponent } from 'react';
- import classNames from 'classnames';
- import PropTypes from 'prop-types';
- import { cssClasses, strings } from '@douyinfe/semi-foundation/tag/constants';
- import Tag from './index';
- import Popover, { PopoverProps } from '../popover/index';
- import { AvatarShape, TagProps } from './interface';
- const prefixCls = cssClasses.PREFIX;
- const tagSize = strings.TAG_SIZE;
- const avatarShapeSet = strings.AVATAR_SHAPE;
- export interface TagGroupProps {
- style?: React.CSSProperties;
- className?: string;
- maxTagCount?: number;
- restCount?: number;
- tagList?: (TagProps | React.ReactNode)[];
- size?: 'small' | 'large';
- showPopover?: boolean;
- popoverProps?: PopoverProps;
- avatarShape?: AvatarShape;
- mode?: string;
- }
- export default class TagGroup extends PureComponent<TagGroupProps> {
- static defaultProps = {
- style: {},
- className: '',
- size: tagSize[0],
- avatarShape: 'square',
- };
- static propTypes = {
- children: PropTypes.node,
- style: PropTypes.object,
- className: PropTypes.string,
- maxTagCount: PropTypes.number,
- restCount: PropTypes.number,
- tagList: PropTypes.array,
- size: PropTypes.oneOf(tagSize),
- mode: PropTypes.string,
- showPopover: PropTypes.bool,
- popoverProps: PropTypes.object,
- avatarShape: PropTypes.oneOf(avatarShapeSet),
- };
- renderNTag(n: number, restTags: React.ReactNode) {
- const { size, showPopover, popoverProps } = this.props;
- let nTag = (
- <Tag
- closable={false}
- size={size}
- color="grey"
- style={{ backgroundColor: 'transparent' }}
- key="_+n"
- >
- +{n}
- </Tag>
- );
- if (showPopover) {
- nTag = (
- <Popover
- showArrow
- content={restTags}
- trigger="hover"
- position="top"
- autoAdjustOverflow
- className={`${prefixCls}-rest-group-popover`}
- {...popoverProps}
- key="_+n_Popover"
- >
- {nTag}
- </Popover>
- );
- }
- return nTag;
- }
- renderMergeTags(tags: (Tag | React.ReactNode)[]) {
- const { maxTagCount, tagList, restCount } = this.props;
- const n = restCount ? restCount : tagList.length - maxTagCount;
- let renderTags: (Tag | React.ReactNode)[] = tags;
- const normalTags: (Tag | React.ReactNode)[] = tags.slice(0, maxTagCount);
- const restTags = tags.slice(maxTagCount) as React.ReactNode;
- let nTag = null;
- if (n > 0) {
- nTag = this.renderNTag(n, restTags);
- normalTags.push(nTag);
- renderTags = normalTags;
- }
- return renderTags;
- }
- renderAllTags() {
- const { tagList, size, mode, avatarShape } = this.props;
- const renderTags = tagList.map((tag, index): (Tag | React.ReactNode) => {
- if (mode === 'custom') {
- return tag as React.ReactNode;
- }
- if (!(tag as TagProps).size) {
- (tag as TagProps).size = size;
- }
- if (!(tag as TagProps).avatarShape) {
- (tag as TagProps).avatarShape = avatarShape;
- }
- return <Tag key={`${index}-tag`} {...(tag as TagProps)} />;
- });
- return renderTags;
- }
- render() {
- const { style, className, maxTagCount, size } = this.props;
- const groupCls = classNames({
- [`${prefixCls}-group`]: true,
- [`${prefixCls}-group-max`]: maxTagCount,
- [`${prefixCls}-group-small`]: size === 'small',
- [`${prefixCls}-group-large`]: size === 'large',
- }, className);
- const tags = this.renderAllTags();
- const tagContents = (typeof maxTagCount === 'undefined' ? tags : this.renderMergeTags(tags)) as React.ReactNode;
- return (
- <div style={style} className={groupCls}>
- {tagContents}
- </div>
- );
- }
- }
|