样式系统

设计令牌(Tokens)

使用设计令牌管理应用中的设计决策。

概述

设计令牌是以与平台无关的方式管理应用或网站设计决策的方法。它是一组描述 任何基础/原子视觉样式的属性集合,每个属性都是一个键值对。

Chakra 中的设计令牌在很大程度上受到 W3C Token 格式 的影响。

一个设计令牌包含以下属性:

  • value:令牌的值,可以是任意合法的 CSS 值。
  • description:可选的说明,描述该令牌可用于什么场景。

定义令牌

令牌定义在系统配置的 theme 键下。

tsx
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"

const config = defineConfig({
  theme: {
    tokens: {
      colors: {
        primary: { value: "#0FEE0F" },
        secondary: { value: "#EE0F0F" },
      },
      fonts: {
        body: { value: "system-ui, sans-serif" },
      },
    },
  },
})

export const system = createSystem(defaultConfig, config)
注意
令牌值需要嵌套在一个包含 value 键的对象中,这是为了 支持将来添加 description 等更多属性。

使用令牌

定义令牌之后,运行 Chakra CLI 生成主题类型,即可在编辑器中获得令牌的自动补全。 关于如何在 postinstall、CI 和 monorepo 中运行 typegen,参见 CLI 文档

bash
npx @chakra-ui/cli typegen ./src/theme.ts

以下是在组件中使用令牌的示例:

tsx
<Box color="primary" fontFamily="body">
  Hello World
</Box>

令牌引用语法

Chakra UI 允许你在 borderpadding box-shadow 等 CSS 属性的复合值中引用设计令牌,这是通过令牌 引用语法 {path.to.token} 实现的。

提示
必须使用完整的令牌路径。例如,不要只写 red.300,而要写 colors.red.300

下面的示例将令牌引用语法同时应用在 border p(内边距)属性上:

tsx
<Box
  border="1px solid {colors.red.300}"
  p="{spacing.4} {spacing.6} {spacing.8} {spacing.10}"
  boxShadow="{spacing.4} {spacing.2} {spacing.2} {colors.red.300}"
/>

令牌嵌套

令牌可以嵌套以创建令牌层级,当你希望将相关令牌分组时,这会很有用。

提示
使用 DEFAULT 键来定义嵌套令牌的默认值。
tsx
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"

const config = defineConfig({
  theme: {
    tokens: {
      colors: {
        red: {
          DEFAULT: { value: "#EE0F0F" },
          100: { value: "#EE0F0F" },
        },
      },
    },
  },
})

export default createSystem(defaultConfig, config)
tsx
<Box
  // 这里将使用 DEFAULT 值
  bg="red"
  color="red.100"
>
  Hello World
</Box>

令牌类型

颜色(Colors)

颜色具有含义并支持内容的用途,传达信息层级和状态等。其值通常定义为字符串值,或对其他令牌的引用。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  colors: {
    red: {
      100: { value: "#fff1f0" },
    },
  },
})

export default createSystem({
  theme: { tokens },
})

渐变(Gradients)

渐变令牌表示两种或多种颜色之间的平滑过渡。其值可以定义为字符串或复合值。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  gradients: {
    // 字符串值
    simple: { value: "linear-gradient(to right, red, blue)" },

    // 复合值
    primary: {
      value: { type: "linear", placement: "to right", stops: ["red", "blue"] },
    },
  },
})

export default createSystem({
  theme: { tokens },
})

尺寸(Sizes)

尺寸令牌表示元素的宽度和高度,其值定义为字符串。尺寸令牌通常用于 width、height、minWidth、maxWidth、minHeight、maxHeight 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  sizes: {
    sm: { value: "12px" },
  },
})

export default createSystem({
  theme: { tokens },
})

间距(Spacing)

间距令牌表示元素的外边距和内边距,其值定义为字符串。间距令牌通常用于 margin、padding、gap 以及 {top,right,bottom,left} 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  spacing: {
    gutter: { value: "12px" },
  },
})

export default createSystem({
  theme: { tokens },
})

字体(Fonts)

字体令牌表示文本元素的字体族。其值可以定义为字符串或字符串数组。字体令牌通常用于 font-family 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  fonts: {
    body: { value: "Inter, sans-serif" },
    heading: { value: ["Roboto Mono", "sans-serif"] },
  },
})

export default createSystem({
  theme: { tokens },
})

字号(Font Sizes)

字号令牌表示文本元素的大小,其值定义为字符串。字号令牌通常用于 font-size 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  fontSizes: {
    sm: { value: "12px" },
  },
})

export default createSystem({
  theme: { tokens },
})

字重(Font Weights)

字重令牌表示文本元素的粗细,其值定义为字符串。字重令牌通常用于 font-weight 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  fontWeights: {
    bold: { value: "700" },
  },
})

