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,60 @@
/**
* 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.
*/
/**
* These class names are used to style page layouts in Docusaurus, meant to be
* targeted by user-provided custom CSS selectors.
*/
export declare const ThemeClassNames: {
readonly page: {
readonly blogListPage: "blog-list-page";
readonly blogPostPage: "blog-post-page";
readonly blogTagsListPage: "blog-tags-list-page";
readonly blogTagPostListPage: "blog-tags-post-list-page";
readonly docsDocPage: "docs-doc-page";
readonly docsTagsListPage: "docs-tags-list-page";
readonly docsTagDocListPage: "docs-tags-doc-list-page";
readonly mdxPage: "mdx-page";
};
readonly wrapper: {
readonly main: "main-wrapper";
readonly blogPages: "blog-wrapper";
readonly docsPages: "docs-wrapper";
readonly mdxPages: "mdx-wrapper";
};
readonly common: {
readonly editThisPage: "theme-edit-this-page";
readonly lastUpdated: "theme-last-updated";
readonly backToTopButton: "theme-back-to-top-button";
readonly codeBlock: "theme-code-block";
readonly admonition: "theme-admonition";
readonly unlistedBanner: "theme-unlisted-banner";
readonly admonitionType: (type: string) => string;
};
readonly layout: {};
/**
* Follows the naming convention "theme-{blog,doc,version,page}?-<suffix>"
*/
readonly docs: {
readonly docVersionBanner: "theme-doc-version-banner";
readonly docVersionBadge: "theme-doc-version-badge";
readonly docBreadcrumbs: "theme-doc-breadcrumbs";
readonly docMarkdown: "theme-doc-markdown";
readonly docTocMobile: "theme-doc-toc-mobile";
readonly docTocDesktop: "theme-doc-toc-desktop";
readonly docFooter: "theme-doc-footer";
readonly docFooterTagsRow: "theme-doc-footer-tags-row";
readonly docFooterEditMetaRow: "theme-doc-footer-edit-meta-row";
readonly docSidebarContainer: "theme-doc-sidebar-container";
readonly docSidebarMenu: "theme-doc-sidebar-menu";
readonly docSidebarItemCategory: "theme-doc-sidebar-item-category";
readonly docSidebarItemLink: "theme-doc-sidebar-item-link";
readonly docSidebarItemCategoryLevel: (level: number) => `theme-doc-sidebar-item-category-level-${number}`;
readonly docSidebarItemLinkLevel: (level: number) => `theme-doc-sidebar-item-link-level-${number}`;
};
readonly blog: {};
};
//# sourceMappingURL=ThemeClassNames.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ThemeClassNames.d.ts","sourceRoot":"","sources":["../../src/utils/ThemeClassNames.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;wCA8BD,MAAM;;;IAM/B;;OAEG;;;;;;;;;;;;;;;sDAeoC,MAAM;kDAEV,MAAM;;;CAOjC,CAAC"}

View File

@@ -0,0 +1,70 @@
/**
* 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.
*/
// Please do not modify the classnames! This is a breaking change, and annoying
// for users!
/**
* These class names are used to style page layouts in Docusaurus, meant to be
* targeted by user-provided custom CSS selectors.
*/
export const ThemeClassNames = {
page: {
blogListPage: 'blog-list-page',
blogPostPage: 'blog-post-page',
blogTagsListPage: 'blog-tags-list-page',
blogTagPostListPage: 'blog-tags-post-list-page',
docsDocPage: 'docs-doc-page',
docsTagsListPage: 'docs-tags-list-page',
docsTagDocListPage: 'docs-tags-doc-list-page',
mdxPage: 'mdx-page',
},
wrapper: {
main: 'main-wrapper',
// TODO these wrapper class names are now quite useless
// TODO do breaking change later in 3.0
// we already add plugin name/id class on <html>: that's enough
blogPages: 'blog-wrapper',
docsPages: 'docs-wrapper',
mdxPages: 'mdx-wrapper',
},
common: {
editThisPage: 'theme-edit-this-page',
lastUpdated: 'theme-last-updated',
backToTopButton: 'theme-back-to-top-button',
codeBlock: 'theme-code-block',
admonition: 'theme-admonition',
unlistedBanner: 'theme-unlisted-banner',
admonitionType: (type) => `theme-admonition-${type}`,
},
layout: {
// TODO add other stable classNames here
},
/**
* Follows the naming convention "theme-{blog,doc,version,page}?-<suffix>"
*/
docs: {
docVersionBanner: 'theme-doc-version-banner',
docVersionBadge: 'theme-doc-version-badge',
docBreadcrumbs: 'theme-doc-breadcrumbs',
docMarkdown: 'theme-doc-markdown',
docTocMobile: 'theme-doc-toc-mobile',
docTocDesktop: 'theme-doc-toc-desktop',
docFooter: 'theme-doc-footer',
docFooterTagsRow: 'theme-doc-footer-tags-row',
docFooterEditMetaRow: 'theme-doc-footer-edit-meta-row',
docSidebarContainer: 'theme-doc-sidebar-container',
docSidebarMenu: 'theme-doc-sidebar-menu',
docSidebarItemCategory: 'theme-doc-sidebar-item-category',
docSidebarItemLink: 'theme-doc-sidebar-item-link',
docSidebarItemCategoryLevel: (level) => `theme-doc-sidebar-item-category-level-${level}`,
docSidebarItemLinkLevel: (level) => `theme-doc-sidebar-item-link-level-${level}`,
// TODO add other stable classNames here
},
blog: {
// TODO add other stable classNames here
},
};
//# sourceMappingURL=ThemeClassNames.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ThemeClassNames.js","sourceRoot":"","sources":["../../src/utils/ThemeClassNames.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+EAA+E;AAC/E,aAAa;AAEb;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE;QACJ,YAAY,EAAE,gBAAgB;QAC9B,YAAY,EAAE,gBAAgB;QAC9B,gBAAgB,EAAE,qBAAqB;QACvC,mBAAmB,EAAE,0BAA0B;QAE/C,WAAW,EAAE,eAAe;QAC5B,gBAAgB,EAAE,qBAAqB;QACvC,kBAAkB,EAAE,yBAAyB;QAE7C,OAAO,EAAE,UAAU;KACpB;IACD,OAAO,EAAE;QACP,IAAI,EAAE,cAAc;QACpB,uDAAuD;QACvD,uCAAuC;QACvC,+DAA+D;QAC/D,SAAS,EAAE,cAAc;QACzB,SAAS,EAAE,cAAc;QACzB,QAAQ,EAAE,aAAa;KACxB;IACD,MAAM,EAAE;QACN,YAAY,EAAE,sBAAsB;QACpC,WAAW,EAAE,oBAAoB;QACjC,eAAe,EAAE,0BAA0B;QAC3C,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,kBAAkB;QAC9B,cAAc,EAAE,uBAAuB;QAEvC,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,oBAAoB,IAAI,EAAE;KAC7D;IACD,MAAM,EAAE;IACN,wCAAwC;KACzC;IAED;;OAEG;IACH,IAAI,EAAE;QACJ,gBAAgB,EAAE,0BAA0B;QAC5C,eAAe,EAAE,yBAAyB;QAC1C,cAAc,EAAE,uBAAuB;QACvC,WAAW,EAAE,oBAAoB;QACjC,YAAY,EAAE,sBAAsB;QACpC,aAAa,EAAE,uBAAuB;QACtC,SAAS,EAAE,kBAAkB;QAC7B,gBAAgB,EAAE,2BAA2B;QAC7C,oBAAoB,EAAE,gCAAgC;QACtD,mBAAmB,EAAE,6BAA6B;QAClD,cAAc,EAAE,wBAAwB;QACxC,sBAAsB,EAAE,iCAAiC;QACzD,kBAAkB,EAAE,6BAA6B;QACjD,2BAA2B,EAAE,CAAC,KAAa,EAAE,EAAE,CAC7C,yCAAyC,KAAK,EAAW;QAC3D,uBAAuB,EAAE,CAAC,KAAa,EAAE,EAAE,CACzC,qCAAqC,KAAK,EAAW;QACvD,wCAAwC;KACzC;IACD,IAAI,EAAE;IACJ,wCAAwC;KACzC;CACO,CAAC"}

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.
*/
export declare function prefersReducedMotion(): boolean;
//# sourceMappingURL=accessibilityUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessibilityUtils.d.ts","sourceRoot":"","sources":["../../src/utils/accessibilityUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C"}

View File

@@ -0,0 +1,10 @@
/**
* 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 function prefersReducedMotion() {
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}
//# sourceMappingURL=accessibilityUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"accessibilityUtils.js","sourceRoot":"","sources":["../../src/utils/accessibilityUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAC,OAAO,CAAC;AACvE,CAAC"}

View File

@@ -0,0 +1,12 @@
/**
* 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 ReactNode } from 'react';
export declare function processAdmonitionProps<Props extends {
readonly children: ReactNode;
readonly title?: ReactNode;
}>(props: Props): Props;
//# sourceMappingURL=admonitionUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"admonitionUtils.d.ts","sourceRoot":"","sources":["../../src/utils/admonitionUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAuB5C,wBAAgB,sBAAsB,CACpC,KAAK,SAAS;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAC,EACxE,KAAK,EAAE,KAAK,GAAG,KAAK,CAWrB"}

View File

@@ -0,0 +1,32 @@
/**
* 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 from 'react';
// Workaround because it's difficult in MDX v1 to provide a MDX title as props
// See https://github.com/facebook/docusaurus/pull/7152#issuecomment-1145779682
function extractMDXAdmonitionTitle(children) {
const items = React.Children.toArray(children);
const mdxAdmonitionTitleWrapper = items.find((item) => React.isValidElement(item) && item.type === 'mdxAdmonitionTitle');
const rest = items.filter((item) => item !== mdxAdmonitionTitleWrapper);
const mdxAdmonitionTitle = mdxAdmonitionTitleWrapper?.props.children;
return {
mdxAdmonitionTitle,
rest: rest.length > 0 ? <>{rest}</> : null,
};
}
export function processAdmonitionProps(props) {
const { mdxAdmonitionTitle, rest } = extractMDXAdmonitionTitle(props.children);
const title = props.title ?? mdxAdmonitionTitle;
return {
...props,
// Do not return "title: undefined" prop
// this might create unwanted props overrides when merging props
// For example: {...default,...props}
...(title && { title }),
children: rest,
};
}
//# sourceMappingURL=admonitionUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"admonitionUtils.js","sourceRoot":"","sources":["../../src/utils/admonitionUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAuB,MAAM,OAAO,CAAC;AAE5C,8EAA8E;AAC9E,+EAA+E;AAC/E,SAAS,yBAAyB,CAAC,QAAmB;IAIpD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,yBAAyB,GAAG,KAAK,CAAC,IAAI,CAC1C,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,oBAAoB,CAChD,CAAC;IAE7B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,yBAAyB,CAAC,CAAC;IAExE,MAAM,kBAAkB,GAAG,yBAAyB,EAAE,KAAK,CAAC,QAAQ,CAAC;IAErE,OAAO;QACL,kBAAkB;QAClB,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;KAC3C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAEpC,KAAY;IACZ,MAAM,EAAC,kBAAkB,EAAE,IAAI,EAAC,GAAG,yBAAyB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,kBAAkB,CAAC;IAChD,OAAO;QACL,GAAG,KAAK;QACR,wCAAwC;QACxC,gEAAgE;QAChE,qCAAqC;QACrC,GAAG,CAAC,KAAK,IAAI,EAAC,KAAK,EAAC,CAAC;QACrB,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,13 @@
/**
* 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 { BlogSidebarItem } from '@docusaurus/plugin-content-blog';
/**
* Return the visible blog sidebar items to display.
* Unlisted items are filtered.
*/
export declare function useVisibleBlogSidebarItems(items: BlogSidebarItem[]): BlogSidebarItem[];
//# sourceMappingURL=blogUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"blogUtils.d.ts","sourceRoot":"","sources":["../../src/utils/blogUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,iCAAiC,CAAC;AASrE;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,eAAe,EAAE,GACvB,eAAe,EAAE,CAMnB"}

View File

@@ -0,0 +1,24 @@
/**
* 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 { useMemo } from 'react';
import { useLocation } from '@docusaurus/router';
import { isSamePath } from './routesUtils';
function isVisible(item, pathname) {
if (item.unlisted && !isSamePath(item.permalink, pathname)) {
return false;
}
return true;
}
/**
* Return the visible blog sidebar items to display.
* Unlisted items are filtered.
*/
export function useVisibleBlogSidebarItems(items) {
const { pathname } = useLocation();
return useMemo(() => items.filter((item) => isVisible(item, pathname)), [items, pathname]);
}
//# sourceMappingURL=blogUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"blogUtils.js","sourceRoot":"","sources":["../../src/utils/blogUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAGzC,SAAS,SAAS,CAAC,IAAqB,EAAE,QAAgB;IACxD,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;QAC1D,OAAO,KAAK,CAAC;KACd;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAwB;IAExB,MAAM,EAAC,QAAQ,EAAC,GAAG,WAAW,EAAE,CAAC;IACjC,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EACvD,CAAC,KAAK,EAAE,QAAQ,CAAC,CAClB,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,70 @@
/**
* 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 { CSSProperties } from 'react';
import type { PrismTheme } from 'prism-react-renderer';
export type MagicCommentConfig = {
className: string;
line?: string;
block?: {
start: string;
end: string;
};
};
export declare function parseCodeBlockTitle(metastring?: string): string;
export declare function containsLineNumbers(metastring?: string): boolean;
/**
* Gets the language name from the class name (set by MDX).
* e.g. `"language-javascript"` => `"javascript"`.
* Returns undefined if there is no language class name.
*/
export declare function parseLanguage(className: string): string | undefined;
/**
* Parses the code content, strips away any magic comments, and returns the
* clean content and the highlighted lines marked by the comments or metastring.
*
* If the metastring contains a range, the `content` will be returned as-is
* without any parsing. The returned `lineClassNames` will be a map from that
* number range to the first magic comment config entry (which _should_ be for
* line highlight directives.)
*
* @param content The raw code with magic comments. Trailing newline will be
* trimmed upfront.
* @param options Options for parsing behavior.
*/
export declare function parseLines(content: string, options: {
/**
* The full metastring, as received from MDX. Line ranges declared here
* start at 1.
*/
metastring: string | undefined;
/**
* Language of the code block, used to determine which kinds of magic
* comment styles to enable.
*/
language: string | undefined;
/**
* Magic comment types that we should try to parse. Each entry would
* correspond to one class name to apply to each line.
*/
magicComments: MagicCommentConfig[];
}): {
/**
* The highlighted lines, 0-indexed. e.g. `{ 0: ["highlight", "sample"] }`
* means the 1st line should have `highlight` and `sample` as class names.
*/
lineClassNames: {
[lineIndex: number]: string[];
};
/**
* If there's number range declared in the metastring, the code block is
* returned as-is (no parsing); otherwise, this is the clean code with all
* magic comments stripped away.
*/
code: string;
};
export declare function getPrismCssVariables(prismTheme: PrismTheme): CSSProperties;
//# sourceMappingURL=codeBlockUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"codeBlockUtils.d.ts","sourceRoot":"","sources":["../../src/utils/codeBlockUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AAEzC,OAAO,KAAK,EAAC,UAAU,EAAkB,MAAM,sBAAsB,CAAC;AAiCtE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,CAAC;CACtC,CAAC;AAqGF,wBAAgB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;;;OAGG;IACH,aAAa,EAAE,kBAAkB,EAAE,CAAC;CACrC,GACA;IACD;;;OAGG;IACH,cAAc,EAAE;QAAC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAC,CAAC;IAChD;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;CACd,CA4EA;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAc1E"}

View File

@@ -0,0 +1,210 @@
/**
* 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 rangeParser from 'parse-numeric-range';
const codeBlockTitleRegex = /title=(?<quote>["'])(?<title>.*?)\1/;
const metastringLinesRangeRegex = /\{(?<range>[\d,-]+)\}/;
// Supported types of highlight comments
const popularCommentPatterns = {
js: { start: '\\/\\/', end: '' },
jsBlock: { start: '\\/\\*', end: '\\*\\/' },
jsx: { start: '\\{\\s*\\/\\*', end: '\\*\\/\\s*\\}' },
bash: { start: '#', end: '' },
html: { start: '<!--', end: '-->' },
};
const commentPatterns = {
...popularCommentPatterns,
// minor comment styles
lua: { start: '--', end: '' },
wasm: { start: '\\;\\;', end: '' },
tex: { start: '%', end: '' },
vb: { start: "[']", end: '' },
vbnet: { start: "(?:_\\s*)?[']", end: '' },
rem: { start: '[Rr][Ee][Mm]\\b', end: '' },
f90: { start: '!', end: '' },
ml: { start: '\\(\\*', end: '\\*\\)' },
cobol: { start: '\\*>', end: '' }, // Free format only
};
const popularCommentTypes = Object.keys(popularCommentPatterns);
function getCommentPattern(languages, magicCommentDirectives) {
// To be more reliable, the opening and closing comment must match
const commentPattern = languages
.map((lang) => {
const { start, end } = commentPatterns[lang];
return `(?:${start}\\s*(${magicCommentDirectives
.flatMap((d) => [d.line, d.block?.start, d.block?.end].filter(Boolean))
.join('|')})\\s*${end})`;
})
.join('|');
// White space is allowed, but otherwise it should be on it's own line
return new RegExp(`^\\s*(?:${commentPattern})\\s*$`);
}
/**
* Select comment styles based on language
*/
function getAllMagicCommentDirectiveStyles(lang, magicCommentDirectives) {
switch (lang) {
case 'js':
case 'javascript':
case 'ts':
case 'typescript':
return getCommentPattern(['js', 'jsBlock'], magicCommentDirectives);
case 'jsx':
case 'tsx':
return getCommentPattern(['js', 'jsBlock', 'jsx'], magicCommentDirectives);
case 'html':
return getCommentPattern(['js', 'jsBlock', 'html'], magicCommentDirectives);
case 'python':
case 'py':
case 'bash':
return getCommentPattern(['bash'], magicCommentDirectives);
case 'markdown':
case 'md':
// Text uses HTML, front matter uses bash
return getCommentPattern(['html', 'jsx', 'bash'], magicCommentDirectives);
case 'tex':
case 'latex':
case 'matlab':
return getCommentPattern(['tex'], magicCommentDirectives);
case 'lua':
case 'haskell':
case 'sql':
return getCommentPattern(['lua'], magicCommentDirectives);
case 'wasm':
return getCommentPattern(['wasm'], magicCommentDirectives);
case 'vb':
case 'vba':
case 'visual-basic':
return getCommentPattern(['vb', 'rem'], magicCommentDirectives);
case 'vbnet':
return getCommentPattern(['vbnet', 'rem'], magicCommentDirectives);
case 'batch':
return getCommentPattern(['rem'], magicCommentDirectives);
case 'basic': // https://github.com/PrismJS/prism/blob/master/components/prism-basic.js#L3
return getCommentPattern(['rem', 'f90'], magicCommentDirectives);
case 'fsharp':
return getCommentPattern(['js', 'ml'], magicCommentDirectives);
case 'ocaml':
case 'sml':
return getCommentPattern(['ml'], magicCommentDirectives);
case 'fortran':
return getCommentPattern(['f90'], magicCommentDirectives);
case 'cobol':
return getCommentPattern(['cobol'], magicCommentDirectives);
default:
// All popular comment types
return getCommentPattern(popularCommentTypes, magicCommentDirectives);
}
}
export function parseCodeBlockTitle(metastring) {
return metastring?.match(codeBlockTitleRegex)?.groups.title ?? '';
}
export function containsLineNumbers(metastring) {
return Boolean(metastring?.includes('showLineNumbers'));
}
/**
* Gets the language name from the class name (set by MDX).
* e.g. `"language-javascript"` => `"javascript"`.
* Returns undefined if there is no language class name.
*/
export function parseLanguage(className) {
const languageClassName = className
.split(' ')
.find((str) => str.startsWith('language-'));
return languageClassName?.replace(/language-/, '');
}
/**
* Parses the code content, strips away any magic comments, and returns the
* clean content and the highlighted lines marked by the comments or metastring.
*
* If the metastring contains a range, the `content` will be returned as-is
* without any parsing. The returned `lineClassNames` will be a map from that
* number range to the first magic comment config entry (which _should_ be for
* line highlight directives.)
*
* @param content The raw code with magic comments. Trailing newline will be
* trimmed upfront.
* @param options Options for parsing behavior.
*/
export function parseLines(content, options) {
let code = content.replace(/\n$/, '');
const { language, magicComments, metastring } = options;
// Highlighted lines specified in props: don't parse the content
if (metastring && metastringLinesRangeRegex.test(metastring)) {
const linesRange = metastring.match(metastringLinesRangeRegex).groups
.range;
if (magicComments.length === 0) {
throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${metastring}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);
}
const metastringRangeClassName = magicComments[0].className;
const lines = rangeParser(linesRange)
.filter((n) => n > 0)
.map((n) => [n - 1, [metastringRangeClassName]]);
return { lineClassNames: Object.fromEntries(lines), code };
}
if (language === undefined) {
return { lineClassNames: {}, code };
}
const directiveRegex = getAllMagicCommentDirectiveStyles(language, magicComments);
// Go through line by line
const lines = code.split('\n');
const blocks = Object.fromEntries(magicComments.map((d) => [d.className, { start: 0, range: '' }]));
const lineToClassName = Object.fromEntries(magicComments
.filter((d) => d.line)
.map(({ className, line }) => [line, className]));
const blockStartToClassName = Object.fromEntries(magicComments
.filter((d) => d.block)
.map(({ className, block }) => [block.start, className]));
const blockEndToClassName = Object.fromEntries(magicComments
.filter((d) => d.block)
.map(({ className, block }) => [block.end, className]));
for (let lineNumber = 0; lineNumber < lines.length;) {
const line = lines[lineNumber];
const match = line.match(directiveRegex);
if (!match) {
// Lines without directives are unchanged
lineNumber += 1;
continue;
}
const directive = match
.slice(1)
.find((item) => item !== undefined);
if (lineToClassName[directive]) {
blocks[lineToClassName[directive]].range += `${lineNumber},`;
}
else if (blockStartToClassName[directive]) {
blocks[blockStartToClassName[directive]].start = lineNumber;
}
else if (blockEndToClassName[directive]) {
blocks[blockEndToClassName[directive]].range += `${blocks[blockEndToClassName[directive]].start}-${lineNumber - 1},`;
}
lines.splice(lineNumber, 1);
}
code = lines.join('\n');
const lineClassNames = {};
Object.entries(blocks).forEach(([className, { range }]) => {
rangeParser(range).forEach((l) => {
lineClassNames[l] ??= [];
lineClassNames[l].push(className);
});
});
return { lineClassNames, code };
}
export function getPrismCssVariables(prismTheme) {
const mapping = {
color: '--prism-color',
backgroundColor: '--prism-background-color',
};
const properties = {};
Object.entries(prismTheme.plain).forEach(([key, value]) => {
const varName = mapping[key];
if (varName && typeof value === 'string') {
properties[varName] = value;
}
});
return properties;
}
//# sourceMappingURL=codeBlockUtils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,109 @@
/**
* 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" />
import { type GlobalVersion, type GlobalSidebar, type GlobalDoc } from '@docusaurus/plugin-content-docs/client';
import type { Props as DocRootProps } from '@theme/DocRoot';
import type { PropSidebar, PropSidebarItem, PropSidebarItemCategory, PropVersionDoc, PropSidebarBreadcrumbsItem } from '@docusaurus/plugin-content-docs';
export declare const isDocsPluginEnabled: boolean;
/**
* A null-safe way to access a doc's data by ID in the active version.
*/
export declare function useDocById(id: string): PropVersionDoc;
/**
* A null-safe way to access a doc's data by ID in the active version.
*/
export declare function useDocById(id: string | undefined): PropVersionDoc | undefined;
/**
* Pure function, similar to `Array#find`, but works on the sidebar tree.
*/
export declare function findSidebarCategory(sidebar: PropSidebar, predicate: (category: PropSidebarItemCategory) => boolean): PropSidebarItemCategory | undefined;
/**
* Best effort to assign a link to a sidebar category. If the category doesn't
* have a link itself, we link to the first sub item with a link.
*/
export declare function findFirstSidebarItemCategoryLink(item: PropSidebarItemCategory): string | undefined;
/**
* Best effort to assign a link to a sidebar item.
*/
export declare function findFirstSidebarItemLink(item: PropSidebarItem): string | undefined;
/**
* Gets the category associated with the current location. Should only be used
* on category index pages.
*/
export declare function useCurrentSidebarCategory(): PropSidebarItemCategory;
/**
* Checks if a sidebar item should be active, based on the active path.
*/
export declare function isActiveSidebarItem(item: PropSidebarItem, activePath: string): boolean;
export declare function isVisibleSidebarItem(item: PropSidebarItem, activePath: string): boolean;
export declare function useVisibleSidebarItems(items: readonly PropSidebarItem[], activePath: string): PropSidebarItem[];
/**
* Gets the breadcrumbs of the current doc page, based on its sidebar location.
* Returns `null` if there's no sidebar or breadcrumbs are disabled.
*/
export declare function useSidebarBreadcrumbs(): PropSidebarBreadcrumbsItem[] | null;
/**
* "Version candidates" are mostly useful for the layout components, which must
* be able to work on all pages. For example, if a user has `{ type: "doc",
* docId: "intro" }` as a navbar item, which version does that refer to? We
* believe that it could refer to at most three version candidates:
*
* 1. The **active version**, the one that the user is currently browsing. See
* {@link useActiveDocContext}.
* 2. The **preferred version**, the one that the user last visited. See
* {@link useDocsPreferredVersion}.
* 3. The **latest version**, the "default". See {@link useLatestVersion}.
*
* @param docsPluginId The plugin ID to get versions from.
* @returns An array of 1~3 versions with priorities defined above, guaranteed
* to be unique and non-sparse. Will be memoized, hence stable for deps array.
*/
export declare function useDocsVersionCandidates(docsPluginId?: string): [GlobalVersion, ...GlobalVersion[]];
/**
* The layout components, like navbar items, must be able to work on all pages,
* even on non-doc ones where there's no version context, so a sidebar ID could
* be ambiguous. This hook would always return a sidebar to be linked to. See
* also {@link useDocsVersionCandidates} for how this selection is done.
*
* @throws This hook throws if a sidebar with said ID is not found.
*/
export declare function useLayoutDocsSidebar(sidebarId: string, docsPluginId?: string): GlobalSidebar;
/**
* The layout components, like navbar items, must be able to work on all pages,
* even on non-doc ones where there's no version context, so a doc ID could be
* ambiguous. This hook would always return a doc to be linked to. See also
* {@link useDocsVersionCandidates} for how this selection is done.
*
* @throws This hook throws if a doc with said ID is not found.
*/
export declare function useLayoutDoc(docId: string, docsPluginId?: string): GlobalDoc | null;
/**
* The docs plugin creates nested routes, with the top-level route providing the
* version metadata, and the subroutes creating individual doc pages. This hook
* will match the current location against all known sub-routes.
*
* @param props The props received by `@theme/DocRoot`
* @returns The data of the relevant document at the current location, or `null`
* if no document associated with the current location can be found.
*/
export declare function useDocRootMetadata({ route }: DocRootProps): null | {
/** The element that should be rendered at the current location. */
docElement: JSX.Element;
/**
* The name of the sidebar associated with the current doc. `sidebarName` and
* `sidebarItems` correspond to the value of {@link useDocsSidebar}.
*/
sidebarName: string | undefined;
/** The items of the sidebar associated with the current doc. */
sidebarItems: PropSidebar | undefined;
};
/**
* Filter items we don't want to display on the doc card list view
* @param items
*/
export declare function filterDocCardListItems(items: PropSidebarItem[]): PropSidebarItem[];
//# sourceMappingURL=docsUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"docsUtils.d.ts","sourceRoot":"","sources":["../../src/utils/docsUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;;AAKH,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAC,KAAK,IAAI,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAM1D,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,0BAA0B,EAC3B,MAAM,iCAAiC,CAAC;AAGzC,eAAO,MAAM,mBAAmB,EAAE,OAA0B,CAAC;AAE7D;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,CAAC;AACvD;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;AAa/E;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,OAAO,GACxD,uBAAuB,GAAG,SAAS,CAarC;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,uBAAuB,GAC5B,MAAM,GAAG,SAAS,CAYpB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,eAAe,GACpB,MAAM,GAAG,SAAS,CASpB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,uBAAuB,CAkBnE;AASD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,eAAe,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAaT;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,UAAU,EAAE,MAAM,GACjB,OAAO,CAaT;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,UAAU,EAAE,MAAM,GACjB,eAAe,EAAE,CAKnB;AAmDD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,0BAA0B,EAAE,GAAG,IAAI,CAQ3E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,CAAC,EAAE,MAAM,GACpB,CAAC,aAAa,EAAE,GAAG,aAAa,EAAE,CAAC,CAWrC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,GACpB,aAAa,CAoBf;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,SAAS,GAAG,IAAI,CAuBlB;AAGD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAC,KAAK,EAAC,EAAE,YAAY,GAAG,IAAI,GAAG;IAChE,mEAAmE;IACnE,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC;IACxB;;;OAGG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,gEAAgE;IAChE,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;CACvC,CAyBA;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,eAAe,EAAE,GACvB,eAAe,EAAE,CAQnB"}

View File

