playbook_ui 14.18.1.pre.rc.0 → 14.19.0.pre.alpha.PLAY21297675

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 (143) 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/Components/RegularTableView.tsx +11 -1
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +148 -15
  5. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +20 -3
  6. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +23 -13
  7. data/app/pb_kits/playbook/pb_advanced_table/Utilities/VisibilityTree.ts +47 -0
  8. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +313 -21
  9. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +12 -3
  10. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +6 -1
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +0 -6
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color.jsx +80 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color.md +3 -0
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.html.erb +58 -0
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.md +3 -0
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.jsx +57 -0
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.md +4 -0
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.jsx +62 -0
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.md +1 -0
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.jsx +82 -0
  21. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.md +1 -0
  22. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.jsx +65 -0
  23. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.md +1 -0
  24. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_no_subrows_rails.md +5 -1
  25. 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
  26. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.md +3 -2
  27. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +10 -5
  28. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +7 -2
  29. data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +106 -0
  30. data/app/pb_kits/playbook/pb_advanced_table/index.js +228 -11
  31. data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +1 -0
  32. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +9 -1
  33. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +0 -3
  34. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +1 -2
  35. data/app/pb_kits/playbook/pb_avatar/_avatar.scss +4 -0
  36. data/app/pb_kits/playbook/pb_avatar/_avatar.tsx +3 -0
  37. data/app/pb_kits/playbook/pb_avatar/avatar.html.erb +3 -3
  38. data/app/pb_kits/playbook/pb_avatar/avatar.rb +2 -0
  39. data/app/pb_kits/playbook/pb_avatar/avatar.test.js +18 -0
  40. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_grayscale.html.erb +5 -0
  41. data/app/pb_kits/playbook/pb_avatar/docs/_avatar_grayscale.jsx +16 -0
  42. data/app/pb_kits/playbook/pb_avatar/docs/example.yml +2 -0
  43. data/app/pb_kits/playbook/pb_avatar/docs/index.js +1 -0
  44. data/app/pb_kits/playbook/pb_card/card.html.erb +1 -1
  45. data/app/pb_kits/playbook/pb_card/card.rb +12 -0
  46. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_error.html.erb +2 -2
  47. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones.html.erb +22 -1
  48. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line.html.erb +55 -0
  49. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_line_rails.md +5 -0
  50. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_drop_zones_rails.md +5 -0
  51. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_event_listeners.jsx +59 -0
  52. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_event_listeners_react.md +1 -0
  53. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +2 -0
  54. data/app/pb_kits/playbook/pb_draggable/docs/index.js +2 -1
  55. data/app/pb_kits/playbook/pb_draggable/draggable_container.rb +11 -1
  56. data/app/pb_kits/playbook/pb_draggable/draggable_item.rb +11 -1
  57. data/app/pb_kits/playbook/pb_draggable/index.js +4 -2
  58. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +33 -5
  59. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +5 -0
  60. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +5 -16
  61. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +5 -2
  62. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.html.erb +28 -0
  63. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +17 -64
  64. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.html.erb +58 -0
  65. data/app/pb_kits/playbook/pb_dropdown/docs/{_dropdown_with_autocomplete_and_custom_display.jsx → _dropdown_with_autocomplete_with_subcomponents.jsx} +11 -25
  66. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.md +1 -0
  67. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.md +1 -0
  68. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.jsx +61 -0
  69. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.md +2 -0
  70. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.html.erb +52 -0
  71. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.md +2 -0
  72. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +7 -4
  73. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -2
  74. data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +2 -2
  75. data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +4 -0
  76. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +45 -1
  77. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.html.erb +10 -0
  78. data/app/pb_kits/playbook/pb_dropdown/dropdown_container.rb +3 -0
  79. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +12 -2
  80. data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +3 -1
  81. data/app/pb_kits/playbook/pb_dropdown/index.js +57 -0
  82. data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +26 -0
  83. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +3 -4
  84. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +4 -4
  85. data/app/pb_kits/playbook/pb_empty_state/_empty_state.scss +8 -1
  86. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_alignment.html.erb +27 -0
  87. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_default.html.erb +7 -0
  88. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_orientation.html.erb +12 -0
  89. data/app/pb_kits/playbook/pb_empty_state/docs/_empty_state_size.html.erb +23 -0
  90. data/app/pb_kits/playbook/pb_empty_state/docs/example.yml +5 -1
  91. data/app/pb_kits/playbook/pb_empty_state/empty_state.html.erb +19 -0
  92. data/app/pb_kits/playbook/pb_empty_state/empty_state.rb +123 -0
  93. data/app/pb_kits/playbook/pb_message/_message.tsx +3 -0
  94. data/app/pb_kits/playbook/pb_message/docs/_message_grayscale.html.erb +9 -0
  95. data/app/pb_kits/playbook/pb_message/docs/_message_grayscale.jsx +21 -0
  96. data/app/pb_kits/playbook/pb_message/docs/example.yml +2 -0
  97. data/app/pb_kits/playbook/pb_message/docs/index.js +1 -0
  98. data/app/pb_kits/playbook/pb_message/message.html.erb +2 -1
  99. data/app/pb_kits/playbook/pb_message/message.rb +1 -0
  100. data/app/pb_kits/playbook/pb_overlay/_overlay.scss +2 -1
  101. data/app/pb_kits/playbook/pb_overlay/docs/_overlay_vertical_dynamic_multi_directional.jsx +1 -1
  102. data/app/pb_kits/playbook/pb_overlay/subcomponents/_overlay_token.tsx +5 -4
  103. data/app/pb_kits/playbook/pb_section_separator/_section_separator.tsx +2 -2
  104. data/app/pb_kits/playbook/pb_select/_select.scss +10 -0
  105. data/app/pb_kits/playbook/pb_select/docs/_select_error.html.erb +1 -1
  106. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.jsx +7 -7
  107. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +5 -5
  108. data/app/pb_kits/playbook/pb_text_input/docs/_text_input_error.html.erb +1 -1
  109. data/app/pb_kits/playbook/pb_textarea/docs/_textarea_error.html.erb +5 -1
  110. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_error_state.html.erb +8 -1
  111. data/app/pb_kits/playbook/pb_user/_user.tsx +3 -0
  112. data/app/pb_kits/playbook/pb_user/docs/_user_grayscale.html.erb +6 -0
  113. data/app/pb_kits/playbook/pb_user/docs/_user_grayscale.jsx +16 -0
  114. data/app/pb_kits/playbook/pb_user/docs/example.yml +2 -0
  115. data/app/pb_kits/playbook/pb_user/docs/index.js +1 -0
  116. data/app/pb_kits/playbook/pb_user/user.html.erb +2 -1
  117. data/app/pb_kits/playbook/pb_user/user.rb +1 -0
  118. data/dist/chunks/{_typeahead-D8CsVBZO.js → _typeahead-BPSIWtFT.js} +3 -3
  119. data/dist/chunks/_weekday_stacked-BeuPAmxG.js +45 -0
  120. data/dist/chunks/{lib-BmTAc7Nc.js → lib-B20MXZcW.js} +2 -2
  121. data/dist/chunks/{pb_form_validation-BWjy4bFn.js → pb_form_validation-WWvUXPKD.js} +1 -1
  122. data/dist/chunks/vendor.js +1 -1
  123. data/dist/menu.yml +6 -14
  124. data/dist/playbook-doc.js +2 -2
  125. data/dist/playbook-rails-react-bindings.js +1 -1
  126. data/dist/playbook-rails.js +1 -1
  127. data/dist/playbook.css +1 -1
  128. data/lib/playbook/version.rb +2 -2
  129. metadata +52 -21
  130. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_and_custom_display.md +0 -1
  131. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_hook.jsx +0 -79
  132. data/app/pb_kits/playbook/pb_gantt_chart/_gantt_chart.scss +0 -3
  133. data/app/pb_kits/playbook/pb_gantt_chart/_gantt_chart.tsx +0 -72
  134. data/app/pb_kits/playbook/pb_gantt_chart/docs/_gantt_chart_default.jsx +0 -53
  135. data/app/pb_kits/playbook/pb_gantt_chart/docs/example.yml +0 -7
  136. data/app/pb_kits/playbook/pb_gantt_chart/docs/index.js +0 -1
  137. data/app/pb_kits/playbook/pb_gantt_chart/gantt_chart.test.jsx +0 -19
  138. data/dist/chunks/_weekday_stacked-CHQsoCdP.js +0 -45
  139. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows_react.md → _advanced_table_selectable_rows.md} +0 -0
  140. /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
  141. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_selectable_rows.html.erb → _advanced_table_selectable_rows_rails.html.erb} +0 -0
  142. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_drop_zones_line.md → _draggable_drop_zones_line_react.md} +0 -0
  143. /data/app/pb_kits/playbook/pb_draggable/docs/{_draggable_event_listeners.md → _draggable_event_listeners_rails.md} +0 -0
