1
0
Fork 0

shared component for views that have patterns and side menus

This commit is contained in:
Enoch Riese 2023-06-23 17:45:50 -05:00
parent 22bb896bc2
commit 6c94afe99f
18 changed files with 221 additions and 210 deletions

View file

@ -1,11 +1,11 @@
import { useContext, useState, useEffect, useCallback } from 'react' import { useContext, useState, useEffect, useCallback } from 'react'
import { ModalContext } from 'shared/context/modal-context.mjs' import { ModalContext } from 'shared/context/modal-context.mjs'
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs' import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
import { CloseIcon } from 'shared/components/icons.mjs' import { CloseIcon, WrenchIcon } from 'shared/components/icons.mjs'
import { shownHeaderSelector } from 'shared/components/wrappers/header.mjs' import { shownHeaderSelector } from 'shared/components/wrappers/header.mjs'
export const MenuWrapper = ({ Icon, children, childProps }) => { export const MenuWrapper = ({ children }) => {
const { setModal, clearModal, setModalProps, modalContent } = useContext(ModalContext) const { setModal, clearModal, modalContent } = useContext(ModalContext)
const [modalOpen, setModalOpen] = useState(false) const [modalOpen, setModalOpen] = useState(false)
const Modal = useCallback( const Modal = useCallback(
@ -17,7 +17,7 @@ export const MenuWrapper = ({ Icon, children, childProps }) => {
return ( return (
<ModalWrapper slideFrom="right" keepOpenOnClick keepOpenOnSwipe> <ModalWrapper slideFrom="right" keepOpenOnClick keepOpenOnSwipe>
{children(props)} {children}
<button <button
className="btn btn-primary btn-circle sticky bottom-2 float-right" className="btn btn-primary btn-circle sticky bottom-2 float-right"
onClick={closeModal} onClick={closeModal}
@ -33,8 +33,8 @@ export const MenuWrapper = ({ Icon, children, childProps }) => {
useEffect(() => { useEffect(() => {
if (!modalOpen) return if (!modalOpen) return
setModal(Modal, childProps) setModal(Modal)
}, [childProps, modalOpen, Modal]) }, [modalOpen, Modal])
useEffect(() => { useEffect(() => {
if (modalContent === null) setModalOpen(false) if (modalContent === null) setModalOpen(false)
@ -46,11 +46,14 @@ export const MenuWrapper = ({ Icon, children, childProps }) => {
return ( return (
<> <>
<div className="hidden lg:block">{children(childProps)}</div> <button
<div className="lg:hidden"> className={`btn btn-primary btn-circle sticky m-4 bottom-16 self-end lg:hidden`}
<button className={`btn btn-primary btn-circle fixed right-2 bottom-16`} onClick={onClick}> onClick={onClick}
<Icon />{' '} >
</button> <WrenchIcon />{' '}
</button>
<div className="hidden lg:block w-1/3 shrink grow-0 lg:p-4 max-w-2xl h-full overflow-scroll">
{children}
</div> </div>
</> </>
) )

View file

@ -2,6 +2,7 @@ import { useEffect, useCallback } from 'react'
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import { CutMenu, ns as menuNs } from './menu.mjs' import { CutMenu, ns as menuNs } from './menu.mjs'
import { MovablePattern } from 'shared/components/workbench/pattern/movable/index.mjs' import { MovablePattern } from 'shared/components/workbench/pattern/movable/index.mjs'
import { PatternWithMenu, ns as wrapperNs } from '../pattern-with-menu.mjs'
import { IconWrapper } from 'shared/components/icons.mjs' import { IconWrapper } from 'shared/components/icons.mjs'
import { import {
activeMaterialPath, activeMaterialPath,
@ -11,7 +12,7 @@ import {
useMaterialLength, useMaterialLength,
} from './hooks' } from './hooks'
export const ns = [...menuNs] export const ns = [...menuNs, ...wrapperNs]
const SheetIcon = (props) => ( const SheetIcon = (props) => (
<IconWrapper {...props}> <IconWrapper {...props}>
@ -44,6 +45,7 @@ export const CutView = ({
account, account,
DynamicDocs, DynamicDocs,
Design, Design,
setSettings,
}) => { }) => {
const { t } = useTranslation(['workbench', 'plugin']) const { t } = useTranslation(['workbench', 'plugin'])
@ -64,15 +66,22 @@ export const CutView = ({
}, [materialSettings, materialList, setActiveMaterial]) }, [materialSettings, materialList, setActiveMaterial])
return ( return (
<div> <PatternWithMenu
<div className="flex flex-row"> {...{
<div className="w-2/3 shrink-0 grow lg:p-4 sticky top-0"> settings,
<div className="flex justify-between items-baseline"> ui,
update,
control: account.control,
setSettings,
title: (
<div className="px-2 flex flex-wrap justify-between items-baseline">
<h2 className="capitalize"> <h2 className="capitalize">
{t('layoutThing', { thing: design }) + ' ' + t('forCutting')} {t('layoutThing', { thing: design }) + ' ' + t('forCutting')}
</h2> </h2>
<MaterialCounter settings={settings} renderProps={renderProps} /> <MaterialCounter settings={settings} renderProps={renderProps} />
</div> </div>
),
pattern: (
<div className="my-4"> <div className="my-4">
{materialList.length > 1 ? ( {materialList.length > 1 ? (
<div className="tabs"> <div className="tabs">
@ -99,8 +108,8 @@ export const CutView = ({
}} }}
/> />
</div> </div>
</div> ),
<div className="w-1/3 shrink grow-0 lg:p-4 max-w-2xl h-screen overflow-scroll"> menu: (
<CutMenu <CutMenu
{...{ {...{
design, design,
@ -115,8 +124,8 @@ export const CutView = ({
materialSettings, materialSettings,
}} }}
/> />
</div> ),
</div> }}
</div> />
) )
} }

View file

@ -19,7 +19,7 @@ const CutActions = ({ update, ui, materialSettings }) => {
const resetLayout = () => update.ui(['layouts', 'cut', materialSettings.activeMaterial]) const resetLayout = () => update.ui(['layouts', 'cut', materialSettings.activeMaterial])
return ( return (
<div className="mt-2 mb-4"> <div>
<div className="flex justify-evenly flex-col lg:flex-row"> <div className="flex justify-evenly flex-col lg:flex-row">
<ShowButtonsToggle update={update} ui={ui} /> <ShowButtonsToggle update={update} ui={ui} />
<button className="btn btn-primary btn-outline" onClick={resetLayout}> <button className="btn btn-primary btn-outline" onClick={resetLayout}>

View file

@ -1,9 +1,8 @@
import { PanZoomPattern as ShowPattern } from 'shared/components/workbench/pan-zoom-pattern.mjs' import { PanZoomPattern as ShowPattern } from 'shared/components/workbench/pan-zoom-pattern.mjs'
import { DraftMenu, ns as menuNs } from './menu.mjs' import { DraftMenu, ns as menuNs } from './menu.mjs'
import { ViewHeader, ns as headerNs } from 'shared/components/workbench/views/view-header.mjs' import { PatternWithMenu, ns as wrapperNs } from '../pattern-with-menu.mjs'
import { PanZoomContextProvider } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
export const ns = [menuNs, ...headerNs] export const ns = [...menuNs, ...wrapperNs]
export const DraftView = ({ export const DraftView = ({
design, design,
@ -34,39 +33,33 @@ export const DraftView = ({
} }
return ( return (
<PanZoomContextProvider> <PatternWithMenu
<div className="flex flex-col"> {...{
<ViewHeader settings,
{...{ ui,
settings, update,
ui, control: account.control,
update, pattern: output,
control: account.control, setSettings,
setSettings, menu: (
}} <DraftMenu
/> {...{
<div className="flex flex-row"> design,
<div className="w-2/3 shrink-0 grow lg:p-4 sticky top-0">{output}</div> pattern,
<div className="w-1/3 shrink grow-0 lg:p-4 max-w-2xl h-screen overflow-scroll"> patternConfig,
<DraftMenu settings,
{...{ ui,
design, update,
pattern, language,
patternConfig, account,
settings, DynamicDocs,
ui, renderProps,
update, view,
language, setView,
account, }}
DynamicDocs, />
renderProps, ),
view, }}
setView, />
}}
/>
</div>
</div>
</div>
</PanZoomContextProvider>
) )
} }

View file

@ -7,46 +7,38 @@ import {
ns as coreMenuNs, ns as coreMenuNs,
} from 'shared/components/workbench/menus/core-settings/index.mjs' } from 'shared/components/workbench/menus/core-settings/index.mjs'
import { UiSettings, ns as uiNs } from 'shared/components/workbench/menus/ui-settings/index.mjs' import { UiSettings, ns as uiNs } from 'shared/components/workbench/menus/ui-settings/index.mjs'
import { MenuWrapper } from 'shared/components/workbench/menus/shared/menu-wrapper.mjs'
import { WrenchIcon } from 'shared/components/icons.mjs'
export const ns = [...coreMenuNs, ...designMenuNs, ...uiNs] export const ns = [...coreMenuNs, ...designMenuNs, ...uiNs]
export const DraftMenu = (props) => { export const DraftMenu = ({
return ( design,
<MenuWrapper Icon={WrenchIcon} childProps={props}> patternConfig,
{({ settings,
design, ui,
patternConfig, update,
settings, language,
ui, account,
update, DynamicDocs,
language, view,
account, setView,
DynamicDocs, }) => {
view, const control = account.control
setView, const menuProps = {
}) => { design,
const control = account.control patternConfig,
const menuProps = { settings,
design, update,
patternConfig, language,
settings, account,
update, DynamicDocs,
language, control,
account, }
DynamicDocs,
control,
}
return ( return (
<nav className="grow mb-12"> <nav>
<DesignOptions {...menuProps} /> <DesignOptions {...menuProps} />
<CoreSettings {...menuProps} /> <CoreSettings {...menuProps} />
<UiSettings {...menuProps} {...{ ui, view, setView }} /> <UiSettings {...menuProps} {...{ ui, view, setView }} />
</nav> </nav>
)
}}
</MenuWrapper>
) )
} }

View file

@ -2,16 +2,16 @@ import { useState } from 'react'
import { InspectorPattern } from './inspector/pattern.mjs' import { InspectorPattern } from './inspector/pattern.mjs'
import { DraftMenu, ns as menuNs } from './menu.mjs' import { DraftMenu, ns as menuNs } from './menu.mjs'
import { objUpdate } from 'shared/utils.mjs' import { objUpdate } from 'shared/utils.mjs'
import { ViewHeader } from '../view-header.mjs' import { PatternWithMenu, ns as wrapperNs } from '../pattern-with-menu.mjs'
import { PanZoomContextProvider } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
export const ns = menuNs export const ns = [...menuNs, ...wrapperNs]
export const InspectView = ({ export const InspectView = ({
design, design,
pattern, pattern,
patternConfig, patternConfig,
settings, settings,
setSettings,
ui, ui,
update, update,
language, language,
@ -67,39 +67,34 @@ export const InspectView = ({
} }
return ( return (
<PanZoomContextProvider> <PatternWithMenu
<div className="flex flex-col"> {...{
<ViewHeader settings,
{...{ ui,
settings, update,
ui, control: account.control,
update, setSettings,
control: account.control, pattern: output,
}} menu: (
/> <DraftMenu
<div className="flex flex-row"> {...{
<div className="w-2/3 shrink-0 grow lg:p-4 sticky top-0">{output}</div> design,
<div className="w-1/3 shrink grow-0 lg:p-4 max-w-2xl h-screen overflow-scroll"> pattern,
<DraftMenu patternConfig,
{...{ settings,
design, ui,
pattern, update,
patternConfig, language,
settings, account,
ui, DynamicDocs,
update, inspector,
language, renderProps,
account, view,
DynamicDocs, setView,
inspector, }}
renderProps, />
view, ),
setView, }}
}} />
/>
</div>
</div>
</div>
</PanZoomContextProvider>
) )
} }

View file

@ -123,7 +123,7 @@ const StackFinder = ({ renderProps, inspector, t }) => {
<select <select
className="select select-bordered w-full" className="select select-bordered w-full"
onChange={findPath} onChange={findPath}
defaultvalue="__title" defaultValue="__title"
> >
<option disabled value="__title"> <option disabled value="__title">
Paths Paths

View file

@ -38,7 +38,7 @@ export const DraftMenu = ({
} }
return ( return (
<nav className="grow mb-12"> <nav>
<Inspector {...menuProps} {...{ ui, inspector, renderProps }} /> <Inspector {...menuProps} {...{ ui, inspector, renderProps }} />
<DesignOptions {...menuProps} /> <DesignOptions {...menuProps} />
<CoreSettings {...menuProps} /> <CoreSettings {...menuProps} />

View file

@ -0,0 +1,37 @@
import { PanZoomContextProvider } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
import { ViewHeader, ns as headerNs } from './view-header.mjs'
import { MenuWrapper } from 'shared/components/workbench/menus/shared/menu-wrapper.mjs'
export const ns = headerNs
export const PatternWithMenu = ({
settings,
ui,
update,
control,
title,
pattern,
menu,
setSettings,
}) => (
<PanZoomContextProvider>
<div className="flex flex-col h-full">
<ViewHeader
{...{
settings,
ui,
update,
control,
setSettings,
}}
/>
<div className="flex flex-col lg:flex-row grow max-h-[90vh] lg:my-4">
<div className="lg:w-2/3 flex flex-col h-full grow px-4">
{title}
{pattern}
</div>
{menu && <MenuWrapper>{menu}</MenuWrapper>}
</div>
</div>
</PanZoomContextProvider>
)

View file

@ -12,9 +12,10 @@ import { defaultPrintSettings, printSettingsPath } from './config.mjs'
import { PrintIcon, RightIcon } from 'shared/components/icons.mjs' import { PrintIcon, RightIcon } from 'shared/components/icons.mjs'
import { LoadingContext } from 'shared/context/loading-context.mjs' import { LoadingContext } from 'shared/context/loading-context.mjs'
import { useToast } from 'shared/hooks/use-toast.mjs' import { useToast } from 'shared/hooks/use-toast.mjs'
import { PatternWithMenu, ns as wrapperNs } from '../pattern-with-menu.mjs'
const viewNs = ['print', ...exportNs] const viewNs = ['print', ...exportNs]
export const ns = [...viewNs, ...menuNs] export const ns = [...viewNs, ...menuNs, ...wrapperNs]
const PageCounter = ({ pattern }) => { const PageCounter = ({ pattern }) => {
const pages = pattern.setStores[0].get('pages', {}) const pages = pattern.setStores[0].get('pages', {})
@ -40,6 +41,7 @@ export const PrintView = ({
pattern, pattern,
patternConfig, patternConfig,
settings, settings,
setSettings,
ui, ui,
update, update,
language, language,
@ -85,15 +87,22 @@ export const PrintView = ({
} }
return ( return (
<div> <PatternWithMenu
<div className="flex flex-row"> {...{
<div className="w-2/3 shrink-0 grow lg:p-4 sticky top-0"> settings,
<div className="flex justify-between items-baseline"> ui,
<h2 className="capitalize"> update,
control: account.control,
setSettings,
title: (
<div className="flex lg:justify-between items-baseline flex-wrap px-2">
<h2 className="text-center lg:text-left capitalize">
{t('layoutThing', { thing: design }) + ' ' + t('forPrinting')} {t('layoutThing', { thing: design }) + ' ' + t('forPrinting')}
</h2> </h2>
<PageCounter pattern={pattern} /> <PageCounter pattern={pattern} />
</div> </div>
),
pattern: (
<MovablePattern <MovablePattern
{...{ {...{
renderProps, renderProps,
@ -103,8 +112,8 @@ export const PrintView = ({
showButtons: !ui.hideMovableButtons, showButtons: !ui.hideMovableButtons,
}} }}
/> />
</div> ),
<div className="w-1/3 shrink grow-0 lg:p-4 max-w-2xl h-screen overflow-scroll"> menu: (
<PrintMenu <PrintMenu
{...{ {...{
design, design,
@ -119,8 +128,8 @@ export const PrintView = ({
exportIt, exportIt,
}} }}
/> />
</div> ),
</div> }}
</div> />
) )
} }

View file

@ -34,7 +34,7 @@ export const PrintMenu = ({
control, control,
} }
return ( return (
<nav className="grow mb-12"> <nav>
<PrintActions {...menuProps} ui={ui} exportIt={exportIt} /> <PrintActions {...menuProps} ui={ui} exportIt={exportIt} />
<PrintSettings {...menuProps} ui={ui} /> <PrintSettings {...menuProps} ui={ui} />
<DesignOptions {...menuProps} isFirst={false} /> <DesignOptions {...menuProps} isFirst={false} />

View file

@ -1,10 +1,9 @@
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import { PanZoomPattern } from 'shared/components/workbench/pan-zoom-pattern.mjs' import { PanZoomPattern } from 'shared/components/workbench/pan-zoom-pattern.mjs'
import { TestMenu, ns as menuNs } from './menu.mjs' import { TestMenu, ns as menuNs } from './menu.mjs'
import { ViewHeader } from '../view-header.mjs' import { PatternWithMenu, ns as wrapperNs } from '../pattern-with-menu.mjs'
import { PanZoomContextProvider } from 'shared/components/workbench/pattern/pan-zoom-context.mjs'
export const ns = menuNs export const ns = [...menuNs, wrapperNs]
export const TestView = ({ export const TestView = ({
design, design,
@ -14,6 +13,7 @@ export const TestView = ({
update, update,
language, language,
account, account,
setSettings,
DynamicDocs, DynamicDocs,
}) => { }) => {
const { t } = useTranslation(ns) const { t } = useTranslation(ns)
@ -26,39 +26,32 @@ export const TestView = ({
const title = t('testThing', { design, thing: t(settings.sample?.[settings.sample.type]) }) const title = t('testThing', { design, thing: t(settings.sample?.[settings.sample.type]) })
return ( return (
<PanZoomContextProvider> <PatternWithMenu
<div className="flex flex-col"> {...{
<ViewHeader settings,
{...{ ui,
settings, update,
ui, control: account.control,
update, setSettings,
control: account.control, title: <h2 className="px-2 capitalize">{title}</h2>,
}} pattern: <PanZoomPattern {...{ renderProps }} />,
/> menu: (
<div className="flex flex-row ml-0 lg:ml-10"> <TestMenu
<div className="w-2/3 shrink-0 grow lg:p-4 sticky top-0"> {...{
<h2 className="capitalize">{title}</h2> design,
<PanZoomPattern {...{ renderProps }} /> pattern,
</div> patternConfig,
<div className="w-1/3 shrink grow-0 lg:p-4 max-w-2xl h-screen overflow-scroll"> settings,
<TestMenu ui,
{...{ update,
design, language,
pattern, account,
patternConfig, DynamicDocs,
settings, renderProps,
ui, }}
update, />
language, ),
account, }}
DynamicDocs, />
renderProps,
}}
/>
</div>
</div>
</div>
</PanZoomContextProvider>
) )
} }

View file

@ -24,7 +24,7 @@ export const TestMenu = ({
} }
return ( return (
<nav className="grow mb-12"> <nav>
<TestOptions {...menuProps} /> <TestOptions {...menuProps} />
<TestMeasurements {...menuProps} /> <TestMeasurements {...menuProps} />
</nav> </nav>

View file

@ -21,7 +21,7 @@ export const SampleItem = ({ name, passProps, t, updateFunc }) => {
return ( return (
<div <div
className={`collapse my-2 shadow border-solid border-l-[6px] min-h-10 rounded-none className={`collapse my-2 shadow border-solid border-l-[6px] min-h-10 rounded-none w-full
${checked ? openClasses : closedClasses}`} ${checked ? openClasses : closedClasses}`}
> >
<input <input

View file

@ -77,17 +77,8 @@ export const ViewHeader = ({ update, settings, ui, control, setSettings }) => {
const { t } = useTranslation(ns) const { t } = useTranslation(ns)
return ( return (
<div <div
className={`flex sticky top-0 z-20 lg:${shownHeaderSelector}top-24 transition-[top] duration-300 ease-in-out drawer`} className={`hidden lg:flex sticky top-0 z-20 lg:${shownHeaderSelector}top-24 transition-[top] duration-300 ease-in-out drawer`}
> >
<label htmlFor="view-header" className="btn btn-primary btn-circle m-2 swap">
<input type="checkbox" id="view-header" />
<span className="swap-off">
<WrenchIcon />
</span>
<span className="swap-on">
<CloseIcon />
</span>
</label>
<div className="hidden lg:flex flex-row flex-wrap gap-4 py-4 pt-4 w-full bg-neutral text-neutral-content items-center justify-center"> <div className="hidden lg:flex flex-row flex-wrap gap-4 py-4 pt-4 w-full bg-neutral text-neutral-content items-center justify-center">
<ZoomButtons t={t} /> <ZoomButtons t={t} />
<Spacer /> <Spacer />

View file

@ -67,7 +67,7 @@ export const ModalWrapper = ({
children children
) : ( ) : (
<div <div
className={`bg-base-100 p-4 lg:px-8 lg:rounded-lg lg:shadow-lg max-h-full overflow-auto`} className={`bg-base-100 p-4 lg:px-8 lg:rounded-lg lg:shadow-lg max-h-full overflow-auto grow`}
> >
{children} {children}
</div> </div>

View file

@ -33,7 +33,7 @@ export const PageWrapper = (props) => {
/* /*
* Contexts * Contexts
*/ */
const { modalContent, modalProps } = useContext(ModalContext) const { modalContent } = useContext(ModalContext)
const { setNavigation, slug } = useContext(NavigationContext) const { setNavigation, slug } = useContext(NavigationContext)
/* /*
@ -94,7 +94,7 @@ export const PageWrapper = (props) => {
<LayoutWrapper {...childProps}> <LayoutWrapper {...childProps}>
{Layout ? <Layout {...childProps}>{children}</Layout> : children} {Layout ? <Layout {...childProps}>{children}</Layout> : children}
</LayoutWrapper> </LayoutWrapper>
{typeof modalContent === 'function' ? modalContent(modalProps) : modalContent} {typeof modalContent === 'function' ? modalContent() : modalContent}
</div> </div>
</SwipeWrapper> </SwipeWrapper>
) )

View file

@ -7,7 +7,6 @@ export const ModalContextProvider = ({ children }) => {
__setModal({ __setModal({
...__modal, ...__modal,
modalContent: null, modalContent: null,
modalProps: {},
}) })
} }
@ -15,23 +14,13 @@ export const ModalContextProvider = ({ children }) => {
__setModal({ __setModal({
...__modal, ...__modal,
modalContent: content, modalContent: content,
modalProps: props,
})
}
function setModalProps(props = {}) {
__setModal({
...__modal,
modalProps: props,
}) })
} }
const [__modal, __setModal] = useState({ const [__modal, __setModal] = useState({
setModal, setModal,
clearModal, clearModal,
setModalProps,
modalContent: null, modalContent: null,
modalProps: {},
}) })
return <ModalContext.Provider value={__modal}>{children}</ModalContext.Provider> return <ModalContext.Provider value={__modal}>{children}</ModalContext.Provider>