import Link from 'next/link' import { pageHasChildren, isSlugPart } from 'shared/utils.mjs' import get from 'lodash.get' import { HomeIcon, RightIcon, BulletIcon } from 'shared/components/icons.mjs' import { PageLink } from 'shared/components/page-link.mjs' import orderBy from 'lodash.orderby' import { icons } from 'shared/components/navigation/primary.mjs' /* * This returns only those children that are expected to show up * in the side navigation. Specifically: * - Key length needs to be longer than 1 * - Child pages cannot have m or h set (main section or hidden) * - Title may not be 'spacer' (header spacer) * * It also takes care of ordering them, and returns an array * * @params tree {object} - A navigation object as returned by useNavigation => siteNav */ const onlyValidChildren = (tree, hIsOk = false) => orderBy(tree, ['o', 't'], ['asc', 'asc']).filter( (entry) => typeof entry === 'object' && entry.t !== 'spacer' && !entry.h ) /* * This returns only those children that are main sections. Specifically: * - Key length needs to be longer than 1 * - Child pages cannot have m set (main section) * - Title may not be 'spacer' (header spacer) * * It also takes care of ordering them, and returns an array * * @params tree {object} - A navigation object as returned by useNavigation => siteNav */ const onlyMainSections = (tree) => orderBy(tree, ['o', 't'], ['asc', 'asc']).filter((entry) => entry.m) const SectionLink = ({ skey, tree, slug }) => tree[skey]._ ? null : tree[skey].s === slug ? ( // Underscore means always hide <> {tree[skey].t} {pageHasChildren(tree[skey]) &&
} ) : isSlugPart(tree[skey].s, slug) ? ( <> {tree[skey].t} {pageHasChildren(tree[skey]) &&
} ) : ( {tree[skey].t} ) /* * A React component to render a section of the navigation * * @param t {string} - The section title * @param s {string} - The section slug * @param tree {object} - The object describing any futher child pages * @param slug {string} - The slug of the currently active/viewed page */ const Section = ({ tree, // Object with the navigation slug, // Slug of the current page (used to make links active) }) => ( ) /* * A React component to render a main link navigation * * @param t {string} - The section title * @param s {string} - The section slug */ const MainLink = ({ t, // The link title/text s, // The link slug slug, // The current page slug }) => { const classes = '' + 'break-all py-2 px-2 block w-full font-bold text-lg ' + 'flex flex-row items-start gap-0.5 lg:gap-1 border-l-2' return s === slug ? ( {t} ) : ( {t} ) } /* * A React component to render breadcrumbs to the current page * * @param slug {string} - The slug of the current page * @param siteNav {object} - The site navigation object as returned by the useNavigation hook */ export const Breadcrumbs = ({ slug, siteNav }) => { // Start with the home crumb const crumbs = [
  • , ] // Then split the slug and add a crumb for each const chunks = slug.split('/') for (let i = 1; i <= chunks.length; i++) { const page = get(siteNav, chunks.slice(0, i)) crumbs.push(
  • , i === chunks.length ? (
  • {page.t}
  • ) : (
  • ) ) } return } /* * A React component to render sidebar navigation based on the siteNav object and current slug * * The main sections are determined in the use-navigation hook. * We always display the navigation as: * - Always show all top-level entries * - Always show all direct children of all top-level entries (this allows for better discoverability) * - If we're deeper down, only expand the active page * * @param slug {string} - The slug of the current page * @param siteNav {object} - The siteNav object from the useNavigation hook * @param ignorecontrol {boolean} - Whether or not to ignore the control setting of the user to hide certain things */ export const NavLinks = ({ slug, siteNav, ignoreControl = false }) => ( ) /* * A React component to render sidebar navigation for the main sections * * @param siteNav {object} - The siteNav object from the useNavigation hook * @param slug {string} - The slug of the current page */ export const MainSections = ({ siteNav, slug }) => { const output = [] for (const page of onlyMainSections(siteNav)) { const act = isSlugPart(page.s, slug) const txt = ( <> {icons[page.s] ? ( icons[page.s](`w-6 h-6 ${act ? 'text-base-100 opacity-70' : ''}`) ) : ( )} {page.t} ) const item = page.t === 'spacer' ? (
  • ) : (
  • {act ? ( {txt} ) : ( {txt} )}
  • ) output.push(item) } return
      {output}
    }