diff --git a/components/Breadcrumbs.tsx b/components/Breadcrumbs.tsx index dad6685c5df5..90a59421c7ea 100644 --- a/components/Breadcrumbs.tsx +++ b/components/Breadcrumbs.tsx @@ -51,7 +51,11 @@ export const Breadcrumbs = ({ variant = 'default' }: Props) => { {breadcrumb.title} ), - i !== arr.length - 1 ? / : null, + i !== arr.length - 1 ? ( + + / + + ) : null, ] })} diff --git a/components/DefaultLayout.tsx b/components/DefaultLayout.tsx index aa5a702dd3a9..4869cf0d9c1b 100644 --- a/components/DefaultLayout.tsx +++ b/components/DefaultLayout.tsx @@ -1,6 +1,6 @@ import Head from 'next/head' -import { SidebarNav } from 'components/SidebarNav' +import { SidebarNav } from 'components/sidebar/SidebarNav' import { Header } from 'components/page-header/Header' import { SmallFooter } from 'components/page-footer/SmallFooter' import { ScrollButton } from 'components/ScrollButton' diff --git a/components/SidebarNav.tsx b/components/SidebarNav.tsx deleted file mode 100644 index 38733ec1ea09..000000000000 --- a/components/SidebarNav.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { useRouter } from 'next/router' -import { LinkExternalIcon, MarkGithubIcon } from '@primer/octicons-react' - -import { Link } from 'components/Link' -import { useTranslation } from './hooks/useTranslation' -import { useMainContext } from './context/MainContext' -import { SidebarProduct } from './product/SidebarProduct' -import { AllProductsLink } from './product/AllProductsLink' -import { useVersion } from './hooks/useVersion' - -export const SidebarNav = () => { - const router = useRouter() - const { error, relativePath, isFPT } = useMainContext() - const { t } = useTranslation('header') - - return ( -
- - - - -
- ) -} - -const SidebarHomepage = () => { - const router = useRouter() - const { currentVersion } = useVersion() - const { activeProducts, isFPT } = useMainContext() - - return ( - <> - {activeProducts.map((product) => { - if (!isFPT && !product.versions?.includes(currentVersion) && !product.external) { - return null - } - - const href = `${!product.external ? `/${router.locale}` : ''}${ - product.versions?.includes(currentVersion) && !isFPT - ? `/${currentVersion}/${product.id}` - : product.href - }` - - return ( -
  • - - {product.name} - {product.external && ( - - - - )} - -
  • - ) - })} - - ) -} diff --git a/components/lib/events.ts b/components/lib/events.ts index ccdc0045c45a..3fe9dbee39d4 100644 --- a/components/lib/events.ts +++ b/components/lib/events.ts @@ -207,38 +207,11 @@ function initExitEvent() { document.addEventListener('visibilitychange', sendExit) } -function initNavigateEvent() { - if (!document.querySelector('.sidebar-products')) return - - Array.from(document.querySelectorAll('.sidebar-products details')).forEach((details) => - details.addEventListener('toggle', (evt) => { - const target = evt.target as HTMLDetailsElement - sendEvent({ - type: EventType.navigate, - navigate_label: `details ${target.open ? 'open' : 'close'}: ${ - target?.querySelector('summary')?.innerText - }`, - }) - }) - ) - - document.querySelector('.sidebar-products')?.addEventListener('click', (evt) => { - const target = evt.target as HTMLElement - const link = target.closest('a') as HTMLAnchorElement - if (!link) return - sendEvent({ - type: EventType.navigate, - navigate_label: `link: ${link.href}`, - }) - }) -} - export default function initializeEvents() { initPageEvent() // must come first initExitEvent() initLinkEvent() initClipboardEvent() - initNavigateEvent() // print event in ./print.js // survey event in ./survey.js // experiment event in ./experiment.js diff --git a/components/product/AllProductsLink.tsx b/components/sidebar/AllProductsLink.tsx similarity index 100% rename from components/product/AllProductsLink.tsx rename to components/sidebar/AllProductsLink.tsx diff --git a/components/sidebar/SidebarHomepage.tsx b/components/sidebar/SidebarHomepage.tsx new file mode 100644 index 000000000000..ecc55ba69e87 --- /dev/null +++ b/components/sidebar/SidebarHomepage.tsx @@ -0,0 +1,53 @@ +import { useRouter } from 'next/router' +import { LinkExternalIcon } from '@primer/octicons-react' + +import { useVersion } from 'components/hooks/useVersion' +import { useMainContext } from 'components/context/MainContext' +import { Link } from 'components/Link' + +import { AllProductsLink } from './AllProductsLink' + +export const SidebarHomepage = () => { + const router = useRouter() + const { currentVersion } = useVersion() + const { activeProducts, isFPT } = useMainContext() + + return ( + + ) +} diff --git a/components/sidebar/SidebarNav.tsx b/components/sidebar/SidebarNav.tsx new file mode 100644 index 000000000000..0f6962c9fca0 --- /dev/null +++ b/components/sidebar/SidebarNav.tsx @@ -0,0 +1,46 @@ +import { useRouter } from 'next/router' +import { MarkGithubIcon } from '@primer/octicons-react' + +import { Link } from 'components/Link' +import { useTranslation } from 'components/hooks/useTranslation' +import { useMainContext } from 'components/context/MainContext' +import { SidebarProduct } from './SidebarProduct' +import { SidebarHomepage } from './SidebarHomepage' + +export const SidebarNav = () => { + const router = useRouter() + const { error, relativePath } = useMainContext() + const { t } = useTranslation('header') + + return ( +
    + + +
    + ) +} diff --git a/components/sidebar/SidebarProduct.module.scss b/components/sidebar/SidebarProduct.module.scss new file mode 100644 index 000000000000..49c8f812849f --- /dev/null +++ b/components/sidebar/SidebarProduct.module.scss @@ -0,0 +1,13 @@ +.sidebarArticle::before { + content: ""; + position: absolute; + left: 26px; + height: 100%; + border-left: 1px solid var(--color-text-primary); + width: 1px; + top: 0; +} + +.sidebarArticleActive::before { + border-left-width: 2px; +} diff --git a/components/product/SidebarProduct.tsx b/components/sidebar/SidebarProduct.tsx similarity index 53% rename from components/product/SidebarProduct.tsx rename to components/sidebar/SidebarProduct.tsx index cab9cbbf0c32..ae80a37f5a5e 100644 --- a/components/product/SidebarProduct.tsx +++ b/components/sidebar/SidebarProduct.tsx @@ -1,17 +1,21 @@ import { useRouter } from 'next/router' import cx from 'classnames' -import { useState, useEffect } from 'react' +import { useState, useEffect, SyntheticEvent } from 'react' import { ChevronDownIcon } from '@primer/octicons-react' import { Link } from 'components/Link' import { ProductTreeNode, useMainContext } from 'components/context/MainContext' -import { AllProductsLink } from 'components/product/AllProductsLink' +import { AllProductsLink } from 'components/sidebar/AllProductsLink' +import { EventType, sendEvent } from 'components/lib/events' + +import styles from './SidebarProduct.module.scss' export const SidebarProduct = () => { const router = useRouter() const { currentProductTree } = useMainContext() + useEffect(() => { - const activeArticle = document.querySelector('.sidebar-article.active') + const activeArticle = document.querySelector('[data-is-current-page=true]') // Setting to the top doesn't give enough context of surrounding categories activeArticle?.scrollIntoView({ block: 'center' }) // scrollIntoView affects some articles that are very low in the sidebar @@ -26,16 +30,16 @@ export const SidebarProduct = () => { const productTitle = currentProductTree.renderedShortTitle || currentProductTree.renderedFullTitle const routePath = `/${router.locale}${router.asPath.split('?')[0]}` // remove query string - const hasExactCategory = currentProductTree.childPages.find(({ href }) => + const hasExactCategory = !!currentProductTree.childPages.find(({ href }) => routePath.includes(href) ) return ( - <> +