wip(dev): Refactoring navigation
This commit is contained in:
parent
264e7a0b9d
commit
244f4524c4
20 changed files with 362 additions and 265 deletions
|
@ -1,32 +1,22 @@
|
|||
import { Fragment } from 'react'
|
||||
import { HomeIcon } from 'shared/components/icons.mjs'
|
||||
import Link from 'next/link'
|
||||
import { FreeSewingIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const Breadcrumbs = ({ crumbs = [] }) =>
|
||||
export const Breadcrumbs = ({ crumbs, title }) =>
|
||||
crumbs ? (
|
||||
<ul className="flex flex-row flex-wrap gap-2 font-bold">
|
||||
<li>
|
||||
<Link href="/" title="FreeSewing" className="text-base-content">
|
||||
<FreeSewingIcon />
|
||||
</Link>
|
||||
</li>
|
||||
{crumbs.map((crumb) => (
|
||||
<Fragment key={crumb[1] + crumb[0]}>
|
||||
<li className="text-base-content px-2">»</li>
|
||||
<li>
|
||||
{crumb[1] ? (
|
||||
<Link
|
||||
href={crumb[1]}
|
||||
title={crumb[0]}
|
||||
className="text-secondary hover:text-secondary-focus"
|
||||
>
|
||||
{crumb[0]}
|
||||
</Link>
|
||||
) : (
|
||||
<span className="text-base-content">{crumb[0]}</span>
|
||||
)}
|
||||
<div className="text-sm breadcrumbs flex-wrap">
|
||||
<ul>
|
||||
<li>
|
||||
<Link href="/" title="FreeSewing">
|
||||
<HomeIcon />
|
||||
</Link>
|
||||
</li>
|
||||
{crumbs.map((crumb) => (
|
||||
<li key={crumb.s}>
|
||||
<Link href={crumb.s} title={crumb.t} className="text-secondary-focus font-bold">
|
||||
{crumb.t}
|
||||
</Link>
|
||||
</li>
|
||||
</Fragment>
|
||||
))}
|
||||
</ul>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
) : null
|
||||
|
|
|
@ -96,6 +96,7 @@ const renderNext = (node) =>
|
|||
)
|
||||
|
||||
export const PrevNext = ({ app }) => {
|
||||
return <p>fixme: prevnext</p>
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-4 border-t mt-12 py-2">
|
||||
{renderPrevious(previous(app))}
|
||||
|
|
97
sites/shared/components/wrappers/page.mjs
Normal file
97
sites/shared/components/wrappers/page.mjs
Normal file
|
@ -0,0 +1,97 @@
|
|||
// Dependencies
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useSwipeable } from 'react-swipeable'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
// Hooks
|
||||
import { useTheme } from 'shared/hooks/use-theme.mjs'
|
||||
// Components
|
||||
import { LayoutWrapper, ns as layoutNs } from 'site/components/wrappers/layout.mjs'
|
||||
import { DocsLayout } from 'site/components/layouts/docs.mjs'
|
||||
import { Feeds } from 'site/components/feeds.mjs'
|
||||
|
||||
//export const ns = [...layoutNs]
|
||||
|
||||
/* This component should wrap all page content */
|
||||
export const PageWrapper = ({
|
||||
noSearch = false,
|
||||
app = false,
|
||||
layout = DocsLayout,
|
||||
footer = true,
|
||||
children = [],
|
||||
title = 'FIXME: No title set',
|
||||
}) => {
|
||||
/*
|
||||
* This forces a re-render upon initial bootstrap of the app
|
||||
* This is needed to avoid hydration errors because theme can't be set reliably in SSR
|
||||
*/
|
||||
const [theme, setTheme] = useTheme()
|
||||
const [currentTheme, setCurrentTheme] = useState()
|
||||
useEffect(() => setCurrentTheme(theme), [currentTheme, theme])
|
||||
|
||||
/*
|
||||
* Swipe handling for the entire site
|
||||
*/
|
||||
const swipeHandlers = useSwipeable({
|
||||
onSwipedLeft: () => (app.primaryMenu ? app.setPrimaryMenu(false) : null),
|
||||
onSwipedRight: () => (app.primaryMenu ? null : app.setPrimaryMenu(true)),
|
||||
trackMouse: true,
|
||||
})
|
||||
|
||||
/*
|
||||
* Hotkeys (keyboard actions)
|
||||
*/
|
||||
// Trigger search with /
|
||||
useHotkeys('/', (evt) => {
|
||||
evt.preventDefault()
|
||||
setSearch(true)
|
||||
})
|
||||
|
||||
// Always close modal when Escape key is hit
|
||||
useHotkeys('esc', (evt) => {
|
||||
evt.preventDefault()
|
||||
app.setModal(false)
|
||||
})
|
||||
|
||||
// Search state
|
||||
const [search, setSearch] = useState(false)
|
||||
|
||||
// Helper object to pass props down (keeps things DRY)
|
||||
const childProps = {
|
||||
app: app,
|
||||
footer,
|
||||
search,
|
||||
setSearch,
|
||||
toggleSearch: () => setSearch(!search),
|
||||
noSearch: noSearch,
|
||||
title,
|
||||
}
|
||||
|
||||
// Make layout prop into a (uppercase) component
|
||||
const Layout = layout
|
||||
|
||||
// Return wrapper
|
||||
return (
|
||||
<div
|
||||
ref={swipeHandlers.ref}
|
||||
onMouseDown={swipeHandlers.onMouseDown}
|
||||
data-theme={currentTheme} // This facilitates CSS selectors
|
||||
key={currentTheme} // This forces the data-theme update
|
||||
>
|
||||
<Feeds />
|
||||
<LayoutWrapper {...childProps}>
|
||||
{Layout ? <Layout {...childProps}>{children}</Layout> : children}
|
||||
</LayoutWrapper>
|
||||
{app.modal ? (
|
||||
<div
|
||||
className={`fixed top-0 left-0 m-0 p-0 shadow drop-shadow-lg w-full h-screen
|
||||
bg-base-100 bg-opacity-90 z-50 hover:cursor-pointer
|
||||
flex flex-row items-center justify-center
|
||||
`}
|
||||
onClick={() => app.setModal(false)}
|
||||
>
|
||||
{app.modal}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue