playbook_ui 14.12.0 → 14.13.0.pre.alpha.PBNTR5596084

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 (172) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +1 -0
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/CustomCell.tsx +1 -1
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +11 -4
  5. data/app/pb_kits/playbook/pb_advanced_table/Utilities/ActionBarAnimationHelper.ts +26 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +71 -10
  7. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +37 -21
  8. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +3 -3
  9. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +3 -1
  10. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +1 -1
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_loading.html.erb +33 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_loading_rails.md +1 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_loading.md → _advanced_table_loading_react.md} +2 -2
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_responsive.html.erb +38 -0
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props.jsx +1 -0
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_react.md +3 -1
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.jsx +55 -0
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header_react.md +3 -0
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -0
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -1
  21. data/app/pb_kits/playbook/pb_advanced_table/index.js +9 -6
  22. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +17 -3
  23. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +15 -11
  24. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +14 -3
  25. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +10 -7
  26. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +9 -1
  27. data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.html.erb +1 -1
  28. data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.rb +9 -0
  29. data/app/pb_kits/playbook/pb_avatar/_avatar.scss +14 -0
  30. data/app/pb_kits/playbook/pb_avatar/_avatar.tsx +11 -7
  31. data/app/pb_kits/playbook/pb_avatar/avatar.html.erb +6 -7
  32. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_badge_component_overlay.jsx +9 -3
  33. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_circle_icon_component_overlay.jsx +6 -2
  34. data/app/pb_kits/playbook/pb_button/button.rb +1 -1
  35. data/app/pb_kits/playbook/pb_card/card.html.erb +21 -2
  36. data/app/pb_kits/playbook/pb_card/card.rb +7 -0
  37. data/app/pb_kits/playbook/pb_copy_button/_copy_button.scss +4 -0
  38. data/app/pb_kits/playbook/pb_copy_button/_copy_button.tsx +92 -0
  39. data/app/pb_kits/playbook/pb_copy_button/copy_button.html.erb +15 -0
  40. data/app/pb_kits/playbook/pb_copy_button/copy_button.rb +28 -0
  41. data/app/pb_kits/playbook/pb_copy_button/copy_button.test.jsx +64 -0
  42. data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_default.html.erb +2 -0
  43. data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_default.jsx +21 -0
  44. data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_from.html.erb +5 -0
  45. data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_from.jsx +45 -0
  46. data/app/pb_kits/playbook/pb_copy_button/docs/_copy_button_from.md +1 -0
  47. data/app/pb_kits/playbook/pb_copy_button/docs/example.yml +8 -0
  48. data/app/pb_kits/playbook/pb_copy_button/docs/index.js +2 -0
  49. data/app/pb_kits/playbook/pb_copy_button/index.js +47 -0
  50. data/app/pb_kits/playbook/pb_date/_date.tsx +14 -4
  51. data/app/pb_kits/playbook/pb_date/docs/_date_default.jsx +2 -1
  52. data/app/pb_kits/playbook/pb_date/docs/_date_unstyled.jsx +13 -5
  53. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +3 -1
  54. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_rails.html.erb +99 -0
  55. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers_rails.md +1 -0
  56. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.html.erb +1 -3
  57. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards_rails.md +7 -0
  58. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table.html.erb +61 -0
  59. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table.md +4 -0
  60. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table_react.jsx +90 -0
  61. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_table_react.md +5 -0
  62. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +4 -5
  63. data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
  64. data/app/pb_kits/playbook/pb_draggable/draggable_container.html.erb +2 -2
  65. data/app/pb_kits/playbook/pb_draggable/draggable_container.rb +5 -0
  66. data/app/pb_kits/playbook/pb_draggable/draggable_item.html.erb +1 -1
  67. data/app/pb_kits/playbook/pb_draggable/draggable_item.rb +4 -0
  68. data/app/pb_kits/playbook/pb_draggable/index.js +151 -15
  69. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +7 -4
  70. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +6 -3
  71. data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +1 -6
  72. data/app/pb_kits/playbook/pb_filter/filter.html.erb +1 -5
  73. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_auto_close.html.erb +58 -0
  74. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_auto_close_rails.md +3 -0
  75. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/example.yml +1 -0
  76. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/index.js +7 -5
  77. data/app/pb_kits/playbook/pb_form_group/form_group.html.erb +1 -6
  78. data/app/pb_kits/playbook/pb_form_pill/form_pill.html.erb +1 -1
  79. data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +11 -7
  80. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting.html.erb +11 -0
  81. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting.jsx +22 -0
  82. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting_rails.md +1 -0
  83. data/app/pb_kits/playbook/pb_home_address_street/docs/_home_address_street_formatting_react.md +1 -0
  84. data/app/pb_kits/playbook/pb_home_address_street/docs/example.yml +2 -0
  85. data/app/pb_kits/playbook/pb_home_address_street/docs/index.js +1 -0
  86. data/app/pb_kits/playbook/pb_home_address_street/home_address_street.rb +13 -2
  87. data/app/pb_kits/playbook/pb_icon/icon.html.erb +2 -6
  88. data/app/pb_kits/playbook/pb_icon_button/docs/_icon_button_default.html.erb +1 -2
  89. data/app/pb_kits/playbook/pb_icon_button/docs/_icon_button_sizes.html.erb +27 -0
  90. data/app/pb_kits/playbook/pb_icon_button/docs/example.yml +1 -3
  91. data/app/pb_kits/playbook/pb_icon_button/icon_button.html.erb +1 -1
  92. data/app/pb_kits/playbook/pb_icon_button/icon_button.rb +3 -0
  93. data/app/pb_kits/playbook/pb_layout/body.html.erb +1 -5
  94. data/app/pb_kits/playbook/pb_layout/footer.html.erb +1 -5
  95. data/app/pb_kits/playbook/pb_layout/header.html.erb +1 -5
  96. data/app/pb_kits/playbook/pb_layout/item.html.erb +1 -5
  97. data/app/pb_kits/playbook/pb_layout/layout.html.erb +1 -5
  98. data/app/pb_kits/playbook/pb_layout/sidebar.html.erb +1 -5
  99. data/app/pb_kits/playbook/pb_legend/legend.html.erb +1 -6
  100. data/app/pb_kits/playbook/pb_lightbox/lightbox.scss +7 -6
  101. data/app/pb_kits/playbook/pb_link/_link.tsx +18 -0
  102. data/app/pb_kits/playbook/pb_link/docs/_link_target.html.erb +15 -0
  103. data/app/pb_kits/playbook/pb_link/docs/_link_target.jsx +29 -0
  104. data/app/pb_kits/playbook/pb_link/docs/example.yml +5 -3
  105. data/app/pb_kits/playbook/pb_link/docs/index.js +2 -1
  106. data/app/pb_kits/playbook/pb_link/link.html.erb +1 -1
  107. data/app/pb_kits/playbook/pb_link/link.rb +6 -0
  108. data/app/pb_kits/playbook/pb_link/link.test.jsx +30 -0
  109. data/app/pb_kits/playbook/pb_message/message.html.erb +1 -6
  110. data/app/pb_kits/playbook/pb_message/message_mention.html.erb +1 -6
  111. data/app/pb_kits/playbook/pb_progress_step/docs/_progress_step_tooltip.html.erb +6 -6
  112. data/app/pb_kits/playbook/pb_table/docs/_table_with_background_kit.html.erb +6 -9
  113. data/app/pb_kits/playbook/pb_table/docs/_table_with_background_kit.jsx +6 -9
  114. data/app/pb_kits/playbook/pb_table/docs/_table_with_clickable_rows.html.erb +47 -0
  115. data/app/pb_kits/playbook/pb_table/docs/_table_with_clickable_rows.jsx +88 -0
  116. data/app/pb_kits/playbook/pb_table/docs/_table_with_clickable_rows.md +1 -0
  117. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content.jsx +12 -8
  118. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content_rails.html.erb +52 -0
  119. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content_rails.md +0 -0
  120. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows_rails.html.erb +52 -0
  121. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows_rails.md +3 -0
  122. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table_rails.html.erb +80 -0
  123. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table_rails.md +1 -0
  124. data/app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.html.erb +96 -0
  125. data/app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.jsx +101 -0
  126. data/app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.md +1 -0
  127. data/app/pb_kits/playbook/pb_table/docs/example.yml +7 -0
  128. data/app/pb_kits/playbook/pb_table/docs/index.js +3 -1
  129. data/app/pb_kits/playbook/pb_table/styles/_desktop_collapse.scss +26 -0
  130. data/app/pb_kits/playbook/pb_table/styles/_mobile.scss +0 -1
  131. data/app/pb_kits/playbook/pb_table/styles/_mobile_collapse.scss +25 -0
  132. data/app/pb_kits/playbook/pb_table/styles/_tablet_collapse.scss +25 -0
  133. data/app/pb_kits/playbook/pb_table/subcomponents/_table_body.tsx +29 -2
  134. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +31 -3
  135. data/app/pb_kits/playbook/pb_table/table_body.html.erb +13 -7
  136. data/app/pb_kits/playbook/pb_table/table_body.rb +2 -0
  137. data/app/pb_kits/playbook/pb_table/table_row.html.erb +13 -7
  138. data/app/pb_kits/playbook/pb_table/table_row.rb +5 -1
  139. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_mask.html.erb +1 -1
  140. data/app/pb_kits/playbook/pb_text_input/index.js +52 -83
  141. data/app/pb_kits/playbook/pb_tooltip/_tooltip.tsx +3 -1
  142. data/app/pb_kits/playbook/pb_tooltip/docs/_tooltip_default.html.erb +1 -1
  143. data/app/pb_kits/playbook/pb_tooltip/index.js +45 -27
  144. data/app/pb_kits/playbook/pb_tooltip/tooltip.rb +5 -1
  145. data/app/pb_kits/playbook/pb_user/_user.tsx +3 -0
  146. data/app/pb_kits/playbook/pb_user/docs/_user_light_weight.html.erb +42 -0
  147. data/app/pb_kits/playbook/pb_user/docs/_user_light_weight.jsx +59 -0
  148. data/app/pb_kits/playbook/pb_user/docs/_user_light_weight.md +2 -0
  149. data/app/pb_kits/playbook/pb_user/docs/example.yml +2 -0
  150. data/app/pb_kits/playbook/pb_user/docs/index.js +1 -0
  151. data/app/pb_kits/playbook/pb_user/user.html.erb +1 -1
  152. data/app/pb_kits/playbook/pb_user/user.rb +1 -0
  153. data/app/pb_kits/playbook/pb_user/user.test.js +14 -0
  154. data/dist/chunks/_typeahead-C_q1qAtC.js +36 -0
  155. data/dist/chunks/_weekday_stacked-DCeouuO3.js +45 -0
  156. data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
  157. data/dist/chunks/{lib-kMuhBuU7.js → lib-WQEeEj3t.js} +2 -2
  158. data/dist/chunks/{pb_form_validation-DBJ0wZuS.js → pb_form_validation-Cq64l4zn.js} +1 -1
  159. data/dist/chunks/vendor.js +1 -1
  160. data/dist/menu.yml +6 -0
  161. data/dist/playbook-doc.js +1 -1
  162. data/dist/playbook-rails-react-bindings.js +1 -1
  163. data/dist/playbook-rails.js +1 -1
  164. data/dist/playbook.css +1 -1
  165. data/lib/playbook/pb_forms_global_props_helper.rb +136 -0
  166. data/lib/playbook/pb_forms_helper.rb +13 -4
  167. data/lib/playbook/version.rb +2 -2
  168. metadata +59 -9
  169. data/dist/chunks/_typeahead-BWwaAo_0.js +0 -36
  170. data/dist/chunks/_weekday_stacked-DE8qVYG2.js +0 -45
  171. data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
  172. /data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/{_fixed_confirmation_toast_auto_close.md → _fixed_confirmation_toast_auto_close_react.md} +0 -0
@@ -9,12 +9,38 @@ export default class PbDraggable extends PbEnhancedElement {
9
9
  }
10
10
 
11
11
  connect() {
12
+ this.state = {
13
+ items: [],
14
+ dragData: { id: "", initialGroup: "" },
15
+ isDragging: "",
16
+ activeContainer: ""
17
+ };
18
+
12
19
  this.draggedItem = null;
13
20
  this.draggedItemId = null;
21
+ this.hasMultipleContainers = false;
22
+
14
23
  document.addEventListener("DOMContentLoaded", () => this.bindEventListeners());
15
24
  }
16
25
 
26
+ setState(newState) {
27
+ this.state = { ...this.state, ...newState };
28
+ if (newState.items) {
29
+ const customEvent = new CustomEvent('pb-draggable-reorder', {
30
+ detail: {
31
+ reorderedItems: this.state.items,
32
+ containerId: this.element.querySelector(DRAGGABLE_CONTAINER).id
33
+ }
34
+ });
35
+ this.element.dispatchEvent(customEvent);
36
+ }
37
+ }
38
+
17
39
  bindEventListeners() {
40
+ // Check for multiple containers
41
+ const containers = this.element.querySelectorAll(DRAGGABLE_CONTAINER);
42
+ this.hasMultipleContainers = containers.length > 1;
43
+
18
44
  // Needed to prevent images within draggable items from being independently draggable
19
45
  // Needed if using Image kit in draggable items
20
46
  this.element.querySelectorAll(".pb_draggable_item img").forEach(img => {
@@ -27,11 +53,10 @@ export default class PbDraggable extends PbEnhancedElement {
27
53
  item.addEventListener("dragenter", this.handleDragEnter.bind(this));
28
54
  });
29
55
 
30
- const container = this.element.querySelector(DRAGGABLE_CONTAINER);
31
- if (container) {
56
+ containers.forEach(container => {
32
57
  container.addEventListener("dragover", this.handleDragOver.bind(this));
33
58
  container.addEventListener("drop", this.handleDrop.bind(this));
34
- }
59
+ });
35
60
  }
36
61
 
37
62
  handleDragStart(event) {
@@ -41,11 +66,17 @@ export default class PbDraggable extends PbEnhancedElement {
41
66
  event.preventDefault();
42
67
  return;
43
68
  }
44
-
69
+
70
+ const container = event.target.closest(DRAGGABLE_CONTAINER);
45
71
  this.draggedItem = event.target;
46
72
  this.draggedItemId = event.target.id;
47
- event.target.classList.add("is_dragging");
48
73
 
74
+ this.setState({
75
+ dragData: { id: this.draggedItemId, initialGroup: container.id },
76
+ isDragging: this.draggedItemId
77
+ });
78
+
79
+ event.target.classList.add("is_dragging");
49
80
  if (event.dataTransfer) {
50
81
  event.dataTransfer.effectAllowed = 'move';
51
82
  event.dataTransfer.setData('text/plain', this.draggedItemId);
@@ -59,11 +90,20 @@ export default class PbDraggable extends PbEnhancedElement {
59
90
  handleDragEnter(event) {
60
91
  if (!this.draggedItem || event.target === this.draggedItem) return;
61
92
 
93
+ if (this.hasMultipleContainers) {
94
+ this.handleMultiContainerDragEnter(event);
95
+ } else {
96
+ this.handleSingleContainerDragEnter(event);
97
+ }
98
+ }
99
+
100
+ handleSingleContainerDragEnter(event) {
62
101
  const targetItem = event.target.closest('.pb_draggable_item');
63
102
  if (!targetItem) return;
64
103
 
65
104
  const container = targetItem.parentNode;
66
105
  const items = Array.from(container.children);
106
+
67
107
  const draggedIndex = items.indexOf(this.draggedItem);
68
108
  const targetIndex = items.indexOf(targetItem);
69
109
 
@@ -74,47 +114,143 @@ export default class PbDraggable extends PbEnhancedElement {
74
114
  }
75
115
  }
76
116
 
117
+ handleMultiContainerDragEnter(event) {
118
+ const targetContainer = event.target.closest(DRAGGABLE_CONTAINER);
119
+ const targetItem = event.target.closest('.pb_draggable_item');
120
+
121
+ if (!targetContainer) return;
122
+
123
+ // If we're entering a container directly or there's no target item
124
+ 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
+ }
131
+ return;
132
+ }
133
+
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 });
143
+
144
+ const rect = targetItem.getBoundingClientRect();
145
+ const middleY = rect.top + rect.height / 2;
146
+
147
+ if (event.clientY < middleY) {
148
+ container.insertBefore(this.draggedItem, targetItem);
149
+ } else {
150
+ container.insertBefore(this.draggedItem, targetItem.nextSibling);
151
+ }
152
+ }
153
+
77
154
  handleDragOver(event) {
78
155
  event.preventDefault();
156
+ event.stopPropagation();
157
+
158
+ if (this.hasMultipleContainers) {
159
+ this.handleMultiContainerDragOver(event);
160
+ } else {
161
+ this.handleSingleContainerDragOver(event);
162
+ }
163
+ }
164
+
165
+ handleSingleContainerDragOver(event) {
79
166
  const container = event.target.closest(DRAGGABLE_CONTAINER);
167
+ if (container) {
168
+ container.classList.add("active_container");
169
+ }
170
+ }
171
+
172
+ 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
+ }
80
179
 
81
180
  if (container) {
181
+ this.setState({ activeContainer: container.id });
82
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
+ }
83
191
  }
84
192
  }
85
193
 
86
194
  handleDrop(event) {
87
195
  event.preventDefault();
88
- const container = event.target.closest(DRAGGABLE_CONTAINER);
196
+ event.stopPropagation();
197
+
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
+
89
205
  if (!container || !this.draggedItem) return;
90
-
206
+
91
207
  container.classList.remove("active_container");
92
208
  this.draggedItem.style.opacity = '1';
93
-
209
+
210
+ // Handle empty containers
211
+ if (this.hasMultipleContainers && !container.querySelector('.pb_draggable_item')) {
212
+ container.appendChild(this.draggedItem);
213
+ }
214
+
94
215
  // Updated order of items as an array of item IDs
95
- const reorderedItems = Array.from(container.children)
96
- .filter(item => item.classList.contains("pb_draggable_item"))
97
- .map(item => item.id.replace("item_", ""));
98
-
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
+
99
223
  // Store reordered items in a data attribute on the container
100
224
  container.setAttribute("data-reordered-items", JSON.stringify(reorderedItems));
101
-
225
+
102
226
  const customEvent = new CustomEvent('pb-draggable-reorder', {
103
227
  detail: {
104
228
  reorderedItems,
105
229
  containerId: container.id,
106
230
  }
107
231
  });
232
+
108
233
  this.element.dispatchEvent(customEvent);
109
-
234
+
235
+ this.setState({
236
+ items: reorderedItems,
237
+ isDragging: "",
238
+ activeContainer: ""
239
+ });
240
+
110
241
  this.draggedItem = null;
111
242
  this.draggedItemId = null;
112
243
  }
