Skip to content

Commit 6640611

Browse files
committed
feat: add standalone playground, improve demo
1 parent 4b7cad7 commit 6640611

File tree

24 files changed

+434
-127
lines changed

24 files changed

+434
-127
lines changed

app/router.scrollBehavior.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,16 @@ function getScrollPaddingTopInPixels () {
2323
export default async function scrollBehavior (to) {
2424
if (to.hash) {
2525
// scroll to anchor by returning the selector
26+
const selector = decodeURIComponent(to.hash)
27+
try {
28+
document.querySelector(decodeURIComponent(to.hash))
29+
} catch (e) {
30+
return { x: 0, y: 0 }
31+
}
32+
2633
await timeout(0)
2734
return {
28-
selector: decodeURIComponent(to.hash),
35+
selector,
2936
offset: {
3037
y: getScrollPaddingTopInPixels()
3138
}

assets/styles/global.styl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,9 @@ main
3737

3838
.DocSearch-Container
3939
backdrop-filter blur(4px)
40+
41+
.veui-icon
42+
fill currentColor
43+
44+
.VueLive-error
45+
display none

common/config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Vue from 'vue'
2+
3+
const config = new Vue({
4+
data () {
5+
return {
6+
value: {
7+
'link.routerLink': 'nuxt-link',
8+
theme: ''
9+
}
10+
}
11+
}
12+
})
13+
14+
export default config

common/play/index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { loading } from 'dls-graphics'
22
import sdk from '@stackblitz/sdk'
3+
import { utoa } from '../util'
4+
import config from '../config'
35
/* eslint-disable import/no-webpack-loader-syntax */
46
import packageCodeSandbox from '!!raw-loader!./templates/package.codesandbox'
57
import packageStackBlitz from '!!raw-loader!./templates/package.stackblitz'
@@ -33,13 +35,18 @@ const PLAYGROUND_FILES = {
3335

3436
const PLAY_IMPLS = {
3537
CodeSandbox: createCodeSandbox,
36-
StackBlitz: createStackBlitz
38+
StackBlitz: createStackBlitz,
39+
VEUI: createPlayground
3740
}
3841

3942
export function play (sfc, { locale, vendor }) {
4043
PLAY_IMPLS[vendor](sfc, { locale })
4144
}
4245

46+
export function createPlayground (sfc) {
47+
window.open(`/play#${utoa(JSON.stringify({ code: sfc, theme: config.value.theme || undefined }))}`, '_blank')
48+
}
49+
4350
const API_CSB = 'https://codesandbox.io/api/v1/sandboxes/define'
4451

4552
export function createCodeSandbox (sfc, { locale }) {

common/util.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { strToU8, zlibSync, strFromU8, unzlibSync } from 'fflate'
2+
13
export function walk (list, base, callback) {
24
if (!Array.isArray(list)) {
35
return
@@ -54,6 +56,28 @@ export function savePref (key, value) {
5456
localStorage.setItem(PREF_KEY, JSON.stringify(pref))
5557
}
5658

59+
export function utoa (data) {
60+
const buffer = strToU8(data)
61+
const zipped = zlibSync(buffer, { level: 9 })
62+
const binary = strFromU8(zipped, true)
63+
return btoa(binary)
64+
}
65+
66+
export function atou (base64) {
67+
const binary = atob(base64)
68+
69+
// zlib header (x78), level 9 (xDA)
70+
if (binary.startsWith('\x78\xDA')) {
71+
const buffer = strToU8(binary, true)
72+
const unzipped = unzlibSync(buffer)
73+
return strFromU8(unzipped)
74+
}
75+
76+
// old unicode hacks for backward compatibility
77+
// https://base64.guru/developers/javascript/examples/unicode-strings
78+
return decodeURIComponent(escape(binary))
79+
}
80+
5781
export function track (...args) {
5882
if (typeof window !== 'object' || !window.__vaTrack) {
5983
return

components/OneHeader.vue

Lines changed: 19 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<header class="one-header">
33
<section class="brand">
44
<h2 class="veui">
5-
<nuxt-link to="/">
5+
<nuxt-link :to="getLocalePath('/')">
66
VEUI
77
</nuxt-link>
88
</h2>
@@ -18,21 +18,14 @@
1818
</a>
1919
</section>
2020
<section class="desc">
21-
<veui-radio-button-group
22-
ui="s"
23-
:items="themes"
24-
:value="theme"
25-
@change="$emit('themechange', $event)"
26-
/>
27-
<nuxt-link
28-
:class="{
29-
'locale-switch': true,
30-
disabled: altLocale.disabled
31-
}"
32-
:to="altLocale.disabled ? '' : altLocale.to"
21+
<one-theme-toggle/>
22+
<one-locale-link
23+
class="play"
24+
to="/play"
3325
>
34-
<span class="locale-full">{{ altLocale.label }}</span><span class="locale-short">{{ altLocale.shortLabel }}</span>
35-
</nuxt-link>
26+
<b>Play<i>!</i></b>
27+
</one-locale-link>
28+
<one-locale-link toggle/>
3629
<one-search/>
3730
<a href="https://github.com/ecomfe/veui">
3831
<veui-icon name="one-header-github"/>
@@ -42,9 +35,11 @@
4235
</template>
4336

4437
<script>
45-
import { Icon, RadioButtonGroup } from 'veui'
38+
import { Icon } from 'veui'
4639
import i18n from '../common/i18n'
4740
import OneSearch from './OneSearch'
41+
import OneLocaleLink from './OneLocaleLink'
42+
import OneThemeToggle from './OneThemeToggle'
4843
4944
Icon.register({
5045
'one-header-github': {
@@ -59,36 +54,11 @@ export default {
5954
name: 'one-header',
6055
components: {
6156
'veui-icon': Icon,
62-
'veui-radio-button-group': RadioButtonGroup,
63-
'one-search': OneSearch
57+
OneSearch,
58+
OneLocaleLink,
59+
OneThemeToggle
6460
},
65-
mixins: [i18n],
66-
props: {
67-
theme: String
68-
},
69-
data () {
70-
return {
71-
themes: [
72-
{ label: 'D20', value: '' },
73-
{ label: 'D22', value: 'd22' }
74-
]
75-
}
76-
},
77-
computed: {
78-
altLocale () {
79-
let { canonicalPath, locale, getLocalePath, isPathDisabled } = this
80-
let altLocale = locale === 'zh-Hans' ? 'en-US' : 'zh-Hans'
81-
let label = locale === 'zh-Hans' ? 'English' : '中文'
82-
let shortLabel = locale === 'zh-Hans' ? 'EN' : ''
83-
let disabled = isPathDisabled(canonicalPath, altLocale)
84-
return {
85-
to: disabled ? '' : getLocalePath(canonicalPath, altLocale),
86-
disabled,
87-
label,
88-
shortLabel
89-
}
90-
}
91-
}
61+
mixins: [i18n]
9262
}
9363
</script>
9464

@@ -124,28 +94,11 @@ export default {
12494
.veui-icon
12595
font-size 24px
12696
127-
.locale-switch
128-
display flex
129-
align-items center
130-
padding 0 6px
131-
border 1px solid #dbdbdb
132-
border-radius 4px
133-
height 28px
134-
font-size 12px
135-
text-decoration none
136-
transition all 0.2s
137-
138-
&:hover
139-
border-color #999
140-
141-
.locale-short
142-
display none
97+
@media (max-width 540px)
98+
.stars
99+
display none
143100
144101
@media (max-width 480px)
145-
.locale-short
146-
display inline
147-
148-
.stars,
149-
.locale-full
102+
.play
150103
display none
151104
</style>

components/OneLive.vue

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
@copy.native="trackCopy('system')"
2020
/>
2121
<div class="editor-toolbar">
22+
<veui-button
23+
v-if="!standalone"
24+
v-tooltip="t('@onedemo.playInPlayground')"
25+
:ui="iconUi"
26+
@click="play('VEUI')"
27+
>
28+
<veui-icon name="external-link"/>
29+
</veui-button>
2230
<veui-button
2331
v-tooltip="t('@onedemo.playInCodeSandbox')"
2432
:ui="iconUi"
@@ -97,7 +105,7 @@
97105
v-if="error"
98106
v-tooltip="t('dismiss')"
99107
ui="s"
100-
type="error"
108+
status="error"
101109
class="editor-error"
102110
@click.native="dismissError"
103111
>
@@ -124,6 +132,7 @@ import i18n from 'veui/mixins/i18n'
124132
import toast from 'veui/plugins/toast'
125133
import 'veui-theme-dls-icons/copy'
126134
import 'veui-theme-dls-icons/anticlockwise'
135+
import 'veui-theme-dls-icons/external-link'
127136
import { Splitpanes, Pane } from 'splitpanes'
128137
import 'splitpanes/dist/splitpanes.css'
129138
import { getLocale } from '../common/i18n'
@@ -137,6 +146,18 @@ Vue.use(toast)
137146
editor.defineTheme('night-owl', NightOwl)
138147
139148
Icon.register({
149+
'one-demo-codesandbox': {
150+
width: 32,
151+
height: 32,
152+
d:
153+
'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'
154+
},
155+
'one-demo-stackblitz': {
156+
width: 28,
157+
height: 28,
158+
d:
159+
'M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.671-10.227z'
160+
},
140161
'one-live-color-scheme-auto': {
141162
width: 24,
142163
height: 24,
@@ -190,7 +211,8 @@ export default {
190211
default: ''
191212
},
192213
browser: Boolean,
193-
path: String
214+
path: String,
215+
standalone: Boolean
194216
},
195217
data () {
196218
return {
@@ -263,25 +285,23 @@ export default {
263285
}
264286
},
265287
watch: {
266-
localCode: {
267-
immediate: true,
268-
handler (code) {
269-
this.$nextTick(() => {
270-
try {
271-
this.transformedCode = transformLessCode(code)
272-
} catch (e) {
273-
this.error = e
274-
return
275-
}
276-
this.error = null
277-
})
288+
code (val) {
289+
if (this.localCode !== val) {
290+
this.localCode = val
278291
}
279292
},
293+
localCode (val) {
294+
this.$emit('codechange', val)
295+
this.$nextTick(() => {
296+
this.renderCode(val)
297+
})
298+
},
280299
transformedCode () {
281300
this.copied = false
282301
}
283302
},
284303
mounted () {
304+
this.renderCode(this.localCode)
285305
this.mql = window.matchMedia('(prefers-color-scheme: dark)')
286306
this.mql.addEventListener('change', this.handleColorSchemeChange)
287307
this.colorSchemeSystemPref = this.mql.matches ? 'dark' : 'light'
@@ -290,6 +310,15 @@ export default {
290310
this.mql.removeEventListener('change', this.handleColorSchemeChange)
291311
},
292312
methods: {
313+
renderCode (code) {
314+
try {
315+
this.transformedCode = transformLessCode(code)
316+
} catch (e) {
317+
this.error = e
318+
return
319+
}
320+
this.error = null
321+
},
293322
play (vendor) {
294323
let locale = getLocale(this.$route.path)
295324
play(this.localCode, { locale, vendor })

0 commit comments

Comments
 (0)