UUI
UUI copied to clipboard
是否有全局配置组件自定义样式的实现?
Is your feature request related to a problem? Please describe.
组件有customize
的属性来实现各个组件的样式自定义,不过没有从文档看到是否有全局配置组件自定义样式的方式
Describe the solution you'd like
依靠React Context
组件来注入自定义的配置
const config = {
Stepper: {
// ... Stepper customize
},
Switch: {
// ...
},
Button: {
// ...
}
}
<ComponentCustomizeProvider config={config}>
{children}
</ComponentCustomizeProvider>
我觉得这样能统一管理所有组件的样式自定义
UUI 的早期设计实现重点
UUI 从开发之初考虑的一个重点就是,这套框架会被用在设计更加个性化的页面上:比如说像 Electron 桌面应用界面,或者一些面向用户使用的页面,而不是后台管理这一类的页面。这就意味着同一个页面下的 Input Select 这些组件都可能有完全不同的样式。所以项目早期重点开发:1. 针对各自组件的 customize 功能 2.完成足够多的常用组件的基本功能实现。这算是目前 UUI 缺乏考虑全局 customize 的一个原因。
UUIProvider 全局自定义组件样式
开发一个 UUIProvider(<UUIProvider customize={{ ... }} otherconfig={{ ... }} />
) 用来提供全局自定义组件的功能,是一个不错的 idea,但是这个功能会同时地影响到目前的实现方式。简单来讲,就是在组件各个层级之间 customize props 的覆盖优先级。
内联样式覆盖优先级:
用户传入的单个组件CustomizeProps.(extendStyle|overrideStyle)
> 用户传入的全局 CustomizeProps
> 组件内部有其他的组件作为 Node 时传入的CustomizeProps.(extendStyle|overrideStyle)
> 组件内部实现功能传入的 style
外部样式覆盖优先级:
用户传入的单个组件CustomizeProps.overrideClassName
> 用户传入的全局 CustomizeProps.overrideClassName
> 组件内部有其他的组件作为 Node 时传入的CustomizeProps.overrideClassName
> 组件内部实现功能传入的 className
(extendClassName 只会在字符串后面追加,没有覆盖关系)
处理好这个覆盖优先级的关系是成功开发 UUIProvider.customize 的关键,这需要做不少的工作(实现和测试),所以我们会考虑这个提议,但是不会立即实现它。目前还有其他更重要的功能需要实现。
现有的全局管理组件自定义样式的方案
相比于全局传入 customize 来统一管理所以组件的自定义样式,写外部 CSS 来覆盖样式会更加的合适。
CSS 内联样式存在一定的局限性,比如说 <div style={{ ... }} />
,没有办法方便的实现 :hover
、:focus
等等这一系列伪类的样式。而对于组件的样式自定义,实际上是很需要自定义伪类的样式的,比如当你希望修改 Button{styling.type=primary}
的颜色时,会同时需要修改 hover 状态和 focus 状态组件的 border 和 box-shadow 的颜色。
目前现有的全局管理组件自定义样式的推荐方案,就是直接写 CSS SASS LESS 样式去覆盖现有的 UUI 提供的默认样式。UUI 的组件每一个 Node 都有它单独的 NodeClassName,所以我有理由相信,通过 CSS 覆盖你完成可以任何可能的样式自定义。
这里做一个简单的示例:
全局自定义样式
<style type="scss">
.UUI-Button-Root.TYPE_default {
border: 1px solid orange;
background-color: orange;
&:hover {
background-color: deeppink;
}
&:focus {
border: border: 1px solid deeppink;
box-shadow: deeppink 0 0 0 3px;
}
.UUI-Button-Content {
color: blue;
}
}
</style>
<Button>Click Me!</Button>
局部自定义样式
<style type="scss">
.SpecialFeaturedButton.UUI-Button-Root.TYPE_default {
// ....
}
</style>
<Button className="SpecialFeaturedButton">Click Me!</Button>
如果你目前正在某个项目中使用 UUI,并且需要全局管理自定义的样式,可以使用上面提到的这种方案。
感谢提供的全局自定义的示例
我会尝试全局和局部css样式搭配的方式看看
v0.5.9 添加了 UUIProvider
和 UUIComponentProxy
两个试验性的组件工具,可以尝试使用。使用反馈希望。
我昨天试了UUIProvider
来全局地给组件注入样式类,我看到UUIProviderCustomize
可以配置各个组件的extendClassName
所以我想是否可以通过UUIProvider搭配tailwind css来自定样式
配置过程中发现extendClassName是不能区分组件各种styling的,即配置的tailwind样式类会应用到组件所有styling,比如Button组件区分不了primary和text的样式,解决方法应该还是使用全局的样式给TYPE_text
等这些不同styling做自定义吧
// src/App.tsx
const UUICustomize: UUIProviderCustomize = {
Button: {
Root: {
extendClassName: 'bg-orange text-white rounded-lg shadow-md py-2 px-4'
}
}
}
// src/pages/AuthPage.tsx
const AuthPage: React.FC = () => {
return (
// ...
<div className={styles.confirmationActions}>
<Button styling={{ type: 'text' }}>拒绝</Button>
<Button>确认授权</Button>
</div>
// ...
)
}
如果搭配tailwind css使用的话,是否应该像下面的写法一样,对不同的样式进行@apply
?
// custom style with tailwind css
button.TYPE_text {
@apply bg-gray-50;
.UUI-Button-Content {
@apply text-gray-500;
}
}
- Props.customize 对应的是组件,不细分到组件里的 styling
- tailwindcss 是个好东西,和 UUI 配合使用效果很好
推荐
- 对于简单的样式定制(比如修改组件边距背景字体等),可使用
Props.customize
- 对于复杂的样式定制(部分或完全修改组件样式),根据 node className 写 css 样式覆盖默认样式更好
tailwindcss文档提到的使用方法 https://tailwindcss.com/docs/extracting-components
- tailwindcss 的 utility classes 用在 Props.customize 比较合适
- tailwindcss 的 @ apply 用在覆盖默认样式的 css 样式文件里比较合适
UUI 在设计和实现上考虑为使用者提供更多更方便的自定义方案, 但是实际怎么用还是希望使用者自己做决定, 以上提到的都是推荐做法。