mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-03-04 10:40:30 +00:00
feat(docs): setup Gridsome for the website
This commit is contained in:
committed by
Dario Tranchitella
parent
14f9686bbb
commit
0acc2d2ef1
49
docs/src/components/AppAccordion.vue
Normal file
49
docs/src/components/AppAccordion.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div>
|
||||
<button @click="toggleIsOpened()" class="flex items-center space-x-3 text-left">
|
||||
<slot name="title" />
|
||||
<icon-arrow
|
||||
class="w-2 transition-all duration-200 transform"
|
||||
:class="{
|
||||
'rotate-180': isOpened,
|
||||
'rotate-0': !isOpened,
|
||||
}"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="transition-all duration-400 overflow-hidden"
|
||||
:class="{
|
||||
'max-h-99': isOpened,
|
||||
'max-h-0': !isOpened,
|
||||
}"
|
||||
>
|
||||
<slot name="content" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IconArrow from "~/assets/icon/arrow.svg?inline";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
IconArrow,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isOpened: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleIsOpened() {
|
||||
this.isOpened = !this.isOpened;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.max-h-99 {
|
||||
max-height: 99rem;
|
||||
}
|
||||
</style>
|
||||
32
docs/src/components/AppButton.vue
Normal file
32
docs/src/components/AppButton.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<component
|
||||
:is="link ? 'g-link' : 'button'"
|
||||
:to="link"
|
||||
class="
|
||||
inline-block
|
||||
focus:outline-none
|
||||
font-medium
|
||||
rounded-md
|
||||
relative
|
||||
bg-primary
|
||||
py-3 px-8
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
link: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: () => undefined,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
71
docs/src/components/AppFooter.vue
Normal file
71
docs/src/components/AppFooter.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<footer class="py-8 bg-gray-900 bg-opacity-50">
|
||||
<div
|
||||
class="
|
||||
container
|
||||
lg:flex lg:items-center lg:justify-between
|
||||
space-y-4
|
||||
lg:space-y-0
|
||||
"
|
||||
>
|
||||
<div class="space-y-2">
|
||||
<h1 class="font-bold text-2xl inline-block">Capsule</h1>
|
||||
<small class="block">
|
||||
©{{ new Date().getFullYear() }} All rights reserved
|
||||
</small>
|
||||
</div>
|
||||
<ul class="lg:flex lg:items-center lg:space-x-5 space-y-2 lg:space-y-0">
|
||||
<li class="block lg:hidden">
|
||||
<g-link to="/">About Capsule</g-link>
|
||||
</li>
|
||||
<li class="block lg:hidden pb-4">
|
||||
<g-link to="/docs">Documentation</g-link>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/clastix/capsule"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex space-x-2 hover:text-blue-400"
|
||||
><icon-github class="w-5 h-5" /> <span> Github </span></a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://twitter.com/clastixio"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex space-x-2 hover:text-blue-400"
|
||||
><icon-twitter class="w-5 h-5" /> <span>Twitter</span></a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://www.linkedin.com/company/clastix/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex space-x-2 hover:text-blue-400"
|
||||
><icon-linkedin class="w-5 h-5" /> <span>Linkedin</span></a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IconGithub from "~/assets/icon/github.svg?inline";
|
||||
import IconTwitter from "~/assets/icon/twitter.svg?inline";
|
||||
import IconLinkedin from "~/assets/icon/linkedin.svg?inline";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
IconGithub,
|
||||
IconLinkedin,
|
||||
IconTwitter,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
404
docs/src/components/AppNavbar.vue
Normal file
404
docs/src/components/AppNavbar.vue
Normal file
@@ -0,0 +1,404 @@
|
||||
<template>
|
||||
<header class="py-3 lg:py-6 relative bg-gray-900 bg-opacity-50">
|
||||
<div class="container flex items-center lg:justify-between">
|
||||
<div class="w-full flex items-center space-x-4 lg:space-x-0">
|
||||
<div class="w-2/12 lg:hidden" v-if="type === 'doc'">
|
||||
<button
|
||||
class="
|
||||
lg:hidden
|
||||
relative
|
||||
z-30
|
||||
shadow-lg
|
||||
w-8
|
||||
h-8
|
||||
space-y-1
|
||||
inline-flex
|
||||
flex-col
|
||||
justify-center
|
||||
items-center
|
||||
outline-none
|
||||
focus:outline-none
|
||||
transition-all
|
||||
duration-200
|
||||
transform
|
||||
"
|
||||
@click="toggleMenu()"
|
||||
>
|
||||
<span
|
||||
class="
|
||||
inline-block
|
||||
w-6
|
||||
h-0.5
|
||||
rounded-sm
|
||||
transition-all
|
||||
duration-200
|
||||
bg-gray-100
|
||||
"
|
||||
:class="{
|
||||
'transform rotate-45 translate-y-1.5': menuOpened,
|
||||
}"
|
||||
></span>
|
||||
<span
|
||||
class="inline-block w-6 h-0.5 rounded-sm bg-gray-100"
|
||||
:class="{
|
||||
invisible: menuOpened,
|
||||
}"
|
||||
></span>
|
||||
<span
|
||||
class="
|
||||
inline-block
|
||||
w-6
|
||||
h-0.5
|
||||
rounded-sm
|
||||
transition-all
|
||||
duration-200
|
||||
bg-gray-100
|
||||
"
|
||||
:class="{
|
||||
'transform -rotate-45 -translate-y-1.5': menuOpened,
|
||||
}"
|
||||
></span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="w-8/12 lg:w-auto text-center flex items-center space-x-16"
|
||||
:class="{
|
||||
'justify-center lg:justify-start': type === 'doc',
|
||||
}"
|
||||
>
|
||||
<g-link to="/" class="flex items-center space-x-4">
|
||||
<logo-capsule class="w-10 lg:w-12" />
|
||||
<h1 class="font-bold text-2xl lg:text-3xl inline-block">Capsule</h1>
|
||||
</g-link>
|
||||
<nav class="hidden lg:inline-block">
|
||||
<ul class="flex items-center font-medium space-x-5">
|
||||
<li class="hidden lg:block">
|
||||
<g-link to="/">About Capsule</g-link>
|
||||
</li>
|
||||
<li>
|
||||
<g-link to="/docs">Documentation</g-link>
|
||||
</li>
|
||||
<!-- <li class="group relative">
|
||||
main
|
||||
<ul
|
||||
class="
|
||||
py-2
|
||||
px-4
|
||||
absolute
|
||||
top-full
|
||||
hidden
|
||||
group-hover:block
|
||||
bg-gray-100
|
||||
text-gray-800
|
||||
rounded
|
||||
text-left
|
||||
"
|
||||
>
|
||||
<li>
|
||||
<a href="/" target="_blank" rel="noopener noreferrer">
|
||||
v1.5.0
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/" target="_blank" rel="noopener noreferrer">
|
||||
v1.6.0
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/" target="_blank" rel="noopener noreferrer">
|
||||
main
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li> -->
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="w-2/12 lg:hidden" v-if="type === 'doc'">
|
||||
<button @click="toggleSearch()" class="block ml-auto">
|
||||
<icon-search class="w-8" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="relative"
|
||||
:class="{
|
||||
'hidden lg:flex items-center space-x-16': type === 'doc',
|
||||
}"
|
||||
>
|
||||
<div v-if="type === 'doc'">
|
||||
<div class="relative">
|
||||
<icon-search
|
||||
class="w-8 absolute left-0 bottom-2 text-gray-100 opacity-80"
|
||||
/>
|
||||
|
||||
<input
|
||||
type="search"
|
||||
name="search"
|
||||
id="search"
|
||||
class="
|
||||
rounded-0
|
||||
pl-10
|
||||
pr-2
|
||||
py-2
|
||||
outline-none
|
||||
w-96
|
||||
bg-transparent
|
||||
border-b border-solid border-gray-100
|
||||
text-gray-100
|
||||
"
|
||||
placeholder="Search"
|
||||
@focus="focused = true"
|
||||
@blur="focusOut()"
|
||||
@input="query = $event.target.value"
|
||||
@change="query = $event.target.value"
|
||||
/>
|
||||
</div>
|
||||
<ul
|
||||
v-show="showResult"
|
||||
class="
|
||||
absolute
|
||||
left-0
|
||||
top-12
|
||||
z-20
|
||||
text-left
|
||||
bg-gray-900
|
||||
rounded-br rounded-bl
|
||||
text-sm
|
||||
min-w-96
|
||||
"
|
||||
>
|
||||
<li v-if="results.length === 0" class="px-4 py-2">
|
||||
No results for <span class="font-bold">{{ query }}</span
|
||||
>.
|
||||
</li>
|
||||
<li v-else v-for="result in results" :key="result.id">
|
||||
<g-link
|
||||
:to="result.item.path + result.item.anchor"
|
||||
class="block px-4 py-2 hover:bg-gray-700 hover:text-blue-400"
|
||||
>
|
||||
<span v-if="result.item.value === result.item.title">
|
||||
{{ result.item.value }}
|
||||
</span>
|
||||
|
||||
<span v-else class="flex items-center">
|
||||
{{ result.item.title }}
|
||||
<icon-arrow class="w-2 mx-2 transform -rotate-90" />
|
||||
<span class="font-normal opacity-75">
|
||||
{{ result.item.value }}
|
||||
</span>
|
||||
</span>
|
||||
</g-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul
|
||||
class="items-center"
|
||||
:class="{
|
||||
'hidden lg:flex': type === 'doc',
|
||||
flex: type === 'default',
|
||||
}"
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/clastix/capsule"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Github
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
container
|
||||
py-4
|
||||
absolute
|
||||
bg-gray-900
|
||||
inset-x-0
|
||||
top-0
|
||||
z-30
|
||||
shadow-xl
|
||||
rounded-br rounded-bl
|
||||
"
|
||||
v-if="searchOpened && type === 'doc'"
|
||||
>
|
||||
<div class="flex items-center space-x-4">
|
||||
<input
|
||||
type="search"
|
||||
name="search"
|
||||
id="search"
|
||||
class="w-full rounded p-2 outline-none text-gray-800"
|
||||
placeholder="Search"
|
||||
@focus="focused = true"
|
||||
@blur="focusOutMobile()"
|
||||
@input="query = $event.target.value"
|
||||
@change="query = $event.target.value"
|
||||
/>
|
||||
<button @click="toggleSearch()">Cancel</button>
|
||||
</div>
|
||||
<ul class="p-4 space-y-2" v-show="showResult">
|
||||
<li v-if="results.length === 0">
|
||||
No results for <span class="font-bold">{{ query }}</span
|
||||
>.
|
||||
</li>
|
||||
<li v-else v-for="result in results" :key="result.id">
|
||||
<g-link
|
||||
:to="result.item.path + result.item.anchor"
|
||||
class="hover:text-blue-400"
|
||||
>
|
||||
<span v-if="result.item.value === result.item.title">
|
||||
{{ result.item.value }}
|
||||
</span>
|
||||
|
||||
<span v-else class="flex items-center">
|
||||
{{ result.item.title }}
|
||||
<span class="block">
|
||||
<icon-arrow class="w-2 mx-2 transform -rotate-90" />
|
||||
</span>
|
||||
<span class="font-normal opacity-75">
|
||||
{{ result.item.value }}
|
||||
</span>
|
||||
</span>
|
||||
</g-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<static-query>
|
||||
query Search {
|
||||
allMarkdownPage{
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
path
|
||||
title
|
||||
headings {
|
||||
depth
|
||||
value
|
||||
anchor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</static-query>
|
||||
|
||||
<script>
|
||||
import Fuse from "fuse.js";
|
||||
|
||||
import IconSearch from "~/assets/icon/search.svg?inline";
|
||||
import IconGithub from "~/assets/icon/github.svg?inline";
|
||||
import IconTwitter from "~/assets/icon/twitter.svg?inline";
|
||||
import IconSlack from "~/assets/icon/slack.svg?inline";
|
||||
import IconArrow from "~/assets/icon/arrow.svg?inline";
|
||||
import LogoCapsule from "~/assets/logo.svg?inline";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: () => "default",
|
||||
validator: (value) => ["default", "doc"].includes(value),
|
||||
},
|
||||
},
|
||||
|
||||
components: {
|
||||
IconSearch,
|
||||
IconGithub,
|
||||
IconTwitter,
|
||||
IconSlack,
|
||||
IconArrow,
|
||||
LogoCapsule,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
menuOpened: false,
|
||||
searchOpened: false,
|
||||
query: "",
|
||||
focusIndex: -1,
|
||||
focused: false,
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route: function () {
|
||||
if (this.menuOpened) {
|
||||
this.menuOpened = false;
|
||||
this.$emit("onToggleMenu", this.menuOpened);
|
||||
document.querySelector("body").classList.remove("overflow-hidden");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
results() {
|
||||
const fuse = new Fuse(this.headings, {
|
||||
keys: ["value"],
|
||||
threshold: 0.25,
|
||||
});
|
||||
return fuse.search(this.query).slice(0, 15);
|
||||
},
|
||||
|
||||
headings() {
|
||||
let result = [];
|
||||
const allPages = this.$static.allMarkdownPage.edges.map(
|
||||
(edge) => edge.node
|
||||
);
|
||||
// Create the array of all headings of all pages.
|
||||
allPages.forEach((page) => {
|
||||
page.headings.forEach((heading) => {
|
||||
result.push({
|
||||
...heading,
|
||||
path: page.path,
|
||||
title: page.title,
|
||||
});
|
||||
});
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
showResult() {
|
||||
// Show results, if the input is focused and the query is not empty.
|
||||
return this.focused && this.query.length > 0;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleMenu() {
|
||||
this.menuOpened = !this.menuOpened;
|
||||
this.$emit("onToggleMenu", this.menuOpened);
|
||||
if (this.menuOpened) {
|
||||
document.querySelector("body").classList.add("overflow-hidden");
|
||||
} else {
|
||||
document.querySelector("body").classList.remove("overflow-hidden");
|
||||
}
|
||||
},
|
||||
|
||||
toggleSearch() {
|
||||
this.searchOpened = !this.searchOpened;
|
||||
},
|
||||
|
||||
focusOut() {
|
||||
const _this = this;
|
||||
setTimeout(function () {
|
||||
_this.focused = false;
|
||||
}, 200);
|
||||
},
|
||||
|
||||
focusOutMobile() {
|
||||
const _this = this;
|
||||
setTimeout(function () {
|
||||
_this.focused = false;
|
||||
_this.toggleSearch();
|
||||
}, 200);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
135
docs/src/components/AppSidebar.vue
Normal file
135
docs/src/components/AppSidebar.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<aside>
|
||||
<nav>
|
||||
<ul class="space-y-3 pl-4 lg:pl-0">
|
||||
<li
|
||||
v-for="section in $static.allSidebar.edges[0].node.sections"
|
||||
:key="section.id"
|
||||
>
|
||||
<h5
|
||||
class="text-2xl lg:text-xl font-bold mb-1"
|
||||
v-if="section.title !== ''"
|
||||
>
|
||||
{{ section.title }}
|
||||
</h5>
|
||||
<ul
|
||||
class="space-y-1.5"
|
||||
:class="{
|
||||
'pl-2': section.title !== '',
|
||||
}"
|
||||
>
|
||||
<template v-for="(item, index) in section.items">
|
||||
<li :key="item.id" v-if="item.title === ''">
|
||||
<g-link
|
||||
:to="item.path"
|
||||
class="
|
||||
block
|
||||
transition-transform
|
||||
duration-100
|
||||
transform
|
||||
hover:translate-x-1
|
||||
text-lg
|
||||
lg:text-base
|
||||
hover:text-blue-400
|
||||
"
|
||||
:class="{
|
||||
'js-index-link': item.path === '/docs/' && index === 0,
|
||||
}"
|
||||
>
|
||||
{{ item.label }}</g-link
|
||||
>
|
||||
</li>
|
||||
<template v-else>
|
||||
<li :key="item.id">
|
||||
<app-accordion>
|
||||
<template v-slot:title>
|
||||
<h6 class="font-semibold text-xl lg:text-lg mb-1">
|
||||
{{ item.title }}
|
||||
</h6>
|
||||
</template>
|
||||
<template v-slot:content>
|
||||
<ul class="space-y-1.5 pl-2">
|
||||
<li v-for="subItem in item.subItems" :key="subItem.id">
|
||||
<g-link
|
||||
:to="subItem.path"
|
||||
class="
|
||||
block
|
||||
transition-transform
|
||||
duration-100
|
||||
transform
|
||||
hover:translate-x-1
|
||||
text-lg
|
||||
lg:text-base
|
||||
hover:text-blue-400
|
||||
"
|
||||
>
|
||||
{{ subItem.label }}</g-link
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</app-accordion>
|
||||
</li>
|
||||
</template>
|
||||
</template>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<static-query>
|
||||
{
|
||||
allSidebar {
|
||||
edges{
|
||||
node{
|
||||
id
|
||||
sections {
|
||||
title
|
||||
items{
|
||||
title
|
||||
label
|
||||
path
|
||||
subItems {
|
||||
label
|
||||
path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</static-query>
|
||||
|
||||
<script>
|
||||
import AppAccordion from "~/components/AppAccordion.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AppAccordion,
|
||||
},
|
||||
watch: {
|
||||
$route: function () {
|
||||
if (process.isClient && this.$route.fullPath !== "/docs/") {
|
||||
setTimeout(function () {
|
||||
document.querySelector(".js-index-link").classList.remove("active");
|
||||
}, 80);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.$route.fullPath !== "/docs/") {
|
||||
document.querySelector(".js-index-link").classList.remove("active");
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.active {
|
||||
@apply text-blue-400 font-semibold;
|
||||
}
|
||||
</style>
|
||||
108
docs/src/components/OnThisPage.vue
Normal file
108
docs/src/components/OnThisPage.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<ul class="space-y-2">
|
||||
<template v-for="(heading, index) in headings">
|
||||
<li v-if="heading.depth > 1" :key="index" class="hover:underline">
|
||||
<g-link
|
||||
:to="`${pagePath}${heading.anchor}`"
|
||||
class="text-sm"
|
||||
:class="{
|
||||
'text-white underline font-semibold':
|
||||
activeAnchor === heading.anchor,
|
||||
'text-gray-300': activeAnchor !== heading.anchor,
|
||||
}"
|
||||
>
|
||||
{{ heading.value }}
|
||||
</g-link>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
headings: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
pagePath: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
activeAnchor: "",
|
||||
observer: null,
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route: function () {
|
||||
if (process.isClient && window.location.hash) {
|
||||
this.activeAnchor = window.location.hash;
|
||||
}
|
||||
|
||||
if (this.observer) {
|
||||
// Clear the current observer.
|
||||
this.observer.disconnect();
|
||||
|
||||
this.$nextTick(this.initObserver);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (process.isClient) {
|
||||
if (window.location.hash) {
|
||||
this.activeAnchor = window.location.hash;
|
||||
}
|
||||
this.$nextTick(this.initObserver);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
observerCallback(entries, observer) {
|
||||
// This early return fixes the jumping
|
||||
// of the bubble active state when we click on a link.
|
||||
// There should be only one intersecting element anyways.
|
||||
if (entries.length > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const id = entries[0].target.id;
|
||||
|
||||
// We want to give the link of the intersecting
|
||||
// headline active and add the hash to the url.
|
||||
if (id) {
|
||||
this.activeAnchor = "#" + id;
|
||||
|
||||
if (history.replaceState) {
|
||||
history.replaceState(null, null, "#" + id);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
initObserver() {
|
||||
this.observer = new IntersectionObserver(this.observerCallback, {
|
||||
// This rootMargin should allow intersections at the top of the page.
|
||||
// root: document.querySelector('.content'),
|
||||
rootMargin: "0px 0px 99999px",
|
||||
threshold: 1,
|
||||
});
|
||||
|
||||
const elements = document.querySelectorAll(
|
||||
".content h2, .content h3, .content h4, .content h5, .content h6"
|
||||
);
|
||||
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
this.observer.observe(elements[i]);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
4
docs/src/components/README.md
Normal file
4
docs/src/components/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
Add components that will be imported to Pages and Layouts to this folder.
|
||||
Learn more about components here: https://gridsome.org/docs/components/
|
||||
|
||||
You can delete this file.
|
||||
Reference in New Issue
Block a user