Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Changed
- **Breaking** `keycloak-js` has been moved from a direct dependency to a peer and optional dependency, so must now be installed by the consuming application.
- Added submitOnBlur boolean prop to VisitInput which defaults to false.

### Fixed
- Icon imports were causing issues downstream when components are unit tested.
Expand Down
9 changes: 9 additions & 0 deletions src/components/controls/VisitInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ export const InitialVisitWithSubmitButton: Story = {
},
};

export const InitialVisitWithSubmitOnBlur: Story = {
args: {
onSubmit: handleSubmit,
visit: { proposalCode: "xx", proposalNumber: 99999, number: 7 },
submitButton: false,
submitOnBlur: true,
},
};

export const InitialVisitWithoutReturnKeySubmission: Story = {
args: {
onSubmit: handleSubmit,
Expand Down
111 changes: 111 additions & 0 deletions src/components/controls/VisitInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,114 @@ it("should update visit on submit", () => {
},
);
});

it("should not produce visit on blur by default", () => {
const onSubmit = vi.fn();
const { getByTestId } = render(<VisitInput onSubmit={onSubmit} />);
const visitField = within(getByTestId("visit-field")).getByRole("textbox");
fireEvent.change(visitField, { target: { value: "zz12345-7" } });
fireEvent.blur(visitField, {
key: "Enter",
code: "Enter",
keyCode: 13,
charCode: 13,
});
expect(onSubmit).not.toHaveBeenCalledWith(
{
proposalCode: "zz",
proposalNumber: 12345,
number: 7,
},
undefined,
);
});

it("should produce visit on blur without submit button", () => {
const onSubmit = vi.fn();
const { getByTestId } = render(
<VisitInput onSubmit={onSubmit} submitButton={false} submitOnBlur={true} />,
);
const visitField = within(getByTestId("visit-field")).getByRole("textbox");
fireEvent.change(visitField, { target: { value: "zz12345-7" } });
fireEvent.blur(visitField, {
key: "Enter",
code: "Enter",
keyCode: 13,
charCode: 13,
});
expect(onSubmit).toHaveBeenCalledWith(
{
proposalCode: "zz",
proposalNumber: 12345,
number: 7,
},
undefined,
);
});

it("should not produce visit on blur", () => {
const onSubmit = vi.fn();
const { getByTestId } = render(
<VisitInput onSubmit={onSubmit} submitOnBlur={false} />,
);
const visitField = within(getByTestId("visit-field")).getByRole("textbox");
fireEvent.change(visitField, { target: { value: "zz12345-7" } });
fireEvent.blur(visitField, {
key: "Enter",
code: "Enter",
keyCode: 13,
charCode: 13,
});
expect(onSubmit).not.toHaveBeenCalledWith(
{
proposalCode: "zz",
proposalNumber: 12345,
number: 7,
},
undefined,
);
});

it("should produce visit on blur", () => {
const onSubmit = vi.fn();
const { getByTestId } = render(
<VisitInput onSubmit={onSubmit} submitOnBlur={true} />,
);
const visitField = within(getByTestId("visit-field")).getByRole("textbox");
fireEvent.change(visitField, { target: { value: "zz12345-7" } });
fireEvent.blur(visitField, {
key: "Enter",
code: "Enter",
keyCode: 13,
charCode: 13,
});
expect(onSubmit).toHaveBeenCalledWith(
{
proposalCode: "zz",
proposalNumber: 12345,
number: 7,
},
undefined,
);
});

it("should not produce visit on blur with no onSubmit", () => {
const onSubmit = vi.fn();
const { getByTestId } = render(<VisitInput submitOnBlur={true} />);
const visitField = within(getByTestId("visit-field")).getByRole("textbox");
fireEvent.change(visitField, { target: { value: "zz12345-7" } });
fireEvent.blur(visitField, {
key: "Enter",
code: "Enter",
keyCode: 13,
charCode: 13,
});
expect(onSubmit).not.toHaveBeenCalledWith(
{
proposalCode: "zz",
proposalNumber: 12345,
number: 7,
},
undefined,
);
});
13 changes: 13 additions & 0 deletions src/components/controls/VisitInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface VisitInputTextProps {
setIsValid: (v: boolean) => void;
handleSubmit?: () => void;
submitOnReturn?: boolean;
submitOnBlur?: boolean;
}

const VisitInputText: React.FC<VisitInputTextProps> = ({
Expand All @@ -23,6 +24,7 @@ const VisitInputText: React.FC<VisitInputTextProps> = ({
setIsValid,
handleSubmit,
submitOnReturn,
submitOnBlur,
}) => {
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
Expand All @@ -36,12 +38,19 @@ const VisitInputText: React.FC<VisitInputTextProps> = ({
}
};

const handleBlur = () => {
if (submitOnBlur && handleSubmit) {
handleSubmit();
}
};

return (
<TextField
label="Visit"
value={visitText}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
onBlur={handleBlur}
error={!isValid}
helperText={!isValid ? "Invalid visit" : ""}
variant="outlined"
Expand All @@ -56,6 +65,7 @@ interface VisitInputProps {
parameters?: object;
submitButton?: boolean;
submitOnReturn?: boolean;
submitOnBlur?: boolean;
}

const VisitInput: React.FC<VisitInputProps> = ({
Expand All @@ -64,6 +74,7 @@ const VisitInput: React.FC<VisitInputProps> = ({
parameters,
submitButton = true,
submitOnReturn = true,
submitOnBlur = false,
}) => {
const [visitText, setVisitText] = useState(visitToText(visit));
const [isValid, setIsValid] = useState(true);
Expand All @@ -88,6 +99,7 @@ const VisitInput: React.FC<VisitInputProps> = ({
setIsValid={setIsValid}
handleSubmit={handleSubmit}
submitOnReturn={submitOnReturn}
submitOnBlur={submitOnBlur}
/>
<Button
variant="contained"
Expand All @@ -107,6 +119,7 @@ const VisitInput: React.FC<VisitInputProps> = ({
setIsValid={setIsValid}
handleSubmit={handleSubmit}
submitOnReturn={submitOnReturn}
submitOnBlur={submitOnBlur}
/>
)}
</>
Expand Down
Loading