组件规范 前端代码

Select 选择器

API#

Select#

属性说明类型默认值
sizesmall,medium(default),largeStringmedium
shapenormal,arrow-onlyStringnormal
placeholder没有值的时候的占位符StringPlease Select
value当前值String,Array,Numbernull
defaultValue初始默认值String,Array,Numbernull
visible当前弹层是否显示Booleanfalse
defaultVisible弹层初始是否显示Booleanfalse
disabled是否禁用Booleanfalse
dataSource传入的数据,可以动态渲染子项,详见dataSourceArraynull
multiple是否是多选Booleanfalse
fillProps填充到选择框里面的值Stringlabel
showSearch是否显示顶部的搜索框Booleanfalse
filterBy在输入的时候过滤的函数,仅在filterLocal为true时候有效Function(filterValue, item):BooleanfilterBy
filterLocal是否使用本地过滤,在数据源为远程的时候需要关闭此选项Booleantrue
hasArrow是否显示右侧的箭头Booleantrue
autoWidth下拉菜单是否与选择器对齐Booleantrue
onChangeSelect发生改变的时候触发的回调Function(value, data)noop
onSearch在搜索框中输入触发的事件,仅在showSearch为true时候有效Function(value)noop

Select.OptionGroup#

属性说明类型默认值
label设置分组的文案String, ReactElement''

Select.Combobox#

属性说明类型默认值
sizesmall,medium(default),largeStringmedium
shapenormal,arrow-onlyStringnormal
placeholder没有值的时候的占位符StringPlease input
value当前值String,Array,Numbernull
defaultValue初始默认值String,Array,Numbernull
visible当前弹层是否显示Booleanfalse
defaultVisible弹层初始是否显示Booleanfalse
disabled是否禁用Booleanfalse
dataSource传入的数据,可以动态渲染子项, 详见dataSourceArraynull
multiple是否是多选Booleanfalse
tags是否启用标签模式, 仅在多选时有效,效果是除了自动提示外的选项, 也可以使用输入的文字作为标签Booleanfalse
fillProps填充到选择框里面的值Stringvalue
hasArrow是否显示右侧的箭头Booleantrue
autoWidth下拉菜单是否与选择器对齐Booleantrue
hiddenSelected选择后是否立即隐藏菜单,单选是默认隐藏的,因此该选项只在多选的时候有效Booleanfalse
filterBy在输入的时候过滤的函数,仅在filterLocal为true时候有效Function(filterValue, item):BooleanfilterBy
filterLocal是否使用本地过滤,在数据源为远程的时候需要关闭此选项Booleantrue
onChangeCombobox发生改变的时候触发的回调, 注意在输入的时候该事件不会被触发,如果需要监听输入的事件请使用onInputUpdateFunction(value, item)noop
onInputUpdateCombobox在用户输入的时候触发的回调Function(value)noop
onInputFocusCombobox获取焦点的时候触发的回调Function(e, clickByUser:Boolean)noop
onInputBlurCombobox失去焦点的时候触发的回调Function(e)noop
onInputEnterCombobox回车的时候触发的回调Function(e)noop

dataSource#

Select同时支持children和在props中传入dataSource作为数据源,如果同时设置,则以children为准.

  1. children的方式
<Select>
    <Select.Option value="option1">option1</Select.Option>
    <Select.Option value="option2">option2</Select.Option>
    <Select.Option disabled>disabled</Select.Option>
</Select>
  1. props的方式
