UNPKG

5.53 kBPlain TextView Raw
1<template>
2 <div
3 class="editor"
4 :class="{
5 'editor--shrink': isSidebarShown
6 }"
7 >
8 <!-- 瀑布流模式 -->
9 <template v-if="config.editorViewMode === 'waterfall'">
10 <div
11 class="editor-box"
12 v-for="[type, content] in showBoxes"
13 :key="type + content.key"
14 >
15 <header
16 class="editor-boxName"
17 :class="{
18 'editor-boxName--folded': isSandboxFolded(type)
19 }"
20 @dblclick="toggleFold(type)"
21 >
22 <span class="editor-boxType">{{ type.toUpperCase() }}</span>
23 <span class="editor-boxTransformer">{{ content.transformer }}</span>
24 </header>
25 <sandbox
26 class="editor-sandbox"
27 :is-folded="isSandboxFolded(type)"
28 :value="content.code"
29 :language="content.transformer"
30 :editorHook="content.editorHook"
31 @input="codeUpdate(type, arguments)"
32 ></sandbox>
33 </div>
34 </template>
35 <template v-if="config.editorViewMode === 'tab'">
36 <ul class="editor-tabs">
37 <li
38 class="editor-tab"
39 :class="{
40 'editor-tab--active': currentBox === type
41 }"
42 v-for="[type, content] in showBoxes"
43 :key="type"
44 @click="updateCurrentBox(type)"
45 >
46 <span class="editor-tabName">{{
47 content.tabName || type.toUpperCase()
48 }}</span>
49 <span v-show="currentBox === type" class="editor-tabTransformer">
50 {{ content.transformer }}
51 </span>
52 </li>
53 </ul>
54 <sandbox
55 v-for="[type, content] in showBoxes"
56 :key="type + content.key"
57 v-show="currentBox === type"
58 class="editor-sandbox--tab"
59 :value="content.code"
60 :language="content.transformer"
61 :editorHook="content.editorHook"
62 @input="codeUpdate(type, arguments)"
63 >
64 &lt;
65 </sandbox>
66 </template>
67 </div>
68</template>
69
70<script>
71import PerfectScrollbar from 'perfect-scrollbar';
72import Sandbox from './sandbox.vue';
73import { mapState, mapActions } from 'vuex';
74export default {
75 computed: {
76 ...mapState([
77 'foldBoxes',
78 'foldBoxes',
79 'config',
80 'currentBox',
81 'isSidebarShown'
82 ]),
83 ...mapState({
84 showBoxes(state) {
85 return Object.entries(state.boxes).filter(([type, value]) => {
86 return value.visible;
87 });
88 }
89 })
90 },
91 components: { Sandbox },
92 methods: {
93 ...mapActions(['toggleBoxFold', 'updateCode', 'updateCurrentBox']),
94 isSandboxFolded(type) {
95 return this.foldBoxes.indexOf(type) > -1;
96 },
97 codeUpdate(type, [code]) {
98 this.updateCode({ type, code });
99 },
100 toggleFold(type) {
101 this.toggleBoxFold(type);
102 }
103 },
104 mounted() {
105 new PerfectScrollbar(document.querySelector('.editor'), {
106 suppressScrollX: true
107 });
108 }
109};
110</script>
111
112<style lang="scss">
113@import '@/css/index.scss';
114@import '~perfect-scrollbar/css/perfect-scrollbar.css';
115.editor {
116 height: 100%;
117 overflow-y: auto;
118 &-box {
119 font-family: $link-font-family;
120 margin: 0 20px 20px 20px;
121 &Name {
122 line-height: 60px;
123 border-bottom: 1px solid rgba($c-highlight, 0.2);
124 display: flex;
125 justify-content: space-between;
126 align-items: center;
127 &Btn {
128 width: 15px;
129 height: 15px;
130 background: $c-highlight;
131 border-radius: 50%;
132 overflow: hidden;
133 position: relative;
134 &::after {
135 content: '';
136 width: 100%;
137 height: 100%;
138 background: $c-bg;
139 position: absolute;
140 top: 0;
141 left: 0;
142 border-radius: 50%;
143 transform: translate(-25%, -25%);
144 transition: 0.5s all ease-out;
145 }
146 &--partial {
147 &::after {
148 transform: translate(-100%, -100%);
149 }
150 }
151 }
152 &--folded {
153 & h2 {
154 color: $c-font;
155 }
156 border-bottom-color: rgba($c-font, 0.2);
157 opacity: 0.4;
158 }
159 }
160 &Transformer {
161 user-select: none;
162 color: rgba($c-font, 0.4);
163 }
164 &Type {
165 font-size: 18px;
166 margin: 0;
167 padding: 0;
168 user-select: none;
169 color: $c-highlight;
170 }
171 }
172 &-tabs {
173 display: flex;
174 margin: 0;
175 padding: 0;
176 margin: 20px 10px 10px 10px;
177 border-bottom: 1px solid rgba($c-highlight, 0.2);
178 }
179 &-tab {
180 font-family: $link-font-family;
181 list-style: none;
182 flex-grow: 1;
183 display: flex;
184 flex-direction: column;
185 align-items: center;
186 justify-content: center;
187 height: 30px;
188 padding-bottom: 10px;
189 filter: brightness(0.6);
190 transition: 0.3s all ease-out;
191 cursor: pointer;
192 border-radius: 8px 8px 0 0;
193 &--active {
194 filter: brightness(1);
195 background: rgba($c-highlight, 0.05);
196 & .editor-tabName {
197 transform: translateY(-6px);
198 font-size: 22px;
199 color: $c-highlight;
200 text-shadow: 0 0 8px rgba($c-highlight, 0.5);
201 }
202 }
203 &Name {
204 transition: 0.3s all ease-out;
205 color: rgba(#f6f4f2, 0.6);
206 font-size: 18px;
207 }
208 &Transformer {
209 font-size: 12px;
210 color: rgba(#f6f4f2, 0.6);
211 }
212 }
213 &-sandbox {
214 &--tab {
215 margin: 0 10px;
216 transition: 0.3s all ease-out;
217 height: calc(100% - 72px);
218 }
219 }
220}
221
222@media (max-width: $c-small-screen) {
223 .editor {
224 &--shrink {
225 height: calc(100vh - 60px);
226 }
227 }
228}
229</style>