@@ -0,0 +1,276 @@
/**
* 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 { useMemo } from 'react';
import { matchPath, useLocation } from '@docusaurus/router';
import renderRoutes from '@docusaurus/renderRoutes';
import { useAllDocsData, useActivePlugin, useActiveDocContext, useLatestVersion, } from '@docusaurus/plugin-content-docs/client';
import { useDocsPreferredVersion } from '../contexts/docsPreferredVersion';
import { useDocsVersion } from '../contexts/docsVersion';
import { useDocsSidebar } from '../contexts/docsSidebar';
import { uniq } from './jsUtils';
import { isSamePath } from './routesUtils';
// TODO not ideal, see also "useDocs"
export const isDocsPluginEnabled = !!useAllDocsData;
export function useDocById(id) {
const version = useDocsVersion();
if (!id) {
return undefined;
}
const doc = version.docs[id];
if (!doc) {
throw new Error(`no version doc found by id=${id}`);
}
return doc;
}
/**
* Pure function, similar to `Array#find`, but works on the sidebar tree.
*/
export function findSidebarCategory(sidebar, predicate) {
for (const item of sidebar) {
if (item.type === 'category') {
if (predicate(item)) {
return item;
}
const subItem = findSidebarCategory(item.items, predicate);
if (subItem) {
return subItem;
}
}
}
return undefined;
}
/**
* Best effort to assign a link to a sidebar category. If the category doesn't
* have a link itself, we link to the first sub item with a link.
*/
export function findFirstSidebarItemCategoryLink(item) {
if (item.href && !item.linkUnlisted) {
return item.href;
}
for (const subItem of item.items) {
const link = findFirstSidebarItemLink(subItem);
if (link) {
return link;
}
}
return undefined;
}
/**
* Best effort to assign a link to a sidebar item.
*/
export function findFirstSidebarItemLink(item) {
if (item.type === 'link' && !item.unlisted) {
return item.href;
}
if (item.type === 'category') {
return findFirstSidebarItemCategoryLink(item);
}
// Other items types, like "html"
return undefined;
}
/**
* Gets the category associated with the current location. Should only be used
* on category index pages.
*/
export function useCurrentSidebarCategory() {
const { pathname } = useLocation();
const sidebar = useDocsSidebar();
if (!sidebar) {
throw new Error('Unexpected: cant find current sidebar in context');
}
const categoryBreadcrumbs = getSidebarBreadcrumbs({
sidebarItems: sidebar.items,
pathname,
onlyCategories: true,
});
const deepestCategory = categoryBreadcrumbs.slice(-1)[0];
if (!deepestCategory) {
throw new Error(`${pathname} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);
}
return deepestCategory;
}
const isActive = (testedPath, activePath) => typeof testedPath !== 'undefined' && isSamePath(testedPath, activePath);
const containsActiveSidebarItem = (items, activePath) => items.some((subItem) => isActiveSidebarItem(subItem, activePath));
/**
* Checks if a sidebar item should be active, based on the active path.
*/
export function isActiveSidebarItem(item, activePath) {
if (item.type === 'link') {
return isActive(item.href, activePath);
}
if (item.type === 'category') {
return (isActive(item.href, activePath) ||
containsActiveSidebarItem(item.items, activePath));
}
return false;
}
export function isVisibleSidebarItem(item, activePath) {
switch (item.type) {
case 'category':
return (isActiveSidebarItem(item, activePath) ||
item.items.some((subItem) => isVisibleSidebarItem(subItem, activePath)));
case 'link':
// An unlisted item remains visible if it is active
return !item.unlisted || isActiveSidebarItem(item, activePath);
default:
return true;
}
}
export function useVisibleSidebarItems(items, activePath) {
return useMemo(() => items.filter((item) => isVisibleSidebarItem(item, activePath)), [items, activePath]);
}
/**
* Get the sidebar the breadcrumbs for a given pathname
* Ordered from top to bottom
*/
function getSidebarBreadcrumbs({ sidebarItems, pathname, onlyCategories = false, }) {
const breadcrumbs = [];
function extract(items) {
for (const item of items) {
if ((item.type === 'category' &&
(isSamePath(item.href, pathname) || extract(item.items))) ||
(item.type === 'link' && isSamePath(item.href, pathname))) {
const filtered = onlyCategories && item.type !== 'category';
if (!filtered) {
breadcrumbs.unshift(item);
}
return true;
}
}
return false;
}
extract(sidebarItems);
return breadcrumbs;
}
/**
* Gets the breadcrumbs of the current doc page, based on its sidebar location.
* Returns `null` if there's no sidebar or breadcrumbs are disabled.
*/
export function useSidebarBreadcrumbs() {
const sidebar = useDocsSidebar();
const { pathname } = useLocation();
const breadcrumbsOption = useActivePlugin()?.pluginData.breadcrumbs;
if (breadcrumbsOption === false || !sidebar) {
return null;
}
return getSidebarBreadcrumbs({ sidebarItems: sidebar.items, pathname });
}
/**
* "Version candidates" are mostly useful for the layout components, which must
* be able to work on all pages. For example, if a user has `{ type: "doc",
* docId: "intro" }` as a navbar item, which version does that refer to? We
* believe that it could refer to at most three version candidates:
*
* 1. The **active version**, the one that the user is currently browsing. See
* {@link useActiveDocContext}.
* 2. The **preferred version**, the one that the user last visited. See
* {@link useDocsPreferredVersion}.
* 3. The **latest version**, the "default". See {@link useLatestVersion}.
*
* @param docsPluginId The plugin ID to get versions from.
* @returns An array of 1~3 versions with priorities defined above, guaranteed
* to be unique and non-sparse. Will be memoized, hence stable for deps array.
*/
export function useDocsVersionCandidates(docsPluginId) {
const { activeVersion } = useActiveDocContext(docsPluginId);
const { preferredVersion } = useDocsPreferredVersion(docsPluginId);
const latestVersion = useLatestVersion(docsPluginId);
return useMemo(() => uniq([activeVersion, preferredVersion, latestVersion].filter(Boolean)), [activeVersion, preferredVersion, latestVersion]);
}
/**
* The layout components, like navbar items, must be able to work on all pages,
* even on non-doc ones where there's no version context, so a sidebar ID could
* be ambiguous. This hook would always return a sidebar to be linked to. See
* also {@link useDocsVersionCandidates} for how this selection is done.
*
* @throws This hook throws if a sidebar with said ID is not found.
*/
export function useLayoutDocsSidebar(sidebarId, docsPluginId) {
const versions = useDocsVersionCandidates(docsPluginId);
return useMemo(() => {
const allSidebars = versions.flatMap((version) => version.sidebars ? Object.entries(version.sidebars) : []);
const sidebarEntry = allSidebars.find((sidebar) => sidebar[0] === sidebarId);
if (!sidebarEntry) {
throw new Error(`Can't find any sidebar with id "${sidebarId}" in version${versions.length > 1 ? 's' : ''} ${versions.map((version) => version.name).join(', ')}".
Available sidebar ids are:
- ${allSidebars.map((entry) => entry[0]).join('\n- ')}`);
}
return sidebarEntry[1];
}, [sidebarId, versions]);
}
/**
* The layout components, like navbar items, must be able to work on all pages,
* even on non-doc ones where there's no version context, so a doc ID could be
* ambiguous. This hook would always return a doc to be linked to. See also
* {@link useDocsVersionCandidates} for how this selection is done.
*
* @throws This hook throws if a doc with said ID is not found.
*/
export function useLayoutDoc(docId, docsPluginId) {
const versions = useDocsVersionCandidates(docsPluginId);
return useMemo(() => {
const allDocs = versions.flatMap((version) => version.docs);
const doc = allDocs.find((versionDoc) => versionDoc.id === docId);
if (!doc) {
const isDraft = versions
.flatMap((version) => version.draftIds)
.includes(docId);
// Drafts should be silently filtered instead of throwing
if (isDraft) {
return null;
}
throw new Error(`Couldn't find any doc with id "${docId}" in version${versions.length > 1 ? 's' : ''} "${versions.map((version) => version.name).join(', ')}".
Available doc ids are:
- ${uniq(allDocs.map((versionDoc) => versionDoc.id)).join('\n- ')}`);
}
return doc;
}, [docId, versions]);
}
// TODO later read version/route directly from context
/**
* The docs plugin creates nested routes, with the top-level route providing the
* version metadata, and the subroutes creating individual doc pages. This hook
* will match the current location against all known sub-routes.
*
* @param props The props received by `@theme/DocRoot`
* @returns The data of the relevant document at the current location, or `null`
* if no document associated with the current location can be found.
*/
export function useDocRootMetadata({ route }) {
const location = useLocation();
const versionMetadata = useDocsVersion();
const docRoutes = route.routes;
const currentDocRoute = docRoutes.find((docRoute) => matchPath(location.pathname, docRoute));
if (!currentDocRoute) {
return null;
}
// For now, the sidebarName is added as route config: not ideal!
const sidebarName = currentDocRoute.sidebar;
const sidebarItems = sidebarName
? versionMetadata.docsSidebars[sidebarName]
: undefined;
const docElement = renderRoutes(docRoutes);
return {
docElement,
sidebarName,
sidebarItems,
};
}
/**
* Filter items we don't want to display on the doc card list view
* @param items
*/
export function filterDocCardListItems(items) {
return items.filter((item) => {
const canHaveLink = item.type === 'category' || item.type === 'link';
if (canHaveLink) {
return !!findFirstSidebarItemLink(item);
}
return true;
});
}
//# sourceMappingURL=docsUtils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,32 @@
/**
* 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="@docusaurus/module-type-aliases" />
import React, { type ComponentProps } from 'react';
import type { Props as ErrorProps } from '@theme/Error';
export declare function ErrorBoundaryTryAgainButton(props: ComponentProps<'button'>): JSX.Element;
export declare function ErrorBoundaryErrorMessageFallback({ error, tryAgain, }: ErrorProps): JSX.Element;
export declare function ErrorBoundaryError({ error }: {
error: Error;
}): JSX.Element;
/**
* This component is useful to wrap a low-level error into a more meaningful
* error with extra context, using the ES error-cause feature.
*
* <ErrorCauseBoundary
* onError={(error) => new Error("extra context message",{cause: error})}
* >
* <RiskyComponent>
* </ErrorCauseBoundary>
*/
export declare class ErrorCauseBoundary extends React.Component<{
children: React.ReactNode;
onError: (error: Error, errorInfo: React.ErrorInfo) => Error;
}, unknown> {
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): never;
render(): React.ReactNode;
}
//# sourceMappingURL=errorBoundaryUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"errorBoundaryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/errorBoundaryUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,cAAc,EAAC,MAAM,OAAO,CAAC;AAGjD,OAAO,KAAK,EAAC,KAAK,IAAI,UAAU,EAAC,MAAM,cAAc,CAAC;AAGtD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,GAC9B,GAAG,CAAC,OAAO,CAUb;AAGD,wBAAgB,iCAAiC,CAAC,EAChD,KAAK,EACL,QAAQ,GACT,EAAE,UAAU,GAAG,GAAG,CAAC,OAAO,CAO1B;AAED,wBAAgB,kBAAkB,CAAC,EAAC,KAAK,EAAC,EAAE;IAAC,KAAK,EAAE,KAAK,CAAA;CAAC,GAAG,GAAG,CAAC,OAAO,CAIvE;AAED;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,SAAQ,KAAK,CAAC,SAAS,CACrD;IACE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC;CAC9D,EACD,OAAO,CACR;IACU,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,KAAK;IAIlE,MAAM,IAAI,KAAK,CAAC,SAAS;CAGnC"}

View File

@@ -0,0 +1,48 @@
/**
* 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 from 'react';
import Translate from '@docusaurus/Translate';
import { getErrorCausalChain } from '@docusaurus/utils-common';
import styles from './errorBoundaryUtils.module.css';
export function ErrorBoundaryTryAgainButton(props) {
return (<button type="button" {...props}>
<Translate id="theme.ErrorPageContent.tryAgain" description="The label of the button to try again rendering when the React error boundary captures an error">
Try again
</Translate>
</button>);
}
// A very simple reusable ErrorBoundary fallback component
export function ErrorBoundaryErrorMessageFallback({ error, tryAgain, }) {
return (<div className={styles.errorBoundaryFallback}>
<p>{error.message}</p>
<ErrorBoundaryTryAgainButton onClick={tryAgain}/>
</div>);
}
export function ErrorBoundaryError({ error }) {
const causalChain = getErrorCausalChain(error);
const fullMessage = causalChain.map((e) => e.message).join('\n\nCause:\n');
return <p className={styles.errorBoundaryError}>{fullMessage}</p>;
}
/**
* This component is useful to wrap a low-level error into a more meaningful
* error with extra context, using the ES error-cause feature.
*
* <ErrorCauseBoundary
* onError={(error) => new Error("extra context message",{cause: error})}
* >
* <RiskyComponent>
* </ErrorCauseBoundary>
*/
export class ErrorCauseBoundary extends React.Component {
componentDidCatch(error, errorInfo) {
throw this.props.onError(error, errorInfo);
}
render() {
return this.props.children;
}
}
//# sourceMappingURL=errorBoundaryUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"errorBoundaryUtils.js","sourceRoot":"","sources":["../../src/utils/errorBoundaryUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAA4B,MAAM,OAAO,CAAC;AACjD,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAC,mBAAmB,EAAC,MAAM,0BAA0B,CAAC;AAE7D,OAAO,MAAM,MAAM,iCAAiC,CAAC;AAErD,MAAM,UAAU,2BAA2B,CACzC,KAA+B;IAE/B,OAAO,CACL,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,CAC9B;MAAA,CAAC,SAAS,CACR,EAAE,CAAC,iCAAiC,CACpC,WAAW,CAAC,gGAAgG,CAC5G;;MACF,EAAE,SAAS,CACb;IAAA,EAAE,MAAM,CAAC,CACV,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,iCAAiC,CAAC,EAChD,KAAK,EACL,QAAQ,GACG;IACX,OAAO,CACL,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAC3C;MAAA,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CACrB;MAAA,CAAC,2BAA2B,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EACjD;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAC,KAAK,EAAiB;IACxD,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3E,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK,CAAC,SAM7C;IACU,iBAAiB,CAAC,KAAY,EAAE,SAA0B;QACjE,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC;IAEQ,MAAM;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF"}

View File

@@ -0,0 +1,16 @@
/**
* 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.
*/
.errorBoundaryError {
white-space: pre-wrap;
color: red;
}
.errorBoundaryFallback {
color: red;
padding: 0.55rem;
}

View File

@@ -0,0 +1,13 @@
/**
* 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 { MultiColumnFooter, SimpleFooter } from './useThemeConfig';
/**
* A rough duck-typing about whether the `footer.links` is intended to be multi-
* column.
*/
export declare function isMultiColumnFooterLinks(links: MultiColumnFooter['links'] | SimpleFooter['links']): links is MultiColumnFooter['links'];
//# sourceMappingURL=footerUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"footerUtils.d.ts","sourceRoot":"","sources":["../../src/utils/footerUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAC,iBAAiB,EAAE,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,GACxD,KAAK,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAErC"}

View File

@@ -0,0 +1,14 @@
/**
* 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.
*/
/**
* A rough duck-typing about whether the `footer.links` is intended to be multi-
* column.
*/
export function isMultiColumnFooterLinks(links) {
return 'title' in links[0];
}
//# sourceMappingURL=footerUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"footerUtils.js","sourceRoot":"","sources":["../../src/utils/footerUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAyD;IAEzD,OAAO,OAAO,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC;AAC9B,CAAC"}

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.
*/
/**
* Formats the page's title based on relevant site config and other contexts.
*/
export declare function useTitleFormatter(title?: string | undefined): string;
//# sourceMappingURL=generalUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMpE"}

View File

@@ -0,0 +1,18 @@
/**
* 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';
/**
* Formats the page's title based on relevant site config and other contexts.
*/
export function useTitleFormatter(title) {
const { siteConfig } = useDocusaurusContext();
const { title: siteTitle, titleDelimiter } = siteConfig;
return title?.trim().length
? `${title.trim()} ${titleDelimiter} ${siteTitle}`
: siteTitle;
}
//# sourceMappingURL=generalUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"generalUtils.js","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,oBAAoB,MAAM,kCAAkC,CAAC;AAEpE;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAA0B;IAC1D,MAAM,EAAC,UAAU,EAAC,GAAG,oBAAoB,EAAE,CAAC;IAC5C,MAAM,EAAC,KAAK,EAAE,SAAS,EAAE,cAAc,EAAC,GAAG,UAAU,CAAC;IACtD,OAAO,KAAK,EAAE,IAAI,EAAE,CAAC,MAAM;QACzB,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,cAAc,IAAI,SAAS,EAAE;QAClD,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC"}

View File

@@ -0,0 +1,34 @@
/**
* 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 { History, Location, Action } from 'history';
type HistoryBlockHandler = (location: Location, action: Action) => void | false;
/**
* Permits to register a handler that will be called on history pop navigation
* (backward/forward). If the handler returns `false`, the backward/forward
* transition will be blocked. Unfortunately there's no good way to detect the
* "direction" (backward/forward) of the POP event.
*/
export declare function useHistoryPopHandler(handler: HistoryBlockHandler): void;
/**
* Permits to efficiently subscribe to a slice of the history
* See https://thisweekinreact.com/articles/useSyncExternalStore-the-underrated-react-api
* @param selector
*/
export declare function useHistorySelector<Value>(selector: (history: History<unknown>) => Value): Value;
/**
* Permits to efficiently subscribe to a specific querystring value
* @param key
*/
export declare function useQueryStringValue(key: string | null): string | null;
export declare function useQueryStringKeySetter(): (key: string, newValue: string | null, options?: {
push: boolean;
}) => void;
export declare function useQueryString(key: string): [string, (newValue: string, options?: {
push: boolean;
}) => void];
export {};
//# sourceMappingURL=historyUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"historyUtils.d.ts","sourceRoot":"","sources":["../../src/utils/historyUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,SAAS,CAAC;AAEvD,KAAK,mBAAmB,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,KAAK,CAAC;AAiBhF;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CASvE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EACtC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,KAAK,GAC7C,KAAK,CAOP;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAOrE;AAED,wBAAgB,uBAAuB,IAAI,CACzC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,CAAC,EAAE;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,KACtB,IAAI,CAiBR;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GACV,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,KAAK,IAAI,CAAC,CAYjE"}

View File

@@ -0,0 +1,85 @@
/**
* 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, useEffect, useSyncExternalStore } from 'react';
import { useHistory } from '@docusaurus/router';
import { useEvent } from './reactUtils';
/**
* Permits to register a handler that will be called on history actions (pop,
* push, replace). If the handler returns `false`, the navigation transition
* will be blocked/cancelled.
*/
function useHistoryActionHandler(handler) {
const history = useHistory();
const stableHandler = useEvent(handler);
useEffect(
// See https://github.com/remix-run/history/blob/main/docs/blocking-transitions.md
() => history.block((location, action) => stableHandler(location, action)), [history, stableHandler]);
}
/**
* Permits to register a handler that will be called on history pop navigation
* (backward/forward). If the handler returns `false`, the backward/forward
* transition will be blocked. Unfortunately there's no good way to detect the
* "direction" (backward/forward) of the POP event.
*/
export function useHistoryPopHandler(handler) {
useHistoryActionHandler((location, action) => {
if (action === 'POP') {
// Maybe block navigation if handler returns false
return handler(location, action);
}
// Don't block other navigation actions
return undefined;
});
}
/**
* Permits to efficiently subscribe to a slice of the history
* See https://thisweekinreact.com/articles/useSyncExternalStore-the-underrated-react-api
* @param selector
*/
export function useHistorySelector(selector) {
const history = useHistory();
return useSyncExternalStore(history.listen, () => selector(history), () => selector(history));
}
/**
* Permits to efficiently subscribe to a specific querystring value
* @param key
*/
export function useQueryStringValue(key) {
return useHistorySelector((history) => {
if (key === null) {
return null;
}
return new URLSearchParams(history.location.search).get(key);
});
}
export function useQueryStringKeySetter() {
const history = useHistory();
return useCallback((key, newValue, options) => {
const searchParams = new URLSearchParams(history.location.search);
if (newValue) {
searchParams.set(key, newValue);
}
else {
searchParams.delete(key);
}
const updaterFn = options?.push ? history.push : history.replace;
updaterFn({
search: searchParams.toString(),
});
}, [history]);
}
export function useQueryString(key) {
const value = useQueryStringValue(key) ?? '';
const setQueryString = useQueryStringKeySetter();
return [
value,
useCallback((newValue, options) => {
setQueryString(key, newValue, options);
}, [setQueryString, key]),
];
}
//# sourceMappingURL=historyUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"historyUtils.js","sourceRoot":"","sources":["../../src/utils/historyUtils.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,23 @@
/**
* 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.
*/
/**
* Gets the duplicate values in an array.
* @param arr The array.
* @param comparator Compares two values and returns `true` if they are equal
* (duplicated).
* @returns Value of the elements `v` that have a preceding element `u` where
* `comparator(u, v) === true`. Values within the returned array are not
* guaranteed to be unique.
*/
export declare function duplicates<T>(arr: readonly T[], comparator?: (a: T, b: T) => boolean): T[];
/**
* Remove duplicate array items (similar to `_.uniq`)
* @param arr The array.
* @returns An array with duplicate elements removed by reference comparison.
*/
export declare function uniq<T>(arr: T[]): T[];
//# sourceMappingURL=jsUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"jsUtils.d.ts","sourceRoot":"","sources":["../../src/utils/jsUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,GAAG,EAAE,SAAS,CAAC,EAAE,EACjB,UAAU,GAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAA2B,GACtD,CAAC,EAAE,CAIL;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAGrC"}

View File

@@ -0,0 +1,29 @@
/**
* 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.
*/
// A replacement of lodash in client code
/**
* Gets the duplicate values in an array.
* @param arr The array.
* @param comparator Compares two values and returns `true` if they are equal
* (duplicated).
* @returns Value of the elements `v` that have a preceding element `u` where
* `comparator(u, v) === true`. Values within the returned array are not
* guaranteed to be unique.
*/
export function duplicates(arr, comparator = (a, b) => a === b) {
return arr.filter((v, vIndex) => arr.findIndex((u) => comparator(u, v)) !== vIndex);
}
/**
* Remove duplicate array items (similar to `_.uniq`)
* @param arr The array.
* @returns An array with duplicate elements removed by reference comparison.
*/
export function uniq(arr) {
// Note: had problems with [...new Set()]: https://github.com/facebook/docusaurus/issues/4972#issuecomment-863895061
return Array.from(new Set(arr));
}
//# sourceMappingURL=jsUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"jsUtils.js","sourceRoot":"","sources":["../../src/utils/jsUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yCAAyC;AAEzC;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CACxB,GAAiB,EACjB,aAAsC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;IAEvD,OAAO,GAAG,CAAC,MAAM,CACf,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM,CACjE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAI,GAAQ;IAC9B,oHAAoH;IACpH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC"}

View File

@@ -0,0 +1,38 @@
/**
* 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 ReactNode } from 'react';
type PageMetadataProps = {
readonly title?: string;
readonly description?: string;
readonly keywords?: readonly string[] | string;
readonly image?: string;
readonly children?: ReactNode;
};
/**
* Helper component to manipulate page metadata and override site defaults.
* Works in the same way as Helmet.
*/
export declare function PageMetadata({ title, description, keywords, image, children, }: PageMetadataProps): JSX.Element;
/**
* Every layer of this provider will append a class name to the HTML element.
* There's no consumer for this hook: it's side-effect-only. This wrapper is
* necessary because Helmet does not "merge" classes.
* @see https://github.com/staylor/react-helmet-async/issues/161
*/
export declare function HtmlClassNameProvider({ className: classNameProp, children, }: {
className: string;
children: ReactNode;
}): JSX.Element;
/**
* A very thin wrapper around `HtmlClassNameProvider` that adds the plugin ID +
* name to the HTML class name.
*/
export declare function PluginHtmlClassNameProvider({ children, }: {
children: ReactNode;
}): JSX.Element;
export {};
//# sourceMappingURL=metadataUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"metadataUtils.d.ts","sourceRoot":"","sources":["../../src/utils/metadataUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAO5C,KAAK,iBAAiB,GAAG;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,WAAW,EACX,QAAQ,EACR,KAAK,EACL,QAAQ,GACT,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CA6BjC;AAID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EAAE,aAAa,EACxB,QAAQ,GACT,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CAWd;AASD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,EAC1C,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CASd"}

View File

@@ -0,0 +1,70 @@
/**
* 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 from 'react';
import clsx from 'clsx';
import Head from '@docusaurus/Head';
import useRouteContext from '@docusaurus/useRouteContext';
import { useBaseUrlUtils } from '@docusaurus/useBaseUrl';
import { useTitleFormatter } from './generalUtils';
/**
* Helper component to manipulate page metadata and override site defaults.
* Works in the same way as Helmet.
*/
export function PageMetadata({ title, description, keywords, image, children, }) {
const pageTitle = useTitleFormatter(title);
const { withBaseUrl } = useBaseUrlUtils();
const pageImage = image ? withBaseUrl(image, { absolute: true }) : undefined;
return (<Head>
{title && <title>{pageTitle}</title>}
{title && <meta property="og:title" content={pageTitle}/>}
{description && <meta name="description" content={description}/>}
{description && <meta property="og:description" content={description}/>}
{keywords && (<meta name="keywords" content={
// https://github.com/microsoft/TypeScript/issues/17002
(Array.isArray(keywords) ? keywords.join(',') : keywords)}/>)}
{pageImage && <meta property="og:image" content={pageImage}/>}
{pageImage && <meta name="twitter:image" content={pageImage}/>}
{children}
</Head>);
}
const HtmlClassNameContext = React.createContext(undefined);
/**
* Every layer of this provider will append a class name to the HTML element.
* There's no consumer for this hook: it's side-effect-only. This wrapper is
* necessary because Helmet does not "merge" classes.
* @see https://github.com/staylor/react-helmet-async/issues/161
*/
export function HtmlClassNameProvider({ className: classNameProp, children, }) {
const classNameContext = React.useContext(HtmlClassNameContext);
const className = clsx(classNameContext, classNameProp);
return (<HtmlClassNameContext.Provider value={className}>
<Head>
<html className={className}/>
</Head>
{children}
</HtmlClassNameContext.Provider>);
}
function pluginNameToClassName(pluginName) {
return `plugin-${pluginName.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi, '')}`;
}
/**
* A very thin wrapper around `HtmlClassNameProvider` that adds the plugin ID +
* name to the HTML class name.
*/
export function PluginHtmlClassNameProvider({ children, }) {
const routeContext = useRouteContext();
const nameClass = pluginNameToClassName(routeContext.plugin.name);
const idClass = `plugin-id-${routeContext.plugin.id}`;
return (<HtmlClassNameProvider className={clsx(nameClass, idClass)}>
{children}
</HtmlClassNameProvider>);
}
//# sourceMappingURL=metadataUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"metadataUtils.js","sourceRoot":"","sources":["../../src/utils/metadataUtils.tsx"],"names":[],"mappings":"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"}

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.
*/
import { type ReactNode } from 'react';
/**
* Split links by left/right. If position is unspecified, fallback to right.
*/
export declare function splitNavbarItems<T extends {
position?: 'left' | 'right';
}>(items: T[]): [leftItems: T[], rightItems: T[]];
/**
* Composes multiple navbar state providers that are mutually dependent and
* hence can't be re-ordered.
*/
export declare function NavbarProvider({ children }: {
children: ReactNode;
}): JSX.Element;
//# sourceMappingURL=navbarUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"navbarUtils.d.ts","sourceRoot":"","sources":["../../src/utils/navbarUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAO5C;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAC,EACtE,KAAK,EAAE,CAAC,EAAE,GACT,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CASnC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAC,QAAQ,EAAC,EAAE;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAC,GAAG,GAAG,CAAC,OAAO,CAU7E"}

View File

@@ -0,0 +1,36 @@
/**
* 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 from 'react';
import { NavbarMobileSidebarProvider } from '../contexts/navbarMobileSidebar';
import { NavbarSecondaryMenuContentProvider } from '../contexts/navbarSecondaryMenu/content';
import { NavbarSecondaryMenuDisplayProvider } from '../contexts/navbarSecondaryMenu/display';
const DefaultNavItemPosition = 'right';
/**
* Split links by left/right. If position is unspecified, fallback to right.
*/
export function splitNavbarItems(items) {
function isLeft(item) {
return (item.position ?? DefaultNavItemPosition) === 'left';
}
const leftItems = items.filter(isLeft);
const rightItems = items.filter((item) => !isLeft(item));
return [leftItems, rightItems];
}
/**
* Composes multiple navbar state providers that are mutually dependent and
* hence can't be re-ordered.
*/
export function NavbarProvider({ children }) {
return (<NavbarSecondaryMenuContentProvider>
<NavbarMobileSidebarProvider>
<NavbarSecondaryMenuDisplayProvider>
{children}
</NavbarSecondaryMenuDisplayProvider>
</NavbarMobileSidebarProvider>
</NavbarSecondaryMenuContentProvider>);
}
//# sourceMappingURL=navbarUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"navbarUtils.js","sourceRoot":"","sources":["../../src/utils/navbarUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAuB,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAC,2BAA2B,EAAC,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAC,kCAAkC,EAAC,MAAM,yCAAyC,CAAC;AAC3F,OAAO,EAAC,kCAAkC,EAAC,MAAM,yCAAyC,CAAC;AAE3F,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAEvC;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAU;IAEV,SAAS,MAAM,CAAC,IAAO;QACrB,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,sBAAsB,CAAC,KAAK,MAAM,CAAC;IAC9D,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzD,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAC,QAAQ,EAAwB;IAC9D,OAAO,CACL,CAAC,kCAAkC,CACjC;MAAA,CAAC,2BAA2B,CAC1B;QAAA,CAAC,kCAAkC,CACjC;UAAA,CAAC,QAAQ,CACX;QAAA,EAAE,kCAAkC,CACtC;MAAA,EAAE,2BAA2B,CAC/B;IAAA,EAAE,kCAAkC,CAAC,CACtC,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,60 @@
/**
* 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 ComponentType, type ReactNode } from 'react';
/**
* Temporary userland implementation until an official hook is implemented
* See RFC: https://github.com/reactjs/rfcs/pull/220
*
* Permits to transform an unstable callback (like an arrow function provided as
* props) to a "stable" callback that is safe to use in a `useEffect` dependency
* array. Useful to avoid React stale closure problems + avoid useless effect
* re-executions.
*
* This generally works but has some potential drawbacks, such as
* https://github.com/facebook/react/issues/16956#issuecomment-536636418
*/
export declare function useEvent<T extends (...args: never[]) => unknown>(callback: T): T;
/**
* Gets `value` from the last render.
*/
export declare function usePrevious<T>(value: T): T | undefined;
/**
* This error is thrown when a context is consumed outside its provider. Allows
* reusing a generic error message format and reduces bundle size. The hook's
* name will be extracted from its stack, so only the provider's name is needed.
*/
export declare class ReactContextError extends Error {
constructor(providerName: string, additionalInfo?: string);
}
/**
* Shallow-memoize an object. This means the returned object will be the same as
* the previous render if the property keys and values did not change. This
* works for simple cases: when property values are primitives or stable
* objects.
*
* @param obj
*/
export declare function useShallowMemoObject<O extends object>(obj: O): O;
type SimpleProvider = ComponentType<{
children: ReactNode;
}>;
/**
* Creates a single React provider from an array of existing providers
* assuming providers only take "children" as props.
*
* Prevents the annoying React element nesting
* Example here: https://getfrontend.tips/compose-multiple-react-providers/
*
* The order matters:
* - The first provider is at the top of the tree.
* - The last provider is the most nested one
*
* @param providers array of providers to compose
*/
export declare function composeProviders(providers: SimpleProvider[]): SimpleProvider;
export {};
//# sourceMappingURL=reactUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"reactUtils.d.ts","sourceRoot":"","sources":["../../src/utils/reactUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAIZ,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,EAC9D,QAAQ,EAAE,CAAC,GACV,CAAC,CAUH;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAQtD;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,YAAY,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM;CAQ1D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAMhE;AAED,KAAK,cAAc,GAAG,aAAa,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAC,CAAC,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG,cAAc,CAY5E"}

View File

@@ -0,0 +1,87 @@
/**
* 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, } from 'react';
import useIsomorphicLayoutEffect from '@docusaurus/useIsomorphicLayoutEffect';
/**
* Temporary userland implementation until an official hook is implemented
* See RFC: https://github.com/reactjs/rfcs/pull/220
*
* Permits to transform an unstable callback (like an arrow function provided as
* props) to a "stable" callback that is safe to use in a `useEffect` dependency
* array. Useful to avoid React stale closure problems + avoid useless effect
* re-executions.
*
* This generally works but has some potential drawbacks, such as
* https://github.com/facebook/react/issues/16956#issuecomment-536636418
*/
export function useEvent(callback) {
const ref = useRef(callback);
useIsomorphicLayoutEffect(() => {
ref.current = callback;
}, [callback]);
// @ts-expect-error: TS is right that this callback may be a supertype of T,
// but good enough for our use
return useCallback((...args) => ref.current(...args), []);
}
/**
* Gets `value` from the last render.
*/
export function usePrevious(value) {
const ref = useRef();
useIsomorphicLayoutEffect(() => {
ref.current = value;
});
return ref.current;
}
/**
* This error is thrown when a context is consumed outside its provider. Allows
* reusing a generic error message format and reduces bundle size. The hook's
* name will be extracted from its stack, so only the provider's name is needed.
*/
export class ReactContextError extends Error {
constructor(providerName, additionalInfo) {
super();
this.name = 'ReactContextError';
this.message = `Hook ${this.stack?.split('\n')[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups
.name ?? ''} is called outside the <${providerName}>. ${additionalInfo ?? ''}`;
}
}
/**
* Shallow-memoize an object. This means the returned object will be the same as
* the previous render if the property keys and values did not change. This
* works for simple cases: when property values are primitives or stable
* objects.
*
* @param obj
*/
export function useShallowMemoObject(obj) {
const deps = Object.entries(obj);
// Sort by keys to make it order-insensitive
deps.sort((a, b) => a[0].localeCompare(b[0]));
// eslint-disable-next-line react-hooks/exhaustive-deps
return useMemo(() => obj, deps.flat());
}
/**
* Creates a single React provider from an array of existing providers
* assuming providers only take "children" as props.
*
* Prevents the annoying React element nesting
* Example here: https://getfrontend.tips/compose-multiple-react-providers/
*
* The order matters:
* - The first provider is at the top of the tree.
* - The last provider is the most nested one
*
* @param providers array of providers to compose
*/
export function composeProviders(providers) {
// Creates a single React component: it's cheaper to compose JSX elements
return ({ children }) => (<>
{providers.reduceRight((element, CurrentProvider) => (<CurrentProvider>{element}</CurrentProvider>), children)}
</>);
}
//# sourceMappingURL=reactUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"reactUtils.js","sourceRoot":"","sources":["../../src/utils/reactUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EACZ,WAAW,EACX,OAAO,EACP,MAAM,GAGP,MAAM,OAAO,CAAC;AACf,OAAO,yBAAyB,MAAM,uCAAuC,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CACtB,QAAW;IAEX,MAAM,GAAG,GAAG,MAAM,CAAI,QAAQ,CAAC,CAAC;IAEhC,yBAAyB,CAAC,GAAG,EAAE;QAC7B,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC;IACzB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,4EAA4E;IAC5E,8BAA8B;IAC9B,OAAO,WAAW,CAAI,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAI,KAAQ;IACrC,MAAM,GAAG,GAAG,MAAM,EAAK,CAAC;IAExB,yBAAyB,CAAC,GAAG,EAAE;QAC7B,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,YAAoB,EAAE,cAAuB;QACvD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,QACb,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,2BAA2B,CAAC,EAAE,MAAO;aACpE,IAAI,IAAI,EACb,2BAA2B,YAAY,MAAM,cAAc,IAAI,EAAE,EAAE,CAAC;IACtE,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAmB,GAAM;IAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,4CAA4C;IAC5C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,uDAAuD;IACvD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAA2B;IAC1D,yEAAyE;IACzE,OAAO,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAE,CAAC,CACrB,EACE;MAAA,CAAC,SAAS,CAAC,WAAW,CACpB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,CAAC,CAC5B,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,CAC7C,EACD,QAAQ,CACT,CACH;IAAA,GAAG,CACJ,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,12 @@
/**
* 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.
*/
/**
* Matches a string regex (as provided from the config) against a target in a
* null-safe fashion, case insensitive and global.
*/
export declare function isRegexpStringMatch(regexAsString?: string, valueToTest?: string): boolean;
//# sourceMappingURL=regexpUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"regexpUtils.d.ts","sourceRoot":"","sources":["../../src/utils/regexpUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAST"}

View File

@@ -0,0 +1,18 @@
/**
* 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.
*/
/**
* Matches a string regex (as provided from the config) against a target in a
* null-safe fashion, case insensitive and global.
*/
export function isRegexpStringMatch(regexAsString, valueToTest) {
if (typeof regexAsString === 'undefined' ||
typeof valueToTest === 'undefined') {
return false;
}
return new RegExp(regexAsString, 'gi').test(valueToTest);
}
//# sourceMappingURL=regexpUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"regexpUtils.js","sourceRoot":"","sources":["../../src/utils/regexpUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,aAAsB,EACtB,WAAoB;IAEpB,IACE,OAAO,aAAa,KAAK,WAAW;QACpC,OAAO,WAAW,KAAK,WAAW,EAClC;QACA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC3D,CAAC"}

View File

@@ -0,0 +1,26 @@
/**
* 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 { RouteConfig } from 'react-router-config';
/**
* Compare the 2 paths, case insensitive and ignoring trailing slash
*/
export declare function isSamePath(path1: string | undefined, path2: string | undefined): boolean;
/**
* Note that sites don't always have a homepage in practice, so we can't assume
* that linking to '/' is always safe.
* @see https://github.com/facebook/docusaurus/pull/6517#issuecomment-1048709116
*/
export declare function findHomePageRoute({ baseUrl, routes: initialRoutes, }: {
routes: RouteConfig[];
baseUrl: string;
}): RouteConfig | undefined;
/**
* Fetches the route that points to "/". Use this instead of the naive "/",
* because the homepage may not exist.
*/
export declare function useHomePageRoute(): RouteConfig | undefined;
//# sourceMappingURL=routesUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"routesUtils.d.ts","sourceRoot":"","sources":["../../src/utils/routesUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AAErD;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAOT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,MAAM,EAAE,aAAa,GACtB,EAAE;IACD,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,WAAW,GAAG,SAAS,CAwB1B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,GAAG,SAAS,CAM1D"}

View File

@@ -0,0 +1,54 @@
/**
* 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 { useMemo } from 'react';
import generatedRoutes from '@generated/routes';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
/**
* Compare the 2 paths, case insensitive and ignoring trailing slash
*/
export function isSamePath(path1, path2) {
const normalize = (pathname) => (!pathname || pathname.endsWith('/')
? pathname
: `${pathname}/`)?.toLowerCase();
return normalize(path1) === normalize(path2);
}
/**
* Note that sites don't always have a homepage in practice, so we can't assume
* that linking to '/' is always safe.
* @see https://github.com/facebook/docusaurus/pull/6517#issuecomment-1048709116
*/
export function findHomePageRoute({ baseUrl, routes: initialRoutes, }) {
function isHomePageRoute(route) {
return route.path === baseUrl && route.exact === true;
}
function isHomeParentRoute(route) {
return route.path === baseUrl && !route.exact;
}
function doFindHomePageRoute(routes) {
if (routes.length === 0) {
return undefined;
}
const homePage = routes.find(isHomePageRoute);
if (homePage) {
return homePage;
}
const indexSubRoutes = routes
.filter(isHomeParentRoute)
.flatMap((route) => route.routes ?? []);
return doFindHomePageRoute(indexSubRoutes);
}
return doFindHomePageRoute(initialRoutes);
}
/**
* Fetches the route that points to "/". Use this instead of the naive "/",
* because the homepage may not exist.
*/
export function useHomePageRoute() {
const { baseUrl } = useDocusaurusContext().siteConfig;
return useMemo(() => findHomePageRoute({ routes: generatedRoutes, baseUrl }), [baseUrl]);
}
//# sourceMappingURL=routesUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"routesUtils.js","sourceRoot":"","sources":["../../src/utils/routesUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,oBAAoB,MAAM,kCAAkC,CAAC;AAGpE;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,KAAyB,EACzB,KAAyB;IAEzB,MAAM,SAAS,GAAG,CAAC,QAA4B,EAAE,EAAE,CACjD,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QAClC,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,GAAG,QAAQ,GAAG,CACjB,EAAE,WAAW,EAAE,CAAC;IACnB,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,OAAO,EACP,MAAM,EAAE,aAAa,GAItB;IACC,SAAS,eAAe,CAAC,KAAkB;QACzC,OAAO,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;IACxD,CAAC;IAED,SAAS,iBAAiB,CAAC,KAAkB;QAC3C,OAAO,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IAChD,CAAC;IAED,SAAS,mBAAmB,CAAC,MAAqB;QAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;YACvB,OAAO,SAAS,CAAC;SAClB;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC9C,IAAI,QAAQ,EAAE;YACZ,OAAO,QAAQ,CAAC;SACjB;QACD,MAAM,cAAc,GAAG,MAAM;aAC1B,MAAM,CAAC,iBAAiB,CAAC;aACzB,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAC1C,OAAO,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,mBAAmB,CAAC,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAC,OAAO,EAAC,GAAG,oBAAoB,EAAE,CAAC,UAAU,CAAC;IACpD,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,iBAAiB,CAAC,EAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAC,CAAC,EAC3D,CAAC,OAAO,CAAC,CACV,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,83 @@
/**
* 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, { type ReactNode } from 'react';
type ScrollController = {
/** A boolean ref tracking whether scroll events are enabled. */
scrollEventsEnabledRef: React.MutableRefObject<boolean>;
/** Enable scroll events in `useScrollPosition`. */
enableScrollEvents: () => void;
/** Disable scroll events in `useScrollPosition`. */
disableScrollEvents: () => void;
};
export declare function ScrollControllerProvider({ children, }: {
children: ReactNode;
}): JSX.Element;
/**
* We need a way to update the scroll position while ignoring scroll events
* so as not to toggle Navbar/BackToTop visibility.
*
* This API permits to temporarily disable/ignore scroll events. Motivated by
* https://github.com/facebook/docusaurus/pull/5618
*/
export declare function useScrollController(): ScrollController;
type ScrollPosition = {
scrollX: number;
scrollY: number;
};
/**
* This hook fires an effect when the scroll position changes. The effect will
* be provided with the before/after scroll positions. Note that the effect may
* not be always run: if scrolling is disabled through `useScrollController`, it
* will be a no-op.
*
* @see {@link useScrollController}
*/
export declare function useScrollPosition(effect: (position: ScrollPosition, lastPosition: ScrollPosition | null) => void, deps?: unknown[]): void;
/**
* This hook permits to "block" the scroll position of a DOM element.
* The idea is that we should be able to update DOM content above this element
* but the screen position of this element should not change.
*
* Feature motivated by the Tabs groups: clicking on a tab may affect tabs of
* the same group upper in the tree, yet to avoid a bad UX, the clicked tab must
* remain under the user mouse.
*
* @see https://github.com/facebook/docusaurus/pull/5618
*/
export declare function useScrollPositionBlocker(): {
/**
* Takes an element, and keeps its screen position no matter what's getting
* rendered above it, until the next render.
*/
blockElementScrollPositionUntilNextRender: (el: HTMLElement) => void;
};
type CancelScrollTop = () => void;
/**
* A "smart polyfill" of `window.scrollTo({ top, behavior: "smooth" })`.
* This currently always uses a polyfilled implementation unless
* `scroll-behavior: smooth` has been set in CSS, because native support
* detection for scroll behavior seems unreliable.
*
* This hook does not do anything by itself: it returns a start and a stop
* handle. You can execute either handle at any time.
*/
export declare function useSmoothScrollTo(): {
/**
* Start the scroll.
*
* @param top The final scroll top position.
*/
startScroll: (top: number) => void;
/**
* A cancel function, because the non-native smooth scroll-top
* implementation must be interrupted if user scrolls down. If there's no
* existing animation or the scroll is using native behavior, this is a no-op.
*/
cancelScroll: CancelScrollTop;
};
export {};
//# sourceMappingURL=scrollUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"scrollUtils.d.ts","sourceRoot":"","sources":["../../src/utils/scrollUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,KAAK,gBAAgB,GAAG;IACtB,gEAAgE;IAChE,sBAAsB,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACxD,mDAAmD;IACnD,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,oDAAoD;IACpD,mBAAmB,EAAE,MAAM,IAAI,CAAC;CACjC,CAAC;AAuBF,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,GAAG,CAAC,OAAO,CAOd;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAMtD;AAED,KAAK,cAAc,GAAG;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAC;AAUzD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,CACN,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,cAAc,GAAG,IAAI,KAChC,IAAI,EACT,IAAI,GAAE,OAAO,EAAO,GACnB,IAAI,CA0BN;AA6CD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,IAAI;IAC1C;;;OAGG;IACH,yCAAyC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;CACtE,CA2CA;AAED,KAAK,eAAe,GAAG,MAAM,IAAI,CAAC;AA6BlC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI;IACnC;;;;OAIG;IACH,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;OAIG;IACH,YAAY,EAAE,eAAe,CAAC;CAC/B,CAoBA"}

View File

@@ -0,0 +1,204 @@
/**
* 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, useContext, useEffect, useMemo, useRef, } from 'react';
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
import useIsBrowser from '@docusaurus/useIsBrowser';
import useIsomorphicLayoutEffect from '@docusaurus/useIsomorphicLayoutEffect';
import { useEvent, ReactContextError } from './reactUtils';
function useScrollControllerContextValue() {
const scrollEventsEnabledRef = useRef(true);
return useMemo(() => ({
scrollEventsEnabledRef,
enableScrollEvents: () => {
scrollEventsEnabledRef.current = true;
},
disableScrollEvents: () => {
scrollEventsEnabledRef.current = false;
},
}), []);
}
const ScrollMonitorContext = React.createContext(undefined);
export function ScrollControllerProvider({ children, }) {
const value = useScrollControllerContextValue();
return (<ScrollMonitorContext.Provider value={value}>
{children}
</ScrollMonitorContext.Provider>);
}
/**
* We need a way to update the scroll position while ignoring scroll events
* so as not to toggle Navbar/BackToTop visibility.
*
* This API permits to temporarily disable/ignore scroll events. Motivated by
* https://github.com/facebook/docusaurus/pull/5618
*/
export function useScrollController() {
const context = useContext(ScrollMonitorContext);
if (context == null) {
throw new ReactContextError('ScrollControllerProvider');
}
return context;
}
const getScrollPosition = () => ExecutionEnvironment.canUseDOM
? {
scrollX: window.pageXOffset,
scrollY: window.pageYOffset,
}
: null;
/**
* This hook fires an effect when the scroll position changes. The effect will
* be provided with the before/after scroll positions. Note that the effect may
* not be always run: if scrolling is disabled through `useScrollController`, it
* will be a no-op.
*
* @see {@link useScrollController}
*/
export function useScrollPosition(effect, deps = []) {
const { scrollEventsEnabledRef } = useScrollController();
const lastPositionRef = useRef(getScrollPosition());
const dynamicEffect = useEvent(effect);
useEffect(() => {
const handleScroll = () => {
if (!scrollEventsEnabledRef.current) {
return;
}
const currentPosition = getScrollPosition();
dynamicEffect(currentPosition, lastPositionRef.current);
lastPositionRef.current = currentPosition;
};
const opts = {
passive: true,
};
handleScroll();
window.addEventListener('scroll', handleScroll, opts);
return () => window.removeEventListener('scroll', handleScroll, opts);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dynamicEffect, scrollEventsEnabledRef, ...deps]);
}
function useScrollPositionSaver() {
const lastElementRef = useRef({
elem: null,
top: 0,
});
const save = useCallback((elem) => {
lastElementRef.current = {
elem,
top: elem.getBoundingClientRect().top,
};
}, []);
const restore = useCallback(() => {
const { current: { elem, top }, } = lastElementRef;
if (!elem) {
return { restored: false };
}
const newTop = elem.getBoundingClientRect().top;
const heightDiff = newTop - top;
if (heightDiff) {
window.scrollBy({ left: 0, top: heightDiff });
}
lastElementRef.current = { elem: null, top: 0 };
return { restored: heightDiff !== 0 };
}, []);
return useMemo(() => ({ save, restore }), [restore, save]);
}
/**
* This hook permits to "block" the scroll position of a DOM element.
* The idea is that we should be able to update DOM content above this element
* but the screen position of this element should not change.
*
* Feature motivated by the Tabs groups: clicking on a tab may affect tabs of
* the same group upper in the tree, yet to avoid a bad UX, the clicked tab must
* remain under the user mouse.
*
* @see https://github.com/facebook/docusaurus/pull/5618
*/
export function useScrollPositionBlocker() {
const scrollController = useScrollController();
const scrollPositionSaver = useScrollPositionSaver();
const nextLayoutEffectCallbackRef = useRef(undefined);
const blockElementScrollPositionUntilNextRender = useCallback((el) => {
scrollPositionSaver.save(el);
scrollController.disableScrollEvents();
nextLayoutEffectCallbackRef.current = () => {
const { restored } = scrollPositionSaver.restore();
nextLayoutEffectCallbackRef.current = undefined;
// Restoring the former scroll position will trigger a scroll event. We
// need to wait for next scroll event to happen before enabling the
// scrollController events again.
if (restored) {
const handleScrollRestoreEvent = () => {
scrollController.enableScrollEvents();
window.removeEventListener('scroll', handleScrollRestoreEvent);
};
window.addEventListener('scroll', handleScrollRestoreEvent);
}
else {
scrollController.enableScrollEvents();
}
};
}, [scrollController, scrollPositionSaver]);
useIsomorphicLayoutEffect(() => {
// Queuing permits to restore scroll position after all useLayoutEffect
// have run, and yet preserve the sync nature of the scroll restoration
// See https://github.com/facebook/docusaurus/issues/8625
queueMicrotask(() => nextLayoutEffectCallbackRef.current?.());
});
return {
blockElementScrollPositionUntilNextRender,
};
}
function smoothScrollNative(top) {
window.scrollTo({ top, behavior: 'smooth' });
return () => {
// Nothing to cancel, it's natively cancelled if user tries to scroll down
};
}
function smoothScrollPolyfill(top) {
let raf = null;
const isUpScroll = document.documentElement.scrollTop > top;
function rafRecursion() {
const currentScroll = document.documentElement.scrollTop;
if ((isUpScroll && currentScroll > top) ||
(!isUpScroll && currentScroll < top)) {
raf = requestAnimationFrame(rafRecursion);
window.scrollTo(0, Math.floor((currentScroll - top) * 0.85) + top);
}
}
rafRecursion();
// Break the recursion. Prevents the user from "fighting" against that
// recursion producing a weird UX
return () => raf && cancelAnimationFrame(raf);
}
/**
* A "smart polyfill" of `window.scrollTo({ top, behavior: "smooth" })`.
* This currently always uses a polyfilled implementation unless
* `scroll-behavior: smooth` has been set in CSS, because native support
* detection for scroll behavior seems unreliable.
*
* This hook does not do anything by itself: it returns a start and a stop
* handle. You can execute either handle at any time.
*/
export function useSmoothScrollTo() {
const cancelRef = useRef(null);
const isBrowser = useIsBrowser();
// Not all have support for smooth scrolling (particularly Safari mobile iOS)
// TODO proper detection is currently unreliable!
// see https://github.com/wessberg/scroll-behavior-polyfill/issues/16
// For now, we only use native scroll behavior if smooth is already set,
// because otherwise the polyfill produces a weird UX when both CSS and JS try
// to scroll a page, and they cancel each other.
const supportsNativeSmoothScrolling = isBrowser &&
getComputedStyle(document.documentElement).scrollBehavior === 'smooth';
return {
startScroll: (top) => {
cancelRef.current = supportsNativeSmoothScrolling
? smoothScrollNative(top)
: smoothScrollPolyfill(top);
},
cancelScroll: () => cancelRef.current?.(),
};
}
//# sourceMappingURL=scrollUtils.js.map

File diff suppressed because one or more lines are too long

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.
*/
export declare const DEFAULT_SEARCH_TAG = "default";
/** The search tag to append as each doc's metadata. */
export declare function docVersionSearchTag(pluginId: string, versionName: string): string;
/**
* 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 declare function useContextualSearchFilters(): {
locale: string;
tags: string[];
};
//# sourceMappingURL=searchUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"searchUtils.d.ts","sourceRoot":"","sources":["../../src/utils/searchUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,uDAAuD;AACvD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAC,CAkC7E"}

View File

@@ -0,0 +1,47 @@
/**
* 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 useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import { useDocsPreferredVersionByPluginId } from '../contexts/docsPreferredVersion';
export const DEFAULT_SEARCH_TAG = 'default';
/** The search tag to append as each doc's metadata. */
export function docVersionSearchTag(pluginId, versionName) {
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() {
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) {
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,
};
}
//# sourceMappingURL=searchUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"searchUtils.js","sourceRoot":"","sources":["../../src/utils/searchUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,cAAc,EACd,yBAAyB,GAC1B,MAAM,wCAAwC,CAAC;AAChD,OAAO,oBAAoB,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAC,iCAAiC,EAAC,MAAM,kCAAkC,CAAC;AAEnF,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE5C,uDAAuD;AACvD,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,WAAmB;IAEnB,OAAO,QAAQ,QAAQ,IAAI,WAAW,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B;IACxC,MAAM,EAAC,IAAI,EAAC,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,sBAAsB,GAAG,yBAAyB,EAAE,CAAC;IAC3D,MAAM,8BAA8B,GAAG,iCAAiC,EAAE,CAAC;IAE3E,wEAAwE;IACxE,oBAAoB;IACpB,SAAS,gBAAgB,CAAC,QAAgB;QACxC,MAAM,aAAa,GACjB,sBAAsB,EAAE,YAAY,CAAC,QAAQ,KAAK,QAAQ;YACxD,CAAC,CAAC,sBAAsB,CAAC,aAAa;YACtC,CAAC,CAAC,SAAS,CAAC;QAEhB,MAAM,gBAAgB,GAAG,8BAA8B,CAAC,QAAQ,CAAC,CAAC;QAElE,MAAM,aAAa,GAAG,WAAW,CAAC,QAAQ,CAAE,CAAC,QAAQ,CAAC,IAAI,CACxD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CACf,CAAC;QAEH,MAAM,OAAO,GAAG,aAAa,IAAI,gBAAgB,IAAI,aAAa,CAAC;QAEnE,OAAO,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,IAAI,GAAG;QACX,kBAAkB;QAClB,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC;KAClD,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,aAAa;QAC1B,IAAI;KACL,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,20 @@
/**
* 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 ComponentProps } from 'react';
/**
* The id of the element that should become focused on a page
* that does not have a <main> html tag.
* Focusing the Docusaurus Layout children is a reasonable fallback.
*
* __ prefix allows search crawlers (Algolia/DocSearch) to ignore anchors
* https://github.com/facebook/docusaurus/issues/8883#issuecomment-1516328368
*/
export declare const SkipToContentFallbackId = "__docusaurus_skipToContent_fallback";
type SkipToContentLinkProps = Omit<ComponentProps<'a'>, 'href' | 'onClick'>;
export declare function SkipToContentLink(props: SkipToContentLinkProps): JSX.Element;
export {};
//# sourceMappingURL=skipToContentUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"skipToContentUtils.d.ts","sourceRoot":"","sources":["../../src/utils/skipToContentUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAc,EAAsB,KAAK,cAAc,EAAC,MAAM,OAAO,CAAC;AAKtE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,wCAAwC,CAAC;AAiE7E,KAAK,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE5E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,GAAG,CAAC,OAAO,CAmB5E"}

View File

@@ -0,0 +1,75 @@
/**
* 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, useRef } from 'react';
import { useHistory } from '@docusaurus/router';
import { translate } from '@docusaurus/Translate';
import { useLocationChange } from './useLocationChange';
/**
* The id of the element that should become focused on a page
* that does not have a <main> html tag.
* Focusing the Docusaurus Layout children is a reasonable fallback.
*
* __ prefix allows search crawlers (Algolia/DocSearch) to ignore anchors
* https://github.com/facebook/docusaurus/issues/8883#issuecomment-1516328368
*/
export const SkipToContentFallbackId = '__docusaurus_skipToContent_fallback';
/**
* Returns the skip to content element to focus when the link is clicked.
*/
function getSkipToContentTarget() {
return (
// Try to focus the <main> in priority
// Note: this will only work if JS is enabled
// See https://github.com/facebook/docusaurus/issues/6411#issuecomment-1284136069
document.querySelector('main:first-of-type') ??
// Then try to focus the fallback element (usually the Layout children)
document.getElementById(SkipToContentFallbackId));
}
function programmaticFocus(el) {
el.setAttribute('tabindex', '-1');
el.focus();
el.removeAttribute('tabindex');
}
/** This hook wires the logic for a skip-to-content link. */
function useSkipToContent() {
const containerRef = useRef(null);
const { action } = useHistory();
const onClick = useCallback((e) => {
e.preventDefault();
const targetElement = getSkipToContentTarget();
if (targetElement) {
programmaticFocus(targetElement);
}
}, []);
// "Reset" focus when navigating.
// See https://github.com/facebook/docusaurus/pull/8204#issuecomment-1276547558
useLocationChange(({ location }) => {
if (containerRef.current && !location.hash && action === 'PUSH') {
programmaticFocus(containerRef.current);
}
});
return { containerRef, onClick };
}
const DefaultSkipToContentLabel = translate({
id: 'theme.common.skipToMainContent',
description: 'The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation',
message: 'Skip to main content',
});
export function SkipToContentLink(props) {
const linkLabel = props.children ?? DefaultSkipToContentLabel;
const { containerRef, onClick } = useSkipToContent();
return (<div ref={containerRef} role="region" aria-label={DefaultSkipToContentLabel}>
{/* eslint-disable-next-line @docusaurus/no-html-links */}
<a {...props}
// Note this is a fallback href in case JS is disabled
// It has limitations, see https://github.com/facebook/docusaurus/issues/6411#issuecomment-1284136069
href={`#${SkipToContentFallbackId}`} onClick={onClick}>
{linkLabel}
</a>
</div>);
}
//# sourceMappingURL=skipToContentUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"skipToContentUtils.js","sourceRoot":"","sources":["../../src/utils/skipToContentUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAAC,WAAW,EAAE,MAAM,EAAsB,MAAM,OAAO,CAAC;AACtE,OAAO,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,qCAAqC,CAAC;AAE7E;;GAEG;AACH,SAAS,sBAAsB;IAC7B,OAAO;IACL,sCAAsC;IACtC,6CAA6C;IAC7C,iFAAiF;IACjF,QAAQ,CAAC,aAAa,CAAC,oBAAoB,CAAC;QAC5C,uEAAuE;QACvE,QAAQ,CAAC,cAAc,CAAC,uBAAuB,CAAC,CACjD,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAe;IACxC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAClC,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC;AAED,4DAA4D;AAC5D,SAAS,gBAAgB;IAavB,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAClD,MAAM,EAAC,MAAM,EAAC,GAAG,UAAU,EAAE,CAAC;IAE9B,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAsC,EAAE,EAAE;QACrE,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,MAAM,aAAa,GAAG,sBAAsB,EAAE,CAAC;QAC/C,IAAI,aAAa,EAAE;YACjB,iBAAiB,CAAC,aAAa,CAAC,CAAC;SAClC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,iCAAiC;IACjC,+EAA+E;IAC/E,iBAAiB,CAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAE;QAC/B,IAAI,YAAY,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE;YAC/D,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;SACzC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAC,YAAY,EAAE,OAAO,EAAC,CAAC;AACjC,CAAC;AAED,MAAM,yBAAyB,GAAG,SAAS,CAAC;IAC1C,EAAE,EAAE,gCAAgC;IACpC,WAAW,EACT,mIAAmI;IACrI,OAAO,EAAE,sBAAsB;CAChC,CAAC,CAAC;AAIH,MAAM,UAAU,iBAAiB,CAAC,KAA6B;IAC7D,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,IAAI,yBAAyB,CAAC;IAC9D,MAAM,EAAC,YAAY,EAAE,OAAO,EAAC,GAAG,gBAAgB,EAAE,CAAC;IACnD,OAAO,CACL,CAAC,GAAG,CACF,GAAG,CAAC,CAAC,YAAY,CAAC,CAClB,IAAI,CAAC,QAAQ,CACb,UAAU,CAAC,CAAC,yBAAyB,CAAC,CACtC;MAAA,CAAC,wDAAwD,CACzD;MAAA,CAAC,CAAC,CACA,IAAI,KAAK,CAAC;IACV,sDAAsD;IACtD,qGAAqG;IACrG,IAAI,CAAC,CAAC,IAAI,uBAAuB,EAAE,CAAC,CACpC,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB;QAAA,CAAC,SAAS,CACZ;MAAA,EAAE,CAAC,CACL;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,37 @@
/**
* 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 StorageTypes: readonly ["localStorage", "sessionStorage", "none"];
export type StorageType = (typeof StorageTypes)[number];
export type StorageSlot = {
get: () => string | null;
set: (value: string) => void;
del: () => void;
listen: (onChange: (event: StorageEvent) => void) => () => void;
};
/**
* Creates an interface to work on a particular key in the storage model.
* Note that this function only initializes the interface, but doesn't allocate
* anything by itself (i.e. no side-effects).
*
* The API is fail-safe, since usage of browser storage should be considered
* unreliable. Local storage might simply be unavailable (iframe + browser
* security) or operations might fail individually. Please assume that using
* this API can be a no-op. See also https://github.com/facebook/docusaurus/issues/6036
*/
export declare function createStorageSlot(key: string, options?: {
persistence?: StorageType;
}): StorageSlot;
export declare function useStorageSlot(key: string | null, options?: {
persistence?: StorageType;
}): [string | null, StorageSlot];
/**
* Returns a list of all the keys currently stored in browser storage,
* or an empty list if browser storage can't be accessed.
*/
export declare function listStorageKeys(storageType?: StorageType): string[];
export {};
//# sourceMappingURL=storageUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"storageUtils.d.ts","sourceRoot":"","sources":["../../src/utils/storageUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,QAAA,MAAM,YAAY,qDAAsD,CAAC;AAEzE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAoFxD,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACzB,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,EAAE,MAAM,IAAI,CAAC;IAChB,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;CACjE,CAAC;AAyBF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;IAAC,WAAW,CAAC,EAAE,WAAW,CAAA;CAAC,GACpC,WAAW,CA6Db;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,OAAO,CAAC,EAAE;IAAC,WAAW,CAAC,EAAE,WAAW,CAAA;CAAC,GACpC,CAAC,MAAM,GAAG,IAAI,EAAE,WAAW,CAAC,CAiC9B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,WAAW,GAAE,WAAgC,GAC5C,MAAM,EAAE,CAcV"}

View File

@@ -0,0 +1,193 @@
/**
* 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, useRef, useSyncExternalStore } from 'react';
const StorageTypes = ['localStorage', 'sessionStorage', 'none'];
const DefaultStorageType = 'localStorage';
// window.addEventListener('storage') only works for different windows...
// so for current window we have to dispatch the event manually
// Now we can listen for both cross-window / current-window storage changes!
// see https://stackoverflow.com/a/71177640/82609
// see https://stackoverflow.com/questions/26974084/listen-for-changes-with-localstorage-on-the-same-window
function dispatchChangeEvent({ key, oldValue, newValue, storage, }) {
// If we set multiple times the same storage value, events should not be fired
// The native events behave this way, so our manual event dispatch should
// rather behave exactly the same. Not doing so might create infinite loops.
// See https://github.com/facebook/docusaurus/issues/8594
if (oldValue === newValue) {
return;
}
const event = document.createEvent('StorageEvent');
event.initStorageEvent('storage', false, false, key, oldValue, newValue, window.location.href, storage);
window.dispatchEvent(event);
}
/**
* Will return `null` if browser storage is unavailable (like running Docusaurus
* in an iframe). This should NOT be called in SSR.
*
* @see https://github.com/facebook/docusaurus/pull/4501
*/
function getBrowserStorage(storageType = DefaultStorageType) {
if (typeof window === 'undefined') {
throw new Error('Browser storage is not available on Node.js/Docusaurus SSR process.');
}
if (storageType === 'none') {
return null;
}
try {
return window[storageType];
}
catch (err) {
logOnceBrowserStorageNotAvailableWarning(err);
return null;
}
}
let hasLoggedBrowserStorageNotAvailableWarning = false;
/**
* Poor man's memoization to avoid logging multiple times the same warning.
* Sometimes, `localStorage`/`sessionStorage` is unavailable due to browser
* policies.
*/
function logOnceBrowserStorageNotAvailableWarning(error) {
if (!hasLoggedBrowserStorageNotAvailableWarning) {
console.warn(`Docusaurus browser storage is not available.
Possible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.`, error);
hasLoggedBrowserStorageNotAvailableWarning = true;
}
}
const NoopStorageSlot = {
get: () => null,
set: () => { },
del: () => { },
listen: () => () => { },
};
// Fail-fast, as storage APIs should not be used during the SSR process
function createServerStorageSlot(key) {
function throwError() {
throw new Error(`Illegal storage API usage for storage key "${key}".
Docusaurus storage APIs are not supposed to be called on the server-rendering process.
Please only call storage APIs in effects and event handlers.`);
}
return {
get: throwError,
set: throwError,
del: throwError,
listen: throwError,
};
}
/**
* Creates an interface to work on a particular key in the storage model.
* Note that this function only initializes the interface, but doesn't allocate
* anything by itself (i.e. no side-effects).
*
* The API is fail-safe, since usage of browser storage should be considered
* unreliable. Local storage might simply be unavailable (iframe + browser
* security) or operations might fail individually. Please assume that using
* this API can be a no-op. See also https://github.com/facebook/docusaurus/issues/6036
*/
export function createStorageSlot(key, options) {
if (typeof window === 'undefined') {
return createServerStorageSlot(key);
}
const storage = getBrowserStorage(options?.persistence);
if (storage === null) {
return NoopStorageSlot;
}
return {
get: () => {
try {
return storage.getItem(key);
}
catch (err) {
console.error(`Docusaurus storage error, can't get key=${key}`, err);
return null;
}
},
set: (newValue) => {
try {
const oldValue = storage.getItem(key);
storage.setItem(key, newValue);
dispatchChangeEvent({
key,
oldValue,
newValue,
storage,
});
}
catch (err) {
console.error(`Docusaurus storage error, can't set ${key}=${newValue}`, err);
}
},
del: () => {
try {
const oldValue = storage.getItem(key);
storage.removeItem(key);
dispatchChangeEvent({ key, oldValue, newValue: null, storage });
}
catch (err) {
console.error(`Docusaurus storage error, can't delete key=${key}`, err);
}
},
listen: (onChange) => {
try {
const listener = (event) => {
if (event.storageArea === storage && event.key === key) {
onChange(event);
}
};
window.addEventListener('storage', listener);
return () => window.removeEventListener('storage', listener);
}
catch (err) {
console.error(`Docusaurus storage error, can't listen for changes of key=${key}`, err);
return () => { };
}
},
};
}
export function useStorageSlot(key, options) {
// Not ideal but good enough: assumes storage slot config is constant
const storageSlot = useRef(() => {
if (key === null) {
return NoopStorageSlot;
}
return createStorageSlot(key, options);
}).current();
const listen = useCallback((onChange) => {
// Do not try to add a listener during SSR
if (typeof window === 'undefined') {
return () => { };
}
return storageSlot.listen(onChange);
}, [storageSlot]);
const currentValue = useSyncExternalStore(listen, () => {
// TODO this check should be useless after React 18
if (typeof window === 'undefined') {
return null;
}
return storageSlot.get();
}, () => null);
return [currentValue, storageSlot];
}
/**
* Returns a list of all the keys currently stored in browser storage,
* or an empty list if browser storage can't be accessed.
*/
export function listStorageKeys(storageType = DefaultStorageType) {
const browserStorage = getBrowserStorage(storageType);
if (!browserStorage) {
return [];
}
const keys = [];
for (let i = 0; i < browserStorage.length; i += 1) {
const key = browserStorage.key(i);
if (key !== null) {
keys.push(key);
}
}
return keys;
}
//# sourceMappingURL=storageUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"storageUtils.js","sourceRoot":"","sources":["../../src/utils/storageUtils.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,49 @@
/**
* 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, { type ReactNode, type ReactElement } from 'react';
/**
* TabValue is the "config" of a given Tab
* Provided through <Tabs> "values" prop or through the children <TabItem> props
*/
export interface TabValue {
readonly value: string;
readonly label?: string;
readonly attributes?: {
[key: string]: unknown;
};
readonly default?: boolean;
}
type TabItem = ReactElement<TabItemProps> | null | false | undefined;
export interface TabsProps {
readonly lazy?: boolean;
readonly block?: boolean;
readonly children: TabItem[] | TabItem;
readonly defaultValue?: string | null;
readonly values?: readonly TabValue[];
readonly groupId?: string;
readonly className?: string;
readonly queryString?: string | boolean;
}
export interface TabItemProps {
readonly children: ReactNode;
readonly value: string;
readonly default?: boolean;
readonly label?: string;
readonly hidden?: boolean;
readonly className?: string;
readonly attributes?: {
[key: string]: unknown;
};
}
export declare function sanitizeTabsChildren(children: TabsProps['children']): React.ReactElement<TabItemProps, string | React.JSXElementConstructor<any>>[];
export declare function useTabs(props: TabsProps): {
selectedValue: string;
selectValue: (value: string) => void;
tabValues: readonly TabValue[];
};
export {};
//# sourceMappingURL=tabsUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tabsUtils.d.ts","sourceRoot":"","sources":["../../src/utils/tabsUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,EAKZ,KAAK,SAAS,EACd,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AAMf;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC,CAAC;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,KAAK,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,GAAG,IAAI,GAAG,KAAK,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACzC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC,CAAC;CAChD;AAWD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,iFAiBnE;AA+ID,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;CAChC,CA8CA"}

View File

@@ -0,0 +1,158 @@
/**
* 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, { isValidElement, useCallback, useState, useMemo, } from 'react';
import { useHistory } from '@docusaurus/router';
import useIsomorphicLayoutEffect from '@docusaurus/useIsomorphicLayoutEffect';
import { useQueryStringValue } from '@docusaurus/theme-common/internal';
import { duplicates, useStorageSlot } from '../index';
// A very rough duck type, but good enough to guard against mistakes while
// allowing customization
function isTabItem(comp) {
const { props } = comp;
return !!props && typeof props === 'object' && 'value' in props;
}
export function sanitizeTabsChildren(children) {
return (React.Children.toArray(children)
.filter((child) => child !== '\n')
.map((child) => {
if (!child || (isValidElement(child) && isTabItem(child))) {
return child;
}
// child.type.name will give non-sensical values in prod because of
// minification, but we assume it won't throw in prod.
throw new Error(`Docusaurus error: Bad <Tabs> child <${
// @ts-expect-error: guarding against unexpected cases
typeof child.type === 'string' ? child.type : child.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`);
})
?.filter(Boolean) ?? []);
}
function extractChildrenTabValues(children) {
return sanitizeTabsChildren(children).map(({ props: { value, label, attributes, default: isDefault } }) => ({
value,
label,
attributes,
default: isDefault,
}));
}
function ensureNoDuplicateValue(values) {
const dup = duplicates(values, (a, b) => a.value === b.value);
if (dup.length > 0) {
throw new Error(`Docusaurus error: Duplicate values "${dup
.map((a) => a.value)
.join(', ')}" found in <Tabs>. Every value needs to be unique.`);
}
}
function useTabValues(props) {
const { values: valuesProp, children } = props;
return useMemo(() => {
const values = valuesProp ?? extractChildrenTabValues(children);
ensureNoDuplicateValue(values);
return values;
}, [valuesProp, children]);
}
function isValidValue({ value, tabValues, }) {
return tabValues.some((a) => a.value === value);
}
function getInitialStateValue({ defaultValue, tabValues, }) {
if (tabValues.length === 0) {
throw new Error('Docusaurus error: the <Tabs> component requires at least one <TabItem> children component');
}
if (defaultValue) {
// Warn user about passing incorrect defaultValue as prop.
if (!isValidValue({ value: defaultValue, tabValues })) {
throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${defaultValue}" but none of its children has the corresponding value. Available values are: ${tabValues
.map((a) => a.value)
.join(', ')}. If you intend to show no default tab, use defaultValue={null} instead.`);
}
return defaultValue;
}
const defaultTabValue = tabValues.find((tabValue) => tabValue.default) ?? tabValues[0];
if (!defaultTabValue) {
throw new Error('Unexpected error: 0 tabValues');
}
return defaultTabValue.value;
}
function getStorageKey(groupId) {
if (!groupId) {
return null;
}
return `docusaurus.tab.${groupId}`;
}
function getQueryStringKey({ queryString = false, groupId, }) {
if (typeof queryString === 'string') {
return queryString;
}
if (queryString === false) {
return null;
}
if (queryString === true && !groupId) {
throw new Error(`Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".`);
}
return groupId ?? null;
}
function useTabQueryString({ queryString = false, groupId, }) {
const history = useHistory();
const key = getQueryStringKey({ queryString, groupId });
const value = useQueryStringValue(key);
const setValue = useCallback((newValue) => {
if (!key) {
return; // no-op
}
const searchParams = new URLSearchParams(history.location.search);
searchParams.set(key, newValue);
history.replace({ ...history.location, search: searchParams.toString() });
}, [key, history]);
return [value, setValue];
}
function useTabStorage({ groupId }) {
const key = getStorageKey(groupId);
const [value, storageSlot] = useStorageSlot(key);
const setValue = useCallback((newValue) => {
if (!key) {
return; // no-op
}
storageSlot.set(newValue);
}, [key, storageSlot]);
return [value, setValue];
}
export function useTabs(props) {
const { defaultValue, queryString = false, groupId } = props;
const tabValues = useTabValues(props);
const [selectedValue, setSelectedValue] = useState(() => getInitialStateValue({ defaultValue, tabValues }));
const [queryStringValue, setQueryString] = useTabQueryString({
queryString,
groupId,
});
const [storageValue, setStorageValue] = useTabStorage({
groupId,
});
// We sync valid querystring/storage value to state on change + hydration
const valueToSync = (() => {
const value = queryStringValue ?? storageValue;
if (!isValidValue({ value, tabValues })) {
return null;
}
return value;
})();
// Sync in a layout/sync effect is important, for useScrollPositionBlocker
// See https://github.com/facebook/docusaurus/issues/8625
useIsomorphicLayoutEffect(() => {
if (valueToSync) {
setSelectedValue(valueToSync);
}
}, [valueToSync]);
const selectValue = useCallback((newValue) => {
if (!isValidValue({ value: newValue, tabValues })) {
throw new Error(`Can't select invalid tab value=${newValue}`);
}
setSelectedValue(newValue);
setQueryString(newValue);
setStorageValue(newValue);
}, [setQueryString, setStorageValue, tabValues]);
return { selectedValue, selectValue, tabValues };
}
//# sourceMappingURL=tabsUtils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
/**
* 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 { TagsListItem } from '@docusaurus/utils';
export declare const translateTagsPageTitle: () => string;
export type TagLetterEntry = {
letter: string;
tags: TagsListItem[];
};
/**
* Takes a list of tags (as provided by the content plugins), and groups them by
* their initials.
*/
export declare function listTagsByLetters(tags: readonly TagsListItem[]): TagLetterEntry[];
//# sourceMappingURL=tagsUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tagsUtils.d.ts","sourceRoot":"","sources":["../../src/utils/tagsUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAEpD,eAAO,MAAM,sBAAsB,QAAO,MAKtC,CAAC;AAEL,MAAM,MAAM,cAAc,GAAG;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAA;CAAC,CAAC;AAMpE;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,SAAS,YAAY,EAAE,GAC5B,cAAc,EAAE,CAoBlB"}

View File

@@ -0,0 +1,36 @@
/**
* 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';
export const translateTagsPageTitle = () => translate({
id: 'theme.tags.tagsPageTitle',
message: 'Tags',
description: 'The title of the tag list page',
});
function getTagLetter(tag) {
return tag[0].toUpperCase();
}
/**
* Takes a list of tags (as provided by the content plugins), and groups them by
* their initials.
*/
export function listTagsByLetters(tags) {
const groups = {};
Object.values(tags).forEach((tag) => {
const initial = getTagLetter(tag.label);
groups[initial] ??= [];
groups[initial].push(tag);
});
return (Object.entries(groups)
// Sort letters
.sort(([letter1], [letter2]) => letter1.localeCompare(letter2))
.map(([letter, letterTags]) => {
// Sort tags inside a letter
const sortedTags = letterTags.sort((tag1, tag2) => tag1.label.localeCompare(tag2.label));
return { letter, tags: sortedTags };
}));
}
//# sourceMappingURL=tagsUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tagsUtils.js","sourceRoot":"","sources":["../../src/utils/tagsUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAGhD,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAW,EAAE,CACjD,SAAS,CAAC;IACR,EAAE,EAAE,0BAA0B;IAC9B,OAAO,EAAE,MAAM;IACf,WAAW,EAAE,gCAAgC;CAC9C,CAAC,CAAC;AAIL,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAA6B;IAE7B,MAAM,MAAM,GAAwC,EAAE,CAAC;IACvD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,CAAC,OAAO,CAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QACpB,eAAe;SACd,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;SAC9D,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE;QAC5B,4BAA4B;QAC5B,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAChD,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CACrC,CAAC;QACF,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAC,CAAC;IACpC,CAAC,CAAC,CACL,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,36 @@
/**
* 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 { TOCItem } from '@docusaurus/mdx-loader';
export type TOCTreeNode = {
readonly value: string;
readonly id: string;
readonly level: number;
readonly children: readonly TOCTreeNode[];
};
/**
* Takes a flat TOC list (from the MDX loader) and treeifies it into what the
* TOC components expect. Memoized for performance.
*/
export declare function useTreeifiedTOC(toc: TOCItem[]): readonly TOCTreeNode[];
/**
* Takes a flat TOC list (from the MDX loader) and treeifies it into what the
* TOC components expect, applying the `minHeadingLevel` and `maxHeadingLevel`.
* Memoized for performance.
*
* **Important**: this is not the same as `useTreeifiedTOC(toc.filter(...))`,
* because we have to filter the TOC after it has been treeified. This is mostly
* to ensure that weird TOC structures preserve their semantics. For example, an
* h3-h2-h4 sequence should not be treeified as an "h3 > h4" hierarchy with
* min=3, max=4, but should rather be "[h3, h4]" (since the h2 heading has split
* the two headings and they are not parent-children)
*/
export declare function useFilteredAndTreeifiedTOC({ toc, minHeadingLevel, maxHeadingLevel, }: {
toc: readonly TOCItem[];
minHeadingLevel: number;
maxHeadingLevel: number;
}): readonly TOCTreeNode[];
//# sourceMappingURL=tocUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tocUtils.d.ts","sourceRoot":"","sources":["../../src/utils/tocUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,wBAAwB,CAAC;AAEpD,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC3C,CAAC;AAuCF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,SAAS,WAAW,EAAE,CAEtE;AAiCD;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,GAAG,EACH,eAAe,EACf,eAAe,GAChB,EAAE;IACD,GAAG,EAAE,SAAS,OAAO,EAAE,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;CACzB,GAAG,SAAS,WAAW,EAAE,CAKzB"}

View File

@@ -0,0 +1,84 @@
/**
* 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 { useMemo } from 'react';
function treeifyTOC(flatTOC) {
const headings = flatTOC.map((heading) => ({
...heading,
parentIndex: -1,
children: [],
}));
// Keep track of which previous index would be the current heading's direct
// parent. Each entry <i> is the last index of the `headings` array at heading
// level <i>. We will modify these indices as we iterate through all headings.
// e.g. if an ### H3 was last seen at index 2, then prevIndexForLevel[3] === 2
// indices 0 and 1 will remain unused.
const prevIndexForLevel = Array(7).fill(-1);
headings.forEach((curr, currIndex) => {
// Take the last seen index for each ancestor level. the highest index will
// be the direct ancestor of the current heading.
const ancestorLevelIndexes = prevIndexForLevel.slice(2, curr.level);
curr.parentIndex = Math.max(...ancestorLevelIndexes);
// Mark that curr.level was last seen at the current index.
prevIndexForLevel[curr.level] = currIndex;
});
const rootNodes = [];
// For a given parentIndex, add each Node into that parent's `children` array
headings.forEach((heading) => {
const { parentIndex, ...rest } = heading;
if (parentIndex >= 0) {
headings[parentIndex].children.push(rest);
}
else {
rootNodes.push(rest);
}
});
return rootNodes;
}
/**
* Takes a flat TOC list (from the MDX loader) and treeifies it into what the
* TOC components expect. Memoized for performance.
*/
export function useTreeifiedTOC(toc) {
return useMemo(() => treeifyTOC(toc), [toc]);
}
function filterTOC({ toc, minHeadingLevel, maxHeadingLevel, }) {
function isValid(item) {
return item.level >= minHeadingLevel && item.level <= maxHeadingLevel;
}
return toc.flatMap((item) => {
const filteredChildren = filterTOC({
toc: item.children,
minHeadingLevel,
maxHeadingLevel,
});
if (isValid(item)) {
return [
{
...item,
children: filteredChildren,
},
];
}
return filteredChildren;
});
}
/**
* Takes a flat TOC list (from the MDX loader) and treeifies it into what the
* TOC components expect, applying the `minHeadingLevel` and `maxHeadingLevel`.
* Memoized for performance.
*
* **Important**: this is not the same as `useTreeifiedTOC(toc.filter(...))`,
* because we have to filter the TOC after it has been treeified. This is mostly
* to ensure that weird TOC structures preserve their semantics. For example, an
* h3-h2-h4 sequence should not be treeified as an "h3 > h4" hierarchy with
* min=3, max=4, but should rather be "[h3, h4]" (since the h2 heading has split
* the two headings and they are not parent-children)
*/
export function useFilteredAndTreeifiedTOC({ toc, minHeadingLevel, maxHeadingLevel, }) {
return useMemo(() => filterTOC({ toc: treeifyTOC(toc), minHeadingLevel, maxHeadingLevel }), [toc, minHeadingLevel, maxHeadingLevel]);
}
//# sourceMappingURL=tocUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"tocUtils.js","sourceRoot":"","sources":["../../src/utils/tocUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAU9B,SAAS,UAAU,CAAC,OAA2B;IAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACzC,GAAG,OAAO;QACV,WAAW,EAAE,CAAC,CAAC;QACf,QAAQ,EAAE,EAAmB;KAC9B,CAAC,CAAC,CAAC;IAEJ,2EAA2E;IAC3E,8EAA8E;IAC9E,8EAA8E;IAC9E,8EAA8E;IAC9E,sCAAsC;IACtC,MAAM,iBAAiB,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpD,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE;QACnC,2EAA2E;QAC3E,iDAAiD;QACjD,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACpE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,CAAC;QACrD,2DAA2D;QAC3D,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAkB,EAAE,CAAC;IAEpC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,MAAM,EAAC,WAAW,EAAE,GAAG,IAAI,EAAC,GAAG,OAAO,CAAC;QACvC,IAAI,WAAW,IAAI,CAAC,EAAE;YACpB,QAAQ,CAAC,WAAW,CAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC5C;aAAM;YACL,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACtB;IACH,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAc;IAC5C,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,SAAS,CAAC,EACjB,GAAG,EACH,eAAe,EACf,eAAe,GAKhB;IACC,SAAS,OAAO,CAAC,IAAiB;QAChC,OAAO,IAAI,CAAC,KAAK,IAAI,eAAe,IAAI,IAAI,CAAC,KAAK,IAAI,eAAe,CAAC;IACxE,CAAC;IAED,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1B,MAAM,gBAAgB,GAAG,SAAS,CAAC;YACjC,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,eAAe;YACf,eAAe;SAChB,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;YACjB,OAAO;gBACL;oBACE,GAAG,IAAI;oBACP,QAAQ,EAAE,gBAAgB;iBAC3B;aACF,CAAC;SACH;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,0BAA0B,CAAC,EACzC,GAAG,EACH,eAAe,EACf,eAAe,GAKhB;IACC,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,SAAS,CAAC,EAAC,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,eAAe,EAAE,eAAe,EAAC,CAAC,EACzE,CAAC,GAAG,EAAE,eAAe,EAAE,eAAe,CAAC,CACxC,CAAC;AACJ,CAAC"}

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.
*/
/// <reference types="react" />
export declare function UnlistedBannerTitle(): JSX.Element;
export declare function UnlistedBannerMessage(): JSX.Element;
export declare function UnlistedMetadata(): JSX.Element;
//# sourceMappingURL=unlistedUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"unlistedUtils.d.ts","sourceRoot":"","sources":["../../src/utils/unlistedUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;;AAMH,wBAAgB,mBAAmB,IAAI,GAAG,CAAC,OAAO,CAQjD;AAED,wBAAgB,qBAAqB,IAAI,GAAG,CAAC,OAAO,CASnD;AAED,wBAAgB,gBAAgB,IAAI,GAAG,CAAC,OAAO,CAM9C"}

View File

@@ -0,0 +1,26 @@
/**
* 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 from 'react';
import Translate from '@docusaurus/Translate';
import Head from '@docusaurus/Head';
export function UnlistedBannerTitle() {
return (<Translate id="theme.unlistedContent.title" description="The unlisted content banner title">
Unlisted page
</Translate>);
}
export function UnlistedBannerMessage() {
return (<Translate id="theme.unlistedContent.message" description="The unlisted content banner message">
This page is unlisted. Search engines will not index it, and only users
having a direct link can access it.
</Translate>);
}
export function UnlistedMetadata() {
return (<Head>
<meta name="robots" content="noindex, nofollow"/>
</Head>);
}
//# sourceMappingURL=unlistedUtils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"unlistedUtils.js","sourceRoot":"","sources":["../../src/utils/unlistedUtils.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,SAAS,MAAM,uBAAuB,CAAC;AAC9C,OAAO,IAAI,MAAM,kBAAkB,CAAC;AAEpC,MAAM,UAAU,mBAAmB;IACjC,OAAO,CACL,CAAC,SAAS,CACR,EAAE,CAAC,6BAA6B,CAChC,WAAW,CAAC,mCAAmC,CAC/C;;IACF,EAAE,SAAS,CAAC,CACb,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CACL,CAAC,SAAS,CACR,EAAE,CAAC,+BAA+B,CAClC,WAAW,CAAC,qCAAqC,CACjD;;;IAEF,EAAE,SAAS,CAAC,CACb,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,CACL,CAAC,IAAI,CACH;MAAA,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EACjD;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,32 @@
/**
* 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.
*/
/**
* Permits to obtain the url of the current page in another locale, useful to
* generate hreflang meta headers etc...
*
* @see https://developers.google.com/search/docs/advanced/crawling/localized-versions
*/
export declare function useAlternatePageUtils(): {
/**
* Everything (pathname, base URL, etc.) is read from the context. Just tell
* it which locale to link to and it will give you the alternate link for the
* current page.
*/
createUrl: ({
/** The locale name to link to. */
locale,
/**
* For hreflang SEO headers, we need it to be fully qualified (full
* protocol/domain/path...); but for locale dropdowns, using a pathname is
* good enough.
*/
fullyQualified, }: {
locale: string;
fullyQualified: boolean;
}) => string;
};
//# sourceMappingURL=useAlternatePageUtils.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"useAlternatePageUtils.d.ts","sourceRoot":"","sources":["../../src/utils/useAlternatePageUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI;IACvC;;;;OAIG;IACH,SAAS,EAAE,CAAC;IACV,kCAAkC;IAClC,MAAM;IACN;;;;OAIG;IACH,cAAc,GACf,EAAE;QACD,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,OAAO,CAAC;KACzB,KAAK,MAAM,CAAC;CACd,CA2CA"}

View File

@@ -0,0 +1,41 @@
/**
* 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';
import { useLocation } from '@docusaurus/router';
import { applyTrailingSlash } from '@docusaurus/utils-common';
/**
* Permits to obtain the url of the current page in another locale, useful to
* generate hreflang meta headers etc...
*
* @see https://developers.google.com/search/docs/advanced/crawling/localized-versions
*/
export function useAlternatePageUtils() {
const { siteConfig: { baseUrl, url, trailingSlash }, i18n: { defaultLocale, currentLocale }, } = useDocusaurusContext();
// TODO using useLocation().pathname is not a super idea
// See https://github.com/facebook/docusaurus/issues/9170
const { pathname } = useLocation();
const canonicalPathname = applyTrailingSlash(pathname, {
trailingSlash,
baseUrl,
});
const baseUrlUnlocalized = currentLocale === defaultLocale
? baseUrl
: baseUrl.replace(`/${currentLocale}/`, '/');
const pathnameSuffix = canonicalPathname.replace(baseUrl, '');
function getLocalizedBaseUrl(locale) {
return locale === defaultLocale
? `${baseUrlUnlocalized}`
: `${baseUrlUnlocalized}${locale}/`;
}
// TODO support correct alternate url when localized site is deployed on
// another domain
function createUrl({ locale, fullyQualified, }) {
return `${fullyQualified ? url : ''}${getLocalizedBaseUrl(locale)}${pathnameSuffix}`;
}
return { createUrl };
}
//# sourceMappingURL=useAlternatePageUtils.js.map

Some files were not shown because too many files have changed in this diff Show More