feat(lab): Paperless and render settings
This commit is contained in:
parent
21d1d15e53
commit
18f9e93cc0
9 changed files with 269 additions and 55 deletions
|
@ -1,11 +1,14 @@
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
sa: 0,
|
sa: 0,
|
||||||
|
saBool: false,
|
||||||
|
saMm: 10,
|
||||||
complete: true,
|
complete: true,
|
||||||
paperless: false,
|
paperless: false,
|
||||||
units: 'metric',
|
units: 'metric',
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
margin: 2,
|
margin: 2,
|
||||||
debug: true,
|
renderer: 'react',
|
||||||
|
embed: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defaultSettings
|
export default defaultSettings
|
||||||
|
|
|
@ -2,11 +2,17 @@ import React, { useState } from 'react'
|
||||||
import Svg from './svg'
|
import Svg from './svg'
|
||||||
import Defs from './defs'
|
import Defs from './defs'
|
||||||
import Part from './part'
|
import Part from './part'
|
||||||
|
import theme from 'pkgs/plugin-theme/src/index.js'
|
||||||
|
|
||||||
const LabDraft = ({ app, pattern, gist, updateGist }) => {
|
const LabDraft = ({ app, pattern, gist, updateGist }) => {
|
||||||
|
|
||||||
const patternInstance = new pattern(gist).draft()
|
const patternInstance = new pattern(gist)
|
||||||
const patternProps = patternInstance.getRenderProps()
|
if (gist?.renderer === 'svg') return <div
|
||||||
|
dangerouslySetInnerHTML={{ __html: patternInstance.use(theme).draft().render()}} />
|
||||||
|
|
||||||
|
const patternProps = patternInstance.draft().getRenderProps()
|
||||||
|
console.log(patternProps)
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Svg {...patternProps}>
|
<Svg {...patternProps}>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const TextOnPath = (props) => {
|
const TextOnPath = (props) => {
|
||||||
const text = []
|
const text = []
|
||||||
// Handle translation
|
// Handle translation (and spaces)
|
||||||
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.locale).replace(/"/g, '"') + ' '
|
translated += props.app.t(string, false, props.locale).replace(/"/g, '"') + ' '
|
||||||
|
@ -16,7 +16,10 @@ const TextOnPath = (props) => {
|
||||||
return (
|
return (
|
||||||
<text>
|
<text>
|
||||||
<textPath {...textPathProps}>
|
<textPath {...textPathProps}>
|
||||||
<tspan {...props.path.attributes.asPropsIfPrefixIs('data-text-')}>{translated}</tspan>
|
<tspan
|
||||||
|
{...props.path.attributes.asPropsIfPrefixIs('data-text-')}
|
||||||
|
dangerouslySetInnerHTML={{__html: translated}}
|
||||||
|
/>
|
||||||
</textPath>
|
</textPath>
|
||||||
</text>
|
</text>
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { linkClasses } from 'shared/components/navigation/primary.js'
|
||||||
|
|
||||||
|
const CoreSettingBool = props => {
|
||||||
|
const val = props.gist[props.setting]
|
||||||
|
const dflt = props.dflt
|
||||||
|
|
||||||
|
const [value, setValue] = useState(val)
|
||||||
|
|
||||||
|
const toggle = (evt) => {
|
||||||
|
props.updateGist([props.setting], !value)
|
||||||
|
setValue(!value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li className="flex flex-row">
|
||||||
|
<button className={`
|
||||||
|
flex flex-row
|
||||||
|
w-full
|
||||||
|
justify-between
|
||||||
|
px-2
|
||||||
|
text-left
|
||||||
|
text-base-content
|
||||||
|
sm:text-neutral-content
|
||||||
|
items-center
|
||||||
|
pr-6
|
||||||
|
`} onClick={toggle}>
|
||||||
|
<div className={`
|
||||||
|
grow pl-2 border-l-2
|
||||||
|
${linkClasses}
|
||||||
|
hover:cursor-pointer
|
||||||
|
hover:border-secondary
|
||||||
|
sm:hover:border-secondary-focus
|
||||||
|
text-base-content sm:text-neutral-content
|
||||||
|
`}>
|
||||||
|
<span className={`
|
||||||
|
text-3xl mr-2 inline-block p-0 pl-2 leading-3
|
||||||
|
translate-y-3
|
||||||
|
`}>
|
||||||
|
<>°</>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{ props.app.t(`settings.${props.setting}.title`) }
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-secondary">
|
||||||
|
{props.app.t('app.'+ (value ? 'yes' : 'no'))}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CoreSettingBool
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { linkClasses } from 'shared/components/navigation/primary.js'
|
||||||
|
|
||||||
|
const CoreSettingSaBool = props => {
|
||||||
|
const val = props.gist.saBool || false
|
||||||
|
|
||||||
|
const [value, setValue] = useState(val)
|
||||||
|
|
||||||
|
const toggle = () => {
|
||||||
|
props.setGist({
|
||||||
|
...props.gist,
|
||||||
|
saBool: !value,
|
||||||
|
sa: value ? 0 : props.gist.saMm
|
||||||
|
})
|
||||||
|
setValue(!value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li className="flex flex-row">
|
||||||
|
<button className={`
|
||||||
|
flex flex-row
|
||||||
|
w-full
|
||||||
|
justify-between
|
||||||
|
px-2
|
||||||
|
text-left
|
||||||
|
text-base-content
|
||||||
|
sm:text-neutral-content
|
||||||
|
items-center
|
||||||
|
pr-6
|
||||||
|
`} onClick={toggle}>
|
||||||
|
<div className={`
|
||||||
|
grow pl-2 border-l-2
|
||||||
|
${linkClasses}
|
||||||
|
hover:cursor-pointer
|
||||||
|
hover:border-secondary
|
||||||
|
sm:hover:border-secondary-focus
|
||||||
|
text-base-content sm:text-neutral-content
|
||||||
|
`}>
|
||||||
|
<span className={`
|
||||||
|
text-3xl mr-2 inline-block p-0 pl-2 leading-3
|
||||||
|
translate-y-3
|
||||||
|
`}>
|
||||||
|
<>°</>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{ props.app.t(`settings.sa.title`) }
|
||||||
|
</span>
|
||||||
|
<span className="ml-4 opacity-50">
|
||||||
|
[ { props.app.t(`app.yes`) }/
|
||||||
|
{ props.app.t(`app.no`) } ]
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-secondary">
|
||||||
|
{props.app.t('app.'+ (value ? 'yes' : 'no'))}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CoreSettingSaBool
|
|
@ -0,0 +1,75 @@
|
||||||
|
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)
|
||||||
|
|
||||||
|
setValue(newVal)
|
||||||
|
if (props.gist.sa) props.setGist({
|
||||||
|
...props.gist,
|
||||||
|
saMm: newVal,
|
||||||
|
sa: newVal,
|
||||||
|
})
|
||||||
|
else props.updateGist(['saMm'], newVal)
|
||||||
|
}
|
||||||
|
const reset = () => {
|
||||||
|
setValue(dflt)
|
||||||
|
props.updateGist(['saMm'], 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.sa.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
|
|
@ -3,6 +3,17 @@ import { linkClasses, Chevron } from 'shared/components/navigation/primary.js'
|
||||||
import Setting from './setting.js'
|
import Setting from './setting.js'
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
|
paperless: {
|
||||||
|
dflt: false,
|
||||||
|
},
|
||||||
|
saBool: {
|
||||||
|
dflt: false,
|
||||||
|
},
|
||||||
|
saMm: {
|
||||||
|
min: 0,
|
||||||
|
max: 25,
|
||||||
|
dflt: 10,
|
||||||
|
},
|
||||||
locale: {
|
locale: {
|
||||||
list: ['de', 'en', 'es', 'fr', 'nl'],
|
list: ['de', 'en', 'es', 'fr', 'nl'],
|
||||||
},
|
},
|
||||||
|
@ -14,6 +25,13 @@ const settings = {
|
||||||
max: 25,
|
max: 25,
|
||||||
dflt: 2,
|
dflt: 2,
|
||||||
},
|
},
|
||||||
|
renderer: {
|
||||||
|
list: ['react', 'svg'],
|
||||||
|
titles: {
|
||||||
|
react: '<Draft /> (React)',
|
||||||
|
svg: '@freesewing/core (SVG)'
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const CoreSettings = props => {
|
const CoreSettings = props => {
|
||||||
|
|
|
@ -3,9 +3,19 @@ import PctDegOption from 'shared/components/workbench/inputs/design-option-pct-d
|
||||||
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 MmSetting from './core-setting-mm'
|
||||||
|
import BoolSetting from './core-setting-bool.js'
|
||||||
|
import SaBoolSetting from './core-setting-sa-bool.js'
|
||||||
|
import SaMmSetting from './core-setting-sa-mm.js'
|
||||||
import { formatMm, formatPercentage, optionType } from 'shared/utils.js'
|
import { formatMm, formatPercentage, optionType } from 'shared/utils.js'
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
|
paperless: props => {
|
||||||
|
return (
|
||||||
|
<span className="text-secondary">
|
||||||
|
{props.app.t(`app.${props.gist.paperless ? 'yes' : 'no'}`)}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
},
|
||||||
locale: props => {
|
locale: props => {
|
||||||
return (
|
return (
|
||||||
<span className="text-secondary">
|
<span className="text-secondary">
|
||||||
|
@ -27,10 +37,20 @@ const settings = {
|
||||||
}} />
|
}} />
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
saMm: props => {
|
||||||
|
return (
|
||||||
|
<span className="text-secondary" dangerouslySetInnerHTML={{
|
||||||
|
__html: formatMm(props.gist.saMm, props.gist.units)
|
||||||
|
}} />
|
||||||
|
)
|
||||||
|
},
|
||||||
|
renderer: props => (
|
||||||
|
<span className="text-secondary">
|
||||||
|
{props.config.titles[props.gist.renderer]}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
const Tmp = props => <p>not yet</p>
|
|
||||||
|
|
||||||
const inputs = {
|
const inputs = {
|
||||||
locale: props => <ListSetting
|
locale: props => <ListSetting
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -47,57 +67,24 @@ const inputs = {
|
||||||
}))}
|
}))}
|
||||||
/>,
|
/>,
|
||||||
margin: props => <MmSetting {...props} {...props.config} />,
|
margin: props => <MmSetting {...props} {...props.config} />,
|
||||||
|
saMm: props => <SaMmSetting {...props} {...props.config} />,
|
||||||
|
renderer: props => <ListSetting
|
||||||
|
{...props}
|
||||||
|
list={props.config.list.map(key => ({
|
||||||
|
key,
|
||||||
|
title: props.config.titles[key]
|
||||||
|
}))}
|
||||||
|
/>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Setting = props => {
|
const Setting = props => {
|
||||||
|
|
||||||
|
if (props.setting === 'saBool') return <SaBoolSetting {...props} {...props.config} />
|
||||||
|
if (props.setting === 'paperless') return <BoolSetting {...props} {...props.config} />
|
||||||
|
|
||||||
const Input = inputs[props.setting]
|
const Input = inputs[props.setting]
|
||||||
const Value = settings[props.setting]
|
const Value = settings[props.setting]
|
||||||
|
|
||||||
const toggleBoolean = () => {
|
|
||||||
const dflt = props.pattern.config.options[props.option].bool
|
|
||||||
const current = props.gist?.options?.[props.option]
|
|
||||||
if (typeof current === 'undefined')
|
|
||||||
props.updateGist(['options', props.option], !dflt)
|
|
||||||
else props.unsetGist(['options', props.option])
|
|
||||||
}
|
|
||||||
|
|
||||||
if (props.setting === 'bool') return (
|
|
||||||
<li className="flex flex-row">
|
|
||||||
<button className={`
|
|
||||||
flex flex-row
|
|
||||||
w-full
|
|
||||||
justify-between
|
|
||||||
px-2
|
|
||||||
text-left
|
|
||||||
text-base-content
|
|
||||||
sm:text-neutral-content
|
|
||||||
items-center
|
|
||||||
pr-6
|
|
||||||
`} onClick={toggleBoolean}>
|
|
||||||
<div className={`
|
|
||||||
grow pl-2 border-l-2
|
|
||||||
${linkClasses}
|
|
||||||
hover:cursor-pointer
|
|
||||||
hover:border-secondary
|
|
||||||
sm:hover:border-secondary-focus
|
|
||||||
text-base-content sm:text-neutral-content
|
|
||||||
`}>
|
|
||||||
<span className={`
|
|
||||||
text-3xl mr-2 inline-block p-0 leading-3
|
|
||||||
translate-y-3
|
|
||||||
`}>
|
|
||||||
<>°</>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
{ props.app.t(`options.${props.pattern.config.name}.${props.option}.title`) }
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<Value setting={props.setting} {...props} />
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className="flex flex-row">
|
<li className="flex flex-row">
|
||||||
<details className="grow">
|
<details className="grow">
|
||||||
|
@ -123,9 +110,15 @@ const Setting = props => {
|
||||||
`}>
|
`}>
|
||||||
<>°</>
|
<>°</>
|
||||||
</span>
|
</span>
|
||||||
<span>
|
{props.setting === 'saMm'
|
||||||
{ props.app.t(`settings.${props.setting}.title`) }
|
? (
|
||||||
</span>
|
<>
|
||||||
|
<span>{props.app.t(`settings.sa.title`)}</span>
|
||||||
|
<span className="ml-4 opacity-50">[ {props.app.t(`app.size`)} ]</span>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
: <span>{props.app.t(`settings.${props.setting}.title`)}</span>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<Value setting={props.setting} {...props} />
|
<Value setting={props.setting} {...props} />
|
||||||
<Chevron w={6} m={3}/>
|
<Chevron w={6} m={3}/>
|
||||||
|
|
|
@ -80,6 +80,7 @@ const WorkbenchWrapper = ({ app, pattern }) => {
|
||||||
gist={gist}
|
gist={gist}
|
||||||
updateGist={updateGist}
|
updateGist={updateGist}
|
||||||
unsetGist={unsetGist}
|
unsetGist={unsetGist}
|
||||||
|
setGist={setGist}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue