diff --git a/src/components/Dropdown.js b/src/components/Dropdown.js
index f325c4f4..cfb80fb5 100644
--- a/src/components/Dropdown.js
+++ b/src/components/Dropdown.js
@@ -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 {
@@ -63,6 +64,7 @@ function Dropdown(props) {
disabled,
validate,
validateData,
+ onChange: propsOnChange,
testId,
__internal__focus,
__internal__open,
@@ -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(
@@ -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,
});
@@ -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");
@@ -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,
diff --git a/src/components/Dropdown.test.js b/src/components/Dropdown.test.js
index 771c1f73..7b7b67a7 100644
--- a/src/components/Dropdown.test.js
+++ b/src/components/Dropdown.test.js
@@ -140,6 +140,27 @@ describe("Dropdown", () => {
});
});
+ it("with onChange", () => {
+ const onChange = jest.fn();
+
+ render();
+
+ 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();
diff --git a/src/components/Select.js b/src/components/Select.js
index 99ccf302..af7303fe 100644
--- a/src/components/Select.js
+++ b/src/components/Select.js
@@ -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 {
@@ -56,6 +57,7 @@ function Select(props) {
optional,
validate,
validateData,
+ onChange: propsOnChange,
testId,
__internal__focus,
} = mergedProps;
@@ -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 (
{
});
});
+ it("with onChange", () => {
+ const onChange = jest.fn();
+
+ render();
+
+ 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(