Skip to content

Commit 84a6513

Browse files
jtbandesantfu
andauthored
feat: add funding buttons to themes & languages list (#1052)
Co-authored-by: Anthony Fu <[email protected]>
1 parent a3c01f6 commit 84a6513

File tree

8 files changed

+95
-44
lines changed

8 files changed

+95
-44
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<script setup lang="ts">
2+
import type { FundingLink } from 'tm-grammars'
3+
import { Tooltip } from 'floating-vue'
4+
5+
defineProps<{
6+
funding: FundingLink[] | undefined
7+
name: string
8+
}>()
9+
</script>
10+
11+
<template>
12+
<Tooltip
13+
v-if="funding && funding.length > 0"
14+
theme="twoslash"
15+
class="group"
16+
relative inline-block mya align-middle
17+
>
18+
<button
19+
title="Funding"
20+
hover="bg-gray/10"
21+
p1 rounded
22+
>
23+
<div
24+
i-carbon:favorite-filled
25+
op25 group-hover:op100 group-focus-within:op100 group-hover:text-red-500
26+
transition-opacity duration-250
27+
/>
28+
</button>
29+
30+
<template #popper>
31+
<div p2 class="vp-doc text-sm">
32+
<strong block mb-2>Support {{ name }} development:</strong>
33+
<div
34+
v-for="link, i in funding"
35+
:key="i"
36+
text-nowrap
37+
>
38+
<template v-if="link.handle">
39+
{{ link.name }}:
40+
</template>
41+
<a :href="link.url" target="_blank">{{ link.handle || link.name }}</a>
42+
</div>
43+
</div>
44+
</template>
45+
</Tooltip>
46+
</template>

docs/.vitepress/components/LanguagesList.vue

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
<script setup lang="ts">
2+
import type { BundledLanguage } from 'shiki'
23
import { computed, ref, watch } from 'vue'
34
import { usePlayground } from '../store/playground'
5+
import FundingButton from './FundingButton.vue'
46
57
const play = usePlayground()
68
const showModel = ref(false)
79
810
function preview(id: string): void {
9-
play.lang = id
11+
play.lang = id as BundledLanguage
1012
showModel.value = true
1113
}
1214
@@ -48,9 +50,11 @@ watch(showModel, () => {
4850
</tr>
4951
</thead>
5052
<tbody>
51-
<tr v-for="l in langs" :key="l.id">
52-
<td>{{ l.name }}</td>
53-
<td><code>{{ l.id }}</code></td>
53+
<tr v-for="l in langs" :key="l.name">
54+
<td>
55+
{{ l.displayName }} <FundingButton :name="`${l.displayName} grammar`" :funding="l.funding" />
56+
</td>
57+
<td><code>{{ l.name }}</code></td>
5458
<td>
5559
<code v-for="alias in l.aliases" :key="alias">{{ alias }}</code>
5660
</td>
@@ -59,7 +63,7 @@ watch(showModel, () => {
5963
<button
6064
title="Preview Example"
6165
ma text-lg
62-
@click="preview(l.id)"
66+
@click="preview(l.name)"
6367
>
6468
<div i-carbon:code />
6569
</button>

docs/.vitepress/components/ShikiMiniPlayground.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { computed, nextTick, ref } from 'vue'
33
import { usePlayground } from '../store/playground'
44
55
const play = usePlayground()
6-
const currentThemeType = computed(() => play.allThemes.find(i => i.id === play.theme)?.type || 'inherit')
6+
const currentThemeType = computed(() => play.allThemes.find(i => i.name === play.theme)?.type || 'inherit')
77
88
const textAreaRef = ref<HTMLDivElement>()
99
const highlightContainerRef = ref<HTMLSpanElement>()
@@ -33,19 +33,19 @@ function onInput() {
3333
<div sticky z-12 p2 px3 pl5 flex="~ gap-1 items-center" left-0 top-0 right-0 border="b-solid gray/5" bg-inherit>
3434
<div i-carbon:chevron-down op50 />
3535
<select v-model="play.lang" font-mono :style="play.preStyle">
36-
<option v-for="lang in play.allLanguages" :key="lang.id" :value="lang.id">
36+
<option v-for="lang in play.allLanguages" :key="lang.name" :value="lang.name">
3737
{{ lang.name }}
3838
</option>
3939
</select>
4040
<div i-carbon:chevron-down op50 />
4141
<select v-model="play.theme" font-mono :style="play.preStyle">
42-
<option v-for="theme in play.allThemes.filter(i => i.type === 'light')" :key="theme.id" :value="theme.id">
42+
<option v-for="theme in play.allThemes.filter(i => i.type === 'light')" :key="theme.name" :value="theme.name">
4343
{{ theme.displayName }}
4444
</option>
4545
<option disabled>
4646
──────────
4747
</option>
48-
<option v-for="theme in play.allThemes.filter(i => i.type === 'dark')" :key="theme.id" :value="theme.id">
48+
<option v-for="theme in play.allThemes.filter(i => i.type === 'dark')" :key="theme.name" :value="theme.name">
4949
{{ theme.displayName }}
5050
</option>
5151
</select>

docs/.vitepress/components/ThemesList.vue

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
<script setup lang="ts">
2+
import type { BundledTheme } from 'shiki'
23
import { ref } from 'vue'
34
import { usePlayground } from '../store/playground'
45
56
const play = usePlayground()
67
const showModel = ref(false)
78
89
function preview(id: string) {
9-
play.theme = id
10+
play.theme = id as BundledTheme
1011
showModel.value = true
1112
}
1213
</script>
@@ -22,15 +23,17 @@ function preview(id: string) {
2223
</tr>
2324
</thead>
2425
<tbody>
25-
<tr v-for="l in play.allThemes" :key="l.id">
26-
<td>{{ l.displayName }}</td>
27-
<td><code>{{ l.id }}</code></td>
26+
<tr v-for="l in play.allThemes" :key="l.name">
27+
<td>
28+
{{ l.displayName }} <FundingButton :name="`${l.displayName} theme`" :funding="l.funding" />
29+
</td>
30+
<td><code>{{ l.name }}</code></td>
2831
<td>
2932
<div flex>
3033
<button
3134
title="Preview Example"
3235
ma text-lg
33-
@click="preview(l.id)"
36+
@click="preview(l.name)"
3437
>
3538
<div i-carbon:code />
3639
</button>

docs/.vitepress/store/playground.ts

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,19 @@
11
/// <reference types="vite/client" />
22

3-
import type { BundledLanguageInfo, BundledThemeInfo } from '@shikijs/types'
3+
import type { BundledLanguage, BundledTheme } from 'shiki'
4+
import type { GrammarInfo } from 'tm-grammars'
5+
import type { ThemeInfo } from 'tm-themes'
46
import { useLocalStorage } from '@vueuse/core'
57
import { acceptHMRUpdate, defineStore } from 'pinia'
68
import { ref, shallowRef, watch } from 'vue'
79

810
export const usePlayground = defineStore('playground', () => {
9-
const lang = useLocalStorage('shiki-playground-lang', 'typescript')
10-
const theme = useLocalStorage('shiki-playground-theme', 'vitesse-dark')
11-
const allThemes = shallowRef<BundledThemeInfo[]>([
12-
{
13-
id: 'vitesse-dark',
14-
displayName: 'Vitesse Dark',
15-
type: 'dark',
16-
import: undefined!,
17-
},
18-
])
19-
const allLanguages = shallowRef<BundledLanguageInfo[]>([
20-
{
21-
id: 'typescript',
22-
name: 'TypeScript',
23-
import: undefined!,
24-
},
25-
])
26-
const bundledLangsFull = shallowRef<BundledLanguageInfo[]>([])
27-
const bundledLangsWeb = shallowRef<BundledLanguageInfo[]>([])
11+
const lang = useLocalStorage<BundledLanguage>('shiki-playground-lang', 'typescript')
12+
const theme = useLocalStorage<BundledTheme>('shiki-playground-theme', 'vitesse-dark')
13+
const allThemes = shallowRef<ThemeInfo[]>([])
14+
const allLanguages = shallowRef<GrammarInfo[]>([])
15+
const bundledLangsFull = shallowRef<GrammarInfo[]>([])
16+
const bundledLangsWeb = shallowRef<GrammarInfo[]>([])
2817

2918
const input = useLocalStorage('shiki-playground-input', '')
3019
const output = ref('<pre></pre>')
@@ -33,16 +22,16 @@ export const usePlayground = defineStore('playground', () => {
3322

3423
function randomize(): void {
3524
if (allLanguages.value.length && allThemes.value.length) {
36-
lang.value = allLanguages.value[Math.floor(Math.random() * allLanguages.value.length)].id as any
37-
theme.value = allThemes.value[Math.floor(Math.random() * allThemes.value.length)].id as any
25+
lang.value = allLanguages.value[Math.floor(Math.random() * allLanguages.value.length)].name as BundledLanguage
26+
theme.value = allThemes.value[Math.floor(Math.random() * allThemes.value.length)].name as BundledTheme
3827
}
3928
}
4029

4130
;(async () => {
4231
const { createHighlighter } = await import('shiki')
43-
const { bundledLanguagesInfo: bundleFull } = await import('shiki/bundle/full')
44-
const { bundledLanguagesInfo: bundleWeb } = await import('shiki/bundle/web')
45-
const { bundledThemesInfo } = await import('shiki/themes')
32+
const allGrammars = await import('tm-grammars')
33+
const webGrammars = allGrammars.grammars.filter(grammar => grammar.categories?.includes('web'))
34+
const { themes: bundledThemesInfo } = await import('tm-themes')
4635

4736
const samplesCache = new Map<string, Promise<string | undefined>>()
4837

@@ -59,9 +48,9 @@ export const usePlayground = defineStore('playground', () => {
5948
}
6049

6150
allThemes.value = bundledThemesInfo
62-
allLanguages.value = bundleFull
63-
bundledLangsFull.value = bundleFull
64-
bundledLangsWeb.value = bundleWeb
51+
allLanguages.value = allGrammars.grammars
52+
bundledLangsFull.value = allGrammars.grammars
53+
bundledLangsWeb.value = webGrammars
6554

6655
if (typeof window !== 'undefined') {
6756
const highlighter = await createHighlighter({
@@ -74,8 +63,8 @@ export const usePlayground = defineStore('playground', () => {
7463
watch([lang, theme], async (n, o) => {
7564
isLoading.value = true
7665
await Promise.all([
77-
highlighter.loadTheme(theme.value as any),
78-
highlighter.loadLanguage(lang.value as any),
66+
highlighter.loadTheme(theme.value),
67+
highlighter.loadLanguage(lang.value),
7968
])
8069
// Fetch sample if language changed
8170
if ((o[0] || !input.value) && n[0] !== o[0]) {

docs/components.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export {}
99
declare module 'vue' {
1010
export interface GlobalComponents {
1111
Badges: typeof import('./.vitepress/components/Badges.vue')['default']
12+
FundingButton: typeof import('./.vitepress/components/FundingButton.vue')['default']
1213
HomeDemo: typeof import('./.vitepress/components/HomeDemo.vue')['default']
1314
LanguagesList: typeof import('./.vitepress/components/LanguagesList.vue')['default']
1415
ShikiMiniPlayground: typeof import('./.vitepress/components/ShikiMiniPlayground.vue')['default']

docs/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
"@vueuse/core": "catalog:docs",
1717
"floating-vue": "catalog:docs",
1818
"pinia": "catalog:cli",
19+
"tm-grammars": "catalog:inlined",
20+
"tm-themes": "catalog:inlined",
1921
"unocss": "catalog:docs",
2022
"unplugin-vue-components": "catalog:docs",
2123
"vitepress": "catalog:docs",

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)