This commit is contained in:
2024-03-22 03:47:51 +05:30
parent 8bcf3d211e
commit 89819f6fe2
28440 changed files with 3211033 additions and 2 deletions

View File

@@ -0,0 +1,9 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export { useAlgoliaThemeConfig } from './useAlgoliaThemeConfig';
export { useAlgoliaContextualFacetFilters } from './useAlgoliaContextualFacetFilters';
export { useSearchResultUrlProcessor } from './useSearchResultUrlProcessor';

View File

@@ -0,0 +1,9 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export { useAlgoliaThemeConfig } from './useAlgoliaThemeConfig';
export { useAlgoliaContextualFacetFilters } from './useAlgoliaContextualFacetFilters';
export { useSearchResultUrlProcessor } from './useSearchResultUrlProcessor';

View File

@@ -0,0 +1,7 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export declare function useAlgoliaContextualFacetFilters(): [string, string[]];

View File

@@ -0,0 +1,15 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useContextualSearchFilters } from '@docusaurus/theme-common';
// Translate search-engine agnostic search filters to Algolia search filters
export function useAlgoliaContextualFacetFilters() {
const { locale, tags } = useContextualSearchFilters();
// Seems safe to convert locale->language, see AlgoliaSearchMetadata comment
const languageFilter = `language:${locale}`;
const tagsFilter = tags.map((tag) => `docusaurus_tag:${tag}`);
return [languageFilter, tagsFilter];
}

View File

@@ -0,0 +1,2 @@
import type { ThemeConfig } from '@docusaurus/theme-search-algolia';
export declare function useAlgoliaThemeConfig(): ThemeConfig;

View File

@@ -0,0 +1,11 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
export function useAlgoliaThemeConfig() {
const { siteConfig: { themeConfig }, } = useDocusaurusContext();
return themeConfig;
}

View File

@@ -0,0 +1,11 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Process the search result url from Algolia to its final form, ready to be
* navigated to or used as a link
*/
export declare function useSearchResultUrlProcessor(): (url: string) => string;

View File

@@ -0,0 +1,33 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useCallback } from 'react';
import { isRegexpStringMatch } from '@docusaurus/theme-common';
import { useBaseUrlUtils } from '@docusaurus/useBaseUrl';
import { useAlgoliaThemeConfig } from './useAlgoliaThemeConfig';
function replacePathname(pathname, replaceSearchResultPathname) {
return replaceSearchResultPathname
? pathname.replaceAll(new RegExp(replaceSearchResultPathname.from, 'g'), replaceSearchResultPathname.to)
: pathname;
}
/**
* Process the search result url from Algolia to its final form, ready to be
* navigated to or used as a link
*/
export function useSearchResultUrlProcessor() {
const { withBaseUrl } = useBaseUrlUtils();
const { algolia: { externalUrlRegex, replaceSearchResultPathname }, } = useAlgoliaThemeConfig();
return useCallback((url) => {
const parsedURL = new URL(url);
// Algolia contains an external domain => navigate to URL
if (isRegexpStringMatch(externalUrlRegex, parsedURL.href)) {
return url;
}
// Otherwise => transform to relative URL for SPA navigation
const relativeUrl = `${parsedURL.pathname + parsedURL.hash}`;
return withBaseUrl(replacePathname(relativeUrl, replaceSearchResultPathname));
}, [withBaseUrl, externalUrlRegex, replaceSearchResultPathname]);
}

View File

@@ -0,0 +1,9 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import type { LoadContext, Plugin } from '@docusaurus/types';
export default function themeSearchAlgolia(context: LoadContext): Plugin<void>;
export { validateThemeConfig } from './validateThemeConfig';

View File

@@ -0,0 +1,90 @@
"use strict";
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateThemeConfig = void 0;
const tslib_1 = require("tslib");
const path_1 = tslib_1.__importDefault(require("path"));
const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
const lodash_1 = tslib_1.__importDefault(require("lodash"));
const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
const eta_1 = require("eta");
const utils_1 = require("@docusaurus/utils");
const theme_translations_1 = require("@docusaurus/theme-translations");
const opensearch_1 = tslib_1.__importDefault(require("./templates/opensearch"));
const getCompiledOpenSearchTemplate = lodash_1.default.memoize(() => (0, eta_1.compile)(opensearch_1.default.trim()));
function renderOpenSearchTemplate(data) {
const compiled = getCompiledOpenSearchTemplate();
return compiled(data, eta_1.defaultConfig);
}
const OPEN_SEARCH_FILENAME = 'opensearch.xml';
function themeSearchAlgolia(context) {
const { baseUrl, siteConfig: { title, url, favicon, themeConfig }, i18n: { currentLocale }, } = context;
const { algolia: { searchPagePath }, } = themeConfig;
return {
name: 'docusaurus-theme-search-algolia',
getThemePath() {
return '../lib/theme';
},
getTypeScriptThemePath() {
return '../src/theme';
},
getDefaultCodeTranslationMessages() {
return (0, theme_translations_1.readDefaultCodeTranslationMessages)({
locale: currentLocale,
name: 'theme-search-algolia',
});
},
contentLoaded({ actions: { addRoute } }) {
if (searchPagePath) {
addRoute({
path: (0, utils_1.normalizeUrl)([baseUrl, searchPagePath]),
component: '@theme/SearchPage',
exact: true,
});
}
},
async postBuild({ outDir }) {
if (searchPagePath) {
const siteUrl = (0, utils_1.normalizeUrl)([url, baseUrl]);
try {
await fs_extra_1.default.writeFile(path_1.default.join(outDir, OPEN_SEARCH_FILENAME), renderOpenSearchTemplate({
title,
siteUrl,
searchUrl: (0, utils_1.normalizeUrl)([siteUrl, searchPagePath]),
faviconUrl: favicon ? (0, utils_1.normalizeUrl)([siteUrl, favicon]) : null,
}));
}
catch (err) {
logger_1.default.error('Generating OpenSearch file failed.');
throw err;
}
}
},
injectHtmlTags() {
if (!searchPagePath) {
return {};
}
return {
headTags: [
{
tagName: 'link',
attributes: {
rel: 'search',
type: 'application/opensearchdescription+xml',
title,
href: (0, utils_1.normalizeUrl)([baseUrl, OPEN_SEARCH_FILENAME]),
},
},
],
};
},
};
}
exports.default = themeSearchAlgolia;
var validateThemeConfig_1 = require("./validateThemeConfig");
Object.defineProperty(exports, "validateThemeConfig", { enumerable: true, get: function () { return validateThemeConfig_1.validateThemeConfig; } });

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
declare const _default: "\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<OpenSearchDescription xmlns=\"http://a9.com/-/spec/opensearch/1.1/\"\n xmlns:moz=\"http://www.mozilla.org/2006/browser/search/\">\n <ShortName><%= it.title %></ShortName>\n <Description>Search <%= it.title %></Description>\n <InputEncoding>UTF-8</InputEncoding>\n <% if (it.faviconUrl) { _%>\n <Image width=\"16\" height=\"16\" type=\"image/x-icon\"><%= it.faviconUrl %></Image>\n <% } _%>\n <Url type=\"text/html\" method=\"get\" template=\"<%= it.searchUrl %>?q={searchTerms}\"/>\n <Url type=\"application/opensearchdescription+xml\" rel=\"self\" template=\"<%= it.siteUrl %>opensearch.xml\" />\n <moz:SearchForm><%= it.siteUrl %></moz:SearchForm>\n</OpenSearchDescription>\n";
export default _default;

View File

@@ -0,0 +1,23 @@
"use strict";
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = `
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName><%= it.title %></ShortName>
<Description>Search <%= it.title %></Description>
<InputEncoding>UTF-8</InputEncoding>
<% if (it.faviconUrl) { _%>
<Image width="16" height="16" type="image/x-icon"><%= it.faviconUrl %></Image>
<% } _%>
<Url type="text/html" method="get" template="<%= it.searchUrl %>?q={searchTerms}"/>
<Url type="application/opensearchdescription+xml" rel="self" template="<%= it.siteUrl %>opensearch.xml" />
<moz:SearchForm><%= it.siteUrl %></moz:SearchForm>
</OpenSearchDescription>
`;

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/// <reference types="react" />
export default function SearchBar(): JSX.Element;

