背景
在MUI中,不管是 Select 还是 AutoComplete , 其 DOM 组件的最外层DOM的
class都是 MuiInputBase-root 并且,其样式和 Input 都是统一的,variant 同样包括 standard , outlined 等格式,很显然,他们之间是复用,但是从代码层面他们是如何复用的呢,这是个值得研究的问题。在我们的设计中, Input 和 Select 以及 Cascader 等样式也同样是统一的,所以是否能参考其设计,让我们的样式也能统一起来,减少重复代码。我们也期望能通过理清
Mui 中 Input 和 Select 以及 AutoComplete 之间的关系找到答案的。Input
Input 分为了
Input
标准的Input,只有一个下划线
FilledInput
带背景色和下划线的Input
OutlinedInput
圆角边框的Input
通常我们不会直接用这三个Input,而是使用 MUI 文档中推荐的 TextField 组件,它是对 三种 Input 组件的封装,同时包括了标签,输入,和帮助文本等
而
Input ,OutlinedInput 和 FilledInput 内部使用的都是 InputBase 组件,所以从 Input 的结构层次来说如下图InputBaseProps.inputComponent 字段
需要注意的是,在
InputBaseProps中,有一个字段 inputComponent ,其默认值为 ‘input’这个
inputComponent 是可以自定义的,假如我们将其自定义为新的组件结果就是,
OutlinedInput内部不再是一个 input, 而是一个 <div>, 其样式通过 props 给了 MyInput 总结来说,
OutlinedInput 依赖于 InputBase ,在 InputBase 的基础上提供了边框的样式,InputBase 并没有将内部的 input 元素写死,而是给外界提供了传入参数 inputComponent ,而 OutlinedInput ,FilledInput 和 Input 都是传入默认的 input DOM。我们如果想自定义这个
inputComponent ,只需要传入自己写的组件即可。Select
Select的实现也是依赖于
Input注意上面的
inputComponent 和 InputComponent ,大写的 InputComponent 指的是要渲染的 Input 类型,standard , outlined , filled 等,而小写的 inputComponent 则是要传入 Input 中用于渲染的组件,在这里是 SelectInput 而对于
SelectInput 来说,里面则是由 SelectSelect ,SelectNativeInput , SelectIcon , Menu 四个部分构成,即用于点击的区域,用来存储 value 的 input,下拉图标,点击后展示的选择菜单。AutoComplete
AutoComplete 和 Select ,AutoComplete 是提供了
renderInput 参数,用于将 TextField 传入为了展示下拉箭头,删除按钮,以及多选后的
Tag 等,需要利用 TextField 提供的能力,从上图可以看到AutoComplete会向
renderInput 函数传入 startAdornment , endAdornment 等参数,也就是说我们的 renderInput 并不是可以随便传的,要不就传入 TextField ,要不就传入能接收这些参数的组件(或者继承 TextField 的组件)AutoComplete 并不完全是一个组件,它提供了一个完整的 hook 函数 ,我们完全可以基于这个 hook 函数构造自己的组件,当然这需要进一步研究其 API。在这篇文章下我们不做深入。
从上面可知,我们只需要定制 三种
Input 的样式就可以影响 TextField , Select 以及 AutoComplete 的样式,而在我们 Pluto 的项目中同样可以遵循这个关系,在主题上 定制 OutlinedInput 的 component 样式,然后使用 AutoComponent 去定制 CSelect ,使用 OutlinedInput 去定制 CInput 以及相关组件