'use client' import React, {PropsWithChildren, useMemo} from 'react' import NextLink from 'next/link' import Head from 'next/head' import type {Folder, MdxFile, PageMapItem} from 'nextra' import {useFSRoute} from 'nextra/hooks' import {BaseStyles, Breadcrumbs, PageLayout, ThemeProvider} from '@primer/react' import '@primer/primitives/dist/css/functional/themes/light.css' import '@primer/primitives/dist/css/functional/themes/dark.css' import { Animate, AnimationProvider, ButtonGroup, ThemeProvider as BrandThemeProvider, Button, Heading, Image, Stack, Text, } from '@primer/react-brand' import {Sidebar} from '../sidebar/Sidebar' import {UnderlineNav} from '../underline-nav/UnderlineNav' import '@primer/react-brand/fonts/fonts.css' import '@primer/react-brand/lib/css/main.css' import {normalizePages} from 'nextra/normalize-pages' import {usePathname} from 'next/navigation' import {useConfig} from '../../context/useConfig' import {Header} from '../header/Header' import {IndexCards} from '../index-cards/IndexCards' import {useColorMode} from '../../context/color-modes/useColorMode' import {SkipToMainContent} from '../skip-to-main-content/SkipToMainContent' import {RelatedContentLinks} from '../related-content-links/RelatedContentLinks' import {getRelatedPages} from '../related-content-links/getRelatedPages' import {hasChildren} from '../../../helpers/hasChildren' import {Footer} from '../footer/Footer' import styles from './Theme.module.css' const repoSrcPath = process.env.NEXT_PUBLIC_REPO_SRC_PATH || '' const repoURL = process.env.NEXT_PUBLIC_REPO || '' if (!repoURL) { console.warn( 'NEXT_PUBLIC_REPO is not set. Edit the .env.local file to set the NEXT_PUBLIC_REPO environment variable.', ) } export type ThemeProps = PropsWithChildren<{ pageMap: PageMapItem[] }> export function Theme({pageMap, children}: ThemeProps) { const pathname = usePathname() const pathHasTrailingSlash = pathname.endsWith('/') const normalizedPages = normalizePages({ list: pageMap, route: pathname, }) const route = usePathname() const fsPath = useFSRoute() const {colorMode} = useColorMode() const {activePath, flatDocsDirectories} = useMemo( () => normalizePages({ list: pageMap, route: fsPath, }), [pageMap, fsPath], ) const siteTitle = process.env.NEXT_PUBLIC_SITE_TITLE || 'Example Site' const {headerLinks} = useConfig() const activeHeaderLink = headerLinks.find(link => link.isActive) const isHomePage = route === '/' const activeFile = isHomePage ? undefined : (normalizedPages.flatDocsDirectories.find( item => `${item.route}${pathHasTrailingSlash ? '/' : ''}` === pathname, ) as MdxFile) const activeMetadata = activeFile?.frontMatter || {} const filePath = activeMetadata.filePath || '' const title = activeMetadata.title || '' const isIndexPage = /index\.mdx?$/.test(filePath) && !isHomePage && activeMetadata['show-tabs'] === undefined const data = !isHomePage && activePath[activePath.length - 2] const filteredTabData: MdxFile[] = data && hasChildren(data) ? ((data as Folder).children as MdxFile[]) : [] const relatedLinks = getRelatedPages(route, activeMetadata, flatDocsDirectories) const disablePageAnimation = activeMetadata.options?.disablePageAnimation || false return ( <> {title} {activeMetadata.description && } {activeMetadata.description && } {/* X (Twitter) OG */} {activeMetadata.description && }
Skip to main content
{!isHomePage && ( <> {activePath.length > 0 && ( {(activeHeaderLink || siteTitle) && ( {activeHeaderLink ? activeHeaderLink.title : siteTitle} )} {activePath .filter((item, index, array) => { const nextItem = array[index + 1] // Skip when current item is a folder followed by its index page // or when it is an index page with a tabbed navigation return !( (index < array.length - 1 && nextItem.name === 'index' && item.route === nextItem.route && !nextItem.frontMatter['tab-label']) || (item.name === 'index' && item.frontMatter['tab-label']) ) }) .map((item, index, visibleItems) => { const itemTitle = Array.isArray(item.children) ? item.children.find(child => child.name === 'index')?.frontMatter.title || item.frontMatter['tab-label'] || item.frontMatter.title || item.title : item.frontMatter['tab-label'] || item.frontMatter.title || item.title const isLastItem = index === visibleItems.length - 1 return ( {itemTitle.replace(/-/g, ' ')} ) })} )}
{activeMetadata.title && ( {activeMetadata.title} )} {activeMetadata.description && ( {activeMetadata.description} )} {activeMetadata.image && (
{activeMetadata['image-alt']}
)} {activeMetadata['action-1-text'] && (
{activeMetadata['action-2-text'] && ( )}
)}
{activeMetadata['show-tabs'] && } )}
{isIndexPage ? ( ) : ( <> <>{children} {relatedLinks.length > 0 && (
)} )}
) } type ContentWrapperProps = PropsWithChildren<{ disableAnimations?: boolean }> /** * The fade in animation masks the layout repainting issues. * That animation however, interferes with nested AnimationProviders so we need * to disable it for certain pages that use that. */ function ContentWrapper({children, disableAnimations}: ContentWrapperProps) { if (disableAnimations) { return <>{children} } return ( <> {children} ) }