docs_vue2/components/OneDemo.vue

344 lines
7.3 KiB
Vue
Raw Permalink Normal View History

2020-08-13 11:47:56 +08:00
<template>
2022-06-14 09:05:00 +08:00
<article class="one-demo" :class="{ codeExpanded }">
<section class="demo">
<browser-window
v-if="browser"
:url="browser"
width="calc(100% - 40px)"
height="400px"
>
<one-iframe
global-style="body { margin: 0 !important; } .veui-layout { min-width: auto !important; }"
>
<slot />
</one-iframe>
</browser-window>
<slot v-else />
</section>
<section v-if="$slots.desc" class="desc">
<slot name="desc" />
</section>
<section class="actions">
<veui-button
v-tooltip="t(codeExpanded ? 'hideCode' : 'showCode')"
ui="icon"
@click="codeExpanded = !codeExpanded"
>
<veui-icon
scale="1.2"
:name="codeExpanded ? 'one-demo-code-off' : 'one-demo-code'"
/>
</veui-button>
2022-02-24 14:38:23 +08:00
<veui-button
2022-06-14 09:05:00 +08:00
v-tooltip="t(editing ? 'closeEditor' : 'openEditor')"
class="toggle-editor"
ui="text"
@click="editing = !editing"
2022-02-24 14:38:23 +08:00
>
2022-06-14 09:05:00 +08:00
Live
2022-02-24 14:38:23 +08:00
</veui-button>
2022-06-14 09:05:00 +08:00
<!-- 禁用跳转Github -->
<!-- <one-edit-link class="edit" variant="quiet" type="demo" :path="path" /> -->
</section>
<section
v-if="$slots.source"
ref="source"
class="source"
:style="{ height: codeExpanded ? `${sourceHeight || 0}px` : '0' }"
>
<div class="source-toolbar">
<veui-button
v-tooltip="t('@onelive.copyCode')"
ui="icon reverse"
@click="copy"
>
<veui-icon name="copy" />
</veui-button>
</div>
<slot name="source" />
</section>
<transition name="editor">
<one-repl
v-if="editing"
class="one-demo-editor"
:class="{
'one-demo-editor-shrink': !editorExpanded,
}"
:code="code"
:expanded="editorExpanded"
:browser="!!browser"
@close="handleEditorClose"
@toggle="handleEditorToggle"
/>
</transition>
</article>
2020-08-13 11:47:56 +08:00
</template>
<script>
2022-06-14 09:05:00 +08:00
import Vue from "vue";
import { Button, Icon } from "veui";
import tooltip from "veui/directives/tooltip";
import modal from "veui/managers/modal";
import i18n from "veui/mixins/i18n";
import toast from "veui/plugins/toast";
import { BrowserWindow } from "vue-windows";
import { getLocale } from "../common/i18n";
import { play } from "../common/play";
import OneIframe from "./OneIframe";
import OneEditLink from "./OneEditLink";
import OneRepl from "./OneRepl";
import "veui-theme-dls-icons/copy";
2022-02-24 14:38:23 +08:00
2022-06-14 09:05:00 +08:00
Vue.use(toast);
2020-08-13 11:47:56 +08:00
export default {
2022-06-14 09:05:00 +08:00
name: "one-demo",
2021-09-15 19:19:09 +08:00
directives: {
2022-06-14 09:05:00 +08:00
tooltip,
2021-09-15 19:19:09 +08:00
},
2020-08-13 11:47:56 +08:00
components: {
2022-06-14 09:05:00 +08:00
"veui-button": Button,
"veui-icon": Icon,
2021-10-25 20:18:05 +08:00
BrowserWindow,
2022-04-26 15:45:48 +08:00
OneIframe,
2021-11-20 13:22:48 +08:00
OneEditLink,
2022-06-14 09:05:00 +08:00
OneRepl,
2020-08-13 11:47:56 +08:00
},
mixins: [i18n],
props: {
2021-10-25 20:18:05 +08:00
browser: String,
2022-06-14 09:05:00 +08:00
path: String,
2020-08-13 11:47:56 +08:00
},
2022-06-14 09:05:00 +08:00
data() {
2020-08-13 11:47:56 +08:00
return {
2022-06-14 09:05:00 +08:00
code: "",
2020-08-13 11:47:56 +08:00
sourceHeight: 0,
codeExpanded: false,
editing: false,
2022-06-14 09:05:00 +08:00
editorExpanded: true,
};
},
computed: {
2022-06-14 09:05:00 +08:00
lock() {
return this.editing && this.editorExpanded;
},
2020-08-13 11:47:56 +08:00
},
watch: {
2022-06-14 09:05:00 +08:00
lock(value) {
2021-11-20 13:22:48 +08:00
if (value) {
2022-06-14 09:05:00 +08:00
modal.open();
2021-11-20 13:22:48 +08:00
} else {
2022-06-14 09:05:00 +08:00
modal.close();
2021-11-20 13:22:48 +08:00
}
2022-06-14 09:05:00 +08:00
},
2020-08-13 11:47:56 +08:00
},
2022-06-14 09:05:00 +08:00
mounted() {
let source = this.$refs.source;
let style = source.style;
style.height = "";
style.height = source.offsetHeight;
this.sourceHeight = source.offsetHeight;
style.height = "0";
2021-11-20 13:22:48 +08:00
2022-06-14 09:05:00 +08:00
this.code = this.$refs.source?.querySelector("pre")?.textContent || "";
2021-09-15 19:19:09 +08:00
},
2022-06-14 09:05:00 +08:00
destroyed() {
modal.close();
2022-05-07 00:02:55 +08:00
},
2021-09-15 19:19:09 +08:00
methods: {
2022-06-14 09:05:00 +08:00
play(vendor) {
let locale = getLocale(this.$route.path);
play(this.$refs.source.textContent, { locale, vendor });
},
2022-06-14 09:05:00 +08:00
async copy() {
2022-02-24 14:38:23 +08:00
try {
2022-06-14 09:05:00 +08:00
await navigator.clipboard.writeText(this.code);
this.$toast.success(this.t("@onelive.copySuccess"));
2022-02-24 14:38:23 +08:00
} catch (e) {
2022-06-14 09:05:00 +08:00
this.$toast.error(this.t("@onelive.copyFailed"));
2022-02-24 14:38:23 +08:00
}
},
2022-06-14 09:05:00 +08:00
handleEditorClose() {
this.editing = false;
},
2022-06-14 09:05:00 +08:00
handleEditorToggle(val) {
this.editorExpanded = val;
},
},
};
2021-09-15 19:19:09 +08:00
Icon.register({
2022-06-14 09:05:00 +08:00
"one-demo-code": {
2021-09-15 19:19:09 +08:00
width: 24,
height: 24,
2022-06-14 09:05:00 +08:00
d: "M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6l6 6l1.4-1.4zm5.2 0l4.6-4.6l-4.6-4.6L16 6l6 6l-6 6l-1.4-1.4z",
2021-09-15 19:19:09 +08:00
},
2022-06-14 09:05:00 +08:00
"one-demo-code-off": {
2021-09-15 19:19:09 +08:00
width: 24,
height: 24,
2022-06-14 09:05:00 +08:00
d: "M19.17 12l-4.58-4.59L16 6l6 6l-3.59 3.59L17 14.17L19.17 12zM1.39 4.22l4.19 4.19L2 12l6 6l1.41-1.41L4.83 12L7 9.83l12.78 12.78l1.41-1.41L2.81 2.81L1.39 4.22z",
2021-09-15 19:19:09 +08:00
},
2022-06-14 09:05:00 +08:00
"one-demo-codesandbox": {
2021-09-15 19:19:09 +08:00
width: 32,
height: 32,
2022-06-14 09:05:00 +08:00
d: "M2.667 8l13.938-8l13.943 8l.12 15.932L16.605 32L2.667 24zm2.786 3.307v6.344l4.458 2.479v4.688l5.297 3.063V16.85zm22.318 0l-9.755 5.542V27.88l5.292-3.063v-4.682l4.464-2.484zM6.844 8.802l9.74 5.526l9.76-5.573l-5.161-2.932l-4.547 2.594l-4.573-2.625z",
2021-09-19 15:34:14 +08:00
},
2022-06-14 09:05:00 +08:00
"one-demo-stackblitz": {
2021-09-19 15:34:14 +08:00
width: 28,
height: 28,
2022-06-14 09:05:00 +08:00
d: "M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.671-10.227z",
},
});
2020-08-13 11:47:56 +08:00
</script>
<style src="vue-windows/dist/vue-windows.css"></style>
<style lang="stylus" scoped>
2022-06-14 09:05:00 +08:00
.one-demo {
overflow: hidden;
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.demo {
border: 1px solid #eee;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
padding: 30px;
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
& >>> .style-module_body__14MV- {
overflow: hidden;
transform: translate(0, 0);
padding: 0;
}
}
2022-06-14 09:05:00 +08:00
.desc {
border: 1px solid #eee;
padding: 18px 20px;
background-color: #fcfcfc;
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.source {
position: relative;
overflow: hidden;
transition: height 0.3s;
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
& >>> pre {
margin-top: 0;
margin-bottom: 0;
border-top-right-radius: 0;
border-top-left-radius: 0;
}
}
2021-07-19 20:12:14 +08:00
2022-06-14 09:05:00 +08:00
.desc, .source >>> pre, .actions {
margin-top: -1px;
}
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.actions {
position: relative;
display: flex;
justify-content: center;
align-items: center;
line-height: 2;
width: 100%;
height: 48px;
border: 1px solid #eee;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
background-color: #fff;
transition: background-color 0.3s;
outline: none;
2020-08-13 11:47:56 +08:00
2022-06-14 09:05:00 +08:00
.codeExpanded & {
border-radius: 0;
}
2022-06-14 09:05:00 +08:00
.veui-button:not(.toggle-editor) {
font-size: 18px;
}
2021-09-15 19:19:09 +08:00
2022-06-14 09:05:00 +08:00
.veui-button + .veui-button {
margin-left: 12px;
}
}
2021-10-25 20:18:05 +08:00
2022-06-14 09:05:00 +08:00
.edit {
position: absolute;
right: 30px;
top: 50%;
transform: translateY(-50%);
font-size: 12px;
}
2021-11-20 13:22:48 +08:00
2022-06-14 09:05:00 +08:00
.one-demo-editor {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
background-color: #fff;
transition: bottom 0.1s, box-shadow 0.2s;
2022-06-14 09:05:00 +08:00
&-shrink {
bottom: 50vh;
box-shadow: 0 0 4px #0006;
}
}
2021-11-20 13:22:48 +08:00
2022-06-14 09:05:00 +08:00
.editor-enter-active, .editor-leave-active {
transform-origin: 50% 50%;
transition: all 0.3s;
}
2021-11-20 13:22:48 +08:00
2022-06-14 09:05:00 +08:00
.editor-enter, .editor-leave-to {
opacity: 0;
transform: scale(0.99) translateY(3px);
}
2021-11-20 13:22:48 +08:00
2022-06-14 09:05:00 +08:00
.toggle-editor {
height: 20px;
padding: 0 3px;
font-weight: 600;
2021-11-20 13:22:48 +08:00
2022-06-14 09:05:00 +08:00
&::after {
content: none !important;
}
2022-02-23 20:19:58 +08:00
2022-06-14 09:05:00 +08:00
&, &:hover, &[data-focus-visible-added], &:active {
border: 1.5px solid currentColor !important;
}
2021-11-20 13:22:48 +08:00
2022-06-14 09:05:00 +08:00
&[data-focus-visible-added] {
border-color: #0052cc !important;
box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.2) !important;
}
}
2022-02-23 20:19:58 +08:00
2022-06-14 09:05:00 +08:00
.source-toolbar {
position: absolute;
top: 12px;
right: 28px;
display: flex;
align-items: center;
}
2022-02-24 14:38:23 +08:00
2022-06-14 09:05:00 +08:00
.veui-button[ui~='icon'][ui~='reverse'] {
color: #ebedf5;
2022-02-24 14:38:23 +08:00
2022-06-14 09:05:00 +08:00
&:hover, &[data-focus-visible-added] {
color: #f6f7fa;
}
2022-02-24 14:38:23 +08:00
2022-06-14 09:05:00 +08:00
&:active {
color: #fff;
}
}
2022-02-24 14:38:23 +08:00
2022-06-14 09:05:00 +08:00
@media (max-width: 480px) {
.toggle-editor {
display: none;
}
}
2020-08-13 11:47:56 +08:00
</style>