fix: fix Previewer component under color scheme change with iframe key#2301
fix: fix Previewer component under color scheme change with iframe key#2301SocietyNiu wants to merge 1 commit intoumijs:masterfrom
Conversation
|
@SocietyNiu is attempting to deploy a commit to the chencheng's projects Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Pull request overview
This PR fixes an issue where demo components rendered in iframes do not update their color scheme when the user changes the theme preference. The fix uses React's key prop to force iframe remounting when the color scheme changes.
Key Changes:
- Added
usePrefersColorhook to track color scheme changes - Introduced state management for an iframe key that increments on color scheme changes
- Applied the key to the iframe element to trigger re-rendering
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (props.iframe) { | ||
| setIframeKey((key) => key + 1); | ||
| } | ||
| }, [preferredColorScheme, props.iframe]); |
There was a problem hiding this comment.
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]);| }, [preferredColorScheme, props.iframe]); | |
| }, [preferredColorScheme]); |
There was a problem hiding this comment.
iframe参数也可以设置为demo的高度,我的理解是这个参数变化应该也要更新demo块吧
| const { hash } = useLocation(); | ||
| const link = `#${props.asset.id}`; | ||
|
|
||
| const [preferredColorScheme] = usePrefersColor(); |
There was a problem hiding this comment.
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();
dumi
dumi-assets-types
@dumijs/vue-meta
father-plugin-dumi-theme
@dumijs/preset-vue
dumi-theme-mobile
commit: |
|
|
||
| useEffect(() => { | ||
| if (props.iframe) { | ||
| setIframeKey((key) => key + 1); |
There was a problem hiding this comment.
感觉 postMessage 比重新渲染的体验更好一些,看是否有兴趣和精力做下方案调整,把实现放在 usePrefersColor hook 里,大致思路是如果发现存在 parentWindow,则监听相应事件做实时更新
useLiveDemo 里也有类似的实现但它基于 ref 不完全一致,局部可以作为参考
🤔 这个变动的性质是?/ What is the nature of this change?
🔗 相关 Issue / Related Issue
ant-design/ant-design#55670
💡 需求背景和解决方案 / Background or solution
由于code demo使用iframe时和文档本身的隔离,使得demo内部无法获取到外部主题变更,导致切换主题时,demo主题颜色不变。
本次修改监听主题偏好,并使用key在切换主题时强制刷新iframe,从而实现颜色同步。
测试:

📝 更新日志 / Changelog
修改了主题变更下使用iframe的组件demo的表现