1
0
Fork 0
freesewing/sites/shared/components/mdx/read-more.mjs

118 lines
3.8 KiB
JavaScript
Raw Normal View History

2021-12-24 18:17:02 +01:00
import get from 'lodash.get'
import Link from 'next/link'
2023-05-15 20:00:45 +02:00
import { useContext } from 'react'
import { NavigationContext } from 'shared/context/navigation-context.mjs'
2024-03-23 17:14:57 +01:00
import { RightIcon } from 'shared/components/icons.mjs'
import { pageHasChildren } from 'shared/utils.mjs'
2023-07-17 11:40:45 -05:00
import orderBy from 'lodash.orderby'
export const getRoot = {
2023-05-21 09:58:59 +02:00
dev: (root, nav) => {
if (!root) return nav
if (root.indexOf('/') === -1) return nav[root]
return get(nav, root.split('/'))
},
2023-05-21 09:58:59 +02:00
org: (root, nav) => {
// Fixme: make this work for org
2023-05-21 09:58:59 +02:00
if (!root) return nav
if (root.indexOf('/') === -1) return get(nav, root)
2023-05-21 09:58:59 +02:00
return get(nav, root.split('/'))
},
}
const onActivePath = (slug, active) => (active ? active.slice(0, slug.length) === slug : false)
/*
* This is a recursive function, so it needs to be lean
*/
2024-03-23 17:14:57 +01:00
const RenderTree = ({ tree, recurse, depth = 1, level = 0, active = false }) => {
const orderedTree = orderBy(tree, ['o', 't'], ['asc', 'asc'])
.filter((item) => typeof item === 'object')
.filter((item) => !item.h)
.filter((item) => !item._)
2023-07-17 11:40:45 -05:00
return (
<ul className="w-full list">
{orderedTree.map((item, i) => {
/*
* Does this have children?
*/
const hasChildren =
recurse && item.s && (!depth || level < depth) && pageHasChildren(item)
2023-07-17 11:40:45 -05:00
? item.s.replaceAll('/', '')
: false
/*
* The rotation of the chevron should in principle be possible with Tailwind's group variant modifiers
* However, despite my best efforts, I can't seem to make it work. So this relies on a bit of CSS.
* The 'summary-chevron' class is what does the trick.
*/
const liClasses =
'hover:bg-opacity-20 bg-secondary bg-opacity-0 block w-full p-0 break-all rounded'
return (
<li key={i} className="w-full flex flex-row items-stretch">
{hasChildren ? (
<details
className={`w-full flex flex-row items-center`}
open={onActivePath(item.s, active)}
>
<summary className="hover:bg-opacity-20 bg-secondary bg-opacity-0 w-full flex flex-row items-center gap-0.5 lg:gap-1 pl-1 lg:pl-2 py-0">
<Link href={`/${item.s}`} className="grow p-1">
{active === item.s ? <b>{item.t}</b> : item.t}
</Link>
<div className="btn btn-sm btn-secondary btn-ghost h-full px-2">
<RightIcon
className={`details-toggle h-5 h-5 summary-chevron transition-all`}
stroke={3}
/>
</div>
</summary>
2023-10-14 12:58:42 +02:00
<RenderTree tree={item} {...{ recurse, depth, active }} level={level + 1} />
</details>
) : (
<>
<Link href={`/${item.s}`} className={`${liClasses} p-1 pl-3`}>
2023-10-14 12:58:42 +02:00
{active === item.s ? <b>{item.t}</b> : item.t}
</Link>
</>
)}
</li>
)
})}
2023-07-17 11:40:45 -05:00
</ul>
)
}
2023-10-14 12:58:42 +02:00
export const ReadMore = ({
recurse = 0,
root = false,
site = 'org',
asMenu = false,
depth = 99,
from = false,
2023-10-14 12:58:42 +02:00
}) => {
const { siteNav, slug } = useContext(NavigationContext)
2023-10-14 12:58:42 +02:00
let active = false
2023-04-16 16:19:49 +02:00
// Deal with recurse not being a number
if (recurse && recurse !== true) {
2023-04-16 16:19:49 +02:00
if (typeof recurse === 'number') recurse--
else recurse = 1
}
// Deal with root being passed as true
if (root === true) root = ''
2021-12-24 18:17:02 +01:00
2023-10-14 12:58:42 +02:00
if (asMenu && slug.split('/').length > 1) {
root = from ? from : slug.split('/').slice(0, -1).join('/')
2023-10-14 12:58:42 +02:00
active = slug
}
const tree =
root === false ? getRoot[site](from ? from : slug, siteNav) : getRoot[site](root, siteNav)
2023-05-22 17:05:59 +02:00
2023-07-17 11:40:45 -05:00
if (!tree) return null
return <RenderTree {...{ tree, recurse, depth, active, from }} />
2021-12-24 18:17:02 +01:00
}