🚧 Progress on workbench and CFP
This commit is contained in:
parent
c2628a0a52
commit
c9afc0edd0
26 changed files with 962 additions and 25 deletions
|
@ -40,6 +40,7 @@ components:
|
|||
"@material-ui/core": "^3.9.3"
|
||||
"@material-ui/icons": "^3.0.2"
|
||||
"@material-ui/lab": "^3.0.0-alpha.30"
|
||||
"prismjs": "1.16.0"
|
||||
core:
|
||||
_:
|
||||
"bezier-js": "^2.2.13"
|
||||
|
|
64
packages/components/src/Draft/DesignPath/index.js
Normal file
64
packages/components/src/Draft/DesignPath/index.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
import React from "react";
|
||||
|
||||
const DesignPath = props => {
|
||||
let output = [];
|
||||
let i = 0;
|
||||
let from = null;
|
||||
for (let op of props.path.ops) {
|
||||
if (op.type === "curve") {
|
||||
output.push(
|
||||
<path
|
||||
key={i}
|
||||
d={`M ${from.x},${from.y} L ${op.cp1.x},${op.cp1.y}`}
|
||||
className="design path cp"
|
||||
/>
|
||||
);
|
||||
i++;
|
||||
output.push(
|
||||
<path
|
||||
key={i}
|
||||
d={`M ${op.to.x},${op.to.y} L ${op.cp2.x},${op.cp2.y}`}
|
||||
className="design path cp"
|
||||
/>
|
||||
);
|
||||
i++;
|
||||
output.push(
|
||||
<circle
|
||||
key={i}
|
||||
cx={op.cp1.x}
|
||||
cy={op.cp1.y}
|
||||
r={3.5}
|
||||
className="design path cp"
|
||||
/>
|
||||
);
|
||||
i++;
|
||||
output.push(
|
||||
<circle
|
||||
key={i}
|
||||
cx={op.cp2.x}
|
||||
cy={op.cp2.y}
|
||||
r={3.5}
|
||||
className="design path cp"
|
||||
/>
|
||||
);
|
||||
from = op.to;
|
||||
} else if (op.type !== "close") from = op.to;
|
||||
}
|
||||
output.push(
|
||||
<path
|
||||
key={"dpath-" + props.name}
|
||||
d={props.path.asPathstring()}
|
||||
onClick={() =>
|
||||
props.raiseEvent("path", {
|
||||
path: props.path,
|
||||
name: props.name,
|
||||
part: props.part
|
||||
})
|
||||
}
|
||||
className="design hovertrap"
|
||||
/>
|
||||
);
|
||||
return output;
|
||||
};
|
||||
|
||||
export default DesignPath;
|
1
packages/components/src/Draft/DesignPath/logo-path.js
Normal file
1
packages/components/src/Draft/DesignPath/logo-path.js
Normal file
File diff suppressed because one or more lines are too long
22
packages/components/src/Draft/DesignPoint/index.js
Normal file
22
packages/components/src/Draft/DesignPoint/index.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import React from "react";
|
||||
|
||||
const DesignPoint = props => (
|
||||
<g className={props.className}>
|
||||
<circle cx={props.point.x} cy={props.point.y} r="2" className="center" />
|
||||
<circle
|
||||
cx={props.point.x}
|
||||
cy={props.point.y}
|
||||
r="7.5"
|
||||
className="hovertrap"
|
||||
onClick={() =>
|
||||
props.raiseEvent("point", {
|
||||
point: props.point,
|
||||
name: props.name,
|
||||
part: props.part
|
||||
})
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
);
|
||||
|
||||
export default DesignPoint;
|
1
packages/components/src/Draft/DesignPoint/logo-path.js
Normal file
1
packages/components/src/Draft/DesignPoint/logo-path.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -6,7 +6,60 @@ import Snippet from "../Snippet";
|
|||
import { getProps } from "../utils";
|
||||
|
||||
const Part = props => {
|
||||
console.log(props.part);
|
||||
const focusPoint = (point, i) => {
|
||||
let p = props.part.points[point];
|
||||
let pathString = `M ${p.x} ${props.part.topLeft.y} `;
|
||||
pathString += `L ${p.x} ${props.part.bottomRight.y} `;
|
||||
pathString += `M ${props.part.topLeft.x} ${p.y} `;
|
||||
pathString += `L ${props.part.bottomRight.x} ${p.y} `;
|
||||
let classes = "focus point c" + (i % 4); // Cycle through 4 CSS classes
|
||||
return (
|
||||
<React.Fragment key={"fp" + point}>
|
||||
<path d={pathString} className={classes} />
|
||||
<circle
|
||||
cx={p.x}
|
||||
cy={p.y}
|
||||
r="5"
|
||||
className={classes}
|
||||
onClick={() =>
|
||||
props.raiseEvent("clearFocus", {
|
||||
part: props.name,
|
||||
type: "points",
|
||||
name: point
|
||||
})
|
||||
}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const focusCoords = (p, i) => {
|
||||
console.log("focus coords", p, i);
|
||||
let pathString = `M ${p.x} ${props.part.topLeft.y} `;
|
||||
pathString += `L ${p.x} ${props.part.bottomRight.y} `;
|
||||
pathString += `M ${props.part.topLeft.x} ${p.y} `;
|
||||
pathString += `L ${props.part.bottomRight.x} ${p.y} `;
|
||||
let classes = "focus coords c" + (i % 4); // Cycle through 4 CSS classes
|
||||
return (
|
||||
<React.Fragment key={"cp" + i}>
|
||||
<path d={pathString} className={classes} />
|
||||
<circle
|
||||
cx={p.x}
|
||||
cy={p.y}
|
||||
r="5"
|
||||
className={classes}
|
||||
onClick={() =>
|
||||
props.raiseEvent("clearFocus", {
|
||||
part: props.name,
|
||||
type: "coords",
|
||||
data: p
|
||||
})
|
||||
}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
let grid = props.paperless ? (
|
||||
<rect
|
||||
x={props.part.topLeft.x}
|
||||
|
@ -18,6 +71,38 @@ const Part = props => {
|
|||
/>
|
||||
) : null;
|
||||
|
||||
let focus = [];
|
||||
if (props.design) {
|
||||
let designProps = {
|
||||
...props,
|
||||
key: "dp-" + props.name,
|
||||
className: "design point"
|
||||
};
|
||||
if (props.focus && typeof props.focus[props.name] !== "undefined") {
|
||||
for (let i in props.focus[props.name].points)
|
||||
focus.push(focusPoint(props.focus[props.name].points[i], i));
|
||||
for (let i in props.focus[props.name].paths) {
|
||||
let name = props.focus[props.name].paths[i];
|
||||
focus.push(
|
||||
<path
|
||||
key={"fpa-" + name}
|
||||
d={props.part.paths[name].asPathstring()}
|
||||
className={"focus path c" + (i % 4)}
|
||||
onClick={() =>
|
||||
props.raiseEvent("clearFocus", {
|
||||
part: props.name,
|
||||
type: "paths",
|
||||
name
|
||||
})
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
for (let i in props.focus[props.name].coords)
|
||||
focus.push(focusCoords(props.focus[props.name].coords[i], i));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<g {...getProps(props.part)}>
|
||||
{grid}
|
||||
|
@ -28,6 +113,11 @@ const Part = props => {
|
|||
part={props.name}
|
||||
language={props.language}
|
||||
path={props.part.paths[name]}
|
||||
focus={props.focus}
|
||||
topLeft={props.part.topLeft}
|
||||
bottomRight={props.part.bottomRight}
|
||||
design={props.design}
|
||||
raiseEvent={props.raiseEvent}
|
||||
/>
|
||||
))}
|
||||
{Object.keys(props.part.points).map(name => (
|
||||
|
@ -37,11 +127,17 @@ const Part = props => {
|
|||
part={props.name}
|
||||
language={props.language}
|
||||
point={props.part.points[name]}
|
||||
focus={props.focus}
|
||||
topLeft={props.part.topLeft}
|
||||
bottomRight={props.part.bottomRight}
|
||||
design={props.design}
|
||||
raiseEvent={props.raiseEvent}
|
||||
/>
|
||||
))}
|
||||
{Object.keys(props.part.snippets).map(name => (
|
||||
<Snippet key={name} name={name} snippet={props.part.snippets[name]} />
|
||||
))}
|
||||
{focus}
|
||||
</g>
|
||||
);
|
||||
};
|
||||
|
@ -51,6 +147,7 @@ Part.propTypes = {
|
|||
name: PropTypes.string.isRequired,
|
||||
language: PropTypes.string.isRequired,
|
||||
paperless: PropTypes.bool.isRequired,
|
||||
design: PropTypes.bool.isRequired,
|
||||
units: PropTypes.oneOf(["metric", "imperial"]).isRequired
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import TextOnPath from "../TextOnPath";
|
||||
import DesignPath from "../DesignPath";
|
||||
import { getProps } from "../utils";
|
||||
|
||||
const Path = props => {
|
||||
if (!props.path.render) return null;
|
||||
const output = [];
|
||||
const pathId = "path-" + props.part + "-" + props.name;
|
||||
if (props.design)
|
||||
output.push(<DesignPath {...props} key={"dpa-" + props.name} />);
|
||||
output.push(
|
||||
<path
|
||||
id={pathId}
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import DesignPoint from "../DesignPoint";
|
||||
import Text from "../Text";
|
||||
import Circle from "../Circle";
|
||||
|
||||
const Point = props => {
|
||||
const output = [];
|
||||
if (props.design)
|
||||
output.push(
|
||||
<DesignPoint
|
||||
{...props}
|
||||
key={"dp-" + props.name}
|
||||
className="design point"
|
||||
/>
|
||||
);
|
||||
if (props.point.attributes.get("data-text"))
|
||||
output.push(<Text {...props} key={"point-" + props.name} />);
|
||||
if (props.point.attributes.get("data-circle"))
|
||||
|
|
|
@ -17,6 +17,7 @@ const Draft = props => {
|
|||
units={props.settings.units}
|
||||
parts={props.parts}
|
||||
paperless={props.settings.paperless}
|
||||
design={props.design}
|
||||
/>
|
||||
<g>
|
||||
{Object.keys(props.parts).map(name => (
|
||||
|
@ -27,6 +28,9 @@ const Draft = props => {
|
|||
units={props.settings.units}
|
||||
key={name}
|
||||
name={name}
|
||||
focus={props.focus}
|
||||
design={props.design}
|
||||
raiseEvent={props.raiseEvent}
|
||||
/>
|
||||
))}
|
||||
</g>
|
||||
|
@ -41,7 +45,8 @@ Draft.propTypes = {
|
|||
};
|
||||
|
||||
Draft.defaultProps = {
|
||||
design: false
|
||||
design: false,
|
||||
focus: false
|
||||
};
|
||||
|
||||
export default Draft;
|
||||
|
|
219
packages/components/src/Workbench/Design/index.js
Normal file
219
packages/components/src/Workbench/Design/index.js
Normal file
|
@ -0,0 +1,219 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { FormattedMessage, FormattedHTMLMessage } from "react-intl";
|
||||
|
||||
const Design = props => {
|
||||
// Methods
|
||||
const renderAttributes = attr => {
|
||||
let list = [];
|
||||
for (let a in attr.list)
|
||||
list.push(
|
||||
<li key={a}>
|
||||
<b>{a}</b>: {renderAttributeValue(attr.list[a])}
|
||||
</li>
|
||||
);
|
||||
|
||||
return <ul className="links">{list}</ul>;
|
||||
};
|
||||
|
||||
const renderAttributeValue = val => {
|
||||
if (Array.isArray(val)) {
|
||||
if (val.length === 1) return val.pop();
|
||||
let list = [];
|
||||
for (let v of val) list.push(<li key={v}>{v}</li>);
|
||||
return <ul>{list}</ul>;
|
||||
}
|
||||
|
||||
return val;
|
||||
};
|
||||
|
||||
const idPathPoint = (part, a) => {
|
||||
for (let p in props.parts[part].points) {
|
||||
let b = props.parts[part].points[p];
|
||||
if (a.x === b.x && a.y === b.y) return p;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const renderPathOps = (path, part) => {
|
||||
let list = [];
|
||||
for (let i in path.ops) list.push(renderPathOp(path.ops[i], i, part));
|
||||
|
||||
return <ul className="links">{list}</ul>;
|
||||
};
|
||||
|
||||
const renderPathOp = (op, key, part) => {
|
||||
let list = [];
|
||||
let focus = {
|
||||
part,
|
||||
coords: {
|
||||
x: null,
|
||||
y: null
|
||||
}
|
||||
};
|
||||
|
||||
if (op.type === "move" || op.type === "line") {
|
||||
focus.coords.x = op.to.x;
|
||||
focus.coords.y = op.to.y;
|
||||
let text = <span>(op.to.x,op.to.y)</span>;
|
||||
let click = () => props.raiseEvent("coords", focus);
|
||||
let pname = idPathPoint(part, op.to);
|
||||
if (pname) {
|
||||
text = pname;
|
||||
click = () =>
|
||||
props.raiseEvent("point", {
|
||||
point: props.parts[part].points[pname],
|
||||
name: pname,
|
||||
part: part
|
||||
});
|
||||
}
|
||||
return (
|
||||
<li key={key}>
|
||||
<b>{op.type}</b>
|
||||
»
|
||||
<a href="#logo" role="button" onClick={click}>
|
||||
{text}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
} else if (op.type === "curve") {
|
||||
let texts = {};
|
||||
let clicks = {};
|
||||
let types = ["to", "cp1", "cp2"];
|
||||
for (let t of types) {
|
||||
let pname = idPathPoint(part, op[t]);
|
||||
if (pname) {
|
||||
texts[t] = pname;
|
||||
clicks[t] = () =>
|
||||
props.raiseEvent("point", {
|
||||
point: props.parts[part].points[pname],
|
||||
name: pname,
|
||||
part
|
||||
});
|
||||
} else {
|
||||
texts[t] = (
|
||||
<span>
|
||||
({op[t].x},{op[t].y})
|
||||
</span>
|
||||
);
|
||||
clicks[t] = () =>
|
||||
props.raiseEvent("coords", {
|
||||
...focus,
|
||||
coords: {
|
||||
x: op[t].x,
|
||||
y: op[t].y
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return (
|
||||
<li key={key}>
|
||||
<b>{op.type}</b>
|
||||
{types.map(t => (
|
||||
<React.Fragment key={t}>
|
||||
<span> » </span>
|
||||
<a href="#logo" role="button" onClick={clicks[t]}>
|
||||
{texts[t]}
|
||||
</a>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</li>
|
||||
);
|
||||
} else if (op.type === "close")
|
||||
return (
|
||||
<li key={key}>
|
||||
<b>close</b>
|
||||
</li>
|
||||
);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
// Variables
|
||||
const styles = {
|
||||
container: {
|
||||
padding: "0 1rem"
|
||||
},
|
||||
h3: {
|
||||
margin: "0.5rem 0"
|
||||
},
|
||||
h4: {
|
||||
margin: "0.25rem 0 0 0.5rem"
|
||||
},
|
||||
ul: {
|
||||
marginTop: "0.25rem"
|
||||
}
|
||||
};
|
||||
|
||||
if (
|
||||
!props.design ||
|
||||
props.focus === null ||
|
||||
Object.keys(props.focus).length < 1
|
||||
)
|
||||
return null;
|
||||
let info = [];
|
||||
for (let part of Object.keys(props.focus)) {
|
||||
info.push(
|
||||
<h3 key={"part-" + part} style={styles.h3}>
|
||||
parts.<b>{part}</b>
|
||||
</h3>
|
||||
);
|
||||
for (let i in props.focus[part].paths) {
|
||||
let name = props.focus[part].paths[i];
|
||||
let path = props.parts[part].paths[name];
|
||||
info.push(
|
||||
<h4
|
||||
key={"patitle-" + name}
|
||||
style={styles.h4}
|
||||
className={"path c" + (i % 4)}
|
||||
>
|
||||
path.<b>{name}</b>
|
||||
</h4>
|
||||
);
|
||||
info.push(
|
||||
<ul className="links" key={"ops-" + name} style={styles.ul}>
|
||||
<li>
|
||||
<b>attributes</b>: {renderAttributes(path.attributes)}
|
||||
</li>
|
||||
<li>
|
||||
<b>ops</b>: {renderPathOps(path, part)}
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
for (let i in props.focus[part].points) {
|
||||
let name = props.focus[part].points[i];
|
||||
let point = props.parts[part].points[name];
|
||||
info.push(
|
||||
<h4
|
||||
key={"potitle-" + name}
|
||||
style={styles.h4}
|
||||
className={"point c" + (i % 4)}
|
||||
>
|
||||
point.<b>{name}</b>
|
||||
</h4>
|
||||
);
|
||||
info.push(
|
||||
<ul className="links" key={"pdata-" + name} style={styles.ul}>
|
||||
<li>
|
||||
<b>x</b>: {point.x}
|
||||
</li>
|
||||
<li>
|
||||
<b>y</b>: {point.y}
|
||||
</li>
|
||||
<li>
|
||||
<b>attributes</b>: {renderAttributes(point.attributes)}
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={styles.container} className="design">
|
||||
{info}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Design;
|
|
@ -1,27 +1,119 @@
|
|||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { defaultGist } from "@freesewing/utils";
|
||||
import Draft from "../../Draft";
|
||||
import Design from "../Design";
|
||||
import DraftConfigurator from "../../DraftConfigurator";
|
||||
import { strings } from "@freesewing/i18n";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import Prism from "prismjs";
|
||||
|
||||
const DraftPattern = props => {
|
||||
const [design, setDesign] = useState(true);
|
||||
const [focus, setFocus] = useState(null);
|
||||
|
||||
const raiseEvent = (type, data) => {
|
||||
if (type === "clearFocusAll") return setFocus(null);
|
||||
let f = {};
|
||||
if (focus !== null) f = { ...focus };
|
||||
if (typeof f[data.part] === "undefined")
|
||||
f[data.part] = { paths: [], points: [], coords: [] };
|
||||
if (type === "point") f[data.part].points.push(data.name);
|
||||
else if (type === "path") f[data.part].paths.push(data.name);
|
||||
else if (type === "coords") f[data.part].coords.push(data.coords);
|
||||
else if (type === "clearFocus") {
|
||||
let i = focus[data.part][data.type].indexOf(data.name);
|
||||
f[data.part][data.type].splice(i, 1);
|
||||
}
|
||||
|
||||
setFocus(f);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
paragraph: {
|
||||
padding: "0 1rem"
|
||||
}
|
||||
};
|
||||
let pattern = new props.Pattern(props.gist.settings);
|
||||
pattern.draft();
|
||||
let patternProps = pattern.getRenderProps();
|
||||
let focusCount = 0;
|
||||
if (focus !== null) {
|
||||
for (let p of Object.keys(focus)) {
|
||||
for (let i in focus[p].points) focusCount++;
|
||||
for (let i in focus[p].paths) focusCount++;
|
||||
for (let i in focus[p].coords) focusCount++;
|
||||
}
|
||||
}
|
||||
|
||||
let gist = Prism.highlight(
|
||||
JSON.stringify(props.gist, null, 2),
|
||||
Prism.languages.javascript,
|
||||
"javascript"
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="fs-sa">
|
||||
<section>
|
||||
<h2>
|
||||
<FormattedMessage id="app.pattern" />
|
||||
</h2>
|
||||
<Draft {...pattern.getRenderProps()} />
|
||||
<Draft
|
||||
{...patternProps}
|
||||
design={design}
|
||||
focus={focus}
|
||||
raiseEvent={raiseEvent}
|
||||
/>
|
||||
<h2>gist</h2>
|
||||
<pre>{JSON.stringify(props.gist, null, 2)}</pre>
|
||||
<div className="gatsby-highlight" dataLanguage="json">
|
||||
<pre
|
||||
className="language-json"
|
||||
dangerouslySetInnerHTML={{ __html: gist }}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside>
|
||||
<div className="sticky">
|
||||
{design ? (
|
||||
<React.Fragment>
|
||||
<p style={styles.paragraph}>
|
||||
<FormattedMessage id="cfp.designModeIsOn" />
|
||||
(
|
||||
<a href="#logo" onClick={() => setDesign(false)}>
|
||||
<FormattedMessage id="cfp.turnOff" />
|
||||
</a>
|
||||
)
|
||||
{focusCount > 0 ? (
|
||||
<React.Fragment>
|
||||
 (
|
||||
<a
|
||||
href="#logo"
|
||||
onClick={() => raiseEvent("clearFocusAll", null)}
|
||||
>
|
||||
<FormattedMessage id="app.reset" />
|
||||
</a>
|
||||
)
|
||||
</React.Fragment>
|
||||
) : null}
|
||||
</p>
|
||||
<Design
|
||||
focus={focus}
|
||||
design={design}
|
||||
raiseEvent={raiseEvent}
|
||||
parts={patternProps.parts}
|
||||
/>
|
||||
</React.Fragment>
|
||||
) : (
|
||||
<p style={styles.paragraph}>
|
||||
<FormattedMessage id="cfp.designModeIsOff" />
|
||||
(
|
||||
<a href="#logo" onClick={() => setDesign(true)}>
|
||||
<FormattedMessage id="cfp.turnOn" />
|
||||
</a>
|
||||
)
|
||||
</p>
|
||||
)}
|
||||
<DraftConfigurator
|
||||
config={props.config}
|
||||
gist={props.gist}
|
||||
|
|
|
@ -82,9 +82,7 @@ const Workbench = props => {
|
|||
if (theme === "light") setTheme("dark");
|
||||
else setTheme("light");
|
||||
};
|
||||
const raiseEvent = (type = null, data = null) => {
|
||||
console.log("FIXME: Event raised", type, data);
|
||||
};
|
||||
const raiseEvent = (type = null, data = null) => {};
|
||||
|
||||
const navs = {
|
||||
left: {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plugins": [
|
||||
["prismjs", {
|
||||
"languages": ["javascript", "css", "markup"],
|
||||
"plugins": ["line-numbers"],
|
||||
"theme": "twilight",
|
||||
"css": true
|
||||
}]
|
||||
]
|
||||
}
|
55
packages/create-freesewing-pattern/template/default/example/package-lock.json
generated
Normal file
55
packages/create-freesewing-pattern/template/default/example/package-lock.json
generated
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"name": "{{name}}-example",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"babel-plugin-prismjs": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-prismjs/-/babel-plugin-prismjs-1.0.2.tgz",
|
||||
"integrity": "sha512-WbUE86Aih6h6daLpyavuikEXECrkon21oWh4MOHa5stMfY/IK1e/Sr79qEGhl7KrL16fMChB3tdbVR82ubnzOg==",
|
||||
"dev": true
|
||||
},
|
||||
"clipboard": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
|
||||
"integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
|
||||
"requires": {
|
||||
"good-listener": "^1.2.2",
|
||||
"select": "^1.1.2",
|
||||
"tiny-emitter": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"delegate": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
|
||||
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
|
||||
},
|
||||
"good-listener": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
|
||||
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
|
||||
"requires": {
|
||||
"delegate": "^3.1.2"
|
||||
}
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.16.0.tgz",
|
||||
"integrity": "sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==",
|
||||
"requires": {
|
||||
"clipboard": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,29 +4,30 @@
|
|||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"react": "^16.8",
|
||||
"react-dom": "^16.8",
|
||||
"react-scripts": "^3.0.0",
|
||||
"@freesewing/core": "alpha",
|
||||
"@freesewing/plugin-debug": "alpha",
|
||||
"@freesewing/plugin-theme": "alpha",
|
||||
"@freesewing/plugin-designer": "alpha",
|
||||
"@freesewing/plugin-svgattr": "alpha",
|
||||
"@freesewing/plugin-i18n": "alpha",
|
||||
"@freesewing/plugin-validate": "alpha",
|
||||
"@freesewing/plugin-react": "alpha",
|
||||
"@freesewing/i18n": "alpha",
|
||||
"@freesewing/utils": "alpha",
|
||||
"@freesewing/models": "alpha",
|
||||
"@freesewing/components": "alpha",
|
||||
"@freesewing/core": "alpha",
|
||||
"@freesewing/css-theme": "alpha",
|
||||
"@freesewing/i18n": "alpha",
|
||||
"@freesewing/models": "alpha",
|
||||
"@freesewing/mui-theme": "alpha",
|
||||
"@freesewing/pattern-info": "alpha",
|
||||
"@freesewing/plugin-debug": "alpha",
|
||||
"@freesewing/plugin-designer": "alpha",
|
||||
"@freesewing/plugin-i18n": "alpha",
|
||||
"@freesewing/plugin-react": "alpha",
|
||||
"@freesewing/plugin-svgattr": "alpha",
|
||||
"@freesewing/plugin-theme": "alpha",
|
||||
"@freesewing/plugin-validate": "alpha",
|
||||
"@freesewing/utils": "alpha",
|
||||
"@material-ui/core": "^3.9.3",
|
||||
"@material-ui/icons": "^3.0.2",
|
||||
"@material-ui/lab": "^3.0.0-alpha.30",
|
||||
"typeface-roboto-condensed": "latest",
|
||||
"pattern": "{{#if yarn}}link:..{{else}}file:..{{/if}}"
|
||||
"pattern": "{{#if yarn}}link:..{{else}}file:..{{/if}}",
|
||||
"prismjs": "1.16.0",
|
||||
"react": "^16.8",
|
||||
"react-dom": "^16.8",
|
||||
"react-scripts": "^3.0.0",
|
||||
"typeface-roboto-condensed": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
@ -42,5 +43,8 @@
|
|||
"not dead",
|
||||
"not ie <= 11",
|
||||
"not op_mini all"
|
||||
]
|
||||
],
|
||||
"devDependencies": {
|
||||
"babel-plugin-prismjs": "1.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
@import "components/navbar";
|
||||
@import "components/draft";
|
||||
@import "components/draft-configurator";
|
||||
@import "components/draft-design";
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
@import "elements/a";
|
||||
@import "elements/footer";
|
||||
@import "elements/ul";
|
||||
@import "elements/code";
|
||||
|
|
147
packages/css-theme/src/_prism.css
Normal file
147
packages/css-theme/src/_prism.css
Normal file
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* atom-dark theme for `prism.js`
|
||||
* Based on Atom's `atom-dark` theme: https://github.com/atom/atom-dark-syntax
|
||||
* @author Joe Gibson (@gibsjose)
|
||||
*/
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: #c5c8c6;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
|
||||
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #1d1f21;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: #7C7C7C;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #c5c8c6;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.keyword,
|
||||
.token.tag {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.token.class-name {
|
||||
color: #FFFFB6;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.constant {
|
||||
color: #99CC99;
|
||||
}
|
||||
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #f92672;
|
||||
}
|
||||
|
||||
.token.number {
|
||||
color: #FF73FD;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #A8FF60;
|
||||
}
|
||||
|
||||
.token.variable {
|
||||
color: #C6C5FE;
|
||||
}
|
||||
|
||||
.token.operator {
|
||||
color: #EDEDED;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
color: #FFFFB6;
|
||||
/* text-decoration: underline; */
|
||||
}
|
||||
|
||||
.token.url {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #87C38A;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value {
|
||||
color: #F9EE98;
|
||||
}
|
||||
|
||||
.token.function {
|
||||
color: #DAD085;
|
||||
}
|
||||
|
||||
.token.regex {
|
||||
color: #E9C062;
|
||||
}
|
||||
|
||||
.token.important {
|
||||
color: #fd971f;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
|
129
packages/css-theme/src/components/_draft-design.scss
Normal file
129
packages/css-theme/src/components/_draft-design.scss
Normal file
|
@ -0,0 +1,129 @@
|
|||
svg.freesewing.draft {
|
||||
g.design.point {
|
||||
circle {
|
||||
stroke: none;
|
||||
fill-opacity: 0.5;
|
||||
}
|
||||
circle.hovertrap {
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s ease-in;
|
||||
}
|
||||
circle.hovertrap:hover {
|
||||
cursor: pointer;
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
path.design.hovertrap {
|
||||
stroke-width: 5;
|
||||
stroke-opacity: 0;
|
||||
transition: stroke-opacity 0.1s ease-in;
|
||||
}
|
||||
path.design.hovertrap:hover {
|
||||
cursor: pointer;
|
||||
stroke-opacity: 0.2;
|
||||
}
|
||||
path.focus.point,
|
||||
path.focus.coords {
|
||||
stroke-width: 0.2;
|
||||
stroke: $oc-red-6;
|
||||
}
|
||||
circle.focus.point,
|
||||
circle.focus.coords {
|
||||
fill: white;
|
||||
fill-opacity: 0.01;
|
||||
stroke: $oc-red-6;
|
||||
stroke-width: 0.2;
|
||||
}
|
||||
circle.focus.point:hover,
|
||||
circle.focus.coords:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
path.focus.path {
|
||||
stroke-width: 5;
|
||||
stroke-opacity: 0.3;
|
||||
stroke-dasharray: 4 5.5;
|
||||
}
|
||||
path.focus.path:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
path.focus.point.c0,
|
||||
circle.focus.point.c0,
|
||||
path.focus.coords.c0,
|
||||
circle.focus.coords.c0 {
|
||||
stroke: $oc-red-6;
|
||||
}
|
||||
path.focus.point.c1,
|
||||
circle.focus.point.c1,
|
||||
path.focus.coords.c1,
|
||||
circle.focus.coords.c01{
|
||||
stroke: $oc-green-6;
|
||||
}
|
||||
path.focus.point.c2,
|
||||
circle.focus.point.c2,
|
||||
path.focus.coords.c2,
|
||||
circle.focus.coords.c02{
|
||||
stroke: $oc-blue-6;
|
||||
}
|
||||
path.focus.point.c3,
|
||||
circle.focus.point.c3,
|
||||
path.focus.coords.c3,
|
||||
circle.focus.coords.c03{
|
||||
stroke: $oc-grape-6;
|
||||
}
|
||||
path.focus.coords,
|
||||
circle.focus.coords {
|
||||
stroke-dasharray: 3 3;
|
||||
}
|
||||
path.design.path.cp {
|
||||
stroke: $oc-orange-5;
|
||||
stroke-width: 0.5;
|
||||
}
|
||||
circle.design.path.cp {
|
||||
stroke: $oc-orange-5;
|
||||
stroke-width: 1;
|
||||
}
|
||||
path.focus.path.c0 { stroke: $oc-red-6 }
|
||||
path.focus.path.c1 { stroke: $oc-green-6 }
|
||||
path.focus.path.c2 { stroke: $oc-blue-6 }
|
||||
path.focus.path.c3 { stroke: $oc-grape-6 }
|
||||
}
|
||||
|
||||
div.design {
|
||||
h4.point.c0 { border-bottom: 1px solid $oc-red-6; }
|
||||
h4.point.c1 { border-bottom: 1px solid $oc-green-6; }
|
||||
h4.point.c2 { border-bottom: 1px solid $oc-blue-6; }
|
||||
h4.point.c3 { border-bottom: 1px solid $oc-grape-6; }
|
||||
}
|
||||
|
||||
.theme-wrapper.light svg.freesewing.draft {
|
||||
g.design.point {
|
||||
circle { fill: $fc-link-light; }
|
||||
circle.hovertrap { stroke: $fc-link-light; }
|
||||
}
|
||||
path.design.hovertrap { stroke: $fc-link-light; }
|
||||
circle.design.path.cp { fill: $fc-bg-light; }
|
||||
}
|
||||
|
||||
.theme-wrapper.light div.design {
|
||||
h4.path.c0 { background-color: rgba($oc-red-6, 0.3) }
|
||||
h4.path.c1 { background-color: rgba($oc-green-6, 0.3) }
|
||||
h4.path.c2 { background-color: rgba($oc-blue-6, 0.3) }
|
||||
h4.path.c3 { background-color: rgba($oc-grape-6, 0.3) }
|
||||
}
|
||||
|
||||
.theme-wrapper.dark svg.freesewing.draft {
|
||||
g.design.point {
|
||||
circle { fill: $fc-link-dark; }
|
||||
circle.hovertrap { stroke: $fc-link-dark; }
|
||||
}
|
||||
path.design.hovertrap { stroke: $fc-link-dark; }
|
||||
circle.design.path.cp { fill: $fc-bg-dark; }
|
||||
path.focus.path { stroke-opacity: 0.5; }
|
||||
}
|
||||
|
||||
.theme-wrapper.dark div.design {
|
||||
h4.path.c0 { background-color: rgba($oc-red-6, 0.5) }
|
||||
h4.path.c1 { background-color: rgba($oc-green-6, 0.5) }
|
||||
h4.path.c2 { background-color: rgba($oc-blue-6, 0.5) }
|
||||
h4.path.c3 { background-color: rgba($oc-grape-6, 0.5) }
|
||||
}
|
54
packages/css-theme/src/elements/_code.scss
Normal file
54
packages/css-theme/src/elements/_code.scss
Normal file
|
@ -0,0 +1,54 @@
|
|||
.theme-wrapper.light :not(pre) > code[class*="language-"] {
|
||||
padding: 0.125rem 0.5rem;
|
||||
background: $oc-gray-6;
|
||||
border: 1px $oc-gray-5 solid;
|
||||
color: $oc-gray-9;
|
||||
}
|
||||
.theme-wrapper.dark :not(pre) > code[class*="language-"] {
|
||||
padding: 0.125rem 0.5rem;
|
||||
background: $oc-gray-6;
|
||||
border: 1px $oc-gray-5 solid;
|
||||
color: $oc-gray-9;
|
||||
}
|
||||
|
||||
div.gatsby-highlight {
|
||||
position: relative;
|
||||
}
|
||||
div.gatsby-highlight pre.language-js {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
pre.language-js:before,
|
||||
pre.language-json:before,
|
||||
pre.language-svg:before,
|
||||
pre.language-bash:before {
|
||||
border-top: 2px dashed $oc-gray-9;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 20px;
|
||||
color: black;
|
||||
padding: 1px 4px;
|
||||
border-bottom-right-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
font-weight: bold;
|
||||
text-shadow: none;
|
||||
}
|
||||
pre.language-js:before {
|
||||
content: "js";
|
||||
background: rgba(255, 255, 0, 0.9);
|
||||
}
|
||||
pre.language-json:before {
|
||||
content: "json";
|
||||
background: rgba(255, 255, 0, 0.9);
|
||||
}
|
||||
pre.language-bash:before {
|
||||
content: "bash";
|
||||
background: rgba(29, 227, 0, 0.9);
|
||||
}
|
||||
pre.language-svg:before {
|
||||
content: "svg";
|
||||
background: rgba(129, 197, 255, 0.9);
|
||||
}
|
||||
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
@import '../../../node_modules/open-color/open-color.scss';
|
||||
@import "variables";
|
||||
@import "mixins";
|
||||
@import "prism";
|
||||
@import "theme-wrapper";
|
||||
@import "layout";
|
||||
@import "scroll";
|
||||
|
|
|
@ -21,4 +21,8 @@ size: Größe
|
|||
noRequiredMeasurements: Dieses Muster hat keine erforderlichen Messungen.
|
||||
howtoAddMeasurements: Um Messungen anzufordern, fügen Sie sie dem <b>measurements</b> der Konfigurationsdatei des Musters hinzu.
|
||||
seeDocsAt: Dokumentation zu diesem Thema finden Sie unter
|
||||
designModeIsOn: Der Designmodus ist aktiviert
|
||||
designModeIsOff: Entwurfsmodus ist deaktiviert
|
||||
turnOn: Aktivieren
|
||||
turnOff: Deaktivieren
|
||||
|
||||
|
|
|
@ -20,3 +20,7 @@ size: Size
|
|||
noRequiredMeasurements: This pattern has no required measurements
|
||||
howtoAddMeasurements: To require measurements, add them to the <b>measurements</b> section of the pattern's configuration file.
|
||||
seeDocsAt: Documentation on this topic is available at
|
||||
designModeIsOn: Design mode is on
|
||||
designModeIsOff: Design mode is off
|
||||
turnOn: Turn on
|
||||
turnOff: Turn off
|
||||
|
|
|
@ -21,3 +21,8 @@ size: Tamaño
|
|||
noRequiredMeasurements: Este patrón no tiene medidas requeridas.
|
||||
howtoAddMeasurements: Para requerir mediciones, agréguelas a la sección de <b>measurements</b> del archivo de configuración del patrón.
|
||||
seeDocsAt: La documentación sobre este tema está disponible en
|
||||
designModeIsOn: El modo de diseño está activado
|
||||
designModeIsOff: El modo de diseño esta apagado
|
||||
turnOn: Encender
|
||||
turnOff: Apagar
|
||||
|
||||
|
|
|
@ -21,3 +21,8 @@ size: Taille
|
|||
noRequiredMeasurements: Ce patron n'a pas de mesures requises.
|
||||
howtoAddMeasurements: Pour exiger des mesures, ajoutez-les à la section <b>measurements</b> du fichier de configuration du patron.
|
||||
seeDocsAt: Documentation sur ce sujet est disponible à l'adresse
|
||||
designModeIsOn: Le mode de conception est activé
|
||||
designModeIsOff: Le mode de conception est désactivé
|
||||
turnOn: Activer
|
||||
turnOff: Désactiver
|
||||
|
||||
|
|
|
@ -21,3 +21,8 @@ size: Maat
|
|||
noRequiredMeasurements: Dit patroon vereist geen lichaamsmaten.
|
||||
howtoAddMeasurements: Om lichaamsmaten te vereisen, voegt u ze toe aan de <b>measurements</b> sectie van het configuratiebestand van het patroon.
|
||||
seeDocsAt: Documentatie over dit onderwerp is beschikbaar op
|
||||
designModeIsOn: Ontwerpmodus is ingeschakeld
|
||||
designModeIsOff: Ontwerpmodus is uitgeschakeld
|
||||
turnOn: Inschakelen
|
||||
turnOff: Uitschakelen
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue