playbook_ui 13.24.0 → 13.25.0.pre.alpha.PBNTR272Dropdownkitv42769

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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +2 -0
  3. data/app/pb_kits/playbook/index.js +2 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +10 -14
  5. data/app/pb_kits/playbook/pb_advanced_table/table_body.html.erb +5 -9
  6. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +2 -6
  7. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -6
  8. data/app/pb_kits/playbook/pb_avatar/avatar.html.erb +1 -6
  9. data/app/pb_kits/playbook/pb_avatar_action_button/avatar_action_button.html.erb +1 -6
  10. data/app/pb_kits/playbook/pb_background/_background.tsx +7 -5
  11. data/app/pb_kits/playbook/pb_background/background.html.erb +2 -11
  12. data/app/pb_kits/playbook/pb_badge/badge.html.erb +1 -6
  13. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +41 -6
  14. data/app/pb_kits/playbook/pb_bar_graph/bar_graph.rb +4 -0
  15. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_negative_numbers.html.erb +23 -0
  16. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_negative_numbers.jsx +35 -0
  17. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_secondary_y_axis.html.erb +26 -0
  18. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_secondary_y_axis.jsx +36 -0
  19. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_secondary_y_axis.md +3 -0
  20. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_stacked.html.erb +22 -0
  21. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_stacked.jsx +34 -0
  22. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_stacked.md +1 -0
  23. data/app/pb_kits/playbook/pb_bar_graph/docs/example.yml +6 -0
  24. data/app/pb_kits/playbook/pb_bar_graph/docs/index.js +3 -0
  25. data/app/pb_kits/playbook/pb_body/_body.scss +3 -3
  26. data/app/pb_kits/playbook/pb_body/_body.tsx +1 -1
  27. data/app/pb_kits/playbook/pb_body/body.html.erb +1 -6
  28. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumb_item.html.erb +1 -6
  29. data/app/pb_kits/playbook/pb_bread_crumbs/bread_crumbs.html.erb +2 -7
  30. data/app/pb_kits/playbook/pb_button/_button.scss +1 -1
  31. data/app/pb_kits/playbook/pb_button/button.html.erb +2 -3
  32. data/app/pb_kits/playbook/pb_button_toolbar/button_toolbar.html.erb +2 -7
  33. data/app/pb_kits/playbook/pb_caption/caption.html.erb +1 -6
  34. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -7
  35. data/app/pb_kits/playbook/pb_card/card_body.html.erb +1 -6
  36. data/app/pb_kits/playbook/pb_card/card_header.html.erb +1 -6
  37. data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +1 -6
  38. data/app/pb_kits/playbook/pb_circle_icon_button/circle_icon_button.html.erb +1 -6
  39. data/app/pb_kits/playbook/pb_collapsible/collapsible.html.erb +1 -6
  40. data/app/pb_kits/playbook/pb_collapsible/collapsible_content.html.erb +1 -6
  41. data/app/pb_kits/playbook/pb_collapsible/collapsible_main.html.erb +1 -7
  42. data/app/pb_kits/playbook/pb_contact/contact.html.erb +1 -6
  43. data/app/pb_kits/playbook/pb_currency/currency.html.erb +1 -6
  44. data/app/pb_kits/playbook/pb_currency/docs/_currency_alignment_swift.md +43 -0
  45. data/app/pb_kits/playbook/pb_currency/docs/_currency_props_swift.md +12 -0
  46. data/app/pb_kits/playbook/pb_currency/docs/_currency_size_swift.md +31 -0
  47. data/app/pb_kits/playbook/pb_currency/docs/example.yml +5 -0
  48. data/app/pb_kits/playbook/pb_dashboard_value/dashboard_value.html.erb +1 -6
  49. data/app/pb_kits/playbook/pb_date/date.html.erb +1 -6
  50. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +2 -6
  51. data/app/pb_kits/playbook/pb_date_range_inline/date_range_inline.html.erb +1 -5
  52. data/app/pb_kits/playbook/pb_date_range_stacked/date_range_stacked.html.erb +1 -5
  53. data/app/pb_kits/playbook/pb_date_range_stacked/docs/_date_range_stacked_default_swift.md +14 -0
  54. data/app/pb_kits/playbook/pb_date_range_stacked/docs/_date_range_stacked_props_swift.md +9 -0
  55. data/app/pb_kits/playbook/pb_date_range_stacked/docs/example.yml +4 -0
  56. data/app/pb_kits/playbook/pb_date_stacked/date_stacked.html.erb +1 -5
  57. data/app/pb_kits/playbook/pb_date_time/date_time.html.erb +1 -6
  58. data/app/pb_kits/playbook/pb_date_time_stacked/date_time_stacked.html.erb +1 -7
  59. data/app/pb_kits/playbook/pb_date_year_stacked/date_year_stacked.html.erb +1 -5
  60. data/app/pb_kits/playbook/pb_detail/detail.html.erb +1 -6
  61. data/app/pb_kits/playbook/pb_dialog/_dialog.scss +4 -2
  62. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +1 -6
  63. data/app/pb_kits/playbook/pb_dialog/dialog_body.html.erb +2 -7
  64. data/app/pb_kits/playbook/pb_dialog/dialog_footer.html.erb +1 -5
  65. data/app/pb_kits/playbook/pb_dialog/dialog_header.html.erb +2 -6
  66. data/app/pb_kits/playbook/pb_dialog/docs/example.yml +1 -1
  67. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +181 -0
  68. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +266 -0
  69. data/app/pb_kits/playbook/pb_dropdown/context/index.tsx +5 -0
  70. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.jsx +38 -0
  71. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.md +1 -0
  72. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +87 -0
  73. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.md +1 -0
  74. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.jsx +102 -0
  75. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.md +1 -0
  76. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +104 -0
  77. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.md +5 -0
  78. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.jsx +63 -0
  79. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.md +1 -0
  80. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.jsx +48 -0
  81. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.md +1 -0
  82. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger.jsx +77 -0
  83. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger.md +1 -0
  84. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.jsx +62 -0
  85. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_hook.jsx +75 -0
  86. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.jsx +39 -0
  87. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.md +1 -0
  88. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +15 -0
  89. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +10 -0
  90. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +207 -0
  91. data/app/pb_kits/playbook/pb_dropdown/hooks/useDropdown.tsx +17 -0
  92. data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +61 -0
  93. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +109 -0
  94. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +116 -0
  95. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +190 -0
  96. data/app/pb_kits/playbook/pb_dropdown/utilities/subComponentHelper.tsx +61 -0
  97. data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +1 -6
  98. data/app/pb_kits/playbook/pb_filter/filter.html.erb +1 -5
  99. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.html.erb +1 -6
  100. data/app/pb_kits/playbook/pb_flex/flex.html.erb +1 -5
  101. data/app/pb_kits/playbook/pb_flex/flex_item.html.erb +2 -6
  102. data/app/pb_kits/playbook/pb_form_group/form_group.html.erb +1 -6
  103. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +1 -1
  104. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -6
  105. data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +1 -5
  106. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +1 -5
  107. data/app/pb_kits/playbook/pb_icon_circle/_icon_circle.scss +1 -1
  108. data/app/pb_kits/playbook/pb_icon_circle/_icon_circle.tsx +1 -1
  109. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.html.erb +2 -7
  110. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.rb +1 -1
  111. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.test.js +3 -3
  112. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.html.erb +1 -6
  113. data/app/pb_kits/playbook/pb_icon_value/icon_value.html.erb +1 -6
  114. data/app/pb_kits/playbook/pb_label_pill/label_pill.html.erb +1 -6
  115. data/app/pb_kits/playbook/pb_label_value/label_value.html.erb +1 -6
  116. data/app/pb_kits/playbook/pb_layout/body.html.erb +1 -5
  117. data/app/pb_kits/playbook/pb_layout/footer.html.erb +1 -5
  118. data/app/pb_kits/playbook/pb_layout/header.html.erb +1 -5
  119. data/app/pb_kits/playbook/pb_layout/item.html.erb +1 -5
  120. data/app/pb_kits/playbook/pb_layout/layout.html.erb +1 -5
  121. data/app/pb_kits/playbook/pb_layout/sidebar.html.erb +1 -5
  122. data/app/pb_kits/playbook/pb_list/_list_item.tsx +2 -2
  123. data/app/pb_kits/playbook/pb_list/item.html.erb +2 -8
  124. data/app/pb_kits/playbook/pb_list/list.html.erb +2 -8
  125. data/app/pb_kits/playbook/pb_loading_inline/loading_inline.html.erb +1 -6
  126. data/app/pb_kits/playbook/pb_message/message.html.erb +1 -6
  127. data/app/pb_kits/playbook/pb_message/message_mention.html.erb +1 -6
  128. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb +1 -6
  129. data/app/pb_kits/playbook/pb_multiple_users/multiple_users.html.erb +1 -6
  130. data/app/pb_kits/playbook/pb_multiple_users_stacked/multiple_users_stacked.html.erb +1 -6
  131. data/app/pb_kits/playbook/pb_nav/item.html.erb +3 -14
  132. data/app/pb_kits/playbook/pb_nav/nav.html.erb +1 -6
  133. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +2 -6
  134. data/app/pb_kits/playbook/pb_pagination/pagination.html.erb +1 -6
  135. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -1
  136. data/app/pb_kits/playbook/pb_person/person.html.erb +7 -12
  137. data/app/pb_kits/playbook/pb_person_contact/person_contact.html.erb +1 -6
  138. data/app/pb_kits/playbook/pb_pill/pill.html.erb +1 -6
  139. data/app/pb_kits/playbook/pb_popover/popover.html.erb +1 -6
  140. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.html.erb +2 -6
  141. data/app/pb_kits/playbook/pb_progress_simple/progress_simple.html.erb +3 -6
  142. data/app/pb_kits/playbook/pb_progress_step/progress_step.html.erb +1 -5
  143. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.html.erb +1 -5
  144. data/app/pb_kits/playbook/pb_radio/radio.html.erb +2 -8
  145. data/app/pb_kits/playbook/pb_section_separator/_section_separator.scss +6 -2
  146. data/app/pb_kits/playbook/pb_section_separator/_section_separator_mixin.scss +11 -1
  147. data/app/pb_kits/playbook/pb_section_separator/section_separator.html.erb +1 -6
  148. data/app/pb_kits/playbook/pb_select/select.html.erb +1 -5
  149. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -5
  150. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +1 -4
  151. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +1 -5
  152. data/app/pb_kits/playbook/pb_selectable_list/selectable_list.html.erb +1 -6
  153. data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.html.erb +1 -6
  154. data/app/pb_kits/playbook/pb_source/source.html.erb +1 -5
  155. data/app/pb_kits/playbook/pb_source/source.test.js +2 -2
  156. data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +1 -5
  157. data/app/pb_kits/playbook/pb_stat_change/stat_change.html.erb +1 -5
  158. data/app/pb_kits/playbook/pb_stat_value/stat_value.html.erb +1 -5
  159. data/app/pb_kits/playbook/pb_table/table.html.erb +2 -12
  160. data/app/pb_kits/playbook/pb_table/table_body.html.erb +6 -16
  161. data/app/pb_kits/playbook/pb_table/table_cell.html.erb +6 -16
  162. data/app/pb_kits/playbook/pb_table/table_head.html.erb +6 -16
  163. data/app/pb_kits/playbook/pb_table/table_header.html.erb +4 -13
  164. data/app/pb_kits/playbook/pb_table/table_row.html.erb +6 -16
  165. data/app/pb_kits/playbook/pb_textarea/textarea.html.erb +1 -5
  166. data/app/pb_kits/playbook/pb_time/time.html.erb +1 -5
  167. data/app/pb_kits/playbook/pb_time_range_inline/time_range_inline.html.erb +1 -5
  168. data/app/pb_kits/playbook/pb_time_stacked/time_stacked.html.erb +1 -5
  169. data/app/pb_kits/playbook/pb_timeline/item.html.erb +3 -7
  170. data/app/pb_kits/playbook/pb_timeline/timeline.html.erb +1 -5
  171. data/app/pb_kits/playbook/pb_timestamp/timestamp.html.erb +1 -6
  172. data/app/pb_kits/playbook/pb_title/title.html.erb +1 -6
  173. data/app/pb_kits/playbook/pb_title_count/title_count.html.erb +1 -6
  174. data/app/pb_kits/playbook/pb_title_detail/title_detail.html.erb +1 -5
  175. data/app/pb_kits/playbook/pb_toggle/toggle.html.erb +1 -6
  176. data/app/pb_kits/playbook/pb_tooltip/tooltip.html.erb +1 -5
  177. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +27 -19
  178. data/app/pb_kits/playbook/pb_typeahead/components/MenuList.tsx +4 -2
  179. data/app/pb_kits/playbook/pb_typeahead/components/index.tsx +19 -0
  180. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_menu_list.jsx +51 -0
  181. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +1 -1
  182. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
  183. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
  184. data/app/pb_kits/playbook/pb_user/user.html.erb +1 -6
  185. data/app/pb_kits/playbook/pb_user_badge/user_badge.html.erb +1 -6
  186. data/app/pb_kits/playbook/pb_weekday_stacked/weekday_stacked.html.erb +1 -6
  187. data/app/pb_kits/playbook/playbook-doc.js +2 -0
  188. data/app/pb_kits/playbook/tokens/_colors.scss +1 -1
  189. data/dist/menu.yml +5 -1
  190. data/dist/playbook-rails.js +6 -6
  191. data/lib/playbook/kit_base.rb +21 -1
  192. data/lib/playbook/version.rb +2 -2
  193. metadata +51 -6
  194. /data/app/pb_kits/playbook/pb_dialog/docs/{_dialog_props_table.md → _dialog_props_swift.md} +0 -0
@@ -0,0 +1,48 @@
1
+ import React from 'react'
2
+ import { Dropdown } from '../..'
3
+
4
+ const DropdownWithCustomPadding = (props) => {
5
+
6
+ const options = [
7
+ {
8
+ label: "United States",
9
+ value: "United States",
10
+ areaCode: "+1",
11
+ icon: "🇺🇸",
12
+ id: "United-states"
13
+ },
14
+ {
15
+ label: "Canada",
16
+ value: "Canada",
17
+ areaCode: "+1",
18
+ icon: "🇨🇦",
19
+ id: "canada"
20
+ },
21
+ {
22
+ label: "Pakistan",
23
+ value: "Pakistan",
24
+ areaCode: "+92",
25
+ icon: "🇵🇰",
26
+ id: "pakistan"
27
+ }
28
+ ];
29
+
30
+
31
+ return (
32
+ <div>
33
+ <Dropdown
34
+ options={options}
35
+ {...props}
36
+ >
37
+ {options.map((option) => (
38
+ <Dropdown.Option key={option.id}
39
+ option={option}
40
+ padding="sm"
41
+ />
42
+ ))}
43
+ </Dropdown>
44
+ </div>
45
+ )
46
+ }
47
+
48
+ 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`.
@@ -0,0 +1,77 @@
1
+ import React, { useState } from 'react'
2
+ import { Dropdown, Icon, Body, FlexItem, Flex, IconCircle } from '../..'
3
+
4
+ const DropdownWithCustomTrigger = (props) => {
5
+
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
+ <Dropdown.Trigger>
41
+ <div key={selectedOption ? selectedOption.icon : "flag"}>
42
+ <IconCircle
43
+ cursor="pointer"
44
+ icon={selectedOption ? selectedOption.icon : "flag"}
45
+ variant="royal"
46
+ />
47
+ </div>
48
+ </Dropdown.Trigger>
49
+ <Dropdown.Container maxWidth="xs">
50
+ {options.map((option) => (
51
+ <Dropdown.Option key={option.id}
52
+ option={option}
53
+ >
54
+ <>
55
+ <FlexItem>
56
+ <Flex>
57
+ <Icon icon={option.icon}
58
+ paddingRight="xs"
59
+ />
60
+ <Body text={option.label} />
61
+ </Flex>
62
+ </FlexItem>
63
+ <FlexItem>
64
+ <Body color="light"
65
+ text={option.areaCode}
66
+ />
67
+ </FlexItem>
68
+ </>
69
+ </Dropdown.Option>
70
+ ))}
71
+ </Dropdown.Container>
72
+ </Dropdown>
73
+ </div>
74
+ )
75
+ }
76
+
77
+ export default DropdownWithCustomTrigger
@@ -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.
@@ -0,0 +1,62 @@
1
+ import React, { useState } from 'react'
2
+ import { Dropdown, useDropdown, Button } from '../../'
3
+
4
+ const DropdownWithExternalControl = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
7
+ const [isDropDownClosed, setIsDropdownClosed] = useDropdown(true);
8
+
9
+ const options = [
10
+ {
11
+ label: "United States",
12
+ value: "United States",
13
+ areaCode: "+1",
14
+ icon: "🇺🇸",
15
+ id: "United-states"
16
+ },
17
+ {
18
+ label: "Canada",
19
+ value: "Canada",
20
+ areaCode: "+1",
21
+ icon: "🇨🇦",
22
+ id: "canada"
23
+ },
24
+ {
25
+ label: "Pakistan",
26
+ value: "Pakistan",
27
+ areaCode: "+92",
28
+ icon: "🇵🇰",
29
+ id: "pakistan"
30
+ }
31
+ ];
32
+
33
+ return (
34
+ <div>
35
+ <Button
36
+ data={{dropdown:'pb-dropdown-trigger'}}
37
+ marginBottom='sm'
38
+ onClick={() => setIsDropdownClosed(!isDropDownClosed)}
39
+ padding="none"
40
+ tabIndex={0}
41
+ variant="link"
42
+ >
43
+ {isDropDownClosed ? "Open Dropdown" : "Close Dropdown"}
44
+ </Button>
45
+
46
+ <Dropdown
47
+ isClosed={isDropDownClosed}
48
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
49
+ options={options}
50
+ {...props}
51
+ >
52
+ {options.map((option) => (
53
+ <Dropdown.Option key={option.id}
54
+ option={option}
55
+ />
56
+ ))}
57
+ </Dropdown>
58
+ </div>
59
+ )
60
+ }
61
+
62
+ export default DropdownWithExternalControl
@@ -0,0 +1,75 @@
1
+ import React, { useState, useRef } from 'react'
2
+ import { Dropdown, useDropdown, CircleIconButton, Icon, Body, FlexItem, Flex } from '../..'
3
+
4
+ const DropdownWithHook = (props) => {
5
+ // eslint-disable-next-line no-unused-vars
6
+ const [selectedOption, setSelectedOption] = useState();
7
+ const [isDropDownClosed, setIsDropdownClosed] = useDropdown(true);
8
+ const buttonRef = useRef(null);
9
+
10
+ const options = [
11
+ {
12
+ label: "United States",
13
+ value: "United States",
14
+ areaCode: "+1",
15
+ icon: "🇺🇸",
16
+ id: "United-states"
17
+ },
18
+ {
19
+ label: "Canada",
20
+ value: "Canada",
21
+ areaCode: "+1",
22
+ icon: "🇨🇦",
23
+ id: "canada"
24
+ },
25
+ {
26
+ label: "Pakistan",
27
+ value: "Pakistan",
28
+ areaCode: "+92",
29
+ icon: "🇵🇰",
30
+ id: "pakistan"
31
+ }
32
+ ];
33
+
34
+ return (
35
+ <div>
36
+ <CircleIconButton
37
+ htmlOptions={{ref: buttonRef}}
38
+ icon={"flag"}
39
+ onClick={() => setIsDropdownClosed(!isDropDownClosed)}
40
+ variant="secondary"
41
+ />
42
+ <Dropdown
43
+ isClosed={isDropDownClosed}
44
+ onSelect={(selectedItem) => setSelectedOption(selectedItem)}
45
+ options={options}
46
+ triggerRef={buttonRef}
47
+ {...props}
48
+ >
49
+ {options.map((option) => (
50
+ <Dropdown.Option key={option.id}
51
+ option={option}
52
+ >
53
+ <>
54
+ <FlexItem>
55
+ <Flex paddingRight='md'>
56
+ <Icon icon={option.icon}
57
+ paddingRight="xs"
58
+ />
59
+ <Body text={option.label} />
60
+ </Flex>
61
+ </FlexItem>
62
+ <FlexItem>
63
+ <Body color="light"
64
+ text={option.areaCode}
65
+ />
66
+ </FlexItem>
67
+ </>
68
+ </Dropdown.Option>
69
+ ))}
70
+ </Dropdown>
71
+ </div>
72
+ )
73
+ }
74
+
75
+ export default DropdownWithHook
@@ -0,0 +1,39 @@
1
+ import React from 'react'
2
+ import { Dropdown } from '../..'
3
+
4
+ const DropdownDefault = (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
+ label="Select a Country"
26
+ options={options}
27
+ {...props}
28
+ >
29
+ {options.map((option) => (
30
+ <Dropdown.Option key={option.id}
31
+ option={option}
32
+ />
33
+ ))}
34
+ </Dropdown>
35
+ </div>
36
+ )
37
+ }
38
+
39
+ export default DropdownDefault
@@ -0,0 +1 @@
1
+ The optional `label` prop takes a string value that if present will render that string as the label for the Dropdown.
@@ -0,0 +1,15 @@
1
+ examples:
2
+
3
+
4
+ react:
5
+ - dropdown_default: Default
6
+ - dropdown_with_label: With Label
7
+ - dropdown_with_custom_options: Custom Options
8
+ - dropdown_with_custom_display: Custom Display
9
+ - dropdown_with_custom_trigger: Custom Trigger
10
+ - dropdown_with_custom_padding: Custom Padding for Dropdown Options
11
+ # - dropdown_with_autocomplete: Autocomplete
12
+ # - dropdown_with_autocomplete_and_custom_display: Autocomplete with Custom Display
13
+ # - dropdown_with_external_control: useDropdown Hook
14
+ # - dropdown_with_hook: useDropdown Hook with Any Trigger
15
+
@@ -0,0 +1,10 @@
1
+ export { default as DropdownDefault } from './_dropdown_default.jsx'
2
+ export { default as DropdownWithCustomDisplay } from './_dropdown_with_custom_display.jsx'
3
+ export { default as DropdownWithCustomOptions } from './_dropdown_with_custom_options.jsx'
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'
8
+ export { default as DropdownWithLabel } from './_dropdown_with_label.jsx'
9
+ export { default as DropdownWithExternalControl } from './_dropdown_with_external_control.jsx'
10
+ export { default as DropdownWithHook } from './_dropdown_with_hook.jsx'
@@ -0,0 +1,207 @@
1
+ import React from "react"
2
+ import { render, screen } from "../utilities/test-utils"
3
+
4
+ import { Dropdown, Icon } from '../'
5
+
6
+
7
+ const testId = 'dropdown'
8
+
9
+ const options = [
10
+ {
11
+ label: "United States",
12
+ value: "United States",
13
+ areaCode: "+1",
14
+ icon: "🇺🇸",
15
+ id: "United-states"
16
+ },
17
+ {
18
+ label: "Canada",
19
+ value: "Canada",
20
+ areaCode: "+1",
21
+ icon: "🇨🇦",
22
+ id: "canada"
23
+ },
24
+ {
25
+ label: "Pakistan",
26
+ value: "Pakistan",
27
+ areaCode: "+92",
28
+ icon: "🇵🇰",
29
+ id: "pakistan"
30
+ }
31
+ ];
32
+
33
+ const DefaultDropdownKit = () => {
34
+ return (
35
+ <Dropdown
36
+ data={{ testid: testId }}
37
+ options={options}
38
+ >
39
+ {options.map((option) => (
40
+ <Dropdown.Option key={option.id}
41
+ option={option}
42
+ />
43
+ ))}
44
+ </Dropdown>
45
+ )
46
+ }
47
+
48
+ test('generated default kit and classname', () => {
49
+ render(<DefaultDropdownKit/>)
50
+
51
+ const kit = screen.getByTestId(testId)
52
+ expect(kit).toBeInTheDocument()
53
+ expect(kit).toHaveClass('pb_dropdown')
54
+ })
55
+
56
+ test('generated default Trigger and Container when none passed in', () => {
57
+ render(<DefaultDropdownKit/>)
58
+
59
+ const kit = screen.getByTestId(testId)
60
+
61
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
62
+ expect(trigger).toBeInTheDocument()
63
+
64
+ const container = kit.querySelector('.pb_dropdown_container')
65
+ expect(container).toBeInTheDocument()
66
+
67
+ const defaultTrigger = kit.querySelector('.dropdown_trigger_wrapper_select_only')
68
+ expect(defaultTrigger).toBeInTheDocument()
69
+ })
70
+
71
+ test('generated Options', () => {
72
+ render(<DefaultDropdownKit/>)
73
+
74
+ const kit = screen.getByTestId(testId)
75
+ const option = kit.querySelector('.pb_dropdown_option')
76
+ expect(option).toBeInTheDocument()
77
+ })
78
+
79
+ test('generated customDisplay for trigger', () => {
80
+ render (
81
+ <Dropdown
82
+ data={{ testid: testId }}
83
+ options={options}
84
+ >
85
+ <Dropdown.Trigger
86
+ customDisplay={<Icon icon="flag" />}
87
+ />
88
+ {options.map((option) => (
89
+ <Dropdown.Option key={option.id}
90
+ option={option}
91
+ />
92
+ ))}
93
+ </Dropdown>
94
+ )
95
+
96
+ const kit = screen.getByTestId(testId)
97
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
98
+ const customDisplay = trigger.querySelector('.fa-flag.pb_icon_kit.fa-fw')
99
+ expect(customDisplay).toBeInTheDocument()
100
+ })
101
+
102
+ test('generated placeholder prop', () => {
103
+ render (
104
+ <Dropdown
105
+ data={{ testid: testId }}
106
+ options={options}
107
+ >
108
+ <Dropdown.Trigger
109
+ placeholder="Select a country"
110
+ />
111
+ {options.map((option) => (
112
+ <Dropdown.Option key={option.id}
113
+ option={option}
114
+ />
115
+ ))}
116
+ </Dropdown>
117
+ )
118
+
119
+ const kit = screen.getByTestId(testId)
120
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
121
+ expect(trigger).toHaveTextContent('Select a country')
122
+
123
+ })
124
+
125
+ test('generated label prop', () => {
126
+ render (
127
+ <Dropdown
128
+ data={{ testid: testId }}
129
+ label="Countries"
130
+ options={options}
131
+ >
132
+ {options.map((option) => (
133
+ <Dropdown.Option key={option.id}
134
+ option={option}
135
+ />
136
+ ))}
137
+ </Dropdown>
138
+ )
139
+
140
+ const kit = screen.getByTestId(testId)
141
+ const label = kit.querySelector('.pb_caption_kit_md')
142
+ expect(label).toHaveTextContent('Countries')
143
+ })
144
+
145
+ test('generated custom option', () => {
146
+ render (
147
+ <Dropdown
148
+ data={{ testid: testId }}
149
+ options={options}
150
+ >
151
+ {options.map((option) => (
152
+ <Dropdown.Option key={option.id}
153
+ option={option}
154
+ >
155
+ <Icon icon={option.icon} />
156
+ </Dropdown.Option>
157
+ ))}
158
+ </Dropdown>
159
+ )
160
+
161
+ const kit = screen.getByTestId(testId)
162
+ const customOption = kit.querySelector('.pb_icon_kit_emoji')
163
+ expect(customOption).toBeInTheDocument()
164
+ })
165
+
166
+ test('generated custom Trigger', () => {
167
+ render (
168
+ <Dropdown
169
+ data={{ testid: testId }}
170
+ options={options}
171
+ >
172
+ <Dropdown.Trigger>
173
+ <Icon icon="home" />
174
+ </Dropdown.Trigger>
175
+ {options.map((option) => (
176
+ <Dropdown.Option key={option.id}
177
+ option={option}
178
+ />
179
+ ))}
180
+ </Dropdown>
181
+ )
182
+
183
+ const kit = screen.getByTestId(testId)
184
+ const trigger = kit.querySelector('.pb_dropdown_trigger')
185
+ const customTrigger = trigger.querySelector('.fa-home.pb_icon_kit.fa-fw')
186
+ expect(customTrigger).toBeInTheDocument()
187
+ })
188
+
189
+ test('selected option on click', () => {
190
+ render (
191
+ <Dropdown
192
+ data={{ testid: testId }}
193
+ options={options}
194
+ >
195
+ {options.map((option) => (
196
+ <Dropdown.Option key={option.id}
197
+ option={option}
198
+ />
199
+ ))}
200
+ </Dropdown>
201
+ )
202
+
203
+ const kit = screen.getByTestId(testId)
204
+ const option = kit.querySelector('.pb_dropdown_option')
205
+ option.click()
206
+ expect(option).toHaveClass('pb_dropdown_option dropdown_option_selected p_xs')
207
+ })
@@ -0,0 +1,17 @@
1
+ import {useState} from 'react';
2
+
3
+
4
+ const useDropdown = (initial= true) => {
5
+
6
+ const [isDropDownClosed, setIsDropDownClosed] = useState(initial);
7
+
8
+ const toggleDropdown = () => setIsDropDownClosed((prev) => !prev);
9
+
10
+ return [
11
+ isDropDownClosed,
12
+ setIsDropDownClosed as any,
13
+ toggleDropdown
14
+ ]
15
+ }
16
+
17
+ export default useDropdown
@@ -0,0 +1,61 @@
1
+ import React, { useContext } from "react";
2
+ import DropdownContext from "../context";
3
+
4
+
5
+ export const useHandleOnKeyDown = () => {
6
+
7
+ const {
8
+ autocomplete,
9
+ filteredOptions,
10
+ focusedOptionIndex,
11
+ handleBackspace,
12
+ handleOptionClick,
13
+ selected,
14
+ setFocusedOptionIndex,
15
+ setIsDropDownClosed,
16
+ }= useContext(DropdownContext)
17
+
18
+ return (e: React.KeyboardEvent) => {
19
+
20
+ if (e.key !== "Tab" && autocomplete && selected && selected.label) {
21
+ handleBackspace();
22
+ }
23
+
24
+ switch (e.key) {
25
+ case "Backspace":
26
+ case "Delete":
27
+ if (autocomplete) {
28
+ handleBackspace();
29
+ }
30
+ break;
31
+ case "ArrowDown": {
32
+ e.preventDefault();
33
+ setIsDropDownClosed(false);
34
+ const nextIndex = (focusedOptionIndex + 1) % filteredOptions.length;
35
+ setFocusedOptionIndex(nextIndex);
36
+ break;
37
+ }
38
+ case "ArrowUp": {
39
+ e.preventDefault();
40
+ const nextIndexUp =
41
+ (focusedOptionIndex - 1 + filteredOptions.length) %
42
+ filteredOptions.length;
43
+ setFocusedOptionIndex(nextIndexUp);
44
+ break;
45
+ }
46
+ case "Enter":
47
+ if (focusedOptionIndex !== -1) {
48
+ e.preventDefault();
49
+ handleOptionClick(filteredOptions[focusedOptionIndex]);
50
+ setFocusedOptionIndex(-1)
51
+ } else if (focusedOptionIndex === -1) {
52
+ setIsDropDownClosed(false)
53
+ }
54
+ break;
55
+ case "Tab":
56
+ setIsDropDownClosed(true);
57
+ setFocusedOptionIndex(-1)
58
+ break;
59
+ }
60
+ }
61
+ };