fix(lab): Add mobile navigation
This commit is contained in:
parent
f7f920526a
commit
c3e54687fc
11 changed files with 46 additions and 62 deletions
|
@ -5,6 +5,7 @@ import Link from 'next/link'
|
||||||
import Logo from 'shared/components/logos/freesewing.js'
|
import Logo from 'shared/components/logos/freesewing.js'
|
||||||
import Aside from 'shared/components/navigation/aside'
|
import Aside from 'shared/components/navigation/aside'
|
||||||
import get from 'lodash.get'
|
import get from 'lodash.get'
|
||||||
|
import { BeforeNav } from './lab'
|
||||||
|
|
||||||
const PageTitle = ({ app, slug, title }) => {
|
const PageTitle = ({ app, slug, title }) => {
|
||||||
if (title) return <h1>{title}</h1>
|
if (title) return <h1>{title}</h1>
|
||||||
|
@ -56,10 +57,10 @@ const Breadcrumbs = ({ app, slug=false, title }) => {
|
||||||
const DefaultLayout = ({ app, title=false, children=[] }) => {
|
const DefaultLayout = ({ app, title=false, children=[] }) => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const slug = router.asPath.slice(1)
|
const slug = router.asPath.slice(1)
|
||||||
|
console.log(BeforeNav)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Aside app={app} slug={slug} mobileOnly />
|
<Aside app={app} slug={slug} before={<BeforeNav app={app}/>} mobileOnly />
|
||||||
{children}
|
{children}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
import ThemePicker from 'shared/components/theme-picker.js'
|
||||||
|
import LocalePicker from 'shared/components/locale-picker.js'
|
||||||
|
import PatternPicker from 'site/components/pattern-picker.js'
|
||||||
|
import VersionPicker from 'site/components/version-picker.js'
|
||||||
|
|
||||||
|
export const BeforeNav = ({ app }) => (
|
||||||
|
<>
|
||||||
|
<div className="md:hidden flex flex-row flex-wrap sm:flex-nowrap gap-2 mb-2">
|
||||||
|
<ThemePicker app={app} />
|
||||||
|
<LocalePicker app={app} />
|
||||||
|
</div>
|
||||||
|
<div className="md:hidden flex flex-row flex-wrap sm:flex-nowrap gap-2 mb-2">
|
||||||
|
<PatternPicker app={app} />
|
||||||
|
<VersionPicker app={app} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
const LabLayout = ({ app, AltMenu, children=[] }) => (
|
const LabLayout = ({ app, AltMenu, children=[] }) => (
|
||||||
<div className="py-24 lg:py-36 flex flex-row">
|
<div className="py-24 lg:py-36 flex flex-row">
|
||||||
<div className="w-full px-8">
|
<div className="w-full px-8">
|
||||||
|
@ -24,6 +42,7 @@ const LabLayout = ({ app, AltMenu, children=[] }) => (
|
||||||
lg:w-96
|
lg:w-96
|
||||||
shrink-0
|
shrink-0
|
||||||
`}>
|
`}>
|
||||||
|
<BeforeNav app={app}/>
|
||||||
{AltMenu}
|
{AltMenu}
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,10 +10,10 @@ const PatternPicker = ({ app }) => {
|
||||||
const version = useVersion()
|
const version = useVersion()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dropdown">
|
<div className="dropdown w-full md:w-auto">
|
||||||
<div tabIndex="0" className={`
|
<div tabIndex="0" className={`
|
||||||
m-0 btn btn-neutral flex flex-row gap-2
|
m-0 btn btn-neutral flex flex-row gap-2 btn-outline
|
||||||
sm:btn-ghost
|
md:btn-ghost
|
||||||
hover:bg-neutral hover:border-neutral-content
|
hover:bg-neutral hover:border-neutral-content
|
||||||
`}>
|
`}>
|
||||||
<DesignIcon />
|
<DesignIcon />
|
||||||
|
|
|
@ -24,10 +24,10 @@ const PatternPicker = ({ app }) => {
|
||||||
const version = useVersion()
|
const version = useVersion()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dropdown">
|
<div className="dropdown w-full md:w-auto">
|
||||||
<div tabIndex="0" className={`
|
<div tabIndex="0" className={`
|
||||||
m-0 btn btn-neutral flex flex-row gap-2
|
m-0 btn btn-neutral flex flex-row gap-2 btn-outline
|
||||||
sm:btn-ghost
|
md:btn-ghost
|
||||||
hover:bg-neutral hover:border-neutral-content
|
hover:bg-neutral hover:border-neutral-content
|
||||||
`}>
|
`}>
|
||||||
<VersionsIcon />
|
<VersionsIcon />
|
||||||
|
|
|
@ -11,7 +11,6 @@ import Left from 'shared/components/icons/left.js'
|
||||||
// Site components
|
// Site components
|
||||||
import Header from 'site/components/header'
|
import Header from 'site/components/header'
|
||||||
import Footer from 'site/components/footer'
|
import Footer from 'site/components/footer'
|
||||||
import Search from 'site/components/search'
|
|
||||||
|
|
||||||
export const PageTitle = ({ app, slug, title }) => {
|
export const PageTitle = ({ app, slug, title }) => {
|
||||||
if (title) return <h1>{title}</h1>
|
if (title) return <h1>{title}</h1>
|
||||||
|
@ -60,30 +59,18 @@ export const Breadcrumbs = ({ app, slug=false, title }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const LayoutWrapper = ({
|
const LayoutWrapper = ({ app, title=false, children=[] }) => {
|
||||||
app,
|
|
||||||
title=false,
|
|
||||||
children=[],
|
|
||||||
search,
|
|
||||||
setSearch,
|
|
||||||
noSearch=false,
|
|
||||||
workbench=false,
|
|
||||||
AltMenu=null,
|
|
||||||
}) => {
|
|
||||||
const startNavigation = () => {
|
const startNavigation = () => {
|
||||||
app.startLoading()
|
app.startLoading()
|
||||||
// Force close of menu on mobile if it is open
|
// Force close of menu on mobile if it is open
|
||||||
if (app.primaryNavigation) app.setPrimaryNavigation(false)
|
if (app.primaryNavigation) app.setPrimaryNavigation(false)
|
||||||
// Force close of search modal if it is open
|
|
||||||
if (search) setSearch(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
router.events?.on('routeChangeStart', startNavigation)
|
router.events?.on('routeChangeStart', startNavigation)
|
||||||
router.events?.on('routeChangeComplete', () => app.stopLoading())
|
router.events?.on('routeChangeComplete', app.stopLoading)
|
||||||
const slug = router.asPath.slice(1)
|
const slug = router.asPath.slice(1)
|
||||||
const [collapsePrimaryNav, setCollapsePrimaryNav] = useState(workbench || false)
|
|
||||||
const [collapseAltMenu, setCollapseAltMenu] = useState(false)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`
|
<div className={`
|
||||||
|
@ -91,22 +78,8 @@ const LayoutWrapper = ({
|
||||||
min-h-screen
|
min-h-screen
|
||||||
bg-base-100
|
bg-base-100
|
||||||
`}>
|
`}>
|
||||||
<Header app={app} setSearch={setSearch} />
|
<Header app={app}/>
|
||||||
<main className="grow">{children}</main>
|
<main className="grow">{children}</main>
|
||||||
{!noSearch && search && (
|
|
||||||
<>
|
|
||||||
<div className={`
|
|
||||||
fixed w-full max-h-screen bg-base-100 top-0 z-30 pt-0 pb-16 px-8
|
|
||||||
md:rounded-lg md:top-24
|
|
||||||
md:max-w-xl md:m-auto md:inset-x-12
|
|
||||||
md:max-w-2xl
|
|
||||||
lg:max-w-4xl
|
|
||||||
`}>
|
|
||||||
<Search app={app} search={search} setSearch={setSearch}/>
|
|
||||||
</div>
|
|
||||||
<div className="fixed top-0 left-0 w-full min-h-screen bg-neutral z-20 bg-opacity-70"></div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<Footer app={app} />
|
<Footer app={app} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,7 +8,6 @@ import LayoutWrapper from 'site/components/wrappers/layout'
|
||||||
/* This component should wrap all page content */
|
/* This component should wrap all page content */
|
||||||
const PageWrapper= ({
|
const PageWrapper= ({
|
||||||
title="FIXME: No title set",
|
title="FIXME: No title set",
|
||||||
noSearch=false,
|
|
||||||
app=false,
|
app=false,
|
||||||
layout=false,
|
layout=false,
|
||||||
children=[]
|
children=[]
|
||||||
|
@ -25,19 +24,9 @@ const PageWrapper= ({
|
||||||
|
|
||||||
useEffect(() => app.setSlug(slug), [slug])
|
useEffect(() => app.setSlug(slug), [slug])
|
||||||
|
|
||||||
// Trigger search with Ctrl+k
|
|
||||||
useHotkeys('ctrl+k', (evt) => {
|
|
||||||
evt.preventDefault()
|
|
||||||
setSearch(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
const [search, setSearch] = useState(false)
|
|
||||||
|
|
||||||
const childProps = {
|
const childProps = {
|
||||||
app: app,
|
app: app,
|
||||||
title: title,
|
title: title,
|
||||||
search, setSearch, toggleSearch: () => setSearch(!search),
|
|
||||||
noSearch: noSearch,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Layout = layout
|
const Layout = layout
|
||||||
|
|
|
@ -33,7 +33,7 @@ const HomePage = (props) => {
|
||||||
}}
|
}}
|
||||||
className="m-0 p-0 shadow drop-shadow-lg w-full mb-8"
|
className="m-0 p-0 shadow drop-shadow-lg w-full mb-8"
|
||||||
>
|
>
|
||||||
<div className="mx-auto px-8 flex flex-col items-center justify-center min-h-screen lg:min-h-0 lg:py-96">
|
<div className="mx-auto px-8 flex flex-col items-center justify-center min-h-screen py-24 lg:min-h-0 lg:py-96">
|
||||||
<div className="flex flex-col items-end max-w-4xl">
|
<div className="flex flex-col items-end max-w-4xl">
|
||||||
<h1
|
<h1
|
||||||
className={`
|
className={`
|
||||||
|
@ -76,7 +76,7 @@ const HomePage = (props) => {
|
||||||
</div>
|
</div>
|
||||||
<Icons app={app} active='/'
|
<Icons app={app} active='/'
|
||||||
ulClasses="flex flex-row flex-wrap mt-8 justify-around w-full max-w-6xl"
|
ulClasses="flex flex-row flex-wrap mt-8 justify-around w-full max-w-6xl"
|
||||||
liClasses="text-neutral-content w-1/3 my-4 lg:mx-2 lg:w-24"
|
liClasses="text-neutral-content w-1/2 my-4 lg:mx-2 lg:w-24"
|
||||||
linkClasses={`
|
linkClasses={`
|
||||||
text-lg lg:text-xl py-1 text-secondary text-center
|
text-lg lg:text-xl py-1 text-secondary text-center
|
||||||
hover:text-secondary sm:hover:text-secondary-focus hover:cursor-pointer
|
hover:text-secondary sm:hover:text-secondary-focus hover:cursor-pointer
|
||||||
|
|
|
@ -9,10 +9,10 @@ const LocalePicker = ({ app }) => {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="dropdown">
|
<div className="dropdown w-full md:w-auto">
|
||||||
<div tabIndex="0" className={`
|
<div tabIndex="0" className={`
|
||||||
m-0 btn btn-neutral flex flex-row gap-2
|
m-0 btn btn-neutral flex flex-row gap-2 btn-outline
|
||||||
sm:btn-ghost
|
md:btn-ghost
|
||||||
hover:bg-neutral hover:border-neutral-content
|
hover:bg-neutral hover:border-neutral-content
|
||||||
`}>
|
`}>
|
||||||
<LocaleIcon />
|
<LocaleIcon />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import PrimaryNavigation from './primary'
|
import PrimaryNavigation from './primary'
|
||||||
|
|
||||||
const Aside = ({ app, slug, mobileOnly=false }) => (
|
const Aside = ({ app, slug, mobileOnly=false, before=[], after=[]}) => (
|
||||||
<aside className={`
|
<aside className={`
|
||||||
fixed top-0 right-0 h-screen w-screen
|
fixed top-0 right-0 h-screen w-screen
|
||||||
overflow-y-auto z-20
|
overflow-y-auto z-20
|
||||||
|
@ -17,7 +17,9 @@ const Aside = ({ app, slug, mobileOnly=false }) => (
|
||||||
2xl:pr-8
|
2xl:pr-8
|
||||||
${mobileOnly ? 'block md:hidden' : ''}
|
${mobileOnly ? 'block md:hidden' : ''}
|
||||||
`}>
|
`}>
|
||||||
|
{before}
|
||||||
<PrimaryNavigation app={app} active={slug}/>
|
<PrimaryNavigation app={app} active={slug}/>
|
||||||
|
{after}
|
||||||
</aside>
|
</aside>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import orderBy from 'lodash.orderby'
|
import orderBy from 'lodash.orderby'
|
||||||
import ThemePicker from 'shared/components/theme-picker.js'
|
|
||||||
import RssIcon from 'shared/components/icons/rss.js'
|
import RssIcon from 'shared/components/icons/rss.js'
|
||||||
import TutorialIcon from 'shared/components/icons/tutorial.js'
|
import TutorialIcon from 'shared/components/icons/tutorial.js'
|
||||||
import GuideIcon from 'shared/components/icons/guide.js'
|
import GuideIcon from 'shared/components/icons/guide.js'
|
||||||
|
@ -231,11 +230,12 @@ export const Icons = ({
|
||||||
return <ul className={ulClasses}>{output}</ul>
|
return <ul className={ulClasses}>{output}</ul>
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrimaryMenu = ({ app, active }) => (
|
const PrimaryMenu = ({ app, active, before=[], after=[] }) => (
|
||||||
<nav className="mb-12">
|
<nav className="mb-12">
|
||||||
<ThemePicker app={app} className="w-full md:hidden"/>
|
{before}
|
||||||
<Icons app={app} ulClasses="hidden md:block lg:hidden flex flex-col items-center"/>
|
<Icons app={app} ulClasses="hidden md:block lg:hidden flex flex-col items-center"/>
|
||||||
<Navigation app={app} active={active} className="md:hidden lg:block"/>
|
<Navigation app={app} active={active} className="md:hidden lg:block"/>
|
||||||
|
{after}
|
||||||
</nav>
|
</nav>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ const ThemePicker = ({ app, className }) => {
|
||||||
const { t } = useTranslation(['themes'])
|
const { t } = useTranslation(['themes'])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`dropdown ${className}`}>
|
<div className={`dropdown ${className} w-full md:w-auto`}>
|
||||||
<div tabIndex="0" className={`
|
<div tabIndex="0" className={`
|
||||||
m-0 btn btn-neutral flex flex-row gap-2
|
m-0 btn btn-neutral flex flex-row gap-2 btn-outline
|
||||||
sm:btn-ghost
|
md:btn-ghost
|
||||||
hover:bg-neutral hover:border-neutral-content
|
hover:bg-neutral hover:border-neutral-content
|
||||||
`}>
|
`}>
|
||||||
<ThemeIcon />
|
<ThemeIcon />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue