Implement button module in React

This commit is contained in:
Daniel Sinn
2019-11-25 10:16:04 -05:00
parent 28a4d8c4f8
commit 5621ab7212
8 changed files with 184 additions and 68 deletions
-11
View File
@@ -112,17 +112,6 @@ nav {
padding: 0.1em 0.5em;
}
#sectionButton {
line-height: 150%;
}
#sectionButton div {
margin-bottom: 1em;
}
#sectionButton .buttonWhite {
border-style: solid;
border-width: 1px;
}
#sectionKeypads ul {
display: inline-block;
list-style-type: none;
+3 -1
View File
@@ -1,5 +1,6 @@
import React from 'react';
import './App.css';
import ButtonModule from "./components/ButtonModule";
import WiresModule from "./components/WiresModule";
function App() {
@@ -9,7 +10,8 @@ function App() {
<h1>Keep Talking and Nobody Explodes</h1>
</header>
<WiresModule id='sectionWires' />
<WiresModule id="sectionWires" />
<ButtonModule id="sectionButton" />
</div>
);
}
+112
View File
@@ -0,0 +1,112 @@
import ButtonModuleColourInput from "./ButtonModuleColourInput";
import ButtonModuleTextInput from "./ButtonModuleTextInput";
import KtaneModule from "./KtaneModule";
import React from "react";
import "../css/ButtonModule.css";
export default class ButtonModule extends KtaneModule {
constructor(props) {
super(props);
this.colourBlue = "blue";
this.colourWhite = "white";
this.colourYellow = "yellow";
this.colourRed = "red";
this.allColours = [this.colourBlue, this.colourWhite, this.colourYellow, this.colourRed];
this.textAbort = "Abort";
this.textDetonate = "Detonate";
this.textHold = "Hold";
this.textPress = "Press";
this.allText = [this.textAbort, this.textDetonate, this.textHold, this.textPress];
this.setColour = this.setColour.bind(this);
this.setText = this.setText.bind(this);
}
getInstruction() {
if (this.state.text === this.textDetonate) {
return <>If 2+ 🔋, press and release.<br />Otherwise, hold button.</>;
} else if (this.state.colour === this.colourWhite) {
return <>
If <span className="litIndicator" title="Lit indicator">CAR</span>, hold button.<br />
Otherwise, if 3+ 🔋 and <span className="litIndicator" title="Lit indicator">FRK</span>, press and release.<br />
Otherwise, hold button.
</>;
} else if ((this.state.colour === this.colourBlue && this.state.text === this.textAbort) || this.state.colour === this.colourYellow) {
return "Hold button.";
} else if (this.state.colour === this.colourRed && this.state.text === this.textHold) {
return "Press and release.";
} else {
return <>
If 3+ 🔋 and <span className="litIndicator" title="Lit indicator">FRK</span>, press and release the button.
<br />Otherwise, hold button.
</>;
}
}
getTitle() {
return "Button";
}
mainRender() {
return (
<>
<div>
Colour:
{
this.allColours.map(colour => (
<ButtonModuleColourInput
colour={colour}
key={colour}
onChange={this.setColour}
stateColour={this.state.colour}
/>
))
}
</div>
<div>
Text:
{
this.allText.map(text => (
<ButtonModuleTextInput
key={text}
onChange={this.setText}
stateText={this.state.text}
text={text}
/>
))
}
</div>
<div className="instruction">{this.getInstruction()}</div>
<div>
If holding button, release when the timer contains the digit that corresponds to the strip colour:
<ul>
<li><span className="button blue">Blue</span>: &nbsp; 4</li>
<li><span className="button yellow">Yellow</span>: 5</li>
<li><span className="button">Other</span>: &nbsp;1</li>
</ul>
</div>
</>
)
}
resetState() {
// @TODO Put string literals into constants
this.state = {
colour: "blue",
text: "Abort"
};
}
setColour(event) {
this.setState({colour: event.target.value});
}
setText(event) {
this.setState({text: event.target.value});
}
}
+31
View File
@@ -0,0 +1,31 @@
import PropTypes from 'prop-types';
import React, {Component} from "react";
export default class ButtonModuleColourInput extends Component {
render() {
return (
<label>
<input
checked={this.props.stateColour === this.props.colour}
name="buttonColour"
onChange={this.props.onChange}
type="radio"
value={this.props.colour}
/>
<span className={`button ${this.props.colour}`}>
{this.props.colour.charAt(0).toUpperCase() + this.props.colour.slice(1)}
</span>
</label>
)
}
shouldComponentUpdate(nextProps) {
return this.props.stateColour !== nextProps.stateColour;
}
}
ButtonModuleColourInput.propTypes = {
colour: PropTypes.string,
onChange: PropTypes.func,
stateColour: PropTypes.string
};
+28
View File
@@ -0,0 +1,28 @@
import PropTypes from 'prop-types';
import React, {Component} from "react";
export default class ButtonModuleTextInput extends Component {
render() {
return (
<label>
<input
checked={this.props.stateText === this.props.text}
onChange={this.props.onChange}
type="radio"
value={this.props.text}
/>
{this.props.text}
</label>
)
}
shouldComponentUpdate(nextProps) {
return this.props.stateText !== nextProps.stateText;
}
}
ButtonModuleTextInput.propTypes = {
onChange: PropTypes.func,
stateText: PropTypes.string,
text: PropTypes.string
};
+10
View File
@@ -0,0 +1,10 @@
#sectionButton {
line-height: 150%;
}
#sectionButton div {
margin-bottom: 1em;
}
#sectionButton .buttonWhite {
border-style: solid;
border-width: 1px;
}