react封装通用tab组件
import React, { Component } from 'react' import PropTypes from 'prop-types' import _ from 'lodash' import classNames from 'classnames' import { CloseButton, } from '@dby-h5-clients/pc-1vn-components' import './index.less' class NormalTab extends Component { static propTypes = { style: PropTypes.object, tagIcon: PropTypes.element, name: PropTypes.string, onClick: PropTypes.func, closable: PropTypes.bool, onClose: PropTypes.func, isActive: PropTypes.bool, } static defaultProps = { style: {}, tagIcon: null, name: 'normal-tab', onClick: _.noop, closable: true, onClose: _.noop, isActive: false, } state = { tabInfoWrapWidth: 100, } componentDidMount() { const tabInfoWrapElem = this.normalTabWrapElemRef.current this.tabInfoWrapElem = tabInfoWrapElem this.resizeObserver = new ResizeObserver(_.throttle(() => { if (tabInfoWrapElem !== undefined) { this.setState({ tabInfoWrapWidth: tabInfoWrapElem.clientWidth, }) } }, 200)) this.resizeObserver.observe(tabInfoWrapElem) } componentWillUnmount() { this.resizeObserver.unobserve(this.tabInfoWrapElem) } resizeObserver normalTabWrapElemRef = React.createRef() tabInfoWrapElem render() { const closeBtnStyle = { height: '20px', width: '20px', flex: 'none', margin: 8, } const tabInfoWrapStyle = { // 当显示区域足够大或当前标签被选中的时候显示完整关闭按钮 flex: (this.state.tabInfoWrapWidth > 84 || this.props.isActive === true) ? 1 : 'none', } return ( <span className={classNames({ 'normal-tab-component-wrap': true, selected: this.props.isActive === true, })} ref={this.normalTabWrapElemRef} style={this.props.style} title={this.props.name} > <span className="normal-tab-info-wrap" tabIndex={0} role="button" style={tabInfoWrapStyle} onClick={this.props.onClick} > {this.props.tagIcon} {this.props.name} </span> { this.props.closable === true && ( <CloseButton style={closeBtnStyle} onClick={this.props.onClose} /> ) } </span> ) } } export default NormalTab
.normal-tab-component-wrap { min-width: 36px; height: 100%; display: flex; flex-direction: row; justify-content: flex-start; align-items: center; border-radius: 4px; background-color: rgba(54, 65, 82, 0.1);; margin-right: 1px; overflow: hidden; &:last-child { margin-right: 0px; } &:hover { background-color: #fff; } &.selected { background-color: #fff; min-width: 64px; .normal-tab-info-wrap { flex: 1; } } .normal-tab-info-wrap { height: 100%; max-width: 180px; display: flex; flex-direction: row; justify-content: flex-start; align-items: center; flex: none; font-size: 12px; color: #616e80; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; cursor: pointer; outline: none; } }