重构-下拉框

动画:
	选择按钮旋转
	下拉框伸缩
	边框、图标、选项hover变色

参数:
	placeholder:PropTypes.string,	 预展示内容,不写则默认展示传入的list数组第一条内容
    selectWidth:PropTypes.string,	 展示框的宽度
    fontSize:PropTypes.string,		 展示框内的字体大小
    selectHeight:PropTypes.string,	 展示框的高度
    borderColor:PropTypes.string,	 展示框的边框色
    hoverBoderColor:PropTypes.string,展示框hover时的边框色
    borderRadius:PropTypes.string,	 展示框的圆角
    iconWidth:PropTypes.string,		 图标的宽度
    iconSize:PropTypes.string,		 图标的大小
    padding:PropTypes.string,		 展示框内的内容距离左边的距离
    selectListHeight:PropTypes.string,     下拉框的高度
    selectListRadius:PropTypes.string,	   下拉框的圆角
    selectListWidth:PropTypes.string,	   下拉框的宽度
    selectListLeft:PropTypes.string,	   下拉框距离左边的距离
    selectListBoderColor:PropTypes.string, 下拉框的边框色
    selectListFontSize:PropTypes.string,   下拉框的字体大小
    selectListPadding:PropTypes.string,	   下拉框的内容距离左边间距
    selectTriangleWidth:PropTypes.string,  下拉框上的三角的大小
    list:PropTypes.array,		下拉框展示的数组内容
    onSelect:PropTypes.func,	选择回调,第一个参数是内容,如果不传入placeholder,默认就会触发一次

效果图:
在这里插入图片描述代码示例:

使用:

import React,{Component} from 'react'
import Select from './select/select'

class App extends Component{

    _onSelect(item)
    {
        console.log(item);
    }

    render()
    {
        return(

            <div>
                <Select list={['a','b','c']} placeholder='请选择' onSelect={this._onSelect.bind(this)}></Select>
                <Select list={['a','b','c']} onSelect={this._onSelect.bind(this)}></Select>
                <Select list={['a','b','c']} placeholder='请选择' onSelect={this._onSelect.bind(this)} disabled></Select>
            </div>
        )
    }
}

export default App

select.jsx:

import React,{Component} from 'react'
import PropTypes from 'prop-types'
import './select.css'

class App extends Component{

    static propTypes={
        placeholder:PropTypes.string,
        selectWidth:PropTypes.string,
        fontSize:PropTypes.string,
        selectHeight:PropTypes.string,
        borderColor:PropTypes.string,
        hoverBoderColor:PropTypes.string,
        borderRadius:PropTypes.string,
        iconWidth:PropTypes.string,
        iconSize:PropTypes.string,
        padding:PropTypes.string,
        selectListHeight:PropTypes.string,
        selectListRadius:PropTypes.string,
        selectListWidth:PropTypes.string,
        selectListLeft:PropTypes.string,
        selectListBoderColor:PropTypes.string,
        selectListFontSize:PropTypes.string,
        selectTriangleWidth:PropTypes.string,
        selectListPadding:PropTypes.string,
        list:PropTypes.array,
        onSelect:PropTypes.func,
    }

    static defaultProps={
        list:[]
    }
    
