<template> <div id="docsearch"> <button type="button" class="DocSearch DocSearch-Button" aria-label="Search"> <svg width="20" height="20" class="d-icon m-auto" 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" /> </svg> </button> </div> </template> <script> function isSpecialClick (event) { return event.button === 1 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey } export default { props: { options: { type: Object, required: true }, settings: { type: Object, required: true } }, watch: { '$i18n.locale' (newValue) { this.update(this.options, newValue) }, options (newValue) { this.update(newValue, this.$i18n.locale) } }, mounted () { this.initialize(this.options, this.$i18n.locale) }, methods: { stripTrailingSlash (url) { return url.replace(/\/$|\/(?=\?)|\/(?=#)/g, '') }, getRelativePath (absoluteUrl) { const { pathname, hash } = new URL(absoluteUrl) const url = pathname.replace(this.settings.url, '/') + hash return this.stripTrailingSlash(url) }, async initialize (userOptions, code) { const lang = this.$i18n.locales.find(locale => locale.code === code) const docsearch = await Promise.all([ import(/* webpackChunkName: "docsearch" */ '@docsearch/js'), import(/* webpackChunkName: "docsearch" */ '@docsearch/css') ]).then(([docsearch]) => docsearch.default) docsearch({ ...userOptions, container: '#docsearch', searchParameters: { ...((!lang) ? {} : { facetFilters: [`${userOptions.langAttribute || 'language'}:${lang.iso}`].concat( userOptions.facetFilters || [] ) }) }, navigator: { navigate: ({ itemUrl }) => { const { pathname: hitPathname } = new URL(window.location.origin + itemUrl) // Vue Router doesn't handle same-page navigation so we use // the native browser location API for anchor navigation. if (this.$router.history.current.path === hitPathname) { window.location.assign(window.location.origin + itemUrl) } else { this.$router.push(itemUrl) } } }, transformItems: (items) => { return items.map((item) => { return { ...item, url: this.getRelativePath(item.url) } }) }, hitComponent: ({ hit, children }) => { return { type: 'a', constructor: undefined, __v: 1, props: { href: hit.url, children, onClick: (event) => { if (isSpecialClick(event)) { return } // We rely on the native link scrolling when user is // already on the right anchor because Vue Router doesn't // support duplicated history entries. if (this.$router.history.current.fullPath === hit.url) { return } const { pathname: hitPathname } = new URL(window.location.origin + hit.url) // If the hits goes to another page, we prevent the native link behavior // to leverage the Vue Router loading feature. if (this.$router.history.current.path !== hitPathname) { event.preventDefault() } this.$router.push(hit.url) } } } } }) }, update (options, lang) { return this.initialize(options, lang) } } } </script> <style lang="postcss"> .DocSearch { --docsearch-primary-color: #00dc82; --docsearch-highlight-color: var(--docsearch-primary-color); --docsearch-text-color: rgb(113, 113, 122); --docsearch-modal-background: theme("colors.gray.100"); --docsearch-searchbox-shadow: 0 0 0 2px var(--docsearch-primary-color); --docsearch-searchbox-background: var(--color-transparent); --docsearch-searchbox-focus-background: var(--color-transparent); --docsearch-hit-color: var(--color-gray-700); --docsearch-hit-shadow: none; --docsearch-logo-color: var(--docsearch-text-color); --docsearch-muted-color: var(--color-gray-500); --docsearch-container-background: rgb(244 244 245 / 55%); } .dark { & .DocSearch { --docsearch-text-color: rgb(146, 173, 173); --docsearch-modal-background: theme("colors.secondary-darker"); --docsearch-modal-shadow: inset 1px 1px 0 0 #052f14, 0 3px 8px 0 #0b160d; --docsearch-hit-color: var(--color-gray-300); --docsearch-hit-background: theme("colors.secondary-darkest"); --docsearch-footer-background: theme("colors.secondary-darkest"); --docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, 0.5), 0 -4px 8px 0 rgba(0, 0, 0, 0.2); --docsearch-container-background: rgb(0 30 38 / 64%); } } .DocSearch-Container { @apply blur-8; } .DocSearch-Modal { @apply lg:rounded-xl !important; } .DocSearch-SearchBar { @apply pb-1 !important; } .DocSearch-Button { @apply rounded-sm w-12 h-12 m-auto bg-transparent hover:shadow-none focus:outline-none !important; } .DocSearch-Button > svg { @apply mx-auto !important; } .DocSearch-Button-Key { @apply hidden !important; } .DocSearch-Button-Placeholder { @apply hidden !important; } .DocSearch-NoResults > .DocSearch-Screen-Icon > svg { @apply mx-auto !important; } .DocSearch-Commands-Key { @apply inline-flex items-center justify-center w-auto h-auto p-1 bg-none rounded shadow-none border light:border-gray-500 !important; } </style>