113
-
114
244
 
115
245
  handleDragEnd(event) {
116
246
  event.target.classList.remove("is_dragging");
117
247
  event.target.style.opacity = '1';
248
+
249
+ this.setState({
250
+ isDragging: "",
251
+ activeContainer: ""
252
+ });
253
+
118
254
  this.draggedItem = null;
119
255
  this.draggedItemId = null;
120
256
 
@@ -17,10 +17,11 @@ type DraggableContainerProps = {
17
17
  data?: { [key: string]: string };
18
18
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
19
19
  id?: string;
20
+ tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div' | 'tr' | 'th' | 'td' | 'thead' | 'col' | 'tbody',
20
21
  };
21
22
 
22
23
  const DraggableContainer = (props: DraggableContainerProps) => {
23
- const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id } = props;
24
+ const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id, tag="div" } = props;
24
25
 
25
26
  const { handleDragOver, handleDrop, activeContainer } = DraggableContext();
26
27
 
@@ -28,6 +29,8 @@ const DraggableContainer = (props: DraggableContainerProps) => {
28
29
  const dataProps = buildDataProps(data);
29
30
  const htmlProps = buildHtmlProps(htmlOptions);
30
31
 
32
+ const Tag: React.ReactElement | any = `${tag}`;
33
+
31
34
  const classes = classnames(
32
35
  buildCss("pb_draggable_container"),
33
36
  `${activeContainer === container ? "active" : ""}`,
@@ -36,18 +39,18 @@ const DraggableContainer = (props: DraggableContainerProps) => {
36
39
  );
37
40
 
38
41
  return (
39
- <div
42
+ <Tag
40
43
  {...ariaProps}
41
44
  {...dataProps}
42
45
  {...htmlProps}
43
46
  className={classes}
44
47
  id={id}
45
48
  key={container}
46
- onDragOver={(e) => handleDragOver(e, container)}
49
+ onDragOver={(e: Event) => handleDragOver(e, container)}
47
50
  onDrop={() => handleDrop(container)}
48
51
  >
49
52
  {children}
50
- </div>
53
+ </Tag>
51
54
  );
52
55
  };
53
56
 
@@ -18,10 +18,11 @@ type DraggableItemProps = {
18
18
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
19
19
  id?: string;
20
20
  dragId?: string;
21
+ tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'div' | 'tr' | 'th' | 'td' | 'thead' | 'col' | 'tbody',
21
22
  };
22
23
 
23
24
  const DraggableItem = (props: DraggableItemProps) => {
24
- const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id, dragId } = props;
25
+ const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id, dragId, tag="div" } = props;
25
26
 