@@ -9,12 +9,182 @@ export default class PbAdvancedTable extends PbEnhancedElement {
9
9
  return ADVANCED_TABLE_SELECTOR;
10
10
  }
11
11
 
12
+ updateTableSelectedRowsAttribute() {
13
+ const mainTable = this.element.closest(".pb_advanced_table");
14
+ mainTable.dataset.selectedRows = JSON.stringify(Array.from(PbAdvancedTable.selectedRows));
15
+ }
16
+
17
+ // Check if the row is expanded or collapsed
18
+ // This is used to determine the background color of the row
19
+ // when the checkbox is checked or unchecked
20
+ isRowExpanded(rowEl) {
21
+ const closeIcon = rowEl.querySelector(UP_ARROW_SELECTOR);
22
+ return closeIcon?.style.display === "none" || !closeIcon;
23
+ }
24
+
25
+ updateParentCheckboxes(checkbox) {
26
+ const rowEl = checkbox.closest("tr");
27
+ if (!rowEl) return;
28
+
29
+ const table = rowEl.closest("table");
30
+ if (!table) return;
31
+
32
+ const contentTrail = rowEl.dataset.advancedTableContent;
33
+ if (!contentTrail) return;
34
+
35
+ const ancestorIds = contentTrail.split("-").slice(0, -1);
36
+
37
+ ancestorIds.reverse();
38
+ ancestorIds.forEach((ancestorId) => {
39
+ const parentRowSelector = `[data-advanced-table-content$="${ancestorId}"]`;
40
+ const parentRow = table.querySelector(parentRowSelector);
41
+ if (!parentRow) return;
42
+
43
+ const parentLabel = parentRow.querySelector("label[data-row-id]");
44
+ if (!parentLabel) return;
45
+
46
+ const parentCheckbox = parentLabel.querySelector(
47
+ "input[type='checkbox']"
48
+ );
49
+ if (!parentCheckbox) return;
50
+
51
+ // Find all immediate children of parent linked to ancestor Id, filter our subrow headers
52
+ const children = Array.from(
53
+ table.querySelectorAll(`tr[data-row-parent$="_${ancestorId}"]`)
54
+ ).filter((child) => {
55
+ const content = child.dataset.advancedTableContent;
56
+ return !(content && content.endsWith("sr"));
57
+ });
58
+
59
+ const allChildrenChecked = Array.from(children).every((child) => {
60
+ const childLabel = child.querySelector("label[data-row-id]");
61
+ if (!childLabel) return false;
62
+ const childCheckbox = childLabel.querySelector(
63
+ "input[type='checkbox']"
64
+ );
65
+ if (!childCheckbox) return false;
66
+ return childCheckbox.checked;
67
+ });
68
+
69
+ // Update parent checkbox
70
+ parentCheckbox.checked = allChildrenChecked;
71
+
72
+ const parentCheckboxId = parentCheckbox.id;
73
+ if (allChildrenChecked) {
74
+ PbAdvancedTable.selectedRows.add(parentCheckboxId);
75
+ parentRow.classList.add("bg-row-selection");
76
+ parentRow.classList.remove("bg-white", "bg-silver");
77
+ } else {
78
+ PbAdvancedTable.selectedRows.delete(parentCheckboxId);
79
+ }
80
+ if (!allChildrenChecked) {
81
+ parentRow.classList.remove("bg-row-selection");
82
+
83
+ if (this.isRowExpanded(parentRow)) {
84
+ parentRow.classList.remove("bg-silver");
85
+ parentRow.classList.add("bg-white");
86
+ } else {
87
+ parentRow.classList.remove("bg-white");
88
+ parentRow.classList.add("bg-silver");
89
+ }
90
+ }
91
+ });
92
+ }
93
+
94
+ handleCheckboxClick(event) {
95
+ const checkbox = event.currentTarget;
96
+ const rowId = checkbox.id;
97
+ const isChecked = checkbox.checked;
98
+ const rowEl = checkbox.closest("tr");
99
+
100
+ if (isChecked) {
101
+ PbAdvancedTable.selectedRows.add(rowId);
102
+ rowEl.classList.add("bg-row-selection");
103
+ rowEl.classList.remove("bg-white", "bg-silver");
104
+ } else {
105
+ PbAdvancedTable.selectedRows.delete(rowId);
106
+ }
107
+ // Update background color on row
108
+ if (!isChecked) {
109
+ rowEl.classList.remove("bg-row-selection");
110
+
111
+ if (this.isRowExpanded(rowEl)) {
112
+ rowEl.classList.remove("bg-silver");
113
+ rowEl.classList.add("bg-white");
114
+ } else {
115
+ rowEl.classList.remove("bg-white");
116
+ rowEl.classList.add("bg-silver");
117
+ }
118
+ }
119
+ if (rowEl) {
120
+ const table = rowEl.closest("table");
121
+ const rowContent = rowEl.dataset.advancedTableContent;
122
+
123
+ if (rowContent) {
124
+ const childRows = table.querySelectorAll(
125
+ `[data-advanced-table-content^="${rowContent}-"]`
126
+ );
127
+
128
+ childRows.forEach((childRow) => {
129
+ const label = childRow.querySelector("label[data-row-id]");
130
+ if (!label) return;
131
+
132
+ const childCheckbox = label.querySelector("input[type='checkbox']");
133
+ if (!childCheckbox) return;
134
+
135
+ childCheckbox.checked = isChecked;
136
+
137
+ const childRowId = childCheckbox.id;
138
+ const childRowEl = childCheckbox.closest("tr");
139
+ if (isChecked) {
140
+ PbAdvancedTable.selectedRows.add(childRowId);
141
+ childRowEl?.classList.add("bg-row-selection");
142
+ childRowEl?.classList.remove("bg-white", "bg-silver");
143
+ } else {
144
+ PbAdvancedTable.selectedRows.delete(childRowId);
145
+ }
146
+ if (!isChecked) {
147
+ childRowEl?.classList.remove("bg-row-selection");
148
+
149
+ if (this.isRowExpanded(childRowEl)) {
150
+ childRowEl?.classList.remove("bg-silver");
151
+ childRowEl?.classList.add("bg-white");
152
+ } else {
153
+ childRowEl?.classList.remove("bg-white");
154
+ childRowEl?.classList.add("bg-silver");
155
+ }
156
+ }
157
+ });
158
+ }
159
+ }
160
+
161
+ this.updateParentCheckboxes(checkbox);
162
+
163
+ this.updateTableSelectedRowsAttribute();
164
+
165
+ const table = checkbox.closest("table");
166
+ const selectAllCheckbox = table.querySelector("#select-all-rows");
167
+
168
+ if (selectAllCheckbox) {
169
+ const allCheckboxes = table.querySelectorAll(
170
+ "label[data-row-id] input[type='checkbox']"
171
+ );
172
+ const allChecked = Array.from(allCheckboxes).every((cb) => cb.checked);
173
+
174
+ const selectAllInput = selectAllCheckbox.querySelector(
175
+ 'input[type="checkbox"]'
176
+ );
177
+ selectAllInput.checked = allChecked;
178
+ }
179
+ }
180
+
12
181
  get target() {
13
182
  const table = this.element.closest("table");
14
183
  return table.querySelectorAll(`[data-row-parent="${this.element.id}"]`);
15
184
  }
