Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(docs): theme-common shouldn't depend on docs content #10316

Merged
merged 23 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor contextual search code
  • Loading branch information
slorber committed Jul 19, 2024
commit 783b61b813e6ef5afb2db1ffc5d732d08db8d3a8
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/

import {docVersionSearchTag} from '../searchUtils';
import {getDocsVersionSearchTag} from './docsSearch';

describe('docVersionSearchTag', () => {
it('works', () => {
expect(docVersionSearchTag('foo', 'bar')).toBe('docs-foo-bar');
expect(getDocsVersionSearchTag('foo', 'bar')).toBe('docs-foo-bar');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* 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 {
useAllDocsData,
useActivePluginAndVersion,
} from '@docusaurus/plugin-content-docs/client';
import {useDocsPreferredVersionByPluginId} from './docsPreferredVersion';

/** The search tag to append as each doc's metadata. */
export function getDocsVersionSearchTag(
pluginId: string,
versionName: string,
): string {
return `docs-${pluginId}-${versionName}`;
}

/**
* Gets the relevant docs tags to search.
* This is the logic that powers the contextual search feature.
*
* If user is browsing Android 1.4 docs, he'll get presented with:
* - Android '1.4' docs
* - iOS 'preferred | latest' docs
*
* The result is generic and not coupled to Algolia/DocSearch on purpose.
*/
export function useDocsContextualSearchTags(): string[] {
const allDocsData = useAllDocsData();
const activePluginAndVersion = useActivePluginAndVersion();
const docsPreferredVersionByPluginId = useDocsPreferredVersionByPluginId();

// This can't use more specialized hooks because we are mapping over all
// plugin instances.
function getDocPluginTags(pluginId: string) {
const activeVersion =
activePluginAndVersion?.activePlugin.pluginId === pluginId
? activePluginAndVersion.activeVersion
: undefined;

const preferredVersion = docsPreferredVersionByPluginId[pluginId];

const latestVersion = allDocsData[pluginId]!.versions.find(
(v) => v.isLast,
)!;

const version = activeVersion ?? preferredVersion ?? latestVersion;

return getDocsVersionSearchTag(pluginId, version.name);
}

return [...Object.keys(allDocsData).map(getDocPluginTags)];
}
5 changes: 5 additions & 0 deletions packages/docusaurus-plugin-content-docs/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ export {
DocsPreferredVersionContextProvider,
} from './docsPreferredVersion';

export {
useDocsContextualSearchTags,
getDocsVersionSearchTag,
} from './docsSearch';

export type ActivePlugin = {
pluginId: string;
pluginData: GlobalPluginData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import React from 'react';
import {HtmlClassNameProvider, PageMetadata} from '@docusaurus/theme-common';
import {
docVersionSearchTag,
getDocsVersionSearchTag,
DocsVersionProvider,
} from '@docusaurus/theme-common/internal';
} from '@docusaurus/plugin-content-docs/client';
import renderRoutes from '@docusaurus/renderRoutes';
import SearchMetadata from '@theme/SearchMetadata';

Expand All @@ -22,7 +22,7 @@ function DocVersionRootMetadata(props: Props): JSX.Element {
<>
<SearchMetadata
version={version.version}
tag={docVersionSearchTag(version.pluginId, version.version)}
tag={getDocsVersionSearchTag(version.pluginId, version.version)}
/>
<PageMetadata>
{version.noIndex && <meta name="robots" content="noindex, nofollow" />}
Expand Down
2 changes: 0 additions & 2 deletions packages/docusaurus-theme-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ export {
listStorageKeys,
} from './utils/storageUtils';

export {useContextualSearchFilters} from './utils/searchUtils';

export {usePluralForm} from './utils/usePluralForm';

export {useCollapsible, Collapsible} from './components/Collapsible';
Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-theme-common/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export {
containsLineNumbers,
} from './utils/codeBlockUtils';

export {docVersionSearchTag, DEFAULT_SEARCH_TAG} from './utils/searchUtils';
export {DEFAULT_SEARCH_TAG} from './utils/searchUtils';

export {useTitleFormatter} from './utils/generalUtils';

Expand Down
58 changes: 0 additions & 58 deletions packages/docusaurus-theme-common/src/utils/searchUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,4 @@
* LICENSE file in the root directory of this source tree.
*/

import {
useAllDocsData,
useActivePluginAndVersion,
} from '@docusaurus/plugin-content-docs/client';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import {useDocsPreferredVersionByPluginId} from '@docusaurus/plugin-content-docs/src/client/docsPreferredVersion';

export const DEFAULT_SEARCH_TAG = 'default';

/** The search tag to append as each doc's metadata. */
export function docVersionSearchTag(
pluginId: string,
versionName: string,
): string {
return `docs-${pluginId}-${versionName}`;
}

/**
* Gets the relevant context information for contextual search.
*
* The value is generic and not coupled to Algolia/DocSearch, since we may want
* to support multiple search engines, or allowing users to use their own search
* engine solution.
*/
export function useContextualSearchFilters(): {locale: string; tags: string[]} {
const {i18n} = useDocusaurusContext();
const allDocsData = useAllDocsData();
const activePluginAndVersion = useActivePluginAndVersion();
const docsPreferredVersionByPluginId = useDocsPreferredVersionByPluginId();

// This can't use more specialized hooks because we are mapping over all
// plugin instances.
function getDocPluginTags(pluginId: string) {
const activeVersion =
activePluginAndVersion?.activePlugin.pluginId === pluginId
? activePluginAndVersion.activeVersion
: undefined;

const preferredVersion = docsPreferredVersionByPluginId[pluginId];

const latestVersion = allDocsData[pluginId]!.versions.find(
(v) => v.isLast,
)!;

const version = activeVersion ?? preferredVersion ?? latestVersion;

return docVersionSearchTag(pluginId, version.name);
}

const tags = [
DEFAULT_SEARCH_TAG,
...Object.keys(allDocsData).map(getDocPluginTags),
];

return {
locale: i18n.currentLocale,
tags,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@
* LICENSE file in the root directory of this source tree.
*/

import {useContextualSearchFilters} from '@docusaurus/theme-common';
import {DEFAULT_SEARCH_TAG} from '@docusaurus/theme-common/internal';
import {useDocsContextualSearchTags} from '@docusaurus/plugin-content-docs/client';
import useDocusaurusContext from '@docusaurus/core/src/client/exports/useDocusaurusContext';

// Translate search-engine agnostic search filters to Algolia search filters
function useSearchTags() {
// only docs have custom search tags per version
const docsTags = useDocsContextualSearchTags();
return [DEFAULT_SEARCH_TAG, ...docsTags];
}

// Translate search-engine agnostic search tags to Algolia search filters
export function useAlgoliaContextualFacetFilters(): [string, string[]] {
const {locale, tags} = useContextualSearchFilters();
const locale = useDocusaurusContext().i18n.currentLocale;
const tags = useSearchTags();

// Seems safe to convert locale->language, see AlgoliaSearchMetadata comment
const languageFilter = `language:${locale}`;
Expand Down