playbook_ui 13.25.0.pre.alpha.PLAY761globalpaddingpropsbuttons2713 β†’ 13.25.0.pre.alpha.PLAY1249fixTooltipswrappingformelementscausingmisalignment2783

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.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +10 -14
  3. data/app/pb_kits/playbook/pb_advanced_table/table_body.html.erb +5 -9
  4. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +2 -6
  5. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -6
  6. data/app/pb_kits/playbook/pb_avatar_action_button/avatar_action_button.html.erb +1 -6
  7. data/app/pb_kits/playbook/pb_background/background.html.erb +2 -11
  8. data/app/pb_kits/playbook/pb_badge/badge.html.erb +1 -6
  9. data/app/pb_kits/playbook/pb_body/_body.tsx +1 -1
  10. data/app/pb_kits/playbook/pb_body/body.html.erb +1 -6
  11. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumb_item.html.erb +1 -6
  12. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumbs.html.erb +2 -7
  13. data/app/pb_kits/playbook/pb_button/button.html.erb +2 -3
  14. data/app/pb_kits/playbook/pb_button_toolbar/button_toolbar.html.erb +2 -7
  15. data/app/pb_kits/playbook/pb_caption/caption.html.erb +1 -6
  16. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -7
  17. data/app/pb_kits/playbook/pb_card/card_body.html.erb +1 -6
  18. data/app/pb_kits/playbook/pb_card/card_header.html.erb +1 -6
  19. data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +1 -6
  20. data/app/pb_kits/playbook/pb_circle_icon_button/circle_icon_button.html.erb +1 -6
  21. data/app/pb_kits/playbook/pb_collapsible/collapsible.html.erb +1 -6
  22. data/app/pb_kits/playbook/pb_collapsible/collapsible_content.html.erb +1 -6
  23. data/app/pb_kits/playbook/pb_collapsible/collapsible_main.html.erb +1 -7
  24. data/app/pb_kits/playbook/pb_contact/contact.html.erb +1 -6
  25. data/app/pb_kits/playbook/pb_currency/currency.html.erb +1 -6
  26. data/app/pb_kits/playbook/pb_currency/docs/_currency_alignment_swift.md +43 -0
  27. data/app/pb_kits/playbook/pb_currency/docs/_currency_props_swift.md +12 -0
  28. data/app/pb_kits/playbook/pb_currency/docs/_currency_size_swift.md +31 -0
  29. data/app/pb_kits/playbook/pb_currency/docs/example.yml +5 -0
  30. data/app/pb_kits/playbook/pb_dashboard_value/dashboard_value.html.erb +1 -6
  31. data/app/pb_kits/playbook/pb_date/date.html.erb +1 -6
  32. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +2 -6
  33. data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.html.erb +1 -5
  34. data/app/pb_kits/playbook/pb_date_range_stacked/date_range_stacked.html.erb +1 -5
  35. data/app/pb_kits/playbook/pb_date_range_stacked/docs/_date_range_stacked_default_swift.md +14 -0
  36. data/app/pb_kits/playbook/pb_date_range_stacked/docs/_date_range_stacked_props_swift.md +9 -0
  37. data/app/pb_kits/playbook/pb_date_range_stacked/docs/example.yml +4 -0
  38. data/app/pb_kits/playbook/pb_date_stacked/date_stacked.html.erb +1 -5
  39. data/app/pb_kits/playbook/pb_date_time/date_time.html.erb +1 -6
  40. data/app/pb_kits/playbook/pb_date_time_stacked/date_time_stacked.html.erb +1 -7
  41. data/app/pb_kits/playbook/pb_date_year_stacked/date_year_stacked.html.erb +1 -5
  42. data/app/pb_kits/playbook/pb_detail/detail.html.erb +1 -6
  43. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +4 -2
  44. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +1 -6
  45. data/app/pb_kits/playbook/pb_dialog/dialog_body.html.erb +2 -7
  46. data/app/pb_kits/playbook/pb_dialog/dialog_footer.html.erb +1 -5
  47. data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +2 -6
  48. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +14 -9
  49. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +34 -6
  50. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.jsx +5 -5
  51. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.md +0 -0
  52. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +87 -0
  53. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.md +1 -0
  54. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.jsx +102 -0
  55. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.md +1 -0
  56. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +4 -2
  57. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.md +3 -0
  58. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.jsx +5 -5
  59. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.md +1 -0
  60. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.jsx +51 -0
  61. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.md +1 -0
  62. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger.jsx +5 -5
  63. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger.md +1 -0
  64. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +3 -0
  65. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +3 -0
  66. data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +11 -6
  67. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +5 -0
  68. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +41 -24
  69. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +91 -47
  70. data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +1 -6
  71. data/app/pb_kits/playbook/pb_filter/filter.html.erb +1 -5
  72. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.html.erb +1 -6
  73. data/app/pb_kits/playbook/pb_flex/flex.html.erb +1 -5
  74. data/app/pb_kits/playbook/pb_flex/flex_item.html.erb +2 -6
  75. data/app/pb_kits/playbook/pb_form_group/form_group.html.erb +1 -6
  76. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +1 -1
  77. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -6
  78. data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +1 -5
  79. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +1 -5
  80. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.html.erb +2 -7
  81. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.html.erb +1 -6
  82. data/app/pb_kits/playbook/pb_icon_value/icon_value.html.erb +1 -6
  83. data/app/pb_kits/playbook/pb_label_pill/label_pill.html.erb +1 -6
  84. data/app/pb_kits/playbook/pb_label_value/label_value.html.erb +1 -6
  85. data/app/pb_kits/playbook/pb_layout/body.html.erb +1 -5
  86. data/app/pb_kits/playbook/pb_layout/footer.html.erb +1 -5
  87. data/app/pb_kits/playbook/pb_layout/header.html.erb +1 -5
  88. data/app/pb_kits/playbook/pb_layout/item.html.erb +1 -5
  89. data/app/pb_kits/playbook/pb_layout/layout.html.erb +1 -5
  90. data/app/pb_kits/playbook/pb_layout/sidebar.html.erb +1 -5
  91. data/app/pb_kits/playbook/pb_list/item.html.erb +2 -8
  92. data/app/pb_kits/playbook/pb_list/list.html.erb +2 -8
  93. data/app/pb_kits/playbook/pb_loading_inline/loading_inline.html.erb +1 -6
  94. data/app/pb_kits/playbook/pb_message/message.html.erb +1 -6
  95. data/app/pb_kits/playbook/pb_message/message_mention.html.erb +1 -6
  96. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb +1 -6
  97. data/app/pb_kits/playbook/pb_multiple_users/multiple_users.html.erb +1 -6
  98. data/app/pb_kits/playbook/pb_multiple_users_stacked/multiple_users_stacked.html.erb +1 -6
  99. data/app/pb_kits/playbook/pb_nav/item.html.erb +3 -14
  100. data/app/pb_kits/playbook/pb_nav/nav.html.erb +1 -6
  101. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +2 -6
  102. data/app/pb_kits/playbook/pb_pagination/pagination.html.erb +1 -6
  103. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -1
  104. data/app/pb_kits/playbook/pb_person/person.html.erb +7 -12
  105. data/app/pb_kits/playbook/pb_person_contact/person_contact.html.erb +1 -6
  106. data/app/pb_kits/playbook/pb_pill/pill.html.erb +1 -6
  107. data/app/pb_kits/playbook/pb_popover/popover.html.erb +1 -6
  108. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.html.erb +2 -6
  109. data/app/pb_kits/playbook/pb_progress_simple/progress_simple.html.erb +3 -6
  110. data/app/pb_kits/playbook/pb_progress_step/progress_step.html.erb +1 -5
  111. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.html.erb +1 -5
  112. data/app/pb_kits/playbook/pb_radio/radio.html.erb +2 -8
  113. data/app/pb_kits/playbook/pb_section_separator/_section_separator.scss +6 -2
  114. data/app/pb_kits/playbook/pb_section_separator/_section_separator_mixin.scss +11 -1
  115. data/app/pb_kits/playbook/pb_section_separator/section_separator.html.erb +1 -6
  116. data/app/pb_kits/playbook/pb_select/select.html.erb +1 -5
  117. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -5
  118. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +1 -4
  119. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +1 -5
  120. data/app/pb_kits/playbook/pb_selectable_list/selectable_list.html.erb +1 -6
  121. data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.html.erb +1 -6
  122. data/app/pb_kits/playbook/pb_source/source.html.erb +1 -5
  123. data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +1 -5
  124. data/app/pb_kits/playbook/pb_stat_change/stat_change.html.erb +1 -5
  125. data/app/pb_kits/playbook/pb_stat_value/stat_value.html.erb +1 -5
  126. data/app/pb_kits/playbook/pb_table/table.html.erb +2 -12
  127. data/app/pb_kits/playbook/pb_table/table_body.html.erb +6 -16
  128. data/app/pb_kits/playbook/pb_table/table_cell.html.erb +6 -16
  129. data/app/pb_kits/playbook/pb_table/table_head.html.erb +6 -16
  130. data/app/pb_kits/playbook/pb_table/table_header.html.erb +4 -13
  131. data/app/pb_kits/playbook/pb_table/table_row.html.erb +6 -16
  132. data/app/pb_kits/playbook/pb_textarea/textarea.html.erb +1 -5
  133. data/app/pb_kits/playbook/pb_time/time.html.erb +1 -5
  134. data/app/pb_kits/playbook/pb_time_range_inline/time_range_inline.html.erb +1 -5
  135. data/app/pb_kits/playbook/pb_time_stacked/time_stacked.html.erb +1 -5
  136. data/app/pb_kits/playbook/pb_timeline/item.html.erb +3 -7
  137. data/app/pb_kits/playbook/pb_timeline/timeline.html.erb +1 -5
  138. data/app/pb_kits/playbook/pb_timestamp/timestamp.html.erb +1 -6
  139. data/app/pb_kits/playbook/pb_title/title.html.erb +1 -6
  140. data/app/pb_kits/playbook/pb_title_count/title_count.html.erb +1 -6
  141. data/app/pb_kits/playbook/pb_title_detail/title_detail.html.erb +1 -5
  142. data/app/pb_kits/playbook/pb_toggle/toggle.html.erb +1 -6
  143. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +0 -1
  144. data/app/pb_kits/playbook/pb_tooltip/tooltip.html.erb +1 -5
  145. data/app/pb_kits/playbook/pb_user/user.html.erb +1 -6
  146. data/app/pb_kits/playbook/pb_user_badge/user_badge.html.erb +1 -6
  147. data/app/pb_kits/playbook/pb_weekday_stacked/weekday_stacked.html.erb +1 -6
  148. data/dist/playbook-rails.js +4 -4
  149. data/lib/playbook/kit_base.rb +1 -1
  150. data/lib/playbook/version.rb +1 -1
  151. metadata +17 -2
