Mui的Select,AutoComplete 和Input的关系

Mui的Select,AutoComplete 和Input的关系

Tags
前端
mui
组件
description
更新时间
Last updated September 15, 2022

背景

在MUI中,不管是 Select 还是 AutoComplete , 其 DOM 组件的最外层DOM的class都是 MuiInputBase-root 并且,其样式和 Input 都是统一的,variant 同样包括 standardoutlined 等格式,很显然,他们之间是复用,但是从代码层面他们是如何复用的呢,这是个值得研究的问题。
 
在我们的设计中, Input 和 Select 以及 Cascader 等样式也同样是统一的,所以是否能参考其设计,让我们的样式也能统一起来,减少重复代码。我们也期望能通过理清 MuiInputSelect 以及 AutoComplete 之间的关系找到答案的。
 

Input

Input 分为了
🌟
Input
标准的Input,只有一个下划线
notion image
 
🌟
FilledInput
带背景色和下划线的Input
notion image
 
🌟
OutlinedInput 圆角边框的Input
notion image
通常我们不会直接用这三个Input,而是使用 MUI 文档中推荐的 TextField 组件,它是对 三种 Input 组件的封装,同时包括了标签,输入,和帮助文本等
 
InputOutlinedInputFilledInput 内部使用的都是 InputBase 组件,所以从 Input 的结构层次来说如下图
notion image
 

InputBaseProps.inputComponent 字段

需要注意的是,在InputBaseProps中,有一个字段 inputComponent ,其默认值为 ‘input’
notion image
这个 inputComponent 是可以自定义的,假如我们将其自定义为新的组件
notion image
notion image
结果就是,OutlinedInput内部不再是一个 input, 而是一个 <div>, 其样式通过 props 给了 MyInput
 
总结来说,OutlinedInput 依赖于 InputBase ,在 InputBase 的基础上提供了边框的样式,
InputBase 并没有将内部的 input 元素写死,而是给外界提供了传入参数 inputComponent ,而 OutlinedInputFilledInputInput 都是传入默认的 input DOM。
我们如果想自定义这个 inputComponent ,只需要传入自己写的组件即可。

Select

Select的实现也是依赖于 Input
notion image
 
注意上面的 inputComponentInputComponent ,大写的 InputComponent 指的是要渲染的 Input 类型,standard , outlined , filled 等,而小写的 inputComponent 则是要传入 Input 中用于渲染的组件,在这里是 SelectInput
notion image
而对于 SelectInput 来说,里面则是由 SelectSelect ,SelectNativeInput , SelectIcon , Menu 四个部分构成,即用于点击的区域,用来存储 value 的 input,下拉图标,点击后展示的选择菜单。
 

AutoComplete

 
AutoComplete 和 Select ,AutoComplete 是提供了 renderInput 参数,用于将 TextField 传入
notion image
为了展示下拉箭头,删除按钮,以及多选后的 Tag 等,需要利用 TextField 提供的能力,
notion image
从上图可以看到AutoComplete会向 renderInput 函数传入 startAdornmentendAdornment 等参数,也就是说我们的 renderInput 并不是可以随便传的,要不就传入 TextField ,要不就传入能接收这些参数的组件(或者继承 TextField 的组件)
 
AutoComplete 并不完全是一个组件,它提供了一个完整的 hook 函数 ,我们完全可以基于这个 hook 函数构造自己的组件,当然这需要进一步研究其 API。在这篇文章下我们不做深入。
notion image
 
从上面可知,我们只需要定制 三种 Input 的样式就可以影响 TextField , Select 以及 AutoComplete 的样式,而在我们 Pluto 的项目中同样可以遵循这个关系,在主题上 定制 OutlinedInputcomponent 样式,然后使用 AutoComponent 去定制 CSelect ,使用 OutlinedInput 去定制 CInput 以及相关组件