playbook_ui 13.24.0 → 13.25.0.pre.alpha.barchartfix2766

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 (190) 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 +1 -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 +103 -0
  68. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +214 -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 +50 -0
  71. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.md +0 -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 +3 -0
  78. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.jsx +66 -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 +51 -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/example.yml +12 -0
  85. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +7 -0
  86. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +17 -0
  87. data/app/pb_kits/playbook/pb_dropdown/hooks/useDropdown.tsx +17 -0
  88. data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +61 -0
  89. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +100 -0
  90. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +108 -0
  91. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +172 -0
  92. data/app/pb_kits/playbook/pb_dropdown/utilities/subComponentHelper.tsx +59 -0
  93. data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +1 -6
  94. data/app/pb_kits/playbook/pb_filter/filter.html.erb +1 -5
  95. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.html.erb +1 -6
  96. data/app/pb_kits/playbook/pb_flex/flex.html.erb +1 -5
  97. data/app/pb_kits/playbook/pb_flex/flex_item.html.erb +2 -6
  98. data/app/pb_kits/playbook/pb_form_group/form_group.html.erb +1 -6
  99. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +1 -1
  100. data/app/pb_kits/playbook/pb_hashtag/hashtag.html.erb +1 -6
  101. data/app/pb_kits/playbook/pb_highlight/highlight.html.erb +1 -5
  102. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.html.erb +1 -5
  103. data/app/pb_kits/playbook/pb_icon_circle/_icon_circle.scss +1 -1
  104. data/app/pb_kits/playbook/pb_icon_circle/_icon_circle.tsx +1 -1
  105. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.html.erb +2 -7
  106. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.rb +1 -1
  107. data/app/pb_kits/playbook/pb_icon_circle/icon_circle.test.js +3 -3
  108. data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.html.erb +1 -6
  109. data/app/pb_kits/playbook/pb_icon_value/icon_value.html.erb +1 -6
  110. data/app/pb_kits/playbook/pb_label_pill/label_pill.html.erb +1 -6
  111. data/app/pb_kits/playbook/pb_label_value/label_value.html.erb +1 -6
  112. data/app/pb_kits/playbook/pb_layout/body.html.erb +1 -5
  113. data/app/pb_kits/playbook/pb_layout/footer.html.erb +1 -5
  114. data/app/pb_kits/playbook/pb_layout/header.html.erb +1 -5
  115. data/app/pb_kits/playbook/pb_layout/item.html.erb +1 -5
  116. data/app/pb_kits/playbook/pb_layout/layout.html.erb +1 -5
  117. data/app/pb_kits/playbook/pb_layout/sidebar.html.erb +1 -5
  118. data/app/pb_kits/playbook/pb_list/_list_item.tsx +2 -2
  119. data/app/pb_kits/playbook/pb_list/item.html.erb +2 -8
  120. data/app/pb_kits/playbook/pb_list/list.html.erb +2 -8
  121. data/app/pb_kits/playbook/pb_loading_inline/loading_inline.html.erb +1 -6
  122. data/app/pb_kits/playbook/pb_message/message.html.erb +1 -6
  123. data/app/pb_kits/playbook/pb_message/message_mention.html.erb +1 -6
  124. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.html.erb +1 -6
  125. data/app/pb_kits/playbook/pb_multiple_users/multiple_users.html.erb +1 -6
  126. data/app/pb_kits/playbook/pb_multiple_users_stacked/multiple_users_stacked.html.erb +1 -6
  127. data/app/pb_kits/playbook/pb_nav/item.html.erb +3 -14
  128. data/app/pb_kits/playbook/pb_nav/nav.html.erb +1 -6
  129. data/app/pb_kits/playbook/pb_online_status/online_status.html.erb +2 -6
  130. data/app/pb_kits/playbook/pb_pagination/pagination.html.erb +1 -6
  131. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -1
  132. data/app/pb_kits/playbook/pb_person/person.html.erb +7 -12
  133. data/app/pb_kits/playbook/pb_person_contact/person_contact.html.erb +1 -6
  134. data/app/pb_kits/playbook/pb_pill/pill.html.erb +1 -6
  135. data/app/pb_kits/playbook/pb_popover/popover.html.erb +1 -6
  136. data/app/pb_kits/playbook/pb_progress_pills/progress_pills.html.erb +2 -6
  137. data/app/pb_kits/playbook/pb_progress_simple/progress_simple.html.erb +3 -6
  138. data/app/pb_kits/playbook/pb_progress_step/progress_step.html.erb +1 -5
  139. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.html.erb +1 -5
  140. data/app/pb_kits/playbook/pb_radio/radio.html.erb +2 -8
  141. data/app/pb_kits/playbook/pb_section_separator/_section_separator.scss +6 -2
  142. data/app/pb_kits/playbook/pb_section_separator/_section_separator_mixin.scss +11 -1
  143. data/app/pb_kits/playbook/pb_section_separator/section_separator.html.erb +1 -6
  144. data/app/pb_kits/playbook/pb_select/select.html.erb +1 -5
  145. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -5
  146. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +1 -4
  147. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +1 -5
  148. data/app/pb_kits/playbook/pb_selectable_list/selectable_list.html.erb +1 -6
  149. data/app/pb_kits/playbook/pb_selectable_list/selectable_list_item.html.erb +1 -6
  150. data/app/pb_kits/playbook/pb_source/source.html.erb +1 -5
  151. data/app/pb_kits/playbook/pb_source/source.test.js +2 -2
  152. data/app/pb_kits/playbook/pb_star_rating/star_rating.html.erb +1 -5
  153. data/app/pb_kits/playbook/pb_stat_change/stat_change.html.erb +1 -5
  154. data/app/pb_kits/playbook/pb_stat_value/stat_value.html.erb +1 -5
  155. data/app/pb_kits/playbook/pb_table/table.html.erb +2 -12
  156. data/app/pb_kits/playbook/pb_table/table_body.html.erb +6 -16
  157. data/app/pb_kits/playbook/pb_table/table_cell.html.erb +6 -16
  158. data/app/pb_kits/playbook/pb_table/table_head.html.erb +6 -16
  159. data/app/pb_kits/playbook/pb_table/table_header.html.erb +4 -13
  160. data/app/pb_kits/playbook/pb_table/table_row.html.erb +6 -16
  161. data/app/pb_kits/playbook/pb_textarea/textarea.html.erb +1 -5
  162. data/app/pb_kits/playbook/pb_time/time.html.erb +1 -5
  163. data/app/pb_kits/playbook/pb_time_range_inline/time_range_inline.html.erb +1 -5
  164. data/app/pb_kits/playbook/pb_time_stacked/time_stacked.html.erb +1 -5
  165. data/app/pb_kits/playbook/pb_timeline/item.html.erb +3 -7
  166. data/app/pb_kits/playbook/pb_timeline/timeline.html.erb +1 -5
  167. data/app/pb_kits/playbook/pb_timestamp/timestamp.html.erb +1 -6
  168. data/app/pb_kits/playbook/pb_title/title.html.erb +1 -6
  169. data/app/pb_kits/playbook/pb_title_count/title_count.html.erb +1 -6
  170. data/app/pb_kits/playbook/pb_title_detail/title_detail.html.erb +1 -5
  171. data/app/pb_kits/playbook/pb_toggle/toggle.html.erb +1 -6
  172. data/app/pb_kits/playbook/pb_tooltip/tooltip.html.erb +1 -5
  173. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +27 -19
  174. data/app/pb_kits/playbook/pb_typeahead/components/MenuList.tsx +4 -2
  175. data/app/pb_kits/playbook/pb_typeahead/components/index.tsx +19 -0
  176. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_custom_menu_list.jsx +51 -0
  177. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +1 -1
  178. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
  179. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
  180. data/app/pb_kits/playbook/pb_user/user.html.erb +1 -6
  181. data/app/pb_kits/playbook/pb_user_badge/user_badge.html.erb +1 -6
  182. data/app/pb_kits/playbook/pb_weekday_stacked/weekday_stacked.html.erb +1 -6
  183. data/app/pb_kits/playbook/playbook-doc.js +2 -0
  184. data/app/pb_kits/playbook/tokens/_colors.scss +1 -1
  185. data/dist/menu.yml +5 -1
  186. data/dist/playbook-rails.js +6 -6
  187. data/lib/playbook/kit_base.rb +21 -1
  188. data/lib/playbook/version.rb +2 -2
  189. metadata +47 -6
  190. /data/app/pb_kits/playbook/pb_dialog/docs/{_dialog_props_table.md → _dialog_props_swift.md} +0 -0
