likes
comments
collection
share

Tailwind + Mantine | Switch 组件主题样式

作者站长头像
站长
· 阅读数 33

概述

项目使用 Mantine 组件库配合 Tailwindcss 以实现切图和动画效果, 不使用 .css 文件单独写样式, 目的在于减少样式维护的成本, 使组件开发更加原子化, 降低不同组件间的影响和副作用

根据 UI 设计图来进行一些原子组件的样式适配, 这里记录一下在修改 Switch 组件时遇到的样式问题以及如何使用 Tailwindcss 修改

设计对比

设计图:

Tailwind + Mantine | Switch 组件主题样式

MantineSwitch 组件初始样式:

Tailwind + Mantine | Switch 组件主题样式 Tailwind + Mantine | Switch 组件主题样式

比对:

  1. track 部分
    • 无边框, 改为内阴影
    • 默认背景颜色和 active 状态背景颜色修改
  2. 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 高亮)

  1. color 属性, 用于控制 active 状态下的 track 部分的背景颜色, 但是没有属性来设置默认的背景颜色
  2. root 元素 group 样式, 用于控制 root 元素 hover 状态时, 子元素展示对应样式 (group-hover:xxx)
  3. input 元素 peer 样式, 用于控制 input 元素 checked 状态时, 相邻的 track 元素展示对应样式 (peer-checked:xxx)
  4. thumb 元素的 bgborder 使用相同颜色
  5. 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\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
  ]
}

以上是全部内容, 最后效果:

Tailwind + Mantine | Switch 组件主题样式

Tailwind + Mantine | Switch 组件主题样式

转载自:https://juejin.cn/post/7366441097583722536
评论
请登录