feat: use live editor on desktop
This commit is contained in:
parent
54393e41bc
commit
6fd9a5a4f4
26
common/transform.js
Normal file
26
common/transform.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import less from 'less/dist/less'
|
||||||
|
|
||||||
|
const lessRE = /<style([^>]* lang="less")?[^>]*>([\s\S]*?)<\/style>/gi
|
||||||
|
|
||||||
|
export function transformLessCode (sfcCode) {
|
||||||
|
return sfcCode.replace(lessRE, (_, p1, p2) => {
|
||||||
|
const lessCode = p2.trim()
|
||||||
|
const cssCode = render(lessCode)
|
||||||
|
return `<style${p1}>${cssCode}</style>`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function render (code) {
|
||||||
|
let css = null
|
||||||
|
|
||||||
|
less.render(code, {
|
||||||
|
syncImport: true
|
||||||
|
}, (err, output) => {
|
||||||
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
css = output.css
|
||||||
|
})
|
||||||
|
|
||||||
|
return css
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<article
|
<article
|
||||||
class="one-demo"
|
class="one-demo"
|
||||||
:class="{ expanded: localExpanded }"
|
:class="{ expanded }"
|
||||||
>
|
>
|
||||||
<section class="demo">
|
<section class="demo">
|
||||||
<browser-window
|
<browser-window
|
||||||
@ -26,27 +26,35 @@
|
|||||||
ui="icon"
|
ui="icon"
|
||||||
@click="play('CodeSandbox')"
|
@click="play('CodeSandbox')"
|
||||||
>
|
>
|
||||||
<veui-icon
|
<veui-icon name="one-demo-codesandbox"/>
|
||||||
name="one-demo-codesandbox"
|
|
||||||
/>
|
|
||||||
</veui-button>
|
</veui-button>
|
||||||
<veui-button
|
<veui-button
|
||||||
v-tooltip="t('playInStackBlitz')"
|
v-tooltip="t('playInStackBlitz')"
|
||||||
ui="icon"
|
ui="icon"
|
||||||
@click="play('StackBlitz')"
|
@click="play('StackBlitz')"
|
||||||
>
|
>
|
||||||
<veui-icon
|
<veui-icon name="one-demo-stackblitz"/>
|
||||||
name="one-demo-stackblitz"
|
|
||||||
/>
|
|
||||||
</veui-button>
|
</veui-button>
|
||||||
<veui-button
|
<veui-button
|
||||||
v-tooltip="t(localExpanded ? 'hideCode' : 'showCode')"
|
v-tooltip="t('expandEditor')"
|
||||||
|
class="toggle-editor"
|
||||||
ui="icon"
|
ui="icon"
|
||||||
@click="localExpanded = !localExpanded"
|
@click="editing = true"
|
||||||
>
|
>
|
||||||
<veui-icon
|
<veui-icon
|
||||||
scale="1.2"
|
scale="1.2"
|
||||||
:name="localExpanded ? 'one-demo-code-off' : 'one-demo-code'"
|
:name="expanded ? 'one-demo-code-off' : 'one-demo-code'"
|
||||||
|
/>
|
||||||
|
</veui-button>
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="t(expanded ? 'hideCode' : 'showCode')"
|
||||||
|
class="toggle-source"
|
||||||
|
ui="icon"
|
||||||
|
@click="expanded = !expanded"
|
||||||
|
>
|
||||||
|
<veui-icon
|
||||||
|
scale="1.2"
|
||||||
|
:name="expanded ? 'one-demo-code-off' : 'one-demo-code'"
|
||||||
/>
|
/>
|
||||||
</veui-button>
|
</veui-button>
|
||||||
<one-edit-link
|
<one-edit-link
|
||||||
@ -59,16 +67,25 @@
|
|||||||
v-if="$slots.source"
|
v-if="$slots.source"
|
||||||
ref="source"
|
ref="source"
|
||||||
class="source"
|
class="source"
|
||||||
:style="{ height: localExpanded ? `${sourceHeight || 0}px` : '0' }"
|
:style="{ height: expanded ? `${sourceHeight || 0}px` : '0' }"
|
||||||
>
|
>
|
||||||
<slot name="source"/>
|
<slot name="source"/>
|
||||||
</section>
|
</section>
|
||||||
|
<transition name="editor">
|
||||||
|
<one-repl
|
||||||
|
v-if="editing"
|
||||||
|
class="one-demo-editor"
|
||||||
|
:code="code"
|
||||||
|
@close="editing = false"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { Button, Icon } from 'veui'
|
import { Button, Icon } from 'veui'
|
||||||
import tooltip from 'veui/directives/tooltip'
|
import tooltip from 'veui/directives/tooltip'
|
||||||
|
import modal from 'veui/managers/modal'
|
||||||
import i18n from 'veui/mixins/i18n'
|
import i18n from 'veui/mixins/i18n'
|
||||||
import { BrowserWindow } from 'vue-windows'
|
import { BrowserWindow } from 'vue-windows'
|
||||||
import { getLocale } from '../common/i18n'
|
import { getLocale } from '../common/i18n'
|
||||||
@ -84,26 +101,29 @@ export default {
|
|||||||
'veui-button': Button,
|
'veui-button': Button,
|
||||||
'veui-icon': Icon,
|
'veui-icon': Icon,
|
||||||
BrowserWindow,
|
BrowserWindow,
|
||||||
OneEditLink
|
OneEditLink,
|
||||||
|
OneRepl: () => import('./OneRepl')
|
||||||
},
|
},
|
||||||
mixins: [i18n],
|
mixins: [i18n],
|
||||||
props: {
|
props: {
|
||||||
expanded: Boolean,
|
|
||||||
browser: String,
|
browser: String,
|
||||||
path: String
|
path: String
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
code: '',
|
||||||
sourceHeight: 0,
|
sourceHeight: 0,
|
||||||
localExpanded: this.expanded
|
expanded: false,
|
||||||
|
editing: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
expanded (val) {
|
editing (value) {
|
||||||
this.localExpanded = val
|
if (value) {
|
||||||
},
|
modal.open()
|
||||||
localExpanded (val) {
|
} else {
|
||||||
this.$emit('update:expanded', val)
|
modal.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@ -113,6 +133,8 @@ export default {
|
|||||||
style.height = source.offsetHeight
|
style.height = source.offsetHeight
|
||||||
this.sourceHeight = source.offsetHeight
|
this.sourceHeight = source.offsetHeight
|
||||||
style.height = '0'
|
style.height = '0'
|
||||||
|
|
||||||
|
this.code = this.$refs.source?.textContent
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
play (vendor) {
|
play (vendor) {
|
||||||
@ -126,22 +148,26 @@ Icon.register({
|
|||||||
'one-demo-code': {
|
'one-demo-code': {
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
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'
|
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'
|
||||||
},
|
},
|
||||||
'one-demo-code-off': {
|
'one-demo-code-off': {
|
||||||
width: 24,
|
width: 24,
|
||||||
height: 24,
|
height: 24,
|
||||||
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'
|
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'
|
||||||
},
|
},
|
||||||
'one-demo-codesandbox': {
|
'one-demo-codesandbox': {
|
||||||
width: 32,
|
width: 32,
|
||||||
height: 32,
|
height: 32,
|
||||||
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'
|
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'
|
||||||
},
|
},
|
||||||
'one-demo-stackblitz': {
|
'one-demo-stackblitz': {
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
d: 'M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.671-10.227z'
|
d:
|
||||||
|
'M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.671-10.227z'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -208,4 +234,33 @@ Icon.register({
|
|||||||
top 50%
|
top 50%
|
||||||
transform translateY(-50%)
|
transform translateY(-50%)
|
||||||
font-size 12px
|
font-size 12px
|
||||||
|
|
||||||
|
.one-demo-editor
|
||||||
|
position fixed
|
||||||
|
top 0
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
bottom 0
|
||||||
|
z-index 10
|
||||||
|
background-color #fff
|
||||||
|
|
||||||
|
.editor-enter-active
|
||||||
|
.editor-leave-active
|
||||||
|
transform-origin 50% 50%
|
||||||
|
transition all 0.3s
|
||||||
|
|
||||||
|
.editor-enter
|
||||||
|
.editor-leave-to
|
||||||
|
opacity 0
|
||||||
|
transform scale(0.99) translateY(3px)
|
||||||
|
|
||||||
|
.toggle-source
|
||||||
|
display none
|
||||||
|
|
||||||
|
@media (max-width 480px)
|
||||||
|
.toggle-source
|
||||||
|
display inline-block
|
||||||
|
|
||||||
|
.toggle-editor
|
||||||
|
display none
|
||||||
</style>
|
</style>
|
||||||
|
262
components/OneLive.vue
Normal file
262
components/OneLive.vue
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
<template>
|
||||||
|
<v-splitpanes class="one-live">
|
||||||
|
<v-pane
|
||||||
|
min-size="30"
|
||||||
|
class="live-editor"
|
||||||
|
>
|
||||||
|
<v-live-editor
|
||||||
|
:code="localCode"
|
||||||
|
line-numbers
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
<div class="editor-toolbar">
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="t('@onedemo.playInCodeSandbox')"
|
||||||
|
ui="s translucent square"
|
||||||
|
@click="play('CodeSandbox')"
|
||||||
|
>
|
||||||
|
<veui-icon name="one-demo-codesandbox"/>
|
||||||
|
</veui-button>
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="t('@onedemo.playInStackBlitz')"
|
||||||
|
ui="s translucent square"
|
||||||
|
@click="play('StackBlitz')"
|
||||||
|
>
|
||||||
|
<veui-icon name="one-demo-stackblitz"/>
|
||||||
|
</veui-button>
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="t('reset')"
|
||||||
|
ui="s translucent square"
|
||||||
|
@click="reset"
|
||||||
|
>
|
||||||
|
<veui-icon name="anticlockwise"/>
|
||||||
|
</veui-button>
|
||||||
|
<veui-button
|
||||||
|
v-tooltip="t('copyCode')"
|
||||||
|
ui="s translucent square"
|
||||||
|
@click="copy"
|
||||||
|
>
|
||||||
|
<veui-icon name="copy"/>
|
||||||
|
</veui-button>
|
||||||
|
<div class="editor-live-badge">
|
||||||
|
<span>Live</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</v-pane>
|
||||||
|
<v-pane
|
||||||
|
min-size="40"
|
||||||
|
class="live-preview"
|
||||||
|
>
|
||||||
|
<v-live-preview
|
||||||
|
:code="transformedCode"
|
||||||
|
:requires="imports"
|
||||||
|
:check-variable-availability="false"
|
||||||
|
@success="dismissError"
|
||||||
|
@error="handleError"
|
||||||
|
/>
|
||||||
|
<transition name="editor-error">
|
||||||
|
<veui-alert
|
||||||
|
v-if="error"
|
||||||
|
v-tooltip="t('dismiss')"
|
||||||
|
ui="s"
|
||||||
|
type="error"
|
||||||
|
class="editor-error"
|
||||||
|
@click.native="dismissError"
|
||||||
|
>
|
||||||
|
<code>{{ errorMessage }}</code>
|
||||||
|
</veui-alert>
|
||||||
|
</transition>
|
||||||
|
</v-pane>
|
||||||
|
</v-splitpanes>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
|
import { VueLiveEditor, VueLivePreview } from 'vue-live'
|
||||||
|
import 'vue-live/lib/vue-live.esm.css'
|
||||||
|
import 'prism-theme-night-owl/build/no-italics.css'
|
||||||
|
import { Button, Icon, Alert } from 'veui'
|
||||||
|
import * as veui from 'veui'
|
||||||
|
import lodash from 'lodash'
|
||||||
|
import 'veui-theme-dls-icons'
|
||||||
|
import tooltip from 'veui/directives/tooltip'
|
||||||
|
import i18n from 'veui/mixins/i18n'
|
||||||
|
import toast from 'veui/plugins/toast'
|
||||||
|
import 'veui-theme-dls-icons/copy'
|
||||||
|
import 'veui-theme-dls-icons/anticlockwise'
|
||||||
|
import { Splitpanes, Pane } from 'splitpanes'
|
||||||
|
import 'splitpanes/dist/splitpanes.css'
|
||||||
|
import { getLocale } from '../common/i18n'
|
||||||
|
import { play } from '../common/play'
|
||||||
|
import { transformLessCode } from '../common/transform'
|
||||||
|
|
||||||
|
Vue.use(toast)
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'one-live',
|
||||||
|
components: {
|
||||||
|
'veui-button': Button,
|
||||||
|
'veui-icon': Icon,
|
||||||
|
'veui-alert': Alert,
|
||||||
|
'v-splitpanes': Splitpanes,
|
||||||
|
'v-pane': Pane,
|
||||||
|
'v-live-editor': VueLiveEditor,
|
||||||
|
'v-live-preview': VueLivePreview
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
tooltip
|
||||||
|
},
|
||||||
|
mixins: [i18n],
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: {
|
||||||
|
code: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
localCode: this.code,
|
||||||
|
transformedCode: '',
|
||||||
|
error: null,
|
||||||
|
imports: {
|
||||||
|
veui,
|
||||||
|
lodash,
|
||||||
|
'veui-theme-dls-icons': {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
errorMessage () {
|
||||||
|
const { error } = this
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return error.name ? `${error.name}: ${error.message}` : error.message
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
localCode: {
|
||||||
|
immediate: true,
|
||||||
|
handler (code) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
try {
|
||||||
|
this.transformedCode = transformLessCode(code)
|
||||||
|
} catch (e) {
|
||||||
|
this.error = e
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.error = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
play (vendor) {
|
||||||
|
let locale = getLocale(this.$route.path)
|
||||||
|
play(this.code, { locale, vendor })
|
||||||
|
},
|
||||||
|
async copy () {
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(this.code)
|
||||||
|
this.$toast.success(this.t('copySuccess'))
|
||||||
|
} catch (e) {
|
||||||
|
this.$toast.error(this.t('copyFailed'))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reset () {
|
||||||
|
this.localCode = this.code
|
||||||
|
},
|
||||||
|
handleChange (code) {
|
||||||
|
this.localCode = code
|
||||||
|
},
|
||||||
|
handleError (error) {
|
||||||
|
this.error = error
|
||||||
|
},
|
||||||
|
dismissError () {
|
||||||
|
this.error = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.one-live
|
||||||
|
& >>> .splitpanes__pane
|
||||||
|
position relative
|
||||||
|
|
||||||
|
& >>> .splitpanes__splitter
|
||||||
|
width 6px
|
||||||
|
background #eee
|
||||||
|
transition all 0.3s
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
background #ccc
|
||||||
|
transform scaleX(2)
|
||||||
|
|
||||||
|
.editor-toolbar
|
||||||
|
position absolute
|
||||||
|
top 12px
|
||||||
|
right 20px
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
|
||||||
|
.editor-live-badge
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
position relative
|
||||||
|
margin-left 8px
|
||||||
|
padding 0 4px 0 20px
|
||||||
|
border-radius 2px
|
||||||
|
font-size 12px
|
||||||
|
background-color #00bf5c
|
||||||
|
color #fff
|
||||||
|
height 18px
|
||||||
|
|
||||||
|
span
|
||||||
|
position relative
|
||||||
|
top -1px
|
||||||
|
|
||||||
|
&::before
|
||||||
|
content ""
|
||||||
|
position absolute
|
||||||
|
left 7px
|
||||||
|
top 6px
|
||||||
|
width 6px
|
||||||
|
height 6px
|
||||||
|
border-radius 50%
|
||||||
|
background-color #fff
|
||||||
|
box-shadow 0 0 0 0 rgba(255, 255, 255, 1)
|
||||||
|
animation pulse 2s infinite
|
||||||
|
|
||||||
|
.editor-error
|
||||||
|
position absolute
|
||||||
|
bottom 16px
|
||||||
|
right 16px
|
||||||
|
left 16px
|
||||||
|
cursor pointer
|
||||||
|
transition all 0.3s
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
opacity 0.8
|
||||||
|
|
||||||
|
.editor-error-enter
|
||||||
|
.editor-error-leave-to
|
||||||
|
opacity 0
|
||||||
|
transform translateY(10px)
|
||||||
|
|
||||||
|
@keyframes pulse
|
||||||
|
0%
|
||||||
|
transform scale(0.95)
|
||||||
|
box-shadow 0 0 0 0 rgba(255, 255, 255, 0.9)
|
||||||
|
|
||||||
|
70%
|
||||||
|
transform scale(1)
|
||||||
|
box-shadow 0 0 0 12px rgba(255, 255, 255, 0)
|
||||||
|
|
||||||
|
100%
|
||||||
|
transform scale(0.95)
|
||||||
|
box-shadow 0 0 0 0 rgba(255, 255, 255, 0)
|
||||||
|
</style>
|
104
components/OneRepl.vue
Normal file
104
components/OneRepl.vue
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<article class="repl">
|
||||||
|
<header class="header">
|
||||||
|
<h1>{{ t('liveEdit') }}</h1>
|
||||||
|
<section class="actions">
|
||||||
|
<veui-button
|
||||||
|
ui="strong text"
|
||||||
|
@click="handleClose"
|
||||||
|
>
|
||||||
|
{{ t('exit') }}
|
||||||
|
</veui-button>
|
||||||
|
</section>
|
||||||
|
</header>
|
||||||
|
<one-live
|
||||||
|
class="editor"
|
||||||
|
:code="code"
|
||||||
|
/>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Button } from 'veui'
|
||||||
|
import i18n from 'veui/mixins/i18n'
|
||||||
|
import OneLive from './OneLive.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'one-repl',
|
||||||
|
components: {
|
||||||
|
'veui-button': Button,
|
||||||
|
'one-live': OneLive
|
||||||
|
},
|
||||||
|
mixins: [i18n],
|
||||||
|
props: {
|
||||||
|
code: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClose () {
|
||||||
|
this.$emit('close')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.repl
|
||||||
|
display flex
|
||||||
|
flex-direction column
|
||||||
|
|
||||||
|
.header
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
flex none
|
||||||
|
height 48px
|
||||||
|
padding 0 24px
|
||||||
|
box-shadow 0 0 4px #0006
|
||||||
|
position relative
|
||||||
|
|
||||||
|
h1
|
||||||
|
flex none
|
||||||
|
margin 0
|
||||||
|
font-size 16px
|
||||||
|
|
||||||
|
.actions
|
||||||
|
display flex
|
||||||
|
justify-content flex-end
|
||||||
|
flex 1 1 auto
|
||||||
|
|
||||||
|
.editor
|
||||||
|
flex 1 1 auto
|
||||||
|
height calc(100vh - 48px)
|
||||||
|
|
||||||
|
& >>> .prism-editor-wrapper
|
||||||
|
padding 8px 12px
|
||||||
|
font-size 12px
|
||||||
|
color #eee
|
||||||
|
background-color #0a0b0d
|
||||||
|
line-height 1.5
|
||||||
|
font-family Menlo, consolas, monospace
|
||||||
|
-webkit-font-smoothing auto
|
||||||
|
|
||||||
|
&::-webkit-scrollbar
|
||||||
|
width 8px
|
||||||
|
background transparent
|
||||||
|
transition all 0.3s
|
||||||
|
|
||||||
|
&-thumb
|
||||||
|
border-radius 4px
|
||||||
|
background-color #282c33
|
||||||
|
|
||||||
|
&:hover::-webkit-scrollbar-thumb
|
||||||
|
background-color #545b66
|
||||||
|
|
||||||
|
textarea
|
||||||
|
outline none
|
||||||
|
|
||||||
|
& >>> .live-preview
|
||||||
|
padding 24px 36px
|
||||||
|
|
||||||
|
& >>> .VueLive-error
|
||||||
|
display none
|
||||||
|
</style>
|
@ -58,7 +58,7 @@ module.exports = {
|
|||||||
transpile: ['veui', 'vue-awesome', 'resize-detector', 'less-plugin-dls', 'dls-graphics'],
|
transpile: ['veui', 'vue-awesome', 'resize-detector', 'less-plugin-dls', 'dls-graphics'],
|
||||||
|
|
||||||
babel: {
|
babel: {
|
||||||
plugins: ['veui', 'lodash']
|
plugins: ['veui']
|
||||||
},
|
},
|
||||||
|
|
||||||
loaders: {
|
loaders: {
|
||||||
@ -104,6 +104,34 @@ module.exports = {
|
|||||||
expr: "process.env.VUE_ENV === 'server'"
|
expr: "process.env.VUE_ENV === 'server'"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
config.resolve.alias.vue$ = 'vue/dist/vue.esm.js'
|
||||||
|
config.resolve.alias['vue-inbrowser-compiler-utils'] = '@justfork/vue-inbrowser-compiler-utils'
|
||||||
|
},
|
||||||
|
|
||||||
|
optimization: {
|
||||||
|
splitChunks: {
|
||||||
|
cacheGroups: {
|
||||||
|
veui: {
|
||||||
|
test: /node_modules[\\/]veui/,
|
||||||
|
chunks: 'all',
|
||||||
|
priority: 20,
|
||||||
|
name: true
|
||||||
|
},
|
||||||
|
'veui-theme-dls-icons': {
|
||||||
|
test: /node_modules[\\/]veui-theme-dls-icons/,
|
||||||
|
chunks: 'all',
|
||||||
|
priority: 20,
|
||||||
|
name: true
|
||||||
|
},
|
||||||
|
'vue-live': {
|
||||||
|
test: /node_modules[\\/]vue-live/,
|
||||||
|
chunks: 'all',
|
||||||
|
priority: 20,
|
||||||
|
name: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
| ``readonly`` | `boolean=` | `false` | 是否为只读状态。 |
|
| ``readonly`` | `boolean=` | `false` | 是否为只读状态。 |
|
||||||
| ``overlay-class`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-class`](./overlay#props-overlay-class) 属性。 |
|
| ``overlay-class`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-class`](./overlay#props-overlay-class) 属性。 |
|
||||||
| ``overlay-style`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-style`](./overlay#props-overlay-style) 属性。 |
|
| ``overlay-style`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-style`](./overlay#props-overlay-style) 属性。 |
|
||||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | [number, number] | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
| ``match`` | `(item, keyword, { ancestors }) => boolean | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||||
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||||
|
|
||||||
^^^ui
|
^^^ui
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
| ``disabled`` | `boolean=` | `false` | 是否为禁用状态。 |
|
| ``disabled`` | `boolean=` | `false` | 是否为禁用状态。 |
|
||||||
| ``overlay-class`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-class`](./overlay#props-overlay-class) 属性。 |
|
| ``overlay-class`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-class`](./overlay#props-overlay-class) 属性。 |
|
||||||
| ``overlay-style`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-style`](./overlay#props-overlay-style) 属性。 |
|
| ``overlay-style`` | `string | Array | Object=` | - | 参考 [`Overlay`](./overlay) 组件的 [`overlay-style`](./overlay#props-overlay-style) 属性。 |
|
||||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | [number, number] | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
| ``match`` | `(item, keyword, { ancestors }) => boolean | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||||
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||||
|
|
||||||
^^^ui
|
^^^ui
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
| ``expanded`` | `boolean=` | `false` | [^expanded] |
|
| ``expanded`` | `boolean=` | `false` | [^expanded] |
|
||||||
| ``disabled`` | `boolean=` | `false` | 是否为禁用状态。 |
|
| ``disabled`` | `boolean=` | `false` | 是否为禁用状态。 |
|
||||||
| ``readonly`` | `boolean=` | `false` | 是否为只读状态。 |
|
| ``readonly`` | `boolean=` | `false` | 是否为只读状态。 |
|
||||||
| ``match`` | `(item, keyword, { ancestors }) => boolean | [number, number] | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
| ``match`` | `(item, keyword, { ancestors }) => boolean | Array<[number, number]>` | - | 支持自定义高亮逻辑, 默认大小写不敏感,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||||
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
| ``filter`` | `(item, keyword, { ancestors, offsets }) => boolean` | - | 支持自定义搜索命中逻辑,参考 [`Autocomplete`](./Autocomplete#自定义搜索逻辑)。 |
|
||||||
|
|
||||||
^^^ui
|
^^^ui
|
||||||
|
@ -6,9 +6,13 @@
|
|||||||
message="恭喜你,你的请求已成功处理"
|
message="恭喜你,你的请求已成功处理"
|
||||||
closable
|
closable
|
||||||
>
|
>
|
||||||
<template slot="title">恭喜你</template>
|
<template slot="title">
|
||||||
|
恭喜你
|
||||||
|
</template>
|
||||||
<template slot="extra">
|
<template slot="extra">
|
||||||
<veui-button ui="text">查看详情</veui-button>
|
<veui-button ui="text">
|
||||||
|
查看详情
|
||||||
|
</veui-button>
|
||||||
</template>
|
</template>
|
||||||
恭喜你,你的请求已成功处理
|
恭喜你,你的请求已成功处理
|
||||||
</veui-alert>
|
</veui-alert>
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
type="success"
|
type="success"
|
||||||
>
|
>
|
||||||
Your profile has been updated.
|
Your profile has been updated.
|
||||||
<template slot="title">消息标题</template>
|
<template slot="title">
|
||||||
|
消息标题
|
||||||
|
</template>
|
||||||
</veui-alert>
|
</veui-alert>
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
@ -101,7 +101,6 @@ export default {
|
|||||||
top: 10px;
|
top: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<docs>
|
<docs>
|
||||||
|
@ -132,7 +132,6 @@ export default {
|
|||||||
top: 50px;
|
top: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<docs>
|
<docs>
|
||||||
|
@ -108,7 +108,6 @@ export default {
|
|||||||
top: 50px;
|
top: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<docs>
|
<docs>
|
||||||
|
@ -46,7 +46,7 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped docs>
|
<style lang="less" scoped>
|
||||||
h4 {
|
h4 {
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<article>
|
<article>
|
||||||
|
<section>
|
||||||
<veui-pagination
|
<veui-pagination
|
||||||
:page="page"
|
:page="page"
|
||||||
:total="total"
|
:total="total"
|
||||||
:to="to"
|
:to="to"
|
||||||
/>
|
/>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
<veui-pagination
|
<veui-pagination
|
||||||
:page="page"
|
:page="page"
|
||||||
:total="total"
|
:total="total"
|
||||||
:to="to"
|
:to="to"
|
||||||
ui="s"
|
ui="s"
|
||||||
/>
|
/>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
<veui-pagination
|
<veui-pagination
|
||||||
:page="page"
|
:page="page"
|
||||||
:total="total"
|
:total="total"
|
||||||
:to="to"
|
:to="to"
|
||||||
ui="xs"
|
ui="xs"
|
||||||
/>
|
/>
|
||||||
|
</section>
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<article>
|
<article>
|
||||||
<section>
|
<section>
|
||||||
<p>loading:<veui-switch v-model="loading"/></p>
|
<div>loading:<veui-switch v-model="loading"/></div>
|
||||||
<veui-table
|
<veui-table
|
||||||
:data="data"
|
:data="data"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<article>
|
<article>
|
||||||
<section>
|
<section>
|
||||||
<p>
|
<div>
|
||||||
允许不排序:<veui-switch
|
允许不排序:<veui-switch
|
||||||
v-model="allowFalse"
|
v-model="allowFalse"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
/>
|
/>
|
||||||
</p>
|
</div>
|
||||||
<veui-table
|
<veui-table
|
||||||
:data="sorted"
|
:data="sorted"
|
||||||
key-field="id"
|
key-field="id"
|
||||||
|
1642
package-lock.json
generated
1642
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docsearch/css": "^3.0.0-alpha.39",
|
"@docsearch/css": "^3.0.0-alpha.39",
|
||||||
"@docsearch/js": "^3.0.0-alpha.39",
|
"@docsearch/js": "^3.0.0-alpha.39",
|
||||||
|
"@justfork/vue-inbrowser-compiler-utils": "^4.42.0",
|
||||||
"@stackblitz/sdk": "^1.5.2",
|
"@stackblitz/sdk": "^1.5.2",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-plugin-lodash": "^3.3.4",
|
"babel-plugin-lodash": "^3.3.4",
|
||||||
@ -45,10 +46,10 @@
|
|||||||
"hastscript": "^3.1.0",
|
"hastscript": "^3.1.0",
|
||||||
"highlight.js": "^10.7.3",
|
"highlight.js": "^10.7.3",
|
||||||
"js-yaml": "^3.13.1",
|
"js-yaml": "^3.13.1",
|
||||||
"less": "3.9.0",
|
"less": "^3.13.1",
|
||||||
"less-loader": "^4.1.0",
|
"less-loader": "^4.1.0",
|
||||||
"less-plugin-est": "^3.0.0",
|
"less-plugin-est": "^3.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lowlight": "^1.9.2",
|
"lowlight": "^1.9.2",
|
||||||
"mdast-util-to-string": "^2.0.0",
|
"mdast-util-to-string": "^2.0.0",
|
||||||
"mkdirp": "^0.5.5",
|
"mkdirp": "^0.5.5",
|
||||||
@ -58,6 +59,7 @@
|
|||||||
"preact": "^10.5.14",
|
"preact": "^10.5.14",
|
||||||
"prettier": "^1.16.4",
|
"prettier": "^1.16.4",
|
||||||
"prettier-eslint": "^8.8.2",
|
"prettier-eslint": "^8.8.2",
|
||||||
|
"prism-theme-night-owl": "^1.4.0",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
"recursive-readdir": "^2.2.2",
|
"recursive-readdir": "^2.2.2",
|
||||||
"recursive-readdir-sync": "^1.0.6",
|
"recursive-readdir-sync": "^1.0.6",
|
||||||
@ -71,6 +73,7 @@
|
|||||||
"remark-shortcodes": "^0.1.5",
|
"remark-shortcodes": "^0.1.5",
|
||||||
"remark-slug": "^4.2.3",
|
"remark-slug": "^4.2.3",
|
||||||
"short-circuit-loader": "0.0.1-alpha.2",
|
"short-circuit-loader": "0.0.1-alpha.2",
|
||||||
|
"splitpanes": "^2.3.8",
|
||||||
"stringify-object": "^3.3.0",
|
"stringify-object": "^3.3.0",
|
||||||
"stylelint": "^13.6.1",
|
"stylelint": "^13.6.1",
|
||||||
"stylelint-plugin-stylus": "^0.9.0",
|
"stylelint-plugin-stylus": "^0.9.0",
|
||||||
@ -84,6 +87,7 @@
|
|||||||
"veui-theme-dls-icons": "^2.2.1",
|
"veui-theme-dls-icons": "^2.2.1",
|
||||||
"vue-awesome": "^4.1.0",
|
"vue-awesome": "^4.1.0",
|
||||||
"vue-i18n": "^8.16.0",
|
"vue-i18n": "^8.16.0",
|
||||||
|
"vue-live": "^1.17.1",
|
||||||
"vue-windows": "^0.2.4"
|
"vue-windows": "^0.2.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -5,6 +5,7 @@ i18n.register(
|
|||||||
{
|
{
|
||||||
showCode: '显示代码',
|
showCode: '显示代码',
|
||||||
hideCode: '隐藏代码',
|
hideCode: '隐藏代码',
|
||||||
|
expandEditor: '展开实时编辑',
|
||||||
playInCodeSandbox: '在 CodeSandbox 中打开',
|
playInCodeSandbox: '在 CodeSandbox 中打开',
|
||||||
playInStackBlitz: '在 StackBlitz 中打开'
|
playInStackBlitz: '在 StackBlitz 中打开'
|
||||||
},
|
},
|
||||||
@ -18,6 +19,7 @@ i18n.register(
|
|||||||
{
|
{
|
||||||
showCode: 'Show code',
|
showCode: 'Show code',
|
||||||
hideCode: 'Hide code',
|
hideCode: 'Hide code',
|
||||||
|
expandEditor: 'Expand Live Editor',
|
||||||
playInCodeSandbox: 'Open in CodeSandbox',
|
playInCodeSandbox: 'Open in CodeSandbox',
|
||||||
playInStackBlitz: 'Open in StackBlitz'
|
playInStackBlitz: 'Open in StackBlitz'
|
||||||
},
|
},
|
||||||
@ -26,6 +28,56 @@ i18n.register(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
i18n.register(
|
||||||
|
'zh-Hans',
|
||||||
|
{
|
||||||
|
copyCode: '复制代码',
|
||||||
|
copySuccess: '复制成功!',
|
||||||
|
copyFailed: '复制失败!',
|
||||||
|
reset: '重置',
|
||||||
|
dismiss: '关闭'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ns: 'onelive'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
i18n.register(
|
||||||
|
'en-US',
|
||||||
|
{
|
||||||
|
copyCode: 'Copy code',
|
||||||
|
copySuccess: 'Copy success!',
|
||||||
|
copyFailed: 'Copy failed!',
|
||||||
|
reset: 'Reset',
|
||||||
|
dismiss: 'Dismiss'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ns: 'onelive'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
i18n.register(
|
||||||
|
'zh-Hans',
|
||||||
|
{
|
||||||
|
exit: '退出',
|
||||||
|
liveEdit: '实时编辑'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ns: 'onerepl'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
i18n.register(
|
||||||
|
'en-US',
|
||||||
|
{
|
||||||
|
exit: 'Exit',
|
||||||
|
liveEdit: 'Live Edit'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ns: 'onerepl'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
i18n.register(
|
i18n.register(
|
||||||
'zh-Hans',
|
'zh-Hans',
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user