playbook_ui 16.1.0 → 16.2.0.pre.rc.1
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_date_picker/_date_picker.tsx +14 -5
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_default.md +1 -0
- data/app/pb_kits/playbook/pb_dialog/_dialog.scss +8 -6
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +6 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +37 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection_rails.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection_react.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_clearable.html.erb +52 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_clearable.jsx +72 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_clearable.md +5 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height.jsx +33 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height_rails.html.erb +20 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height_rails.md +8 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_constrain_height_react.md +8 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_placeholder.html.erb +9 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_placeholder.jsx +33 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_placeholder.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +6 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +4 -1
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +2 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +6 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +94 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +5 -1
- data/app/pb_kits/playbook/pb_dropdown/index.js +59 -4
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +3 -0
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +2 -1
- data/app/pb_kits/playbook/pb_filter/Filter/SortMenu.tsx +1 -1
- data/app/pb_kits/playbook/pb_filter/docs/_filter_default.html.erb +2 -2
- data/app/pb_kits/playbook/pb_filter/docs/_filter_default.jsx +16 -9
- data/app/pb_kits/playbook/pb_filter/filter.rb +2 -2
- data/app/pb_kits/playbook/pb_form/docs/_form_with_required_indicator.html.erb +2 -0
- data/app/pb_kits/playbook/pb_form/pb_form_validation.js +9 -2
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_truncated_text.html.erb +5 -5
- data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_truncated_text.jsx +4 -4
- data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +4 -0
- data/app/pb_kits/playbook/pb_passphrase/_passphrase.tsx +20 -5
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx +1 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_required_indicator.html.erb +7 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_required_indicator.jsx +24 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_passphrase/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +2 -0
- data/app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx +30 -1
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +3 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_required_indicator.html.erb +5 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_required_indicator.jsx +14 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +2 -0
- 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_phone_number_input/phone_number_input.test.js +34 -3
- data/app/pb_kits/playbook/pb_textarea/_textarea.tsx +10 -0
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_default.html.erb +3 -3
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_default.jsx +3 -0
- data/app/pb_kits/playbook/pb_textarea/docs/_textarea_default.md +1 -0
- data/app/pb_kits/playbook/pb_textarea/textarea.html.erb +25 -9
- data/app/pb_kits/playbook/pb_textarea/textarea.rb +7 -1
- data/app/pb_kits/playbook/pb_time_picker/_time_picker.tsx +97 -11
- data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_on_handler.jsx +5 -2
- data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_required_indicator.html.erb +6 -0
- data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_required_indicator.jsx +16 -0
- data/app/pb_kits/playbook/pb_time_picker/docs/_time_picker_required_indicator.md +3 -0
- data/app/pb_kits/playbook/pb_time_picker/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_time_picker/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_time_picker/time_picker.rb +3 -0
- data/app/pb_kits/playbook/pb_time_picker/time_picker.test.jsx +47 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.test.jsx +24 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +2 -1
- data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +4 -1
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.html.erb +1 -1
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_truncated_text.jsx +1 -1
- data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +4 -0
- data/dist/chunks/{_pb_line_graph-ERhTGrxH.js → _pb_line_graph-BgKF_zz1.js} +1 -1
- data/dist/chunks/_typeahead-CWA5wlah.js +1 -0
- data/dist/chunks/{globalProps-C5qTX7aJ.js → globalProps-BhVYCqRf.js} +1 -1
- data/dist/chunks/{lib-B7ivt23s.js → lib-DD34ZrWL.js} +2 -2
- data/dist/chunks/vendor.js +4 -4
- data/dist/menu.yml +1 -1
- 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/align_content.rb +13 -3
- data/lib/playbook/align_items.rb +13 -3
- data/lib/playbook/align_self.rb +13 -3
- data/lib/playbook/display.rb +5 -0
- data/lib/playbook/flex.rb +13 -3
- data/lib/playbook/flex_direction.rb +13 -3
- data/lib/playbook/flex_grow.rb +13 -3
- data/lib/playbook/flex_shrink.rb +13 -3
- data/lib/playbook/flex_wrap.rb +13 -3
- data/lib/playbook/forms/builder/phone_number_field.rb +9 -0
- data/lib/playbook/justify_content.rb +13 -3
- data/lib/playbook/justify_self.rb +13 -3
- data/lib/playbook/order.rb +13 -3
- data/lib/playbook/spacing.rb +39 -9
- data/lib/playbook/text_align.rb +13 -3
- data/lib/playbook/truncate.rb +1 -1
- data/lib/playbook/version.rb +2 -2
- data/lib/playbook/vertical_align.rb +13 -3
- data/lib/playbook/z_index.rb +5 -0
- metadata +29 -6
- data/dist/chunks/_typeahead-DmWq2Utd.js +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4716e526924fd62bb0c877a51c1b135e4d881bb50c2995a67a51aa3c667bf320
|
|
4
|
+
data.tar.gz: d8e539ed648f227860fee870d7c8b80ea9a6ba2cf9e0420c59cd192bf58dae50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d2b0e61996919c9d3234518bf9ce2708f3be86de41039abf8a820029d22063a2ebdceb41a183852f5ab88315a44c6bd20daeba2bb1a95ec3dcb2aa59cf74d1a
|
|
7
|
+
data.tar.gz: b5b94f8ead24d755a3d0c1a10fe6e2175c45eb874fe413705a99d5740b82a25be3b44abb98a1c22c41da6562f61cd1815eea65622ad97686e7a9f07069d573cc
|
|
@@ -40,7 +40,7 @@ type DatePickerProps = {
|
|
|
40
40
|
maxDate: string,
|
|
41
41
|
minDate: string,
|
|
42
42
|
name: string,
|
|
43
|
-
pickerId
|
|
43
|
+
pickerId: string,
|
|
44
44
|
placeholder?: string,
|
|
45
45
|
positionElement?: HTMLElement | null,
|
|
46
46
|
scrollContainer?: string,
|
|
@@ -196,6 +196,8 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
|
196
196
|
|
|
197
197
|
const angleDown = getAllIcons()["angleDown"].icon as unknown as { [key: string]: SVGElement }
|
|
198
198
|
|
|
199
|
+
const errorId = error ? `${pickerId}-error` : undefined
|
|
200
|
+
|
|
199
201
|
return (
|
|
200
202
|
<div
|
|
201
203
|
{...ariaProps}
|
|
@@ -211,14 +213,18 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
|
211
213
|
>
|
|
212
214
|
|
|
213
215
|
{!hideLabel && (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
<label htmlFor={pickerId}>
|
|
217
|
+
<Caption
|
|
218
|
+
className="pb_date_picker_kit_label"
|
|
219
|
+
text={label}
|
|
220
|
+
/>
|
|
221
|
+
</label>
|
|
218
222
|
)}
|
|
219
223
|
<>
|
|
220
224
|
<div className="date_picker_input_wrapper">
|
|
221
225
|
<input
|
|
226
|
+
aria-describedby={errorId}
|
|
227
|
+
aria-invalid={!!error}
|
|
222
228
|
autoComplete="off"
|
|
223
229
|
className="date_picker_input"
|
|
224
230
|
disabled={disableInput}
|
|
@@ -232,6 +238,9 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
|
232
238
|
|
|
233
239
|
{error &&
|
|
234
240
|
<Body
|
|
241
|
+
aria={{ atomic: "true", live: "polite" }}
|
|
242
|
+
htmlOptions={{ role: "alert" }}
|
|
243
|
+
id={errorId}
|
|
235
244
|
status="negative"
|
|
236
245
|
text={error}
|
|
237
246
|
variant={null}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
`pickerId`/`picker_id` is a **required prop** to instantiate the Date Picker. The presence of `pickerId`/`picker_id` in your Date Picker also associates the label with the input, providing the ability to focus the Date Picker by clicking the label.
|
|
@@ -135,6 +135,8 @@
|
|
|
135
135
|
position: sticky;
|
|
136
136
|
top: 0;
|
|
137
137
|
background-color: $white;
|
|
138
|
+
border-top-left-radius: $border_radius_md;
|
|
139
|
+
border-top-right-radius: $border_radius_md;
|
|
138
140
|
z-index: $z_8;
|
|
139
141
|
}
|
|
140
142
|
|
|
@@ -256,7 +258,7 @@
|
|
|
256
258
|
}
|
|
257
259
|
&.full_height_left {
|
|
258
260
|
justify-content: flex-start;
|
|
259
|
-
|
|
261
|
+
|
|
260
262
|
.pb_dialog {
|
|
261
263
|
border-radius: 0;
|
|
262
264
|
height: 100%;
|
|
@@ -302,7 +304,7 @@
|
|
|
302
304
|
|
|
303
305
|
&.full_height_center {
|
|
304
306
|
justify-content: center;
|
|
305
|
-
|
|
307
|
+
|
|
306
308
|
.pb_dialog {
|
|
307
309
|
border-radius: 0;
|
|
308
310
|
height: 100%;
|
|
@@ -346,7 +348,7 @@
|
|
|
346
348
|
|
|
347
349
|
&.full_height_right {
|
|
348
350
|
justify-content: flex-end;
|
|
349
|
-
|
|
351
|
+
|
|
350
352
|
.pb_dialog {
|
|
351
353
|
border-radius: 0;
|
|
352
354
|
height: 100%;
|
|
@@ -417,7 +419,7 @@
|
|
|
417
419
|
margin: unset !important;
|
|
418
420
|
margin-right: auto !important;
|
|
419
421
|
}
|
|
420
|
-
|
|
422
|
+
|
|
421
423
|
.pb_dialog {
|
|
422
424
|
border-radius: 0;
|
|
423
425
|
height: 100% !important;
|
|
@@ -463,7 +465,7 @@
|
|
|
463
465
|
|
|
464
466
|
&.full_height_center {
|
|
465
467
|
justify-content: center;
|
|
466
|
-
|
|
468
|
+
|
|
467
469
|
.pb_dialog {
|
|
468
470
|
border-radius: 0;
|
|
469
471
|
height: 100% !important;
|
|
@@ -510,7 +512,7 @@
|
|
|
510
512
|
margin: unset !important;
|
|
511
513
|
margin-left: auto !important;
|
|
512
514
|
}
|
|
513
|
-
|
|
515
|
+
|
|
514
516
|
.pb_dialog {
|
|
515
517
|
border-radius: 0;
|
|
516
518
|
height: 100% !important;
|
|
@@ -36,6 +36,8 @@ type DropdownProps = {
|
|
|
36
36
|
blankSelection?: string;
|
|
37
37
|
children?: React.ReactChild[] | React.ReactChild | React.ReactElement[];
|
|
38
38
|
className?: string;
|
|
39
|
+
clearable?: boolean;
|
|
40
|
+
constrainHeight?: boolean;
|
|
39
41
|
customQuickPickDates?: CustomQuickPickDates;
|
|
40
42
|
formPillProps?: GenericObject;
|
|
41
43
|
dark?: boolean;
|
|
@@ -49,6 +51,7 @@ type DropdownProps = {
|
|
|
49
51
|
multiSelect?: boolean;
|
|
50
52
|
onSelect?: (arg: GenericObject) => null;
|
|
51
53
|
options?: GenericObject;
|
|
54
|
+
placeholder?: string;
|
|
52
55
|
separators?: boolean;
|
|
53
56
|
variant?: "default" | "subtle" | "quickpick";
|
|
54
57
|
rangeEndsToday?: boolean;
|
|
@@ -74,6 +77,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
74
77
|
blankSelection = '',
|
|
75
78
|
children,
|
|
76
79
|
className,
|
|
80
|
+
clearable = true,
|
|
81
|
+
constrainHeight = false,
|
|
77
82
|
customQuickPickDates,
|
|
78
83
|
dark = false,
|
|
79
84
|
data = {},
|
|
@@ -87,6 +92,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
87
92
|
formPillProps,
|
|
88
93
|
onSelect,
|
|
89
94
|
options,
|
|
95
|
+
placeholder,
|
|
90
96
|
rangeEndsToday = false,
|
|
91
97
|
controlsStartId,
|
|
92
98
|
controlsEndId,
|
|
@@ -211,6 +217,34 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
211
217
|
}
|
|
212
218
|
}, [isDropDownClosed]);
|
|
213
219
|
|
|
220
|
+
// Auto-position dropdown above/below based on available space
|
|
221
|
+
useEffect(() => {
|
|
222
|
+
if (!isDropDownClosed && dropdownContainerRef.current) {
|
|
223
|
+
const container = dropdownContainerRef.current;
|
|
224
|
+
const wrapper = container.closest('.dropdown_wrapper') as HTMLElement;
|
|
225
|
+
if (!wrapper) return;
|
|
226
|
+
|
|
227
|
+
const wrapperRect = wrapper.getBoundingClientRect();
|
|
228
|
+
const h = container.getBoundingClientRect().height || container.scrollHeight;
|
|
229
|
+
const spaceBelow = window.innerHeight - wrapperRect.bottom;
|
|
230
|
+
const spaceAbove = wrapperRect.top;
|
|
231
|
+
|
|
232
|
+
// If not enough space below but enough space above, position above
|
|
233
|
+
if (spaceBelow < h + 10 && spaceAbove >= h + 10) {
|
|
234
|
+
container.style.top = "auto";
|
|
235
|
+
container.style.bottom = "calc(100% + 5px)";
|
|
236
|
+
container.style.marginTop = "0";
|
|
237
|
+
container.style.marginBottom = "0";
|
|
238
|
+
} else {
|
|
239
|
+
// Default: position below
|
|
240
|
+
container.style.top = "";
|
|
241
|
+
container.style.bottom = "";
|
|
242
|
+
container.style.marginTop = "";
|
|
243
|
+
container.style.marginBottom = "";
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}, [isDropDownClosed, dropdownContainerRef]);
|
|
247
|
+
|
|
214
248
|
|
|
215
249
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
216
250
|
setFilterItem(e.target.value);
|
|
@@ -375,6 +409,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
375
409
|
value={{
|
|
376
410
|
activeStyle,
|
|
377
411
|
autocomplete,
|
|
412
|
+
clearable,
|
|
378
413
|
dropdownContainerRef,
|
|
379
414
|
filteredOptions,
|
|
380
415
|
filterItem,
|
|
@@ -426,8 +461,8 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
|
|
|
426
461
|
</>
|
|
427
462
|
) : (
|
|
428
463
|
<>
|
|
429
|
-
<DropdownTrigger />
|
|
430
|
-
<DropdownContainer>
|
|
464
|
+
<DropdownTrigger placeholder={placeholder} />
|
|
465
|
+
<DropdownContainer constrainHeight={constrainHeight}>
|
|
431
466
|
{optionsWithBlankSelection &&
|
|
432
467
|
optionsWithBlankSelection?.map((option: GenericObject) => (
|
|
433
468
|
<DropdownOption key={option.id}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
The `blank_selection` prop adds a blank option at the top of the dropdown options list. This allows users to explicitly clear their selection by choosing the blank option.
|
|
2
|
+
|
|
3
|
+
The blank selection option appears as the first item in the dropdown and has an empty value (`id: ""`, `value: ""`). When selected, it effectively clears the dropdown selection.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
The `blankSelection` prop adds a blank option at the top of the dropdown options list. This allows users to explicitly clear their selection by choosing the blank option.
|
|
2
|
+
|
|
3
|
+
The blank selection option appears as the first item in the dropdown and has an empty value (`id: ""`, `value: ""`). When selected, it effectively clears the dropdown selection.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<%
|
|
2
|
+
options = [
|
|
3
|
+
{ label: 'United States', value: 'unitedStates', id: 'us' },
|
|
4
|
+
{ label: 'Canada', value: 'canada', id: 'ca' },
|
|
5
|
+
{ label: 'Pakistan', value: 'pakistan', id: 'pk' },
|
|
6
|
+
]
|
|
7
|
+
%>
|
|
8
|
+
|
|
9
|
+
<%= pb_rails("dropdown", props: {
|
|
10
|
+
id: "date-range-quickpick-reset-closeable",
|
|
11
|
+
label: "Quick Pick",
|
|
12
|
+
variant: "quickpick",
|
|
13
|
+
clearable: false
|
|
14
|
+
}) %>
|
|
15
|
+
|
|
16
|
+
<%= pb_rails("button", props: {
|
|
17
|
+
margin_y: "md",
|
|
18
|
+
text: "Reset",
|
|
19
|
+
html_options: {
|
|
20
|
+
onclick: "handleReset()"
|
|
21
|
+
}
|
|
22
|
+
}) %>
|
|
23
|
+
|
|
24
|
+
<%= pb_rails("dropdown", props: {
|
|
25
|
+
id: "closeable-default",
|
|
26
|
+
options: options,
|
|
27
|
+
clearable: false,
|
|
28
|
+
default_value: options.last,
|
|
29
|
+
margin_bottom: "md",
|
|
30
|
+
label: "Default"
|
|
31
|
+
}) %>
|
|
32
|
+
|
|
33
|
+
<%= pb_rails("dropdown", props: {
|
|
34
|
+
id: "closeable-subtle",
|
|
35
|
+
options: options,
|
|
36
|
+
clearable: false,
|
|
37
|
+
default_value: options.second,
|
|
38
|
+
variant: "subtle",
|
|
39
|
+
separators: false,
|
|
40
|
+
label: "Subtle"
|
|
41
|
+
}) %>
|
|
42
|
+
|
|
43
|
+
<script>
|
|
44
|
+
function handleReset() {
|
|
45
|
+
const dropdown = document.querySelector("#date-range-quickpick-reset-closeable[data-pb-dropdown]");
|
|
46
|
+
const instance = dropdown?._pbDropdownInstance;
|
|
47
|
+
|
|
48
|
+
if (instance) {
|
|
49
|
+
instance.clearSelection();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React, { useRef } from 'react'
|
|
2
|
+
|
|
3
|
+
import Button from '../../pb_button/_button'
|
|
4
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
|
5
|
+
|
|
6
|
+
const DropdownWithClearable = (props) => {
|
|
7
|
+
const dropdownRef = useRef(null)
|
|
8
|
+
|
|
9
|
+
const options = [
|
|
10
|
+
{
|
|
11
|
+
label: "United States",
|
|
12
|
+
value: "unitedStates",
|
|
13
|
+
id: "us"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
label: "Canada",
|
|
17
|
+
value: "canada",
|
|
18
|
+
id: "ca"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
label: "Pakistan",
|
|
22
|
+
value: "pakistan",
|
|
23
|
+
id: "pk"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const handleReset = () => {
|
|
28
|
+
if (dropdownRef.current) {
|
|
29
|
+
dropdownRef.current.clearSelected()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<Dropdown
|
|
36
|
+
clearable={false}
|
|
37
|
+
label="Quick Pick"
|
|
38
|
+
onSelect={() => {}}
|
|
39
|
+
ref={dropdownRef}
|
|
40
|
+
variant="quickpick"
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
<Button
|
|
44
|
+
marginY="md"
|
|
45
|
+
onClick={handleReset}
|
|
46
|
+
text="Reset"
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
<Dropdown
|
|
50
|
+
clearable={false}
|
|
51
|
+
defaultValue={options[options.length - 1]}
|
|
52
|
+
label="Default"
|
|
53
|
+
marginBottom="md"
|
|
54
|
+
options={options}
|
|
55
|
+
variant="default"
|
|
56
|
+
{...props}
|
|
57
|
+
/>
|
|
58
|
+
|
|
59
|
+
<Dropdown
|
|
60
|
+
clearable={false}
|
|
61
|
+
defaultValue={options[1]}
|
|
62
|
+
label="Subtle"
|
|
63
|
+
options={options}
|
|
64
|
+
separators={false}
|
|
65
|
+
variant="subtle"
|
|
66
|
+
{...props}
|
|
67
|
+
/>
|
|
68
|
+
</>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default DropdownWithClearable
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
The `clearable` prop controls whether the clear (X) button appears in the dropdown. When set to `false`, the clear button is hidden.
|
|
2
|
+
|
|
3
|
+
This is useful in two scenarios:
|
|
4
|
+
1. When you have a separate "Reset" or "Defaults" button that handles clearing the selection (as shown in the Quick Pick example)
|
|
5
|
+
2. When you don't want to provide any way to clear the selection (as shown in the Default and Subtle examples)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
|
3
|
+
|
|
4
|
+
const DropdownWithConstrainHeight = (props) => {
|
|
5
|
+
// Create a long list of options to demonstrate height constraint
|
|
6
|
+
const options = Array.from({ length: 30 }, (_, i) => ({
|
|
7
|
+
label: `Option ${i + 1}`,
|
|
8
|
+
value: `option_${i + 1}`,
|
|
9
|
+
id: `opt_${i + 1}`
|
|
10
|
+
}))
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<Dropdown
|
|
15
|
+
data={{ testid: "dropdown-no-constrain" }}
|
|
16
|
+
label="Without Constrain Height (Default)"
|
|
17
|
+
marginBottom="md"
|
|
18
|
+
options={options}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
|
|
22
|
+
<Dropdown
|
|
23
|
+
constrainHeight
|
|
24
|
+
data={{ testid: "dropdown-constrain" }}
|
|
25
|
+
label="With Constrain Height"
|
|
26
|
+
options={options}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
</>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default DropdownWithConstrainHeight
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<%
|
|
2
|
+
# Create a long list of options to demonstrate height constraint
|
|
3
|
+
options = (1..30).map do |i|
|
|
4
|
+
{ label: "Option #{i}", value: "option_#{i}", id: "opt_#{i}" }
|
|
5
|
+
end
|
|
6
|
+
%>
|
|
7
|
+
|
|
8
|
+
<%= pb_rails("dropdown", props: {
|
|
9
|
+
id: "dropdown-no-constrain",
|
|
10
|
+
options: options,
|
|
11
|
+
label: "Without Constrain Height (Default)",
|
|
12
|
+
margin_bottom: "md"
|
|
13
|
+
}) %>
|
|
14
|
+
|
|
15
|
+
<%= pb_rails("dropdown", props: {
|
|
16
|
+
id: "dropdown-constrain",
|
|
17
|
+
options: options,
|
|
18
|
+
constrain_height: true,
|
|
19
|
+
label: "With Constrain Height"
|
|
20
|
+
}) %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
The `constrain_height` prop limits the dropdown container height to 18em and enables vertical scrolling when the content exceeds this height. This prevents long dropdown lists from rendering off-screen.
|
|
2
|
+
|
|
3
|
+
When `constrain_height` is `true`, the dropdown will:
|
|
4
|
+
- Have a maximum height of 18em
|
|
5
|
+
- Show a scrollbar when content exceeds the max height
|
|
6
|
+
- Prevent the dropdown from extending beyond the viewport
|
|
7
|
+
|
|
8
|
+
This is particularly useful for dropdowns with many options, such as long lists or quickpick variants with many date range options.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
The `constrainHeight` prop limits the dropdown container height to 18em and enables vertical scrolling when the content exceeds this height. This prevents long dropdown lists from rendering off-screen.
|
|
2
|
+
|
|
3
|
+
When `constrainHeight` is `true`, the dropdown will:
|
|
4
|
+
- Have a maximum height of 18em
|
|
5
|
+
- Show a scrollbar when content exceeds the max height
|
|
6
|
+
- Prevent the dropdown from extending beyond the viewport
|
|
7
|
+
|
|
8
|
+
This is particularly useful for dropdowns with many options, such as long lists or quickpick variants with many date range options.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<%
|
|
2
|
+
options = [
|
|
3
|
+
{ label: 'United States', value: 'unitedStates', id: 'us' },
|
|
4
|
+
{ label: 'Canada', value: 'canada', id: 'ca' },
|
|
5
|
+
{ label: 'Pakistan', value: 'pakistan', id: 'pk' },
|
|
6
|
+
]
|
|
7
|
+
%>
|
|
8
|
+
|
|
9
|
+
<%= pb_rails("dropdown", props: { options: options, placeholder: "Choose a country" }) %>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import Dropdown from '../../pb_dropdown/_dropdown'
|
|
3
|
+
|
|
4
|
+
const DropdownWithPlaceholder = (props) => {
|
|
5
|
+
|
|
6
|
+
const options = [
|
|
7
|
+
{
|
|
8
|
+
label: "United States",
|
|
9
|
+
value: "unitedStates",
|
|
10
|
+
id: "us"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
label: "Canada",
|
|
14
|
+
value: "canada",
|
|
15
|
+
id: "ca"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
label: "Pakistan",
|
|
19
|
+
value: "pakistan",
|
|
20
|
+
id: "pk"
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Dropdown
|
|
26
|
+
options={options}
|
|
27
|
+
placeholder="Choose a country"
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default DropdownWithPlaceholder
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
The `placeholder` prop allows you to customize the placeholder text that appears when no option is selected in the dropdown.
|
|
2
|
+
|
|
3
|
+
The placeholder prop works with all dropdown variants (`default`, `subtle`, and `quickpick`). When no option is selected, the placeholder text is displayed. When an option is selected, the placeholder is replaced by the selected option's label. The default placeholder text is "Select..." if no placeholder is provided.
|
|
@@ -21,7 +21,10 @@ examples:
|
|
|
21
21
|
- dropdown_default_value: Default Value
|
|
22
22
|
- dropdown_multi_select_with_default: Multi Select Default Value
|
|
23
23
|
- dropdown_blank_selection: Blank Selection
|
|
24
|
+
- dropdown_with_placeholder: Placeholder
|
|
24
25
|
- dropdown_separators_hidden: Separators Hidden
|
|
26
|
+
- dropdown_with_clearable: Clearable
|
|
27
|
+
- dropdown_with_constrain_height_rails: Constrain Height
|
|
25
28
|
- dropdown_quickpick_rails: Quick Pick Variant
|
|
26
29
|
- dropdown_quickpick_range_end_rails: Quick Pick Variant (Range Ends Today)
|
|
27
30
|
- dropdown_quickpick_default_dates: Quick Pick Variant (Default Dates)
|
|
@@ -52,7 +55,10 @@ examples:
|
|
|
52
55
|
- dropdown_default_value: Default Value
|
|
53
56
|
- dropdown_multi_select_with_default: Multi Select Default Value
|
|
54
57
|
- dropdown_blank_selection: Blank Selection
|
|
58
|
+
- dropdown_with_placeholder: Placeholder
|
|
55
59
|
- dropdown_clear_selection: Clear Selection
|
|
60
|
+
- dropdown_with_clearable: Clearable
|
|
61
|
+
- dropdown_with_constrain_height: Constrain Height
|
|
56
62
|
- dropdown_separators_hidden: Separators Hidden
|
|
57
63
|
- dropdown_with_external_control: useDropdown Hook
|
|
58
64
|
- dropdown_quickpick: Quick Pick Variant
|
|
@@ -11,6 +11,7 @@ export { default as DropdownSubcomponentStructure } from './_dropdown_subcompone
|
|
|
11
11
|
export { default as DropdownError } from './_dropdown_error.jsx'
|
|
12
12
|
export { default as DropdownDefaultValue } from './_dropdown_default_value.jsx'
|
|
13
13
|
export { default as DropdownBlankSelection } from './_dropdown_blank_selection.jsx'
|
|
14
|
+
export { default as DropdownWithPlaceholder } from './_dropdown_with_placeholder.jsx'
|
|
14
15
|
export { default as DropdownClearSelection } from './_dropdown_clear_selection.jsx'
|
|
15
16
|
export { default as DropdownSubtleVariant } from './_dropdown_subtle_variant.jsx'
|
|
16
17
|
export { default as DropdownSeparatorsHidden } from './_dropdown_separators_hidden.jsx'
|
|
@@ -27,4 +28,6 @@ export { default as DropdownQuickpick } from './_dropdown_quickpick.jsx'
|
|
|
27
28
|
export { default as DropdownQuickpickRangeEnd } from './_dropdown_quickpick_range_end.jsx'
|
|
28
29
|
export { default as DropdownQuickpickDefaultDates } from './_dropdown_quickpick_default_dates.jsx'
|
|
29
30
|
export { default as DropdownQuickpickWithDatePickers } from './_dropdown_quickpick_with_date_pickers.jsx'
|
|
30
|
-
export { default as DropdownQuickpickCustom } from './_dropdown_quickpick_custom.jsx'
|
|
31
|
+
export { default as DropdownQuickpickCustom } from './_dropdown_quickpick_custom.jsx'
|
|
32
|
+
export { default as DropdownWithClearable } from './_dropdown_with_clearable.jsx'
|
|
33
|
+
export { default as DropdownWithConstrainHeight } from './_dropdown_with_constrain_height.jsx'
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
<%= content.presence %>
|
|
19
19
|
<%= pb_rails("body", props: { status: "negative", text: object.error }) %>
|
|
20
20
|
<% else %>
|
|
21
|
-
<%= pb_rails("dropdown/dropdown_trigger", props:{ autocomplete: object.autocomplete, multi_select:object.multi_select }) %>
|
|
22
|
-
<%= pb_rails("dropdown/dropdown_container", props: { searchbar: object.searchbar }) do %>
|
|
21
|
+
<%= pb_rails("dropdown/dropdown_trigger", props:{ autocomplete: object.autocomplete, multi_select:object.multi_select, placeholder: object.placeholder }) %>
|
|
22
|
+
<%= pb_rails("dropdown/dropdown_container", props: { searchbar: object.searchbar, constrain_height: object.constrain_height }) do %>
|
|
23
23
|
<% if options_with_blank.present? %>
|
|
24
24
|
<% options_with_blank.each do |option| %>
|
|
25
25
|
<%= pb_rails("dropdown/dropdown_option", props: {option: option}) %>
|
|
@@ -36,6 +36,8 @@ module Playbook
|
|
|
36
36
|
default: ""
|
|
37
37
|
prop :controls_start_id, type: Playbook::Props::String,
|
|
38
38
|
default: ""
|
|
39
|
+
prop :clearable, type: Playbook::Props::Boolean,
|
|
40
|
+
default: true
|
|
39
41
|
prop :start_date_id, type: Playbook::Props::String,
|
|
40
42
|
default: "start_date_id"
|
|
41
43
|
prop :start_date_name, type: Playbook::Props::String,
|
|
@@ -44,12 +46,16 @@ module Playbook
|
|
|
44
46
|
default: "end_date_id"
|
|
45
47
|
prop :end_date_name, type: Playbook::Props::String,
|
|
46
48
|
default: "end_date_name"
|
|
49
|
+
prop :placeholder, type: Playbook::Props::String
|
|
50
|
+
prop :constrain_height, type: Playbook::Props::Boolean,
|
|
51
|
+
default: false
|
|
47
52
|
|
|
48
53
|
def data
|
|
49
54
|
Hash(prop(:data)).merge(
|
|
50
55
|
pb_dropdown: true,
|
|
51
56
|
pb_dropdown_multi_select: multi_select,
|
|
52
57
|
pb_dropdown_variant: variant,
|
|
58
|
+
pb_dropdown_clearable: clearable,
|
|
53
59
|
form_pill_props: form_pill_props.to_json,
|
|
54
60
|
start_date_id: variant == "quickpick" ? start_date_id : nil,
|
|
55
61
|
end_date_id: variant == "quickpick" ? end_date_id : nil,
|