/* 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,
};
componentDidMount() {
const { meta, location } = this.props;
if (meta.id === location.hash.slice(1)) {
this.anchor.click();
}
}
shouldComponentUpdate(nextProps, nextState) {
const { codeExpand, copied, copyTooltipOpen } = this.state;
const { expand, theme, showRiddleButton, react18 } = this.props;
return (
(codeExpand || expand) !== (nextState.codeExpand || nextProps.expand) ||
copied !== nextState.copied ||
copyTooltipOpen !== nextState.copyTooltipOpen ||
nextProps.theme !== theme ||
nextProps.showRiddleButton !== showRiddleButton ||
nextProps.react18 !== react18
);
}
getSourceCode() {
const { highlightedCodes } = this.props;
if (typeof document !== 'undefined') {
const div = document.createElement('div');
div.innerHTML = highlightedCodes.jsx;
return 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,
react18,
} = props;
const { copied, copyTooltipOpen } = state;
if (!this.liveDemo) {
this.liveDemo = meta.iframe ? (