Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

是否有全局配置组件自定义样式的实现? #50

Open
hirohe opened this issue Oct 31, 2020 · 5 comments · Fixed by #55
Open

是否有全局配置组件自定义样式的实现? #50

hirohe opened this issue Oct 31, 2020 · 5 comments · Fixed by #55
Labels
enhancement New feature or request feature New feature proposal new feature proposal

Comments

@hirohe
Copy link
Contributor

hirohe commented Oct 31, 2020

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>

我觉得这样能统一管理所有组件的样式自定义

@shincurry
Copy link
Member

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,并且需要全局管理自定义的样式,可以使用上面提到的这种方案。

@shincurry shincurry added enhancement New feature or request feature New feature proposal new feature proposal labels Oct 31, 2020
@hirohe
Copy link
Contributor Author

hirohe commented Oct 31, 2020

感谢提供的全局自定义的示例

我会尝试全局和局部css样式搭配的方式看看

@shincurry shincurry linked a pull request Nov 28, 2020 that will close this issue
@shincurry shincurry reopened this Nov 30, 2020
@shincurry
Copy link
Member

shincurry commented Nov 30, 2020

v0.5.9 添加了 UUIProviderUUIComponentProxy 两个试验性的组件工具,可以尝试使用。使用反馈希望。

@hirohe
Copy link
Contributor Author

hirohe commented Dec 7, 2020

我昨天试了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>
    // ...
  )
}

image


如果搭配tailwind css使用的话,是否应该像下面的写法一样,对不同的样式进行@apply

// custom style with tailwind css
button.TYPE_text {
  @apply bg-gray-50;
  .UUI-Button-Content {
    @apply text-gray-500;
  }
}

image

@shincurry
Copy link
Member

  • 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 在设计和实现上考虑为使用者提供更多更方便的自定义方案,
但是实际怎么用还是希望使用者自己做决定,
以上提到的都是推荐做法。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feature New feature proposal new feature proposal
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants