wip: Fix all design option inputs
This commit is contained in:
parent
899b323563
commit
e78864f274
4 changed files with 76 additions and 25 deletions
|
@ -35,8 +35,13 @@ import { OptionsIcon } from '@freesewing/react/components/Icon'
|
||||||
*/
|
*/
|
||||||
export const DesignOptionsMenu = ({ Design, isFirst = true, state, i18n, update }) => {
|
export const DesignOptionsMenu = ({ Design, isFirst = true, state, i18n, update }) => {
|
||||||
const structure = useMemo(
|
const structure = useMemo(
|
||||||
() => menuDesignOptionsStructure(Design.patternConfig.options, state.settings),
|
() =>
|
||||||
[Design.patternConfig, state.settings]
|
menuDesignOptionsStructure(
|
||||||
|
Design.designConfig.data.id,
|
||||||
|
Design.patternConfig.options,
|
||||||
|
state.settings
|
||||||
|
),
|
||||||
|
[Design.designConfig.data.id, Design.patternConfig, state.settings]
|
||||||
)
|
)
|
||||||
const updateHandler = useCallback(
|
const updateHandler = useCallback(
|
||||||
(name, value = '__UNSET__') => update.settings(['options', ...name], value),
|
(name, value = '__UNSET__') => update.settings(['options', ...name], value),
|
||||||
|
|
|
@ -10,9 +10,9 @@ import { capitalize } from '@freesewing/core'
|
||||||
/** A boolean version of {@see MenuListInput} that sets up the necessary configuration */
|
/** A boolean version of {@see MenuListInput} that sets up the necessary configuration */
|
||||||
export const MenuBoolInput = (props) => {
|
export const MenuBoolInput = (props) => {
|
||||||
const { name, config } = props
|
const { name, config } = props
|
||||||
const boolConfig = useBoolConfig(name, config)
|
//const boolConfig = useBoolConfig(name, config)
|
||||||
|
|
||||||
return <MenuListInput {...props} config={boolConfig} />
|
return <MenuListInput {...props} />
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A placeholder for an input to handle constant values */
|
/** A placeholder for an input to handle constant values */
|
||||||
|
@ -136,13 +136,19 @@ export const MenuListInput = ({
|
||||||
onClick={() => handleChange(entry)}
|
onClick={() => handleChange(entry)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`tw-w-full tw-flex tw-items-start ${
|
className={`tw-w-full tw-flex ${
|
||||||
sideBySide ? 'tw-flex-row tw-justify-between tw-gap-2' : 'tw-flex-col'
|
sideBySide
|
||||||
|
? 'tw-flex-row tw-justify-between tw-gap-2 tw-items-center'
|
||||||
|
: 'tw-flex-col tw-items-start'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="tw-font-semibold tw-shrink-0">{config.choiceTitles[entry]}</div>
|
<div className="tw-font-semibold">{config.choiceTitles[entry]}</div>
|
||||||
{compact || !config.choiceDescriptions ? null : (
|
{compact || !config.choiceDescriptions ? null : (
|
||||||
<div className="tw-text-base tw-font-normal">{config.choiceDescriptions[entry]}</div>
|
<div
|
||||||
|
className={`${config.dense ? 'tw-text-sm tw-leading-5 tw-py-1' : 'tw-text-base'} tw-font-normal`}
|
||||||
|
>
|
||||||
|
{config.choiceDescriptions[entry]}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</ButtonFrame>
|
</ButtonFrame>
|
||||||
|
@ -390,19 +396,6 @@ const useBoolConfig = (name, config) => {
|
||||||
/** an input for the 'only' setting. toggles individual parts*/
|
/** an input for the 'only' setting. toggles individual parts*/
|
||||||
export const MenuOnlySettingInput = (props) => {
|
export const MenuOnlySettingInput = (props) => {
|
||||||
const { config } = props
|
const { config } = props
|
||||||
//config.sideBySide = true
|
|
||||||
//config.titleMethod = (entry, t) => {
|
|
||||||
// const chunks = entry.split('.')
|
|
||||||
// return <span className="tw-font-medium tw-text-base">{entry}</span> //t(`${chunks[0]}:${chunks[1]}`)}</span>
|
|
||||||
//}
|
|
||||||
//config.valueMethod = (entry) => (
|
|
||||||
// <span className="tw-text-sm">{capitalize(entry.split('.')[0])}</span>
|
|
||||||
//)
|
|
||||||
//config.dense = true
|
|
||||||
// Sort alphabetically
|
|
||||||
//const order = []
|
|
||||||
//order.sort()
|
|
||||||
console.log(i18n)
|
|
||||||
config.list = config.list.sort()
|
config.list = config.list.sort()
|
||||||
config.choiceTitles = {}
|
config.choiceTitles = {}
|
||||||
for (const part of config.list) {
|
for (const part of config.list) {
|
||||||
|
|
|
@ -1,20 +1,73 @@
|
||||||
|
import React from 'react'
|
||||||
import { mergeOptions } from '@freesewing/core'
|
import { mergeOptions } from '@freesewing/core'
|
||||||
import { designOptionType, set, orderBy } from '@freesewing/utils'
|
import { designOptionType, set, orderBy } from '@freesewing/utils'
|
||||||
|
import { i18n } from '@freesewing/collection'
|
||||||
|
import { linkClasses } from '@freesewing/utils'
|
||||||
|
|
||||||
export function menuDesignOptionsStructure(options, settings, asFullList = false) {
|
const DesignDocsLink = ({ design, item }) => (
|
||||||
|
<a
|
||||||
|
href={`/docs/designs/${design}/options/#${item.toLowerCase()}`}
|
||||||
|
className={`${linkClasses} tw-px-2`}
|
||||||
|
target="_BLANK"
|
||||||
|
>
|
||||||
|
Learn more
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
|
||||||
|
export function menuDesignOptionsStructure(design, options, settings, asFullList = false) {
|
||||||
if (!options) return options
|
if (!options) return options
|
||||||
const sorted = {}
|
const sorted = {}
|
||||||
for (const [name, option] of Object.entries(options)) {
|
for (const [name, option] of Object.entries(options)) {
|
||||||
if (typeof option === 'object') sorted[name] = { ...option, name }
|
if (typeof option === 'object') {
|
||||||
|
sorted[name] = {
|
||||||
|
...option,
|
||||||
|
name,
|
||||||
|
title: i18n[design].en.o[name].t,
|
||||||
|
about: (
|
||||||
|
<span>
|
||||||
|
{i18n[design].en.o[name].d}
|
||||||
|
<DesignDocsLink item={name} design={design} />
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
dense: true,
|
||||||
|
sideBySide: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const menu = {}
|
const menu = {}
|
||||||
// Fixme: One day we should sort this based on the translation
|
|
||||||
for (const option of orderBy(sorted, ['order', 'menu', 'name'], ['asc', 'asc', 'asc'])) {
|
for (const option of orderBy(sorted, ['order', 'menu', 'name'], ['asc', 'asc', 'asc'])) {
|
||||||
if (typeof option === 'object') {
|
if (typeof option === 'object') {
|
||||||
const oType = designOptionType(option)
|
const oType = designOptionType(option)
|
||||||
option.dflt = option.dflt || option[oType]
|
option.dflt = option.dflt || option[oType]
|
||||||
|
// Percentage option tweaks
|
||||||
if (oType === 'pct') option.dflt /= 100
|
if (oType === 'pct') option.dflt /= 100
|
||||||
|
// List option tweaks
|
||||||
|
else if (oType === 'list') {
|
||||||
|
option.valueTitles = {}
|
||||||
|
option.choiceTitles = {}
|
||||||
|
option.choiceDescriptions = {}
|
||||||
|
for (const entry of option.list) {
|
||||||
|
option.choiceTitles[entry] = i18n[design].en.o[`${option.name}.${entry}`].t
|
||||||
|
option.choiceDescriptions[entry] = i18n[design].en.o[`${option.name}.${entry}`].d
|
||||||
|
option.valueTitles[entry] = i18n[design].en.o[`${option.name}.${entry}`].t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Bool option tweaks
|
||||||
|
else if (oType === 'bool') {
|
||||||
|
option.list = [false, true]
|
||||||
|
option.valueTitles = {}
|
||||||
|
option.choiceTitles = {}
|
||||||
|
option.choiceDescriptions = {}
|
||||||
|
for (const entry of option.list) {
|
||||||
|
option.choiceTitles.false = i18n[design].en.o[`${option.name}No`].t
|
||||||
|
option.choiceDescriptions.false = i18n[design].en.o[`${option.name}No`].d
|
||||||
|
option.valueTitles.false = 'No'
|
||||||
|
option.choiceTitles.true = i18n[design].en.o[`${option.name}Yes`].t
|
||||||
|
option.choiceDescriptions.true = i18n[design].en.o[`${option.name}Yes`].d
|
||||||
|
option.valueTitles.true = 'Yes'
|
||||||
|
}
|
||||||
|
}
|
||||||
if (typeof option.menu === 'function')
|
if (typeof option.menu === 'function')
|
||||||
option.menu = asFullList
|
option.menu = asFullList
|
||||||
? 'conditional'
|
? 'conditional'
|
||||||
|
|
|
@ -98,7 +98,7 @@ export const ButtonFrame = ({
|
||||||
}) => (
|
}) => (
|
||||||
<button
|
<button
|
||||||
className={`
|
className={`
|
||||||
tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-secondary
|
tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-secondary tw-h-fit
|
||||||
tw-w-full ${dense ? 'tw-mt-1 tw-daisy-btn-sm tw-font-light' : 'tw-mt-2 tw-py-4 tw-h-auto tw-content-start'}
|
tw-w-full ${dense ? 'tw-mt-1 tw-daisy-btn-sm tw-font-light' : 'tw-mt-2 tw-py-4 tw-h-auto tw-content-start'}
|
||||||
tw-border-2 tw-border-secondary tw-text-left tw-bg-opacity-20
|
tw-border-2 tw-border-secondary tw-text-left tw-bg-opacity-20
|
||||||
${accordion ? 'hover:tw-bg-transparent' : 'hover:tw-bg-secondary hover:tw-bg-opacity-10'}
|
${accordion ? 'hover:tw-bg-transparent' : 'hover:tw-bg-secondary hover:tw-bg-opacity-10'}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue