1
0
Fork 0

🚧 Progress on workbench

This commit is contained in:
Joost De Cock 2019-05-05 17:06:22 +02:00
parent 1a8fe110f8
commit 158c19ae1d
101 changed files with 1222 additions and 200 deletions

View file

@ -31,7 +31,6 @@ plugin-flip: "A FreeSewing plugin to flip parts horizontally"
plugin-grainline: "A FreeSewing plugin to add grainline indicators on your patterns"
plugin-i18n: "A FreeSewing plugin for pattern translation"
plugin-logo: "A FreeSewing plugin to add our logo to your patterns"
plugin-react: "A FreeSewing plugin to turn your pattern into a React component"
plugin-round: "A FreeSewing plugin to round corners"
plugin-scalebox: "A FreeSewing plugin to add a scalebox to your pattern"
plugin-sprinkle: "A FreeSewing plugin to bulk-add snippets to your pattern"

View file

@ -33,9 +33,9 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/brian": "^2.0.0-alpha.18",
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19",
"@freesewing/brian": "^2.0.0-alpha.19"
},
"files": [
"dist/*",

View file

@ -33,9 +33,9 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/brian": "^2.0.0-alpha.18",
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19",
"@freesewing/brian": "^2.0.0-alpha.19"
},
"files": [
"dist/*",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,12 +33,12 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/bent": "^2.0.0-alpha.18",
"@freesewing/carlton": "^2.0.0-alpha.18",
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18",
"@freesewing/plugin-bust": "^2.0.0-alpha.18",
"@freesewing/plugin-buttons": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19",
"@freesewing/bent": "^2.0.0-alpha.19",
"@freesewing/carlton": "^2.0.0-alpha.19",
"@freesewing/plugin-bust": "^2.0.0-alpha.19",
"@freesewing/plugin-buttons": "^2.0.0-alpha.19"
},
"files": [
"dist/*",

View file

@ -33,10 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/bent": "^2.0.0-alpha.18",
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18",
"@freesewing/plugin-buttons": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19",
"@freesewing/bent": "^2.0.0-alpha.19",
"@freesewing/plugin-buttons": "^2.0.0-alpha.19"
},
"files": [
"dist/*",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -26,19 +26,19 @@
"watch": "BABEL_ENV=production rollup -c -w -o dist/index.js -f cjs"
},
"peerDependencies": {
"@freesewing/css-theme": "^2.0.0-alpha.18",
"@freesewing/i18n": "^2.0.0-alpha.18",
"@freesewing/mui-theme": "^2.0.0-alpha.18",
"@freesewing/pattern-info": "^2.0.0-alpha.18",
"@freesewing/plugin-react": "^2.0.0-alpha.18",
"@freesewing/utils": "^2.0.0-alpha.18",
"react": "^16.8",
"prop-types": "15.7.2",
"@freesewing/pattern-info": "^2.0.0-alpha.19",
"@freesewing/mui-theme": "^2.0.0-alpha.19",
"@freesewing/css-theme": "^2.0.0-alpha.19",
"@freesewing/plugin-react": "^2.0.0-alpha.19",
"typeface-roboto-condensed": "latest",
"@freesewing/i18n": "^2.0.0-alpha.19",
"@freesewing/utils": "^2.0.0-alpha.19",
"react-intl": "^2.8.0",
"@material-ui/core": "^3.9.3",
"@material-ui/icons": "^3.0.2",
"@material-ui/lab": "^3.0.0-alpha.30",
"prop-types": "15.7.2",
"react": "^16.8",
"react-intl": "^2.8.0",
"typeface-roboto-condensed": "latest"
"@material-ui/lab": "^3.0.0-alpha.30"
},
"files": [
"dist/*",

View file

@ -0,0 +1,59 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import TextField from "@material-ui/core/TextField";
import IconButton from "@material-ui/core/IconButton";
import InvalidIcon from "@material-ui/icons/Warning";
import InputAdornment from "@material-ui/core/InputAdornment";
import { withStyles } from "@material-ui/core/styles";
import { measurementAsMm, formatMm } from "@freesewing/utils";
import { injectIntl } from "react-intl";
const FormFieldMeasurement = props => {
const update = evt => {
props.updateValue(
props.name,
measurementAsMm(evt.target.value, props.units)
);
};
const distance = {
asMm: () => false
};
return (
<TextField
id={props.name}
fullWidth={true}
label={props.intl.formatMessage({ id: props.label })}
margin="normal"
variant="outlined"
value={formatMm(props.value, props.units, "text")}
type="text"
onChange={update}
InputProps={{
endAdornment: (
<InputAdornment position="end">
{measurementAsMm(props.value, props.units) === false ? (
<InvalidIcon color="error" />
) : (
<IconButton classes={{ label: "color-success" }} size="small">
{props.units === "imperial" ? '"' : "cm"}
</IconButton>
)}
</InputAdornment>
)
}}
/>
);
};
FormFieldMeasurement.propTypes = {
updateValue: PropTypes.func.isRequired,
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
units: PropTypes.oneOf(["metric", "imperial"])
};
FormFieldMeasurement.defaultProps = {};
export default injectIntl(FormFieldMeasurement);

View file

@ -0,0 +1,19 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import FormFieldSlider from ".";
const props = {
updateValue: (name, value) =>
console.log(`Updated option ${name}, value is now: ${value}`),
name: "exampleSliderOption"
};
storiesOf("Low level/Form/FormFieldSlider", module)
.add("Basic", () => <FormFieldSlider {...props} />)
.add("From 1 to 10", () => <FormFieldSlider {...props} min={1} max={10} />)
.add("Step: 1", () => (
<FormFieldSlider {...props} min={1} max={10} step={1} />
))
.add("Defalt: 7", () => (
<FormFieldSlider {...props} min={1} max={10} dflt={7} />
));

View file

@ -0,0 +1,20 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
const Circle = props => {
return null;
let foo = (
<circle
cx={props.point.x}
cy={props.point.y}
r={props.point.attributes.get("data-circle")}
{...props.point.attributes.asPropsIfPrefixIs("data-circle-")}
/>
);
};
Circle.propTypes = {
point: PropTypes.object.isRequired
};
export default Circle;

View file

@ -0,0 +1,9 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
const Defs = props => <defs>{props.defs}</defs>;
Defs.propTypes = { defs: PropTypes.string };
Defs.defaultProps = { defs: "" };
export default Defs;

View file

@ -0,0 +1,31 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import Path from "../Path";
import Point from "../Point";
import { getProps } from "../utils";
const Part = props => {
return (
<g {...getProps(props.part)}>
{Object.keys(props.part.points).map(name => (
<Point
key={name}
name={name}
language={props.language}
point={props.part.points[name]}
/>
))}
{Object.keys(props.part.paths).map(name => (
<Path key={name} name={name} path={props.part.paths[name]} />
))}
</g>
);
};
Part.propTypes = {
part: PropTypes.object.isRequired,
name: PropTypes.string.isRequired,
language: PropTypes.string.isRequired
};
export default Part;

View file

@ -0,0 +1,14 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import { getProps } from "../utils";
const Path = props => {
if (!props.path.render) return null;
return <path d={props.path.asPathstring()} {...getProps(props.path)} />;
};
Path.propTypes = {
path: PropTypes.object.isRequired
};
export default Path;

View file

@ -0,0 +1,22 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import Text from "../Text";
import Circle from "../Circle";
const Point = props => {
const output = [];
if (props.point.attributes.get("data-text"))
output.push(<Text {...props} key={"point-" + props.name} />);
if (props.point.attributes.get("data-circle"))
output.push(<Circle point={props.point} key={"circle-" + props.name} />);
if (output.length < 1) return null;
else return output;
};
Point.propTypes = {
point: PropTypes.object.isRequired,
name: PropTypes.string.isRequired,
language: PropTypes.string.isRequired
};
export default Point;

View file

@ -0,0 +1,9 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
const Style = props => <style>{props.css}</style>;
Style.propTypes = { css: PropTypes.string };
Style.defaultProps = { css: "" };
export default Style;

View file

@ -0,0 +1,37 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
const Svg = props => {
let attributes = {
xmlns: "http://www.w3.org/2000/svg",
"xmlns:svg": "http://www.w3.org/2000/svg",
xmlnsXlink: "http://www.w3.org/1999/xlink",
xmlLang: props.language,
viewBox: `0 0 ${props.width} ${props.height}`,
className: props.className
};
if (!props.embed) {
attributes.width = props.width;
attributes.height = props.height;
}
return <svg {...attributes}>{props.children}</svg>;
};
Svg.propTypes = {
attributes: PropTypes.object,
embed: PropTypes.bool,
languages: PropTypes.string,
className: PropTypes.string,
design: PropTypes.bool
};
Svg.defaultProps = {
embed: true,
design: false,
language: "en",
className: "freesewing draft"
};
export default Svg;

View file

@ -0,0 +1,49 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import { strings } from "@freesewing/i18n";
const Text = props => {
let text = [];
// Handle translation
let translated = "";
for (let string of props.point.attributes.getAsArray("data-text")) {
if (strings[props.language]["plugin." + string])
translated += strings[props.language]["plugin." + string];
else translated += string;
translated += " ";
}
// Handle muti-line text
if (translated.indexOf("\n") !== -1) {
let key = 0;
let lines = translated.split("\n");
text.push(<tspan key={"tspan-" + key}>{lines.shift()}</tspan>);
for (let line of lines) {
key++;
text.push(
<tspan
key={"tspan-" + key}
x={props.point.x}
dy={props.point.attributes.get("data-text-lineheight") || 12}
>
{line}
</tspan>
);
}
} else text.push(<tspan key="tspan-1">{translated}</tspan>);
return null;
return (
<text
x={props.point.x}
y={props.point.y}
{...props.point.attributes.asPropsIfPrefixIs("data-text-")}
>
{text}
</text>
);
};
Text.propTypes = {
point: PropTypes.object.isRequired
};
export default Text;

View file

@ -0,0 +1,93 @@
svg.freesewing {
/* Reset */
path,circle,rect{fill:none;stroke:none}
/* Defaults */
path,circle{
stroke:#000;
stroke-opacity:1;
stroke-width:.3;
stroke-linecap:round;
stroke-linejoin:round;
}
/* Stroke classes */
.fabric{
stroke-width:.6;
stroke:#212121
}
.lining{
stroke-width:.6;
stroke:#ff5b77;
}
.interfacing{
stroke-width:.6;
stroke:#64b5f6;
}
.canvas{
stroke-width:.6;
stroke:#ff9000;
}
.various{
stroke-width:.6;
stroke:#4caf50;
}
.note{
stroke-width:.4;
stroke:#dd60dd;
}
.mark{
stroke-width:.4;
stroke:blue;
}
.contrast{
stroke-width:.8;
stroke:red;
}
.stroke-xs{ stroke-width:.1; }
.stroke-sm{ stroke-width:.2; }
.stroke-lg{ stroke-width:.6; }
.stroke-xl{ stroke-width:1; }
.stroke-xxl{ stroke-width:2; }
.sa { stroke-dasharray:0.4,0.8; }
.help {
stroke-width:.2;
stroke-dasharray:15,1.5,1,1.5;
}
.dotted { stroke-dasharray:0.4,0.8; }
.dashed { stroke-dasharray:1,1.5; }
.lashed { stroke-dasharray:6,6; }
.hidden {
stroke:none;
fill:none;
}
/* Fill classes */
.fill-fabric{ fill:#212121; }
.fill-lining{ fill:#ff5b77; }
.fill-interfacing{ fill:#64b5f6; }
.fill-canvas{ fill:#ff9000; }
.fill-various{ fill:#4caf50; }
.fill-note{ fill:#dd69dd; }
.fill-mark{ fill:blue; }
.fill-contrast{ fill:red; }
/* Text */
text{
font-size:5px;
font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
fill:#000;
text-anchor:start;
font-weight:200;
dominant-baseline:ideographic;
}
.text-xs { font-size:3px; }
.text-sm { font-size:4px; }
.text-lg { font-size:7px; }
.text-xl { font-size:9px; }
.text-xxl{ font-size:12px; }
.center{ text-anchor:middle; }
.right{ text-anchor:end; }
}

View file

@ -0,0 +1,41 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import Svg from "./Svg";
//import Style from "./Style";
//import Defs from "./Defs";
import Part from "./Part";
const Draft = props => {
return (
<Svg
embed={props.settings.embed}
width={props.width}
height={props.height}
language={props.settings.locale}
id={props.settings.idPrefix + "svg"}
>
<g>
{Object.keys(props.parts).map(name => (
<Part
part={props.parts[name]}
language={props.settings.locale}
key={name}
name={name}
/>
))}
</g>
</Svg>
);
};
Draft.propTypes = {
parts: PropTypes.object.isRequired,
settings: PropTypes.object.isRequired,
design: PropTypes.bool
};
Draft.defaultProps = {
design: false
};
export default Draft;

View file

@ -0,0 +1,16 @@
export const getProps = obj => {
let rename = {
class: "className",
"marker-start": "markerStart",
"marker-end": "markerEnd"
};
let props = {};
for (let key in obj.attributes.list) {
if (key === "style") console.log("style in", key, obj.attributes.get(key));
if (Object.keys(rename).indexOf(key) !== -1)
props[rename[key]] = obj.attributes.get(key);
else if (key !== "style") props[key] = obj.attributes.get(key);
}
return props;
};

View file

@ -61,8 +61,10 @@ const DraftSettings = props => {
childProps.dflt = "dflt";
childProps.customDflt = [];
childProps.parts = {};
for (let part of props.config.parts) // HERE
childProps.parts[part] = <FormattedMessage id={"parts." + part} />;
if (props.config.parts) {
for (let part of props.config.parts) // HERE
childProps.parts[part] = <FormattedMessage id={"parts." + part} />;
}
}
return childProps;

View file

@ -16,11 +16,15 @@ const PatternOptionPctDegCount = props => {
// causes a weird timing issue to result in a value that is NaN.
// If that's the case, just ignore this update and keep the
// previous one instead
let factor = 1;
if (props.type === "pct") factor = 100;
if (!isNaN(newValue)) {
setValue(newValue);
if (evt.type !== "mousemove") props.updateValue(props.name, newValue);
if (evt.type !== "mousemove")
props.updateValue(props.name, newValue / factor);
} else {
if (evt.type !== "mousemove") props.updateValue(props.name, value);
if (evt.type !== "mousemove")
props.updateValue(props.name, value / factor);
}
};

View file

@ -0,0 +1,80 @@
import React from "react";
import PropTypes from "prop-types";
import Logo from "../Logo";
import { FormattedMessage, FormattedHTMLMessage } from "react-intl";
import Button from "@material-ui/core/Button";
import IconButton from "@material-ui/core/IconButton";
import Icon from "../Icon";
const Footer = props => {
const icons = {
gitter: "https://gitter.im/freesewing/freesewing",
twitter: "https://twitter.com/freesewing_org",
github: "https://github.com/freesewing",
instagram: "https://instagram.com/freesewing_org",
facebook: "https://facebook.com/freesewing.org/"
};
const links = {
docs: {
aboutFreesewing:
"https://" + props.language + ".freesewing.org/docs/about",
faq: "https://" + props.language + ".freesewing.org/docs/faq",
makerDocs: "https://" + props.language + ".freesewing.org/docs/",
devDocs: "https://" + props.language + ".freesewing.dev/"
},
community: {
becomeAPatron:
"https://" + props.language + ".freesewing.org/patrons/join",
showcase: "https://" + props.language + ".freesewing.org/showcase",
makerBlog: "https://" + props.language + ".freesewing.org/blog",
devBlog: "https://" + props.language + ".freesewing.dev/blog"
}
};
const styles = {
container: {
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "space-evenly"
}
};
return (
<footer>
<Logo size={101} />
<p>
{Object.keys(icons).map(i => (
<IconButton href={icons[i]} className={i} title={i} key={i}>
<Icon icon={i} />
</IconButton>
))}
</p>
<p>
<FormattedHTMLMessage id="app.txt-footer" />
</p>
<div style={styles.container}>
{Object.keys(links).map(l => {
let items = [];
for (let i of Object.keys(links[l])) {
items.push(
<li key={i}>
<a href={links[l][i]}>
<FormattedMessage id={"app." + i} />
</a>
</li>
);
}
return (
<div>
<h4>
<FormattedMessage id={"app." + l} />
</h4>
<ul>{items}</ul>
</div>
);
})}
</div>
</footer>
);
};
export default Footer;

View file

@ -1,3 +1,4 @@
// These are from simpleicons.org - thanks guys!
const gitter =
"M8.501 4.001H10.5V24H8.501V4.001zm6.999 0V24h-2V4.001h2zM3.5 0h2.001v15H3.5V0zm15 4.001h2V15h-2V4.001z";
@ -13,10 +14,14 @@ const instagram =
const google =
"M 12.25009,0 C 7.5567085,0 3.5033589,2.69334 1.530043,6.613315 0.71674427,8.240005 0.25,10.06676 0.25,12.00009 c 0,1.93333 0.46674427,3.759905 1.280043,5.386595 C 3.5033589,21.30666 7.5567085,24 12.25009,24 c 3.239959,0 5.959944,-1.066635 7.94668,-2.906575 2.266629,-2.093365 3.573349,-5.173415 3.573349,-8.826735 0,-0.98666 -0.08023,-1.70661 -0.253496,-2.453265 l -11.266533,0 0,4.45322 6.613137,0 c -0.133283,1.106705 -0.853233,2.77333 -2.453266,3.89327 -1.013315,0.706675 -2.373243,1.199975 -4.159871,1.199975 -3.173318,0 -5.8666835,-2.09327 -6.826777,-4.986605 -0.2533286,-0.746655 -0.399991,-1.54657 -0.399991,-2.373195 0,-0.82672 0.1467055,-1.62672 0.386706,-2.373375 C 6.3834495,6.73338 9.076772,4.63993 12.25009,4.63993 c 2.253301,0 3.773228,0.973465 4.639932,1.786855 L 20.27666,3.12004 C 18.196718,1.186705 15.490049,0 12.25009,0 Z";
const facebook =
"M22.676 0H1.324C.593 0 0 .593 0 1.324v21.352C0 23.408.593 24 1.324 24h11.494v-9.294H9.689v-3.621h3.129V8.41c0-3.099 1.894-4.785 4.659-4.785 1.325 0 2.464.097 2.796.141v3.24h-1.921c-1.5 0-1.792.721-1.792 1.771v2.311h3.584l-.465 3.63H16.56V24h6.115c.733 0 1.325-.592 1.325-1.324V1.324C24 .593 23.408 0 22.676 0";
export default {
gitter,
github,
twitter,
instagram,
google
google,
facebook
};

View file

@ -16,12 +16,22 @@ const Navbar = props => {
if (nav.type === "component") return nav.component;
else if (nav.type === "button")
return (
<button title={title} onClick={nav.onClick} key={key}>
<button
title={title}
onClick={nav.onClick}
key={key}
className={nav.active ? "active" : ""}
>
{text}
</button>
);
return (
<a href={nav.href} className="nav" title={title} key={key}>
<a
href={nav.href}
className={nav.active ? "nav active" : "nav"}
title={title}
key={key}
>
{text}
</a>
);
@ -60,7 +70,7 @@ Navbar.propTypes = {
navs: PropTypes.object,
logo: PropTypes.node,
emblem: PropTypes.node,
home: PropTypes.string
home: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
};
Navbar.defaultProps = {

View file

@ -1,31 +1,30 @@
import React from "react";
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 reactPlugin from "@freesewing/plugin-react";
//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)
.use(themePlugin)
.use(svgattrPlugin, { class: "freesewing draft" })
.use(i18nPlugin, { strings: strings })
.use(validatePlugin)
.use(reactPlugin);
let pattern = new props.Pattern(props.gist.settings);
pattern.draft();
//.use(themePlugin)
//.use(svgattrPlugin, { class: "freesewing draft" })
//.use(i18nPlugin, { strings: strings })
//.use(validatePlugin)
//<pre>{pattern.render()}</pre>
return (
<div className="fs-sa">
<section>
<h2>
<FormattedMessage id="app.pattern" />
</h2>
<div dangerouslySetInnerHTML={{ __html: pattern.render() }} />
<Draft {...pattern.getRenderProps()} />
<h2>gist</h2>
<pre>{JSON.stringify(props.gist, null, 2)}</pre>
</section>

View file

@ -7,7 +7,6 @@ const LanguageChooser = props => {
container: {
display: "flex",
flexDirection: "row",
height: "calc(100vh - 64px)",
width: "100%"
},
chooser: {

View file

@ -0,0 +1,98 @@
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 FormFieldMeasurement from "../../.form/FormFieldMeasurement";
import models from "@freesewing/models";
const Measurements = props => {
const styles = {
container: {
display: "flex",
flexDirection: "row",
width: "100%"
},
chooser: {
width: "100%",
maxWidth: "500px",
margin: "auto",
alignSelf: "center"
}
};
const getValue = m => {
if (props.measurements === null) return "";
if (typeof props.measurements[m] === "undefined") return "";
return props.measurements[m];
};
return (
<div style={styles.container}>
<div style={styles.chooser}>
<h2>
<FormattedMessage id="app.requiredMeasurements" />
</h2>
<p>
<FormattedMessage id="cfp.youCan" />
</p>
<ul>
<li>
<a href="#manual">
<FormattedMessage id="cfp.enterMeasurements" />
</a>
</li>
<li>
<a href="#preload">
<FormattedMessage id="cfp.preloadMeasurements" />
</a>
</li>
</ul>
<h3 id="manual">
<FormattedMessage id="cfp.enterMeasurements" />
</h3>
{props.required.map(m => (
<FormFieldMeasurement
key={m}
name={m}
units={props.units}
value={getValue(m)}
label={"measurements." + m}
updateValue={props.updateMeasurement}
/>
))}
<h3 id="preload">
<FormattedMessage id="cfp.preloadMeasurements" />
</h3>
<h4>
<FormattedMessage id="app.withoutBreasts" />
</h4>
<ul>
{Object.keys(models).map(m => (
<li key={m}>
<Button onClick={() => props.preloadMeasurements(models[m])}>
<FormattedMessage id="cfp.size" />
&nbsp;
{m.slice(-2)}
</Button>
</li>
))}
</ul>
<h4>
<FormattedMessage id="app.withBreasts" />
</h4>
<p>FIXME</p>
</div>
</div>
);
};
Measurements.propTypes = {
measuremnents: PropTypes.object.isRequired,
required: PropTypes.array.isRequired,
units: PropTypes.oneOf(["metric", "imperial"]),
updateMeasurement: PropTypes.func.isRequired,
preloadMeasurements: PropTypes.func.isRequired
};
export default Measurements;

View file

@ -34,66 +34,43 @@ const Welcome = props => {
};
return (
<div className="fs-sa">
<section style={styles.container}>
<div>
<Logo size={250} />
</div>
<h1 style={styles.title}>
<FormattedMessage id="app.welcome" />
</h1>
<p>
<FormattedMessage id="cfp.renderInBrowser" />
<br />
<FormattedMessage id="cfp.weWillReRender" />
</p>
<Button
style={styles.bigButton}
variant="contained"
size="large"
color="primary"
onClick={() => props.setDisplay("draft")}
>
<FormattedMessage id="cfp.renderYourPattern" />
</Button>
<footer style={styles.footer}>
<React.Fragment>
<div />
<div className="fs-sa">
<section style={styles.container}>
<div>
<Logo size={250} />
</div>
<h1 style={styles.title}>
<FormattedMessage id="app.welcome" />
</h1>
<p>
<FormattedMessage id="cfp.renderInBrowser" />
<br />
<FormattedMessage id="cfp.weWillReRender" />
</p>
<Button
style={styles.button}
href={
"https://" +
props.language +
".freesewing.dev/pkg/create-freesewing-pattern"
}
style={styles.bigButton}
variant="contained"
size="large"
color="primary"
onClick={() => props.setDisplay("pattern")}
onClick={() => props.setDisplay("draft")}
>
<FormattedMessage id="app.docs" />
<FormattedMessage id="cfp.draftYourPattern" />
</Button>
<Button
style={styles.button}
href="https://gitter.im/freesewing/freesewing"
style={styles.bigButton}
variant="contained"
size="large"
color="primary"
onClick={() => props.setDisplay("pattern")}
onClick={() => props.setDisplay("sample")}
>
<FormattedMessage id="app.askForHelp" />
<FormattedMessage id="cfp.testYourPattern" />
</Button>
<p>
<IconButton href="https://twitter.com/freesewing_org">
<Icon icon="twitter" color="#00aced" />
</IconButton>
<IconButton href="https://twitter.com/freesewing_org">
<Icon icon="github" color="#666" />
</IconButton>
<IconButton href="https://twitter.com/freesewing_org">
<Icon icon="instagram" color="#e1306c" />
</IconButton>
</p>
<p>
<FormattedHTMLMessage id="app.txt-footer" />
</p>
</footer>
</section>
</div>
</section>
</div>
<div />
</React.Fragment>
);
};

View file

@ -15,18 +15,57 @@ import DarkModeIcon from "@material-ui/icons/Brightness3";
import LanguageChooser from "./LanguageChooser";
import DraftPattern from "./DraftPattern";
import Welcome from "./Welcome";
import Footer from "../Footer";
import Measurements from "./Measurements";
const Workbench = props => {
const [display, setDisplay] = useState("welcome");
const [pattern, setPattern] = useState(false);
const [settings, setSettings] = useState(false);
const [theme, setTheme] = useState("light");
const [measurements, setMeasurements] = useState(null);
useEffect(() => {
let m = getMeasurements();
setMeasurements(m);
props.updateGist(m, "settings", "measurements");
}, []);
useEffect(() => {
if (props.from) props.importGist(props.from);
}, [props.from]);
useEffect(() => {
if (props.language !== props.gist.settings.locale)
props.updateGist(props.language, "settings", "locale");
}, [props.language]);
const getMeasurements = () =>
storage.get(props.config.name + "-measurements");
const saveMeasurements = data => {
storage.set(props.config.name + "-measurements", data);
props.updateGist(data, "settings", "measurements");
};
const updateMeasurement = (name, val) => {
let updatedMeasurements = { ...measurements };
updatedMeasurements[name] = val;
setMeasurements(updatedMeasurements);
saveMeasurements(updatedMeasurements);
};
const preloadMeasurements = model => {
let updatedMeasurements = {
...measurements,
...model
};
setMeasurements(updatedMeasurements);
saveMeasurements(updatedMeasurements);
};
const measurementsMissing = () => {
let required = props.config.measurements;
if (measurements === null) return true;
for (let m of required) {
if (typeof measurements[m] === "undefined") return true;
}
return false;
};
const showLanguageChooser = () => setDisplay("language");
const toggleSettings = () => setSettings(!settings);
const updatePattern = p => {
setPattern(p);
store.set("pattern", p);
@ -41,28 +80,37 @@ const Workbench = props => {
const navs = {
left: {
docs: {
type: "link",
href: "https://freesewing.dev/",
text: "app.docs"
draft: {
type: "button",
onClick: () => setDisplay("draft"),
text: "cfp.draftYourPattern",
active: display === "draft" ? true : false
},
help: {
type: "link",
href: "https://gitter.im/freesewing/freesewing/",
text: "app.askForHelp"
sample: {
type: "button",
onClick: () => setDisplay("sample"),
text: "cfp.testYourPattern",
active: display === "sample" ? true : false
},
measurements: {
type: "button",
onClick: () => setDisplay("measurements"),
text: "app.measurements",
active: display === "measurements" ? true : false
}
},
right: {
version: {
type: "link",
href: "https://github.com/freesewing/freesewing",
href: "https://github.com/freesewing/freesewing/releases",
text: "v" + props.freesewing.version
},
language: {
type: "button",
onClick: () => setDisplay("languages"),
text: <LanguageIcon className="nav-icon" />,
title: "Languages"
title: "Languages",
active: display === "languages" ? true : false
},
dark: {
type: "button",
@ -84,6 +132,7 @@ const Workbench = props => {
);
break;
case "draft":
if (measurementsMissing()) setDisplay("measurements");
main = (
<DraftPattern
freesewing={props.freesewing}
@ -96,6 +145,21 @@ const Workbench = props => {
/>
);
break;
case "sample":
if (measurementsMissing()) setDisplay("measurements");
main = <p>Sample: TODO</p>;
break;
case "measurements":
main = (
<Measurements
measurements={measurements}
required={props.config.measurements}
units={props.units}
updateMeasurement={updateMeasurement}
preloadMeasurements={preloadMeasurements}
/>
);
break;
default:
main = <Welcome language={props.language} setDisplay={setDisplay} />;
}
@ -113,6 +177,7 @@ const Workbench = props => {
<Navbar navs={navs} home={() => setDisplay("welcome")} />
) : null}
{main}
{display !== "welcome" ? <Footer language={props.language} /> : null}
</div>
</MuiThemeProvider>
);

View file

@ -1,3 +1,4 @@
export { default as Draft } from "./Draft";
export { default as DraftConfigurator } from "./DraftConfigurator";
export { default as Emblem } from "./Emblem";
export { default as Logo } from "./Logo";

View file

View file

@ -1,6 +1,6 @@
{
"name": "@freesewing/core",
"version": "2.0.0-alpha.18",
"version": "2.0.0-alpha.19",
"description": "A library for creating made-to-measure sewing patterns",
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",
@ -33,7 +33,8 @@
"pubforce": "npm publish",
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
"report": "BABEL_ENV=production nyc report --reporter=html mocha --compilers js:babel-core/register tests/*.test.js",
"coverage": "BABEL_ENV=production nyc npm test && nyc report --reporter=text-lcov > coverage.lcov && ./node_modules/.bin/codecov"
"coverage": "BABEL_ENV=production nyc npm test && nyc report --reporter=text-lcov > coverage.lcov && ./node_modules/.bin/codecov",
"watch": "BABEL_ENV=production rollup -c -w -o dist/index.mjs -f es"
},
"dependencies": {
"bezier-js": "^2.2.13",

View file

@ -72,6 +72,22 @@ Attributes.prototype.renderIfPrefixIs = function(prefix = "") {
return svg;
};
/** Returns a props object for attributes with a fiven prefix
* typically used for data-text*/
Attributes.prototype.asPropsIfPrefixIs = function(prefix = "") {
let props = {};
let prefixLen = prefix.length;
for (let key in this.list) {
if (key.substr(0, prefixLen) === prefix) {
let propKey = key.substr(prefixLen);
if (propKey === "class") propKey = "className";
props[propKey] = this.get(key);
}
}
return props;
};
/** Returns a deep copy of this */
Attributes.prototype.clone = function() {
let clone = new Attributes();

View file

@ -142,6 +142,8 @@ Pattern.prototype.draft = function() {
"() was undefined. Did you forget to return the Part object?"
);
this.parts[partName].render = this.wants(partName);
} else {
this.parts[partName].render = false;
}
}
this.runHooks("postDraft");
@ -390,7 +392,7 @@ Pattern.prototype.pack = function() {
let part = this.parts[key];
// Avoid multiple render calls to cause stacking of transforms
part.attributes.remove("transform");
if (part.render && this.needs(key)) {
if (part.render) {
part.stack();
let width = part.bottomRight.x - part.topLeft.x;
let height = part.bottomRight.y - part.topLeft.y;
@ -577,3 +579,31 @@ Pattern.prototype.wants = function(partName) {
return true;
};
/** Returns props required to render this pattern through
* an external renderer (eg. a React component)
*/
Pattern.prototype.getRenderProps = function() {
this.pack();
let props = {};
props.width = this.width;
props.height = this.height;
props.settings = this.settings;
props.parts = {};
for (let p of Object.keys(this.parts)) {
if (this.parts[p].render) {
props.parts[p] = {
paths: this.parts[p].paths,
points: this.parts[p].points,
snippets: this.parts[p].points,
attributes: this.parts[p].attributes,
height: this.parts[p].height,
width: this.parts[p].width,
bottomRight: this.parts[p].bottomRight,
topLeft: this.parts[p].topLeft
};
}
}
return props;
};

View file

@ -62,7 +62,7 @@ Svg.prototype.render = function(pattern) {
this.layout = {}; // Reset layout
for (let partId in pattern.parts) {
let part = pattern.parts[partId];
if (part.render && pattern.needs(partId)) {
if (part.render) {
let partSvg = this.renderPart(part);
this.layout[partId] = {
svg: partSvg,

View file

@ -23,8 +23,6 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"dependencies": {
"@freesewing/i18n": "^2.0.0-alpha.19",
"@freesewing/pattern-info": "^2.0.0-alpha.19",
"chalk": "^2.4.2",
"commander": "^2.19.0",
"conf": "^2.2.0",
@ -40,7 +38,9 @@
"p-each-series": "^1.0.0",
"parse-git-config": "^3.0.0",
"validate-npm-package-name": "^3.0.0",
"which": "^1.3.1"
"which": "^1.3.1",
"@freesewing/i18n": "^2.0.0-alpha.19",
"@freesewing/pattern-info": "^2.0.0-alpha.19"
},
"files": [
"lib",

View file

@ -16,6 +16,8 @@
"@freesewing/plugin-validate": "alpha",
"@freesewing/plugin-react": "alpha",
"@freesewing/i18n": "alpha",
"@freesewing/utils": "alpha",
"@freesewing/models": "alpha",
"@freesewing/components": "alpha",
"@freesewing/css-theme": "alpha",
"@freesewing/mui-theme": "alpha",

View file

@ -1,6 +1,6 @@
{
"name": "@freesewing/css-theme",
"version": "2.0.0-alpha.18",
"version": "2.0.0-alpha.19",
"description": "A CSS theme for FreeSewing web UIs",
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",

View file

@ -1,3 +1,4 @@
@import "components/emblem";
@import "components/navbar";
@import "components/draft";
@import "components/draft-configurator";

View file

@ -0,0 +1,2 @@
@import "elements/a";
@import "elements/footer";

View file

@ -0,0 +1,6 @@
// Smooth scrolling by default
html { scroll-behavior: smooth; }
// But let people override it
@media screen and (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
}

View file

@ -1,7 +1,10 @@
.theme-wrapper {
margin-top: 0;
padding-top: 64px;
min-height: calc(100vh - 64px);
margin: 0;
padding: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.theme-wrapper.light {

View file

@ -8,6 +8,24 @@ $fc-hoverbg-light: $oc-gray-1;
$fc-hoverbg-dark: $oc-gray-8;
$fc-accentbg-light: $oc-teal-5;
$fc-accentbg-dark: $oc-teal-8;
$fc-link-light: $oc-teal-8;
$fc-link-light: $oc-blue-6;
$fc-link-dark: $oc-blue-3;
$fc-draft-lining-light: $oc-teal-6;
$fc-draft-fabric-light: $oc-gray-9;
$fc-draft-canvas-light: $oc-yellow-7;
$fc-draft-interfacing-light: $oc-gray-6;
$fc-draft-various-light: $oc-pink-5;
$fc-draft-mark-light: $oc-indigo-6;
$fc-draft-contrast-light: $oc-orange-7;
$fc-draft-note-light: $oc-blue-7;
$fc-draft-lining-dark: $oc-teal-6;
$fc-draft-fabric-dark: $oc-gray-9;
$fc-draft-canvas-dark: $oc-yellow-7;
$fc-draft-interfacing-dark: $oc-gray-6;
$fc-draft-various-dark: $oc-pink-5;
$fc-draft-mark-dark: $oc-indigo-6;
$fc-draft-contrast-dark: $oc-orange-7;
$fc-draft-note-dark: $oc-blue-7;

View file

@ -0,0 +1,108 @@
svg.freesewing.draft {
max-width: 100%;
max-height: 90vh;
/* Reset */
path,circle,rect{fill:none;stroke:none}
/* Defaults */
path,circle{
stroke-opacity:1;
stroke-width:.7;
stroke-linecap:round;
stroke-linejoin:round;
}
/* Stroke classes */
.note{ stroke-width:.8; }
.mark{ stroke-width:.8; }
.contrast{ stroke-width:1.2; }
.stroke-xs{ stroke-width:.5; }
.stroke-sm{ stroke-width:.5; }
.stroke-xl{ stroke-width:1.4; }
.stroke-xxl{ stroke-width:2.4; }
.sa { stroke-dasharray:1,3; }
.help {
stroke-width:.6;
stroke-dasharray:15,5,2,5;
}
.dotted { stroke-dasharray:2,3; }
.dashed { stroke-dasharray:2,5; }
.lashed { stroke-dasharray:8,8; }
.hidden {
stroke:none;
fill:none;
}
/* Sampling */
path.sample-focus {stroke-width: 1.5; fill: rgba(0,0,0,0.1)}
/* Text */
text{
font-size:6px;
@include title-font;
text-anchor:start;
font-weight:200;
dominant-baseline:ideographic;
}
.text-xs { font-size:4px; }
.text-sm { font-size:5px; }
.text-lg { font-size:8px; }
.text-xl { font-size:10px; }
.text-xxl{ font-size:13px; }
.center{ text-anchor:middle; }
.right{ text-anchor:end; }
/* Plugins */
text.title-nr {
font-size: 32px;
@include title-font;
font-weight: bold;
stroke: none;
}
}
.theme-wrapper.light svg.freesewing.draft {
/* Stroke classes */
path,circle{ stroke: $fc-draft-fabric-light; }
.fabric{ stroke: $fc-draft-fabric-light; }
.lining{ stroke: $fc-draft-lining-light; }
.interfacing{ stroke: $fc-draft-interfacing-light; }
.canvas{ stroke: $fc-draft-canvas-light; }
.various{ stroke: $fc-draft-various-light; }
.mark{ stroke: $fc-draft-mark-light; }
.contrast{ stroke: $fc-draft-contrast-light; }
.note{ stroke: $fc-draft-note-light; }
/* Fill classes */
.fill-fabric{ fill: $fc-draft-fabric-light; }
.fill-lining{ fill: $fc-draft-lining-light; }
.fill-interfacing{ fill: $fc-draft-interfacing-light; }
.fill-canvas{ fill: $fc-draft-canvas-light; }
.fill-various{ fill: $fc-draft-various-light; }
.fill-mark{ fill: $fc-draft-mark-light; }
.fill-contrast{ fill: $fc-draft-contrast-light; }
.fill-note{ fill: $fc-draft-note-light; }
}
.theme-wrapper.dark svg.freesewing.draft {
/* Stroke classes */
path,circle{ stroke: $fc-draft-fabric-dark; }
.fabric{ stroke: $fc-draft-fabric-dark; }
.lining{ stroke: $fc-draft-lining-dark; }
.interfacing{ stroke: $fc-draft-interfacing-dark; }
.canvas{ stroke: $fc-draft-canvas-dark; }
.various{ stroke: $fc-draft-various-dark; }
.mark{ stroke: $fc-draft-mark-dark; }
.contrast{ stroke: $fc-draft-contrast-dark; }
.note{ stroke: $fc-draft-note-dark; }
/* Fill classes */
.fill-fabric{ fill: $fc-draft-fabric-dark; }
.fill-lining{ fill: $fc-draft-lining-dark; }
.fill-interfacing{ fill: $fc-draft-interfacing-dark; }
.fill-canvas{ fill: $fc-draft-canvas-dark; }
.fill-various{ fill: $fc-draft-various-dark; }
.fill-mark{ fill: $fc-draft-mark-dark; }
.fill-contrast{ fill: $fc-draft-contrast-dark; }
.fill-note{ fill: $fc-draft-note-dark; }
}

View file

@ -1,7 +1,4 @@
header.navbar {
position: fixed;
top: 0;
left: 0;
height: 64px;
width: calc(100% - 52px);
margin: 0;
@ -17,9 +14,11 @@ header.navbar {
display: flex;
align-items: center;
color: $oc-gray-2;
a { text-decoration: none; }
}
div.emblem {
margin-right: 26px;
a { text-decoration: none; }
}
div.spread { flex-grow: 1}
a.nav,
@ -44,10 +43,12 @@ header.navbar {
button:hover,
a.nav:hover {
cursor: pointer;
color: $fc-link-dark;
border-color: $fc-link-dark;
}
button:hover,
a.nav:hover,
button.active,
a.nav.active {
color: $fc-link-dark;
border-color: $fc-link-dark;
}
svg.nav-icon {

View file

@ -0,0 +1,12 @@
.theme-wrapper a {
text-decoration: none;
}
.theme-wrapper a:hover {
text-decoration: underline;
}
.theme-wrapper.light a {
color: $fc-link-light;
}
.theme-wrapper.dark a {
color: $fc-link-dark;
}

View file

@ -0,0 +1,19 @@
footer {
background: $fc-bg-dark;
color: $fc-text-dark;
margin: 0;
padding: 4rem 1rem;
text-align: center;
a { color: $fc-text-dark!important; }
a:hover { color: $fc-link-dark!important; }
a.gitter:hover { color: #ed1965!important; }
a.twitter:hover { color: #1da1f2!important; }
a.github:hover { color: #6cc644!important; }
a.instagram:hover { color: #e1306c!important; }
a.facebook:hover { color: #3b5998!important; }
ul {
margin: 0;
padding: 0;
}
li { list-style-type: none; }
}

View file

@ -10,14 +10,14 @@ div.fs-sa {
max-width: 400px;
min-width: 200px;
width: 30%;
height: 100%;
min-height: calc(120vh - 64px);
background: $oc-gray-1;
border-left: 1px solid $oc-gray-3;
}
aside div.sticky {
position: sticky;
top: calc(64px + 1rem);
top: 1rem;
height: 100vh;
overflow-y: scroll;
}
}

View file

@ -2,6 +2,8 @@
@import '../../../node_modules/open-color/open-color.scss';
@import "variables";
@import "mixins";
@import "dark";
@import "theme-wrapper";
@import "layout";
@import "scroll";
@import "components";
@import "elements";

View file

@ -28,9 +28,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -28,7 +28,7 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/pattern-info": "^2.0.0-alpha.18"
"@freesewing/pattern-info": "^2.0.0-alpha.19"
},
"files": [
"dist/*",

View file

@ -218,3 +218,8 @@ youAreAPatron: Du bist ein Gönner
youAreNotAPatron: Sie sind gein Gönner
youAreNotLoggedIn: Du bist nicht eingeloggt
yourRights: Deine Rechte
makerDocs: Herstellerdokumentation
devDocs: Entwicklerdokumentation
makerBlog: Hersteller-Blog
devBlog: Entwickler-Blog

View file

@ -10,7 +10,11 @@ startRollup: Starten Sie den Rollup-Bündler in einem Terminal im Überwachungsm
startWebpack: Führen Sie in einem anderen Terminal den Webpack-Dev-Server aus
devDocsAvailableAt: Entwicklerdokumentation ist verfügbar unter
talkToUs: Für Fragen, Feedback oder Anregungen sprechen Sie mit uns in unserem Chatroom
renderYourPattern: Rendern Sie Ihr Schnitmuster
draftYourPattern: Entwürf Ihr Schnitmuster
testYourPattern: Test Ihr Schnitmuster
renderInBrowser: Klicken Sie unten, um Ihr schnittmuster im Browser zu rendern.
weWillReRender: Wenn Sie Änderungen vornehmen, werden wir für Sie erneut rendern.
youCan: Sie können
enterMeasurements: Geben Sie die Maße von Hand ein
preloadMeasurements: Laden Sie eine Reihe von Messungen vor
size: Größe

View file

@ -217,3 +217,7 @@ youAreAPatron: You are a patron
youAreNotAPatron: Your are not a patron
youAreNotLoggedIn: You are not logged in
yourRights: Your rights
makerDocs: Maker documentation
devDocs: Developer documentation
makerBlog: Maker blog
devBlog: Developer blog

View file

@ -9,6 +9,11 @@ startRollup: In one terminal, start the rollup bundler in watch mode
startWebpack: And in another terminal, run the webpack dev server
devDocsAvailableAt: Developer documentation is available at
talkToUs: For questions, feedback or suggestions, come talk to us in our chat room
renderYourPattern: Render your pattern
draftYourPattern: Draft your pattern
testYourPattern: Test your pattern
renderInBrowser: Click below to render your pattern in the browser.
weWillReRender: When you make changes, we will re-render for you.
youCan: You can
enterMeasurements: Enter measurements by hand
preloadMeasurements: Preload a set of measurements
size: Size

View file

@ -218,3 +218,8 @@ youAreAPatron: Eres un mecenas
youAreNotAPatron: Tu no eres un mecenas
youAreNotLoggedIn: No has iniciado sesión
yourRights: Tus derechos
makerDocs: Documentación del creador
devDocs: Documentación del desarrollador
makerBlog: Blog de creadores
devBlog: Blog de desarrolladores

View file

@ -10,7 +10,11 @@ startRollup: En un terminal, inicie rollup en modo de reloj
startWebpack: Y en otro terminal, ejecuta el servidor webpack dev
devDocsAvailableAt: La documentación del desarrollador está disponible en
talkToUs: Para preguntas, comentarios o sugerencias, venga a hablar con nosotros en nuestra sala de chat
renderYourPattern: Rinda su patrón
draftYourPattern: Trazar su patrón
testYourPattern: Prueba su patrón
renderInBrowser: Haga clic a continuación para representar su patrón en el navegador.
weWillReRender: Cuando haga cambios, volveremos a renderizar por usted.
youCan: Usted puede
enterMeasurements: Introducir medidas a mano
preloadMeasurements: Precargar un conjunto de medidas
size: Tamaño

View file

@ -218,3 +218,8 @@ youAreAPatron: Vous êtes un mécène
youAreNotAPatron: Vous n'êtes pas mécène
youAreNotLoggedIn: Vous n'êtes pas connecté
yourRights: Vos droits
makerDocs: Documentation créateur
devDocs: Documentation développeur
makerBlog: Blog de créateur
devBlog: Blog de développeur

View file

@ -10,6 +10,11 @@ startRollup: Dans un terminal, démarrez rollup en mode veille
startWebpack: Et dans un autre terminal, exécutez le serveur de développement webpack
devDocsAvailableAt: La documentation du développeur est disponible à l'adresse
talkToUs: Pour des questions, des commentaires ou des suggestions, venez nous parler dans notre salle de chat
renderYourPattern: Rendez votre patron
draftYourPattern: Ébauche votre patron
testYourPattern: Test votre patron
renderInBrowser: Cliquez ci-dessous pour rendre votre motif dans le navigateur.
weWillReRender: Lorsque vous apportez des modifications, nous effectuons un nouveau rendu pour vous.
youCan: Vous pouvez
enterMeasurements: Entrer les mesures à la main
preloadMeasurements: Précharger un ensemble de mesures
size: Taille

View file

@ -218,3 +218,8 @@ youAreAPatron: Je bent een mecenas
youAreNotAPatron: Je bent geen mecenas
youAreNotLoggedIn: Je bent niet ingelogd
yourRights: Jouw rechten
makerDocs: Maker documentatie
devDocs: Ontwikkelaar documentatie
makerBlog: Maker blog
devBlog: Ontwikkelaar blog

View file

@ -10,7 +10,11 @@ startRollup: Start in één terminal rollup in watch-modus
startWebpack: En in een andere terminal start je de webpack dev-server
devDocsAvailableAt: Documentatie voor ontwikkelaars is beschikbaar op
talkToUs: Voor vragen, feedback of suggesties, kan je terecht in onze chatroom
renderYourPattern: Render je patroon
draftYourPattern: Teken je patroon
testYourPattern: Test je patroon
renderInBrowser: Klik hieronder om uw patroon te renderen in de browser.
weWillReRender: Telkens u wijzigingen aanbrengt renderen we opnieuw.
youCan: Je kan
enterMeasurements: Handmatig afmetingen invoeren
preloadMeasurements: Een reeks afmetingen laden
size: Maat

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -29,6 +29,9 @@
"pubforce": "npm publish",
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -1,6 +1,6 @@
{
"name": "@freesewing/mui-theme",
"version": "2.0.0-alpha.18",
"version": "2.0.0-alpha.19",
"description": "A Material-UI theme for FreeSewing web UIs",
"author": "Joost De Cock <joost@decock.org> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",

View file

@ -31,6 +31,9 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
"prebuild": "node src/prebuild.js"
},
"peerDependencies": {},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,8 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {
"@freesewing/aaron": "^2.0.0-alpha.19",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -34,8 +34,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,8 +33,10 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,11 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/brian": "^2.0.0-alpha.18",
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18",
"@freesewing/plugin-buttons": "^2.0.0-alpha.18",
"@freesewing/plugin-flip": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19",
"@freesewing/brian": "^2.0.0-alpha.19",
"@freesewing/plugin-buttons": "^2.0.0-alpha.19",
"@freesewing/plugin-flip": "^2.0.0-alpha.19"
},
"files": [
"dist/*",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -33,9 +33,11 @@
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {
"@freesewing/core": "^2.0.0-alpha.18",
"@freesewing/plugin-bundle": "^2.0.0-alpha.18"
"@freesewing/core": "^2.0.0-alpha.19",
"@freesewing/plugin-bundle": "^2.0.0-alpha.19"
},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -28,6 +28,9 @@
"pubforce": "npm publish",
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -"
},
"peerDependencies": {},
"dependencies": {},
"devDependencies": {},
"files": [
"dist/*",
"README.md",

View file

@ -11,3 +11,4 @@ export { default as roundMmUp } from "./roundMmUp";
export { default as sliderStep } from "./sliderStep";
export { default as smallestImperialStep } from "./smallestImperialStep";
export { default as storage } from "./storage";
export { default as measurementAsMm } from "./measurementAsMm";

View file

@ -0,0 +1,25 @@
const measurementAsMm = (value, units = "metric") => {
if (typeof value === "number")
return value * (units === "imperial" ? 25.4 : 10);
if (units === "metric") {
value = Number(value);
if (isNaN(value)) return false;
return value * (units === "imperial" ? 25.4 : 10);
} else {
let chunks = value.split(" ");
if (chunks.length === 1) {
let val = chunks[0];
if (!isNaN(Number(val))) return Number(val) * 25.4;
else return imperialFractionToMm(val);
} else if (chunks.length === 2) {
let inches = Number(chunks[0]);
if (isNaN(inches)) return false;
let fraction = imperialFractionToMm(chunks[1]);
if (fraction === false) return false;
return inches * 25.4 + fraction;
}
}
return false;
};
export default measurementAsMm;

Some files were not shown because too many files have changed in this diff Show more