    componentDidMount()
    {   const {list,placeholder,fontSize,selectWidth,selectHeight,borderColor,borderRadius,hoverBoderColor,iconWidth,iconSize,padding,
        selectListHeight,selectListRadius,selectListWidth,selectListLeft,selectListBoderColor,selectListFontSize,selectTriangleWidth,selectListPadding
        } = this.props;
        const selectf=this.selectf.style;

        (list.length)&&this.setState({
            selectList:list,
            inputValue:placeholder?'':list[0]
        },()=>{
            !placeholder&&this._filter(this.state.inputValue);
            !placeholder&&this._onSelected(this.state.inputValue,0);
            
        })

        selectWidth&&selectf.setProperty('--selectWidth',selectWidth);
        fontSize&&selectf.setProperty('--fontSize',fontSize);
        selectHeight&&selectf.setProperty('--selectHeight',selectHeight);
        borderColor&&selectf.setProperty('--borderColor',borderColor);
        borderRadius&&selectf.setProperty('--borderRadius',borderRadius);
        hoverBoderColor&&selectf.setProperty('--hoverBoderColor',hoverBoderColor);
        iconWidth&&selectf.setProperty('--iconWidth',iconWidth);
        iconSize&&selectf.setProperty('--iconSize',iconSize);
        padding&&selectf.setProperty('--padding',padding);
        selectListHeight&&selectf.setProperty('--selectListHeight',selectListHeight);
        selectListRadius&&selectf.setProperty('--selectListRadius',selectListRadius);
        selectListWidth&&selectf.setProperty('--selectListWidth',selectListWidth);
        selectListLeft&&selectf.setProperty('--selectListLeft',selectListLeft);
        selectListBoderColor&&selectf.setProperty('--selectListBoderColor',selectListBoderColor);
        selectListFontSize&&selectf.setProperty('--selectListFontSize',selectListFontSize);
        selectTriangleWidth&&selectf.setProperty('--selectTriangleWidth',selectTriangleWidth);
        selectListPadding&&selectf.setProperty('--selectListPadding',selectListPadding);

        
    }

    state={
        isChecked:false,
        inputValue:'',
        selectList:[],
    }

    _onChecked()
    {
        if(!this.props.disabled)
        {
            this.setState({
                isChecked:!this.state.isChecked
            })
        }
    }

    _onSelected(item)
    {
        this.setState({inputValue:item,isChecked:false});
        this._filter(item);
        this.props.onSelect(item);
    }

    _filter(name)
    {

        
        let arr=this.props.list.filter((item,index)=>{
            return name!=item
        })
        
        this.setState({
            selectList:arr
        });
    }

    render()
    {

        const {isChecked,inputValue,selectList} = this.state;
        const {disabled,placeholder}=this.props;
        
        return(

            <div className='jf-select-container' ref={(v)=>{this.selectf=v;}}>
                <input disabled={disabled} value={inputValue} placeholder={placeholder} className={`jf-select-inner ${!disabled&&'jf-select-inner-notDisabled'} ${disabled&&'jf-select-disabled'}`} type="text" readOnly/>
                <span  onClick={this._onChecked.bind(this)} className={`jf-select-inner-icon iconfont ${!disabled&&'jf-select-inner-icon-notDisabled'} ${disabled&&'jf-select-disabled'} icon-xiasanjiao ${isChecked&&'jf-select-inner-icon-selected'}`}></span>
                <div className={`jf-select-list-container ${isChecked?'jf-select-list-container-show':'jf-select-list-container-hide'} `}>
                    <div className='jf-select-list'>
                        <div className='jf-select-list-triangle'></div>
                        <ul className='jf-select-list-ul'>
                            {
                                selectList.map((item,index)=>{
                                    return <li onClick={()=>{this._onSelected(item)}} key={item+index}>{item}</li>
                                })
                            }
                        </ul>
                    </div>
                    
                </div>
            </div>
        )
    }
}

export default App

select.css:

.jf-select-container{
    width: var(--selectWidth);
    height:var(--selectHeight);
    display: inline-block;
    /* background-color: red; */
    box-sizing: border-box;
    margin-left: 5px;
    border-radius: var(--borderRadius);
    position: relative;

    --selectWidth:240px;
    --fontSize:16px;
    --selectHeight:40px;
    --borderColor:#ccc;
    --hoverBoderColor:#aaa;
    --borderRadius:5px;
    --cursor:pointer;
    --iconWidth:40px;
    --iconSize:16px;
    --padding:5%;
    --selectListHeight:200px;
    --selectListRadius:5px;
    /* --selectListWidth:240px; */
    /* --selectListPadding */
    --selectListLeft:0px;
    --selectListBoderColor:#ccc;
    --selectListFontSize:16px;
    --selectTriangleWidth:6px;
    

}

