🚧 Progress on React components
This commit is contained in:
parent
ea87274eb2
commit
d8cc1f76f3
59 changed files with 341 additions and 260 deletions
|
@ -1,89 +0,0 @@
|
||||||
import React, { useState } from "react";
|
|
||||||
import PropTypes from "prop-types";
|
|
||||||
import { gistDefaults } from "../utils";
|
|
||||||
import { patternInfo, patternList } from "@freesewing/patterns";
|
|
||||||
import { FormattedMessage } from "react-intl";
|
|
||||||
import List from "@material-ui/core/List";
|
|
||||||
import DraftSettingSa from "../DraftSettingSa";
|
|
||||||
import DraftSettingMargin from "../DraftSettingMargin";
|
|
||||||
import DraftSettingComplete from "../DraftSettingComplete";
|
|
||||||
import DraftSettingPaperless from "../DraftSettingPaperless";
|
|
||||||
import DraftSettingUnits from "../DraftSettingUnits";
|
|
||||||
import DraftSettingLanguage from "../DraftSettingLanguage";
|
|
||||||
import DraftSettingOnly from "../DraftSettingOnly";
|
|
||||||
import DownIcon from "@material-ui/icons/KeyboardArrowDown";
|
|
||||||
|
|
||||||
const DraftActions = props => {
|
|
||||||
const [expanded, setExpanded] = useState([]);
|
|
||||||
|
|
||||||
const toggleGroup = group => {
|
|
||||||
let shown = expanded.slice(0);
|
|
||||||
let index = shown.indexOf(group);
|
|
||||||
if (index === -1) shown.push(group);
|
|
||||||
else shown.splice(index, 1);
|
|
||||||
setExpanded(shown);
|
|
||||||
};
|
|
||||||
|
|
||||||
let paperSizes = ["A4", "Letter", "A3", "Tabloid", "A2", "A1", "A0"];
|
|
||||||
let groups = {
|
|
||||||
saveDraft: [
|
|
||||||
<li>
|
|
||||||
<FormattedMessage id="app.saveDraftToYourAccount" />
|
|
||||||
</li>,
|
|
||||||
<li>
|
|
||||||
<FormattedMessage id="app.saveGistAsJSON" />
|
|
||||||
</li>,
|
|
||||||
<li>
|
|
||||||
<FormattedMessage id="app.saveGistAsYAML" />
|
|
||||||
</li>,
|
|
||||||
<li>
|
|
||||||
<FormattedMessage id="app.saveSvg" />
|
|
||||||
</li>
|
|
||||||
],
|
|
||||||
exportDraft: [
|
|
||||||
<li>
|
|
||||||
<FormattedMessage id="app.exportDraft" />: PDF
|
|
||||||
</li>,
|
|
||||||
paperSizes.map(size => (
|
|
||||||
<li>
|
|
||||||
<FormattedMessage id="app.exportTiledPdf" />: {size}
|
|
||||||
</li>
|
|
||||||
))
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ul className="nav l2">
|
|
||||||
{Object.keys(groups).map(group => {
|
|
||||||
let open = true;
|
|
||||||
if (expanded.indexOf(group) === -1) open = false;
|
|
||||||
let children = null;
|
|
||||||
if (open) children = groups[group].map(component => component);
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
<li
|
|
||||||
className={open ? "expanded" : "collapsed"}
|
|
||||||
key={group + "-ghead"}
|
|
||||||
>
|
|
||||||
<h3 onClick={() => toggleGroup(group)}>
|
|
||||||
<DownIcon
|
|
||||||
className={
|
|
||||||
"icon-col-exp " + (open ? "expanded" : "collapsed")
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<FormattedMessage id={"app." + group} />
|
|
||||||
</h3>
|
|
||||||
</li>
|
|
||||||
{children}
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
DraftActions.propTypes = {};
|
|
||||||
|
|
||||||
DraftActions.defaultProps = {};
|
|
||||||
|
|
||||||
export default DraftActions;
|
|
|
@ -14,6 +14,6 @@ const props = {
|
||||||
labels: ["No", "Yes"]
|
labels: ["No", "Yes"]
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftSettingComplete", module).add("Basic", () => (
|
storiesOf("Low level/DraftSettingComplete", module).add("Basic", () => (
|
||||||
<Complete {...props} />
|
<Complete {...props} />
|
||||||
));
|
));
|
|
@ -1,10 +1,12 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import FormFieldList from "../FormFieldList";
|
import FormFieldList from "../../form/FormFieldList";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
import { injectIntl } from "react-intl";
|
||||||
|
import { i18n as languages } from "@freesewing/i18n";
|
||||||
|
|
||||||
const DraftSettingLanguage = props => {
|
const DraftSettingLanguage = props => {
|
||||||
const [value, setValue] = useState(props.dflt);
|
const [value, setValue] = useState(props.intl.locale);
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
|
||||||
const update = (name, newValue, evt) => {
|
const update = (name, newValue, evt) => {
|
||||||
|
@ -13,33 +15,32 @@ const DraftSettingLanguage = props => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
setValue(props.dflt);
|
setValue(props.intl.locale);
|
||||||
props.updateValue(props.name, props.dflt);
|
props.updateValue(props.name, props.intl.locale);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleExpanded = () => setExpanded(!expanded);
|
const toggleExpanded = () => setExpanded(!expanded);
|
||||||
|
|
||||||
const option = (
|
const option = (
|
||||||
<FormFieldList
|
<FormFieldList
|
||||||
name={props.name}
|
name={props.name}
|
||||||
value={value}
|
value={value}
|
||||||
dflt={props.dflt}
|
dflt={props.intl.locale}
|
||||||
onChange={update}
|
onChange={update}
|
||||||
label={"po-list-" + props.name}
|
label={"po-list-" + props.name}
|
||||||
updateValue={update}
|
updateValue={update}
|
||||||
list={props.languages}
|
list={languages[props.intl.locale]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<OptionPreamble
|
<OptionPreamble
|
||||||
dflt={props.dflt}
|
dflt={props.intl.locale}
|
||||||
value={value}
|
value={value}
|
||||||
desc={props.desc}
|
desc={props.desc}
|
||||||
title={props.title}
|
title={props.title}
|
||||||
id={"po-list-" + props.name}
|
id={"po-list-" + props.name}
|
||||||
displayValue={props.languages[value]}
|
displayValue={languages[props.intl.locale][value]}
|
||||||
reset={reset}
|
reset={reset}
|
||||||
toggleExpanded={toggleExpanded}
|
toggleExpanded={toggleExpanded}
|
||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
|
@ -59,13 +60,9 @@ DraftSettingLanguage.propTypes = {
|
||||||
triggerAction: PropTypes.func.isRequired,
|
triggerAction: PropTypes.func.isRequired,
|
||||||
updateValue: PropTypes.func.isRequired,
|
updateValue: PropTypes.func.isRequired,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
dflt: PropTypes.oneOfType([
|
|
||||||
PropTypes.number.isRequired,
|
|
||||||
PropTypes.string.isRequired
|
|
||||||
]),
|
|
||||||
title: PropTypes.node.isRequired,
|
title: PropTypes.node.isRequired,
|
||||||
desc: PropTypes.node.isRequired,
|
desc: PropTypes.node.isRequired,
|
||||||
list: PropTypes.object.isRequired
|
list: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DraftSettingLanguage;
|
export default injectIntl(DraftSettingLanguage);
|
|
@ -22,6 +22,6 @@ const props = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftSettingLanguage", module).add("Basic", () => (
|
storiesOf("Low level/DraftSettingLanguage", module).add("Basic", () => (
|
||||||
<Lang {...props} />
|
<Lang {...props} />
|
||||||
));
|
));
|
|
@ -1,12 +1,13 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import FormFieldList from "../FormFieldList";
|
import FormFieldList from "../../form/FormFieldList";
|
||||||
import FormFieldSlider from "../FormFieldSlider";
|
import FormFieldSlider from "../../form/FormFieldSlider";
|
||||||
import { formatMm, roundMm, defaultSa, sliderStep } from "../utils";
|
import { formatMm, roundMm, defaultSa, sliderStep } from "../../utils";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const DraftSettingMargin = props => {
|
const DraftSettingMargin = props => {
|
||||||
const [value, setValue] = useState(props.dflt);
|
const [value, setValue] = useState(props.dflt);
|
||||||
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
|
||||||
const update = (name, newValue, evt) => {
|
const update = (name, newValue, evt) => {
|
||||||
newValue = roundMm(newValue);
|
newValue = roundMm(newValue);
|
||||||
|
@ -27,23 +28,9 @@ const DraftSettingMargin = props => {
|
||||||
props.updateValue("margin", props.dflt);
|
props.updateValue("margin", props.dflt);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const toggleExpanded = () => setExpanded(!expanded);
|
||||||
<div className={"pattern-option list"}>
|
|
||||||
<OptionPreamble
|
let option = (
|
||||||
dflt={props.dflt}
|
|
||||||
value={value}
|
|
||||||
desc={props.desc}
|
|
||||||
title={props.title}
|
|
||||||
id="po-slider-margin"
|
|
||||||
displayValue={formatMm(value, props.units)}
|
|
||||||
reset={reset}
|
|
||||||
showHelp={() =>
|
|
||||||
props.triggerAction("showHelp", {
|
|
||||||
type: "draftSetting",
|
|
||||||
value: "margin"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<FormFieldSlider
|
<FormFieldSlider
|
||||||
name="customSa"
|
name="customSa"
|
||||||
value={value}
|
value={value}
|
||||||
|
@ -54,7 +41,29 @@ const DraftSettingMargin = props => {
|
||||||
max={25.4}
|
max={25.4}
|
||||||
step={sliderStep[props.units]}
|
step={sliderStep[props.units]}
|
||||||
/>
|
/>
|
||||||
</div>
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li>
|
||||||
|
<OptionPreamble
|
||||||
|
dflt={props.dflt}
|
||||||
|
value={value}
|
||||||
|
desc={props.desc}
|
||||||
|
title={props.title}
|
||||||
|
id="po-slider-margin"
|
||||||
|
displayValue={formatMm(value, props.units)}
|
||||||
|
reset={reset}
|
||||||
|
toggleExpanded={toggleExpanded}
|
||||||
|
expanded={expanded}
|
||||||
|
showHelp={() =>
|
||||||
|
props.triggerAction("showHelp", {
|
||||||
|
type: "draftSetting",
|
||||||
|
value: "margin"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
option={option}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,6 @@ const props = {
|
||||||
"This is the margin description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
"This is the margin description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftSettingMargin", module)
|
storiesOf("Low level/DraftSettingMargin", module)
|
||||||
.add("Metric", () => <Margin {...props} units="metric" />)
|
.add("Metric", () => <Margin {...props} units="metric" />)
|
||||||
.add("Imperial", () => <Margin {...props} units="imperial" />);
|
.add("Imperial", () => <Margin {...props} units="imperial" />);
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import FormFieldChecks from "../FormFieldChecks";
|
import FormFieldChecks from "../../form/FormFieldChecks";
|
||||||
import FormFieldList from "../FormFieldList";
|
import FormFieldList from "../../form/FormFieldList";
|
||||||
import FormFieldSlider from "../FormFieldSlider";
|
import FormFieldSlider from "../../form/FormFieldSlider";
|
||||||
import { formatMm, roundMm, defaultSa, sliderStep } from "../utils";
|
import { formatMm, roundMm, defaultSa, sliderStep } from "../../utils";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const DraftSettingOnly = props => {
|
const DraftSettingOnly = props => {
|
|
@ -24,7 +24,7 @@ const props = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftSettingOnly", module)
|
storiesOf("Low level/DraftSettingOnly", module)
|
||||||
.add("Default", () => <Sa {...props} />)
|
.add("Default", () => <Sa {...props} />)
|
||||||
.add("Default, all parts preselected", () => (
|
.add("Default, all parts preselected", () => (
|
||||||
<Sa {...props} customDflt={Object.keys(props.parts)} />
|
<Sa {...props} customDflt={Object.keys(props.parts)} />
|
|
@ -15,6 +15,6 @@ const props = {
|
||||||
labels: ["No", "Yes"]
|
labels: ["No", "Yes"]
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftSettingPaperless", module).add("Basic", () => (
|
storiesOf("Low level/DraftSettingPaperless", module).add("Basic", () => (
|
||||||
<Paperless {...props} />
|
<Paperless {...props} />
|
||||||
));
|
));
|
|
@ -1,8 +1,8 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import FormFieldList from "../FormFieldList";
|
import FormFieldList from "../../form/FormFieldList";
|
||||||
import FormFieldSlider from "../FormFieldSlider";
|
import FormFieldSlider from "../../form/FormFieldSlider";
|
||||||
import { formatMm, roundMm, defaultSa, sliderStep } from "../utils";
|
import { formatMm, roundMm, defaultSa, sliderStep } from "../../utils";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const DraftSettingSa = props => {
|
const DraftSettingSa = props => {
|
|
@ -19,6 +19,6 @@ const props = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftSettingSa", module)
|
storiesOf("Low level/DraftSettingSa", module)
|
||||||
.add("Metric", () => <Sa {...props} units="metric" />)
|
.add("Metric", () => <Sa {...props} units="metric" />)
|
||||||
.add("Imperial", () => <Sa {...props} units="imperial" />);
|
.add("Imperial", () => <Sa {...props} units="imperial" />);
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import FormFieldList from "../FormFieldList";
|
import FormFieldList from "../../form/FormFieldList";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const DraftSettingUnits = props => {
|
const DraftSettingUnits = props => {
|
|
@ -18,4 +18,4 @@ const props = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftSettingUnits", module).add("Basic", () => <Units {...props} />);
|
storiesOf("Low level/DraftSettingUnits", module).add("Basic", () => <Units {...props} />);
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { gistDefaults } from "../utils";
|
import { gistDefaults } from "../../utils";
|
||||||
import { patternInfo, patternList } from "@freesewing/patterns";
|
import { patternInfo, patternList } from "@freesewing/patterns";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import List from "@material-ui/core/List";
|
import List from "@material-ui/core/List";
|
||||||
|
@ -89,11 +89,7 @@ const DraftSettings = props => {
|
||||||
dflt={props.units}
|
dflt={props.units}
|
||||||
list={units}
|
list={units}
|
||||||
/>,
|
/>,
|
||||||
<DraftSettingLanguage
|
<DraftSettingLanguage {...addProps("locale")} />
|
||||||
{...addProps("locale")}
|
|
||||||
dflt={props.language}
|
|
||||||
languages={props.languages}
|
|
||||||
/>
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,7 @@ const props = {
|
||||||
language: "en"
|
language: "en"
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("DraftActions", module)
|
storiesOf("Low level/DraftSettings", module)
|
||||||
.add("Simon metric", () => (
|
.add("Simon metric", () => (
|
||||||
<DraftSettings pattern="simon" gist={false} units="metric" {...props} />
|
<DraftSettings pattern="simon" gist={false} units="metric" {...props} />
|
||||||
))
|
))
|
|
@ -6,12 +6,11 @@ import Mm from "../PatternOptionMillimeter";
|
||||||
import Bool from "../PatternOptionBool";
|
import Bool from "../PatternOptionBool";
|
||||||
import List from "../PatternOptionList";
|
import List from "../PatternOptionList";
|
||||||
import Count from "../PatternOptionCount";
|
import Count from "../PatternOptionCount";
|
||||||
import { optionType } from "../utils";
|
import { optionType } from "../../utils";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { injectIntl } from "react-intl";
|
import { injectIntl } from "react-intl";
|
||||||
|
|
||||||
const OptionGroup = props => {
|
const OptionGroup = props => {
|
||||||
const update = (name, value) => props.updateValue("option", name, value);
|
|
||||||
|
|
||||||
const renderOption = (name, sub=false) => {
|
const renderOption = (name, sub=false) => {
|
||||||
let option = props.pattern.config.options[name];
|
let option = props.pattern.config.options[name];
|
||||||
|
@ -21,7 +20,7 @@ const OptionGroup = props => {
|
||||||
name,
|
name,
|
||||||
dflt: props.dflts.options[name],
|
dflt: props.dflts.options[name],
|
||||||
units: props.units,
|
units: props.units,
|
||||||
updateValue: update,
|
updateValue: props.updateValue,
|
||||||
triggerAction: props.triggerAction,
|
triggerAction: props.triggerAction,
|
||||||
title: <FormattedMessage id={stringKey + "title"} />,
|
title: <FormattedMessage id={stringKey + "title"} />,
|
||||||
desc: <FormattedMessage id={stringKey + "description"} />,
|
desc: <FormattedMessage id={stringKey + "description"} />,
|
|
@ -35,6 +35,6 @@ const props = {
|
||||||
options: Object.keys(options)
|
options: Object.keys(options)
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("OptionGroup", module).add("Simon metric", () => (
|
storiesOf("Low level/OptionGroup", module).add("Simon metric", () => (
|
||||||
<OptionGroup pattern="simon" {...props} units="metric" />
|
<OptionGroup pattern="simon" {...props} units="metric" />
|
||||||
));
|
));
|
|
@ -15,6 +15,6 @@ const props = {
|
||||||
"This is the description. I'm wrapped in a p tag. This component is used within other components, and not very useful on its own."
|
"This is the description. I'm wrapped in a p tag. This component is used within other components, and not very useful on its own."
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("OptionPreamble", module).add("Preamble", () => (
|
storiesOf("Low level/OptionPreamble", module).add("Preamble", () => (
|
||||||
<Preamble {...props} />
|
<Preamble {...props} />
|
||||||
));
|
));
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import FormFieldBool from "../FormFieldBool";
|
import FormFieldBool from "../../form/FormFieldBool";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const PatternOptionBool = props => {
|
const PatternOptionBool = props => {
|
|
@ -16,6 +16,6 @@ const props = {
|
||||||
labels: ["No", "Yes"]
|
labels: ["No", "Yes"]
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("PatternOptionBool", module)
|
storiesOf("Low level/PatternOptionBool", module)
|
||||||
.add("Basic", () => <Bool {...props} />)
|
.add("Basic", () => <Bool {...props} />)
|
||||||
.add("Yes as default", () => <Bool {...props} dflt={true} />);
|
.add("Yes as default", () => <Bool {...props} dflt={true} />);
|
|
@ -15,7 +15,7 @@ const props = {
|
||||||
"This is the description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
"This is the description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("PatternOptionCount", module)
|
storiesOf("Low level/PatternOptionCount", module)
|
||||||
.add("Basic", () => <Count {...props} />)
|
.add("Basic", () => <Count {...props} />)
|
||||||
.add("From 20 to 80", () => <Count {...props} min={20} max={80} />)
|
.add("From 20 to 80", () => <Count {...props} min={20} max={80} />)
|
||||||
.add("Step: 5", () => <Count {...props} step={5} />);
|
.add("Step: 5", () => <Count {...props} step={5} />);
|
|
@ -16,7 +16,7 @@ const props = {
|
||||||
"This is the description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
"This is the description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("PatternOptionDegree", module)
|
storiesOf("Low level/PatternOptionDegree", module)
|
||||||
.add("Basic", () => <Pct {...props} />)
|
.add("Basic", () => <Pct {...props} />)
|
||||||
.add("From 30 to 45", () => <Pct {...props} min={30} max={45} />)
|
.add("From 30 to 45", () => <Pct {...props} min={30} max={45} />)
|
||||||
.add("Step: 10", () => <Pct {...props} step={10} max={180} dflt={90} />);
|
.add("Step: 10", () => <Pct {...props} step={10} max={180} dflt={90} />);
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import FormFieldList from "../FormFieldList";
|
import FormFieldList from "../../form/FormFieldList";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const PatternOptionList = props => {
|
const PatternOptionList = props => {
|
|
@ -20,4 +20,4 @@ const props = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("PatternOptionList", module).add("Basic", () => <List {...props} />);
|
storiesOf("Low level/PatternOptionList", module).add("Basic", () => <List {...props} />);
|
|
@ -6,8 +6,8 @@ import {
|
||||||
roundMmUp,
|
roundMmUp,
|
||||||
roundMmDown,
|
roundMmDown,
|
||||||
formatMm
|
formatMm
|
||||||
} from "../utils";
|
} from "../../utils";
|
||||||
import FormFieldSlider from "../FormFieldSlider";
|
import FormFieldSlider from "../../form/FormFieldSlider";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const PatternOptionMillimeter = props => {
|
const PatternOptionMillimeter = props => {
|
|
@ -21,7 +21,7 @@ const maxNotOnStep =
|
||||||
const minNotOnStep =
|
const minNotOnStep =
|
||||||
"Since our step is 0.1mm and our min value is 24.06 mm, it falls in between two steps (24mm and 24.1mm). Picking the min value would result in the rounded min value of 24mm, which is outside our min boundary. So we always round the min value up to the closest step. Also note that while the displayed value rounds to mm, under the hood we use 1/10th of a mm and the actual value passed for the min here is not 2.4cm but 24.1mm (2.41cm)";
|
"Since our step is 0.1mm and our min value is 24.06 mm, it falls in between two steps (24mm and 24.1mm). Picking the min value would result in the rounded min value of 24mm, which is outside our min boundary. So we always round the min value up to the closest step. Also note that while the displayed value rounds to mm, under the hood we use 1/10th of a mm and the actual value passed for the min here is not 2.4cm but 24.1mm (2.41cm)";
|
||||||
|
|
||||||
storiesOf("PatternOptionMillimeter", module)
|
storiesOf("Low level/PatternOptionMillimeter", module)
|
||||||
.add("Metric", () => <Mm {...props} />)
|
.add("Metric", () => <Mm {...props} />)
|
||||||
.add("Max: 12.486 cm", () => (
|
.add("Max: 12.486 cm", () => (
|
||||||
<Mm {...props} max={124.86} desc={maxNotOnStep} />
|
<Mm {...props} max={124.86} desc={maxNotOnStep} />
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import FormFieldSlider from "../FormFieldSlider";
|
import FormFieldSlider from "../../form/FormFieldSlider";
|
||||||
import OptionPreamble from "../OptionPreamble";
|
import OptionPreamble from "../OptionPreamble";
|
||||||
|
|
||||||
const PatternOptionPctDegCount = props => {
|
const PatternOptionPctDegCount = props => {
|
|
@ -14,12 +14,12 @@ const props = {
|
||||||
"This is the description. I'm wrapped in a p tag. This component is the base for the percentage, degree, and count pattern options."
|
"This is the description. I'm wrapped in a p tag. This component is the base for the percentage, degree, and count pattern options."
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("PatternOptionPctDegCount", module).add("Percentage", () => (
|
storiesOf("Low level/PatternOptionPctDegCount", module).add("Percentage", () => (
|
||||||
<PctDegCount {...props} type="pct" />
|
<PctDegCount {...props} type="pct" />
|
||||||
));
|
));
|
||||||
storiesOf("PatternOptionPctDegCount", module).add("Degree", () => (
|
storiesOf("Low level/PatternOptionPctDegCount", module).add("Degree", () => (
|
||||||
<PctDegCount {...props} type="deg" />
|
<PctDegCount {...props} type="deg" />
|
||||||
));
|
));
|
||||||
storiesOf("PatternOptionPctDegCount", module).add("Count", () => (
|
storiesOf("Low level/PatternOptionPctDegCount", module).add("Count", () => (
|
||||||
<PctDegCount {...props} type="count" />
|
<PctDegCount {...props} type="count" />
|
||||||
));
|
));
|
|
@ -15,7 +15,7 @@ const props = {
|
||||||
"This is the description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
"This is the description. I'm wrapped in a p tag. This component only sets the CSS class on a non-default value. It's up to you to supply the CSS to style it."
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("PatternOptionPercentage", module)
|
storiesOf("Low level/PatternOptionPercentage", module)
|
||||||
.add("Basic", () => <Pct {...props} />)
|
.add("Basic", () => <Pct {...props} />)
|
||||||
.add("From 20 to 80", () => <Pct {...props} min={20} max={80} />)
|
.add("From 20 to 80", () => <Pct {...props} min={20} max={80} />)
|
||||||
.add("Step: 5", () => <Pct {...props} step={5} />);
|
.add("Step: 5", () => <Pct {...props} step={5} />);
|
|
@ -5,7 +5,7 @@ import Deg from "../PatternOptionDegree";
|
||||||
import Mm from "../PatternOptionMillimeter";
|
import Mm from "../PatternOptionMillimeter";
|
||||||
import Bool from "../PatternOptionBool";
|
import Bool from "../PatternOptionBool";
|
||||||
import OptionGroup from "../OptionGroup";
|
import OptionGroup from "../OptionGroup";
|
||||||
import { optionType, defaultGist, gistDefaults } from "../utils";
|
import { optionType, defaultGist, gistDefaults } from "../../utils";
|
||||||
import { patternInfo, patternList } from "@freesewing/patterns";
|
import { patternInfo, patternList } from "@freesewing/patterns";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import List from "@material-ui/core/List";
|
import List from "@material-ui/core/List";
|
|
@ -14,7 +14,7 @@ const props = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("PatternOptions", module)
|
storiesOf("Low level/PatternOptions", module)
|
||||||
.add("Simon metric", () => (
|
.add("Simon metric", () => (
|
||||||
<PatternOptions pattern="simon" gist={false} units="metric" {...props} />
|
<PatternOptions pattern="simon" gist={false} units="metric" {...props} />
|
||||||
))
|
))
|
|
@ -1,23 +1,22 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import Pct from "../PatternOptionPercentage";
|
import Pct from "./PatternOptionPercentage";
|
||||||
import Deg from "../PatternOptionDegree";
|
import Deg from "./PatternOptionDegree";
|
||||||
import Mm from "../PatternOptionMillimeter";
|
import Mm from "./PatternOptionMillimeter";
|
||||||
import Bool from "../PatternOptionBool";
|
import Bool from "./PatternOptionBool";
|
||||||
import OptionGroup from "../OptionGroup";
|
import OptionGroup from "./OptionGroup";
|
||||||
import { optionType, gistDefaults } from "../utils";
|
import { optionType, gistDefaults } from "../utils";
|
||||||
import { patternInfo, patternList } from "@freesewing/patterns";
|
import { patternInfo, patternList } from "@freesewing/patterns";
|
||||||
import { FormattedMessage, injectIntl } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { i18n as languages } from "@freesewing/i18n";
|
|
||||||
import CollapsedIcon from "@material-ui/icons/ArrowDropDown";
|
import CollapsedIcon from "@material-ui/icons/ArrowDropDown";
|
||||||
import ExpandedIcon from "@material-ui/icons/ArrowRight";
|
import ExpandedIcon from "@material-ui/icons/ArrowRight";
|
||||||
import PatternOptions from "../PatternOptions";
|
import PatternOptions from "./PatternOptions";
|
||||||
import DraftSettings from "../DraftSettings";
|
import DraftSettings from "./DraftSettings";
|
||||||
import DraftActions from "../DraftActions";
|
//import DraftActions from "DraftActions";
|
||||||
|
import withGist from "../withGist";
|
||||||
|
|
||||||
const GistConfigurator = props => {
|
const DraftConfigurator = props => {
|
||||||
console.log(languages);
|
const [gist, setGist] = useState(props.gist.get);
|
||||||
const [gist, setGist] = useState(props.gist);
|
|
||||||
const [expanded, setExpanded] = useState([]);
|
const [expanded, setExpanded] = useState([]);
|
||||||
|
|
||||||
const update = (type, name, value) => {
|
const update = (type, name, value) => {
|
||||||
|
@ -31,9 +30,8 @@ const GistConfigurator = props => {
|
||||||
else shown.splice(index, 1);
|
else shown.splice(index, 1);
|
||||||
setExpanded(shown);
|
setExpanded(shown);
|
||||||
};
|
};
|
||||||
|
|
||||||
let pattern = patternInfo[props.pattern];
|
let pattern = patternInfo[props.pattern];
|
||||||
let dflts = gistDefaults(pattern.config, props.gist);
|
let dflts = gistDefaults(pattern.config, props.gist.get);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ul className="nav l1">
|
<ul className="nav l1">
|
||||||
|
@ -44,7 +42,7 @@ const GistConfigurator = props => {
|
||||||
<PatternOptions
|
<PatternOptions
|
||||||
pattern={props.pattern}
|
pattern={props.pattern}
|
||||||
units={props.units}
|
units={props.units}
|
||||||
updateValue={update}
|
updateValue={(name, value) => props.gist.set(value, 'settings', 'options', name)}
|
||||||
triggerAction={props.triggerAction}
|
triggerAction={props.triggerAction}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
@ -55,27 +53,19 @@ const GistConfigurator = props => {
|
||||||
<DraftSettings
|
<DraftSettings
|
||||||
pattern={props.pattern}
|
pattern={props.pattern}
|
||||||
units={props.units}
|
units={props.units}
|
||||||
updateValue={update}
|
updateValue={(name, value) => props.gist.set(value, 'settings', name)}
|
||||||
triggerAction={props.triggerAction}
|
triggerAction={props.triggerAction}
|
||||||
language={props.intl.locale}
|
|
||||||
languages={languages[props.intl.locale]}
|
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<h2>
|
|
||||||
<FormattedMessage id="app.save" />
|
|
||||||
</h2>
|
|
||||||
<DraftActions />
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
GistConfigurator.propTypes = {
|
DraftConfigurator.propTypes = {
|
||||||
pattern: PropTypes.oneOf(patternList),
|
pattern: PropTypes.oneOf(patternList),
|
||||||
units: PropTypes.oneOf(["metric", "imperial"]).isRequired
|
units: PropTypes.oneOf(["metric", "imperial"]).isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
GistConfigurator.defaultProps = {};
|
DraftConfigurator.defaultProps = {};
|
||||||
|
|
||||||
export default injectIntl(GistConfigurator);
|
export default withGist(DraftConfigurator, {gist: {}, store: "yes"});
|
|
@ -9,14 +9,9 @@ const props = {
|
||||||
console.log(`Action of type ${type} triggered, data passed is`, data),
|
console.log(`Action of type ${type} triggered, data passed is`, data),
|
||||||
updateValue: (type, data) =>
|
updateValue: (type, data) =>
|
||||||
console.log(`Update ${type} with new value`, data),
|
console.log(`Update ${type} with new value`, data),
|
||||||
gist: {
|
|
||||||
settings: {
|
|
||||||
options: {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("GistConfigurator", module)
|
storiesOf("DraftConfigurator", module)
|
||||||
.add("Simon metric", () => (
|
.add("Simon metric", () => (
|
||||||
<GistConfigurator pattern="simon" {...props} units="metric" />
|
<GistConfigurator pattern="simon" {...props} units="metric" />
|
||||||
))
|
))
|
|
@ -1,31 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { storiesOf } from "@storybook/react";
|
|
||||||
import DraftSettings from ".";
|
|
||||||
|
|
||||||
const props = {
|
|
||||||
triggerAction: (type, data) =>
|
|
||||||
console.log(`Action of type ${type} triggered, data passed is`, data),
|
|
||||||
updateValue: (type, data) =>
|
|
||||||
console.log(`Update ${type} with new value`, data),
|
|
||||||
gist: {
|
|
||||||
settings: {
|
|
||||||
options: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
languages: {
|
|
||||||
de: "German",
|
|
||||||
en: "English",
|
|
||||||
es: "Spanish",
|
|
||||||
fr: "French",
|
|
||||||
nl: "Dutch"
|
|
||||||
},
|
|
||||||
language: "en"
|
|
||||||
};
|
|
||||||
|
|
||||||
storiesOf("DraftSettings", module)
|
|
||||||
.add("Simon metric", () => (
|
|
||||||
<DraftSettings pattern="simon" gist={false} units="metric" {...props} />
|
|
||||||
))
|
|
||||||
.add("Trayvon imperial", () => (
|
|
||||||
<DraftSettings pattern="trayvon" gist={false} units="imperial" {...props} />
|
|
||||||
));
|
|
|
@ -3,8 +3,8 @@ import PropTypes from "prop-types";
|
||||||
|
|
||||||
const Emblem = props => (
|
const Emblem = props => (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<span className="emb" style={{color: props.c1}}>{props.t1}</span>
|
<span className="emb" style={{color: props.c1, fontSize: props.size+"px"}}>{props.t1}</span>
|
||||||
<span className="lem" style={{color: props.c2}}>{props.t2}</span>
|
<span className="lem" style={{color: props.c2, fontSize: props.size+"px"}}>{props.t2}</span>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -17,11 +17,11 @@ Emblem.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
Emblem.defaultProps = {
|
Emblem.defaultProps = {
|
||||||
size: 24,
|
size: 36,
|
||||||
c1: "#111111",
|
c1: "#111111",
|
||||||
c2: "#111111",
|
c2: "#111111",
|
||||||
t1: "",
|
t1: "",
|
||||||
t2: ""
|
t2: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Emblem;
|
export default Emblem;
|
||||||
|
|
42
packages/components/src/Navbar/index.js
Normal file
42
packages/components/src/Navbar/index.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import React from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import Logo from "../Logo";
|
||||||
|
import Emblem from "../Emblem";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
|
const Navbar = props => {
|
||||||
|
|
||||||
|
const renderNav = nav => {
|
||||||
|
let title = nav.title || nav.text;
|
||||||
|
let text = typeof nav.text === "string"
|
||||||
|
? <FormattedMessage id={nav.text} />
|
||||||
|
: nav.text
|
||||||
|
if (nav.type === "component") return nav.component
|
||||||
|
return <a href={nav.href} className="nav" title={nav.title}>{text}</a>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className="navbar">
|
||||||
|
<div>
|
||||||
|
<div className="logo">{props.logo}</div>
|
||||||
|
<div className="emblem">{props.emblem}</div>
|
||||||
|
{props.navs.left.map(nav => renderNav(nav))}
|
||||||
|
<div className="spread" />
|
||||||
|
{props.navs.right.map(nav => renderNav(nav))}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Navbar.propTypes = {
|
||||||
|
navs: PropTypes.object,
|
||||||
|
logo: PropTypes.node,
|
||||||
|
emblem: PropTypes.node,
|
||||||
|
};
|
||||||
|
|
||||||
|
Navbar.defaultProps = {
|
||||||
|
navs: {left:[], right: []},
|
||||||
|
logo: <Logo size={32} />,
|
||||||
|
emblem: <Emblem t1="Free" t2="Sewing" size={20} c1="#74c0fc" c2="#e9ecef"/>
|
||||||
|
};
|
||||||
|
export default Navbar;
|
55
packages/components/src/Navbar/stories.js
Normal file
55
packages/components/src/Navbar/stories.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import React from "react";
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import Navbar from ".";
|
||||||
|
import LanguageIcon from "@material-ui/icons/Translate";
|
||||||
|
import DarkModeIcon from "@material-ui/icons/Brightness3";
|
||||||
|
import Avatar from '@material-ui/core/Avatar';
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
triggerAction: (type, data) =>
|
||||||
|
console.log(`Action of type ${type} triggered, data passed is`, data),
|
||||||
|
updateValue: (type, data) =>
|
||||||
|
console.log(`Update ${type} with new value`, data),
|
||||||
|
};
|
||||||
|
const navs = {
|
||||||
|
left: [
|
||||||
|
{
|
||||||
|
type: "link",
|
||||||
|
href: "https://freesewing.org/",
|
||||||
|
text: "app.patterns"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "link",
|
||||||
|
href: "https://freesewing.org/",
|
||||||
|
text: "app.docs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "link",
|
||||||
|
href: "https://freesewing.org/",
|
||||||
|
text: "app.community"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
right: [
|
||||||
|
{
|
||||||
|
type: "link",
|
||||||
|
href: "https://freesewing.org/",
|
||||||
|
text: "app.account",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "link",
|
||||||
|
href: "https://freesewing.org/",
|
||||||
|
text: <LanguageIcon className="nav-icon"/>,
|
||||||
|
title: 'Languages'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "link",
|
||||||
|
href: "https://freesewing.org/",
|
||||||
|
text: <DarkModeIcon className="nav-icon moon"/>,
|
||||||
|
title: 'Dark mode'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
storiesOf("Navbar", module)
|
||||||
|
.add("Basic", () => <Navbar navs={navs}/>)
|
|
@ -9,7 +9,7 @@ const props = {
|
||||||
};
|
};
|
||||||
const noyes = ["No", "Yes"];
|
const noyes = ["No", "Yes"];
|
||||||
|
|
||||||
storiesOf("FormFieldBool", module)
|
storiesOf("Low level/Form/FormFieldBool", module)
|
||||||
.add("Basic", () => <FormFieldBool {...props} />)
|
.add("Basic", () => <FormFieldBool {...props} />)
|
||||||
.add("False", () => <FormFieldBool {...props} dflt={false} />)
|
.add("False", () => <FormFieldBool {...props} dflt={false} />)
|
||||||
.add("True", () => <FormFieldBool {...props} dflt={true} />)
|
.add("True", () => <FormFieldBool {...props} dflt={true} />)
|
|
@ -14,7 +14,7 @@ const props = {
|
||||||
dflt: []
|
dflt: []
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("FormFieldChecks", module)
|
storiesOf("Low level/Form/FormFieldChecks", module)
|
||||||
.add("Basic", () => <FormFieldChecks {...props} />)
|
.add("Basic", () => <FormFieldChecks {...props} />)
|
||||||
.add("Apple", () => <FormFieldChecks {...props} dflt={["apple"]} />)
|
.add("Apple", () => <FormFieldChecks {...props} dflt={["apple"]} />)
|
||||||
.add("Banana", () => <FormFieldChecks {...props} dflt={["banana"]} />)
|
.add("Banana", () => <FormFieldChecks {...props} dflt={["banana"]} />)
|
|
@ -13,7 +13,7 @@ const props = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("FormFieldList", module)
|
storiesOf("Low level/Form/FormFieldList", module)
|
||||||
.add("Basic", () => <FormFieldList {...props} />)
|
.add("Basic", () => <FormFieldList {...props} />)
|
||||||
.add("Apple", () => <FormFieldList {...props} dflt="apple" />)
|
.add("Apple", () => <FormFieldList {...props} dflt="apple" />)
|
||||||
.add("Banana", () => <FormFieldList {...props} dflt="banana" />)
|
.add("Banana", () => <FormFieldList {...props} dflt="banana" />)
|
|
@ -8,7 +8,7 @@ const props = {
|
||||||
name: "exampleSliderOption"
|
name: "exampleSliderOption"
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("FormFieldSlider", module)
|
storiesOf("Low level/Form/FormFieldSlider", module)
|
||||||
.add("Basic", () => <FormFieldSlider {...props} />)
|
.add("Basic", () => <FormFieldSlider {...props} />)
|
||||||
.add("From 1 to 10", () => <FormFieldSlider {...props} min={1} max={10} />)
|
.add("From 1 to 10", () => <FormFieldSlider {...props} min={1} max={10} />)
|
||||||
.add("Step: 1", () => (
|
.add("Step: 1", () => (
|
|
@ -159,3 +159,28 @@ export const optionDefault = option => {
|
||||||
return option[type];
|
return option[type];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const storage = {
|
||||||
|
set: (key, value, raw) => {
|
||||||
|
if (typeof localStorage === "undefined")
|
||||||
|
throw(new Error("No localStorage support. And we need it. Bailing out."));
|
||||||
|
|
||||||
|
const _key = "fs_" + key;
|
||||||
|
|
||||||
|
if (typeof value === "undefined" || value === null)
|
||||||
|
localStorage.removeItem(_key);
|
||||||
|
else localStorage.setItem(_key, raw ? value : JSON.stringify(value));
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
get: (key, raw) => {
|
||||||
|
if (typeof localStorage === "undefined")
|
||||||
|
throw(new Error("No localStorage support. And we need it. Bailing out."));
|
||||||
|
|
||||||
|
const value = localStorage.getItem("fs_"+key);
|
||||||
|
|
||||||
|
return raw ? value : JSON.parse(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const cloneObject = src => Object.assign({}, src);
|
||||||
|
|
39
packages/components/src/withGist/index.js
Normal file
39
packages/components/src/withGist/index.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import React from "react";
|
||||||
|
import { storage, cloneObject } from "../utils";
|
||||||
|
|
||||||
|
const withGist = (WrappedComponent, settings={gist:{}, store:false}) => {
|
||||||
|
|
||||||
|
return class extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.update = this.update.bind(this);
|
||||||
|
this.state = settings.gist || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
update(value, l1 = false, l2 = false, l3 = false) {
|
||||||
|
console.log('update', value, l1, l2, l3, this.state);
|
||||||
|
if (!l1) return;
|
||||||
|
let gist = this.state;
|
||||||
|
|
||||||
|
if(typeof gist === "undefined") gist = {};
|
||||||
|
if(l1 && typeof gist[l1] === "undefined") gist[l1] = {};
|
||||||
|
if(l2 && typeof gist[l1][l2] === "undefined") gist[l1][l2] = {};
|
||||||
|
if(l3 && typeof gist[l1][l2][l3] === "undefined") gist[l1][l2][l3] = {};
|
||||||
|
|
||||||
|
if (l3) gist[l1][l2][l3] = value;
|
||||||
|
else if (l2) gist[l1][l2] = value;
|
||||||
|
else if (l1) gist[l1] = value;
|
||||||
|
this.setState(gist, () => {
|
||||||
|
if (settings.store) storage.set(settings.store, this.state);
|
||||||
|
console.log(this.state);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <WrappedComponent gist={{get: this.state.gist, set: this.update}} {...this.props} />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withGist;
|
|
@ -1,3 +1,3 @@
|
||||||
@import "components/emblem";
|
@import "components/emblem";
|
||||||
@import "components/pattern-option";
|
@import "components/navbar";
|
||||||
@import "components/pattern-options";
|
@import "components/draft-configurator";
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
|
$fc-text-light: $oc-gray-9;
|
||||||
|
$fc-text-dark: $oc-gray-0;
|
||||||
$fc-bg-light: $oc-gray-0;
|
$fc-bg-light: $oc-gray-0;
|
||||||
$fc-bg-dark: $oc-gray-9;
|
$fc-bg-dark: $oc-gray-9;
|
||||||
$fc-notice-light: $oc-yellow-7;
|
$fc-notice-light: $oc-yellow-7;
|
||||||
$fc-notice-dark: $oc-lime-3;
|
$fc-notice-dark: $oc-lime-3;
|
||||||
$fc-hoverbg-light: $oc-gray-1;
|
$fc-hoverbg-light: $oc-gray-1;
|
||||||
$fc-hoverbg-dark: $oc-gray-8;
|
$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-dark: $oc-blue-3;
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,8 @@ svg.icon-col-exp.expanded {
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.nav.l2 div.col-exp,
|
ul.nav.l2 div.col-exp,
|
||||||
ul.nav.l3 div.col-exp {
|
ul.nav.l3 div.col-exp,
|
||||||
|
ul.nav.l4 div.col-exp {
|
||||||
margin: 0 27px;
|
margin: 0 27px;
|
||||||
}
|
}
|
||||||
|
|
65
packages/css-theme/src/components/_navbar.scss
Normal file
65
packages/css-theme/src/components/_navbar.scss
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
header.navbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 64px;
|
||||||
|
width: calc(100% - 52px);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 26px;
|
||||||
|
background: $fc-bg-dark;
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
height: 64px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
margin-right: 13px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: $oc-gray-2;
|
||||||
|
}
|
||||||
|
div.emblem {
|
||||||
|
margin-right: 26px;
|
||||||
|
}
|
||||||
|
div.spread { flex-grow: 1}
|
||||||
|
a.nav,
|
||||||
|
button {
|
||||||
|
@include title-font;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 13px;
|
||||||
|
height: 60px;
|
||||||
|
color: $fc-text-dark;
|
||||||
|
border: 0;
|
||||||
|
line-height: 64px;
|
||||||
|
border-bottom: 4px solid $fc-bg-dark;
|
||||||
|
font-size: 18px;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.2s ease, border-color 0.2s ease-in-out;
|
||||||
|
background:none;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
/* For buttons, border does not count for height */
|
||||||
|
height: 64px;
|
||||||
|
}
|
||||||
|
button:hover,
|
||||||
|
a.nav:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: $fc-link-dark;
|
||||||
|
border-color: $fc-link-dark;
|
||||||
|
}
|
||||||
|
a.nav.active {
|
||||||
|
border-color: $fc-link-dark;
|
||||||
|
}
|
||||||
|
svg.nav-icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-bottom: -6px;
|
||||||
|
}
|
||||||
|
svg.nav-icon.moon {
|
||||||
|
transform: rotate(26deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
header.navbar > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
div.pattern-option {
|
|
||||||
.po-custom {
|
|
||||||
color: $fc-notice-light;
|
|
||||||
}
|
|
||||||
label.po-list-item:hover {
|
|
||||||
background: $fc-hoverbg-light;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body.dark {
|
|
||||||
div.pattern-option {
|
|
||||||
.po-custom {
|
|
||||||
color: $fc-notice-dark;
|
|
||||||
}
|
|
||||||
label.po-list-item:hover {
|
|
||||||
background: $fc-hoverbg-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
export default class Storage {
|
export default class Storage {
|
||||||
set(key, value, isJson) {
|
set(key, value, raw = false) {
|
||||||
if (typeof localStorage === "undefined") {
|
if (typeof localStorage === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,13 @@ export default class Storage {
|
||||||
if (typeof value === "undefined" || value === null) {
|
if (typeof value === "undefined" || value === null) {
|
||||||
localStorage.removeItem(_key);
|
localStorage.removeItem(_key);
|
||||||
} else {
|
} else {
|
||||||
localStorage.setItem(_key, isJson ? JSON.stringify(value) : value);
|
localStorage.setItem(_key, raw ? value : JSON.stringify(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(key, isJson) {
|
get(key, raw = false) {
|
||||||
if (typeof localStorage === "undefined") {
|
if (typeof localStorage === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,6 @@ export default class Storage {
|
||||||
|
|
||||||
const value = localStorage.getItem(_key);
|
const value = localStorage.getItem(_key);
|
||||||
|
|
||||||
return isJson ? JSON.parse(value) : value;
|
return raw ? value : JSON.parse(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue