diff --git a/packages/components/index.js b/packages/components/index.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/components/src/SampleConfigurator/OptionGroup/index.js b/packages/components/src/SampleConfigurator/OptionGroup/index.js new file mode 100644 index 00000000000..2fde8075587 --- /dev/null +++ b/packages/components/src/SampleConfigurator/OptionGroup/index.js @@ -0,0 +1,51 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import { optionType } from "@freesewing/utils"; +import { FormattedMessage } from "react-intl"; +import { injectIntl } from "react-intl"; + +const OptionGroup = props => { + return ( + + {props.options.map(name => { + let key = name; + let output = []; + if (typeof name === "object") { + key = Object.keys(name).pop(); + // Subgroup + for (let subGroup of Object.keys(name)) { + output.push( +
+ +
+ ); + let children = []; + for (let option of name[subGroup]) children.push(

{option}

); + output.push(); + } + } else + output.push( +
  • + props.sampleOption(name)}> + + +
  • + ); + + return output; + })} +
    + ); +}; + +OptionGroup.propTypes = { + config: PropTypes.object.isRequired, + options: PropTypes.array.isRequired, + units: PropTypes.oneOf(["metric", "imperial"]).isRequired +}; + +OptionGroup.defaultProps = {}; + +export default injectIntl(OptionGroup); diff --git a/packages/components/src/SampleConfigurator/OptionGroup/stories.js b/packages/components/src/SampleConfigurator/OptionGroup/stories.js new file mode 100644 index 00000000000..f2d23347886 --- /dev/null +++ b/packages/components/src/SampleConfigurator/OptionGroup/stories.js @@ -0,0 +1,40 @@ +import React from "react"; +import { storiesOf } from "@storybook/react"; +import OptionGroup from "."; + +const options = { + armholeDrop: { pct: 10, min: 1, max: 75 }, + backlineBend: { pct: 50, min: 50, max: 100 }, + chestEase: { pct: 8, min: 0, max: 20 }, + hipsEase: { pct: 8, min: 0, max: 20 }, + lengthBonus: { pct: 10, min: -20, max: 60 }, + necklineBend: { pct: 100, min: 40, max: 100 }, + necklineDrop: { pct: 20, min: 10, max: 35 }, + stretchFactor: { pct: 5, min: 0, max: 15 }, + shoulderStrapWidth: { pct: 15, min: 10, max: 40 }, + shoulderStrapPlacement: { pct: 40, min: 20, max: 80 } +}; + +const props = { + raiseEvent: (type, data) => + console.log(`Action of type ${type} triggered, data passed is`, data), + updateValue: (type, data) => + console.log(`Update ${type} with new value`, data), + gist: { + settings: { + options: {} + } + }, + pattern: { + config: { + name: "aaron", + options: options + } + }, + dflts: { options: {} }, + options: Object.keys(options) +}; + +storiesOf("Low level/OptionGroup", module).add("Simon metric", () => ( + +)); diff --git a/packages/components/src/SampleConfigurator/PatternOptions/index.js b/packages/components/src/SampleConfigurator/PatternOptions/index.js new file mode 100644 index 00000000000..d0c19e1f1a5 --- /dev/null +++ b/packages/components/src/SampleConfigurator/PatternOptions/index.js @@ -0,0 +1,49 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import OptionGroup from "../OptionGroup"; +import { optionType } from "@freesewing/utils"; +import { FormattedMessage } from "react-intl"; +import DownIcon from "@material-ui/icons/KeyboardArrowDown"; + +const PatternOptions = props => { + const renderGroup = group => { + let output = []; + let children = ( + + ); + output.push( +
  • +

    + +

    + {children} +
  • + ); + + return output; + }; + + return ( + + ); +}; + +PatternOptions.propTypes = { + config: PropTypes.object.isRequired, + gist: PropTypes.object.isRequired, + sampleOption: PropTypes.func.isRequired +}; + +PatternOptions.defaultProps = {}; + +export default PatternOptions; diff --git a/packages/components/src/SampleConfigurator/PatternOptions/stories.js b/packages/components/src/SampleConfigurator/PatternOptions/stories.js new file mode 100644 index 00000000000..13e2fdbdf50 --- /dev/null +++ b/packages/components/src/SampleConfigurator/PatternOptions/stories.js @@ -0,0 +1,28 @@ +import React from "react"; +import { storiesOf } from "@storybook/react"; +import PatternOptions from "."; + +const props = { + raiseEvent: (type, data) => + console.log(`Action of type ${type} triggered, data passed is`, data), + updateValue: (type, data) => + console.log(`Update ${type} with new value`, data), + gist: { + settings: { + options: {} + } + } +}; + +storiesOf("Low level/PatternOptions", module) + .add("Simon metric", () => ( + + )) + .add("Trayvon imperial", () => ( + + )); diff --git a/packages/components/src/SampleConfigurator/index.js b/packages/components/src/SampleConfigurator/index.js new file mode 100644 index 00000000000..46927d784e8 --- /dev/null +++ b/packages/components/src/SampleConfigurator/index.js @@ -0,0 +1,109 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import { FormattedMessage } from "react-intl"; +import PatternOptions from "./PatternOptions"; +import models from "@freesewing/models"; + +const SampleConfigurator = props => { + const [expanded, setExpanded] = useState([]); + + const toggleGroup = group => { + let shown = expanded.slice(0); + let index = shown.indexOf(group); + if (index === -1) shown.push(group); + else shown.splice(index, 1); + setExpanded(shown); + }; + + const sampleOption = option => { + props.updateGist( + { + type: "option", + option + }, + "settings", + "sample" + ); + }; + + const sampleMeasurement = measurement => { + props.updateGist( + { + type: "measurement", + measurement + }, + "settings", + "sample" + ); + }; + + const sampleModels = models => { + props.updateGist( + { + type: "models", + models + }, + "settings", + "sample" + ); + }; + let antMan = { + ant: {}, + man: models.manSize42 + }; + for (let m in models.manSize42) antMan.ant[m] = antMan.man[m] / 10; + + return ( + + ); +}; + +SampleConfigurator.propTypes = { + units: PropTypes.oneOf(["metric", "imperial"]).isRequired +}; + +SampleConfigurator.defaultProps = {}; + +export default SampleConfigurator; diff --git a/packages/components/src/SampleConfigurator/stories.js b/packages/components/src/SampleConfigurator/stories.js new file mode 100644 index 00000000000..7a8944b6a27 --- /dev/null +++ b/packages/components/src/SampleConfigurator/stories.js @@ -0,0 +1,20 @@ +import React from "react"; +import { storiesOf } from "@storybook/react"; +import GistConfigurator from "."; +//import { IntlProvider } from "react-intl"; +//import { strings } from "@freesewing/i18n"; + +const props = { + raiseEvent: (type, data) => + console.log(`Action of type ${type} triggered, data passed is`, data), + updateValue: (type, data) => + console.log(`Update ${type} with new value`, data) +}; + +storiesOf("DraftConfigurator", module) + .add("Simon metric", () => ( + + )) + .add("Trayvon imperial", () => ( + + )); diff --git a/packages/components/src/Workbench/DraftPattern/index.js b/packages/components/src/Workbench/DraftPattern/index.js index e226b5c5582..86a979774e1 100644 --- a/packages/components/src/Workbench/DraftPattern/index.js +++ b/packages/components/src/Workbench/DraftPattern/index.js @@ -3,21 +3,12 @@ import PropTypes from "prop-types"; import { defaultGist } from "@freesewing/utils"; import Draft from "../../Draft"; import DraftConfigurator from "../../DraftConfigurator"; -//import themePlugin from "@freesewing/plugin-theme"; -//import svgattrPlugin from "@freesewing/plugin-svgattr"; -//import i18nPlugin from "@freesewing/plugin-i18n"; -//import validatePlugin from "@freesewing/plugin-validate"; import { strings } from "@freesewing/i18n"; import { FormattedMessage } from "react-intl"; const DraftPattern = props => { let pattern = new props.Pattern(props.gist.settings); pattern.draft(); - //.use(themePlugin) - //.use(svgattrPlugin, { class: "freesewing draft" }) - //.use(i18nPlugin, { strings: strings }) - //.use(validatePlugin) - //
    {pattern.render()}
    return (
    diff --git a/packages/components/src/Workbench/Measurements/index.js b/packages/components/src/Workbench/Measurements/index.js index be5786b2eea..897bd9f0c93 100644 --- a/packages/components/src/Workbench/Measurements/index.js +++ b/packages/components/src/Workbench/Measurements/index.js @@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react"; import PropTypes from "prop-types"; import { storage } from "@freesewing/utils"; import Button from "@material-ui/core/Button"; -import { FormattedMessage } from "react-intl"; +import { FormattedMessage, FormattedHTMLMessage } from "react-intl"; import FormFieldMeasurement from "../../.form/FormFieldMeasurement"; import models from "@freesewing/models"; @@ -11,7 +11,8 @@ const Measurements = props => { container: { display: "flex", flexDirection: "row", - width: "100%" + width: "100%", + minHeight: "70vh" }, chooser: { width: "100%", @@ -27,6 +28,33 @@ const Measurements = props => { return props.measurements[m]; }; + if (props.required.length < 1) + return ( +
    +
    +

    + +

    +

    + +

    +

    + +

    +

    + +   + + {props.language}.freesewing.dev/core/config + +

    +
    +
    + ); return (
    diff --git a/packages/components/src/Workbench/SamplePattern/index.js b/packages/components/src/Workbench/SamplePattern/index.js new file mode 100644 index 00000000000..c6c3420d3d7 --- /dev/null +++ b/packages/components/src/Workbench/SamplePattern/index.js @@ -0,0 +1,60 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { defaultGist } from "@freesewing/utils"; +import Draft from "../../Draft"; +import SampleConfigurator from "../../SampleConfigurator"; +import svgattrPlugin from "@freesewing/plugin-svgattr"; +import { strings } from "@freesewing/i18n"; +import { FormattedMessage } from "react-intl"; + +const SamplePattern = props => { + let pattern = new props.Pattern(props.gist.settings).use(svgattrPlugin, { + class: "freesewing draft" + }); + try { + pattern.sample(); + } catch (err) { + console.log(err); + } + return ( +
    +
    +

    + +

    +
    +

    gist

    +
    {JSON.stringify(props.gist, null, 2)}
    +
    + + +
    + ); +}; + +SamplePattern.propTypes = { + gist: PropTypes.object.isRequired, + updateGist: PropTypes.func.isRequired, + config: PropTypes.object.isRequired, + raiseEvent: PropTypes.func.isRequired, + Pattern: PropTypes.func.isRequired, + units: PropTypes.oneOf(["metric", "imperial"]) +}; + +SamplePattern.defaultProps = { + units: "metric", + pointInfo: null +}; + +export default SamplePattern; diff --git a/packages/components/src/Workbench/index.js b/packages/components/src/Workbench/index.js index 8e6bfa35c49..5005bcaf82e 100644 --- a/packages/components/src/Workbench/index.js +++ b/packages/components/src/Workbench/index.js @@ -14,12 +14,13 @@ import LanguageIcon from "@material-ui/icons/Translate"; import DarkModeIcon from "@material-ui/icons/Brightness3"; import LanguageChooser from "./LanguageChooser"; import DraftPattern from "./DraftPattern"; +import SamplePattern from "./SamplePattern"; import Welcome from "./Welcome"; import Footer from "../Footer"; import Measurements from "./Measurements"; const Workbench = props => { - const [display, setDisplay] = useState("welcome"); + const [display, setDisplay] = useState(null); const [pattern, setPattern] = useState(false); const [theme, setTheme] = useState("light"); const [measurements, setMeasurements] = useState(null); @@ -27,6 +28,7 @@ const Workbench = props => { let m = getMeasurements(); setMeasurements(m); props.updateGist(m, "settings", "measurements"); + setDisplay(getDisplay()); }, []); useEffect(() => { if (props.from) props.importGist(props.from); @@ -36,6 +38,11 @@ const Workbench = props => { props.updateGist(props.language, "settings", "locale"); }, [props.language]); + const getDisplay = () => storage.get(props.config.name + "-display"); + const saveDisplay = d => { + setDisplay(d); + storage.set(props.config.name + "-display", d); + }; const getMeasurements = () => storage.get(props.config.name + "-measurements"); const saveMeasurements = data => { @@ -66,7 +73,7 @@ const Workbench = props => { return false; }; - const showLanguageChooser = () => setDisplay("language"); + const showLanguageChooser = () => saveDisplay("language"); const updatePattern = p => { setPattern(p); store.set("pattern", p); @@ -83,19 +90,19 @@ const Workbench = props => { left: { draft: { type: "button", - onClick: () => setDisplay("draft"), + onClick: () => saveDisplay("draft"), text: "cfp.draftYourPattern", active: display === "draft" ? true : false }, sample: { type: "button", - onClick: () => setDisplay("sample"), + onClick: () => saveDisplay("sample"), text: "cfp.testYourPattern", active: display === "sample" ? true : false }, measurements: { type: "button", - onClick: () => setDisplay("measurements"), + onClick: () => saveDisplay("measurements"), text: "app.measurements", active: display === "measurements" ? true : false } @@ -108,7 +115,7 @@ const Workbench = props => { }, language: { type: "button", - onClick: () => setDisplay("languages"), + onClick: () => saveDisplay("languages"), text: , title: "Languages", active: display === "languages" ? true : false @@ -128,12 +135,12 @@ const Workbench = props => { main = ( ); break; case "draft": - if (measurementsMissing()) setDisplay("measurements"); + if (measurementsMissing()) saveDisplay("measurements"); main = ( { ); break; case "sample": - if (measurementsMissing()) setDisplay("measurements"); - main =

    Sample: TODO

    ; + if (measurementsMissing()) saveDisplay("measurements"); + main = ( + + ); break; case "measurements": main = ( @@ -158,11 +175,12 @@ const Workbench = props => { units={props.units} updateMeasurement={updateMeasurement} preloadMeasurements={preloadMeasurements} + language={props.language} /> ); break; default: - main = ; + main = ; } const themes = { dark, light }; @@ -175,7 +193,7 @@ const Workbench = props => { } > {display !== "welcome" ? ( - setDisplay("welcome")} /> + saveDisplay("welcome")} /> ) : null} {main} {display !== "welcome" ?