🚧 Added sampling to workbench
This commit is contained in:
parent
3754680841
commit
c2628a0a52
19 changed files with 463 additions and 33 deletions
|
@ -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 (
|
||||||
|
<React.Fragment>
|
||||||
|
{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(
|
||||||
|
<h5 key={subGroup + "-title"} className="subheading">
|
||||||
|
<FormattedMessage id={"optiongroups." + subGroup} />
|
||||||
|
</h5>
|
||||||
|
);
|
||||||
|
let children = [];
|
||||||
|
for (let option of name[subGroup]) children.push(<p>{option}</p>);
|
||||||
|
output.push(<ul style={{ paddingLeft: "1rem" }}>{children}</ul>);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
output.push(
|
||||||
|
<li>
|
||||||
|
<a href="#logo" onClick={() => props.sampleOption(name)}>
|
||||||
|
<FormattedMessage
|
||||||
|
id={"options." + props.config.name + "." + name + ".title"}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
})}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
OptionGroup.propTypes = {
|
||||||
|
config: PropTypes.object.isRequired,
|
||||||
|
options: PropTypes.array.isRequired,
|
||||||
|
units: PropTypes.oneOf(["metric", "imperial"]).isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
OptionGroup.defaultProps = {};
|
||||||
|
|
||||||
|
export default injectIntl(OptionGroup);
|
|
@ -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", () => (
|
||||||
|
<OptionGroup pattern="simon" {...props} units="metric" />
|
||||||
|
));
|
|
@ -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 = (
|
||||||
|
<ul className="links">
|
||||||
|
<OptionGroup
|
||||||
|
key={group + "-group"}
|
||||||
|
units={props.units}
|
||||||
|
config={props.config}
|
||||||
|
options={props.config.optionGroups[group]}
|
||||||
|
sampleOption={props.sampleOption}
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
output.push(
|
||||||
|
<li key={group + "-ghead"} className="nodot">
|
||||||
|
<h3>
|
||||||
|
<FormattedMessage id={"optiongroups." + group} />
|
||||||
|
</h3>
|
||||||
|
{children}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul className="links">
|
||||||
|
{Object.keys(props.config.optionGroups).map(group => renderGroup(group))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PatternOptions.propTypes = {
|
||||||
|
config: PropTypes.object.isRequired,
|
||||||
|
gist: PropTypes.object.isRequired,
|
||||||
|
sampleOption: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
PatternOptions.defaultProps = {};
|
||||||
|
|
||||||
|
export default PatternOptions;
|
|
@ -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", () => (
|
||||||
|
<PatternOptions pattern="simon" gist={false} units="metric" {...props} />
|
||||||
|
))
|
||||||
|
.add("Trayvon imperial", () => (
|
||||||
|
<PatternOptions
|
||||||
|
pattern="trayvon"
|
||||||
|
gist={false}
|
||||||
|
units="imperial"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
109
packages/components/src/SampleConfigurator/index.js
Normal file
109
packages/components/src/SampleConfigurator/index.js
Normal file
|
@ -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 (
|
||||||
|
<ul className="links">
|
||||||
|
<li className="nodot">
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage id="app.patternOptions" />
|
||||||
|
</h2>
|
||||||
|
<PatternOptions
|
||||||
|
config={props.config}
|
||||||
|
gist={props.gist}
|
||||||
|
sampleOption={sampleOption}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
<li className="nodot">
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage id="app.measurements" />
|
||||||
|
</h2>
|
||||||
|
<ul style={{ paddingLeft: "1rem" }}>
|
||||||
|
{props.config.measurements.map(m => (
|
||||||
|
<li key={m}>
|
||||||
|
<a href="#logo" onClick={() => sampleMeasurement(m)}>
|
||||||
|
<FormattedMessage id={"measurements." + m} />
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li className="nodot">
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage id="app.models" />
|
||||||
|
</h2>
|
||||||
|
<ul style={{ paddingLeft: "1rem" }}>
|
||||||
|
<li>
|
||||||
|
<a href="#logo" onClick={() => sampleModels(models)}>
|
||||||
|
<FormattedMessage id="app.withoutBreasts" />
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#logo" onClick={() => sampleModels(antMan)}>
|
||||||
|
Antman
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SampleConfigurator.propTypes = {
|
||||||
|
units: PropTypes.oneOf(["metric", "imperial"]).isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
SampleConfigurator.defaultProps = {};
|
||||||
|
|
||||||
|
export default SampleConfigurator;
|
20
packages/components/src/SampleConfigurator/stories.js
Normal file
20
packages/components/src/SampleConfigurator/stories.js
Normal file
|
@ -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", () => (
|
||||||
|
<GistConfigurator pattern="simon" {...props} units="metric" />
|
||||||
|
))
|
||||||
|
.add("Trayvon imperial", () => (
|
||||||
|
<GistConfigurator pattern="trayvon" {...props} units="imperial" />
|
||||||
|
));
|
|
@ -3,21 +3,12 @@ import PropTypes from "prop-types";
|
||||||
import { defaultGist } from "@freesewing/utils";
|
import { defaultGist } from "@freesewing/utils";
|
||||||
import Draft from "../../Draft";
|
import Draft from "../../Draft";
|
||||||
import DraftConfigurator from "../../DraftConfigurator";
|
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 { strings } from "@freesewing/i18n";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
const DraftPattern = props => {
|
const DraftPattern = props => {
|
||||||
let pattern = new props.Pattern(props.gist.settings);
|
let pattern = new props.Pattern(props.gist.settings);
|
||||||
pattern.draft();
|
pattern.draft();
|
||||||
//.use(themePlugin)
|
|
||||||
//.use(svgattrPlugin, { class: "freesewing draft" })
|
|
||||||
//.use(i18nPlugin, { strings: strings })
|
|
||||||
//.use(validatePlugin)
|
|
||||||
//<pre>{pattern.render()}</pre>
|
|
||||||
return (
|
return (
|
||||||
<div className="fs-sa">
|
<div className="fs-sa">
|
||||||
<section>
|
<section>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { storage } from "@freesewing/utils";
|
import { storage } from "@freesewing/utils";
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage, FormattedHTMLMessage } from "react-intl";
|
||||||
import FormFieldMeasurement from "../../.form/FormFieldMeasurement";
|
import FormFieldMeasurement from "../../.form/FormFieldMeasurement";
|
||||||
import models from "@freesewing/models";
|
import models from "@freesewing/models";
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@ const Measurements = props => {
|
||||||
container: {
|
container: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
width: "100%"
|
width: "100%",
|
||||||
|
minHeight: "70vh"
|
||||||
},
|
},
|
||||||
chooser: {
|
chooser: {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
@ -27,6 +28,33 @@ const Measurements = props => {
|
||||||
return props.measurements[m];
|
return props.measurements[m];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (props.required.length < 1)
|
||||||
|
return (
|
||||||
|
<div style={styles.container}>
|
||||||
|
<div style={styles.chooser}>
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage id="app.requiredMeasurements" />
|
||||||
|
</h2>
|
||||||
|
<h3>
|
||||||
|
<FormattedMessage id="cfp.noRequiredMeasurements" />
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
<FormattedHTMLMessage id="cfp.howtoAddMeasurements" />
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FormattedMessage id="cfp.seeDocsAt" />
|
||||||
|
|
||||||
|
<a
|
||||||
|
href={
|
||||||
|
"https://" + props.language + "/.freesewing.dev/core/config"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{props.language}.freesewing.dev/core/config
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<div style={styles.container}>
|
<div style={styles.container}>
|
||||||
<div style={styles.chooser}>
|
<div style={styles.chooser}>
|
||||||
|
|
60
packages/components/src/Workbench/SamplePattern/index.js
Normal file
60
packages/components/src/Workbench/SamplePattern/index.js
Normal file
|
@ -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 (
|
||||||
|
<div className="fs-sa">
|
||||||
|
<section>
|
||||||
|
<h2>
|
||||||
|
<FormattedMessage id="app.pattern" />
|
||||||
|
</h2>
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: pattern.render() }} />
|
||||||
|
<h2>gist</h2>
|
||||||
|
<pre>{JSON.stringify(props.gist, null, 2)}</pre>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
<div className="sticky">
|
||||||
|
<SampleConfigurator
|
||||||
|
config={props.config}
|
||||||
|
gist={props.gist}
|
||||||
|
updateGist={props.updateGist}
|
||||||
|
raiseEvent={props.raiseEvent}
|
||||||
|
freesewing={props.freesewing}
|
||||||
|
units={props.units}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
|
@ -14,12 +14,13 @@ import LanguageIcon from "@material-ui/icons/Translate";
|
||||||
import DarkModeIcon from "@material-ui/icons/Brightness3";
|
import DarkModeIcon from "@material-ui/icons/Brightness3";
|
||||||
import LanguageChooser from "./LanguageChooser";
|
import LanguageChooser from "./LanguageChooser";
|
||||||
import DraftPattern from "./DraftPattern";
|
import DraftPattern from "./DraftPattern";
|
||||||
|
import SamplePattern from "./SamplePattern";
|
||||||
import Welcome from "./Welcome";
|
import Welcome from "./Welcome";
|
||||||
import Footer from "../Footer";
|
import Footer from "../Footer";
|
||||||
import Measurements from "./Measurements";
|
import Measurements from "./Measurements";
|
||||||
|
|
||||||
const Workbench = props => {
|
const Workbench = props => {
|
||||||
const [display, setDisplay] = useState("welcome");
|
const [display, setDisplay] = useState(null);
|
||||||
const [pattern, setPattern] = useState(false);
|
const [pattern, setPattern] = useState(false);
|
||||||
const [theme, setTheme] = useState("light");
|
const [theme, setTheme] = useState("light");
|
||||||
const [measurements, setMeasurements] = useState(null);
|
const [measurements, setMeasurements] = useState(null);
|
||||||
|
@ -27,6 +28,7 @@ const Workbench = props => {
|
||||||
let m = getMeasurements();
|
let m = getMeasurements();
|
||||||
setMeasurements(m);
|
setMeasurements(m);
|
||||||
props.updateGist(m, "settings", "measurements");
|
props.updateGist(m, "settings", "measurements");
|
||||||
|
setDisplay(getDisplay());
|
||||||
}, []);
|
}, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.from) props.importGist(props.from);
|
if (props.from) props.importGist(props.from);
|
||||||
|
@ -36,6 +38,11 @@ const Workbench = props => {
|
||||||
props.updateGist(props.language, "settings", "locale");
|
props.updateGist(props.language, "settings", "locale");
|
||||||
}, [props.language]);
|
}, [props.language]);
|
||||||
|
|
||||||
|
const getDisplay = () => storage.get(props.config.name + "-display");
|
||||||
|
const saveDisplay = d => {
|
||||||
|
setDisplay(d);
|
||||||
|
storage.set(props.config.name + "-display", d);
|
||||||
|
};
|
||||||
const getMeasurements = () =>
|
const getMeasurements = () =>
|
||||||
storage.get(props.config.name + "-measurements");
|
storage.get(props.config.name + "-measurements");
|
||||||
const saveMeasurements = data => {
|
const saveMeasurements = data => {
|
||||||
|
@ -66,7 +73,7 @@ const Workbench = props => {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const showLanguageChooser = () => setDisplay("language");
|
const showLanguageChooser = () => saveDisplay("language");
|
||||||
const updatePattern = p => {
|
const updatePattern = p => {
|
||||||
setPattern(p);
|
setPattern(p);
|
||||||
store.set("pattern", p);
|
store.set("pattern", p);
|
||||||
|
@ -83,19 +90,19 @@ const Workbench = props => {
|
||||||
left: {
|
left: {
|
||||||
draft: {
|
draft: {
|
||||||
type: "button",
|
type: "button",
|
||||||
onClick: () => setDisplay("draft"),
|
onClick: () => saveDisplay("draft"),
|
||||||
text: "cfp.draftYourPattern",
|
text: "cfp.draftYourPattern",
|
||||||
active: display === "draft" ? true : false
|
active: display === "draft" ? true : false
|
||||||
},
|
},
|
||||||
sample: {
|
sample: {
|
||||||
type: "button",
|
type: "button",
|
||||||
onClick: () => setDisplay("sample"),
|
onClick: () => saveDisplay("sample"),
|
||||||
text: "cfp.testYourPattern",
|
text: "cfp.testYourPattern",
|
||||||
active: display === "sample" ? true : false
|
active: display === "sample" ? true : false
|
||||||
},
|
},
|
||||||
measurements: {
|
measurements: {
|
||||||
type: "button",
|
type: "button",
|
||||||
onClick: () => setDisplay("measurements"),
|
onClick: () => saveDisplay("measurements"),
|
||||||
text: "app.measurements",
|
text: "app.measurements",
|
||||||
active: display === "measurements" ? true : false
|
active: display === "measurements" ? true : false
|
||||||
}
|
}
|
||||||
|
@ -108,7 +115,7 @@ const Workbench = props => {
|
||||||
},
|
},
|
||||||
language: {
|
language: {
|
||||||
type: "button",
|
type: "button",
|
||||||
onClick: () => setDisplay("languages"),
|
onClick: () => saveDisplay("languages"),
|
||||||
text: <LanguageIcon className="nav-icon" />,
|
text: <LanguageIcon className="nav-icon" />,
|
||||||
title: "Languages",
|
title: "Languages",
|
||||||
active: display === "languages" ? true : false
|
active: display === "languages" ? true : false
|
||||||
|
@ -128,12 +135,12 @@ const Workbench = props => {
|
||||||
main = (
|
main = (
|
||||||
<LanguageChooser
|
<LanguageChooser
|
||||||
setLanguage={props.setLanguage}
|
setLanguage={props.setLanguage}
|
||||||
setDisplay={setDisplay}
|
setDisplay={saveDisplay}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "draft":
|
case "draft":
|
||||||
if (measurementsMissing()) setDisplay("measurements");
|
if (measurementsMissing()) saveDisplay("measurements");
|
||||||
main = (
|
main = (
|
||||||
<DraftPattern
|
<DraftPattern
|
||||||
freesewing={props.freesewing}
|
freesewing={props.freesewing}
|
||||||
|
@ -147,8 +154,18 @@ const Workbench = props => {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "sample":
|
case "sample":
|
||||||
if (measurementsMissing()) setDisplay("measurements");
|
if (measurementsMissing()) saveDisplay("measurements");
|
||||||
main = <p>Sample: TODO</p>;
|
main = (
|
||||||
|
<SamplePattern
|
||||||
|
freesewing={props.freesewing}
|
||||||
|
Pattern={props.Pattern}
|
||||||
|
config={props.config}
|
||||||
|
gist={props.gist}
|
||||||
|
updateGist={props.updateGist}
|
||||||
|
raiseEvent={raiseEvent}
|
||||||
|
units={props.units}
|
||||||
|
/>
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "measurements":
|
case "measurements":
|
||||||
main = (
|
main = (
|
||||||
|
@ -158,11 +175,12 @@ const Workbench = props => {
|
||||||
units={props.units}
|
units={props.units}
|
||||||
updateMeasurement={updateMeasurement}
|
updateMeasurement={updateMeasurement}
|
||||||
preloadMeasurements={preloadMeasurements}
|
preloadMeasurements={preloadMeasurements}
|
||||||
|
language={props.language}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
main = <Welcome language={props.language} setDisplay={setDisplay} />;
|
main = <Welcome language={props.language} setDisplay={saveDisplay} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const themes = { dark, light };
|
const themes = { dark, light };
|
||||||
|
@ -175,7 +193,7 @@ const Workbench = props => {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{display !== "welcome" ? (
|
{display !== "welcome" ? (
|
||||||
<Navbar navs={navs} home={() => setDisplay("welcome")} />
|
<Navbar navs={navs} home={() => saveDisplay("welcome")} />
|
||||||
) : null}
|
) : null}
|
||||||
{main}
|
{main}
|
||||||
{display !== "welcome" ? <Footer language={props.language} /> : null}
|
{display !== "welcome" ? <Footer language={props.language} /> : null}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
@import "elements/a";
|
@import "elements/a";
|
||||||
@import "elements/footer";
|
@import "elements/footer";
|
||||||
|
@import "elements/ul";
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
ul.nav { padding-left: 0;}
|
||||||
ul.nav.l1 { overflow-x: hidden;}
|
ul.nav.l1 { overflow-x: hidden;}
|
||||||
ul.nav.l1,
|
|
||||||
ul.nav.l2,
|
ul.nav.l2,
|
||||||
ul.nav.l3,
|
ul.nav.l3,
|
||||||
ul.nav.l4 {
|
ul.nav.l4 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@include title-font;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.nav li {list-style-type: none;}
|
ul.nav li {list-style-type: none;}
|
||||||
|
@ -15,21 +14,17 @@ ul.nav h2,
|
||||||
ul.nav h3,
|
ul.nav h3,
|
||||||
ul.nav h4,
|
ul.nav h4,
|
||||||
ul.nav h5 {
|
ul.nav h5 {
|
||||||
font-weight: normal;
|
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.5rem 0.25rem;
|
padding: 0.5rem 0.25rem 0.5rem 1rem;
|
||||||
}
|
}
|
||||||
ul.nav h3:hover,
|
ul.nav h3:hover,
|
||||||
ul.nav h4:hover {
|
ul.nav h4:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: $oc-gray-3;
|
background: $oc-gray-3;
|
||||||
}
|
}
|
||||||
ul.nav h2 { font-size: 1.2rem; margin-left: 5px;}
|
ul.nav h5 { padding-left: 1.5rem; }
|
||||||
ul.nav h4 { font-size: 1rem; }
|
|
||||||
ul.nav h5 { font-size: 1rem; padding-left: 1.5rem; font-weight: bold;}
|
|
||||||
ul.nav h3 {
|
ul.nav h3 {
|
||||||
font-size: 1.1rem;
|
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: $oc-gray-1;
|
background: $oc-gray-1;
|
||||||
|
|
24
packages/css-theme/src/elements/_ul.scss
Normal file
24
packages/css-theme/src/elements/_ul.scss
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
ul.links {
|
||||||
|
padding-left: 1rem;
|
||||||
|
li {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
li:before {
|
||||||
|
content: "\00a0";
|
||||||
|
background: $oc-gray-5;
|
||||||
|
border-radius: 3.5px;
|
||||||
|
display: inline-block;
|
||||||
|
height: 7px;
|
||||||
|
width: 7px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0.5rem 0 0;
|
||||||
|
font-size: 9px;
|
||||||
|
transition: background 0.15s ease-in;
|
||||||
|
}
|
||||||
|
li.nodot:before {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
li:hover:before {
|
||||||
|
background: $fc-link-light;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,3 +18,7 @@ youCan: Sie können
|
||||||
enterMeasurements: Geben Sie die Maße von Hand ein
|
enterMeasurements: Geben Sie die Maße von Hand ein
|
||||||
preloadMeasurements: Laden Sie eine Reihe von Messungen vor
|
preloadMeasurements: Laden Sie eine Reihe von Messungen vor
|
||||||
size: Größe
|
size: Größe
|
||||||
|
noRequiredMeasurements: Dieses Muster hat keine erforderlichen Messungen.
|
||||||
|
howtoAddMeasurements: Um Messungen anzufordern, fügen Sie sie dem <b>measurements</b> der Konfigurationsdatei des Musters hinzu.
|
||||||
|
seeDocsAt: Dokumentation zu diesem Thema finden Sie unter
|
||||||
|
|
||||||
|
|
|
@ -17,3 +17,6 @@ youCan: You can
|
||||||
enterMeasurements: Enter measurements by hand
|
enterMeasurements: Enter measurements by hand
|
||||||
preloadMeasurements: Preload a set of measurements
|
preloadMeasurements: Preload a set of measurements
|
||||||
size: Size
|
size: Size
|
||||||
|
noRequiredMeasurements: This pattern has no required measurements
|
||||||
|
howtoAddMeasurements: To require measurements, add them to the <b>measurements</b> section of the pattern's configuration file.
|
||||||
|
seeDocsAt: Documentation on this topic is available at
|
||||||
|
|
|
@ -18,3 +18,6 @@ youCan: Usted puede
|
||||||
enterMeasurements: Introducir medidas a mano
|
enterMeasurements: Introducir medidas a mano
|
||||||
preloadMeasurements: Precargar un conjunto de medidas
|
preloadMeasurements: Precargar un conjunto de medidas
|
||||||
size: Tamaño
|
size: Tamaño
|
||||||
|
noRequiredMeasurements: Este patrón no tiene medidas requeridas.
|
||||||
|
howtoAddMeasurements: Para requerir mediciones, agréguelas a la sección de <b>measurements</b> del archivo de configuración del patrón.
|
||||||
|
seeDocsAt: La documentación sobre este tema está disponible en
|
||||||
|
|
|
@ -18,3 +18,6 @@ youCan: Vous pouvez
|
||||||
enterMeasurements: Entrer les mesures à la main
|
enterMeasurements: Entrer les mesures à la main
|
||||||
preloadMeasurements: Précharger un ensemble de mesures
|
preloadMeasurements: Précharger un ensemble de mesures
|
||||||
size: Taille
|
size: Taille
|
||||||
|
noRequiredMeasurements: Ce patron n'a pas de mesures requises.
|
||||||
|
howtoAddMeasurements: Pour exiger des mesures, ajoutez-les à la section <b>measurements</b> du fichier de configuration du patron.
|
||||||
|
seeDocsAt: Documentation sur ce sujet est disponible à l'adresse
|
||||||
|
|
|
@ -15,6 +15,9 @@ testYourPattern: Test je patroon
|
||||||
renderInBrowser: Klik hieronder om uw patroon te renderen in de browser.
|
renderInBrowser: Klik hieronder om uw patroon te renderen in de browser.
|
||||||
weWillReRender: Telkens u wijzigingen aanbrengt renderen we opnieuw.
|
weWillReRender: Telkens u wijzigingen aanbrengt renderen we opnieuw.
|
||||||
youCan: Je kan
|
youCan: Je kan
|
||||||
enterMeasurements: Handmatig afmetingen invoeren
|
enterMeasurements: Handmatig lichaamsmaten invoeren
|
||||||
preloadMeasurements: Een reeks afmetingen laden
|
preloadMeasurements: Een reeks lichaamsmaten laden
|
||||||
size: Maat
|
size: Maat
|
||||||
|
noRequiredMeasurements: Dit patroon vereist geen lichaamsmaten.
|
||||||
|
howtoAddMeasurements: Om lichaamsmaten te vereisen, voegt u ze toe aan de <b>measurements</b> sectie van het configuratiebestand van het patroon.
|
||||||
|
seeDocsAt: Documentatie over dit onderwerp is beschikbaar op
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue