Skip to Content
文档

在 iframe 中使用 Chakra UI

Chakra UI 在 iframe 中的安装和使用指南

iframe 有助于在单独的上下文中隔离样式和逻辑。例如,你可能希望在专用沙盒中展示 Chakra 组件。

¥Iframes are useful for isolating styles and logic in a separate context. For example, you might want to showcase a Chakra component in dedicated sandbox.

模板

¥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-frame-component

使用的附加包如下:

¥The additional packages used are:

  • react-frame-component 用于轻松创建 iframe

  • @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

设置 iframe

¥Setup Iframe

创建一个 components/ui/iframe-provider.tsx 文件,使用 react-frame-component 包设置 iframe。

¥Create a components/ui/iframe-provider.tsx file to setup the iframe using the react-frame-component package.

components/ui/iframe-provider.tsx

import {
  ChakraProvider,
  EnvironmentProvider,
  defaultSystem,
} from "@chakra-ui/react"
import createCache from "@emotion/cache"
import { CacheProvider } from "@emotion/react"
import Iframe, { FrameContextConsumer } from "react-frame-component"

function memoize<T extends object, R>(func: (arg: T) => R): (arg: T) => R {
  const cache = new WeakMap<T, R>()
  return (arg: T) => {
    if (cache.has(arg)) return cache.get(arg)!
    const ret = func(arg)
    cache.set(arg, ret)
    return ret
  }
}

const createCacheFn = memoize((container: HTMLElement) =>
  createCache({ container, key: "frame" }),
)

export const IframeProvider = (props: React.PropsWithChildren) => {
  const { children } = props
  return (
    
      <FrameContextConsumer>
        {(frame) => {
          const head = frame.document?.head
          if (!head) return null
          return (
            <CacheProvider value={createCacheFn(head)}>
              <EnvironmentProvider value={() => head.ownerDocument}>
                <ChakraProvider value={defaultSystem}>
                  {children}
                </ChakraProvider>
              </EnvironmentProvider>
            </CacheProvider>
          )
        }}
      </FrameContextConsumer>
    </Iframe>
  )
}
5

设置提供者

¥Setup 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.

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

¥This provider composes the following:

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

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

import { Provider } from "@/components/ui/provider"
import React from "react"
import ReactDOM from "react-dom/client"
import App from "./App"

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <Provider>
      <App />
    </Provider>
  </React.StrictMode>,
)
6

使用 Iframe 提供程序

¥Use the IframeProvider

在应用中的任何组件中,使用 IframeProvider 组件封装它,以便在 iframe 内渲染它。

¥At any component in your application, wrap it with the IframeProvider component to render it inside the iframe.

src/App.tsx

import { Button, Container, Heading, Stack } from "@chakra-ui/react"
import { IframeProvider } from "./components/ui/iframe-provider"

function App() {
  return (
    <Container py="8">
      <Heading mb="5">Outside Iframe</Heading>

      
        <Stack p="6" align="flex-start" border="1px solid red">
          <Heading>Inside Iframe</Heading>
          <Button>Click me</Button>
        </Stack>
      </IframeProvider>
    </Container>
  )
}

export default App

自定义

¥Customization

如果你使用 createSystem 函数创建了自定义主题,请确保将其传递给 IframeProviderProvider 组件,以确保它在 iframe 内使用。

¥If you created a custom theme using the createSystem function, ensure it's passed to the IframeProvider and Provider components to ensure it's used inside the iframe.

例如,假设你创建了一个自定义主题:

¥For example, let's say you created a custom theme:

export const system = createSystem(defaultConfig, {
  theme: { colors: {} },
})

然后,将其传递给 IframeProviderProvider 组件:

¥Then, pass it to the IframeProvider and Provider components:

<ChakraProvider value={system}>{/* ... */}</ChakraProvider>

Previous

阴影 DOM

Next

概述