mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-25 19:30:17 +08:00
refactor: use custom properties in shadow host
This commit is contained in:
parent
e801b9d298
commit
4c81443930
@ -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">
|
||||
<StyledGraphviz ref={containerRef} className="graphviz special-preview" />
|
||||
<ShadowWhiteContainer ref={containerRef} className="graphviz special-preview" />
|
||||
</ImagePreviewLayout>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledGraphviz = styled.div`
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`
|
||||
|
||||
export default memo(GraphvizPreview)
|
||||
|
||||
@ -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">
|
||||
<StyledMermaid ref={containerRef} className="mermaid special-preview" />
|
||||
<ShadowTransparentContainer ref={containerRef} className="mermaid special-preview" />
|
||||
</ImagePreviewLayout>
|
||||
)
|
||||
}
|
||||
|
||||
const StyledMermaid = styled.div`
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`
|
||||
|
||||
export default memo(MermaidPreview)
|
||||
|
||||
@ -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">
|
||||
<div ref={containerRef} className="plantuml-preview special-preview" />
|
||||
<ShadowWhiteContainer ref={containerRef} className="plantuml-preview special-preview" />
|
||||
</ImagePreviewLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@ -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">
|
||||
<div ref={containerRef} className={className ?? 'svg-preview special-preview'}></div>
|
||||
<ShadowWhiteContainer ref={containerRef} className={className ?? 'svg-preview special-preview'} />
|
||||
</ImagePreviewLayout>
|
||||
)
|
||||
}
|
||||
|
||||
@ -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;
|
||||
`
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user