Skip to content

feat: allow starting on a specific view #15

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 5 commits into from
Jan 20, 2022
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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,19 @@ import '@vue/repl/style.css'
import { watchEffect } from 'vue'
import { Repl, ReplStore } from '@vue/repl'

// retrieve some configuration options from the URL
const query = new URLSearchParams(location.search)

const store = new ReplStore({
// initialize repl with previously serialized state
serializedState: location.hash.slice(1),

// starts on the output pane (mobile only) if the URL has a showOutput query
showOutput: query.has('showOutput'),
// starts on a different tab on the output pane if the URL has a outputMode query
// and default to the "preview" tab
outputMode: (query.get('outputMode') || 'preview')

// specify the default URL to import Vue runtime from in the sandbox
// default is the CDN link from unpkg.com with version matching Vue's version
// from peerDependency
Expand Down
6 changes: 4 additions & 2 deletions src/SplitPane.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { ref, reactive, computed, inject } from 'vue'
import { Store } from './store'

const props = defineProps<{ layout?: string }>()
const isVertical = computed(() => props.layout === 'vertical')

const container = ref()

// mobile only
const showOutput = ref(false)
const store = inject('store') as Store
const showOutput = ref(store.initialShowOutput)

const state = reactive({
dragging: false,
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as Repl } from './Repl.vue'
export { ReplStore, File } from './store'
export { compileFile } from './transform'
export type { Store, SFCOptions, StoreState } from './store'
export type { OutputModes } from './output/types'
8 changes: 6 additions & 2 deletions src/output/Output.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Preview from './Preview.vue'
import CodeMirror from '../codemirror/CodeMirror.vue'
import { Store } from '../store'
import { inject, ref, computed } from 'vue'
import type { OutputModes } from './types'

const props = defineProps<{
showCompileOutput?: boolean
Expand All @@ -15,8 +16,11 @@ const modes = computed(() =>
: (['preview'] as const)
)

type Modes = typeof modes.value[number]
const mode = ref<Modes>('preview')
const mode = ref<OutputModes>(
(modes.value as readonly string[]).includes(store.initialOutputMode)
? store.initialOutputMode as OutputModes
: 'preview'
)
</script>

<template>
Expand Down
1 change: 1 addition & 0 deletions src/output/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type OutputModes = 'preview' | 'js' | 'css' | 'ssr'
12 changes: 11 additions & 1 deletion src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
SFCAsyncStyleCompileOptions,
SFCTemplateCompileOptions
} from 'vue/compiler-sfc'
import { OutputModes } from './output/types'

const defaultMainFile = 'App.vue'

Expand Down Expand Up @@ -66,15 +67,22 @@ export class ReplStore implements Store {
state: StoreState
compiler = defaultCompiler
options?: SFCOptions
initialShowOutput: boolean
initialOutputMode: OutputModes | string

private defaultVueRuntimeURL: string
private pendingCompiler: Promise<any> | null = null

constructor({
serializedState = '',
defaultVueRuntimeURL = `https://unpkg.com/@vue/runtime-dom@${version}/dist/runtime-dom.esm-browser.js`
defaultVueRuntimeURL = `https://unpkg.com/@vue/runtime-dom@${version}/dist/runtime-dom.esm-browser.js`,
showOutput = false,
outputMode = 'preview'
}: {
serializedState?: string
showOutput?: boolean
// loose type to allow getting from the URL without inducing a typing error
outputMode?: OutputModes | string
defaultVueRuntimeURL?: string
} = {}) {
let files: StoreState['files'] = {}
Expand All @@ -91,6 +99,8 @@ export class ReplStore implements Store {
}

this.defaultVueRuntimeURL = defaultVueRuntimeURL
this.initialShowOutput = showOutput
this.initialOutputMode = outputMode

let mainFile = defaultMainFile
if (!files[mainFile]) {
Expand Down
3 changes: 3 additions & 0 deletions test/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import { Repl, ReplStore } from '../src'

const App = {
setup() {
const query = new URLSearchParams(location.search)
const store = new ReplStore({
serializedState: location.hash.slice(1),
showOutput: query.has('so'),
outputMode: query.get('om') || 'preview',
defaultVueRuntimeURL: import.meta.env.PROD
? undefined
: `${location.origin}/src/vue-dev-proxy`
Expand Down