chore(shared): Changes kiosk/expand/flags/header
- Revamped the flags ui to be consistent with the rest - The expand setting is on by default now. Tweaks to its dialog and header - Added a new kiosk mode that will use the entire screen for the workbench - Got rid of the auto-hiding behaviour of the header which gets annoying quick
This commit is contained in:
parent
8247cd6832
commit
ddbbbda2bc
21 changed files with 89 additions and 86 deletions
|
@ -116,10 +116,10 @@ const NavIcons = ({ setModal, setSearch }) => {
|
|||
)
|
||||
}
|
||||
|
||||
export const Header = ({ show }) => {
|
||||
export const Header = () => {
|
||||
const { setModal } = useContext(ModalContext)
|
||||
return (
|
||||
<HeaderWrapper show={show}>
|
||||
<HeaderWrapper>
|
||||
<div className="m-auto">
|
||||
<div className="p-0 flex flex-row gap-2 justify-between text-neutral-content items-center">
|
||||
{/* Non-mobile content */}
|
||||
|
|
|
@ -13,7 +13,7 @@ export const DefaultLayout = ({ children = [], pageTitle = false }) => (
|
|||
|
||||
<BaseLayoutWide>
|
||||
{pageTitle && (
|
||||
<div className="xl:pl-4 md:pt-8">
|
||||
<div className="xl:pl-4">
|
||||
<Breadcrumbs />
|
||||
<h1 className="break-words">{pageTitle}</h1>
|
||||
</div>
|
||||
|
|
|
@ -60,7 +60,7 @@ export const DocsLayout = ({ children = [], frontmatter }) => {
|
|||
</BaseLayoutLeft>
|
||||
|
||||
<BaseLayoutProse>
|
||||
<div className="w-full md:pt-8">
|
||||
<div className="w-full">
|
||||
<Breadcrumbs />
|
||||
<h1 className="break-words searchme">{frontmatter.title}</h1>
|
||||
<div className="block xl:hidden">
|
||||
|
|
|
@ -31,7 +31,7 @@ export const PostLayout = ({ children = [], slug, frontmatter, locale }) => (
|
|||
</BaseLayoutLeft>
|
||||
|
||||
<BaseLayoutProse>
|
||||
<div className="w-full md:pt-8">
|
||||
<div className="w-full">
|
||||
<Breadcrumbs />
|
||||
<h1 className="break-words searchme">{frontmatter.title}</h1>
|
||||
<div className="block xl:hidden">
|
||||
|
|
|
@ -16,7 +16,7 @@ const NewDesignPage = ({ page, design }) => {
|
|||
const Design = useDesign(design)
|
||||
|
||||
return (
|
||||
<PageWrapper {...page} title={design} layout={WorkbenchLayout}>
|
||||
<PageWrapper {...page} title={design} layout={WorkbenchLayout} header={null}>
|
||||
<Workbench {...{ design, Design, DynamicDocs }} />
|
||||
</PageWrapper>
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* The default full-page FreeSewing layout
|
||||
*/
|
||||
export const BaseLayout = ({ children = [] }) => (
|
||||
<div className="flex flex-row items-start mt-8 w-full justify-between 2xl:px-36 xl:px-12 px-4 gap-0 lg:gap-4 xl:gap-8 3xl: gap-12">
|
||||
<div className="flex flex-row items-start w-full justify-between 2xl:px-36 xl:px-12 px-4 gap-0 lg:gap-4 xl:gap-8 3xl: gap-12">
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
|
@ -11,26 +11,26 @@ export const BaseLayout = ({ children = [] }) => (
|
|||
* The left column of the default layout
|
||||
*/
|
||||
export const BaseLayoutLeft = ({ children = [] }) => (
|
||||
<div className="max-w-96 w-1/4 mt-8 hidden lg:block shrink-0">{children}</div>
|
||||
<div className="max-w-96 w-1/4 hidden lg:block shrink-0 my-8">{children}</div>
|
||||
)
|
||||
|
||||
/*
|
||||
* The right column of the default layout
|
||||
*/
|
||||
export const BaseLayoutRight = ({ children = [] }) => (
|
||||
<div className="max-w-96 w-1/4 mt-8 hidden xl:block">{children}</div>
|
||||
<div className="max-w-96 w-1/4 hidden xl:block my-8">{children}</div>
|
||||
)
|
||||
|
||||
/*
|
||||
* The main column for prose (text like docs and so on)
|
||||
*/
|
||||
export const BaseLayoutProse = ({ children = [] }) => (
|
||||
<div className="grow w-full m-auto max-w-prose mt-0 mb-8">{children}</div>
|
||||
<div className="grow w-full m-auto max-w-prose my-8">{children}</div>
|
||||
)
|
||||
|
||||
/*
|
||||
* The central column for wide content (no max-width)
|
||||
*/
|
||||
export const BaseLayoutWide = ({ children = [] }) => (
|
||||
<div className="grow w-full m-auto mt-0 mb-8 grow">{children}</div>
|
||||
<div className="grow w-full m-auto my-8 grow">{children}</div>
|
||||
)
|
||||
|
|
|
@ -12,7 +12,7 @@ export const DesignPicker = ({ hrefBuilder = false }) => {
|
|||
for (const d in designs) translated[t(`${d}.t`)] = d
|
||||
|
||||
return (
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
<div className="flex flex-row flex-wrap gap-2 mt-8">
|
||||
{Object.keys(translated)
|
||||
.sort()
|
||||
.map((d) => (
|
||||
|
|
|
@ -391,6 +391,12 @@ export const KeyIcon = (props) => (
|
|||
</IconWrapper>
|
||||
)
|
||||
|
||||
export const KioskIcon = (props) => (
|
||||
<IconWrapper {...props}>
|
||||
<path d="M 3,17.033898 V 7.2838983 c 0,-1.242641 1.007359,-2.25 2.25,-2.25 h 13.5 c 1.242641,0 2.25,1.007359 2.25,2.25 v 9.7499997 m -18,0 c 0,1.242641 1.007359,2.25 2.25,2.25 h 13.5 c 1.242641,0 2.25,-1.007359 2.25,-2.25" />
|
||||
</IconWrapper>
|
||||
)
|
||||
|
||||
export const LabelIcon = (props) => (
|
||||
<IconWrapper {...props}>
|
||||
<path d="M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z" />
|
||||
|
|
|
@ -109,8 +109,8 @@ export const loadSettingsConfig = ({
|
|||
},
|
||||
expand: {
|
||||
control: 4, // Show when control > 3
|
||||
list: [0, 1],
|
||||
dflt: 0,
|
||||
list: [1, 0],
|
||||
dflt: 1,
|
||||
choiceTitles: {
|
||||
0: 'expandNo',
|
||||
1: 'expandYes',
|
||||
|
|
|
@ -3,7 +3,6 @@ import { ModalContext } from 'shared/context/modal-context.mjs'
|
|||
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
||||
import { CloseIcon } from 'shared/components/icons.mjs'
|
||||
import { MobileMenubarContext } from 'shared/context/mobile-menubar-context.mjs'
|
||||
import { shownHeaderSelector } from 'shared/components/wrappers/header.mjs'
|
||||
import { MenuAltIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
/**
|
||||
|
@ -64,7 +63,6 @@ export const MobileMenubar = () => {
|
|||
<div
|
||||
className={`
|
||||
lg:hidden
|
||||
${shownHeaderSelector('bottom-16')}
|
||||
sticky bottom-0 w-20 -ml-20 self-end
|
||||
duration-300 transition-all
|
||||
flex flex-col-reverse gap-2 mb-2
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { RocketIcon, ControlIcon } from 'shared/components/icons.mjs'
|
||||
import { RocketIcon, ControlIcon, KioskIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const loadSettingsConfig = () => {
|
||||
const uiSettings = {
|
||||
|
@ -9,12 +9,26 @@ export const loadSettingsConfig = () => {
|
|||
choiceTitles: {},
|
||||
icon: ControlIcon,
|
||||
},
|
||||
kiosk: {
|
||||
control: 4, // Show when control > 3
|
||||
list: [0, 1],
|
||||
choiceTitles: {
|
||||
0: 'ui-settings:websiteMode',
|
||||
1: 'ui-settings:kioskMode',
|
||||
},
|
||||
//valueTitles: {
|
||||
// react: 'ui-settings:regular',
|
||||
// svg: 'ui-settings:kiosk',
|
||||
//},
|
||||
dflt: 0,
|
||||
icon: KioskIcon,
|
||||
},
|
||||
renderer: {
|
||||
control: 4, // Show when control > 3
|
||||
list: ['react', 'svg'],
|
||||
choiceTitles: {
|
||||
react: 'renderWithReact',
|
||||
svg: 'renderWithCore',
|
||||
react: 'ui-settings:renderWithReact',
|
||||
svg: 'ui-settings:renderWithCore',
|
||||
},
|
||||
valueTitles: {
|
||||
react: 'React',
|
||||
|
|
|
@ -8,12 +8,13 @@ renderWithCore.t: Render with Freesewing's Core library
|
|||
renderWithCore.d: Render directly to SVG from Core. Allows no interactivity and is optimized for print. Use this if you want to know what it will look like when exported.
|
||||
control.t: User Experience
|
||||
control.d: Which user experience do you prefer? Please note that this is an account setting, so it will impact the entire website.
|
||||
inspect.t: Inspect
|
||||
inspect.d: Enabling this will allow you to drill down into the pattern, and pull up information about its various parts, paths, and points.
|
||||
inspectNo.t: Disable the inspector
|
||||
inspectNo.d: This is the default, the pattern inspector is disabled and the pattern is displayed as usual.
|
||||
inspectYes.t: Enable the inspector
|
||||
inspectYes.d: With the pattern inspector enabled and the React rendering engine selected, we will add interactivity to the pattern to allow you to inspect the various elements that make up the pattern.
|
||||
kiosk.t: Kiosk mode
|
||||
kiosk.d: Enable this to utilize the entire screen for the pattern drafting environment
|
||||
websiteMode.t: Regular mode
|
||||
websiteMode.d: Anchors the pattern drafting environment whithin the default website layout.
|
||||
kioskMode.t: Kiosk mode
|
||||
kioskMode.d: Utilizes the entire screen for the pattern drafting environment, hiding all other website elements.
|
||||
|
||||
no: No
|
||||
yes: Yes
|
||||
draft: Draft
|
||||
|
|
|
@ -16,6 +16,7 @@ export const ControlSettingInput = (props) => {
|
|||
}
|
||||
|
||||
export const inputs = {
|
||||
renderer: ListInput,
|
||||
control: ControlSettingInput,
|
||||
kiosk: ListInput,
|
||||
renderer: ListInput,
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Difficulty } from 'shared/components/designs/difficulty.mjs'
|
|||
import { ListValue } from '../shared/values.mjs'
|
||||
|
||||
export const values = {
|
||||
renderer: ListValue,
|
||||
control: ({ control }) => <Difficulty score={control} color="primary" />,
|
||||
kiosk: ListValue,
|
||||
renderer: ListValue,
|
||||
}
|
||||
|
|
|
@ -8,8 +8,9 @@ import { useControlState } from 'shared/components/account/control.mjs'
|
|||
// Dependencies
|
||||
import { pluginTheme } from '@freesewing/plugin-theme'
|
||||
import { pluginI18n } from '@freesewing/plugin-i18n'
|
||||
import { objUpdate, hasRequiredMeasurements } from 'shared/utils.mjs'
|
||||
import { objUpdate, hasRequiredMeasurements, nsMerge } from 'shared/utils.mjs'
|
||||
// Components
|
||||
import { Header, ns as headerNs } from 'site/components/header/index.mjs'
|
||||
import { WorkbenchHeader } from './header.mjs'
|
||||
import { ErrorView } from 'shared/components/error/view.mjs'
|
||||
import { ModalSpinner } from 'shared/components/modal/spinner.mjs'
|
||||
|
@ -45,6 +46,7 @@ export const ns = [
|
|||
|
||||
const defaultUi = {
|
||||
renderer: 'react',
|
||||
kiosk: false,
|
||||
}
|
||||
|
||||
const views = {
|
||||
|
@ -61,6 +63,8 @@ const views = {
|
|||
|
||||
const draftViews = ['draft', 'inspect']
|
||||
|
||||
const kioskClasses = 'z-30 w-screen h-screen fixed top-0 left-0 bg-base-100'
|
||||
|
||||
export const Workbench = ({ design, Design, DynamicDocs }) => {
|
||||
// Hooks
|
||||
const { t, i18n } = useTranslation([...ns, design])
|
||||
|
@ -214,10 +218,13 @@ export const Workbench = ({ design, Design, DynamicDocs }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-row min-h-screen">
|
||||
<>
|
||||
{!ui.kiosk && <Header />}
|
||||
<div className={`flex flex-row min-h-screen ${ui.kiosk ? kioskClasses : ''}`}>
|
||||
<WorkbenchHeader {...{ view, setView, update }} />
|
||||
<div className="grow">{viewContent}</div>
|
||||
<MobileMenubar />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ import {
|
|||
ZoomInIcon,
|
||||
ZoomOutIcon,
|
||||
ExpandIcon,
|
||||
KioskIcon,
|
||||
} from 'shared/components/icons.mjs'
|
||||
import { shownHeaderSelector } from 'shared/components/wrappers/header.mjs'
|
||||
|
||||
export const ns = ['common', 'core-settings', 'ui-settings']
|
||||
|
||||
|
@ -128,11 +128,13 @@ export const DraftHeader = ({ update, settings, ui, control, account, design, se
|
|||
|
||||
return (
|
||||
<div
|
||||
className={`hidden lg:flex sticky top-0 z-20 ${shownHeaderSelector(
|
||||
'lg:top-24'
|
||||
)} transition-[top] duration-300 ease-in-out`}
|
||||
className={`hidden lg:flex sticky top-0 ${
|
||||
ui.kiosk ? 'z-50' : 'z-20'
|
||||
}} transition-[top] duration-300 ease-in-out`}
|
||||
>
|
||||
<div
|
||||
className={`hidden lg:flex flex-row flex-wrap gap-4 py-2 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-8 w-full bg-neutral text-neutral-content items-center justify-center">
|
||||
{headerZoomButtons}
|
||||
<Spacer />
|
||||
<div className="flex flex-row items-center gap-4">
|
||||
|
@ -161,7 +163,7 @@ export const DraftHeader = ({ update, settings, ui, control, account, design, se
|
|||
/>
|
||||
<IconButton
|
||||
Icon={ExpandIcon}
|
||||
dflt={settings.expand}
|
||||
dflt={settings.expand || typeof settings.expand === 'undefined' ? true : false}
|
||||
onClick={() =>
|
||||
update.settings(
|
||||
['expand'],
|
||||
|
@ -194,7 +196,14 @@ export const DraftHeader = ({ update, settings, ui, control, account, design, se
|
|||
</button>
|
||||
))}
|
||||
</div>
|
||||
<Spacer />
|
||||
<div className="flex flex-row items-center gap-4">
|
||||
<IconButton
|
||||
Icon={KioskIcon}
|
||||
dflt={ui.kiosk ? false : true}
|
||||
onClick={() => update.ui(['kiosk'], ui.kiosk ? 0 : 1)}
|
||||
title={t('ui-settings:kiosk.t')}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row items-center gap-4">
|
||||
<IconButton
|
||||
Icon={RocketIcon}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { loadSettingsConfig as loadUiSettingsConfig } from 'shared/components/workbench/menus/ui-settings/config.mjs'
|
||||
import {
|
||||
DesignOptions,
|
||||
ns as designMenuNs,
|
||||
|
@ -7,6 +8,7 @@ import {
|
|||
ns as coreMenuNs,
|
||||
} from 'shared/components/workbench/menus/core-settings/index.mjs'
|
||||
import { UiSettings, ns as uiNs } from 'shared/components/workbench/menus/ui-settings/index.mjs'
|
||||
import { UiConfig } from 'shared/components/workbench/menus/ui-settings/config.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
import { SettingsIcon, OptionsIcon, DesktopIcon, FlagIcon } from 'shared/components/icons.mjs'
|
||||
|
@ -44,6 +46,7 @@ export const DraftMenu = ({
|
|||
DynamicDocs,
|
||||
control,
|
||||
}
|
||||
const uiSettingsConfig = loadUiSettingsConfig()
|
||||
|
||||
const sections = [
|
||||
{
|
||||
|
@ -67,7 +70,7 @@ export const DraftMenu = ({
|
|||
]
|
||||
|
||||
const items = []
|
||||
if (flags)
|
||||
if (control >= uiSettingsConfig.kiosk.control && flags)
|
||||
items.push([
|
||||
<FlagsAccordionTitle flags={flags} />,
|
||||
<FlagsAccordionEntries {...{ update, control, flags }} />,
|
||||
|
|
|
@ -119,7 +119,7 @@ export const FlagsAccordionEntries = ({ flags, update }) => {
|
|||
<div className="w-full flex flex-row gap2 justify-between" key={i}>
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<Icon />
|
||||
<span className="font-medium">{title}</span>
|
||||
<span className="font-medium text-left">{title}</span>
|
||||
</div>
|
||||
<span className="uppercase font-bold">{flag.type}</span>
|
||||
</div>,
|
||||
|
|
|
@ -1,24 +1,11 @@
|
|||
export const HeaderWrapper = ({ show, children }) => (
|
||||
export const HeaderWrapper = ({ children }) => (
|
||||
<header
|
||||
className={`
|
||||
fixed bottom-0 md:bottom-auto md:top-0 left-0
|
||||
bg-neutral
|
||||
w-full
|
||||
z-30
|
||||
transition-transform
|
||||
duration-300 ease-in-out
|
||||
${show ? '' : 'translate-y-36 md:-translate-y-36'}
|
||||
drop-shadow-xl
|
||||
fixed bottom-0 left-0 md:relative
|
||||
bg-neutral drop-shadow-xl w-full
|
||||
border-t border-solid border-base-300 z-20
|
||||
`}
|
||||
>
|
||||
{' '}
|
||||
{children}
|
||||
</header>
|
||||
)
|
||||
|
||||
// can't use string interpolation or tailwind won't account for these classes
|
||||
const shownHeaderClasses = {
|
||||
'bottom-16': 'group-[.header-shown]/layout:bottom-16',
|
||||
'md:top-24': 'group-[.header-shown]/layout:md:top-24',
|
||||
}
|
||||
export const shownHeaderSelector = (cls) => shownHeaderClasses[cls]
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { useState, useEffect, useRef } from 'react'
|
||||
import Head from 'next/head'
|
||||
import { Header, ns as headerNs } from 'site/components/header/index.mjs'
|
||||
import { Footer, ns as footerNs } from 'shared/components/footer/index.mjs'
|
||||
|
@ -15,44 +14,21 @@ export const LayoutWrapper = ({
|
|||
footer = true,
|
||||
slug,
|
||||
}) => {
|
||||
const ChosenHeader = header ? header : Header
|
||||
const prevScrollPos = useRef(0)
|
||||
const [showHeader, setShowHeader] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const handleScroll = () => {
|
||||
const curScrollPos = typeof window !== 'undefined' ? window.pageYOffset : 0
|
||||
|
||||
if (curScrollPos >= prevScrollPos.current) {
|
||||
if (curScrollPos > 20) setShowHeader(false)
|
||||
} else setShowHeader(true)
|
||||
|
||||
prevScrollPos.current = curScrollPos
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [prevScrollPos, setShowHeader])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
flex flex-col justify-between
|
||||
min-h-screen
|
||||
bg-base-100
|
||||
group/layout
|
||||
header-${showHeader ? 'shown' : 'hidden'}
|
||||
`}
|
||||
>
|
||||
<Head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</Head>
|
||||
<ChosenHeader show={showHeader} slug={slug} />
|
||||
{header && <Header slug={slug} />}
|
||||
|
||||
<main
|
||||
className={`grow transition-margin duration-300 ease-in-out md:group-[.header-shown]/layout:mt-20 lg:mt-4
|
||||
className={`grow transition-margin duration-300 ease-in-out
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -20,7 +20,7 @@ export const PageWrapper = (props) => {
|
|||
/*
|
||||
* Deconstruct props
|
||||
*/
|
||||
const { layout = DefaultLayout, footer = true, header = false, children = [], path = [] } = props
|
||||
const { layout = DefaultLayout, footer = true, header = true, children = [], path = [] } = props
|
||||
// Title is typically set in props.t but check props.title too
|
||||
const pageTitle = props.t ? props.t : props.title ? props.title : null
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue