chore(lab): Use locale and hover resize consistently
This commit is contained in:
parent
2380b4f2db
commit
e8d747a949
18 changed files with 162 additions and 96 deletions
|
@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'
|
||||||
import Logo from 'shared/components/logos/freesewing.js'
|
import Logo from 'shared/components/logos/freesewing.js'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import ThemePicker from 'shared/components/theme-picker.js'
|
import ThemePicker from 'shared/components/theme-picker.js'
|
||||||
import LanguagePicker from 'shared/components/language-picker.js'
|
import LocalePicker from 'shared/components/locale-picker.js'
|
||||||
import PatternPicker from 'site/components/pattern-picker.js'
|
import PatternPicker from 'site/components/pattern-picker.js'
|
||||||
import CloseIcon from 'shared/components/icons/close.js'
|
import CloseIcon from 'shared/components/icons/close.js'
|
||||||
import MenuIcon from 'shared/components/icons/menu.js'
|
import MenuIcon from 'shared/components/icons/menu.js'
|
||||||
|
@ -82,7 +82,7 @@ const Header = ({ app }) => {
|
||||||
</div>
|
</div>
|
||||||
<div className="hidden sm:flex flex-row items-center">
|
<div className="hidden sm:flex flex-row items-center">
|
||||||
<ThemePicker app={app} />
|
<ThemePicker app={app} />
|
||||||
<LanguagePicker app={app} />
|
<LocalePicker app={app} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import mustache from 'mustache'
|
||||||
import useLocalStorage from 'shared/hooks/useLocalStorage.js'
|
import useLocalStorage from 'shared/hooks/useLocalStorage.js'
|
||||||
// Patterns
|
// Patterns
|
||||||
import patterns from 'site/patterns.json'
|
import patterns from 'site/patterns.json'
|
||||||
// Languages
|
// Locales
|
||||||
import { strings } from 'pkgs/i18n'
|
import { strings } from 'pkgs/i18n'
|
||||||
|
|
||||||
// Initial navigation
|
// Initial navigation
|
||||||
|
@ -70,7 +70,7 @@ function useApp(full = true) {
|
||||||
// Persistent state
|
// Persistent state
|
||||||
const [account, setAccount] = useLocalStorage('account', { username: false })
|
const [account, setAccount] = useLocalStorage('account', { username: false })
|
||||||
const [theme, setTheme] = useLocalStorage('theme', prefersDarkMode ? 'dark' : 'light')
|
const [theme, setTheme] = useLocalStorage('theme', prefersDarkMode ? 'dark' : 'light')
|
||||||
const [language, setLanguage] = useLocalStorage('language', 'en')
|
const [locale, setLocale] = useLocalStorage('locale', 'en')
|
||||||
|
|
||||||
// React State
|
// React State
|
||||||
const [primaryMenu, setPrimaryMenu] = useState(false)
|
const [primaryMenu, setPrimaryMenu] = useState(false)
|
||||||
|
@ -81,20 +81,20 @@ function useApp(full = true) {
|
||||||
|
|
||||||
// State methods
|
// State methods
|
||||||
const togglePrimaryMenu = () => setPrimaryMenu(!primaryMenu)
|
const togglePrimaryMenu = () => setPrimaryMenu(!primaryMenu)
|
||||||
const changeLanguage = lang => {
|
const changeLocale = loc => {
|
||||||
setLanguage(lang)
|
setLocale(loc)
|
||||||
setNavigation(translateNavigation(lang, t))
|
setNavigation(translateNavigation(loc, t))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translation method
|
* Translation method
|
||||||
*/
|
*/
|
||||||
const t = (key, props=false, toLanguage=false) => {
|
const t = (key, props=false, toLocale=false) => {
|
||||||
if (!toLanguage) toLanguage = language
|
if (!toLocale) toLocale = locale
|
||||||
const template =
|
const template =
|
||||||
strings[toLanguage][key] ||
|
strings[toLocale][key] ||
|
||||||
strings[toLanguage][`app.${key}`] ||
|
strings[toLocale][`app.${key}`] ||
|
||||||
strings[toLanguage][`plugin.${key}`] ||
|
strings[toLocale][`plugin.${key}`] ||
|
||||||
strings.en[`app.${key}`] ||
|
strings.en[`app.${key}`] ||
|
||||||
false
|
false
|
||||||
if (!props && template) return template
|
if (!props && template) return template
|
||||||
|
@ -117,7 +117,7 @@ function useApp(full = true) {
|
||||||
patterns,
|
patterns,
|
||||||
|
|
||||||
// State
|
// State
|
||||||
language,
|
locale,
|
||||||
loading,
|
loading,
|
||||||
navigation,
|
navigation,
|
||||||
pattern,
|
pattern,
|
||||||
|
@ -137,11 +137,11 @@ function useApp(full = true) {
|
||||||
|
|
||||||
// State handlers
|
// State handlers
|
||||||
togglePrimaryMenu,
|
togglePrimaryMenu,
|
||||||
changeLanguage,
|
changeLocale,
|
||||||
|
|
||||||
// Translation
|
// Translation
|
||||||
t,
|
t,
|
||||||
languages: Object.keys(strings),
|
locales: Object.keys(strings),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import themes from 'shared/themes/index.js'
|
import themes from 'shared/themes/index.js'
|
||||||
import LanguageIcon from 'shared/components/icons/i18n.js'
|
import LocaleIcon from 'shared/components/icons/i18n.js'
|
||||||
import { languages } from 'pkgs/i18n'
|
import { languages } from 'pkgs/i18n'
|
||||||
|
|
||||||
const LanguagePicker = ({ app }) => {
|
const LocalePicker = ({ app }) => {
|
||||||
return (
|
return (
|
||||||
<div className="dropdown">
|
<div className="dropdown">
|
||||||
<div tabIndex="0" className={`
|
<div tabIndex="0" className={`
|
||||||
|
@ -10,14 +10,14 @@ const LanguagePicker = ({ app }) => {
|
||||||
sm:btn-ghost
|
sm:btn-ghost
|
||||||
hover:bg-neutral hover:border-neutral-content
|
hover:bg-neutral hover:border-neutral-content
|
||||||
`}>
|
`}>
|
||||||
<LanguageIcon />
|
<LocaleIcon />
|
||||||
<span>{languages[app.language]}</span>
|
<span>{languages[app.locale]}</span>
|
||||||
</div>
|
</div>
|
||||||
<ul tabIndex="0" className="p-2 shadow menu dropdown-content bg-base-100 rounded-box w-52">
|
<ul tabIndex="0" className="p-2 shadow menu dropdown-content bg-base-100 rounded-box w-52">
|
||||||
{Object.keys(languages).map(language => (
|
{Object.keys(app.locales).map(locale => (
|
||||||
<li key={language}>
|
<li key={locale}>
|
||||||
<button onClick={() => app.changeLanguage(language)} className="btn btn-ghost text-base-content hover:bg-base-200">
|
<button onClick={() => app.changeLocale(locale)} className="btn btn-ghost text-base-content hover:bg-base-200">
|
||||||
{languages[language]}
|
{languages[locale]}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
@ -26,4 +26,4 @@ const LanguagePicker = ({ app }) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LanguagePicker
|
export default LocalePicker
|
|
@ -46,7 +46,7 @@ const currentChildren = current => Object.values(order(current))
|
||||||
// Shared classes for links
|
// Shared classes for links
|
||||||
// Exported for re-use
|
// Exported for re-use
|
||||||
export const linkClasses = `text-lg lg:text-xl
|
export const linkClasses = `text-lg lg:text-xl
|
||||||
py-1 hover:cursor-pointer
|
py-1
|
||||||
text-base-content sm:text-neutral-content
|
text-base-content sm:text-neutral-content
|
||||||
hover:text-secondary
|
hover:text-secondary
|
||||||
sm:hover:text-secondary-focus
|
sm:hover:text-secondary-focus
|
||||||
|
@ -84,6 +84,7 @@ const SubLevel = ({ nodes={}, active }) => (
|
||||||
<a title={child.__title} className={`
|
<a title={child.__title} className={`
|
||||||
grow pl-2 border-l-2
|
grow pl-2 border-l-2
|
||||||
${linkClasses}
|
${linkClasses}
|
||||||
|
hover:cursor-pointer
|
||||||
hover:border-secondary
|
hover:border-secondary
|
||||||
sm:hover:border-secondary-focus
|
sm:hover:border-secondary-focus
|
||||||
${child.__slug === active
|
${child.__slug === active
|
||||||
|
@ -117,6 +118,7 @@ const SubLevel = ({ nodes={}, active }) => (
|
||||||
pl-2 border-l-2
|
pl-2 border-l-2
|
||||||
grow
|
grow
|
||||||
${linkClasses}
|
${linkClasses}
|
||||||
|
hover:cursor-pointer
|
||||||
hover:border-secondary
|
hover:border-secondary
|
||||||
sm:hover:border-secondary-focus
|
sm:hover:border-secondary-focus
|
||||||
${child.__slug === active
|
${child.__slug === active
|
||||||
|
@ -157,7 +159,13 @@ const TopLevel = ({ icon, title, nav, current, slug, hasChildren=false, active }
|
||||||
`}>
|
`}>
|
||||||
<span className="text-secondary-focus">{icon}</span>
|
<span className="text-secondary-focus">{icon}</span>
|
||||||
<Link href={`/${slug}`}>
|
<Link href={`/${slug}`}>
|
||||||
<a className={`grow ${linkClasses} ${slug === active ? 'text-secondary sm:text-secondary-focus' : ''}`}>
|
<a className={`
|
||||||
|
grow ${linkClasses} hover:cursor-pointer
|
||||||
|
${slug === active
|
||||||
|
? 'text-secondary sm:text-secondary-focus'
|
||||||
|
: ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
{title}
|
{title}
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -11,15 +11,15 @@ const LabDraft = ({ app, pattern, gist, updateGist }) => {
|
||||||
return (
|
return (
|
||||||
<Svg {...patternProps}>
|
<Svg {...patternProps}>
|
||||||
<Defs {...patternProps} />
|
<Defs {...patternProps} />
|
||||||
<style>{`:root { --pattern-scale: ${gist.settings.scale || 1}}`}</style>
|
<style>{`:root { --pattern-scale: ${gist.scale || 1}}`}</style>
|
||||||
<g>
|
<g>
|
||||||
{Object.keys(patternProps.parts).map((name) => (
|
{Object.keys(patternProps.parts).map((name) => (
|
||||||
<Part
|
<Part
|
||||||
key={name}
|
key={name}
|
||||||
part={patternProps.parts[name]}
|
part={patternProps.parts[name]}
|
||||||
language={gist.settings.locale}
|
locale={gist.locale}
|
||||||
paperless={gist.settings.paperless}
|
paperless={gist.paperless}
|
||||||
units={gist.settings.units}
|
units={gist.units}
|
||||||
name={name}
|
name={name}
|
||||||
app={app}
|
app={app}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -103,7 +103,7 @@ const Part = (props) => {
|
||||||
key={name}
|
key={name}
|
||||||
name={name}
|
name={name}
|
||||||
part={props.name}
|
part={props.name}
|
||||||
language={props.language}
|
locale={props.locale}
|
||||||
path={props.part.paths[name]}
|
path={props.part.paths[name]}
|
||||||
focus={props.focus}
|
focus={props.focus}
|
||||||
topLeft={props.part.topLeft}
|
topLeft={props.part.topLeft}
|
||||||
|
@ -118,7 +118,7 @@ const Part = (props) => {
|
||||||
key={name}
|
key={name}
|
||||||
name={name}
|
name={name}
|
||||||
part={props.name}
|
part={props.name}
|
||||||
language={props.language}
|
locale={props.locale}
|
||||||
point={props.part.points[name]}
|
point={props.part.points[name]}
|
||||||
focus={props.focus}
|
focus={props.focus}
|
||||||
topLeft={props.part.topLeft}
|
topLeft={props.part.topLeft}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React from 'react'
|
||||||
const Svg = ({
|
const Svg = ({
|
||||||
embed = true,
|
embed = true,
|
||||||
develop = false,
|
develop = false,
|
||||||
language = 'en',
|
locale = 'en',
|
||||||
className = 'freesewing pattern',
|
className = 'freesewing pattern',
|
||||||
style = {},
|
style = {},
|
||||||
viewBox = false,
|
viewBox = false,
|
||||||
|
@ -15,7 +15,7 @@ const Svg = ({
|
||||||
xmlns: 'http://www.w3.org/2000/svg',
|
xmlns: 'http://www.w3.org/2000/svg',
|
||||||
'xmlns:svg': 'http://www.w3.org/2000/svg',
|
'xmlns:svg': 'http://www.w3.org/2000/svg',
|
||||||
xmlnsXlink: 'http://www.w3.org/1999/xlink',
|
xmlnsXlink: 'http://www.w3.org/1999/xlink',
|
||||||
xmlLang: language,
|
xmlLang: locale,
|
||||||
viewBox: viewBox || `0 0 ${width} ${height}`,
|
viewBox: viewBox || `0 0 ${width} ${height}`,
|
||||||
className,
|
className,
|
||||||
style
|
style
|
||||||
|
|
|
@ -3,7 +3,7 @@ const TextOnPath = (props) => {
|
||||||
// Handle translation
|
// Handle translation
|
||||||
let translated = ''
|
let translated = ''
|
||||||
for (let string of props.path.attributes.getAsArray('data-text')) {
|
for (let string of props.path.attributes.getAsArray('data-text')) {
|
||||||
translated += props.app.t(string, false, props.language).replace(/"/g, '"') + ' '
|
translated += props.app.t(string, false, props.locale).replace(/"/g, '"') + ' '
|
||||||
}
|
}
|
||||||
const textPathProps = {
|
const textPathProps = {
|
||||||
xlinkHref: '#' + props.pathId,
|
xlinkHref: '#' + props.pathId,
|
||||||
|
|
|
@ -3,7 +3,7 @@ const Text = (props) => {
|
||||||
// Handle translation
|
// Handle translation
|
||||||
let translated = ''
|
let translated = ''
|
||||||
for (let string of props.point.attributes.getAsArray('data-text')) {
|
for (let string of props.point.attributes.getAsArray('data-text')) {
|
||||||
translated += props.app.t(string.toString(), false, props.language).replace(/"/g, '"') + ' '
|
translated += props.app.t(string.toString(), false, props.locale).replace(/"/g, '"') + ' '
|
||||||
}
|
}
|
||||||
// Handle muti-line text
|
// Handle muti-line text
|
||||||
if (translated.indexOf('\n') !== -1) {
|
if (translated.indexOf('\n') !== -1) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ const DesignOptionPctDeg = props => {
|
||||||
return (
|
return (
|
||||||
<div className="py-4 mx-6 border-l-2 pl-2">
|
<div className="py-4 mx-6 border-l-2 pl-2">
|
||||||
<p className="m-0 p-0 px-2 mb-2 text-neutral-content opacity-60 italic">
|
<p className="m-0 p-0 px-2 mb-2 text-neutral-content opacity-60 italic">
|
||||||
{props.app.t(`options.${props.pattern.config.name}.${props.option}.description`, props.app.language)}
|
{props.app.t(`options.${props.pattern.config.name}.${props.option}.description`, props.app.locale)}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-row justify-between">
|
<div className="flex flex-row justify-between">
|
||||||
{editOption
|
{editOption
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useState } from 'react'
|
||||||
|
|
||||||
const CoreSettingList = props => {
|
const CoreSettingList = props => {
|
||||||
const { dflt, list } = props
|
const { dflt, list } = props
|
||||||
const val = props.gist?.settings?.[props.setting]
|
const val = props.gist?.[props.setting]
|
||||||
|
|
||||||
const [value, setValue] = useState(val)
|
const [value, setValue] = useState(val)
|
||||||
|
|
||||||
|
@ -10,10 +10,15 @@ const CoreSettingList = props => {
|
||||||
if (newVal === dflt) reset()
|
if (newVal === dflt) reset()
|
||||||
else {
|
else {
|
||||||
setValue(newVal)
|
setValue(newVal)
|
||||||
props.updateGist(['settings', props.setting], newVal)
|
props.updateGist([props.setting], newVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
setValue(props.dflt)
|
||||||
|
props.updateGist([props.setting], props.dflt)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="py-4 mx-6 border-l-2 pl-2">
|
<div className="py-4 mx-6 border-l-2 pl-2">
|
||||||
<p className="m-0 p-0 px-2 mb-2 text-neutral-content opacity-60 italic">
|
<p className="m-0 p-0 px-2 mb-2 text-neutral-content opacity-60 italic">
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { formatMm } from 'shared/utils.js'
|
||||||
|
import ClearIcon from 'shared/components/icons/clear.js'
|
||||||
|
import EditIcon from 'shared/components/icons/edit.js'
|
||||||
|
|
||||||
|
const CoreSettingMm = props => {
|
||||||
|
const { dflt, min, max } = props
|
||||||
|
const val = props.gist?.[props.setting]
|
||||||
|
|
||||||
|
const [value, setValue] = useState(val)
|
||||||
|
|
||||||
|
const handleChange = evt => {
|
||||||
|
const newVal = parseFloat(evt.target.value)
|
||||||
|
|
||||||
|
if (newVal === dflt) reset()
|
||||||
|
else {
|
||||||
|
setValue(newVal)
|
||||||
|
props.updateGist([props.setting], newVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const reset = () => {
|
||||||
|
setValue(props.dflt)
|
||||||
|
props.updateGist([props.setting], props.dflt)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="py-4 mx-6 border-l-2 pl-2">
|
||||||
|
<p className="m-0 p-0 px-2 mb-2 text-neutral-content opacity-60 italic">
|
||||||
|
{props.app.t(`settings.${props.setting}.description`)}
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
|
<span
|
||||||
|
className="opacity-50"
|
||||||
|
dangerouslySetInnerHTML={{__html: formatMm(min, props.gist.units)}}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className={`font-bold ${val===dflt ? 'text-secondary' : 'text-accent'}`}
|
||||||
|
dangerouslySetInnerHTML={{__html: formatMm(val, props.gist.units)}}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="opacity-50"
|
||||||
|
dangerouslySetInnerHTML={{__html: formatMm(max, props.gist.units)}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
max={max}
|
||||||
|
min={min}
|
||||||
|
step={0.1}
|
||||||
|
value={value}
|
||||||
|
onChange={handleChange}
|
||||||
|
className={`
|
||||||
|
range range-sm mt-1
|
||||||
|
${val === dflt ? 'range-secondary' : 'range-accent'}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
|
<span />
|
||||||
|
<button
|
||||||
|
title={props.app.t('app.reset')}
|
||||||
|
className="btn btn-ghost btn-xs text-accent"
|
||||||
|
disabled={val === dflt}
|
||||||
|
onClick={reset}
|
||||||
|
>
|
||||||
|
<ClearIcon />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CoreSettingMm
|
|
@ -4,9 +4,16 @@ import Setting from './setting.js'
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
locale: {
|
locale: {
|
||||||
dflt: 'en',
|
|
||||||
list: ['de', 'en', 'es', 'fr', 'nl'],
|
list: ['de', 'en', 'es', 'fr', 'nl'],
|
||||||
},
|
},
|
||||||
|
units: {
|
||||||
|
list: ['metric', 'imperial'],
|
||||||
|
},
|
||||||
|
margin: {
|
||||||
|
min: 0,
|
||||||
|
max: 25,
|
||||||
|
dflt: 2,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const CoreSettings = props => {
|
const CoreSettings = props => {
|
||||||
|
@ -22,7 +29,7 @@ const CoreSettings = props => {
|
||||||
items-center
|
items-center
|
||||||
`}>
|
`}>
|
||||||
<span className="text-secondary-focus mr-4"><SettingsIcon /></span>
|
<span className="text-secondary-focus mr-4"><SettingsIcon /></span>
|
||||||
<span className={`grow ${linkClasses}`}>
|
<span className={`grow ${linkClasses} hover:cursor-resize`}>
|
||||||
{props.app.t('app.settings')}
|
{props.app.t('app.settings')}
|
||||||
</span>
|
</span>
|
||||||
<Chevron />
|
<Chevron />
|
||||||
|
|
|
@ -2,70 +2,31 @@ import { linkClasses, Chevron } from 'shared/components/navigation/primary.js'
|
||||||
import PctDegOption from 'shared/components/workbench/inputs/design-option-pct-deg'
|
import PctDegOption from 'shared/components/workbench/inputs/design-option-pct-deg'
|
||||||
import CountOption from 'shared/components/workbench/inputs/design-option-count'
|
import CountOption from 'shared/components/workbench/inputs/design-option-count'
|
||||||
import ListSetting from './core-setting-list'
|
import ListSetting from './core-setting-list'
|
||||||
|
import MmSetting from './core-setting-mm'
|
||||||
import { formatMm, formatPercentage, optionType } from 'shared/utils.js'
|
import { formatMm, formatPercentage, optionType } from 'shared/utils.js'
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
locale: props => {
|
locale: props => {
|
||||||
return (
|
return (
|
||||||
<span className="text-secondary">
|
<span className="text-secondary">
|
||||||
{props.app.t(`i18n.${props.gist.settings.locale}`)}
|
{props.app.t(`i18n.${props.gist.locale}`)}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
pct: props => {
|
units: props => {
|
||||||
const val = (typeof props.gist?.options?.[props.option] === 'undefined')
|
|
||||||
? props.pattern.config.options[props.option].pct/100
|
|
||||||
: props.gist.options[props.option]
|
|
||||||
return (
|
return (
|
||||||
<span className={
|
<span className="text-secondary">
|
||||||
val=== props.pattern.config.options[props.option].pct/100
|
{props.app.t(`app.${props.gist.units}Units`)}
|
||||||
? 'text-secondary'
|
|
||||||
: 'text-accent'
|
|
||||||
}>
|
|
||||||
{formatPercentage(val)}
|
|
||||||
{props.pattern.config.options[props.option]?.toAbs
|
|
||||||
? ' | ' +formatMm(props.pattern.config.options[props.option]?.toAbs(val, props.gist))
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bool: props => {
|
margin: props => {
|
||||||
const dflt = props.pattern.config.options[props.option].bool
|
|
||||||
const current = props.gist?.options?.[props.option]
|
|
||||||
return (
|
return (
|
||||||
<span className={
|
<span className="text-secondary" dangerouslySetInnerHTML={{
|
||||||
(dflt==current || typeof current === 'undefined')
|
__html: formatMm(props.gist.margin, props.gist.units)
|
||||||
? 'text-secondary'
|
}} />
|
||||||
: 'text-accent'
|
|
||||||
}>
|
|
||||||
{props.gist?.options?.[props.option]
|
|
||||||
? props.app.t('app.yes')
|
|
||||||
: props.app.t('app.no')
|
|
||||||
}
|
|
||||||
</span>
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
count: props => {
|
|
||||||
const dflt = props.pattern.config.options[props.option].count
|
|
||||||
const current = props.gist?.options?.[props.option]
|
|
||||||
return (dflt==current || typeof current === 'undefined')
|
|
||||||
? <span className="text-secondary">{dflt}</span>
|
|
||||||
: <span className="text-accent">{current}</span>
|
|
||||||
},
|
|
||||||
deg: props => {
|
|
||||||
const dflt = props.pattern.config.options[props.option].deg
|
|
||||||
const current = props.gist?.options?.[props.option]
|
|
||||||
return (dflt==current || typeof current === 'undefined')
|
|
||||||
? <span className="text-secondary">{dflt}°</span>
|
|
||||||
: <span className="text-accent">{current}°</span>
|
|
||||||
},
|
|
||||||
mm: props => {
|
|
||||||
return <p>No mm val yet</p>
|
|
||||||
},
|
|
||||||
constant: props => {
|
|
||||||
return <p>No constant val yet</p>
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Tmp = props => <p>not yet</p>
|
const Tmp = props => <p>not yet</p>
|
||||||
|
@ -73,14 +34,21 @@ const Tmp = props => <p>not yet</p>
|
||||||
const inputs = {
|
const inputs = {
|
||||||
locale: props => <ListSetting
|
locale: props => <ListSetting
|
||||||
{...props}
|
{...props}
|
||||||
list={props.app.languages.map(key => ({
|
list={props.config.list.map(key => ({
|
||||||
key,
|
key,
|
||||||
title: props.app.t(`i18n.${key}`)
|
title: props.app.t(`i18n.${key}`)
|
||||||
}))}
|
}))}
|
||||||
/>,
|
/>,
|
||||||
|
units: props => <ListSetting
|
||||||
|
{...props}
|
||||||
|
list={props.config.list.map(key => ({
|
||||||
|
key,
|
||||||
|
title: props.app.t(`app.${key}Units`)
|
||||||
|
}))}
|
||||||
|
/>,
|
||||||
|
margin: props => <MmSetting {...props} {...props.config} />,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Setting = props => {
|
const Setting = props => {
|
||||||
const Input = inputs[props.setting]
|
const Input = inputs[props.setting]
|
||||||
const Value = settings[props.setting]
|
const Value = settings[props.setting]
|
||||||
|
@ -109,6 +77,7 @@ const Setting = props => {
|
||||||
<div className={`
|
<div className={`
|
||||||
grow pl-2 border-l-2
|
grow pl-2 border-l-2
|
||||||
${linkClasses}
|
${linkClasses}
|
||||||
|
hover:cursor-pointer
|
||||||
hover:border-secondary
|
hover:border-secondary
|
||||||
sm:hover:border-secondary-focus
|
sm:hover:border-secondary-focus
|
||||||
text-base-content sm:text-neutral-content
|
text-base-content sm:text-neutral-content
|
||||||
|
@ -143,6 +112,7 @@ const Setting = props => {
|
||||||
<div className={`
|
<div className={`
|
||||||
grow pl-2 border-l-2
|
grow pl-2 border-l-2
|
||||||
${linkClasses}
|
${linkClasses}
|
||||||
|
hover:cursor-resize
|
||||||
hover:border-secondary
|
hover:border-secondary
|
||||||
sm:hover:border-secondary-focus
|
sm:hover:border-secondary-focus
|
||||||
text-base-content sm:text-neutral-content
|
text-base-content sm:text-neutral-content
|
||||||
|
|
|
@ -18,6 +18,7 @@ const OptionGroup = props => {
|
||||||
<div className={`
|
<div className={`
|
||||||
grow pl-2 border-l-2
|
grow pl-2 border-l-2
|
||||||
${linkClasses}
|
${linkClasses}
|
||||||
|
hover:cursor-resize
|
||||||
hover:border-secondary
|
hover:border-secondary
|
||||||
sm:hover:border-secondary-focus
|
sm:hover:border-secondary-focus
|
||||||
text-base-content sm:text-neutral-content
|
text-base-content sm:text-neutral-content
|
||||||
|
|
|
@ -16,6 +16,7 @@ const OptionSubGroup = props => {
|
||||||
<div className={`
|
<div className={`
|
||||||
grow pl-2 border-l-2
|
grow pl-2 border-l-2
|
||||||
${linkClasses}
|
${linkClasses}
|
||||||
|
hover:cursor-resize
|
||||||
hover:border-secondary
|
hover:border-secondary
|
||||||
sm:hover:border-secondary-focus
|
sm:hover:border-secondary-focus
|
||||||
text-base-content sm:text-neutral-content
|
text-base-content sm:text-neutral-content
|
||||||
|
|
|
@ -37,7 +37,7 @@ const Modes = props => {
|
||||||
items-center
|
items-center
|
||||||
`}>
|
`}>
|
||||||
<span className="text-secondary-focus mr-4"><MenuIcon /></span>
|
<span className="text-secondary-focus mr-4"><MenuIcon /></span>
|
||||||
<span className={`grow ${linkClasses}`}>
|
<span className={`grow ${linkClasses} hover:cursor-resize`}>
|
||||||
{props.app.t('app.modes')}
|
{props.app.t('app.modes')}
|
||||||
</span>
|
</span>
|
||||||
<Chevron />
|
<Chevron />
|
||||||
|
@ -48,6 +48,7 @@ const Modes = props => {
|
||||||
<button title={entry.title} className={`
|
<button title={entry.title} className={`
|
||||||
grow pl-2 border-l-2
|
grow pl-2 border-l-2
|
||||||
${linkClasses}
|
${linkClasses}
|
||||||
|
hover:cursor-pointer
|
||||||
hover:border-secondary
|
hover:border-secondary
|
||||||
sm:hover:border-secondary-focus
|
sm:hover:border-secondary-focus
|
||||||
text-left
|
text-left
|
||||||
|
|
|
@ -10,13 +10,13 @@ import defaultSettings from 'shared/components/workbench/default-settings.js'
|
||||||
|
|
||||||
|
|
||||||
// Generates a default pattern gist to start from
|
// Generates a default pattern gist to start from
|
||||||
const defaultGist = (pattern, language='en') => {
|
const defaultGist = (pattern, locale='en') => {
|
||||||
const gist = {
|
const gist = {
|
||||||
design: pattern.config.name,
|
design: pattern.config.name,
|
||||||
version: pattern.config.version,
|
version: pattern.config.version,
|
||||||
settings: defaultSettings
|
...defaultSettings
|
||||||
}
|
}
|
||||||
if (language) gist.settings.locale = language
|
if (locale) gist.locale = locale
|
||||||
|
|
||||||
return gist
|
return gist
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ const WorkbenchWrapper = ({ app, pattern }) => {
|
||||||
|
|
||||||
// State for display mode and gist
|
// State for display mode and gist
|
||||||
const [mode, setMode] = useState('measurements')
|
const [mode, setMode] = useState('measurements')
|
||||||
const [gist, setGist] = useLocalStorage('gist', defaultGist(pattern, app.language))
|
const [gist, setGist] = useLocalStorage('gist', defaultGist(pattern, app.locale))
|
||||||
|
|
||||||
// If we don't have the requiremed measurements,
|
// If we don't have the requiremed measurements,
|
||||||
// force mode to measurements
|
// force mode to measurements
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue