Skip to content

Commit

Permalink
Improve UX of numeric input
Browse files Browse the repository at this point in the history
  • Loading branch information
axelboc committed Jul 25, 2023
1 parent 2ba9087 commit 0094b6c
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 120 deletions.
109 changes: 94 additions & 15 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"lodash": "^4.17.21",
"plotly.js": "^1.52.3",
"popper.js": "^1.16.1",
"rc-input-number": "8.0.3",
"react": "^17.0.2",
"react-bootstrap": "2.8.0",
"react-chat-widget": "^3.1.4",
Expand All @@ -49,7 +50,6 @@
"react-hook-form": "7.45.0",
"react-icons": "^4.3.1",
"react-lazyload": "^3.2.0",
"react-numeric-input": "^2.2.3",
"react-plotly.js": "^2.4.0",
"react-redux": "7.2.6",
"react-router": "^6.2.1",
Expand Down Expand Up @@ -78,9 +78,9 @@
"cypress": "^12.13.0",
"eslint": "8.42.0",
"eslint-config-galex": "4.5.2",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jest": "27.2.1",
"eslint-plugin-jsx-a11y": "6.7.1",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-react": "7.32.2",
"less": "^4.1.2",
"less-watch-compiler": "^1.16.3",
Expand Down
79 changes: 35 additions & 44 deletions ui/src/components/MotorInput/MotorInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,59 +140,50 @@ export default class MotorInput extends React.Component {
}
/>
</div>
<div
className="rw-widget-right-border"
style={{
width: 'auto',
display: 'inline-flex',
alignItems: 'center',
textAlign: 'center',
fontSize: '12px',
cursor: 'pointer',
backgroundColor: '#EAEAEA',
}}
>
{this.props.saveStep &&
this.props.state === MOTOR_STATE.READY &&
!this.props.inplace ? (
<PopInput
pkey={motorName.toLowerCase()}
value={step}
suffix={suffix}
inputSize="5"
immediate
onSave={this.props.saveStep}
{this.props.saveStep &&
(this.props.state === MOTOR_STATE.READY ? (
<div
className="rw-widget-right-border"
style={{
display: 'inline-block',
marginLeft: 'auto',
marginRight: '0.5em',
paddingLeft: '0.5em',
width: 'auto',
display: 'inline-flex',
alignItems: 'center',
textAlign: 'center',
fontSize: '12px',
cursor: 'pointer',
backgroundColor: '#EAEAEA',
}}
/>
) : null}
{this.props.state !== MOTOR_STATE.READY ? (
>
{this.props.inplace ? (
<span className="ms-2 me-2">
{this.props.step} {suffix}
</span>
) : (
<PopInput
pkey={motorName.toLowerCase()}
value={step}
suffix={suffix}
inputSize="5"
immediate
onSave={this.props.saveStep}
style={{
display: 'inline-block',
marginLeft: 'auto',
marginRight: '0.5em',
paddingLeft: '0.5em',
}}
/>
)}
</div>
) : (
<Button
style={{
width: '100%',
height: '100%',
display: 'block',
border: 'none',
}}
className="btn-xs motor-abort rw-widget-no-left-border"
variant="danger"
onClick={this.stopMotor}
>
<i className="fas fa-times" />
</Button>
) : null}
{this.props.saveStep &&
this.props.state === MOTOR_STATE.READY &&
this.props.inplace ? (
<span className="ms-2 me-2">
{this.props.step} {suffix}
</span>
) : null}
</div>
))}
</div>
</form>
{this.props.inplace && (
Expand Down
96 changes: 44 additions & 52 deletions ui/src/components/PopInput/NumericInput.jsx
Original file line number Diff line number Diff line change
@@ -1,68 +1,60 @@
import React from 'react';
import { Form, InputGroup, Button, ButtonToolbar } from 'react-bootstrap';
import ReactNumericInput from 'react-numeric-input';
import { Form, Button, ButtonToolbar } from 'react-bootstrap';
import RcInputNumber from 'rc-input-number';
import { TiTick, TiTimes } from 'react-icons/ti';

export default class NumericInput extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.inputRef = React.createRef();
}
function NumericInput(props) {
const { initialValue, precision, step, size, busy, onCancel, onSubmit } =
props;

handleSubmit(evt) {
function handleSubmit(evt) {
evt.preventDefault();
if (!this.props.busy) {
this.props.onSubmit(this.inputRef.current.state.value);

if (!busy) {
const formData = new FormData(evt.currentTarget);
const val = formData.get('value');
const parsedVal = Number.parseFloat(val);

onSubmit(Number.isNaN(parsedVal) ? initialValue : parsedVal);
}
}

render() {
return (
<Form className="popinput" onSubmit={this.handleSubmit} noValidate>
<InputGroup>
{this.props.busy ? (
<div className="popinput-input-busy" />
) : (
<ReactNumericInput
ref={this.inputRef}
className="popinput-input"
size={this.props.inputSize}
precision={this.props.precision}
value={this.props.value}
step={this.props.step}
/>
)}
<ButtonToolbar className="ms-1">
{!this.props.busy && (
<Button type="submit" variant="success" size="sm">
<TiTick size="1.5em" />
</Button>
)}
{!this.props.inplace && (
<Button
variant={this.props.busy ? 'danger' : 'outline-secondary'}
size="sm"
className="ms-1"
onClick={() => this.props.onCancel()}
>
<TiTimes size="1.5em" />
</Button>
)}
</ButtonToolbar>
</InputGroup>
</Form>
);
}
return (
<Form className="popinput-form" onSubmit={handleSubmit} noValidate>
<RcInputNumber
name="value"
className="popinput-input"
defaultValue={initialValue}
precision={precision}
step={step}
size={size}
disabled={busy}
upHandler={<i aria-hidden="true" className="fas fa-caret-up" />}
downHandler={<i aria-hidden="true" className="fas fa-caret-down" />}
/>
<ButtonToolbar className="ms-1">
{busy ? (
<Button variant="danger" size="sm" onClick={() => onCancel()}>
<TiTimes size="1.5em" />
</Button>
) : (
<Button type="submit" variant="success" size="sm">
<TiTick size="1.5em" />
</Button>
)}
</ButtonToolbar>
</Form>
);
}

NumericInput.defaultProps = {
inputSize: '3',
step: 0.1,
inplace: false,
initialValue: 0,
precision: 3,
value: 0,
step: 0.1,
size: 5,
busy: false,
onCancel: undefined,
onSubmit: undefined,
};

export default NumericInput;
Loading

0 comments on commit 0094b6c

Please sign in to comment.