From c1ca217b5232f671b06b7fba3df91b0bb4fd5295 Mon Sep 17 00:00:00 2001 From: joostdecock Date: Sat, 15 Jul 2023 11:00:18 +0200 Subject: [PATCH] fix(dev): Hide contact page from site navigation --- sites/dev/hooks/use-navigation.mjs | 3 + .../shared/components/navigation/sitenav.mjs | 275 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 sites/shared/components/navigation/sitenav.mjs diff --git a/sites/dev/hooks/use-navigation.mjs b/sites/dev/hooks/use-navigation.mjs index 36d3b4a7a0f..97b41e72173 100644 --- a/sites/dev/hooks/use-navigation.mjs +++ b/sites/dev/hooks/use-navigation.mjs @@ -91,6 +91,9 @@ export const useNavigation = () => { siteNav[page].i = 1 } + // Hide contact from the sitenav + siteNav.contact.h = 1 + return { siteNav, // Site navigation slugLut: orderedSlugLut(siteNav), // Slug lookup table diff --git a/sites/shared/components/navigation/sitenav.mjs b/sites/shared/components/navigation/sitenav.mjs new file mode 100644 index 00000000000..881d30d067d --- /dev/null +++ b/sites/shared/components/navigation/sitenav.mjs @@ -0,0 +1,275 @@ +import Link from 'next/link' +import { useContext } from 'react' +import { NavigationContext } from 'shared/context/navigation-context.mjs' +import { pageHasChildren, oneUpSlug, maxPovDepthSlug, isSlugPart } from 'shared/utils.mjs' +import { getRoot } from 'shared/components/mdx/read-more.mjs' +import { siteConfig } from 'site/site.config.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 && !entry.m + ) + +/* + * 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].s === slug ? ( + <> + + {tree[skey].t} fixme-sectionlink-1 + + {pageHasChildren(tree[skey]) &&
} + + ) : isSlugPart(tree[skey].s, slug) ? ( + <> + + {tree[skey].t} fixme-sectionlink-2 + + {pageHasChildren(tree[skey]) &&
} + + ) : ( + + {tree[skey].t} fixme-sectionlink-3 + + ) + +/* + * 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) +}) => ( +
    + {onlyValidChildren(tree).map((page, i) => ( +
  • + {slug === page.s ? ( + <> + + {page.t} fixme-section-1 + + {pageHasChildren(page) &&
    } + + ) : ( + + )} +
  • + ))} +
+) + +/* + * 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-medium ' + + 'flex flex-row items-start gap-0.5 lg:gap-1 border-l-2' + + return s === slug ? ( + + {t} fixme-main-1 + + ) : ( + + {t} fixme-main-2 + + ) +} + +/* + * 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
      {crumbs}
    +} + +/* + * A React component to render sidebar navigation based on the siteNav object and current slug + * + * @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 }) => { + /* + * Point of view from which we'll render the side navigation + * We descend only to a maximum level + */ + let tree = getRoot[siteConfig.tld](maxPovDepthSlug(slug, siteConfig.tld), siteNav) + let hIsOk = false // hide top-level stuff + // If we're on a main section page, just show the entire tree + if (tree.m) { + tree = siteNav + hIsOk = true + } + + /* + * Return navigation + */ + return ( +
      + {onlyValidChildren(tree, hIsOk).map((page, i) => ( +
    • + + {pageHasChildren(page) &&
      } +
    • + ))} +
    + ) +} + +/* + * 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}
    +}