playbook_ui 14.14.0 → 14.15.0.pre.alpha.PBNTR900phonenumberinputhidden6620

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 (173) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +127 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +55 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TablePagination.tsx +33 -0
  5. data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +275 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +143 -3
  7. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +66 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +195 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +45 -99
  10. data/app/pb_kits/playbook/pb_advanced_table/Utilities/CellRendererUtils.tsx +73 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/Utilities/RowUtils.ts +52 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/Utilities/TableContainerStyles.ts +80 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +123 -7
  14. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +153 -299
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_infinite_scroll.jsx +50 -0
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_mock_data_infinite_scroll.json +152002 -0
  17. data/app/pb_kits/playbook/pb_card/_card.tsx +2 -1
  18. data/app/pb_kits/playbook/pb_currency/_currency.tsx +46 -31
  19. data/app/pb_kits/playbook/pb_currency/currency.html.erb +15 -8
  20. data/app/pb_kits/playbook/pb_currency/currency.rb +17 -2
  21. data/app/pb_kits/playbook/pb_currency/docs/_currency_null_display.html.erb +22 -0
  22. data/app/pb_kits/playbook/pb_currency/docs/_currency_null_display.jsx +34 -0
  23. data/app/pb_kits/playbook/pb_currency/docs/_currency_null_display_rails.md +1 -0
  24. data/app/pb_kits/playbook/pb_currency/docs/_currency_null_display_react.md +1 -0
  25. data/app/pb_kits/playbook/pb_currency/docs/example.yml +2 -0
  26. data/app/pb_kits/playbook/pb_currency/docs/index.js +2 -1
  27. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +4 -1
  28. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +2 -0
  29. data/app/pb_kits/playbook/pb_date_picker/index.ts +38 -0
  30. data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +5 -6
  31. data/app/pb_kits/playbook/pb_dialog/dialogHelper.js +2 -0
  32. data/app/pb_kits/playbook/pb_dialog/index.js +75 -0
  33. data/app/pb_kits/playbook/pb_drawer/_drawer.scss +43 -3
  34. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_behavior.html.erb +8 -0
  35. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.html.erb +33 -0
  36. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_borders.jsx +3 -3
  37. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.html.erb +0 -0
  38. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_breakpoints.jsx +20 -37
  39. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_default.html.erb +20 -1
  40. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.html.erb +24 -0
  41. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_menu.jsx +6 -6
  42. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.html.erb +21 -0
  43. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.jsx +1 -0
  44. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_overlay.md +1 -0
  45. data/app/pb_kits/playbook/pb_drawer/docs/_drawer_sizes.html.erb +49 -0
  46. data/app/pb_kits/playbook/pb_drawer/docs/example.yml +6 -0
  47. data/app/pb_kits/playbook/pb_drawer/drawer.html.erb +20 -12
  48. data/app/pb_kits/playbook/pb_drawer/drawer.rb +49 -1
  49. data/app/pb_kits/playbook/pb_drawer/index.js +257 -0
  50. data/app/pb_kits/playbook/pb_filter/Filter/CurrentFilters.tsx +5 -4
  51. data/app/pb_kits/playbook/pb_filter/Filter/FilterSingle.tsx +2 -2
  52. data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +2 -1
  53. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +4 -3
  54. data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +9 -2
  55. data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +4 -0
  56. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.html.erb +40 -0
  57. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.jsx +50 -0
  58. data/app/pb_kits/playbook/pb_form_pill/docs/_form_pill_wrapped.md +3 -0
  59. data/app/pb_kits/playbook/pb_form_pill/docs/example.yml +2 -0
  60. data/app/pb_kits/playbook/pb_form_pill/docs/index.js +1 -0
  61. data/app/pb_kits/playbook/pb_form_pill/form_pill.rb +7 -1
  62. data/app/pb_kits/playbook/pb_icon_button/_icon_button.tsx +71 -0
  63. data/app/pb_kits/playbook/pb_icon_button/docs/_icon_button_default.jsx +17 -0
  64. data/app/pb_kits/playbook/pb_icon_button/docs/_icon_button_sizes.jsx +61 -0
  65. data/app/pb_kits/playbook/pb_icon_button/docs/example.yml +4 -0
  66. data/app/pb_kits/playbook/pb_icon_button/docs/index.js +2 -0
  67. data/app/pb_kits/playbook/pb_icon_button/icon_button.test.jsx +39 -0
  68. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.scss +7 -0
  69. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +13 -3
  70. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.html.erb +72 -0
  71. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.jsx +91 -0
  72. data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +2 -1
  73. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +1 -0
  74. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +6 -0
  75. data/app/pb_kits/playbook/pb_overlay/_overlay.scss +13 -0
  76. data/app/pb_kits/playbook/pb_overlay/_overlay.tsx +7 -1
  77. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar.html.erb +11 -0
  78. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar.jsx +37 -0
  79. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar_rails.md +1 -0
  80. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_hide_scroll_bar_react.md +1 -0
  81. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.html.erb +11 -0
  82. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.md +1 -0
  83. data/app/pb_kits/playbook/pb_overlay/docs/example.yml +3 -0
  84. data/app/pb_kits/playbook/pb_overlay/docs/index.js +1 -0
  85. data/app/pb_kits/playbook/pb_overlay/index.js +61 -0
  86. data/app/pb_kits/playbook/pb_overlay/overlay.html.erb +5 -3
  87. data/app/pb_kits/playbook/pb_overlay/overlay.rb +16 -1
  88. data/app/pb_kits/playbook/pb_overlay/overlay.test.jsx +12 -0
  89. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +6 -0
  90. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_default.html.erb +1 -1
  91. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_hidden_inputs.html.erb +5 -0
  92. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_hidden_inputs.md +1 -0
  93. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +3 -1
  94. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
  95. data/app/pb_kits/playbook/pb_popover/_popover.tsx +2 -2
  96. data/app/pb_kits/playbook/pb_popover/popover.test.js +1 -1
  97. data/app/pb_kits/playbook/pb_progress_step/progress_step_item.html.erb +2 -2
  98. data/app/pb_kits/playbook/pb_radio/_radio.tsx +85 -74
  99. data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.jsx +60 -0
  100. data/app/pb_kits/playbook/pb_radio/docs/_radio_react_hook.md +1 -0
  101. data/app/pb_kits/playbook/pb_radio/docs/example.yml +2 -1
  102. data/app/pb_kits/playbook/pb_radio/docs/index.js +1 -0
  103. data/app/pb_kits/playbook/pb_radio/radio.test.js +16 -0
  104. data/app/pb_kits/playbook/pb_select/docs/_select_react_hook.jsx +58 -0
  105. data/app/pb_kits/playbook/pb_select/docs/_select_react_hook.md +1 -0
  106. data/app/pb_kits/playbook/pb_select/docs/example.yml +1 -0
  107. data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
  108. data/app/pb_kits/playbook/pb_select/index.js +38 -0
  109. data/app/pb_kits/playbook/pb_select/select.html.erb +3 -5
  110. data/app/pb_kits/playbook/pb_select/select.rb +8 -0
  111. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -5
  112. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +1 -4
  113. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +1 -5
  114. data/app/pb_kits/playbook/pb_text_input/inputMask.ts +2 -3
  115. data/app/pb_kits/playbook/pb_timeline/_timeline.scss +2 -2
  116. data/app/pb_kits/playbook/pb_title/_title.scss +32 -0
  117. data/app/pb_kits/playbook/pb_title/_title.tsx +10 -1
  118. data/app/pb_kits/playbook/pb_title/docs/_title_default.html.erb +1 -2
  119. data/app/pb_kits/playbook/pb_title/docs/_title_default.jsx +1 -1
  120. data/app/pb_kits/playbook/pb_title/docs/_title_display_size.html.erb +7 -0
  121. data/app/pb_kits/playbook/pb_title/docs/_title_display_size.jsx +54 -0
  122. data/app/pb_kits/playbook/pb_title/docs/_title_display_size.md +1 -0
  123. data/app/pb_kits/playbook/pb_title/docs/example.yml +2 -0
  124. data/app/pb_kits/playbook/pb_title/docs/index.js +1 -0
  125. data/app/pb_kits/playbook/pb_title/title.rb +10 -1
  126. data/app/pb_kits/playbook/pb_tooltip/_tooltip.scss +0 -3
  127. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +25 -0
  128. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.html.erb +39 -0
  129. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_delay_rails.md +3 -0
  130. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_icon_rails.html.erb +22 -0
  131. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_interaction.html.erb +26 -0
  132. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_sizing.jsx +69 -0
  133. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_sizing.md +3 -0
  134. data/app/pb_kits/playbook/pb_tooltip/docs/example.yml +4 -1
  135. data/app/pb_kits/playbook/pb_tooltip/docs/index.js +1 -0
  136. data/app/pb_kits/playbook/pb_tooltip/floating_ui.js +282 -0
  137. data/app/pb_kits/playbook/pb_tooltip/index.js +2 -2
  138. data/app/pb_kits/playbook/pb_tooltip/tooltip.rb +10 -2
  139. data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +51 -5
  140. data/app/pb_kits/playbook/pb_typeahead/components/MultiValue.tsx +5 -1
  141. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options.html.erb +45 -0
  142. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options.md +5 -0
  143. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options_pure_rails.html.erb +33 -0
  144. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_dynamic_options_pure_rails.md +3 -0
  145. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.jsx +66 -0
  146. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_react_hook.md +1 -0
  147. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_custom_options.jsx +1 -1
  148. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async_users.jsx +1 -1
  149. data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +3 -0
  150. data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
  151. data/app/pb_kits/playbook/pb_typeahead/index.ts +61 -8
  152. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +17 -2
  153. data/app/pb_kits/playbook/utilities/object.test.js +99 -0
  154. data/app/pb_kits/playbook/utilities/object.ts +29 -1
  155. data/dist/chunks/_typeahead-ClZGb4WZ.js +36 -0
  156. data/dist/chunks/_weekday_stacked-BAbPkPFp.js +45 -0
  157. data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
  158. data/dist/chunks/{lib-D3us1bGD.js → lib-5OzNgeeu.js} +2 -2
  159. data/dist/chunks/{pb_form_validation-BpihMSOQ.js → pb_form_validation-DGhKbZtO.js} +1 -1
  160. data/dist/chunks/vendor.js +1 -1
  161. data/dist/menu.yml +3 -3
  162. data/dist/playbook-doc.js +1 -1
  163. data/dist/playbook-rails-react-bindings.js +1 -1
  164. data/dist/playbook-rails.js +1 -1
  165. data/dist/playbook.css +1 -1
  166. data/lib/playbook/forms/builder/time_zone_select_field.rb +19 -0
  167. data/lib/playbook/forms/builder.rb +1 -0
  168. data/lib/playbook/version.rb +2 -2
  169. metadata +74 -8
  170. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_icon.erb +0 -10
  171. data/dist/chunks/_typeahead-PqkcDf1H.js +0 -36
  172. data/dist/chunks/_weekday_stacked-B_pw5Znc.js +0 -45
  173. data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
@@ -0,0 +1,39 @@
1
+ <%= pb_rails("flex", props: { orientation: "row", gap: "md" }) do %>
2
+ <%= pb_rails("flex/flex_item", props: {margin_top: "md"}) do %>
3
+ <%= pb_rails("button", props: {classname: "tooltip-delay", text: "1s delay"}) %>
4
+ <% end %>
5
+
6
+ <%= pb_rails("flex/flex_item", props: {margin_top: "md"}) do %>
7
+ <%= pb_rails("button", props: {classname: "tooltip-open-delay", text: "Open only"}) %>
8
+ <% end %>
9
+
10
+ <%= pb_rails("flex/flex_item", props: {margin_top: "md"}) do %>
11
+ <%= pb_rails("button", props: {classname: "tooltip-close-delay", text: "Close only"}) %>
12
+ <% end %>
13
+
14
+ <%= pb_rails("tooltip", props: {
15
+ trigger_element_selector: ".tooltip-delay",
16
+ tooltip_id: "delay-tooltip",
17
+ position: 'top',
18
+ delay_open: 1000,
19
+ delay_close: 1000
20
+ }) do %>
21
+ 1s open/close delay
22
+ <% end %>
23
+ <%= pb_rails("tooltip", props: {
24
+ trigger_element_selector: ".tooltip-open-delay",
25
+ tooltip_id: "open-tooltip",
26
+ position: 'top',
27
+ delay_open: 1000
28
+ }) do %>
29
+ 1s open delay
30
+ <% end %>
31
+ <%= pb_rails("tooltip", props: {
32
+ trigger_element_selector: ".tooltip-close-delay",
33
+ tooltip_id: "close-tooltip",
34
+ position: 'top',
35
+ delay_close: 1000
36
+ }) do %>
37
+ 1s close delay
38
+ <% end %>
39
+ <% end %>
@@ -0,0 +1,3 @@
1
+ Waits for the specified time when the event listener runs before triggering the tooltip.
2
+
3
+ The `delay_open` and `delay_close` accept numbers in milliseconds. 1 second is 1000 milliseconds.
@@ -0,0 +1,22 @@
1
+ <%= pb_rails "flex", props: { flex_direction: "row", gap: "md", wrap: true } do %>
2
+ <%= pb_rails "button", props: { id: "tool-tip-with-icon-1", text: "Tooltip With Icon" } %>
3
+ <%= pb_rails "tooltip", props: { trigger_element_selector: "#tool-tip-with-icon-1", tooltip_id: "tool-tip-with-icon-1", position: "top" } do %>
4
+ <%= pb_rails("icon", props: { icon: "paper-plane", fixed_width: true, color: "white", size: "1x", padding_right: "xxs" }) %>
5
+ Send Email
6
+ <% end %>
7
+ <%= pb_rails "button", props: { id: "tool-tip-with-icon-2", text: "Tooltip With Icon" } %>
8
+ <%= pb_rails "tooltip", props: { trigger_element_selector: "#tool-tip-with-icon-2", tooltip_id: "tool-tip-with-icon-2", position: "bottom" } do %>
9
+ <%= pb_rails("icon", props: { icon: "paper-plane", fixed_width: true, color: "white", size: "1x", padding_right: "xxs" }) %>
10
+ Send Email
11
+ <% end %>
12
+ <%= pb_rails "button", props: { id: "tool-tip-with-icon-3", text: "Tooltip With Icon" } %>
13
+ <%= pb_rails "tooltip", props: { trigger_element_selector: "#tool-tip-with-icon-3", tooltip_id: "tool-tip-with-icon-3", position: "left" } do %>
14
+ <%= pb_rails("icon", props: { icon: "paper-plane", fixed_width: true, color: "white", size: "1x", padding_right: "xxs" }) %>
15
+ Send Email
16
+ <% end %>
17
+ <%= pb_rails "button", props: { id: "tool-tip-with-icon-4", text: "Tooltip With Icon" } %>
18
+ <%= pb_rails "tooltip", props: { trigger_element_selector: "#tool-tip-with-icon-4", tooltip_id: "tool-tip-with-icon-4", position: "right" } do %>
19
+ <%= pb_rails("icon", props: { icon: "paper-plane", fixed_width: true, color: "white", size: "1x", padding_right: "xxs" }) %>
20
+ Send Email
21
+ <% end %>
22
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <%= pb_rails("flex", props: { gap: "md", wrap: true }) do %>
2
+ <%= pb_rails("flex/flex_item") do %>
3
+ <%= pb_rails("button", props: { text: "With Interaction", id: "tooltip-interaction"}) %>
4
+
5
+ <%= pb_rails("tooltip", props: {
6
+ trigger_element_selector: "#tooltip-interaction",
7
+ tooltip_id: "tooltip-with-interaction",
8
+ position: 'top',
9
+ interaction: true
10
+ }) do %>
11
+ You can copy me
12
+ <% end %>
13
+ <% end %>
14
+
15
+ <%= pb_rails("flex/flex_item") do %>
16
+ <%= pb_rails("button", props: { text: "No Interaction", id: "tooltip-no-interaction"}) %>
17
+
18
+ <%= pb_rails("tooltip", props: {
19
+ trigger_element_selector: "#tooltip-no-interaction",
20
+ tooltip_id: "tooltip-without-interaction",
21
+ position: 'top',
22
+ }) do %>
23
+ I'm just a regular tooltip
24
+ <% end %>
25
+ <% end %>
26
+ <% end %>
@@ -0,0 +1,69 @@
1
+ import React from 'react'
2
+ import { Button, Tooltip, Flex, FlexItem } from 'playbook-ui';
3
+
4
+ const TooltipSizing = (props) => {
5
+
6
+ return (
7
+ <Flex
8
+ flexDirection='row'
9
+ gap='md'
10
+ wrap
11
+ >
12
+ <FlexItem>
13
+ <Tooltip
14
+ height='150px'
15
+ placement='top'
16
+ text="I'm 150px high and 100px wide!"
17
+ width='100px'
18
+ {...props}
19
+ >
20
+ <Button text="Height and Width"/>
21
+ </Tooltip>
22
+ </FlexItem>
23
+ <FlexItem>
24
+ <Tooltip
25
+ maxHeight='100px'
26
+ placement='top'
27
+ text="I have a maxHeight of 100px! Lorem ipsum dolor sit amet consectetur adipisicing elit."
28
+ width='250px'
29
+ {...props}
30
+ >
31
+ <Button text="maxHeight"/>
32
+ </Tooltip>
33
+ </FlexItem>
34
+ <FlexItem>
35
+ <Tooltip
36
+ maxWidth='150px'
37
+ placement='top'
38
+ text="I have a maxWidth of 150px! Lorem ipsum dolor sit amet consectetur adipisicing elit."
39
+ {...props}
40
+ >
41
+ <Button text="maxWidth"/>
42
+ </Tooltip>
43
+ </FlexItem>
44
+ <FlexItem>
45
+ <Tooltip
46
+ minWidth='300px'
47
+ placement='top'
48
+ text="I have a minWidth of 300px!"
49
+ {...props}
50
+ >
51
+ <Button text="minWidth"/>
52
+ </Tooltip>
53
+ </FlexItem>
54
+ <FlexItem>
55
+ <Tooltip
56
+ maxWidth='150px'
57
+ minHeight='300px'
58
+ placement='top'
59
+ text="I have a minHeight of 300px!"
60
+ {...props}
61
+ >
62
+ <Button text="minHeight"/>
63
+ </Tooltip>
64
+ </FlexItem>
65
+ </Flex>
66
+ )
67
+ }
68
+
69
+ export default TooltipSizing
@@ -0,0 +1,3 @@
1
+ You can customize the `height` and `width` of the tooltip's popover.
2
+
3
+ When using `maxHeight`, be sure to set a `width` as well. The text needs to truncate within the `width` prop.
@@ -2,15 +2,18 @@ examples:
2
2
 
