// __SDEFILE__ - This file is a dependency for the stand-alone environment import { NavigationContext } from 'shared/context/navigation-context.mjs' import { useContext } from 'react' import Link from 'next/link' import orderBy from 'lodash.orderby' import { CsetIcon, DesignIcon, DocsIcon, RssIcon, ShowcaseIcon, UserIcon, CodeIcon, BulletIcon, PlusIcon, GitHubIcon, RocketIcon, TutorialIcon, YouTubeIcon, HeartIcon, } from 'shared/components/icons.mjs' import { Breadcrumbs } from 'shared/components/breadcrumbs.mjs' export const ns = ['sections'] // List of icons matched to top-level slug export const icons = { // FreeSewing.dev guides: (className = '') => , howtos: (className = '') => , reference: (className = '') => , tutorials: (className = '') => , training: (className = '') => , // FreeSewing.org account: (className = '') => , blog: (className = '') => , designs: (className = '') => , docs: (className = '') => , showcase: (className = '') => , new: (className = '') => , support: (className = '') => , csets: (className = '') => , // Lab code: (className = '') => , } /* helper method to order nav entries */ const order = (obj) => orderBy(obj, ['o', 't'], ['asc', 'asc']) // Component for the collapse toggle // Exported for re-use export const Chevron = ({ w = 8, m = 2 }) => ( ) // Helper method to filter out the real children const currentChildren = (current) => Object.values(order(current)).filter((entry) => typeof entry === 'object') // Shared classes for links // Exported for re-use export const linkClasses = ` py-1 text-base text-base-content sm:text-base-content hover:text-secondary sm:hover:text-secondary ` // Figure out whether a page is on the path to the active page export const isActive = (slug, active) => { if (!slug) return false if (slug === active) return true let result = true const slugParts = slug.split('/') const activeParts = active.split('/') for (const i in slugParts) { if (slugParts[i] !== activeParts[i]) result = false } return result } const hasChildren = (page) => { const keys = new Set([...Object.keys(page)]) for (const key of ['t', 's']) keys.delete(key) return keys.size } // Component that renders a sublevel of navigation const SubLevel = ({ nodes = {}, active = '' }) => (
    {currentChildren(nodes).map((child) => hasChildren(child) ? (
  • {child.s === active ? <>• : <>°} {child.t}
  • ) : (
  • {child.s === active ? <>• : <>°} {child.t}
  • ) )}
) export const Icons = ({ ulClasses = '', linkClasses = `grow text-lg lg:text-xl py-1 text-base-content sm:text-base-content hover:text-secondary sm:hover:text-secondary hover:cursor-pointer flex flex-col items-center`, linkStyle = {}, }) => { const { nav } = useContext(NavigationContext) if (!nav) return null const output = [] for (const page of order(nav)) { output.push(
  • {icons[page.s] ? icons[page.s]('w-14 h-14') : } {page.t}
  • ) } return
      {output}
    } export const Spacer = () => (
    ) export const MainSections = () => { const { sections = false, slug } = useContext(NavigationContext) if (!sections) return null // Ensure each page as an `o` key so we can put them in order const sortableSections = sections.map((s) => ({ ...s, o: s.o ? s.o : s.t })) const output = [] for (const page of orderBy(sortableSections, ['o', 't'])) { const act = isActive(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}
    } const getCrumb = (index, crumbs) => crumbs[index].s.split('/').pop() export const ActiveSection = () => { // Get navigation context const { crumbs = [], nav = {}, slug } = useContext(NavigationContext) // Don't bother if we don't know where we are if (!crumbs || !Array.isArray(crumbs) || crumbs.length < 1) return null let slice = 1 let nodes = nav // Some sections are further trimmed if (crumbs[0].s === 'docs') { if (crumbs.length > 1 && crumbs[1].s === 'docs/faq') { slice = 2 nodes = nav[getCrumb(1, crumbs)] } else if (crumbs.length === 2) { slice = 2 nodes = nav[getCrumb(1, crumbs)] } else if ( crumbs.length === 4 && crumbs[1].s === 'docs/patterns' && crumbs[3].s.split('/').pop() === 'options' ) { slice = 4 nodes = nav[getCrumb(1, crumbs)][getCrumb(2, crumbs)][getCrumb(3, crumbs)] } else if (crumbs.length > 2 && crumbs[1].s === 'docs/patterns') { slice = 3 nodes = nav[getCrumb(1, crumbs)][getCrumb(2, crumbs)] } } return (
    ) }