@@ -1,8 +1,4 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- aria: object.aria,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
6
2
  <% if object.confirm_button && object.cancel_button %>
7
3
  <div class="dialog-pseudo-footer"></div>
8
4
  <%= pb_rails("flex", props: { classname:object.classname, spacing:"between", padding_x:"sm", padding:"sm", padding_bottom:"sm" }) do %>
@@ -1,9 +1,5 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.sticky_header,
5
- aria: object.aria,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:div,
2
+ class: object.sticky_header) do %>
7
3
  <%= pb_rails("flex", props: {classname:object.classname, spacing:"between", padding:"sm", align:"center"}) do %>
8
4
  <%= content.presence || object.title %>
9
5
 
@@ -13,15 +13,15 @@
13
13
  @include pb_body;
14
14
  border: 1px solid $border_light;
15
15
  background-color: $white;
16
- box-shadow: inset 0 -11px 20px rgba($primary, 0.05);
16
+ height: 45px;
17
17
  @media (hover: hover) {
18
18
  &:hover,
19
19
  &:active,
20
20
  &:focus {
21
21
  background-color: $focus_input_light;
22
- }
23
- input {
24
- background-color: $focus_input_light;
22
+ input {
23
+ background-color: $focus_input_light;
24
+ }
25
25
  }
26
26
  }