3
3
  rails:
4
4
  - tooltip_default: Default
5
+ - tooltip_interaction: Content Interaction
5
6
  - tooltip_selectors: Using Common Selectors
7
+ - tooltip_icon_rails: Tooltip with Icon
6
8
  - tooltip_with_icon_circle: Icon Circle Tooltip
9
+ - tooltip_delay_rails: Delay
7
10
  - tooltip_show_tooltip: Show Tooltip
8
11
 
9
12
  react:
10
13
  - tooltip_default_react: Default
11
14
  - tooltip_interaction: Content Interaction
12
15
  - tooltip_margin: Margin
16
+ - tooltip_sizing: Tooltip Sizing
13
17
  - tooltip_icon: Tooltip with Icon
14
18
  - tooltip_delay: Delay
15
19
  - tooltip_show_tooltip_react: Show Tooltip
16
-
@@ -1,6 +1,7 @@
1
1
  export { default as TooltipDefaultReact } from './_tooltip_default_react'
2
2
  export { default as TooltipInteraction } from './_tooltip_interaction'
3
3
  export { default as TooltipMargin } from './_tooltip_margin'
4
+ export { default as TooltipSizing } from './_tooltip_sizing'
4
5
  export { default as TooltipIcon } from './_tooltip_icon'
5
6
  export { default as TooltipDelay } from './_tooltip_delay'
