GrowingIO Design 组件库搭建之Select组件

前言

Select 是最频繁使用的UI组件之一,它可以运用在很多场景。大多数情况下,原生HTML的<Select>标签无法满足业务的功能过需求,以及原生HTML的<Select>标签在各个浏览器版本里样式表现不太一样。在这样的情况下,多数人都会选择实现一个符合UI要求以及产品功能需求的Select组件,或者选择使用一些开源组件库提供的 Select 组件。本文主要梳理了 gio-design 中的Select组件在实现过程中遇到的一些阻碍及需要注意的地方,希望能对大家在设计和实现select组件时提供一些帮助。

数据源(dataSource)

Select 组件的两种使用方法:

// 第一种写法
const options = [{label:'a',value:'a'},{label:'b',value:''b}];
<Select options={options} />

// 第二种
<Select>
    <Select.Option value={'a'} >a</Select.Option>
    <Select.Option value={'b'} >b</Select.Option>
</Select>

使用 Select 组件的时候,一般情况下,有两种方式来设定 dataSource

  1. 通过 options 参数,传入纯数据格式。
  2. JSX,通过拦截子组件 <Select.Option/> 的参数,转化为 nodeOptions。相比较 JSX 而言,options 参数形式拥有更好的性能( JSX 方式最终也会转为类似 options 参数的形式)。
该转换方式借鉴了rc-select 中的写法。
export function convertChildrenToData(nodes: React.ReactNode, group = {}): Option[] {
  let nodeOptions: Option[] = [];
  React.Children.forEach(nodes, (node: React.ReactElement & { type: { isSelectOptGroup?: boolean }; props: OptionProps }) => {
    if (!React.isValidElement(node)) return;
    const {
      type: { isSelectOptGroup },
      props: { children, label, value },
    } = node;
    if (!isSelectOptGroup) { // option
      nodeOptions.push(convertNodeToOption(node, group));
    } else { // Group
      nodeOptions = concat(nodeOptions, convertChildrenToData(children, { groupLabel: label, groupValue: value }));
    }
  });
  return nodeOptions;
}

// ReactNode To Options
export function convertNodeToOption(node: React.ReactElement, group: group): Option {
  const {
    props: { value, children, ...restProps },
  } = node as React.ReactElement & { props: OptionProps };
  const { groupValue, groupLabel } = group;
  if (groupLabel && groupLabel) {
    return { value, label: children !== undefined ? children : value, groupValue, groupLabel, ...restProps };
  }
    return { value, label: children !== undefined ? children : value, ...restProps };
}

GroupOption 的定义:

// group

export interface OptionGroupFC extends React.FC<OptGroupProps> {
  isSelectOptGroup: boolean;
}
export const OptGroup: OptionGroupFC = () => null;

OptGroup.isSelectOptGroup = true;

export default OptGroup;

// option

export interface OptionFC extends React.FC<OptionProps> {
  isSelectOption: boolean;
}
const Option: OptionFC = () => null;

Option.isSelectOption = true;

export default Option;

上面这个两个方法思路也比较清晰,用 isSelectOptGroup 来区分 GroupOptionGroup 会在 Option 原有参数上额外增加 groupLabel 和 groupValue 两个 key。

当两种传

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值