🚧 Progress on workbench
This commit is contained in:
parent
1a8fe110f8
commit
158c19ae1d
101 changed files with 1222 additions and 200 deletions
|
@ -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"
|
||||
|
|
|
@ -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/*",
|
||||
|
|
|
@ -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/*",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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/*",
|
||||
|
|
|
@ -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/*",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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/*",
|
||||
|
|
59
packages/components/src/.form/FormFieldMeasurement/index.js
Normal file
59
packages/components/src/.form/FormFieldMeasurement/index.js
Normal 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);
|
|
@ -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} />
|
||||
));
|
20
packages/components/src/Draft/Circle/index.js
Normal file
20
packages/components/src/Draft/Circle/index.js
Normal 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;
|
9
packages/components/src/Draft/Defs/index.js
Normal file
9
packages/components/src/Draft/Defs/index.js
Normal 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;
|
31
packages/components/src/Draft/Part/index.js
Normal file
31
packages/components/src/Draft/Part/index.js
Normal 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;
|
14
packages/components/src/Draft/Path/index.js
Normal file
14
packages/components/src/Draft/Path/index.js
Normal 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;
|
22
packages/components/src/Draft/Point/index.js
Normal file
22
packages/components/src/Draft/Point/index.js
Normal 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;
|
9
packages/components/src/Draft/Style/index.js
Normal file
9
packages/components/src/Draft/Style/index.js
Normal 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;
|
37
packages/components/src/Draft/Svg/index.js
Normal file
37
packages/components/src/Draft/Svg/index.js
Normal 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;
|
49
packages/components/src/Draft/Text/index.js
Normal file
49
packages/components/src/Draft/Text/index.js
Normal 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;
|
93
packages/components/src/Draft/draft.scss
Normal file
93
packages/components/src/Draft/draft.scss
Normal 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; }
|
||||
}
|
41
packages/components/src/Draft/index.js
Normal file
41
packages/components/src/Draft/index.js
Normal 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;
|
16
packages/components/src/Draft/utils.js
Normal file
16
packages/components/src/Draft/utils.js
Normal 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;
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
80
packages/components/src/Footer/index.js
Normal file
80
packages/components/src/Footer/index.js
Normal 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;
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -7,7 +7,6 @@ const LanguageChooser = props => {
|
|||
container: {
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
height: "calc(100vh - 64px)",
|
||||
width: "100%"
|
||||
},
|
||||
chooser: {
|
||||
|
|
98
packages/components/src/Workbench/Measurements/index.js
Normal file
98
packages/components/src/Workbench/Measurements/index.js
Normal 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" />
|
||||
|
||||
{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;
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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";
|
||||
|
|
0
packages/components/src/touch
Normal file
0
packages/components/src/touch
Normal 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",
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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/",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@import "components/emblem";
|
||||
@import "components/navbar";
|
||||
@import "components/draft";
|
||||
@import "components/draft-configurator";
|
||||
|
|
2
packages/css-theme/src/_elements.scss
Normal file
2
packages/css-theme/src/_elements.scss
Normal file
|
@ -0,0 +1,2 @@
|
|||
@import "elements/a";
|
||||
@import "elements/footer";
|
6
packages/css-theme/src/_scroll.scss
Normal file
6
packages/css-theme/src/_scroll.scss
Normal 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; }
|
||||
}
|
|
@ -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 {
|
|
@ -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;
|
||||
|
||||
|
|
108
packages/css-theme/src/components/_draft.scss
Normal file
108
packages/css-theme/src/components/_draft.scss
Normal 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; }
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
12
packages/css-theme/src/elements/_a.scss
Normal file
12
packages/css-theme/src/elements/_a.scss
Normal 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;
|
||||
}
|
19
packages/css-theme/src/elements/_footer.scss
Normal file
19
packages/css-theme/src/elements/_footer.scss
Normal 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; }
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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/*",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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/",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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/*",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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";
|
||||
|
|
25
packages/utils/src/measurementAsMm.js
Normal file
25
packages/utils/src/measurementAsMm.js
Normal 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
Loading…
Add table
Add a link
Reference in a new issue