Skip to content
Closed
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
27 changes: 18 additions & 9 deletions playbook/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ type DropdownProps = {
isClosed?: boolean;
label?: string;
multiSelect?: boolean;
name?: string;
onChange?: (event: { target: { name?: string; value: any } }) => void;
onSelect?: (arg: GenericObject) => null;
options?: GenericObject;
placeholder?: string;
Expand Down Expand Up @@ -156,6 +158,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
label,
multiSelect = false,
formPillProps,
name,
onChange,
onSelect,
options,
placeholder,
Expand Down Expand Up @@ -414,6 +418,10 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
setIsDropDownClosed(false);
};

const handleSelectionChange = (value: any) => {
onSelect && onSelect(value);
onChange && onChange({ target: { name, value } });
};

const handleOptionClick = (clickedItem: GenericObject) => {
if (disabled) return;
Expand All @@ -426,7 +434,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
const next = exists
? list.filter((option) => option.value !== clickedItem.value)
: [...list, clickedItem];
onSelect && onSelect(next);
handleSelectionChange(next);
return next;
});
setFilterItem("");
Expand All @@ -439,7 +447,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
if (shouldCloseOnClick) {
setIsDropDownClosed(true);
}
onSelect && onSelect(clickedItem);
handleSelectionChange(clickedItem);

// Sync with DatePickers if this is a quickpick variant
if (variant === "quickpick" && Array.isArray(clickedItem.value)) {
Expand Down Expand Up @@ -468,10 +476,10 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
if (disabled) return;
if (multiSelect) {
setSelected([]);
onSelect && onSelect([]);
handleSelectionChange([]);
} else {
setSelected({});
onSelect && onSelect(null);
handleSelectionChange(null);
setFocusedOptionIndex(-1);
setFilterItem("");

Expand Down Expand Up @@ -505,10 +513,10 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
clearSelected: () => {
if (multiSelect) {
setSelected([]);
onSelect && onSelect([]);
handleSelectionChange([]);
} else {
setSelected({});
onSelect && onSelect(null);
handleSelectionChange(null);
}
setFilterItem("");
setIsDropDownClosed(true);
Expand All @@ -522,16 +530,16 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
clearSelected: () => {
if (multiSelect) {
setSelected([]);
onSelect && onSelect([]);
handleSelectionChange([]);
} else {
setSelected({});
onSelect && onSelect(null);
handleSelectionChange(null);
}
setFilterItem("");
setIsDropDownClosed(true);
},
};
}, [multiSelect, onSelect, setSelected, setFilterItem, setIsDropDownClosed]);
}, [multiSelect, handleSelectionChange, setSelected, setFilterItem, setIsDropDownClosed]);

useImperativeHandle(ref, () => imperativeRef.current);

Expand Down Expand Up @@ -594,6 +602,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
handleBackspace,
handleChange,
handleOptionClick,
handleSelectionChange,
handleWrapperClick,
inputRef,
inputWrapperRef,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react'

import Dropdown from '../_dropdown'
import Title from '../../pb_title/_title'
import { useForm } from 'react-hook-form'

const options = [
{ label: 'United States', value: 'unitedStates', id: 'us' },
{ label: 'United Kingdom', value: 'unitedKingdom', id: 'gb' },
{ label: 'Canada', value: 'canada', id: 'ca' },
{ label: 'Pakistan', value: 'pakistan', id: 'pk' },
{ label: 'India', value: 'india', id: 'in' },
{ label: 'Australia', value: 'australia', id: 'au' },
{ label: 'New Zealand', value: 'new Zealand', id: 'nz' },
{ label: 'Italy', value: 'italy', id: 'it' },
{ label: 'Spain', value: 'spain', id: 'es' },
]

const DropdownMultiSelectReactHook = (props) => {
const { register, watch } = useForm()

const selectedCountries = watch('countries')

return (
<>
<Dropdown
label="Countries"
multiSelect
options={options}
{...props}
{...register('countries')}
/>
<Title
marginTop="sm"
size={4}
text="Selected Countries"
/>
{selectedCountries && selectedCountries.map(country => (
<p key={country.id}>{`${country.label} - ${country.value}`}</p>
))}
</>
)
}

export default DropdownMultiSelectReactHook
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You can pass `react-hook-form` props to a multi-select Dropdown. Spread `register` onto Dropdown with `multiSelect` to keep the selected options array in form state.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react'

import Dropdown from '../_dropdown'
import Title from '../../pb_title/_title'
import { useForm } from 'react-hook-form'

const options = [
{ label: 'United States', value: 'unitedStates', id: 'us' },
{ label: 'Canada', value: 'canada', id: 'ca' },
{ label: 'Pakistan', value: 'pakistan', id: 'pk' },
]

const DropdownReactHook = (props) => {
const { register, watch } = useForm()

const selectedCountry = watch('country')

return (
<>
<Dropdown
label="Countries"
options={options}
{...props}
{...register('country')}
/>
<Title
marginTop="sm"
size={4}
text="Selected Country"
/>
<p>{selectedCountry && `${selectedCountry.label} - ${selectedCountry.value}`}</p>
</>
)
}

export default DropdownReactHook
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You can pass `react-hook-form` props to the Dropdown kit. Spread `register` onto a single-select Dropdown to keep the selected option in form state.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"name": "Content",
"props": [
"label",
"name",
"placeholder",
"options",
"defaultValue",
Expand Down Expand Up @@ -130,6 +131,7 @@
{
"name": "Events",
"props": [
"onChange",
"onSelect"
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"name": "Content",
"props": [
"label",
"name",
"placeholder",
"options",
"defaultValue",
Expand Down Expand Up @@ -111,7 +112,7 @@
},
{
"name": "Events",
"props": ["onSelect"]
"props": ["onChange", "onSelect"]
}
],
"presets": [
Expand Down
3 changes: 3 additions & 0 deletions playbook/app/pb_kits/playbook/pb_dropdown/docs/example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,6 @@ examples:
- dropdown_required_indicator: Required Indicator
- dropdown_disabled: Disabled Input
- dropdown_grouped_options: Grouped Options
- dropdown_react_hook: React Hook
- dropdown_multi_select_react_hook: React Hook Multi Select

2 changes: 2 additions & 0 deletions playbook/app/pb_kits/playbook/pb_dropdown/docs/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export { default as DropdownDefault } from './_dropdown_default.jsx'
export { default as DropdownReactHook } from './_dropdown_react_hook.jsx'
export { default as DropdownMultiSelectReactHook } from './_dropdown_multi_select_react_hook.jsx'
export { default as DropdownWithCustomDisplay } from './_dropdown_with_custom_display.jsx'
export { default as DropdownWithCustomOptions } from './_dropdown_with_custom_options.jsx'
export { default as DropdownWithCustomTrigger } from './_dropdown_with_custom_trigger.jsx'
Expand Down
Loading
Loading