16
185
 
17
186
  static expandedRows = new Set();
187
+ static selectedRows = new Set();
18
188
  static isCollapsing = false;
19
189
 
20
190
  connect() {
@@ -31,17 +201,31 @@ export default class PbAdvancedTable extends PbEnhancedElement {
31
201
  this.toggleElement(this.target);
32
202
  }
33
203
  });
34
-
35
- this.hideCloseIcon()
36
-
37
- const nestedButtons = this.element
38
- .closest("table")
39
- .querySelectorAll("[data-advanced-table]");
204
+
205
+ this.hideCloseIcon();
206
+
207
+ const table = this.element.closest("table");
208
+
209
+ // Prevent duplicate initialization
210
+ if (table.dataset.pbAdvancedTableInitialized) return;
211
+ table.dataset.pbAdvancedTableInitialized = "true";
212
+
213
+ // Bind checkbox change handlers for all row checkboxes
214
+ const checkboxLabels = table.querySelectorAll("label[data-row-id]");
215
+ checkboxLabels.forEach((label) => {
216
+ const checkbox = label.querySelector("input[type='checkbox']");
217
+ if (!checkbox) return;
218
+ checkbox.addEventListener("change", (event) => {
219
+ this.handleCheckboxClick(event);
220
+ });
221
+ });
222
+
223
+ // Bind nested row expansion logic
224
+ const nestedButtons = table.querySelectorAll("[data-advanced-table]");
40
225
  nestedButtons.forEach((button) => {
41
226
  button.addEventListener("click", () => {
42
227
  const isExpanded =
43
- button.querySelector(UP_ARROW_SELECTOR).style.display ===
44
- "inline-block";
228
+ button.querySelector(UP_ARROW_SELECTOR).style.display === "inline-block";
45
229
  if (isExpanded) {
46
230
  PbAdvancedTable.expandedRows.add(button.id);
47
231
  } else {
@@ -49,12 +233,46 @@ export default class PbAdvancedTable extends PbEnhancedElement {
49
233
  }
50
234
  });
51
235
  });
236
+
237
+ // Bind select-all logic for this table
238
+ const selectAllCheckbox = table.querySelector("#select-all-rows");
239
+ if (selectAllCheckbox) {
240
+ selectAllCheckbox.addEventListener("change", () => {
241
+ const checkboxInput = selectAllCheckbox.querySelector('input[type="checkbox"]');
242
+ const checkAll = checkboxInput.checked;
243
+
244
+ const checkboxes = Array.from(
245
+ table.querySelectorAll("label[data-row-id] input[type='checkbox']")
246
+ );
247
+
248
+ checkboxes.forEach((cb) => {
249
+ cb.checked = checkAll;
250
+ const rowId = cb.id;
251
+ const rowEl = cb.closest("tr");
252
+
253
+ if (checkAll) {
254
+ PbAdvancedTable.selectedRows.add(rowId);
255
+ rowEl?.classList.add("bg-row-selection");
256
+ rowEl?.classList.remove("bg-white", "bg-silver");
257
+ } else {
258
+ PbAdvancedTable.selectedRows.delete(rowId);
259
+ rowEl?.classList.remove("bg-row-selection");
260
+ rowEl?.classList.add("bg-white");
261
+ }
262
+ });
263
+
264
+ checkboxes.forEach((cb) => this.updateParentCheckboxes(cb));
265
+
266
+ this.updateTableSelectedRowsAttribute();
267
+ });
268
+ }
52
269
  }
