1
0
Fork 0

🚧 More work on React components

This commit is contained in:
Joost De Cock 2019-04-22 14:31:50 +02:00
parent 4d7b7df674
commit fa43bf1d0c
16 changed files with 313 additions and 30 deletions

View file

@ -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",

View file

@ -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**` } }

View 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} />);

View 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;

View 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" />);

View 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;

View 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

View file

@ -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", () => (

View file

@ -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 });

View 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;

View file

@ -0,0 +1 @@
div.pattern-option .custom { color: #5c940d; }

View 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)."
/>
));

View file

@ -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} />
));

View file

@ -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=