.jf-select-disabled{
    cursor: not-allowed !important;
    background-color: #F5F7FA;
}

.jf-select-inner{
    width: 100%;
    height: 100%;
    outline: none;
    box-sizing: border-box;
    border:solid 1px var(--borderColor);
    cursor: var(--cursor);
    border-radius: var(--borderRadius);
    padding-left: var(--padding);
    font-size: var(--fontSize);
    padding-right: var(--iconWidth);
    overflow: hidden;
    text-overflow: ellipsis;
}

.jf-select-inner-notDisabled:hover{
    border-color: var(--hoverBoderColor);
}



.jf-select-inner-icon{
    position: absolute;
    height: 90%;
    display:flex;
    justify-content: center;
    align-items: center;
    width:var(--iconWidth);
    margin: 0;
    top:50%;
    transform: translateY(-50%) rotate(0deg);
    right: 2px;
    color:var(--borderColor);
    cursor:var(--cursor);
    box-sizing: border-box;
    font-size: var(--iconSize);
    transition:transform .25s;
    z-index: 10;
}

.jf-select-inner-icon-selected{
    transform:translateY(-50%) rotate(-180deg);
}

.jf-select-inner-icon-notDisabled:hover{
    color:var(--hoverBoderColor);
}

.jf-select-list-container{
    position: absolute;
    box-sizing: border-box;
    width: var(--selectListWidth,var(--selectWidth));
    height:0;
    opacity: 0;
    top: 110%;
    left:var(--selectListLeft);
    margin: 0;
    display: flex;
    transition: height .5s,opacity .5s;
}
.jf-select-list-container-show{
    height: var(--selectListHeight);
    opacity: 1;
}

.jf-select-list{
    width: 100%;
    height: 100%;
    position: relative;
    display: flex;
}

.jf-select-list-triangle{
    position: absolute;
    top:0;
    left:var(--padding) ;
    height: 0;
    width: 0;

    border-top-width: 0px;
    border-right-width:var(--selectTriangleWidth,6px);
    border-bottom-width: var(--selectTriangleWidth,6px);
    border-left-width:var(--selectTriangleWidth,6px);
    border-style: solid;
    border-left-color: transparent;
    border-right-color: transparent;
    border-top-color: transparent;
    border-bottom-color:var(--selectListBoderColor);
    
}
.jf-select-list-triangle::after{
    content: '';
    position: absolute;
    left: 0;
    top: 1px;
    margin-left: calc(-1 * var(--selectTriangleWidth,6px));
    border-top-width: 0px;
    border-right-width:var(--selectTriangleWidth,6px);
    border-bottom-width: var(--selectTriangleWidth,6px);
    border-left-width:var(--selectTriangleWidth,6px);
    border-style: solid;
    border-left-color: transparent;
    border-right-color: transparent;
    border-top-color: #ccc;
    border-bottom-color: white;

}

.jf-select-list-ul{
    width: 100%;
    /* height: 100%; */
    padding-left: 0;
    box-sizing: border-box;
    border: solid 1px var(--selectListBoderColor);
    border-radius:var(--selectListRadius);
    margin-top: var(--selectTriangleWidth);
    margin-bottom: 0;
    overflow-y:scroll;
}


.jf-select-list-ul>li{
    list-style: none;
    padding-left:var(--selectListPadding,var(--padding));
    font-size:var(--selectListFontSize);
    text-overflow: ellipsis;
    overflow: hidden;
    cursor: pointer;
}

.jf-select-list-ul>li:hover{
    background-color: #F5F7FA;
}

.jf-select-list-ul::-webkit-scrollbar {
    width: 5px;
    background-color: transparent;
}
.jf-select-list-ul::-webkit-scrollbar-thumb {
    border-radius: 20px;
    background-color: #D0D0D1;
}
.jf-select-list-ul::-webkit-scrollbar-track {
    
    background-color: transparent;
    border-radius: 5px;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值