View File

@@ -0,0 +1,194 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, {useCallback, useMemo, useRef, useState} from 'react';
import {createPortal} from 'react-dom';
import {DocSearchButton, useDocSearchKeyboardEvents} from '@docsearch/react';
import Head from '@docusaurus/Head';
import Link from '@docusaurus/Link';
import {useHistory} from '@docusaurus/router';
import {
isRegexpStringMatch,
useSearchLinkCreator,
} from '@docusaurus/theme-common';
import {
useAlgoliaContextualFacetFilters,
useSearchResultUrlProcessor,
} from '@docusaurus/theme-search-algolia/client';
import Translate from '@docusaurus/Translate';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import translations from '@theme/SearchTranslations';
let DocSearchModal = null;
function Hit({hit, children}) {
return <Link to={hit.url}>{children}</Link>;
}
function ResultsFooter({state, onClose}) {
const createSearchLink = useSearchLinkCreator();
return (
<Link to={createSearchLink(state.query)} onClick={onClose}>
<Translate
id="theme.SearchBar.seeAll"
values={{count: state.context.nbHits}}>
{'See all {count} results'}
</Translate>
</Link>
);
}
function mergeFacetFilters(f1, f2) {
const normalize = (f) => (typeof f === 'string' ? [f] : f);
return [...normalize(f1), ...normalize(f2)];
}
function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
const {siteMetadata} = useDocusaurusContext();
const processSearchResultUrl = useSearchResultUrlProcessor();
const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters();
const configFacetFilters = props.searchParameters?.facetFilters ?? [];
const facetFilters = contextualSearch
? // Merge contextual search filters with config filters
mergeFacetFilters(contextualSearchFacetFilters, configFacetFilters)
: // ... or use config facetFilters
configFacetFilters;
// We let user override default searchParameters if she wants to
const searchParameters = {
...props.searchParameters,
facetFilters,
};
const history = useHistory();
const searchContainer = useRef(null);
const searchButtonRef = useRef(null);
const [isOpen, setIsOpen] = useState(false);
const [initialQuery, setInitialQuery] = useState(undefined);
const importDocSearchModalIfNeeded = useCallback(() => {
if (DocSearchModal) {
return Promise.resolve();
}
return Promise.all([
import('@docsearch/react/modal'),
import('@docsearch/react/style'),
import('./styles.css'),
]).then(([{DocSearchModal: Modal}]) => {
DocSearchModal = Modal;
});
}, []);
const onOpen = useCallback(() => {
importDocSearchModalIfNeeded().then(() => {
searchContainer.current = document.createElement('div');
document.body.insertBefore(
searchContainer.current,
document.body.firstChild,
);
setIsOpen(true);
});
}, [importDocSearchModalIfNeeded, setIsOpen]);
const onClose = useCallback(() => {
setIsOpen(false);
searchContainer.current?.remove();
}, [setIsOpen]);
const onInput = useCallback(
(event) => {
importDocSearchModalIfNeeded().then(() => {
setIsOpen(true);
setInitialQuery(event.key);
});
},
[importDocSearchModalIfNeeded, setIsOpen, setInitialQuery],
);
const navigator = useRef({
navigate({itemUrl}) {
// Algolia results could contain URL's from other domains which cannot
// be served through history and should navigate with window.location
if (isRegexpStringMatch(externalUrlRegex, itemUrl)) {
window.location.href = itemUrl;
} else {
history.push(itemUrl);
}
},
}).current;
const transformItems = useRef((items) =>
props.transformItems
? // Custom transformItems
props.transformItems(items)
: // Default transformItems
items.map((item) => ({
...item,
url: processSearchResultUrl(item.url),
})),
).current;
const resultsFooterComponent = useMemo(
() =>
// eslint-disable-next-line react/no-unstable-nested-components
(footerProps) =>
<ResultsFooter {...footerProps} onClose={onClose} />,
[onClose],
);
const transformSearchClient = useCallback(
(searchClient) => {
searchClient.addAlgoliaAgent(
'docusaurus',
siteMetadata.docusaurusVersion,
);
return searchClient;
},
[siteMetadata.docusaurusVersion],
);
useDocSearchKeyboardEvents({
isOpen,
onOpen,
onClose,
onInput,
searchButtonRef,
});
return (
<>
<Head>
{/* This hints the browser that the website will load data from Algolia,
and allows it to preconnect to the DocSearch cluster. It makes the first
query faster, especially on mobile. */}
<link
rel="preconnect"
href={`https://${props.appId}-dsn.algolia.net`}
crossOrigin="anonymous"
/>
</Head>
<DocSearchButton
onTouchStart={importDocSearchModalIfNeeded}
onFocus={importDocSearchModalIfNeeded}
onMouseOver={importDocSearchModalIfNeeded}
onClick={onOpen}
ref={searchButtonRef}
translations={translations.button}
/>
{isOpen &&
DocSearchModal &&
searchContainer.current &&
createPortal(
<DocSearchModal
onClose={onClose}
initialScrollY={window.scrollY}
initialQuery={initialQuery}
navigator={navigator}
transformItems={transformItems}
hitComponent={Hit}
transformSearchClient={transformSearchClient}
{...(props.searchPagePath && {
resultsFooterComponent,
})}
{...props}
searchParameters={searchParameters}
placeholder={translations.placeholder}
translations={translations.modal}
/>,
searchContainer.current,
)}
</>
);
}
export default function SearchBar() {
const {siteConfig} = useDocusaurusContext();
return <DocSearch {...siteConfig.themeConfig.algolia} />;
}

View File

@@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
:root {
--docsearch-primary-color: var(--ifm-color-primary);
--docsearch-text-color: var(--ifm-font-color-base);
}
.DocSearch-Button {
margin: 0;
transition: all var(--ifm-transition-fast)
var(--ifm-transition-timing-default);
}
.DocSearch-Container {
z-index: calc(var(--ifm-z-index-fixed) + 1);
}

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/// <reference types="react" />
export default function SearchPage(): JSX.Element;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,119 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
.searchQueryInput,
.searchVersionInput {
border-radius: var(--ifm-global-radius);
border: 2px solid var(--ifm-toc-border-color);
font: var(--ifm-font-size-base) var(--ifm-font-family-base);
padding: 0.8rem;
width: 100%;
background: var(--docsearch-searchbox-focus-background);
color: var(--docsearch-text-color);
margin-bottom: 0.5rem;
transition: border var(--ifm-transition-fast) ease;
}
.searchQueryInput:focus,
.searchVersionInput:focus {
border-color: var(--docsearch-primary-color);
outline: none;
}
.searchQueryInput::placeholder {
color: var(--docsearch-muted-color);
}
.searchResultsColumn {
font-size: 0.9rem;
font-weight: bold;
}
.algoliaLogo {
max-width: 150px;
}
.algoliaLogoPathFill {
fill: var(--ifm-font-color-base);
}
.searchResultItem {
padding: 1rem 0;
border-bottom: 1px solid var(--ifm-toc-border-color);
}
.searchResultItemHeading {
font-weight: 400;
margin-bottom: 0;
}
.searchResultItemPath {
font-size: 0.8rem;
color: var(--ifm-color-content-secondary);
--ifm-breadcrumb-separator-size-multiplier: 1;
}
.searchResultItemSummary {
margin: 0.5rem 0 0;
font-style: italic;
}
@media only screen and (max-width: 996px) {
.searchQueryColumn {
max-width: 60% !important;
}
.searchVersionColumn {
max-width: 40% !important;
}
.searchResultsColumn {
max-width: 60% !important;
}
.searchLogoColumn {
max-width: 40% !important;
padding-left: 0 !important;
}
}
@media screen and (max-width: 576px) {
.searchQueryColumn {
max-width: 100% !important;
}
.searchVersionColumn {
max-width: 100% !important;
padding-left: var(--ifm-spacing-horizontal) !important;
}
}
.loadingSpinner {
width: 3rem;
height: 3rem;
border: 0.4em solid #eee;
border-top-color: var(--ifm-color-primary);
border-radius: 50%;
animation: loading-spin 1s linear infinite;
margin: 0 auto;
}
@keyframes loading-spin {
100% {
transform: rotate(360deg);
}
}
.loader {
margin-top: 2rem;
}
:global(.search-result-match) {
color: var(--docsearch-hit-color);
background: rgb(255 215 142 / 25%);
padding: 0.09em 0;
}

View File

@@ -0,0 +1,11 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import type { DocSearchTranslations } from '@docsearch/react';
declare const translations: DocSearchTranslations & {
placeholder: string;
};
export default translations;

View File

@@ -0,0 +1,167 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {translate} from '@docusaurus/Translate';
const translations = {
button: {
buttonText: translate({
id: 'theme.SearchBar.label',
message: 'Search',
description: 'The ARIA label and placeholder for search button',
}),
buttonAriaLabel: translate({
id: 'theme.SearchBar.label',
message: 'Search',
description: 'The ARIA label and placeholder for search button',
}),
},
modal: {
searchBox: {
resetButtonTitle: translate({
id: 'theme.SearchModal.searchBox.resetButtonTitle',
message: 'Clear the query',
description: 'The label and ARIA label for search box reset button',
}),
resetButtonAriaLabel: translate({
id: 'theme.SearchModal.searchBox.resetButtonTitle',
message: 'Clear the query',
description: 'The label and ARIA label for search box reset button',
}),
cancelButtonText: translate({
id: 'theme.SearchModal.searchBox.cancelButtonText',
message: 'Cancel',
description: 'The label and ARIA label for search box cancel button',
}),
cancelButtonAriaLabel: translate({
id: 'theme.SearchModal.searchBox.cancelButtonText',
message: 'Cancel',
description: 'The label and ARIA label for search box cancel button',
}),
},
startScreen: {
recentSearchesTitle: translate({
id: 'theme.SearchModal.startScreen.recentSearchesTitle',
message: 'Recent',
description: 'The title for recent searches',
}),
noRecentSearchesText: translate({
id: 'theme.SearchModal.startScreen.noRecentSearchesText',
message: 'No recent searches',
description: 'The text when no recent searches',
}),
saveRecentSearchButtonTitle: translate({
id: 'theme.SearchModal.startScreen.saveRecentSearchButtonTitle',
message: 'Save this search',
description: 'The label for save recent search button',
}),
removeRecentSearchButtonTitle: translate({
id: 'theme.SearchModal.startScreen.removeRecentSearchButtonTitle',
message: 'Remove this search from history',
description: 'The label for remove recent search button',
}),
favoriteSearchesTitle: translate({
id: 'theme.SearchModal.startScreen.favoriteSearchesTitle',
message: 'Favorite',
description: 'The title for favorite searches',
}),
removeFavoriteSearchButtonTitle: translate({
id: 'theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle',
message: 'Remove this search from favorites',
description: 'The label for remove favorite search button',
}),
},
errorScreen: {
titleText: translate({
id: 'theme.SearchModal.errorScreen.titleText',
message: 'Unable to fetch results',
description: 'The title for error screen of search modal',
}),
helpText: translate({
id: 'theme.SearchModal.errorScreen.helpText',
message: 'You might want to check your network connection.',
description: 'The help text for error screen of search modal',
}),
},
footer: {
selectText: translate({
id: 'theme.SearchModal.footer.selectText',
message: 'to select',
description: 'The explanatory text of the action for the enter key',
}),
selectKeyAriaLabel: translate({
id: 'theme.SearchModal.footer.selectKeyAriaLabel',
message: 'Enter key',
description:
'The ARIA label for the Enter key button that makes the selection',
}),
navigateText: translate({
id: 'theme.SearchModal.footer.navigateText',
message: 'to navigate',
description:
'The explanatory text of the action for the Arrow up and Arrow down key',
}),
navigateUpKeyAriaLabel: translate({
id: 'theme.SearchModal.footer.navigateUpKeyAriaLabel',
message: 'Arrow up',
description:
'The ARIA label for the Arrow up key button that makes the navigation',
}),
navigateDownKeyAriaLabel: translate({
id: 'theme.SearchModal.footer.navigateDownKeyAriaLabel',
message: 'Arrow down',
description:
'The ARIA label for the Arrow down key button that makes the navigation',
}),
closeText: translate({
id: 'theme.SearchModal.footer.closeText',
message: 'to close',
description: 'The explanatory text of the action for Escape key',
}),
closeKeyAriaLabel: translate({
id: 'theme.SearchModal.footer.closeKeyAriaLabel',
message: 'Escape key',
description:
'The ARIA label for the Escape key button that close the modal',
}),
searchByText: translate({
id: 'theme.SearchModal.footer.searchByText',
message: 'Search by',
description: 'The text explain that the search is making by Algolia',
}),
},
noResultsScreen: {
noResultsText: translate({
id: 'theme.SearchModal.noResultsScreen.noResultsText',
message: 'No results for',
description:
'The text explains that there are no results for the following search',
}),
suggestedQueryText: translate({
id: 'theme.SearchModal.noResultsScreen.suggestedQueryText',
message: 'Try searching for',
description:
'The text for the suggested query when no results are found for the following search',
}),
reportMissingResultsText: translate({
id: 'theme.SearchModal.noResultsScreen.reportMissingResultsText',
message: 'Believe this query should return results?',
description:
'The text for the question where the user thinks there are missing results',
}),
reportMissingResultsLinkText: translate({
id: 'theme.SearchModal.noResultsScreen.reportMissingResultsLinkText',
message: 'Let us know.',
description: 'The text for the link to report missing results',
}),
},
},
placeholder: translate({
id: 'theme.SearchModal.placeholder',
message: 'Search docs',
description: 'The placeholder of the input of the DocSearch pop-up modal',
}),
};
export default translations;

View File

@@ -0,0 +1,15 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Joi } from '@docusaurus/utils-validation';
import type { ThemeConfig, ThemeConfigValidationContext } from '@docusaurus/types';
export declare const DEFAULT_CONFIG: {
contextualSearch: boolean;
searchParameters: {};
searchPagePath: string;
};
export declare const Schema: Joi.ObjectSchema<ThemeConfig>;
export declare function validateThemeConfig({ validate, themeConfig, }: ThemeConfigValidationContext<ThemeConfig>): ThemeConfig;

View File

@@ -0,0 +1,57 @@
"use strict";
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateThemeConfig = exports.Schema = exports.DEFAULT_CONFIG = void 0;
const utils_1 = require("@docusaurus/utils");
const utils_validation_1 = require("@docusaurus/utils-validation");
exports.DEFAULT_CONFIG = {
// Enabled by default, as it makes sense in most cases
// see also https://github.com/facebook/docusaurus/issues/5880
contextualSearch: true,
searchParameters: {},
searchPagePath: 'search',
};
exports.Schema = utils_validation_1.Joi.object({
algolia: utils_validation_1.Joi.object({
// Docusaurus attributes
contextualSearch: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.contextualSearch),
externalUrlRegex: utils_validation_1.Joi.string().optional(),
// Algolia attributes
appId: utils_validation_1.Joi.string().required().messages({
'any.required': '"algolia.appId" is required. If you haven\'t migrated to the new DocSearch infra, please refer to the blog post for instructions: https://docusaurus.io/blog/2021/11/21/algolia-docsearch-migration',
}),
apiKey: utils_validation_1.Joi.string().required(),
indexName: utils_validation_1.Joi.string().required(),
searchParameters: utils_validation_1.Joi.object()
.default(exports.DEFAULT_CONFIG.searchParameters)
.unknown(),
searchPagePath: utils_validation_1.Joi.alternatives()
.try(utils_validation_1.Joi.boolean().invalid(true), utils_validation_1.Joi.string())
.allow(null)
.default(exports.DEFAULT_CONFIG.searchPagePath),
replaceSearchResultPathname: utils_validation_1.Joi.object({
from: utils_validation_1.Joi.custom((from) => {
if (typeof from === 'string') {
return (0, utils_1.escapeRegexp)(from);
}
else if (from instanceof RegExp) {
return from.source;
}
throw new Error(`it should be a RegExp or a string, but received ${from}`);
}).required(),
to: utils_validation_1.Joi.string().required(),
}).optional(),
})
.label('themeConfig.algolia')
.required()
.unknown(), // DocSearch 3 is still alpha: don't validate the rest for now
});
function validateThemeConfig({ validate, themeConfig, }) {
return validate(exports.Schema, themeConfig);
}
exports.validateThemeConfig = validateThemeConfig;