diff --git a/.github/workflows/v2-build-size-report.yml b/.github/workflows/v2-build-size-report.yml index d24d65f1bf84..867eabf257d5 100644 --- a/.github/workflows/v2-build-size-report.yml +++ b/.github/workflows/v2-build-size-report.yml @@ -26,7 +26,7 @@ jobs: with: repo-token: '${{ secrets.GITHUB_TOKEN }}' build-script: 'build:v2:en' - pattern: '{website/build/assets/js/main*js,website/build/assets/css/styles*css,website/.docusaurus/globalData.json,website/build/index.html,website/build/blog/**/introducing-docusaurus/*,website/build/docs/index.html,website/build/docs/introduction/index.html,website/build/docs-tests/index.html,website/build/docs-tests/standalone/index.html}' + pattern: '{website/build/assets/js/main*js,website/build/assets/css/styles*css,website/.docusaurus/globalData.json,website/build/index.html,website/build/blog/index.html,website/build/blog/**/introducing-docusaurus/*,website/build/docs/index.html,website/build/docs/installation/index.html,website/build/docs-tests/index.html,website/build/docs-tests/standalone/index.html}' strip-hash: '\.([^;]\w{7})\.' minimum-change-threshold: 30 compression: 'none' diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index c7f7fb79b185..a412668ff49e 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -456,11 +456,6 @@ Object { ] } ] - }, - \\"permalinkToSidebar\\": { - \\"/docs/foo/bar\\": \\"docs\\", - \\"/docs/foo/bazSlug.html\\": \\"docs\\", - \\"/docs/\\": \\"docs\\" } }", } @@ -575,6 +570,7 @@ Array [ "content": "@site/docs/hello.md", }, "path": "/docs/", + "sidebar": "docs", }, Object { "component": "@theme/DocItem", @@ -591,6 +587,7 @@ Array [ "content": "@site/docs/foo/bar.md", }, "path": "/docs/foo/bar", + "sidebar": "docs", }, Object { "component": "@theme/DocItem", @@ -599,6 +596,7 @@ Array [ "content": "@site/docs/foo/baz.md", }, "path": "/docs/foo/bazSlug.html", + "sidebar": "docs", }, Object { "component": "@theme/DocItem", @@ -883,9 +881,6 @@ Object { \\"href\\": \\"/community/team\\" } ] - }, - \\"permalinkToSidebar\\": { - \\"/community/team\\": \\"version-1.0.0/community\\" } }", "version-current-metadata-prop-751.json": "{ @@ -902,9 +897,6 @@ Object { \\"href\\": \\"/community/next/team\\" } ] - }, - \\"permalinkToSidebar\\": { - \\"/community/next/team\\": \\"community\\" } }", } @@ -968,6 +960,7 @@ Array [ "content": "@site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md", }, "path": "/community/next/team", + "sidebar": "community", }, ], }, @@ -987,6 +980,7 @@ Array [ "content": "@site/community_versioned_docs/version-1.0.0/team.md", }, "path": "/community/team", + "sidebar": "version-1.0.0/community", }, ], }, @@ -1439,11 +1433,6 @@ Object { ] } ] - }, - \\"permalinkToSidebar\\": { - \\"/docs/1.0.0/foo/barSlug\\": \\"version-1.0.0/docs\\", - \\"/docs/1.0.0/foo/baz\\": \\"version-1.0.0/docs\\", - \\"/docs/1.0.0/\\": \\"version-1.0.0/docs\\" } }", "version-1-0-1-metadata-prop-e87.json": "{ @@ -1479,10 +1468,6 @@ Object { ] } ] - }, - \\"permalinkToSidebar\\": { - \\"/docs/foo/bar\\": \\"version-1.0.1/docs\\", - \\"/docs/\\": \\"version-1.0.1/docs\\" } }", "version-current-metadata-prop-751.json": "{ @@ -1518,10 +1503,6 @@ Object { ] } ] - }, - \\"permalinkToSidebar\\": { - \\"/docs/next/foo/barSlug\\": \\"docs\\", - \\"/docs/next/\\": \\"docs\\" } }", "version-with-slugs-metadata-prop-2bf.json": "{ @@ -1545,9 +1526,6 @@ Object { ] } ] - }, - \\"permalinkToSidebar\\": { - \\"/docs/withSlugs/rootAbsoluteSlug\\": \\"version-1.0.1/docs\\" } }", } @@ -1714,6 +1692,7 @@ Array [ "content": "@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md", }, "path": "/docs/1.0.0/", + "sidebar": "version-1.0.0/docs", }, Object { "component": "@theme/DocItem", @@ -1722,6 +1701,7 @@ Array [ "content": "@site/versioned_docs/version-1.0.0/foo/bar.md", }, "path": "/docs/1.0.0/foo/barSlug", + "sidebar": "version-1.0.0/docs", }, Object { "component": "@theme/DocItem", @@ -1730,6 +1710,7 @@ Array [ "content": "@site/versioned_docs/version-1.0.0/foo/baz.md", }, "path": "/docs/1.0.0/foo/baz", + "sidebar": "version-1.0.0/docs", }, ], }, @@ -1749,6 +1730,7 @@ Array [ "content": "@site/docs/hello.md", }, "path": "/docs/next/", + "sidebar": "docs", }, Object { "component": "@theme/DocItem", @@ -1765,6 +1747,7 @@ Array [ "content": "@site/docs/foo/bar.md", }, "path": "/docs/next/foo/barSlug", + "sidebar": "docs", }, Object { "component": "@theme/DocItem", @@ -1824,6 +1807,7 @@ Array [ "content": "@site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md", }, "path": "/docs/withSlugs/rootAbsoluteSlug", + "sidebar": "version-1.0.1/docs", }, Object { "component": "@theme/DocItem", @@ -1883,6 +1867,7 @@ Array [ "content": "@site/versioned_docs/version-1.0.1/hello.md", }, "path": "/docs/", + "sidebar": "version-1.0.1/docs", }, Object { "component": "@theme/DocItem", @@ -1891,6 +1876,7 @@ Array [ "content": "@site/versioned_docs/version-1.0.1/foo/bar.md", }, "path": "/docs/foo/bar", + "sidebar": "version-1.0.1/docs", }, ], }, diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap index 2344d708297b..18d95700386d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/translations.test.ts.snap @@ -151,7 +151,6 @@ Object { ], "isLast": true, "mainDocId": "", - "permalinkToSidebar": Object {}, "routePriority": undefined, "sidebarFilePath": "any", "sidebars": Object { @@ -292,7 +291,6 @@ Object { ], "isLast": true, "mainDocId": "", - "permalinkToSidebar": Object {}, "routePriority": undefined, "sidebarFilePath": "any", "sidebars": Object { @@ -433,7 +431,6 @@ Object { ], "isLast": true, "mainDocId": "", - "permalinkToSidebar": Object {}, "routePriority": undefined, "sidebarFilePath": "any", "sidebars": Object { diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index fce3a99c03d8..9caa702f7eb0 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -105,9 +105,6 @@ Entries created: `version-${kebabCase(version.versionName)}-metadata-prop`, ); expect(versionMetadataProp.docsSidebars).toEqual(toSidebarsProp(version)); - expect(versionMetadataProp.permalinkToSidebar).toEqual( - version.permalinkToSidebar, - ); }, expectSnapshot: () => { diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts index 21f0d8b55d65..26751c412205 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/translations.test.ts @@ -40,7 +40,6 @@ function createSampleVersion( versionLabel: `${version.versionName} label`, versionPath: '/docs/', mainDocId: '', - permalinkToSidebar: {}, routePriority: undefined, sidebarFilePath: 'any', isLast: true, diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 8617e57a69b4..76d4beed2b9c 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -37,7 +37,6 @@ import { DocFile, DocsMarkdownOption, } from './types'; -import {PermalinkToSidebar} from '@docusaurus/plugin-content-docs-types'; import {RuleSetRule} from 'webpack'; import {cliDocsVersionCommand} from './cli'; import {VERSIONS_JSON_FILE} from './constants'; @@ -224,14 +223,6 @@ export default function pluginContentDocs( // sort to ensure consistent output for tests docs.sort((a, b) => a.id.localeCompare(b.id)); - // TODO really useful? replace with global state logic? - const permalinkToSidebar: PermalinkToSidebar = {}; - Object.values(docs).forEach((doc) => { - if (doc.sidebar) { - permalinkToSidebar[doc.permalink] = doc.sidebar; - } - }); - // The "main doc" is the "version entry point" // We browse this doc by clicking on a version: // - the "home" doc (at '/docs/') @@ -256,7 +247,6 @@ export default function pluginContentDocs( ...versionMetadata, mainDocId: getMainDoc().unversionedId, sidebars, - permalinkToSidebar, docs: docs.map(addNavData), }; } @@ -300,30 +290,36 @@ export default function pluginContentDocs( JSON.stringify(metadataItem, null, 2), ); - return { + const docRoute: RouteConfig = { path: metadataItem.permalink, component: docItemComponent, exact: true, modules: { content: metadataItem.source, }, + // Because the parent (DocPage) comp need to access it easily + // This permits to render the sidebar once without unmount/remount when navigating (and preserve sidebar state) + ...(metadataItem.sidebar && { + sidebar: metadataItem.sidebar, + }), }; + + return docRoute; }), ); return routes.sort((a, b) => a.path.localeCompare(b.path)); }; - async function doCreateVersionRoutes(loadedVersion: LoadedVersion) { + async function doCreateVersionRoutes( + loadedVersion: LoadedVersion, + ): Promise { + const versionMetadata = toVersionMetadataProp(pluginId, loadedVersion); const versionMetadataPropPath = await createData( `${docuHash( `version-${loadedVersion.versionName}-metadata-prop`, )}.json`, - JSON.stringify( - toVersionMetadataProp(pluginId, loadedVersion), - null, - 2, - ), + JSON.stringify(versionMetadata, null, 2), ); addRoute({ @@ -341,7 +337,9 @@ export default function pluginContentDocs( }); } - async function createVersionRoutes(loadedVersion: LoadedVersion) { + async function createVersionRoutes( + loadedVersion: LoadedVersion, + ): Promise { try { return await doCreateVersionRoutes(loadedVersion); } catch (e) { diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 7370f4d84d72..54a95695301e 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -10,10 +10,6 @@ declare module '@docusaurus/plugin-content-docs-types' { import type {VersionBanner} from './types'; - export type PermalinkToSidebar = { - [permalink: string]: string; - }; - export type PropVersionMetadata = { pluginId: string; version: string; @@ -21,7 +17,6 @@ declare module '@docusaurus/plugin-content-docs-types' { banner: VersionBanner; isLast: boolean; docsSidebars: PropSidebars; - permalinkToSidebar: PermalinkToSidebar; }; type PropsSidebarItemBase = { @@ -60,6 +55,7 @@ declare module '@theme/DocItem' { readonly component: () => JSX.Element; readonly exact: boolean; readonly path: string; + readonly sidebar?: string; }; export type FrontMatter = { diff --git a/packages/docusaurus-plugin-content-docs/src/props.ts b/packages/docusaurus-plugin-content-docs/src/props.ts index 5d32bea3a889..a9c3446725f1 100644 --- a/packages/docusaurus-plugin-content-docs/src/props.ts +++ b/packages/docusaurus-plugin-content-docs/src/props.ts @@ -77,6 +77,5 @@ export function toVersionMetadataProp( banner: loadedVersion.versionBanner, isLast: loadedVersion.isLast, docsSidebars: toSidebarsProp(loadedVersion), - permalinkToSidebar: loadedVersion.permalinkToSidebar, }; } diff --git a/packages/docusaurus-plugin-content-docs/src/types.ts b/packages/docusaurus-plugin-content-docs/src/types.ts index 3e5475f9f676..e546d8a319be 100644 --- a/packages/docusaurus-plugin-content-docs/src/types.ts +++ b/packages/docusaurus-plugin-content-docs/src/types.ts @@ -239,7 +239,6 @@ export type LoadedVersion = VersionMetadata & { mainDocId: string; docs: DocMetadata[]; sidebars: Sidebars; - permalinkToSidebar: Record; }; export type LoadedContent = { diff --git a/packages/docusaurus-theme-bootstrap/src/theme/DocPage/index.tsx b/packages/docusaurus-theme-bootstrap/src/theme/DocPage/index.tsx index 54828fc32dfd..ac90418917dd 100644 --- a/packages/docusaurus-theme-bootstrap/src/theme/DocPage/index.tsx +++ b/packages/docusaurus-theme-bootstrap/src/theme/DocPage/index.tsx @@ -8,37 +8,25 @@ import React, {ReactNode} from 'react'; import renderRoutes from '@docusaurus/renderRoutes'; import NotFound from '@theme/NotFound'; -import DocSidebar from '@theme/DocSidebar'; import MDXComponents from '@theme/MDXComponents'; import Layout from '@theme/Layout'; import {MDXProvider} from '@mdx-js/react'; import {matchPath} from '@docusaurus/router'; import type {Props} from '@theme/DocPage'; -import type {DocumentRoute} from '@theme/DocItem'; import type {PropVersionMetadata} from '@docusaurus/plugin-content-docs-types'; type DocPageContentProps = { - readonly currentDocRoute: DocumentRoute; readonly versionMetadata: PropVersionMetadata; readonly children: ReactNode; }; function DocPageContent({ - currentDocRoute, - versionMetadata, + versionMetadata: _versionMetadata, children, }: DocPageContentProps): JSX.Element { - const {permalinkToSidebar, docsSidebars} = versionMetadata; - const sidebarName = permalinkToSidebar[currentDocRoute.path]; - const sidebar = docsSidebars[sidebarName]; return (
- {sidebar && ( -
- -
- )}
{children}
@@ -60,9 +48,7 @@ function DocPage(props: Props): JSX.Element { return ; } return ( - + {renderRoutes(docRoutes)} ); diff --git a/packages/docusaurus-theme-classic/codeTranslations/ar.json b/packages/docusaurus-theme-classic/codeTranslations/ar.json index 57a6bc70d41d..b14faa0c95cc 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/ar.json +++ b/packages/docusaurus-theme-classic/codeTranslations/ar.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "بحث", "theme.SearchPage.inputPlaceholder": "اكتب ما تبحث عنه هنا", "theme.SearchPage.noResultsText": "لم يتم العثور على نتائج", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "التنقل في صفحة قائمة المدونة", "theme.blog.paginator.newerEntries": "إدخالات أحدث", "theme.blog.paginator.olderEntries": "إدخالات أقدم", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "طي الشريط الجانبي", "theme.docs.sidebar.expandButtonAriaLabel": "توسيع الشريط الجانبي", "theme.docs.sidebar.expandButtonTitle": "توسيع الشريط الجانبي", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "إغلاق القائمة", - "theme.docs.sidebar.responsiveOpenButtonLabel": "فتح القائمة", "theme.docs.versions.latestVersionLinkLabel": "احدث اصدار", "theme.docs.versions.latestVersionSuggestionLabel": "للحصول على أحدث الوثائق، راجع {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "هذه هي وثائق {siteTitle} {versionLabel}، التي لم تعد تتم صيانتها بشكل نشط.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " في {date}", "theme.lastUpdated.byUser": " بواسطة {user}", "theme.lastUpdated.lastUpdatedAtBy": "آخر تحديث{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "الوسوم:", "theme.tags.tagsPageLink": "عرض كل الوسوم", "theme.tags.tagsPageTitle": "الوسوم" diff --git a/packages/docusaurus-theme-classic/codeTranslations/base.json b/packages/docusaurus-theme-classic/codeTranslations/base.json index 4656b5c9d2df..0a333c0e4b51 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/base.json +++ b/packages/docusaurus-theme-classic/codeTranslations/base.json @@ -41,6 +41,8 @@ "theme.SearchPage.inputPlaceholder___DESCRIPTION": "The placeholder for search page input", "theme.SearchPage.noResultsText": "No results were found", "theme.SearchPage.noResultsText___DESCRIPTION": "The paragraph for empty search result", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", + "theme.TOCCollapsible.toggleButtonLabel___DESCRIPTION": "The label used by the button on the collapsible TOC component", "theme.blog.paginator.navAriaLabel": "Blog list page navigation", "theme.blog.paginator.navAriaLabel___DESCRIPTION": "The ARIA label for the blog pagination", "theme.blog.paginator.newerEntries": "Newer Entries", @@ -83,16 +85,10 @@ "theme.docs.sidebar.expandButtonAriaLabel___DESCRIPTION": "The ARIA label and title attribute for expand button of doc sidebar", "theme.docs.sidebar.expandButtonTitle": "Expand sidebar", "theme.docs.sidebar.expandButtonTitle___DESCRIPTION": "The ARIA label and title attribute for expand button of doc sidebar", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.navAriaLabel___DESCRIPTION": "The ARIA label for documentation menu", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Close menu", - "theme.docs.sidebar.responsiveCloseButtonLabel___DESCRIPTION": "The ARIA label for close button of mobile doc sidebar", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Open menu", - "theme.docs.sidebar.responsiveOpenButtonLabel___DESCRIPTION": "The ARIA label for open button of mobile doc sidebar", "theme.docs.versions.latestVersionLinkLabel": "latest version", "theme.docs.versions.latestVersionLinkLabel___DESCRIPTION": "The label used for the latest version suggestion link label", "theme.docs.versions.latestVersionSuggestionLabel": "For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).", - "theme.docs.versions.latestVersionSuggestionLabel___DESCRIPTION": "The label userd to tell the user that he's browsing an unmaintained doc version", + "theme.docs.versions.latestVersionSuggestionLabel___DESCRIPTION": "The label used to tell the user to check the latest version", "theme.docs.versions.unmaintainedVersionLabel": "This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.", "theme.docs.versions.unmaintainedVersionLabel___DESCRIPTION": "The label used to tell the user that he's browsing an unmaintained doc version", "theme.docs.versions.unreleasedVersionLabel": "This is unreleased documentation for {siteTitle} {versionLabel} version.", @@ -103,6 +99,8 @@ "theme.lastUpdated.byUser___DESCRIPTION": "The words used to describe by who the page has been last updated", "theme.lastUpdated.lastUpdatedAtBy": "Last updated{atDate}{byUser}", "theme.lastUpdated.lastUpdatedAtBy___DESCRIPTION": "The sentence used to display when a page has been last updated, and by who", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel___DESCRIPTION": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)", "theme.tags.tagsListLabel": "Tags:", "theme.tags.tagsListLabel___DESCRIPTION": "The label alongside a tag list", "theme.tags.tagsPageLink": "View All Tags", diff --git a/packages/docusaurus-theme-classic/codeTranslations/bn.json b/packages/docusaurus-theme-classic/codeTranslations/bn.json index 6fde77a415de..e3bb8a5edfce 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/bn.json +++ b/packages/docusaurus-theme-classic/codeTranslations/bn.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "সার্চ", "theme.SearchPage.inputPlaceholder": "আপনার অনুসন্ধান এখানে টাইপ করুন", "theme.SearchPage.noResultsText": "কোন ফলাফল পাওয়া যায়নি", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "ব্লগ তালিকা পেজ নেভিগেশন", "theme.blog.paginator.newerEntries": "নতুন এন্ট্রি", "theme.blog.paginator.olderEntries": "পুরানো এন্ট্রি", @@ -41,8 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "সাইডবারটি সঙ্কুচিত করুন", "theme.docs.sidebar.expandButtonAriaLabel": "সাইডবারটি প্রসারিত করুন", "theme.docs.sidebar.expandButtonTitle": "সাইডবারটি প্রসারিত করুন", - "theme.docs.sidebar.responsiveCloseButtonLabel": "মেনু বন্ধ করুন", - "theme.docs.sidebar.responsiveOpenButtonLabel": "মেনু খুলুন", "theme.docs.versions.latestVersionLinkLabel": "লেটেস্ট ভার্সন", "theme.docs.versions.latestVersionSuggestionLabel": "আপ-টু-ডেট ডকুমেন্টেশনের জন্য, {latestVersionLink} ({versionLabel}) দেখুন।", "theme.docs.versions.unmaintainedVersionLabel": "এটি {siteTitle} {versionLabel} এর জন্যে ডকুমেন্টেশন, যা আর সক্রিয়ভাবে রক্ষণাবেক্ষণ করা হয় না।", @@ -50,6 +49,7 @@ "theme.lastUpdated.atDate": " {date} তারিখে", "theme.lastUpdated.byUser": "{user} দ্বারা", "theme.lastUpdated.lastUpdatedAtBy": "সর্বশেষ সংষ্করণ{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "ট্যাগ্স:", "theme.tags.tagsPageLink": "সমস্ত ট্যাগ্স দেখুন", "theme.tags.tagsPageTitle": "ট্যাগ্স" diff --git a/packages/docusaurus-theme-classic/codeTranslations/da.json b/packages/docusaurus-theme-classic/codeTranslations/da.json index 57732f462580..307c067f1f86 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/da.json +++ b/packages/docusaurus-theme-classic/codeTranslations/da.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Søg", "theme.SearchPage.inputPlaceholder": "Indtast din søgning her", "theme.SearchPage.noResultsText": "Ingen resultater fundet", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Blogoversigt navigation", "theme.blog.paginator.newerEntries": "Nyere indslag", "theme.blog.paginator.olderEntries": "Tidligere indslag", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Sammenlæg sidenavigation", "theme.docs.sidebar.expandButtonAriaLabel": "Udvid sidenavigation", "theme.docs.sidebar.expandButtonTitle": "Udvid sidenavigation", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Luk menu", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Åben menu", "theme.docs.versions.latestVersionLinkLabel": "seneste version", "theme.docs.versions.latestVersionSuggestionLabel": "For seneste dokumentation, se {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Dette er dokumentationen for {siteTitle} {versionLabel}, som ikke længere bliver aktivt vedligeholdt.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " den {date}", "theme.lastUpdated.byUser": " af {user}", "theme.lastUpdated.lastUpdatedAtBy": "Senest opdateret{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Tags:", "theme.tags.tagsPageLink": "Se alle Tags", "theme.tags.tagsPageTitle": "Tags" diff --git a/packages/docusaurus-theme-classic/codeTranslations/de.json b/packages/docusaurus-theme-classic/codeTranslations/de.json index d360ce0fdcc9..d39d30858d30 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/de.json +++ b/packages/docusaurus-theme-classic/codeTranslations/de.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Suche", "theme.SearchPage.inputPlaceholder": "Geben Sie hier Ihre Suche ein", "theme.SearchPage.noResultsText": "Es wurden keine Ergebnisse gefunden", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Navigation der Blog-Listenseite", "theme.blog.paginator.newerEntries": "Neuere Einträge", "theme.blog.paginator.olderEntries": "Ältere Einträge", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Seitenleiste einklappen", "theme.docs.sidebar.expandButtonAriaLabel": "Seitenleiste ausklappen", "theme.docs.sidebar.expandButtonTitle": "Seitenleiste ausklappen", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Menü schließen", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Menü öffenen", "theme.docs.versions.latestVersionLinkLabel": "letzte Version", "theme.docs.versions.latestVersionSuggestionLabel": "Für die aktuellste Dokumentation bitte auf {latestVersionLink} ({versionLabel}) gehen.", "theme.docs.versions.unmaintainedVersionLabel": "Das ist die Dokumentation für {siteTitle} {versionLabel} und wird nicht weiter gewartet.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " am {date}", "theme.lastUpdated.byUser": " von {user}", "theme.lastUpdated.lastUpdatedAtBy": "Letztes Update{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Tags:", "theme.tags.tagsPageLink": "Alle Tags anzeigen", "theme.tags.tagsPageTitle": "Tags" diff --git a/packages/docusaurus-theme-classic/codeTranslations/es.json b/packages/docusaurus-theme-classic/codeTranslations/es.json index 8a98598f777f..c59d93d78171 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/es.json +++ b/packages/docusaurus-theme-classic/codeTranslations/es.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Buscar", "theme.SearchPage.inputPlaceholder": "Escribe tu búsqueda aquí", "theme.SearchPage.noResultsText": "No se encontraron resultados", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Navegación por la página de la lista de blogs ", "theme.blog.paginator.newerEntries": "Entradas más recientes", "theme.blog.paginator.olderEntries": "Entradas más antiguas", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Colapsar barra lateral", "theme.docs.sidebar.expandButtonAriaLabel": "Expandir barra lateral", "theme.docs.sidebar.expandButtonTitle": "Expandir barra lateral", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Cerrar menu", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Abrir menu", "theme.docs.versions.latestVersionLinkLabel": "última versión", "theme.docs.versions.latestVersionSuggestionLabel": "Para documentación actualizada, ver {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Está es documentación para {siteTitle} {versionLabel}, que ya no se mantiene activamente.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " en {date}", "theme.lastUpdated.byUser": " por {user}", "theme.lastUpdated.lastUpdatedAtBy": "Última actualización{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Etiquetas:", "theme.tags.tagsPageLink": "Ver Todas las Etiquetas", "theme.tags.tagsPageTitle": "Etiquetas" diff --git a/packages/docusaurus-theme-classic/codeTranslations/fa.json b/packages/docusaurus-theme-classic/codeTranslations/fa.json index f98eb8d981f2..894524471a27 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/fa.json +++ b/packages/docusaurus-theme-classic/codeTranslations/fa.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "جستجو", "theme.SearchPage.inputPlaceholder": "عبارت مورد نظر را اینجا بنویسید", "theme.SearchPage.noResultsText": "هیچ نتیجه ای پیدا نشد", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "کنترل لیست صفحه وبسایت", "theme.blog.paginator.newerEntries": "مطالب جدیدتر", "theme.blog.paginator.olderEntries": "مطالب قدیمی تر", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "بستن نوار کناری", "theme.docs.sidebar.expandButtonAriaLabel": "بزرگ کردن نوار کناری", "theme.docs.sidebar.expandButtonTitle": "بزرگ کردن نوار کناری", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "بستن منو", - "theme.docs.sidebar.responsiveOpenButtonLabel": "باز کردن منو", "theme.docs.versions.latestVersionLinkLabel": "آخرین نسخه", "theme.docs.versions.latestVersionSuggestionLabel": "برای دیدن آخرین نسخه، {latestVersionLink} ({versionLabel}) را ببینید.", "theme.docs.versions.unmaintainedVersionLabel": "نسخه {siteTitle} {versionLabel} دیگر بروزرسانی نمی شود.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " در تاریخ {date}", "theme.lastUpdated.byUser": " توسط {user}", "theme.lastUpdated.lastUpdatedAtBy": "آخرین به روزرسانی{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": ":برچسب ها", "theme.tags.tagsPageLink": "مشاهده تمام برچسب ها", "theme.tags.tagsPageTitle": "برچسب ها" diff --git a/packages/docusaurus-theme-classic/codeTranslations/fil.json b/packages/docusaurus-theme-classic/codeTranslations/fil.json index 61f20e098168..7d7f9942315d 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/fil.json +++ b/packages/docusaurus-theme-classic/codeTranslations/fil.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Maghanap", "theme.SearchPage.inputPlaceholder": "I-type and inyong hinahanap dito", "theme.SearchPage.noResultsText": "Walang resultang nahanap", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Nabegasyón para sa pahina na listahan ng blog", "theme.blog.paginator.newerEntries": "Mas bagong mga éntri", "theme.blog.paginator.olderEntries": "Mas lumang mga éntri", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Itupî ang sidebar", "theme.docs.sidebar.expandButtonAriaLabel": "Palakihin ang sidebar", "theme.docs.sidebar.expandButtonTitle": "Palakihin ang sidebar", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Isara ang menu", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Buksan ang menu", "theme.docs.versions.latestVersionLinkLabel": "pinakahuling bersiyón", "theme.docs.versions.latestVersionSuggestionLabel": "Para sa up-to-date na dokumentasyón, tingnan ang {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Ito ay dokumentasyón para sa {siteTitle} {versionLabel} na hindi na aktibong mine-maintain.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " noong {date}", "theme.lastUpdated.byUser": " ni {user}", "theme.lastUpdated.lastUpdatedAtBy": "Huling inapdeyt{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Mga Tag:", "theme.tags.tagsPageLink": "Tingnan Lahat ng mga Tag", "theme.tags.tagsPageTitle": "Mga Tag" diff --git a/packages/docusaurus-theme-classic/codeTranslations/fr.json b/packages/docusaurus-theme-classic/codeTranslations/fr.json index a869b53b305d..b3fdd4275367 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/fr.json +++ b/packages/docusaurus-theme-classic/codeTranslations/fr.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Chercher", "theme.SearchPage.inputPlaceholder": "Tapez votre recherche ici", "theme.SearchPage.noResultsText": "Aucun résultat trouvé", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Pagination de la liste des articles du blog", "theme.blog.paginator.newerEntries": "Nouvelles entrées", "theme.blog.paginator.olderEntries": "Anciennes entrées", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Réduire le menu latéral", "theme.docs.sidebar.expandButtonAriaLabel": "Déplier le menu latéral", "theme.docs.sidebar.expandButtonTitle": "Déplier le menu latéral", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Fermer le menu latéral", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Ouvrir le menu latéral", "theme.docs.versions.latestVersionLinkLabel": "dernière version", "theme.docs.versions.latestVersionSuggestionLabel": "Pour une documentation à jour, consultez la {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Ceci est la documentation de {siteTitle} {versionLabel}, qui n'est plus activement maintenue.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " le {date}", "theme.lastUpdated.byUser": " par {user}", "theme.lastUpdated.lastUpdatedAtBy": "Dernière mise à jour{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Tags :", "theme.tags.tagsPageLink": "Voir tous les tags", "theme.tags.tagsPageTitle": "Tags" diff --git a/packages/docusaurus-theme-classic/codeTranslations/he.json b/packages/docusaurus-theme-classic/codeTranslations/he.json index 44e20fd48495..f20664891032 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/he.json +++ b/packages/docusaurus-theme-classic/codeTranslations/he.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "חיפוש", "theme.SearchPage.inputPlaceholder": "הקלד כאן לחיפוש", "theme.SearchPage.noResultsText": "לא נמצאו תוצאות", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "רשימת דפי הבלוג", "theme.blog.paginator.newerEntries": "הכי חדש", "theme.blog.paginator.olderEntries": "ישן יותר", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "סגור", "theme.docs.sidebar.expandButtonAriaLabel": "פתח", "theme.docs.sidebar.expandButtonTitle": "פתח", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "סגור תפריט", - "theme.docs.sidebar.responsiveOpenButtonLabel": "פתח תפריט", "theme.docs.versions.latestVersionLinkLabel": "גרסא אחרונה", "theme.docs.versions.latestVersionSuggestionLabel": "לדוקומנטאציה עדכנית, ראה {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "דוקומנטאציה זו {siteTitle} {versionLabel}, כבר לא נתמכת.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " בתאריך {date}", "theme.lastUpdated.byUser": " על ידי {user}", "theme.lastUpdated.lastUpdatedAtBy": "עודכן{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "תגיות:", "theme.tags.tagsPageLink": "כל התגיות", "theme.tags.tagsPageTitle": "תגיות" diff --git a/packages/docusaurus-theme-classic/codeTranslations/hi.json b/packages/docusaurus-theme-classic/codeTranslations/hi.json index b11e72ab879d..740f54a781dd 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/hi.json +++ b/packages/docusaurus-theme-classic/codeTranslations/hi.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "खोज करें", "theme.SearchPage.inputPlaceholder": "अपनी खोज यहाँ टाइप करें", "theme.SearchPage.noResultsText": "कोई परिणाम नहीं मिलें", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "ब्लॉग सूची पेज नेविगेशन", "theme.blog.paginator.newerEntries": "नए एंट्रीज़", "theme.blog.paginator.olderEntries": "पुराने एंट्रीज़", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "साइडबार बंद करें", "theme.docs.sidebar.expandButtonAriaLabel": "साइडबार खोलें", "theme.docs.sidebar.expandButtonTitle": "साइडबार खोलें", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "मेन्यू बंद करें", - "theme.docs.sidebar.responsiveOpenButtonLabel": "मेन्यू खोलें", "theme.docs.versions.latestVersionLinkLabel": "सबसे नया वर्जन", "theme.docs.versions.latestVersionSuggestionLabel": "अप-टू-डेट डॉक्यूमेंटेशन के लिए {latestVersionLink} ({versionLabel}) देखें।", "theme.docs.versions.unmaintainedVersionLabel": "यह {siteTitle} {versionLabel} के लिए डॉक्यूमेंटेशन है, जिसे अब सक्रिय रूप से नहीं बनाए रखा गया है।", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " {date} पर", "theme.lastUpdated.byUser": " {user} द्वारा", "theme.lastUpdated.lastUpdatedAtBy": "आखरी अपडेट{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "टैग:", "theme.tags.tagsPageLink": "सारे टैग देखें", "theme.tags.tagsPageTitle": "टैग" diff --git a/packages/docusaurus-theme-classic/codeTranslations/ja.json b/packages/docusaurus-theme-classic/codeTranslations/ja.json index 13ff38ffe993..1eb8db9893f1 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/ja.json +++ b/packages/docusaurus-theme-classic/codeTranslations/ja.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "検索", "theme.SearchPage.inputPlaceholder": "ここに検索するキーワードを入力してください", "theme.SearchPage.noResultsText": "検索結果が見つかりませんでした", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "ブログ記事一覧のナビゲーション", "theme.blog.paginator.newerEntries": "新しい記事", "theme.blog.paginator.olderEntries": "過去の記事", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "サイドバーを隠す", "theme.docs.sidebar.expandButtonAriaLabel": "サイドバーを開く", "theme.docs.sidebar.expandButtonTitle": "サイドバーを開く", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "メニューを閉じる", - "theme.docs.sidebar.responsiveOpenButtonLabel": "メニューを開く", "theme.docs.versions.latestVersionLinkLabel": "最新バージョン", "theme.docs.versions.latestVersionSuggestionLabel": "最新のドキュメントは{latestVersionLink} ({versionLabel}) を見てください。", "theme.docs.versions.unmaintainedVersionLabel": "これは{siteTitle} {versionLabel}のドキュメントで現在はアクティブにメンテナンスされていません。", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": "{date}に", "theme.lastUpdated.byUser": "{user}が", "theme.lastUpdated.lastUpdatedAtBy": "{atDate}{byUser}最終更新", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "タグ:", "theme.tags.tagsPageLink": "全てのタグを見る", "theme.tags.tagsPageTitle": "タグ" diff --git a/packages/docusaurus-theme-classic/codeTranslations/ko.json b/packages/docusaurus-theme-classic/codeTranslations/ko.json index 8e8dbb5384ab..abfe30751408 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/ko.json +++ b/packages/docusaurus-theme-classic/codeTranslations/ko.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "검색", "theme.SearchPage.inputPlaceholder": "여기에 검색할 키워드를 입력하세요.", "theme.SearchPage.noResultsText": "검색 결과가 없습니다.", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "블로그 게시물 목록 탐색", "theme.blog.paginator.newerEntries": "이전 페이지", "theme.blog.paginator.olderEntries": "다음 페이지", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "사이드바 숨기기", "theme.docs.sidebar.expandButtonAriaLabel": "사이드바 열기", "theme.docs.sidebar.expandButtonTitle": "사이드바 열기", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "메뉴 닫기", - "theme.docs.sidebar.responsiveOpenButtonLabel": "메뉴 열기", "theme.docs.versions.latestVersionLinkLabel": "최신 버전", "theme.docs.versions.latestVersionSuggestionLabel": "최신 문서는 {latestVersionLink} ({versionLabel})을 확인하세요.", "theme.docs.versions.unmaintainedVersionLabel": "{siteTitle} {versionLabel} 문서는 업데이트되지 않습니다.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " {date}에", "theme.lastUpdated.byUser": " {user}가", "theme.lastUpdated.lastUpdatedAtBy": "{atDate}{byUser} 마지막으로 업데이트했습니다.", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "태그:", "theme.tags.tagsPageLink": "모든 태그 보기", "theme.tags.tagsPageTitle": "태그" diff --git a/packages/docusaurus-theme-classic/codeTranslations/pl.json b/packages/docusaurus-theme-classic/codeTranslations/pl.json index c34d6e1d040c..ab491a69666d 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/pl.json +++ b/packages/docusaurus-theme-classic/codeTranslations/pl.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Szukaj", "theme.SearchPage.inputPlaceholder": "wpisz szukaną frazę tutaj…", "theme.SearchPage.noResultsText": "Nie znaleziono żadnych wyników", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Nawigacja na stronie listy wpisów na blogu", "theme.blog.paginator.newerEntries": "Nowsze wpisy", "theme.blog.paginator.olderEntries": "Starsze wpisy", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Zwiń boczny panel", "theme.docs.sidebar.expandButtonAriaLabel": "Rozszerz boczny panel", "theme.docs.sidebar.expandButtonTitle": "Rozszerz boczny panel", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Zamknij menu", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Otwórz menu", "theme.docs.versions.latestVersionLinkLabel": "bieżącej wersji", "theme.docs.versions.latestVersionSuggestionLabel": "Aby zobaczyć bieżącą dokumentację, przejdź do wersji {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Ta dokumentacja dotyczy {siteTitle} w wersji {versionLabel} i nie jest już aktywnie aktualizowana.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " dnia {date}", "theme.lastUpdated.byUser": " przez {user}", "theme.lastUpdated.lastUpdatedAtBy": "Ostatnia aktualizacja{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Tagi:", "theme.tags.tagsPageLink": "Wyświetl wszystkie tagi", "theme.tags.tagsPageTitle": "Tagi" diff --git a/packages/docusaurus-theme-classic/codeTranslations/pt-BR.json b/packages/docusaurus-theme-classic/codeTranslations/pt-BR.json index 742304459454..11b8be97fbb2 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/pt-BR.json +++ b/packages/docusaurus-theme-classic/codeTranslations/pt-BR.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Buscar", "theme.SearchPage.inputPlaceholder": "Digite sua busca aqui", "theme.SearchPage.noResultsText": "Nenhum resultado foi encontrado", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Navegação da página de listagem do blog", "theme.blog.paginator.newerEntries": "Conteúdo mais novo", "theme.blog.paginator.olderEntries": "Conteúdo mais antigo", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Fechar painel lateral", "theme.docs.sidebar.expandButtonAriaLabel": "Expandir painel lateral", "theme.docs.sidebar.expandButtonTitle": "Expandir painel lateral", - "theme.docs.sidebar.navAriaLabel": "Navegação do painel lateral", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Fechar menu", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Abrir menu", "theme.docs.versions.latestVersionLinkLabel": "última versão", "theme.docs.versions.latestVersionSuggestionLabel": "Para a documentação atualizada, veja: {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Esta é a documentação para {siteTitle} {versionLabel}, que não é mais mantida ativamente.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " em {date}", "theme.lastUpdated.byUser": " por {user}", "theme.lastUpdated.lastUpdatedAtBy": "Última atualização {atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Marcadores:", "theme.tags.tagsPageLink": "Ver todas os Marcadores", "theme.tags.tagsPageTitle": "Marcadores" diff --git a/packages/docusaurus-theme-classic/codeTranslations/pt-PT.json b/packages/docusaurus-theme-classic/codeTranslations/pt-PT.json index a5b2f5945cf4..34f2eca432e7 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/pt-PT.json +++ b/packages/docusaurus-theme-classic/codeTranslations/pt-PT.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Pesquisar", "theme.SearchPage.inputPlaceholder": "Escreva aqui a sua pesquisa", "theme.SearchPage.noResultsText": "Nenhum resultado encontrado", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Navegação da página de listagem do blog", "theme.blog.paginator.newerEntries": "Publicações mais recentes", "theme.blog.paginator.olderEntries": "Publicações mais antigas", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Colapsar barra lateral", "theme.docs.sidebar.expandButtonAriaLabel": "Expandir barra lateral", "theme.docs.sidebar.expandButtonTitle": "Expandir barra lateral", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Fechar menu", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Abrir menu", "theme.docs.versions.latestVersionLinkLabel": "última versão", "theme.docs.versions.latestVersionSuggestionLabel": "Para a documentação atualizada, veja: {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Esta é a documentação para {siteTitle} {versionLabel}, que já não é mantida ativamente.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " a {date}", "theme.lastUpdated.byUser": " por {user}", "theme.lastUpdated.lastUpdatedAtBy": "Última atualização{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Tags:", "theme.tags.tagsPageLink": "Ver todas as Tags", "theme.tags.tagsPageTitle": "Tags" diff --git a/packages/docusaurus-theme-classic/codeTranslations/ru.json b/packages/docusaurus-theme-classic/codeTranslations/ru.json index 623ead67a692..ca4681aa0d16 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/ru.json +++ b/packages/docusaurus-theme-classic/codeTranslations/ru.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Поиск", "theme.SearchPage.inputPlaceholder": "Введите фразу для поиска", "theme.SearchPage.noResultsText": "По запросу ничего не найдено", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Навигация по странице списка блогов", "theme.blog.paginator.newerEntries": "Следующие записи", "theme.blog.paginator.olderEntries": "Предыдущие записи", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Свернуть сайдбар", "theme.docs.sidebar.expandButtonAriaLabel": "Развернуть сайдбар", "theme.docs.sidebar.expandButtonTitle": "Развернуть сайдбар", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Закрыть меню", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Открыть меню", "theme.docs.versions.latestVersionLinkLabel": "последней версии", "theme.docs.versions.latestVersionSuggestionLabel": "Актуальная документация находится на странице {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Это документация {siteTitle} для версии {versionLabel}, которая уже не поддерживается.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " {date}", "theme.lastUpdated.byUser": " от {user}", "theme.lastUpdated.lastUpdatedAtBy": "Последнее обновление{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Теги:", "theme.tags.tagsPageLink": "Посмотреть все теги", "theme.tags.tagsPageTitle": "Теги" diff --git a/packages/docusaurus-theme-classic/codeTranslations/tr.json b/packages/docusaurus-theme-classic/codeTranslations/tr.json index 3440c0a57acb..acdff3d05cd2 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/tr.json +++ b/packages/docusaurus-theme-classic/codeTranslations/tr.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Ara", "theme.SearchPage.inputPlaceholder": "Aramanızı buraya yazın", "theme.SearchPage.noResultsText": "Hiçbir sonuç bulunamadı", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Blog gönderi sayfası navigasyonu", "theme.blog.paginator.newerEntries": "Yeni Girdiler", "theme.blog.paginator.olderEntries": "Eski Girdiler", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Kenar çubuğunu daralt", "theme.docs.sidebar.expandButtonAriaLabel": "Kenar çubuğunu genişlet", "theme.docs.sidebar.expandButtonTitle": "Kenar çubuğunu genişlet", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Menüyü kapat", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Menüyü aç", "theme.docs.versions.latestVersionLinkLabel": "en son sürüm", "theme.docs.versions.latestVersionSuggestionLabel": "Güncel belgeler için bkz. {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Bu, {siteTitle} {versionLabel} dokümantasyonudur ve bakımı sonlanmıştır.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " {date} tarihinde", "theme.lastUpdated.byUser": " {user} tarafından", "theme.lastUpdated.lastUpdatedAtBy": "En son{atDate}{byUser} güncellendi", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Etiketler:", "theme.tags.tagsPageLink": "Tüm Etiketleri Görüntüle", "theme.tags.tagsPageTitle": "Etiketler" diff --git a/packages/docusaurus-theme-classic/codeTranslations/vi.json b/packages/docusaurus-theme-classic/codeTranslations/vi.json index 6d7c396844da..81db429536d0 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/vi.json +++ b/packages/docusaurus-theme-classic/codeTranslations/vi.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "Tìm kiếm", "theme.SearchPage.inputPlaceholder": "Nhập từ khóa cần tìm vào đây", "theme.SearchPage.noResultsText": "Không tìm thấy kết quả nào", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "Thanh điều hướng của trang danh sách bài viết", "theme.blog.paginator.newerEntries": "Các bài mới hơn", "theme.blog.paginator.olderEntries": "Các bài cũ hơn", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "Thu gọn thanh bên", "theme.docs.sidebar.expandButtonAriaLabel": "Mở rộng thanh bên", "theme.docs.sidebar.expandButtonTitle": "Mở rộng thanh bên", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "Đóng menu", - "theme.docs.sidebar.responsiveOpenButtonLabel": "Mở menu", "theme.docs.versions.latestVersionLinkLabel": "phiên bản mới nhất", "theme.docs.versions.latestVersionSuggestionLabel": "Để xem các cập nhật mới nhất, vui lòng xem phiên bản {latestVersionLink} ({versionLabel}).", "theme.docs.versions.unmaintainedVersionLabel": "Đây là tài liệu của {siteTitle} {versionLabel}, hiện không còn được bảo trì.", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": " vào {date}", "theme.lastUpdated.byUser": " bởi {user}", "theme.lastUpdated.lastUpdatedAtBy": "Cập nhật lần cuối{atDate}{byUser}", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "Thẻ:", "theme.tags.tagsPageLink": "Xem tất cả Thẻ", "theme.tags.tagsPageTitle": "Thẻ" diff --git a/packages/docusaurus-theme-classic/codeTranslations/zh-Hans.json b/packages/docusaurus-theme-classic/codeTranslations/zh-Hans.json index d08382d82035..c3eef278b76c 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/zh-Hans.json +++ b/packages/docusaurus-theme-classic/codeTranslations/zh-Hans.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "搜索", "theme.SearchPage.inputPlaceholder": "在此输入搜索字词", "theme.SearchPage.noResultsText": "未找到任何结果", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "博文列表分页导航", "theme.blog.paginator.newerEntries": "较新的博文", "theme.blog.paginator.olderEntries": "较旧的博文", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "收起侧边栏", "theme.docs.sidebar.expandButtonAriaLabel": "展开侧边栏", "theme.docs.sidebar.expandButtonTitle": "展开侧边栏", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "关闭菜单", - "theme.docs.sidebar.responsiveOpenButtonLabel": "打开菜单", "theme.docs.versions.latestVersionLinkLabel": "最新版本", "theme.docs.versions.latestVersionSuggestionLabel": "最新的文档请参阅 {latestVersionLink} ({versionLabel})。", "theme.docs.versions.unmaintainedVersionLabel": "此为 {siteTitle} {versionLabel} 版的文档,现已不再积极维护。", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": "于 {date} ", "theme.lastUpdated.byUser": "由 {user} ", "theme.lastUpdated.lastUpdatedAtBy": "最后{byUser}{atDate}更新", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "标签:", "theme.tags.tagsPageLink": "查看所有标签", "theme.tags.tagsPageTitle": "标签" diff --git a/packages/docusaurus-theme-classic/codeTranslations/zh-Hant.json b/packages/docusaurus-theme-classic/codeTranslations/zh-Hant.json index c63cb25e17ad..fab32c446f67 100644 --- a/packages/docusaurus-theme-classic/codeTranslations/zh-Hant.json +++ b/packages/docusaurus-theme-classic/codeTranslations/zh-Hant.json @@ -20,6 +20,7 @@ "theme.SearchPage.inputLabel": "搜尋", "theme.SearchPage.inputPlaceholder": "在此輸入搜尋字詞", "theme.SearchPage.noResultsText": "未找到任何結果", + "theme.TOCCollapsible.toggleButtonLabel": "On this page", "theme.blog.paginator.navAriaLabel": "部落格文章列表分頁導覽", "theme.blog.paginator.newerEntries": "較新的文章", "theme.blog.paginator.olderEntries": "較舊的文章", @@ -41,9 +42,6 @@ "theme.docs.sidebar.collapseButtonTitle": "收起側邊欄", "theme.docs.sidebar.expandButtonAriaLabel": "展開側邊欄", "theme.docs.sidebar.expandButtonTitle": "展開側邊欄", - "theme.docs.sidebar.navAriaLabel": "Sidebar navigation", - "theme.docs.sidebar.responsiveCloseButtonLabel": "關閉選單", - "theme.docs.sidebar.responsiveOpenButtonLabel": "打開選單", "theme.docs.versions.latestVersionLinkLabel": "最新版本", "theme.docs.versions.latestVersionSuggestionLabel": "最新的文件請參閱 {latestVersionLink} ({versionLabel})。", "theme.docs.versions.unmaintainedVersionLabel": "此為 {siteTitle} {versionLabel} 版的文件,現已不再積極維護。", @@ -51,6 +49,7 @@ "theme.lastUpdated.atDate": "於 {date} ", "theme.lastUpdated.byUser": "由 {user} ", "theme.lastUpdated.lastUpdatedAtBy": "最後{byUser}{atDate}更新", + "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu", "theme.tags.tagsListLabel": "標籤:", "theme.tags.tagsPageLink": "查看所有標籤", "theme.tags.tagsPageTitle": "標籤" diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx index 929f66c7f374..075c860c0d6a 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx @@ -6,18 +6,21 @@ */ import React from 'react'; +import clsx from 'clsx'; + +import {useActivePlugin, useVersions} from '@theme/hooks/useDocs'; +import useWindowSize from '@theme/hooks/useWindowSize'; import DocPaginator from '@theme/DocPaginator'; import DocVersionBanner from '@theme/DocVersionBanner'; import Seo from '@theme/Seo'; import LastUpdated from '@theme/LastUpdated'; import type {Props} from '@theme/DocItem'; import TOC from '@theme/TOC'; +import TOCCollapsible from '@theme/TOCCollapsible'; import EditThisPage from '@theme/EditThisPage'; import {MainHeading} from '@theme/Heading'; -import clsx from 'clsx'; import styles from './styles.module.css'; -import {useActivePlugin, useVersions} from '@theme/hooks/useDocs'; function DocItem(props: Props): JSX.Element { const {content: DocContent, versionMetadata} = props; @@ -51,6 +54,18 @@ function DocItem(props: Props): JSX.Element { const shouldAddTitle = !hideTitle && typeof DocContent.contentTitle === 'undefined'; + const windowSize = useWindowSize(); + + const renderTocMobile = + !hideTableOfContents && + DocContent.toc && + (windowSize === 'mobile' || windowSize === 'ssr'); + + const renderTocDesktop = + !hideTableOfContents && + DocContent.toc && + (windowSize === 'desktop' || windowSize === 'ssr'); + return ( <> @@ -69,6 +84,13 @@ function DocItem(props: Props): JSX.Element { )} + {renderTocMobile && ( + + )} +
{/* Title can be declared inside md content or declared through frontmatter and added manually @@ -102,7 +124,7 @@ function DocItem(props: Props): JSX.Element {
- {!hideTableOfContents && DocContent.toc && ( + {renderTocDesktop && (
diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css index 781a95bf258d..c8bf66096fac 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css @@ -23,4 +23,9 @@ .lastUpdated { text-align: right; } + + /* Prevent hydration FOUC, as the mobile TOC needs to be server-rendered */ + .tocMobile { + display: none; + } } diff --git a/packages/docusaurus-theme-classic/src/theme/DocPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocPage/index.tsx index edc3f9463e94..83e38c2ac493 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocPage/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocPage/index.tsx @@ -31,28 +31,6 @@ type DocPageContentProps = { readonly children: ReactNode; }; -function getSidebar({versionMetadata, currentDocRoute}) { - function addTrailingSlash(str: string): string { - return str.endsWith('/') ? str : `${str}/`; - } - function removeTrailingSlash(str: string): string { - return str.endsWith('/') ? str.slice(0, -1) : str; - } - - const {permalinkToSidebar, docsSidebars} = versionMetadata; - - // With/without trailingSlash, we should always be able to get the appropriate sidebar - // note: docs plugin permalinks currently never have trailing slashes - // trailingSlash is handled globally at the framework level, not plugin level - const sidebarName = - permalinkToSidebar[currentDocRoute.path] || - permalinkToSidebar[addTrailingSlash(currentDocRoute.path)] || - permalinkToSidebar[removeTrailingSlash(currentDocRoute.path)]; - - const sidebar = docsSidebars[sidebarName]; - return {sidebar, sidebarName}; -} - function DocPageContent({ currentDocRoute, versionMetadata, @@ -60,7 +38,11 @@ function DocPageContent({ }: DocPageContentProps): JSX.Element { const {siteConfig, isClient} = useDocusaurusContext(); const {pluginId, version} = versionMetadata; - const {sidebarName, sidebar} = getSidebar({versionMetadata, currentDocRoute}); + + const sidebarName = currentDocRoute.sidebar; + const sidebar = sidebarName + ? versionMetadata.docsSidebars[sidebarName] + : undefined; const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false); const [hiddenSidebar, setHiddenSidebar] = useState(false); @@ -106,9 +88,7 @@ function DocPageContent({ } sidebar={sidebar} path={currentDocRoute.path} - sidebarCollapsible={ - siteConfig.themeConfig?.sidebarCollapsible ?? true - } + sidebarCollapsible={siteConfig.themeConfig.sidebarCollapsible} onCollapse={toggleSidebar} isHidden={hiddenSidebar} /> diff --git a/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css index 6d9c59153792..778a2bbbe1b0 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css @@ -20,6 +20,10 @@ width: 100%; } +.docSidebarContainer { + display: none; +} + @media (min-width: 997px) { .docMainContainer { flex-grow: 1; @@ -31,6 +35,7 @@ } .docSidebarContainer { + display: block; width: var(--doc-sidebar-width); margin-top: calc(-1 * var(--ifm-navbar-height)); border-right: 1px solid var(--ifm-toc-border-color); diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx index 01c893bca76e..33faa9cb2078 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx @@ -5,175 +5,24 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useState, useCallback, useEffect, memo} from 'react'; +import React, {useState} from 'react'; import clsx from 'clsx'; import { useThemeConfig, - isSamePath, - usePrevious, useAnnouncementBar, - useCollapsible, + MobileSecondaryMenuFiller, + MobileSecondaryMenuComponent, } from '@docusaurus/theme-common'; -import useLockBodyScroll from '@theme/hooks/useLockBodyScroll'; -import useWindowSize, {windowSizes} from '@theme/hooks/useWindowSize'; +import useWindowSize from '@theme/hooks/useWindowSize'; import useScrollPosition from '@theme/hooks/useScrollPosition'; -import Link from '@docusaurus/Link'; -import isInternalUrl from '@docusaurus/isInternalUrl'; -import type {Props} from '@theme/DocSidebar'; import Logo from '@theme/Logo'; import IconArrow from '@theme/IconArrow'; -import IconMenu from '@theme/IconMenu'; -import IconExternalLink from '@theme/IconExternalLink'; import {translate} from '@docusaurus/Translate'; +import {DocSidebarItems} from '@theme/DocSidebarItem'; +import type {Props} from '@theme/DocSidebar'; import styles from './styles.module.css'; -const MOBILE_TOGGLE_SIZE = 24; - -const isActiveSidebarItem = (item, activePath) => { - if (item.type === 'link') { - return isSamePath(item.href, activePath); - } - if (item.type === 'category') { - return item.items.some((subItem) => - isActiveSidebarItem(subItem, activePath), - ); - } - return false; -}; - -// Optimize sidebar at each "level" -// TODO this item should probably not receive the "activePath" props -// TODO this triggers whole sidebar re-renders on navigation -const DocSidebarItems = memo(function DocSidebarItems({ - items, - ...props -}: any): JSX.Element { - return items.map((item, index) => ( - - )); -}); - -function DocSidebarItem(props): JSX.Element | null { - switch (props.item.type) { - case 'category': - // Never render empty categories - if (props.item.items.length === 0) { - return null; - } - return ; - case 'link': - default: - return ; - } -} - -function DocSidebarItemCategory({ - item, - onItemClick, - collapsible, - activePath, - ...props -}) { - const {items, label} = item; - - const isActive = isActiveSidebarItem(item, activePath); - const wasActive = usePrevious(isActive); - - const { - collapsed, - setCollapsed, - getToggleProps, - getCollapsibleProps, - } = useCollapsible({ - // active categories are always initialized as expanded - // the default (item.collapsed) is only used for non-active categories - initialState: () => { - if (!collapsible) { - return false; - } - return isActive ? false : item.collapsed; - }, - }); - - // If we navigate to a category, it should automatically expand itself - useEffect(() => { - const justBecameActive = isActive && !wasActive; - if (justBecameActive && collapsed) { - setCollapsed(false); - } - }, [isActive, wasActive, collapsed]); - - return ( -
  • - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - {label} - - -
      - -
    -
  • - ); -} - -function DocSidebarItemLink({ - item, - onItemClick, - activePath, - collapsible: _collapsible, - ...props -}) { - const {href, label} = item; - const isActive = isActiveSidebarItem(item, activePath); - return ( -
  • - - {isInternalUrl(href) ? ( - label - ) : ( - - {label} - - - )} - -
  • - ); -} - function useShowAnnouncementBar() { const {isClosed} = useAnnouncementBar(); const [showAnnouncementBar, setShowAnnouncementBar] = useState(!isClosed); @@ -185,36 +34,6 @@ function useShowAnnouncementBar() { return showAnnouncementBar; } -function useResponsiveSidebar() { - const [showResponsiveSidebar, setShowResponsiveSidebar] = useState(false); - useLockBodyScroll(showResponsiveSidebar); - - const windowSize = useWindowSize(); - useEffect(() => { - if (windowSize === windowSizes.desktop) { - setShowResponsiveSidebar(false); - } - }, [windowSize]); - - const closeResponsiveSidebar = useCallback( - (e) => { - e.target.blur(); - setShowResponsiveSidebar(false); - }, - [setShowResponsiveSidebar], - ); - - const toggleResponsiveSidebar = useCallback(() => { - setShowResponsiveSidebar((value) => !value); - }, [setShowResponsiveSidebar]); - - return { - showResponsiveSidebar, - closeResponsiveSidebar, - toggleResponsiveSidebar, - }; -} - function HideableSidebarButton({onClick}) { return ( - ); -} - -function DocSidebar({ +function DocSidebarDesktop({ path, sidebar, - sidebarCollapsible = true, + sidebarCollapsible, onCollapse, isHidden, -}: Props): JSX.Element | null { +}: Props) { const showAnnouncementBar = useShowAnnouncementBar(); const { navbar: {hideOnScroll}, @@ -291,12 +72,6 @@ function DocSidebar({ } = useThemeConfig(); const {isClosed: isAnnouncementBarClosed} = useAnnouncementBar(); - const { - showResponsiveSidebar, - closeResponsiveSidebar, - toggleResponsiveSidebar, - } = useResponsiveSidebar(); - return (
    {hideOnScroll && } ); } diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/styles.module.css b/packages/docusaurus-theme-classic/src/theme/Navbar/styles.module.css index 9e4ab9b4ecaa..43ade4b969d4 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/styles.module.css @@ -18,3 +18,47 @@ .navbarHidden { transform: translate3d(0, calc(-100% - 2px), 0); } + +:global(.navbar-sidebar__items) { + padding: 0; +} + +:global(.navbar-sidebar) { + overflow-x: hidden; +} + +.menuWrapper { + display: flex; + width: calc(var(--ifm-navbar-sidebar-width)); + transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1); + transform: translateZ(0) !important; +} + +.menuWrapperDocShown { + transform: translate3d( + calc((var(--ifm-navbar-sidebar-width)) * -1), + 0, + 0 + ) !important; +} + +.menuWrapper > div { + flex-shrink: 0; + width: calc(var(--ifm-navbar-sidebar-width)); + font-weight: var(--ifm-font-weight-semibold); + padding: 0.5rem; +} + +.backButton { + width: calc(100% + 1rem); + margin: 0 0 0.7rem -0.5rem; + text-align: left; + font-size: 15px; + padding: 0.6rem 1.5rem; + background: var(--ifm-menu-color-background-active); + font-weight: var(--ifm-button-font-weight); +} + +.docSidebarSecondaryMenu { + padding-top: 0 !important; +} diff --git a/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx b/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx index 831c26b10e9b..83a6c0f7841a 100644 --- a/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx @@ -8,22 +8,15 @@ import React from 'react'; import clsx from 'clsx'; import useTOCHighlight from '@theme/hooks/useTOCHighlight'; -import type {TOCProps} from '@theme/TOC'; +import type {TOCProps, TOCHeadingsProps} from '@theme/TOC'; import styles from './styles.module.css'; -import {TOCItem} from '@docusaurus/types'; const LINK_CLASS_NAME = 'table-of-contents__link'; const ACTIVE_LINK_CLASS_NAME = 'table-of-contents__link--active'; const TOP_OFFSET = 100; /* eslint-disable jsx-a11y/control-has-associated-label */ -function Headings({ - toc, - isChild, -}: { - toc: readonly TOCItem[]; - isChild?: boolean; -}) { +export function TOCHeadings({toc, isChild}: TOCHeadingsProps) { if (!toc.length) { return null; } @@ -41,7 +34,7 @@ function Headings({ // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{__html: heading.value}} /> - + ))} @@ -52,7 +45,7 @@ function TOC({toc}: TOCProps): JSX.Element { useTOCHighlight(LINK_CLASS_NAME, ACTIVE_LINK_CLASS_NAME, TOP_OFFSET); return (
    - +
    ); } diff --git a/packages/docusaurus-theme-classic/src/theme/TOCCollapsible/index.tsx b/packages/docusaurus-theme-classic/src/theme/TOCCollapsible/index.tsx new file mode 100644 index 000000000000..d5904845357c --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/TOCCollapsible/index.tsx @@ -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 from 'react'; +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import {useCollapsible, Collapsible} from '@docusaurus/theme-common'; +import styles from './styles.module.css'; +import {TOCHeadings} from '@theme/TOC'; +import type {TOCCollapsibleProps} from '@theme/TOCCollapsible'; + +export default function TOCCollapsible({toc, className}: TOCCollapsibleProps) { + const {collapsed, toggleCollapsed} = useCollapsible({ + initialState: true, + }); + + return ( +
    + + + + + +
    + ); +} diff --git a/packages/docusaurus-theme-classic/src/theme/TOCCollapsible/styles.module.css b/packages/docusaurus-theme-classic/src/theme/TOCCollapsible/styles.module.css new file mode 100644 index 000000000000..19034bcda7d8 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/TOCCollapsible/styles.module.css @@ -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. + */ + +.tocCollapsible { + background-color: var(--ifm-menu-color-background-active); + border-radius: var(--ifm-global-radius); +} + +.tocCollapsibleButton { + font-size: inherit; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.4rem 0.8rem; + width: 100%; +} + +.tocCollapsibleButton:after { + content: ''; + background: var(--ifm-menu-link-sublist-icon) 50% 50% / 2rem 2rem no-repeat; + filter: var(--ifm-menu-link-sublist-icon-filter); + height: 1.25rem; + width: 1.25rem; + transform: rotate(180deg); + transition: transform var(--ifm-transition-fast); +} + +.tocCollapsibleContent > ul { + border-left: none; + border-top: 1px solid var(--ifm-color-emphasis-300); + padding: 0.2rem 0; + font-size: 15px; +} + +.tocCollapsibleContent ul li { + margin: 0.4rem 0.8rem; +} + +.tocCollapsibleContent a { + display: block; +} + +.tocCollapsibleExpanded .tocCollapsibleButton:after { + transform: none; +} diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts index 6c899431cc95..3447e7a1be0c 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts @@ -10,42 +10,65 @@ import {useEffect, useState} from 'react'; import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; import type {WindowSize} from '@theme/hooks/useWindowSize'; -const desktopThresholdWidth = 996; - const windowSizes = { desktop: 'desktop', mobile: 'mobile', + + // This "ssr" value is very important to handle hydration FOUC / layout shifts + // You have to handle server-rendering explicitly on the call-site + // On the server, you may need to render BOTH the mobile/desktop elements (and hide one of them with mediaquery) + // We don't return "undefined" on purpose, to make it more explicit + ssr: 'ssr', } as const; -function useWindowSize(): WindowSize | undefined { - const isClient = ExecutionEnvironment.canUseDOM; +const DesktopThresholdWidth = 996; - function getSize() { - if (!isClient) { - return undefined; - } - return window.innerWidth > desktopThresholdWidth - ? windowSizes.desktop - : windowSizes.mobile; +function getWindowSize() { + if (!ExecutionEnvironment.canUseDOM) { + return windowSizes.ssr; } + return window.innerWidth > DesktopThresholdWidth + ? windowSizes.desktop + : windowSizes.mobile; +} - const [windowSize, setWindowSize] = useState(getSize); +// Simulate the SSR window size in dev, so that potential hydration FOUC/layout shift problems can be seen in dev too! +const DevSimulateSSR = process.env.NODE_ENV === 'development' && true; + +// This hook returns an enum value on purpose! +// We don't want it to return the actual width value, for resize perf reasons +// We only want to re-render once a breakpoint is crossed +function useWindowSize(): WindowSize { + const [windowSize, setWindowSize] = useState(() => { + if (DevSimulateSSR) { + return 'ssr'; + } + return getWindowSize(); + }); useEffect(() => { - if (!isClient) { + if (!ExecutionEnvironment.canUseDOM) { return undefined; } - function handleResize() { - setWindowSize(getSize()); + function updateWindowSize() { + setWindowSize(getWindowSize()); } - window.addEventListener('resize', handleResize); - return () => window.removeEventListener('resize', handleResize); + // @ts-expect-error: annoying TS setTimeout typing... + const timeout: number | undefined = DevSimulateSSR + ? setTimeout(updateWindowSize, 1000) + : undefined; + + window.addEventListener('resize', updateWindowSize); + + return () => { + window.removeEventListener('resize', updateWindowSize); + clearTimeout(timeout); + }; }, []); return windowSize; } -export {windowSizes}; export default useWindowSize; diff --git a/packages/docusaurus-theme-classic/src/types.d.ts b/packages/docusaurus-theme-classic/src/types.d.ts index f04abccf1be6..b78ecfa17503 100644 --- a/packages/docusaurus-theme-classic/src/types.d.ts +++ b/packages/docusaurus-theme-classic/src/types.d.ts @@ -88,6 +88,28 @@ declare module '@theme/DocSidebar' { export default DocSidebar; } +declare module '@theme/DocSidebarItem' { + import type {PropSidebarItem} from '@docusaurus/plugin-content-docs-types'; + + type DocSidebarPropsBase = { + readonly activePath: string; + readonly collapsible?: boolean; + readonly onItemClick?: () => void; + readonly tabIndex?: number; + }; + + export type Props = DocSidebarPropsBase & { + readonly item: PropSidebarItem; + }; + const DocSidebarItem: (props: Props) => JSX.Element; + export default DocSidebarItem; + + export type DocSidebarItemsProps = DocSidebarPropsBase & { + readonly items: readonly PropSidebarItem[]; + }; + export const DocSidebarItems: (props: DocSidebarItemsProps) => JSX.Element; +} + declare module '@theme/DocVersionSuggestions' { const DocVersionSuggestions: () => JSX.Element; export default DocVersionSuggestions; @@ -213,11 +235,12 @@ declare module '@theme/hooks/useWindowSize' { export const windowSizes: { desktop: 'desktop'; mobile: 'mobile'; + ssr: 'ssr'; }; export type WindowSize = keyof typeof windowSizes; - export default function useWindowSize(): WindowSize | undefined; + export default function useWindowSize(): WindowSize; } declare module '@theme/hooks/useKeyboardNavigation' { @@ -476,6 +499,13 @@ declare module '@theme/TOC' { readonly toc: readonly TOCItem[]; }; + export type TOCHeadingsProps = { + readonly toc: readonly TOCItem[]; + readonly isChild?: boolean; + }; + + export const TOCHeadings: (props: HeadingsProps) => JSX.Element; + const TOC: (props: TOCProps) => JSX.Element; export default TOC; } @@ -491,6 +521,18 @@ declare module '@theme/TOCInline' { export default TOCInline; } +declare module '@theme/TOCCollapsible' { + import type {TOCItem} from '@docusaurus/types'; + + export type TOCCollapsibleProps = { + readonly className?: string; + readonly toc: readonly TOCItem[]; + }; + + const TOCCollapsible: (props: TOCCollapsibleProps) => JSX.Element; + export default TOCCollapsible; +} + declare module '@theme/Toggle' { import type {SyntheticEvent} from 'react'; diff --git a/packages/docusaurus-theme-classic/src/validateThemeConfig.js b/packages/docusaurus-theme-classic/src/validateThemeConfig.js index 2f339e23d249..12b9a36ed6f0 100644 --- a/packages/docusaurus-theme-classic/src/validateThemeConfig.js +++ b/packages/docusaurus-theme-classic/src/validateThemeConfig.js @@ -40,6 +40,7 @@ const DEFAULT_CONFIG = { items: [], }, hideableSidebar: false, + sidebarCollapsible: true, }; exports.DEFAULT_CONFIG = DEFAULT_CONFIG; @@ -309,6 +310,7 @@ const ThemeConfigSchema = Joi.object({ .default(DEFAULT_CONFIG.prism) .unknown(), hideableSidebar: Joi.bool().default(DEFAULT_CONFIG.hideableSidebar), + sidebarCollapsible: Joi.bool().default(DEFAULT_CONFIG.sidebarCollapsible), }); exports.ThemeConfigSchema = ThemeConfigSchema; diff --git a/packages/docusaurus-theme-classic/update-code-translations.js b/packages/docusaurus-theme-classic/update-code-translations.js index bbd76fcf224e..ce3a95a1fdcf 100644 --- a/packages/docusaurus-theme-classic/update-code-translations.js +++ b/packages/docusaurus-theme-classic/update-code-translations.js @@ -149,10 +149,12 @@ ${logKeys(unknownMessages)}`), const newBaseMessagesDescriptions = Object.entries(newBaseMessages).reduce( (acc, [key]) => { + const codeTranslation = codeExtractedTranslations[key]; return { ...acc, - [`${key}${DescriptionSuffix}`]: codeExtractedTranslations[key] - .description, + [`${key}${DescriptionSuffix}`]: codeTranslation + ? codeTranslation.description + : undefined, }; }, {}, diff --git a/packages/docusaurus-theme-common/src/index.ts b/packages/docusaurus-theme-common/src/index.ts index 65b2211501c5..32010abaff62 100644 --- a/packages/docusaurus-theme-common/src/index.ts +++ b/packages/docusaurus-theme-common/src/index.ts @@ -37,12 +37,19 @@ export {useLocationChange} from './utils/useLocationChange'; export {usePrevious} from './utils/usePrevious'; -export {useCollapsible} from './utils/useCollapsible'; +export {useCollapsible, Collapsible} from './utils/useCollapsible'; export type { UseCollapsibleConfig, UseCollapsibleReturns, } from './utils/useCollapsible'; +export { + MobileSecondaryMenuProvider, + MobileSecondaryMenuFiller, + useMobileSecondaryMenuRenderer, +} from './utils/mobileSecondaryMenu'; +export type {MobileSecondaryMenuComponent} from './utils/mobileSecondaryMenu'; + export { useDocsPreferredVersion, useDocsPreferredVersionByPluginId, diff --git a/packages/docusaurus-theme-common/src/utils/mobileSecondaryMenu.tsx b/packages/docusaurus-theme-common/src/utils/mobileSecondaryMenu.tsx new file mode 100644 index 000000000000..db429854f621 --- /dev/null +++ b/packages/docusaurus-theme-common/src/utils/mobileSecondaryMenu.tsx @@ -0,0 +1,111 @@ +/** + * 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, { + useState, + ReactNode, + useContext, + createContext, + useEffect, + ComponentType, + useMemo, +} from 'react'; + +/* +The idea behind all this is that a specific component must be able to fill a placeholder in the generic layout +The doc page should be able to fill the secondary menu of the main mobile navbar. +This permits to reduce coupling between the main layout and the specific page. + +This kind of feature is often called portal/teleport/gateway... various unmaintained React libs exist +Most up-to-date one: https://github.com/gregberge/react-teleporter +Not sure any of those is safe regarding concurrent mode. + */ + +type ExtraProps = { + toggleSidebar: () => void; +}; + +export type MobileSecondaryMenuComponent = ComponentType< + Props & ExtraProps +>; + +type State = { + component: MobileSecondaryMenuComponent; + props: unknown; +} | null; + +function useContextValue() { + return useState(null); +} + +type ContextValue = ReturnType; + +const Context = createContext(null); + +export function MobileSecondaryMenuProvider({children}: {children: ReactNode}) { + return ( + {children} + ); +} + +function useMobileSecondaryMenuContext(): ContextValue { + const value = useContext(Context); + if (value === null) { + throw new Error( + 'MobileSecondaryMenuProvider was not used correctly, context value is null', + ); + } + return value; +} + +export function useMobileSecondaryMenuRenderer(): ( + extraProps: ExtraProps, +) => ReactNode | undefined { + const [state] = useMobileSecondaryMenuContext(); + if (state) { + const Comp = state.component; + return function render(extraProps) { + return ; + }; + } + return () => undefined; +} + +function useShallowMemoizedObject>(obj: O) { + return useMemo( + () => obj, + // Is this safe? + [...Object.keys(obj), ...Object.values(obj)], + ); +} + +// Fill the secondary menu placeholder with some real content +export function MobileSecondaryMenuFiller< + Props extends Record +>({ + component, + props, +}: { + component: MobileSecondaryMenuComponent; + props: Props; +}): JSX.Element | null { + const [, setState] = useMobileSecondaryMenuContext(); + + // To avoid useless context re-renders, props are memoized shallowly + const memoizedProps = useShallowMemoizedObject(props); + + useEffect(() => { + // @ts-expect-error: context is not 100% typesafe but it's ok + setState({component, props: memoizedProps}); + }, [setState, component, memoizedProps]); + + useEffect(() => { + return () => setState(null); + }, [setState]); + + return null; +} diff --git a/packages/docusaurus-theme-common/src/utils/useCollapsible.ts b/packages/docusaurus-theme-common/src/utils/useCollapsible.tsx similarity index 79% rename from packages/docusaurus-theme-common/src/utils/useCollapsible.ts rename to packages/docusaurus-theme-common/src/utils/useCollapsible.tsx index 4a6f1f416885..1dc8556a7352 100644 --- a/packages/docusaurus-theme-common/src/utils/useCollapsible.ts +++ b/packages/docusaurus-theme-common/src/utils/useCollapsible.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import { +import React, { useState, useEffect, useRef, @@ -13,45 +13,37 @@ import { RefObject, Dispatch, SetStateAction, - TransitionEvent, + ReactNode, } from 'react'; -/* -Lex111: Dynamic transition duration is used in Material deisign, this technique is good for a large number of items. -https://material.io/archive/guidelines/motion/duration-easing.html#duration-easing-dynamic-durations -https://github.com/mui-org/material-ui/blob/e724d98eba018e55e1a684236a2037e24bcf050c/packages/material-ui/src/styles/createTransitions.js#L40-L43 - */ -function getAutoHeightDuration(height: number) { - const constant = height / 36; - return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10); -} - -type CollapsibleAnimationConfig = { - duration?: number; - easing?: string; -}; - const DefaultAnimationEasing = 'ease-in-out'; export type UseCollapsibleConfig = { initialState: boolean | (() => boolean); - animation?: CollapsibleAnimationConfig; }; export type UseCollapsibleReturns = { collapsed: boolean; setCollapsed: Dispatch>; toggleCollapsed: () => void; +}; - getToggleProps(): { - onClick?: () => void; - }; +// This hook just define the state +export function useCollapsible({ + initialState, +}: UseCollapsibleConfig): UseCollapsibleReturns { + const [collapsed, setCollapsed] = useState(initialState ?? false); - getCollapsibleProps(): { - ref: RefObject; // any because TS is a pain for HTML element refs, see https://twitter.com/sebastienlorber/status/1412784677795110914 - onTransitionEnd: (e: TransitionEvent) => void; + const toggleCollapsed = useCallback(() => { + setCollapsed((expanded) => !expanded); + }, []); + + return { + collapsed, + setCollapsed, + toggleCollapsed, }; -}; +} const CollapsedStyles = { display: 'none', @@ -72,6 +64,21 @@ function applyCollapsedStyle(el: HTMLElement, collapsed: boolean) { el.style.height = collapsedStyles.height; } +/* +Lex111: Dynamic transition duration is used in Material design, this technique is good for a large number of items. +https://material.io/archive/guidelines/motion/duration-easing.html#duration-easing-dynamic-durations +https://github.com/mui-org/material-ui/blob/e724d98eba018e55e1a684236a2037e24bcf050c/packages/material-ui/src/styles/createTransitions.js#L40-L43 + */ +function getAutoHeightDuration(height: number) { + const constant = height / 36; + return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10); +} + +type CollapsibleAnimationConfig = { + duration?: number; + easing?: string; +}; + function useCollapseAnimation({ collapsibleRef, collapsed, @@ -135,41 +142,39 @@ function useCollapseAnimation({ }, [collapsibleRef, collapsed, animation]); } -/* -This hook encapsulate the animated collapsible behavior -You have to apply the getToggleProps + getCollapsibleProps wire everything -Similar to other solutions in the React ecosystem, like Downshift for Selects - */ -export function useCollapsible({ - initialState, - animation, -}: UseCollapsibleConfig): UseCollapsibleReturns { - const collapsibleRef = useRef(null); - - const [collapsed, setCollapsed] = useState(initialState ?? false); +type CollapsibleElementType = React.ElementType< + Pick, 'className' | 'onTransitionEnd'> +>; - const toggleCollapsed = useCallback(() => { - setCollapsed((expanded) => !expanded); - }, []); +export function Collapsible({ + as: As = 'div', + collapsed, + children, + animation, + className, +}: { + as?: CollapsibleElementType; // TODO better typing, allow any html element (keyof JSX.IntrinsicElement => not working) + collapsed: boolean; + children: ReactNode; + animation?: CollapsibleAnimationConfig; + className?: string; +}) { + // any because TS is a pain for HTML element refs, see https://twitter.com/sebastienlorber/status/1412784677795110914 + const collapsibleRef = useRef(null); useCollapseAnimation({collapsibleRef, collapsed, animation}); - return { - collapsed, - setCollapsed, - toggleCollapsed, - - getToggleProps: () => ({ - onClick: toggleCollapsed, - }), - - getCollapsibleProps: () => ({ - ref: collapsibleRef, - onTransitionEnd: (e) => { + return ( + { if (e.propertyName === 'height') { applyCollapsedStyle(collapsibleRef.current!, collapsed); } - }, - }), - }; + }} + className={className}> + {children} + + ); } diff --git a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts index 375879d67ef7..b33fa2872d51 100644 --- a/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts +++ b/packages/docusaurus-theme-common/src/utils/useThemeConfig.ts @@ -103,6 +103,7 @@ export type ThemeConfig = { hideableSidebar: boolean; image: string; metadatas: Array>; + sidebarCollapsible: boolean; }; export function useThemeConfig(): ThemeConfig { diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 72ad60f8ecdf..55d57eb18705 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -346,6 +346,7 @@ export interface RouteConfig { routes?: RouteConfig[]; exact?: boolean; priority?: number; + [propName: string]: any; } // Aliases used for Webpack resolution (when using docusaurus swizzle) diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap index bf1e81a3116b..03623c65b4f1 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap @@ -38,16 +38,17 @@ Object { "routesConfig": " import React from 'react'; import ComponentCreator from '@docusaurus/ComponentCreator'; + export default [ -{ - path: '/blog', - component: ComponentCreator('/blog','94e'), - exact: true, -}, -{ - path: '*', - component: ComponentCreator('*') -} + { + path: '/blog', + component: ComponentCreator('/blog','94e'), + exact: true + }, + { + path: '*', + component: ComponentCreator('*') + } ]; ", "routesPaths": Array [ @@ -90,16 +91,16 @@ Object { }, }, "routesChunkNames": Object { - "/docs/hello-f94": Object { + "/docs/hello-44b": Object { "component": "component---theme-doc-item-178-a40", "content": "content---docs-helloaff-811", "metadata": "metadata---docs-hello-956-741", }, - "/docs:route-838": Object { + "/docs:route-63b": Object { "component": "component---theme-doc-page-1-be-9be", "docsMetadata": "docsMetadata---docs-routef-34-881", }, - "docs/foo/baz-f88": Object { + "docs/foo/baz-ac2": Object { "component": "component---theme-doc-item-178-a40", "content": "content---docs-foo-baz-8-ce-61e", "metadata": "metadata---docs-foo-baz-2-cf-fa7", @@ -108,28 +109,29 @@ Object { "routesConfig": " import React from 'react'; import ComponentCreator from '@docusaurus/ComponentCreator'; + export default [ -{ - path: '/docs:route', - component: ComponentCreator('/docs:route','838'), - - routes: [ -{ - path: '/docs/hello', - component: ComponentCreator('/docs/hello','f94'), - exact: true, -}, -{ - path: 'docs/foo/baz', - component: ComponentCreator('docs/foo/baz','f88'), - -}, -] -}, -{ - path: '*', - component: ComponentCreator('*') -} + { + path: '/docs:route', + component: ComponentCreator('/docs:route','63b'), + routes: [ + { + path: '/docs/hello', + component: ComponentCreator('/docs/hello','44b'), + exact: true, + 'sidebar': \\"main\\" + }, + { + path: 'docs/foo/baz', + component: ComponentCreator('docs/foo/baz','ac2'), + 'sidebar': \\"secondary\\" + } + ] + }, + { + path: '*', + component: ComponentCreator('*') + } ]; ", "routesPaths": Array [ @@ -156,16 +158,16 @@ Object { "routesConfig": " import React from 'react'; import ComponentCreator from '@docusaurus/ComponentCreator'; + export default [ -{ - path: '', - component: ComponentCreator('','b2a'), - -}, -{ - path: '*', - component: ComponentCreator('*') -} + { + path: '', + component: ComponentCreator('','b2a') + }, + { + path: '*', + component: ComponentCreator('*') + } ]; ", "routesPaths": Array [ diff --git a/packages/docusaurus/src/server/__tests__/routes.test.ts b/packages/docusaurus/src/server/__tests__/routes.test.ts index 881db5c4ae33..24f5e51b3c09 100644 --- a/packages/docusaurus/src/server/__tests__/routes.test.ts +++ b/packages/docusaurus/src/server/__tests__/routes.test.ts @@ -25,6 +25,7 @@ describe('loadRoutes', () => { content: 'docs/hello.md', metadata: 'docs-hello-da2.json', }, + sidebar: 'main', }, { path: 'docs/foo/baz', @@ -33,6 +34,7 @@ describe('loadRoutes', () => { content: 'docs/foo/baz.md', metadata: 'docs-foo-baz-dd9.json', }, + sidebar: 'secondary', }, ], }; diff --git a/packages/docusaurus/src/server/routes.ts b/packages/docusaurus/src/server/routes.ts index 904be52f724a..18e96d7ddfe2 100644 --- a/packages/docusaurus/src/server/routes.ts +++ b/packages/docusaurus/src/server/routes.ts @@ -21,30 +21,52 @@ import { ChunkNames, } from '@docusaurus/types'; +function indent(str: string) { + const spaces = ' '; + return `${spaces}${str.replace(/(\n)/g, `\n${spaces}`)}`; +} + const createRouteCodeString = ({ routePath, routeHash, exact, subroutesCodeStrings, + props, }: { routePath: string; routeHash: string; exact?: boolean; subroutesCodeStrings?: string[]; + props: {[propName: string]: any}; }) => { - const str = `{ - path: '${routePath}', - component: ComponentCreator('${routePath}','${routeHash}'), - ${exact ? `exact: true,` : ''} -${ - subroutesCodeStrings - ? ` routes: [ -${removeSuffix(subroutesCodeStrings.join(',\n'), ',\n')}, -] -` - : '' -}}`; - return str; + const parts = [ + `path: '${routePath}'`, + `component: ComponentCreator('${routePath}','${routeHash}')`, + ]; + + if (exact) { + parts.push(`exact: true`); + } + + if (subroutesCodeStrings) { + parts.push( + `routes: [ +${indent(removeSuffix(subroutesCodeStrings.join(',\n'), ',\n'))} +]`, + ); + } + + Object.entries(props).forEach(([propName, propValue]) => { + // Figure out how to "unquote" JS attributes that don't need to be quoted + // Is this lib reliable? https://github.com/armanozak/should-quote + const shouldQuote = true; // TODO + const key = shouldQuote ? `'${propName}'` : propName; + parts.push(`${key}: ${JSON.stringify(propValue)}`); + }); + + return `{ +${indent(parts.join(',\n'))} +}`; }; const NotFoundRouteCode = `{ @@ -106,6 +128,9 @@ export default async function loadRoutes( modules = {}, routes: subroutes, exact, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + priority, + ...props } = routeConfig; if (!isString(routePath) || !component) { @@ -138,15 +163,18 @@ export default async function loadRoutes( routeHash, exact, subroutesCodeStrings: subroutes?.map(generateRouteCode), + props, }); } const routesConfig = ` ${RoutesImportsCode} + export default [ -${pluginsRouteConfigs.map(generateRouteCode).join(',\n')}, -${NotFoundRouteCode} -];\n`; +${indent(`${pluginsRouteConfigs.map(generateRouteCode).join(',\n')},`)} +${indent(NotFoundRouteCode)} +]; +`; return { registry, diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index a335176e7eae..9b21a0e158bd 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -310,6 +310,7 @@ const isVersioningDisabled = !!process.env.DISABLE_VERSIONING || isI18nStaging; liveCodeBlock: { playgroundPosition: 'bottom', }, + sidebarCollapsible: true, hideableSidebar: true, colorMode: { defaultMode: 'light',