1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2024-12-25 00:11:36 +01:00

Merge branch '89-arrows-number-input' into 'dev'

Disable default styles for number input

See merge request turris/reforis/foris-js!5
This commit is contained in:
Maciej Lenartowicz 2019-09-25 11:59:45 +00:00
commit 8296c6129e
6 changed files with 105 additions and 13 deletions

View File

@ -60,6 +60,7 @@
"scripts": { "scripts": {
"watch": "babel src --verbose --watch --out-dir dist --ignore '**/__tests__' --source-maps inline", "watch": "babel src --verbose --watch --out-dir dist --ignore '**/__tests__' --source-maps inline",
"build": "rm -rf dist; babel src --out-dir dist --ignore '**/__tests__' --source-maps inline", "build": "rm -rf dist; babel src --out-dir dist --ignore '**/__tests__' --source-maps inline",
"build:watch": "babel src --verbose --watch --out-dir dist --ignore '**/__tests__' --source-maps inline",
"prepare": "rm -rf ./dist && npm run build", "prepare": "rm -rf ./dist && npm run build",
"lint": "eslint src", "lint": "eslint src",
"test": "jest", "test": "jest",

View File

@ -10,8 +10,6 @@ import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { Input } from "./Input"; import { Input } from "./Input";
export const NumberInput = ({ ...props }) => <Input type="number" {...props} />;
NumberInput.propTypes = { NumberInput.propTypes = {
/** Field label. */ /** Field label. */
label: PropTypes.string.isRequired, label: PropTypes.string.isRequired,
@ -24,4 +22,38 @@ NumberInput.propTypes = {
PropTypes.string, PropTypes.string,
PropTypes.number, PropTypes.number,
]), ]),
/** Function called when value changes. */
onChange: PropTypes.func.isRequired,
/** Additional description dispaled to the right of input value. */
inlineText: PropTypes.string,
}; };
NumberInput.defaultProps = {
value: 0,
};
export function NumberInput({ onChange, inlineText, ...props }) {
return (
<Input type="number" onChange={onChange} {...props}>
<div className="input-group-append">
{inlineText && <p className="input-group-text">{inlineText}</p>}
<button
type="button"
className="btn btn-outline-secondary"
onClick={() => onChange({ target: { value: props.value + 1 } })}
aria-label="Increase"
>
<i className="fas fa-plus" />
</button>
<button
type="button"
className="btn btn-outline-secondary"
onClick={() => onChange({ target: { value: props.value - 1 } })}
aria-label="Decrease"
>
<i className="fas fa-minus" />
</button>
</div>
</Input>
);
}

View File

@ -7,23 +7,39 @@
import React from "react"; import React from "react";
import { render } from "customTestRender"; import { render, fireEvent } from "customTestRender";
import { NumberInput } from "../NumberInput"; import { NumberInput } from "../NumberInput";
describe("<NumberInput/>", () => { describe("<NumberInput/>", () => {
it("Render number input", () => { const onChangeMock = jest.fn();
const { container } = render( let container;
let getByLabelText;
beforeEach(() => {
({ container, getByLabelText } = render(
<NumberInput <NumberInput
label="Test label" label="Test label"
helpText="Some help text" helpText="Some help text"
value={1123} value={1}
onChange={() => { onChange={onChangeMock}
}}
/> />
); ));
expect(container.firstChild) });
.toMatchSnapshot();
it("Render number input", () => {
expect(container.firstChild).toMatchSnapshot();
});
it("Increase number with button", () => {
const increaseButton = getByLabelText("Increase");
fireEvent.click(increaseButton);
expect(onChangeMock).toHaveBeenCalledWith({"target": {"value": 2}});
});
it("Decrease number with button", () => {
const decreaseButton = getByLabelText("Decrease");
fireEvent.click(decreaseButton);
expect(onChangeMock).toHaveBeenCalledWith({"target": {"value": 0}});
}); });
}); });

View File

@ -19,8 +19,30 @@ exports[`<NumberInput/> Render number input 1`] = `
class="form-control" class="form-control"
id="1" id="1"
type="number" type="number"
value="1123" value="1"
/> />
<div
class="input-group-append"
>
<button
aria-label="Increase"
class="btn btn-outline-secondary"
type="button"
>
<i
class="fas fa-plus"
/>
</button>
<button
aria-label="Decrease"
class="btn btn-outline-secondary"
type="button"
>
<i
class="fas fa-minus"
/>
</button>
</div>
</div> </div>
<small <small
class="form-text text-muted" class="form-text text-muted"

View File

@ -40,6 +40,7 @@ export { WebSockets } from "webSockets/WebSockets";
// Utils // Utils
export { Portal } from "utils/Portal"; export { Portal } from "utils/Portal";
export { undefinedIfEmpty, withoutUndefinedKeys } from "utils/objectHelpers";
// Foris URL // Foris URL
export { ForisURLs, REFORIS_URL_PREFIX } from "forisUrls"; export { ForisURLs, REFORIS_URL_PREFIX } from "forisUrls";

View File

@ -0,0 +1,20 @@
/** Return undefined if object has no keys, otherwise return object. */
export function undefinedIfEmpty(instance) {
if (Object.keys(instance).length > 0) {
return instance;
}
return undefined;
}
/** Return object without keys that have undefined value. */
export function withoutUndefinedKeys(instance) {
return Object.keys(instance).reduce(
(accumulator, key) => {
if (instance[key] !== undefined) {
accumulator[key] = instance[key];
}
return accumulator;
},
{},
);
}