27
27
 
@@ -30,7 +30,7 @@
30
30
  border: unset;
31
31
  border-radius: $border_rad_heavier;
32
32
  padding: 0;
33
-
33
+ background-color: $white;
34
34
  &:focus-visible {
35
35
  outline: none;
36
36
  }
@@ -42,9 +42,13 @@
42
42
  }
43
43
  }
44
44
 
45
+ .dropdown_trigger_wrapper_select_only {
46
+ box-shadow: inset 0 -11px 20px rgba($primary, 0.05);
47
+ }
48
+
45
49
  .dropdown_trigger_wrapper_focus {
46
50
  box-shadow: 0px 0px 0 1px $primary;
47
- transition: box-shadow .10s ease-in-out;
51
+ transition: box-shadow 0.1s ease-in-out;
48
52
  }
49
53
 
50
54
  .pb_dropdown_container {
@@ -60,7 +64,8 @@
60
64
  transition: opacity 0.25s ease-in-out;
61
65
 
62
66
  .pb_dropdown_option {
63
- :hover {
67
+ cursor: pointer;
68
+ &:hover {
64
69
  background-color: $border_light;
65
70
  }
66
71
  }
@@ -82,8 +87,8 @@
82
87
  [class^="pb_title_kit"] {
83
88
  color: $white !important;
84
89
  }
85
- :hover {
86
- background-color: unset;
90
+ &:hover {
91
+ background-color: $primary !important;
87
92
  }
88
93
  }
89
94
  }
@@ -1,6 +1,6 @@
1
1
  import React, { useState, useRef, useEffect, ReactElement } from "react";
2
2
  import classnames from "classnames";
3
- import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
3
+ import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
4
4
  import { globalProps } from "../utilities/globalProps";
5
5
 
6
6
  import Body from "../pb_body/_body";
@@ -22,6 +22,7 @@ type DropdownProps = {
22
22
  autocomplete?: boolean;
23
23
  className?: string;
24
24
  data?: { [key: string]: string };
25
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
25
26
  id?: string;
26
27
  children?: React.ReactChild[] | React.ReactChild | ReactElement[];
27
28
  options: GenericObject;
@@ -35,6 +36,7 @@ const Dropdown = (props: DropdownProps) => {
35
36
  children,
36
37
  className,
37
38
  data = {},
39
+ htmlOptions = {},
38
40
  id,
39
41
  options,
40
42
  onSelect,
@@ -42,6 +44,7 @@ const Dropdown = (props: DropdownProps) => {
42
44
 
43
45
  const ariaProps = buildAriaProps(aria);
44
46
  const dataProps = buildDataProps(data);
47
+ const htmlProps = buildHtmlProps(htmlOptions);
45
48
  const classes = classnames(
46
49
  buildCss("pb_dropdown"),
47
50
  globalProps(props),
@@ -51,7 +54,7 @@ const Dropdown = (props: DropdownProps) => {
51
54
  const [isDropDownClosed, setIsDropDownClosed, toggleDropdown] = useDropdown();
52
55
 
53
56
  const [filterItem, setFilterItem] = useState("");
54
- const [selected, setSelected] = useState({});
57
+ const [selected, setSelected] = useState<GenericObject>({});
55
58
  const [isInputFocused, setIsInputFocused] = useState(false);
56
59
  const [hasTriggerSubcomponent, setHasTriggerSubcomponent] = useState(true);
57
60
  const [hasContainerSubcomponent, setHasContainerSubcomponent] =
@@ -71,6 +74,7 @@ const Dropdown = (props: DropdownProps) => {
71
74
  const handleClickOutside = (e: MouseEvent) => {
72
75
  if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
73
76
  setIsDropDownClosed(true);
77
+ setFocusedOptionIndex(-1)
74
78
  setIsInputFocused(false);
75
79
  }
76
80
  };
@@ -85,6 +89,24 @@ const Dropdown = (props: DropdownProps) => {
85
89
  setHasContainerSubcomponent(!!container);
86
90
  }, []);
87
91
 
92
+
93
+ const filteredOptions = options?.filter((option: GenericObject) =>
94
+ option.label.toLowerCase().includes(filterItem.toLowerCase())
95
+ );
96
+
97
+ useEffect(() => {
98
+ if (!isDropDownClosed) {
99
+ let newIndex = 0;
100
+ if (selected && selected?.label) {
101
+ const selectedIndex = filteredOptions.findIndex((option: GenericObject) => option.label === selected.label);
102
+ if (selectedIndex >= 0) {
103
+ newIndex = selectedIndex;
104
+ }
105
+ }
106
+ setFocusedOptionIndex(newIndex);
107
+ }
108
+ }, [isDropDownClosed]);
109
+
88
110
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
89
111
  setFilterItem(e.target.value);
90
112
  setIsDropDownClosed(false);
@@ -108,10 +130,6 @@ const Dropdown = (props: DropdownProps) => {
108
130
  setFocusedOptionIndex(-1);
109
131
  };
110
132
 
111
- const filteredOptions = options?.filter((option: GenericObject) =>
112
- option.label.toLowerCase().includes(filterItem.toLowerCase())
113
- );
114
-
115
133
  const componentsToRender = prepareSubcomponents({
116
134
  children,
117
135
  hasTriggerSubcomponent,
@@ -124,6 +142,7 @@ const Dropdown = (props: DropdownProps) => {
124
142
  return (
125
143
  <div {...ariaProps}
126
144
  {...dataProps}
145
+ {...htmlProps}
127
146
  className={classes}
128
147
  id={id}
129
148
  >
@@ -150,6 +169,15 @@ const Dropdown = (props: DropdownProps) => {
150
169
  }}
151
170
  >
152
171
  <div className="dropdown_wrapper"
172
+ onBlur={() => {
173
+ // Debounce to delay the execution to prevent jumpiness in Focus state
174
+ setTimeout(() => {
175
+ if (!dropdownRef.current.contains(document.activeElement)) {
176
+ setIsInputFocused(false);
177
+ }
178
+ }, 0);
179
+ }}
180
+ onFocus={() => setIsInputFocused(true)}
153
181
  ref={dropdownRef}
154
182
  >
155
183
  {children ? (
@@ -14,11 +14,11 @@ const [selectedOption, setSelectedOption] = useState();
14
14
  id: "United-states"
15
15
  },
16
16
  {
17
- label: "Ukraine",
18
- value: "Ukraine",
19
- areaCode: "+380",
20
- icon: "πŸ‡ΊπŸ‡¦",
21
- id: "ukraine"
17
+ label: "Canada",
18
+ value: "Canada",
19
+ areaCode: "+1",
20
+ icon: "πŸ‡¨πŸ‡¦",
21
+ id: "canada"
22
22
  },
23
23
  {
24
24
  label: "Pakistan",
@@ -0,0 +1,87 @@
1
+ import React, { useState } from 'react'
2
+ import { Dropdown, User, Badge, FlexItem } from '../..'
3
+
4
+ const DropdownWithAutocomplete = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
7
+
8
+ const options = [
9
+ {
10
+ label: "Jasper Furniss",
11
+ value: "Jasper Furniss",
12
+ territory: "PHL",
13
+ title: "Senior UX Engineer",
14
+ id: "jasper-furniss",
15
+ status: "Offline"
16
+ },
17
+ {
18
+ label: "Ramon Ruiz",
19
+ value: "Ramon Ruiz",
20
+ territory: "PHL",
21
+ title: "Senior UX Desinger",
22
+ id: "ramon-ruiz",
23
+ status: "Away"
24
+ },
25
+ {
26
+ label: "Jason Cypret",
27
+ value: "Jason Cypret",
28
+ territory: "PHL",
29
+ title: "VP of User Experience",
30
+ id: "jason-cypret",
31
+ status: "Online"
32
+ },
33
+ {
34
+ label: "Courtney Long",
35
+ value: "Courtney Long",
36
+ territory: "PHL",
37
+ title: "UX Design Mentor",
38
+ id: "courtney-long",
39
+ status: "Online"
40
+ }
41
+ ];
42
+
43
+
44
+ return (
45
+ <div>
46
+ <Dropdown autocomplete
47
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
48
+ options={options}
49
+ {...props}
50
+ >
51
+ {options.map((option) => (
52
+ <Dropdown.Option key={option.id}
53
+ option={option}
54
+ >
55
+ <>
56
+ <FlexItem>
57
+ <User
58
+ align="left"
59
+ avatar
60
+ name={option.label}
61
+ orientation="horizontal"
62
+ territory={option.territory}
63
+ title={option.title}
64
+ />
65
+ </FlexItem>
66
+ <FlexItem>
67
+ <Badge
68
+ rounded
69
+ text={option.status}
70
+ variant={`${
71
+ option.status === "Offline"
72
+ ? "neutral"
73
+ : option.status === "Online"
74
+ ? "success"
75
+ : "warning"
76
+ }`}
77
+ />
78
+ </FlexItem>
79
+ </>
80
+ </Dropdown.Option>
81
+ ))}
82
+ </Dropdown>
83
+ </div>
84
+ )
85
+ }
86
+
87
+ export default DropdownWithAutocomplete
@@ -0,0 +1 @@
1
+ The `autocomplete` prop can be used to add autocomplete or typeahead functionality to the Dropdown's default Trigger. This prop is set to 'false' by default.
@@ -0,0 +1,102 @@
1
+ import React, { useState } from 'react'
2
+ import { Dropdown, User, Badge, FlexItem, Avatar } from '../..'
3
+
4
+ const DropdownWithAutocompleteAndCustomDisplay = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
7
+
8
+ const options = [
9
+ {
10
+ label: "Jasper Furniss",
11
+ value: "Jasper Furniss",
12
+ territory: "PHL",
13
+ title: "Senior UX Engineer",
14
+ id: "jasper-furniss",
15
+ status: "Offline"
16
+ },
17
+ {
18
+ label: "Ramon Ruiz",
19
+ value: "Ramon Ruiz",
20
+ territory: "PHL",
21
+ title: "Senior UX Desinger",
22
+ id: "ramon-ruiz",
23
+ status: "Away"
24
+ },
25
+ {
26
+ label: "Jason Cypret",
27
+ value: "Jason Cypret",
28
+ territory: "PHL",
29
+ title: "VP of User Experience",
30
+ id: "jason-cypret",
31
+ status: "Online"
32
+ },
33
+ {
34
+ label: "Courtney Long",
35
+ value: "Courtney Long",
36
+ territory: "PHL",
37
+ title: "UX Design Mentor",
38
+ id: "courtney-long",
39
+ status: "Online"
40
+ }
41
+ ];
42
+
43
+ const CustomDisplay = () => {
44
+ return (
45
+ <>
46
+ {
47
+ selectedOption && (
48
+ <Avatar
49
+ name={selectedOption.label}
50
+ size="xs"
51
+ />
52
+ )
53
+ }
54
+ </>
55
+ )
56
+ };
57
+
58
+ return (
59
+ <div>
60
+ <Dropdown autocomplete
61
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
62
+ options={options}
63
+ {...props}
64
+ >
65
+ <Dropdown.Trigger customDisplay={<CustomDisplay/>} />
66
+ {options.map((option) => (
67
+ <Dropdown.Option key={option.id}
68
+ option={option}
69
+ >
70
+ <>
71
+ <FlexItem>
72
+ <User
73
+ align="left"
74
+ avatar
75
+ name={option.label}
76
+ orientation="horizontal"
77
+ territory={option.territory}
78
+ title={option.title}
79
+ />
80
+ </FlexItem>
81
+ <FlexItem>
82
+ <Badge
83
+ rounded
84
+ text={option.status}
85
+ variant={`${
86
+ option.status === "Offline"
87
+ ? "neutral"
88
+ : option.status === "Online"
89
+ ? "success"
90
+ : "warning"
91
+ }`}
92
+ />
93
+ </FlexItem>
94
+ </>
95
+ </Dropdown.Option>
96
+ ))}
97
+ </Dropdown>
98
+ </div>
99
+ )
100
+ }
101
+
102
+ export default DropdownWithAutocompleteAndCustomDisplay
@@ -0,0 +1 @@
1
+ `autocomplete` prop can also be used in conjunction with the `customDisplay` prop.
@@ -39,7 +39,7 @@ const DropdownWithCustomDisplay = (props) => {
39
39
  }
40
40
  ];
41
41
 
42
- const customDisplay = () => {
42
+ const CustomDisplay = () => {
43
43
  return (
44
44
  <>
45
45
  {
@@ -62,7 +62,9 @@ const DropdownWithCustomDisplay = (props) => {
62
62
  options={options}
63
63
  {...props}
64
64
  >
65
- <Dropdown.Trigger customDisplay={customDisplay()}/>
65
+ <Dropdown.Trigger customDisplay={<CustomDisplay/>}
66
+ placeholder="Select a User"
67
+ />
66
68
  {options.map((option) => (
67
69
  <Dropdown.Option key={option.id}
68
70
  option={option}
@@ -0,0 +1,3 @@
1
+ The `customDisplay` prop can be used to customize the display of the selected item by allowing devs to pass in a component that will be rendered to the left of the default text-based display. In this example the Avatar kit is being used.
2
+
3
+ The `placeholder` prop can also be used to customize the placeholder text for the default Trigger.
@@ -14,11 +14,11 @@ const DropdownWithCustomOptions = (props) => {
14
14
  id: "United-states"
15
15
  },
16
16
  {
17
- label: "Ukraine",
18
- value: "Ukraine",
19
- areaCode: "+380",
20
- icon: "πŸ‡ΊπŸ‡¦",
21
- id: "ukraine"
17
+ label: "Canada",
18
+ value: "Canada",
19
+ areaCode: "+1",
20
+ icon: "πŸ‡¨πŸ‡¦",
21
+ id: "canada"
22
22
  },
23
23
  {
24
24
  label: "Pakistan",
@@ -0,0 +1 @@
1
+ The Dropdown also allows for custom options that can be passed in as children to the `Dropdown.Option` subcomponent. If no children are passed in the `Dropdown.Option`, the kit will render each option as text by default.
@@ -0,0 +1,51 @@
1
+ import React, { useState } from 'react'
2
+ import { Dropdown } from '../..'
3
+
4
+ const DropdownWithCustomPadding = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
7
+
8
+ const options = [
9
+ {
10
+ label: "United States",
11
+ value: "United States",
12
+ areaCode: "+1",
13
+ icon: "πŸ‡ΊπŸ‡Έ",
14
+ id: "United-states"
15
+ },
16
+ {
17
+ label: "Canada",
18
+ value: "Canada",
19
+ areaCode: "+1",
20
+ icon: "πŸ‡¨πŸ‡¦",
21
+ id: "canada"
22
+ },
23
+ {
24
+ label: "Pakistan",
25
+ value: "Pakistan",
26
+ areaCode: "+92",
27
+ icon: "πŸ‡΅πŸ‡°",
28
+ id: "pakistan"
29
+ }
30
+ ];
31
+
32
+
33
+ return (
34
+ <div>
35
+ <Dropdown
36
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
37
+ options={options}
38
+ {...props}
39
+ >
40
+ {options.map((option) => (
41
+ <Dropdown.Option key={option.id}
42
+ option={option}
43
+ padding="sm"
44
+ />
45
+ ))}
46
+ </Dropdown>
47
+ </div>
48
+ )
49
+ }
50
+
51
+ export default DropdownWithCustomPadding
@@ -0,0 +1 @@
1
+ By default, the padding on each option in the dropdown is set to `xs`. The `padding` Global Props however can be used to override this default. In this example, we are setting padding to `sm`.
@@ -14,11 +14,11 @@ const [selectedOption, setSelectedOption] = useState();
14
14
  id: "United-states"
15
15
  },
16
16
  {
17
- label: "Ukraine",
18
- value: "Ukraine",
19
- areaCode: "+380",
20
- icon: "πŸ‡ΊπŸ‡¦",
21
- id: "ukraine"
17
+ label: "Canada",
18
+ value: "Canada",
19
+ areaCode: "+1",
20
+ icon: "πŸ‡¨πŸ‡¦",
21
+ id: "canada"
22
22
  },
23
23
  {
24
24
  label: "Pakistan",
@@ -0,0 +1 @@
1
+ The Dropdown can also be given a custom Trigger by passing children to the `Dropdown.Trigger` subcomponent as shown in this example. Here we are using the IconCircle kit.
@@ -6,4 +6,7 @@ examples:
6
6
  - dropdown_with_custom_options: Custom Options
7
7
  - dropdown_with_custom_display: Custom Display
8
8
  - dropdown_with_custom_trigger: Custom Trigger
9
+ - dropdown_with_autocomplete: Autocomplete
10
+ - dropdown_with_autocomplete_and_custom_display: Autocomplete with Custom Display
11
+ - dropdown_with_custom_padding: Custom Padding for Dropdown Options
9
12
 
@@ -2,3 +2,6 @@ export { default as DropdownDefault } from './_dropdown_default.jsx'
2
2
  export { default as DropdownWithCustomDisplay } from './_dropdown_with_custom_display.jsx'
3
3
  export { default as DropdownWithCustomOptions } from './_dropdown_with_custom_options.jsx'
4
4
  export { default as DropdownWithCustomTrigger } from './_dropdown_with_custom_trigger.jsx'
5
+ export { default as DropdownWithAutocomplete } from './_dropdown_with_autocomplete.jsx'
6
+ export { default as DropdownWithAutocompleteAndCustomDisplay } from './_dropdown_with_autocomplete_and_custom_display.jsx'
7
+ export { default as DropdownWithCustomPadding } from './_dropdown_with_custom_padding.jsx'
@@ -12,10 +12,15 @@ const {
12
12
  handleOptionClick,
13
13
  setIsDropDownClosed,
14
14
  handleBackspace,
15
- selected
15
+ selected,
16
16
  }= useContext(DropdownContext)
17
17
 
18
18
  return (e: React.KeyboardEvent) => {
19
+
20
+ if (e.key !== "Tab" && autocomplete && selected && selected.label) {
21
+ handleBackspace();
22
+ }
23
+
19
24
  switch (e.key) {
20
25
  case "Backspace":
21
26
  case "Delete":
@@ -43,13 +48,13 @@ const {
43
48
  e.preventDefault();
44
49
  handleOptionClick(filteredOptions[focusedOptionIndex]);
45
50
  setFocusedOptionIndex(-1)
51
+ } else if (focusedOptionIndex === -1) {
52
+ setIsDropDownClosed(false)
46
53
  }
47
54
  break;
48
- default:
49
- if (selected && selected.label) {
50
- e.preventDefault();
51
- handleBackspace();
52
- }
55
+ case "Tab":
56
+ setIsDropDownClosed(true);
57
+ setFocusedOptionIndex(-1)
53
58
  break;
54
59
  }
55
60
  }
@@ -4,6 +4,7 @@ import {
4
4
  buildAriaProps,
5
5
  buildCss,
6
6
  buildDataProps,
7
+ buildHtmlProps
7
8
  } from "../../utilities/props";
8
9
  import { globalProps } from "../../utilities/globalProps";
9
10
 
@@ -19,6 +20,7 @@ type DropdownContainerProps = {
19
20
  className?: string;
20
21
  children?: React.ReactChild[] | React.ReactChild;
21
22
  data?: { [key: string]: string };
23
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
22
24
  id?: string;
23
25
  searchbar?: boolean;
24
26
  };
@@ -29,6 +31,7 @@ const DropdownContainer = (props: DropdownContainerProps) => {
29
31
  className,
30
32
  children,
31
33
  data = {},
34
+ htmlOptions = {},
32
35
  id,
33
36
  searchbar = false,
34
37
  } = props;
@@ -44,6 +47,7 @@ const DropdownContainer = (props: DropdownContainerProps) => {
44
47
 
45
48
  const ariaProps = buildAriaProps(aria);
46
49
  const dataProps = buildDataProps(data);
50
+ const htmlProps = buildHtmlProps(htmlOptions);
47
51
  const classes = classnames(
48
52
  buildCss("pb_dropdown_container"),
49
53
  `${isDropDownClosed ? "close" : "open"}`,
@@ -54,6 +58,7 @@ const DropdownContainer = (props: DropdownContainerProps) => {
54
58
  return (
55
59
  <div {...ariaProps}
56
60
  {...dataProps}
61
+ {...htmlProps}
57
62
  className={classes}
58
63
  id={id}
59
64
  onMouseEnter={() => setFocusedOptionIndex(-1)}