React antd tags封装

import React, { memo, useState } from 'react'
import { Tag, Input } from 'antd'
import { TweenOneGroup } from 'rc-tween-one'
import { PlusOutlined } from '@ant-design/icons'
import PropTypes from 'prop-types'

const Tags = memo((props) => {
    const { tagNames = ['Tag 1', 'Tag 2', 'Tag 3'] } = props

    const [tags, setTags] = useState(tagNames)
    const [inputVisible, setInputVisible] = useState(false)
    const [inputValue, setInputValue] = useState('')

    // 移除标签
    const handleClose = (removeTag) => {
        const newTags = tags.filter(tag => {
            return tag !== removeTag
        })
        setTags(newTags)
    }

    // 输入框显示
    const showInput = () => {
        setInputVisible(true)
    }

    // 输入框内容存储
    const handleInputChange = (e) => {
        setInputValue(e.target.value)
    }

    // 输入框内容确认
    const handleInputConfirm = () => {
        inputValue && setTags([...tags, inputValue])
        setInputVisible(false)
        setInputValue('')
    }

    const tagChild = tags.map(tag => {
        const tagElem = (
            <Tag
                closable
                onClose={e => {
                    e.preventDefault()
                    handleClose(tag)
                }}>
                {tag}
            </Tag>
        )
        return (
            <span key={tag} style={{ display: 'inline-block' }}>
                {tagElem}
            </span>
        )
    })

    return (
        <>
            <div style={{ marginBottom: 16, marginTop:6 }}>
                <TweenOneGroup
                    enter={{
                        scale: 0.8,
                        opacity: 0,
                        type: 'from',
                        duration: 100,
                        onComplete: e => {
                            e.target.style = '';
                        },
                    }}
                    leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
                    appear={false}>
                        {tagChild}
                </TweenOneGroup>
            </div>
            {inputVisible && 
                <Input
                    type="text"
                    size="small"
                    style={{ width: 78 }}
                    value={inputValue}
                    onChange={handleInputChange}
                    onBlur={handleInputConfirm}
                    onPressEnter={handleInputConfirm}/>
            }
            {!inputVisible && 
                <Tag onClick={showInput} className="site-tag-plus">
                    <PlusOutlined /> New Tag
                </Tag>
            }
        </>
    )
})

Tags.displayName = 'Tags'

Tags.propTypes = {
    tagNames: PropTypes.array
}

export default Tags

 


版权声明:本文为qq_34870529原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。