@@ -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,12 @@
1
+ examples:
2
+
3
+
4
+ react:
5
+ - dropdown_default: Default
6
+ - dropdown_with_custom_options: Custom Options
7
+ - dropdown_with_custom_display: Custom Display
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
12
+
@@ -0,0 +1,7 @@
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'
@@ -0,0 +1,17 @@
1
+ import { renderKit } from '../utilities/test-utils'
2
+
3
+ import { Dropdown } from '../'
4
+
5
+ /* See these resources for more testing info:
6
+ - https://github.com/testing-library/jest-dom#usage for useage and examples
7
+ - https://jestjs.io/docs/en/using-matchers
8
+ */
9
+
10
+ test('generated scaffold test - update me', () => {
11
+ const props = {
12
+ data: { testid: 'default' }
13
+ }
14
+
15
+ const kit = renderKit(Dropdown , props)
16
+ expect(kit).toBeInTheDocument()
17
+ })
@@ -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(!isDropDownClosed);
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
+ focusedOptionIndex,
10
+ filteredOptions,
11
+ setFocusedOptionIndex,
12
+ handleOptionClick,
13
+ setIsDropDownClosed,
14
+ handleBackspace,
15
+ selected,
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
+ };
@@ -0,0 +1,100 @@
1
+ import React, { useContext } from "react";
2
+ import classnames from "classnames";
3
+ import {
4
+ buildAriaProps,
5
+ buildCss,
6
+ buildDataProps,
7
+ buildHtmlProps
8
+ } from "../../utilities/props";
9
+ import { globalProps } from "../../utilities/globalProps";
10
+
11
+ import DropdownContext from "../context";
12
+
13
+ import List from "../../pb_list/_list";
14
+ import ListItem from "../../pb_list/_list_item";
15
+ import TextInput from "../../pb_text_input/_text_input";
16
+ import Body from "../../pb_body/_body";
17
+
18
+ type DropdownContainerProps = {
19
+ aria?: { [key: string]: string };
20
+ className?: string;
21
+ children?: React.ReactChild[] | React.ReactChild;
22
+ data?: { [key: string]: string };
23
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
24
+ id?: string;
25
+ searchbar?: boolean;
26
+ };
27
+
28
+ const DropdownContainer = (props: DropdownContainerProps) => {
29
+ const {
30
+ aria = {},
31
+ className,
32
+ children,
33
+ data = {},
34
+ htmlOptions = {},
35
+ id,
36
+ searchbar = false,
37
+ } = props;
38
+
39
+ const {
40
+ isDropDownClosed,
41
+ handleChange,
42
+ filterItem,
43
+ filteredOptions,
44
+ inputRef,
45
+ setFocusedOptionIndex,
46
+ } = useContext(DropdownContext);
47
+
48
+ const ariaProps = buildAriaProps(aria);
49
+ const dataProps = buildDataProps(data);
50
+ const htmlProps = buildHtmlProps(htmlOptions);
51
+ const classes = classnames(
52
+ buildCss("pb_dropdown_container"),
53
+ `${isDropDownClosed ? "close" : "open"}`,
54
+ globalProps(props),
55
+ className
56
+ );
57
+
58
+ return (
59
+ <div {...ariaProps}
60
+ {...dataProps}
61
+ {...htmlProps}
62
+ className={classes}
63
+ id={id}
64
+ onMouseEnter={() => setFocusedOptionIndex(-1)}
65
+ >
66
+ {searchbar && (
67
+ <TextInput paddingTop="xs"
68
+ paddingX="xs"
69
+ >
70
+ <input
71
+ onChange={handleChange}
72
+ placeholder="Select..."
73
+ ref={inputRef}
74
+ value={filterItem}
75
+ />
76
+ </TextInput>
77
+ )}
78
+ <List>{
79
+ filteredOptions?.length === 0 ? (
80
+ <ListItem
81
+ display="flex"
82
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
83
+ // @ts-ignore
84
+ justifyContent="center"
85
+ padding="xs"
86
+ >
87
+ <Body color="light"
88
+ text="no option"
89
+ />
90
+ </ListItem>
91
+ ): (
92
+ children
93
+ )
94
+ }
95
+ </List>
96
+ </div>
97
+ );
98
+ };
99
+
100
+ export default DropdownContainer;
@@ -0,0 +1,108 @@
1
+ import React, { useContext } from "react";
2
+ import classnames from "classnames";
3
+ import {
4
+ buildAriaProps,
5
+ buildCss,
6
+ buildDataProps,
7
+ buildHtmlProps,
8
+ } from "../../utilities/props";
9
+ import { globalProps, GlobalProps } from "../../utilities/globalProps";
10
+
11
+ import DropdownContext from "../context";
12
+
13
+ import Flex from "../../pb_flex/_flex";
14
+ import Body from "../../pb_body/_body";
15
+ import ListItem from "../../pb_list/_list_item";
16
+ import { GenericObject } from "../../types";
17
+
18
+ type DropdownOptionProps = {
19
+ aria?: { [key: string]: string };
20
+ className?: string;
21
+ children?: React.ReactChild[] | React.ReactChild;
22
+ data?: { [key: string]: string };
23
+ htmlOptions?: { [key: string]: string | number | boolean | (() => void) };
24
+ id?: string;
25
+ option?: GenericObject;
26
+ key?: string;
27
+ padding?: string;
28
+ } & GlobalProps;
29
+
30
+ const DropdownOption = (props: DropdownOptionProps) => {
31
+ const {
32
+ aria = {},
33
+ className,
34
+ children,
35
+ data = {},
36
+ htmlOptions = {},
37
+ id,
38
+ option,
39
+ key,
40
+ padding = "xs",
41
+ } = props;
42
+
43
+ const {
44
+ handleOptionClick,
45
+ selected,
46
+ filterItem,
47
+ filteredOptions,
48
+ focusedOptionIndex,
49
+ } = useContext(DropdownContext);
50
+
51
+ const isItemMatchingFilter = (option: GenericObject) =>
52
+ option?.label.toLowerCase().includes(filterItem.toLowerCase());
53
+
54
+ if (!isItemMatchingFilter(option)) {
55
+ return null;
56
+ }
57
+ const isFocused =
58
+ focusedOptionIndex >= 0 &&
59
+ filteredOptions[focusedOptionIndex].label === option.label;
60
+ const focusedClass = isFocused && "dropdown_option_focused";
61
+
62
+ const selectedClass = `${
63
+ selected.label === option.label
64
+ ? "dropdown_option_selected"
65
+ : "dropdown_option_list"
66
+ }`;
67
+ const ariaProps = buildAriaProps(aria);
68
+ const dataProps = buildDataProps(data);
69
+ const htmlProps = buildHtmlProps(htmlOptions);
70
+ const classes = classnames(
71
+ buildCss("pb_dropdown_option"),
72
+ selectedClass,
73
+ focusedClass,
74
+ globalProps(props, {padding}),
75
+ className
76
+ );
77
+
78
+ return (
79
+ <div
80
+ {...ariaProps}
81
+ {...dataProps}
82
+ {...htmlProps}
83
+ className={classes}
84
+ id={id}
85
+ key={key}
86
+ onClick= {() => handleOptionClick(option)}
87
+ >
88
+ <ListItem
89
+ cursor="pointer"
90
+ data-name={option.value}
91
+ key={option.label}
92
+ padding="none"
93
+ >
94
+ <Flex
95
+ align="center"
96
+ className="dropdown_option"
97
+ justify="between"
98
+ paddingX="sm"
99
+ paddingY="xxs"
100
+ >
101
+ {children ? children : <Body text={option.label} />}
102
+ </Flex>
103
+ </ListItem>
104
+ </div>
105
+ );
106
+ };
107
+
108
+ export default DropdownOption;
@@ -0,0 +1,172 @@
1
+ import React, { useContext } from "react";
2
+ import classnames from "classnames";
3
+ import {
4
+ buildAriaProps,
5
+ buildCss,
6
+ buildDataProps,
7
+ buildHtmlProps
8
+ } from "../../utilities/props";
9
+ import { globalProps } from "../../utilities/globalProps";
10
+ import { useHandleOnKeyDown } from "../hooks/useHandleOnKeydown";
11
+
12
+ import DropdownContext from "../context";
13
+
14
+ import Body from "../../pb_body/_body";
15
+ import Icon from "../../pb_icon/_icon";
16
+ import Flex from "../../pb_flex/_flex";
17
+ import FlexItem from "../../pb_flex/_flex_item";
18
+
19
+ type DropdownTriggerProps = {
20
+ aria?: { [key: string]: string };
21
+ children?: React.ReactChild[] | React.ReactChild;
22
+ className?: string;
23
+ customDisplay?: React.ReactChild[] | React.ReactChild;
24
+ data?: { [key: string]: string };
25
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
26
+ id?: string;
27
+ placeholder?: string;
28
+ };
29
+
30
+ const DropdownTrigger = (props: DropdownTriggerProps) => {
31
+ const {
32
+ aria = {},
33
+ className,
34
+ children,
35
+ customDisplay,
36
+ data = {},
37
+ htmlOptions = {},
38
+ id,
39
+ placeholder,
40
+ } = props;
41
+
42
+ const {
43
+ autocomplete,
44
+ handleWrapperClick,
45
+ selected,
46
+ filterItem,
47
+ handleChange,
48
+ toggleDropdown,
49
+ isDropDownClosed,
50
+ inputRef,
51
+ isInputFocused,
52
+ setIsInputFocused,
53
+ } = useContext(DropdownContext);
54
+
55
+ const handleKeyDown = useHandleOnKeyDown();
56
+
57
+ const ariaProps = buildAriaProps(aria);
58
+ const dataProps = buildDataProps(data);
59
+ const htmlProps = buildHtmlProps(htmlOptions);
60
+ const classes = classnames(
61
+ buildCss("pb_dropdown_trigger"),
62
+ globalProps(props),
63
+ className
64
+ );
65
+
66
+ const triggerWrapperClasses = `dropdown_trigger_wrapper ${
67
+ isInputFocused && "dropdown_trigger_wrapper_focus"
68
+ } ${!autocomplete && "dropdown_trigger_wrapper_select_only"}`;
69
+
70
+ const customDisplayPlaceholder = selected.label ? (
71
+ <b>{selected.label}</b>
72
+ ) : autocomplete ? (
73
+ ""
74
+ ) : placeholder ? (
75
+ placeholder
76
+ ) : (
77
+ "Select..."
78
+ );
79
+
80
+ const defaultDisplayPlaceholder = selected.label
81
+ ? selected.label
82
+ : autocomplete
83
+ ? ""
84
+ : placeholder
85
+ ? placeholder
86
+ : "Select...";
87
+
88
+ return (
89
+ <div {...ariaProps}
90
+ {...dataProps}
91
+ {...htmlProps}
92
+ className={classes}
93
+ id={id}
94
+ >
95
+ {children ? (
96
+ <div
97
+ onClick={() => toggleDropdown()}
98
+ onKeyDown= {handleKeyDown}
99
+ style={{ display: "inline-block" }}
100
+ tabIndex= {0}
101
+ >
102
+ {children}
103
+ </div>
104
+ ) : (
105
+ <>
106
+ <Flex
107
+ align="center"
108
+ borderRadius="lg"
109
+ className={triggerWrapperClasses}
110
+ cursor={`${autocomplete ? "text" : "pointer"}`}
111
+ htmlOptions={{
112
+ onClick: () => handleWrapperClick(),
113
+ onKeyDown: handleKeyDown,
114
+ tabIndex: "0",
115
+ }}
116
+ justify="between"
117
+ paddingX="sm"
118
+ paddingY="xs"
119
+ >
120
+ <FlexItem>
121
+ <Flex align="center">
122
+ {customDisplay ? (
123
+ <Flex align="center">
124
+ {customDisplay}
125
+ <Body paddingLeft={`${selected.label ? "xs" : "none"}`}>
126
+ {customDisplayPlaceholder}
127
+ </Body>
128
+ </Flex>
129
+ ) : (
130
+ <Body text={defaultDisplayPlaceholder} />
131
+ )}
132
+ {autocomplete && (
133
+ <input
134
+ className="dropdown_input"
135
+ onChange={handleChange}
136
+ onClick={() => toggleDropdown()}
137
+ onFocus={() => setIsInputFocused(true)}
138
+ onKeyDown={handleKeyDown}
139
+ placeholder={
140
+ selected.label
141
+ ? ""
142
+ : placeholder
143
+ ? placeholder
144
+ : "Select..."
145
+ }
146
+ ref={inputRef}
147
+ value={filterItem}
148
+ />
149
+ )}
150
+ </Flex>
151
+ </FlexItem>
152
+ <Body
153
+ display="flex"
154
+ htmlOptions={{
155
+ onClick: (e: Event) => {e.stopPropagation();handleWrapperClick()}
156
+ }}
157
+ key={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
158
+ >
159
+ <Icon
160
+ cursor="pointer"
161
+ icon={`${isDropDownClosed ? "chevron-down" : "chevron-up"}`}
162
+ size="sm"
163
+ />
164
+ </Body>
165
+ </Flex>
166
+ </>
167
+ )}
168
+ </div>
169
+ );
170
+ };
171
+
172
+ export default DropdownTrigger;
@@ -0,0 +1,59 @@
1
+ import React, { ReactElement } from "react";
2
+ import DropdownTrigger from "../subcomponents/DropdownTrigger";
3
+ import DropdownContainer from "../subcomponents/DropdownContainer";
4
+
5
+ type PrepareComponentsProps = {
6
+ children: React.ReactChild[] | React.ReactChild;
7
+ hasTriggerSubcomponent: boolean;
8
+ hasContainerSubcomponent: boolean;
9
+ trigger: React.ReactChild;
10
+ container: React.ReactChild;
11
+ otherChildren: React.ReactChild[];
12
+ };
13
+
14
+ export const separateChildComponents = (children: React.ReactChild[] | React.ReactChild | ReactElement[]) => {
15
+ let trigger: React.ReactChild = null;
16
+ let container: React.ReactChild = null;
17
+ const otherChildren: React.ReactChild[] = [];
18
+
19
+ React.Children.forEach(children, (child) => {
20
+ if (child && (child as ReactElement).type === DropdownTrigger) {
21
+ trigger = child;
22
+ } else if (child && (child as ReactElement).type === DropdownContainer) {
23
+ container = child;
24
+ } else {
25
+ otherChildren.push(child);
26
+ }
27
+ });
28
+
29
+ return { trigger, container, otherChildren };
30
+ };
31
+
32
+ export const prepareSubcomponents = ({
33
+ children,
34
+ hasTriggerSubcomponent,
35
+ hasContainerSubcomponent,
36
+ trigger,
37
+ container,
38
+ otherChildren,
39
+ }: PrepareComponentsProps) => {
40
+ const componentsToRender = [];
41
+
42
+ if (!hasTriggerSubcomponent && !hasContainerSubcomponent) {
43
+ componentsToRender.push(<DropdownTrigger />);
44
+ componentsToRender.push(<DropdownContainer>{children}</DropdownContainer>);
45
+ } else if (!hasTriggerSubcomponent && hasContainerSubcomponent) {
46
+ componentsToRender.push(<DropdownTrigger />);
47
+ componentsToRender.push(children);
48
+ } else if (hasTriggerSubcomponent && !hasContainerSubcomponent) {
49
+ componentsToRender.push(trigger);
50
+ componentsToRender.push(
51
+ <DropdownContainer>{otherChildren}</DropdownContainer>
52
+ );
53
+ } else {
54
+ componentsToRender.push(trigger);
55
+ componentsToRender.push(container);
56
+ }
57
+
58
+ return componentsToRender;
59
+ };
@@ -1,9 +1,4 @@
1
- <%= content_tag("div",
2
- aria: object.aria,
3
- class: object.classname,
4
- data: object.data,
5
- id: object.id,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
7
2
  <%= pb_rails("form_group", props: {cursor: "pointer", full_width: object.full_width}) do %>
8
3
  <label for="upload-<%= object.id %>" class="pb_button_kit_secondary_inline_enabled"><%= "#{object.label}" %></label>
9
4
  <%= pb_rails("text_input", props: {
@@ -1,8 +1,4 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
6
2
  <%= object.wrapper do %>
7
3
  <%= pb_rails("flex", props: { orientation: "row", padding_right: "lg", vertical: "center" }) do %>
8
4
  <% if (object.template != "sort_only") %>
@@ -1,9 +1,4 @@
1
- <%= content_tag(:div,
2
- aria: object.aria,
3
- id: object.id,
4
- data: object.data,
5
- class: object.classname,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
7
2
  <%= pb_rails("icon", props: { icon: object.icon_value, classname: "pb_icon", fixed_width: true }) %>
8
3
 
9
4
  <% if content %>
@@ -1,7 +1,3 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- **combined_html_options) do %>
1
+ <%= pb_content_tag do %>
6
2
  <%= content.presence %>
7
3
  <% end %>
@@ -1,8 +1,4 @@
1
- <%= content_tag(:div,
2
- id: object.id,
3
- data: object.data,
4
- class: object.classname,
5
- style: object.style_value,
6
- **combined_html_options) do %>
1
+ <%= pb_content_tag(:div,
2
+ style: object.style_value) do %>
7
3
  <%= content.presence %>
8
4
  <% end %>