mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-02 03:58:05 +08:00
doc: support CodeSandbox (#4861)
This commit is contained in:
parent
c3400115dd
commit
45c0583426
@ -127,6 +127,7 @@
|
||||
"chalk": "^4.1.1",
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"codecov": "^3.0.0",
|
||||
"codesandbox": "^2.2.3",
|
||||
"colorful": "^2.1.0",
|
||||
"commander": "^7.2.0",
|
||||
"compare-versions": "^3.3.0",
|
||||
|
@ -19,6 +19,12 @@
|
||||
</div>
|
||||
<div class="code-box-description" v-html="docHtml"></div>
|
||||
<div class="code-box-actions">
|
||||
<a-tooltip :title="$t('app.demo.codesandbox')">
|
||||
<CodeSandboxOutlined
|
||||
class="code-box-code-copy code-box-code-action"
|
||||
@click="handleCodeSandbox"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="$t(`app.demo.type.${type === 'JS' ? 'js' : 'ts'}`)">
|
||||
<span
|
||||
class="code-expand-icon code-box-code-action"
|
||||
@ -72,7 +78,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<section :class="highlightClass">
|
||||
<div class="highlight">
|
||||
<div class="highlight" ref="codeRef">
|
||||
<slot v-if="type === 'TS'" name="htmlCode" />
|
||||
<slot v-else name="jsVersionHtml" />
|
||||
</div>
|
||||
@ -84,13 +90,17 @@
|
||||
import type { GlobalConfig } from '../App.vue';
|
||||
import { GLOBAL_CONFIG } from '../SymbolKey';
|
||||
import { computed, defineComponent, inject, onMounted, ref } from 'vue';
|
||||
import { CheckOutlined, SnippetsOutlined } from '@ant-design/icons-vue';
|
||||
import { CheckOutlined, SnippetsOutlined, CodeSandboxOutlined } from '@ant-design/icons-vue';
|
||||
import { getCodeSandboxParams } from '../utils/generateOnlineDemo';
|
||||
import packageInfo from '../../../package.json';
|
||||
|
||||
// import { Modal } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
name: 'DemoBox',
|
||||
components: {
|
||||
CheckOutlined,
|
||||
SnippetsOutlined,
|
||||
CodeSandboxOutlined,
|
||||
},
|
||||
props: {
|
||||
jsfiddle: Object,
|
||||
@ -100,6 +110,7 @@ export default defineComponent({
|
||||
const type = ref('TS');
|
||||
const copyTooltipVisible = ref(false);
|
||||
const copied = ref(false);
|
||||
const codeRef = ref<HTMLDivElement>();
|
||||
const sectionId = computed(() => {
|
||||
const relativePath = props.jsfiddle?.relativePath || '';
|
||||
return `${relativePath.split('/').join('-').replace('.vue', '')}`;
|
||||
@ -170,6 +181,21 @@ export default defineComponent({
|
||||
}
|
||||
type.value = type.value === 'TS' ? 'JS' : 'TS';
|
||||
};
|
||||
const handleCodeSandbox = () => {
|
||||
const code = codeRef.value!.innerText;
|
||||
const params = getCodeSandboxParams(code, {
|
||||
title: `${title.value} - ant-design-vue@${packageInfo.version}`,
|
||||
});
|
||||
const div = document.createElement('div');
|
||||
div.style.display = 'none';
|
||||
div.innerHTML = `<form action="https://codesandbox.io/api/v1/sandboxes/define" method="POST" target="_blank">
|
||||
<input type="hidden" name="parameters" value="${params}" />
|
||||
<input type="submit" value="Open in sandbox" />
|
||||
</form>`;
|
||||
document.body.appendChild(div);
|
||||
(div.firstElementChild as HTMLFormElement).submit();
|
||||
document.body.removeChild(div);
|
||||
};
|
||||
const highlightClass = computed(() => {
|
||||
return {
|
||||
'highlight-wrapper': true,
|
||||
@ -207,6 +233,8 @@ export default defineComponent({
|
||||
highlightClass,
|
||||
sourceCode: decodeURIComponent(escape(window.atob(props.jsfiddle?.sourceCode))),
|
||||
jsSourceCode: decodeURIComponent(escape(window.atob(props.jsfiddle?.jsSourceCode))),
|
||||
codeRef,
|
||||
handleCodeSandbox,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
94
site/src/utils/generateOnlineDemo.ts
Normal file
94
site/src/utils/generateOnlineDemo.ts
Normal file
@ -0,0 +1,94 @@
|
||||
import { getParameters } from 'codesandbox/lib/api/define';
|
||||
|
||||
const indexHtml = `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Ant Design Vue Demo</title>
|
||||
<style>
|
||||
body {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
const appVue = `<template>
|
||||
<Demo />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "vue";
|
||||
import Demo from "./demo.vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Demo,
|
||||
},
|
||||
});
|
||||
</script>`;
|
||||
|
||||
const mainJs = `import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import Antd from 'ant-design-vue';
|
||||
import 'ant-design-vue/dist/antd.css';
|
||||
|
||||
const app = createApp(App).use(Antd);
|
||||
app.mount("#app");
|
||||
`;
|
||||
|
||||
function getDeps(code: string) {
|
||||
return (code.match(/from '([^']+)';\n/g) || [])
|
||||
.map(v => v.slice(6, v.length - 3))
|
||||
.reduce((prevV, dep) => {
|
||||
prevV[dep] = 'latest';
|
||||
return prevV;
|
||||
}, {});
|
||||
}
|
||||
|
||||
type Meta = {
|
||||
title: string;
|
||||
};
|
||||
|
||||
// codeSandbox
|
||||
export function getCodeSandboxParams(code: string, meta: Meta): string {
|
||||
return getParameters({
|
||||
files: {
|
||||
'package.json': {
|
||||
content: JSON.stringify({
|
||||
title: meta.title,
|
||||
dependencies: {
|
||||
...getDeps(code),
|
||||
vue: 'next',
|
||||
'ant-design-vue': 'next',
|
||||
},
|
||||
devDependencies: {
|
||||
'@vue/cli-plugin-babel': '~4.5.0',
|
||||
typescript: '^4.0.5',
|
||||
},
|
||||
browserslist: ['> 0.2%', 'not dead'],
|
||||
}),
|
||||
isBinary: false,
|
||||
},
|
||||
'index.html': {
|
||||
content: indexHtml,
|
||||
isBinary: false,
|
||||
},
|
||||
'src/demo.vue': {
|
||||
content: code,
|
||||
isBinary: false,
|
||||
},
|
||||
'src/App.vue': {
|
||||
content: appVue,
|
||||
isBinary: false,
|
||||
},
|
||||
'src/main.js': {
|
||||
content: mainJs,
|
||||
isBinary: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user