import { CheckOutlined, SnippetsOutlined, ThunderboltOutlined, LinkOutlined, } from '@ant-design/icons'; import stackblitzSdk from '@stackblitz/sdk'; import type { Project } from '@stackblitz/sdk'; import { Alert, Badge, Tooltip, Space } from 'antd'; import classNames from 'classnames'; import LZString from 'lz-string'; import React, { useContext, useEffect, useRef, useState } from 'react'; import CopyToClipboard from 'react-copy-to-clipboard'; import ReactDOM from 'react-dom'; import { FormattedMessage } from 'dumi'; import BrowserFrame from '../../common/BrowserFrame'; import EditButton from '../../common/EditButton'; import CodePenIcon from '../../common/CodePenIcon'; import CodePreview from '../../common/CodePreview'; import CodeSandboxIcon from '../../common/CodeSandboxIcon'; import RiddleIcon from '../../common/RiddleIcon'; import ExternalLinkIcon from '../../common/ExternalLinkIcon'; import fromDumiProps from './fromDumiProps'; import type { SiteContextProps } from '../../slots/SiteContext'; import SiteContext from '../../slots/SiteContext'; import { version } from '../../../../package.json'; const { ErrorBoundary } = Alert; function compress(string: string): string { return LZString.compressToBase64(string) .replace(/\+/g, '-') // Convert '+' to '-' .replace(/\//g, '_') // Convert '/' to '_' .replace(/=+$/, ''); // Remove ending '=' } const track = ({ type, demo }: { type: string; demo: string }) => { if (!window.gtag) { return; } window.gtag('event', 'demo', { event_category: type, event_label: demo }); }; interface DemoProps { meta: any; intl: any; utils?: any; src: string; content: string; highlightedCodes: Record; style: string; highlightedStyle: string; expand: boolean; sourceCodes: Record<'jsx' | 'tsx', string>; location: Location; showRiddleButton: boolean; preview: (react: typeof React, reactDOM: typeof ReactDOM) => React.ReactNode; } const Demo: React.FC = (props) => { const { location, sourceCodes, meta, src, utils, content, highlightedCodes, style, highlightedStyle, expand, intl: { locale }, showRiddleButton, preview, } = props; const liveDemo = useRef(null); const anchorRef = useRef(null); const codeSandboxIconRef = useRef(null); const riddleIconRef = useRef(null); const codepenIconRef = useRef(null); const [codeExpand, setCodeExpand] = useState(false); const [copyTooltipOpen, setCopyTooltipOpen] = useState(false); const [copied, setCopied] = useState(false); const [codeType, setCodeType] = useState('tsx'); const { theme } = useContext(SiteContext); const { hash, pathname, search } = location; const isDev = process.env.NODE_ENV === 'development'; const docsOnlineUrl = `https://ant.design${pathname}${search}#${meta.id}`; const handleCodeExpand = (demo: string) => { setCodeExpand(!codeExpand); track({ type: 'expand', demo }); }; const handleCodeCopied = (demo: string) => { setCopied(true); track({ type: 'copy', demo }); }; const onCopyTooltipOpenChange = (open: boolean) => { setCopyTooltipOpen(open); if (open) { setCopied(false); } }; useEffect(() => { if (meta.id === hash.slice(1)) { anchorRef.current?.click(); } }, []); if (!liveDemo.current) { liveDemo.current = meta.iframe ? (