背景
在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
以及相关组件