/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */ import { CheckOutlined, SnippetsOutlined, ThunderboltOutlined } from '@ant-design/icons'; import stackblitzSdk from '@stackblitz/sdk'; import { Alert, Badge, Tooltip } from 'antd'; import classNames from 'classnames'; import LZString from 'lz-string'; import React from 'react'; import CopyToClipboard from 'react-copy-to-clipboard'; import ReactDOM from 'react-dom'; import { FormattedMessage, injectIntl } from 'react-intl'; import BrowserFrame from '../../BrowserFrame'; import EditButton from '../EditButton'; import CodePenIcon from './CodePenIcon'; import CodePreview from './CodePreview'; import CodeSandboxIcon from './CodeSandboxIcon'; import RiddleIcon from './RiddleIcon'; const { ErrorBoundary } = Alert; function compress(string) { return LZString.compressToBase64(string) .replace(/\+/g, '-') // Convert '+' to '-' .replace(/\//g, '_') // Convert '/' to '_' .replace(/=+$/, ''); // Remove ending '=' } class Demo extends React.Component { iframeRef = React.createRef(); codeSandboxIconRef = React.createRef(); riddleIconRef = React.createRef(); codepenIconRef = React.createRef(); state = { codeExpand: false, copied: false, copyTooltipOpen: false, codeType: 'tsx', }; componentDidMount() { const { meta, location } = this.props; if (meta.id === location.hash.slice(1)) { this.anchor.click(); } } shouldComponentUpdate(nextProps, nextState) { const { codeExpand, copied, copyTooltipOpen, codeType } = this.state; const { expand, theme, showRiddleButton } = this.props; return ( (codeExpand || expand) !== (nextState.codeExpand || nextProps.expand) || copied !== nextState.copied || copyTooltipOpen !== nextState.copyTooltipOpen || codeType !== nextState.copyTooltipOpen || nextProps.theme !== theme || nextProps.showRiddleButton !== showRiddleButton ); } getSourceCode() { const { highlightedCodes } = this.props; const { codeType } = this.state; if (typeof document !== 'undefined') { const div = document.createElement('div'); const divJSX = document.createElement('div'); div.innerHTML = highlightedCodes[codeType] || highlightedCodes.jsx; divJSX.innerHTML = highlightedCodes.jsx; return [divJSX.textContent, div.textContent]; } return ['', '']; } handleCodeExpand = demo => { const { codeExpand } = this.state; this.setState({ codeExpand: !codeExpand }); this.track({ type: 'expand', demo, }); }; saveAnchor = anchor => { this.anchor = anchor; }; handleCodeCopied = demo => { this.setState({ copied: true }); this.track({ type: 'copy', demo, }); }; onCopyTooltipOpenChange = open => { if (open) { this.setState({ copyTooltipOpen: open, copied: false, }); return; } this.setState({ copyTooltipOpen: open, }); }; // eslint-disable-next-line class-methods-use-this track({ type, demo }) { if (!window.gtag) { return; } window.gtag('event', 'demo', { event_category: type, event_label: demo, }); } handleIframeReady = () => { const { theme, setIframeTheme } = this.props; if (this.iframeRef.current) { setIframeTheme(this.iframeRef.current, theme); } }; render() { const { state } = this; const { props } = this; const { meta, src, content, preview, highlightedCodes, style, highlightedStyle, expand, utils, intl: { locale }, theme, showRiddleButton, } = props; const { copied, copyTooltipOpen, codeType } = state; if (!this.liveDemo) { this.liveDemo = meta.iframe ? (