Lzh on GitHub

Tailwind Variants 是一个用于 TailwindCSS 的一流变体 API 库。

主要功能

变体

Stitches 引入变体以来,我们就成了它们的忠实粉丝,它们是创建一致设计体系的好方法,因此我们创建了 Tailwind Variants,将它们带到了 TailwindCSS 中。

import { tv } from 'tailwind-variants';
 
const button = tv({
  base: 'font-medium bg-blue-500 text-white rounded-full active:opacity-80',
  variants: {
    color: {
      primary: 'bg-blue-500 text-white',
      secondary: 'bg-purple-500 text-white'
    },
    size: {
      sm: 'text-sm',
      md: 'text-base',
      lg: 'px-4 py-3 text-lg'
    }
  },
  compoundVariants: [
    {
      size: ['sm', 'md'],
      class: 'px-3 py-1'
    }
  ],
  defaultVariants: {
    size: 'md',
    color: 'primary'
  }
});
 
return (
  <button className={button({ size: 'sm', color: 'secondary' })}>
    Click me
  </button>
);

要了解更多关于变体的信息,请查看 variants 页面。

将组件拆分为多个槽位

您可以使用 slots 属性一次性为多个组件设置样式。

import { tv } from 'tailwind-variants';
 
const card = tv({
  slots: {
    base: 'md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-gray-900',
    avatar:
      'w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto drop-shadow-lg',
    wrapper: 'flex-1 pt-6 md:p-8 text-center md:text-left space-y-4',
    description: 'text-md font-medium',
    infoWrapper: 'font-medium',
    name: 'text-sm text-sky-500 dark:text-sky-400',
    role: 'text-sm text-slate-700 dark:text-slate-500'
  }
});
 
const { base, avatar, wrapper, description, infoWrapper, name, role } = card();
 
return (
  <figure className={base()}>
    <img
      className={avatar()}
      src="/intro-avatar.png"
      alt=""
      width="384"
      height="512"
    />
    <div className={wrapper()}>
      <blockquote>
        <p className={description()}>
          “Tailwind variants allows you to reduce repeated code in your project
          and make it more readable. They fixed the headache of building a
          design system with TailwindCSS.”
        </p>
      </blockquote>
      <figcaption className={infoWrapper()}>
        <div className={name()}>Zoey Lang</div>
        <div className={role()}>Full-stack developer, HeroUI</div>
      </figcaption>
    </div>
  </figure>
);

要了解更多关于槽位及其使用方法,请查看 Slots 页面。

覆盖

Tailwind Variants 为任何组件提供了一个 class / className 属性,用于覆盖类。

import { tv } from 'tailwind-variants';
 
const button = tv({
  base: 'font-semibold text-white py-1 px-3 rounded-full active:opacity-80',
  variants: {
    color: {
      primary: 'bg-blue-500 hover:bg-blue-700',
      secondary: 'bg-purple-500 hover:bg-purple-700',
      success: 'bg-green-500 hover:bg-green-700',
      error: 'bg-red-500 hover:bg-red-700'
    }
  }
});
 
button({
  color: 'secondary',
  class: 'bg-pink-500 hover:bg-pink-500' // 覆盖了 color 变体
});
 
/**
 * 结果:
 * font-semibold text-white py-1 px-3 rounded-full active:opacity-80 bg-pink-500 hover:bg-pink-500
 */

要了解更多关于覆盖的信息,请查看此 页面

组件组合

Tailwind Variants 允许您使用 extend 参数来组合组件。它会自动合并被扩展组件的 classesslotsvariantsdefaultVariantscompoundVariants

import { tv } from 'tailwind-variants';
 
const baseButton = tv({
  base: [
    'font-semibold',
    'dark:text-white',
    'py-1',
    'px-3',
    'rounded-full',
    'active:opacity-80',
    'bg-zinc-100',
    'hover:bg-zinc-200',
    'dark:bg-zinc-800',
    'dark:hover:bg-zinc-800'
  ]
});
 
const buyButton = tv({
  extend: baseButton,
  base: [
    'text-sm',
    'text-white',
    'rounded-lg',
    'shadow-lg',
    'uppercase',
    'tracking-wider',
    'bg-blue-500',
    'hover:bg-blue-600',
    'shadow-blue-500/50',
    'dark:bg-blue-500',
    'dark:hover:bg-blue-600'
  ]
});
 
return (
  <div className="flex gap-3">
    <button className={baseButton()}>Button</button>
    <button className={buyButton()}>Buy button</button>
  </div>
);
 
/**
 * buyButton();
 *
 * 结果:
 * font-semibold dark:text-white py-1 px-3 active:opacity-80 text-sm text-white rounded-lg
 * shadow-lg shadow-blue-500/50 uppercase tracking-wider bg-blue-500 hover:bg-blue-600
 * dark:bg-blue-500 dark:hover:bg-blue-600
 */

要了解更多关于 组件组合 的信息,请查看此 页面

开发者体验

Tailwind Variants 的构建考虑了开发者体验,它通过完全类型化的 API 提供了出色的自动完成体验,因此在使用 TypeScript 时,slotsvaluesbreakpoints 将为您自动完成。

自动冲突解决

Tailwind Variants 支持 tailwind-merge 以实现自动冲突解决。从 v2 开始,tailwind-merge 是一个可选的对等依赖项 - 如果您需要此功能,请单独安装它。启用后,它将有效地合并您的类,因此您无需担心 TailwindCSS 类冲突。

与框架无关

Tailwind Variants 是一个与任何框架都兼容的实用程序库。它不与 React 绑定。

支持 Tailwindcss v4

Tailwind Variants v1.x 现已支持 Tailwindcss v4。您可以在 升级指南 中查看更多详细信息。

v2 中的性能改进

Tailwind Variants v2 带来了显著的性能增强:

  • 37-62% 的操作速度更快
  • 优化的对象创建和数组操作
  • 减少了函数调用开销
  • 更好的内存使用
  • 可选 tailwind-merge 的更小捆绑包大小

这些改进使得 Tailwind Variants 对于大型应用程序更加高效,同时保持了完全的向后兼容性。

社区

我们很高兴看到社区采用 HeroUI,提出问题并提供反馈。无论是功能请求、错误报告还是展示项目,请参与进来!

鸣谢

Tailwind Variants 的灵感主要来自 StitchesCVA