const dataSource = [
    {label:'option1', value:'option1},
    {label:'option2', value:'option2'},
    {label:'disabled', disabled:true}
]
<Select dataSource={dataSource}/>
`

ARIA and KeyBoard.#

Select#

按键说明
tab在可以被聚焦的select之间导航
enter: select弹出下拉菜单
upArrow向上导航到一个MenuItem
downArrow向下导航到一个MenuItem
enter: menuItem选中当前的MenuItem

Select.Combobox#

按键说明
tab在可以被聚焦的combobox之间导航
enter选中当前的MenuItem
upArrow向上导航到一个MenuItem
downArrow向下导航到一个MenuItem

代码演示

import Select, {Option} from 'blue/lib/select';
import Button from 'blue/lib/button';
import 'blue/lib/select/index.scss';
import 'blue/lib/button/index.scss';

class App extends React.Component{

    constructor(props) {
        super(props);
        this.state = {
            value : 'small'
        };
    }

    render() {
        return (
            <Select placeholder="选择尺寸" onChange={this.onSelect.bind(this)} value={this.state.value}>
                <Option value="small">Small</Option>
                <Option value="medium">Medium</Option>
                <Option value="large">Large</Option>
            </Select>
        );
    }
    onSelect(value){
        this.setState({
            value
        });
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{
    margin-right:10px;
    vertical-align: middle;
}

演示了Select的control功能

import Select from 'blue/lib/select';
import 'blue/lib/select/index.scss';

const provinceData = ['浙江', '江苏'];
const cityData = {
  浙江: ['杭州', '宁波', '温州'],
  江苏: ['南京', '苏州', '镇江']
};

class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
          data: [],
          disabled: true
        };
    }
    render(){
        return (<span>
                <Select placeholder="选择省份" dataSource={provinceData} value={this.state.province} onChange={this.onSelect.bind(this)} />
                <Select placeholder="选择城市" dataSource={this.state.data} value={this.state.city} onChange={this.onChange.bind(this)} disabled={this.state.disabled}/>
                </span>)
    }
    onSelect(value){
        let data = cityData[value];
        this.setState({data, province: value, disabled: false});
    }
    onChange(value){
        this.setState({city: value});
        console.log(this.state.province, value);
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{margin-right:10px;}

使用Select构建级联选择框.

import Select, {Combobox} from 'blue/lib/select';
import 'blue/lib/select/index.scss';
import Button from 'blue/lib/button';
import 'blue/lib/button/index.scss';
import jsonp from 'jsonp';
import Icon from 'blue/lib/icon';

const onChange = function(...args){
    console.log(args);
}

class App extends React.Component{

    state = {
        dataSource: []
    }

    render() {
        return (
                <Combobox onInputUpdate={this.onInputUpdate.bind(this)}
                          filterLocal={false}
                          fillProps = 'label'
                          placeholder = '请输入淘宝商品'
                          onChange = {onChange}
                          dataSource = {this.state.dataSource}/>
        );
    }
    onInputUpdate(value){
        if(this.searchTimeout){
            clearTimeout(this.searchTimeout);
        }
        this.searchTimeout = setTimeout(() => {
            jsonp(`https://suggest.taobao.com/sug?code=utf-8&q=${value}`, (err, data) => {
                const dataSource = data.result.map(item => {
                    return {
                        label: item[0],
                        value: item[1]
                    }
                });
                this.setState({
                    dataSource
                })
            });
        },100);
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{
    margin-right:10px;
    vertical-align: middle;
}

使用动态数据填充Combobox, 设置filterLocal为false

import Select, {Combobox} from 'blue/lib/select';
import 'blue/lib/select/index.scss';
import Button from 'blue/lib/button';
import 'blue/lib/button/index.scss';
import jsonp from 'jsonp';
import Icon from 'blue/lib/icon';

const onChange = function(...args){
    console.log(args);
}

const formatter = function(item){
    return <div><Icon type="gifts" size="small"/>&nbsp;{item}</div>
}

class App extends React.Component{

