mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(site): migrate search from Pagefind to Algolia DocSearch v4 (#941)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
9ce94ee2d3
commit
9ef1e61b63
@@ -45,7 +45,7 @@ const { class: className, dark = false } = Astro.props;
|
||||
>
|
||||
<Logo width="100%" />
|
||||
</a>
|
||||
<Search class="mr-4 ml-auto sm:self-center" />
|
||||
<Search client:load className="mr-4 ml-auto sm:self-center" />
|
||||
{/* Desktop nav links */}
|
||||
<div class="hidden md:flex">
|
||||
<GetStartedLink
|
||||
|
||||
@@ -42,7 +42,7 @@ const { class: className } = Astro.props;
|
||||
<LogoDocs width="100%" />
|
||||
</div>
|
||||
</a>
|
||||
<Search class="mr-4 ml-auto sm:self-center" />
|
||||
<Search client:load className="mr-4 ml-auto sm:self-center" />
|
||||
{/* Desktop nav links */}
|
||||
<div class="hidden h-full md:flex">
|
||||
<GetStartedLink
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { DocSearch } from '@docsearch/react';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { GITHUB_REPO_URL } from '@/consts';
|
||||
import { DOCSEARCH_API_KEY, DOCSEARCH_APP_ID, DOCSEARCH_BLOG_INDEX, DOCSEARCH_DOCS_INDEX } from '@/search.config';
|
||||
import { currentFramework } from '@/stores/preferences';
|
||||
|
||||
interface SearchProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function Search({ className }: SearchProps) {
|
||||
const framework = useStore(currentFramework);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<DocSearch
|
||||
appId={DOCSEARCH_APP_ID}
|
||||
apiKey={DOCSEARCH_API_KEY}
|
||||
indices={[
|
||||
{
|
||||
name: DOCSEARCH_DOCS_INDEX,
|
||||
searchParameters: {
|
||||
facetFilters: framework ? [`framework:${framework}`] : [],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: DOCSEARCH_BLOG_INDEX,
|
||||
},
|
||||
]}
|
||||
getMissingResultsUrl={({ query }) =>
|
||||
`${GITHUB_REPO_URL}issues/new?title=${encodeURIComponent(`Search: no results for "${query}"`)}&labels=search`
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
---
|
||||
|
||||
import { join } from 'node:path/posix';
|
||||
import clsx from 'clsx';
|
||||
/**
|
||||
* We wrap Search.tsx in an .astro entry point for
|
||||
* 1. easy CSS support, since we can't use Tailwind on pagefind-ui
|
||||
* 2. a synchronous script to set the meta key (ctrl or cmd) without FOUC or hydration errors
|
||||
*/
|
||||
import SearchClient from './Search';
|
||||
import SearchIcon from './searchIcon.svg';
|
||||
import searchIconString from './searchIcon.svg?raw';
|
||||
|
||||
const baseUrl = import.meta.env.BASE_URL || '/';
|
||||
const bundlePath = join(baseUrl, 'pagefind/');
|
||||
|
||||
interface Props {
|
||||
class?: string;
|
||||
}
|
||||
const { class: className } = Astro.props;
|
||||
---
|
||||
|
||||
<SearchClient
|
||||
client:load
|
||||
className={clsx(
|
||||
"inline-flex min-h-6 cursor-pointer items-center gap-2 rounded-full border-faded-black px-2 sm:border dark:border-manila-dark intent:border-manila-dark dark:intent:border-warm-gray",
|
||||
className,
|
||||
)}
|
||||
baseUrl={baseUrl}
|
||||
bundlePath={bundlePath}
|
||||
searchId="pagefind-ui"
|
||||
searchStyle={{
|
||||
"--search-icon-url": `url('data:image/svg+xml;utf8,${encodeURIComponent(searchIconString)}')`,
|
||||
} as React.CSSProperties}
|
||||
>
|
||||
<SearchIcon class="h-4 w-4 sm:h-3 sm:w-3" />
|
||||
<kbd data-platform-key="default" class="hidden font-display text-h4 sm:inline"
|
||||
>Ctrl K</kbd
|
||||
>
|
||||
<kbd data-platform-key="mac" class="hidden font-display text-h4 sm:inline"
|
||||
>⌘K</kbd
|
||||
>
|
||||
</SearchClient>
|
||||
|
||||
{
|
||||
/**
|
||||
* Adapted from https://github.com/withastro/starlight/blob/8a72a19e2cfec235941b4e1401b69b44e6695068/packages/starlight/components/Search.astro#L55C1-L75C1
|
||||
* This is intentionally inlined to avoid briefly showing an invalid shortcut.
|
||||
* Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the
|
||||
* user agent is spoofed by some browsers when opening the devtools.
|
||||
*/
|
||||
}
|
||||
<script is:inline>
|
||||
(() => {
|
||||
const defaultPlatformKey = document.querySelector(
|
||||
'kbd[data-platform-key="default"]',
|
||||
);
|
||||
const macPlatformKey = document.querySelector(
|
||||
'kbd[data-platform-key="mac"]',
|
||||
);
|
||||
if (/Mac|iPhone|iPod|iPad/i.test(navigator.platform)) {
|
||||
if (defaultPlatformKey) defaultPlatformKey.style.display = "none";
|
||||
} else {
|
||||
if (macPlatformKey) macPlatformKey.style.display = "none";
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style is:global>
|
||||
@import url("@pagefind/default-ui/css/ui.css");
|
||||
|
||||
#pagefind-ui {
|
||||
--pagefind-ui-scale: 1;
|
||||
--pagefind-ui-primary: var(--color-gold);
|
||||
--pagefind-ui-text: var(--color-faded-black);
|
||||
--pagefind-ui-background: var(--color-manila-50);
|
||||
--pagefind-ui-border: var(--color-manila-75);
|
||||
--pagefind-ui-tag: green;
|
||||
--pagefind-ui-border-width: 1px;
|
||||
--pagefind-ui-border-radius: var(--radius-xs);
|
||||
--pagefind-ui-font: inherit;
|
||||
}
|
||||
|
||||
.dark #pagefind-ui {
|
||||
--pagefind-ui-text: var(--color-manila-light);
|
||||
--pagefind-ui-background: var(--color-warm-gray);
|
||||
--pagefind-ui-border: var(--color-soot);
|
||||
}
|
||||
|
||||
#pagefind-ui .pagefind-ui__form::before {
|
||||
-webkit-mask-image: var(--search-icon-url);
|
||||
mask-image: var(--search-icon-url);
|
||||
}
|
||||
#pagefind-ui .pagefind-ui__search-input {
|
||||
font-size: var(--text-p2);
|
||||
line-height: var(--text-p2--line-height);
|
||||
letter-spacing: var(--text-p2--letter-spacing);
|
||||
font-weight: var(--text-p2--font-weight);
|
||||
}
|
||||
#pagefind-ui .pagefind-ui__filter-block {
|
||||
border-bottom: solid 1px var(--pagefind-ui-border);
|
||||
}
|
||||
#pagefind-ui .pagefind-ui__message {
|
||||
font-weight: var(--font-weight-normal);
|
||||
}
|
||||
#pagefind-ui .pagefind-ui__result-title,
|
||||
#pagefind-ui .pagefind-ui__filter-name {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
#pagefind-ui .pagefind-ui__result-nested .pagefind-ui__result-link::before {
|
||||
font-weight: var(--font-weight-normal);
|
||||
font-size: 0.9em;
|
||||
}
|
||||
#pagefind-ui mark {
|
||||
background-color: var(--color-gold);
|
||||
color: var(--color-faded-black);
|
||||
}
|
||||
</style>
|
||||
@@ -1,90 +0,0 @@
|
||||
import { Dialog } from '@base-ui/react/dialog';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { currentFramework } from '@/stores/preferences';
|
||||
|
||||
interface SearchProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
baseUrl: string;
|
||||
bundlePath: string;
|
||||
searchId: string;
|
||||
searchStyle?: React.CSSProperties;
|
||||
}
|
||||
export default function Search({ children, className, baseUrl, bundlePath, searchId, searchStyle }: SearchProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const framework = useStore(currentFramework);
|
||||
const searchRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// load Pagefind when opened
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
let search: any;
|
||||
const init = async () => {
|
||||
// default-ui is actually an ultra-lightweight svelte app
|
||||
// ...which we're loading in this react component, in an astro app.
|
||||
// this isn't relevant to dev. I just found it funny.
|
||||
const { PagefindUI } = await import('@pagefind/default-ui');
|
||||
// I'd love if we built our own ui with BaseUI/Autocomplete, but... time, ya know?
|
||||
search = new PagefindUI({
|
||||
element: `#${searchId}`,
|
||||
baseUrl,
|
||||
bundlePath,
|
||||
showImages: false,
|
||||
showSubResults: true,
|
||||
autofocus: true,
|
||||
});
|
||||
search.triggerFilters({
|
||||
framework: [framework],
|
||||
});
|
||||
};
|
||||
init();
|
||||
return () => {
|
||||
search.destroy();
|
||||
};
|
||||
}, [baseUrl, bundlePath, framework, open, searchId]);
|
||||
|
||||
// open with cmd+k or ctrl+k
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
|
||||
e.preventDefault();
|
||||
setOpen((prev) => !prev);
|
||||
}
|
||||
};
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dialog.Root
|
||||
open={open}
|
||||
onOpenChange={(newOpen) => {
|
||||
setOpen(newOpen);
|
||||
}}
|
||||
modal
|
||||
>
|
||||
<Dialog.Trigger aria-label="Search" className={className}>
|
||||
{children}
|
||||
</Dialog.Trigger>
|
||||
<Dialog.Portal>
|
||||
<Dialog.Backdrop className="fixed inset-0 flex items-start justify-center bg-faded-black/20 backdrop-blur-xs z-50">
|
||||
<Dialog.Popup
|
||||
initialFocus={false} // pagefind.autofocus = true
|
||||
id={searchId}
|
||||
ref={searchRef}
|
||||
className="w-full max-w-5xl mx-4 mb-4 p-4 rounded-xs bg-manila-light dark:bg-faded-black dark:border-warm-gray border-manila-75 border overflow-y-scroll overflow-x-hidden"
|
||||
style={{
|
||||
minHeight: '50svh',
|
||||
maxHeight: '75svh',
|
||||
marginTop: '12.5svh',
|
||||
...searchStyle,
|
||||
}}
|
||||
/>
|
||||
</Dialog.Backdrop>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './Search.astro';
|
||||
@@ -1,12 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M21 21l-4.34-4.34" vector-effect="non-scaling-stroke" />
|
||||
<circle cx="11" cy="11" r="8" vector-effect="non-scaling-stroke" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 319 B |
@@ -254,7 +254,9 @@ export function Tab({ value, children, initial, variant = 'compact' }: TabProps)
|
||||
)}
|
||||
<span className="relative">
|
||||
{/* to prevent layout shift on state change, we have an invisible bold version of the text preserving space */}
|
||||
<span className="font-bold invisible">{children}</span>
|
||||
<span className="font-bold invisible" data-search-ignore data-llms-ignore>
|
||||
{children}
|
||||
</span>
|
||||
<span className={clsx('absolute top-0 left-0', isActive && 'font-bold')}>{children}</span>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
@@ -30,7 +30,7 @@ const shouldRender = !frameworks || frameworks.includes(framework as SupportedFr
|
||||
<div
|
||||
class="contents"
|
||||
hidden={!shouldRender}
|
||||
data-pagefind-ignore={shouldRender ? undefined : "all"}
|
||||
data-search-ignore={shouldRender ? undefined : "all"}
|
||||
data-llms-ignore={shouldRender ? undefined : "all"}
|
||||
>
|
||||
<slot />
|
||||
|
||||
@@ -56,12 +56,11 @@ const jsonLdSchema = createBlogPostingSchema({
|
||||
<JsonLd slot="head" schema={jsonLdSchema} />
|
||||
<article
|
||||
class="@container"
|
||||
data-pagefind-body
|
||||
data-search-content
|
||||
data-llms-content
|
||||
data-llms-description={post.data.description}
|
||||
data-llms-sort={post.data.pubDate.toISOString()}
|
||||
data-site="blog"
|
||||
data-pagefind-filter="site[data-site]"
|
||||
>
|
||||
<header
|
||||
class="relative mx-auto mb-10 max-w-3xl border-y border-faded-black py-10 dark:border-manila-light"
|
||||
@@ -69,12 +68,9 @@ const jsonLdSchema = createBlogPostingSchema({
|
||||
<div
|
||||
class="mb-3 flex flex-col gap-2 font-display text-h4 font-bold text-orange uppercase sm:flex-row sm:gap-4"
|
||||
>
|
||||
<FormattedDate
|
||||
data-pagefind-sort={`date:${post.data.pubDate.toISOString()}`}
|
||||
date={post.data.pubDate}
|
||||
/>
|
||||
<FormattedDate date={post.data.pubDate} />
|
||||
<span class="hidden sm:inline">•</span>
|
||||
<span data-pagefind-ignore data-llms-ignore
|
||||
<span data-search-ignore data-llms-ignore
|
||||
>{remarkPluginFrontmatter.minutesRead}</span
|
||||
>
|
||||
</div>
|
||||
@@ -91,7 +87,6 @@ const jsonLdSchema = createBlogPostingSchema({
|
||||
<a
|
||||
href={`/blog/authors/${authors.find((a) => a.data.name === part.value)?.id}`}
|
||||
class="inline-block intent:underline"
|
||||
data-pagefind-meta="author"
|
||||
>
|
||||
{part.value}
|
||||
</a>
|
||||
|
||||
@@ -129,13 +129,12 @@ const jsonLdSchema = createTechArticleSchema({
|
||||
>
|
||||
<article
|
||||
class="mb-18 flex-1"
|
||||
data-pagefind-body
|
||||
data-search-content
|
||||
data-llms-content
|
||||
data-llms-description={doc.data.description}
|
||||
data-framework={framework}
|
||||
data-site="docs"
|
||||
data-category={sections[0]}
|
||||
data-pagefind-filter="framework[data-framework], section[data-site]"
|
||||
>
|
||||
<header
|
||||
class:list={[
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
/** Algolia DocSearch — search API key is public (read-only). */
|
||||
export const DOCSEARCH_APP_ID = '5WD2PWU9HZ';
|
||||
export const DOCSEARCH_API_KEY = '68c102f304dc6e38fa3c2d167d2389ed';
|
||||
export const DOCSEARCH_DOCS_INDEX = 'videojs_docs';
|
||||
export const DOCSEARCH_BLOG_INDEX = 'videojs_blog';
|
||||
@@ -0,0 +1,282 @@
|
||||
@import "@docsearch/css/dist/style.css";
|
||||
/* ── Light theme ── */
|
||||
:root {
|
||||
--docsearch-primary-color: var(--color-gold);
|
||||
--docsearch-text-color: var(--color-faded-black);
|
||||
--docsearch-secondary-text-color: var(--color-soot);
|
||||
--docsearch-background-color: var(--color-manila-50);
|
||||
--docsearch-modal-background: var(--color-manila-50);
|
||||
--docsearch-modal-shadow:
|
||||
0 calc(var(--spacing) * 3) calc(var(--spacing) * 7) color-mix(in srgb, var(--color-faded-black) 15%, transparent),
|
||||
0 calc(var(--spacing) / 2) var(--spacing) color-mix(in srgb, var(--color-faded-black) 8%, transparent);
|
||||
--docsearch-searchbox-background: var(--color-manila-light);
|
||||
--docsearch-searchbox-focus-background: var(--color-manila-light);
|
||||
--docsearch-hit-background: var(--color-manila-light);
|
||||
--docsearch-hit-color: var(--color-faded-black);
|
||||
--docsearch-hit-highlight-color: color-mix(in srgb, var(--color-gold) 15%, var(--color-manila-light));
|
||||
--docsearch-highlight-color: var(--color-orange);
|
||||
--docsearch-soft-primary-color: color-mix(in srgb, var(--color-gold) 10%, transparent);
|
||||
--docsearch-focus-color: var(--color-gold);
|
||||
--docsearch-subtle-color: var(--color-manila-75);
|
||||
--docsearch-muted-color: var(--color-manila-dark);
|
||||
--docsearch-icon-color: var(--color-soot);
|
||||
--docsearch-container-background: color-mix(in srgb, var(--color-faded-black) 20%, transparent);
|
||||
--docsearch-key-background: var(--color-manila-75);
|
||||
--docsearch-key-color: var(--color-faded-black);
|
||||
--docsearch-key-pressed-shadow: inset 0 calc(var(--spacing) / 2) var(--spacing)
|
||||
color-mix(in srgb, var(--color-faded-black) 15%, transparent);
|
||||
--docsearch-footer-background: var(--color-manila-light);
|
||||
--docsearch-footer-shadow: 0 -1px 0 0 var(--color-manila-75); /* 1px hairline */
|
||||
--docsearch-logo-color: currentColor;
|
||||
--docsearch-border-radius: var(--radius-xs);
|
||||
--docsearch-spacing: calc(var(--spacing) * 4);
|
||||
--docsearch-searchbox-height: calc(var(--spacing) * 14);
|
||||
--docsearch-searchbox-initial-height: calc(var(--spacing) * 14);
|
||||
--docsearch-hit-height: calc(var(--spacing) * 14);
|
||||
--docsearch-actions-height: calc(var(--spacing) * 11);
|
||||
--docsearch-footer-height: calc(var(--spacing) * 13);
|
||||
--docsearch-icon-stroke-width: 2;
|
||||
--docsearch-search-button-background: transparent;
|
||||
--docsearch-search-button-text-color: var(--color-faded-black);
|
||||
}
|
||||
|
||||
/* ── Dark theme ── */
|
||||
.dark {
|
||||
--docsearch-text-color: var(--color-manila-light);
|
||||
--docsearch-secondary-text-color: var(--color-manila-dark);
|
||||
--docsearch-background-color: var(--color-warm-gray);
|
||||
--docsearch-modal-background: var(--color-faded-black);
|
||||
--docsearch-modal-shadow:
|
||||
inset 1px 1px 0 0 var(--color-warm-gray),
|
||||
0 calc(var(--spacing) * 0.75) calc(var(--spacing) * 2) color-mix(in srgb, var(--color-black) 50%, transparent);
|
||||
--docsearch-searchbox-background: var(--color-soot);
|
||||
--docsearch-searchbox-focus-background: var(--color-soot);
|
||||
--docsearch-hit-background: var(--color-warm-gray);
|
||||
--docsearch-hit-color: var(--color-manila-light);
|
||||
--docsearch-hit-highlight-color: color-mix(in srgb, var(--color-gold) 10%, var(--color-warm-gray));
|
||||
--docsearch-highlight-color: var(--color-gold);
|
||||
--docsearch-soft-primary-color: color-mix(in srgb, var(--color-gold) 10%, transparent);
|
||||
--docsearch-focus-color: var(--color-gold);
|
||||
--docsearch-subtle-color: var(--color-warm-gray);
|
||||
--docsearch-muted-color: var(--color-manila-dark);
|
||||
--docsearch-icon-color: var(--color-manila-dark);
|
||||
--docsearch-container-background: color-mix(in srgb, var(--color-faded-black) 60%, transparent);
|
||||
--docsearch-key-background: var(--color-soot);
|
||||
--docsearch-key-color: var(--color-manila-light);
|
||||
--docsearch-key-pressed-shadow: inset 0 calc(var(--spacing) / 2) var(--spacing)
|
||||
color-mix(in srgb, var(--color-black) 40%, transparent);
|
||||
--docsearch-footer-background: var(--color-soot);
|
||||
--docsearch-footer-shadow: 0 -1px 0 0 var(--color-warm-gray); /* 1px hairline */
|
||||
--docsearch-logo-color: currentColor;
|
||||
--docsearch-search-button-background: transparent;
|
||||
--docsearch-search-button-text-color: var(--color-manila-light);
|
||||
}
|
||||
|
||||
/* ── Trigger button — match rounded-pill navbar style ── */
|
||||
.DocSearch-Button {
|
||||
box-sizing: border-box;
|
||||
border-radius: 9999px;
|
||||
border: none;
|
||||
padding: 0 calc(var(--spacing) * 2);
|
||||
gap: calc(var(--spacing) * 2);
|
||||
height: auto;
|
||||
min-height: calc(var(--spacing) * 6);
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.DocSearch-Button:hover,
|
||||
.DocSearch-Button:focus-within {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Search-Icon {
|
||||
width: calc(var(--spacing) * 4);
|
||||
height: calc(var(--spacing) * 4);
|
||||
}
|
||||
|
||||
.DocSearch-Search-Icon circle,
|
||||
.DocSearch-Search-Icon path {
|
||||
stroke-width: var(--docsearch-icon-stroke-width);
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Search-Icon circle,
|
||||
.DocSearch-Button .DocSearch-Search-Icon path {
|
||||
stroke-width: calc(var(--docsearch-icon-stroke-width) * 2);
|
||||
}
|
||||
|
||||
/* Hide button label text on small screens, keep icon + keyboard shortcut */
|
||||
.DocSearch-Button-Placeholder {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.DocSearch-Button-Keys {
|
||||
display: none;
|
||||
min-width: 0;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.DocSearch-Button-Keys:has(.DocSearch-Button-Key--ctrl) {
|
||||
gap: var(--spacing);
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Button-Key {
|
||||
background: none;
|
||||
border: none;
|
||||
box-shadow: none !important;
|
||||
color: inherit;
|
||||
width: auto;
|
||||
height: auto;
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-h4);
|
||||
line-height: var(--text-h4--line-height);
|
||||
letter-spacing: var(--text-h4--letter-spacing);
|
||||
font-weight: var(--font-weight-bold);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (width >= 40rem) {
|
||||
.DocSearch-Button {
|
||||
border: 1px solid var(--color-faded-black);
|
||||
width: calc(var(--spacing) * 16.5);
|
||||
}
|
||||
|
||||
.DocSearch-Button:has(.DocSearch-Button-Key--ctrl) {
|
||||
width: calc(var(--spacing) * 25);
|
||||
}
|
||||
|
||||
.dark .DocSearch-Button {
|
||||
border-color: var(--color-manila-dark);
|
||||
}
|
||||
|
||||
.DocSearch-Button:hover,
|
||||
.DocSearch-Button:focus-within {
|
||||
border-color: var(--color-manila-dark);
|
||||
}
|
||||
|
||||
.dark .DocSearch-Button:hover,
|
||||
.dark .DocSearch-Button:focus-within {
|
||||
border-color: var(--color-warm-gray);
|
||||
}
|
||||
|
||||
.DocSearch-Button-Keys {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.DocSearch-Button .DocSearch-Search-Icon {
|
||||
width: calc(var(--spacing) * 3);
|
||||
height: calc(var(--spacing) * 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Modal backdrop ── */
|
||||
.DocSearch-Container {
|
||||
backdrop-filter: blur(calc(var(--spacing) / 2));
|
||||
}
|
||||
|
||||
/* ── Consistent border-radius — DocSearch hardcodes 4px on these ── */
|
||||
.DocSearch-Modal {
|
||||
border-radius: var(--radius-xs);
|
||||
}
|
||||
|
||||
.DocSearch-Form {
|
||||
border-radius: var(--radius-xs) var(--radius-xs) 0 0;
|
||||
}
|
||||
|
||||
.DocSearch-Footer {
|
||||
border-radius: 0 0 var(--radius-xs) var(--radius-xs);
|
||||
border-block-start: none;
|
||||
}
|
||||
|
||||
.DocSearch-Dropdown + .DocSearch-Footer {
|
||||
border-block-start: 1px solid var(--docsearch-subtle-color);
|
||||
}
|
||||
|
||||
.DocSearch-Hit a {
|
||||
border-radius: var(--radius-xs);
|
||||
}
|
||||
|
||||
/* ── Typography — full text-token treatment (size + leading + tracking + weight) ── */
|
||||
.DocSearch-Modal {
|
||||
font-family: var(--font-sans);
|
||||
font-size: var(--text-p2);
|
||||
line-height: var(--text-p2--line-height);
|
||||
letter-spacing: var(--text-p2--letter-spacing);
|
||||
font-weight: var(--text-p2--font-weight);
|
||||
text-underline-offset: 0.25em;
|
||||
}
|
||||
|
||||
.DocSearch-Input {
|
||||
letter-spacing: var(--tracking-tight);
|
||||
font-weight: var(--text-p1--font-weight);
|
||||
}
|
||||
|
||||
.DocSearch-Button-Key,
|
||||
.DocSearch-Escape-Key {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-code);
|
||||
line-height: var(--text-code--line-height);
|
||||
letter-spacing: var(--text-code--letter-spacing);
|
||||
font-weight: var(--text-code--font-weight);
|
||||
font-variant-ligatures: none;
|
||||
text-underline-offset: 0.125em;
|
||||
}
|
||||
|
||||
.DocSearch-Hit-source {
|
||||
font-size: var(--text-p2);
|
||||
line-height: var(--text-p2--line-height);
|
||||
letter-spacing: var(--text-p2--letter-spacing);
|
||||
font-weight: var(--font-weight-bold);
|
||||
padding-block-start: calc(var(--spacing) * 4);
|
||||
padding-block-end: calc(var(--spacing) * 2);
|
||||
}
|
||||
|
||||
.DocSearch-Hit-title {
|
||||
font-size: var(--text-p2);
|
||||
line-height: var(--text-p2--line-height);
|
||||
letter-spacing: var(--text-p2--letter-spacing);
|
||||
}
|
||||
|
||||
.DocSearch-Hit-path {
|
||||
font-size: var(--text-p3);
|
||||
line-height: var(--text-p3--line-height);
|
||||
letter-spacing: var(--text-p3--letter-spacing);
|
||||
font-weight: var(--text-p3--font-weight);
|
||||
}
|
||||
|
||||
.DocSearch-Label,
|
||||
.DocSearch-Help,
|
||||
.DocSearch-NoResults-Help {
|
||||
font-size: var(--text-p3);
|
||||
line-height: var(--text-p3--line-height);
|
||||
letter-spacing: var(--text-p3--letter-spacing);
|
||||
font-weight: var(--text-p3--font-weight);
|
||||
}
|
||||
|
||||
.DocSearch-Clear {
|
||||
font-size: var(--text-p3);
|
||||
font-weight: var(--text-p3--font-weight);
|
||||
}
|
||||
|
||||
.DocSearch-Title strong {
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
|
||||
/* ── Hit spacing — more breathing room, tighter title/path gap ── */
|
||||
.DocSearch-Hit-content-wrapper {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
/* ── Algolia logo — SVG paths hardcode blue fills via .cls-1/.cls-2 ── */
|
||||
.DocSearch-Logo svg .cls-1,
|
||||
.DocSearch-Logo svg .cls-2 {
|
||||
fill: var(--docsearch-logo-color);
|
||||
}
|
||||
|
||||
/* ── Text match highlight — keep readable in all states ── */
|
||||
.DocSearch-Hit mark,
|
||||
.DocSearch-Hit[aria-selected="true"] mark {
|
||||
text-decoration-color: var(--color-gold);
|
||||
color: currentColor;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
@import "tailwindcss";
|
||||
@import "./shiki-transformers.css";
|
||||
@import "./docsearch.css";
|
||||
|
||||
/**
|
||||
* @license
|
||||
|
||||
Reference in New Issue
Block a user