1
0
Fork 0

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:
Joost De Cock 2023-09-09 17:58:44 +02:00
parent 8247cd6832
commit ddbbbda2bc
21 changed files with 89 additions and 86 deletions

View file

@ -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 */}

View file

@ -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>

View file

@ -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">

View file

@ -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">

View file

@ -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>
)

View file

@ -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>
)

View file

@ -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) => (

View file

@ -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" />

View file

@ -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',

View file

@ -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

View file

@ -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',

View file

@ -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

View file

@ -16,6 +16,7 @@ export const ControlSettingInput = (props) => {
}
export const inputs = {
renderer: ListInput,
control: ControlSettingInput,
kiosk: ListInput,
renderer: ListInput,
}

View file

@ -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,
}

View file

@ -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>
</>
)
}

View file

@ -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}

View file

@ -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 }} />,

View file

@ -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>,

View file

@ -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]

View file

@ -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}

View file

@ -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