在 Shadow DOM 中使用 Chakra UI
在 Shadow DOM 中安装 Chakra UI 的指南
在为浏览器开发扩展或将 Chakra 作为大型项目的一部分使用时,利用 Shadow DOM 对于样式和逻辑封装非常有用。
模板
使用以下模板快速开始
安装
所需的最低节点版本为 Node.20.x
1
安装依赖项
npm i @chakra-ui/react @emotion/react @emotion/cache react-shadow
使用的额外包有
react-shadow
用于轻松创建 Shadow DOM@emotion/cache
用于为样式创建自定义插入点
2
3
更新 tsconfig
如果您使用 TypeScript,您需要更新 tsconfig 文件中的 compilerOptions
以包含以下选项
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
}
}
}
4
配置样式引擎
在项目根目录中创建 system.ts
文件并配置样式引擎。
components/ui/system.ts
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
const varRoot = ":host"
const config = defineConfig({
cssVarsRoot: varRoot,
conditions: {
light: `${varRoot} &, .light &`,
},
preflight: { scope: varRoot },
globalCss: {
[varRoot]: defaultConfig.globalCss?.html ?? {},
},
})
export const system = createSystem(defaultConfig, config)
须知: system.ts
文件的主要目的是配置样式引擎以定位 Shadow DOM。
5
设置 Provider
使用 Provider
组件更新生成的 components/ui/provider
组件。
此 provider 包含以下内容
- 来自
@chakra-ui/react
的ChakraProvider
用于样式系统 - 来自
react-shadow
的EnvironmentProvider
以确保 Chakra 组件正确查询 DOM - 来自
@emotion/react
的CacheProvider
用于提供自定义插入点 - 来自
next-themes
的ThemeProvider
用于颜色模式
components/ui/provider.tsx
"use client"
import { ChakraProvider, EnvironmentProvider } from "@chakra-ui/react"
import createCache from "@emotion/cache"
import { CacheProvider } from "@emotion/react"
import { ThemeProvider, type ThemeProviderProps } from "next-themes"
import { useEffect, useState } from "react"
import root from "react-shadow/emotion"
import { system } from "./system"
export function Provider(props: ThemeProviderProps) {
const [shadow, setShadow] = useState<HTMLElement | null>(null)
const [cache, setCache] = useState<ReturnType<typeof createCache> | null>(
null,
)
useEffect(() => {
if (!shadow?.shadowRoot || cache) return
const emotionCache = createCache({
key: "root",
container: shadow.shadowRoot,
})
setCache(emotionCache)
}, [shadow, cache])
return (
<root.div ref={setShadow}>
{shadow && cache && (
<EnvironmentProvider value={() => shadow.shadowRoot ?? document}>
<CacheProvider value={cache}>
<ChakraProvider value={system}>
<ThemeProvider {...props} />
</ChakraProvider>
</CacheProvider>
</EnvironmentProvider>
)}
</root.div>
)
}
6
使用 Provider
在应用程序的根目录中,用 components/ui/provider
组件中生成的 Provider
组件包裹您的应用程序。
src/main.tsx
import { Provider } from "@/components/ui/provider"
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import App from "./App.tsx"
createRoot(document.getElementById("root")!).render(
<StrictMode>
<Provider>
<App />
</Provider>
</StrictMode>,
)
7
尽情享受吧!
借助代码片段和 Chakra UI 的原始组件的强大功能,您可以更快地构建 UI。
import { Button, HStack } from "@chakra-ui/react"
export default function App() {
return (
<HStack>
<Button>Click me</Button>
<Button>Click me</Button>
</HStack>
)
}