6
7
  export { default as TooltipShowTooltipReact } from './_tooltip_show_tooltip_react'
@@ -0,0 +1,282 @@
1
+ import PbEnhancedElement from '../pb_enhanced_element'
2
+ import { computePosition, offset, flip, shift, arrow, autoUpdate } from '@floating-ui/dom'
3
+
4
+ const TOOLTIP_OFFSET = 20
5
+ const TOOLTIP_TIMEOUT = 250
6
+ const SAFE_ZONE_MARGIN = 1
7
+
8
+ export default class PbTooltipFloatingUi extends PbEnhancedElement {
9
+ static get selector() {
10
+ return '[data-pb-tooltip-kit="true"][data-pb-tooltip-delay-open], [data-pb-tooltip-kit="true"][data-pb-tooltip-delay-close], [data-pb-tooltip-kit="true"][data-pb-tooltip-interaction="true"]'
11
+ }
12
+
13
+ connect() {
14
+ if (this.tooltipInteraction) {
15
+ document.addEventListener('mousemove', (e) => {
16
+ this.lastMouseX = e.clientX
17
+ this.lastMouseY = e.clientY
18
+ })
19
+ }
20
+
21
+ this.triggerElements.forEach((trigger) => {
22
+ const method = this.triggerMethod
23
+ const interactionEnabled = this.tooltipInteraction
24
+
25
+ if (method === 'click') {
26
+ trigger.addEventListener('click', () => {
27
+ this.showTooltip(trigger)
28
+ })
29
+ } else {
30
+ trigger.addEventListener('mouseenter', () => {
31
+ clearSafeZoneListener(this)
32
+ clearTimeout(this.mouseleaveTimeout)
33
+ this.currentTrigger = trigger
34
+ const delayOpen = this.delayOpen ? parseInt(this.delayOpen) : TOOLTIP_TIMEOUT
35
+ this.mouseenterTimeout = setTimeout(() => {
36
+ this.showTooltip(trigger)
37
+ if (interactionEnabled) {
38
+ this.checkCloseTooltip(trigger)
39
+ }
40
+ }, delayOpen)
41
+ })
42
+
43
+ trigger.addEventListener('mouseleave', () => {
44
+ clearTimeout(this.mouseenterTimeout)
45
+ if (this.delayClose) {
46
+ const delayClose = parseInt(this.delayClose)
47
+ this.mouseleaveTimeout = setTimeout(() => {
48
+ if (interactionEnabled) {
49
+ this.attachSafeZoneListener()
50
+ } else {
51
+ this.hideTooltip()
52
+ }
53
+ }, delayClose)
54
+ } else {
55
+ if (interactionEnabled) {
56
+ this.attachSafeZoneListener()
57
+ } else {
58
+ this.hideTooltip()
59
+ }
60
+ }
61
+ })
62
+
63
+ if (interactionEnabled) {
64
+ this.tooltip.addEventListener('mouseenter', () => {
65
+ clearSafeZoneListener(this)
66
+ })
67
+
68
+ this.tooltip.addEventListener('mouseleave', () => {
69
+ this.attachSafeZoneListener()
70
+ })
71
+ }
72
+ }
73
+ })
74
+ }
75
+
76
+ attachSafeZoneListener() {
77
+ clearSafeZoneListener(this)
78
+ this.safeZoneHandler = (e) => {
79
+ if (!this.currentTrigger) return
80
+ const triggerRect = this.currentTrigger.getBoundingClientRect()
81
+ const tooltipRect = this.tooltip.getBoundingClientRect()
82
+ const safeRect = getSafeZone(triggerRect, tooltipRect, this.position, SAFE_ZONE_MARGIN)
83
+ if (!isPointInsideRect(e.clientX, e.clientY, safeRect)) {
84
+ this.hideTooltip()
85
+ clearSafeZoneListener(this)
86
+ }
87
+ }
88
+ document.addEventListener('mousemove', this.safeZoneHandler)
89
+ }
90
+
91
+ checkCloseTooltip(trigger) {
92
+ document.querySelector('body').addEventListener('click', ({ target }) => {
93
+ const isTooltip = target.closest(`#${this.tooltipId}`) === this.tooltip
94
+ const isTrigger = target.closest(this.triggerElementSelector) === trigger
95
+ if (isTrigger || isTooltip) {
96
+ this.checkCloseTooltip(trigger)
97
+ } else {
98
+ this.hideTooltip()
99
+ }
100
+ }, { once: true })
101
+ }
102
+
103
+ showTooltip(trigger) {
104
+ if (this.shouldShowTooltip === 'false') return
105
+
106
+ clearSafeZoneListener(this)
107
+
108
+ this.tooltip.style.opacity = '1'
109
+ this.tooltip.style.visibility = 'visible'
110
+ this.tooltip.style.pointerEvents = 'auto'
111
+
112
+ if (this.cleanup) {
113
+ this.cleanup()
114
+ }
115
+
116
+ const arrowElement = document.querySelector(`#${this.tooltipId}-arrow`)
117
+
118
+ this.cleanup = autoUpdate(trigger, this.tooltip, () => {
119
+ computePosition(trigger, this.tooltip, {
120
+ placement: this.position,
121
+ strategy: 'fixed',
122
+ middleware: [
123
+ offset({ mainAxis: TOOLTIP_OFFSET, crossAxis: 0 }),
124
+ flip(),
125
+ shift(),
126
+ arrow({ element: arrowElement })
127
+ ],
128
+ }).then(({ x, y, placement, middlewareData }) => {
129
+ Object.assign(this.tooltip.style, {
130
+ left: `${x}px`,
131
+ top: `${y}px`,
132
+ position: 'fixed'
133
+ })
134
+ this.tooltip.setAttribute('data-popper-placement', placement)
135
+ if (arrowElement && middlewareData.arrow) {
136
+ const { x: arrowX, y: arrowY } = middlewareData.arrow
137
+ Object.assign(arrowElement.style, {
138
+ left: arrowX != null ? `${arrowX}px` : '',
139
+ top: arrowY != null ? `${arrowY}px` : '',
140
+ position: 'absolute'
141
+ })
142
+ }
143
+ })
144
+ })
145
+
146
+ this.tooltip.classList.add('show')
147
+
148
+ if (this.triggerMethod === 'click') {
149
+ clearTimeout(this.autoHideTimeout)
150
+ this.autoHideTimeout = setTimeout(() => {
151
+ this.hideTooltip()
152
+ }, 1000)
153
+ }
154
+ }
155
+
156
+ hideTooltip() {
157
+ if (!this.tooltip) return
158
+
159
+ this.tooltip.classList.add('fade_out')
160
+ setTimeout(() => {
161
+ if (this.cleanup) {
162
+ this.cleanup()
163
+ this.cleanup = null
164
+ }
165
+ this.tooltip.classList.remove('show')
166
+ this.tooltip.classList.remove('fade_out')
167
+ this.tooltip.style.opacity = '0'
168
+ this.tooltip.style.visibility = 'hidden'
169
+ this.tooltip.style.pointerEvents = 'none'
170
+ this.tooltip.style.position = ''
171
+ this.tooltip.style.top = ''
172
+ this.tooltip.style.left = ''
173
+ this.tooltip.style.transform = ''
174
+ }, TOOLTIP_TIMEOUT)
175
+ }
176
+
177
+ get triggerElements() {
178
+ let triggerEl
179
+ if (this.triggerElementId) {
180
+ triggerEl = document.querySelector(`#${this.triggerElementId}`)
181
+ } else if (this.triggerElementSelector) {
182
+ const selectorIsId = this.triggerElementSelector.indexOf('#') > -1
183
+ triggerEl = selectorIsId
184
+ ? document.querySelector(this.triggerElementSelector)
185
+ : document.querySelectorAll(this.triggerElementSelector)
186
+ } else {
187
+ triggerEl = this.element
188
+ }
189
+ if (!triggerEl) {
190
+ console.error('Tooltip Kit: No valid trigger element found!')
191
+ return []
192
+ }
193
+ if (triggerEl.length === undefined) {
194
+ triggerEl = [triggerEl]
195
+ }
196
+ return triggerEl
197
+ }
198
+
199
+ get tooltip() {
200
+ return (this._tooltip = this._tooltip || this.element.querySelector(`#${this.tooltipId}`))
201
+ }
202
+
203
+ get position() {
204
+ return this.element.dataset.pbTooltipPosition
205
+ }
206
+
207
+ get triggerElementId() {
208
+ return this.element.dataset.pbTooltipTriggerElementId
209
+ }
210
+
211
+ get tooltipId() {
212
+ return this.element.dataset.pbTooltipTooltipId
213
+ }
214
+
215
+ get triggerElementSelector() {
216
+ return this.element.dataset.pbTooltipTriggerElementSelector
217
+ }
218
+
219
+ get shouldShowTooltip() {
220
+ return this.element.dataset.pbTooltipShowTooltip
221
+ }
222
+
223
+ get triggerMethod() {
224
+ return this.element.dataset.pbTooltipTriggerMethod || 'hover'
225
+ }
226
+
227
+ get tooltipInteraction() {
228
+ return this.element.dataset.pbTooltipInteraction === 'true'
229
+ }
230
+
231
+ get delayOpen() {
232
+ return this.element.dataset.pbTooltipDelayOpen
233
+ }
234
+
235
+ get delayClose() {
236
+ return this.element.dataset.pbTooltipDelayClose
237
+ }
238
+ }
239
+
240
+ function clearSafeZoneListener(context) {
241
+ if (context.safeZoneHandler) {
242
+ document.removeEventListener('mousemove', context.safeZoneHandler)
243
+ context.safeZoneHandler = null
244
+ }
245
+ }
246
+
247
+ function getSafeZone(triggerRect, tooltipRect, placement, margin) {
248
+ let safeRect = {}
249
+ if (placement.startsWith('top')) {
250
+ safeRect.left = triggerRect.left - margin
251
+ safeRect.right = triggerRect.right + margin
252
+ safeRect.top = tooltipRect.bottom - margin
253
+ safeRect.bottom = triggerRect.top + margin
254
+ } else if (placement.startsWith('bottom')) {
255
+ safeRect.left = triggerRect.left - margin
256
+ safeRect.right = triggerRect.right + margin
257
+ safeRect.top = triggerRect.bottom - margin
258
+ safeRect.bottom = tooltipRect.top + margin
259
+ } else if (placement.startsWith('left')) {
260
+ safeRect.top = triggerRect.top - margin
261
+ safeRect.bottom = triggerRect.bottom + margin
262
+ safeRect.left = tooltipRect.right - margin
263
+ safeRect.right = triggerRect.left + margin
264
+ } else if (placement.startsWith('right')) {
265
+ safeRect.top = triggerRect.top - margin
266
+ safeRect.bottom = triggerRect.bottom + margin
267
+ safeRect.left = triggerRect.right - margin
268
+ safeRect.right = tooltipRect.left + margin
269
+ } else {
270
+ safeRect = {
271
+ left: triggerRect.left - margin,
272
+ right: triggerRect.right + margin,
273
+ top: triggerRect.top - margin,
274
+ bottom: triggerRect.bottom + margin,
275
+ }
276
+ }
277
+ return safeRect
278
+ }
279
+
280
+ function isPointInsideRect(x, y, rect) {
281
+ return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
282
+ }
@@ -11,7 +11,7 @@ const TOOLTIP_TIMEOUT = 250
11
11
 
