Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/client/theme-default/builtins/Previewer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { ReactComponent as IconError } from '@ant-design/icons-svg/inline-svg/filled/close-circle.svg';
import classnames from 'classnames';
import { useLiveDemo, useLocation, type IPreviewerProps } from 'dumi';
import {
useLiveDemo,
useLocation,
usePrefersColor,
type IPreviewerProps,
} from 'dumi';
import PreviewerActions from 'dumi/theme/slots/PreviewerActions';
import React, { useRef, type FC } from 'react';
import React, { useEffect, useRef, useState, type FC } from 'react';
import './index.less';

const Previewer: FC<IPreviewerProps> = (props) => {
const demoContainer = useRef<HTMLDivElement>(null);
const { hash } = useLocation();
const link = `#${props.asset.id}`;

const [preferredColorScheme] = usePrefersColor();

Copilot AI Nov 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name preferredColorScheme is misleading. The first value returned by usePrefersColor() is the resolved color ('light' or 'dark'), not the preferred color scheme (which can be 'auto', 'light', or 'dark').

Consider renaming to color or colorScheme to match the convention used in the hook's implementation and to be more accurate about what it represents.

Example:

const [color] = usePrefersColor();

Copilot uses AI. Check for mistakes.
const [iframeKey, setIframeKey] = useState(0);

const {
node: liveDemoNode,
error: liveDemoError,
Expand All @@ -20,6 +28,12 @@ const Previewer: FC<IPreviewerProps> = (props) => {
containerRef: demoContainer,
});

useEffect(() => {
if (props.iframe) {
setIframeKey((key) => key + 1);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉 postMessage 比重新渲染的体验更好一些,看是否有兴趣和精力做下方案调整,把实现放在 usePrefersColor hook 里,大致思路是如果发现存在 parentWindow,则监听相应事件做实时更新

useLiveDemo 里也有类似的实现但它基于 ref 不完全一致,局部可以作为参考

}
}, [preferredColorScheme, props.iframe]);

Copilot AI Nov 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The props.iframe dependency in the useEffect is unnecessary and could cause issues. When props.iframe changes from truthy to falsy (or vice versa), the effect runs and updates iframeKey even though there's no iframe to refresh.

The dependency array should only include preferredColorScheme since that's the only value that should trigger an iframe reload. The props.iframe check inside the effect is sufficient to prevent updates when there's no iframe.

Suggested change:

}, [preferredColorScheme]);
Suggested change
}, [preferredColorScheme, props.iframe]);
}, [preferredColorScheme]);

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iframe参数也可以设置为demo的高度,我的理解是这个参数变化应该也要更新demo块吧


return (
<div
id={props.asset.id}
Expand All @@ -46,6 +60,7 @@ const Previewer: FC<IPreviewerProps> = (props) => {
: {}
}
src={props.demoUrl}
key={iframeKey}
></iframe>
) : (
liveDemoNode || props.children
Expand Down
Loading