docus 1.0.6 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -22
- package/app/router.options.ts +18 -0
- package/assets/css/fonts.css +84 -0
- package/assets/css/main.css +11 -0
- package/assets/css/tailwind.css +282 -0
- package/components/app/Container.vue +23 -0
- package/components/app/Footer.vue +38 -0
- package/components/app/Navbar.vue +26 -0
- package/components/app/NavbarLogo.vue +31 -0
- package/components/app/Page.vue +7 -0
- package/components/app/PoweredByDocus.vue +11 -0
- package/components/content/Alert.vue +124 -0
- package/components/content/BlockHero.vue +54 -0
- package/components/content/ButtonLink.vue +44 -0
- package/components/content/Card.vue +46 -0
- package/components/content/CardGrid.vue +23 -0
- package/components/content/CodeBlock.vue +47 -0
- package/components/content/CodeGroup.vue +134 -0
- package/components/content/CopyButton.vue +48 -0
- package/components/content/List.vue +5 -0
- package/components/content/NeedContribution.vue +23 -0
- package/components/content/ReadMore.vue +24 -0
- package/components/content/Sandbox.vue +100 -0
- package/components/content/TabsHeader.vue +44 -0
- package/components/content/Terminal.vue +70 -0
- package/components/content/VideoPlayer.vue +113 -0
- package/components/docs/DocsAside.vue +19 -0
- package/components/docs/DocsAsideTree.vue +101 -0
- package/components/docs/DocsHero.vue +39 -0
- package/components/docs/DocsPage.vue +22 -0
- package/components/docs/DocsPageContent.vue +29 -0
- package/components/docs/DocsToc.vue +72 -0
- package/components/globals/Icon.vue +24 -0
- package/components/globals/Logo.vue +3 -0
- package/components/globals/NuxtImg.vue +43 -0
- package/components/globals/SocialIcons.vue +43 -0
- package/components/globals/ThemeSelect.vue +35 -0
- package/components/icons/IconAlgolia.vue +8 -0
- package/components/icons/IconArrowLeft.vue +10 -0
- package/components/icons/IconArrowRight.vue +10 -0
- package/components/icons/IconBadgeCheck.vue +14 -0
- package/components/icons/IconCheck.vue +10 -0
- package/components/icons/IconCheckCircle.vue +10 -0
- package/components/icons/IconChevronRight.vue +12 -0
- package/components/icons/IconClipboardCheck.vue +14 -0
- package/components/icons/IconClipboardCopy.vue +14 -0
- package/components/icons/IconCodeSandbox.vue +8 -0
- package/components/icons/IconCopy.vue +17 -0
- package/components/icons/IconDots.vue +10 -0
- package/components/icons/IconEdit.vue +18 -0
- package/components/icons/IconExclamationCircle.vue +12 -0
- package/components/icons/IconExclamationTriangle.vue +10 -0
- package/components/icons/IconExternalLink.vue +12 -0
- package/components/icons/IconGit.vue +7 -0
- package/components/icons/IconGitHub.vue +10 -0
- package/components/icons/IconHeart.vue +9 -0
- package/components/icons/IconInformationCircle.vue +10 -0
- package/components/icons/IconLighthouse.vue +83 -0
- package/components/icons/IconLine.vue +10 -0
- package/components/icons/IconMarkdown.vue +13 -0
- package/components/icons/IconMenu.vue +12 -0
- package/components/icons/IconMenuAlt.vue +10 -0
- package/components/icons/IconMinus.vue +10 -0
- package/components/icons/IconMoon.vue +10 -0
- package/components/icons/IconNuxt.vue +14 -0
- package/components/icons/IconNuxtContent.vue +20 -0
- package/components/icons/IconNuxtLabs.vue +21 -0
- package/components/icons/IconPlus.vue +10 -0
- package/components/icons/IconPuzzle.vue +8 -0
- package/components/icons/IconSSG.vue +7 -0
- package/components/icons/IconSearch.vue +12 -0
- package/components/icons/IconSun.vue +10 -0
- package/components/icons/IconTocBack.vue +21 -0
- package/components/icons/IconTocCurrent.vue +21 -0
- package/components/icons/IconTocNext.vue +8 -0
- package/components/icons/IconTranslate.vue +14 -0
- package/components/icons/IconTwitter.vue +8 -0
- package/components/icons/IconVite.vue +30 -0
- package/components/icons/IconVue.vue +6 -0
- package/components/icons/IconVueTelescope.vue +11 -0
- package/components/icons/IconWindi.vue +17 -0
- package/components/icons/IconX.vue +12 -0
- package/components/icons/IconXCircle.vue +10 -0
- package/components/icons/IconZap.vue +8 -0
- package/components/prose/ProseA.vue +66 -0
- package/components/prose/ProseBlockquote.vue +21 -0
- package/components/prose/ProseCode.vue +68 -0
- package/components/prose/ProseCodeInline.vue +38 -0
- package/components/prose/ProseEm.vue +11 -0
- package/components/prose/ProseH1.vue +22 -0
- package/components/prose/ProseH2.vue +22 -0
- package/components/prose/ProseH3.vue +24 -0
- package/components/prose/ProseH4.vue +24 -0
- package/components/prose/ProseHr.vue +13 -0
- package/components/prose/ProseImg.vue +32 -0
- package/components/prose/ProseLi.vue +31 -0
- package/components/prose/ProseOl.vue +16 -0
- package/components/prose/ProseP.vue +14 -0
- package/components/prose/ProseStrong.vue +14 -0
- package/components/prose/ProseTable.vue +13 -0
- package/components/prose/ProseTbody.vue +5 -0
- package/components/prose/ProseTd.vue +11 -0
- package/components/prose/ProseTh.vue +11 -0
- package/components/prose/ProseThead.vue +11 -0
- package/components/prose/ProseTr.vue +11 -0
- package/components/prose/ProseUl.vue +15 -0
- package/composables/useContent.ts +155 -0
- package/composables/useMenu.ts +20 -0
- package/composables/useScrollToHeading.ts +35 -0
- package/composables/useScrollspy.ts +45 -0
- package/composables/useTheme.ts +10 -0
- package/layouts/default.vue +27 -0
- package/layouts/page.vue +11 -0
- package/nuxt.config.ts +151 -0
- package/package.json +45 -63
- package/pages/[...slug].vue +24 -0
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/site.webmanifest +1 -0
- package/dist/create-docus/create-docus.js +0 -7
- package/dist/create-docus/index.js +0 -122
- package/dist/helpers.js +0 -154
- package/dist/index.js +0 -10
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
poster: {
|
|
4
|
+
type: String,
|
|
5
|
+
default: '',
|
|
6
|
+
},
|
|
7
|
+
src: {
|
|
8
|
+
type: String,
|
|
9
|
+
default: '',
|
|
10
|
+
},
|
|
11
|
+
sources: {
|
|
12
|
+
type: Array,
|
|
13
|
+
default: () => [],
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const provider = ref(null)
|
|
18
|
+
const loaded = ref(false)
|
|
19
|
+
|
|
20
|
+
if (!props.src && !props.sources.length)
|
|
21
|
+
throw new Error('VideoPlayer: you need to provide either `src` or `sources` props')
|
|
22
|
+
|
|
23
|
+
const src = props.src || props.sources[0].src
|
|
24
|
+
|
|
25
|
+
if (src && src.includes('youtube.com/watch')) {
|
|
26
|
+
const match = src.match(/\?v=([^&]*)/)
|
|
27
|
+
|
|
28
|
+
provider.value = {
|
|
29
|
+
name: 'youtube',
|
|
30
|
+
src: `https://www.youtube-nocookie.com/embed/${match[1]}?autoplay=1`,
|
|
31
|
+
poster: props.poster || `https://i3.ytimg.com/vi/${match[1]}/hqdefault.jpg`,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<div class="video-player relative my-4 bg-black bg-opacity-25 rounded-sm overflow-hidden" :class="{ loaded }">
|
|
38
|
+
<NuxtImg
|
|
39
|
+
v-if="provider ? provider.poster : poster"
|
|
40
|
+
class="video absolute top-0 left-0 w-full h-full object-cover"
|
|
41
|
+
:src="provider ? provider.poster : poster"
|
|
42
|
+
:width="670"
|
|
43
|
+
:height="377"
|
|
44
|
+
/>
|
|
45
|
+
<div v-if="loaded" class="video absolute top-0 left-0 w-full h-full">
|
|
46
|
+
<!-- remote videos -->
|
|
47
|
+
<video v-if="!provider" :poster="poster" controls autoplay>
|
|
48
|
+
<source v-if="src" :src="src">
|
|
49
|
+
<source v-for="source in sources" :key="source.src || source" :src="source.src || source" :type="source.type">
|
|
50
|
+
</video>
|
|
51
|
+
<!-- youtube -->
|
|
52
|
+
<iframe
|
|
53
|
+
v-else-if="provider.name === 'youtube'"
|
|
54
|
+
width="560"
|
|
55
|
+
height="377"
|
|
56
|
+
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
|
57
|
+
allowfullscreen=""
|
|
58
|
+
class="w-full h-full"
|
|
59
|
+
:src="provider.src"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
<div v-if="!loaded" class="overlay absolute top-0 left-0 w-full h-full cursor-pointer" @click="loaded = true">
|
|
63
|
+
<button class="play" />
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</template>
|
|
67
|
+
|
|
68
|
+
<style scoped lang="postcss">
|
|
69
|
+
.video-player {
|
|
70
|
+
&:not(.loaded):before {
|
|
71
|
+
content: ' ';
|
|
72
|
+
display: block;
|
|
73
|
+
position: absolute;
|
|
74
|
+
top: 0;
|
|
75
|
+
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==');
|
|
76
|
+
background-position: top;
|
|
77
|
+
background-repeat: repeat-x;
|
|
78
|
+
height: 60px;
|
|
79
|
+
padding-bottom: 50px;
|
|
80
|
+
width: 100%;
|
|
81
|
+
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
|
82
|
+
z-index: 1;
|
|
83
|
+
}
|
|
84
|
+
&:after {
|
|
85
|
+
content: ' ';
|
|
86
|
+
display: block;
|
|
87
|
+
padding-bottom: 56.25%;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.play {
|
|
91
|
+
width: 68px;
|
|
92
|
+
height: 48px;
|
|
93
|
+
position: absolute;
|
|
94
|
+
cursor: pointer;
|
|
95
|
+
transform: translate3d(-50%, -50%, 0);
|
|
96
|
+
top: 50%;
|
|
97
|
+
left: 50%;
|
|
98
|
+
z-index: 1;
|
|
99
|
+
background-color: transparent;
|
|
100
|
+
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 68 48"><path fill="%23f00" fill-opacity="0.8" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z"></path><path d="M 45,24 27,14 27,34" fill="%23fff"></path></svg>');
|
|
101
|
+
filter: grayscale(100%);
|
|
102
|
+
transition: filter 0.1s cubic-bezier(0, 0, 0.2, 1);
|
|
103
|
+
border: none;
|
|
104
|
+
}
|
|
105
|
+
&:hover .play {
|
|
106
|
+
filter: none;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
video {
|
|
111
|
+
@apply w-full;
|
|
112
|
+
}
|
|
113
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const { navigation } = useContent()
|
|
3
|
+
|
|
4
|
+
const tree = computed(() => {
|
|
5
|
+
return navigation.value.filter(
|
|
6
|
+
(item) => {
|
|
7
|
+
if (item.slug === '/' || item.slug === '/templates')
|
|
8
|
+
return false
|
|
9
|
+
return true
|
|
10
|
+
},
|
|
11
|
+
)
|
|
12
|
+
})
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<nav>
|
|
17
|
+
<DocsAsideTree :tree="tree" />
|
|
18
|
+
</nav>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PropType } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
tree: {
|
|
6
|
+
type: Array as PropType<any>,
|
|
7
|
+
default: () => [],
|
|
8
|
+
},
|
|
9
|
+
level: {
|
|
10
|
+
type: Number,
|
|
11
|
+
default: 0,
|
|
12
|
+
},
|
|
13
|
+
max: {
|
|
14
|
+
type: Number,
|
|
15
|
+
default: null,
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
const emit = defineEmits(['close', 'select'])
|
|
19
|
+
|
|
20
|
+
const route = useRoute()
|
|
21
|
+
const router = useRouter()
|
|
22
|
+
|
|
23
|
+
const isChildOpen = reactive({})
|
|
24
|
+
|
|
25
|
+
function isActive(link) {
|
|
26
|
+
return link.exact ? route.path === link.slug : route.path.startsWith(link.slug)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function onClick(link) {
|
|
30
|
+
if (link.children?.length) {
|
|
31
|
+
// Open dir when element is collapsible
|
|
32
|
+
openDir(link.slug)
|
|
33
|
+
|
|
34
|
+
// Select element for mobile nav
|
|
35
|
+
if (props.max !== null && props.level + 1 === props.max)
|
|
36
|
+
emit('select', link)
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
router.push(link.slug)
|
|
40
|
+
emit('close')
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function openDir(slug, force?) {
|
|
45
|
+
isChildOpen[slug] = force ? true : !isChildOpen[slug]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
watch(
|
|
49
|
+
() => route.path,
|
|
50
|
+
() => {
|
|
51
|
+
const paths = route.path.split('/')
|
|
52
|
+
for (let i = paths.length - 1; i > 1; i--) {
|
|
53
|
+
paths.pop()
|
|
54
|
+
openDir(paths.join('/'), true)
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{ immediate: true },
|
|
58
|
+
)
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<template>
|
|
62
|
+
<ul :class="{ 'pl-4': level > 1 }">
|
|
63
|
+
<li
|
|
64
|
+
v-for="(link, index) in tree"
|
|
65
|
+
:key="link.slug"
|
|
66
|
+
:class="{
|
|
67
|
+
'border-l-2': level > 0,
|
|
68
|
+
'border-primary-600': isActive(link),
|
|
69
|
+
'border-primary-300 hover:border-primary-300': !isActive(link)
|
|
70
|
+
}"
|
|
71
|
+
>
|
|
72
|
+
<NuxtLink
|
|
73
|
+
class="block py-1.5 flex items-center justify-between focus:outline-none cursor-pointer font-semibold"
|
|
74
|
+
:exact="link.exact"
|
|
75
|
+
:class="{
|
|
76
|
+
'pl-4': level > 0,
|
|
77
|
+
'text-xl !text-primary': level === 0,
|
|
78
|
+
'!pt-0': level === 0 && index === 0,
|
|
79
|
+
'text-secondary-active': isActive(link),
|
|
80
|
+
'text-secondary text-secondary-hover': !isActive(link)
|
|
81
|
+
}"
|
|
82
|
+
@click.stop.prevent="onClick(link)"
|
|
83
|
+
>
|
|
84
|
+
<span>{{ link.title }}</span>
|
|
85
|
+
|
|
86
|
+
<Icon v-if="link.icon" :name="link.icon" class="w-5 h-5 u-text-gray-500" />
|
|
87
|
+
</NuxtLink>
|
|
88
|
+
|
|
89
|
+
<DocsAsideTree
|
|
90
|
+
v-if="link.children?.length && (max === null || ((level + 1) < max))"
|
|
91
|
+
v-show="isChildOpen[link.slug]"
|
|
92
|
+
:tree="link.children"
|
|
93
|
+
:level="level + 1"
|
|
94
|
+
:max="max"
|
|
95
|
+
class="py-2"
|
|
96
|
+
@select="link => $emit('select', link)"
|
|
97
|
+
@close="$emit('close')"
|
|
98
|
+
/>
|
|
99
|
+
</li>
|
|
100
|
+
</ul>
|
|
101
|
+
</template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PropType } from 'vue'
|
|
3
|
+
|
|
4
|
+
defineProps({
|
|
5
|
+
buttons: {
|
|
6
|
+
type: Array as PropType<{ label?: string; variant?: string; to?: string; size?: string; icon?: string }[]>,
|
|
7
|
+
default: () => [],
|
|
8
|
+
},
|
|
9
|
+
})
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<template>
|
|
13
|
+
<div class="flex flex-col items-center justify-center pb-48 gap-y-8 pt-36 md:pt-44 lg:pb-56 lg:pt-36 ">
|
|
14
|
+
<div v-if="$slots.badge" class="flex gap-x-2">
|
|
15
|
+
<UBadge rounded label="Warning" />
|
|
16
|
+
|
|
17
|
+
<span class="u-text-gray-500">
|
|
18
|
+
<Markdown unwrap="p" :use="$slots.badge" />
|
|
19
|
+
</span>
|
|
20
|
+
</div>
|
|
21
|
+
<h1 v-if="$slots.title" class="font-bold text-7xl text-center mb-0 u-text-gray-900">
|
|
22
|
+
<Markdown unwrap="p" :use="$slots.title" />
|
|
23
|
+
</h1>
|
|
24
|
+
<p v-if="$slots.description" class="w-1/2 text-lg text-center u-text-gray-500">
|
|
25
|
+
<Markdown unwrap="p" :use="$slots.description" />
|
|
26
|
+
</p>
|
|
27
|
+
<div class="flex gap-x-8">
|
|
28
|
+
<UButton
|
|
29
|
+
v-for="button of buttons"
|
|
30
|
+
:key="button.label"
|
|
31
|
+
:size="button.size || 'xl'"
|
|
32
|
+
:variant="button.variant || 'transparent'"
|
|
33
|
+
:icon="button.icon || undefined"
|
|
34
|
+
:label="button.label || ''"
|
|
35
|
+
:to="button.to || '#'"
|
|
36
|
+
/>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="relative flex-1">
|
|
3
|
+
<slot name="header" />
|
|
4
|
+
|
|
5
|
+
<main class="relative pb-4 sm:pb-6 lg:py-8">
|
|
6
|
+
<Container padded>
|
|
7
|
+
<div class="grid grid-cols-10 gap-8 relative">
|
|
8
|
+
<aside
|
|
9
|
+
v-if="$slots.aside"
|
|
10
|
+
class="pb-8 overflow-x-hidden overflow-y-auto lg:pb-0 hidden lg:block lg:sticky lg:top-16 lg:pt-8 lg:-mt-8 lg:self-start col-span-2 lg:max-h-[calc(100vh-64px)]"
|
|
11
|
+
>
|
|
12
|
+
<slot name="aside" />
|
|
13
|
+
</aside>
|
|
14
|
+
|
|
15
|
+
<div class="relative" :class="{ 'col-span-10 lg:col-span-8': !!$slots.aside, 'col-span-10': !$slots.aside }">
|
|
16
|
+
<slot />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</Container>
|
|
20
|
+
</main>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const { page } = useContent()
|
|
3
|
+
|
|
4
|
+
const isOpen = ref(false)
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div class="flex flex-col-reverse lg:grid lg:grid-cols-10 gap-8 relative">
|
|
9
|
+
<div
|
|
10
|
+
class="col-span-10 lg:col-span-8"
|
|
11
|
+
>
|
|
12
|
+
<slot />
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div
|
|
16
|
+
class="lg:col-span-2 lg:self-start overflow-x-hidden sticky top-16 -mx-4 sm:-mx-6 px-4 sm:px-6 lg:mx-0 lg:px-0 lg:pt-8 lg:-mt-8 backdrop-blur-md lg:max-h-[calc(100vh-64px)]"
|
|
17
|
+
>
|
|
18
|
+
<div class="py-4 lg:py-0">
|
|
19
|
+
<button class="flex lg:hidden items-center gap-3" @click="isOpen = !isOpen">
|
|
20
|
+
<span class="u-text-gray-900 font-semibold text-sm">Table of Contents</span>
|
|
21
|
+
|
|
22
|
+
<Icon name="heroicons-outline:chevron-right" class="w-4 h-4 u-text-gray-400 transition-transform duration-100 transform" :class="[isOpen ? 'rotate-90' : 'rotate-0']" />
|
|
23
|
+
</button>
|
|
24
|
+
|
|
25
|
+
<DocsToc class="mt-4 lg:mt-0" :class="[isOpen ? 'lg:block' : 'hidden lg:block']" />
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const route = useRoute()
|
|
3
|
+
|
|
4
|
+
const { activeHeadings, updateHeadings } = useScrollspy()
|
|
5
|
+
|
|
6
|
+
const { toc, prev, next } = useContent()
|
|
7
|
+
|
|
8
|
+
watch(
|
|
9
|
+
() => route.path,
|
|
10
|
+
() => {
|
|
11
|
+
if (process.client) {
|
|
12
|
+
setTimeout(() => {
|
|
13
|
+
updateHeadings([
|
|
14
|
+
...document.querySelectorAll('.prose h1'),
|
|
15
|
+
...document.querySelectorAll('.prose h2'),
|
|
16
|
+
...document.querySelectorAll('.prose h3'),
|
|
17
|
+
])
|
|
18
|
+
}, 1000)
|
|
19
|
+
}
|
|
20
|
+
}, {
|
|
21
|
+
immediate: true,
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
function scrollToHeading(id: string, scrollMarginCssVar: string) {
|
|
25
|
+
useScrollToHeading(id, scrollMarginCssVar)
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<div class="space-y-2">
|
|
31
|
+
<NuxtLink v-if="prev" :to="prev.slug" class="flex lg:flex-row-reverse items-center text-primary font-semibold group gap-x-3">
|
|
32
|
+
<div class="flex-shrink-0 p-1 rounded-md text-secondary-group-hover transition-base">
|
|
33
|
+
<Icon name="heroicons-solid:chevron-double-left" class="w-6 h-6" />
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<span>Previous page</span>
|
|
37
|
+
</NuxtLink>
|
|
38
|
+
|
|
39
|
+
<template v-if="toc.length">
|
|
40
|
+
<div class="flex lg:flex-row-reverse items-center font-semibold gap-x-3">
|
|
41
|
+
<div class="flex-shrink-0 p-1 rounded-md">
|
|
42
|
+
<Icon name="heroicons-outline:view-grid" class="w-6 h-6" />
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<span>On this page</span>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<ul class="pl-3 lg:pr-3 mr-1">
|
|
49
|
+
<li v-for="link in toc" :key="link.text" class="group border-l-2 lg:border-r-2 lg:border-l-0 min-w-0 lg:text-right" :class="activeHeadings.includes(link.id) ? 'u-border-gray-900' : 'u-border-gray-300'">
|
|
50
|
+
<a
|
|
51
|
+
:href="`#${link.id}`"
|
|
52
|
+
class="text-secondary text-secondary-group-hover py-1 pl-3 lg:pr-3 block truncate"
|
|
53
|
+
:class="{
|
|
54
|
+
'text-primary-500 dark:text-primary-400': activeHeadings.includes(link.id),
|
|
55
|
+
}"
|
|
56
|
+
@click.prevent="scrollToHeading(link.id, '--docs-scroll-margin-block')"
|
|
57
|
+
>
|
|
58
|
+
{{ link.text }}
|
|
59
|
+
</a>
|
|
60
|
+
</li>
|
|
61
|
+
</ul>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<NuxtLink v-if="next" :to="next.slug" class="flex lg:flex-row-reverse items-center text-primary font-semibold group gap-x-3">
|
|
65
|
+
<div class="flex-shrink-0 p-1 rounded-md text-secondary-group-hover transition-base">
|
|
66
|
+
<Icon name="heroicons-solid:chevron-double-right" class="w-6 h-6" />
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<span>Next page</span>
|
|
70
|
+
</NuxtLink>
|
|
71
|
+
</div>
|
|
72
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, watch } from 'vue'
|
|
3
|
+
import { Icon } from '@iconify/vue/dist/offline'
|
|
4
|
+
import { loadIcon } from '@iconify/vue'
|
|
5
|
+
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
name: {
|
|
8
|
+
type: [String, Object],
|
|
9
|
+
required: true,
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const icon = ref(null)
|
|
14
|
+
|
|
15
|
+
icon.value = await loadIcon(props.name)
|
|
16
|
+
|
|
17
|
+
watch(() => props.name, async() => {
|
|
18
|
+
icon.value = await loadIcon(props.name)
|
|
19
|
+
})
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<Icon :icon="icon" />
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PropType } from 'vue'
|
|
3
|
+
|
|
4
|
+
export interface NuxtImg {
|
|
5
|
+
light: string
|
|
6
|
+
dark: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
src: {
|
|
11
|
+
type: [String, Object] as PropType<NuxtImg>,
|
|
12
|
+
default: null,
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const colorMode = useColorMode()
|
|
17
|
+
|
|
18
|
+
const src = computed(
|
|
19
|
+
() => {
|
|
20
|
+
let src = props.src
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
src = JSON.parse(src as any)
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
src = props.src
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof src === 'string')
|
|
30
|
+
return props.src
|
|
31
|
+
|
|
32
|
+
if (colorMode.value === 'dark')
|
|
33
|
+
return props.src.dark || props.src.light
|
|
34
|
+
|
|
35
|
+
if (colorMode.value === 'light')
|
|
36
|
+
return props.src.light || props.src.light
|
|
37
|
+
},
|
|
38
|
+
)
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template>
|
|
42
|
+
<img :src="src">
|
|
43
|
+
</template>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
defineProps({
|
|
3
|
+
size: {
|
|
4
|
+
type: String,
|
|
5
|
+
default: 'w-6 h-6',
|
|
6
|
+
},
|
|
7
|
+
padding: {
|
|
8
|
+
type: String,
|
|
9
|
+
default: 'p-0',
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const theme = useTheme()
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<div class="flex">
|
|
18
|
+
<a
|
|
19
|
+
v-if="theme.twitter"
|
|
20
|
+
:href="`https://twitter.com/${theme.twitter}`"
|
|
21
|
+
target="_blank"
|
|
22
|
+
rel="noopener noreferrer"
|
|
23
|
+
title="Twitter"
|
|
24
|
+
name="Twitter"
|
|
25
|
+
class="icon-base"
|
|
26
|
+
:class="[padding]"
|
|
27
|
+
>
|
|
28
|
+
<IconTwitter :class="size" />
|
|
29
|
+
</a>
|
|
30
|
+
<a
|
|
31
|
+
v-if="theme.github"
|
|
32
|
+
:href="`https://github.com/${theme.github}`"
|
|
33
|
+
target="_blank"
|
|
34
|
+
rel="noopener noreferrer"
|
|
35
|
+
title="GitHub"
|
|
36
|
+
name="GitHub"
|
|
37
|
+
class="icon-base"
|
|
38
|
+
:class="[padding]"
|
|
39
|
+
>
|
|
40
|
+
<IconGitHub :class="size" />
|
|
41
|
+
</a>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const colorMode = useColorMode()
|
|
3
|
+
|
|
4
|
+
type ColorMode = 'light' | 'dark'
|
|
5
|
+
|
|
6
|
+
const mode = computed<ColorMode>({
|
|
7
|
+
get() {
|
|
8
|
+
return colorMode.value as ColorMode
|
|
9
|
+
},
|
|
10
|
+
set(v: ColorMode) {
|
|
11
|
+
colorMode.preference = v
|
|
12
|
+
},
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const onClick = () => {
|
|
16
|
+
mode.value === 'light' ? (mode.value = 'dark') : (mode.value = 'light')
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<button
|
|
22
|
+
class="icon-base w-6 h-6"
|
|
23
|
+
aria-label="Color Mode"
|
|
24
|
+
@click="onClick"
|
|
25
|
+
>
|
|
26
|
+
<ClientOnly>
|
|
27
|
+
<IconSun v-if="mode === 'dark'" />
|
|
28
|
+
<IconMoon v-else />
|
|
29
|
+
|
|
30
|
+
<template #placeholder>
|
|
31
|
+
...
|
|
32
|
+
</template>
|
|
33
|
+
</ClientOnly>
|
|
34
|
+
</button>
|
|
35
|
+
</template>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
|
3
|
+
<path
|
|
4
|
+
fill="currentColor"
|
|
5
|
+
d="M229.3 182.6c-49.3 0-89.2 39.9-89.2 89.2 0 49.3 39.9 89.2 89.2 89.2s89.2-39.9 89.2-89.2c0-49.3-40-89.2-89.2-89.2zm62.7 56.6l-58.9 30.6c-1.8.9-3.8-.4-3.8-2.3V201c0-1.5 1.3-2.7 2.7-2.6 26.2 1 48.9 15.7 61.1 37.1.7 1.3.2 3-1.1 3.7zM389.1 32H58.9C26.4 32 0 58.4 0 90.9V421c0 32.6 26.4 59 58.9 59H389c32.6 0 58.9-26.4 58.9-58.9V90.9C448 58.4 421.6 32 389.1 32zm-202.6 84.7c0-10.8 8.7-19.5 19.5-19.5h45.3c10.8 0 19.5 8.7 19.5 19.5v15.4c0 1.8-1.7 3-3.3 2.5-12.3-3.4-25.1-5.1-38.1-5.1-13.5 0-26.7 1.8-39.4 5.5-1.7.5-3.4-.8-3.4-2.5v-15.8zm-84.4 37l9.2-9.2c7.6-7.6 19.9-7.6 27.5 0l7.7 7.7c1.1 1.1 1 3-.3 4-6.2 4.5-12.1 9.4-17.6 14.9-5.4 5.4-10.4 11.3-14.8 17.4-1 1.3-2.9 1.5-4 .3l-7.7-7.7c-7.6-7.5-7.6-19.8 0-27.4zm127.2 244.8c-70 0-126.6-56.7-126.6-126.6s56.7-126.6 126.6-126.6c70 0 126.6 56.6 126.6 126.6 0 69.8-56.7 126.6-126.6 126.6z"
|
|
6
|
+
/>
|
|
7
|
+
</svg>
|
|
8
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path
|
|
4
|
+
d="M6.85355 3.14645C7.04882 3.34171 7.04882 3.65829 6.85355 3.85355L3.70711 7H12.5C12.7761 7 13 7.22386 13 7.5C13 7.77614 12.7761 8 12.5 8H3.70711L6.85355 11.1464C7.04882 11.3417 7.04882 11.6583 6.85355 11.8536C6.65829 12.0488 6.34171 12.0488 6.14645 11.8536L2.14645 7.85355C1.95118 7.65829 1.95118 7.34171 2.14645 7.14645L6.14645 3.14645C6.34171 2.95118 6.65829 2.95118 6.85355 3.14645Z"
|
|
5
|
+
fill="currentColor"
|
|
6
|
+
fill-rule="evenodd"
|
|
7
|
+
clip-rule="evenodd"
|
|
8
|
+
/>
|
|
9
|
+
</svg>
|
|
10
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path
|
|
4
|
+
d="M8.14645 3.14645C8.34171 2.95118 8.65829 2.95118 8.85355 3.14645L12.8536 7.14645C13.0488 7.34171 13.0488 7.65829 12.8536 7.85355L8.85355 11.8536C8.65829 12.0488 8.34171 12.0488 8.14645 11.8536C7.95118 11.6583 7.95118 11.3417 8.14645 11.1464L11.2929 8H2.5C2.22386 8 2 7.77614 2 7.5C2 7.22386 2.22386 7 2.5 7H11.2929L8.14645 3.85355C7.95118 3.65829 7.95118 3.34171 8.14645 3.14645Z"
|
|
5
|
+
fill="currentColor"
|
|
6
|
+
fill-rule="evenodd"
|
|
7
|
+
clip-rule="evenodd"
|
|
8
|
+
/>
|
|
9
|
+
</svg>
|
|
10
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
fill="none"
|
|
4
|
+
stroke-linecap="round"
|
|
5
|
+
stroke-linejoin="round"
|
|
6
|
+
stroke-width="2"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"
|
|
12
|
+
/>
|
|
13
|
+
</svg>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path
|
|
4
|
+
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
|
|
5
|
+
fill="currentColor"
|
|
6
|
+
fill-rule="evenodd"
|
|
7
|
+
clip-rule="evenodd"
|
|
8
|
+
/>
|
|
9
|
+
</svg>
|
|
10
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path
|
|
4
|
+
d="M7.49991 0.877045C3.84222 0.877045 0.877075 3.84219 0.877075 7.49988C0.877075 11.1575 3.84222 14.1227 7.49991 14.1227C11.1576 14.1227 14.1227 11.1575 14.1227 7.49988C14.1227 3.84219 11.1576 0.877045 7.49991 0.877045ZM1.82708 7.49988C1.82708 4.36686 4.36689 1.82704 7.49991 1.82704C10.6329 1.82704 13.1727 4.36686 13.1727 7.49988C13.1727 10.6329 10.6329 13.1727 7.49991 13.1727C4.36689 13.1727 1.82708 10.6329 1.82708 7.49988ZM10.1589 5.53774C10.3178 5.31191 10.2636 5.00001 10.0378 4.84109C9.81194 4.68217 9.50004 4.73642 9.34112 4.96225L6.51977 8.97154L5.35681 7.78706C5.16334 7.59002 4.84677 7.58711 4.64973 7.78058C4.45268 7.97404 4.44978 8.29061 4.64325 8.48765L6.22658 10.1003C6.33054 10.2062 6.47617 10.2604 6.62407 10.2483C6.77197 10.2363 6.90686 10.1591 6.99226 10.0377L10.1589 5.53774Z"
|
|
5
|
+
fill="currentColor"
|
|
6
|
+
fill-rule="evenodd"
|
|
7
|
+
clip-rule="evenodd"
|
|
8
|
+
/>
|
|
9
|
+
</svg>
|
|
10
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
fill="none"
|
|
4
|
+
stroke-linecap="round"
|
|
5
|
+
stroke-linejoin="round"
|
|
6
|
+
stroke-width="2"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
|
|
12
|
+
/>
|
|
13
|
+
</svg>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
fill="none"
|
|
4
|
+
stroke-linecap="round"
|
|
5
|
+
stroke-linejoin="round"
|
|
6
|
+
stroke-width="2"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
stroke="currentColor"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"
|
|
12
|
+
/>
|
|
13
|
+
</svg>
|
|
14
|
+
</template>
|