Skyroc Web Kit

@skyroc/tailwind-plugin

Skyroc UI 的 Tailwind CSS 插件 — 通过 CSS 变量提供主题系统、12 套内置配色、语义化 token、可配置圆角与一组常用 utility,支持 Web / Native 双平台与运行时主题切换

概述

@skyroc/tailwind-plugin 是面向 Skyroc UI 的 Tailwind CSS 插件,使用一个 plugin.withOptions 同时完成两件事:

  • addBase — 注入 CSS 变量、全局样式、字号档位与动画 keyframes
  • addUtilities — 注册一组高频复用的 flex / 动画 utility(如 flex-centeranimate-accordion-down

并通过 withOptions 的第二个参数向 Tailwind 主题注入:

  • 一组完整的语义化颜色(primarydestructivesuccesswarninginfocarbon 含 50–950 完整色阶 + DEFAULT + foreground
  • --radius 联动的圆角系统(sm / md / lg / xl
  • 三档极小字号(2xs / 3xs / 4xs

颜色实现完全基于 CSS 变量驱动,可在运行时通过修改 :root.dark 下的变量切换主题,无需重新构建。

架构

src/
├── index.ts              skyrocUIPlugin 主入口(plugin.withOptions)
├── presets.ts            presetSkyrocUI():flex-* / animate-* utility
├── themePresets.ts       skyrocUITheme():base 样式(CSS 变量 + keyframes + html.size-* 字号档)
├── generate.ts           generateCSSVars / generateGlobalStyles + 色板生成
├── theme.json            12 套内置颜色主题(default / zinc / blue / rose ...)的亮暗 CSS 变量
└── types.ts              类型定义(HslColorString / ThemeOptions / SkyrocUIPluginOptions ...)

数据流:

SkyrocUIPluginOptions


skyrocUITheme(options)            ← addBase
        ├─ generateCSSVars()         为 :root / .dark 生成 --xxx 变量
        ├─ generateGlobalStyles()    *.borderColor、body 背景/前景
        ├─ html.size-xs ~ size-2xl   根字号档位(12px ~ 24px)
        └─ shadcn-* keyframes        accordion / collapsible 动画

presetSkyrocUI()                  ← addUtilities
        └─ flex-center / flex-c / flex-1-hidden / animate-* ...

withOptions 第二参                 ← Tailwind theme.extend
        ├─ borderRadius { sm/md/lg/xl }   随 options.radius 动态计算
        ├─ colors { primary / destructive / sidebar-* / ... }   c() 包装
        └─ fontSize { '2xs' / '3xs' / '4xs' }

安装

pnpm add -D @skyroc/tailwind-plugin tailwindcss

Peer / 同伴依赖tailwindcss(catalog 中为 css 通道版本,需 ≥ 3.4)。本包同时依赖 @skyroc/color,由 monorepo workspace 自动解析。

快速上手

1. 基础配置

tailwind.config.js 中启用插件:

import { skyrocUIPlugin } from '@skyroc/tailwind-plugin';

export default {
  content: ['./src/**/*.{js,ts,jsx,tsx}'],
  plugins: [skyrocUIPlugin()]
};

无任何参数时使用默认值:color = 'default'radius = 0.5platform = 'web'globals = truedarkSelector = '.dark'

2. 带选项配置

import { skyrocUIPlugin } from '@skyroc/tailwind-plugin';

export default {
  content: ['./src/**/*.{js,ts,jsx,tsx}'],
  plugins: [
    skyrocUIPlugin({
      color: 'blue',     // 12 套内置主题之一
      radius: 0.75,      // 圆角基准(rem)
      platform: 'web',   // 'web' | 'native'
      globals: true,     // 是否注入 *.borderColor、body 背景/前景
      darkSelector: '.dark'
    })
  ]
};

3. 在组件中使用

<div className="bg-background text-foreground">
  <button className="bg-primary text-primary-foreground rounded-md px-4 py-2">
    主要按钮
  </button>

  <div className="bg-card border border-border rounded-lg p-4">
    <p className="text-muted-foreground">次要文字</p>
  </div>

  {/* 使用色阶 */}
  <div className="bg-primary-100 text-primary-900">浅色主背景</div>
  <div className="bg-destructive-500 text-destructive-foreground">错误状态</div>

  {/* 使用 utility */}
  <div className="flex-center gap-2">居中内容</div>
</div>

4. 暗色模式

通过为根元素加 .dark 类即可切换(class 名由 darkSelector 决定):

document.documentElement.classList.toggle('dark');

generateCSSVars 会同时输出 :root.dark 两组 CSS 变量,所有依赖 hsl(var(--xxx)) 的 utility 自动跟随。

配置选项

完整接口:

interface SkyrocUIPluginOptions extends ThemeOptions {
  /** 是否注入 *.borderColor 与 body 全局样式,默认 true */
  globals?: boolean;
  /** 目标平台:native 模式下变量值输出为 hex,支持 opacity modifier,默认 'web' */
  platform?: 'native' | 'web';
}

interface ThemeOptions {
  /** 主题色:内置名称、完整 ThemeCSSVarsVariant 对象,或 { base, ...override },默认 'default' */
  color?: ColorOptions | false;
  /** 暗色选择器,默认 '.dark' */
  darkSelector?: string;
  /** 反馈色(success / warning / info / carbon)覆盖 */
  feedbackColor?: FeedbackColorOfThemeCssVarsVariant;
  /** 圆角基准(rem),默认 0.5 */
  radius?: number | false;
  /** Sidebar 颜色覆盖 */
  sidebar?: SidebarColorOfThemeCssVarsVariant;
}

内置颜色主题

theme.json 提供 12 套主题,每套都有完整的 light / dark CSS 变量:

名称风格
default经典靛蓝主色
zinc锌灰
slate石板灰
stone石灰
gray中性灰
neutral纯中性
red
rose玫瑰
orange
green绿
blue
yellow
violet紫罗兰
import { builtinColors, builtinColorMap } from '@skyroc/tailwind-plugin';

builtinColors;    // ['default', 'zinc', 'slate', ...]
builtinColorMap;  // { default: '236.9 100% 69.61%', zinc: '...', ... }

自定义颜色

color 字段除内置名称外还接受两种形式:

方式一 · 基于内置主题局部覆盖(最常用):

skyrocUIPlugin({
  color: {
    base: 'blue',
    light: { primary: '210 100% 50%' },
    dark: { primary: '210 100% 60%' }
  }
});

base 决定起点,其余字段会通过 mergeDeep 深度合并到内置主题之上。

方式二 · 完整 ThemeCSSVarsVariant

skyrocUIPlugin({
  color: {
    name: 'corp',
    light: { /* 全部 ThemeCSSVars 字段 */ },
    dark:  { /* ... */ }
  }
});

设置 color: false 时只输出 --radius 变量,不生成任何颜色相关 CSS。

圆角

radius 是一个 rem 数值(推荐 00.30.50.751),与 Tailwind 的 rounded-* 联动:

import { builtinRadiuses } from '@skyroc/tailwind-plugin';

builtinRadiuses; // [0, 0.3, 0.5, 0.75, 1] as const

最终生效的映射(r = options.radius):

rounded-sm → r - 0.25 rem
rounded-md → r - 0.125 rem
rounded-lg → r rem            ← 与 --radius 同值
rounded-xl → r + 0.25 rem

任何负数计算结果都会被 Math.max(0, value) 夹紧到 0,并保留三位小数。

反馈色与 Sidebar 色覆盖

feedbackColorsidebar 是两个独立的 variant 对象,便于在不修改主题的前提下统一调整警示色或后台侧边栏:

skyrocUIPlugin({
  color: 'default',
  feedbackColor: {
    light: {
      success: '160 84% 39%', 'success-foreground': '0 0% 100%',
      warning: '38 92% 50%',  'warning-foreground': '0 0% 100%',
      info: '199 89% 48%',    'info-foreground': '0 0% 100%',
      carbon: '240 4% 16%',   'carbon-foreground': '0 0% 98%'
    },
    dark: { /* 同结构 */ }
  }
});

不传时使用 createBuiltinFeedbackColorTheme()createBuiltinSidebarColorTheme() 的内置默认值。

Web vs Native

平台颜色值形态Tailwind 写法opacity 修饰符
webhsl() 三元组(H S% L%hsl(var(--primary))不支持
nativehex(#rrggbbvar(--primary)支持

切换示例:

skyrocUIPlugin({ platform: 'native' });

generateCSSVars 会调用 hslToHex 将所有变量值转为 hex;色板(50–950)也同步输出为 hex。

主题颜色 Token

基础颜色

Token描述
background页面背景
foreground默认文字
card卡片背景
card-foreground卡片文字
popover弹层背景
popover-foreground弹层文字
muted禁用 / 次要背景
muted-foreground次要文字
accent强调
accent-foreground强调文字
border边框
input输入框边框
ringfocus ring
secondary次要颜色
secondary-foreground次要颜色文字

语义颜色(含 50–950 全色阶)

Token用途
primary主品牌色
destructive错误 / 危险
warning警告
success成功
info信息
carbon中性碳色

每个语义色都展开为 <token>-{50,100,200,300,400,500,600,700,800,900,950} + <token> 主色 + <token>-foreground 文字色。色阶由 @skyroc/colorgetColorPalette 基于主色推导而来。

Token描述
sidebar-background侧栏背景
sidebar-foreground侧栏文字
sidebar-primary侧栏主色
sidebar-primary-foreground侧栏主色文字
sidebar-accent侧栏强调
sidebar-accent-foreground侧栏强调文字
sidebar-border侧栏边框
sidebar-ring侧栏 focus ring

内置 Utility

presetSkyrocUI() 注册的高频 utility(出自 src/presets.ts):

Flex 布局

Class等价于
flex-centerflex justify-center items-center
flex-x-centerflex justify-center
flex-y-centerflex items-center
flex-cflex flex-col
flex-c-centerflex justify-center items-center flex-col
flex-c-stretchflex flex-col items-stretch
flex-1-hiddenflex-1 overflow-hidden

i-flex-* 系列对应 inline-flex 版本(i-flex-center / i-flex-c-center 等)。

动画

Class用途
animate-accordion-downshadcn Accordion 展开动画
animate-accordion-upshadcn Accordion 折叠动画
animate-collapsible-downshadcn Collapsible 展开动画
animate-collapsible-upshadcn Collapsible 折叠动画

依赖的 keyframes(shadcn-down / shadcn-up / shadcn-collapsible-down / shadcn-collapsible-up)由 skyrocUITheme() 通过 addBase 同步注入,无需额外配置。

根字号档位

themePresets.tsaddBase 中注入了 6 个根字号档,配合在 <html> 上加 class 即可整体放缩:

html.size-xs   → 12px
html.size-sm   → 14px
html.size-md   → 16px   (默认)
html.size-lg   → 18px
html.size-xl   → 20px
html.size-2xl  → 24px

由于 Tailwind 的 rem 体系依赖根字号,这套档位可以为「极小信息密度」「适老化模式」等场景一键全局切换字号比例。

字号扩展

text-2xs  → 0.625rem / line-height 1.2
text-3xs  → 0.5rem  / line-height 1.25
text-4xs  → 0.375rem / line-height 1.333

补足 Tailwind 默认从 text-xs 起步,无更小档位的空白。

API 参考

skyrocUIPlugin

主插件函数(默认导出 + 命名导出):

skyrocUIPlugin(options?: SkyrocUIPluginOptions)

skyrocUITheme

返回 addBase 输入对象,可在自定义 plugin 中复用:

import { skyrocUITheme } from '@skyroc/tailwind-plugin';

const baseStyles = skyrocUITheme({ color: 'blue', radius: 0.75 });

presetSkyrocUI

返回 addUtilities 输入对象,包含全部 flex-*animate-* 定义:

import { presetSkyrocUI } from '@skyroc/tailwind-plugin';

generateCSSVars

底层 CSS 变量生成器,可在 SSR / 服务端直接生成主题 CSS:

function generateCSSVars(
  theme: ThemeOptions,
  onlyOne?: boolean,   // 是否只输出当前一套主题,默认 true
  native?: boolean     // 是否输出 hex 而非 hsl,默认 false
): object

onlyOne = false 时会以 .theme-<name> 作为额外作用域包裹(除 default 外),便于在同一文档中并存多套主题。

generateGlobalStyles

返回 * / body / .lucide 的全局样式片段,独立可用:

import { generateGlobalStyles } from '@skyroc/tailwind-plugin';

辅助导出

import {
  skyrocUIPlugin,    // 主插件
  skyrocUITheme,     // 主题 base 样式生成
  presetSkyrocUI,    // utility 预设
  generateCSSVars,   // CSS 变量生成器
  builtinColors,     // 内置颜色名数组
  builtinColorMap,   // 颜色名 → 主色 hsl 字符串映射
  builtinRadiuses    // 可用圆角枚举
} from '@skyroc/tailwind-plugin';

类型参考

HslColorString

CSS 变量的统一格式:

type HslColorString = `${number} ${number}% ${number}%`;
// 例:'236.9 100% 69.61%'

约定不带 hsl() 包装与 , 分隔符,便于在 utility 中 hsl(var(--xxx) / <alpha>) 拼接 alpha。

ThemeCSSVars

主题色 + 基础色的完整字段集合:

interface ThemeCSSVars {
  background: HslColorString;
  foreground: HslColorString;
  card: HslColorString;
  'card-foreground': HslColorString;
  popover: HslColorString;
  'popover-foreground': HslColorString;
  primary: HslColorString;
  'primary-foreground': HslColorString;
  secondary: HslColorString;
  'secondary-foreground': HslColorString;
  muted: HslColorString;
  'muted-foreground': HslColorString;
  accent: HslColorString;
  'accent-foreground': HslColorString;
  destructive: HslColorString;
  'destructive-foreground': HslColorString;
  border: HslColorString;
  input: HslColorString;
  ring: HslColorString;
}

FeedbackColorOfThemeCssVars

interface FeedbackColorOfThemeCssVars {
  carbon: HslColorString;
  'carbon-foreground': HslColorString;
  info: HslColorString;
  'info-foreground': HslColorString;
  success: HslColorString;
  'success-foreground': HslColorString;
  warning: HslColorString;
  'warning-foreground': HslColorString;
}

SidebarColorOfThemeCssVars

interface SidebarColorOfThemeCssVars {
  'sidebar-background': HslColorString;
  'sidebar-foreground': HslColorString;
  'sidebar-primary': HslColorString;
  'sidebar-primary-foreground': HslColorString;
  'sidebar-accent': HslColorString;
  'sidebar-accent-foreground': HslColorString;
  'sidebar-border': HslColorString;
  'sidebar-ring': HslColorString;
}

ThemeColorKey

updateThemeColorsgenColorMapToken 等场景中常用的语义色键集合:

type ThemeColorKey =
  | 'primary' | 'secondary' | 'destructive'
  | 'carbon' | 'info' | 'success' | 'warning';

ThemeConfig

theme.json 中每一项的形态:

interface ThemeConfig<T = ThemeConfigColor> {
  name: T;
  label: string;
  cssVars: { light: ThemeCSSVars; dark: ThemeCSSVars };
}

type ThemeConfigColor =
  | 'default' | 'blue' | 'gray' | 'green' | 'neutral'
  | 'orange' | 'red' | 'rose' | 'slate' | 'stone'
  | 'violet' | 'yellow' | 'zinc';

高级用法

多主题并存

设置 generateCSSVars(theme, false) 可生成 .theme-<name> 命名空间,搭配在同一页面切换 wrapper class 即可对比效果:

.theme-blue   { /* 蓝色变量 */ }
.theme-blue.dark { /* 蓝色暗色变量 */ }
.theme-rose   { /* 玫瑰色变量 */ }
.theme-rose.dark { /* 玫瑰色暗色变量 */ }

与 React Native 集成

skyrocUIPlugin({ platform: 'native', color: 'blue' });

输出后所有变量值为 hex,组件中可写 bg-primary/50text-foreground/80 等带 alpha 的写法,由 NativeWind 等 RN Tailwind 实现解析。

关闭全局样式

某些需要嵌入第三方页面的场景,应避免污染外部 * 选择器:

skyrocUIPlugin({ globals: false });

此时不会注入 * { border-color: ... }body { background, color },但 CSS 变量、utility、keyframes 仍然生效。

仅输出圆角

skyrocUIPlugin({ color: false, radius: 0.75 });
// → :root { --radius: 0.75rem }

适用于颜色由其他系统(如 @skyroc/web-admin-theme + Ant Design)接管,仅希望 Tailwind 端共享 rounded-* 数值。

设计说明

为什么用 hsl(var(--xxx)) 而不是直接 var(--xxx)

CSS 变量存的是「H S% L%」三元组而非完整 hsl()。这样在 utility 层可以拼接 alpha:

.bg-primary\/50 { background: hsl(var(--primary) / 0.5); }

如果直接存 hsl(...) 完整字符串,Tailwind 的 opacity modifier 就无法工作。Native 平台不需要 alpha modifier,因此存 hex 即可。

为什么 radius 用 rem 而不是 px

Tailwind 的语义化尺寸全部以 rem 为基准;用 rem 表达 radius 可以让 html.size-xs ~ size-2xl 的根字号档位自动放缩圆角,与字号、间距保持比例一致。

为什么 keyframes 与 utility 分散注入

  • keyframes(@keyframes shadcn-*)通过 addBase 注入,因为它们是文档级声明而非 class
  • 对应的 animate-* 通过 addUtilities 注入,因为它们是 class
  • 两者必须同时存在才能完整工作;插件已自动处理,使用方无需手动配置 keyframes

@skyroc/web-admin-theme 的关系

场景用法
仅用 Tailwind直接使用本插件,所有颜色和 utility 走 CSS 变量
Tailwind + Ant Design本插件提供 utility 与基础色阶;@skyroc/web-admin-theme 接管 antd token 与运行时主题切换
仅用 Ant Design不需要本插件

两者互不依赖:本插件负责 Tailwind 端的样式系统,@skyroc/web-admin-theme 负责 React 状态与 antd 集成。

On this page