270
+
53
271
 
54
272
  hideCloseIcon() {
55
273
  const closeIcon = this.element.querySelector(UP_ARROW_SELECTOR);
56
274
  closeIcon.style.display = "none";
57
- }
275
+ }
58
276
 
59
277
  showElement(elements) {
60
278
  elements.forEach((elem) => {
@@ -151,7 +369,6 @@ export default class PbAdvancedTable extends PbEnhancedElement {
151
369
  }
152
370
  }
153
371
 
154
-
155
372
  displayDownArrow() {
156
373
  this.element.querySelector(DOWN_ARROW_SELECTOR).style.display =
157
374
  "inline-block";
@@ -238,4 +455,4 @@ window.expandAllRows = (element) => {
238
455
 
239
456
  window.expandAllSubRows = (element, rowDepth) => {
240
457
  PbAdvancedTable.handleToggleAllSubRows(element, rowDepth);
241
- };
458
+ };
@@ -77,6 +77,7 @@
77
77
  top: 0;
78
78
  left: 0;
79
79
  border-radius: unset;
80
+ z-index: 5;
80
81
  }
81
82
 
82
83
  .checkbox-cell {
@@ -55,7 +55,15 @@ module Playbook
55
55
  # Subrow header if applicable
56
56
  output << pb_rails("advanced_table/table_subrow_header", props: { row: row, column_definitions: leaf_columns, depth: current_depth, subrow_header: subrow_headers[current_depth - 1], collapsible_trail: collapsible_trail, classname: "toggle-content", responsive: responsive, subrow_data_attributes: subrow_data_attributes }) if is_first_child_of_subrow && enable_toggle_expansion == "all"
57
57
 
58
- current_data_attributes = current_depth.zero? ? { row_depth: 0 } : table_data_attributes
58
+ current_data_attributes = if current_depth.zero?
59
+ {
60
+ row_depth: 0,
61
+ advanced_table_content: row.object_id.to_s,
62
+ row_parent: nil,
63
+ }
64
+ else
65
+ table_data_attributes
66
+ end
59
67
 
60
68
  # Additional class and data attributes needed for toggle logic
61
69
  output << pb_rails("advanced_table/table_row", props: { id: id, row: row, column_definitions: leaf_columns, depth: current_depth, collapsible_trail: collapsible_trail, classname: additional_classes, table_data_attributes: current_data_attributes, responsive: responsive, loading: loading, selectable_rows: selectable_rows, row_id: row[:id], enable_toggle_expansion: enable_toggle_expansion })
@@ -54,9 +54,6 @@ module Playbook
54
54
  pb_rails("checkbox", props: {
55
55
  id: "select-all-rows",
56
56
  name: "select-all-rows",
57
- data: {
58
- action: "click->pb-advanced-table#toggleAllRowSelection",
59
- },
60
57
  })
61
58
  end
62
59
  end
@@ -60,7 +60,7 @@ module Playbook
60
60
  name: "select-row-#{row_id || row.object_id}",
61
61
  data: {
62
62
  row_id: row_id || row.object_id.to_s,
63
- action: "click->pb-advanced-table#toggleRowSelection",
63
+ flat_advanced_table_select: true,
64
64
  },
65
65
  })
66
66
  end
@@ -75,7 +75,6 @@ module Playbook
75
75
  name: "select-row-#{row_id || row.object_id}",
76
76
  data: {
77
77
  row_id: row_id || row.object_id.to_s,
78
- action: "click->pb-advanced-table#toggleRowSelection",
79
78
  },
80
79
  })