26
27
  const { isDragging, handleDragStart, handleDragEnter, handleDragEnd } =
27
28
  DraggableContext();
@@ -30,6 +31,8 @@ const DraggableItem = (props: DraggableItemProps) => {
30
31
  const dataProps = buildDataProps(data);
31
32
  const htmlProps = buildHtmlProps(htmlOptions);
32
33
 
34
+ const Tag: React.ReactElement | any = `${tag}`;
35
+
33
36
  const classes = classnames(
34
37
  buildCss("pb_draggable_item"),
35
38
  `${isDragging === dragId ? "is_dragging" : ""}`,
@@ -38,7 +41,7 @@ const DraggableItem = (props: DraggableItemProps) => {
38
41
  );
39
42
 
40
43
  return (
41
- <div
44
+ <Tag
42
45
  {...ariaProps}
43
46
  {...dataProps}
44
47
  {...htmlProps}
@@ -51,7 +54,7 @@ const DraggableItem = (props: DraggableItemProps) => {
51
54
  onDragStart={() => handleDragStart(dragId, container)}
52
55
  >
53
56
  {children}
54
- </div>
57
+ </Tag>
55
58
  );
56
59
  };
57
60
 
@@ -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(:div) do %>
7
2
  <%= pb_rails("form_group", props: {cursor: "pointer", full_width: object.full_width}) do %>
8
3
  <label
9
4
  for="upload-<%= object.id %>"
@@ -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(:div) 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") %>
@@ -0,0 +1,58 @@
1
+ <%= pb_rails("button", props: { text: "Show Auto Close Toast", variant: "secondary", data: { toast: "#toast-auto-close" } }) %>
2
+ <%= pb_rails("button", props: { text: "Show Closeable Auto Close Toast", variant: "secondary", data: { toast: "#toast-auto-close-closeable" } }) %>
3
+
4
+ <%= pb_rails("fixed_confirmation_toast", props: {
5
+ auto_close: 3000,
6
+ classname: "toast-to-hide",
7
+ id: "toast-auto-close",
8
+ text: "I will disappear in 3 seconds.",
9
+ status: "tip",
10
+ vertical: "top",
11
+ horizontal: "center"
12
+ }) %>
13
+
14
+ <%= pb_rails("fixed_confirmation_toast", props: {
15
+ auto_close: 10000,
16
+ closeable: true,
17
+ id: "toast-auto-close-closeable",
18
+ text: "I will disappear in 10 seconds.",
19
+ status: "tip",
20
+ vertical: "top",
21
+ horizontal: "center"
22
+ }) %>
23
+
24
+ <script>
25
+ document.addEventListener('DOMContentLoaded', () => {
26
+ // Initialize toast elements and buttons
27
+ const toasts = {
28
+ '#toast-auto-close': document.querySelector("#toast-auto-close"),
29
+ '#toast-auto-close-closeable': document.querySelector("#toast-auto-close-closeable")
30
+ }
31
+
32
+ const buttons = {
33
+ '#toast-auto-close': document.querySelector("button[data-toast='#toast-auto-close']"),
34
+ '#toast-auto-close-closeable': document.querySelector("button[data-toast='#toast-auto-close-closeable']")
35
+ }
36
+
37
+ // Store original toasts and remove them from DOM
38
+ const originalToasts = {}
39
+ Object.entries(toasts).forEach(([id, toast]) => {
40
+ if (toast) {
41
+ originalToasts[id] = toast.cloneNode(true)
42
+ toast.remove()
43
+ }
44
+ })
45
+
46
+ // Set up button click handlers
47
+ Object.keys(buttons).forEach((toastId) => {
48
+ const button = buttons[toastId]
49
+ if (button) {
50
+ button.onclick = () => {
51
+ const newToast = originalToasts[toastId].cloneNode(true)
52
+ newToast.style.display = "flex"
53
+ document.body.appendChild(newToast)
54
+ }
55
+ }
56
+ })
57
+ })
58
+ </script>
@@ -0,0 +1,3 @@
1
+ Auto close is used when you want the confirmation toast to close automatically after a certain time. `auto_close` property will be a delay number in ms.
2
+
3
+ The script tag in this code snippet is for demonstration purposes only. It clones the toasts in order to have it appear with a button click prompt and not upon initial page load. In a typical production environment the event triggering a fixed confirmation toast to appear would be handled by a controller or a separate javascript file.
@@ -5,6 +5,7 @@ examples:
5
5
  - fixed_confirmation_toast_multi_line: Multi Line
6
6
  - fixed_confirmation_toast_close: Click to Close
7
7
  - fixed_confirmation_toast_positions: Click to Show Positions
8
+ - fixed_confirmation_toast_auto_close: Click to Show Auto Close
8
9
  - fixed_confirmation_toast_children: Children
9
10
  - fixed_confirmation_toast_custom_icon: Custom Icon
10
11
 
@@ -2,16 +2,18 @@ import PbEnhancedElement from '../pb_enhanced_element'
2
2
 
3
3
  export default class PbFixedConfirmationToast extends PbEnhancedElement {
4
4
  static get selector() {
5
- return '.remove_toast'
5
+ return '[class*="pb_fixed_confirmation_toast_kit"]'
6
6
  }
7
7
 
8
8
  connect() {
9
9
  this.self = this.element
10
10
  this.autoCloseToast(this.self)
11
11
 
12
- this.self.addEventListener('click', () => {
13
- this.removeToast(this.self)
14
- })
12
+ if (this.self.classList.contains('remove_toast')) {
13
+ this.self.addEventListener('click', () => {
14
+ this.removeToast(this.self)
15
+ })
16
+ }
15
17
  }
16
18
 
17
19
  removeToast(elem) {
@@ -32,4 +34,4 @@ export default class PbFixedConfirmationToast extends PbEnhancedElement {
32
34
  }, autoCloseIntValue)
33
35
  }
34
36
  }
35
- }
37
+ }
@@ -1,8 +1,3 @@
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(:div) do %>
7
2
  <%= content.presence %>