12
12
  export default class PbTooltip extends PbEnhancedElement {
13
13
  static get selector() {
14
- return '[data-pb-tooltip-kit]'
14
+ return '[data-pb-tooltip-kit="true"][data-pb-tooltip-interaction="false"]:not([data-pb-tooltip-delay-open]):not([data-pb-tooltip-delay-close])'
15
15
  }
16
16
 
17
17
  connect() {
@@ -152,4 +152,4 @@ export default class PbTooltip extends PbEnhancedElement {
152
152
  get triggerMethod() {
153
153
  return this.element.dataset.pbTooltipTriggerMethod || 'hover'
154
154
  }
155
- }
155
+ }
@@ -7,6 +7,10 @@ module Playbook
7
7
  prop :trigger_element_selector
8
8
  prop :trigger_element_id, deprecated: true
9
9
  prop :tooltip_id
10
+ prop :interaction, type: Playbook::Props::Boolean,
11
+ default: false
12
+ prop :delay_open
13
+ prop :delay_close
10
14
  prop :dark, type: Playbook::Props::Boolean,
11
15
  default: false
12
16
  prop :trigger_method, type: Playbook::Props::Enum,
@@ -18,15 +22,19 @@ module Playbook
18
22
  end
19
23
 
20
24
  def data
21
- Hash(values[:data]).merge(
25
+ data = Hash(values[:data]).merge(
22
26
  pb_tooltip_kit: true,
23
27
  pb_tooltip_position: position,
24
28
  pb_tooltip_trigger_element_selector: trigger_element_selector,
25
29
  pb_tooltip_trigger_element_id: trigger_element_id,
26
30
  pb_tooltip_tooltip_id: tooltip_id,
27
31
  pb_tooltip_show_tooltip: true,
28
- pb_tooltip_trigger_method: trigger_method
32
+ pb_tooltip_trigger_method: trigger_method,
33
+ pb_tooltip_interaction: interaction
29
34
  )
35
+ data = data.merge(pb_tooltip_delay_open: delay_open) if delay_open
36
+ data = data.merge(pb_tooltip_delay_close: delay_close) if delay_close
37
+ data
30
38
  end
31
39
 
32
40
  private
@@ -1,9 +1,10 @@
1
- import React from 'react'
1
+ import React, { useState, useEffect, forwardRef} from 'react'
2
2
  import Select from 'react-select'
3
3
  import AsyncSelect from 'react-select/async'
4
4
  import CreateableSelect from 'react-select/creatable'
5
5
  import AsyncCreateableSelect from 'react-select/async-creatable'
6
- import { get, isString, uniqueId } from 'lodash'
6
+ import { get, isString, uniqueId } from '../utilities/object'
7
+
7
8
  import { globalProps, GlobalProps } from '../utilities/globalProps'
8
9
  import classnames from 'classnames'
9
10
 
@@ -45,8 +46,13 @@ type TypeaheadProps = {
45
46
  getOptionLabel?: string | (() => string),
46
47
  getOptionValue?: string | (() => string),
47
48
  name?: string,
49
+ options?: Array<{ label: string; value?: string }>,
48
50
  marginBottom?: "none" | "xxs" | "xs" | "sm" | "md" | "lg" | "xl",
49
51
  pillColor?: "primary" | "neutral" | "success" | "warning" | "error" | "info" | "data_1" | "data_2" | "data_3" | "data_4" | "data_5" | "data_6" | "data_7" | "data_8" | "windows" | "siding" | "roofing" | "doors" | "gutters" | "solar" | "insulation" | "accessories",
52
+ onChange?: any,
53
+ optionsByContext?: Record<string, Array<{ label: string; value?: string }>>
54
+ searchContextSelector?: string,
55
+ clearOnContextChange?: boolean,
50
56
  } & GlobalProps
51
57
 
52
58
  export type SelectValueType = {
@@ -66,8 +72,7 @@ type TagOnChangeValues = {
66
72
  * @constant {React.ReactComponent} Typeahead
67
73
  * @param {TypeaheadProps} props - props as described at https://react-select.com/props
68
74
  */
69
-
70
- const Typeahead = ({
75
+ const Typeahead = forwardRef<HTMLInputElement, TypeaheadProps>(({
71
76
  async,
72
77
  className,
73
78
  components = {},
@@ -78,9 +83,14 @@ const Typeahead = ({
78
83
  getOptionValue,
79
84
  htmlOptions = {},
80
85
  id,
86
+ name,
81
87
  loadOptions = noop,
82
88
  marginBottom = "sm",
83
89
  pillColor,
90
+ onChange,
91
+ optionsByContext = {},
92
+ searchContextSelector,
93
+ clearOnContextChange = false,
84
94
  ...props
85
95
  }: TypeaheadProps) => {
86
96
  const selectProps = {
@@ -115,6 +125,32 @@ const Typeahead = ({
115
125
  ...props,
116
126
  }
117
127
 
128
+ const [contextValue, setContextValue] = useState("")
129
+
130
+ useEffect(() => {
131
+ if (searchContextSelector) {
132
+ const searchContextElement = document.getElementById(searchContextSelector)
133
+
134
+ setContextValue((searchContextElement as HTMLInputElement)?.value)
135
+ const handleContextChange = (e: Event) => {
136
+ const target = e.target as HTMLInputElement;
137
+ setContextValue(target.value);
138
+ if (clearOnContextChange) document.dispatchEvent(new CustomEvent(`pb-typeahead-kit-${selectProps.id}:clear`))
139
+ }
140
+
141
+ if (searchContextElement) searchContextElement.addEventListener('change', handleContextChange)
142
+
143
+ return () => {
144
+ if (searchContextElement) searchContextElement.removeEventListener('change', handleContextChange)
145
+ }
146
+ }
147
+ }, [searchContextSelector])
148
+
149
+ const contextArray = optionsByContext[contextValue]
150
+ if (Array.isArray(contextArray) && contextArray.length > 0) {
151
+ selectProps.options = contextArray
152
+ }
153
+
118
154
  const Tag = (
119
155
  createable
120
156
  ? (async ? AsyncCreateableSelect : CreateableSelect)
@@ -122,6 +158,15 @@ const Typeahead = ({
122
158
  )
123
159
 
124
160
  const handleOnChange = (_data: SelectValueType, { action, option, removedValue }: TagOnChangeValues) => {
161
+ if (onChange) {
162
+ const isReactHookForm = onChange.toString().includes("target")
163
+ if (isReactHookForm) {
164
+ onChange({ target: { name, value: _data } })
165
+ } else {
166
+ onChange(_data)
167
+ }
168
+ }
169
+
125
170
  if (action === 'select-option') {
126
171
  if (selectProps.onMultiValueClick) selectProps.onMultiValueClick(option)
127
172
  const multiValueClearEvent = new CustomEvent(`pb-typeahead-kit-${selectProps.id}-result-option-select`, { detail: option ? option : _data })
@@ -165,10 +210,11 @@ const Typeahead = ({
165
210
  />
166
211
  </div>
167
212
  )
168
- }
213
+ })
169
214
 
170
215
  Object.keys(kitComponents).forEach((k) => {
171
216
  (Typeahead as GenericObject)[k] = (kitComponents as {[key: string]: unknown})[k]
172
217
  })
173
218
 
219
+ Typeahead.displayName = 'Typeahead'
174
220
  export default Typeahead
@@ -8,15 +8,17 @@ import { SelectValueType } from '../_typeahead'
8
8
  type Props = {
9
9
  data: SelectValueType,
10
10
  multiValueTemplate: any,
11
+ wrapped?: boolean,
11
12
  pillColor?: "primary" | "neutral" | "success" | "warning" | "error" | "info" | "data_1" | "data_2" | "data_3" | "data_4" | "data_5" | "data_6" | "data_7" | "data_8" | "windows" | "siding" | "roofing" | "doors" | "gutters" | "solar" | "insulation" | "accessories",
12
13
  removeProps: any,
13
14
  selectProps: any,
14
15
  }
15
16
 
17
+
16
18
  const MultiValue = (props: Props) => {
17
19
  const { removeProps } = props
18
20
  const { imageUrl, label } = props.data
19
- const { dark, multiKit, pillColor, truncate } = props.selectProps
21
+ const { dark, multiKit, pillColor, truncate, wrapped } = props.selectProps
20
22
 
21
23
  const formPillProps = {
22
24
  marginRight: 'xs',
@@ -52,6 +54,7 @@ const MultiValue = (props: Props) => {
52
54
  size={multiKit === 'smallPill' ? 'small' : ''}
53
55
  text=''
54
56
  truncate={truncate}
57
+ wrapped={wrapped}
55
58
  {...props}
56
59
  />
57
60
  }
@@ -66,6 +69,7 @@ const MultiValue = (props: Props) => {
66
69
  size={multiKit === 'smallPill' ? 'small' : ''}
67
70
  text={label}
68
71
  truncate={truncate}
72
+ wrapped={wrapped}
69
73
  {...props}
70
74
  />
71
75
  }