如何单独渲染 Chakra UI 组件(NextJs 15 iframe)

问题描述 投票:0回答:1

我有一个使用 Tailwind 构建的应用程序,用于渲染和操作 Chakra UI 组件,以便使用 iframe 进行隔离测试。我这样做是为了让 tailwind CSS 不会影响 chakra ui 组件样式。

我尝试使用 React-frame-Component 来渲染包裹在 Chakra 提供程序中的组件,但这不起作用。

'use client';
import Frame from 'react-frame-component';
import { Provider } from "@/components/ui/provider"
import {useEffect, useState} from "react";
import {Text} from "@chakra-ui/react";
import {Button} from "@/components/ui/button";

export default function Preview() {
  

    return (
        <>
            <Frame
                className="h-80 w-80"
                initialContent={`
                    <!DOCTYPE html>
                    <html>
                        <head>
                            <style>
                                body { margin: 0; padding: 0; box-sizing: border-box; }
                            </style>
                        </head>
                        <body>
                            <div class="frame-root"></div>
                        </body>
                    </html>
                `}
            >
                    <div>
                        <Provider>
                        <Text textStyle="2xl">My Large Heading</Text>
                        <Button>My Chakra Button</Button>
                        </Provider>
                    </div>
            </Frame>
        </>
    );
}

reactjs shadow-dom next.js15
1个回答
0
投票

您面临的问题

react-frame-component
无法正确渲染 Chakra UI 组件可能是由于 iframe 隔离样式和上下文造成的。由于 Chakra UI 依赖
Provider
来管理其主题和上下文,因此您需要确保 Chakra
CSSReset
和主题样式注入到 iframe 的文档中。以下是解决问题的方法:

解决问题的调整

  1. 使用
    FrameContextConsumer
    中的
    react-frame-component
    访问 iframe 的
    document
    window
  2. 确保 Chakra
    Provider
    包裹 iframe 内渲染的内容,并且 Chakra 样式包含在 iframe 中。

更新的代码示例

'use client';
import Frame, { FrameContextConsumer } from 'react-frame-component';
import { ChakraProvider, Text, extendTheme } from '@chakra-ui/react';
import { Button } from '@/components/ui/button';

export default function Preview() {
    // Optionally customize the theme
    const theme = extendTheme({
        textStyles: {
            '2xl': {
                fontSize: '2xl',
                fontWeight: 'bold',
            },
        },
    });

    return (
        <Frame
            className="h-80 w-80"
            initialContent={`
                <!DOCTYPE html>
                <html>
                    <head>
                        <style>
                            body { margin: 0; padding: 0; box-sizing: border-box; }
                        </style>
                    </head>
                    <body>
                        <div class="frame-root"></div>
                    </body>
                </html>
            `}
        >
            <FrameContextConsumer>
                {({ document }) => (
                    // Render the ChakraProvider and components inside the iframe
                    <ChakraProvider theme={theme}>
                        <div>
                            <Text textStyle="2xl">My Large Heading</Text>
                            <Button>My Chakra Button</Button>
                        </div>
                    </ChakraProvider>
                )}
            </FrameContextConsumer>
        </Frame>
    );
}

使用
FrameContextConsumer

  • 这提供了对 iframe 的
    document
    window
    的访问,确保 Chakra 样式和上下文正确地限定在 iframe 范围内。

iframe 内的 ChakraProvider:

  • ChakraProvider
    确保所有 Chakra UI 组件都能按照 iframe 内的指定主题正确渲染。

自定义主题(可选):

  • 示例使用扩展主题来演示
© www.soinside.com 2019 - 2024. All rights reserved.