81
80
  end
@@ -82,6 +82,10 @@ $avatar-sizes: (
82
82
  object-fit: cover;
83
83
  display: block;
84
84
  }
85
+
86
+ .grayscale {
87
+ filter: grayscale(1);
88
+ }
85
89
  }
86
90
  }
87
91
  }
@@ -25,6 +25,7 @@ export type AvatarProps = {
25
25
  },
26
26
  dark?: boolean,
27
27
  data?: {[key: string]: string},
28
+ grayscale?: boolean,
28
29
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
29
30
  id?: string,
30
31
  imageAlt?: string,
@@ -47,6 +48,7 @@ const Avatar = (props: AvatarProps): React.ReactElement => {
47
48
  htmlOptions = {},
48
49
  name = undefined,
49
50
  componentOverlay,
51
+ grayscale = false,
50
52
  id = '',
51
53
  imageAlt = '',
52
54
  imageUrl,
@@ -155,6 +157,7 @@ const Avatar = (props: AvatarProps): React.ReactElement => {
155
157
  {canShowImage && (
156
158
  <Image
157
159
  alt={imageAlt ? imageAlt : name}
160
+ className={grayscale ? "grayscale" : ""}
158
161
  onError={handleError}
159
162
  url={imageUrl}
160
163
  />
@@ -3,7 +3,7 @@
3
3
  <% if object.component_overlay && object.component_overlay[:component] == "icon_circle" %>
4
4
  <%= pb_rails("flex", props: { display: "display_inline_block", position: "relative" }) do %>
5
5
  <%= content_tag(:div, data: { initials: object.initials }, class: "avatar_wrapper") do %>
6
- <%= pb_rails("image", props: { alt: object.alt_text, url: object.image_url, on_error: object.handle_img_error }) if object.image_url.present? %>
6
+ <%= pb_rails("image", props: { alt: object.alt_text, url: object.image_url, on_error: object.handle_img_error, classname: object.grayscale ? "grayscale" : "" }) if object.image_url.present? %>
7
7
  <% end %>
8
8
  <%= pb_rails("card", props: { border_none: true, border_radius: "rounded", dark: object.dark, position: "absolute" }.merge(specific_placement_style)) do %>
9
9
 
@@ -13,7 +13,7 @@
13
13
  <% elsif object.component_overlay && object.component_overlay[:component] == "badge" %>
14
14
  <%= pb_rails("flex", props: { display: "display_inline_block", position: "relative" }) do %>
15
15
  <%= content_tag(:div, data: { initials: object.initials }, class: "avatar_wrapper") do %>
16
- <%= pb_rails("image", props: { alt: object.alt_text, url: object.image_url, on_error: object.handle_img_error }) if object.image_url.present? %>
16
+ <%= pb_rails("image", props: { alt: object.alt_text, url: object.image_url, on_error: object.handle_img_error, classname: object.grayscale ? "grayscale" : "" }) if object.image_url.present? %>
17
17
  <% end %>
18
18
  <%= pb_rails("card", props: { border_none: true, border_radius: "rounded", dark: object.dark, padding: "none", position: "absolute" }.merge(specific_placement_style)) do %>
19
19
  <%= pb_rails("badge", props: { dark: object.dark, rounded: true, text: object.component_overlay[:text], variant: object.component_overlay[:variant] }) %>
@@ -21,7 +21,7 @@
21
21
  <% end %>
22
22
  <% else %>
23
23
  <%= content_tag(:div, data: { initials: object.initials }, class: "avatar_wrapper") do %>
24
- <%= pb_rails("image", props: { alt: object.alt_text, url: object.image_url, on_error: object.handle_img_error }) if object.image_url.present? %>
24
+ <%= pb_rails("image", props: { alt: object.alt_text, url: object.image_url, on_error: object.handle_img_error, classname: object.grayscale ? "grayscale" : "" }) if object.image_url.present? %>
25
25
  <% end %>
26
26
  <%= pb_rails("online_status", props: object.online_status_props) if object.status %>
27
27
  <% end %>
@@ -15,6 +15,8 @@ module Playbook
15
15
  values: %w[xxs xs sm md base lg xl],
16
16
  default: "md"
17
17
  prop :status
18
+ prop :grayscale, type: Playbook::Props::Boolean,
19
+ default: false
18
20
 
19
21
  def initials
20
22
  name.split.map(&:first).join.downcase
@@ -106,3 +106,21 @@ test('renders with online status', () => {
106
106
  const onlineStatus = onlineStatusAvatar.querySelector('.pb_online_status_kit_online_size_md')
107
107
  expect(onlineStatus).toBeInTheDocument();
108
108
  });
109
+
110
+ test('renders with grayscale filter', () => {
111
+ render(
112
+ <Avatar
113
+ data={{ testid: testId }}
114
+ grayscale
115
+ imageAlt={imageAlt}
116
+ imageUrl={imageUrl}
117
+ name={name}
118
+ />
119
+ );
120
+
121
+ const grayscaleAvatar = screen.getByTestId(testId);
122
+ expect(grayscaleAvatar).toBeInTheDocument();
123
+
124
+ const grayscaleImage = grayscaleAvatar.querySelector('.grayscale')
125
+ expect(grayscaleImage).toBeInTheDocument();
126
+ });
@@ -0,0 +1,5 @@
1
+ <%= pb_rails("avatar", props: {
2
+ name: "Terry Johnson",
3
+ image_url: "https://randomuser.me/api/portraits/men/44.jpg",
4
+ grayscale: true
5
+ }) %>
@@ -0,0 +1,16 @@
1
+ import React from 'react'
2
+ import Avatar from '../../pb_avatar/_avatar'
3
+
4
+ const AvatarGrayscale = (props) => {
5
+ return (
6
+ <Avatar
7
+ grayscale
8
+ imageAlt="Terry Johnson Standing"
9
+ imageUrl="https://randomuser.me/api/portraits/men/44.jpg"
10
+ name="Terry Johnson"
11
+ {...props}
12
+ />
13
+ )
14
+ }
15
+
16
+ export default AvatarGrayscale
@@ -6,6 +6,7 @@ examples:
6
6
  - avatar_status: Status
7
7
  - avatar_circle_icon_component_overlay: Icon Circle Component Overlay
8
8
  - avatar_badge_component_overlay: Badge Component Overlay
9
+ - avatar_grayscale: Grayscale
9
10
  react:
10
11
  - avatar_default: Default
11
12
  - avatar_monogram: Monogram
@@ -13,6 +14,7 @@ examples:
13
14
  - avatar_status: Status
14
15
  - avatar_circle_icon_component_overlay: Icon Circle Component Overlay
15
16
  - avatar_badge_component_overlay: Badge Component Overlay
17
+ - avatar_grayscale: Grayscale
16
18
  swift:
17
19
  - avatar_default_swift: Default
18
20
  - avatar_monogram_swift: Monogram
@@ -4,3 +4,4 @@ export { default as AvatarStatus } from './_avatar_status.jsx'
4
4
  export { default as AvatarNoImage } from './_avatar_no_image.jsx'
5
5
  export { default as AvatarCircleIconComponentOverlay } from './_avatar_circle_icon_component_overlay.jsx'
6
6
  export { default as AvatarBadgeComponentOverlay } from './_avatar_badge_component_overlay.jsx'
7
+ export { default as AvatarGrayscale } from './_avatar_grayscale.jsx'
@@ -1,5 +1,5 @@
1
1
  <% if object.draggable_item %>
2
- <%= pb_rails("draggable/draggable_item", props:{drag_id: object.drag_id}) do %>
2
+ <%= pb_rails("draggable/draggable_item", props:{drag_id: object.drag_id, classname: drop_zone_line_color ? line_color_class : nil}) do %>
3
3
  <%= pb_content_tag(object.tag) do %>
4
4
  <% if object.draggable_item %>
5
5
  <%= pb_rails("flex", props: { align: "center" }) do %>
@@ -24,6 +24,9 @@ module Playbook
24
24
  default: true
25
25
  prop :items, type: Playbook::Props::Array,
26
26
  default: []
27
+ prop :drop_zone_line_color, type: Playbook::Props::Enum,
28
+ values: ["primary", "purple", nil],
29
+ default: nil
27
30
 
28
31
  def classname
29
32
  generate_classname("pb_card_kit",
@@ -60,6 +63,15 @@ module Playbook
60
63
  def border_radius_class
61
64
  border_radius != "md" ? "border_radius_#{border_radius}" : nil
62
65
  end
66
+
67
+ def line_color_class
68
+ case drop_zone_line_color
69
+ when "primary"
70
+ "drop_zone_color_primary"
71
+ when "purple"
72
+ "drop_zone_color_purple"
73
+ end
74
+ end
63
75
  end
64
76
  end
65
77
  end
@@ -1,4 +1,4 @@
1
- <%= pb_rails("date_picker", props: {
2
- error: "Invalid date. Please pick a valid date.",
1
+ <%= pb_rails("date_picker", props: {
2
+ error: raw(pb_rails("icon", props: { icon: "warning" }) + " Invalid date. Please pick a valid date."),
3
3
  picker_id: "date-picker-error"
4
4
  }) %>
@@ -10,7 +10,13 @@
10
10
  { id: "63", text: "Task 3" }
11
11
  ] %>
12
12
 
13
- <%= pb_rails("flex", props: { justify: "around" }) do %>
13
+ <% data_line = [
14
+ { id: "71", text: "Task 1" },
15
+ { id: "72", text: "Task 2" },
16
+ { id: "73", text: "Task 3" }
17
+ ] %>
18
+
19
+ <%= pb_rails("flex", props: { justify: "between" }) do %>
14
20
  <%= pb_rails("flex/flex_item", props: { margin_right: "xl" }) do %>
15
21
  <%= pb_rails("draggable", props: { drop_zone_type: "shadow", initial_items: data_shadow }) do %>
16
22
  <%= pb_rails("caption", props: { margin_bottom: "xs", text: "Shadow", text_align: "center" }) %>
@@ -40,4 +46,19 @@
40
46
  <% end %>
41
47
  <% end %>
42
48
  <% end %>
49
+
50
+ <%= pb_rails("flex/flex_item", props: { margin_right: "xl" }) do %>
51
+ <%= pb_rails("draggable", props: { drop_zone_type: "line", initial_items: data_line }) do %>
52
+ <%= pb_rails("caption", props: { margin_bottom: "xs", text: "Line", text_align: "center" }) %>
53
+ <%= pb_rails("draggable/draggable_container", props: { drop_zone_direction: "vertical", html_options: { style: { width: "200px" } } }) do %>
54
+ <% data_line.each do |item| %>
55
+ <%= pb_rails("card", props: { drag_id: item[:id], draggable_item: true, margin_bottom: "xs", padding: "xs", padding_right: "xl", drop_zone_line_color: "primary" }) do %>
56
+ <%= pb_rails("flex", props: { align_items: "stretch", flex_direction: "column" }) do %>
57
+ <%= pb_rails("body", props: { text: item[:text] }) %>
58
+ <% end %>
59
+ <% end %>
60
+ <% end %>
61
+ <% end %>
62
+ <% end %>
63
+ <% end %>
43
64
  <% end %>
@@ -0,0 +1,55 @@
1
+ <% initial_items = [
2
+ {
3
+ id: "211",
4
+ url: "https://unsplash.it/500/400/?image=633",
5
+ },
6
+ {
7
+ id: "212",
8
+ url: "https://unsplash.it/500/400/?image=634",
9
+ },
10
+ {
11
+ id: "213",
12
+ url: "https://unsplash.it/500/400/?image=637",
13
+ },
14
+ ] %>
15
+
16
+ <% next_init_items = [
17
+ {
18
+ id: "2111",
19
+ url: "https://unsplash.it/500/400/?image=633",
20
+ },
21
+ {
22
+ id: "2112",
23
+ url: "https://unsplash.it/500/400/?image=634",
24
+ },
25
+ {
26
+ id: "2113",
27
+ url: "https://unsplash.it/500/400/?image=637",
28
+ },
29
+ ] %>
30
+
31
+ <%= pb_rails("draggable", props: {initial_items: initial_items, drop_zone_type: "line"}) do %>
32
+ <%= pb_rails("draggable/draggable_container", props: { drop_zone_direction: "vertical" }) do %>
33
+ <%= pb_rails("flex", props: { gap: "sm", orientation: "column", height: "367px" }) do %>
34
+ <% initial_items.each do |item| %>
35
+ <%= pb_rails("draggable/draggable_item", props:{drag_id: item[:id], drop_zone_line_color: "purple"}) do %>
36
+ <%= pb_rails("image", props: { alt: item[:id], size: "md", url: item[:url] }) %>
37
+ <% end %>
38
+ <% end %>
39
+ <% end %>
40
+ <% end %>
41
+ <% end %>
42
+
43
+ <br/>
44
+
45
+ <%= pb_rails("draggable", props: {initial_items: next_init_items, drop_zone_type: "line"}) do %>
46
+ <%= pb_rails("draggable/draggable_container", props: { drop_zone_direction: "horizontal" }) do %>
47
+ <%= pb_rails("flex", props: { gap: "sm", html_options: { style: "width: 332px;" } }) do %>
48
+ <% initial_items.each do |item| %>
49
+ <%= pb_rails("draggable/draggable_item", props:{drag_id: item[:id], drop_zone_line_color: "primary"}) do %>
50
+ <%= pb_rails("image", props: { alt: item[:id], size: "md", url: item[:url] }) %>
51
+ <% end %>
52
+ <% end %>
53
+ <% end %>
54
+ <% end %>
55
+ <% end %>
@@ -0,0 +1,5 @@
1
+ When using the "line" style, make sure to set the appropriate `direction` attribute within the `drop_zone_direction` prop on the `draggable/draggable_container` component based on the orientation of your draggable view: "vertical" or "horizontal." Note that the direction attribute only applies to the "line" style and does not affect other drop zone styles. Also, set the `drop_zone_line_color` prop on the `draggable/draggable_item` component to "primary" or "purple".
2
+
3
+ The length of the line is calculated based off of the width (for "vertical") or height (for "horizontal") of the parent container holding the draggable items.
4
+
5
+ Additionally, if the parent container of the `draggable`/`draggable/draggable_container` (or a subcontainer within) does not have a set height (for "vertical") or width (for "horizontal"), like the [Draggable Drop Zones doc example](https://playbook.powerapp.cloud/kits/draggable/rails#draggable-drop-zones) does, elements on the page may jump up (for "vertical") or to the left (for "horizontal") when an item is actively being dragged. To prevent this, give a parent element a fixed height (for "vertical") or width (for "horizontal") as demonstrated in this doc example.
@@ -0,0 +1,5 @@
1
+ The Draggable kit lets you customize the style of drop zones that appear when dragging an item.
2
+
3
+ By default, drop zones are in the "ghost" style, but you can also choose from "shadow," "outline," and "line."
4
+
5
+ When using the "line" type, make sure to set the appropriate `direction` attribute on the `draggable/draggable_container` component based on the orientation of your draggable view: "vertical" or "horizontal." Note that the direction attribute only applies to the "line" type and does not affect other drop zone styles. For more on the "line" style in particular, check out the [Draggable Drop Zones Line doc example](https://playbook.powerapp.cloud/kits/draggable/rails#draggable-drop-zones-line).