使用高级 Chakra UI 组件,更快地构建 💎
了解更多2025年4月1日
在本指南中,我们将学习如何使用 Chakra UI 的样式系统为外部库设置样式。
随着 Ark UI、Radix UI 等无头组件库的兴起,通常会希望在使用它们的同时,也使用 Chakra UI 来设置样式。
假设我们想为 Ark UI(一个无头组件库)的 Carousel 组件设置样式。
首先安装 React 版本的 Ark UI
npm install @ark-ui/react
Ark UI 将每个无头组件分解为更小、功能性的部分。例如,轮播组件的一些部分(https://ark-ui.com/react/docs/components/carousel#anatomy)将会是
Root
: 轮播的根组件Item
: 轮播的项组件PrevTrigger
: 轮播的上一个触发器组件NextTrigger
: 轮播的下一个触发器组件每个部分都非常灵活,可以独立设置样式。一旦您了解了每个部分的作用,就可以更容易地为这些部分添加自定义样式。
import { Carousel } from "@ark-ui/react/carousel"
const images = Array.from(
{ length: 5 },
(_, i) => `https://picsum.photos/seed/${i + 1}/500/300`,
)
export const Demo = () => {
return (
<Carousel.Root defaultPage={0} slideCount={images.length}>
<Carousel.Control>
<Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
<Carousel.NextTrigger>Next</Carousel.NextTrigger>
</Carousel.Control>
<Carousel.IndicatorGroup>
{images.map((_, index) => (
<Carousel.Indicator key={index} index={index} />
))}
</Carousel.IndicatorGroup>
<Carousel.ItemGroup>
{images.map((image, index) => (
<Carousel.Item key={index} index={index}>
<img src={image} alt={`Slide ${index}`} />
</Carousel.Item>
))}
</Carousel.ItemGroup>
</Carousel.Root>
)
}
一种可以轻松为无头原始组件设置样式的方法是将其包裹在 chakra
工厂函数中。
使用工厂函数,您可以将样式对象或样式配方应用于组件。
components/ui/carousel.tsx
import { Carousel as ArkCarousel } from "@ark-ui/react/carousel"
import { chakra } from "@chakra-ui/react"
const CarouselRoot = chakra(ArkCarousel.Root, {
base: {
display: "flex",
flexDirection: "column",
alignItems: "center",
},
variants: {},
})
const CarouselItem = chakra(ArkCarousel.Item, {
base: {
width: "100%",
height: "100%",
},
})
const CarouselIndicatorGroup = chakra(ArkCarousel.IndicatorGroup, {
base: {
display: "flex",
gap: 2,
},
})
const CarouselIndicator = chakra(ArkCarousel.Indicator, {
base: {
borderRadius: "full",
bg: "bg.subtle",
_selected: {
bg: "teal.solid",
},
},
variants: {
size: {
sm: {
width: 3,
height: 3,
},
md: {
width: 4,
height: 4,
},
},
},
})
const CarouselItemGroup = chakra(ArkCarousel.ItemGroup, {
base: {
display: "flex",
gap: 2,
},
})
export const Carousel = {
Root: CarouselRoot,
IndicatorGroup: CarouselIndicatorGroup,
Indicator: CarouselIndicator,
ItemGroup: CarouselItemGroup,
Item: CarouselItem,
NextTrigger: ArkCarousel.NextTrigger,
PrevTrigger: ArkCarousel.PrevTrigger,
}
现在我们有了样式化组件,可以在应用程序中使用它们。
对于 PrevTrigger
和 NextTrigger
组件,我们可以将它们渲染为 Chakra UI 的 IconButton
组件。
pages/index.tsx
import { Carousel } from "@/components/ui/carousel"
import { IconButton } from "@chakra-ui/react"
import { LuArrowLeft, LuArrowRight } from "react-icons/lu"
const images = Array.from(
{ length: 5 },
(_, i) => `https://picsum.photos/seed/${i + 1}/500/300`,
)
export const Demo = () => {
return (
<Carousel.Root defaultPage={0} slideCount={images.length}>
<Carousel.Control>
<Carousel.PrevTrigger asChild>
<IconButton>
<LuArrowLeft />
</IconButton>
</Carousel.PrevTrigger>
<Carousel.NextTrigger asChild>
<IconButton>
<LuArrowRight />
</IconButton>
</Carousel.NextTrigger>
</Carousel.Control>
<Carousel.IndicatorGroup>
{images.map((_, index) => (
<Carousel.Indicator key={index} index={index} />
))}
</Carousel.IndicatorGroup>
<Carousel.ItemGroup>
{images.map((image, index) => (
<Carousel.Item key={index} index={index}>
<img src={image} alt={`Slide ${index}`} />
</Carousel.Item>
))}
</Carousel.ItemGroup>
</Carousel.Root>
)
}
就是这样!您现在已经使用 Chakra UI 为无头组件库设置了样式。