export default createSystem({
  theme: { tokens },
})

字间距(Letter Spacings)

字间距令牌表示文本元素中字符之间的间距,其值定义为字符串。字间距令牌通常用于 letter-spacing 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  letterSpacings: {
    wide: { value: "0.1em" },
  },
})

export default createSystem({
  theme: { tokens },
})

行高(Line Heights)

行高令牌表示一行文本的高度,其值定义为字符串。行高令牌通常用于 line-height 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  lineHeights: {
    normal: { value: "1.5" },
  },
})

export default createSystem({
  theme: { tokens },
})

圆角(Radii)

圆角令牌表示边框的圆角半径,其值定义为字符串。圆角令牌通常用于 border-radius 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  radii: {
    sm: { value: "4px" },
  },
})

export default createSystem({
  theme: { tokens },
})

边框(Borders)

边框是围绕 UI 元素的线条。你可以将其定义为字符串值或复合值。边框令牌通常用于 border、border-top、border-right、border-bottom、border-left、outline 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  borders: {
    // 字符串值
    subtle: { value: "1px solid red" },
    // 引用了颜色令牌的字符串值
    danger: { value: "1px solid {colors.red.400}" },
    // 复合值
    accent: { value: { width: "1px", color: "red", style: "solid" } },
  },
})

export default createSystem({
  theme: { tokens },
})

边框宽度(Border Widths)

边框宽度令牌表示边框的宽度,其值定义为字符串。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  borderWidths: {
    thin: { value: "1px" },
    thick: { value: "2px" },
    medium: { value: "1.5px" },
  },
})

export default createSystem({
  theme: { tokens },
})

阴影(Shadows)

阴影令牌表示元素的阴影。其值可以定义为单个或多个值,其中包含字符串或复合值。阴影令牌通常用于 box-shadow 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  shadows: {
    // 字符串值
    subtle: { value: "0 1px 2px 0 rgba(0, 0, 0, 0.05)" },
    // 复合值
    accent: {
      value: {
        offsetX: 0,
        offsetY: 4,
        blur: 4,
        spread: 0,
        color: "rgba(0, 0, 0, 0.1)",
      },
    },
    // 多个字符串值
    realistic: {
      value: [
        "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
        "0 1px 4px 0 rgba(0, 0, 0, 0.1)",
      ],
    },
  },
})

export default createSystem({
  theme: { tokens },
})

缓动(Easings)

缓动令牌表示动画或过渡的缓动函数。其值定义为字符串,或表示三次贝塞尔曲线的数值数组。缓动令牌通常用于 transition-timing-function 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  easings: {
    // 字符串值
    easeIn: { value: "cubic-bezier(0.4, 0, 0.2, 1)" },
    // 数组值
    easeOut: { value: [0.4, 0, 0.2, 1] },
  },
})

export default createSystem({
  theme: { tokens },
})

透明度(Opacity)

透明度令牌帮助你设置元素的透明度。通常用于 opacity 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  opacity: {
    50: { value: 0.5 },
  },
})

export default createSystem({
  theme: { tokens },
})

层级(Z-Index)

该令牌类型表示元素在 z 轴上的位置深度。通常用于 z-index 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  zIndex: {
    modal: { value: 1000 },
  },
})

export default createSystem({
  theme: { tokens },
})

资源(Assets)

资源令牌表示一个 url 或 svg 字符串。其值定义为字符串或复合值。资源令牌通常用于 background-image 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  tokens: {
    assets: {
      logo: {
        value: { type: "url", value: "/static/logo.png" },
      },
      checkmark: {
        value: { type: "svg", value: "<svg>...</svg>" },
      },
    },
  },
})

export default createSystem({
  theme: { tokens },
})

时长(Durations)

时长令牌表示动画或动画循环完成所需的时间(毫秒)。其值定义为字符串。时长令牌通常用于 transition-duration 和 animation-duration 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  durations: {
    fast: { value: "100ms" },
  },
})

export default createSystem({
  theme: { tokens },
})

动画(Animations)

动画令牌表示一个 keyframe 动画。其值定义为字符串值。动画令牌通常用于 animation 属性。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  animations: {
    spin: {
      value: "spin 1s linear infinite",
    },
  },
})

export default createSystem({
  theme: { tokens },
})

宽高比(Aspect Ratios)

宽高比令牌表示元素的宽高比,其值定义为字符串。

tsx
import { defineTokens } from "@chakra-ui/react"

const tokens = defineTokens({
  aspectRatios: {
    "1:1": { value: "1 / 1" },
    "16:9": { value: "16 / 9" },
  },
})

export default createSystem({
  theme: { tokens },
})