playbook_ui 14.19.0 β 14.20.0.pre.alpha.PLAY2127dropdowncloseonselectionpropreact8006
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +11 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +175 -16
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +56 -25
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +23 -13
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/VisibilityTree.ts +47 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +14 -10
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +7 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +16 -8
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +9 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +6 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.jsx +57 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.md +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.jsx +62 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.jsx +82 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.jsx +66 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_default.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.html.erb +137 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.html.erb +40 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +6 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +5 -1
- data/app/pb_kits/playbook/pb_advanced_table/index.js +155 -12
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.html.erb +23 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.rb +19 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +4 -0
- data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +4 -11
- data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +10 -6
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +2 -48
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate_rails.md +1 -0
- data/app/pb_kits/playbook/pb_checkbox/index.js +56 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +1 -1
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +86 -19
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.jsx +42 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.html.erb +31 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.md +5 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.jsx +56 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.jsx +58 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.html.erb +20 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.html.erb +19 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.html.erb +20 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.jsx +57 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.html.erb +50 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.jsx +105 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.html.erb +22 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.jsx +67 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +11 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.md +1 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +33 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.md +3 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +13 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +6 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +16 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +108 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +34 -13
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +3 -1
- data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +0 -6
- data/app/pb_kits/playbook/pb_dropdown/index.js +359 -29
- data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +39 -12
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +2 -2
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +26 -18
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +97 -20
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/MultiSelectTriggerDisplay.tsx +58 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +13 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.tsx +11 -1
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.html.erb +1 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.jsx +41 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +1 -0
- data/app/pb_kits/playbook/pb_file_upload/file_upload.rb +7 -1
- data/app/pb_kits/playbook/pb_file_upload/fileupload.test.js +18 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +1 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -0
- data/app/pb_kits/playbook/pb_form_group/_error_state_mixin.scss +2 -2
- data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +19 -12
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +13 -7
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +2 -2
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_color.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_color.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_hook.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_reset.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.md +2 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids_react.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids_react.md +3 -1
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.html.erb +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.jsx +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single_children_only.html.erb +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single_children_only.jsx +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children_with_radios.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_form.html.erb +11 -11
- data/app/pb_kits/playbook/pb_person/_person.tsx +12 -2
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +9 -9
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +4 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.html.erb +4 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.jsx +15 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.md +1 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_only_countries.jsx +1 -1
- data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +4 -3
- data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
- data/app/pb_kits/playbook/pb_section_separator/_section_separator.tsx +2 -2
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.html.erb +12 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.jsx +31 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.md +1 -0
- data/app/pb_kits/playbook/pb_select/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.html.erb +3 -51
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +4 -2
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +73 -3
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_preserve_input.jsx +23 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_preserve_input.md +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
- data/dist/chunks/_typeahead-CRW6dJbW.js +22 -0
- data/dist/chunks/_weekday_stacked-fRmhq4xQ.js +45 -0
- data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
- data/dist/chunks/lib-D5R1BjUn.js +29 -0
- data/dist/chunks/{pb_form_validation-BioH7DWv.js β pb_form_validation-BZ2AVAi_.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +1 -1
- data/dist/playbook-doc.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/kit_base.rb +3 -3
- data/lib/playbook/version.rb +2 -2
- metadata +54 -8
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.html.erb +0 -10
- data/dist/chunks/_typeahead-D62OcwsT.js +0 -22
- data/dist/chunks/_weekday_stacked-Ceh9N0ow.js +0 -45
- data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
- data/dist/chunks/lib-CeKZrPmu.js +0 -29
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle } from "react";
|
1
|
+
import React, { useState, useRef, useEffect, forwardRef, useImperativeHandle, useMemo } from "react";
|
2
2
|
import classnames from "classnames";
|
3
3
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
|
4
4
|
import { globalProps } from "../utilities/globalProps";
|
@@ -25,6 +25,8 @@ type DropdownProps = {
|
|
25
25
|
blankSelection?: string;
|
26
26
|
children?: React.ReactChild[] | React.ReactChild | React.ReactElement[];
|
27
27
|
className?: string;
|
28
|
+
closeOnSelection?: boolean;
|
29
|
+
formPillProps?: GenericObject;
|
28
30
|
dark?: boolean;
|
29
31
|
data?: { [key: string]: string };
|
30
32
|
defaultValue?: GenericObject;
|
@@ -33,6 +35,7 @@ type DropdownProps = {
|
|
33
35
|
id?: string;
|
34
36
|
isClosed?: boolean;
|
35
37
|
label?: string;
|
38
|
+
multiSelect?: boolean;
|
36
39
|
onSelect?: (arg: GenericObject) => null;
|
37
40
|
options: GenericObject;
|
38
41
|
separators?: boolean;
|
@@ -53,6 +56,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
53
56
|
blankSelection = '',
|
54
57
|
children,
|
55
58
|
className,
|
59
|
+
closeOnSelection = true,
|
56
60
|
dark = false,
|
57
61
|
data = {},
|
58
62
|
defaultValue = {},
|
@@ -61,6 +65,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
61
65
|
id,
|
62
66
|
isClosed = true,
|
63
67
|
label,
|
68
|
+
multiSelect = false,
|
69
|
+
formPillProps,
|
64
70
|
onSelect,
|
65
71
|
options,
|
66
72
|
separators = true,
|
@@ -80,7 +86,20 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
80
86
|
const [isDropDownClosed, setIsDropDownClosed, toggleDropdown] = useDropdown(isClosed);
|
81
87
|
|
82
88
|
const [filterItem, setFilterItem] = useState("");
|
83
|
-
const
|
89
|
+
const initialSelected = useMemo(() => {
|
90
|
+
if (multiSelect) {
|
91
|
+
if (Array.isArray(defaultValue)) return defaultValue;
|
92
|
+
return defaultValue && Object.keys(defaultValue).length
|
93
|
+
? [defaultValue]
|
94
|
+
: [];
|
95
|
+
}
|
96
|
+
return defaultValue || {};
|
97
|
+
}, [multiSelect, defaultValue]);
|
98
|
+
|
99
|
+
const [selected, setSelected] = useState<GenericObject | GenericObject[]>(
|
100
|
+
initialSelected
|
101
|
+
);
|
102
|
+
|
84
103
|
const [isInputFocused, setIsInputFocused] = useState(false);
|
85
104
|
const [hasTriggerSubcomponent, setHasTriggerSubcomponent] = useState(true);
|
86
105
|
const [hasContainerSubcomponent, setHasContainerSubcomponent] =
|
@@ -93,6 +112,12 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
93
112
|
const inputWrapperRef = useRef(null);
|
94
113
|
const dropdownContainerRef = useRef(null);
|
95
114
|
|
115
|
+
const selectedArray = Array.isArray(selected)
|
116
|
+
? selected
|
117
|
+
: selected && Object.keys(selected).length
|
118
|
+
? [selected]
|
119
|
+
: [];
|
120
|
+
|
96
121
|
const { trigger, container, otherChildren } =
|
97
122
|
separateChildComponents(children);
|
98
123
|
|
@@ -124,16 +149,23 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
124
149
|
|
125
150
|
const blankSelectionOption: GenericObject = blankSelection ? [{ label: blankSelection, value: "" }] : [];
|
126
151
|
const optionsWithBlankSelection = blankSelectionOption.concat(options);
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
152
|
+
|
153
|
+
const availableOptions = useMemo(()=> {
|
154
|
+
if (!multiSelect) return optionsWithBlankSelection;
|
155
|
+
return optionsWithBlankSelection.filter((option: GenericObject) => !selectedArray.some((sel) => sel.label === option.label));
|
156
|
+
}, [optionsWithBlankSelection, selectedArray, multiSelect]);
|
157
|
+
|
158
|
+
const filteredOptions = useMemo(() => {
|
159
|
+
return availableOptions.filter((opt: GenericObject) =>
|
160
|
+
String(opt.label).toLowerCase().includes(filterItem.toLowerCase())
|
161
|
+
);
|
162
|
+
}, [availableOptions, filterItem]);
|
131
163
|
|
132
164
|
// For keyboard accessibility: Set focus within dropdown to selected item if it exists
|
133
165
|
useEffect(() => {
|
134
166
|
if (!isDropDownClosed) {
|
135
167
|
let newIndex = 0;
|
136
|
-
if (selected && selected
|
168
|
+
if (selected && !Array.isArray(selected) && selected.label) {
|
137
169
|
const selectedIndex = filteredOptions.findIndex((option: GenericObject) => option.label === selected.label);
|
138
170
|
if (selectedIndex >= 0) {
|
139
171
|
newIndex = selectedIndex;
|
@@ -149,12 +181,33 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
149
181
|
setIsDropDownClosed(false);
|
150
182
|
};
|
151
183
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
184
|
+
|
185
|
+
const handleOptionClick = (clickedItem: GenericObject) => {
|
186
|
+
if (multiSelect) {
|
187
|
+
setSelected((prev) => {
|
188
|
+
const list = prev as GenericObject[];
|
189
|
+
const exists = list.find((option) => option.value === clickedItem.value);
|
190
|
+
const next = exists
|
191
|
+
? list.filter((option) => option.value !== clickedItem.value)
|
192
|
+
: [...list, clickedItem];
|
193
|
+
onSelect && onSelect(next);
|
194
|
+
return next;
|
195
|
+
});
|
196
|
+
setFilterItem("");
|
197
|
+
// Only close dropdown if closeOnSelection is true
|
198
|
+
if (closeOnSelection) {
|
199
|
+
setIsDropDownClosed(true);
|
200
|
+
}
|
201
|
+
} else {
|
202
|
+
setSelected(clickedItem);
|
203
|
+
setFilterItem("");
|
204
|
+
onSelect && onSelect(clickedItem);
|
205
|
+
// Only close dropdown if closeOnSelection is true
|
206
|
+
if (closeOnSelection) {
|
207
|
+
setIsDropDownClosed(true);
|
208
|
+
}
|
209
|
+
}
|
210
|
+
};
|
158
211
|
|
159
212
|
const handleWrapperClick = () => {
|
160
213
|
autocomplete && inputRef?.current?.focus();
|
@@ -162,9 +215,14 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
162
215
|
};
|
163
216
|
|
164
217
|
const handleBackspace = () => {
|
218
|
+
if (multiSelect) {
|
219
|
+
setSelected([]);
|
220
|
+
onSelect && onSelect([]);
|
221
|
+
} else {
|
165
222
|
setSelected({});
|
166
223
|
onSelect && onSelect(null);
|
167
224
|
setFocusedOptionIndex(-1);
|
225
|
+
}
|
168
226
|
};
|
169
227
|
|
170
228
|
const componentsToRender = prepareSubcomponents({
|
@@ -178,12 +236,17 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
178
236
|
});
|
179
237
|
|
180
238
|
useImperativeHandle(ref, () => ({
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
239
|
+
clearSelected: () => {
|
240
|
+
if (multiSelect) {
|
241
|
+
setSelected([]);
|
242
|
+
onSelect && onSelect([]);
|
243
|
+
} else {
|
244
|
+
setSelected({});
|
245
|
+
onSelect && onSelect(null);
|
246
|
+
}
|
247
|
+
setFilterItem("");
|
248
|
+
setIsDropDownClosed(true);
|
249
|
+
},
|
187
250
|
}));
|
188
251
|
|
189
252
|
return (
|
@@ -197,10 +260,12 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
197
260
|
<DropdownContext.Provider
|
198
261
|
value={{
|
199
262
|
autocomplete,
|
263
|
+
closeOnSelection,
|
200
264
|
dropdownContainerRef,
|
201
265
|
filteredOptions,
|
202
266
|
filterItem,
|
203
267
|
focusedOptionIndex,
|
268
|
+
formPillProps,
|
204
269
|
handleBackspace,
|
205
270
|
handleChange,
|
206
271
|
handleOptionClick,
|
@@ -209,6 +274,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
209
274
|
inputWrapperRef,
|
210
275
|
isDropDownClosed,
|
211
276
|
isInputFocused,
|
277
|
+
multiSelect,
|
278
|
+
onSelect,
|
212
279
|
optionsWithBlankSelection,
|
213
280
|
selected,
|
214
281
|
setFocusedOptionIndex,
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
3
|
+
|
4
|
+
const DropdownCloseOnSelect = (props) => {
|
5
|
+
|
6
|
+
const options = [
|
7
|
+
{
|
8
|
+
label: "United States",
|
9
|
+
value: "United States",
|
10
|
+
},
|
11
|
+
{
|
12
|
+
label: "Canada",
|
13
|
+
value: "Canada",
|
14
|
+
},
|
15
|
+
{
|
16
|
+
label: "Pakistan",
|
17
|
+
value: "Pakistan",
|
18
|
+
}
|
19
|
+
];
|
20
|
+
|
21
|
+
|
22
|
+
return (
|
23
|
+
<div>
|
24
|
+
<Dropdown
|
25
|
+
closeOnSelection={false}
|
26
|
+
label="Default"
|
27
|
+
options={options}
|
28
|
+
{...props}
|
29
|
+
/>
|
30
|
+
<br />
|
31
|
+
<Dropdown
|
32
|
+
closeOnSelection={false}
|
33
|
+
label="Multi Select"
|
34
|
+
multiSelect
|
35
|
+
options={options}
|
36
|
+
{...props}
|
37
|
+
/>
|
38
|
+
</div>
|
39
|
+
)
|
40
|
+
}
|
41
|
+
|
42
|
+
export default DropdownCloseOnSelect
|
@@ -0,0 +1 @@
|
|
1
|
+
By default, the dropdown menu will close when a selection is made. You can prevent this behavior by using the `closeOnSelection` prop, which will leave the menu open after a selection is made when set to 'false'.
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<%
|
2
|
+
options = [
|
3
|
+
{ label: 'United States', value: 'United States', id: 'us' },
|
4
|
+
{ label: 'Canada', value: 'Canada', id: 'ca' },
|
5
|
+
{ label: 'Pakistan', value: 'Pakistan', id: 'pk' },
|
6
|
+
]
|
7
|
+
|
8
|
+
%>
|
9
|
+
|
10
|
+
<%
|
11
|
+
options2 = [
|
12
|
+
{ label: 'India', value: 'India', id: 'in' },
|
13
|
+
{ label: 'Mexico', value: 'Mexico', id: 'mx' },
|
14
|
+
{ label: 'Brazil', value: 'Brazil', id: 'br' },
|
15
|
+
{ label: 'Argentina', value: 'Argentina', id: 'ar' },
|
16
|
+
{ label: 'Colombia', value: 'Colombia', id: 'co' },
|
17
|
+
{ label: 'Chile', value: 'Chile', id: 'cl' },
|
18
|
+
{ label: 'Peru', value: 'Peru', id: 'pe' },
|
19
|
+
]
|
20
|
+
|
21
|
+
%>
|
22
|
+
|
23
|
+
<%= pb_rails("dropdown", props: {options: options}) %>
|
24
|
+
|
25
|
+
<script>
|
26
|
+
document.addEventListener("pb:dropdown:selected", (e) => {
|
27
|
+
const option = e.detail;
|
28
|
+
const dropdown = e.target;
|
29
|
+
console.log("Selected option:", option);
|
30
|
+
})
|
31
|
+
</script>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
This kit's `options` prop requires an array of objects, each of which will be used as the selectable options within the dropdown. Each option object can support any number of key-value pairs, but each MUST contain `label`, `value` and `id`.
|
2
|
+
|
3
|
+
The kit also comes with a custom event called "pb:dropdown:selected" which updates dynamically with the selection as it changes. See code snippet to see this in action.
|
4
|
+
|
5
|
+
In addition, a data attribute called `data-option-selected` with the selection is also rendered on the parent dropdown div.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
3
|
+
|
4
|
+
const DropdownMultiSelect = (props) => {
|
5
|
+
|
6
|
+
const options = [
|
7
|
+
{
|
8
|
+
label: "United States",
|
9
|
+
value: "United States",
|
10
|
+
},
|
11
|
+
{
|
12
|
+
label: "United Kingdom",
|
13
|
+
value: "United Kingdom",
|
14
|
+
},
|
15
|
+
{
|
16
|
+
label: "Canada",
|
17
|
+
value: "Canada",
|
18
|
+
},
|
19
|
+
{
|
20
|
+
label: "Pakistan",
|
21
|
+
value: "Pakistan",
|
22
|
+
},
|
23
|
+
{
|
24
|
+
label: "India",
|
25
|
+
value: "India",
|
26
|
+
},
|
27
|
+
{
|
28
|
+
label: "Australia",
|
29
|
+
value: "Australia",
|
30
|
+
},
|
31
|
+
{
|
32
|
+
label: "New Zealand",
|
33
|
+
value: "New Zealand",
|
34
|
+
},
|
35
|
+
{
|
36
|
+
label: "Italy",
|
37
|
+
value: "Italy",
|
38
|
+
},
|
39
|
+
{
|
40
|
+
label: "Spain",
|
41
|
+
value: "Spain",
|
42
|
+
}
|
43
|
+
];
|
44
|
+
|
45
|
+
return (
|
46
|
+
<div>
|
47
|
+
<Dropdown
|
48
|
+
multiSelect
|
49
|
+
options={options}
|
50
|
+
{...props}
|
51
|
+
/>
|
52
|
+
</div>
|
53
|
+
)
|
54
|
+
}
|
55
|
+
|
56
|
+
export default DropdownMultiSelect
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
3
|
+
|
4
|
+
const DropdownMultiSelectDisplay = (props) => {
|
5
|
+
|
6
|
+
const options = [
|
7
|
+
{
|
8
|
+
label: "United States",
|
9
|
+
value: "United States",
|
10
|
+
},
|
11
|
+
{
|
12
|
+
label: "United Kingdom",
|
13
|
+
value: "United Kingdom",
|
14
|
+
},
|
15
|
+
{
|
16
|
+
label: "Canada",
|
17
|
+
value: "Canada",
|
18
|
+
},
|
19
|
+
{
|
20
|
+
label: "Pakistan",
|
21
|
+
value: "Pakistan",
|
22
|
+
},
|
23
|
+
{
|
24
|
+
label: "India",
|
25
|
+
value: "India",
|
26
|
+
},
|
27
|
+
{
|
28
|
+
label: "Australia",
|
29
|
+
value: "Australia",
|
30
|
+
},
|
31
|
+
{
|
32
|
+
label: "New Zealand",
|
33
|
+
value: "New Zealand",
|
34
|
+
},
|
35
|
+
{
|
36
|
+
label: "Italy",
|
37
|
+
value: "Italy",
|
38
|
+
},
|
39
|
+
{
|
40
|
+
label: "Spain",
|
41
|
+
value: "Spain",
|
42
|
+
}
|
43
|
+
];
|
44
|
+
|
45
|
+
|
46
|
+
return (
|
47
|
+
<div>
|
48
|
+
<Dropdown
|
49
|
+
formPillProps={{size:"small", color:"neutral"}}
|
50
|
+
multiSelect
|
51
|
+
options={options}
|
52
|
+
{...props}
|
53
|
+
/>
|
54
|
+
</div>
|
55
|
+
)
|
56
|
+
}
|
57
|
+
|
58
|
+
export default DropdownMultiSelectDisplay
|
@@ -0,0 +1,3 @@
|
|
1
|
+
By default, the `multiSelect` prop will render selected options as the default FormPill. `FormPillProps` however can be used to customize these Pills with any props that exist for the FormPill.
|
2
|
+
|
3
|
+
This prop must be an object that contains valid FormPill props. For a full list of FormPill props, see [here](https://playbook.powerapp.cloud/kits/form_pill/react).
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%
|
2
|
+
options = [
|
3
|
+
{ label: 'United States', value: 'United States', id: 'us' },
|
4
|
+
{ label: 'Canada', value: 'Canada', id: 'ca' },
|
5
|
+
{ label: 'Pakistan', value: 'Pakistan', id: 'pk' },
|
6
|
+
{ label: 'India', value: 'India', id: 'in' },
|
7
|
+
{ label: 'United Kingdom', value: 'United Kingdom', id: 'uk' },
|
8
|
+
{ label: 'Australia', value: 'Australia', id: 'au' },
|
9
|
+
{ label: 'New Zealand', value: 'New Zealand', id: 'nz' },
|
10
|
+
{ label: 'Germany', value: 'Germany', id: 'de' },
|
11
|
+
{ label: 'France', value: 'France', id: 'fr' },
|
12
|
+
{ label: 'Italy', value: 'Italy', id: 'it' },
|
13
|
+
]
|
14
|
+
%>
|
15
|
+
|
16
|
+
<%= pb_rails("dropdown", props: {
|
17
|
+
options: options,
|
18
|
+
multi_select: true,
|
19
|
+
form_pill_props: { size:"small", color:"neutral" },
|
20
|
+
}) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
By default, the `multi_select` prop will render selected options as the default form_pill. `form_pill_props` however can be used to customize these Pills with props that exist for the form_pill. Currently, only the '[color](https://playbook.powerapp.cloud/kits/form_pill/rails#form-pill-colors)' and '[size](https://playbook.powerapp.cloud/kits/form_pill/rails#form-pill-size)' props are supported as shown here.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%
|
2
|
+
options = [
|
3
|
+
{ label: 'United States', value: 'United States', id: 'us' },
|
4
|
+
{ label: 'Canada', value: 'Canada', id: 'ca' },
|
5
|
+
{ label: 'Pakistan', value: 'Pakistan', id: 'pk' },
|
6
|
+
{ label: 'India', value: 'India', id: 'in' },
|
7
|
+
{ label: 'United Kingdom', value: 'United Kingdom', id: 'uk' },
|
8
|
+
{ label: 'Australia', value: 'Australia', id: 'au' },
|
9
|
+
{ label: 'New Zealand', value: 'New Zealand', id: 'nz' },
|
10
|
+
{ label: 'Germany', value: 'Germany', id: 'de' },
|
11
|
+
{ label: 'France', value: 'France', id: 'fr' },
|
12
|
+
{ label: 'Italy', value: 'Italy', id: 'it' },
|
13
|
+
]
|
14
|
+
%>
|
15
|
+
|
16
|
+
<%= pb_rails("dropdown", props: {
|
17
|
+
options: options,
|
18
|
+
multi_select: true,
|
19
|
+
}) %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%
|
2
|
+
options = [
|
3
|
+
{ label: 'United States', value: 'United States', id: 'us' },
|
4
|
+
{ label: 'Canada', value: 'Canada', id: 'ca' },
|
5
|
+
{ label: 'Pakistan', value: 'Pakistan', id: 'pk' },
|
6
|
+
{ label: 'India', value: 'India', id: 'in' },
|
7
|
+
{ label: 'United Kingdom', value: 'United Kingdom', id: 'uk' },
|
8
|
+
{ label: 'Australia', value: 'Australia', id: 'au' },
|
9
|
+
{ label: 'New Zealand', value: 'New Zealand', id: 'nz' },
|
10
|
+
{ label: 'Germany', value: 'Germany', id: 'de' },
|
11
|
+
{ label: 'France', value: 'France', id: 'fr' },
|
12
|
+
{ label: 'Italy', value: 'Italy', id: 'it' },
|
13
|
+
]
|
14
|
+
%>
|
15
|
+
|
16
|
+
<%= pb_rails("dropdown", props: {
|
17
|
+
autocomplete: true,
|
18
|
+
options: options,
|
19
|
+
multi_select: true,
|
20
|
+
}) %>
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
3
|
+
|
4
|
+
const DropdownMultiSelectWithAutocomplete = (props) => {
|
5
|
+
|
6
|
+
const options = [
|
7
|
+
{
|
8
|
+
label: "United States",
|
9
|
+
value: "United States",
|
10
|
+
},
|
11
|
+
{
|
12
|
+
label: "United Kingdom",
|
13
|
+
value: "United Kingdom",
|
14
|
+
},
|
15
|
+
{
|
16
|
+
label: "Canada",
|
17
|
+
value: "Canada",
|
18
|
+
},
|
19
|
+
{
|
20
|
+
label: "Pakistan",
|
21
|
+
value: "Pakistan",
|
22
|
+
},
|
23
|
+
{
|
24
|
+
label: "India",
|
25
|
+
value: "India",
|
26
|
+
},
|
27
|
+
{
|
28
|
+
label: "Australia",
|
29
|
+
value: "Australia",
|
30
|
+
},
|
31
|
+
{
|
32
|
+
label: "New Zealand",
|
33
|
+
value: "New Zealand",
|
34
|
+
},
|
35
|
+
{
|
36
|
+
label: "Italy",
|
37
|
+
value: "Italy",
|
38
|
+
},
|
39
|
+
{
|
40
|
+
label: "Spain",
|
41
|
+
value: "Spain",
|
42
|
+
}
|
43
|
+
];
|
44
|
+
|
45
|
+
return (
|
46
|
+
<div>
|
47
|
+
<Dropdown
|
48
|
+
autocomplete
|
49
|
+
multiSelect
|
50
|
+
options={options}
|
51
|
+
{...props}
|
52
|
+
/>
|
53
|
+
</div>
|
54
|
+
)
|
55
|
+
}
|
56
|
+
|
57
|
+
export default DropdownMultiSelectWithAutocomplete
|
@@ -0,0 +1 @@
|
|
1
|
+
`multiSelect` can also be used with the `autocomplete` functionality.
|
data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.html.erb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
<%
|
2
|
+
options = [
|
3
|
+
{
|
4
|
+
label: "United States",
|
5
|
+
value: "United States",
|
6
|
+
areaCode: "+1",
|
7
|
+
icon: "πΊπΈ",
|
8
|
+
id: "us"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
label: "Canada",
|
12
|
+
value: "Canada",
|
13
|
+
areaCode: "+1",
|
14
|
+
icon: "π¨π¦",
|
15
|
+
id: "ca"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
label: "Pakistan",
|
19
|
+
value: "Pakistan",
|
20
|
+
areaCode: "+92",
|
21
|
+
icon: "π΅π°",
|
22
|
+
id: "pk"
|
23
|
+
}
|
24
|
+
]
|
25
|
+
|
26
|
+
%>
|
27
|
+
|
28
|
+
<%= pb_rails("dropdown", props: { options: options, multi_select: true }) do %>
|
29
|
+
<%= pb_rails("dropdown/dropdown_trigger", props:{ multi_select: true }) %>
|
30
|
+
<%= pb_rails("dropdown/dropdown_container") do %>
|
31
|
+
<% options.each do |option| %>
|
32
|
+
<%= pb_rails("dropdown/dropdown_option", props: {option: option}) do %>
|
33
|
+
<%= pb_rails("flex", props: {
|
34
|
+
align: "center",
|
35
|
+
justify: "between",
|
36
|
+
}) do %>
|
37
|
+
<%= pb_rails("flex/flex_item") do %>
|
38
|
+
<%= pb_rails("flex") do %>
|
39
|
+
<%= pb_rails("icon", props: {icon: option[:icon]}) %>
|
40
|
+
<%= pb_rails("body", props: {text: option[:label], padding_left:"xs"}) %>
|
41
|
+
<% end %>
|
42
|
+
<% end %>
|
43
|
+
<%= pb_rails("flex/flex_item") do %>
|
44
|
+
<%= pb_rails("body", props: {color:"light", text: option[:areaCode]}) %>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
47
|
+
<% end %>
|
48
|
+
<% end %>
|
49
|
+
<% end %>
|
50
|
+
<% end %>
|