CEC-5436: add release_notes, update_duration, and max_attempts to manifest update form (#489)
This commit is contained in:
44
src/components/Controls/NumberField/NumberField.jsx
Normal file
44
src/components/Controls/NumberField/NumberField.jsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import {
|
||||
Box,
|
||||
FormControl,
|
||||
FormHelperText,
|
||||
Input,
|
||||
InputLabel,
|
||||
} from "@material-ui/core";
|
||||
|
||||
const PREFIX = "number-field";
|
||||
|
||||
function kebab(str) {
|
||||
return str.replaceAll(" ", "-").toLowerCase();
|
||||
}
|
||||
|
||||
export function NumberField({
|
||||
name,
|
||||
description,
|
||||
value = 0,
|
||||
setValue = () => { },
|
||||
...rest
|
||||
}) {
|
||||
const inputId = `${PREFIX}-${kebab(name)}`;
|
||||
const describeId = `${PREFIX}-${kebab(name)}-describe`;
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValue(event.target.value);
|
||||
}
|
||||
return (
|
||||
<Box sx={{ my: 2 }}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel htmlFor={inputId}>{name}</InputLabel>
|
||||
<Input
|
||||
id={inputId}
|
||||
aria-describedby={describeId}
|
||||
type="number"
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
{...rest}
|
||||
/>
|
||||
<FormHelperText id={describeId}>{description}</FormHelperText>
|
||||
</FormControl>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
55
src/components/Controls/NumberField/NumberField.test.jsx
Normal file
55
src/components/Controls/NumberField/NumberField.test.jsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import React from "react";
|
||||
import { fireEvent, render } from "@testing-library/react";
|
||||
|
||||
import { NumberField } from "./index";
|
||||
|
||||
describe("NumberField", () => {
|
||||
it("renders with form label and aria describe", () => {
|
||||
const { getByText } = render(
|
||||
<NumberField
|
||||
name="My First Field"
|
||||
description="Some helper text"
|
||||
/>
|
||||
);
|
||||
|
||||
const labelEl = getByText("My First Field");
|
||||
const describeEl = getByText("Some helper text");
|
||||
|
||||
expect(labelEl.htmlFor).toEqual("number-field-my-first-field");
|
||||
expect(describeEl.id).toEqual("number-field-my-first-field-describe");
|
||||
});
|
||||
|
||||
it("input is of type number", () => {
|
||||
const { getByLabelText } = render(
|
||||
<NumberField
|
||||
name="My First Field"
|
||||
description="Some helper text"
|
||||
/>
|
||||
);
|
||||
|
||||
const inputEl = getByLabelText("My First Field", { selector: "input" });
|
||||
|
||||
expect(inputEl.type).toEqual("number");
|
||||
});
|
||||
|
||||
it("updates parent state", () => {
|
||||
let mockState = 0;
|
||||
const mockSetState = jest.fn((value) => mockState = value);
|
||||
|
||||
const { getByLabelText } = render(
|
||||
<NumberField
|
||||
name="My First Field"
|
||||
description="Enter a number"
|
||||
value={mockState}
|
||||
setValue={mockSetState}
|
||||
/>
|
||||
);
|
||||
|
||||
const inputEl = getByLabelText("My First Field", { selector: "input" });
|
||||
|
||||
fireEvent.change(inputEl, { target: { value: "1" } });
|
||||
|
||||
expect(mockState).toEqual("1");
|
||||
expect(mockSetState.mock.calls.length).toEqual(1);
|
||||
});
|
||||
})
|
||||
1
src/components/Controls/NumberField/index.jsx
Normal file
1
src/components/Controls/NumberField/index.jsx
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./NumberField";
|
||||
Reference in New Issue
Block a user