deploy: ebd4cc0010
This commit is contained in:
21
node_modules/vitepress/LICENSE
generated
vendored
21
node_modules/vitepress/LICENSE
generated
vendored
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-present, Yuxi (Evan) You
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
29
node_modules/vitepress/README.md
generated
vendored
29
node_modules/vitepress/README.md
generated
vendored
@@ -1,29 +0,0 @@
|
||||
# VitePress (RC: release candidate) 📝💨
|
||||
|
||||
[](https://github.com/vuejs/vitepress/actions)
|
||||
[](https://www.npmjs.com/package/vitepress)
|
||||
[](https://chat.vuejs.org)
|
||||
|
||||
---
|
||||
|
||||
VitePress is [VuePress](https://vuepress.vuejs.org)' spiritual successor, built on top of [vite](https://github.com/vitejs/vite).
|
||||
|
||||
Currently, it is in the `release candidate` stage. It is already suitable for out-of-the-box documentation use. We do not plan to introduce any breaking changes from here on until the stable release.
|
||||
|
||||
## Documentation
|
||||
|
||||
To check out docs, visit [vitepress.dev](https://vitepress.dev).
|
||||
|
||||
## Changelog
|
||||
|
||||
Detailed changes for each release are documented in the [CHANGELOG](https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md).
|
||||
|
||||
## Contribution
|
||||
|
||||
Please make sure to read the [Contributing Guide](https://github.com/vuejs/vitepress/blob/main/.github/contributing.md) before making a pull request.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://github.com/vuejs/vitepress/blob/main/LICENSE)
|
||||
|
||||
Copyright (c) 2019-present, Yuxi (Evan) You
|
||||
2
node_modules/vitepress/bin/vitepress.js
generated
vendored
2
node_modules/vitepress/bin/vitepress.js
generated
vendored
@@ -1,2 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
import('../dist/node/cli.js')
|
||||
5
node_modules/vitepress/client.d.ts
generated
vendored
5
node_modules/vitepress/client.d.ts
generated
vendored
@@ -1,5 +0,0 @@
|
||||
// re-export vite client types. with strict installers like pnpm, user won't
|
||||
// be able to reference vite/client in project root.
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
export * from './dist/client/index.js'
|
||||
10
node_modules/vitepress/dist/client/app/components/ClientOnly.js
generated
vendored
10
node_modules/vitepress/dist/client/app/components/ClientOnly.js
generated
vendored
@@ -1,10 +0,0 @@
|
||||
import { defineComponent, ref, onMounted } from 'vue';
|
||||
export const ClientOnly = defineComponent({
|
||||
setup(_, { slots }) {
|
||||
const show = ref(false);
|
||||
onMounted(() => {
|
||||
show.value = true;
|
||||
});
|
||||
return () => (show.value && slots.default ? slots.default() : null);
|
||||
}
|
||||
});
|
||||
22
node_modules/vitepress/dist/client/app/components/Content.js
generated
vendored
22
node_modules/vitepress/dist/client/app/components/Content.js
generated
vendored
@@ -1,22 +0,0 @@
|
||||
import { defineComponent, h } from 'vue';
|
||||
import { useData, useRoute } from 'vitepress';
|
||||
import { contentUpdatedCallbacks } from '../utils';
|
||||
const runCbs = () => contentUpdatedCallbacks.forEach((fn) => fn());
|
||||
export const Content = defineComponent({
|
||||
name: 'VitePressContent',
|
||||
props: {
|
||||
as: { type: [Object, String], default: 'div' }
|
||||
},
|
||||
setup(props) {
|
||||
const route = useRoute();
|
||||
const { site } = useData();
|
||||
return () => h(props.as, site.value.contentProps ?? { style: { position: 'relative' } }, [
|
||||
route.component
|
||||
? h(route.component, {
|
||||
onVnodeMounted: runCbs,
|
||||
onVnodeUpdated: runCbs
|
||||
})
|
||||
: '404 Page Not Found'
|
||||
]);
|
||||
}
|
||||
});
|
||||
40
node_modules/vitepress/dist/client/app/composables/codeGroups.js
generated
vendored
40
node_modules/vitepress/dist/client/app/composables/codeGroups.js
generated
vendored
@@ -1,40 +0,0 @@
|
||||
import { inBrowser, onContentUpdated } from 'vitepress';
|
||||
export function useCodeGroups() {
|
||||
if (import.meta.env.DEV) {
|
||||
onContentUpdated(() => {
|
||||
document.querySelectorAll('.vp-code-group > .blocks').forEach((el) => {
|
||||
Array.from(el.children).forEach((child) => {
|
||||
child.classList.remove('active');
|
||||
});
|
||||
el.children[0].classList.add('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
if (inBrowser) {
|
||||
window.addEventListener('click', (e) => {
|
||||
const el = e.target;
|
||||
if (el.matches('.vp-code-group input')) {
|
||||
// input <- .tabs <- .vp-code-group
|
||||
const group = el.parentElement?.parentElement;
|
||||
if (!group)
|
||||
return;
|
||||
const i = Array.from(group.querySelectorAll('input')).indexOf(el);
|
||||
if (i < 0)
|
||||
return;
|
||||
const blocks = group.querySelector('.blocks');
|
||||
if (!blocks)
|
||||
return;
|
||||
const current = Array.from(blocks.children).find((child) => child.classList.contains('active'));
|
||||
if (!current)
|
||||
return;
|
||||
const next = blocks.children[i];
|
||||
if (!next || current === next)
|
||||
return;
|
||||
current.classList.remove('active');
|
||||
next.classList.add('active');
|
||||
const label = group?.querySelector(`label[for="${el.id}"]`);
|
||||
label?.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
71
node_modules/vitepress/dist/client/app/composables/copyCode.js
generated
vendored
71
node_modules/vitepress/dist/client/app/composables/copyCode.js
generated
vendored
@@ -1,71 +0,0 @@
|
||||
import { inBrowser } from 'vitepress';
|
||||
export function useCopyCode() {
|
||||
if (inBrowser) {
|
||||
const timeoutIdMap = new WeakMap();
|
||||
window.addEventListener('click', (e) => {
|
||||
const el = e.target;
|
||||
if (el.matches('div[class*="language-"] > button.copy')) {
|
||||
const parent = el.parentElement;
|
||||
const sibling = el.nextElementSibling?.nextElementSibling;
|
||||
if (!parent || !sibling) {
|
||||
return;
|
||||
}
|
||||
const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(parent.className);
|
||||
let text = '';
|
||||
sibling
|
||||
.querySelectorAll('span.line:not(.diff.remove)')
|
||||
.forEach((node) => (text += (node.textContent || '') + '\n'));
|
||||
text = text.slice(0, -1);
|
||||
if (isShell) {
|
||||
text = text.replace(/^ *(\$|>) /gm, '').trim();
|
||||
}
|
||||
copyToClipboard(text).then(() => {
|
||||
el.classList.add('copied');
|
||||
clearTimeout(timeoutIdMap.get(el));
|
||||
const timeoutId = setTimeout(() => {
|
||||
el.classList.remove('copied');
|
||||
el.blur();
|
||||
timeoutIdMap.delete(el);
|
||||
}, 2000);
|
||||
timeoutIdMap.set(el, timeoutId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
async function copyToClipboard(text) {
|
||||
try {
|
||||
return navigator.clipboard.writeText(text);
|
||||
}
|
||||
catch {
|
||||
const element = document.createElement('textarea');
|
||||
const previouslyFocusedElement = document.activeElement;
|
||||
element.value = text;
|
||||
// Prevent keyboard from showing on mobile
|
||||
element.setAttribute('readonly', '');
|
||||
element.style.contain = 'strict';
|
||||
element.style.position = 'absolute';
|
||||
element.style.left = '-9999px';
|
||||
element.style.fontSize = '12pt'; // Prevent zooming on iOS
|
||||
const selection = document.getSelection();
|
||||
const originalRange = selection
|
||||
? selection.rangeCount > 0 && selection.getRangeAt(0)
|
||||
: null;
|
||||
document.body.appendChild(element);
|
||||
element.select();
|
||||
// Explicit selection workaround for iOS
|
||||
element.selectionStart = 0;
|
||||
element.selectionEnd = text.length;
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(element);
|
||||
if (originalRange) {
|
||||
selection.removeAllRanges(); // originalRange can't be truthy when selection is falsy
|
||||
selection.addRange(originalRange);
|
||||
}
|
||||
// Get the focus back on the previously focused element, if any
|
||||
if (previouslyFocusedElement) {
|
||||
;
|
||||
previouslyFocusedElement.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
61
node_modules/vitepress/dist/client/app/composables/head.js
generated
vendored
61
node_modules/vitepress/dist/client/app/composables/head.js
generated
vendored
@@ -1,61 +0,0 @@
|
||||
import { watchEffect } from 'vue';
|
||||
import { createTitle, mergeHead } from '../../shared';
|
||||
export function useUpdateHead(route, siteDataByRouteRef) {
|
||||
let managedHeadTags = [];
|
||||
let isFirstUpdate = true;
|
||||
const updateHeadTags = (newTags) => {
|
||||
if (import.meta.env.PROD && isFirstUpdate) {
|
||||
// in production, the initial meta tags are already pre-rendered so we
|
||||
// skip the first update.
|
||||
isFirstUpdate = false;
|
||||
return;
|
||||
}
|
||||
managedHeadTags.forEach((el) => document.head.removeChild(el));
|
||||
managedHeadTags = [];
|
||||
newTags.forEach((headConfig) => {
|
||||
const el = createHeadElement(headConfig);
|
||||
document.head.appendChild(el);
|
||||
managedHeadTags.push(el);
|
||||
});
|
||||
};
|
||||
watchEffect(() => {
|
||||
const pageData = route.data;
|
||||
const siteData = siteDataByRouteRef.value;
|
||||
const pageDescription = pageData && pageData.description;
|
||||
const frontmatterHead = (pageData && pageData.frontmatter.head) || [];
|
||||
// update title and description
|
||||
document.title = createTitle(siteData, pageData);
|
||||
const description = pageDescription || siteData.description;
|
||||
let metaDescriptionElement = document.querySelector(`meta[name=description]`);
|
||||
if (metaDescriptionElement) {
|
||||
metaDescriptionElement.setAttribute('content', description);
|
||||
}
|
||||
else {
|
||||
createHeadElement(['meta', { name: 'description', content: description }]);
|
||||
}
|
||||
updateHeadTags(mergeHead(siteData.head, filterOutHeadDescription(frontmatterHead)));
|
||||
});
|
||||
}
|
||||
function createHeadElement([tag, attrs, innerHTML]) {
|
||||
const el = document.createElement(tag);
|
||||
for (const key in attrs) {
|
||||
el.setAttribute(key, attrs[key]);
|
||||
}
|
||||
if (innerHTML) {
|
||||
el.innerHTML = innerHTML;
|
||||
}
|
||||
if (tag === 'script' && !attrs.async) {
|
||||
// async is true by default for dynamically created scripts
|
||||
;
|
||||
el.async = false;
|
||||
}
|
||||
return el;
|
||||
}
|
||||
function isMetaDescription(headConfig) {
|
||||
return (headConfig[0] === 'meta' &&
|
||||
headConfig[1] &&
|
||||
headConfig[1].name === 'description');
|
||||
}
|
||||
function filterOutHeadDescription(head) {
|
||||
return head.filter((h) => !isMetaDescription(h));
|
||||
}
|
||||
99
node_modules/vitepress/dist/client/app/composables/preFetch.js
generated
vendored
99
node_modules/vitepress/dist/client/app/composables/preFetch.js
generated
vendored
@@ -1,99 +0,0 @@
|
||||
// Customized pre-fetch for page chunks based on
|
||||
// https://github.com/GoogleChromeLabs/quicklink
|
||||
import { useRoute } from '../router';
|
||||
import { onMounted, onUnmounted, watch } from 'vue';
|
||||
import { inBrowser, pathToFile } from '../utils';
|
||||
const hasFetched = new Set();
|
||||
const createLink = () => document.createElement('link');
|
||||
const viaDOM = (url) => {
|
||||
const link = createLink();
|
||||
link.rel = `prefetch`;
|
||||
link.href = url;
|
||||
document.head.appendChild(link);
|
||||
};
|
||||
const viaXHR = (url) => {
|
||||
const req = new XMLHttpRequest();
|
||||
req.open('GET', url, (req.withCredentials = true));
|
||||
req.send();
|
||||
};
|
||||
let link;
|
||||
const doFetch = inBrowser &&
|
||||
(link = createLink()) &&
|
||||
link.relList &&
|
||||
link.relList.supports &&
|
||||
link.relList.supports('prefetch')
|
||||
? viaDOM
|
||||
: viaXHR;
|
||||
export function usePrefetch() {
|
||||
if (!inBrowser) {
|
||||
return;
|
||||
}
|
||||
if (!window.IntersectionObserver) {
|
||||
return;
|
||||
}
|
||||
let conn;
|
||||
if ((conn = navigator.connection) &&
|
||||
(conn.saveData || /2g/.test(conn.effectiveType))) {
|
||||
// Don't prefetch if using 2G or if Save-Data is enabled.
|
||||
return;
|
||||
}
|
||||
const rIC = window.requestIdleCallback || setTimeout;
|
||||
let observer = null;
|
||||
const observeLinks = () => {
|
||||
if (observer) {
|
||||
observer.disconnect();
|
||||
}
|
||||
observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const link = entry.target;
|
||||
observer.unobserve(link);
|
||||
const { pathname } = link;
|
||||
if (!hasFetched.has(pathname)) {
|
||||
hasFetched.add(pathname);
|
||||
const pageChunkPath = pathToFile(pathname);
|
||||
if (pageChunkPath)
|
||||
doFetch(pageChunkPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
rIC(() => {
|
||||
document
|
||||
.querySelectorAll('#app a')
|
||||
.forEach((link) => {
|
||||
const { hostname, pathname } = new URL(link.href instanceof SVGAnimatedString
|
||||
? link.href.animVal
|
||||
: link.href, link.baseURI);
|
||||
const extMatch = pathname.match(/\.\w+$/);
|
||||
if (extMatch && extMatch[0] !== '.html') {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
// only prefetch same tab navigation, since a new tab will load
|
||||
// the lean js chunk instead.
|
||||
link.target !== '_blank' &&
|
||||
// only prefetch inbound links
|
||||
hostname === location.hostname) {
|
||||
if (pathname !== location.pathname) {
|
||||
observer.observe(link);
|
||||
}
|
||||
else {
|
||||
// No need to prefetch chunk for the current page, but also mark
|
||||
// it as already fetched. This is because the initial page uses its
|
||||
// lean chunk, and if we don't mark it, navigation to another page
|
||||
// with a link back to the first page will fetch its full chunk
|
||||
// which isn't needed.
|
||||
hasFetched.add(pathname);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
onMounted(observeLinks);
|
||||
const route = useRoute();
|
||||
watch(() => route.path, observeLinks);
|
||||
onUnmounted(() => {
|
||||
observer && observer.disconnect();
|
||||
});
|
||||
}
|
||||
53
node_modules/vitepress/dist/client/app/data.js
generated
vendored
53
node_modules/vitepress/dist/client/app/data.js
generated
vendored
@@ -1,53 +0,0 @@
|
||||
import siteData from '@siteData';
|
||||
import { useDark } from '@vueuse/core';
|
||||
import { computed, inject, readonly, ref, shallowRef } from 'vue';
|
||||
import { APPEARANCE_KEY, createTitle, resolveSiteDataByRoute } from '../shared';
|
||||
export const dataSymbol = Symbol();
|
||||
// site data is a singleton
|
||||
export const siteDataRef = shallowRef((import.meta.env.PROD ? siteData : readonly(siteData)));
|
||||
// hmr
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept('/@siteData', (m) => {
|
||||
if (m) {
|
||||
siteDataRef.value = m.default;
|
||||
}
|
||||
});
|
||||
}
|
||||
// per-app data
|
||||
export function initData(route) {
|
||||
const site = computed(() => resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath));
|
||||
const appearance = site.value.appearance; // fine with reactivity being lost here, config change triggers a restart
|
||||
const isDark = appearance === 'force-dark'
|
||||
? ref(true)
|
||||
: appearance
|
||||
? useDark({
|
||||
storageKey: APPEARANCE_KEY,
|
||||
initialValue: () => typeof appearance === 'string' ? appearance : 'auto',
|
||||
...(typeof appearance === 'object' ? appearance : {})
|
||||
})
|
||||
: ref(false);
|
||||
return {
|
||||
site,
|
||||
theme: computed(() => site.value.themeConfig),
|
||||
page: computed(() => route.data),
|
||||
frontmatter: computed(() => route.data.frontmatter),
|
||||
params: computed(() => route.data.params),
|
||||
lang: computed(() => site.value.lang),
|
||||
dir: computed(() => site.value.dir),
|
||||
localeIndex: computed(() => site.value.localeIndex || 'root'),
|
||||
title: computed(() => {
|
||||
return createTitle(site.value, route.data);
|
||||
}),
|
||||
description: computed(() => {
|
||||
return route.data.description || site.value.description;
|
||||
}),
|
||||
isDark
|
||||
};
|
||||
}
|
||||
export function useData() {
|
||||
const data = inject(dataSymbol);
|
||||
if (!data) {
|
||||
throw new Error('vitepress data not properly injected in app');
|
||||
}
|
||||
return data;
|
||||
}
|
||||
28
node_modules/vitepress/dist/client/app/devtools.js
generated
vendored
28
node_modules/vitepress/dist/client/app/devtools.js
generated
vendored
@@ -1,28 +0,0 @@
|
||||
import { setupDevtoolsPlugin } from '@vue/devtools-api';
|
||||
const COMPONENT_STATE_TYPE = 'VitePress';
|
||||
export const setupDevtools = (app, router, data) => {
|
||||
setupDevtoolsPlugin({
|
||||
// fix recursive reference
|
||||
app: app,
|
||||
id: 'org.vuejs.vitepress',
|
||||
label: 'VitePress',
|
||||
packageName: 'vitepress',
|
||||
homepage: 'https://vitepress.dev',
|
||||
componentStateTypes: [COMPONENT_STATE_TYPE]
|
||||
}, (api) => {
|
||||
api.on.inspectComponent((payload) => {
|
||||
payload.instanceData.state.push({
|
||||
type: COMPONENT_STATE_TYPE,
|
||||
key: 'route',
|
||||
value: router.route,
|
||||
editable: false
|
||||
});
|
||||
payload.instanceData.state.push({
|
||||
type: COMPONENT_STATE_TYPE,
|
||||
key: 'data',
|
||||
value: data,
|
||||
editable: false
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
133
node_modules/vitepress/dist/client/app/index.js
generated
vendored
133
node_modules/vitepress/dist/client/app/index.js
generated
vendored
@@ -1,133 +0,0 @@
|
||||
import RawTheme from '@theme/index';
|
||||
import { createApp as createClientApp, createSSRApp, defineComponent, h, onMounted, watchEffect } from 'vue';
|
||||
import { ClientOnly } from './components/ClientOnly';
|
||||
import { Content } from './components/Content';
|
||||
import { useCodeGroups } from './composables/codeGroups';
|
||||
import { useCopyCode } from './composables/copyCode';
|
||||
import { useUpdateHead } from './composables/head';
|
||||
import { usePrefetch } from './composables/preFetch';
|
||||
import { dataSymbol, initData, siteDataRef, useData } from './data';
|
||||
import { RouterSymbol, createRouter, scrollTo } from './router';
|
||||
import { inBrowser, pathToFile } from './utils';
|
||||
function resolveThemeExtends(theme) {
|
||||
if (theme.extends) {
|
||||
const base = resolveThemeExtends(theme.extends);
|
||||
return {
|
||||
...base,
|
||||
...theme,
|
||||
async enhanceApp(ctx) {
|
||||
if (base.enhanceApp)
|
||||
await base.enhanceApp(ctx);
|
||||
if (theme.enhanceApp)
|
||||
await theme.enhanceApp(ctx);
|
||||
}
|
||||
};
|
||||
}
|
||||
return theme;
|
||||
}
|
||||
const Theme = resolveThemeExtends(RawTheme);
|
||||
const VitePressApp = defineComponent({
|
||||
name: 'VitePressApp',
|
||||
setup() {
|
||||
const { site } = useData();
|
||||
// change the language on the HTML element based on the current lang
|
||||
onMounted(() => {
|
||||
watchEffect(() => {
|
||||
document.documentElement.lang = site.value.lang;
|
||||
document.documentElement.dir = site.value.dir;
|
||||
});
|
||||
});
|
||||
if (import.meta.env.PROD) {
|
||||
// in prod mode, enable intersectionObserver based pre-fetch
|
||||
usePrefetch();
|
||||
}
|
||||
// setup global copy code handler
|
||||
useCopyCode();
|
||||
// setup global code groups handler
|
||||
useCodeGroups();
|
||||
if (Theme.setup)
|
||||
Theme.setup();
|
||||
return () => h(Theme.Layout);
|
||||
}
|
||||
});
|
||||
export async function createApp() {
|
||||
const router = newRouter();
|
||||
const app = newApp();
|
||||
app.provide(RouterSymbol, router);
|
||||
const data = initData(router.route);
|
||||
app.provide(dataSymbol, data);
|
||||
// install global components
|
||||
app.component('Content', Content);
|
||||
app.component('ClientOnly', ClientOnly);
|
||||
// expose $frontmatter & $params
|
||||
Object.defineProperties(app.config.globalProperties, {
|
||||
$frontmatter: {
|
||||
get() {
|
||||
return data.frontmatter.value;
|
||||
}
|
||||
},
|
||||
$params: {
|
||||
get() {
|
||||
return data.page.value.params;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (Theme.enhanceApp) {
|
||||
await Theme.enhanceApp({
|
||||
app,
|
||||
router,
|
||||
siteData: siteDataRef
|
||||
});
|
||||
}
|
||||
// setup devtools in dev mode
|
||||
if (import.meta.env.DEV || __VUE_PROD_DEVTOOLS__) {
|
||||
import('./devtools.js').then(({ setupDevtools }) => setupDevtools(app, router, data));
|
||||
}
|
||||
return { app, router, data };
|
||||
}
|
||||
function newApp() {
|
||||
return import.meta.env.PROD
|
||||
? createSSRApp(VitePressApp)
|
||||
: createClientApp(VitePressApp);
|
||||
}
|
||||
function newRouter() {
|
||||
let isInitialPageLoad = inBrowser;
|
||||
let initialPath;
|
||||
return createRouter((path) => {
|
||||
let pageFilePath = pathToFile(path);
|
||||
let pageModule = null;
|
||||
if (pageFilePath) {
|
||||
if (isInitialPageLoad) {
|
||||
initialPath = pageFilePath;
|
||||
}
|
||||
// use lean build if this is the initial page load or navigating back
|
||||
// to the initial loaded path (the static vnodes already adopted the
|
||||
// static content on that load so no need to re-fetch the page)
|
||||
if (isInitialPageLoad || initialPath === pageFilePath) {
|
||||
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js');
|
||||
}
|
||||
pageModule = import(/*@vite-ignore*/ pageFilePath);
|
||||
}
|
||||
if (inBrowser) {
|
||||
isInitialPageLoad = false;
|
||||
}
|
||||
return pageModule;
|
||||
}, Theme.NotFound);
|
||||
}
|
||||
if (inBrowser) {
|
||||
createApp().then(({ app, router, data }) => {
|
||||
// wait until page component is fetched before mounting
|
||||
router.go().then(() => {
|
||||
// dynamically update head tags
|
||||
useUpdateHead(router.route, data.site);
|
||||
app.mount('#app');
|
||||
// scroll to hash on new tab during dev
|
||||
if (import.meta.env.DEV && location.hash) {
|
||||
const target = document.getElementById(decodeURIComponent(location.hash).slice(1));
|
||||
if (target) {
|
||||
scrollTo(target, location.hash);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
266
node_modules/vitepress/dist/client/app/router.js
generated
vendored
266
node_modules/vitepress/dist/client/app/router.js
generated
vendored
@@ -1,266 +0,0 @@
|
||||
import { reactive, inject, markRaw, nextTick, readonly } from 'vue';
|
||||
import { notFoundPageData } from '../shared';
|
||||
import { inBrowser, withBase } from './utils';
|
||||
import { siteDataRef } from './data';
|
||||
export const RouterSymbol = Symbol();
|
||||
// we are just using URL to parse the pathname and hash - the base doesn't
|
||||
// matter and is only passed to support same-host hrefs.
|
||||
const fakeHost = 'http://a.com';
|
||||
const getDefaultRoute = () => ({
|
||||
path: '/',
|
||||
component: null,
|
||||
data: notFoundPageData
|
||||
});
|
||||
export function createRouter(loadPageModule, fallbackComponent) {
|
||||
const route = reactive(getDefaultRoute());
|
||||
const router = {
|
||||
route,
|
||||
go
|
||||
};
|
||||
async function go(href = inBrowser ? location.href : '/') {
|
||||
href = normalizeHref(href);
|
||||
if ((await router.onBeforeRouteChange?.(href)) === false)
|
||||
return;
|
||||
updateHistory(href);
|
||||
await loadPage(href);
|
||||
await router.onAfterRouteChanged?.(href);
|
||||
}
|
||||
let latestPendingPath = null;
|
||||
async function loadPage(href, scrollPosition = 0, isRetry = false) {
|
||||
if ((await router.onBeforePageLoad?.(href)) === false)
|
||||
return;
|
||||
const targetLoc = new URL(href, fakeHost);
|
||||
const pendingPath = (latestPendingPath = targetLoc.pathname);
|
||||
try {
|
||||
let page = await loadPageModule(pendingPath);
|
||||
if (!page) {
|
||||
throw new Error(`Page not found: ${pendingPath}`);
|
||||
}
|
||||
if (latestPendingPath === pendingPath) {
|
||||
latestPendingPath = null;
|
||||
const { default: comp, __pageData } = page;
|
||||
if (!comp) {
|
||||
throw new Error(`Invalid route component: ${comp}`);
|
||||
}
|
||||
route.path = inBrowser ? pendingPath : withBase(pendingPath);
|
||||
route.component = markRaw(comp);
|
||||
route.data = import.meta.env.PROD
|
||||
? markRaw(__pageData)
|
||||
: readonly(__pageData);
|
||||
if (inBrowser) {
|
||||
nextTick(() => {
|
||||
let actualPathname = siteDataRef.value.base +
|
||||
__pageData.relativePath.replace(/(?:(^|\/)index)?\.md$/, '$1');
|
||||
if (!siteDataRef.value.cleanUrls && !actualPathname.endsWith('/')) {
|
||||
actualPathname += '.html';
|
||||
}
|
||||
if (actualPathname !== targetLoc.pathname) {
|
||||
targetLoc.pathname = actualPathname;
|
||||
href = actualPathname + targetLoc.search + targetLoc.hash;
|
||||
history.replaceState(null, '', href);
|
||||
}
|
||||
if (targetLoc.hash && !scrollPosition) {
|
||||
let target = null;
|
||||
try {
|
||||
target = document.getElementById(decodeURIComponent(targetLoc.hash).slice(1));
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
if (target) {
|
||||
scrollTo(target, targetLoc.hash);
|
||||
return;
|
||||
}
|
||||
}
|
||||
window.scrollTo(0, scrollPosition);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
if (!/fetch|Page not found/.test(err.message) &&
|
||||
!/^\/404(\.html|\/)?$/.test(href)) {
|
||||
console.error(err);
|
||||
}
|
||||
// retry on fetch fail: the page to hash map may have been invalidated
|
||||
// because a new deploy happened while the page is open. Try to fetch
|
||||
// the updated pageToHash map and fetch again.
|
||||
if (!isRetry) {
|
||||
try {
|
||||
const res = await fetch(siteDataRef.value.base + 'hashmap.json');
|
||||
window.__VP_HASH_MAP__ = await res.json();
|
||||
await loadPage(href, scrollPosition, true);
|
||||
return;
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
if (latestPendingPath === pendingPath) {
|
||||
latestPendingPath = null;
|
||||
route.path = inBrowser ? pendingPath : withBase(pendingPath);
|
||||
route.component = fallbackComponent ? markRaw(fallbackComponent) : null;
|
||||
route.data = notFoundPageData;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inBrowser) {
|
||||
window.addEventListener('click', (e) => {
|
||||
// temporary fix for docsearch action buttons
|
||||
const button = e.target.closest('button');
|
||||
if (button)
|
||||
return;
|
||||
const link = e.target.closest('a');
|
||||
if (link &&
|
||||
!link.closest('.vp-raw') &&
|
||||
(link instanceof SVGElement || !link.download)) {
|
||||
const { target } = link;
|
||||
const { href, origin, pathname, hash, search } = new URL(link.href instanceof SVGAnimatedString
|
||||
? link.href.animVal
|
||||
: link.href, link.baseURI);
|
||||
const currentUrl = window.location;
|
||||
const extMatch = pathname.match(/\.\w+$/);
|
||||
// only intercept inbound links
|
||||
if (!e.ctrlKey &&
|
||||
!e.shiftKey &&
|
||||
!e.altKey &&
|
||||
!e.metaKey &&
|
||||
!target &&
|
||||
origin === currentUrl.origin &&
|
||||
// don't intercept if non-html extension is present
|
||||
!(extMatch && extMatch[0] !== '.html')) {
|
||||
e.preventDefault();
|
||||
if (pathname === currentUrl.pathname &&
|
||||
search === currentUrl.search) {
|
||||
// scroll between hash anchors in the same page
|
||||
// avoid duplicate history entries when the hash is same
|
||||
if (hash !== currentUrl.hash) {
|
||||
history.pushState(null, '', hash);
|
||||
// still emit the event so we can listen to it in themes
|
||||
window.dispatchEvent(new Event('hashchange'));
|
||||
}
|
||||
if (hash) {
|
||||
// use smooth scroll when clicking on header anchor links
|
||||
scrollTo(link, hash, link.classList.contains('header-anchor'));
|
||||
}
|
||||
else {
|
||||
updateHistory(href);
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
go(href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, { capture: true });
|
||||
window.addEventListener('popstate', (e) => {
|
||||
loadPage(normalizeHref(location.href), (e.state && e.state.scrollPosition) || 0);
|
||||
});
|
||||
window.addEventListener('hashchange', (e) => {
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
handleHMR(route);
|
||||
return router;
|
||||
}
|
||||
export function useRouter() {
|
||||
const router = inject(RouterSymbol);
|
||||
if (!router) {
|
||||
throw new Error('useRouter() is called without provider.');
|
||||
}
|
||||
return router;
|
||||
}
|
||||
export function useRoute() {
|
||||
return useRouter().route;
|
||||
}
|
||||
export function scrollTo(el, hash, smooth = false) {
|
||||
let target = null;
|
||||
try {
|
||||
target = el.classList.contains('header-anchor')
|
||||
? el
|
||||
: document.getElementById(decodeURIComponent(hash).slice(1));
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
if (target) {
|
||||
let scrollOffset = siteDataRef.value.scrollOffset;
|
||||
let offset = 0;
|
||||
let padding = 24;
|
||||
if (typeof scrollOffset === 'object' && 'padding' in scrollOffset) {
|
||||
padding = scrollOffset.padding;
|
||||
scrollOffset = scrollOffset.selector;
|
||||
}
|
||||
if (typeof scrollOffset === 'number') {
|
||||
offset = scrollOffset;
|
||||
}
|
||||
else if (typeof scrollOffset === 'string') {
|
||||
offset = tryOffsetSelector(scrollOffset, padding);
|
||||
}
|
||||
else if (Array.isArray(scrollOffset)) {
|
||||
for (const selector of scrollOffset) {
|
||||
const res = tryOffsetSelector(selector, padding);
|
||||
if (res) {
|
||||
offset = res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const targetPadding = parseInt(window.getComputedStyle(target).paddingTop, 10);
|
||||
const targetTop = window.scrollY +
|
||||
target.getBoundingClientRect().top -
|
||||
offset +
|
||||
targetPadding;
|
||||
function scrollToTarget() {
|
||||
// only smooth scroll if distance is smaller than screen height.
|
||||
if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight)
|
||||
window.scrollTo(0, targetTop);
|
||||
else
|
||||
window.scrollTo({ left: 0, top: targetTop, behavior: 'smooth' });
|
||||
}
|
||||
requestAnimationFrame(scrollToTarget);
|
||||
}
|
||||
}
|
||||
function tryOffsetSelector(selector, padding) {
|
||||
const el = document.querySelector(selector);
|
||||
if (!el)
|
||||
return 0;
|
||||
const bot = el.getBoundingClientRect().bottom;
|
||||
if (bot < 0)
|
||||
return 0;
|
||||
return bot + padding;
|
||||
}
|
||||
function handleHMR(route) {
|
||||
// update route.data on HMR updates of active page
|
||||
if (import.meta.hot) {
|
||||
// hot reload pageData
|
||||
import.meta.hot.on('vitepress:pageData', (payload) => {
|
||||
if (shouldHotReload(payload)) {
|
||||
route.data = payload.pageData;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
function shouldHotReload(payload) {
|
||||
const payloadPath = payload.path.replace(/(?:(^|\/)index)?\.md$/, '$1');
|
||||
const locationPath = location.pathname
|
||||
.replace(/(?:(^|\/)index)?\.html$/, '')
|
||||
.slice(siteDataRef.value.base.length - 1);
|
||||
return payloadPath === locationPath;
|
||||
}
|
||||
function updateHistory(href) {
|
||||
if (inBrowser && href !== normalizeHref(location.href)) {
|
||||
// save scroll position before changing url
|
||||
history.replaceState({ scrollPosition: window.scrollY }, document.title);
|
||||
history.pushState(null, '', href);
|
||||
}
|
||||
}
|
||||
function normalizeHref(href) {
|
||||
const url = new URL(href, fakeHost);
|
||||
url.pathname = url.pathname.replace(/(^|\/)index(\.html)?$/, '$1');
|
||||
// ensure correct deep link so page refresh lands on correct files.
|
||||
if (siteDataRef.value.cleanUrls)
|
||||
url.pathname = url.pathname.replace(/\.html$/, '');
|
||||
else if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html'))
|
||||
url.pathname += '.html';
|
||||
return url.pathname + url.search + url.hash;
|
||||
}
|
||||
10
node_modules/vitepress/dist/client/app/ssr.js
generated
vendored
10
node_modules/vitepress/dist/client/app/ssr.js
generated
vendored
@@ -1,10 +0,0 @@
|
||||
// entry for SSR
|
||||
import { createApp } from './index';
|
||||
import { renderToString } from 'vue/server-renderer';
|
||||
export async function render(path) {
|
||||
const { app, router } = await createApp();
|
||||
await router.go(path);
|
||||
const ctx = { content: '' };
|
||||
ctx.content = await renderToString(app, ctx);
|
||||
return ctx;
|
||||
}
|
||||
1
node_modules/vitepress/dist/client/app/theme.js
generated
vendored
1
node_modules/vitepress/dist/client/app/theme.js
generated
vendored
@@ -1 +0,0 @@
|
||||
export {};
|
||||
85
node_modules/vitepress/dist/client/app/utils.js
generated
vendored
85
node_modules/vitepress/dist/client/app/utils.js
generated
vendored
@@ -1,85 +0,0 @@
|
||||
import { siteDataRef } from './data';
|
||||
import { inBrowser, EXTERNAL_URL_RE, sanitizeFileName } from '../shared';
|
||||
import { h, onMounted, onUnmounted, shallowRef } from 'vue';
|
||||
export { inBrowser } from '../shared';
|
||||
/**
|
||||
* Join two paths by resolving the slash collision.
|
||||
*/
|
||||
export function joinPath(base, path) {
|
||||
return `${base}${path}`.replace(/\/+/g, '/');
|
||||
}
|
||||
/**
|
||||
* Append base to internal (non-relative) urls
|
||||
*/
|
||||
export function withBase(path) {
|
||||
return EXTERNAL_URL_RE.test(path) || !path.startsWith('/')
|
||||
? path
|
||||
: joinPath(siteDataRef.value.base, path);
|
||||
}
|
||||
/**
|
||||
* Converts a url path to the corresponding js chunk filename.
|
||||
*/
|
||||
export function pathToFile(path) {
|
||||
let pagePath = path.replace(/\.html$/, '');
|
||||
pagePath = decodeURIComponent(pagePath);
|
||||
pagePath = pagePath.replace(/\/$/, '/index'); // /foo/ -> /foo/index
|
||||
if (import.meta.env.DEV) {
|
||||
// always force re-fetch content in dev
|
||||
pagePath += `.md?t=${Date.now()}`;
|
||||
}
|
||||
else {
|
||||
// in production, each .md file is built into a .md.js file following
|
||||
// the path conversion scheme.
|
||||
// /foo/bar.html -> ./foo_bar.md
|
||||
if (inBrowser) {
|
||||
const base = import.meta.env.BASE_URL;
|
||||
pagePath =
|
||||
sanitizeFileName(pagePath.slice(base.length).replace(/\//g, '_') || 'index') + '.md';
|
||||
// client production build needs to account for page hash, which is
|
||||
// injected directly in the page's html
|
||||
let pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()];
|
||||
if (!pageHash) {
|
||||
pagePath = pagePath.endsWith('_index.md')
|
||||
? pagePath.slice(0, -9) + '.md'
|
||||
: pagePath.slice(0, -3) + '_index.md';
|
||||
pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()];
|
||||
}
|
||||
if (!pageHash)
|
||||
return null;
|
||||
pagePath = `${base}${__ASSETS_DIR__}/${pagePath}.${pageHash}.js`;
|
||||
}
|
||||
else {
|
||||
// ssr build uses much simpler name mapping
|
||||
pagePath = `./${sanitizeFileName(pagePath.slice(1).replace(/\//g, '_'))}.md.js`;
|
||||
}
|
||||
}
|
||||
return pagePath;
|
||||
}
|
||||
export let contentUpdatedCallbacks = [];
|
||||
/**
|
||||
* Register callback that is called every time the markdown content is updated
|
||||
* in the DOM.
|
||||
*/
|
||||
export function onContentUpdated(fn) {
|
||||
contentUpdatedCallbacks.push(fn);
|
||||
onUnmounted(() => {
|
||||
contentUpdatedCallbacks = contentUpdatedCallbacks.filter((f) => f !== fn);
|
||||
});
|
||||
}
|
||||
export function defineClientComponent(loader, args, cb) {
|
||||
return {
|
||||
setup() {
|
||||
const comp = shallowRef();
|
||||
onMounted(async () => {
|
||||
let res = await loader();
|
||||
// interop module default
|
||||
if (res && (res.__esModule || res[Symbol.toStringTag] === 'Module')) {
|
||||
res = res.default;
|
||||
}
|
||||
comp.value = res;
|
||||
await cb?.();
|
||||
});
|
||||
return () => (comp.value ? h(comp.value, ...(args ?? [])) : null);
|
||||
}
|
||||
};
|
||||
}
|
||||
120
node_modules/vitepress/dist/client/index.d.ts
generated
vendored
120
node_modules/vitepress/dist/client/index.d.ts
generated
vendored
@@ -1,120 +0,0 @@
|
||||
import * as vue from 'vue';
|
||||
import { Component, InjectionKey, Ref, App, AsyncComponentLoader } from 'vue';
|
||||
import { PageData, Awaitable, SiteData } from '../../types/shared.js';
|
||||
export { HeadConfig, Header, PageData, SiteData } from '../../types/shared.js';
|
||||
|
||||
declare const inBrowser: boolean;
|
||||
|
||||
interface Route {
|
||||
path: string;
|
||||
data: PageData;
|
||||
component: Component | null;
|
||||
}
|
||||
interface Router {
|
||||
/**
|
||||
* Current route.
|
||||
*/
|
||||
route: Route;
|
||||
/**
|
||||
* Navigate to a new URL.
|
||||
*/
|
||||
go: (to?: string) => Promise<void>;
|
||||
/**
|
||||
* Called before the route changes. Return `false` to cancel the navigation.
|
||||
*/
|
||||
onBeforeRouteChange?: (to: string) => Awaitable<void | boolean>;
|
||||
/**
|
||||
* Called before the page component is loaded (after the history state is
|
||||
* updated). Return `false` to cancel the navigation.
|
||||
*/
|
||||
onBeforePageLoad?: (to: string) => Awaitable<void | boolean>;
|
||||
/**
|
||||
* Called after the route changes.
|
||||
*/
|
||||
onAfterRouteChanged?: (to: string) => Awaitable<void>;
|
||||
}
|
||||
declare function useRouter(): Router;
|
||||
declare function useRoute(): Route;
|
||||
|
||||
declare const dataSymbol: InjectionKey<VitePressData>;
|
||||
interface VitePressData<T = any> {
|
||||
/**
|
||||
* Site-level metadata
|
||||
*/
|
||||
site: Ref<SiteData<T>>;
|
||||
/**
|
||||
* themeConfig from .vitepress/config.js
|
||||
*/
|
||||
theme: Ref<T>;
|
||||
/**
|
||||
* Page-level metadata
|
||||
*/
|
||||
page: Ref<PageData>;
|
||||
/**
|
||||
* page frontmatter data
|
||||
*/
|
||||
frontmatter: Ref<PageData['frontmatter']>;
|
||||
/**
|
||||
* dynamic route params
|
||||
*/
|
||||
params: Ref<PageData['params']>;
|
||||
title: Ref<string>;
|
||||
description: Ref<string>;
|
||||
lang: Ref<string>;
|
||||
isDark: Ref<boolean>;
|
||||
dir: Ref<string>;
|
||||
localeIndex: Ref<string>;
|
||||
}
|
||||
declare function useData<T = any>(): VitePressData<T>;
|
||||
|
||||
interface EnhanceAppContext {
|
||||
app: App;
|
||||
router: Router;
|
||||
siteData: Ref<SiteData>;
|
||||
}
|
||||
interface Theme {
|
||||
Layout?: Component;
|
||||
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>;
|
||||
extends?: Theme;
|
||||
/**
|
||||
* @deprecated can be replaced by wrapping layout component
|
||||
*/
|
||||
setup?: () => void;
|
||||
/**
|
||||
* @deprecated Render not found page by checking `useData().page.value.isNotFound` in Layout instead.
|
||||
*/
|
||||
NotFound?: Component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append base to internal (non-relative) urls
|
||||
*/
|
||||
declare function withBase(path: string): string;
|
||||
/**
|
||||
* Register callback that is called every time the markdown content is updated
|
||||
* in the DOM.
|
||||
*/
|
||||
declare function onContentUpdated(fn: () => any): void;
|
||||
declare function defineClientComponent(loader: AsyncComponentLoader, args?: any[], cb?: () => Awaitable<void>): {
|
||||
setup(): () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
||||
[key: string]: any;
|
||||
}> | null;
|
||||
};
|
||||
|
||||
declare const Content: vue.DefineComponent<{
|
||||
as: {
|
||||
type: (ObjectConstructor | StringConstructor)[];
|
||||
default: string;
|
||||
};
|
||||
}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
||||
[key: string]: any;
|
||||
}>, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly<vue.ExtractPropTypes<{
|
||||
as: {
|
||||
type: (ObjectConstructor | StringConstructor)[];
|
||||
default: string;
|
||||
};
|
||||
}>>, {
|
||||
as: string | Record<string, any>;
|
||||
}, {}>;
|
||||
|
||||
export { Content, type EnhanceAppContext, type Route, type Router, type Theme, type VitePressData, dataSymbol, defineClientComponent, inBrowser, onContentUpdated, useData, useRoute, useRouter, withBase };
|
||||
9
node_modules/vitepress/dist/client/index.js
generated
vendored
9
node_modules/vitepress/dist/client/index.js
generated
vendored
@@ -1,9 +0,0 @@
|
||||
// exports in this file are exposed to themes and md files via 'vitepress'
|
||||
// so the user can do `import { useRoute, useData } from 'vitepress'`
|
||||
// composables
|
||||
export { useData, dataSymbol } from './app/data';
|
||||
export { useRoute, useRouter } from './app/router';
|
||||
// utilities
|
||||
export { inBrowser, onContentUpdated, defineClientComponent, withBase } from './app/utils';
|
||||
// components
|
||||
export { Content } from './app/components/Content';
|
||||
110
node_modules/vitepress/dist/client/shared.js
generated
vendored
110
node_modules/vitepress/dist/client/shared.js
generated
vendored
@@ -1,110 +0,0 @@
|
||||
export const EXTERNAL_URL_RE = /^[a-z]+:/i;
|
||||
export const APPEARANCE_KEY = 'vitepress-theme-appearance';
|
||||
export const HASH_RE = /#.*$/;
|
||||
export const EXT_RE = /(index)?\.(md|html)$/;
|
||||
export const inBrowser = typeof document !== 'undefined';
|
||||
export const notFoundPageData = {
|
||||
relativePath: '',
|
||||
filePath: '',
|
||||
title: '404',
|
||||
description: 'Not Found',
|
||||
headers: [],
|
||||
frontmatter: { sidebar: false, layout: 'page' },
|
||||
lastUpdated: 0,
|
||||
isNotFound: true
|
||||
};
|
||||
export function isActive(currentPath, matchPath, asRegex = false) {
|
||||
if (matchPath === undefined) {
|
||||
return false;
|
||||
}
|
||||
currentPath = normalize(`/${currentPath}`);
|
||||
if (asRegex) {
|
||||
return new RegExp(matchPath).test(currentPath);
|
||||
}
|
||||
if (normalize(matchPath) !== currentPath) {
|
||||
return false;
|
||||
}
|
||||
const hashMatch = matchPath.match(HASH_RE);
|
||||
if (hashMatch) {
|
||||
return (inBrowser ? location.hash : '') === hashMatch[0];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export function normalize(path) {
|
||||
return decodeURI(path).replace(HASH_RE, '').replace(EXT_RE, '');
|
||||
}
|
||||
export function isExternal(path) {
|
||||
return EXTERNAL_URL_RE.test(path);
|
||||
}
|
||||
/**
|
||||
* this merges the locales data to the main data by the route
|
||||
*/
|
||||
export function resolveSiteDataByRoute(siteData, relativePath) {
|
||||
const localeIndex = Object.keys(siteData.locales).find((key) => key !== 'root' &&
|
||||
!isExternal(key) &&
|
||||
isActive(relativePath, `/${key}/`, true)) || 'root';
|
||||
return Object.assign({}, siteData, {
|
||||
localeIndex,
|
||||
lang: siteData.locales[localeIndex]?.lang ?? siteData.lang,
|
||||
dir: siteData.locales[localeIndex]?.dir ?? siteData.dir,
|
||||
title: siteData.locales[localeIndex]?.title ?? siteData.title,
|
||||
titleTemplate: siteData.locales[localeIndex]?.titleTemplate ?? siteData.titleTemplate,
|
||||
description: siteData.locales[localeIndex]?.description ?? siteData.description,
|
||||
head: mergeHead(siteData.head, siteData.locales[localeIndex]?.head ?? []),
|
||||
themeConfig: {
|
||||
...siteData.themeConfig,
|
||||
...siteData.locales[localeIndex]?.themeConfig
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Create the page title string based on config.
|
||||
*/
|
||||
export function createTitle(siteData, pageData) {
|
||||
const title = pageData.title || siteData.title;
|
||||
const template = pageData.titleTemplate ?? siteData.titleTemplate;
|
||||
if (typeof template === 'string' && template.includes(':title')) {
|
||||
return template.replace(/:title/g, title);
|
||||
}
|
||||
const templateString = createTitleTemplate(siteData.title, template);
|
||||
return `${title}${templateString}`;
|
||||
}
|
||||
function createTitleTemplate(siteTitle, template) {
|
||||
if (template === false) {
|
||||
return '';
|
||||
}
|
||||
if (template === true || template === undefined) {
|
||||
return ` | ${siteTitle}`;
|
||||
}
|
||||
if (siteTitle === template) {
|
||||
return '';
|
||||
}
|
||||
return ` | ${template}`;
|
||||
}
|
||||
function hasTag(head, tag) {
|
||||
const [tagType, tagAttrs] = tag;
|
||||
if (tagType !== 'meta')
|
||||
return false;
|
||||
const keyAttr = Object.entries(tagAttrs)[0]; // First key
|
||||
if (keyAttr == null)
|
||||
return false;
|
||||
return head.some(([type, attrs]) => type === tagType && attrs[keyAttr[0]] === keyAttr[1]);
|
||||
}
|
||||
export function mergeHead(prev, curr) {
|
||||
return [...prev.filter((tagAttrs) => !hasTag(curr, tagAttrs)), ...curr];
|
||||
}
|
||||
// https://github.com/rollup/rollup/blob/fec513270c6ac350072425cc045db367656c623b/src/utils/sanitizeFileName.ts
|
||||
const INVALID_CHAR_REGEX = /[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g;
|
||||
const DRIVE_LETTER_REGEX = /^[a-z]:/i;
|
||||
export function sanitizeFileName(name) {
|
||||
const match = DRIVE_LETTER_REGEX.exec(name);
|
||||
const driveLetter = match ? match[0] : '';
|
||||
return (driveLetter +
|
||||
name
|
||||
.slice(driveLetter.length)
|
||||
.replace(INVALID_CHAR_REGEX, '_')
|
||||
.replace(/(^|\/)_+(?=[^/]*$)/, '$1'));
|
||||
}
|
||||
export function slash(p) {
|
||||
return p.replace(/\\/g, '/');
|
||||
}
|
||||
91
node_modules/vitepress/dist/client/theme-default/Layout.vue
generated
vendored
91
node_modules/vitepress/dist/client/theme-default/Layout.vue
generated
vendored
@@ -1,91 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vitepress'
|
||||
import { computed, provide, useSlots, watch } from 'vue'
|
||||
import VPBackdrop from './components/VPBackdrop.vue'
|
||||
import VPContent from './components/VPContent.vue'
|
||||
import VPFooter from './components/VPFooter.vue'
|
||||
import VPLocalNav from './components/VPLocalNav.vue'
|
||||
import VPNav from './components/VPNav.vue'
|
||||
import VPSidebar from './components/VPSidebar.vue'
|
||||
import VPSkipLink from './components/VPSkipLink.vue'
|
||||
import { useData } from './composables/data'
|
||||
import { useCloseSidebarOnEscape, useSidebar } from './composables/sidebar'
|
||||
|
||||
const {
|
||||
isOpen: isSidebarOpen,
|
||||
open: openSidebar,
|
||||
close: closeSidebar
|
||||
} = useSidebar()
|
||||
|
||||
const route = useRoute()
|
||||
watch(() => route.path, closeSidebar)
|
||||
|
||||
useCloseSidebarOnEscape(isSidebarOpen, closeSidebar)
|
||||
|
||||
const { frontmatter } = useData()
|
||||
|
||||
const slots = useSlots()
|
||||
const heroImageSlotExists = computed(() => !!slots['home-hero-image'])
|
||||
|
||||
provide('hero-image-slot-exists', heroImageSlotExists)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="frontmatter.layout !== false" class="Layout" :class="frontmatter.pageClass" >
|
||||
<slot name="layout-top" />
|
||||
<VPSkipLink />
|
||||
<VPBackdrop class="backdrop" :show="isSidebarOpen" @click="closeSidebar" />
|
||||
<VPNav>
|
||||
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
|
||||
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>
|
||||
<template #nav-bar-content-before><slot name="nav-bar-content-before" /></template>
|
||||
<template #nav-bar-content-after><slot name="nav-bar-content-after" /></template>
|
||||
<template #nav-screen-content-before><slot name="nav-screen-content-before" /></template>
|
||||
<template #nav-screen-content-after><slot name="nav-screen-content-after" /></template>
|
||||
</VPNav>
|
||||
<VPLocalNav :open="isSidebarOpen" @open-menu="openSidebar" />
|
||||
|
||||
<VPSidebar :open="isSidebarOpen">
|
||||
<template #sidebar-nav-before><slot name="sidebar-nav-before" /></template>
|
||||
<template #sidebar-nav-after><slot name="sidebar-nav-after" /></template>
|
||||
</VPSidebar>
|
||||
|
||||
<VPContent>
|
||||
<template #page-top><slot name="page-top" /></template>
|
||||
<template #page-bottom><slot name="page-bottom" /></template>
|
||||
|
||||
<template #not-found><slot name="not-found" /></template>
|
||||
<template #home-hero-before><slot name="home-hero-before" /></template>
|
||||
<template #home-hero-info><slot name="home-hero-info" /></template>
|
||||
<template #home-hero-image><slot name="home-hero-image" /></template>
|
||||
<template #home-hero-after><slot name="home-hero-after" /></template>
|
||||
<template #home-features-before><slot name="home-features-before" /></template>
|
||||
<template #home-features-after><slot name="home-features-after" /></template>
|
||||
|
||||
<template #doc-footer-before><slot name="doc-footer-before" /></template>
|
||||
<template #doc-before><slot name="doc-before" /></template>
|
||||
<template #doc-after><slot name="doc-after" /></template>
|
||||
<template #doc-top><slot name="doc-top" /></template>
|
||||
<template #doc-bottom><slot name="doc-bottom" /></template>
|
||||
|
||||
<template #aside-top><slot name="aside-top" /></template>
|
||||
<template #aside-bottom><slot name="aside-bottom" /></template>
|
||||
<template #aside-outline-before><slot name="aside-outline-before" /></template>
|
||||
<template #aside-outline-after><slot name="aside-outline-after" /></template>
|
||||
<template #aside-ads-before><slot name="aside-ads-before" /></template>
|
||||
<template #aside-ads-after><slot name="aside-ads-after" /></template>
|
||||
</VPContent>
|
||||
|
||||
<VPFooter />
|
||||
<slot name="layout-bottom" />
|
||||
</div>
|
||||
<Content v-else />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.Layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
}
|
||||
</style>
|
||||
109
node_modules/vitepress/dist/client/theme-default/NotFound.vue
generated
vendored
109
node_modules/vitepress/dist/client/theme-default/NotFound.vue
generated
vendored
@@ -1,109 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { withBase } from 'vitepress'
|
||||
import { useData } from './composables/data'
|
||||
import { useLangs } from './composables/langs'
|
||||
|
||||
const { site, theme } = useData()
|
||||
const { localeLinks } = useLangs({ removeCurrent: false })
|
||||
|
||||
const root = ref('/')
|
||||
onMounted(() => {
|
||||
const path = window.location.pathname
|
||||
.replace(site.value.base, '')
|
||||
.replace(/(^.*?\/).*$/, '/$1')
|
||||
if (localeLinks.value.length) {
|
||||
root.value =
|
||||
localeLinks.value.find(({ link }) => link.startsWith(path))?.link ||
|
||||
localeLinks.value[0].link
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="NotFound">
|
||||
<p class="code">{{ theme.notFound?.code ?? '404' }}</p>
|
||||
<h1 class="title">{{ theme.notFound?.title ?? 'PAGE NOT FOUND' }}</h1>
|
||||
<div class="divider" />
|
||||
<blockquote class="quote">
|
||||
{{
|
||||
theme.notFound?.quote ??
|
||||
"But if you don't change your direction, and if you keep looking, you may end up where you are heading."
|
||||
}}
|
||||
</blockquote>
|
||||
|
||||
<div class="action">
|
||||
<a
|
||||
class="link"
|
||||
:href="withBase(root)"
|
||||
:aria-label="theme.notFound?.linkLabel ?? 'go to home'"
|
||||
>
|
||||
{{ theme.notFound?.linkText ?? 'Take me home' }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.NotFound {
|
||||
padding: 64px 24px 96px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.NotFound {
|
||||
padding: 96px 32px 168px;
|
||||
}
|
||||
}
|
||||
|
||||
.code {
|
||||
line-height: 64px;
|
||||
font-size: 64px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.title {
|
||||
padding-top: 12px;
|
||||
letter-spacing: 2px;
|
||||
line-height: 20px;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 24px auto 18px;
|
||||
width: 64px;
|
||||
height: 1px;
|
||||
background-color: var(--vp-c-divider);
|
||||
}
|
||||
|
||||
.quote {
|
||||
margin: 0 auto;
|
||||
max-width: 256px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.action {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.link {
|
||||
display: inline-block;
|
||||
border: 1px solid var(--vp-c-brand-1);
|
||||
border-radius: 16px;
|
||||
padding: 3px 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-brand-1);
|
||||
transition:
|
||||
border-color 0.25s,
|
||||
color 0.25s;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
border-color: var(--vp-c-brand-2);
|
||||
color: var(--vp-c-brand-2);
|
||||
}
|
||||
</style>
|
||||
100
node_modules/vitepress/dist/client/theme-default/components/VPAlgoliaSearchBox.vue
generated
vendored
100
node_modules/vitepress/dist/client/theme-default/components/VPAlgoliaSearchBox.vue
generated
vendored
@@ -1,100 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import docsearch from '@docsearch/js'
|
||||
import { onMounted, watch } from 'vue'
|
||||
import { useRouter, useRoute } from 'vitepress'
|
||||
import { useData } from '../composables/data'
|
||||
|
||||
const props = defineProps<{
|
||||
algolia: DefaultTheme.AlgoliaSearchOptions
|
||||
}>()
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const { site, localeIndex, lang } = useData()
|
||||
|
||||
type DocSearchProps = Parameters<typeof docsearch>[0]
|
||||
|
||||
onMounted(update)
|
||||
watch(localeIndex, update)
|
||||
|
||||
function update() {
|
||||
const options = {
|
||||
...props.algolia,
|
||||
...props.algolia.locales?.[localeIndex.value]
|
||||
}
|
||||
const rawFacetFilters = options.searchParameters?.facetFilters ?? []
|
||||
const facetFilters = [
|
||||
...(Array.isArray(rawFacetFilters)
|
||||
? rawFacetFilters
|
||||
: [rawFacetFilters]
|
||||
).filter((f) => !f.startsWith('lang:')),
|
||||
`lang:${lang.value}`
|
||||
]
|
||||
initialize({
|
||||
...options,
|
||||
searchParameters: {
|
||||
...options.searchParameters,
|
||||
facetFilters
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
|
||||
const options = Object.assign<{}, {}, DocSearchProps>({}, userOptions, {
|
||||
container: '#docsearch',
|
||||
|
||||
navigator: {
|
||||
navigate({ itemUrl }) {
|
||||
const { pathname: hitPathname } = new URL(
|
||||
window.location.origin + itemUrl
|
||||
)
|
||||
|
||||
// router doesn't handle same-page navigation so we use the native
|
||||
// browser location API for anchor navigation
|
||||
if (route.path === hitPathname) {
|
||||
window.location.assign(window.location.origin + itemUrl)
|
||||
} else {
|
||||
router.go(itemUrl)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
transformItems(items) {
|
||||
return items.map((item) => {
|
||||
return Object.assign({}, item, {
|
||||
url: getRelativePath(item.url)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// @ts-expect-error vue-tsc thinks this should return Vue JSX but it returns the required React one
|
||||
hitComponent({ hit, children }) {
|
||||
return {
|
||||
__v: null,
|
||||
type: 'a',
|
||||
ref: undefined,
|
||||
constructor: undefined,
|
||||
key: undefined,
|
||||
props: { href: hit.url, children }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
docsearch(options)
|
||||
}
|
||||
|
||||
function getRelativePath(url: string) {
|
||||
const { pathname, hash } = new URL(url, location.origin)
|
||||
return (
|
||||
pathname.replace(
|
||||
/\.html$/,
|
||||
site.value.cleanUrls ? '' : '.html'
|
||||
) + hash
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="docsearch" />
|
||||
</template>
|
||||
41
node_modules/vitepress/dist/client/theme-default/components/VPBackdrop.vue
generated
vendored
41
node_modules/vitepress/dist/client/theme-default/components/VPBackdrop.vue
generated
vendored
@@ -1,41 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
show: boolean
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition name="fade">
|
||||
<div v-if="show" class="VPBackdrop" />
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPBackdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
/*rtl:ignore*/
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/*rtl:ignore*/
|
||||
left: 0;
|
||||
z-index: var(--vp-z-index-backdrop);
|
||||
background: var(--vp-backdrop-bg-color);
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
|
||||
.VPBackdrop.fade-enter-from,
|
||||
.VPBackdrop.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.VPBackdrop.fade-leave-active {
|
||||
transition-duration: .25s;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.VPBackdrop {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
75
node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue
generated
vendored
75
node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue
generated
vendored
@@ -1,75 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
text?: string
|
||||
type?: 'info' | 'tip' | 'warning' | 'danger'
|
||||
}
|
||||
withDefaults(defineProps<Props>(), {
|
||||
type: 'tip'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="VPBadge" :class="type">
|
||||
<slot>{{ text }}</slot>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPBadge {
|
||||
display: inline-block;
|
||||
margin-left: 2px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 12px;
|
||||
padding: 0 10px;
|
||||
line-height: 22px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.vp-doc h1 > .VPBadge {
|
||||
margin-top: 4px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.vp-doc h2 > .VPBadge {
|
||||
margin-top: 3px;
|
||||
padding: 0 8px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.vp-doc h3 > .VPBadge {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.vp-doc h4 > .VPBadge,
|
||||
.vp-doc h5 > .VPBadge,
|
||||
.vp-doc h6 > .VPBadge {
|
||||
vertical-align: middle;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.VPBadge.info {
|
||||
border-color: var(--vp-badge-info-border);
|
||||
color: var(--vp-badge-info-text);
|
||||
background-color: var(--vp-badge-info-bg);
|
||||
}
|
||||
|
||||
.VPBadge.tip {
|
||||
border-color: var(--vp-badge-tip-border);
|
||||
color: var(--vp-badge-tip-text);
|
||||
background-color: var(--vp-badge-tip-bg);
|
||||
}
|
||||
|
||||
.VPBadge.warning {
|
||||
border-color: var(--vp-badge-warning-border);
|
||||
color: var(--vp-badge-warning-text);
|
||||
background-color: var(--vp-badge-warning-bg);
|
||||
}
|
||||
|
||||
.VPBadge.danger {
|
||||
border-color: var(--vp-badge-danger-border);
|
||||
color: var(--vp-badge-danger-text);
|
||||
background-color: var(--vp-badge-danger-bg);
|
||||
}
|
||||
</style>
|
||||
121
node_modules/vitepress/dist/client/theme-default/components/VPButton.vue
generated
vendored
121
node_modules/vitepress/dist/client/theme-default/components/VPButton.vue
generated
vendored
@@ -1,121 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { normalizeLink } from '../support/utils'
|
||||
import { EXTERNAL_URL_RE } from '../../shared'
|
||||
|
||||
interface Props {
|
||||
tag?: string
|
||||
size?: 'medium' | 'big'
|
||||
theme?: 'brand' | 'alt' | 'sponsor'
|
||||
text: string
|
||||
href?: string
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
size: 'medium',
|
||||
theme: 'brand'
|
||||
})
|
||||
|
||||
const isExternal = computed(
|
||||
() => props.href && EXTERNAL_URL_RE.test(props.href)
|
||||
)
|
||||
|
||||
const component = computed(() => {
|
||||
return props.tag || props.href ? 'a' : 'button'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="component"
|
||||
class="VPButton"
|
||||
:class="[size, theme]"
|
||||
:href="href ? normalizeLink(href) : undefined"
|
||||
:target="isExternal ? '_blank' : undefined"
|
||||
:rel="isExternal ? 'noreferrer' : undefined"
|
||||
>
|
||||
{{ text }}
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPButton {
|
||||
display: inline-block;
|
||||
border: 1px solid transparent;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
transition: color 0.25s, border-color 0.25s, background-color 0.25s;
|
||||
}
|
||||
|
||||
.VPButton:active {
|
||||
transition: color 0.1s, border-color 0.1s, background-color 0.1s;
|
||||
}
|
||||
|
||||
.VPButton.medium {
|
||||
border-radius: 20px;
|
||||
padding: 0 20px;
|
||||
line-height: 38px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.VPButton.big {
|
||||
border-radius: 24px;
|
||||
padding: 0 24px;
|
||||
line-height: 46px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.VPButton.brand {
|
||||
border-color: var(--vp-button-brand-border);
|
||||
color: var(--vp-button-brand-text);
|
||||
background-color: var(--vp-button-brand-bg);
|
||||
}
|
||||
|
||||
.VPButton.brand:hover {
|
||||
border-color: var(--vp-button-brand-hover-border);
|
||||
color: var(--vp-button-brand-hover-text);
|
||||
background-color: var(--vp-button-brand-hover-bg);
|
||||
}
|
||||
|
||||
.VPButton.brand:active {
|
||||
border-color: var(--vp-button-brand-active-border);
|
||||
color: var(--vp-button-brand-active-text);
|
||||
background-color: var(--vp-button-brand-active-bg);
|
||||
}
|
||||
|
||||
.VPButton.alt {
|
||||
border-color: var(--vp-button-alt-border);
|
||||
color: var(--vp-button-alt-text);
|
||||
background-color: var(--vp-button-alt-bg);
|
||||
}
|
||||
|
||||
.VPButton.alt:hover {
|
||||
border-color: var(--vp-button-alt-hover-border);
|
||||
color: var(--vp-button-alt-hover-text);
|
||||
background-color: var(--vp-button-alt-hover-bg);
|
||||
}
|
||||
|
||||
.VPButton.alt:active {
|
||||
border-color: var(--vp-button-alt-active-border);
|
||||
color: var(--vp-button-alt-active-text);
|
||||
background-color: var(--vp-button-alt-active-bg);
|
||||
}
|
||||
|
||||
.VPButton.sponsor {
|
||||
border-color: var(--vp-button-sponsor-border);
|
||||
color: var(--vp-button-sponsor-text);
|
||||
background-color: var(--vp-button-sponsor-bg);
|
||||
}
|
||||
|
||||
.VPButton.sponsor:hover {
|
||||
border-color: var(--vp-button-sponsor-hover-border);
|
||||
color: var(--vp-button-sponsor-hover-text);
|
||||
background-color: var(--vp-button-sponsor-hover-bg);
|
||||
}
|
||||
|
||||
.VPButton.sponsor:active {
|
||||
border-color: var(--vp-button-sponsor-active-border);
|
||||
color: var(--vp-button-sponsor-active-text);
|
||||
background-color: var(--vp-button-sponsor-active-bg);
|
||||
}
|
||||
</style>
|
||||
109
node_modules/vitepress/dist/client/theme-default/components/VPCarbonAds.vue
generated
vendored
109
node_modules/vitepress/dist/client/theme-default/components/VPCarbonAds.vue
generated
vendored
@@ -1,109 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import { useAside } from '../composables/aside'
|
||||
import { useData } from '../composables/data'
|
||||
|
||||
const { page } = useData()
|
||||
const props = defineProps<{
|
||||
carbonAds: DefaultTheme.CarbonAdsOptions
|
||||
}>()
|
||||
|
||||
const carbonOptions = props.carbonAds
|
||||
|
||||
const { isAsideEnabled } = useAside()
|
||||
const container = ref()
|
||||
|
||||
let isInitialized = false
|
||||
|
||||
function init() {
|
||||
if (!isInitialized) {
|
||||
isInitialized = true
|
||||
const s = document.createElement('script')
|
||||
s.id = '_carbonads_js'
|
||||
s.src = `//cdn.carbonads.com/carbon.js?serve=${carbonOptions.code}&placement=${carbonOptions.placement}`
|
||||
s.async = true
|
||||
container.value.appendChild(s)
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => page.value.relativePath, () => {
|
||||
if (isInitialized && isAsideEnabled.value) {
|
||||
;(window as any)._carbonads?.refresh()
|
||||
}
|
||||
})
|
||||
|
||||
// no need to account for option changes during dev, we can just
|
||||
// refresh the page
|
||||
if (carbonOptions) {
|
||||
onMounted(() => {
|
||||
// if the page is loaded when aside is active, load carbon directly.
|
||||
// otherwise, only load it if the page resizes to wide enough. this avoids
|
||||
// loading carbon at all on mobile where it's never shown
|
||||
if (isAsideEnabled.value) {
|
||||
init()
|
||||
} else {
|
||||
watch(isAsideEnabled, (wide) => wide && init())
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPCarbonAds" ref="container" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPCarbonAds {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 24px;
|
||||
border-radius: 12px;
|
||||
min-height: 256px;
|
||||
text-align: center;
|
||||
line-height: 18px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
background-color: var(--vp-carbon-ads-bg-color);
|
||||
}
|
||||
|
||||
.VPCarbonAds :deep(img) {
|
||||
margin: 0 auto;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.VPCarbonAds :deep(.carbon-text) {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
padding-top: 12px;
|
||||
color: var(--vp-carbon-ads-text-color);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPCarbonAds :deep(.carbon-text:hover) {
|
||||
color: var(--vp-carbon-ads-hover-text-color);
|
||||
}
|
||||
|
||||
.VPCarbonAds :deep(.carbon-poweredby) {
|
||||
display: block;
|
||||
padding-top: 6px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-carbon-ads-poweredby-color);
|
||||
text-transform: uppercase;
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPCarbonAds :deep(.carbon-poweredby:hover) {
|
||||
color: var(--vp-carbon-ads-hover-poweredby-color);
|
||||
}
|
||||
|
||||
.VPCarbonAds :deep(> div) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.VPCarbonAds :deep(> div:first-of-type) {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
95
node_modules/vitepress/dist/client/theme-default/components/VPContent.vue
generated
vendored
95
node_modules/vitepress/dist/client/theme-default/components/VPContent.vue
generated
vendored
@@ -1,95 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import NotFound from '../NotFound.vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { useSidebar } from '../composables/sidebar'
|
||||
import VPDoc from './VPDoc.vue'
|
||||
import VPHome from './VPHome.vue'
|
||||
import VPPage from './VPPage.vue'
|
||||
|
||||
const { page, frontmatter } = useData()
|
||||
const { hasSidebar } = useSidebar()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="VPContent"
|
||||
id="VPContent"
|
||||
:class="{
|
||||
'has-sidebar': hasSidebar,
|
||||
'is-home': frontmatter.layout === 'home'
|
||||
}"
|
||||
>
|
||||
<slot name="not-found" v-if="page.isNotFound"><NotFound /></slot>
|
||||
|
||||
<VPPage v-else-if="frontmatter.layout === 'page'">
|
||||
<template #page-top><slot name="page-top" /></template>
|
||||
<template #page-bottom><slot name="page-bottom" /></template>
|
||||
</VPPage>
|
||||
|
||||
<VPHome v-else-if="frontmatter.layout === 'home'">
|
||||
<template #home-hero-before><slot name="home-hero-before" /></template>
|
||||
<template #home-hero-info><slot name="home-hero-info" /></template>
|
||||
<template #home-hero-image><slot name="home-hero-image" /></template>
|
||||
<template #home-hero-after><slot name="home-hero-after" /></template>
|
||||
<template #home-features-before><slot name="home-features-before" /></template>
|
||||
<template #home-features-after><slot name="home-features-after" /></template>
|
||||
</VPHome>
|
||||
|
||||
<component
|
||||
v-else-if="frontmatter.layout && frontmatter.layout !== 'doc'"
|
||||
:is="frontmatter.layout"
|
||||
/>
|
||||
|
||||
<VPDoc v-else>
|
||||
<template #doc-top><slot name="doc-top" /></template>
|
||||
<template #doc-bottom><slot name="doc-bottom" /></template>
|
||||
|
||||
<template #doc-footer-before><slot name="doc-footer-before" /></template>
|
||||
<template #doc-before><slot name="doc-before" /></template>
|
||||
<template #doc-after><slot name="doc-after" /></template>
|
||||
|
||||
<template #aside-top><slot name="aside-top" /></template>
|
||||
<template #aside-outline-before><slot name="aside-outline-before" /></template>
|
||||
<template #aside-outline-after><slot name="aside-outline-after" /></template>
|
||||
<template #aside-ads-before><slot name="aside-ads-before" /></template>
|
||||
<template #aside-ads-after><slot name="aside-ads-after" /></template>
|
||||
<template #aside-bottom><slot name="aside-bottom" /></template>
|
||||
</VPDoc>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPContent {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
margin: var(--vp-layout-top-height, 0px) auto 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.VPContent.is-home {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.VPContent.has-sidebar {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPContent {
|
||||
padding-top: var(--vp-nav-height);
|
||||
}
|
||||
|
||||
.VPContent.has-sidebar {
|
||||
margin: var(--vp-layout-top-height, 0px) 0 0;
|
||||
padding-left: var(--vp-sidebar-width);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.VPContent.has-sidebar {
|
||||
padding-right: calc((100vw - var(--vp-layout-max-width)) / 2);
|
||||
padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
210
node_modules/vitepress/dist/client/theme-default/components/VPDoc.vue
generated
vendored
210
node_modules/vitepress/dist/client/theme-default/components/VPDoc.vue
generated
vendored
@@ -1,210 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vitepress'
|
||||
import { computed } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { useSidebar } from '../composables/sidebar'
|
||||
import VPDocAside from './VPDocAside.vue'
|
||||
import VPDocFooter from './VPDocFooter.vue'
|
||||
import VPDocOutlineDropdown from './VPDocOutlineDropdown.vue'
|
||||
|
||||
const { theme } = useData()
|
||||
|
||||
const route = useRoute()
|
||||
const { hasSidebar, hasAside, leftAside } = useSidebar()
|
||||
|
||||
const pageName = computed(() =>
|
||||
route.path.replace(/[./]+/g, '_').replace(/_html$/, '')
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="VPDoc"
|
||||
:class="{ 'has-sidebar': hasSidebar, 'has-aside': hasAside }"
|
||||
>
|
||||
<slot name="doc-top" />
|
||||
<div class="container">
|
||||
<div v-if="hasAside" class="aside" :class="{'left-aside': leftAside}">
|
||||
<div class="aside-curtain" />
|
||||
<div class="aside-container">
|
||||
<div class="aside-content">
|
||||
<VPDocAside>
|
||||
<template #aside-top><slot name="aside-top" /></template>
|
||||
<template #aside-bottom><slot name="aside-bottom" /></template>
|
||||
<template #aside-outline-before><slot name="aside-outline-before" /></template>
|
||||
<template #aside-outline-after><slot name="aside-outline-after" /></template>
|
||||
<template #aside-ads-before><slot name="aside-ads-before" /></template>
|
||||
<template #aside-ads-after><slot name="aside-ads-after" /></template>
|
||||
</VPDocAside>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="content-container">
|
||||
<slot name="doc-before" />
|
||||
<VPDocOutlineDropdown />
|
||||
<main class="main">
|
||||
<Content
|
||||
class="vp-doc"
|
||||
:class="[
|
||||
pageName,
|
||||
theme.externalLinkIcon && 'external-link-icon-enabled'
|
||||
]"
|
||||
/>
|
||||
</main>
|
||||
<VPDocFooter>
|
||||
<template #doc-footer-before><slot name="doc-footer-before" /></template>
|
||||
</VPDocFooter>
|
||||
<slot name="doc-after" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<slot name="doc-bottom" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPDoc {
|
||||
padding: 32px 24px 96px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.VPDoc .VPDocOutlineDropdown {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) and (max-width: 1279px) {
|
||||
.VPDoc .VPDocOutlineDropdown {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPDoc {
|
||||
padding: 48px 32px 128px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPDoc {
|
||||
padding: 32px 32px 0;
|
||||
}
|
||||
|
||||
.VPDoc:not(.has-sidebar) .container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
max-width: 992px;
|
||||
}
|
||||
|
||||
.VPDoc:not(.has-sidebar) .content {
|
||||
max-width: 752px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.VPDoc .container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.VPDoc .aside {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.VPDoc:not(.has-sidebar) .content {
|
||||
max-width: 784px;
|
||||
}
|
||||
|
||||
.VPDoc:not(.has-sidebar) .container {
|
||||
max-width: 1104px;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.aside {
|
||||
position: relative;
|
||||
display: none;
|
||||
order: 2;
|
||||
flex-grow: 1;
|
||||
padding-left: 32px;
|
||||
width: 100%;
|
||||
max-width: 256px;
|
||||
}
|
||||
|
||||
.left-aside {
|
||||
order: 1;
|
||||
padding-left: unset;
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
.aside-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
padding-top: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 32px);
|
||||
width: 224px;
|
||||
height: 100vh;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.aside-container::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.aside-curtain {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
width: 224px;
|
||||
height: 32px;
|
||||
background: linear-gradient(transparent, var(--vp-c-bg) 70%);
|
||||
}
|
||||
|
||||
.aside-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 32px));
|
||||
padding-bottom: 32px;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.content {
|
||||
padding: 0 32px 128px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.content {
|
||||
order: 1;
|
||||
margin: 0;
|
||||
min-width: 640px;
|
||||
}
|
||||
}
|
||||
|
||||
.content-container {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.VPDoc.has-aside .content-container {
|
||||
max-width: 688px;
|
||||
}
|
||||
|
||||
.external-link-icon-enabled :is(.vp-doc a[href*='://'], .vp-doc a[target='_blank'])::after {
|
||||
content: '';
|
||||
color: currentColor;
|
||||
}
|
||||
</style>
|
||||
46
node_modules/vitepress/dist/client/theme-default/components/VPDocAside.vue
generated
vendored
46
node_modules/vitepress/dist/client/theme-default/components/VPDocAside.vue
generated
vendored
@@ -1,46 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useData } from '../composables/data'
|
||||
import VPDocAsideOutline from './VPDocAsideOutline.vue'
|
||||
import VPDocAsideCarbonAds from './VPDocAsideCarbonAds.vue'
|
||||
|
||||
const { theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPDocAside">
|
||||
<slot name="aside-top" />
|
||||
|
||||
<slot name="aside-outline-before" />
|
||||
<VPDocAsideOutline />
|
||||
<slot name="aside-outline-after" />
|
||||
|
||||
<div class="spacer" />
|
||||
|
||||
<slot name="aside-ads-before" />
|
||||
<VPDocAsideCarbonAds v-if="theme.carbonAds" :carbon-ads="theme.carbonAds" />
|
||||
<slot name="aside-ads-after" />
|
||||
|
||||
<slot name="aside-bottom" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPDocAside {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.VPDocAside :deep(.spacer + .VPDocAsideSponsors),
|
||||
.VPDocAside :deep(.spacer + .VPDocAsideCarbonAds) {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.VPDocAside :deep(.VPDocAsideSponsors + .VPDocAsideCarbonAds) {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
18
node_modules/vitepress/dist/client/theme-default/components/VPDocAsideCarbonAds.vue
generated
vendored
18
node_modules/vitepress/dist/client/theme-default/components/VPDocAsideCarbonAds.vue
generated
vendored
@@ -1,18 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
|
||||
defineProps<{
|
||||
carbonAds: DefaultTheme.CarbonAdsOptions
|
||||
}>()
|
||||
|
||||
const VPCarbonAds = __CARBON__
|
||||
? defineAsyncComponent(() => import('./VPCarbonAds.vue'))
|
||||
: () => null
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPDocAsideCarbonAds">
|
||||
<VPCarbonAds :carbon-ads="carbonAds" />
|
||||
</div>
|
||||
</template>
|
||||
88
node_modules/vitepress/dist/client/theme-default/components/VPDocAsideOutline.vue
generated
vendored
88
node_modules/vitepress/dist/client/theme-default/components/VPDocAsideOutline.vue
generated
vendored
@@ -1,88 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onContentUpdated } from 'vitepress'
|
||||
import { ref, shallowRef } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import {
|
||||
getHeaders,
|
||||
resolveTitle,
|
||||
useActiveAnchor,
|
||||
type MenuItem
|
||||
} from '../composables/outline'
|
||||
import VPDocOutlineItem from './VPDocOutlineItem.vue'
|
||||
|
||||
const { frontmatter, theme } = useData()
|
||||
|
||||
const headers = shallowRef<MenuItem[]>([])
|
||||
|
||||
onContentUpdated(() => {
|
||||
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
|
||||
})
|
||||
|
||||
const container = ref()
|
||||
const marker = ref()
|
||||
|
||||
useActiveAnchor(container, marker)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="VPDocAsideOutline"
|
||||
:class="{ 'has-outline': headers.length > 0 }"
|
||||
ref="container"
|
||||
role="navigation"
|
||||
>
|
||||
<div class="content">
|
||||
<div class="outline-marker" ref="marker" />
|
||||
|
||||
<div class="outline-title" role="heading" aria-level="2">{{ resolveTitle(theme) }}</div>
|
||||
|
||||
<nav aria-labelledby="doc-outline-aria-label">
|
||||
<span class="visually-hidden" id="doc-outline-aria-label">
|
||||
Table of Contents for current page
|
||||
</span>
|
||||
<VPDocOutlineItem :headers="headers" :root="true" />
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPDocAsideOutline {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.VPDocAsideOutline.has-outline {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
border-left: 1px solid var(--vp-c-divider);
|
||||
padding-left: 16px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.outline-marker {
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
left: -1px;
|
||||
z-index: 0;
|
||||
opacity: 0;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
height: 18px;
|
||||
background-color: var(--vp-c-brand-1);
|
||||
transition:
|
||||
top 0.25s cubic-bezier(0, 1, 0.5, 1),
|
||||
background-color 0.5s,
|
||||
opacity 0.25s;
|
||||
}
|
||||
|
||||
.outline-title {
|
||||
letter-spacing: 0.4px;
|
||||
line-height: 28px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
17
node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue
generated
vendored
17
node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue
generated
vendored
@@ -1,17 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { Sponsors } from './VPSponsors.vue'
|
||||
import type { Sponsor } from './VPSponsorsGrid.vue'
|
||||
import VPSponsors from './VPSponsors.vue'
|
||||
|
||||
defineProps<{
|
||||
tier?: string
|
||||
size?: 'xmini' | 'mini' | 'small'
|
||||
data: Sponsors[] | Sponsor[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPDocAsideSponsors">
|
||||
<VPSponsors mode="aside" :tier="tier" :size="size" :data="data" />
|
||||
</div>
|
||||
</template>
|
||||
150
node_modules/vitepress/dist/client/theme-default/components/VPDocFooter.vue
generated
vendored
150
node_modules/vitepress/dist/client/theme-default/components/VPDocFooter.vue
generated
vendored
@@ -1,150 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { normalizeLink } from '../support/utils'
|
||||
import { useEditLink } from '../composables/edit-link'
|
||||
import { usePrevNext } from '../composables/prev-next'
|
||||
import VPIconEdit from './icons/VPIconEdit.vue'
|
||||
import VPLink from './VPLink.vue'
|
||||
import VPDocFooterLastUpdated from './VPDocFooterLastUpdated.vue'
|
||||
|
||||
const { theme, page, frontmatter } = useData()
|
||||
|
||||
const editLink = useEditLink()
|
||||
const control = usePrevNext()
|
||||
|
||||
const hasEditLink = computed(() => {
|
||||
return theme.value.editLink && frontmatter.value.editLink !== false
|
||||
})
|
||||
const hasLastUpdated = computed(() => {
|
||||
return page.value.lastUpdated && frontmatter.value.lastUpdated !== false
|
||||
})
|
||||
const showFooter = computed(() => {
|
||||
return hasEditLink.value || hasLastUpdated.value || control.value.prev || control.value.next
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<footer v-if="showFooter" class="VPDocFooter">
|
||||
<slot name="doc-footer-before" />
|
||||
|
||||
<div v-if="hasEditLink || hasLastUpdated" class="edit-info">
|
||||
<div v-if="hasEditLink" class="edit-link">
|
||||
<VPLink class="edit-link-button" :href="editLink.url" :no-icon="true">
|
||||
<VPIconEdit class="edit-link-icon" aria-label="edit icon"/>
|
||||
{{ editLink.text }}
|
||||
</VPLink>
|
||||
</div>
|
||||
|
||||
<div v-if="hasLastUpdated" class="last-updated">
|
||||
<VPDocFooterLastUpdated />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav v-if="control.prev?.link || control.next?.link" class="prev-next">
|
||||
<div class="pager">
|
||||
<a v-if="control.prev?.link" class="pager-link prev" :href="normalizeLink(control.prev.link)">
|
||||
<span class="desc" v-html="theme.docFooter?.prev || 'Previous page'"></span>
|
||||
<span class="title" v-html="control.prev.text"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<a v-if="control.next?.link" class="pager-link next" :href="normalizeLink(control.next.link)">
|
||||
<span class="desc" v-html="theme.docFooter?.next || 'Next page'"></span>
|
||||
<span class="title" v-html="control.next.text"></span>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPDocFooter {
|
||||
margin-top: 64px;
|
||||
}
|
||||
|
||||
.edit-info {
|
||||
padding-bottom: 18px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.edit-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-link-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 0;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-brand-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.edit-link-button:hover {
|
||||
color: var(--vp-c-brand-2);
|
||||
}
|
||||
|
||||
.edit-link-icon {
|
||||
margin-right: 8px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.prev-next {
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
padding-top: 24px;
|
||||
display: grid;
|
||||
grid-row-gap: 8px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.prev-next {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-column-gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.pager-link {
|
||||
display: block;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 8px;
|
||||
padding: 11px 16px 13px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
|
||||
.pager-link:hover {
|
||||
border-color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.pager-link.next {
|
||||
margin-left: auto;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.desc {
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-brand-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
</style>
|
||||
50
node_modules/vitepress/dist/client/theme-default/components/VPDocFooterLastUpdated.vue
generated
vendored
50
node_modules/vitepress/dist/client/theme-default/components/VPDocFooterLastUpdated.vue
generated
vendored
@@ -1,50 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watchEffect, onMounted } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
|
||||
const { theme, page, frontmatter, lang } = useData()
|
||||
|
||||
const date = computed(
|
||||
() => new Date(frontmatter.value.lastUpdated ?? page.value.lastUpdated)
|
||||
)
|
||||
const isoDatetime = computed(() => date.value.toISOString())
|
||||
const datetime = ref('')
|
||||
|
||||
// set time on mounted hook to avoid hydration mismatch due to
|
||||
// potential differences in timezones of the server and clients
|
||||
onMounted(() => {
|
||||
watchEffect(() => {
|
||||
datetime.value = new Intl.DateTimeFormat(
|
||||
theme.value.lastUpdated?.formatOptions?.forceLocale ? lang.value : undefined,
|
||||
theme.value.lastUpdated?.formatOptions ?? {
|
||||
dateStyle: 'short',
|
||||
timeStyle: 'short'
|
||||
}
|
||||
).format(date.value)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p class="VPLastUpdated">
|
||||
{{ theme.lastUpdated?.text || theme.lastUpdatedText || 'Last updated' }}:
|
||||
<time :datetime="isoDatetime">{{ datetime }}</time>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPLastUpdated {
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.VPLastUpdated {
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
85
node_modules/vitepress/dist/client/theme-default/components/VPDocOutlineDropdown.vue
generated
vendored
85
node_modules/vitepress/dist/client/theme-default/components/VPDocOutlineDropdown.vue
generated
vendored
@@ -1,85 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, shallowRef } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { getHeaders, resolveTitle, type MenuItem } from '../composables/outline'
|
||||
import VPDocOutlineItem from './VPDocOutlineItem.vue'
|
||||
import { onContentUpdated } from 'vitepress'
|
||||
import VPIconChevronRight from './icons/VPIconChevronRight.vue'
|
||||
|
||||
const { frontmatter, theme } = useData()
|
||||
const open = ref(false)
|
||||
|
||||
onContentUpdated(() => {
|
||||
open.value = false
|
||||
})
|
||||
|
||||
const headers = shallowRef<MenuItem[]>([])
|
||||
|
||||
onContentUpdated(() => {
|
||||
headers.value = getHeaders(
|
||||
frontmatter.value.outline ?? theme.value.outline
|
||||
)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPDocOutlineDropdown" v-if="headers.length > 0">
|
||||
<button @click="open = !open" :class="{ open }">
|
||||
{{ resolveTitle(theme) }}
|
||||
<VPIconChevronRight class="icon" />
|
||||
</button>
|
||||
<div class="items" v-if="open">
|
||||
<VPDocOutlineItem :headers="headers" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPDocOutlineDropdown {
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.VPDocOutlineDropdown button {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
border: 1px solid var(--vp-c-border);
|
||||
padding: 4px 12px;
|
||||
color: var(--vp-c-text-2);
|
||||
background-color: var(--vp-c-default-soft);
|
||||
border-radius: 8px;
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.VPDocOutlineDropdown button:hover {
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPDocOutlineDropdown button.open {
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
:deep(.outline-link) {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.open > .icon {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.items {
|
||||
margin-top: 12px;
|
||||
border-left: 1px solid var(--vp-c-divider);
|
||||
}
|
||||
</style>
|
||||
57
node_modules/vitepress/dist/client/theme-default/components/VPDocOutlineItem.vue
generated
vendored
57
node_modules/vitepress/dist/client/theme-default/components/VPDocOutlineItem.vue
generated
vendored
@@ -1,57 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { MenuItem } from '../composables/outline'
|
||||
|
||||
defineProps<{
|
||||
headers: MenuItem[]
|
||||
root?: boolean
|
||||
}>()
|
||||
|
||||
function onClick({ target: el }: Event) {
|
||||
const id = (el as HTMLAnchorElement).href!.split('#')[1]
|
||||
const heading = document.getElementById(decodeURIComponent(id))
|
||||
heading?.focus({ preventScroll: true })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ul :class="root ? 'root' : 'nested'">
|
||||
<li v-for="{ children, link, title } in headers">
|
||||
<a class="outline-link" :href="link" @click="onClick" :title="title">{{ title }}</a>
|
||||
<template v-if="children?.length">
|
||||
<VPDocOutlineItem :headers="children" />
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.root {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.nested {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.outline-link {
|
||||
display: block;
|
||||
line-height: 28px;
|
||||
color: var(--vp-c-text-2);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: color 0.5s;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.outline-link:hover,
|
||||
.outline-link.active {
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.outline-link.nested {
|
||||
padding-left: 13px;
|
||||
}
|
||||
</style>
|
||||
128
node_modules/vitepress/dist/client/theme-default/components/VPFeature.vue
generated
vendored
128
node_modules/vitepress/dist/client/theme-default/components/VPFeature.vue
generated
vendored
@@ -1,128 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import VPImage from './VPImage.vue'
|
||||
import VPLink from './VPLink.vue'
|
||||
import VPIconArrowRight from './icons/VPIconArrowRight.vue'
|
||||
|
||||
defineProps<{
|
||||
icon?: DefaultTheme.FeatureIcon
|
||||
title: string
|
||||
details?: string
|
||||
link?: string
|
||||
linkText?: string
|
||||
rel?: string
|
||||
target?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPLink
|
||||
class="VPFeature"
|
||||
:href="link"
|
||||
:rel="rel"
|
||||
:target="target"
|
||||
:no-icon="true"
|
||||
:tag="link ? 'a' : 'div'"
|
||||
>
|
||||
<article class="box">
|
||||
<div v-if="typeof icon === 'object' && icon.wrap" class="icon">
|
||||
<VPImage
|
||||
:image="icon"
|
||||
:alt="icon.alt"
|
||||
:height="icon.height || 48"
|
||||
:width="icon.width || 48"
|
||||
/>
|
||||
</div>
|
||||
<VPImage
|
||||
v-else-if="typeof icon === 'object'"
|
||||
:image="icon"
|
||||
:alt="icon.alt"
|
||||
:height="icon.height || 48"
|
||||
:width="icon.width || 48"
|
||||
/>
|
||||
<div v-else-if="icon" class="icon" v-html="icon"></div>
|
||||
<h2 class="title" v-html="title"></h2>
|
||||
<p v-if="details" class="details" v-html="details"></p>
|
||||
|
||||
<div v-if="linkText" class="link-text">
|
||||
<p class="link-text-value">
|
||||
{{ linkText }} <VPIconArrowRight class="link-text-icon" />
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
</VPLink>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPFeature {
|
||||
display: block;
|
||||
border: 1px solid var(--vp-c-bg-soft);
|
||||
border-radius: 12px;
|
||||
height: 100%;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
transition: border-color 0.25s, background-color 0.25s;
|
||||
}
|
||||
|
||||
.VPFeature.link:hover {
|
||||
border-color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.box > :deep(.VPImage) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 6px;
|
||||
background-color: var(--vp-c-default-soft);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
font-size: 24px;
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
.title {
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.details {
|
||||
flex-grow: 1;
|
||||
padding-top: 8px;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.link-text {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.link-text-value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.link-text-icon {
|
||||
display: inline-block;
|
||||
margin-left: 6px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
fill: currentColor;
|
||||
}
|
||||
</style>
|
||||
121
node_modules/vitepress/dist/client/theme-default/components/VPFeatures.vue
generated
vendored
121
node_modules/vitepress/dist/client/theme-default/components/VPFeatures.vue
generated
vendored
@@ -1,121 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { computed } from 'vue'
|
||||
import VPFeature from './VPFeature.vue'
|
||||
|
||||
export interface Feature {
|
||||
icon?: DefaultTheme.FeatureIcon
|
||||
title: string
|
||||
details: string
|
||||
link?: string
|
||||
linkText?: string
|
||||
rel?: string
|
||||
target?: string
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
features: Feature[]
|
||||
}>()
|
||||
|
||||
const grid = computed(() => {
|
||||
const length = props.features.length
|
||||
|
||||
if (!length) {
|
||||
return
|
||||
} else if (length === 2) {
|
||||
return 'grid-2'
|
||||
} else if (length === 3) {
|
||||
return 'grid-3'
|
||||
} else if (length % 3 === 0) {
|
||||
return 'grid-6'
|
||||
} else if (length > 3) {
|
||||
return 'grid-4'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="features" class="VPFeatures">
|
||||
<div class="container">
|
||||
<div class="items">
|
||||
<div
|
||||
v-for="feature in features"
|
||||
:key="feature.title"
|
||||
class="item"
|
||||
:class="[grid]"
|
||||
>
|
||||
<VPFeature
|
||||
:icon="feature.icon"
|
||||
:title="feature.title"
|
||||
:details="feature.details"
|
||||
:link="feature.link"
|
||||
:link-text="feature.linkText"
|
||||
:rel="feature.rel"
|
||||
:target="feature.target"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPFeatures {
|
||||
position: relative;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.VPFeatures {
|
||||
padding: 0 48px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPFeatures {
|
||||
padding: 0 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
max-width: 1152px;
|
||||
}
|
||||
|
||||
.items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: -8px;
|
||||
}
|
||||
|
||||
.item {
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.item.grid-2,
|
||||
.item.grid-4,
|
||||
.item.grid-6 {
|
||||
width: calc(100% / 2);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.item.grid-2,
|
||||
.item.grid-4 {
|
||||
width: calc(100% / 2);
|
||||
}
|
||||
|
||||
.item.grid-3,
|
||||
.item.grid-6 {
|
||||
width: calc(100% / 3);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.item.grid-4 {
|
||||
width: calc(100% / 4);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
144
node_modules/vitepress/dist/client/theme-default/components/VPFlyout.vue
generated
vendored
144
node_modules/vitepress/dist/client/theme-default/components/VPFlyout.vue
generated
vendored
@@ -1,144 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { useFlyout } from '../composables/flyout'
|
||||
import VPIconChevronDown from './icons/VPIconChevronDown.vue'
|
||||
import VPIconMoreHorizontal from './icons/VPIconMoreHorizontal.vue'
|
||||
import VPMenu from './VPMenu.vue'
|
||||
|
||||
defineProps<{
|
||||
icon?: any
|
||||
button?: string
|
||||
label?: string
|
||||
items?: any[]
|
||||
}>()
|
||||
|
||||
const open = ref(false)
|
||||
const el = ref<HTMLElement>()
|
||||
|
||||
useFlyout({ el, onBlur })
|
||||
|
||||
function onBlur() {
|
||||
open.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="VPFlyout"
|
||||
ref="el"
|
||||
@mouseenter="open = true"
|
||||
@mouseleave="open = false"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="button"
|
||||
aria-haspopup="true"
|
||||
:aria-expanded="open"
|
||||
:aria-label="label"
|
||||
@click="open = !open"
|
||||
>
|
||||
<span v-if="button || icon" class="text">
|
||||
<component v-if="icon" :is="icon" class="option-icon" />
|
||||
<span v-if="button" v-html="button"></span>
|
||||
<VPIconChevronDown class="text-icon" />
|
||||
</span>
|
||||
|
||||
<VPIconMoreHorizontal v-else class="icon" />
|
||||
</button>
|
||||
|
||||
<div class="menu">
|
||||
<VPMenu :items="items">
|
||||
<slot />
|
||||
</VPMenu>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPFlyout {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.VPFlyout:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPFlyout:hover .text {
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.VPFlyout:hover .icon {
|
||||
fill: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.VPFlyout.active .text {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.VPFlyout.active:hover .text {
|
||||
color: var(--vp-c-brand-2);
|
||||
}
|
||||
|
||||
.VPFlyout:hover .menu,
|
||||
.button[aria-expanded="true"] + .menu {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.button[aria-expanded="false"] + .menu {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
height: var(--vp-nav-height);
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: var(--vp-nav-height);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.option-icon {
|
||||
margin-right: 0px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.text-icon {
|
||||
margin-left: 4px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: currentColor;
|
||||
transition: fill 0.25s;
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
top: calc(var(--vp-nav-height) / 2 + 20px);
|
||||
right: 0;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.25s, visibility 0.25s, transform 0.25s;
|
||||
}
|
||||
</style>
|
||||
50
node_modules/vitepress/dist/client/theme-default/components/VPFooter.vue
generated
vendored
50
node_modules/vitepress/dist/client/theme-default/components/VPFooter.vue
generated
vendored
@@ -1,50 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useData } from '../composables/data'
|
||||
import { useSidebar } from '../composables/sidebar'
|
||||
|
||||
const { theme, frontmatter } = useData()
|
||||
const { hasSidebar } = useSidebar()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<footer v-if="theme.footer && frontmatter.footer !== false" class="VPFooter" :class="{ 'has-sidebar': hasSidebar }">
|
||||
<div class="container">
|
||||
<p v-if="theme.footer.message" class="message" v-html="theme.footer.message"></p>
|
||||
<p v-if="theme.footer.copyright" class="copyright" v-html="theme.footer.copyright"></p>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPFooter {
|
||||
position: relative;
|
||||
z-index: var(--vp-z-index-footer);
|
||||
border-top: 1px solid var(--vp-c-gutter);
|
||||
padding: 32px 24px;
|
||||
background-color: var(--vp-c-bg);
|
||||
}
|
||||
|
||||
.VPFooter.has-sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPFooter {
|
||||
padding: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
max-width: var(--vp-layout-max-width);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.message,
|
||||
.copyright {
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
</style>
|
||||
329
node_modules/vitepress/dist/client/theme-default/components/VPHero.vue
generated
vendored
329
node_modules/vitepress/dist/client/theme-default/components/VPHero.vue
generated
vendored
@@ -1,329 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { type Ref, inject } from 'vue'
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import VPButton from './VPButton.vue'
|
||||
import VPImage from './VPImage.vue'
|
||||
|
||||
export interface HeroAction {
|
||||
theme?: 'brand' | 'alt'
|
||||
text: string
|
||||
link: string
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
name?: string
|
||||
text?: string
|
||||
tagline?: string
|
||||
image?: DefaultTheme.ThemeableImage
|
||||
actions?: HeroAction[]
|
||||
}>()
|
||||
|
||||
const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPHero" :class="{ 'has-image': image || heroImageSlotExists }">
|
||||
<div class="container">
|
||||
<div class="main">
|
||||
<slot name="home-hero-info">
|
||||
<h1 v-if="name" class="name">
|
||||
<span v-html="name" class="clip"></span>
|
||||
</h1>
|
||||
<p v-if="text" v-html="text" class="text"></p>
|
||||
<p v-if="tagline" v-html="tagline" class="tagline"></p>
|
||||
</slot>
|
||||
|
||||
<div v-if="actions" class="actions">
|
||||
<div v-for="action in actions" :key="action.link" class="action">
|
||||
<VPButton
|
||||
tag="a"
|
||||
size="medium"
|
||||
:theme="action.theme"
|
||||
:text="action.text"
|
||||
:href="action.link"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="image || heroImageSlotExists" class="image">
|
||||
<div class="image-container">
|
||||
<div class="image-bg" />
|
||||
<slot name="home-hero-image">
|
||||
<VPImage v-if="image" class="image-src" :image="image" />
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPHero {
|
||||
margin-top: calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);
|
||||
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.VPHero {
|
||||
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPHero {
|
||||
padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
max-width: 1152px;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.container {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
order: 2;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.VPHero.has-image .container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPHero.has-image .container {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.main {
|
||||
order: 1;
|
||||
width: calc((100% / 3) * 2);
|
||||
}
|
||||
|
||||
.VPHero.has-image .main {
|
||||
max-width: 592px;
|
||||
}
|
||||
}
|
||||
|
||||
.name,
|
||||
.text {
|
||||
max-width: 392px;
|
||||
letter-spacing: -0.4px;
|
||||
line-height: 40px;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.VPHero.has-image .name,
|
||||
.VPHero.has-image .text {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: var(--vp-home-hero-name-color);
|
||||
}
|
||||
|
||||
.clip {
|
||||
background: var(--vp-home-hero-name-background);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: var(--vp-home-hero-name-color);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.name,
|
||||
.text {
|
||||
max-width: 576px;
|
||||
line-height: 56px;
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.name,
|
||||
.text {
|
||||
line-height: 64px;
|
||||
font-size: 56px;
|
||||
}
|
||||
|
||||
.VPHero.has-image .name,
|
||||
.VPHero.has-image .text {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tagline {
|
||||
padding-top: 8px;
|
||||
max-width: 392px;
|
||||
line-height: 28px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
white-space: pre-wrap;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.VPHero.has-image .tagline {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.tagline {
|
||||
padding-top: 12px;
|
||||
max-width: 576px;
|
||||
line-height: 32px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.tagline {
|
||||
line-height: 36px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.VPHero.has-image .tagline {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: -6px;
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.VPHero.has-image .actions {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.actions {
|
||||
padding-top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPHero.has-image .actions {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
.action {
|
||||
flex-shrink: 0;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.image {
|
||||
order: 1;
|
||||
margin: -76px -24px -48px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.image {
|
||||
margin: -108px -24px -48px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.image {
|
||||
flex-grow: 1;
|
||||
order: 2;
|
||||
margin: 0;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.image-container {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.image-container {
|
||||
width: 392px;
|
||||
height: 392px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.image-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/*rtl:ignore*/
|
||||
transform: translate(-32px, -32px);
|
||||
}
|
||||
}
|
||||
|
||||
.image-bg {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
/*rtl:ignore*/
|
||||
left: 50%;
|
||||
border-radius: 50%;
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
background-image: var(--vp-home-hero-image-background-image);
|
||||
filter: var(--vp-home-hero-image-filter);
|
||||
/*rtl:ignore*/
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.image-bg {
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.image-bg {
|
||||
width: 320px;
|
||||
height: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.image-src) {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
/*rtl:ignore*/
|
||||
left: 50%;
|
||||
max-width: 192px;
|
||||
max-height: 192px;
|
||||
/*rtl:ignore*/
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
:deep(.image-src) {
|
||||
max-width: 256px;
|
||||
max-height: 256px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
:deep(.image-src) {
|
||||
max-width: 320px;
|
||||
max-height: 320px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
node_modules/vitepress/dist/client/theme-default/components/VPHome.vue
generated
vendored
38
node_modules/vitepress/dist/client/theme-default/components/VPHome.vue
generated
vendored
@@ -1,38 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import VPHomeHero from './VPHomeHero.vue'
|
||||
import VPHomeFeatures from './VPHomeFeatures.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPHome">
|
||||
<slot name="home-hero-before" />
|
||||
<VPHomeHero>
|
||||
<template #home-hero-info><slot name="home-hero-info" /></template>
|
||||
<template #home-hero-image><slot name="home-hero-image" /></template>
|
||||
</VPHomeHero>
|
||||
<slot name="home-hero-after" />
|
||||
|
||||
<slot name="home-features-before" />
|
||||
<VPHomeFeatures />
|
||||
<slot name="home-features-after" />
|
||||
|
||||
<Content />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPHome {
|
||||
padding-bottom: 96px;
|
||||
}
|
||||
|
||||
.VPHome :deep(.VPHomeSponsors) {
|
||||
margin-top: 112px;
|
||||
margin-bottom: -128px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPHome {
|
||||
padding-bottom: 128px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
14
node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue
generated
vendored
14
node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue
generated
vendored
@@ -1,14 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useData } from '../composables/data'
|
||||
import VPFeatures from './VPFeatures.vue'
|
||||
|
||||
const { frontmatter: fm } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPFeatures
|
||||
v-if="fm.features"
|
||||
class="VPHomeFeatures"
|
||||
:features="fm.features"
|
||||
/>
|
||||
</template>
|
||||
21
node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue
generated
vendored
21
node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue
generated
vendored
@@ -1,21 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useData } from '../composables/data'
|
||||
import VPHero from './VPHero.vue'
|
||||
|
||||
const { frontmatter: fm } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPHero
|
||||
v-if="fm.hero"
|
||||
class="VPHomeHero"
|
||||
:name="fm.hero.name"
|
||||
:text="fm.hero.text"
|
||||
:tagline="fm.hero.tagline"
|
||||
:image="fm.hero.image"
|
||||
:actions="fm.hero.actions"
|
||||
>
|
||||
<template #home-hero-info><slot name="home-hero-info" /></template>
|
||||
<template #home-hero-image><slot name="home-hero-image" /></template>
|
||||
</VPHero>
|
||||
</template>
|
||||
92
node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue
generated
vendored
92
node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue
generated
vendored
@@ -1,92 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import VPIconHeart from './icons/VPIconHeart.vue'
|
||||
import VPButton from './VPButton.vue'
|
||||
import VPSponsors from './VPSponsors.vue'
|
||||
|
||||
export interface Sponsors {
|
||||
tier: string
|
||||
size?: 'medium' | 'big'
|
||||
items: Sponsor[]
|
||||
}
|
||||
|
||||
export interface Sponsor {
|
||||
name: string
|
||||
img: string
|
||||
url: string
|
||||
}
|
||||
interface Props {
|
||||
message?: string
|
||||
actionText?: string
|
||||
actionLink?: string
|
||||
data: Sponsors[]
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
actionText: 'Become a sponsor'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="VPHomeSponsors">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<div class="love"><VPIconHeart class="icon" /></div>
|
||||
<h2 v-if="message" class="message">{{ message }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="sponsors">
|
||||
<VPSponsors :data="data" />
|
||||
</div>
|
||||
|
||||
<div v-if="actionLink" class="action">
|
||||
<VPButton theme="sponsor" :text="actionText" :href="actionLink" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPHomeSponsors {
|
||||
border-top: 1px solid var(--vp-c-gutter);
|
||||
padding: 88px 24px 96px;
|
||||
background-color: var(--vp-c-bg);
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
max-width: 1152px;
|
||||
}
|
||||
|
||||
.love {
|
||||
margin: 0 auto;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
color: var(--vp-c-text-3);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.message {
|
||||
margin: 0 auto;
|
||||
padding-top: 10px;
|
||||
max-width: 320px;
|
||||
text-align: center;
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.sponsors {
|
||||
padding-top: 32px;
|
||||
}
|
||||
|
||||
.action {
|
||||
padding-top: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
46
node_modules/vitepress/dist/client/theme-default/components/VPImage.vue
generated
vendored
46
node_modules/vitepress/dist/client/theme-default/components/VPImage.vue
generated
vendored
@@ -1,46 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { withBase } from 'vitepress'
|
||||
|
||||
defineProps<{
|
||||
image: DefaultTheme.ThemeableImage
|
||||
alt?: string
|
||||
}>()
|
||||
|
||||
defineOptions({ inheritAttrs: false })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="image">
|
||||
<img
|
||||
v-if="typeof image === 'string' || 'src' in image"
|
||||
class="VPImage"
|
||||
v-bind="typeof image === 'string' ? $attrs : { ...image, ...$attrs }"
|
||||
:src="withBase(typeof image === 'string' ? image : image.src)"
|
||||
:alt="alt ?? (typeof image === 'string' ? '' : image.alt || '')"
|
||||
/>
|
||||
<template v-else>
|
||||
<VPImage
|
||||
class="dark"
|
||||
:image="image.dark"
|
||||
:alt="image.alt"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
<VPImage
|
||||
class="light"
|
||||
:image="image.light"
|
||||
:alt="image.alt"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
html:not(.dark) .VPImage.dark {
|
||||
display: none;
|
||||
}
|
||||
.dark .VPImage.light {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
33
node_modules/vitepress/dist/client/theme-default/components/VPLink.vue
generated
vendored
33
node_modules/vitepress/dist/client/theme-default/components/VPLink.vue
generated
vendored
@@ -1,33 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { normalizeLink } from '../support/utils'
|
||||
import { EXTERNAL_URL_RE } from '../../shared'
|
||||
|
||||
const props = defineProps<{
|
||||
tag?: string
|
||||
href?: string
|
||||
noIcon?: boolean
|
||||
target?: string
|
||||
rel?: string
|
||||
}>()
|
||||
|
||||
const tag = computed(() => props.tag ?? (props.href ? 'a' : 'span'))
|
||||
const isExternal = computed(() => props.href && EXTERNAL_URL_RE.test(props.href))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="tag"
|
||||
class="VPLink"
|
||||
:class="{
|
||||
link: href,
|
||||
'vp-external-link-icon': isExternal,
|
||||
'no-icon': noIcon
|
||||
}"
|
||||
:href="href ? normalizeLink(href) : undefined"
|
||||
:target="target ?? (isExternal ? '_blank' : undefined)"
|
||||
:rel="rel ?? (isExternal ? 'noreferrer' : undefined)"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
143
node_modules/vitepress/dist/client/theme-default/components/VPLocalNav.vue
generated
vendored
143
node_modules/vitepress/dist/client/theme-default/components/VPLocalNav.vue
generated
vendored
@@ -1,143 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useWindowScroll } from '@vueuse/core'
|
||||
import { onContentUpdated } from 'vitepress'
|
||||
import { computed, onMounted, ref, shallowRef } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { getHeaders, type MenuItem } from '../composables/outline'
|
||||
import { useSidebar } from '../composables/sidebar'
|
||||
import VPLocalNavOutlineDropdown from './VPLocalNavOutlineDropdown.vue'
|
||||
import VPIconAlignLeft from './icons/VPIconAlignLeft.vue'
|
||||
|
||||
defineProps<{
|
||||
open: boolean
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
(e: 'open-menu'): void
|
||||
}>()
|
||||
|
||||
const { theme, frontmatter } = useData()
|
||||
const { hasSidebar } = useSidebar()
|
||||
// @ts-ignore
|
||||
const { y } = useWindowScroll()
|
||||
|
||||
const headers = shallowRef<MenuItem[]>([])
|
||||
const navHeight = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
navHeight.value = parseInt(
|
||||
getComputedStyle(document.documentElement).getPropertyValue(
|
||||
'--vp-nav-height'
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
onContentUpdated(() => {
|
||||
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
|
||||
})
|
||||
|
||||
const empty = computed(() => {
|
||||
return headers.value.length === 0 && !hasSidebar.value
|
||||
})
|
||||
|
||||
const classes = computed(() => {
|
||||
return {
|
||||
VPLocalNav: true,
|
||||
fixed: empty.value,
|
||||
'reached-top': y.value >= navHeight.value
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="frontmatter.layout !== 'home' && (!empty || y >= navHeight)"
|
||||
:class="classes"
|
||||
>
|
||||
<button
|
||||
v-if="hasSidebar"
|
||||
class="menu"
|
||||
:aria-expanded="open"
|
||||
aria-controls="VPSidebarNav"
|
||||
@click="$emit('open-menu')"
|
||||
>
|
||||
<VPIconAlignLeft class="menu-icon" />
|
||||
<span class="menu-text">
|
||||
{{ theme.sidebarMenuLabel || 'Menu' }}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<VPLocalNavOutlineDropdown :headers="headers" :navHeight="navHeight" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPLocalNav {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
/*rtl:ignore*/
|
||||
left: 0;
|
||||
z-index: var(--vp-z-index-local-nav);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--vp-c-gutter);
|
||||
border-bottom: 1px solid var(--vp-c-gutter);
|
||||
padding-top: var(--vp-layout-top-height, 0px);
|
||||
width: 100%;
|
||||
background-color: var(--vp-local-nav-bg-color);
|
||||
}
|
||||
|
||||
.VPLocalNav.fixed {
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.VPLocalNav.reached-top {
|
||||
border-top-color: transparent;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPLocalNav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 24px 11px;
|
||||
line-height: 24px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.menu:hover {
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.menu {
|
||||
padding: 0 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
margin-right: 8px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.VPOutlineDropdown {
|
||||
padding: 12px 24px 11px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPOutlineDropdown {
|
||||
padding: 12px 32px 11px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
162
node_modules/vitepress/dist/client/theme-default/components/VPLocalNavOutlineDropdown.vue
generated
vendored
162
node_modules/vitepress/dist/client/theme-default/components/VPLocalNavOutlineDropdown.vue
generated
vendored
@@ -1,162 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { onContentUpdated } from 'vitepress'
|
||||
import { nextTick, ref } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { resolveTitle, type MenuItem } from '../composables/outline'
|
||||
import VPDocOutlineItem from './VPDocOutlineItem.vue'
|
||||
import VPIconChevronRight from './icons/VPIconChevronRight.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
headers: MenuItem[]
|
||||
navHeight: number
|
||||
}>()
|
||||
|
||||
const { theme } = useData()
|
||||
const open = ref(false)
|
||||
const vh = ref(0)
|
||||
const items = ref<HTMLDivElement>()
|
||||
|
||||
onContentUpdated(() => {
|
||||
open.value = false
|
||||
})
|
||||
|
||||
function toggle() {
|
||||
open.value = !open.value
|
||||
vh.value = window.innerHeight + Math.min(window.scrollY - props.navHeight, 0)
|
||||
}
|
||||
|
||||
function onItemClick(e: Event) {
|
||||
if ((e.target as HTMLElement).classList.contains('outline-link')) {
|
||||
// disable animation on hash navigation when page jumps
|
||||
if (items.value) {
|
||||
items.value.style.transition = 'none'
|
||||
}
|
||||
nextTick(() => {
|
||||
open.value = false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToTop() {
|
||||
open.value = false
|
||||
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPLocalNavOutlineDropdown" :style="{ '--vp-vh': vh + 'px' }">
|
||||
<button @click="toggle" :class="{ open }" v-if="headers.length > 0">
|
||||
{{ resolveTitle(theme) }}
|
||||
<VPIconChevronRight class="icon" />
|
||||
</button>
|
||||
<button @click="scrollToTop" v-else>
|
||||
{{ theme.returnToTopLabel || 'Return to top' }}
|
||||
</button>
|
||||
<Transition name="flyout">
|
||||
<div v-if="open"
|
||||
ref="items"
|
||||
class="items"
|
||||
@click="onItemClick"
|
||||
>
|
||||
<div class="header">
|
||||
<a class="top-link" href="#" @click="scrollToTop">
|
||||
{{ theme.returnToTopLabel || 'Return to top' }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="outline">
|
||||
<VPDocOutlineItem :headers="headers" />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPLocalNavOutlineDropdown {
|
||||
padding: 12px 20px 11px;
|
||||
}
|
||||
|
||||
.VPLocalNavOutlineDropdown button {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color 0.5s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.VPLocalNavOutlineDropdown button:hover {
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPLocalNavOutlineDropdown button.open {
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: 2px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
:deep(.outline-link) {
|
||||
font-size: 14px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.open > .icon {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.items {
|
||||
position: absolute;
|
||||
top: 64px;
|
||||
right: 16px;
|
||||
left: 16px;
|
||||
display: grid;
|
||||
gap: 1px;
|
||||
border: 1px solid var(--vp-c-border);
|
||||
border-radius: 8px;
|
||||
background-color: var(--vp-c-gutter);
|
||||
max-height: calc(var(--vp-vh, 100vh) - 86px);
|
||||
overflow: hidden auto;
|
||||
box-shadow: var(--vp-shadow-3);
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
}
|
||||
|
||||
.top-link {
|
||||
display: block;
|
||||
padding: 0 16px;
|
||||
line-height: 48px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.outline {
|
||||
padding: 8px 0;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
}
|
||||
|
||||
.flyout-enter-active {
|
||||
transition: all .2s ease-out;
|
||||
}
|
||||
|
||||
.flyout-leave-active {
|
||||
transition: all .15s ease-in;
|
||||
}
|
||||
|
||||
.flyout-enter-from,
|
||||
.flyout-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-16px);
|
||||
}
|
||||
</style>
|
||||
931
node_modules/vitepress/dist/client/theme-default/components/VPLocalSearchBox.vue
generated
vendored
931
node_modules/vitepress/dist/client/theme-default/components/VPLocalSearchBox.vue
generated
vendored
@@ -1,931 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import localSearchIndex from '@localSearchIndex'
|
||||
import {
|
||||
computedAsync,
|
||||
debouncedWatch,
|
||||
onKeyStroke,
|
||||
useEventListener,
|
||||
useLocalStorage,
|
||||
useScrollLock,
|
||||
useSessionStorage
|
||||
} from '@vueuse/core'
|
||||
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
||||
import Mark from 'mark.js/src/vanilla.js'
|
||||
import MiniSearch, { type SearchResult } from 'minisearch'
|
||||
import { inBrowser, useRouter, dataSymbol } from 'vitepress'
|
||||
import {
|
||||
computed,
|
||||
createApp,
|
||||
markRaw,
|
||||
nextTick,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
ref,
|
||||
shallowRef,
|
||||
watch,
|
||||
watchEffect,
|
||||
type Ref
|
||||
} from 'vue'
|
||||
import type { ModalTranslations } from '../../../../types/local-search'
|
||||
import { pathToFile } from '../../app/utils'
|
||||
import { useData } from '../composables/data'
|
||||
import { createTranslate } from '../support/translation'
|
||||
|
||||
defineProps<{
|
||||
placeholder: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'close'): void
|
||||
}>()
|
||||
|
||||
const el = shallowRef<HTMLElement>()
|
||||
const resultsEl = shallowRef<HTMLElement>()
|
||||
|
||||
/* Search */
|
||||
|
||||
const searchIndexData = shallowRef(localSearchIndex)
|
||||
|
||||
// hmr
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept('/@localSearchIndex', (m) => {
|
||||
if (m) {
|
||||
searchIndexData.value = m.default
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
interface Result {
|
||||
title: string
|
||||
titles: string[]
|
||||
text?: string
|
||||
}
|
||||
|
||||
const vitePressData = useData()
|
||||
const { activate } = useFocusTrap(el, {
|
||||
immediate: true,
|
||||
allowOutsideClick: true,
|
||||
clickOutsideDeactivates: true,
|
||||
escapeDeactivates: true
|
||||
})
|
||||
const { localeIndex, theme } = vitePressData
|
||||
const searchIndex = computedAsync(async () =>
|
||||
markRaw(
|
||||
MiniSearch.loadJSON<Result>(
|
||||
(await searchIndexData.value[localeIndex.value]?.())?.default,
|
||||
{
|
||||
fields: ['title', 'titles', 'text'],
|
||||
storeFields: ['title', 'titles'],
|
||||
searchOptions: {
|
||||
fuzzy: 0.2,
|
||||
prefix: true,
|
||||
boost: { title: 4, text: 2, titles: 1 },
|
||||
...(theme.value.search?.provider === 'local' &&
|
||||
theme.value.search.options?.miniSearch?.searchOptions)
|
||||
},
|
||||
...(theme.value.search?.provider === 'local' &&
|
||||
theme.value.search.options?.miniSearch?.options)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
const disableQueryPersistence = computed(() => {
|
||||
return (
|
||||
theme.value.search?.provider === 'local' &&
|
||||
theme.value.search.options?.disableQueryPersistence === true
|
||||
)
|
||||
})
|
||||
|
||||
const filterText = disableQueryPersistence.value
|
||||
? ref('')
|
||||
: useSessionStorage('vitepress:local-search-filter', '')
|
||||
|
||||
const showDetailedList = useLocalStorage(
|
||||
'vitepress:local-search-detailed-list',
|
||||
theme.value.search?.provider === 'local' &&
|
||||
theme.value.search.options?.detailedView === true
|
||||
)
|
||||
|
||||
const disableDetailedView = computed(() => {
|
||||
return (
|
||||
theme.value.search?.provider === 'local' &&
|
||||
(theme.value.search.options?.disableDetailedView === true ||
|
||||
theme.value.search.options?.detailedView === false)
|
||||
)
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
if (disableDetailedView.value) {
|
||||
showDetailedList.value = false
|
||||
}
|
||||
})
|
||||
|
||||
const results: Ref<(SearchResult & Result)[]> = shallowRef([])
|
||||
|
||||
const enableNoResults = ref(false)
|
||||
|
||||
watch(filterText, () => {
|
||||
enableNoResults.value = false
|
||||
})
|
||||
|
||||
const mark = computedAsync(async () => {
|
||||
if (!resultsEl.value) return
|
||||
return markRaw(new Mark(resultsEl.value))
|
||||
}, null)
|
||||
|
||||
debouncedWatch(
|
||||
() => [searchIndex.value, filterText.value, showDetailedList.value] as const,
|
||||
async ([index, filterTextValue, showDetailedListValue], old, onCleanup) => {
|
||||
let canceled = false
|
||||
onCleanup(() => {
|
||||
canceled = true
|
||||
})
|
||||
|
||||
if (!index) return
|
||||
|
||||
// Search
|
||||
results.value = index
|
||||
.search(filterTextValue)
|
||||
.slice(0, 16) as (SearchResult & Result)[]
|
||||
enableNoResults.value = true
|
||||
|
||||
// Highlighting
|
||||
const mods = showDetailedListValue
|
||||
? await Promise.all(results.value.map((r) => fetchExcerpt(r.id)))
|
||||
: []
|
||||
if (canceled) return
|
||||
const c = new Map<string, Map<string, string>>()
|
||||
for (const { id, mod } of mods) {
|
||||
const mapId = id.slice(0, id.indexOf('#'))
|
||||
let map = c.get(mapId)
|
||||
if (map) continue
|
||||
map = new Map()
|
||||
c.set(mapId, map)
|
||||
const comp = mod.default ?? mod
|
||||
if (comp?.render || comp?.setup) {
|
||||
const app = createApp(comp)
|
||||
// Silence warnings about missing components
|
||||
app.config.warnHandler = () => {}
|
||||
app.provide(dataSymbol, vitePressData)
|
||||
Object.defineProperties(app.config.globalProperties, {
|
||||
$frontmatter: {
|
||||
get() {
|
||||
return vitePressData.frontmatter.value
|
||||
}
|
||||
},
|
||||
$params: {
|
||||
get() {
|
||||
return vitePressData.page.value.params
|
||||
}
|
||||
}
|
||||
})
|
||||
const div = document.createElement('div')
|
||||
app.mount(div)
|
||||
const headings = div.querySelectorAll('h1, h2, h3, h4, h5, h6')
|
||||
headings.forEach((el) => {
|
||||
const href = el.querySelector('a')?.getAttribute('href')
|
||||
const anchor = href?.startsWith('#') && href.slice(1)
|
||||
if (!anchor) return
|
||||
let html = ''
|
||||
while ((el = el.nextElementSibling!) && !/^h[1-6]$/i.test(el.tagName))
|
||||
html += el.outerHTML
|
||||
map!.set(anchor, html)
|
||||
})
|
||||
app.unmount()
|
||||
}
|
||||
if (canceled) return
|
||||
}
|
||||
|
||||
const terms = new Set<string>()
|
||||
|
||||
results.value = results.value.map((r) => {
|
||||
const [id, anchor] = r.id.split('#')
|
||||
const map = c.get(id)
|
||||
const text = map?.get(anchor) ?? ''
|
||||
for (const term in r.match) {
|
||||
terms.add(term)
|
||||
}
|
||||
return { ...r, text }
|
||||
})
|
||||
|
||||
await nextTick()
|
||||
if (canceled) return
|
||||
|
||||
await new Promise((r) => {
|
||||
mark.value?.unmark({
|
||||
done: () => {
|
||||
mark.value?.markRegExp(formMarkRegex(terms), { done: r })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const excerpts = el.value?.querySelectorAll('.result .excerpt') ?? []
|
||||
for (const excerpt of excerpts) {
|
||||
excerpt
|
||||
.querySelector('mark[data-markjs="true"]')
|
||||
?.scrollIntoView({ block: 'center' })
|
||||
}
|
||||
// FIXME: without this whole page scrolls to the bottom
|
||||
resultsEl.value?.firstElementChild?.scrollIntoView({ block: 'start' })
|
||||
},
|
||||
{ debounce: 200, immediate: true }
|
||||
)
|
||||
|
||||
async function fetchExcerpt(id: string) {
|
||||
const file = pathToFile(id.slice(0, id.indexOf('#')))
|
||||
try {
|
||||
if (!file) throw new Error(`Cannot find file for id: ${id}`)
|
||||
return { id, mod: await import(/*@vite-ignore*/ file) }
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return { id, mod: {} }
|
||||
}
|
||||
}
|
||||
|
||||
/* Search input focus */
|
||||
|
||||
const searchInput = ref<HTMLInputElement>()
|
||||
const disableReset = computed(() => {
|
||||
return filterText.value?.length <= 0
|
||||
})
|
||||
function focusSearchInput(select = true) {
|
||||
searchInput.value?.focus()
|
||||
select && searchInput.value?.select()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
focusSearchInput()
|
||||
})
|
||||
|
||||
function onSearchBarClick(event: PointerEvent) {
|
||||
if (event.pointerType === 'mouse') {
|
||||
focusSearchInput()
|
||||
}
|
||||
}
|
||||
|
||||
/* Search keyboard selection */
|
||||
|
||||
const selectedIndex = ref(-1)
|
||||
const disableMouseOver = ref(false)
|
||||
|
||||
watch(results, (r) => {
|
||||
selectedIndex.value = r.length ? 0 : -1
|
||||
scrollToSelectedResult()
|
||||
})
|
||||
|
||||
function scrollToSelectedResult() {
|
||||
nextTick(() => {
|
||||
const selectedEl = document.querySelector('.result.selected')
|
||||
if (selectedEl) {
|
||||
selectedEl.scrollIntoView({
|
||||
block: 'nearest'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onKeyStroke('ArrowUp', (event) => {
|
||||
event.preventDefault()
|
||||
selectedIndex.value--
|
||||
if (selectedIndex.value < 0) {
|
||||
selectedIndex.value = results.value.length - 1
|
||||
}
|
||||
disableMouseOver.value = true
|
||||
scrollToSelectedResult()
|
||||
})
|
||||
|
||||
onKeyStroke('ArrowDown', (event) => {
|
||||
event.preventDefault()
|
||||
selectedIndex.value++
|
||||
if (selectedIndex.value >= results.value.length) {
|
||||
selectedIndex.value = 0
|
||||
}
|
||||
disableMouseOver.value = true
|
||||
scrollToSelectedResult()
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
onKeyStroke('Enter', (e) => {
|
||||
if (e.target instanceof HTMLButtonElement && e.target.type !== 'submit')
|
||||
return
|
||||
|
||||
const selectedPackage = results.value[selectedIndex.value]
|
||||
if (e.target instanceof HTMLInputElement && !selectedPackage) {
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
|
||||
if (selectedPackage) {
|
||||
router.go(selectedPackage.id)
|
||||
emit('close')
|
||||
}
|
||||
})
|
||||
|
||||
onKeyStroke('Escape', () => {
|
||||
emit('close')
|
||||
})
|
||||
|
||||
// Translations
|
||||
const defaultTranslations: { modal: ModalTranslations } = {
|
||||
modal: {
|
||||
displayDetails: 'Display detailed list',
|
||||
resetButtonTitle: 'Reset search',
|
||||
backButtonTitle: 'Close search',
|
||||
noResultsText: 'No results for',
|
||||
footer: {
|
||||
selectText: 'to select',
|
||||
selectKeyAriaLabel: 'enter',
|
||||
navigateText: 'to navigate',
|
||||
navigateUpKeyAriaLabel: 'up arrow',
|
||||
navigateDownKeyAriaLabel: 'down arrow',
|
||||
closeText: 'to close',
|
||||
closeKeyAriaLabel: 'escape'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const $t = createTranslate(theme.value.search?.options, defaultTranslations)
|
||||
|
||||
// Back
|
||||
|
||||
onMounted(() => {
|
||||
// Prevents going to previous site
|
||||
window.history.pushState(null, '', null)
|
||||
})
|
||||
|
||||
useEventListener('popstate', (event) => {
|
||||
event.preventDefault()
|
||||
emit('close')
|
||||
})
|
||||
|
||||
/** Lock body */
|
||||
const isLocked = useScrollLock(inBrowser ? document.body : null)
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
isLocked.value = true
|
||||
nextTick().then(() => activate())
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
isLocked.value = false
|
||||
})
|
||||
|
||||
function resetSearch() {
|
||||
filterText.value = ''
|
||||
nextTick().then(() => focusSearchInput(false))
|
||||
}
|
||||
|
||||
function formMarkRegex(terms: Set<string>) {
|
||||
return new RegExp(
|
||||
[...terms]
|
||||
.sort((a, b) => b.length - a.length)
|
||||
.map((term) => {
|
||||
return `(${term
|
||||
.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')
|
||||
.replace(/-/g, '\\x2d')})`
|
||||
})
|
||||
.join('|'),
|
||||
'gi'
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div
|
||||
ref="el"
|
||||
role="button"
|
||||
:aria-owns="results?.length ? 'localsearch-list' : undefined"
|
||||
aria-expanded="true"
|
||||
aria-haspopup="listbox"
|
||||
aria-labelledby="localsearch-label"
|
||||
class="VPLocalSearchBox"
|
||||
>
|
||||
<div class="backdrop" @click="$emit('close')" />
|
||||
|
||||
<div class="shell">
|
||||
<form
|
||||
class="search-bar"
|
||||
@pointerup="onSearchBarClick($event)"
|
||||
@submit.prevent=""
|
||||
>
|
||||
<label
|
||||
:title="placeholder"
|
||||
id="localsearch-label"
|
||||
for="localsearch-input"
|
||||
>
|
||||
<svg
|
||||
class="search-icon"
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<g
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
>
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<path d="m21 21l-4.35-4.35" />
|
||||
</g>
|
||||
</svg>
|
||||
</label>
|
||||
<div class="search-actions before">
|
||||
<button
|
||||
class="back-button"
|
||||
:title="$t('modal.backButtonTitle')"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M19 12H5m7 7l-7-7l7-7"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
ref="searchInput"
|
||||
v-model="filterText"
|
||||
:placeholder="placeholder"
|
||||
id="localsearch-input"
|
||||
aria-labelledby="localsearch-label"
|
||||
class="search-input"
|
||||
/>
|
||||
<div class="search-actions">
|
||||
<button
|
||||
v-if="!disableDetailedView"
|
||||
class="toggle-layout-button"
|
||||
type="button"
|
||||
:class="{ 'detailed-list': showDetailedList }"
|
||||
:title="$t('modal.displayDetails')"
|
||||
@click="
|
||||
selectedIndex > -1 && (showDetailedList = !showDetailedList)
|
||||
"
|
||||
>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M3 14h7v7H3zM3 3h7v7H3zm11 1h7m-7 5h7m-7 6h7m-7 5h7"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="clear-button"
|
||||
type="reset"
|
||||
:disabled="disableReset"
|
||||
:title="$t('modal.resetButtonTitle')"
|
||||
@click="resetSearch"
|
||||
>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M20 5H9l-7 7l7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2Zm-2 4l-6 6m0-6l6 6"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ul
|
||||
ref="resultsEl"
|
||||
:id="results?.length ? 'localsearch-list' : undefined"
|
||||
:role="results?.length ? 'listbox' : undefined"
|
||||
:aria-labelledby="results?.length ? 'localsearch-label' : undefined"
|
||||
class="results"
|
||||
@mousemove="disableMouseOver = false"
|
||||
>
|
||||
<li
|
||||
v-for="(p, index) in results"
|
||||
:key="p.id"
|
||||
role="option"
|
||||
:aria-selected="selectedIndex === index ? 'true' : 'false'"
|
||||
>
|
||||
<a
|
||||
:href="p.id"
|
||||
class="result"
|
||||
:class="{
|
||||
selected: selectedIndex === index
|
||||
}"
|
||||
:aria-label="[...p.titles, p.title].join(' > ')"
|
||||
@mouseenter="!disableMouseOver && (selectedIndex = index)"
|
||||
@focusin="selectedIndex = index"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<div>
|
||||
<div class="titles">
|
||||
<span class="title-icon">#</span>
|
||||
<span
|
||||
v-for="(t, index) in p.titles"
|
||||
:key="index"
|
||||
class="title"
|
||||
>
|
||||
<span class="text" v-html="t" />
|
||||
<svg width="18" height="18" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="m9 18l6-6l-6-6"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="title main">
|
||||
<span class="text" v-html="p.title" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-if="showDetailedList" class="excerpt-wrapper">
|
||||
<div v-if="p.text" class="excerpt" inert>
|
||||
<div class="vp-doc" v-html="p.text" />
|
||||
</div>
|
||||
<div class="excerpt-gradient-bottom" />
|
||||
<div class="excerpt-gradient-top" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="filterText && !results.length && enableNoResults"
|
||||
class="no-results"
|
||||
>
|
||||
{{ $t('modal.noResultsText') }} "<strong>{{ filterText }}</strong
|
||||
>"
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="search-keyboard-shortcuts">
|
||||
<span>
|
||||
<kbd :aria-label="$t('modal.footer.navigateUpKeyAriaLabel')">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 19V5m-7 7l7-7l7 7"
|
||||
/>
|
||||
</svg>
|
||||
</kbd>
|
||||
<kbd :aria-label="$t('modal.footer.navigateDownKeyAriaLabel')">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 5v14m7-7l-7 7l-7-7"
|
||||
/>
|
||||
</svg>
|
||||
</kbd>
|
||||
{{ $t('modal.footer.navigateText') }}
|
||||
</span>
|
||||
<span>
|
||||
<kbd :aria-label="$t('modal.footer.selectKeyAriaLabel')">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24">
|
||||
<g
|
||||
fill="none"
|
||||
stroke="currentcolor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path d="m9 10l-5 5l5 5" />
|
||||
<path d="M20 4v7a4 4 0 0 1-4 4H4" />
|
||||
</g>
|
||||
</svg>
|
||||
</kbd>
|
||||
{{ $t('modal.footer.selectText') }}
|
||||
</span>
|
||||
<span>
|
||||
<kbd :aria-label="$t('modal.footer.closeKeyAriaLabel')">esc</kbd>
|
||||
{{ $t('modal.footer.closeText') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPLocalSearchBox {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.backdrop {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--vp-backdrop-bg-color);
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
|
||||
.shell {
|
||||
position: relative;
|
||||
padding: 12px;
|
||||
margin: 64px auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
background: var(--vp-local-search-bg);
|
||||
width: min(100vw - 60px, 900px);
|
||||
height: min-content;
|
||||
max-height: min(100vh - 128px, 900px);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.shell {
|
||||
margin: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
max-height: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.search-bar {
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-bar:focus-within {
|
||||
border-color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.search-icon {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
padding: 6px 12px;
|
||||
font-size: inherit;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.search-input {
|
||||
padding: 6px 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
@media (any-pointer: coarse) {
|
||||
.search-actions {
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.search-actions.before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.search-actions button {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.search-actions button:not([disabled]):hover,
|
||||
.toggle-layout-button.detailed-list {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.search-actions button.clear-button:disabled {
|
||||
opacity: 0.37;
|
||||
}
|
||||
|
||||
.search-keyboard-shortcuts {
|
||||
font-size: 0.8rem;
|
||||
opacity: 75%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
.search-keyboard-shortcuts span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.search-keyboard-shortcuts {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.search-keyboard-shortcuts kbd {
|
||||
background: rgba(128, 128, 128, 0.1);
|
||||
border-radius: 4px;
|
||||
padding: 3px 6px;
|
||||
min-width: 24px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
border: 1px solid rgba(128, 128, 128, 0.15);
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.results {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.result {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-radius: 4px;
|
||||
transition: none;
|
||||
line-height: 1rem;
|
||||
border: solid 2px var(--vp-local-search-result-border);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.result > div {
|
||||
margin: 12px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.result > div {
|
||||
margin: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.titles {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
position: relative;
|
||||
z-index: 1001;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.title.main {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.title-icon {
|
||||
opacity: 0.5;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.title svg {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.result.selected {
|
||||
--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);
|
||||
border-color: var(--vp-local-search-result-selected-border);
|
||||
}
|
||||
|
||||
.excerpt-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.excerpt {
|
||||
opacity: 75%;
|
||||
pointer-events: none;
|
||||
max-height: 140px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
opacity: 0.5;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.result.selected .excerpt {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.excerpt :deep(*) {
|
||||
font-size: 0.8rem !important;
|
||||
line-height: 130% !important;
|
||||
}
|
||||
|
||||
.titles :deep(mark),
|
||||
.excerpt :deep(mark) {
|
||||
background-color: var(--vp-local-search-highlight-bg);
|
||||
color: var(--vp-local-search-highlight-text);
|
||||
border-radius: 2px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.excerpt :deep(.vp-code-group) .tabs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.excerpt :deep(.vp-code-group) div[class*='language-'] {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.excerpt-gradient-bottom {
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
background: linear-gradient(transparent, var(--vp-local-search-result-bg));
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.excerpt-gradient-top {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
background: linear-gradient(var(--vp-local-search-result-bg), transparent);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.result.selected .titles,
|
||||
.result.selected .title-icon {
|
||||
color: var(--vp-c-brand-1) !important;
|
||||
}
|
||||
|
||||
.no-results {
|
||||
font-size: 0.9rem;
|
||||
text-align: center;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
svg {
|
||||
flex: none;
|
||||
}
|
||||
</style>
|
||||
72
node_modules/vitepress/dist/client/theme-default/components/VPMenu.vue
generated
vendored
72
node_modules/vitepress/dist/client/theme-default/components/VPMenu.vue
generated
vendored
@@ -1,72 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import VPMenuLink from './VPMenuLink.vue'
|
||||
import VPMenuGroup from './VPMenuGroup.vue'
|
||||
|
||||
defineProps<{
|
||||
items?: any[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPMenu">
|
||||
<div v-if="items" class="items">
|
||||
<template v-for="item in items" :key="item.text">
|
||||
<VPMenuLink v-if="'link' in item" :item="item" />
|
||||
<VPMenuGroup v-else :text="item.text" :items="item.items" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPMenu {
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
min-width: 128px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
background-color: var(--vp-c-bg-elv);
|
||||
box-shadow: var(--vp-shadow-3);
|
||||
transition: background-color 0.5s;
|
||||
max-height: calc(100vh - var(--vp-nav-height));
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.VPMenu :deep(.group) {
|
||||
margin: 0 -12px;
|
||||
padding: 0 12px 12px;
|
||||
}
|
||||
|
||||
.VPMenu :deep(.group + .group) {
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
padding: 11px 12px 12px;
|
||||
}
|
||||
|
||||
.VPMenu :deep(.group:last-child) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.VPMenu :deep(.group + .item) {
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
padding: 11px 16px 0;
|
||||
}
|
||||
|
||||
.VPMenu :deep(.item) {
|
||||
padding: 0 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.VPMenu :deep(.label) {
|
||||
flex-grow: 1;
|
||||
line-height: 28px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color .5s;
|
||||
}
|
||||
|
||||
.VPMenu :deep(.action) {
|
||||
padding-left: 24px;
|
||||
}
|
||||
</style>
|
||||
47
node_modules/vitepress/dist/client/theme-default/components/VPMenuGroup.vue
generated
vendored
47
node_modules/vitepress/dist/client/theme-default/components/VPMenuGroup.vue
generated
vendored
@@ -1,47 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import VPMenuLink from './VPMenuLink.vue'
|
||||
|
||||
defineProps<{
|
||||
text?: string
|
||||
items: any[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPMenuGroup">
|
||||
<p v-if="text" class="title">{{ text }}</p>
|
||||
|
||||
<template v-for="item in items">
|
||||
<VPMenuLink v-if="'link' in item" :item="item" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPMenuGroup {
|
||||
margin: 12px -12px 0;
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
padding: 12px 12px 0;
|
||||
}
|
||||
|
||||
.VPMenuGroup:first-child {
|
||||
margin-top: 0;
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.VPMenuGroup + .VPMenuGroup {
|
||||
margin-top: 12px;
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 0 12px;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--vp-c-text-2);
|
||||
white-space: nowrap;
|
||||
transition: color 0.25s;
|
||||
}
|
||||
</style>
|
||||
54
node_modules/vitepress/dist/client/theme-default/components/VPMenuLink.vue
generated
vendored
54
node_modules/vitepress/dist/client/theme-default/components/VPMenuLink.vue
generated
vendored
@@ -1,54 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { useData } from '../composables/data'
|
||||
import { isActive } from '../../shared'
|
||||
import VPLink from './VPLink.vue'
|
||||
|
||||
defineProps<{
|
||||
item: DefaultTheme.NavItemWithLink
|
||||
}>()
|
||||
|
||||
const { page } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPMenuLink">
|
||||
<VPLink
|
||||
:class="{ active: isActive(page.relativePath, item.activeMatch || item.link, !!item.activeMatch) }"
|
||||
:href="item.link"
|
||||
:target="item.target"
|
||||
:rel="item.rel"
|
||||
>
|
||||
{{ item.text }}
|
||||
</VPLink>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPMenuGroup + .VPMenuLink {
|
||||
margin: 12px -12px 0;
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
padding: 12px 12px 0;
|
||||
}
|
||||
|
||||
.link {
|
||||
display: block;
|
||||
border-radius: 6px;
|
||||
padding: 0 12px;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-1);
|
||||
white-space: nowrap;
|
||||
transition: background-color 0.25s, color 0.25s;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
background-color: var(--vp-c-default-soft);
|
||||
}
|
||||
|
||||
.link.active {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
</style>
|
||||
57
node_modules/vitepress/dist/client/theme-default/components/VPNav.vue
generated
vendored
57
node_modules/vitepress/dist/client/theme-default/components/VPNav.vue
generated
vendored
@@ -1,57 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { inBrowser } from 'vitepress'
|
||||
import { computed, provide, watchEffect } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { useNav } from '../composables/nav'
|
||||
import VPNavBar from './VPNavBar.vue'
|
||||
import VPNavScreen from './VPNavScreen.vue'
|
||||
|
||||
const { isScreenOpen, closeScreen, toggleScreen } = useNav()
|
||||
const { frontmatter } = useData()
|
||||
|
||||
const hasNavbar = computed(() => {
|
||||
return frontmatter.value.navbar !== false
|
||||
})
|
||||
|
||||
provide('close-screen', closeScreen)
|
||||
|
||||
watchEffect(() => {
|
||||
if (inBrowser) {
|
||||
document.documentElement.classList.toggle('hide-nav', !hasNavbar.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header v-if="hasNavbar" class="VPNav">
|
||||
<VPNavBar :is-screen-open="isScreenOpen" @toggle-screen="toggleScreen">
|
||||
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
|
||||
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>
|
||||
<template #nav-bar-content-before><slot name="nav-bar-content-before" /></template>
|
||||
<template #nav-bar-content-after><slot name="nav-bar-content-after" /></template>
|
||||
</VPNavBar>
|
||||
<VPNavScreen :open="isScreenOpen">
|
||||
<template #nav-screen-content-before><slot name="nav-screen-content-before" /></template>
|
||||
<template #nav-screen-content-after><slot name="nav-screen-content-after" /></template>
|
||||
</VPNavScreen>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNav {
|
||||
position: relative;
|
||||
top: var(--vp-layout-top-height, 0px);
|
||||
/*rtl:ignore*/
|
||||
left: 0;
|
||||
z-index: var(--vp-z-index-nav);
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
transition: background-color 0.5s;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNav {
|
||||
position: fixed;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
233
node_modules/vitepress/dist/client/theme-default/components/VPNavBar.vue
generated
vendored
233
node_modules/vitepress/dist/client/theme-default/components/VPNavBar.vue
generated
vendored
@@ -1,233 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useWindowScroll } from '@vueuse/core'
|
||||
import { ref, watchPostEffect } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { useSidebar } from '../composables/sidebar'
|
||||
import VPNavBarAppearance from './VPNavBarAppearance.vue'
|
||||
import VPNavBarExtra from './VPNavBarExtra.vue'
|
||||
import VPNavBarHamburger from './VPNavBarHamburger.vue'
|
||||
import VPNavBarMenu from './VPNavBarMenu.vue'
|
||||
import VPNavBarSearch from './VPNavBarSearch.vue'
|
||||
import VPNavBarSocialLinks from './VPNavBarSocialLinks.vue'
|
||||
import VPNavBarTitle from './VPNavBarTitle.vue'
|
||||
import VPNavBarTranslations from './VPNavBarTranslations.vue'
|
||||
|
||||
defineProps<{
|
||||
isScreenOpen: boolean
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
(e: 'toggle-screen'): void
|
||||
}>()
|
||||
|
||||
// @ts-ignore
|
||||
const { y } = useWindowScroll()
|
||||
const { hasSidebar } = useSidebar()
|
||||
const { frontmatter } = useData()
|
||||
|
||||
const classes = ref<Record<string, boolean>>({})
|
||||
|
||||
watchPostEffect(() => {
|
||||
classes.value = {
|
||||
'has-sidebar': hasSidebar.value,
|
||||
top: frontmatter.value.layout === 'home' && y.value === 0,
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPNavBar" :class="classes">
|
||||
<div class="container">
|
||||
<div class="title">
|
||||
<VPNavBarTitle>
|
||||
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
|
||||
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>
|
||||
</VPNavBarTitle>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="curtain" />
|
||||
<div class="content-body">
|
||||
<slot name="nav-bar-content-before" />
|
||||
<VPNavBarSearch class="search" />
|
||||
<VPNavBarMenu class="menu" />
|
||||
<VPNavBarTranslations class="translations" />
|
||||
<VPNavBarAppearance class="appearance" />
|
||||
<VPNavBarSocialLinks class="social-links" />
|
||||
<VPNavBarExtra class="extra" />
|
||||
<slot name="nav-bar-content-after" />
|
||||
<VPNavBarHamburger class="hamburger" :active="isScreenOpen" @click="$emit('toggle-screen')" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBar {
|
||||
position: relative;
|
||||
border-bottom: 1px solid transparent;
|
||||
padding: 0 8px 0 24px;
|
||||
height: var(--vp-nav-height);
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPNavBar {
|
||||
padding: 0 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNavBar.has-sidebar {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.VPNavBar:not(.has-sidebar):not(.top) {
|
||||
border-bottom-color: var(--vp-c-gutter);
|
||||
background-color: var(--vp-nav-bg-color);
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0 auto;
|
||||
max-width: calc(var(--vp-layout-max-width) - 64px);
|
||||
height: var(--vp-nav-height);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.container > .title,
|
||||
.container > .content {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.container :deep(*) {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNavBar.has-sidebar .container {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
flex-shrink: 0;
|
||||
height: calc(var(--vp-nav-height) - 1px);
|
||||
transition: background-color 0.5s;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNavBar.has-sidebar .title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
padding: 0 32px;
|
||||
width: var(--vp-sidebar-width);
|
||||
height: var(--vp-nav-height);
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.VPNavBar.has-sidebar .title {
|
||||
padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));
|
||||
width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px);
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNavBar.has-sidebar .content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding-right: 32px;
|
||||
padding-left: var(--vp-sidebar-width);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.VPNavBar.has-sidebar .content {
|
||||
padding-right: calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);
|
||||
padding-left: calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width));
|
||||
}
|
||||
}
|
||||
|
||||
.content-body {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: calc(var(--vp-nav-height) - 1px);
|
||||
transition: background-color 0.5s;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNavBar:not(.top) .content-body{
|
||||
position: relative;
|
||||
background-color: var(--vp-nav-bg-color);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.content-body {
|
||||
column-gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.menu + .translations::before,
|
||||
.menu + .appearance::before,
|
||||
.menu + .social-links::before,
|
||||
.translations + .appearance::before,
|
||||
.appearance + .social-links::before {
|
||||
margin-right: 8px;
|
||||
margin-left: 8px;
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background-color: var(--vp-c-divider);
|
||||
content: "";
|
||||
}
|
||||
|
||||
.menu + .appearance::before,
|
||||
.translations + .appearance::before {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.appearance + .social-links::before {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.social-links {
|
||||
margin-right: -8px;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNavBar.has-sidebar .curtain {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -31px;
|
||||
width: calc(100% - var(--vp-sidebar-width));
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.VPNavBar.has-sidebar .curtain::before {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
background: linear-gradient(var(--vp-c-bg), transparent 70%);
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.VPNavBar.has-sidebar .curtain {
|
||||
width: calc(100% - ((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
25
node_modules/vitepress/dist/client/theme-default/components/VPNavBarAppearance.vue
generated
vendored
25
node_modules/vitepress/dist/client/theme-default/components/VPNavBarAppearance.vue
generated
vendored
@@ -1,25 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useData } from '../composables/data'
|
||||
import VPSwitchAppearance from './VPSwitchAppearance.vue'
|
||||
|
||||
const { site } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="site.appearance && site.appearance !== 'force-dark'" class="VPNavBarAppearance">
|
||||
<VPSwitchAppearance />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBarAppearance {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.VPNavBarAppearance {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
94
node_modules/vitepress/dist/client/theme-default/components/VPNavBarExtra.vue
generated
vendored
94
node_modules/vitepress/dist/client/theme-default/components/VPNavBarExtra.vue
generated
vendored
@@ -1,94 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import VPFlyout from './VPFlyout.vue'
|
||||
import VPMenuLink from './VPMenuLink.vue'
|
||||
import VPSwitchAppearance from './VPSwitchAppearance.vue'
|
||||
import VPSocialLinks from './VPSocialLinks.vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { useLangs } from '../composables/langs'
|
||||
|
||||
const { site, theme } = useData()
|
||||
const { localeLinks, currentLang } = useLangs({ correspondingLink: true })
|
||||
|
||||
const hasExtraContent = computed(
|
||||
() =>
|
||||
(localeLinks.value.length && currentLang.value.label) ||
|
||||
site.value.appearance ||
|
||||
theme.value.socialLinks
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPFlyout v-if="hasExtraContent" class="VPNavBarExtra" label="extra navigation">
|
||||
<div v-if="localeLinks.length && currentLang.label" class="group translations">
|
||||
<p class="trans-title">{{ currentLang.label }}</p>
|
||||
|
||||
<template v-for="locale in localeLinks" :key="locale.link">
|
||||
<VPMenuLink :item="locale" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-if="site.appearance" class="group">
|
||||
<div class="item appearance">
|
||||
<p class="label">
|
||||
{{ theme.darkModeSwitchLabel || 'Appearance' }}
|
||||
</p>
|
||||
<div class="appearance-action">
|
||||
<VPSwitchAppearance />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="theme.socialLinks" class="group">
|
||||
<div class="item social-links">
|
||||
<VPSocialLinks class="social-links-list" :links="theme.socialLinks" />
|
||||
</div>
|
||||
</div>
|
||||
</VPFlyout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBarExtra {
|
||||
display: none;
|
||||
margin-right: -12px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPNavBarExtra {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.VPNavBarExtra {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.trans-title {
|
||||
padding: 0 24px 0 12px;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.item.appearance,
|
||||
.item.social-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.item.appearance {
|
||||
min-width: 176px;
|
||||
}
|
||||
|
||||
.appearance-action {
|
||||
margin-right: -2px;
|
||||
}
|
||||
|
||||
.social-links-list {
|
||||
margin: -4px -8px;
|
||||
}
|
||||
</style>
|
||||
79
node_modules/vitepress/dist/client/theme-default/components/VPNavBarHamburger.vue
generated
vendored
79
node_modules/vitepress/dist/client/theme-default/components/VPNavBarHamburger.vue
generated
vendored
@@ -1,79 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
active: boolean
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
(e: 'click'): void
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
type="button"
|
||||
class="VPNavBarHamburger"
|
||||
:class="{ active }"
|
||||
aria-label="mobile navigation"
|
||||
:aria-expanded="active"
|
||||
aria-controls="VPNavScreen"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<span class="container">
|
||||
<span class="top" />
|
||||
<span class="middle" />
|
||||
<span class="bottom" />
|
||||
</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBarHamburger {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 48px;
|
||||
height: var(--vp-nav-height);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPNavBarHamburger {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.VPNavBarHamburger:hover .top { top: 0; left: 0; transform: translateX(4px); }
|
||||
.VPNavBarHamburger:hover .middle { top: 6px; left: 0; transform: translateX(0); }
|
||||
.VPNavBarHamburger:hover .bottom { top: 12px; left: 0; transform: translateX(8px); }
|
||||
|
||||
.VPNavBarHamburger.active .top { top: 6px; transform: translateX(0) rotate(225deg); }
|
||||
.VPNavBarHamburger.active .middle { top: 6px; transform: translateX(16px); }
|
||||
.VPNavBarHamburger.active .bottom { top: 6px; transform: translateX(0) rotate(135deg); }
|
||||
|
||||
.VPNavBarHamburger.active:hover .top,
|
||||
.VPNavBarHamburger.active:hover .middle,
|
||||
.VPNavBarHamburger.active:hover .bottom {
|
||||
background-color: var(--vp-c-text-2);
|
||||
transition: top .25s, background-color .25s, transform .25s;
|
||||
}
|
||||
|
||||
.top,
|
||||
.middle,
|
||||
.bottom {
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 2px;
|
||||
background-color: var(--vp-c-text-1);
|
||||
transition: top .25s, background-color .5s, transform .25s;
|
||||
}
|
||||
|
||||
.top { top: 0; left: 0; transform: translateX(0); }
|
||||
.middle { top: 6px; left: 0; transform: translateX(8px); }
|
||||
.bottom { top: 12px; left: 0; transform: translateX(4px); }
|
||||
</style>
|
||||
29
node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenu.vue
generated
vendored
29
node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenu.vue
generated
vendored
@@ -1,29 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useData } from '../composables/data'
|
||||
import VPNavBarMenuLink from './VPNavBarMenuLink.vue'
|
||||
import VPNavBarMenuGroup from './VPNavBarMenuGroup.vue'
|
||||
|
||||
const { theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav v-if="theme.nav" aria-labelledby="main-nav-aria-label" class="VPNavBarMenu">
|
||||
<span id="main-nav-aria-label" class="visually-hidden">Main Navigation</span>
|
||||
<template v-for="item in theme.nav" :key="item.text">
|
||||
<VPNavBarMenuLink v-if="'link' in item" :item="item" />
|
||||
<VPNavBarMenuGroup v-else :item="item" />
|
||||
</template>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBarMenu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPNavBarMenu {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
42
node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenuGroup.vue
generated
vendored
42
node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenuGroup.vue
generated
vendored
@@ -1,42 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { computed } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { isActive } from '../../shared'
|
||||
import VPFlyout from './VPFlyout.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
item: DefaultTheme.NavItemWithChildren
|
||||
}>()
|
||||
|
||||
const { page } = useData()
|
||||
|
||||
const isChildActive = (navItem: DefaultTheme.NavItem) => {
|
||||
if ('link' in navItem) {
|
||||
return isActive(
|
||||
page.value.relativePath,
|
||||
navItem.link,
|
||||
!!props.item.activeMatch
|
||||
)
|
||||
} else {
|
||||
return navItem.items.some(isChildActive)
|
||||
}
|
||||
}
|
||||
|
||||
const childrenActive = computed(() => isChildActive(props.item))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPFlyout
|
||||
:class="{
|
||||
VPNavBarMenuGroup: true,
|
||||
active: isActive(
|
||||
page.relativePath,
|
||||
item.activeMatch,
|
||||
!!item.activeMatch
|
||||
) || childrenActive
|
||||
}"
|
||||
:button="item.text"
|
||||
:items="item.items"
|
||||
/>
|
||||
</template>
|
||||
52
node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenuLink.vue
generated
vendored
52
node_modules/vitepress/dist/client/theme-default/components/VPNavBarMenuLink.vue
generated
vendored
@@ -1,52 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { useData } from '../composables/data'
|
||||
import { isActive } from '../../shared'
|
||||
import VPLink from './VPLink.vue'
|
||||
|
||||
defineProps<{
|
||||
item: DefaultTheme.NavItemWithLink
|
||||
}>()
|
||||
|
||||
const { page } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPLink
|
||||
:class="{
|
||||
VPNavBarMenuLink: true,
|
||||
active: isActive(
|
||||
page.relativePath,
|
||||
item.activeMatch || item.link,
|
||||
!!item.activeMatch
|
||||
)
|
||||
}"
|
||||
:href="item.link"
|
||||
:target="item.target"
|
||||
:rel="item.rel"
|
||||
tabindex="0"
|
||||
>
|
||||
<span v-html="item.text"></span>
|
||||
</VPLink>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBarMenuLink {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
line-height: var(--vp-nav-height);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPNavBarMenuLink.active {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.VPNavBarMenuLink:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
</style>
|
||||
209
node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearch.vue
generated
vendored
209
node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearch.vue
generated
vendored
@@ -1,209 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import '@docsearch/css'
|
||||
import { onKeyStroke } from '@vueuse/core'
|
||||
import {
|
||||
computed,
|
||||
defineAsyncComponent,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref
|
||||
} from 'vue'
|
||||
import type { DefaultTheme } from '../../shared'
|
||||
import { useData } from '../composables/data'
|
||||
import VPNavBarSearchButton from './VPNavBarSearchButton.vue'
|
||||
|
||||
const VPLocalSearchBox = __VP_LOCAL_SEARCH__
|
||||
? defineAsyncComponent(() => import('./VPLocalSearchBox.vue'))
|
||||
: () => null
|
||||
|
||||
const VPAlgoliaSearchBox = __ALGOLIA__
|
||||
? defineAsyncComponent(() => import('./VPAlgoliaSearchBox.vue'))
|
||||
: () => null
|
||||
|
||||
const { theme, localeIndex } = useData()
|
||||
|
||||
// to avoid loading the docsearch js upfront (which is more than 1/3 of the
|
||||
// payload), we delay initializing it until the user has actually clicked or
|
||||
// hit the hotkey to invoke it.
|
||||
const loaded = ref(false)
|
||||
const actuallyLoaded = ref(false)
|
||||
|
||||
const buttonText = computed(() => {
|
||||
const options = theme.value.search?.options ?? theme.value.algolia
|
||||
|
||||
return (
|
||||
options?.locales?.[localeIndex.value]?.translations?.button?.buttonText ||
|
||||
options?.translations?.button?.buttonText ||
|
||||
'Search'
|
||||
)
|
||||
})
|
||||
|
||||
const preconnect = () => {
|
||||
const id = 'VPAlgoliaPreconnect'
|
||||
|
||||
const rIC = window.requestIdleCallback || setTimeout
|
||||
rIC(() => {
|
||||
const preconnect = document.createElement('link')
|
||||
preconnect.id = id
|
||||
preconnect.rel = 'preconnect'
|
||||
preconnect.href = `https://${
|
||||
((theme.value.search?.options as DefaultTheme.AlgoliaSearchOptions) ??
|
||||
theme.value.algolia)!.appId
|
||||
}-dsn.algolia.net`
|
||||
preconnect.crossOrigin = ''
|
||||
document.head.appendChild(preconnect)
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!__ALGOLIA__) {
|
||||
return
|
||||
}
|
||||
|
||||
preconnect()
|
||||
|
||||
const handleSearchHotKey = (event: KeyboardEvent) => {
|
||||
if (
|
||||
(event.key.toLowerCase() === 'k' && (event.metaKey || event.ctrlKey)) ||
|
||||
(!isEditingContent(event) && event.key === '/')
|
||||
) {
|
||||
event.preventDefault()
|
||||
load()
|
||||
remove()
|
||||
}
|
||||
}
|
||||
|
||||
const remove = () => {
|
||||
window.removeEventListener('keydown', handleSearchHotKey)
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', handleSearchHotKey)
|
||||
|
||||
onUnmounted(remove)
|
||||
})
|
||||
|
||||
function load() {
|
||||
if (!loaded.value) {
|
||||
loaded.value = true
|
||||
setTimeout(poll, 16)
|
||||
}
|
||||
}
|
||||
|
||||
function poll() {
|
||||
// programmatically open the search box after initialize
|
||||
const e = new Event('keydown') as any
|
||||
|
||||
e.key = 'k'
|
||||
e.metaKey = true
|
||||
|
||||
window.dispatchEvent(e)
|
||||
|
||||
setTimeout(() => {
|
||||
if (!document.querySelector('.DocSearch-Modal')) {
|
||||
poll()
|
||||
}
|
||||
}, 16)
|
||||
}
|
||||
|
||||
function isEditingContent(event: KeyboardEvent): boolean {
|
||||
const element = event.target as HTMLElement
|
||||
const tagName = element.tagName
|
||||
|
||||
return (
|
||||
element.isContentEditable ||
|
||||
tagName === 'INPUT' ||
|
||||
tagName === 'SELECT' ||
|
||||
tagName === 'TEXTAREA'
|
||||
)
|
||||
}
|
||||
|
||||
// Local search
|
||||
|
||||
const showSearch = ref(false)
|
||||
|
||||
if (__VP_LOCAL_SEARCH__) {
|
||||
onKeyStroke('k', (event) => {
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
event.preventDefault()
|
||||
showSearch.value = true
|
||||
}
|
||||
})
|
||||
|
||||
onKeyStroke('/', (event) => {
|
||||
if (!isEditingContent(event)) {
|
||||
event.preventDefault()
|
||||
showSearch.value = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const provider = __ALGOLIA__ ? 'algolia' : __VP_LOCAL_SEARCH__ ? 'local' : ''
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPNavBarSearch">
|
||||
<template v-if="provider === 'local'">
|
||||
<VPLocalSearchBox
|
||||
v-if="showSearch"
|
||||
:placeholder="buttonText"
|
||||
@close="showSearch = false"
|
||||
/>
|
||||
|
||||
<div id="local-search">
|
||||
<VPNavBarSearchButton
|
||||
:placeholder="buttonText"
|
||||
@click="showSearch = true"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="provider === 'algolia'">
|
||||
<VPAlgoliaSearchBox
|
||||
v-if="loaded"
|
||||
:algolia="theme.search?.options ?? theme.algolia"
|
||||
@vue:beforeMount="actuallyLoaded = true"
|
||||
/>
|
||||
|
||||
<div v-if="!actuallyLoaded" id="docsearch">
|
||||
<VPNavBarSearchButton :placeholder="buttonText" @click="load" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.VPNavBarSearch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPNavBarSearch {
|
||||
flex-grow: 1;
|
||||
padding-left: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPNavBarSearch {
|
||||
padding-left: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.dark .DocSearch-Footer {
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
}
|
||||
|
||||
.DocSearch-Form {
|
||||
border: 1px solid var(--vp-c-brand-1);
|
||||
background-color: var(--vp-c-white);
|
||||
}
|
||||
|
||||
.dark .DocSearch-Form {
|
||||
background-color: var(--vp-c-default-soft);
|
||||
}
|
||||
|
||||
.DocSearch-Screen-Icon > svg {
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
210
node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearchButton.vue
generated
vendored
210
node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearchButton.vue
generated
vendored
@@ -1,210 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
placeholder: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button type="button" class="DocSearch DocSearch-Button" aria-label="Search">
|
||||
<span class="DocSearch-Button-Container">
|
||||
<svg
|
||||
class="DocSearch-Search-Icon"
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
aria-label="search icon"
|
||||
>
|
||||
<path
|
||||
d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
<span class="DocSearch-Button-Placeholder">{{ placeholder }}</span>
|
||||
</span>
|
||||
<span class="DocSearch-Button-Keys">
|
||||
<kbd class="DocSearch-Button-Key"></kbd>
|
||||
<kbd class="DocSearch-Button-Key">K</kbd>
|
||||
</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
[class*='DocSearch'] {
|
||||
--docsearch-primary-color: var(--vp-c-brand-1);
|
||||
--docsearch-highlight-color: var(--docsearch-primary-color);
|
||||
--docsearch-text-color: var(--vp-c-text-1);
|
||||
--docsearch-muted-color: var(--vp-c-text-2);
|
||||
--docsearch-searchbox-shadow: none;
|
||||
--docsearch-searchbox-background: transparent;
|
||||
--docsearch-searchbox-focus-background: transparent;
|
||||
--docsearch-key-gradient: transparent;
|
||||
--docsearch-key-shadow: none;
|
||||
--docsearch-modal-background: var(--vp-c-bg-soft);
|
||||
--docsearch-footer-background: var(--vp-c-bg);
|
||||
}
|
||||
|
||||
.dark [class*='DocSearch'] {
|
||||
--docsearch-modal-shadow: none;
|
||||
--docsearch-footer-shadow: none;
|
||||
--docsearch-logo-color: var(--vp-c-text-2);
|
||||
--docsearch-hit-background: var(--vp-c-default-soft);
|
||||
--docsearch-hit-color: var(--vp-c-text-2);
|
||||
--docsearch-hit-shadow: none;
|
||||
}
|
||||
|
||||
.DocSearch-Button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 48px;
|
||||
height: 55px;
|
||||
background: transparent;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
|
||||
.DocSearch-Button:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.DocSearch-Button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
.DocSearch-Button:focus:not(:focus-visible) {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.DocSearch-Button {
|
||||
justify-content: flex-start;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 8px;
|
||||
padding: 0 10px 0 12px;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background-color: var(--vp-c-bg-alt);
|
||||
}
|
||||
|
||||
.DocSearch-Button:hover {
|
||||
border-color: var(--vp-c-brand-1);
|
||||
background: var(--vp-c-bg-alt);
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Search-Icon {
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: var(--vp-c-text-1);
|
||||
fill: currentColor;
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.DocSearch-Button:hover .DocSearch-Search-Icon {
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.DocSearch-Button .DocSearch-Search-Icon {
|
||||
top: 1px;
|
||||
margin-right: 8px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Placeholder {
|
||||
display: none;
|
||||
margin-top: 2px;
|
||||
padding: 0 16px 0 0;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.DocSearch-Button:hover .DocSearch-Button-Placeholder {
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.DocSearch-Button .DocSearch-Button-Placeholder {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Keys {
|
||||
/*rtl:ignore*/
|
||||
direction: ltr;
|
||||
display: none;
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.DocSearch-Button .DocSearch-Button-Keys {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Key {
|
||||
display: block;
|
||||
margin: 2px 0 0 0;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
/*rtl:begin:ignore*/
|
||||
border-right: none;
|
||||
border-radius: 4px 0 0 4px;
|
||||
padding-left: 6px;
|
||||
/*rtl:end:ignore*/
|
||||
min-width: 0;
|
||||
width: auto;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
font-family: var(--vp-font-family-base);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
transition: color 0.5s, border-color 0.5s;
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Key + .DocSearch-Button-Key {
|
||||
/*rtl:begin:ignore*/
|
||||
border-right: 1px solid var(--vp-c-divider);
|
||||
border-left: none;
|
||||
border-radius: 0 4px 4px 0;
|
||||
padding-left: 2px;
|
||||
padding-right: 6px;
|
||||
/*rtl:end:ignore*/
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Key:first-child {
|
||||
font-size: 0 !important;
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Key:first-child:after {
|
||||
content: 'Ctrl';
|
||||
font-size: 12px;
|
||||
letter-spacing: normal;
|
||||
color: var(--docsearch-muted-color);
|
||||
}
|
||||
|
||||
.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after {
|
||||
content: '\2318';
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Key:first-child > * {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
27
node_modules/vitepress/dist/client/theme-default/components/VPNavBarSocialLinks.vue
generated
vendored
27
node_modules/vitepress/dist/client/theme-default/components/VPNavBarSocialLinks.vue
generated
vendored
@@ -1,27 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useData } from '../composables/data'
|
||||
import VPSocialLinks from './VPSocialLinks.vue'
|
||||
|
||||
const { theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPSocialLinks
|
||||
v-if="theme.socialLinks"
|
||||
class="VPNavBarSocialLinks"
|
||||
:links="theme.socialLinks"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBarSocialLinks {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.VPNavBarSocialLinks {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
52
node_modules/vitepress/dist/client/theme-default/components/VPNavBarTitle.vue
generated
vendored
52
node_modules/vitepress/dist/client/theme-default/components/VPNavBarTitle.vue
generated
vendored
@@ -1,52 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useData } from '../composables/data'
|
||||
import { useLangs } from '../composables/langs'
|
||||
import { useSidebar } from '../composables/sidebar'
|
||||
import { normalizeLink } from '../support/utils'
|
||||
import VPImage from './VPImage.vue'
|
||||
|
||||
const { site, theme } = useData()
|
||||
const { hasSidebar } = useSidebar()
|
||||
const { currentLang } = useLangs()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPNavBarTitle" :class="{ 'has-sidebar': hasSidebar }">
|
||||
<a class="title" :href="theme.logoLink ?? normalizeLink(currentLang.link)">
|
||||
<slot name="nav-bar-title-before" />
|
||||
<VPImage v-if="theme.logo" class="logo" :image="theme.logo" />
|
||||
<template v-if="theme.siteTitle">{{ theme.siteTitle }}</template>
|
||||
<template v-else-if="theme.siteTitle === undefined">{{ site.title }}</template>
|
||||
<slot name="nav-bar-title-after" />
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid transparent;
|
||||
width: 100%;
|
||||
height: var(--vp-nav-height);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--vp-c-text-1);
|
||||
transition: opacity 0.25s;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.title {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.VPNavBarTitle.has-sidebar .title {
|
||||
border-bottom-color: var(--vp-c-divider);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.logo) {
|
||||
margin-right: 8px;
|
||||
height: var(--vp-nav-logo-height);
|
||||
}
|
||||
</style>
|
||||
48
node_modules/vitepress/dist/client/theme-default/components/VPNavBarTranslations.vue
generated
vendored
48
node_modules/vitepress/dist/client/theme-default/components/VPNavBarTranslations.vue
generated
vendored
@@ -1,48 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import VPIconLanguages from './icons/VPIconLanguages.vue'
|
||||
import VPFlyout from './VPFlyout.vue'
|
||||
import VPMenuLink from './VPMenuLink.vue'
|
||||
import { useData } from '../composables/data'
|
||||
import { useLangs } from '../composables/langs'
|
||||
|
||||
const { theme } = useData()
|
||||
const { localeLinks, currentLang } = useLangs({ correspondingLink: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPFlyout
|
||||
v-if="localeLinks.length && currentLang.label"
|
||||
class="VPNavBarTranslations"
|
||||
:icon="VPIconLanguages"
|
||||
:label="theme.langMenuLabel || 'Change language'"
|
||||
>
|
||||
<div class="items">
|
||||
<p class="title">{{ currentLang.label }}</p>
|
||||
|
||||
<template v-for="locale in localeLinks" :key="locale.link">
|
||||
<VPMenuLink :item="locale" />
|
||||
</template>
|
||||
</div>
|
||||
</VPFlyout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavBarTranslations {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.VPNavBarTranslations {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 0 24px 0 12px;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
</style>
|
||||
99
node_modules/vitepress/dist/client/theme-default/components/VPNavScreen.vue
generated
vendored
99
node_modules/vitepress/dist/client/theme-default/components/VPNavScreen.vue
generated
vendored
@@ -1,99 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { useScrollLock } from '@vueuse/core'
|
||||
import { inBrowser } from 'vitepress'
|
||||
import { ref } from 'vue'
|
||||
import VPNavScreenAppearance from './VPNavScreenAppearance.vue'
|
||||
import VPNavScreenMenu from './VPNavScreenMenu.vue'
|
||||
import VPNavScreenSocialLinks from './VPNavScreenSocialLinks.vue'
|
||||
import VPNavScreenTranslations from './VPNavScreenTranslations.vue'
|
||||
|
||||
defineProps<{
|
||||
open: boolean
|
||||
}>()
|
||||
|
||||
const screen = ref<HTMLElement | null>(null)
|
||||
const isLocked = useScrollLock(inBrowser ? document.body : null)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition
|
||||
name="fade"
|
||||
@enter="isLocked = true"
|
||||
@after-leave="isLocked = false"
|
||||
>
|
||||
<div v-if="open" class="VPNavScreen" ref="screen" id="VPNavScreen">
|
||||
<div class="container">
|
||||
<slot name="nav-screen-content-before" />
|
||||
<VPNavScreenMenu class="menu" />
|
||||
<VPNavScreenTranslations class="translations" />
|
||||
<VPNavScreenAppearance class="appearance" />
|
||||
<VPNavScreenSocialLinks class="social-links" />
|
||||
<slot name="nav-screen-content-after" />
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavScreen {
|
||||
position: fixed;
|
||||
top: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 1px);
|
||||
/*rtl:ignore*/
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/*rtl:ignore*/
|
||||
left: 0;
|
||||
padding: 0 32px;
|
||||
width: 100%;
|
||||
background-color: var(--vp-nav-screen-bg-color);
|
||||
overflow-y: auto;
|
||||
transition: background-color 0.5s;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.VPNavScreen.fade-enter-active,
|
||||
.VPNavScreen.fade-leave-active {
|
||||
transition: opacity 0.25s;
|
||||
}
|
||||
|
||||
.VPNavScreen.fade-enter-active .container,
|
||||
.VPNavScreen.fade-leave-active .container {
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
|
||||
.VPNavScreen.fade-enter-from,
|
||||
.VPNavScreen.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.VPNavScreen.fade-enter-from .container,
|
||||
.VPNavScreen.fade-leave-to .container {
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPNavScreen {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
padding: 24px 0 96px;
|
||||
max-width: 288px;
|
||||
}
|
||||
|
||||
.menu + .translations,
|
||||
.menu + .appearance,
|
||||
.translations + .appearance {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.menu + .social-links {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.appearance + .social-links {
|
||||
margin-top: 16px;
|
||||
}
|
||||
</style>
|
||||
33
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenAppearance.vue
generated
vendored
33
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenAppearance.vue
generated
vendored
@@ -1,33 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useData } from '../composables/data'
|
||||
import VPSwitchAppearance from './VPSwitchAppearance.vue'
|
||||
|
||||
const { site, theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="site.appearance" class="VPNavScreenAppearance">
|
||||
<p class="text">
|
||||
{{ theme.darkModeSwitchLabel || 'Appearance' }}
|
||||
</p>
|
||||
<VPSwitchAppearance />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavScreenAppearance {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
padding: 12px 14px 12px 16px;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
}
|
||||
|
||||
.text {
|
||||
line-height: 24px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
</style>
|
||||
23
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenu.vue
generated
vendored
23
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenu.vue
generated
vendored
@@ -1,23 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useData } from '../composables/data'
|
||||
import VPNavScreenMenuLink from './VPNavScreenMenuLink.vue'
|
||||
import VPNavScreenMenuGroup from './VPNavScreenMenuGroup.vue'
|
||||
|
||||
const { theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav v-if="theme.nav" class="VPNavScreenMenu">
|
||||
<template v-for="item in theme.nav" :key="item.text">
|
||||
<VPNavScreenMenuLink
|
||||
v-if="'link' in item"
|
||||
:item="item"
|
||||
/>
|
||||
<VPNavScreenMenuGroup
|
||||
v-else
|
||||
:text="item.text || ''"
|
||||
:items="item.items"
|
||||
/>
|
||||
</template>
|
||||
</nav>
|
||||
</template>
|
||||
115
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuGroup.vue
generated
vendored
115
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuGroup.vue
generated
vendored
@@ -1,115 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import VPIconPlus from './icons/VPIconPlus.vue'
|
||||
import VPNavScreenMenuGroupLink from './VPNavScreenMenuGroupLink.vue'
|
||||
import VPNavScreenMenuGroupSection from './VPNavScreenMenuGroupSection.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
text: string
|
||||
items: any[]
|
||||
}>()
|
||||
|
||||
const isOpen = ref(false)
|
||||
|
||||
const groupId = computed(() =>
|
||||
`NavScreenGroup-${props.text.replace(' ', '-').toLowerCase()}`
|
||||
)
|
||||
|
||||
function toggle() {
|
||||
isOpen.value = !isOpen.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPNavScreenMenuGroup" :class="{ open: isOpen }">
|
||||
<button
|
||||
class="button"
|
||||
:aria-controls="groupId"
|
||||
:aria-expanded="isOpen"
|
||||
@click="toggle"
|
||||
>
|
||||
<span class="button-text">{{ text }}</span>
|
||||
<VPIconPlus class="button-icon" />
|
||||
</button>
|
||||
|
||||
<div :id="groupId" class="items">
|
||||
<template v-for="item in items" :key="item.text">
|
||||
<div v-if="'link' in item" :key="item.text" class="item">
|
||||
<VPNavScreenMenuGroupLink :item="item" />
|
||||
</div>
|
||||
|
||||
<div v-else class="group">
|
||||
<VPNavScreenMenuGroupSection
|
||||
:text="item.text"
|
||||
:items="item.items"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavScreenMenuGroup {
|
||||
border-bottom: 1px solid var(--vp-c-divider);
|
||||
height: 48px;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.5s;
|
||||
}
|
||||
|
||||
.VPNavScreenMenuGroup .items {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.VPNavScreenMenuGroup.open .items {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.VPNavScreenMenuGroup.open {
|
||||
padding-bottom: 10px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.VPNavScreenMenuGroup.open .button {
|
||||
padding-bottom: 6px;
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.VPNavScreenMenuGroup.open .button-icon {
|
||||
/*rtl:ignore*/
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.button {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 4px 11px 0;
|
||||
width: 100%;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
fill: var(--vp-c-text-2);
|
||||
transition: fill 0.5s, transform 0.25s;
|
||||
}
|
||||
|
||||
.group:first-child {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.group + .group,
|
||||
.group + .item {
|
||||
padding-top: 4px;
|
||||
}
|
||||
</style>
|
||||
39
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuGroupLink.vue
generated
vendored
39
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuGroupLink.vue
generated
vendored
@@ -1,39 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { inject } from 'vue'
|
||||
import VPLink from './VPLink.vue'
|
||||
|
||||
defineProps<{
|
||||
item: DefaultTheme.NavItemWithLink
|
||||
}>()
|
||||
|
||||
const closeScreen = inject('close-screen') as () => void
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPLink
|
||||
class="VPNavScreenMenuGroupLink"
|
||||
:href="item.link"
|
||||
:target="item.target"
|
||||
:rel="item.rel"
|
||||
@click="closeScreen"
|
||||
>
|
||||
{{ item.text }}
|
||||
</VPLink>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavScreenMenuGroupLink {
|
||||
display: block;
|
||||
margin-left: 12px;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPNavScreenMenuGroupLink:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
</style>
|
||||
@@ -1,34 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import VPNavScreenMenuGroupLink from './VPNavScreenMenuGroupLink.vue'
|
||||
|
||||
defineProps<{
|
||||
text?: string
|
||||
items: DefaultTheme.NavItemWithLink[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPNavScreenMenuGroupSection">
|
||||
<p v-if="text" class="title">{{ text }}</p>
|
||||
<VPNavScreenMenuGroupLink
|
||||
v-for="item in items"
|
||||
:key="item.text"
|
||||
:item="item"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavScreenMenuGroupSection {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.title {
|
||||
line-height: 32px;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
</style>
|
||||
40
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuLink.vue
generated
vendored
40
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenMenuLink.vue
generated
vendored
@@ -1,40 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { inject } from 'vue'
|
||||
import VPLink from './VPLink.vue'
|
||||
|
||||
defineProps<{
|
||||
item: DefaultTheme.NavItemWithLink
|
||||
}>()
|
||||
|
||||
const closeScreen = inject('close-screen') as () => void
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPLink
|
||||
class="VPNavScreenMenuLink"
|
||||
:href="item.link"
|
||||
:target="item.target"
|
||||
:rel="item.rel"
|
||||
@click="closeScreen"
|
||||
>
|
||||
{{ item.text }}
|
||||
</VPLink>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavScreenMenuLink {
|
||||
display: block;
|
||||
border-bottom: 1px solid var(--vp-c-divider);
|
||||
padding: 12px 0 11px;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-1);
|
||||
transition: border-color 0.25s, color 0.25s;
|
||||
}
|
||||
|
||||
.VPNavScreenMenuLink:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
</style>
|
||||
14
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenSocialLinks.vue
generated
vendored
14
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenSocialLinks.vue
generated
vendored
@@ -1,14 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useData } from '../composables/data'
|
||||
import VPSocialLinks from './VPSocialLinks.vue'
|
||||
|
||||
const { theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPSocialLinks
|
||||
v-if="theme.socialLinks"
|
||||
class="VPNavScreenSocialLinks"
|
||||
:links="theme.socialLinks"
|
||||
/>
|
||||
</template>
|
||||
77
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenTranslations.vue
generated
vendored
77
node_modules/vitepress/dist/client/theme-default/components/VPNavScreenTranslations.vue
generated
vendored
@@ -1,77 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import VPIconChevronDown from './icons/VPIconChevronDown.vue'
|
||||
import VPIconLanguages from './icons/VPIconLanguages.vue'
|
||||
import { useLangs } from '../composables/langs'
|
||||
import VPLink from './VPLink.vue'
|
||||
|
||||
const { localeLinks, currentLang } = useLangs({ correspondingLink: true })
|
||||
const isOpen = ref(false)
|
||||
|
||||
function toggle() {
|
||||
isOpen.value = !isOpen.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="localeLinks.length && currentLang.label"
|
||||
class="VPNavScreenTranslations"
|
||||
:class="{ open: isOpen }"
|
||||
>
|
||||
<button class="title" @click="toggle">
|
||||
<VPIconLanguages class="icon lang" />
|
||||
{{ currentLang.label }}
|
||||
<VPIconChevronDown class="icon chevron" />
|
||||
</button>
|
||||
|
||||
<ul class="list">
|
||||
<li v-for="locale in localeLinks" :key="locale.link" class="item">
|
||||
<VPLink class="link" :href="locale.link">{{ locale.text }}</VPLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPNavScreenTranslations {
|
||||
height: 24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.VPNavScreenTranslations.open {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.icon.lang {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.icon.chevron {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.list {
|
||||
padding: 4px 0 0 24px;
|
||||
}
|
||||
|
||||
.link {
|
||||
line-height: 32px;
|
||||
font-size: 13px;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
</style>
|
||||
7
node_modules/vitepress/dist/client/theme-default/components/VPPage.vue
generated
vendored
7
node_modules/vitepress/dist/client/theme-default/components/VPPage.vue
generated
vendored
@@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<div class="VPPage">
|
||||
<slot name="page-top" />
|
||||
<Content />
|
||||
<slot name="page-bottom" />
|
||||
</div>
|
||||
</template>
|
||||
139
node_modules/vitepress/dist/client/theme-default/components/VPSidebar.vue
generated
vendored
139
node_modules/vitepress/dist/client/theme-default/components/VPSidebar.vue
generated
vendored
@@ -1,139 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { useScrollLock } from '@vueuse/core'
|
||||
import { inBrowser } from 'vitepress'
|
||||
import { ref, watch } from 'vue'
|
||||
import { useSidebar } from '../composables/sidebar'
|
||||
import VPSidebarItem from './VPSidebarItem.vue'
|
||||
|
||||
const { sidebarGroups, hasSidebar } = useSidebar()
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
}>()
|
||||
|
||||
// a11y: focus Nav element when menu has opened
|
||||
const navEl = ref<HTMLElement | null>(null)
|
||||
const isLocked = useScrollLock(inBrowser ? document.body : null)
|
||||
|
||||
watch(
|
||||
[props, navEl],
|
||||
() => {
|
||||
if (props.open) {
|
||||
isLocked.value = true
|
||||
navEl.value?.focus()
|
||||
} else isLocked.value = false
|
||||
},
|
||||
{ immediate: true, flush: 'post' }
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<aside
|
||||
v-if="hasSidebar"
|
||||
class="VPSidebar"
|
||||
:class="{ open }"
|
||||
ref="navEl"
|
||||
@click.stop
|
||||
>
|
||||
<div class="curtain" />
|
||||
|
||||
<nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1">
|
||||
<span class="visually-hidden" id="sidebar-aria-label">
|
||||
Sidebar Navigation
|
||||
</span>
|
||||
|
||||
<slot name="sidebar-nav-before" />
|
||||
|
||||
<div v-for="item in sidebarGroups" :key="item.text" class="group">
|
||||
<VPSidebarItem :item="item" :depth="0" />
|
||||
</div>
|
||||
|
||||
<slot name="sidebar-nav-after" />
|
||||
</nav>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPSidebar {
|
||||
position: fixed;
|
||||
top: var(--vp-layout-top-height, 0px);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: var(--vp-z-index-sidebar);
|
||||
padding: 32px 32px 96px;
|
||||
width: calc(100vw - 64px);
|
||||
max-width: 320px;
|
||||
background-color: var(--vp-sidebar-bg-color);
|
||||
opacity: 0;
|
||||
box-shadow: var(--vp-c-shadow-3);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
transform: translateX(-100%);
|
||||
transition: opacity 0.5s, transform 0.25s ease;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.VPSidebar.open {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(0);
|
||||
transition: opacity 0.25s,
|
||||
transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
|
||||
}
|
||||
|
||||
.dark .VPSidebar {
|
||||
box-shadow: var(--vp-shadow-1);
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPSidebar {
|
||||
z-index: 1;
|
||||
padding-top: var(--vp-nav-height);
|
||||
padding-bottom: 128px;
|
||||
width: var(--vp-sidebar-width);
|
||||
max-width: 100%;
|
||||
background-color: var(--vp-sidebar-bg-color);
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
box-shadow: none;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.VPSidebar {
|
||||
padding-left: max(32px, calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));
|
||||
width: calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.curtain {
|
||||
position: sticky;
|
||||
top: -64px;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
margin-top: calc(var(--vp-nav-height) * -1);
|
||||
margin-right: -32px;
|
||||
margin-left: -32px;
|
||||
height: var(--vp-nav-height);
|
||||
background-color: var(--vp-sidebar-bg-color);
|
||||
}
|
||||
}
|
||||
|
||||
.nav {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.group + .group {
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.group {
|
||||
padding-top: 10px;
|
||||
width: calc(var(--vp-sidebar-width) - 64px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
253
node_modules/vitepress/dist/client/theme-default/components/VPSidebarItem.vue
generated
vendored
253
node_modules/vitepress/dist/client/theme-default/components/VPSidebarItem.vue
generated
vendored
@@ -1,253 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { useSidebarControl } from '../composables/sidebar'
|
||||
import VPIconChevronRight from './icons/VPIconChevronRight.vue'
|
||||
import VPLink from './VPLink.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
item: DefaultTheme.SidebarItem
|
||||
depth: number
|
||||
}>()
|
||||
|
||||
const {
|
||||
collapsed,
|
||||
collapsible,
|
||||
isLink,
|
||||
isActiveLink,
|
||||
hasActiveLink,
|
||||
hasChildren,
|
||||
toggle
|
||||
} = useSidebarControl(computed(() => props.item))
|
||||
|
||||
const sectionTag = computed(() => (hasChildren.value ? 'section' : `div`))
|
||||
|
||||
const linkTag = computed(() => (isLink.value ? 'a' : 'div'))
|
||||
|
||||
const textTag = computed(() => {
|
||||
return !hasChildren.value
|
||||
? 'p'
|
||||
: props.depth + 2 === 7
|
||||
? 'p'
|
||||
: `h${props.depth + 2}`
|
||||
})
|
||||
|
||||
const itemRole = computed(() => (isLink.value ? undefined : 'button'))
|
||||
|
||||
const classes = computed(() => [
|
||||
[`level-${props.depth}`],
|
||||
{ collapsible: collapsible.value },
|
||||
{ collapsed: collapsed.value },
|
||||
{ 'is-link': isLink.value },
|
||||
{ 'is-active': isActiveLink.value },
|
||||
{ 'has-active': hasActiveLink.value }
|
||||
])
|
||||
|
||||
function onItemInteraction(e: MouseEvent | Event) {
|
||||
if ('key' in e && e.key !== 'Enter') {
|
||||
return
|
||||
}
|
||||
!props.item.link && toggle()
|
||||
}
|
||||
|
||||
function onCaretClick() {
|
||||
props.item.link && toggle()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component :is="sectionTag" class="VPSidebarItem" :class="classes">
|
||||
<div
|
||||
v-if="item.text"
|
||||
class="item"
|
||||
:role="itemRole"
|
||||
v-on="
|
||||
item.items
|
||||
? { click: onItemInteraction, keydown: onItemInteraction }
|
||||
: {}
|
||||
"
|
||||
:tabindex="item.items && 0"
|
||||
>
|
||||
<div class="indicator" />
|
||||
|
||||
<VPLink
|
||||
v-if="item.link"
|
||||
:tag="linkTag"
|
||||
class="link"
|
||||
:href="item.link"
|
||||
:rel="item.rel"
|
||||
:target="item.target"
|
||||
>
|
||||
<component :is="textTag" class="text" v-html="item.text" />
|
||||
</VPLink>
|
||||
<component v-else :is="textTag" class="text" v-html="item.text" />
|
||||
|
||||
<div
|
||||
v-if="item.collapsed != null"
|
||||
class="caret"
|
||||
role="button"
|
||||
aria-label="toggle section"
|
||||
@click="onCaretClick"
|
||||
@keydown.enter="onCaretClick"
|
||||
tabindex="0"
|
||||
>
|
||||
<VPIconChevronRight class="caret-icon" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="item.items && item.items.length" class="items">
|
||||
<template v-if="depth < 5">
|
||||
<VPSidebarItem
|
||||
v-for="i in item.items"
|
||||
:key="i.text"
|
||||
:item="i"
|
||||
:depth="depth + 1"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPSidebarItem.level-0 {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
.VPSidebarItem.collapsed.level-0 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.VPSidebarItem.collapsible > .item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
bottom: 6px;
|
||||
left: -17px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
.VPSidebarItem.level-2.is-active > .item > .indicator,
|
||||
.VPSidebarItem.level-3.is-active > .item > .indicator,
|
||||
.VPSidebarItem.level-4.is-active > .item > .indicator,
|
||||
.VPSidebarItem.level-5.is-active > .item > .indicator {
|
||||
background-color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.text {
|
||||
flex-grow: 1;
|
||||
padding: 4px 0;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPSidebarItem.level-0 .text {
|
||||
font-weight: 700;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.VPSidebarItem.level-1 .text,
|
||||
.VPSidebarItem.level-2 .text,
|
||||
.VPSidebarItem.level-3 .text,
|
||||
.VPSidebarItem.level-4 .text,
|
||||
.VPSidebarItem.level-5 .text {
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.VPSidebarItem.level-0.is-link > .item > .link:hover .text,
|
||||
.VPSidebarItem.level-1.is-link > .item > .link:hover .text,
|
||||
.VPSidebarItem.level-2.is-link > .item > .link:hover .text,
|
||||
.VPSidebarItem.level-3.is-link > .item > .link:hover .text,
|
||||
.VPSidebarItem.level-4.is-link > .item > .link:hover .text,
|
||||
.VPSidebarItem.level-5.is-link > .item > .link:hover .text {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.VPSidebarItem.level-0.has-active > .item > .text,
|
||||
.VPSidebarItem.level-1.has-active > .item > .text,
|
||||
.VPSidebarItem.level-2.has-active > .item > .text,
|
||||
.VPSidebarItem.level-3.has-active > .item > .text,
|
||||
.VPSidebarItem.level-4.has-active > .item > .text,
|
||||
.VPSidebarItem.level-5.has-active > .item > .text,
|
||||
.VPSidebarItem.level-0.has-active > .item > .link > .text,
|
||||
.VPSidebarItem.level-1.has-active > .item > .link > .text,
|
||||
.VPSidebarItem.level-2.has-active > .item > .link > .text,
|
||||
.VPSidebarItem.level-3.has-active > .item > .link > .text,
|
||||
.VPSidebarItem.level-4.has-active > .item > .link > .text,
|
||||
.VPSidebarItem.level-5.has-active > .item > .link > .text {
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.VPSidebarItem.level-0.is-active > .item .link > .text,
|
||||
.VPSidebarItem.level-1.is-active > .item .link > .text,
|
||||
.VPSidebarItem.level-2.is-active > .item .link > .text,
|
||||
.VPSidebarItem.level-3.is-active > .item .link > .text,
|
||||
.VPSidebarItem.level-4.is-active > .item .link > .text,
|
||||
.VPSidebarItem.level-5.is-active > .item .link > .text {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.caret {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: -7px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
color: var(--vp-c-text-3);
|
||||
cursor: pointer;
|
||||
transition: color 0.25s;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.item:hover .caret {
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.item:hover .caret:hover {
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.caret-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
fill: currentColor;
|
||||
transform: rotate(90deg);
|
||||
transition: transform 0.25s;
|
||||
}
|
||||
|
||||
.VPSidebarItem.collapsed .caret-icon {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
.VPSidebarItem.level-1 .items,
|
||||
.VPSidebarItem.level-2 .items,
|
||||
.VPSidebarItem.level-3 .items,
|
||||
.VPSidebarItem.level-4 .items,
|
||||
.VPSidebarItem.level-5 .items {
|
||||
border-left: 1px solid var(--vp-c-divider);
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.VPSidebarItem.collapsed .items {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
68
node_modules/vitepress/dist/client/theme-default/components/VPSkipLink.vue
generated
vendored
68
node_modules/vitepress/dist/client/theme-default/components/VPSkipLink.vue
generated
vendored
@@ -1,68 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { useRoute } from 'vitepress'
|
||||
|
||||
const route = useRoute()
|
||||
const backToTop = ref()
|
||||
|
||||
watch(() => route.path, () => backToTop.value.focus())
|
||||
|
||||
function focusOnTargetAnchor({ target }: Event) {
|
||||
const el = document.getElementById(
|
||||
decodeURIComponent((target as HTMLAnchorElement).hash).slice(1)
|
||||
)
|
||||
|
||||
if (el) {
|
||||
const removeTabIndex = () => {
|
||||
el.removeAttribute('tabindex')
|
||||
el.removeEventListener('blur', removeTabIndex)
|
||||
}
|
||||
|
||||
el.setAttribute('tabindex', '-1')
|
||||
el.addEventListener('blur', removeTabIndex)
|
||||
el.focus()
|
||||
window.scrollTo(0, 0)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span ref="backToTop" tabindex="-1" />
|
||||
<a
|
||||
href="#VPContent"
|
||||
class="VPSkipLink visually-hidden"
|
||||
@click="focusOnTargetAnchor"
|
||||
>
|
||||
Skip to content
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPSkipLink {
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
padding: 8px 16px;
|
||||
z-index: 999;
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: var(--vp-c-brand-1);
|
||||
box-shadow: var(--vp-shadow-3);
|
||||
background-color: var(--vp-c-bg);
|
||||
}
|
||||
|
||||
.VPSkipLink:focus {
|
||||
height: auto;
|
||||
width: auto;
|
||||
clip: auto;
|
||||
clip-path: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.VPSkipLink {
|
||||
top: 14px;
|
||||
left: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
51
node_modules/vitepress/dist/client/theme-default/components/VPSocialLink.vue
generated
vendored
51
node_modules/vitepress/dist/client/theme-default/components/VPSocialLink.vue
generated
vendored
@@ -1,51 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { computed } from 'vue'
|
||||
import { icons } from '../support/socialIcons'
|
||||
|
||||
const props = defineProps<{
|
||||
icon: DefaultTheme.SocialLinkIcon
|
||||
link: string
|
||||
ariaLabel?: string
|
||||
}>()
|
||||
|
||||
const svg = computed(() => {
|
||||
if (typeof props.icon === 'object') return props.icon.svg
|
||||
return icons[props.icon]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
class="VPSocialLink no-icon"
|
||||
:href="link"
|
||||
:aria-label="ariaLabel ?? (typeof icon === 'string' ? icon : '')"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
v-html="svg"
|
||||
>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPSocialLink {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color 0.5s;
|
||||
}
|
||||
|
||||
.VPSocialLink:hover {
|
||||
color: var(--vp-c-text-1);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.VPSocialLink > :deep(svg) {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: currentColor;
|
||||
}
|
||||
</style>
|
||||
27
node_modules/vitepress/dist/client/theme-default/components/VPSocialLinks.vue
generated
vendored
27
node_modules/vitepress/dist/client/theme-default/components/VPSocialLinks.vue
generated
vendored
@@ -1,27 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import VPSocialLink from './VPSocialLink.vue'
|
||||
|
||||
defineProps<{
|
||||
links: DefaultTheme.SocialLink[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPSocialLinks">
|
||||
<VPSocialLink
|
||||
v-for="{ link, icon, ariaLabel } in links"
|
||||
:key="link"
|
||||
:icon="icon"
|
||||
:link="link"
|
||||
:ariaLabel="ariaLabel"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPSocialLinks {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
48
node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue
generated
vendored
48
node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue
generated
vendored
@@ -1,48 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { GridSize } from '../composables/sponsor-grid'
|
||||
import type { Sponsor } from './VPSponsorsGrid.vue'
|
||||
import { computed } from 'vue'
|
||||
import VPSponsorsGrid from './VPSponsorsGrid.vue'
|
||||
|
||||
export interface Sponsors {
|
||||
tier?: string
|
||||
size?: GridSize
|
||||
items: Sponsor[]
|
||||
}
|
||||
interface Props {
|
||||
mode?: 'normal' | 'aside'
|
||||
tier?: string
|
||||
size?: GridSize
|
||||
data: Sponsors[] | Sponsor[]
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
mode: 'normal'
|
||||
})
|
||||
|
||||
const sponsors = computed(() => {
|
||||
const isSponsors = props.data.some((s) => {
|
||||
return 'items' in s
|
||||
})
|
||||
|
||||
if (isSponsors) {
|
||||
return props.data as Sponsors[]
|
||||
}
|
||||
|
||||
return [
|
||||
{ tier: props.tier, size: props.size, items: props.data as Sponsor[] }
|
||||
]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPSponsors vp-sponsor" :class="[mode]">
|
||||
<section
|
||||
v-for="(sponsor, index) in sponsors"
|
||||
:key="index"
|
||||
class="vp-sponsor-section"
|
||||
>
|
||||
<h3 v-if="sponsor.tier" class="vp-sponsor-tier">{{ sponsor.tier }}</h3>
|
||||
<VPSponsorsGrid :size="sponsor.size" :data="sponsor.items" />
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
48
node_modules/vitepress/dist/client/theme-default/components/VPSponsorsGrid.vue
generated
vendored
48
node_modules/vitepress/dist/client/theme-default/components/VPSponsorsGrid.vue
generated
vendored
@@ -1,48 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { GridSize } from '../composables/sponsor-grid'
|
||||
import { ref } from 'vue'
|
||||
import { useSponsorsGrid } from '../composables/sponsor-grid'
|
||||
|
||||
export interface Sponsor {
|
||||
name: string
|
||||
img: string
|
||||
url: string
|
||||
}
|
||||
interface Props {
|
||||
size?: GridSize
|
||||
data: Sponsor[]
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
size: 'medium'
|
||||
})
|
||||
|
||||
const el = ref(null)
|
||||
|
||||
useSponsorsGrid({ el, size: props.size })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPSponsorsGrid vp-sponsor-grid" :class="[size]" ref="el">
|
||||
<div
|
||||
v-for="sponsor in data"
|
||||
:key="sponsor.name"
|
||||
class="vp-sponsor-grid-item"
|
||||
>
|
||||
<a
|
||||
class="vp-sponsor-grid-link"
|
||||
:href="sponsor.url"
|
||||
target="_blank"
|
||||
rel="sponsored noopener"
|
||||
>
|
||||
<article class="vp-sponsor-grid-box">
|
||||
<h4 class="visually-hidden">{{ sponsor.name }}</h4>
|
||||
<img
|
||||
class="vp-sponsor-grid-image"
|
||||
:src="sponsor.img"
|
||||
:alt="sponsor.name"
|
||||
/>
|
||||
</article>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
63
node_modules/vitepress/dist/client/theme-default/components/VPSwitch.vue
generated
vendored
63
node_modules/vitepress/dist/client/theme-default/components/VPSwitch.vue
generated
vendored
@@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<button class="VPSwitch" type="button" role="switch">
|
||||
<span class="check">
|
||||
<span class="icon" v-if="$slots.default">
|
||||
<slot />
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPSwitch {
|
||||
position: relative;
|
||||
border-radius: 11px;
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 22px;
|
||||
flex-shrink: 0;
|
||||
border: 1px solid var(--vp-input-border-color);
|
||||
background-color: var(--vp-input-switch-bg-color);
|
||||
transition: border-color 0.25s !important;
|
||||
}
|
||||
|
||||
.VPSwitch:hover {
|
||||
border-color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.check {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
/*rtl:ignore*/
|
||||
left: 1px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--vp-c-neutral-inverse);
|
||||
box-shadow: var(--vp-shadow-1);
|
||||
transition: transform 0.25s !important;
|
||||
}
|
||||
|
||||
.icon {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon :deep(svg) {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
fill: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.dark .icon :deep(svg) {
|
||||
fill: var(--vp-c-text-1);
|
||||
transition: opacity 0.25s !important;
|
||||
}
|
||||
</style>
|
||||
48
node_modules/vitepress/dist/client/theme-default/components/VPSwitchAppearance.vue
generated
vendored
48
node_modules/vitepress/dist/client/theme-default/components/VPSwitchAppearance.vue
generated
vendored
@@ -1,48 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
import { inject } from 'vue'
|
||||
import { useData } from '../composables/data'
|
||||
import VPSwitch from './VPSwitch.vue'
|
||||
import VPIconMoon from './icons/VPIconMoon.vue'
|
||||
import VPIconSun from './icons/VPIconSun.vue'
|
||||
|
||||
const { isDark } = useData()
|
||||
|
||||
const toggleAppearance = inject('toggle-appearance', () => {
|
||||
isDark.value = !isDark.value
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPSwitch
|
||||
title="toggle dark mode"
|
||||
class="VPSwitchAppearance"
|
||||
:aria-checked="isDark"
|
||||
@click="toggleAppearance"
|
||||
>
|
||||
<VPIconSun class="sun" />
|
||||
<VPIconMoon class="moon" />
|
||||
</VPSwitch>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.sun {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.moon {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.dark .sun {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.dark .moon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dark .VPSwitchAppearance :deep(.check) {
|
||||
/*rtl:ignore*/
|
||||
transform: translateX(18px);
|
||||
}
|
||||
</style>
|
||||
66
node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue
generated
vendored
66
node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue
generated
vendored
@@ -1,66 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import { computed } from 'vue'
|
||||
import VPTeamMembersItem from './VPTeamMembersItem.vue'
|
||||
|
||||
interface Props {
|
||||
size?: 'small' | 'medium'
|
||||
members: DefaultTheme.TeamMember[]
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
size: 'medium'
|
||||
})
|
||||
|
||||
const classes = computed(() => [props.size, `count-${props.members.length}`])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="VPTeamMembers" :class="classes">
|
||||
<div class="container">
|
||||
<div v-for="member in members" :key="member.name" class="item">
|
||||
<VPTeamMembersItem :size="size" :member="member" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPTeamMembers.small .container {
|
||||
grid-template-columns: repeat(auto-fit, minmax(224px, 1fr));
|
||||
}
|
||||
|
||||
.VPTeamMembers.small.count-1 .container {
|
||||
max-width: 276px;
|
||||
}
|
||||
.VPTeamMembers.small.count-2 .container {
|
||||
max-width: calc(276px * 2 + 24px);
|
||||
}
|
||||
.VPTeamMembers.small.count-3 .container {
|
||||
max-width: calc(276px * 3 + 24px * 2);
|
||||
}
|
||||
|
||||
.VPTeamMembers.medium .container {
|
||||
grid-template-columns: repeat(auto-fit, minmax(256px, 1fr));
|
||||
}
|
||||
|
||||
@media (min-width: 375px) {
|
||||
.VPTeamMembers.medium .container {
|
||||
grid-template-columns: repeat(auto-fit, minmax(288px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
.VPTeamMembers.medium.count-1 .container {
|
||||
max-width: 368px;
|
||||
}
|
||||
.VPTeamMembers.medium.count-2 .container {
|
||||
max-width: calc(368px * 2 + 24px);
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
gap: 24px;
|
||||
margin: 0 auto;
|
||||
max-width: 1152px;
|
||||
}
|
||||
</style>
|
||||
228
node_modules/vitepress/dist/client/theme-default/components/VPTeamMembersItem.vue
generated
vendored
228
node_modules/vitepress/dist/client/theme-default/components/VPTeamMembersItem.vue
generated
vendored
@@ -1,228 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import type { DefaultTheme } from 'vitepress/theme'
|
||||
import VPIconHeart from './icons/VPIconHeart.vue'
|
||||
import VPLink from './VPLink.vue'
|
||||
import VPSocialLinks from './VPSocialLinks.vue'
|
||||
|
||||
interface Props {
|
||||
size?: 'small' | 'medium'
|
||||
member: DefaultTheme.TeamMember
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
size: 'medium'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article class="VPTeamMembersItem" :class="[size]">
|
||||
<div class="profile">
|
||||
<figure class="avatar">
|
||||
<img class="avatar-img" :src="member.avatar" :alt="member.name" />
|
||||
</figure>
|
||||
<div class="data">
|
||||
<h1 class="name">
|
||||
{{ member.name }}
|
||||
</h1>
|
||||
<p v-if="member.title || member.org" class="affiliation">
|
||||
<span v-if="member.title" class="title">
|
||||
{{ member.title }}
|
||||
</span>
|
||||
<span v-if="member.title && member.org" class="at"> @ </span>
|
||||
<VPLink
|
||||
v-if="member.org"
|
||||
class="org"
|
||||
:class="{ link: member.orgLink }"
|
||||
:href="member.orgLink"
|
||||
no-icon
|
||||
>
|
||||
{{ member.org }}
|
||||
</VPLink>
|
||||
</p>
|
||||
<p v-if="member.desc" class="desc" v-html="member.desc" />
|
||||
<div v-if="member.links" class="links">
|
||||
<VPSocialLinks :links="member.links" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="member.sponsor" class="sp">
|
||||
<VPLink class="sp-link" :href="member.sponsor" no-icon>
|
||||
<VPIconHeart class="sp-icon" /> Sponsor
|
||||
</VPLink>
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPTeamMembersItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
border-radius: 12px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.small .profile {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.small .data {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.small .avatar {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.small .name {
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.small .affiliation {
|
||||
padding-top: 4px;
|
||||
line-height: 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.small .desc {
|
||||
padding-top: 12px;
|
||||
line-height: 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.small .links {
|
||||
margin: 0 -16px -20px;
|
||||
padding: 10px 0 0;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.medium .profile {
|
||||
padding: 48px 32px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.medium .data {
|
||||
padding-top: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.medium .avatar {
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.medium .name {
|
||||
letter-spacing: 0.15px;
|
||||
line-height: 28px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.medium .affiliation {
|
||||
padding-top: 4px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.medium .desc {
|
||||
padding-top: 16px;
|
||||
max-width: 288px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.VPTeamMembersItem.medium .links {
|
||||
margin: 0 -16px -12px;
|
||||
padding: 16px 12px 0;
|
||||
}
|
||||
|
||||
.profile {
|
||||
flex-grow: 1;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
}
|
||||
|
||||
.data {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
margin: 0 auto;
|
||||
border-radius: 50%;
|
||||
box-shadow: var(--vp-shadow-3);
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.affiliation {
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.org.link {
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.org.link:hover {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.desc :deep(a) {
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-brand-1);
|
||||
text-decoration-style: dotted;
|
||||
transition: color 0.25s;
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.sp-link {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-sponsor);
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
transition: color 0.25s, background-color 0.25s;
|
||||
}
|
||||
|
||||
.sp .sp-link.link:hover,
|
||||
.sp .sp-link.link:focus {
|
||||
outline: none;
|
||||
color: var(--vp-c-white);
|
||||
background-color: var(--vp-c-sponsor);
|
||||
}
|
||||
|
||||
.sp-icon {
|
||||
margin-right: 8px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: currentColor;
|
||||
}
|
||||
</style>
|
||||
53
node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue
generated
vendored
53
node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue
generated
vendored
@@ -1,53 +0,0 @@
|
||||
<template>
|
||||
<div class="VPTeamPage">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPTeamPage {
|
||||
padding-bottom: 96px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPTeamPage {
|
||||
padding-bottom: 128px;
|
||||
}
|
||||
}
|
||||
|
||||
:slotted(.VPTeamPageSection + .VPTeamPageSection),
|
||||
:slotted(.VPTeamMembers + .VPTeamPageSection) {
|
||||
margin-top: 64px;
|
||||
}
|
||||
|
||||
:slotted(.VPTeamMembers + .VPTeamMembers) {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
:slotted(.VPTeamPageTitle + .VPTeamPageSection) {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
:slotted(.VPTeamPageSection + .VPTeamPageSection),
|
||||
:slotted(.VPTeamMembers + .VPTeamPageSection) {
|
||||
margin-top: 96px;
|
||||
}
|
||||
}
|
||||
|
||||
:slotted(.VPTeamMembers) {
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
:slotted(.VPTeamMembers) {
|
||||
padding: 0 48px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
:slotted(.VPTeamMembers) {
|
||||
padding: 0 64px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
77
node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue
generated
vendored
77
node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue
generated
vendored
@@ -1,77 +0,0 @@
|
||||
<template>
|
||||
<section class="VPTeamPageSection">
|
||||
<div class="title">
|
||||
<div class="title-line" />
|
||||
<h2 v-if="$slots.title" class="title-text">
|
||||
<slot name="title" />
|
||||
</h2>
|
||||
</div>
|
||||
<p v-if="$slots.lead" class="lead">
|
||||
<slot name="lead" />
|
||||
</p>
|
||||
<div v-if="$slots.members" class="members">
|
||||
<slot name="members" />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPTeamPageSection {
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPTeamPageSection {
|
||||
padding: 0 48px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPTeamPageSection {
|
||||
padding: 0 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 1152px;
|
||||
text-align: center;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.title-line {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: var(--vp-c-divider);
|
||||
}
|
||||
|
||||
.title-text {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 0 24px;
|
||||
letter-spacing: 0;
|
||||
line-height: 32px;
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
background-color: var(--vp-c-bg);
|
||||
}
|
||||
|
||||
.lead {
|
||||
margin: 0 auto;
|
||||
max-width: 480px;
|
||||
padding-top: 12px;
|
||||
text-align: center;
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.members {
|
||||
padding-top: 40px;
|
||||
}
|
||||
</style>
|
||||
63
node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue
generated
vendored
63
node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue
generated
vendored
@@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<div class="VPTeamPageTitle">
|
||||
<h1 v-if="$slots.title" class="title">
|
||||
<slot name="title" />
|
||||
</h1>
|
||||
<p v-if="$slots.lead" class="lead">
|
||||
<slot name="lead" />
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.VPTeamPageTitle {
|
||||
padding: 48px 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.VPTeamPageTitle {
|
||||
padding: 64px 48px 48px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 960px) {
|
||||
.VPTeamPageTitle {
|
||||
padding: 80px 64px 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
letter-spacing: 0;
|
||||
line-height: 44px;
|
||||
font-size: 36px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.title {
|
||||
letter-spacing: -0.5px;
|
||||
line-height: 56px;
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.lead {
|
||||
margin: 0 auto;
|
||||
max-width: 512px;
|
||||
padding-top: 12px;
|
||||
line-height: 24px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.lead {
|
||||
max-width: 592px;
|
||||
letter-spacing: 0.15px;
|
||||
line-height: 28px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,8 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
||||
<path d="M21,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,11,21,11z" />
|
||||
<path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z" />
|
||||
<path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z" />
|
||||
<path d="M21,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,19,21,19z" />
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,8 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
||||
<path d="M17,11H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,11,17,11z" />
|
||||
<path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z" />
|
||||
<path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z" />
|
||||
<path d="M17,19H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S17.6,19,17,19z" />
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,8 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
||||
<path d="M21,11H7c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S21.6,11,21,11z" />
|
||||
<path d="M21,7H3C2.4,7,2,6.6,2,6s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,7,21,7z" />
|
||||
<path d="M21,15H3c-0.6,0-1-0.4-1-1s0.4-1,1-1h18c0.6,0,1,0.4,1,1S21.6,15,21,15z" />
|
||||
<path d="M21,19H7c-0.6,0-1-0.4-1-1s0.4-1,1-1h14c0.6,0,1,0.4,1,1S21.6,19,21,19z" />
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,7 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,5 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
||||
<path d="M12,16c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l5.3,5.3l5.3-5.3c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4l-6,6C12.5,15.9,12.3,16,12,16z" />
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,5 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
||||
<path d="M15,19c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4l6-6c0.4-0.4,1-0.4,1.4,0s0.4,1,0,1.4L10.4,12l5.3,5.3c0.4,0.4,0.4,1,0,1.4C15.5,18.9,15.3,19,15,19z" />
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,5 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
||||
<path d="M9,19c-0.3,0-0.5-0.1-0.7-0.3c-0.4-0.4-0.4-1,0-1.4l5.3-5.3L8.3,6.7c-0.4-0.4-0.4-1,0-1.4s1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4l-6,6C9.5,18.9,9.3,19,9,19z" />
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,5 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 24 24">
|
||||
<path d="M18,16c-0.3,0-0.5-0.1-0.7-0.3L12,10.4l-5.3,5.3c-0.4,0.4-1,0.4-1.4,0s-0.4-1,0-1.4l6-6c0.4-0.4,1-0.4,1.4,0l6,6c0.4,0.4,0.4,1,0,1.4C18.5,15.9,18.3,16,18,16z" />
|
||||
</svg>
|
||||
</template>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user