From 14566e7e816e589c24fdc62d17484a06d7fcee5f Mon Sep 17 00:00:00 2001 From: Andre Angelantoni Date: Thu, 26 Sep 2024 14:26:40 -0600 Subject: [PATCH] 5623: Add HeroDevs support banners to specfic pages. --- docusaurus.config.js | 1 + src/theme/DocPage/Layout/Main/index.js | 23 ++++ .../DocPage/Layout/Main/styles.module.css | 19 +++ .../Layout/Sidebar/ExpandButton/index.js | 26 ++++ .../Sidebar/ExpandButton/styles.module.css | 27 ++++ src/theme/DocPage/Layout/Sidebar/index.js | 53 ++++++++ .../DocPage/Layout/Sidebar/styles.module.css | 32 +++++ src/theme/DocPage/Layout/index.js | 26 ++++ src/theme/DocPage/Layout/styles.module.css | 18 +++ src/theme/DocPage/index.js | 110 +++++++++++++++ src/theme/DocVersionBanner/index.js | 126 ++++++++++++++++++ 11 files changed, 461 insertions(+) create mode 100644 src/theme/DocPage/Layout/Main/index.js create mode 100644 src/theme/DocPage/Layout/Main/styles.module.css create mode 100644 src/theme/DocPage/Layout/Sidebar/ExpandButton/index.js create mode 100644 src/theme/DocPage/Layout/Sidebar/ExpandButton/styles.module.css create mode 100644 src/theme/DocPage/Layout/Sidebar/index.js create mode 100644 src/theme/DocPage/Layout/Sidebar/styles.module.css create mode 100644 src/theme/DocPage/Layout/index.js create mode 100644 src/theme/DocPage/Layout/styles.module.css create mode 100644 src/theme/DocPage/index.js create mode 100644 src/theme/DocVersionBanner/index.js diff --git a/docusaurus.config.js b/docusaurus.config.js index 4005b47c..d8d364d6 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -121,6 +121,7 @@ const config = { { to: '/organisations', label: 'Adopters', position: 'left' }, { to: '/contribute', label: 'Contribute', position: 'left' }, { to: '/resources', label: 'Resources', position: 'left' }, + { to: '/docs/latest/Reference/LTS', label: 'Support', position: 'left' }, { type: 'docsVersionDropdown', position: 'right', diff --git a/src/theme/DocPage/Layout/Main/index.js b/src/theme/DocPage/Layout/Main/index.js new file mode 100644 index 00000000..65704fd0 --- /dev/null +++ b/src/theme/DocPage/Layout/Main/index.js @@ -0,0 +1,23 @@ +import React from 'react' +import clsx from 'clsx' +import { useDocsSidebar } from '@docusaurus/theme-common/internal' +import styles from './styles.module.css' +export default function DocPageLayoutMain({ hiddenSidebarContainer, children }) { + const sidebar = useDocsSidebar() + return ( +
+
+ {children} +
+
+ ) +} diff --git a/src/theme/DocPage/Layout/Main/styles.module.css b/src/theme/DocPage/Layout/Main/styles.module.css new file mode 100644 index 00000000..b0319384 --- /dev/null +++ b/src/theme/DocPage/Layout/Main/styles.module.css @@ -0,0 +1,19 @@ +.docMainContainer { + display: flex; + width: 100%; +} + +@media (min-width: 997px) { + .docMainContainer { + flex-grow: 1; + max-width: calc(100% - var(--doc-sidebar-width)); + } + + .docMainContainerEnhanced { + max-width: calc(100% - var(--doc-sidebar-hidden-width)); + } + + .docItemWrapperEnhanced { + max-width: calc(var(--ifm-container-width) + var(--doc-sidebar-width)) !important; + } +} diff --git a/src/theme/DocPage/Layout/Sidebar/ExpandButton/index.js b/src/theme/DocPage/Layout/Sidebar/ExpandButton/index.js new file mode 100644 index 00000000..932fb431 --- /dev/null +++ b/src/theme/DocPage/Layout/Sidebar/ExpandButton/index.js @@ -0,0 +1,26 @@ +import React from 'react' +import { translate } from '@docusaurus/Translate' +import IconArrow from '@theme/Icon/Arrow' +import styles from './styles.module.css' +export default function DocPageLayoutSidebarExpandButton({ toggleSidebar }) { + return ( +
+ +
+ ) +} diff --git a/src/theme/DocPage/Layout/Sidebar/ExpandButton/styles.module.css b/src/theme/DocPage/Layout/Sidebar/ExpandButton/styles.module.css new file mode 100644 index 00000000..f4cd944d --- /dev/null +++ b/src/theme/DocPage/Layout/Sidebar/ExpandButton/styles.module.css @@ -0,0 +1,27 @@ +@media (min-width: 997px) { + .expandButton { + position: absolute; + top: 0; + right: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + transition: background-color var(--ifm-transition-fast) ease; + background-color: var(--docusaurus-collapse-button-bg); + } + + .expandButton:hover, + .expandButton:focus { + background-color: var(--docusaurus-collapse-button-bg-hover); + } + + .expandButtonIcon { + transform: rotate(0); + } + + [dir='rtl'] .expandButtonIcon { + transform: rotate(180deg); + } +} diff --git a/src/theme/DocPage/Layout/Sidebar/index.js b/src/theme/DocPage/Layout/Sidebar/index.js new file mode 100644 index 00000000..53f3e8b7 --- /dev/null +++ b/src/theme/DocPage/Layout/Sidebar/index.js @@ -0,0 +1,53 @@ +import React, { useState, useCallback } from 'react' +import clsx from 'clsx' +import { prefersReducedMotion, ThemeClassNames } from '@docusaurus/theme-common' +import { useDocsSidebar } from '@docusaurus/theme-common/internal' +import { useLocation } from '@docusaurus/router' +import DocSidebar from '@theme/DocSidebar' +import ExpandButton from '@theme/DocPage/Layout/Sidebar/ExpandButton' +import styles from './styles.module.css' +// Reset sidebar state when sidebar changes +// Use React key to unmount/remount the children +// See https://github.com/facebook/docusaurus/issues/3414 +function ResetOnSidebarChange({ children }) { + const sidebar = useDocsSidebar() + return {children} +} +export default function DocPageLayoutSidebar({ sidebar, hiddenSidebarContainer, setHiddenSidebarContainer }) { + const { pathname } = useLocation() + const [hiddenSidebar, setHiddenSidebar] = useState(false) + const toggleSidebar = useCallback(() => { + if (hiddenSidebar) { + setHiddenSidebar(false) + } + // onTransitionEnd won't fire when sidebar animation is disabled + // fixes https://github.com/facebook/docusaurus/issues/8918 + if (!hiddenSidebar && prefersReducedMotion()) { + setHiddenSidebar(true) + } + setHiddenSidebarContainer((value) => !value) + }, [setHiddenSidebarContainer, hiddenSidebar]) + return ( + + ) +} diff --git a/src/theme/DocPage/Layout/Sidebar/styles.module.css b/src/theme/DocPage/Layout/Sidebar/styles.module.css new file mode 100644 index 00000000..221aabf5 --- /dev/null +++ b/src/theme/DocPage/Layout/Sidebar/styles.module.css @@ -0,0 +1,32 @@ +:root { + --doc-sidebar-width: 300px; + --doc-sidebar-hidden-width: 30px; +} + +.docSidebarContainer { + display: none; +} + +@media (min-width: 997px) { + .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); + will-change: width; + transition: width var(--ifm-transition-fast) ease; + clip-path: inset(0); + } + + .docSidebarContainerHidden { + width: var(--doc-sidebar-hidden-width); + cursor: pointer; + } + + .sidebarViewport { + top: 0; + position: sticky; + height: 100%; + max-height: 100vh; + } +} diff --git a/src/theme/DocPage/Layout/index.js b/src/theme/DocPage/Layout/index.js new file mode 100644 index 00000000..09be5603 --- /dev/null +++ b/src/theme/DocPage/Layout/index.js @@ -0,0 +1,26 @@ +import React, { useState } from 'react' +import { useDocsSidebar } from '@docusaurus/theme-common/internal' +import Layout from '@theme/Layout' +import BackToTopButton from '@theme/BackToTopButton' +import DocPageLayoutSidebar from '@theme/DocPage/Layout/Sidebar' +import DocPageLayoutMain from '@theme/DocPage/Layout/Main' +import styles from './styles.module.css' +export default function DocPageLayout({ children }) { + const sidebar = useDocsSidebar() + const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false) + return ( + + +
+ {sidebar && ( + + )} + {children} +
+
+ ) +} diff --git a/src/theme/DocPage/Layout/styles.module.css b/src/theme/DocPage/Layout/styles.module.css new file mode 100644 index 00000000..008456fe --- /dev/null +++ b/src/theme/DocPage/Layout/styles.module.css @@ -0,0 +1,18 @@ +.docPage { + display: flex; + width: 100%; + flex: 1 0; +} + +.docsWrapper { + display: flex; + flex: 1 0 auto; +} + +/* +JS disabled??? Show light version by default => better than showing nothing +TODO bad, but we currently always show light mode when there's no data-theme + */ +html:not([data-theme]) .themedComponent--light { + display: initial; +} diff --git a/src/theme/DocPage/index.js b/src/theme/DocPage/index.js new file mode 100644 index 00000000..596c006f --- /dev/null +++ b/src/theme/DocPage/index.js @@ -0,0 +1,110 @@ +import React from 'react' +import clsx from 'clsx' +import { HtmlClassNameProvider, ThemeClassNames, PageMetadata } from '@docusaurus/theme-common' +import { + docVersionSearchTag, + DocsSidebarProvider, + DocsVersionProvider, + useDocRouteMetadata, +} from '@docusaurus/theme-common/internal' +import DocPageLayout from '@theme/DocPage/Layout' +import NotFound from '@theme/NotFound' +import SearchMetadata from '@theme/SearchMetadata' +import Link from '@docusaurus/Link' +import Translate from '@docusaurus/Translate' +import { useLocation } from '@docusaurus/router' + +function DocPageMetadata(props) { + const { versionMetadata } = props + return ( + <> + + {versionMetadata.noIndex && } + + ) +} +export default function DocPage(props) { + const { versionMetadata } = props + const currentDocRouteMetadata = useDocRouteMetadata(props) + const location = useLocation() + + if (!currentDocRouteMetadata) { + return + } + const { docElement, sidebarName, sidebarItems } = currentDocRouteMetadata + + // Show this warning only on migration guide pages for the latest version. + const isMigrationGuide = location.pathname.toLowerCase().includes('migration-guide') + const versionNumber = parseVersion(versionMetadata.version) + + return ( + <> + + + + + + {/* NaN indicates the latest version */} + {isMigrationGuide && (isNaN(versionNumber) || versionNumber === 5) && ( +
+

Version 3 and before of Fastify are no longer maintained.

+ {/*

+ savePreferredVersionName(latestVersionSuggestion.name)} + /> +

*/} + For information about support options for end-of-life versions, see the{' '} + Long Term Support page. +
+ )} + {docElement} +
+
+
+
+ + ) +} +function LatestVersionSuggestionLabel({ versionLabel, to, onClick }) { + return ( + + + + latest version + + + + ), + }}> + {'For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).'} + + ) +} + +const parseVersion = (versionString) => { + // Remove 'v' prefix if present + const cleanVersion = versionString.startsWith('v') ? versionString.slice(1) : versionString + // Split the version string and get the first part (major version) + const majorVersion = cleanVersion.split('.')[0] + // Parse the major version to an integer + return parseInt(majorVersion, 10) +} diff --git a/src/theme/DocVersionBanner/index.js b/src/theme/DocVersionBanner/index.js new file mode 100644 index 00000000..c1e8a7aa --- /dev/null +++ b/src/theme/DocVersionBanner/index.js @@ -0,0 +1,126 @@ +/** + * 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 useDocusaurusContext from '@docusaurus/useDocusaurusContext' +import Link from '@docusaurus/Link' +import Translate from '@docusaurus/Translate' +import { useActivePlugin, useDocVersionSuggestions } from '@docusaurus/plugin-content-docs/client' +import { ThemeClassNames } from '@docusaurus/theme-common' +import { useDocsPreferredVersion, useDocsVersion } from '@docusaurus/theme-common/internal' +function UnreleasedVersionLabel({ siteTitle, versionMetadata }) { + return ( + {versionMetadata.label}, + }}> + {'This is unreleased documentation for {siteTitle} {versionLabel} version.'} + + ) +} +function UnmaintainedVersionLabel({ siteTitle, versionMetadata }) { + return ( + {versionMetadata.label}, + }}> + {'This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.'} + + ) +} +const BannerLabelComponents = { + unreleased: UnreleasedVersionLabel, + unmaintained: UnmaintainedVersionLabel, +} +function BannerLabel(props) { + const BannerLabelComponent = BannerLabelComponents[props.versionMetadata.banner] + return +} +function LatestVersionSuggestionLabel({ versionLabel, to, onClick }) { + return ( + + + + latest version + + + + ), + }}> + {'For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).'} + + ) +} +function DocVersionBannerEnabled({ className, versionMetadata }) { + const { + siteConfig: { title: siteTitle }, + } = useDocusaurusContext() + const { pluginId } = useActivePlugin({ failfast: true }) + const getVersionMainDoc = (version) => version.docs.find((doc) => doc.id === version.mainDocId) + const { savePreferredVersionName } = useDocsPreferredVersion(pluginId) + const { latestDocSuggestion, latestVersionSuggestion } = useDocVersionSuggestions(pluginId) + + // Parse the version number + const versionNumber = parseVersion(versionMetadata.version) + + // Try to link to same doc in latest version (not always possible), falling + // back to main doc of latest version + const latestVersionSuggestedDoc = latestDocSuggestion ?? getVersionMainDoc(latestVersionSuggestion) + + return ( +
+
+ +
+
+ savePreferredVersionName(latestVersionSuggestion.name)} + /> +
+ {/* When a new version is released, increment the value below. */} + {versionNumber < 4 && ( +
+ For information about support options for end-of-life versions, see the{' '} + Long Term Support page. +
+ )} +
+ ) +} +export default function DocVersionBanner({ className }) { + const versionMetadata = useDocsVersion() + if (versionMetadata.banner) { + return + } + return null +} +const parseVersion = (versionString) => { + // Remove 'v' prefix if present + const cleanVersion = versionString.startsWith('v') ? versionString.slice(1) : versionString + // Split the version string and get the first part (major version) + const majorVersion = cleanVersion.split('.')[0] + // Parse the major version to an integer + return parseInt(majorVersion, 10) +}