+
@@ -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
();
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 = ``;
+ 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,
};
},
});
diff --git a/site/src/utils/generateOnlineDemo.ts b/site/src/utils/generateOnlineDemo.ts
new file mode 100644
index 000000000..0d9dc7f2a
--- /dev/null
+++ b/site/src/utils/generateOnlineDemo.ts
@@ -0,0 +1,94 @@
+import { getParameters } from 'codesandbox/lib/api/define';
+
+const indexHtml = `
+
+
+ Ant Design Vue Demo
+
+
+
+
+
+
+`;
+
+const appVue = `
+
+
+
+`;
+
+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,
+ },
+ },
+ });
+}