playbook_ui 13.24.0 → 13.25.0.pre.alpha.barchartfix2766

Sign up to get free protection for your applications and to get access to all the features.
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 %>