使用高级 Chakra UI 组件,更快地进行构建 💎

了解更多
跳到内容
文档Playground指南博客
赞助商

迁移到 v3

如何从 Chakra UI v2.x 迁移到 v3.x

警告
我们建议使用LLMs.txt 文件,使 Chakra UI v3 文档可供大型语言模型使用。

步骤

所需的最低 Node 版本为 Node.20.x

1

更新包

移除未使用的包@emotion/styledframer-motion。Chakra UI 中不再需要这些包。

npm uninstall @emotion/styled framer-motion

安装更新版本的包:@chakra-ui/react@emotion/react

npm install @chakra-ui/react@latest @emotion/react@latest

接下来,使用 CLI 代码片段安装组件代码片段。代码片段提供了预构建的 Chakra 组件组合,以节省您的时间并让您掌控一切。

npx @chakra-ui/cli snippet add
2

重构自定义主题

将您的自定义主题移至专门的 theme.jstheme.ts 文件。使用 createSystemdefaultConfig 配置您的主题。

之前

import { extendTheme } from "@chakra-ui/react"

export const theme = extendTheme({
  fonts: {
    heading: `'Figtree', sans-serif`,
    body: `'Figtree', sans-serif`,
  },
})

之后

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

export const system = createSystem(defaultConfig, {
  theme: {
    tokens: {
      fonts: {
        heading: { value: `'Figtree', sans-serif` },
        body: { value: `'Figtree', sans-serif` },
      },
    },
  },
})

所有令牌值都需要用一个带有 value 键的对象包裹。在此处了解有关令牌的更多信息。

3

更新 ChakraProvider

将 ChakraProvider 的导入从 @chakra-ui/react 更新为从代码片段导入。接下来,将 theme 属性重命名为 value,以匹配新的基于系统的主题方法。

之前

import { ChakraProvider } from "@chakra-ui/react"

export const App = ({ Component }) => (
  <ChakraProvider theme={theme}>
    <Component />
  </ChakraProvider>
)

之后

import { Provider } from "@/components/ui/provider"
import { defaultSystem } from "@chakra-ui/react"

export const App = ({ Component }) => (
  <Provider>
    <Component />
  </Provider>
)
import { ColorModeProvider } from "@/components/ui/color-mode"
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"

export function Provider(props) {
  return (
    <ChakraProvider value={defaultSystem}>
      <ColorModeProvider {...props} />
    </ChakraProvider>
  )
}

如果您有自定义主题,请用自定义 system 替换 defaultSystem

Provider 组件由 Chakra 的 ChakraProvidernext-themesThemeProvider 组成

改进

  • 性能: 协调性能提升 4 倍,重新渲染性能提升 1.6 倍

  • 命名空间导入: 使用点表示法导入组件,实现更简洁的导入

    import { Accordion } from "@chakra-ui/react"
    
    const Demo = () => {
      return (
        <Accordion.Root>
          <Accordion.Item>
            <Accordion.ItemTrigger />
            <Accordion.ItemContent />
          </Accordion.Item>
        </Accordion.Root>
      )
    }
  • TypeScript: 改进了样式属性和令牌的 IntelliSense 和类型推断。

  • 多态性: 放宽了 as 属性的类型,转而使用 asChild 属性。此模式受 Radix Primitives 和 Ark UI 启发。

移除的功能

颜色模式

  • ColorModeProvideruseColorMode 已被移除,取而代之的是 next-themes
  • LightModeDarkModeColorModeScript 组件已被移除。您现在必须使用 className="light"className="dark" 来强制主题。
  • useColorModeValue 已被移除,取而代之的是 next-themes 中的 useTheme
注意
我们通过 CLI 提供了颜色模式的代码片段,帮助您使用 next-themes 快速设置颜色模式

钩子

我们移除了 hooks 包,转而使用专门、健壮的库,如 react-useusehooks-ts

我们现在只提供 useBreakpointValueuseCallbackRefuseDisclosureuseControllableStateuseMediaQuery 等钩子。

样式配置

我们移除了 styleConfigmultiStyleConfig 概念,转而使用 recipes 和 slot recipes。此模式受 Panda CSS 启发。

Next.js 包

我们移除了 @chakra-ui/next-js 包,转而使用 asChild 属性以获得更好的灵活性。

要为 Next.js 图像组件设置样式,请在 Box 组件上使用 asChild 属性。

<Box asChild>
  <NextImage />
</Box>

要为 Next.js 链接组件设置样式,请在 Link 组件上使用 asChild 属性

<Link isExternal asChild>
  <NextLink />
</Link>

主题工具

我们移除了此包,转而使用 CSS color mix。

之前

我们以前使用 JS 来解析颜色,然后应用透明度

defineStyle({
  bg: transparentize("blue.200", 0.16)(theme),
  // -> rgba(0, 0, 255, 0.16)
})

之后

我们现在使用 CSS color-mix

defineStyle({
  bg: "blue.200/16",
  // -> color-mix(in srgb, var(--chakra-colors-200), transparent 16%)
})

forwardRef

由于 as 属性的简化,我们不再提供自定义的 forwardRef。请直接使用 React 的 forwardRef

之前

import { Button as ChakraButton, forwardRef } from "@chakra-ui/react"

const Button = forwardRef<ButtonProps, "button">(function Button(props, ref) {
  return <ChakraButton ref={ref} {...props} />
})

之后

import { Button as ChakraButton } from "@chakra-ui/react"
import { forwardRef } from "react"

const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  function Button(props, ref) {
    return <ChakraButton ref={ref} {...props} />
  },
)

图标

移除了 @chakra-ui/icons 包。建议改用 lucide-reactreact-icons

Storybook 插件

我们移除了 Storybook 插件,转而使用 @storybook/addon-themeswithThemeByClassName 辅助函数。

import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
import { withThemeByClassName } from "@storybook/addon-themes"
import type { Preview, ReactRenderer } from "@storybook/react"

const preview: Preview = {
  decorators: [
    withThemeByClassName<ReactRenderer>({
      defaultTheme: "light",
      themes: {
        light: "",
        dark: "dark",
      },
    }),
    (Story) => (
      <ChakraProvider value={defaultSystem}>
        <Story />
      </ChakraProvider>
    ),
  ],
}

export default preview

移除的组件

  • StackItem: 您不再需要此组件。请改用 Box
  • FocusLock: 我们不再提供焦点锁定组件。请直接安装并使用 react-focus-lock
  • FormControl: 替换为 Field 组件。
  • FormErrorMessage: 替换为 Field.ErrorText 组件。

之前

<FormControl>
  <Input />
  <FormErrorMessage>This field is required</FormErrorMessage>
</FormControl>

之后

<Field.Root>
  <Input />
  <Field.ErrorText>This field is required</Field.ErrorText>
</Field.Root>
  • AlertDialog

    • 替换为 Dialog 组件并设置 role=alertdialog
    • leastDestructiveRef 属性设置为 Dialog.Root 组件的 initialFocusEl
  • Collapse: 替换为 Collapsible 组件。

之前

<Collapse in={isOpen} animateOpacity>
  Some content
</Collapse>

之后

<Collapsible.Root open={isOpen}>
  <Collapsible.Content>Some content</Collapsible.Content>
</Collapsible.Root>

属性更改

布尔属性

将布尔属性的命名约定从 is<X> 更改为 <x>

  • isOpen -> open
  • defaultIsOpen -> defaultOpen
  • isDisabled -> disabled
  • isInvalid -> invalid
  • isRequired -> required

ColorScheme 属性

colorScheme 属性已更改为 colorPalette

之前

  • 您只能在组件的主题中使用 colorScheme
  • colorScheme 与 HTML 元素中的原生 colorScheme 属性冲突
<Button colorScheme="blue">Click me</Button>

之后

  • 您现在可以在任何地方使用 colorPalette
<Button colorPalette="blue">Click me</Button>

在任何组件中使用,您可以这样做

<Box colorPalette="red">
  <Box bg="colorPalette.400">Some box</Box>
  <Text color="colorPalette.600">Some text</Text>
</Box>

如果您使用自定义颜色,必须定义两件事才能使 colorPalette 工作

  • tokens: 用于 50-950 颜色调色板
  • semanticTokens: 用于 solidcontrastfgmutedsubtleemphasizedfocusRing 颜色键

theme.ts

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

export const system = createSystem(defaultConfig, {
  theme: {
    tokens: {
      colors: {
        brand: {
          50: { value: "#e6f2ff" },
          100: { value: "#e6f2ff" },
          200: { value: "#bfdeff" },
          300: { value: "#99caff" },
          // ...
          950: { value: "#001a33" },
        },
      },
    },
    semanticTokens: {
      colors: {
        brand: {
          solid: { value: "{colors.brand.500}" },
          contrast: { value: "{colors.brand.100}" },
          fg: { value: "{colors.brand.700}" },
          muted: { value: "{colors.brand.100}" },
          subtle: { value: "{colors.brand.200}" },
          emphasized: { value: "{colors.brand.300}" },
          focusRing: { value: "{colors.brand.500}" },
        },
      },
    },
  },
})

在此处阅读更多相关信息。

渐变属性

渐变样式属性简化为 gradientgradientFromgradientTo 属性。这减少了解析渐变字符串的运行时性能成本,并允许更好的类型推断。

之前

<Box bgGradient="linear(to-r, red.200, pink.500)" />

之后

<Box bgGradient="to-r" gradientFrom="red.200" gradientTo="pink.500" />

颜色调色板

  • 所有组件的默认颜色调色板现在是 gray,但您可以在主题中配置它。

  • 默认主题颜色调色板的大小已增加到 11 种色调,以允许更多颜色变化。

    之前

    const colors = {
      // ...
      gray: {
        50: "#F7FAFC",
        100: "#EDF2F7",
        200: "#E2E8F0",
        300: "#CBD5E0",
        400: "#A0AEC0",
        500: "#718096",
        600: "#4A5568",
        700: "#2D3748",
        800: "#1A202C",
        900: "#171923",
      },
    }

    之后

    const colors = {
      // ...
      gray: {
        50: { value: "#fafafa" },
        100: { value: "#f4f4f5" },
        200: { value: "#e4e4e7" },
        300: { value: "#d4d4d8" },
        400: { value: "#a1a1aa" },
        500: { value: "#71717a" },
        600: { value: "#52525b" },
        700: { value: "#3f3f46" },
        800: { value: "#27272a" },
        900: { value: "#18181b" },
        950: { value: "#09090b" },
      },
    }

样式属性

更改了一些样式属性的命名约定

  • noOfLines -> lineClamp
  • truncated -> truncate
  • _activeLink -> _currentPage
  • _activeStep -> _currentStep
  • _mediaDark -> _osDark
  • _mediaLight -> _osLight

我们移除了 apply 属性,转而使用 textStylelayerStyles

嵌套样式

我们改变了 Chakra UI 组件中编写嵌套样式的方式。

之前

使用 sx__css 属性编写嵌套样式,有时无法获得嵌套样式的自动补全。

<Box
  sx={{
    svg: { color: "red.500" },
  }}
/>

之后

使用 css 属性编写嵌套样式。所有嵌套选择器都需要使用 & 符号 & 前缀

<Box
  css={{
    "& svg": { color: "red.500" },
  }}
/>

这样做有两个原因

  • 更快的样式处理: 以前我们必须检查样式键是样式属性还是选择器,这总体上相当昂贵。
  • 更好的类型: 这使得嵌套样式属性更易于强类型化

组件更改

ChakraProvider

  • 移除了 theme 属性,转而传递 system 属性。请导入 defaultSystem 模块而非 theme

  • 移除了 resetCss 属性,转而将 preflight: false 传递给 createSystem 函数

之前

<ChakraProvider resetCss={false}>
  <Component />
</ChakraProvider>

之后

const system = createSystem(defaultConfig, { preflight: false })

<Provider value={system}>
  <Component />
</Provider>
  • 移除了对配置 toast 选项的支持。请改将它传递给 components/ui/toaster.tsx 文件中的 createToaster 函数。
  • 重命名为 Dialog
  • 移除 isCentered 属性,转而使用 placement=center 属性
  • 移除了 isOpenonClose 属性,转而使用 openonOpenChange 属性

头像

  • 移除 max 属性,转而由用户控制
  • 移除多余的标签部分
  • 将与图片相关的属性移至 Avatar.Image 组件
  • 将回退图标移至 Avatar.Fallback 组件
  • name 属性移至 Avatar.Fallback 组件

Portal

  • 移除 appendToParentPortal 属性,转而使用 containerRef
  • 移除 PortalManager 组件

堆栈

  • spacing 更改为 gap
  • 移除了 StackItem,转而直接使用 Box 组件

折叠

  • Collapse 重命名为 Collapsible 命名空间
  • in 重命名为 open
  • animateOpacity 已被移除,请改用关键帧动画 expand-heightcollapse-height

之前

<Collapse in={isOpen} animateOpacity>
  Some content
</Collapse>

之后

<Collapsible.Root open={isOpen}>
  <Collapsible.Content>Some content</Collapsible.Content>
</Collapsible.Root>

图像

  • 现在渲染一个原生的 img,没有任何回退
  • 由于其引起的 SSR 问题,移除了 fallbackSrc
  • 移除 useImage 钩子
  • 移除了 Img,转而直接使用 Image 组件

密码输入

  • value, defaultValue 更改为使用 string[] 而不是 string
  • onChange 属性现在称为 onValueChange
  • 添加了新的 PinInput.ControlPinInput.Label 组件部分
  • PinInput.Root 现在默认渲染一个 div 元素。考虑与 StackGroup 结合使用以获得更好的布局控制

数字输入

  • NumberInputStepper 重命名为 NumberInput.Control
  • NumberInputStepperIncrement 重命名为 NumberInput.IncrementTrigger
  • NumberInputStepperDecrement 重命名为 NumberInput.DecrementTrigger
  • onChange 属性现在称为 onValueChange
  • 移除了 focusBorderColorerrorBorderColor,请考虑设置 --focus-color--error-color CSS 变量

之前

<NumberInput>
  <NumberInputField />
  <NumberInputStepper>
    <NumberIncrementStepper />
    <NumberDecrementStepper />
  </NumberInputStepper>
</NumberInput>

之后

<NumberInput.Root>
  <NumberInput.Input />
  <NumberInput.Control>
    <NumberInput.IncrementTrigger />
    <NumberInput.DecrementTrigger />
  </NumberInput.Control>
</NumberInput.Root>

分隔线

  • 重命名为 Separator
  • 切换到 div 元素以获得更好的布局控制
  • 简化组件,使其依赖于 borderTopWidthborderInlineStartWidth
  • 要可靠地更改厚度,请设置 --divider-border-width CSS 变量

输入框、选择框、文本域

  • 移除了 invalid 属性,转而将组件包裹在 Field 组件中。这允许轻松添加标签、错误文本和星号。

之前

<Input invalid />

之后

<Field.Root invalid>
  <Field.Label>Email</Field.Label>
  <Input />
  <Field.ErrorText>This field is required</Field.ErrorText>
</Field.Root>
  • 移除了 isExternal 属性,转而明确设置 targetrel 属性

之前

<Link isExternal>Click me</Link>

之后

<Link target="_blank" rel="noopener noreferrer">
  Click me
</Link>

按钮

  • 移除了 isActive,转而传递 data-active

之前

<Button isActive>Click me</Button>

之后

<Button data-active>Click me</Button>

图标按钮

  • 移除了 icon 属性,转而直接渲染 children 属性
  • 移除了 isRounded,转而使用 borderRadius=full 属性

加载指示器

  • thickness 属性更改为 borderWidth
  • speed 属性更改为 animationDuration

之前

<Spinner thickness="2px" speed="0.5s" />

之后

<Spinner borderWidth="2px" animationDuration="0.5s" />

上一页

安装

下一页

CLI