1
0
Fork 0

wip: Fix all design option inputs

This commit is contained in:
joostdecock 2025-01-26 17:22:24 +01:00
parent 899b323563
commit e78864f274
4 changed files with 76 additions and 25 deletions

View file

@ -35,8 +35,13 @@ import { OptionsIcon } from '@freesewing/react/components/Icon'
*/
export const DesignOptionsMenu = ({ Design, isFirst = true, state, i18n, update }) => {
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(
(name, value = '__UNSET__') => update.settings(['options', ...name], value),

View file

@ -10,9 +10,9 @@ import { capitalize } from '@freesewing/core'
/** A boolean version of {@see MenuListInput} that sets up the necessary configuration */
export const MenuBoolInput = (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 */
@ -136,13 +136,19 @@ export const MenuListInput = ({
onClick={() => handleChange(entry)}
>
<div
className={`tw-w-full tw-flex tw-items-start ${
sideBySide ? 'tw-flex-row tw-justify-between tw-gap-2' : 'tw-flex-col'
className={`tw-w-full tw-flex ${
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 : (
<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>
</ButtonFrame>
@ -390,19 +396,6 @@ const useBoolConfig = (name, config) => {
/** an input for the 'only' setting. toggles individual parts*/
export const MenuOnlySettingInput = (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.choiceTitles = {}
for (const part of config.list) {

View file

@ -1,20 +1,73 @@
import React from 'react'
import { mergeOptions } from '@freesewing/core'
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
const sorted = {}
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 = {}
// Fixme: One day we should sort this based on the translation
for (const option of orderBy(sorted, ['order', 'menu', 'name'], ['asc', 'asc', 'asc'])) {
if (typeof option === 'object') {
const oType = designOptionType(option)
option.dflt = option.dflt || option[oType]
// Percentage option tweaks
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')
option.menu = asFullList
? 'conditional'

View file

@ -98,7 +98,7 @@ export const ButtonFrame = ({
}) => (
<button
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-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'}