迁移到 v3
如何从 Chakra UI v2.x 迁移到 v3.x
步骤
¥Steps
所需的最低 Node 版本为 Node.20.x
更新软件包
¥Update Packages
删除未使用的包:@emotion/styled 和 framer-motion。Chakra UI 中不再需要这些包。
¥Remove the unused packages: @emotion/styled and framer-motion. These
packages are no longer required in Chakra UI.
npm uninstall @emotion/styled framer-motion安装以下软件包的更新版本:@chakra-ui/react 和 @emotion/react。
¥Install updated versions of the packages: @chakra-ui/react and
@emotion/react.
npm install @chakra-ui/react@latest @emotion/react@latest接下来,使用 CLI 代码片段安装组件代码片段。代码片段提供 Chakra 组件的预构建组合,以节省你的时间并让你掌控一切。
¥Next, install component snippets using the CLI snippets. Snippets provide pre-built compositions of Chakra components to save you time and put you in charge.
npx @chakra-ui/cli snippet add重构自定义主题
¥Refactor Custom Theme
将你的自定义主题移至专用的 theme.js 或 theme.ts 文件。使用 createSystem 和 defaultConfig 配置你的主题。
¥Move your custom theme to a dedicated theme.js or theme.ts file. Use
createSystem and defaultConfig to configure your theme.
修改前
¥Before
import { extendTheme } from "@chakra-ui/react"
export const theme = extendTheme({
fonts: {
heading: `'Figtree', sans-serif`,
body: `'Figtree', sans-serif`,
},
})修改后
¥After
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` },
},
},
},
})所有 token 值都需要封装在一个带有 value 键的对象中。了解更多关于 token 此处 的信息。
更新 Chakra 提供程序
¥Update ChakraProvider
将 ChakraProvider 的导入从 @chakra-ui/react 更新为代码片段中的导入。接下来,将 theme 属性重命名为 value,以匹配新的基于系统的主题方法。
¥Update the ChakraProvider import from @chakra-ui/react to the one from the
snippets. Next, rename the theme prop to value to match the new system-based
theming approach.
修改前
¥Before
import { ChakraProvider } from "@chakra-ui/react"
export const App = ({ Component }) => (
<ChakraProvider theme={theme}>
<Component />
</ChakraProvider>
)修改后
¥After
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>
)
}如果你有自定义主题,请将 defaultSystem 替换为自定义 system
Provider 组件由 Chakra 中的 ChakraProvider 和 next-themes 中的 ThemeProvider 组成。
¥The Provider component compose the ChakraProvider from Chakra and
ThemeProvider from next-themes
改进
¥Improvements
-
性能:
4x改进了协调性能,1.6x改进了重新渲染性能 -
命名空间导入:使用点符号导入组件,使导入更简洁
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。
移除的功能
¥Removed Features
颜色模式
¥Color Mode
-
ColorModeProvider和useColorMode已被移除,取而代之的是next-themes -
LightMode、DarkMode和ColorModeScript组件已被移除。现在你必须使用className="light"或className="dark"来强制主题。 -
useColorModeValue已从next-themes中移除,取而代之的是useTheme
我们通过 CLI 提供颜色模式的代码片段,以帮助你使用 next-themes 快速设置颜色模式。
¥We provide snippets for color mode via the CLI to help you set up color mode
quickly using next-themes
钩子
¥Hooks
我们删除了 hooks 包,转而使用专用的、健壮的库,例如 react-use 和 usehooks-ts。
¥We removed the hooks package in favor of using dedicated, robust libraries like
react-use and usehooks-ts
我们现在仅提供 useBreakpointValue、useCallbackRef、useDisclosure、useControllableState 和 useMediaQuery 钩子函数。
¥The only hooks we ship now are useBreakpointValue, useCallbackRef,
useDisclosure, useControllableState and useMediaQuery.
样式配置
¥Style Config
我们删除了 styleConfig 和 multiStyleConfig 概念,转而使用配方和插槽配方。此模式的灵感来自 Panda CSS。
¥We removed the styleConfig and multiStyleConfig concept in favor of recipes
and slot recipes. This pattern was inspired by Panda CSS.
Next.js 包
¥Next.js package
我们已移除 @chakra-ui/next-js 包,转而使用 asChild 属性,以提高灵活性。
¥We've removed the @chakra-ui/next-js package in favor of using the asChild
prop for better flexibility.
要设置 Next.js 图片组件的样式,请在 Box 组件上使用 asChild 属性。
¥To style the Next.js image component, use the asChild prop on the Box
component.
<Box asChild>
<NextImage />
</Box>
要设置 Next.js 链接组件的样式,请在 Link 组件上使用 asChild 属性。
¥To style the Next.js link component, use the asChild prop on the Link
component
<Link isExternal asChild>
<NextLink />
</Link>
主题工具
¥Theme Tools
我们已移除此包,转而使用 CSS 颜色混合。
¥We've removed this package in favor using CSS color mix.
修改前
¥Before
我们使用 JS 解析颜色,然后应用透明度。
¥We used JS to resolve the colors and then apply the transparency
defineStyle({
bg: transparentize("blue.200", 0.16)(theme),
// -> rgba(0, 0, 255, 0.16)
})
修改后
¥After
我们现在使用 CSS color-mix
¥We now use CSS color-mix
defineStyle({
bg: "blue.200/16",
// -> color-mix(in srgb, var(--chakra-colors-200), transparent 16%)
})
forwardRef
由于 as 属性的简化,我们不再提供自定义 forwardRef。建议直接使用 React 中的 forwardRef。
¥Due to the simplification of the as prop, we no longer provide a custom
forwardRef. Prefer to use forwardRef from React directly.
修改前:
¥Before:
import { Button as ChakraButton, forwardRef } from "@chakra-ui/react"
const Button = forwardRef<ButtonProps, "button">(function Button(props, ref) {
return <ChakraButton ref={ref} {...props} />
})
修改后:
¥After:
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} />
},
)
图标
¥Icons
已删除 @chakra-ui/icons 包。建议改用 lucide-react 或 react-icons。
¥Removed @chakra-ui/icons package. Prefer to use lucide-react or
react-icons instead.
Storybook 插件
¥Storybook Addon
我们已移除 Storybook 插件,转而使用 @storybook/addon-themes 和 withThemeByClassName 助手。
¥We're removed the storybook addon in favor of using @storybook/addon-themes
and withThemeByClassName helper.
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
移除的组件
¥Removed Components
-
堆栈项:你不再需要这样做。请改用
Box。 -
FocusLock:我们不再提供焦点锁定组件。直接安装并使用
react-focus-lock。 -
AlertDialog
-
用
Dialog组件替换并设置role=alertdialog -
将
leastDestructiveRef属性设置为initialFocusEl到Dialog.Root组件
-
CircularProgress
-
重命名为
ProgressCircle,现在使用复合组件。 -
isIndeterminate变为value={null} -
thickness属性变为--thicknessCSS 变量 -
color属性在ProgressCircle.Range上变为stroke属性
修改前:
¥Before:
<CircularProgress
value={75}
thickness="4px"
color="blue.500"
isIndeterminate={false}
/>
修改后:
¥After:
<ProgressCircle.Root value={75}>
<ProgressCircle.Circle css={{ "--thickness": "4px" }}>
<ProgressCircle.Track />
<ProgressCircle.Range stroke="blue.500" />
</ProgressCircle.Circle>
</ProgressCircle.Root>
不确定进度:
¥For indeterminate progress:
<ProgressCircle.Root value={null}>
<ProgressCircle.Circle>
<ProgressCircle.Track />
<ProgressCircle.Range />
</ProgressCircle.Circle>
</ProgressCircle.Root>
StackDivider
-
不再作为单独的组件提供
-
在堆叠项目之间使用显式
Stack.Separator组件
修改前:
¥Before:
<VStack divider={<StackDivider borderColor="gray.200" />} spacing={4}>
<Box>Item 1</Box>
<Box>Item 2</Box>
<Box>Item 3</Box>
</VStack>
修改后:
¥After:
<VStack gap={4}>
<Box>Item 1</Box>
<Stack.Separator borderColor="gray.200" />
<Box>Item 2</Box>
<Stack.Separator borderColor="gray.200" />
<Box>Item 3</Box>
</VStack>
属性变化
¥Prop Changes
布尔属性
¥Boolean Props
将布尔属性的命名约定从 is<X> 更改为 <x>
¥Changed naming convention for boolean properties from is<X> to <x>
-
isOpen->open -
defaultIsOpen->defaultOpen -
isDisabled->disabled -
isInvalid->invalid -
isRequired->required
配色方案属性
¥ColorScheme Prop
colorScheme 属性已更改为 colorPalette
¥The colorScheme prop has been changed to colorPalette
修改前
¥Before
-
你只能在组件的主题中使用
colorScheme。 -
colorScheme与 HTML 元素中的原生colorScheme属性冲突
<Button colorScheme="blue">Click me</Button>
修改后
¥After
- 你现在可以在任何地方使用
colorPalette。
<Button colorPalette="blue">Click me</Button>
在任何组件中的用法,你可以执行以下操作:
¥Usage in any component, you can do something like:
<Box colorPalette="red">
<Box bg="colorPalette.400">Some box</Box>
<Text color="colorPalette.600">Some text</Text>
</Box>
如果你使用自定义颜色,则必须定义两件事才能使 colorPalette 正常工作:
¥If you are using custom colors, you must define two things to make
colorPalette work:
-
tokens
50-950 调色板 -
semanticTokens
solid、contrast、fg、muted、subtle、emphasized和focusRing颜色键
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}" },
},
},
},
},
})了解更多关于 此处 的信息。
渐变属性
¥Gradient Props
渐变样式属性简化为 gradient、gradientFrom 和 gradientTo 属性。这降低了解析渐变字符串的运行时性能成本,并允许更好的类型推断。
¥Gradient style prop simplified to gradient and gradientFrom and gradientTo
props. This reduces the runtime performance cost of parsing the gradient string,
and allows for better type inference.
修改前
¥Before
<Box bgGradient="linear(to-r, red.200, pink.500)" />
修改后
¥After
<Box bgGradient="to-r" gradientFrom="red.200" gradientTo="pink.500" />
调色板
¥Color Palette
-
现在所有组件的默认调色板均为
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",
},
}
修改后
¥After
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" },
},
}
样式属性
¥Style Props
更改了部分样式属性的命名约定
¥Changed the naming convention for some style props
-
noOfLines->lineClamp -
truncated->truncate -
_activeLink->_currentPage -
_activeStep->_currentStep -
_mediaDark->_osDark -
_mediaLight->_osLight
示例:
¥Examples:
// Before
<Text noOfLines={2}>
Long text that will be clamped to 2 lines
</Text>
<Text truncated>
This text will be truncated with ellipsis
</Text>
// After
<Text lineClamp={2}>
Long text that will be clamped to 2 lines
</Text>
<Text truncate>
This text will be truncated with ellipsis
</Text>
我们删除了 apply 属性,转而使用 textStyle 或 layerStyles。
¥We removed the apply prop in favor of textStyle or layerStyles
嵌套样式
¥Nested Styles
我们改变了在 Chakra UI 组件中编写嵌套样式的方式。
¥We have changed the way you write nested styles in Chakra UI components.
修改前
¥Before
使用 sx 或 __css 属性编写嵌套样式,有时嵌套样式无法自动补齐。
¥Write nested styles using the sx or __css prop, and you sometimes don't get
auto-completion for nested styles.
<Box
sx={{
svg: { color: "red.500" },
}}
/>
修改后
¥After
使用 css 属性编写嵌套样式。所有嵌套选择器都需要使用 & 符号 & 前缀。
¥Write nested styles using the css prop. All nested selectors require the
use of the ampersand & prefix
<Box
css={{
"& svg": { color: "red.500" },
}}
/>
这样做有两个原因:
¥This was done for two reasons:
-
更快的样式处理:之前我们必须检查样式键是样式属性还是选择器,这总体来说开销很大。
-
更好的输入:这更容易键入嵌套的样式属性,使其具有强类型
组件更改
¥Component Changes
ChakraProvider
-
移除
theme属性,改为传递system属性。导入defaultSystem模块而不是theme -
移除
resetCss属性,改为将preflight: false属性传递给createSystem函数。
修改前
¥Before
<ChakraProvider resetCss={false}>
<Component />
</ChakraProvider>
修改后
¥After
const system = createSystem(defaultConfig, { preflight: false })
<Provider value={system}>
<Component />
</Provider>
- 移除了对配置提示框选项的支持。请将其传递给
components/ui/toaster.tsx文件中的createToaster函数。
模态窗口
¥Modal
-
已重命名为
Dialog -
移除
isCentered属性,以便使用placement=center属性。 -
移除
isOpen和onClose属性,改为使用open和onOpenChange属性。
头像
¥Avatar
-
移除
max属性,以便用户空间控制。 -
删除多余的标签部分
-
将图片相关属性移至
Avatar.Image组件 -
将后备图标移至
Avatar.Fallback组件 -
将
name属性移至Avatar.Fallback组件
门户
¥Portal
-
移除
appendToParentPortal属性,以便使用containerRef属性。 -
删除
PortalManager组件
进度
¥Progress
-
现在可以使用带有
Progress.Root、Progress.Track和Progress.Range的复合组件 -
hasStripe属性重命名为striped -
isAnimated属性重命名为animated -
colorScheme属性重命名为colorPalette
修改前:
¥Before:
<Progress hasStripe isAnimated value={75} colorScheme="blue" />
修改后:
¥After:
<Progress.Root striped animated value={75} colorPalette="blue">
<Progress.Track>
<Progress.Range />
</Progress.Track>
</Progress.Root>
堆叠
¥Stack
-
将
spacing更改为gap -
移除
StackItem属性,改为直接使用Box组件。
选择
¥Select
现在称为 NativeSelect,并公开所有部分。
¥Now called NativeSelect and exposes all parts now.
修改前:
¥Before:
<Select placeholder="Select option">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</Select>
修改后:
¥After:
<NativeSelect.Root size="sm" width="240px">
<NativeSelect.Field placeholder="Select option">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
更改图标
¥Changing the icon
修改前:
¥Before:
<Select icon={<MdArrowDropDown />} placeholder="Woohoo! A new icon" />
修改后:
¥After:
<NativeSelect.Indicator>
<MdArrowDropDown />
</NativeSelect.Indicator>
收起
¥Collapse
-
将
Collapse重命名为Collapsible命名空间 -
将
in重命名为open -
animateOpacity已被移除,请使用关键帧动画expand-height和collapse-height代替
修改前
¥Before
<Collapse in={isOpen} animateOpacity>
Some content
</Collapse>
修改后
¥After
<Collapsible.Root open={isOpen}>
<Collapsible.Content>Some content</Collapsible.Content>
</Collapsible.Root>
图片
¥Image
-
现在渲染原生
img,没有任何回退。 -
移除
fallbackSrc,因为它会导致服务器端渲染 (SSR) 问题。 -
删除
useImage钩子 -
移除
Img,以便直接使用Image组件。
PinInput
-
将
value和defaultValue更改为使用string[]而不是string -
onChange属性现为onValueChange -
添加新的
PinInput.Control和PinInput.Label组件 -
PinInput.Root现在默认渲染div元素。考虑与Stack或Group结合使用以获得更好的布局控制。 -
onComplete属性现为onValueComplete
NumberInput
-
将
NumberInputStepper重命名为NumberInput.Control -
将
NumberInputStepperIncrement重命名为NumberInput.IncrementTrigger -
将
NumberInputStepperDecrement重命名为NumberInput.DecrementTrigger -
onChange属性现为onValueChange -
移除
focusBorderColor和errorBorderColor,考虑改为设置--focus-color和--error-colorcss 变量。 -
onInvalid属性现为onValueInvalid -
parse和format属性已被移除,取而代之的是formatOptions属性
修改前
¥Before
<NumberInput>
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
修改后
¥After
<NumberInput.Root>
<NumberInput.Input />
<NumberInput.Control>
<NumberInput.IncrementTrigger />
<NumberInput.DecrementTrigger />
</NumberInput.Control>
</NumberInput.Root>
分隔符
¥Divider
-
重命名为
Separator -
切换到
div元素以获得更好的布局控制 -
简化组件以依赖
borderTopWidth和borderInlineStartWidth。 -
要可靠地更改宽度,请设置
--divider-border-widthCSS 变量。
输入框、选择框、文本框
¥Input, Select, Textarea
- 移除
invalid属性,改为将组件封装在Field组件中。这允许轻松添加标签、错误文本和星号。
修改前
¥Before
<Input invalid />
修改后
¥After
<Field.Root invalid>
<Field.Label>Email</Field.Label>
<Input />
<Field.ErrorText>This field is required</Field.ErrorText>
</Field.Root>
链接
¥Link
- 移除
isExternal属性,改为明确设置target和rel属性。
修改前
¥Before
<Link isExternal>Click me</Link>
修改后
¥After
<Link target="_blank" rel="noopener noreferrer">
Click me
</Link>
按钮
¥Button
- 移除
isActive属性,改为传递data-active属性。
修改前
¥Before
<Button isActive>Click me</Button>
修改后
¥After
<Button data-active>Click me</Button>
IconButton
-
移除
icon属性,改为直接渲染children属性。 -
移除
isRounded属性,改为使用borderRadius=full属性。
旋转器
¥Spinner
-
将
thickness属性更改为borderWidth -
将
speed属性更改为animationDuration
修改前
¥Before
<Spinner thickness="2px" speed="0.5s" />
修改后
¥After
<Spinner borderWidth="2px" animationDuration="0.5s" />
对话框,抽屉
¥Dialog, Drawer
-
isOpen和onChange属性已被移除,取而代之的是open和onOpenChange属性 -
blockScrollOnMount现在是preventScroll -
closeOnEsc现在是closeOnEscape -
closeOnOverlayClick现在是closeOnInteractOutside -
initialFocusRef现在是返回元素的initialFocusEl函数 -
finalFocusRef现在是返回元素的finalFocusEl函数
可编辑
¥Editable
-
finalFocusRef现在是返回元素的finalFocusEl函数 -
isDisabled现在是disabled -
onSubmit现在是onValueCommit -
onCancel现在是onValueRevert -
onChange现在是onValueChange -
startWithEditView现在是defaultEdit -
将
submitOnBlur替换为submitMode
FormControl
-
用
Field组件替换FormControl。 -
用
Field.ErrorText组件替换FormErrorMessage。
修改前:
¥Before:
<FormControl>
<Input />
<FormErrorMessage>This field is required</FormErrorMessage>
</FormControl>
修改后:
¥After:
<Field.Root>
<Input />
<Field.ErrorText>This field is required</Field.ErrorText>
</Field.Root>
收起
¥Collapse
用 Collapsible 组件替换。
¥Replace with the Collapsible component.
修改前:
¥Before:
<Collapse in={isOpen} animateOpacity>
Some content
</Collapse>
修改后:
¥After:
<Collapsible.Root open={isOpen}>
<Collapsible.Content>Some content</Collapsible.Content>
</Collapsible.Root>
滑块
¥Slider
-
onChange属性现为onValueChange -
onChangeEnd属性现为onValueChangeEnd -
onChangeStart属性现已移除 -
isReversed属性现已移除
RangeSlider
现在可以通过传递值数组将其用作单个滑块。
¥Can now be used as a single slider by passing an array of values
修改前:
¥Before:
<RangeSlider defaultValue={[10, 30]}>
<RangeSliderTrack>
<RangeSliderFilledTrack />
</RangeSliderTrack>
<RangeSliderThumb index={0} />
<RangeSliderThumb index={1} />
</RangeSlider>
修改后:
¥After:
<Slider.Root defaultValue={[10, 30]}>
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumbs />
</Slider.Control>
</Slider.Root>
表格
¥Table
-
TableContainer现在是Table.ScrollArea -
Td(现称为Table.ColumnHeader)isNumeric现为textAlign="end"
复合组件已略微重命名。
¥The compound component have been renamed slightly.
修改前:
¥Before:
<Table variant="simple">
<TableCaption>Imperial to metric conversion factors</TableCaption>
<Thead>
<Tr>
<Th>Product</Th>
<Th>Category</Th>
<Th isNumeric>Price</Th>
</Tr>
</Thead>
<Tbody>
{items.map((item) => (
<Tr key={item.id}>
<Td>{item.name}</Td>
<Td>{item.category}</Td>
<Td isNumeric>{item.price}</Td>
</Tr>
))}
</Tbody>
<Tfoot>
<Tr>
<Th>Product</Th>
<Th>Category</Th>
<Th isNumeric>Price</Th>
</Tr>
</Tfoot>
</Table>
修改后:
¥After:
<Table.Root size="sm">
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Product</Table.ColumnHeader>
<Table.ColumnHeader>Category</Table.ColumnHeader>
<Table.ColumnHeader textAlign="end">Price</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
{items.map((item) => (
<Table.Row key={item.id}>
<Table.Cell>{item.name}</Table.Cell>
<Table.Cell>{item.category}</Table.Cell>
<Table.Cell textAlign="end">{item.price}</Table.Cell>
</Table.Row>
))}
</Table.Body>
</Table.Root>
标签
¥Tag
TagLeftIcon 和 TagRightIcon 现在是 Tag.StartElement 和 Tag.EndElement
¥TagLeftIcon and TagRightIcon are now Tag.StartElement and Tag.EndElement
修改前:
¥Before:
<Tag>
<TagLeftIcon boxSize="12px" as={AddIcon} />
<TagLabel>Cyan</TagLabel>
<TagRightIcon boxSize="12px" as={AddIcon} />
</Tag>
修改后:
¥After:
<Tag.Root>
<Tag.StartElement>
<AddIcon />
</Tag.StartElement>
<Tag.Label>Cyan</Tag.Label>
<Tag.EndElement>
<AddIcon />
</Tag.EndElement>
</Tag.Root>
TagCloseButton现在是Tag.CloseTrigger
修改前:
¥Before:
<Tag>
<TagLabel>Green</TagLabel>
<TagCloseButton />
</Tag>
修改后:
¥After:
<Tag.Root>
<Tag.Label>Green</Tag.Label>
<Tag.CloseTrigger />
</Tag.Root>
警报
¥Alert
AlertIcon现在是Alert.Indicator
修改前:
¥Before:
<Alert>
<AlertIcon />
<AlertTitle>Your browser is outdated!</AlertTitle>
<AlertDescription>Your Chakra experience may be degraded.</AlertDescription>
</Alert>
修改后:
¥After:
<Alert.Root status="error">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Invalid Fields</Alert.Title>
<Alert.Description>
Your form has some errors. Please fix them and try again.
</Alert.Description>
</Alert.Content>
</Alert.Root>
- 移除
addRole属性,替换为role属性。
骨架
¥Skeleton
startColor和endColor属性现在使用 CSS 变量
修改前:
¥Before:
<Skeleton startColor="pink.500" endColor="orange.500" />
修改后:
¥After:
<Skeleton
css={{
"--start-color": "colors.pink.500",
"--end-color": "colors.orange.500",
}}
/>
isLoaded属性现为loading
修改前:
¥Before:
<Skeleton isLoaded>
<span>Chakra ui is cool</span>
</Skeleton>
修改后:
¥After:
<Skeleton loading={false}>
<span>Chakra ui is cool</span>
</Skeleton>
菜单
¥Menu
- 现在到处都可以使用复合组件
修改前:
¥Before:
<Menu>
<MenuButton as={Button} rightIcon={<ChevronDownIcon />}>
Actions
</MenuButton>
<MenuList>
<MenuItem>Download</MenuItem>
<MenuItem>Create a Copy</MenuItem>
</MenuList>
</Menu>
修改后:
¥After:
<Menu.Root>
<Menu.Trigger asChild>
<Button>
Actions
<ChevronDownIcon />
</Button>
</Menu.Trigger>
<Portal>
<Menu.Positioner>
<Menu.Content>
<Menu.Item value="download">Download</Menu.Item>
<Menu.Item value="copy">Create a Copy</Menu.Item>
</Menu.Content>
</Menu.Positioner>
</Portal>
</Menu.Root>
- 现在通过
Menu.Context访问内部状态,不再通过 render 属性。
修改前:
¥Before:
<Menu>
{({ isOpen }) => (
<>
<MenuButton isActive={isOpen} as={Button} rightIcon={<ChevronDownIcon />}>
{isOpen ? "Close" : "Open"}
</MenuButton>
<MenuList>
<MenuItem>Download</MenuItem>
<MenuItem onClick={() => alert("Kagebunshin")}>Create a Copy</MenuItem>
</MenuList>
</>
)}
</Menu>
修改后:
¥After:
<Menu.Root>
<Menu.Context>
{(menu) => (
<Menu.Trigger asChild>
<Button>
{menu.open ? "Close" : "Open"}
<ChevronDownIcon />
</Button>
</Menu.Trigger>
)}
</Menu.Context>
<Portal>
<Menu.Positioner>
<Menu.Content>
<Menu.Item value="download">Download</Menu.Item>
<Menu.Item value="copy" onSelect={() => alert("Kagebunshin")}>
Create a Copy
</Menu.Item>
</Menu.Content>
</Menu.Positioner>
</Portal>
</Menu.Root>
-
Menu上的isLazy属性已拆分为lazyMount和Menu.Root上的unmountOnExit -
MenuOptionGroup现在拆分为Menu.RadioItemGroup和Menu.CheckboxItemGroup,以分别处理状态。
修改前:
¥Before:
<Menu>
<MenuButton as={Button}>Trigger</MenuButton>
<MenuList>
<MenuOptionGroup defaultValue="asc" title="Order" type="radio">
<MenuItemOption value="asc">Ascending</MenuItemOption>
<MenuItemOption value="desc">Descending</MenuItemOption>
</MenuOptionGroup>
<MenuDivider />
<MenuOptionGroup title="Country" type="checkbox">
<MenuItemOption value="email">Email</MenuItemOption>
<MenuItemOption value="phone">Phone</MenuItemOption>
<MenuItemOption value="country">Country</MenuItemOption>
</MenuOptionGroup>
</MenuList>
</Menu>
修改后:
¥After:
<Menu.Root>
<Menu.Trigger asChild>
<Button>Trigger</Button>
</Menu.Trigger>
<Portal>
<Menu.Positioner>
<Menu.Content minW="10rem">
<Menu.RadioItemGroup defaultValue="asc">
<Menu.RadioItem value="asc">Ascending</Menu.RadioItem>
<Menu.RadioItem value="desc">Descending</Menu.RadioItem>
</Menu.RadioItemGroup>
<Menu.CheckboxItemGroup defaultValue={["email"]}>
<Menu.CheckboxItem value="email">Email</Menu.CheckboxItem>
<Menu.CheckboxItem value="phone">Phone</Menu.CheckboxItem>
<Menu.CheckboxItem value="country">Country</Menu.CheckboxItem>
</Menu.CheckboxItemGroup>
</Menu.Content>
</Menu.Positioner>
</Portal>
</Menu.Root>
工具提示
¥Tooltip
-
closeOnEsc现已重命名为closeOnEscape -
closeOnMouseDown现在是closeOnPointerDown -
Tooltip上的placement、gutter、offset和arrow现在包含在Tooltip.Root上的positioning属性中
修改前:
¥Before:
<Tooltip placement="top" />
修改后:
¥After:
<Tooltip.Root positioning={{ placement: "top" }} />
折叠面板
¥Accordion
-
以下属性已更改:
-
allowMultiple->multiple -
allowToggle->collapsible -
index->value -
defaultIndex->defaultValue
-
修改前:
¥Before:
<Accordion allowMultiple index={[0]} onChange={() => {}} />
修改后:
¥After:
<Accordion multiple value={["0"]} onValueChange={() => {}} />
-
AccordionButton现在是Accordion.Trigger -
AccordionIcon现在是Accordion.ItemIndicator
修改前:
¥Before:
<AccordionButton>Section 1 title</AccordionButton>
修改后:
¥After:
<Accordion.Trigger>Section 1 title</Accordion.Trigger>
标签
¥Tabs
- 组件结构已更改,现在列表和面板上都需要
value属性。
修改前:
¥Before:
<Tabs>
<TabList>
<Tab>One</Tab>
<Tab>Two</Tab>
<Tab>Three</Tab>
</TabList>
<TabPanels>
<TabPanel>one!</TabPanel>
<TabPanel>two!</TabPanel>
<TabPanel>three!</TabPanel>
</TabPanels>
</Tabs>
修改后:
¥After:
<Tabs.Root>
<Tabs.List>
<Tabs.Trigger value="one">One</Tabs.Trigger>
<Tabs.Trigger value="two">Two</Tabs.Trigger>
<Tabs.Trigger value="three">Three</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="one">one!</Tabs.Content>
<Tabs.Content value="two">two!</Tabs.Content>
<Tabs.Content value="three">three!</Tabs.Content>
</Tabs.Root>
defaultIndex、index和onChange现在分别为defaultValue、value和onValueChange
修改前:
¥Before:
<Tabs defaultIndex={0} index={0} onChange={(index) => {}} />
修改后:
¥After:
<Tabs defaultValue={0} value={0} onValueChange={({ value }) => {}} />
Tabs上的isLazy属性现为lazyMount,Tabs.Root上的unmountOnExit
修改前:
¥Before:
<Tabs isLazy />
修改后:
¥After:
<Tabs.Root lazyMount unmountOnExit />
显示和隐藏
¥Show and Hide
Show和Hide组件已被移除,取而代之的是hideFrom和hideBelow
修改前:
¥Before:
<Show below="md">
This text appears only on screens md and smaller.
</Show>
<Hide below="md">
This text hides at the "md" value screen width and smaller.
</Hide>
修改后:
¥After:
<Box hideBelow="md">
This text hides at the "md" value screen width and smaller.
</Box>
<Box hideFrom="md">
This text appears only on screens md and larger.
</Box>
复选框
¥Checkbox
- 已重构以使用复合组件
修改前:
¥Before:
<Checkbox defaultChecked>Checkbox</Checkbox>
修改后:
¥After:
<Checkbox.Root defaultChecked>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label>Checkbox</Checkbox.Label>
</Checkbox.Root>
单选按钮组
¥Radio Group
- 已重构以使用复合组件
修改前:
¥Before:
<RadioGroup defaultValue="2">
<Radio value="1">Radio</Radio>
<Radio value="2">Radio</Radio>
</RadioGroup>
修改后:
¥After:
<RadioGroup.Root defaultValue="2">
<RadioGroup.Item value="1">
<RadioGroup.ItemHiddenInput />
<RadioGroup.ItemIndicator />
<RadioGroup.ItemText />
</RadioGroup.Item>
</RadioGroup.Root>
按钮属性
¥Button Props
-
isActive→data-active属性 -
isDisabled→disabled -
isLoading→loading -
leftIcon和rightIcon→ 作为子元素传递 -
iconSpacing→ 已移除(在弹性布局中使用间隙) -
colorScheme→colorPalette
示例:
¥Example:
// Before
<Button
isActive={true}
isDisabled={false}
isLoading={true}
leftIcon={<Icon />}
rightIcon={<Icon />}
colorScheme="blue"
>
Submit
</Button>
// After
<Button
data-active=""
disabled={false}
loading={true}
colorPalette="blue"
>
<LeftIcon />
Submit
<RightIcon />
</Button>
输入框属性
¥Input Props
-
isDisabled→disabled -
isInvalid→invalid -
isReadOnly→readOnly -
isRequired→required -
colorScheme→colorPalette -
focusBorderColor→ 使用 CSS 变量 -
errorBorderColor→ 使用 CSS 变量
示例:
¥Example:
// Before
<Input
isDisabled={false}
isInvalid={true}
isReadOnly={false}
isRequired={true}
colorScheme="blue"
focusBorderColor="blue.500"
errorBorderColor="red.500"
/>
// After
<Input
disabled={false}
invalid={true}
readOnly={false}
required={true}
colorPalette="blue"
style={{
"--focus-color": "blue.500",
"--error-color": "red.500"
}}
/>
复选框属性
¥Checkbox Props
-
isChecked→checked -
isDisabled→disabled -
isInvalid→invalid -
isIndeterminate→indeterminate(在指示器上) -
colorScheme→colorPalette -
iconColor→ 已移除(使用 CSS) -
iconSize→ 已移除(使用 CSS) -
spacing→ 已移除(使用间隙)
示例:
¥Example:
// Before
<Checkbox
isChecked={true}
isDisabled={false}
isInvalid={true}
isIndeterminate={true}
colorScheme="blue"
>
Accept terms
</Checkbox>
// After
<Checkbox.Root
checked={true}
disabled={false}
invalid={true}
colorPalette="blue"
>
<Checkbox.Control>
<Checkbox.Indicator indeterminate={true} />
</Checkbox.Control>
<Checkbox.Label>Accept terms</Checkbox.Label>
</Checkbox.Root>
模态窗口到对话框的属性
¥Modal to Dialog Props
-
isOpen→open -
onClose→onOpenChange(不同签名) -
isCentered→placement="center" -
scrollBehavior→ 相同 -
motionPreset→ 已更新值(例如,slideInBottom→slide-in-bottom) -
closeOnOverlayClick→closeOnInteractOutside -
closeOnEsc→closeOnEscape -
blockScrollOnMount→preventScroll -
returnFocusOnClose→restoreFocus -
initialFocusRef→initialFocusEl(函数) -
finalFocusRef→finalFocusEl(函数)
示例:
¥Example:
// Before
<Modal
isOpen={isOpen}
onClose={onClose}
isCentered={true}
closeOnOverlayClick={true}
initialFocusRef={initialRef}
>
<ModalOverlay />
<ModalContent>
<ModalHeader>Title</ModalHeader>
<ModalBody>Content</ModalBody>
</ModalContent>
</Modal>
// After
<Dialog.Root
open={isOpen}
onOpenChange={(e) => !e.open && onClose()}
placement="center"
closeOnInteractOutside={true}
initialFocusEl={() => initialRef.current}
>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Title</Dialog.Title>
</Dialog.Header>
<Dialog.Body>Content</Dialog.Body>
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
堆叠属性
¥Stack Props
-
spacing→gap -
divider→separator -
其他属性保持不变
示例:
¥Example:
// Before
<Stack
spacing="4"
divider={<StackDivider />}
>
<Box>Item 1</Box>
<Box>Item 2</Box>
</Stack>
// After
<Stack
gap="4"
separator={<Stack.Separator />}
>
<Box>Item 1</Box>
<Box>Item 2</Box>
</Stack>