diff --git a/packages/react/components/Editor/components/HeaderMenu.mjs b/packages/react/components/Editor/components/HeaderMenu.mjs index 50d664d5f0b..6e9c6db55d0 100644 --- a/packages/react/components/Editor/components/HeaderMenu.mjs +++ b/packages/react/components/Editor/components/HeaderMenu.mjs @@ -2,6 +2,7 @@ import { missingMeasurements, flattenFlags } from '../lib/index.mjs' // Hooks import React, { useState } from 'react' +import { useDesignTranslation } from '@freesewing/react/hooks/useDesignTranslation' // Components import { Null } from './Null.mjs' import { AsideViewMenuSpacer } from './AsideViewMenu.mjs' @@ -65,15 +66,16 @@ export const HeaderMenuAllViews = ({ config, state, update, open, setOpen }) => ) export const HeaderMenuDraftView = (props) => { + const i18n = useDesignTranslation(props.Design.designConfig.data.id) const flags = props.pattern?.setStores?.[0]?.plugins?.['plugin-annotations']?.flags return ( <>
- - - - {flags ? : null} + + + + {flags ? : null}
@@ -114,7 +116,8 @@ export const HeaderMenuDropdown = (props) => {
{props.children}
diff --git a/packages/react/components/Editor/components/PatternLayout.mjs b/packages/react/components/Editor/components/PatternLayout.mjs index 5a9dee4fa26..8cbaeeb0edd 100644 --- a/packages/react/components/Editor/components/PatternLayout.mjs +++ b/packages/react/components/Editor/components/PatternLayout.mjs @@ -17,13 +17,15 @@ export const PatternLayout = (props) => { return ( -
+
-
-
{props.output}
+
+
+ {props.output} +
{menu ? (
{menu}
diff --git a/packages/react/components/Editor/components/ZoomablePattern.mjs b/packages/react/components/Editor/components/ZoomablePattern.mjs index 7e71cda3317..803ac63139a 100644 --- a/packages/react/components/Editor/components/ZoomablePattern.mjs +++ b/packages/react/components/Editor/components/ZoomablePattern.mjs @@ -28,7 +28,7 @@ export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref )} diff --git a/packages/react/components/Editor/components/menus/Container.mjs b/packages/react/components/Editor/components/menus/Container.mjs index 74da6f0d16d..5099d2a43a7 100644 --- a/packages/react/components/Editor/components/menus/Container.mjs +++ b/packages/react/components/Editor/components/menus/Container.mjs @@ -104,7 +104,11 @@ export const MenuItem = ({ return ( {i18n.en.o[name].d}} + label={ + + {config.choiceTitles ? config.choiceTitles[current] : i18n.en.o[name].d} + + } id={config.name} labelBR={
{buttons}
} labelBL={ @@ -120,6 +124,19 @@ export const MenuItem = ({ ) } +const coreLabels = { + complete: 'Details', + only: 'Included Parts', + paperless: 'Paperless', + sabool: 'Include Seam Allowance', +} + +const getItemLabel = (i18n, name) => { + if (Object.keys(coreLabels).includes(name)) return coreLabels[name] + + return i18n && i18n.en.o[name]?.t ? i18n.en.o[name].t : name +} + /** * A component for recursively displaying groups of menu items. * Accepts any object where menu item configurations are keyed by name @@ -189,9 +206,7 @@ export const MenuItemGroup = ({
- - {i18n && i18n.en.o[itemName]?.t ? i18n.en.o[itemName].t : itemName} - + {getItemLabel(i18n, itemName)}
{ +export const CoreSettingsMenu = ({ Design, state, i18n, update }) => { const structure = menuCoreSettingsStructure({ - language, units: state.settings?.units, sabool: state.settings?.sabool, parts: Design.patternConfig.draftOrder, @@ -71,11 +69,10 @@ export const CoreSettingsMenu = ({ update, state, language, Design }) => { currentValues: state.settings || {}, Icon: SettingsIcon, Item: (props) => ( - + ), isFirst: true, - name: 'pe:designOptions', - language: state.locale, + name: 'Core Settings', passProps: { ux: state.ui.ux, settings: state.settings, @@ -88,6 +85,7 @@ export const CoreSettingsMenu = ({ update, state, language, Design }) => { Design, inputs, values, + i18n, }} /> ) @@ -120,7 +118,7 @@ export const CoreSetting = ({ name, config, ux, updateHandler, current, passProp : updateHandler return ( - { +export const ClearAllButton = ({ setSettings, compact = false }) => { return (
) diff --git a/packages/react/components/Editor/components/menus/DesignOptionsMenu.mjs b/packages/react/components/Editor/components/menus/DesignOptionsMenu.mjs index 9eecae96aef..99d2f482ac7 100644 --- a/packages/react/components/Editor/components/menus/DesignOptionsMenu.mjs +++ b/packages/react/components/Editor/components/menus/DesignOptionsMenu.mjs @@ -3,7 +3,6 @@ import { menuDesignOptionsStructure } from '../../lib/index.mjs' import { designOptionType } from '@freesewing/utils' // Hooks import React, { useCallback, useMemo } from 'react' -import { useDesignTranslation } from '@freesewing/react/hooks/useDesignTranslation' // Components import { MenuBoolInput, @@ -25,16 +24,16 @@ import { import { MenuItemGroup, MenuItem } from './Container.mjs' import { OptionsIcon } from '@freesewing/react/components/Icon' -// /** * The design options menu + * * @param {object} props.Design - An object holding the Design instance * @param {String} props.isFirst - Boolean indicating whether this is the first/top entry of the menu * @param {Object} props.state - Object holding state + * @param {Object} props.i18n - Object holding translations loaded from the design * @param {Object} props.update - Object holding state handlers */ -export const DesignOptionsMenu = ({ Design, isFirst = true, state, update }) => { - const i18n = useDesignTranslation(Design.designConfig.data.id) +export const DesignOptionsMenu = ({ Design, isFirst = true, state, i18n, update }) => { const structure = useMemo( () => menuDesignOptionsStructure(Design.patternConfig.options, state.settings), [Design.patternConfig, state.settings] diff --git a/packages/react/components/Editor/components/menus/DraftMenu.mjs b/packages/react/components/Editor/components/menus/DraftMenu.mjs index 2ebe13aa6a7..259f10f87be 100644 --- a/packages/react/components/Editor/components/menus/DraftMenu.mjs +++ b/packages/react/components/Editor/components/menus/DraftMenu.mjs @@ -1,26 +1,32 @@ -export const DraftMenu = ({ Design, pattern, state, Swizzled, update }) => { - // Swizzled methods - const { t } = Swizzled.methods - // Swizzled components - const { FlagsAccordionTitle, FlagsAccordionEntries, Accordion } = Swizzled.components +import React from 'react' +import { OptionsIcon, SettingsIcon, UiIcon } from '@freesewing/react/components/Icon' +import { DesignOptionsMenu } from './DesignOptionsMenu.mjs' +import { CoreSettingsMenu } from './CoreSettingsMenu.mjs' +import { UiPreferencesMenu } from './UiPreferencesMenu.mjs' +import { FlagsAccordionEntries } from '../Flag.mjs' +import { Accordion } from '../Accordion.mjs' - const menuProps = { Design, state, Swizzled, pattern, update } +export const DraftMenu = ({ Design, pattern, state, update }) => { + const menuProps = { Design, state, pattern, update } const sections = [ { - name: 'designOptions', - icon: , - menu: , + t: 'Design Options', + d: 'These options are specific to this design. You can use them to customize your pattern in a variety of ways.', + icon: , + menu: , }, { - name: 'coreSettings', - icon: , - menu: , + t: 'Core Settings', + d: 'These settings are not specific to the design, but instead allow you to customize various parameters of the FreeSewing core library, which generates the design for you.', + icon: , + menu: , }, { - name: 'uiPreferences', - icon: , - menu: , + t: 'UI Preferences', + d: 'These preferences control the UI (User Interface) of the pattern editor', + icon: , + menu: , }, ] @@ -28,11 +34,11 @@ export const DraftMenu = ({ Design, pattern, state, Swizzled, update }) => { items.push( ...sections.map((section) => [ <> -
- {t(`pe:${section.name}.t`)} +
+ {section.t} {section.icon}
-

{t(`pe:${section.name}.d`)}

+

{section.d}

, section.menu, section.name, @@ -43,7 +49,7 @@ export const DraftMenu = ({ Design, pattern, state, Swizzled, update }) => { if (flags) items.push([ - , + , , 'flags', ]) diff --git a/packages/react/components/Editor/components/menus/Input.mjs b/packages/react/components/Editor/components/menus/Input.mjs index dc859e79dc1..045fe95455b 100644 --- a/packages/react/components/Editor/components/menus/Input.mjs +++ b/packages/react/components/Editor/components/menus/Input.mjs @@ -49,6 +49,41 @@ export const MenuDegInput = (props) => { ) } +const getTitleAndDesc = (config = {}, i18n = {}, isDesignOption = false) => { + if (config.choiceTitles && config.choiceDescriptions) { + const current = typeof config.current === 'undefined' ? config.dflt : config.current + return { + title: config.choiceTitles[current], + desc: config.choiceDescriptions[current], + } + } + + console.log(config) + let titleKey = config.choiceTitles + ? config.choiceTitles[entry] + : isDesignOption + ? i18n.en.o[name] + : `${name}.o.${entry}` + if (!config.choiceTitles && i18n && i18n.en.o[`${name}.${entry}`]) + titleKey = i18n.en.o[`${name}.${entry}`] + console.log({ titleKey, titles: config.choiceTitles, isDesignOption }) + const title = config.titleMethod + ? config.titleMethod(entry) + : typeof titleKey === 'string' + ? i18n.en.o[titleKey]?.t + : titleKey.t + const desc = config.valueMethod + ? config.valueMethod(entry) + : typeof titleKey === 'string' + ? i18n.en.o[titleKey]?.d + : titleKey.d + + return { + title: 'fixmeTitle', + desc: 'fixmeDesc', + } +} + /** * An input for selecting and item from a list * @param {String} options.name the name of the property this input changes @@ -80,23 +115,7 @@ export const MenuListInput = ({ }) return config.list.map((entry) => { - let titleKey = config.choiceTitles - ? config.choiceTitles[entry] - : isDesignOption - ? i18n.en.o[name] - : `${name}.o.${entry}` - if (i18n.en.o[`${name}.${entry}`]) titleKey = i18n.en.o[`${name}.${entry}`] - console.log({ titleKey, titles: config.choiceTitles, isDesignOption }) - const title = config.titleMethod - ? config.titleMethod(entry) - : typeof titleKey === 'string' - ? i18n.en.o[titleKey]?.t - : titleKey.t - const desc = config.valueMethod - ? config.valueMethod(entry) - : typeof titleKey === 'string' - ? i18n.en.o[titleKey]?.d - : titleKey.d + const { title, desc } = getTitleAndDesc(config, i18n, isDesignOption) const sideBySide = config.sideBySide || desc.length + title.length < 42 return ( diff --git a/packages/react/components/Editor/components/menus/UiPreferencesMenu.mjs b/packages/react/components/Editor/components/menus/UiPreferencesMenu.mjs index bd48d2025ae..36717d99756 100644 --- a/packages/react/components/Editor/components/menus/UiPreferencesMenu.mjs +++ b/packages/react/components/Editor/components/menus/UiPreferencesMenu.mjs @@ -4,7 +4,7 @@ import { menuUiPreferencesStructure } from '../../lib/index.mjs' // Components import { MenuUxSettingInput, MenuListInput } from './Input.mjs' import { MenuListValue } from './Value.mjs' -import { MenuItemGroup } from './Container.mjs' +import { MenuItemGroup, MenuItem } from './Container.mjs' import { Ux } from '@freesewing/react/components/Ux' export const UiPreferencesMenu = ({ update, state, Design }) => { diff --git a/packages/react/components/Editor/components/views/DraftView.mjs b/packages/react/components/Editor/components/views/DraftView.mjs index e1cf21622df..c2c17fbf663 100644 --- a/packages/react/components/Editor/components/views/DraftView.mjs +++ b/packages/react/components/Editor/components/views/DraftView.mjs @@ -46,7 +46,7 @@ export const DraftView = ({ Design, state, update, config }) => { const __html = pattern.render() output = ( -
+
) } catch (err) { diff --git a/packages/react/components/Editor/lib/core-settings.mjs b/packages/react/components/Editor/lib/core-settings.mjs index 36badad09fc..e6bbfa33b10 100644 --- a/packages/react/components/Editor/lib/core-settings.mjs +++ b/packages/react/components/Editor/lib/core-settings.mjs @@ -64,12 +64,16 @@ export function menuCoreSettingsStructure({ units = 'metric', sabool = false, pa ux: config.uxLevels.core.sa, list: [0, 1], choiceTitles: { - 0: 'saNo', - 1: 'saYes', + 0: 'Do not include seam allowance', + 1: 'Include seam allowance', + }, + choiceDescriptions: { + 0: 'This generates a pattern which does not include any seam allowance. The size of the seam allowance does not matter as no seam allowance will be included', + 1: 'This generates a pattern that will include seam allowance. The size of the seam allowance is set individually', }, valueTitles: { - 0: 'no', - 1: 'yes', + 0: 'No', + 1: 'Yes', }, dflt: 0, icon: SaIcon, @@ -87,12 +91,16 @@ export function menuCoreSettingsStructure({ units = 'metric', sabool = false, pa ux: config.uxLevels.core.paperless, list: [0, 1], choiceTitles: { - 0: 'paperlessNo', - 1: 'paperlessYes', + 0: 'Generate a regular pattern', + 1: 'Generate a paperless pattern', + }, + choiceDescriptions: { + 0: 'This will generate a regular pattern, which you can them print out.', + 1: 'This will generate a pattern with dimensions and a grid, which allows you to transfer it on fabric or another medium without the need to print the pattern.', }, valueTitles: { - 0: 'no', - 1: 'yes', + 0: 'No', + 1: 'Yes', }, dflt: 0, icon: PaperlessIcon, @@ -102,12 +110,16 @@ export function menuCoreSettingsStructure({ units = 'metric', sabool = false, pa list: ['metric', 'imperial'], dflt: 'metric', choiceTitles: { - metric: 'metric', - imperial: 'imperial', + metric: 'Metric', + imperial: 'Imperial', + }, + choiceDescriptions: { + 0: 'Use this if you use the metric system, and centimeters are something you are familiar with. This is the best choice for most people around the world.', + 1: 'Use this if inches are more familiar to you. This is often the preferred choice for people based in the UK & US.', }, valueTitles: { - metric: 'metric', - imperial: 'imperial', + metric: 'Metric', + imperial: 'Imperial', }, icon: UnitsIcon, }, @@ -116,12 +128,16 @@ export function menuCoreSettingsStructure({ units = 'metric', sabool = false, pa list: [1, 0], dflt: 1, choiceTitles: { - 0: 'completeNo', - 1: 'completeYes', + 0: 'Generate a pattern outline', + 1: 'Generate a complete pattern', + }, + choiceDescriptions: { + 0: 'Only generate the outline of the pattern parts. Use this if you are looking to use a laser cutter or have other specific needs.', + 1: 'This will generate a complete pattern with all annotations, markings and lines. Use this if you are not certain what to choose.', }, valueTitles: { - 0: 'no', - 1: 'yes', + 0: 'No', + 1: 'Yes', }, icon: DetailIcon, }, @@ -130,12 +146,16 @@ export function menuCoreSettingsStructure({ units = 'metric', sabool = false, pa list: [1, 0], dflt: 1, choiceTitles: { - 0: 'expandNo', - 1: 'expandYes', + 0: 'Keep pattern parts compact where possible', + 1: 'Expand all pattern parts', + }, + choiceDescriptions: { + 0: 'This will generate a more dense representation of the pattern which includes all info without using up too much space.', + 1: 'This will generate a pattern where all parts are drown to their full size, even if they are simple rectangles.', }, valueTitles: { - 0: 'no', - 1: 'yes', + 0: 'No', + 1: 'Yes', }, icon: ExpandIcon, }, diff --git a/packages/react/components/Editor/lib/ui-preferences.mjs b/packages/react/components/Editor/lib/ui-preferences.mjs index 119984d7f6e..ceca7e40eb8 100644 --- a/packages/react/components/Editor/lib/ui-preferences.mjs +++ b/packages/react/components/Editor/lib/ui-preferences.mjs @@ -25,6 +25,10 @@ export function menuUiPreferencesStructure() { 0: 'pe:noAside', 1: 'pe:withAside', }, + choiceDescriptions: { + 0: 'pe:noAside', + 1: 'pe:withAside', + }, dflt: 1, icon: MenuIcon, }, @@ -35,6 +39,10 @@ export function menuUiPreferencesStructure() { 0: 'pe:websiteMode', 1: 'pe:kioskMode', }, + choiceDescriptions: { + 0: 'pe:noAside', + 1: 'pe:withAside', + }, dflt: 0, icon: KioskIcon, }, @@ -45,6 +53,10 @@ export function menuUiPreferencesStructure() { 0: 'pe:rotateNo', 1: 'pe:rotateYes', }, + choiceDescriptions: { + 0: 'pe:noAside', + 1: 'pe:withAside', + }, dflt: 0, icon: RotateIcon, }, @@ -55,6 +67,10 @@ export function menuUiPreferencesStructure() { react: 'pe:renderWithReact', svg: 'pe:renderWithCore', }, + choiceDescriptions: { + 0: 'pe:noAside', + 1: 'pe:withAside', + }, valueTitles: { react: 'React', svg: 'SVG',