diff options
Diffstat (limited to 'docs/api')
| -rw-r--r-- | docs/api/.gitignore | 8 | ||||
| -rw-r--r-- | docs/api/ApiIndex.vue | 240 | ||||
| -rw-r--r-- | docs/api/api-types.ts | 26 | ||||
| -rw-r--r-- | docs/api/index.md | 12 |
4 files changed, 286 insertions, 0 deletions
diff --git a/docs/api/.gitignore b/docs/api/.gitignore index 3d5066c5..fc720b3c 100644 --- a/docs/api/.gitignore +++ b/docs/api/.gitignore @@ -1,3 +1,11 @@ +# Markdown *.md +!index.md !localization.md + +# TypeScript +*.ts +!api-types.ts + +# JSON *.json diff --git a/docs/api/ApiIndex.vue b/docs/api/ApiIndex.vue new file mode 100644 index 00000000..0846d9f2 --- /dev/null +++ b/docs/api/ApiIndex.vue @@ -0,0 +1,240 @@ +<!-- This content is mostly copied over from https://github.com/vuejs/docs/blob/main/src/api/ApiIndex.vue --> + +<script setup lang="ts"> +import { computed, ref } from 'vue'; +import apiSearchIndex from './api-search-index.json'; +import { APIGroup } from './api-types'; + +const query = ref(''); +const normalize = (s: string) => s.toLowerCase().replace(/-/g, ' '); + +const filtered = computed(() => { + const q = normalize(query.value); + const matches = (text: string) => normalize(text).includes(q); + + return (apiSearchIndex as APIGroup[]) + .map((section) => { + // section title match + if (matches(section.text)) { + return section; + } + + // filter groups + const matchedGroups = section.items + .map((item) => { + // group title match + if (matches(item.text)) { + return item; + } + // filter headers + const matchedHeaders = item.headers.filter( + ({ text, anchor }) => matches(text) || matches(anchor) + ); + return matchedHeaders.length + ? { text: item.text, link: item.link, headers: matchedHeaders } + : null; + }) + .filter((i) => i); + + return matchedGroups.length + ? { text: section.text, items: matchedGroups } + : null; + }) + .filter((i) => i) as APIGroup[]; +}); + +// same as vitepress' slugify logic +function slugify(text: string): string { + return ( + text + // Replace special characters + .replace(/[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g, '-') + // Remove continuous separators + .replace(/\-{2,}/g, '-') + // Remove prefixing and trailing separators + .replace(/^\-+|\-+$/g, '') + // ensure it doesn't start with a number (like #123) + .replace(/^(\d)/, '_$1') + // // lowercase + // .toLowerCase() + ); +} +</script> + +<template> + <div id="api-index"> + <div class="header"> + <h1>API Reference</h1> + <div class="api-filter"> + <label for="api-filter">Filter</label> + <input + type="search" + placeholder="Enter keyword" + id="api-filter" + v-model="query" + /> + </div> + </div> + + <div v-for="section of filtered" :key="section.text" class="api-section"> + <h2 :id="slugify(section.text)">{{ section.text }}</h2> + <div class="api-groups"> + <div v-for="item of section.items" :key="item.text" class="api-group"> + <h3>{{ item.text }}</h3> + <ul> + <li v-for="h of item.headers" :key="h.anchor"> + <a :href="item.link + '.html#' + slugify(h.anchor)">{{ + h.anchor + }}</a> + </li> + </ul> + </div> + </div> + </div> + + <div v-if="!filtered.length" class="no-match"> + No API matching "{{ query }}" found. + </div> + </div> +</template> + +<style scoped> +#api-index { + max-width: 1024px; + margin: 0px auto; + padding: 64px 32px; +} + +h1, +h2, +h3 { + font-weight: 600; + line-height: 1; +} + +h1, +h2 { + letter-spacing: -0.02em; +} + +h1 { + font-size: 38px; +} + +h2 { + font-size: 24px; + color: var(--vp-c-text-1); + margin: 36px 0; + transition: color 0.5s; + padding-top: 36px; + border-top: 1px solid var(--vp-c-divider-light); +} + +h3 { + letter-spacing: -0.01em; + color: var(--vp-c-green); + font-size: 18px; + margin-bottom: 1em; + transition: color 0.5s; +} + +.api-section { + margin-bottom: 64px; +} + +.api-groups a { + font-size: 15px; + font-weight: 500; + line-height: 2; + color: var(--vp-c-text-code); + transition: color 0.5s; +} + +.dark .api-groups a { + font-weight: 400; +} + +.api-groups a:hover { + color: var(--vp-c-green); + transition: none; +} + +.api-group { + break-inside: avoid; + overflow: auto; + margin-bottom: 20px; + background-color: var(--vp-c-bg-soft); + border-radius: 8px; + padding: 28px 32px; + transition: background-color 0.5s; +} + +.header { + display: flex; + align-items: center; + justify-content: space-between; +} + +.api-filter { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 1rem; +} + +.api-filter input { + border: 1px solid var(--vp-c-divider); + border-radius: 8px; + padding: 6px 12px; +} + +.api-filter:focus { + border-color: var(--vp-c-green-light); +} + +.no-match { + font-size: 1.2em; + color: var(--vp-c-text-3); + text-align: center; + margin-top: 36px; + padding-top: 36px; + border-top: 1px solid var(--vp-c-divider-light); +} + +@media (max-width: 768px) { + #api-index { + padding: 42px 24px; + } + + h1 { + font-size: 32px; + margin-bottom: 24px; + } + + h2 { + font-size: 22px; + margin: 42px 0 32px; + padding-top: 32px; + } + + .api-groups a { + font-size: 14px; + } + + .header { + display: block; + } +} + +@media (min-width: 768px) { + .api-groups { + columns: 2; + } +} + +@media (min-width: 1024px) { + .api-groups { + columns: 3; + } +} +</style> diff --git a/docs/api/api-types.ts b/docs/api/api-types.ts new file mode 100644 index 00000000..f5dcd659 --- /dev/null +++ b/docs/api/api-types.ts @@ -0,0 +1,26 @@ +// These interfaces are copied over from https://github.com/vuejs/docs/blob/main/src/api/api.data.ts + +/** + * Represents a link to e.g. a Faker-Module method within the API search index page. + */ +export interface APIHeader { + anchor: string; + text: string; +} + +/** + * Represents a container for e.g. a Faker-Module within the API search index page. + */ +export interface APIItem { + text: string; + link: string; + headers: APIHeader[]; +} + +/** + * Represents a whole section within the API search index page. + */ +export interface APIGroup { + text: string; + items: APIItem[]; +} diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 00000000..d962f905 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,12 @@ +--- +layout: page +title: API Reference +sidebar: false +footer: false +--- + +<script setup> +import ApiIndex from './ApiIndex.vue' +</script> + +<ApiIndex /> |
