Skip to content

Commit 5b14fa3

Browse files
committed
Add code block and code group components
1 parent b5f906a commit 5b14fa3

File tree

4 files changed

+142
-1
lines changed

4 files changed

+142
-1
lines changed

src/.vitepress/theme/CodeBlock.vue

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<div class="code-block" :class="[active && 'active']">
3+
<slot />
4+
</div>
5+
</template>
6+
7+
<script setup>
8+
defineProps({
9+
title: { type: String, required: true },
10+
active: { type: Boolean, default: false }
11+
})
12+
</script>
13+
14+
<style scoped>
15+
.code-block {
16+
display: none;
17+
}
18+
19+
.code-block.active {
20+
display: block;
21+
}
22+
</style>

src/.vitepress/theme/CodeGroup.vue

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<script setup>
2+
import { onMounted, computed, ref, useSlots, watch } from 'vue'
3+
4+
const slots = useSlots()
5+
const tabLabels = computed(() => slots.default().map(key => key.props.title))
6+
7+
const activeTabIndex = ref(0)
8+
const tabs = ref([])
9+
10+
const underline = ref(null)
11+
12+
const updateHighlighteUnderlinePosition = () => {
13+
const activeTab = tabs.value[activeTabIndex.value]
14+
if (!activeTab) {
15+
return
16+
}
17+
18+
underline.value.style.left = `${activeTab.offsetLeft}px`
19+
underline.value.style.width = `${activeTab.clientWidth}px`
20+
}
21+
22+
onMounted(() => {
23+
updateHighlighteUnderlinePosition()
24+
})
25+
26+
const slot = ref(null)
27+
28+
const switchTab = (i) => {
29+
const tabs = slot.value.children
30+
31+
for (const tab of tabs) {
32+
tab.classList.remove('active')
33+
}
34+
35+
tabs[i].classList.add('active')
36+
}
37+
38+
watch(activeTabIndex, (value) => {
39+
switchTab(value)
40+
})
41+
42+
const updateTabs = i => {
43+
activeTabIndex.value = i
44+
updateHighlighteUnderlinePosition()
45+
}
46+
</script>
47+
48+
<template>
49+
<div class="code-group">
50+
<div class="buttons">
51+
<button
52+
v-for="(label, i) in tabLabels"
53+
ref="tabs"
54+
:key="label"
55+
class="button mono"
56+
:class="[activeTabIndex === i && 'active']"
57+
@click="updateTabs(i)"
58+
>{{ label }}</button>
59+
<span ref="underline" class="highlight-underline" />
60+
</div>
61+
<div ref="slot">
62+
<slot ref="inner" />
63+
</div>
64+
</div>
65+
</template>
66+
67+
<style scoped>
68+
.buttons {
69+
border: 0 solid #e2e8f0;
70+
border-top-left-radius: .375rem;
71+
border-top-right-radius: .375rem;
72+
border-bottom-width: 2px;
73+
border-color: #4a5568;
74+
padding-left: .5rem;
75+
padding-right: .5rem;
76+
background-color: #2d3748;
77+
font-size: .875rem;
78+
line-height: 1.25rem;
79+
color: #fff;
80+
position: relative;
81+
}
82+
83+
button {
84+
outline: none;
85+
padding-left: 1rem;
86+
padding-right: 1rem;
87+
padding-top: .75rem;
88+
padding-bottom: .75rem;
89+
color: #cbd5e0;
90+
font-weight: 700;
91+
}
92+
93+
.highlight-underline {
94+
background-color: #00cd81;
95+
position: absolute;
96+
bottom: -2px;
97+
height: 2px;
98+
transition: left .15s,width .15s;
99+
bottom: -2px;
100+
height: 2px;
101+
transition: left 150ms, width 150ms;
102+
}
103+
104+
.code-group :deep([class*="language-"]){
105+
border-top-left-radius: 0;
106+
border-top-right-radius: 0;
107+
margin-top: 0;
108+
}
109+
</style>

src/.vitepress/theme/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { createFluentVue } from 'fluent-vue'
55

66
import { format } from 'date-fns'
77

8+
import CodeGroup from './CodeGroup.vue'
9+
import CodeBlock from './CodeBlock.vue'
10+
811
import './theme.css'
912

1013
const bundle = new FluentBundle('en', {
@@ -24,5 +27,8 @@ export default {
2427
...DefaultTheme,
2528
enhanceApp({ app, router, siteData }) {
2629
app.use(fluent)
30+
31+
app.component('code-group', CodeGroup)
32+
app.component('code-block', CodeBlock)
2733
}
2834
}

src/.vitepress/theme/theme.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@ code {
1616
}
1717

1818
pre {
19-
font-family: "JetBrains Mono", "Consolas", "Monaco", "Andale Mono", "Ubuntu Mono", monospace;
19+
font-family: var(--font-family-code);
20+
}
21+
22+
.mono {
23+
font-family: var(--font-family-code)
2024
}

0 commit comments

Comments
 (0)