Tailwind + Mantine | Switch 组件主题样式
概述
项目使用 Mantine
组件库配合 Tailwindcss
以实现切图和动画效果, 不使用 .css
文件单独写样式, 目的在于减少样式维护的成本, 使组件开发更加原子化, 降低不同组件间的影响和副作用
根据 UI 设计图来进行一些原子组件的样式适配, 这里记录一下在修改 Switch
组件时遇到的样式问题以及如何使用 Tailwindcss
修改
设计对比
设计图:
Mantine
的 Switch
组件初始样式:
比对:
track
部分- 无边框, 改为内阴影
- 默认背景颜色和
active
状态背景颜色修改
thumb
部分- 无边框
hover
状态下增加蓝色边框和一圈半透明的outline
最终修改
// Switch.ts
import { Switch } from '@mantine/core'
import { cn } from '../../utils/className'
export const SwitchTheme = Switch.extend({
// defaultProps: {
// NOTE 可行, 但不能控制未选中时的颜色
// color: 'var(--tw-color-brand5)',
// },
classNames: {
root: cn(' group cursor-pointer'),
thumb: cn(
cn(' bg-bg1 border-bg1'),
cn(' group-hover:border-[#00A6FF] group-hover:ring-[3px]'),
cn(' group-hover:ring-[rgba(81,193,253,0.4)]'),
),
input: cn(' peer'),
track: cn(
// NOTE 如果只有 bg-bg4, 会覆盖 checked 的 bg
cn(' bg-bg4 peer-checked:bg-brand5'),
cn('shadow-[0px_1px_1px_0px_rgba(0,0,0,0.06)_inset]'),
cn('overflow-visible border-0'),
),
},
vars: () => {
return {
root: {
// NOTE 这个生效, 和 defaultProps 的 color 一样
// '--switch-color': 'var(--tw-color-brand5)',
// NOTE 这个不生效, 虽然样式里是用的这个变量, 但是定义后不会生效
// '--switch-bg': 'var(--tw-color-bg4)',
},
}
},
})
代码解释
里面有几个 NOTE
可以看一下 (在 vscode
中, 可以使用 Todo Tree
插件来设置 NOTE
高亮)
color
属性, 用于控制active
状态下的track
部分的背景颜色, 但是没有属性来设置默认的背景颜色- 给
root
元素group
样式, 用于控制root
元素hover
状态时, 子元素展示对应样式 (group-hover:xxx
) - 给
input
元素peer
样式, 用于控制input
元素checked
状态时, 相邻的track
元素展示对应样式 (peer-checked:xxx
) thumb
元素的bg
和border
使用相同颜色track
元素的bg
只能通过peer
来控制, 其他方式都有不足
里面的 cn
(className
的简写) 方法用于支持 tailwind
的开发, 代码如下:
// className.ts
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
配合 vscode
插件 Tailwind CSS IntelliSense
可以用于代码补全, .vscode/settings.json
中相关配置如下:
// .vscode/settings.json
{
"tailwindCSS.experimental.classRegex": [
["clsx\\(([^)]*)\\)"],
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["classNames\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["className: [\"'`]([^\"'`]*).*?[\"'`]"],
["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
]
}
以上是全部内容, 最后效果:
转载自:https://juejin.cn/post/7366441097583722536