Skip to content

Commit

Permalink
docs: playground
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Feb 22, 2024
1 parent 8e6f08b commit 19f1edf
Show file tree
Hide file tree
Showing 19 changed files with 1,149 additions and 556 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
[![JSDocs][jsdocs-src]][jsdocs-href]
[![License][license-src]][license-href]

_description_
Smoothly animated code blocks with Shiki.

> **Note**:
> Replace `shiki-magic-move`, `_description_` and `antfu` globally to use this template.
> Working in progress.
## Sponsors

Expand Down
3 changes: 3 additions & 0 deletions build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
entries: [
'src/index',
'src/vue',
'src/core',
],
declaration: true,
clean: true,
rollup: {
emitCJS: true,
inlineDependencies: true,
},
})
6 changes: 6 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[build]
publish = "playground/dist"
command = "pnpm run play:build"

[build.environment]
NODE_VERSION = "20"
15 changes: 10 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "module",
"version": "0.0.0",
"packageManager": "pnpm@8.14.0",
"description": "_description_",
"description": "Smoothly animated code blocks with Shiki",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
Expand Down Expand Up @@ -38,35 +38,40 @@
],
"scripts": {
"build": "unbuild",
"dev": "unbuild --stub",
"dev": "nr play",
"lint": "eslint .",
"prepublishOnly": "nr build",
"release": "bumpp && npm publish",
"start": "esno src/index.ts",
"test": "vitest",
"typecheck": "tsc --noEmit",
"prepare": "simple-git-hooks",
"play": "nr -C playground dev"
"play": "nr -C playground dev",
"play:build": "nr -C playground build"
},
"dependencies": {
"shiki": "^1.1.6"
"peerDependencies": {
"shiki": "^1.1.6",
"vue": "^3.4.0"
},
"devDependencies": {
"@antfu/eslint-config": "^2.6.2",
"@antfu/ni": "^0.21.12",
"@antfu/utils": "^0.7.7",
"@types/diff-match-patch": "^1.0.36",
"@types/node": "^20.10.7",
"@unocss/reset": "^0.58.5",
"bumpp": "^9.2.1",
"diff-match-patch": "^1.0.5",
"eslint": "^8.56.0",
"esno": "^4.0.0",
"lint-staged": "^15.2.0",
"pnpm": "^8.14.0",
"rimraf": "^5.0.5",
"shiki": "^1.1.6",
"simple-git-hooks": "^2.9.0",
"typescript": "^5.3.3",
"unbuild": "^2.0.0",
"unocss": "^0.58.5",
"vite": "^5.0.11",
"vitest": "^1.1.3",
"vue": "^3.4.19"
Expand Down
2 changes: 1 addition & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
Expand Down
16 changes: 14 additions & 2 deletions playground/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
<script setup lang="ts">
import Block from './Block.vue'
import Playground from './Playground.vue'
</script>

<template>
<Suspense>
<template #default>
<Block />
<Playground />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>

<style>
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
}
html {
background: #020202;
color: #ccc;
}
}
</style>
175 changes: 175 additions & 0 deletions playground/src/Playground.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<script setup lang="ts">
import type { Highlighter } from 'shiki'
import { getHighlighter } from 'shiki'
import { bundledThemesInfo } from 'shiki/themes'
import { bundledLanguagesInfo } from 'shiki/langs'
import { ref, shallowRef, watch } from 'vue'
import { ShikiMagicMove } from '../../src/vue'
import { vueAfter, vueBefore } from './fixture'
const theme = ref('vitesse-dark')
const lang = ref('vue')
const highlighter = ref<Highlighter>()
const loadingPromise = shallowRef<Promise<void> | undefined>(
getHighlighter({
themes: [theme.value],
langs: [lang.value],
}).then((h) => {
highlighter.value = h
loadingPromise.value = undefined
}),
)
const samplesCache = new Map<string, Promise<string | undefined>>()
function fetchSample(id: string) {
if (!samplesCache.has(id)) {
samplesCache.set(id, fetch(`https://raw.githubusercontent.com/shikijs/textmate-grammars-themes/main/samples/${id}.sample`)
.then(r => r.text())
.catch((e) => {
console.error(e)
return undefined
}))
}
return samplesCache.get(id)!
}
const example = ref(vueBefore)
const code = ref(example)
const input = ref(code.value)
const autoCommit = ref(true)
function reset() {
if (lang.value === 'vue')
example.value = example.value === vueBefore ? vueAfter : vueBefore
code.value = example.value
input.value = example.value
}
function commit() {
code.value = input.value
}
let timer: ReturnType<typeof setTimeout> | undefined
watch(
input,
() => {
if (timer)
clearTimeout(timer)
if (autoCommit.value)
timer = setTimeout(commit, 300)
},
)
watch(
[theme, lang],
(n, o) => {
const previous = loadingPromise.value || Promise.resolve()
loadingPromise.value = previous.then(() => {
const promises: Promise<void>[] = []
if (!highlighter.value!.getLoadedLanguages().includes(lang.value))
promises.push(highlighter.value!.loadLanguage(lang.value as any))
if (!highlighter.value!.getLoadedThemes().includes(theme.value))
promises.push(highlighter.value!.loadTheme(theme.value as any))
if (n[1] !== o[1]) {
promises.push(fetchSample(lang.value).then((code) => {
example.value = code || 'ERROR'
reset()
}))
}
return Promise.all(promises)
})
.then(() => {
loadingPromise.value = undefined
})
},
)
</script>

<template>
<div class="h-screen flex flex-col font-sans max-h-screen">
<div class="flex flex-col items-center flex-none px4 pt6">
<span class="text-2xl font-200 bg-gradient-to-r from-teal to-orange inline-block text-transparent bg-clip-text">
<span>Shiki</span>
<span class="font-800 mx1">Magic</span>
<span class="italic font-serif">Move</span>
</span>
<div class="text-stone:75">
Smoothly animated code blocks with <a href="https://github.com/shikijs/shiki" target="_blank" class="underline">Shiki</a> & Vue <sup>(demo)</sup>
</div>
<div class="text-stone:50 italic">
Working in progress. Repo is currently private, get early access by <a href="https://github.com/sponsors/antfu" target="_blank" class="underline hover:text-rose">sponsoring Anthony Fu</a>
</div>
</div>
<div class="grid grid-cols-2 p6 gap-4 flex-auto of-hidden">
<div class="flex flex-col gap-2">
<textarea
v-model="input"
class="font-mono w-full h-full flex-auto p-4 border border-gray:20 rounded bg-transparent"
@keydown.meta.enter.prevent="commit"
/>
<div class="flex-none flex flex-wrap gap-4 items-center">
<button class="border border-gray:20 rounded px2 py1" @click="reset">
Reset Example
</button>
<label>
<input
v-model="autoCommit"
type="checkbox"
>
Auto Commit <sup v-if="!autoCommit" class="op50">(Cmd+Enter to commit)</sup>
</label>
<button v-if="!autoCommit" class="border border-gray:20 rounded px2 py1" @click="commit">
Commit
</button>

<div class="flex-auto" />
<select
v-model="theme"
class="border border-gray:20 rounded px2 py1"
>
<option
v-for="t of bundledThemesInfo"
:key="t.id"
:value="t.id"
>
{{ t.displayName }}
</option>
</select>
<select
v-model="lang"
class="border border-gray:20 rounded px2 py1"
>
<option
v-for="l of bundledLanguagesInfo"
:key="l.id"
:value="l.id"
>
{{ l.name }}
</option>
</select>
</div>
</div>
<div class="of-hidden">
<ShikiMagicMove
v-if="highlighter && !loadingPromise"
:highlighter="highlighter"
:code="code"
:lang="lang"
:theme="theme"
class="font-mono w-full h-full p-4 border border-gray:20 shadow-xl rounded max-h-full of-scroll"
/>
<div
v-else
class="font-mono w-full h-full p-4 border border-gray:20 shadow-xl rounded"
>
<span class="animate-pulse">Loading...</span>
</div>
</div>
</div>
</div>
</template>
6 changes: 2 additions & 4 deletions playground/src/code.ts → playground/src/fixture.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const before = `
<script>
export const vueBefore = `<script>
export default {
data() {
return {
Expand All @@ -20,8 +19,7 @@ export default {
}
</style>`

export const after = `
<script setup>
export const vueAfter = `<script setup>
import { ref } from 'vue'
const greeting = ref('Hello World!')
</script>
Expand Down
3 changes: 3 additions & 0 deletions playground/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { createApp } from 'vue'
import App from './App.vue'

Check failure on line 2 in playground/src/main.ts

View workflow job for this annotation

GitHub Actions / typecheck

Cannot find module './App.vue' or its corresponding type declarations.

import '@unocss/reset/tailwind.css'
import 'uno.css'

createApp(App).mount('#app')
2 changes: 2 additions & 0 deletions playground/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import UnoCSS from 'unocss/vite'

export default defineConfig({
plugins: [
Vue(),
UnoCSS(),
],
})
Loading

0 comments on commit 19f1edf

Please sign in to comment.