UNPKG

@rise4fun/docusaurus-theme-codesandbox-button

Version:
74 lines (73 loc) 2.71 kB
import React, { useState } from 'react'; import clsx from 'clsx'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import styles from './styles.module.css'; const DEFAULT_CODESANDBOX = { files: { 'package.json': { content: { dependencies: {}, }, }, 'sandbox.config.json': { content: { template: 'node', view: 'terminal', container: { node: '18', }, }, }, }, }; export default function CodeSandboxButton(props) { const { siteConfig } = useDocusaurusContext(); const { themeConfig } = siteConfig; const { codeSandbox = {} } = themeConfig; const { templates, defaultTemplate } = codeSandbox; const { className, files, startFile, template = defaultTemplate, label = 'CodeSandbox' } = props; const sandbox = templates?.[template || ''] || DEFAULT_CODESANDBOX; const [error, setError] = useState(); const [importing, setImporting] = useState(false); const handleClick = async () => { const f = files; const body = { files: { ...(sandbox?.files || {}), ...f, }, }; try { setError(undefined); setImporting(true); const x = await fetch('https://codesandbox.io/api/v1/sandboxes/define?json=1', { method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json', }, body: JSON.stringify(body), }); if (!x.ok) throw new Error('codesandbox.io api call failed'); const data = await x.json(); const { sandbox_id } = data; if (sandbox_id === undefined) throw new Error('failed to create new sandbox'); let url = `https://codesandbox.io/s/${data.sandbox_id}?`; if (startFile) url += `file=/${encodeURIComponent(startFile)}`; window.open(url, '_blank', 'noreferrer'); } catch (error) { console.error(error); setError(error?.message || error + ''); } finally { setImporting(false); } }; return (React.createElement("button", { type: "button", "aria-label": "Open code in CodeSandbox", title: error || 'Open in CodeSandbox', className: clsx(styles.hidemobile, styles.mr1, className || 'button button--secondary'), onClick: handleClick, disabled: importing }, label, error && `!!!`)); }