2021-12-16 19:01:37 +01:00
|
|
|
import get from 'lodash.get'
|
2021-12-11 14:04:05 +01:00
|
|
|
import Icon from 'shared/components/icon/index.js'
|
2021-12-12 18:58:24 +01:00
|
|
|
import Link from 'next/link'
|
2021-12-16 19:01:37 +01:00
|
|
|
import orderBy from 'lodash.orderby'
|
2021-12-21 19:29:28 +01:00
|
|
|
import Logo from 'shared/components/logos/freesewing.js'
|
2021-12-18 16:13:55 +01:00
|
|
|
import ThemePicker from 'shared/components/theme-picker.js'
|
2021-12-18 16:26:55 +01:00
|
|
|
import { getTagline } from 'site/utils.js'
|
2021-12-11 14:04:05 +01:00
|
|
|
|
2021-12-17 17:51:20 +01:00
|
|
|
// TODO: Clean this up after restructuring markdown content
|
|
|
|
const hide = ['contributors', 'developers', 'editors', 'translators']
|
|
|
|
|
|
|
|
// Don't show children for blog and showcase posts
|
2021-12-12 18:58:24 +01:00
|
|
|
const keepClosed = ['blog', 'showcase', ]
|
|
|
|
|
2021-12-17 17:51:20 +01:00
|
|
|
// TODO: For now we force tailwind to pickup these styles
|
|
|
|
// At some point this should 'just work' though, but let's not worry about it now
|
2021-12-18 09:54:53 +01:00
|
|
|
const force = [
|
|
|
|
<p className="w-6 mr-2"/>,
|
|
|
|
<p className="w-8 mr-3"/>
|
|
|
|
]
|
2021-12-17 17:51:20 +01:00
|
|
|
|
|
|
|
// Component for the collapse toggle
|
2021-12-18 09:54:53 +01:00
|
|
|
const Chevron = ({w=8, m=2}) => <svg
|
2021-12-21 18:50:19 +01:00
|
|
|
className={`fill-current opacity-75 w-${w} h-${w} mr-${m} details-toggle hover:text-secondary`}
|
2021-12-17 17:51:20 +01:00
|
|
|
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
|
|
|
<path d="M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z"/>
|
|
|
|
</svg>
|
|
|
|
|
|
|
|
// Helper method to filter out the real children
|
|
|
|
const currentChildren = current => Object.values(current)
|
|
|
|
.filter(entry => (typeof entry === 'object'))
|
2021-12-16 19:01:37 +01:00
|
|
|
|
2021-12-21 20:47:13 +01:00
|
|
|
const howActive = (slug) => {
|
|
|
|
}
|
|
|
|
|
|
|
|
// Shared classes for links
|
|
|
|
const linkClasses = "text-lg lg:text-xl py-1 text-base-content hover:cursor-pointer hover:text-secondary bg-opacity-50"
|
|
|
|
|
|
|
|
|
2021-12-21 18:50:19 +01:00
|
|
|
|
2021-12-17 17:51:20 +01:00
|
|
|
// Component that renders a sublevel of navigation
|
2021-12-21 20:47:13 +01:00
|
|
|
const SubLevel = ({ nodes={}, level=1 }) => (
|
|
|
|
<ul className="pl-5 list-inside">
|
2021-12-17 17:51:20 +01:00
|
|
|
{currentChildren(nodes).map(child => (Object.keys(child).length > 4)
|
|
|
|
? (
|
2021-12-21 20:47:13 +01:00
|
|
|
<li key={child.__slug} className="flex flex-row">
|
|
|
|
<details className="grow">
|
2021-12-17 17:51:20 +01:00
|
|
|
<summary className={`
|
2021-12-21 20:47:13 +01:00
|
|
|
flex flex-row
|
|
|
|
px-2
|
2021-12-21 18:50:19 +01:00
|
|
|
text-base-content
|
2021-12-17 17:51:20 +01:00
|
|
|
hover:cursor-row-resize
|
2021-12-21 20:47:13 +01:00
|
|
|
items-center
|
2021-12-17 17:51:20 +01:00
|
|
|
`}>
|
2021-12-21 20:47:13 +01:00
|
|
|
<Link href={child.__slug}>
|
|
|
|
<a title={child.__title} className={`grow pl-2 border-l-2 ${linkClasses} hover:border-secondary`}>
|
|
|
|
<Icon icon="middot" size="24" className="text-secondary inline" />
|
|
|
|
{ child?.__linktitle || child.__title }
|
|
|
|
</a>
|
|
|
|
</Link>
|
2021-12-17 17:51:20 +01:00
|
|
|
<Chevron w={6} m={3}/>
|
|
|
|
</summary>
|
2021-12-21 20:47:13 +01:00
|
|
|
<SubLevel nodes={child} level={level+1} />
|
2021-12-17 17:51:20 +01:00
|
|
|
</details>
|
|
|
|
</li>
|
|
|
|
) : (
|
2021-12-21 20:47:13 +01:00
|
|
|
<li className='pl-2 flex flex-row items-center'>
|
2021-12-17 17:51:20 +01:00
|
|
|
<Link href={child.__slug} title={child.__title}>
|
2021-12-21 20:47:13 +01:00
|
|
|
<a className={`pl-2 border-l-2 ${linkClasses} grow hover:border-secondary`}>
|
|
|
|
<Icon icon="middot" size="24" className="text-secondary inline" />
|
2021-12-21 18:50:19 +01:00
|
|
|
{child.__linktitle}
|
|
|
|
</a>
|
2021-12-17 17:51:20 +01:00
|
|
|
</Link>
|
|
|
|
</li>
|
|
|
|
)
|
|
|
|
|
|
|
|
)}
|
|
|
|
</ul>
|
|
|
|
)
|
2021-12-16 19:01:37 +01:00
|
|
|
|
2021-12-17 17:51:20 +01:00
|
|
|
// Component that renders a toplevel of navigation
|
2021-12-21 20:47:13 +01:00
|
|
|
const TopLevel = ({ icon, title, nav, current, slug, hasChildren=false, active }) => (
|
|
|
|
<details className='py-1' open={((keepClosed.indexOf(current.__slug) === -1) ? 1 : 0)}>
|
2021-12-12 18:58:24 +01:00
|
|
|
<summary className={`
|
|
|
|
flex flex-row uppercase gap-4 font-bold text-lg
|
|
|
|
hover:cursor-row-resize
|
|
|
|
p-2
|
2021-12-21 18:50:19 +01:00
|
|
|
text-base-content
|
|
|
|
items-center
|
2021-12-12 18:58:24 +01:00
|
|
|
`}>
|
2021-12-16 19:01:37 +01:00
|
|
|
{icon}
|
2021-12-21 20:47:13 +01:00
|
|
|
<Link href={`/${current.__slug}/`}>
|
2021-12-21 18:50:19 +01:00
|
|
|
<a className={`grow ${linkClasses}`}>
|
2021-12-21 20:47:13 +01:00
|
|
|
{title} {active}
|
2021-12-20 18:40:02 +01:00
|
|
|
</a>
|
|
|
|
</Link>
|
2021-12-21 20:47:13 +01:00
|
|
|
{hasChildren && <Chevron />}
|
2021-12-11 18:19:20 +01:00
|
|
|
</summary>
|
2021-12-21 20:47:13 +01:00
|
|
|
{hasChildren && <SubLevel nodes={current} />}
|
2021-12-11 18:19:20 +01:00
|
|
|
</details>
|
|
|
|
)
|
|
|
|
|
2021-12-18 16:13:55 +01:00
|
|
|
// Component that renders the logo first entry
|
|
|
|
const TopLogo = ({ app }) => (
|
|
|
|
<div className={`
|
|
|
|
flex flex-row uppercase gap-4 font-bold text-lg
|
|
|
|
items-center
|
|
|
|
hover:cursor-row-resize
|
|
|
|
p-2
|
2021-12-21 18:50:19 +01:00
|
|
|
text-base-content
|
2021-12-18 16:13:55 +01:00
|
|
|
`}>
|
2021-12-21 19:29:28 +01:00
|
|
|
<Logo size={32} theme={app.theme} />
|
2021-12-21 18:50:19 +01:00
|
|
|
<div>
|
|
|
|
<Link href='/'>
|
|
|
|
<a className={`grow ${linkClasses}`}>
|
|
|
|
freesewing.{app.site}
|
|
|
|
</a>
|
|
|
|
</Link>
|
|
|
|
<p className={`text-base-content text-captalize text-sm font-normal
|
|
|
|
`}>{getTagline()}</p>
|
2021-12-18 16:13:55 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
|
|
|
|
// Component that renders the theme picker first entry
|
|
|
|
const TopTheme = ({ app }) => (
|
|
|
|
<>
|
|
|
|
<div className={`
|
|
|
|
flex flex-row uppercase gap-4 font-bold text-lg
|
|
|
|
items-center
|
|
|
|
hover:cursor-row-resize
|
|
|
|
hover:bg-base-200
|
|
|
|
p-2
|
|
|
|
text-primary
|
|
|
|
`}>
|
2021-12-21 18:50:19 +01:00
|
|
|
<Icon icon='theme' className="text-secondary"/>
|
|
|
|
<div className={`grow`}>
|
2021-12-18 16:13:55 +01:00
|
|
|
Theme
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-12-21 20:47:13 +01:00
|
|
|
<div className="p-2">
|
|
|
|
<ThemePicker app={app} className="pr-8"/>
|
|
|
|
</div>
|
2021-12-18 16:13:55 +01:00
|
|
|
</>
|
|
|
|
)
|
|
|
|
|
2021-12-12 18:58:24 +01:00
|
|
|
// TODO: Get rid of this when markdown has been restructured
|
|
|
|
const remove = ['contributors', 'developers', 'editors', 'translators']
|
2021-12-21 20:47:13 +01:00
|
|
|
const Navigation = ({ app, active }) => {
|
2021-12-19 18:37:08 +01:00
|
|
|
if (!app.navigation) return null
|
2021-12-12 18:58:24 +01:00
|
|
|
const output = []
|
2021-12-19 18:37:08 +01:00
|
|
|
for (const key of Object.keys(app.navigation).sort()) {
|
2021-12-17 17:51:20 +01:00
|
|
|
if (hide.indexOf(key) === -1) output.push(<TopLevel
|
2021-12-21 18:50:19 +01:00
|
|
|
icon={<Icon icon={key} className="text-secondary"/>}
|
2021-12-17 17:51:20 +01:00
|
|
|
title={key}
|
|
|
|
slug={key}
|
|
|
|
key={key}
|
2021-12-21 20:47:13 +01:00
|
|
|
hasChildren={keepClosed.indexOf(key) === -1}
|
2021-12-19 18:37:08 +01:00
|
|
|
nav={app.navigation}
|
|
|
|
current={orderBy(app.navigation[key], ['order', 'title'], ['asc', 'asc'])}
|
2021-12-21 20:47:13 +01:00
|
|
|
active={active}
|
2021-12-17 17:51:20 +01:00
|
|
|
/>)
|
2021-12-12 18:58:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return output
|
|
|
|
}
|
|
|
|
|
2021-12-21 20:47:13 +01:00
|
|
|
const PrimaryMenu = ({ app, active }) => {
|
2021-12-11 14:04:05 +01:00
|
|
|
|
|
|
|
return (
|
|
|
|
<nav className={`
|
|
|
|
sm:max-w-sm
|
2021-12-11 18:19:20 +01:00
|
|
|
grow
|
2021-12-11 14:04:05 +01:00
|
|
|
`}>
|
2021-12-19 18:37:08 +01:00
|
|
|
<TopLogo app={app}/>
|
2021-12-21 20:47:13 +01:00
|
|
|
<Navigation app={app} active={active} />
|
2021-12-19 18:37:08 +01:00
|
|
|
<TopTheme app={app}/>
|
2021-12-11 14:04:05 +01:00
|
|
|
</nav>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default PrimaryMenu
|