🚧 More work on React components
This commit is contained in:
parent
4d7b7df674
commit
fa43bf1d0c
16 changed files with 313 additions and 30 deletions
|
@ -53,6 +53,7 @@
|
||||||
"@babel/register": "^7.0.0",
|
"@babel/register": "^7.0.0",
|
||||||
"@material-ui/core": "3.9.3",
|
"@material-ui/core": "3.9.3",
|
||||||
"@material-ui/icons": "3.0.2",
|
"@material-ui/icons": "3.0.2",
|
||||||
|
"@material-ui/lab": "3.0.0-alpha.30",
|
||||||
"@storybook/addon-backgrounds": "5.0.10",
|
"@storybook/addon-backgrounds": "5.0.10",
|
||||||
"@storybook/addon-knobs": "5.0.10",
|
"@storybook/addon-knobs": "5.0.10",
|
||||||
"@storybook/addon-notes": "5.0.10",
|
"@storybook/addon-notes": "5.0.10",
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { storiesOf, addDecorator } from "@storybook/react";
|
||||||
import Emblem from ".";
|
import Emblem from ".";
|
||||||
import "../../../../dist/css-theme/theme.css";
|
import "../../../../dist/css-theme/theme.css";
|
||||||
|
|
||||||
storiesOf("Graphics/Emblem", module).add(
|
storiesOf("Emblem", module).add(
|
||||||
"FreeSewing",
|
"FreeSewing",
|
||||||
() => <Emblem t1="Free" t2="Sewing" />,
|
() => <Emblem t1="Free" t2="Sewing" />,
|
||||||
{ notes: { markdown: ` test **here**` } }
|
{ notes: { markdown: ` test **here**` } }
|
||||||
|
|
17
packages/components/src/FormFieldBool/stories.js
Normal file
17
packages/components/src/FormFieldBool/stories.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import React from "react";
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import FormFieldBool from ".";
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
updateOption: (name, value) =>
|
||||||
|
console.log(`Updated option ${name}, value is now: ${value}`),
|
||||||
|
name: "exampleBoolOption"
|
||||||
|
};
|
||||||
|
const noyes = ["No", "Yes"];
|
||||||
|
|
||||||
|
storiesOf("FormFieldBool", module)
|
||||||
|
.add("Basic", () => <FormFieldBool {...props} />)
|
||||||
|
.add("False", () => <FormFieldBool {...props} dflt={false} />)
|
||||||
|
.add("True", () => <FormFieldBool {...props} dflt={true} />)
|
||||||
|
.add("No", () => <FormFieldBool {...props} dflt={false} labels={noyes} />)
|
||||||
|
.add("Yes", () => <FormFieldBool {...props} dflt={true} labels={noyes} />);
|
35
packages/components/src/FormFieldList/index.js
Normal file
35
packages/components/src/FormFieldList/index.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import Radio from "@material-ui/core/Radio";
|
||||||
|
import RadioGroup from "@material-ui/core/RadioGroup";
|
||||||
|
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||||
|
|
||||||
|
const FormFieldList = props => {
|
||||||
|
const [value, setValue] = useState(props.dflt);
|
||||||
|
const update = evt => {
|
||||||
|
props.updateOption(props.name, evt.target.value);
|
||||||
|
setValue(evt.target.value);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<RadioGroup onChange={update} value={value}>
|
||||||
|
{Object.keys(props.list).map((item, index) => (
|
||||||
|
<FormControlLabel
|
||||||
|
key={item}
|
||||||
|
control={<Radio color="primary" />}
|
||||||
|
value={item}
|
||||||
|
checked={value === item ? true : false}
|
||||||
|
label={props.list[item]}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
FormFieldList.propTypes = {
|
||||||
|
dflt: PropTypes.bool,
|
||||||
|
list: PropTypes.object,
|
||||||
|
updateOption: PropTypes.func.isRequired,
|
||||||
|
name: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormFieldList;
|
20
packages/components/src/FormFieldList/stories.js
Normal file
20
packages/components/src/FormFieldList/stories.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import React from "react";
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import FormFieldList from ".";
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
updateOption: (name, value) =>
|
||||||
|
console.log(`Updated option ${name}, value is now: ${value}`),
|
||||||
|
name: "exampleListOption",
|
||||||
|
list: {
|
||||||
|
apple: "Apple",
|
||||||
|
banana: "Banana",
|
||||||
|
cherry: "Cherry"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
storiesOf("FormFieldList", module)
|
||||||
|
.add("Basic", () => <FormFieldList {...props} />)
|
||||||
|
.add("Apple", () => <FormFieldList {...props} dflt="apple" />)
|
||||||
|
.add("Banana", () => <FormFieldList {...props} dflt="banana" />)
|
||||||
|
.add("Cherry", () => <FormFieldList {...props} dflt="cherry" />);
|
56
packages/components/src/FormFieldSlider/index.js
Normal file
56
packages/components/src/FormFieldSlider/index.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import Slider from "@material-ui/lab/Slider";
|
||||||
|
import { withStyles } from "@material-ui/core/styles";
|
||||||
|
|
||||||
|
const PaddedSlider = withStyles({
|
||||||
|
container: { padding: "25px 0" },
|
||||||
|
track: { height: "4px" },
|
||||||
|
thumb: { width: "16px", height: "16px" }
|
||||||
|
})(Slider);
|
||||||
|
|
||||||
|
const FormFieldSlider = props => {
|
||||||
|
const [value, setValue] = useState(props.value);
|
||||||
|
|
||||||
|
const update = (evt, newValue) => {
|
||||||
|
props.updateOption(props.name, newValue, evt);
|
||||||
|
setValue(newValue);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Force state update when rerendering due to props change
|
||||||
|
if (props.value !== value) setValue(props.value);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PaddedSlider
|
||||||
|
value={value}
|
||||||
|
min={props.min}
|
||||||
|
max={props.max}
|
||||||
|
step={props.step}
|
||||||
|
onChange={update}
|
||||||
|
onDragEnd={update}
|
||||||
|
classes={{
|
||||||
|
track: "slider-track",
|
||||||
|
thumb: "slider-thumb"
|
||||||
|
}}
|
||||||
|
aria-labelledby={props.label}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
FormFieldSlider.propTypes = {
|
||||||
|
min: PropTypes.number,
|
||||||
|
max: PropTypes.number,
|
||||||
|
step: PropTypes.number,
|
||||||
|
updateOption: PropTypes.func.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
label: PropTypes.oneOfType([PropTypes.string, PropTypes.oneOf([false])])
|
||||||
|
};
|
||||||
|
|
||||||
|
FormFieldSlider.defaultProps = {
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 0.1,
|
||||||
|
label: false
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormFieldSlider;
|
19
packages/components/src/FormFieldSlider/stories.js
Normal file
19
packages/components/src/FormFieldSlider/stories.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import React from "react";
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import FormFieldSlider from ".";
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
updateOption: (name, value) =>
|
||||||
|
console.log(`Updated option ${name}, value is now: ${value}`),
|
||||||
|
name: "exampleSliderOption"
|
||||||
|
};
|
||||||
|
|
||||||
|
storiesOf("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} />
|
||||||
|
));
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,8 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { storiesOf, addDecorator } from "@storybook/react";
|
import { storiesOf, addDecorator } from "@storybook/react";
|
||||||
//import {muiTheme} from 'storybook-addon-material-ui';
|
|
||||||
import Logo from ".";
|
import Logo from ".";
|
||||||
|
|
||||||
storiesOf("Graphics/Logo", module)
|
storiesOf("Logo", module)
|
||||||
// .addDecorator(muiTheme())
|
|
||||||
.add("Default", () => <Logo />)
|
.add("Default", () => <Logo />)
|
||||||
.add("Custom size", () => <Logo size={100} />)
|
.add("Custom size", () => <Logo size={100} />)
|
||||||
.add("Custom color", () => (
|
.add("Custom color", () => (
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import Ogol from ".";
|
import Ogol from ".";
|
||||||
import "../../../../dist/css-theme/theme.css";
|
|
||||||
import { dark as backgrounds } from "../../.storybook/backgrounds";
|
import { dark as backgrounds } from "../../.storybook/backgrounds";
|
||||||
|
|
||||||
storiesOf("Graphics/Ogol", module)
|
storiesOf("Ogol", module)
|
||||||
.add("Default", () => <Ogol />, { backgrounds })
|
.add("Default", () => <Ogol />, { backgrounds })
|
||||||
.add("Custom color", () => <Ogol color="green" />, { backgrounds })
|
.add("Custom color", () => <Ogol color="yellow" />, { backgrounds })
|
||||||
.add("Custom size", () => <Ogol size={200} />, { backgrounds });
|
.add("Custom size", () => <Ogol size={200} />, { backgrounds });
|
||||||
|
|
122
packages/components/src/PatternOptionPercentage/index.js
Normal file
122
packages/components/src/PatternOptionPercentage/index.js
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import FormFieldSlider from "../FormFieldSlider";
|
||||||
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
|
import ResetIcon from "@material-ui/icons/SettingsBackupRestore";
|
||||||
|
import HelpIcon from "@material-ui/icons/Help";
|
||||||
|
|
||||||
|
const PatternOptionPercentage = props => {
|
||||||
|
const [value, setValue] = useState(props.dflt);
|
||||||
|
const [previousValue, setPreviousValue] = useState(props.dflt);
|
||||||
|
|
||||||
|
const round = val => Math.round(val * 10) / 10;
|
||||||
|
|
||||||
|
const update = (name, newValue, evt) => {
|
||||||
|
newValue = round(newValue);
|
||||||
|
// Sometimes, when sliding, the rapid succession of updates
|
||||||
|
// 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
|
||||||
|
if (!isNaN(newValue)) {
|
||||||
|
setValue(newValue);
|
||||||
|
if (evt.type !== "mousemove") props.updateOption(props.name, newValue);
|
||||||
|
} else {
|
||||||
|
if (evt.type !== "mousemove") props.updateOption(props.name, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
setValue(props.dflt);
|
||||||
|
props.updateOption(props.name, props.dflt);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = {
|
||||||
|
container: {
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "center"
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
flexGrow: 1,
|
||||||
|
margin: "0 0.5rem"
|
||||||
|
},
|
||||||
|
right: { margin: "0 0.5rem" }
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="pattern-option percentage">
|
||||||
|
<div style={styles.container}>
|
||||||
|
<div style={styles.left}>
|
||||||
|
<h4 id={"po-pct-" + props.name}>{props.title}</h4>
|
||||||
|
</div>
|
||||||
|
<div style={styles.right}>
|
||||||
|
<h4 className={value === props.dflt ? "dflt" : "custom"}>{value}%</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={styles.container}>
|
||||||
|
<div style={styles.left}>
|
||||||
|
<p>{props.desc}</p>
|
||||||
|
</div>
|
||||||
|
<div style={styles.right}>
|
||||||
|
<IconButton
|
||||||
|
title={props.resetLabel}
|
||||||
|
aria-label={props.resetLabel}
|
||||||
|
color="primary"
|
||||||
|
disabled={value === props.dflt ? true : false}
|
||||||
|
onClick={reset}
|
||||||
|
>
|
||||||
|
<ResetIcon />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
title={props.docsLabel}
|
||||||
|
aria-label={props.docsLabel}
|
||||||
|
color="primary"
|
||||||
|
onClick={() =>
|
||||||
|
props.triggerAction("showHelp", {
|
||||||
|
type: "patternOption",
|
||||||
|
value: props.name
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<HelpIcon />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<FormFieldSlider
|
||||||
|
name={props.name}
|
||||||
|
value={value}
|
||||||
|
min={props.min}
|
||||||
|
max={props.max}
|
||||||
|
step={props.step}
|
||||||
|
onChange={update}
|
||||||
|
label={"po-pct-" + props.name}
|
||||||
|
updateOption={update}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
PatternOptionPercentage.propTypes = {
|
||||||
|
min: PropTypes.number,
|
||||||
|
max: PropTypes.number,
|
||||||
|
step: PropTypes.number,
|
||||||
|
updateOption: PropTypes.func.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
dflt: PropTypes.number.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
desc: PropTypes.string.isRequired,
|
||||||
|
resetLabel: PropTypes.string,
|
||||||
|
docsLabel: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
PatternOptionPercentage.defaultProps = {
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 0.1,
|
||||||
|
title: false,
|
||||||
|
desc: false,
|
||||||
|
resetLabel: "♻️",
|
||||||
|
docsLabel: "🤔"
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PatternOptionPercentage;
|
|
@ -0,0 +1 @@
|
||||||
|
div.pattern-option .custom { color: #5c940d; }
|
21
packages/components/src/PatternOptionPercentage/stories.js
Normal file
21
packages/components/src/PatternOptionPercentage/stories.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import React from "react";
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import Pct from ".";
|
||||||
|
import "./stories.css";
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
triggerAction: (type, data) =>
|
||||||
|
console.log(`Action of type ${type} triggered, data passed is`, data),
|
||||||
|
updateOption: (name, value) =>
|
||||||
|
console.log(`Updated percentage option ${name}, value is now: ${value}`),
|
||||||
|
name: "examplePercentageOption",
|
||||||
|
dflt: 50
|
||||||
|
};
|
||||||
|
|
||||||
|
storiesOf("PatternOptionPercentage", module).add("Basic", () => (
|
||||||
|
<Pct
|
||||||
|
{...props}
|
||||||
|
title="This is the title. I'm wrapped in an h4 tag"
|
||||||
|
desc="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 (we've made it green in this example)."
|
||||||
|
/>
|
||||||
|
));
|
|
@ -1,19 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { storiesOf } from "@storybook/react";
|
|
||||||
import Bool from ".";
|
|
||||||
|
|
||||||
const props = {
|
|
||||||
updateOption: (name, value) =>
|
|
||||||
console.log(`Updated option ${name}, value is now: ${value}`),
|
|
||||||
name: "exampleBoolOption"
|
|
||||||
};
|
|
||||||
const noyes = ["No", "Yes"];
|
|
||||||
|
|
||||||
storiesOf("Draft/Options/Bool", module)
|
|
||||||
.add("Default", () => <Bool {...props} />)
|
|
||||||
.add("Default: false", () => <Bool {...props} dflt={false} />)
|
|
||||||
.add("Default: true", () => <Bool {...props} dflt={true} />)
|
|
||||||
.add("With labels, No", () => <Bool {...props} dflt={false} labels={noyes} />)
|
|
||||||
.add("With labels, Yes", () => (
|
|
||||||
<Bool {...props} dflt={true} labels={noyes} />
|
|
||||||
));
|
|
13
yarn.lock
13
yarn.lock
|
@ -2195,6 +2195,17 @@
|
||||||
"@babel/runtime" "^7.2.0"
|
"@babel/runtime" "^7.2.0"
|
||||||
recompose "0.28.0 - 0.30.0"
|
recompose "0.28.0 - 0.30.0"
|
||||||
|
|
||||||
|
"@material-ui/lab@3.0.0-alpha.30":
|
||||||
|
version "3.0.0-alpha.30"
|
||||||
|
resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-3.0.0-alpha.30.tgz#c6c64d0ff2b28410a09e4009f3677499461f3df8"
|
||||||
|
integrity sha512-d8IXbkQO92Ln7f/Tzy8Q5cLi/sMWH/Uz1xrOO5NKUgg42whwyCuoT9ErddDPFNQmPi9d1C7A5AG8ONjEAbAIyQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.2.0"
|
||||||
|
"@material-ui/utils" "^3.0.0-alpha.2"
|
||||||
|
classnames "^2.2.5"
|
||||||
|
keycode "^2.1.9"
|
||||||
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
"@material-ui/system@^3.0.0-alpha.0":
|
"@material-ui/system@^3.0.0-alpha.0":
|
||||||
version "3.0.0-alpha.2"
|
version "3.0.0-alpha.2"
|
||||||
resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-3.0.0-alpha.2.tgz#096e80c8bb0f70aea435b9e38ea7749ee77b4e46"
|
resolved "https://registry.yarnpkg.com/@material-ui/system/-/system-3.0.0-alpha.2.tgz#096e80c8bb0f70aea435b9e38ea7749ee77b4e46"
|
||||||
|
@ -11543,7 +11554,7 @@ jws@^3.1.5:
|
||||||
jwa "^1.4.1"
|
jwa "^1.4.1"
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
keycode@^2.2.0:
|
keycode@^2.1.9, keycode@^2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
|
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
|
||||||
integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=
|
integrity sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue