playbook_ui 14.18.0 β†’ 14.19.0.pre.alpha.PLAY20937693

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +0 -1
  3. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +304 -21
  4. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +5 -1
  5. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +6 -1
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +0 -6
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color.jsx +80 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color.md +3 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.html.erb +58 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.md +3 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows_rails.md +5 -1
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_no_subrows.jsx β†’ _advanced_table_selectable_rows_no_subrows_react.jsx} +2 -2
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.md +3 -2
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +6 -5
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +3 -2
  16. data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +106 -0
  17. data/app/pb_kits/playbook/pb_advanced_table/index.js +228 -11
  18. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +9 -1
  19. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +0 -3
  20. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +1 -2
  21. data/app/pb_kits/playbook/pb_avatar/_avatar.scss +4 -0
  22. data/app/pb_kits/playbook/pb_avatar/_avatar.tsx +3 -0
  23. data/app/pb_kits/playbook/pb_avatar/avatar.html.erb +3 -3
  24. data/app/pb_kits/playbook/pb_avatar/avatar.rb +2 -0
  25. data/app/pb_kits/playbook/pb_avatar/avatar.test.js +18 -0
  26. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_grayscale.html.erb +5 -0
  27. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_grayscale.jsx +16 -0
  28. data/app/pb_kits/playbook/pb_avatar/docs/example.yml +2 -0
  29. data/app/pb_kits/playbook/pb_avatar/docs/index.js +1 -0
  30. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
  31. data/app/pb_kits/playbook/pb_card/card.rb +12 -0
  32. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +1 -1
  33. data/app/pb_kits/playbook/pb_circle_chart/circleChart.test.js +2 -2
  34. data/app/pb_kits/playbook/pb_circle_chart/circleChartTheme.ts +53 -0
  35. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_block.html.erb +2 -2
  36. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_block.jsx +1 -1
  37. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_colors.html.erb +1 -1
  38. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_colors.jsx +1 -1
  39. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_custom_tooltip.html.erb +1 -1
  40. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_custom_tooltip.jsx +1 -1
  41. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_default.html.erb +1 -1
  42. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_default.jsx +1 -1
  43. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_legend_position.html.erb +1 -1
  44. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_legend_position.jsx +1 -1
  45. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_live_data.jsx +2 -2
  46. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_pb_styles.jsx +38 -0
  47. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_pb_styles.md +1 -0
  48. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_rounded.html.erb +1 -1
  49. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_rounded.jsx +1 -1
  50. data/app/pb_kits/playbook/pb_circle_chart/docs/example.yml +2 -3
  51. data/app/pb_kits/playbook/pb_circle_chart/docs/index.js +2 -1
  52. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +12 -0
  53. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +12 -0
  54. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +50 -1
  55. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_error.html.erb +2 -2
  56. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_error.jsx +4 -1
  57. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_rails.md +4 -0
  58. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_range_limit.md +1 -1
  59. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick_react.md +5 -1
  60. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range_pattern.jsx +34 -0
  61. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range_pattern.md +14 -0
  62. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range_pattern_rails.html.erb +20 -0
  63. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range_pattern_rails.md +14 -0
  64. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +2 -0
  65. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +1 -0
  66. data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.tsx +10 -0
  67. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.html.erb +64 -0
  68. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors.html.erb +55 -0
  69. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_colors_rails.md +1 -0
  70. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line.html.erb +55 -0
  71. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line_rails.md +5 -0
  72. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_rails.md +5 -0
  73. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_event_listeners.jsx +59 -0
  74. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_event_listeners_react.md +1 -0
  75. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +4 -1
  76. data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
  77. data/app/pb_kits/playbook/pb_draggable/draggable.rb +9 -1
  78. data/app/pb_kits/playbook/pb_draggable/draggable_container.rb +11 -1
  79. data/app/pb_kits/playbook/pb_draggable/draggable_item.rb +11 -1
  80. data/app/pb_kits/playbook/pb_draggable/index.js +141 -142
  81. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +33 -5
  82. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +5 -0
  83. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +5 -16
  84. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +5 -2
  85. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.jsx +4 -1
  86. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.html.erb +28 -0
  87. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +17 -64
  88. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.html.erb +58 -0
  89. data/app/pb_kits/playbook/pb_dropdown/docs/{_dropdown_with_autocomplete_and_custom_display.jsx β†’ _dropdown_with_autocomplete_with_subcomponents.jsx} +11 -25
  90. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.md +1 -0
  91. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.md +1 -0
  92. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.jsx +61 -0
  93. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.md +2 -0
  94. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.html.erb +52 -0
  95. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.md +2 -0
  96. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +7 -4
  97. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -2
  98. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +2 -2
  99. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +4 -0
  100. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +45 -1
  101. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +10 -0
  102. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +3 -0
  103. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +12 -2
  104. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +3 -1
  105. data/app/pb_kits/playbook/pb_dropdown/index.js +57 -0
  106. data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +26 -0
  107. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +1 -2
  108. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +4 -4
  109. data/app/pb_kits/playbook/pb_empty_state/_empty_state.scss +8 -1
  110. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_alignment.html.erb +27 -0
  111. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_default.html.erb +7 -0
  112. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_orientation.html.erb +12 -0
  113. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_size.html.erb +23 -0
  114. data/app/pb_kits/playbook/pb_empty_state/docs/example.yml +5 -1
  115. data/app/pb_kits/playbook/pb_empty_state/empty_state.html.erb +19 -0
  116. data/app/pb_kits/playbook/pb_empty_state/empty_state.rb +123 -0
  117. data/app/pb_kits/playbook/pb_filter/docs/_filter_within_turbo_frames.html.erb +41 -0
  118. data/app/pb_kits/playbook/pb_filter/docs/_filter_within_turbo_frames.md +1 -0
  119. data/app/pb_kits/playbook/pb_filter/docs/example.yml +1 -0
  120. data/app/pb_kits/playbook/pb_form_group/_error_state_mixin.scss +22 -18
  121. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_pb_styles.jsx +0 -1
  122. data/app/pb_kits/playbook/pb_gauge/gaugeTheme.ts +3 -1
  123. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_pb_styles.jsx +52 -0
  124. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_pb_styles.md +1 -0
  125. data/app/pb_kits/playbook/pb_line_graph/docs/example.yml +1 -0
  126. data/app/pb_kits/playbook/pb_line_graph/docs/index.js +1 -0
  127. data/app/pb_kits/playbook/pb_line_graph/lineGraphTheme.ts +110 -0
  128. data/app/pb_kits/playbook/pb_message/_message.tsx +3 -0
  129. data/app/pb_kits/playbook/pb_message/docs/_message_grayscale.html.erb +9 -0
  130. data/app/pb_kits/playbook/pb_message/docs/_message_grayscale.jsx +21 -0
  131. data/app/pb_kits/playbook/pb_message/docs/example.yml +2 -0
  132. data/app/pb_kits/playbook/pb_message/docs/index.js +1 -0
  133. data/app/pb_kits/playbook/pb_message/message.html.erb +2 -1
  134. data/app/pb_kits/playbook/pb_message/message.rb +1 -0
  135. data/app/pb_kits/playbook/pb_overlay/_overlay.scss +2 -1
  136. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.jsx +1 -1
  137. data/app/pb_kits/playbook/pb_overlay/subcomponents/_overlay_token.tsx +5 -4
  138. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +13 -0
  139. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +3 -1
  140. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_country_search.html.erb +10 -0
  141. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_country_search.jsx +20 -0
  142. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_country_search.md +1 -0
  143. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_validation.jsx +8 -1
  144. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +2 -0
  145. data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +1 -0
  146. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
  147. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.test.js +19 -0
  148. data/app/pb_kits/playbook/pb_popover/docs/_popover_append_to.html.erb +46 -0
  149. data/app/pb_kits/playbook/pb_popover/docs/_popover_append_to.md +1 -0
  150. data/app/pb_kits/playbook/pb_popover/docs/example.yml +1 -0
  151. data/app/pb_kits/playbook/pb_popover/index.ts +13 -1
  152. data/app/pb_kits/playbook/pb_popover/popover.rb +2 -0
  153. data/app/pb_kits/playbook/pb_select/_select.scss +10 -0
  154. data/app/pb_kits/playbook/pb_select/docs/_select_error.html.erb +1 -1
  155. data/app/pb_kits/playbook/pb_select/docs/_select_error.jsx +7 -2
  156. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.jsx +7 -7
  157. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +5 -5
  158. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_error.html.erb +1 -1
  159. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_error.jsx +9 -1
  160. data/app/pb_kits/playbook/pb_textarea/docs/_textarea_error.html.erb +5 -1
  161. data/app/pb_kits/playbook/pb_textarea/docs/_textarea_error.jsx +7 -1
  162. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.html.erb +8 -1
  163. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.jsx +6 -2
  164. data/app/pb_kits/playbook/pb_user/_user.tsx +3 -0
  165. data/app/pb_kits/playbook/pb_user/docs/_user_grayscale.html.erb +6 -0
  166. data/app/pb_kits/playbook/pb_user/docs/_user_grayscale.jsx +16 -0
  167. data/app/pb_kits/playbook/pb_user/docs/example.yml +2 -0
  168. data/app/pb_kits/playbook/pb_user/docs/index.js +1 -0
  169. data/app/pb_kits/playbook/pb_user/user.html.erb +2 -1
  170. data/app/pb_kits/playbook/pb_user/user.rb +1 -0
  171. data/dist/chunks/_typeahead-BQV04mOl.js +22 -0
  172. data/dist/chunks/_weekday_stacked-CVwWr8B2.js +45 -0
  173. data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
  174. data/dist/chunks/lib-DwFasxbk.js +29 -0
  175. data/dist/chunks/{pb_form_validation-BRjyJrKh.js β†’ pb_form_validation-nnXW3T-3.js} +1 -1
  176. data/dist/chunks/vendor.js +1 -1
  177. data/dist/menu.yml +6 -14
  178. data/dist/playbook-doc.js +2 -2
  179. data/dist/playbook-rails-react-bindings.js +1 -1
  180. data/dist/playbook-rails.js +1 -1
  181. data/dist/playbook.css +1 -1
  182. data/lib/playbook/version.rb +2 -2
  183. metadata +66 -24
  184. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.md +0 -1
  185. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_hook.jsx +0 -79
  186. data/app/pb_kits/playbook/pb_gantt_chart/_gantt_chart.scss +0 -3
  187. data/app/pb_kits/playbook/pb_gantt_chart/_gantt_chart.tsx +0 -72
  188. data/app/pb_kits/playbook/pb_gantt_chart/docs/_gantt_chart_default.jsx +0 -53
  189. data/app/pb_kits/playbook/pb_gantt_chart/docs/example.yml +0 -7
  190. data/app/pb_kits/playbook/pb_gantt_chart/docs/index.js +0 -1
  191. data/app/pb_kits/playbook/pb_gantt_chart/gantt_chart.test.jsx +0 -19
  192. data/dist/chunks/_typeahead-C_FX7o_S.js +0 -22
  193. data/dist/chunks/_weekday_stacked-B4RLTeDo.js +0 -45
  194. data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
  195. data/dist/chunks/lib-ySl8uEpT.js +0 -29
  196. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_react.md β†’ _advanced_table_selectable_rows.md} +0 -0
  197. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_no_subrows.html.erb β†’ _advanced_table_selectable_rows_no_subrows_rails.html.erb} +0 -0
  198. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows.html.erb β†’ _advanced_table_selectable_rows_rails.html.erb} +0 -0
  199. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_drop_zones_colors.md β†’ _draggable_drop_zones_colors_react.md} +0 -0
  200. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_drop_zones_line.md β†’ _draggable_drop_zones_line_react.md} +0 -0
  201. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_drop_zones.md β†’ _draggable_drop_zones_react.md} +0 -0
  202. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_event_listeners.md β†’ _draggable_event_listeners_rails.md} +0 -0
@@ -1,24 +1,26 @@
1
1
  import PbEnhancedElement from "../pb_enhanced_element";
2
2
 
3
- const DRAGGABLE_SELECTOR = "[data-pb-draggable]";
3
+ const DRAGGABLE_SELECTOR = "[data-pb-draggable]";
4
4
  const DRAGGABLE_CONTAINER = ".pb_draggable_container";
5
+ const NEEDS_CLONE = ["shadow", "outline", "line"]; // clone only for these types
5
6
 
6
7
  export default class PbDraggable extends PbEnhancedElement {
7
- static get selector() {
8
- return DRAGGABLE_SELECTOR;
9
- }
8
+ static get selector() { return DRAGGABLE_SELECTOR; }
10
9
 
11
10
  connect() {
12
11
  this.state = {
13
- items: [],
14
- dragData: { id: "", initialGroup: "" },
15
- isDragging: "",
16
- activeContainer: ""
12
+ items: [],
13
+ dragData: { id: "", initialGroup: "" },
14
+ isDragging: "",
15
+ activeContainer: "",
17
16
  };
18
17
 
19
- this.draggedItem = null;
18
+ this.draggedItem = null;
20
19
  this.draggedItemId = null;
20
+ this.dragGhost = null;
21
21
  this.hasMultipleContainers = false;
22
+ this.dragZoneType = "";
23
+ this.dragZoneColor = "";
22
24
 
23
25
  document.addEventListener("DOMContentLoaded", () => this.bindEventListeners());
24
26
  }
@@ -26,13 +28,12 @@ export default class PbDraggable extends PbEnhancedElement {
26
28
  setState(newState) {
27
29
  this.state = { ...this.state, ...newState };
28
30
  if (newState.items) {
29
- const customEvent = new CustomEvent('pb-draggable-reorder', {
31
+ this.element.dispatchEvent(new CustomEvent("pb-draggable-reorder", {
30
32
  detail: {
31
33
  reorderedItems: this.state.items,
32
- containerId: this.element.querySelector(DRAGGABLE_CONTAINER).id
33
- }
34
- });
35
- this.element.dispatchEvent(customEvent);
34
+ containerId: this.element.querySelector(DRAGGABLE_CONTAINER).id,
35
+ },
36
+ }));
36
37
  }
37
38
  }
38
39
 
@@ -43,71 +44,102 @@ export default class PbDraggable extends PbEnhancedElement {
43
44
 
44
45
  // Needed to prevent images within draggable items from being independently draggable
45
46
  // Needed if using Image kit in draggable items
46
- this.element.querySelectorAll(".pb_draggable_item img").forEach(img => {
47
- img.setAttribute("draggable", "false");
48
- });
49
-
50
- this.element.querySelectorAll(".pb_draggable_item").forEach(item => {
51
- item.addEventListener("dragstart", this.handleDragStart.bind(this));
52
- item.addEventListener("dragend", this.handleDragEnd.bind(this));
53
- item.addEventListener("dragenter", this.handleDragEnter.bind(this));
54
- });
47
+ this.element.querySelectorAll(".pb_draggable_item img")
48
+ .forEach(img => img.setAttribute("draggable", "false"));
49
+
50
+ this.element.querySelectorAll(".pb_draggable_item")
51
+ .forEach(item => {
52
+ item.addEventListener("dragstart", this.handleDragStart.bind(this));
53
+ item.addEventListener("dragend", this.handleDragEnd.bind(this));
54
+ item.addEventListener("dragenter", this.handleDragEnter.bind(this));
55
+ });
55
56
 
56
- containers.forEach(container => {
57
- container.addEventListener("dragover", this.handleDragOver.bind(this));
58
- container.addEventListener("drop", this.handleDrop.bind(this));
57
+ containers.forEach(c => {
58
+ c.addEventListener("dragover", this.handleDragOver.bind(this));
59
+ c.addEventListener("drop", this.handleDrop.bind(this));
59
60
  });
60
61
  }
61
62
 
63
+ /* ---------------- DRAG START ---------------- */
62
64
  handleDragStart(event) {
63
65
  // Needed to prevent images within draggable items from being independently draggable
64
66
  // Needed if using Image kit in draggable items
65
- if (event.target.tagName.toLowerCase() === 'img') {
67
+ if (event.target.tagName.toLowerCase() === "img") {
66
68
  event.preventDefault();
67
69
  return;
68
70
  }
69
71
 
70
- const container = event.target.closest(DRAGGABLE_CONTAINER);
71
- this.draggedItem = event.target;
72
+ const container = event.target.closest(DRAGGABLE_CONTAINER);
73
+ this.draggedItem = event.target;
72
74
  this.draggedItemId = event.target.id;
75
+ this.dragZoneType = this.element.dataset.dropZoneType || "";
76
+ this.dragZoneColor = this.element.dataset.dropZoneColor || "";
73
77
 
74
78
  this.setState({
75
- dragData: { id: this.draggedItemId, initialGroup: container.id },
76
- isDragging: this.draggedItemId
79
+ dragData: { id: this.draggedItemId, initialGroup: container.id },
80
+ isDragging: this.draggedItemId,
77
81
  });
78
82
 
79
- event.target.classList.add("is_dragging");
83
+ this.draggedItem.classList.add(
84
+ "is_dragging",
85
+ `drop_zone_${this.dragZoneType}`,
86
+ `drop_zone_color_${this.dragZoneColor}`,
87
+ );
88
+
80
89
  if (event.dataTransfer) {
81
- event.dataTransfer.effectAllowed = 'move';
82
- event.dataTransfer.setData('text/plain', this.draggedItemId);
90
+ event.dataTransfer.effectAllowed = "move";
91
+ event.dataTransfer.setData("text/plain", this.draggedItemId);
92
+
93
+ /* ---------- custom ghost clone (shadow + outline only) ---------- */
94
+ if (NEEDS_CLONE.includes(this.dragZoneType)) {
95
+ const ghost = this.draggedItem.cloneNode(true);
96
+ ghost.classList.remove(
97
+ "is_dragging",
98
+ `drop_zone_${this.dragZoneType}`,
99
+ `drop_zone_color_${this.dragZoneColor}`,
100
+ );
101
+ const { width, height } = this.draggedItem.getBoundingClientRect();
102
+ Object.assign(ghost.style, {
103
+ border: "none",
104
+ width: `${width}px`,
105
+ height: `${height}px`,
106
+ position: "absolute",
107
+ top: "-9999px",
108
+ left: "-9999px",
109
+ boxSizing: "border-box",
110
+ zIndex: "9999",
111
+ });
112
+ document.body.appendChild(ghost);
113
+ this.dragGhost = ghost;
114
+ event.dataTransfer.setDragImage(ghost, width / 2, height / 2);
115
+ }
116
+ /* ---------------------------------------------------------------- */
83
117
  }
84
118
 
85
- setTimeout(() => {
86
- event.target.style.opacity = '0.5';
87
- }, 0);
119
+ if (this.dragZoneType !== "line") {
120
+ requestAnimationFrame(() => (event.target.style.opacity = "0.5"));
121
+ }
88
122
  }
89
123
 
124
+ /* ---------------- DRAG ENTER ---------------- */
90
125
  handleDragEnter(event) {
91
126
  if (!this.draggedItem || event.target === this.draggedItem) return;
92
-
93
- if (this.hasMultipleContainers) {
94
- this.handleMultiContainerDragEnter(event);
95
- } else {
96
- this.handleSingleContainerDragEnter(event);
97
- }
127
+ this.hasMultipleContainers
128
+ ? this.handleMultiContainerDragEnter(event)
129
+ : this.handleSingleContainerDragEnter(event);
98
130
  }
99
131
 
100
132
  handleSingleContainerDragEnter(event) {
101
- const targetItem = event.target.closest('.pb_draggable_item');
133
+ const targetItem = event.target.closest(".pb_draggable_item");
134
+ // If we're entering a container directly or there's no target item
102
135
  if (!targetItem) return;
103
136
 
104
137
  const container = targetItem.parentNode;
105
- const items = Array.from(container.children);
106
-
107
- const draggedIndex = items.indexOf(this.draggedItem);
108
- const targetIndex = items.indexOf(targetItem);
138
+ const items = Array.from(container.children);
139
+ const fromIdx = items.indexOf(this.draggedItem);
140
+ const toIdx = items.indexOf(targetItem);
109
141
 
110
- if (draggedIndex > targetIndex) {
142
+ if (fromIdx > toIdx) {
111
143
  container.insertBefore(this.draggedItem, targetItem);
112
144
  } else {
113
145
  container.insertBefore(this.draggedItem, targetItem.nextSibling);
@@ -116,146 +148,113 @@ export default class PbDraggable extends PbEnhancedElement {
116
148
 
117
149
  handleMultiContainerDragEnter(event) {
118
150
  const targetContainer = event.target.closest(DRAGGABLE_CONTAINER);
119
- const targetItem = event.target.closest('.pb_draggable_item');
120
-
151
+ const targetItem = event.target.closest(".pb_draggable_item");
121
152
  if (!targetContainer) return;
122
153
 
123
- // If we're entering a container directly or there's no target item
124
154
  if (!targetItem) {
125
- const lastItem = targetContainer.querySelector('.pb_draggable_item:last-child');
126
- if (lastItem) {
127
- targetContainer.insertBefore(this.draggedItem, lastItem.nextSibling);
128
- } else {
129
- targetContainer.appendChild(this.draggedItem);
130
- }
155
+ const last = targetContainer.querySelector(".pb_draggable_item:last-child");
156
+ last
157
+ ? targetContainer.insertBefore(this.draggedItem, last.nextSibling)
158
+ : targetContainer.appendChild(this.draggedItem);
131
159
  return;
132
160
  }
133
161
 
134
- const container = targetItem.parentNode;
135
- const items = Array.from(container.children);
136
-
137
- const newItems = [...items].map(item => ({
138
- id: item.id,
139
- container: container.id
140
- }));
141
-
142
- this.setState({ items: newItems });
162
+ const items = Array.from(targetContainer.children);
163
+ this.setState({ items: items.map(i => ({ id: i.id, container: targetContainer.id })) });
143
164
 
144
- const rect = targetItem.getBoundingClientRect();
145
- const middleY = rect.top + rect.height / 2;
165
+ const midY = targetItem.getBoundingClientRect().top +
166
+ targetItem.getBoundingClientRect().height / 2;
146
167
 
147
- if (event.clientY < middleY) {
148
- container.insertBefore(this.draggedItem, targetItem);
168
+ if (event.clientY < midY) {
169
+ targetContainer.insertBefore(this.draggedItem, targetItem);
149
170
  } else {
150
- container.insertBefore(this.draggedItem, targetItem.nextSibling);
171
+ targetContainer.insertBefore(this.draggedItem, targetItem.nextSibling);
151
172
  }
152
173
  }
153
174
 
175
+ /* ---------------- DRAG OVER ---------------- */
154
176
  handleDragOver(event) {
155
177
  event.preventDefault();
156
178
  event.stopPropagation();
157
-
158
- if (this.hasMultipleContainers) {
159
- this.handleMultiContainerDragOver(event);
160
- } else {
161
- this.handleSingleContainerDragOver(event);
162
- }
179
+ this.hasMultipleContainers
180
+ ? this.handleMultiContainerDragOver(event)
181
+ : this.handleSingleContainerDragOver(event);
163
182
  }
164
183
 
165
184
  handleSingleContainerDragOver(event) {
166
185
  const container = event.target.closest(DRAGGABLE_CONTAINER);
167
- if (container) {
168
- container.classList.add("active_container");
169
- }
186
+ if (container) container.classList.add("active_container");
170
187
  }
171
188
 
172
189
  handleMultiContainerDragOver(event) {
173
- let container;
174
- if (event.target.matches(DRAGGABLE_CONTAINER)) {
175
- container = event.target;
176
- } else {
177
- container = event.target.closest(DRAGGABLE_CONTAINER);
178
- }
179
-
180
- if (container) {
181
- this.setState({ activeContainer: container.id });
182
- container.classList.add("active_container");
183
-
184
- // If dragging over empty container or below last item
185
- const lastItem = container.querySelector('.pb_draggable_item:last-child');
186
- if (!lastItem || (lastItem && event.clientY > lastItem.getBoundingClientRect().bottom)) {
187
- if (this.draggedItem && this.draggedItem.parentNode !== container) {
188
- container.appendChild(this.draggedItem);
189
- }
190
+ const container = event.target.matches(DRAGGABLE_CONTAINER)
191
+ ? event.target
192
+ : event.target.closest(DRAGGABLE_CONTAINER);
193
+ if (!container) return;
194
+
195
+ this.setState({ activeContainer: container.id });
196
+ container.classList.add("active_container");
197
+
198
+ const last = container.querySelector(".pb_draggable_item:last-child");
199
+ if (!last || event.clientY > last.getBoundingClientRect().bottom) {
200
+ if (this.draggedItem && this.draggedItem.parentNode !== container) {
201
+ container.appendChild(this.draggedItem);
190
202
  }
191
203
  }
192
204
  }
193
205
 
206
+ /* ---------------- DROP ---------------- */
194
207
  handleDrop(event) {
195
208
  event.preventDefault();
196
209
  event.stopPropagation();
197
210
 
198
- let container;
199
- if (event.target.matches(DRAGGABLE_CONTAINER)) {
200
- container = event.target;
201
- } else {
202
- container = event.target.closest(DRAGGABLE_CONTAINER);
203
- }
204
-
211
+ const container = event.target.matches(DRAGGABLE_CONTAINER)
212
+ ? event.target
213
+ : event.target.closest(DRAGGABLE_CONTAINER);
205
214
  if (!container || !this.draggedItem) return;
206
215
 
207
216
  container.classList.remove("active_container");
208
- this.draggedItem.style.opacity = '1';
217
+ this.draggedItem.style.opacity = "1";
209
218
 
210
219
  // Handle empty containers
211
- if (this.hasMultipleContainers && !container.querySelector('.pb_draggable_item')) {
220
+ if (this.hasMultipleContainers && !container.querySelector(".pb_draggable_item")) {
212
221
  container.appendChild(this.draggedItem);
213
222
  }
214
223
 
215
224
  // Updated order of items as an array of item IDs
216
- const reorderedItems = Array.from(
217
- this.element.querySelectorAll('.pb_draggable_item')
218
- ).map(item => ({
219
- id: item.id,
220
- container: item.closest(DRAGGABLE_CONTAINER).id
221
- }));
222
-
223
- // Store reordered items in a data attribute on the container
224
- container.setAttribute("data-reordered-items", JSON.stringify(reorderedItems));
225
+ const reorderedItems = Array.from(this.element.querySelectorAll(".pb_draggable_item"))
226
+ .map(i => ({ id: i.id, container: i.closest(DRAGGABLE_CONTAINER).id }));
225
227
 
226
- const customEvent = new CustomEvent('pb-draggable-reorder', {
227
- detail: {
228
- reorderedItems,
229
- containerId: container.id,
230
- }
231
- });
232
-
233
- this.element.dispatchEvent(customEvent);
234
-
235
- this.setState({
236
- items: reorderedItems,
237
- isDragging: "",
238
- activeContainer: ""
239
- });
228
+ container.dataset.reorderedItems = JSON.stringify(reorderedItems);
229
+ this.element.dispatchEvent(new CustomEvent("pb-draggable-reorder", {
230
+ detail: { reorderedItems, containerId: container.id },
231
+ }));
240
232
 
241
- this.draggedItem = null;
233
+ this.setState({ items: reorderedItems, isDragging: "", activeContainer: "" });
234
+ this.draggedItem = null;
242
235
  this.draggedItemId = null;
243
236
  }
244
237
 
238
+ /* ---------------- DRAG END ---------------- */
245
239
  handleDragEnd(event) {
246
- event.target.classList.remove("is_dragging");
247
- event.target.style.opacity = '1';
240
+ event.target.classList.remove(
241
+ "is_dragging",
242
+ `drop_zone_${this.dragZoneType}`,
243
+ `drop_zone_color_${this.dragZoneColor}`,
244
+ );
245
+ event.target.style.opacity = "1";
246
+
247
+ if (this.dragGhost) {
248
+ document.body.removeChild(this.dragGhost);
249
+ this.dragGhost = null;
250
+ }
248
251
 
249
- this.setState({
250
- isDragging: "",
251
- activeContainer: ""
252
- });
252
+ this.setState({ isDragging: "", activeContainer: "" });
253
253
 
254
- this.draggedItem = null;
255
- this.draggedItemId = null;
254
+ this.element.querySelectorAll(DRAGGABLE_CONTAINER)
255
+ .forEach(c => c.classList.remove("active_container"));
256
256
 
257
- this.element.querySelectorAll(DRAGGABLE_CONTAINER).forEach(container => {
258
- container.classList.remove("active_container");
259
- });
257
+ this.draggedItem = null;
258
+ this.draggedItemId = null;
260
259
  }
261
260
  }
@@ -8,6 +8,7 @@ import {
8
8
  } from "../../utilities/props";
9
9
  import { globalProps } from "../../utilities/globalProps";
10
10
  import { DraggableContext } from "../context";
11
+ import { noop } from '../../utilities/object'
11
12
 
12
13
  type DraggableItemProps = {
13
14
  aria?: { [key: string]: string };
@@ -17,6 +18,13 @@ type DraggableItemProps = {
17
18
  data?: { [key: string]: string };
18
19
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
19
20
  id?: string;
21
+ onDrag?: () => void,
22
+ onDragEnd?: () => void,
23
+ onDragEnter?: () => void,
24
+ onDragLeave?: () => void,
25
+ onDragOver?: () => void,
26
+ onDragStart?: () => void,
27
+ onDrop?: () => void,
20
28
  dragId?: string;
21
29
  tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div' | 'tr' | 'th' | 'td' | 'thead' | 'col' | 'tbody',
22
30
  };
@@ -31,7 +39,14 @@ const DraggableItem = (props: DraggableItemProps) => {
31
39
  htmlOptions = {},
32
40
  id,
33
41
  dragId,
34
- tag="div"
42
+ tag="div",
43
+ onDrag = noop,
44
+ onDragEnd = noop,
45
+ onDragEnter = noop,
46
+ onDragLeave = noop,
47
+ onDragOver = noop,
48
+ onDragStart = noop,
49
+ onDrop = noop,
35
50
  } = props;
36
51
 
37
52
  const {
@@ -61,7 +76,7 @@ const DraggableItem = (props: DraggableItemProps) => {
61
76
  );
62
77
 
63
78
  // Enhanced drag start handler that preserves dimensions
64
- const onDragStart = (e: React.DragEvent) => {
79
+ const handleDragStartWithCustom = (e: React.DragEvent) => {
65
80
  if (dropZone !== 'ghost' && itemRef.current) {
66
81
  // Create a clone for the drag image
67
82
  const clone = itemRef.current.cloneNode(true) as HTMLElement;
@@ -96,6 +111,9 @@ const DraggableItem = (props: DraggableItemProps) => {
96
111
 
97
112
  // Call the original handler
98
113
  handleDragStart(dragId, container);
114
+
115
+ // Custom event handler
116
+ onDragStart()
99
117
  };
100
118
 
101
119
  return (
@@ -107,9 +125,19 @@ const DraggableItem = (props: DraggableItemProps) => {
107
125
  draggable
108
126
  id={id}
109
127
  key={dragId}
110
- onDragEnd={() => handleDragEnd()}
111
- onDragEnter={() => handleDragEnter(dragId, container)}
112
- onDragStart={onDragStart}
128
+ onDrag={onDrag}
129
+ onDragEnd={() => {
130
+ handleDragEnd()
131
+ onDragEnd()
132
+ }}
133
+ onDragEnter={() => {
134
+ handleDragEnter(dragId, container)
135
+ onDragEnter()
136
+ }}
137
+ onDragLeave={onDragLeave}
138
+ onDragOver={onDragOver}
139
+ onDragStart={handleDragStartWithCustom}
140
+ onDrop={onDrop}
113
141
  ref={itemRef}
114
142
  >
115
143
  {children}
@@ -41,6 +41,11 @@
41
41
  outline: unset;
42
42
  transition: box-shadow 0.15s ease-in-out;
43
43
  }
44
+ &:focus-within {
45
+ box-shadow: 0px 0px 0 1px $primary !important;
46
+ outline: unset;
47
+ transition: box-shadow 0.15s ease-in-out;
48
+ }
44
49
 
45
50
  &[class*="_select_only"] {
46
51
  box-shadow: inset 0 -11px 20px rgba($primary, 0.05);
@@ -36,7 +36,6 @@ type DropdownProps = {
36
36
  onSelect?: (arg: GenericObject) => null;
37
37
  options: GenericObject;
38
38
  separators?: boolean;
39
- triggerRef?: any;
40
39
  variant?: "default" | "subtle";
41
40
  };
42
41
 
@@ -65,7 +64,6 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
65
64
  onSelect,
66
65
  options,
67
66
  separators = true,
68
- triggerRef,
69
67
  variant = "default",
70
68
  } = props;
71
69
 
@@ -91,7 +89,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
91
89
  const [focusedOptionIndex, setFocusedOptionIndex] = useState(-1);
92
90
 
93
91
  const dropdownRef = useRef(null);
94
- const inputRef = useRef(null);
92
+ const inputRef = useRef<HTMLInputElement>(null);
95
93
  const inputWrapperRef = useRef(null);
96
94
  const dropdownContainerRef = useRef(null);
97
95
 
@@ -99,15 +97,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
99
97
  separateChildComponents(children);
100
98
 
101
99
  useEffect(() => {
102
- // Set the parent element of the trigger to relative to allow for absolute positioning of the dropdown
103
- //Only needed for when useDropdown hook used with external trigger
104
- if (triggerRef?.current) {
105
- const parentElement = triggerRef.current.parentNode;
106
- if (parentElement) {
107
- parentElement.style.position = 'relative';
108
- }
109
- }
110
- // Handle clicks outside the dropdown
100
+ // Handle clicks outside the dropdown
111
101
  const handleClick = handleClickOutside({
112
102
  inputWrapperRef,
113
103
  dropdownContainerRef,
@@ -167,7 +157,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
167
157
  };
168
158
 
169
159
  const handleWrapperClick = () => {
170
- autocomplete && inputRef.current.focus();
160
+ autocomplete && inputRef?.current?.focus();
171
161
  toggleDropdown();
172
162
  };
173
163
 
@@ -202,7 +192,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
202
192
  {...htmlProps}
203
193
  className={classes}
204
194
  id={id}
205
- style={triggerRef ? { position: "absolute" } : { position: "relative" }}
195
+ style={{position: "relative"}}
206
196
  >
207
197
  <DropdownContext.Provider
208
198
  value={{
@@ -225,8 +215,7 @@ let Dropdown = (props: DropdownProps, ref: any): React.ReactElement | null => {
225
215
  setIsDropDownClosed,
226
216
  setIsInputFocused,
227
217
  setSelected,
228
- toggleDropdown,
229
- triggerRef
218
+ toggleDropdown
230
219
  }}
231
220
  >
232
221
  {label &&
@@ -1,4 +1,4 @@
1
- <%
1
+ <%
2
2
  options = [
3
3
  { label: 'United States', value: 'United States', id: 'us' },
4
4
  { label: 'Canada', value: 'Canada', id: 'ca' },
@@ -6,4 +6,7 @@
6
6
  ]
7
7
  %>
8
8
 
9
- <%= pb_rails("dropdown", props: { error: "Please make a valid selection", options: options }) %>
9
+ <%= pb_rails("dropdown", props: {
10
+ error: raw(pb_rails("icon", props: { icon: "warning" }) + " Please make a valid selection"),
11
+ options: options
12
+ }) %>
@@ -1,9 +1,12 @@
1
1
  import React, { useState } from 'react'
2
2
  import Dropdown from '../../pb_dropdown/_dropdown'
3
+ import Icon from '../../pb_icon/_icon'
3
4
 
4
5
  const DropdownError = (props) => {
5
6
  const [selectedOption, setSelectedOption] = useState()
6
- const error = selectedOption?.value ? null : "Please make a valid selection"
7
+ const error = selectedOption?.value ? null : (<>
8
+ <Icon icon="warning" /> Please make a valid selection
9
+ </>)
7
10
  const options = [
8
11
  {
9
12
  label: "United States",
@@ -0,0 +1,28 @@
1
+ <%
2
+ options = [
3
+ {
4
+ label: "United States",
5
+ value: "United States",
6
+ areaCode: "+1",
7
+ icon: "πŸ‡ΊπŸ‡Έ",
8
+ id: "us"
9
+ },
10
+ {
11
+ label: "United Kingdom",
12
+ value: "United Kingdom",
13
+ areaCode: "+44",
14
+ icon: "πŸ‡¬πŸ‡§",
15
+ id: "gb"
16
+ },
17
+ {
18
+ label: "Pakistan",
19
+ value: "Pakistan",
20
+ areaCode: "+92",
21
+ icon: "πŸ‡΅πŸ‡°",
22
+ id: "pk"
23
+ }
24
+ ]
25
+
26
+ %>
27
+
28
+ <%= pb_rails("dropdown", props: {options: options, autocomplete: true}) %>