import React, { useState } from 'react'; import styled from 'styled-components'; import type { JSX } from 'react'; import { concatClassNames } from '@redocly/theme/core/utils'; import { useColorSwitcher } from '@redocly/theme/core/hooks'; import { useThemeHooks } from '@redocly/theme/core/hooks'; import { SvgViewer } from '@redocly/theme/components/SvgViewer/SvgViewer'; type DiagramProps = { id?: string; diagramHtml: string; diagramHtmlDark?: string; diagramError?: string; diagramType: string; align?: 'left' | 'center' | 'right'; width?: string; 'data-source'?: string; 'data-hash'?: string; className?: string; }; export function Diagram({ id, diagramHtml, diagramHtmlDark, diagramError, diagramType, align, width, 'data-source': dataSource, 'data-hash': dataHash, className, }: DiagramProps): JSX.Element { const { useTranslate } = useThemeHooks(); const { translate } = useTranslate(); const { activeColorMode } = useColorSwitcher(); const [isOpen, setIsOpen] = useState(false); const activeDiagramHtml = activeColorMode === 'dark' ? diagramHtmlDark || diagramHtml : diagramHtml; const open = () => setIsOpen(true); const close = () => setIsOpen(false); const handleKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); open(); } }; if (diagramError) { return ( {diagramError} ); } return ( <> {diagramHtmlDark ? ( ) : null} ); } const Wrapper = styled.div<{ $width?: string }>` background-color: var(--diagram-bg-color); border-radius: var(--diagram-border-radius); cursor: pointer; transition: box-shadow 0.2s ease; &:hover, &:focus { outline: none; box-shadow: 0 0 0 2px var(--border-color-input-focus); } svg { max-width: 100%; display: block; ${({ $width }) => ($width ? `width: ${$width} !important; height: auto !important;` : '')} } `; const DiagramVariant = styled.div<{ $colorMode: 'light' | 'dark'; $align?: DiagramProps['align'] }>` display: flex; justify-content: ${({ $align }) => { switch ($align) { case 'center': return 'center'; case 'right': return 'flex-end'; default: return 'flex-start'; } }}; width: 100%; ${({ $colorMode }) => $colorMode === 'dark' ? ` html:not(.dark) && { display: none; } ` : ` html.dark && { display: none; } `} `; const ErrorWrapper = styled.div` border: 1px solid var(--color-error-border); border-radius: var(--diagram-border-radius); background: var(--color-error-bg); color: var(--color-error-text); font-size: var(--font-size-sm); padding: var(--spacing-sm); white-space: pre-wrap; word-break: break-word; `; const ViewerContent = styled.div` svg { display: block; max-width: none !important; } `;