Skip to content

workflow: support custom TS version for playground #8735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/sfc-playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.2.3",
"vite": "^4.3.9"
"vite": "^4.4.2"
},
"dependencies": {
"@vue/repl": "^2.4.0",
"@vue/repl": "^2.5.4",
"file-saver": "^2.0.5",
"jszip": "^3.6.0",
"vue": "workspace:*"
Expand Down
2 changes: 1 addition & 1 deletion packages/sfc-playground/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function toggleSSR() {
store.setFiles(store.getFiles())
}

const theme = ref('dark')
const theme = ref<'dark' | 'light'>('dark')
function toggleTheme(isDark: boolean) {
theme.value = isDark ? 'dark' : 'light'
}
Expand Down
148 changes: 36 additions & 112 deletions packages/sfc-playground/src/Header.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
<script setup lang="ts">
import { downloadProject } from './download/download'
import { ref, onMounted } from 'vue'
import { ref } from 'vue'
import Sun from './icons/Sun.vue'
import Moon from './icons/Moon.vue'
import Share from './icons/Share.vue'
import Download from './icons/Download.vue'
import GitHub from './icons/GitHub.vue'
import type { ReplStore } from '@vue/repl'
import VersionSelect from './VersionSelect.vue'

const props = defineProps<{
store: ReplStore
dev: boolean
ssr: boolean
}>()
const emit = defineEmits(['toggle-theme', 'toggle-ssr', 'toggle-dev'])

const { store } = props

const currentCommit = __COMMIT__
const activeVersion = ref(`@${currentCommit}`)
const publishedVersions = ref<string[]>()
const expanded = ref(false)

async function toggle() {
expanded.value = !expanded.value
if (!publishedVersions.value) {
publishedVersions.value = await fetchVersions()
}
}
const vueVersion = ref(`@${currentCommit}`)

async function setVueVersion(v: string) {
activeVersion.value = `loading...`
vueVersion.value = `loading...`
await store.setVueVersion(v)
activeVersion.value = `v${v}`
expanded.value = false
vueVersion.value = `v${v}`
}

function resetVueVersion() {
store.resetVueVersion()
activeVersion.value = `@${currentCommit}`
expanded.value = false
vueVersion.value = `@${currentCommit}`
}

async function copyLink(e: MouseEvent) {
Expand All @@ -51,54 +42,14 @@ async function copyLink(e: MouseEvent) {
alert('Sharable URL has been copied to clipboard.')
}

const emit = defineEmits(['toggle-theme', 'toggle-ssr','toggle-dev'])
function toggleDark() {
function toggleDark() {
const cls = document.documentElement.classList
cls.toggle('dark')
localStorage.setItem(
'vue-sfc-playground-prefer-dark',
String(cls.contains('dark'))
)
emit('toggle-theme', cls.contains('dark'))
}

onMounted(async () => {
window.addEventListener('click', () => {
expanded.value = false
})
window.addEventListener('blur', () => {
if (document.activeElement?.tagName === 'IFRAME') {
expanded.value = false
}
})
})

async function fetchVersions(): Promise<string[]> {
const res = await fetch(
`https://api.github.com/repos/vuejs/core/releases?per_page=100`
cls.toggle('dark')
localStorage.setItem(
'vue-sfc-playground-prefer-dark',
String(cls.contains('dark'))
)
const releases: any[] = await res.json()
const versions = releases.map(r =>
/^v/.test(r.tag_name) ? r.tag_name.slice(1) : r.tag_name
)
// if the latest version is a pre-release, list all current pre-releases
// otherwise filter out pre-releases
let isInPreRelease = versions[0].includes('-')
const filteredVersions: string[] = []
for (const v of versions) {
if (v.includes('-')) {
if (isInPreRelease) {
filteredVersions.push(v)
}
} else {
filteredVersions.push(v)
isInPreRelease = false
}
if (filteredVersions.length >= 30 || v === '3.0.10') {
break
}
}
return filteredVersions
emit('toggle-theme', cls.contains('dark'))
}
</script>

Expand All @@ -109,28 +60,28 @@ async function fetchVersions(): Promise<string[]> {
<span>Vue SFC Playground</span>
</h1>
<div class="links">
<div class="version" @click.stop>
<span class="active-version" @click="toggle">
Version
<span class="number">{{ activeVersion }}</span>
</span>
<ul class="versions" :class="{ expanded }">
<li v-if="!publishedVersions"><a>loading versions...</a></li>
<li v-for="version of publishedVersions">
<a @click="setVueVersion(version)">v{{ version }}</a>
</li>
<li>
<a @click="resetVueVersion">This Commit ({{ currentCommit }})</a>
</li>
<li>
<a
href="https://app.netlify.com/sites/vue-sfc-playground/deploys"
target="_blank"
>Commits History</a
>
</li>
</ul>
</div>
<VersionSelect
v-model="store.state.typescriptVersion"
pkg="typescript"
label="TypeScript Version"
/>
<VersionSelect
:model-value="vueVersion"
@update:model-value="setVueVersion"
pkg="vue"
label="Vue Version"
>
<li>
<a @click="resetVueVersion">This Commit ({{ currentCommit }})</a>
</li>
<li>
<a
href="https://app.netlify.com/sites/vue-sfc-playground/deploys"
target="_blank"
>Commits History</a
>
</li>
</VersionSelect>
<button
title="Toggle development production mode"
class="toggle-dev"
Expand All @@ -147,7 +98,7 @@ async function fetchVersions(): Promise<string[]> {
>
<span>{{ ssr ? 'SSR ON' : 'SSR OFF' }}</span>
</button>
<button title="Toggle dark mode" class="toggle-dark" @click="toggleDark">
<button title="Toggle dark mode" class="toggle-dark" @click="toggleDark">
<Sun class="light" />
<Moon class="dark" />
</button>
Expand Down Expand Up @@ -235,33 +186,6 @@ h1 img {
display: flex;
}

.version {
margin-right: 12px;
position: relative;
}

.active-version {
cursor: pointer;
position: relative;
display: inline-flex;
place-items: center;
}

.active-version .number {
color: var(--green);
margin-left: 4px;
}

.active-version::after {
content: '';
width: 0;
height: 0;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 6px solid #aaa;
margin-left: 8px;
}

.toggle-dev span,
.toggle-ssr span {
font-size: 12px;
Expand Down
114 changes: 114 additions & 0 deletions packages/sfc-playground/src/VersionSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue'

const expanded = ref(false)
const versions = ref<string[]>()

const version = defineModel()
const props = defineProps<{
pkg: string
label: string
}>()

async function toggle() {
expanded.value = !expanded.value
if (!versions.value) {
versions.value = await fetchVersions()
}
}

async function fetchVersions(): Promise<string[]> {
const res = await fetch(
`https://data.jsdelivr.com/v1/package/npm/${props.pkg}`
)
const { versions } = (await res.json()) as { versions: string[] }

if (props.pkg === 'vue') {
// if the latest version is a pre-release, list all current pre-releases
// otherwise filter out pre-releases
let isInPreRelease = versions[0].includes('-')
const filteredVersions: string[] = []
for (const v of versions) {
if (v.includes('-')) {
if (isInPreRelease) {
filteredVersions.push(v)
}
} else {
filteredVersions.push(v)
isInPreRelease = false
}
if (filteredVersions.length >= 30 || v === '3.0.10') {
break
}
}
return filteredVersions
} else if (props.pkg === 'typescript') {
return versions.filter(v => !v.includes('dev') && !v.includes('insiders'))
}
return versions
}

function setVersion(v: string) {
version.value = v
expanded.value = false
}

onMounted(() => {
window.addEventListener('click', () => {
expanded.value = false
})
window.addEventListener('blur', () => {
if (document.activeElement?.tagName === 'IFRAME') {
expanded.value = false
}
})
})
</script>

<template>
<div class="version" @click.stop>
<span class="active-version" @click="toggle">
{{ label }}
<span class="number">{{ version }}</span>
</span>

<ul class="versions" :class="{ expanded }">
<li v-if="!versions"><a>loading versions...</a></li>
<li v-for="version of versions">
<a @click="setVersion(version)">v{{ version }}</a>
</li>
<div @click="expanded = false">
<slot />
</div>
</ul>
</div>
</template>

<style>
.version {
margin-right: 12px;
position: relative;
}

.active-version {
cursor: pointer;
position: relative;
display: inline-flex;
place-items: center;
}

.active-version .number {
color: var(--green);
margin-left: 4px;
}

.active-version::after {
content: '';
width: 0;
height: 0;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 6px solid #aaa;
margin-left: 8px;
}
</style>
1 change: 1 addition & 0 deletions packages/sfc-playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default defineConfig({
plugins: [
vue({
script: {
defineModel: true,
fs: {
fileExists: fs.existsSync,
readFile: file => fs.readFileSync(file, 'utf-8')
Expand Down
Loading