Skip to Content
文档

在 Shadow DOM 中使用 Chakra UI

Chakra UI 在 Shadow DOM 中的安装指南

在开发浏览器扩展程序或在大型项目中使用 Chakra 时,利用 Shadow DOM 有助于样式和逻辑封装。

¥When developing extensions for browsers or using Chakra as part of a large project, leveraging the Shadow DOM is useful for style and logic encapsulation.

模板

¥Template

使用以下模板快速入门

¥Use the following template to get started quickly

安装

¥Installation

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

1

安装依赖

¥Install dependencies

npm i @chakra-ui/react @emotion/react @emotion/cache react-shadow

使用的附加包如下:

¥The additional packages used are:

  • react-shadow 用于轻松创建 Shadow DOM

  • @emotion/cache 用于创建样式的自定义插入点

2

添加代码片段

¥Add snippets

代码片段是预先构建的组件,你可以使用它们更快地构建 UI。使用 @chakra-ui/cli 属性,你可以将代码片段添加到你的项目中。

¥Snippets are pre-built components that you can use to build your UI faster. Using the @chakra-ui/cli you can add snippets to your project.

npx @chakra-ui/cli snippet add
3

更新 tsconfig

¥Update tsconfig

如果你使用的是 TypeScript,则需要更新 tsconfig 文件中的 compilerOptions,使其包含以下选项:

¥If you're using TypeScript, you need to update the compilerOptions in the tsconfig file to include the following options:

{
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "skipLibCheck": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
4

配置样式引擎

¥Configure style engine

在项目根目录中创建一个 system.ts 文件并配置样式引擎。

¥Create a system.ts file in the root of your project and configure the style engine.

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

设置提供者

¥Setup provider

使用 Provider 组件更新生成的 components/ui/provider 组件。

¥Update the generated components/ui/provider component with the Provider component.

此提供程序包含以下内容:

¥This provider composes the following:

  • ChakraProvider 来自 @chakra-ui/react,用于样式系统

  • EnvironmentProvider 来自 react-shadow,用于确保 Chakra 组件正确查询 DOM

  • CacheProvider 来自 @emotion/react,用于提供自定义插入点

  • ThemeProvider 来自 next-themes,用于颜色模式

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

使用提供程序

¥Use the provider

使用应用根目录下 components/ui/provider 组件中生成的 Provider 组件封装你的应用。

¥Wrap your application with the Provider component generated in the components/ui/provider component at the root of your application.

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

尽情享受吧!

¥Enjoy!

借助 Chakra UI 的代码片段和原始组件的强大功能,你可以更快地构建 UI。

¥With the power of the snippets and the primitive components from Chakra UI, you can build your UI faster.

import { Button, HStack } from "@chakra-ui/react"

export default function App() {
  return (
    <HStack>
      <Button>Click me</Button>
      <Button>Click me</Button>
    </HStack>
  )
}

Previous

Vite

Next

iframe