8
3
  <% end %>
@@ -1,4 +1,4 @@
1
- <%= content_tag(:div, id: object.id, data: object.data, class: object.classname + object.size_class, tabindex: object.tabindex, **combined_html_options) do %>
1
+ <%= pb_content_tag(:div, class: object.classname + object.size_class, tabindex: object.tabindex) do %>
2
2
  <% if object.name.present? %>
3
3
  <%= pb_rails("avatar", props: { name: object.name, image_url: object.avatar_url, size: "xxs" }) %>
4
4
  <% if object.truncate %>
@@ -18,6 +18,7 @@ type HomeAddressStreetProps = {
18
18
  className?: string,
19
19
  data?: { [key: string]: string },
20
20
  dark?: boolean,
21
+ preserveCase?: boolean,
21
22
  emphasis: "street" | "city" | "none",
22
23
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
23
24
  homeId: string,
@@ -43,6 +44,7 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
43
44
  htmlOptions = {},
44
45
  homeId,
45
46
  homeUrl,
47
+ preserveCase = false,
46
48
  target,
47
49
  newWindow,
48
50
  houseStyle,
@@ -77,6 +79,8 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
77
79
  return null
78
80
  }
79
81
 
82
+ const formatStreetAdr = (address: string): string => preserveCase ? address : titleize(address)
83
+
80
84
  return (
81
85
  <div
82
86
  className={classes(className, dark)}
@@ -91,7 +95,7 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
91
95
  dark={dark}
92
96
  size={4}
93
97
  >
94
- {joinPresent([titleize(address), houseStyle], ' · ')}
98
+ {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
95
99
  </Title>
96
100
  <Title
97
101
  className="pb_home_address_street_address"
@@ -101,14 +105,14 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
101
105
  {titleize(addressCont)}
102
106
  </Title>
103
107
  <Body color="light">
104
- {`${titleize(city)}, ${state} ${zipcode}`}
108
+ {`${titleize(city)}, ${state.toUpperCase()} ${zipcode}`}
105
109
  </Body>
106
110
  </div>
107
111
  }
108
112
  {emphasis == 'city' &&
109
113
  <div>
110
114
  <Body color="light">
111
- {joinPresent([titleize(address), houseStyle], ' · ')}
115
+ {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
112
116
  </Body>
113
117
  <Body color="light">{titleize(addressCont)}</Body>
114
118
  <div>
@@ -118,7 +122,7 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
118
122
  size={4}
119
123
  tag="span"
120
124
  >
121
- {`${titleize(city)}, ${state}`}
125
+ {`${titleize(city)}, ${state.toUpperCase()}`}
122
126
  </Title>
123
127
  <Body
124
128
  color="light"
@@ -132,15 +136,15 @@ const HomeAddressStreet = (props: HomeAddressStreetProps): React.ReactElement =>
132
136
  {emphasis == 'none' &&
133
137
  <div>
134
138
  <Body dark={dark}>
135
- {joinPresent([titleize(address), houseStyle], ' · ')}
139
+ {joinPresent([formatStreetAdr(address), houseStyle], ' · ')}
136
140
  </Body>
137
- <Body dark={dark}>{titleize(addressCont)}</Body>
141
+ <Body dark={dark}>{formatStreetAdr(addressCont)}</Body>
138
142
  <div>
139
143
  <Body
140
144
  color="light"
141
145
  dark={dark}
142
146
  >
143
- {`${titleize(city)}, ${state} ${zipcode}`}
147
+ {`${titleize(city)}, ${state.toUpperCase()} ${zipcode}`}
144
148
  </Body>
145
149
  </div>
146
150
  </div>
@@ -0,0 +1,11 @@
1
+ <%= pb_rails("home_address_street", props: {
2
+ address: "70 pRoSpEcT ave",
3
+ address_cont: "Apt M18",
4
+ city: "West Chester",
5
+ home_id: 8250263,
6
+ home_url: "https://powerhrg.com/",
7
+ preserve_case: true,
8
+ state: "pa",
9
+ zipcode: "19382",
10
+ territory: "PHL",
11
+ }) %>
@@ -0,0 +1,22 @@
1
+ import React from 'react'
2
+
3
+ import HomeAddressStreet from '../_home_address_street'
4
+
5
+ const HomeAddressStreetFormatting = (props) => {
6
+ return (
7
+ <HomeAddressStreet
8
+ address="70 pRoSpEcT ave"
9
+ addressCont="Apt M18"
10
+ city="West Chester"
11
+ homeId="8250263"
12
+ homeUrl="https://powerhrg.com/"
13
+ preserveCase
14
+ state="pa"
15
+ territory="PHL"
16
+ zipcode="19382"
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ export default HomeAddressStreetFormatting
@@ -0,0 +1 @@
1
+ The `state` prop will always capitalize the state name, even if the data entered is in lowercase. For example, when `state="pa"` is passed, it will be rendered as "PA". When you pass `preserve_case: true`, the street address will be rendered exactly as entered, without automatic title capitalization.
@@ -0,0 +1 @@
1
+ The `state` prop will always capitalize the state name, even if the data entered is in lowercase. For example, when `state="pa"` is passed, it will be rendered as "PA". When you pass `preserveCase`, the street address will be rendered exactly as entered, without automatic title capitalization.
@@ -5,12 +5,14 @@ examples:
5
5
  - home_address_street_emphasis: Emphasis
6
6
  - home_address_street_modified: Modified
7
7
  - home_address_street_link: Link
8
+ - home_address_street_formatting: Formatting
8
9
 
9
10
  react:
10
11
  - home_address_street_default: Default
11
12
  - home_address_street_emphasis: Emphasis
12
13
  - home_address_street_modified: Modified
13
14
  - home_address_street_link: Link
15
+ - home_address_street_formatting: Formatting
14
16
 
15
17
  swift:
16
18
  - home_address_street_default_swift: Default
@@ -2,3 +2,4 @@ export { default as HomeAddressStreetDefault } from './_home_address_street_defa
2
2
  export { default as HomeAddressStreetEmphasis } from './_home_address_street_emphasis.jsx'
3
3
  export { default as HomeAddressStreetModified } from './_home_address_street_modified.jsx'
4
4
  export { default as HomeAddressStreetLink } from './_home_address_street_link.jsx'
5
+ export { default as HomeAddressStreetFormatting } from './_home_address_street_formatting.jsx'
@@ -18,6 +18,7 @@ module Playbook
18
18
  prop :state
19
19
  prop :zipcode
20
20
  prop :territory
21
+ prop :preserve_case, default: false
21
22
  prop :dark, type: Playbook::Props::Boolean, default: false
22
23
 
23
24
  def classname
@@ -29,7 +30,7 @@ module Playbook
29
30
  end
30
31
 
31
32
  def city_state
32
- [city&.titleize, state].join(", ")
33
+ [city&.titleize, state&.upcase].join(", ")
33
34
  end
34
35
 
35
36
  def zip
@@ -37,7 +38,7 @@ module Playbook
37
38
  end
38
39
 
39
40
  def address_house_style
40
- [address&.titleize, house_style].join(separator)
41
+ [format_street_address, house_style].join(separator)
41
42
  end
42
43
 
43
44
  def address_house_style2
@@ -48,6 +49,16 @@ module Playbook
48
49
  house_style ? " \u00b7 " : ""
49
50
  end
50
51
 
52
+ def format_street_address
53
+ preserve_case ? address : custom_titleize(address)
54
+ end
55
+
56
+ def custom_titleize(str)
57
+ return "" if str.nil?
58
+
59
+ str.split(" ").map(&:capitalize).join(" ")
60
+ end
61
+
51
62
  def city_emphasis_props
52
63
  {
53
64
  address_house_style: address_house_style,
@@ -5,12 +5,8 @@
5
5
  <%= object.icon.html_safe %>
6
6
  </span>
7
7
  <% else %>
8
- <%= content_tag(:i, nil,
9
- id: object.id,
10
- data: object.data,
11
- class: object.classname,
12
- **combined_html_options
13
- ) %>
8
+ <%= pb_content_tag(:i) do %>
9
+ <% end %>
14
10
  <%= content_tag(:span, nil,
15
11
  aria: { label: "#{object.icon} icon" }.merge(object.aria),
16
12
  hidden: true