    state = {
        dataSource: []
    }
    // 由于这个时候展示的是富文本,所以fillProps需要设置成展示合理的值(originLabel)
    render() {
        return (
                <Combobox onInputUpdate={this.onInputUpdate.bind(this)}
                          filterLocal={false}
                          fillProps = 'originLabel'
                          placeholder = '请输入淘宝商品'
                          onChange = {onChange}
                          dataSource = {this.state.dataSource}/>
        );
    }
    onInputUpdate(value){
        if(this.searchTimeout){
            clearTimeout(this.searchTimeout);
        }
        this.searchTimeout = setTimeout(() => {
            jsonp(`https://suggest.taobao.com/sug?code=utf-8&q=${value}`, (err, data) => {
                const dataSource = data.result.map(item => {
                    return {
                        label: formatter(item[0]),
                        value: item[1],
                        originLabel: item[0]
                    }
                });
                this.setState({
                    dataSource
                })
            });
        },100);
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{
    margin-right:10px;
    vertical-align: middle;
}

展示较为复杂的内容

import {Combobox} from 'blue/lib/select';
import 'blue/lib/select/index.scss';
import Button from 'blue/lib/button';
import 'blue/lib/button/index.scss';

class App extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            dataSource: [{
                value:'测试',
                label:'测试',
                time: 123
            }],
            value: '测试',
            visible: false
        }
    }
    render(){
        return (
            <div>
                <p>
                    <Button onClick={this.toggleTags.bind(this)}>切换tags模式</Button>&nbsp;
                    <Button onClick={this.toggleHiddenSelect.bind(this)}>切换在多选的时候是否隐藏菜单</Button>&nbsp;
                    <Button onClick={this.toggleVisible.bind(this)} ref="visibleElement">切换显示</Button>&nbsp;
                </p>
                <Combobox size="large"
                    value = {this.state.value}
                    dataSource={this.state.dataSource}
                    onChange={this.onChange.bind(this)}
                    onInputUpdate ={this.onInputUpdate.bind(this)}
                    multiple
                    tags = {this.state.tags}
                    filterLocal = {false}
                    safeNode = {() => this.refs.visibleElement}
                    visible = {this.state.visible}
                    onVisibleChange = {this.onVisibleChange.bind(this)}
                    hiddenSelected = {this.state.hiddenSelected}
                    />
            </div>
        )
    }
    onInputUpdate(value){
        let options;
        if(!value || value.indexOf('@') > 0){
            options = [];
        }else{
            options = ['126.com','163.com','gmail.com'].map(mail => {
                return {
                    label: value + '@'+ mail,
                    value: value + '@'+ mail,
                    time: Math.random()
                }
            });
        }
        this.setState({dataSource: options});
    }

    onChange(value, item){
        this.setState({value});
        console.log(item);
    }
    toggleTags(){
        this.setState({tags: !this.state.tags});
    }
    toggleHiddenSelect(){
       this.setState({hiddenSelected: !this.state.hiddenSelected});
    }
    toggleVisible(){
        this.setState({visible: !this.state.visible});
    }
    onVisibleChange(visible){
        this.setState({visible});
    }

}
ReactDOM.render(<App/>, mountNode);

演示combobox的tags功能

import Select, {Option} from 'blue/lib/select';
import Button from 'blue/lib/button';
import 'blue/lib/select/index.scss';
import 'blue/lib/button/index.scss';

const onChange = function(...args){
    console.log(args);
}

class App extends React.Component{

    constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        return (
            <div>
                <p>
                    <Select placeholder="选择尺寸" onChange={this.onSelect.bind(this,'size')}>
                        <Option value="small">Small</Option>
                        <Option value="medium">Medium</Option>
                        <Option value="large">Large</Option>
                    </Select>
                    <Select placeholder="选择模式" onChange={this.onSelect.bind(this,'mode')}>
                        <Option value="single">单选</Option>
                        <Option value="multiple">多选</Option>
                    </Select>
                    <Select placeholder="显示搜索框" onChange={this.onSelect.bind(this,'search')}>
                        <Option value="no">不显示</Option>
                        <Option value="yes">显示</Option>
                    </Select>
                    <Select placeholder="选择形状" onChange={this.onSelect.bind(this,'shape')}>
                        <Option value="normal">常规</Option>
                        <Option value="arrow-only">无边框</Option>
                    </Select>
                    <Select placeholder="显示箭头" onChange={this.onSelect.bind(this,'hasArrow')}>
                        <Option value="yes">常规</Option>
                        <Option value="no">无下拉箭头</Option>
                    </Select>
                    <Button onClick={this.onToggle.bind(this)} type="primary">Toggle disabled</Button>
                </p>
                <h4>效果预览</h4>
                <Select 
                    size={this.state.size}
                    multiple={this.state.mode}
                    showSearch={this.state.search}
                    shape={this.state.shape}
                    hasArrow={this.state.hasArrow}
                    disabled={this.state.disabled}
                    onChange={onChange}
                >   
                    <Option value=""></Option>
                    <Option value="jack">Jack</Option>
                    <Option value="lucy">Lucy</Option>
                    <Option value="andy">Andy</Option>
                    <Option value="disabled" disabled>Disabled</Option>
                </Select>
            </div>
        );
    }
    onToggle(){
        this.setState({
            disabled: !this.state.disabled
        })
    }
    onSelect(type, value){
        switch(type){
            case 'mode':
                this.setState({
                    [type]: value == 'multiple'
                })
            break;
            case 'search':
            case 'hasArrow':
                this.setState({
                    [type]: value == 'yes'
                })
            break;
            default:
                this.setState({
                    [type]: value
                })
        }
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{
    margin-right:10px;
    vertical-align: middle;
}

演示了Select的多种形态.

import Select, {Option, OptionGroup} from 'blue/lib/select';
import Button from 'blue/lib/button';
import 'blue/lib/select/index.scss';

const dataSource = [{ 
    label: '文案1', 
    children:[{
        label:'文案11', 
        value:'text11'
    }]
    },{
    label:'文案2',
    children:[{
        label:'文案22',
        value:'text22'
    }]
}]

ReactDOM.render(<div><Select placeholder="选择尺寸" showSearch>
    <OptionGroup label="尺寸1">
        <Option value="small">Small</Option>
        <Option value="medium">Medium</Option>
        <Option value="large">Large</Option>
    </OptionGroup>
    <OptionGroup label="尺寸2">
        <Option value="small2">Small2</Option>
        <Option value="medium2">Medium2</Option>
        <Option value="large2">Large2</Option>
    </OptionGroup>

</Select><Select dataSource={dataSource}></Select></div>, mountNode);
.next-select{margin-right:10px;}

使用OptionGroup针对选项进行分组

import Select, {Combobox} from 'blue/lib/select';
import 'blue/lib/select/index.scss';
import Button from 'blue/lib/button';
import 'blue/lib/button/index.scss';

const onChange = function(...args){
    console.log(args);
}

class App extends React.Component{

    constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        return (
            <div>
                <p>
                    <Select placeholder="选择尺寸" onChange={this.onSelect.bind(this,'size')}>
                        <Option value="small">Small</Option>
                        <Option value="medium">Medium</Option>
                        <Option value="large">Large</Option>
                    </Select>
                    <Select placeholder="选择模式" onChange={this.onSelect.bind(this,'mode')}>
                        <Option value="single">单选</Option>
                        <Option value="multiple">多选</Option>
                    </Select>
                    <Select placeholder="显示箭头" onChange={this.onSelect.bind(this,'hasArrow')}>
                        <Option value="yes">常规</Option>
                        <Option value="no">无下拉箭头</Option>
                    </Select>
                    <Select placeholder="填充属性" onChange={this.onSelect.bind(this,'fillProps')}>
                        <Option value="value">value</Option>
                        <Option value="label">label</Option>
                    </Select>
                    <Button onClick={this.onToggle.bind(this)} type="primary">Toggle disabled</Button>
                </p>
                <h4>效果预览</h4>
                <Combobox
                    size={this.state.size}
                    multiple={this.state.mode}
                    hasArrow={this.state.hasArrow}
                    disabled={this.state.disabled}
                    fillProps={this.state.fillProps}
                    onChange={onChange}
                    onInputUpdate={this.onInputUpdate.bind(this)}
                >   
                    <Option value=""></Option>
                    <Option value="jack">Jack</Option>
                    <Option value="lucy">Lucy</Option>
                    <Option value="andy">Andy</Option>
                    <Option value="disabled" disabled>Disabled</Option>
                </Combobox>
            </div>
        );
    }
    onToggle(){
        this.setState({
            disabled: !this.state.disabled
        })
    }
    onSelect(type, value){
        switch(type){
            case 'mode':
                this.setState({
                    [type]: value == 'multiple'
                })
            break;
            case 'search':
            case 'hasArrow':
                this.setState({
                    [type]: value == 'yes'
                })
            break;
            default:
                this.setState({
                    [type]: value
                })
        }
    }
    onInputUpdate(value){
        console.log(value);
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{
    margin-right:10px;
    vertical-align: middle;
}

演示了Combobox的多种形态.

import Select, {Combobox} from 'blue/lib/select';
import 'blue/lib/select/index.scss';
import Button from 'blue/lib/button';
import 'blue/lib/button/index.scss';
import jsonp from 'jsonp';
import Icon from 'blue/lib/icon';


class App extends React.Component{

    state = {
        dataSource: [],
        value: 'test'
    }
    render() {
        return (
                <Combobox onInputUpdate={this.onInputUpdate.bind(this)}
                          filterLocal={false}
                          value = {this.state.value}
                          fillProps = 'label'
                          placeholder = '请输入淘宝商品'
                          onChange = {this.onChange.bind(this)}
                          dataSource = {this.state.dataSource}/>
        );
    }

    onInputUpdate(value){
        if(this.searchTimeout){
            clearTimeout(this.searchTimeout);
        }
        this.searchTimeout = setTimeout(() => {
            jsonp(`https://suggest.taobao.com/sug?code=utf-8&q=${value}`, (err, data) => {
                const dataSource = data.result.map(item => {
                    return {
                        label: item[0],
                        value: item[1],
                    }
                });
                this.setState({
                    dataSource
                })
            });
        },100);
        //单选情况下需要更新input的值
        this.setState({
            value
        })
    }
    onChange(value){
        this.setState({
            value
        })
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{
    margin-right:10px;
    vertical-align: middle;
}

演示Combobox的受控状态

import Select, {Combobox} from 'blue/lib/select';
import 'blue/lib/select/index.scss';
import Button from 'blue/lib/button';
import 'blue/lib/button/index.scss';
import jsonp from 'jsonp';
import Icon from 'blue/lib/icon';


class App extends React.Component{

    state = {
        dataSource: [],
        value: 'test'
    }
    render() {
        return (
                <Combobox onInputUpdate={this.onInputUpdate.bind(this)}
                          filterLocal={false}
                          value = {this.state.value}
                          fillProps = 'label'
                          multiple 
                          placeholder = '请输入淘宝商品'
                          onChange = {this.onChange.bind(this)}
                          dataSource = {this.state.dataSource}/>
        );
    }
    //多选情况下不需要更新input的值
    onInputUpdate(value){
        if(this.searchTimeout){
            clearTimeout(this.searchTimeout);
        }
        this.searchTimeout = setTimeout(() => {
            jsonp(`https://suggest.taobao.com/sug?code=utf-8&q=${value}`, (err, data) => {
                const dataSource = data.result.map(item => {
                    return {
                        label: item[0],
                        value: item[1],
                    }
                });
                this.setState({
                    dataSource
                })
            });
        },100);
    }
    onChange(value){
        this.setState({
            value
        })
    }
}
ReactDOM.render(<App/>, mountNode);
.next-select{
    margin-right:10px;
    vertical-align: middle;
}

演示多选情况下Combobox的受控状态