diff --git a/packages/react/src/components/dropdown/Dropdown.stories.tsx b/packages/react/src/components/dropdown/Dropdown.stories.tsx
index 6d30d3e0dd..381ef6d9fa 100644
--- a/packages/react/src/components/dropdown/Dropdown.stories.tsx
+++ b/packages/react/src/components/dropdown/Dropdown.stories.tsx
@@ -1,7 +1,8 @@
-import React from 'react';
+import React, { useState } from 'react';
import { boolean, number, text, withKnobs } from '@storybook/addon-knobs';
import Dropdown from './Dropdown';
+import Button from '../button/Button';
const options = [
{ label: 'Plutonium' },
@@ -76,6 +77,50 @@ export const Multiselect = () => (
/>
);
+export const Controlled = () => {
+ const [selectedItem, setSelectedItem] = useState(null);
+ const [multiselectSelectedItem, setMultiselectSelectedItem] = useState(null);
+
+ const handleSelectedItemChange = (item) => setSelectedItem(item);
+ const handleMultiselectSelectedItemChange = (item) => setMultiselectSelectedItem(item);
+
+ return (
+ <>
+
+ {['Dropdown 1', 'Dropdown 2'].map((label) => (
+
+ ))}
+
+ {['Multiselect 1', 'Multiselect 2'].map((label) => (
+
+ ))}
+ >
+ );
+};
+
+Controlled.story = {
+ name: 'With controlled state',
+};
+
Multiselect.story = {
name: 'With multiselect',
};
diff --git a/packages/react/src/components/dropdown/Dropdown.tsx b/packages/react/src/components/dropdown/Dropdown.tsx
index 797a604542..8cdf62024f 100644
--- a/packages/react/src/components/dropdown/Dropdown.tsx
+++ b/packages/react/src/components/dropdown/Dropdown.tsx
@@ -113,6 +113,10 @@ export type DropdownProps = {
* If `true`, the label is displayed as required
*/
required?: boolean;
+ /**
+ * The option(s) that should be selected
+ */
+ selectedOption?: OptionType | OptionType[];
/**
* Override or extend the root styles applied to the component
*/
@@ -171,6 +175,7 @@ const Dropdown: FC = ({
options = [],
placeholder = '',
required,
+ selectedOption,
style,
toggleButtonId,
visibleOptions = 5,
@@ -188,6 +193,7 @@ const Dropdown: FC = ({
// init multi-select
const { getDropdownProps, addSelectedItem, removeSelectedItem, selectedItems } = useMultipleSelection({
initialSelectedItems: defaultValues,
+ ...(multiselect && selectedOption !== undefined && { selectedItems: (selectedOption as OptionType[]) ?? [] }),
onSelectedItemsChange: ({ selectedItems: _selectedItems }) => multiselect && onChange(_selectedItems),
});
@@ -233,6 +239,9 @@ const Dropdown: FC = ({
onSelectedItemChange: ({ selectedItem }) => !multiselect && onChange(selectedItem),
// selected items are handled by stateReducer when multiselect is enabled
...(multiselect && { selectedItem: null }),
+ // a value for selectedOption indicates that the dropdown should be controlled
+ // don't set selectedItem if it's not, so that downshift can control the selected item(s)
+ ...(!multiselect && selectedOption !== undefined && { selectedItem: selectedOption }),
stateReducer,
toggleButtonId,
};