• Select 选择器

    下拉选择器。

    何时使用

    代码演示

    基本使用。
    expand code expand code
    import { Select } from 'choerodon-ui';
    const Option = Select.Option;
    
    function handleChange(value) {
      console.log(`selected ${value}`);
    }
    
    ReactDOM.render(
      <div>
        <Select label="Select" placeholder="Please Select" allowClear style={{ width: 200 }} onChange={handleChange}>
          <Option value="jack">Jack</Option>
          <Option value="lucy">Lucy</Option>
          <Option value="disabled" disabled>Disabled</Option>
          <Option value="Yiminghe">yiminghe</Option>
        </Select>
        <Select defaultValue="lucy" style={{ width: 200 }} allowClear disabled>
          <Option value="lucy">Lucy</Option>
        </Select>
      </div>,
      mountNode);
    
    展开后可对选项进行搜索。
    expand code expand code
    import { Select } from 'choerodon-ui';
    const Option = Select.Option;
    
    ReactDOM.render(
      <Select
        style={{ width: 300 }}
        placeholder="Select a person"
        optionFilterProp="children"
        filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
        filter
      >
        <Option value="jack">Jack</Option>
        <Option value="lucy">Lucy</Option>
        <Option value="tom">Tom</Option>
      </Select>,
      mountNode);
    
    tags select,随意输入的内容(scroll the menu)
    expand code expand code
    import { Select } from 'choerodon-ui';
    import classNames from 'classnames';
    
    const Option = Select.Option;
    
    const children = [];
    for (let i = 10; i < 36; i++) {
      children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
    }
    
    function handleChange(value) {
      console.log(`selected ${value}`);
    }
    
    function handleRender(liNode, value) {
      console.log(value);
      return React.cloneElement(liNode, {
        className: classNames(liNode.props.className, 'choice-render'),
      });
    }
    
    ReactDOM.render(
      <Select
        mode="tags"
        style={{ width: '100%' }}
        label="标签用例"
        placeholder="tags"
        onChange={handleChange}
        choiceRender={handleRender}
        allowClear
      >
        {children}
      </Select>,
      mountNode);
    
    OptGroup 进行选项分组。
    expand code expand code
    import { Select } from 'choerodon-ui';
    const { Option, OptGroup } = Select;
    
    function handleChange(value) {
      console.log(`selected ${value}`);
    }
    
    ReactDOM.render(
      <Select
        defaultValue="lucy"
        style={{ width: 200 }}
        onChange={handleChange}
      >
        <OptGroup label="Manager">
          <Option value="jack">Jack</Option>
          <Option value="lucy">Lucy</Option>
        </OptGroup>
        <OptGroup label="Engineer">
          <Option value="Yiminghe">yiminghe</Option>
        </OptGroup>
      </Select>,
      mountNode);
    
    自动补全和远程数据结合。
    expand code expand code
    import { Select } from 'choerodon-ui';
    import jsonp from 'fetch-jsonp';
    import querystring from 'querystring';
    const Option = Select.Option;
    
    let timeout;
    let currentValue;
    
    function fetch(value, callback) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      currentValue = value;
    
      function fake() {
        const str = querystring.encode({
          code: 'utf-8',
          q: value,
        });
        jsonp(`https://suggest.taobao.com/sug?${str}`)
          .then(response => response.json())
          .then((d) => {
            if (currentValue === value) {
              const result = d.result;
              const data = [];
              result.forEach((r) => {
                data.push({
                  value: r[0],
                  text: r[0],
                });
              });
              callback(data);
            }
          });
      }
    
      timeout = setTimeout(fake, 300);
    }
    
    class SearchInput extends React.Component {
      state = {
        data: [],
        value: '',
      }
    
      handleChange = (value) => {
        this.setState({ value });
        fetch(value, data => this.setState({ data }));
      }
    
      render() {
        const options = this.state.data.map(d => <Option key={d.value}>{d.text}</Option>);
        return (
          <Select
            mode="combobox"
            value={this.state.value}
            placeholder={this.props.placeholder}
            style={this.props.style}
            defaultActiveFirstOption={false}
            showArrow={false}
            filterOption={false}
            onChange={this.handleChange}
          >
            {options}
          </Select>
        );
      }
    }
    
    ReactDOM.render(
      <SearchInput placeholder="input search text" style={{ width: 200 }} />,
      mountNode);
    
    试下复制 露西,杰克 到输入框里。只在 tags 和 multiple 模式下可用。
    expand code expand code
    import { Select } from 'choerodon-ui';
    const Option = Select.Option;
    
    const children = [];
    for (let i = 10; i < 36; i++) {
      children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
    }
    
    function handleChange(value) {
      console.log(`selected ${value}`);
    }
    
    ReactDOM.render(
      <Select
        mode="tags"
        style={{ width: '100%' }}
        onChange={handleChange}
        tokenSeparators={[',']}
      >
        {children}
      </Select>,
      mountNode);
    
    三种大小的选择框,当 size 分别为 largesmall 时,输入框高度为 40px24px ,默认高度为 32px
    expand code expand code
    import { Select, Radio } from 'choerodon-ui';
    const Option = Select.Option;
    
    const children = [];
    for (let i = 10; i < 36; i++) {
      children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
    }
    
    function handleChange(value) {
      console.log(`Selected: ${value}`);
    }
    
    class SelectSizesDemo extends React.Component {
      state = {
        size: 'default',
      };
    
      handleSizeChange = (e) => {
        this.setState({ size: e.target.value });
      }
    
      render() {
        const { size } = this.state;
        return (
          <div>
            <Radio.Group value={size} onChange={this.handleSizeChange}>
              <Radio.Button value="large">Large</Radio.Button>
              <Radio.Button value="default">Default</Radio.Button>
              <Radio.Button value="small">Small</Radio.Button>
            </Radio.Group>
            <br /><br />
            <Select
              size={size}
              defaultValue="a1"
              onChange={handleChange}
              style={{ width: 200 }}
            >
              {children}
            </Select>
            <br />
            <Select
              mode="combobox"
              size={size}
              defaultValue="a1"
              onChange={handleChange}
              style={{ width: 200 }}
            >
              {children}
            </Select>
            <br />
            <Select
              mode="multiple"
              size={size}
              placeholder="Please select"
              defaultValue={['a10', 'c12']}
              onChange={handleChange}
              style={{ width: '100%' }}
            >
              {children}
            </Select>
            <br />
            <Select
              mode="tags"
              size={size}
              placeholder="Please select"
              defaultValue={['a10', 'c12']}
              onChange={handleChange}
              style={{ width: '100%' }}
            >
              {children}
            </Select>
          </div>
        );
      }
    }
    
    ReactDOM.render(<SelectSizesDemo />, mountNode);
    
    多选,从已有条目中选择(scroll the menu)
    expand code expand code
    import { Select, Button } from 'choerodon-ui';
    const Option = Select.Option;
    
    const children = [];
    for (let i = 10; i < 36; i++) {
      children.push(<Option key={i}>{i.toString(36) + i}</Option>);
    }
    
    class SelectMulitpleDemo extends React.Component {
      state = {
        loading: true,
        options: [],
      }
    
      componentDidMount() {
        this.getOptions();
      }
    
      getOptions = () => {
        setTimeout(() => {
          this.setState({
            options: children,
            loading: false,
          });
        }, 3000);
      }
    
      handleChoiceRemove = (value) => {
        return value >= 15;
      }
    
      render() {
        const { options, loading } = this.state;
        return (
          <Select
            mode="multiple"
            style={{ width: '100%' }}
            label="多选用例"
            optionFilterProp="children"
            footer={<Button funcType="raised" type="primary">这里是footer</Button>}
            loading={loading}
            choiceRemove={this.handleChoiceRemove}
            filter
            allowClear
          >
            {options}
          </Select>
        );
      }
    }
    
    ReactDOM.render(<SelectMulitpleDemo />, mountNode);
    

    输入框自动完成功能,下面是一个账号注册表单的例子。

    推荐使用 AutoComplete 组件。

    expand code expand code
    import { Select } from 'choerodon-ui';
    const Option = Select.Option;
    
    class App extends React.Component {
      state = {
        options: [],
      }
    
      handleChange = (value) => {
        let options;
        if (!value || value.indexOf('@') >= 0) {
          options = [];
        } else {
          options = ['gmail.com', '163.com', 'qq.com'].map((domain) => {
            const email = `${value}@${domain}`;
            return <Option key={email}>{email}</Option>;
          });
        }
        this.setState({ options });
      }
    
      render() {
        // filterOption needs to be false,as the value is dynamically generated
        return (
          <Select
            mode="combobox"
            style={{ width: 200 }}
            onChange={this.handleChange}
            filterOption={false}
            placeholder="Enter the account name"
          >
            {this.state.options}
          </Select>
        );
      }
    }
    
    ReactDOM.render(<App />, mountNode);
    

    省市联动是典型的例子。

    推荐使用 Cascader 组件。

    expand code expand code
    import { Select } from 'choerodon-ui';
    const Option = Select.Option;
    
    const provinceData = ['Zhejiang', 'Jiangsu'];
    const cityData = {
      Zhejiang: ['Hangzhou', 'Ningbo', 'Wenzhou'],
      Jiangsu: ['Nanjing', 'Suzhou', 'Zhenjiang'],
    };
    
    class App extends React.Component {
      state = {
        cities: cityData[provinceData[0]],
        secondCity: cityData[provinceData[0]][0],
      }
    
      handleProvinceChange = (value) => {
        this.setState({
          cities: cityData[value],
          secondCity: cityData[value][0],
        });
      }
    
      onSecondCityChange = (value) => {
        this.setState({
          secondCity: value,
        });
      }
    
      render() {
        const provinceOptions = provinceData.map(province => <Option key={province}>{province}</Option>);
        const cityOptions = this.state.cities.map(city => <Option key={city}>{city}</Option>);
        return (
          <div>
            <Select defaultValue={provinceData[0]} style={{ width: 90 }} onChange={this.handleProvinceChange}>
              {provinceOptions}
            </Select>
            <Select value={this.state.secondCity} style={{ width: 90 }} onChange={this.onSecondCityChange}>
              {cityOptions}
            </Select>
          </div>
        );
      }
    }
    
    ReactDOM.render(<App />, mountNode);
    

    默认情况下 onChange 里只能拿到 value,如果需要拿到选中的节点文本 label,可以使用 labelInValue 属性。

    选中项的 label 会被包装到 value 中传递给 onChange 等函数,此时 value 是一个对象。

    expand code expand code
    import { Select } from 'choerodon-ui';
    const Option = Select.Option;
    
    function handleChange(value) {
      console.log(value); // { key: "lucy", label: "Lucy (101)" }
    }
    
    ReactDOM.render(
      <Select labelInValue defaultValue={{ key: 'lucy' }} style={{ width: 120 }} onChange={handleChange}>
        <Option value="jack">Jack (100)</Option>
        <Option value="lucy">Lucy (101)</Option>
      </Select>,
      mountNode);
    
    图标下拉框。
    expand code expand code
    import { IconSelect } from 'choerodon-ui';
    
    ReactDOM.render(
      <IconSelect style={{ width: '300px' }} defaultValue={['root']} />,
      mountNode);
    

    API

    <Select>
      <Option value="lucy">lucy</Option>
    </Select>
    

    Select props

    参数 说明 类型 默认值
    allowClear 支持清除 boolean false
    autoFocus 默认获取焦点 boolean false
    combobox 输入框自动提示模式(2.9 之后废弃,请使用 mode boolean false
    defaultActiveFirstOption 是否默认高亮第一个选项。 boolean true
    defaultValue 指定默认选中的条目 string|string[]|number|number[] -
    disabled 是否禁用 boolean false
    dropdownClassName 下拉菜单的 className 属性 string -
    dropdownMatchSelectWidth 下拉菜单和选择器同宽 boolean true
    dropdownStyle 下拉菜单的 style 属性 object -
    filterOption 是否根据输入项进行筛选。当其为一个函数时,会接收 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 false boolean or function(inputValue, option) true
    firstActiveValue 默认高亮的选项 string|string[] -
    getPopupContainer 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。示例 Function(triggerNode) () => document.body
    labelInValue 是否把每个选项的 label 包装到 value 中,会把 Select 的 value 类型从 string 变为 {key: string, label: ReactNode} 的格式 boolean false
    maxTagCount 最多显示多少个 tag number -
    maxTagPlaceholder 隐藏 tag 时显示的内容 ReactNode/function(omittedValues) -
    mode 设置 Select 的模式(2.9 之后支持) ‘multiple’ | ‘tags’ | ‘combobox’ -
    multiple 支持多选(2.9 之后废弃,请使用 mode boolean false
    notFoundContent 当下拉列表为空时显示的内容 string ‘Not Found’
    optionFilterProp 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索 string value
    optionLabelProp 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 value string children (combobox 模式下为 value
    placeholder 选择框默认文字 string -
    showArrow 是否显示下拉小箭头 boolean true
    size 选择框大小,可选 large small string default
    tags 可以把随意输入的条目作为 tag,输入项不需要与下拉选项匹配(2.9 之后废弃,请使用 mode boolean false
    tokenSeparators 在 tags 和 multiple 模式下自动分词的分隔符 string[]
    value 指定当前选中的条目 string|string[]|number|number[] -
    onBlur 失去焦点的时回调 function -
    onChange 选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数 function(value, option:Option/Array) -
    onDeselect 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 function(value,option:Option) -
    onFocus 获得焦点时回调 function -
    onMouseEnter 鼠标移入时回调 function -
    onMouseLeave 鼠标移出时回调 function -
    onPopupScroll 下拉列表滚动时的回调 function -
    onSearch 文本框值变化时回调 function(value: string)
    onSelect 被选中时调用,参数为选中项的 value (或 key) 值 function(value, option:Option) -
    showCheckAll 是否显示下拉菜单的全选按钮 boolean true
    footer 下拉菜单底部内容 string| ReactNode -
    choiceRender 仅适用于tags 函数返回值为 Select value展示内容 function(liDom, value) -
    filter 下拉框顶部查询框 boolean false
    filterValue 下拉框顶部查询框值 string -
    onFilterChange 下拉框顶部查询框值改变回调 function(value) -
    loading 数据是否加载中 boolean|object ([更多]
    choiceRemove 仅适用于tags multiple 是否可以直接删除value boolean | function(value) true | (value) => true
    onChoiceRemove 仅适用于tags multiple 删除每一个值的回调 function(value) -

    注意,如果发现下拉菜单跟随页面滚动,或者需要在其他弹层中触发 Select,请尝试使用 getPopupContainer={triggerNode => triggerNode.parentNode} 将下拉弹层渲染节点固定在触发器的父元素中。

    Select Methods

    名称 说明
    blur() 取消焦点
    focus() 获取焦点

    Option props

    参数 说明 类型 默认值
    disabled 是否禁用 boolean false
    key 和 value 含义一致。如果 React 需要你设置此项,此项值与 value 的值相同,然后可以省略 value 设置 string
    title 选中该 Option 后,Select 的 title string -
    value 默认根据此属性值进行筛选 string|number -

    OptGroup props

    参数 说明 类型 默认值
    key string -
    label 组名 string|React.Element