Skip to content

Commit

Permalink
feat(playground): init
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Oct 11, 2023
1 parent 7478376 commit c0b16ea
Show file tree
Hide file tree
Showing 29 changed files with 1,477 additions and 517 deletions.
19 changes: 19 additions & 0 deletions packages/online-playground/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SFC Playground

This is continuously deployed at [https://play.vuejs.org](https://play.vuejs.org).

## Run Locally in Dev

In repo root:

```sh
pnpm dev-sfc
```

## Build for Prod

In repo root

```sh
pnpm build-sfc-playground
```
28 changes: 28 additions & 0 deletions packages/online-playground/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg" href="/logo.svg" />
<title>Pinia Playground</title>
<script>
// process shim for old versions of @vue/compiler-sfc dependency
window.process = { env: {} }
const savedPreferDark = localStorage.getItem(
'vue-sfc-playground-prefer-dark'
)
if (
savedPreferDark === 'true' ||
(!savedPreferDark &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark')
}
</script>
<script type="module" src="/src/main.ts"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
23 changes: 23 additions & 0 deletions packages/online-playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@pinia/playground",
"version": "0.0.0",
"type": "module",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.4.0",
"execa": "^7.1.1",
"vite": "^4.4.11"
},
"dependencies": {
"@vue/repl": "^2.5.8",
"file-saver": "^2.0.5",
"jszip": "^3.10.1",
"pinia": "workspace:*",
"vue": "^3.3.4"
}
}
1 change: 1 addition & 0 deletions packages/online-playground/public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/online-playground/shims-vue.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
160 changes: 160 additions & 0 deletions packages/online-playground/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<script setup lang="ts">
import Header from './Header.vue'
import { Repl, ReplStore, SFCOptions, ReplProps } from '@vue/repl'
import Monaco from '@vue/repl/monaco-editor'
import { ref, watchEffect, onMounted, inject, provide, onUnmounted } from 'vue'
import { AppVue, PiniaVersionKey, counterTs } from './defaults'
const setVH = () => {
document.documentElement.style.setProperty('--vh', window.innerHeight + `px`)
}
window.addEventListener('resize', setVH)
setVH()
const useDevMode = ref(false)
let hash = location.hash.slice(1)
if (hash.startsWith('__DEV__')) {
hash = hash.slice(7)
useDevMode.value = true
}
const store = new ReplStore({
serializedState: hash,
})
const previewOptions: ReplProps['previewOptions'] = {
customCode: {
importCode: `import { createPinia } from 'pinia'`,
useCode: `app.use(createPinia())`,
},
}
// enable experimental features
const sfcOptions: SFCOptions = {
script: {
inlineTemplate: !useDevMode.value,
isProd: !useDevMode.value,
reactivityTransform: true,
defineModel: true,
},
style: {
isProd: !useDevMode.value,
},
template: {
isProd: !useDevMode.value,
},
}
const piniaVersion = ref(`latest`)
provide(PiniaVersionKey, piniaVersion)
// FIXME: cannot get autocompletion and auto import to work like it does for Vue
// watchEffect(() => {
// store.state.dependencyVersion ??= {}
// store.state.dependencyVersion.pinia ??=
// piniaVersion.value === 'latest' ? '^2.1.0' : piniaVersion.value
// })
if (!hash) {
store.setImportMap({
imports: {
...store.getImportMap().imports,
pinia: import.meta.env.PROD
? `${location.origin}/'pinia.esm-browser.js'`
: `${location.origin}/src/pinia-dev-proxy`,
},
})
store
.setFiles({
// gets the tsconfig and import map
...store.getFiles(),
'App.vue': AppVue,
'counter.ts': counterTs,
})
.then(() => {
console.log(store.state.mainFile)
})
// store.setFiles({}, 'main.ts').then(() => {
// console.log('done')
// })
}
// persist state
watchEffect(() => {
const newHash = store
.serialize()
.replace(/^#/, useDevMode.value ? `#__DEV__` : `#`)
history.replaceState({}, '', newHash)
})
function toggleDevMode() {
const dev = (useDevMode.value = !useDevMode.value)
sfcOptions.script!.inlineTemplate =
sfcOptions.script!.isProd =
sfcOptions.template!.isProd =
sfcOptions.style!.isProd =
!dev
store.setFiles(store.getFiles())
}
const theme = ref<'dark' | 'light'>('dark')
function toggleTheme(isDark: boolean) {
theme.value = isDark ? 'dark' : 'light'
}
onMounted(() => {
const cls = document.documentElement.classList
toggleTheme(cls.contains('dark'))
})
</script>

<template>
<Header
:store="store"
:dev="useDevMode"
@toggle-theme="toggleTheme"
@toggle-dev="toggleDevMode"
/>
<Repl
:theme="theme"
:editor="Monaco"
@keydown.ctrl.s.prevent
@keydown.meta.s.prevent
:store="store"
:showCompileOutput="true"
:autoResize="true"
:sfcOptions="sfcOptions"
:clearConsole="false"
:previewOptions="previewOptions"
/>
</template>

<style>
.dark {
color-scheme: dark;
}
body {
font-size: 13px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
margin: 0;
--base: #444;
--nav-height: 50px;
}
.vue-repl {
height: calc(var(--vh) - var(--nav-height)) !important;
}
button {
border: none;
outline: none;
cursor: pointer;
margin: 0;
background-color: transparent;
}
</style>
Loading

0 comments on commit c0b16ea

Please sign in to comment.