From 4c81443930ae745b6379efece9e4fa1b3d30a13e Mon Sep 17 00:00:00 2001 From: one Date: Fri, 15 Aug 2025 16:18:32 +0800 Subject: [PATCH] refactor: use custom properties in shadow host --- .../components/Preview/GraphvizPreview.tsx | 14 +++----------- .../src/components/Preview/MermaidPreview.tsx | 11 ++--------- .../components/Preview/PlantUmlPreview.tsx | 6 +++--- .../src/components/Preview/SvgPreview.tsx | 6 +++--- src/renderer/src/components/Preview/styles.ts | 16 ++++++++++------ src/renderer/src/components/Preview/utils.ts | 19 ++++++++++--------- 6 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/renderer/src/components/Preview/GraphvizPreview.tsx b/src/renderer/src/components/Preview/GraphvizPreview.tsx index ab1338bac3..578a35450b 100644 --- a/src/renderer/src/components/Preview/GraphvizPreview.tsx +++ b/src/renderer/src/components/Preview/GraphvizPreview.tsx @@ -1,10 +1,9 @@ import { AsyncInitializer } from '@renderer/utils/asyncInitializer' import React, { memo, useCallback } from 'react' -import styled from 'styled-components' import { useDebouncedRender } from './hooks/useDebouncedRender' import ImagePreviewLayout from './ImagePreviewLayout' -import { PreviewHostCssWhite } from './styles' +import { ShadowWhiteContainer } from './styles' import { BasicPreviewHandles, BasicPreviewProps } from './types' import { renderSvgInShadowHost } from './utils' @@ -28,7 +27,7 @@ const GraphvizPreview = ({ const renderGraphviz = useCallback(async (content: string, container: HTMLDivElement) => { const viz = await vizInitializer.get() const svg = viz.renderString(content, { format: 'svg' }) - renderSvgInShadowHost(svg, container, { customCss: PreviewHostCssWhite }) + renderSvgInShadowHost(svg, container) }, []) // 使用预览渲染器 hook @@ -44,16 +43,9 @@ const GraphvizPreview = ({ ref={ref} imageRef={containerRef} source="graphviz"> - + ) } -const StyledGraphviz = styled.div` - overflow: auto; - position: relative; - width: 100%; - height: 100%; -` - export default memo(GraphvizPreview) diff --git a/src/renderer/src/components/Preview/MermaidPreview.tsx b/src/renderer/src/components/Preview/MermaidPreview.tsx index 953fbcca71..86e0339c2f 100644 --- a/src/renderer/src/components/Preview/MermaidPreview.tsx +++ b/src/renderer/src/components/Preview/MermaidPreview.tsx @@ -1,10 +1,10 @@ import { nanoid } from '@reduxjs/toolkit' import { useMermaid } from '@renderer/hooks/useMermaid' import React, { memo, useCallback, useEffect, useRef, useState } from 'react' -import styled from 'styled-components' import { useDebouncedRender } from './hooks/useDebouncedRender' import ImagePreviewLayout from './ImagePreviewLayout' +import { ShadowTransparentContainer } from './styles' import { BasicPreviewHandles, BasicPreviewProps } from './types' import { renderSvgInShadowHost } from './utils' @@ -129,16 +129,9 @@ const MermaidPreview = ({ ref={ref} imageRef={containerRef} source="mermaid"> - + ) } -const StyledMermaid = styled.div` - overflow: auto; - position: relative; - width: 100%; - height: 100%; -` - export default memo(MermaidPreview) diff --git a/src/renderer/src/components/Preview/PlantUmlPreview.tsx b/src/renderer/src/components/Preview/PlantUmlPreview.tsx index 6a1aed514c..f29a0c1ffc 100644 --- a/src/renderer/src/components/Preview/PlantUmlPreview.tsx +++ b/src/renderer/src/components/Preview/PlantUmlPreview.tsx @@ -4,7 +4,7 @@ import React, { memo, useCallback, useEffect } from 'react' import { useDebouncedRender } from './hooks/useDebouncedRender' import ImagePreviewLayout from './ImagePreviewLayout' -import { PreviewHostCssWhite } from './styles' +import { ShadowWhiteContainer } from './styles' import { BasicPreviewHandles, BasicPreviewProps } from './types' import { renderSvgInShadowHost } from './utils' @@ -104,7 +104,7 @@ const PlantUmlPreview = ({ } const text = await response.text() - renderSvgInShadowHost(text, container, { customCss: PreviewHostCssWhite }) + renderSvgInShadowHost(text, container) }, []) // 使用预览渲染器 hook @@ -129,7 +129,7 @@ const PlantUmlPreview = ({ ref={ref} imageRef={containerRef} source="plantuml"> -
+ ) } diff --git a/src/renderer/src/components/Preview/SvgPreview.tsx b/src/renderer/src/components/Preview/SvgPreview.tsx index bc2351e7a3..2122ebe091 100644 --- a/src/renderer/src/components/Preview/SvgPreview.tsx +++ b/src/renderer/src/components/Preview/SvgPreview.tsx @@ -2,7 +2,7 @@ import { memo, useCallback } from 'react' import { useDebouncedRender } from './hooks/useDebouncedRender' import ImagePreviewLayout from './ImagePreviewLayout' -import { PreviewHostCssWhite } from './styles' +import { ShadowWhiteContainer } from './styles' import { BasicPreviewHandles } from './types' import { renderSvgInShadowHost } from './utils' @@ -19,7 +19,7 @@ interface SvgPreviewProps { const SvgPreview = ({ children, enableToolbar = false, className, ref }: SvgPreviewProps) => { // 定义渲染函数 const renderSvg = useCallback(async (content: string, container: HTMLDivElement) => { - renderSvgInShadowHost(content, container, { customCss: PreviewHostCssWhite }) + renderSvgInShadowHost(content, container) }, []) // 使用预览渲染器 hook @@ -35,7 +35,7 @@ const SvgPreview = ({ children, enableToolbar = false, className, ref }: SvgPrev ref={ref} imageRef={containerRef} source="svg"> -
+ ) } diff --git a/src/renderer/src/components/Preview/styles.ts b/src/renderer/src/components/Preview/styles.ts index 73cb5f56a8..521b96e225 100644 --- a/src/renderer/src/components/Preview/styles.ts +++ b/src/renderer/src/components/Preview/styles.ts @@ -34,10 +34,14 @@ export const PreviewContainer = styled(Flex).attrs({ role: 'alert' })` } ` -export const PreviewHostCssWhite = ` - :host { - background-color: white; - border: 0.5px solid var(--color-code-background); - border-radius: 8px; - } +export const ShadowWhiteContainer = styled.div` + --shadow-host-background-color: white; + --shadow-host-border: 0.5px solid var(--color-code-background); + --shadow-host-border-radius: 8px; +` + +export const ShadowTransparentContainer = styled.div` + --shadow-host-background-color: transparent; + --shadow-host-border: unset; + --shadow-host-border-radius: unset; ` diff --git a/src/renderer/src/components/Preview/utils.ts b/src/renderer/src/components/Preview/utils.ts index fa6b8bfe1a..54070eab9a 100644 --- a/src/renderer/src/components/Preview/utils.ts +++ b/src/renderer/src/components/Preview/utils.ts @@ -1,7 +1,3 @@ -type ShadowHostOptions = { - customCss?: string // override styles -} - /** * Renders an SVG string inside a host element's Shadow DOM to ensure style encapsulation. * This function handles creating the shadow root, injecting base styles for the host, @@ -11,7 +7,7 @@ type ShadowHostOptions = { * @param hostElement The container element that will host the Shadow DOM. * @throws An error if the SVG content is invalid or cannot be parsed. */ -export function renderSvgInShadowHost(svgContent: string, hostElement: HTMLElement, options?: ShadowHostOptions): void { +export function renderSvgInShadowHost(svgContent: string, hostElement: HTMLElement): void { if (!hostElement) { throw new Error('Host element for SVG rendering is not available.') } @@ -19,8 +15,16 @@ export function renderSvgInShadowHost(svgContent: string, hostElement: HTMLEleme const shadowRoot = hostElement.shadowRoot || hostElement.attachShadow({ mode: 'open' }) // Base styles for the host element - const base = ` + const style = document.createElement('style') + style.textContent = ` :host { + --shadow-host-background-color: white; + --shadow-host-border: 0.5px solid var(--color-code-background); + --shadow-host-border-radius: 8px; + + background-color: var(--shadow-host-background-color); + border: var(--shadow-host-border); + border-radius: var(--shadow-host-border-radius); padding: 1em; overflow: auto; display: block; @@ -34,9 +38,6 @@ export function renderSvgInShadowHost(svgContent: string, hostElement: HTMLEleme } ` - const style = document.createElement('style') - style.textContent = base + (options?.customCss ? `\n${options.customCss}\n` : '') - // Clear previous content and append new style and SVG shadowRoot.innerHTML = '' shadowRoot.appendChild(style)