Files
website/node_modules/@astrojs/starlight-docsearch/DocSearch.astro
2024-05-06 17:15:30 -04:00

140 lines
4.4 KiB
Plaintext

---
import type { Props } from '@astrojs/starlight/props';
import '@docsearch/css/dist/modal.css';
import type docsearch from '@docsearch/js';
import './variables.css';
const { labels } = Astro.props;
type DocSearchTranslationProps = Pick<
Parameters<typeof docsearch>[0],
'placeholder' | 'translations'
>;
const pick = (keyStart: string) =>
Object.fromEntries(
Object.entries(labels)
.filter(([key]) => key.startsWith(keyStart))
.map(([key, value]) => [key.replace(keyStart, ''), value])
);
const docsearchTranslations: DocSearchTranslationProps = {
placeholder: labels['search.label'],
translations: {
button: { buttonText: labels['search.label'], buttonAriaLabel: labels['search.label'] },
modal: {
searchBox: pick('docsearch.searchBox.'),
startScreen: pick('docsearch.startScreen.'),
errorScreen: pick('docsearch.errorScreen.'),
footer: pick('docsearch.footer.'),
noResultsScreen: pick('docsearch.noResultsScreen.'),
},
},
};
---
<sl-doc-search data-translations={JSON.stringify(docsearchTranslations)}>
<button type="button" class="DocSearch DocSearch-Button" aria-label={labels['search.label']}>
<span class="DocSearch-Button-Container">
<svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20">
<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"></path>
</svg>
<span class="DocSearch-Button-Placeholder">{labels['search.label']}</span>
</span>
<span class="DocSearch-Button-Keys"></span>
</button>
</sl-doc-search>
<style is:global>
.DocSearch-Button {
display: flex;
align-items: center;
gap: 0.5rem;
border: 0;
background-color: transparent;
color: var(--sl-color-gray-1);
cursor: pointer;
height: 2.5rem;
font-size: var(--sl-text-xl);
}
.DocSearch-Button-Container {
display: contents;
}
.DocSearch-Search-Icon {
width: 0.875em;
height: 0.875em;
stroke-width: 0.125rem;
}
.DocSearch-Button-Placeholder,
.DocSearch-Button-Keys,
.DocSearch-Button-Key {
display: none;
}
@media (min-width: 50rem) {
sl-doc-search {
width: 100%;
}
.DocSearch-Button {
border: 1px solid var(--sl-color-gray-5);
border-radius: 0.5rem;
padding-inline-start: 0.75rem;
padding-inline-end: 1rem;
background-color: var(--sl-color-black);
color: var(--sl-color-gray-2);
font-size: var(--sl-text-sm);
width: 100%;
max-width: 22rem;
}
.DocSearch-Button:hover {
border-color: var(--sl-color-gray-2);
color: var(--sl-color-white);
}
.DocSearch-Button-Placeholder,
.DocSearch-Button-Keys {
display: flex;
}
.DocSearch-Button-Keys {
margin-inline-start: auto;
}
.DocSearch-Button-Keys::before {
content: '';
width: 1em;
height: 1em;
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17 2H7a5 5 0 0 0-5 5v10a5 5 0 0 0 5 5h10a5 5 0 0 0 5-5V7a5 5 0 0 0-5-5Zm3 15a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v10Z'%3E%3C/path%3E%3Cpath d='M15.293 6.707a1 1 0 1 1 1.414 1.414l-8.485 8.486a1 1 0 0 1-1.414-1.415l8.485-8.485Z'%3E%3C/path%3E%3C/svg%3E");
-webkit-mask-size: 100%;
mask-size: 100%;
background-color: currentColor;
}
}
</style>
<script>
import config from 'virtual:starlight/docsearch-config';
class StarlightDocSearch extends HTMLElement {
constructor() {
super();
window.addEventListener('DOMContentLoaded', async () => {
const { default: docsearch } = await import('@docsearch/js');
const options: Parameters<typeof docsearch>[0] = { ...config, container: 'sl-doc-search' };
try {
const translations = JSON.parse(this.dataset.translations || '{}');
Object.assign(options, translations);
} catch {}
docsearch(options);
});
}
}
customElements.define('sl-doc-search', StarlightDocSearch);
</script>