Skip to content

Commit

Permalink
Add onChange prop to Select and Dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
moroshko committed Oct 4, 2020
1 parent ddb6620 commit ba819c6
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 32 deletions.
42 changes: 21 additions & 21 deletions src/components/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function Dropdown(props) {
helpText: (helpText) => typeof helpText === "string",
disabled: (disabled) => typeof disabled === "boolean",
options: (options) => areDropdownOptionsValid(options),
onChange: (onChange) => typeof onChange === "function",
}
);
const {
Expand All @@ -63,6 +64,7 @@ function Dropdown(props) {
disabled,
validate,
validateData,
onChange: propsOnChange,
testId,
__internal__focus,
__internal__open,
Expand All @@ -87,16 +89,20 @@ function Dropdown(props) {
}),
[isEmpty, validateData]
);
const { value, errors, hasErrors, onFocus, onBlur, onChange } = useField(
"Dropdown",
{
name,
disabled,
optional: false,
validate,
data,
}
);
const {
value,
errors,
hasErrors,
onFocus,
onBlur,
onChange: fieldOnChange,
} = useField("Dropdown", {
name,
disabled,
optional: false,
validate,
data,
});
const windowFromContext = useWindow();
const buttonRef = useRef();
const itemToString = useCallback(
Expand All @@ -118,10 +124,12 @@ function Dropdown(props) {
itemToString,
initialSelectedItem,
onSelectedItemChange: ({ selectedItem: selectedOption }) => {
onChange({
fieldOnChange({
target: buttonRef.current,
value: selectedOption.value,
});

propsOnChange && propsOnChange({ selectedOption });
},
environment: windowFromContext,
});
Expand All @@ -132,21 +140,12 @@ function Dropdown(props) {
getToggleButtonProps({
onFocus,
onBlur,
onChange,
disabled,
"aria-invalid": isValid ? null : "true",
"aria-describedby": describedBy,
ref: buttonRef,
}),
[
getToggleButtonProps,
onFocus,
onBlur,
onChange,
disabled,
isValid,
describedBy,
]
[getToggleButtonProps, onFocus, onBlur, disabled, isValid, describedBy]
);
const maxHeightProps = useAllResponsiveProps(props, "maxHeight");

Expand Down Expand Up @@ -203,6 +202,7 @@ Dropdown.propTypes = {
...responsiveMaxHeightType,
validate: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
validateData: PropTypes.any,
onChange: PropTypes.func,
testId: PropTypes.string,
__internal__focus: PropTypes.bool,
__internal__open: PropTypes.bool,
Expand Down
21 changes: 21 additions & 0 deletions src/components/Dropdown.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,27 @@ describe("Dropdown", () => {
});
});

it("with onChange", () => {
const onChange = jest.fn();

render(<FormWithDropdown onChange={onChange} />);

const button = screen.getByRole("button", { name: /Please select/ });

userEvent.click(button);
userEvent.click(screen.getByText("Movie 2"));

expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toBeCalledWith({
selectedOption: {
data: {
name: "Movie 2",
},
value: "movie-2",
},
});
});

it("with testId", () => {
const { container } = render(<FormWithDropdown testId="my-dropdown" />);

Expand Down
35 changes: 25 additions & 10 deletions src/components/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ function Select(props) {
disabled: (disabled) => typeof disabled === "boolean",
optional: (optional) => typeof optional === "boolean",
options: (options) => areOptionsValid(options),
onChange: (onChange) => typeof onChange === "function",
}
);
const {
Expand All @@ -56,6 +57,7 @@ function Select(props) {
optional,
validate,
validateData,
onChange: propsOnChange,
testId,
__internal__focus,
} = mergedProps;
Expand All @@ -79,16 +81,28 @@ function Select(props) {
}),
[isEmpty, validateData]
);
const { value, errors, hasErrors, onFocus, onBlur, onChange } = useField(
"Select",
{
name,
disabled,
optional,
validate,
data,
}
);
const {
value,
errors,
hasErrors,
onFocus,
onBlur,
onChange: fieldOnChange,
} = useField("Select", {
name,
disabled,
optional,
validate,
data,
});
const onChange = (event) => {
fieldOnChange(event);

const selectedValue = event.target.value;
const selectedOption = options.find(({ value }) => value === selectedValue);

propsOnChange && propsOnChange({ selectedOption });
};

return (
<Field
Expand Down Expand Up @@ -140,6 +154,7 @@ Select.propTypes = {
optional: PropTypes.bool,
validate: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
validateData: PropTypes.any,
onChange: PropTypes.func,
testId: PropTypes.string,
__internal__focus: PropTypes.bool,
};
Expand Down
20 changes: 19 additions & 1 deletion src/components/Select.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { render, screen } from "../utils/test";
import { render, screen, userEvent } from "../utils/test";
import "@testing-library/jest-dom/extend-expect";
import Form from "./Form";
import Select from "./Select";
Expand Down Expand Up @@ -131,6 +131,24 @@ describe("Select", () => {
});
});

it("with onChange", () => {
const onChange = jest.fn();

render(<FormWithSelect label="Relationship status" onChange={onChange} />);

const select = screen.getByDisplayValue("Please select");

userEvent.selectOptions(select, "married");

expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toBeCalledWith({
selectedOption: {
label: "Married",
value: "married",
},
});
});

it("with testId", () => {
const { container } = render(
<FormWithSelect label="Relationship status" testId="my-select" />
Expand Down

0 comments on commit ba819c6

Please sign in to comment.