playbook_ui 14.23.0.pre.rc.3 → 14.24.0.pre.alpha.PLAY1972validatemissingareacodeandrepeatcountrycode9457

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 (152) 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/CustomCell.tsx +7 -6
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/SortIconButton.tsx +24 -25
  5. data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +10 -10
  6. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +11 -12
  7. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +7 -4
  8. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +1 -1
  9. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +112 -2
  10. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +13 -7
  11. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +2 -2
  12. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +14 -2
  13. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +34 -0
  14. data/app/pb_kits/playbook/pb_advanced_table/advanced_table_action_bar.js +16 -0
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers_vertical_border.html.erb +43 -0
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_headers_vertical_border.jsx +64 -0
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.html.erb +46 -0
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling_rails.md +7 -0
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.html.erb +1 -1
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_rails.html.erb +1 -1
  21. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_per_column.jsx +55 -0
  22. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_per_column.md +6 -0
  23. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_per_column_for_multi_column.jsx +80 -0
  24. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_per_column_for_multi_column.md +1 -0
  25. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_with_custom_header.md +1 -1
  26. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_with_custom_header_multi_header.jsx +107 -0
  27. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_with_custom_header_multi_header.md +1 -0
  28. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_with_custom_header_rails.html.erb +51 -0
  29. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_with_custom_header_rails.md +1 -0
  30. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +7 -0
  31. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +4 -0
  32. data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +4 -11
  33. data/app/pb_kits/playbook/pb_advanced_table/index.js +108 -125
  34. data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +7 -1
  35. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +7 -4
  36. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +5 -1
  37. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +46 -4
  38. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +13 -4
  39. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +24 -5
  40. data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.rb +1 -1
  41. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_legend_position.md +1 -1
  42. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +12 -1
  43. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +1 -1
  44. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate_rails.md +2 -1
  45. data/app/pb_kits/playbook/pb_checkbox/index.js +218 -26
  46. data/app/pb_kits/playbook/pb_circle_chart/docs/_circle_chart_legend_position.md +1 -1
  47. data/app/pb_kits/playbook/pb_date/_date.tsx +5 -3
  48. data/app/pb_kits/playbook/pb_date/date.html.erb +6 -6
  49. data/app/pb_kits/playbook/pb_date/date.rb +2 -0
  50. data/app/pb_kits/playbook/pb_date/docs/_date_with_show_current_year.html.erb +4 -0
  51. data/app/pb_kits/playbook/pb_date/docs/_date_with_show_current_year.jsx +17 -0
  52. data/app/pb_kits/playbook/pb_date/docs/_date_with_show_current_year.md +1 -0
  53. data/app/pb_kits/playbook/pb_date/docs/example.yml +2 -0
  54. data/app/pb_kits/playbook/pb_date/docs/index.js +1 -0
  55. data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +17 -1
  56. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +6 -0
  57. data/app/pb_kits/playbook/pb_dropdown/_dropdown_mixin.scss +36 -0
  58. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_active_style_options.jsx +90 -0
  59. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_active_style_options_react.md +4 -0
  60. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options.jsx +1 -0
  61. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options_react.md +1 -1
  62. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +3 -2
  63. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -1
  64. data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +24 -0
  65. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +11 -1
  66. data/app/pb_kits/playbook/pb_gauge/docs/_description.md +1 -0
  67. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_colors.jsx +32 -15
  68. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_colors_react.md +2 -0
  69. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex.jsx +35 -9
  70. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex_react.md +1 -0
  71. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_default.jsx +26 -14
  72. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_disable_animation.jsx +32 -15
  73. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_full_circle.jsx +45 -17
  74. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_height.jsx +59 -22
  75. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_live_data.jsx +40 -9
  76. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_min_max.jsx +50 -18
  77. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_sizing.jsx +31 -18
  78. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_title.jsx +34 -17
  79. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_units.jsx +64 -23
  80. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_units_react.md +1 -0
  81. data/app/pb_kits/playbook/pb_gauge/docs/example.yml +0 -1
  82. data/app/pb_kits/playbook/pb_gauge/docs/index.js +0 -1
  83. data/app/pb_kits/playbook/pb_gauge/gaugeTheme.ts +7 -1
  84. data/app/pb_kits/playbook/pb_line_graph/docs/_description.md +1 -3
  85. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_colors.jsx +36 -17
  86. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_colors_react.md +3 -0
  87. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_default.jsx +31 -16
  88. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_height.jsx +63 -31
  89. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_height.md +3 -0
  90. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_legend.jsx +35 -16
  91. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_legend_nonclickable.jsx +41 -16
  92. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_legend_position.jsx +107 -62
  93. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_legend_position.md +4 -7
  94. data/app/pb_kits/playbook/pb_line_graph/docs/example.yml +0 -1
  95. data/app/pb_kits/playbook/pb_line_graph/docs/index.js +0 -1
  96. data/app/pb_kits/playbook/pb_line_graph/lineGraphTheme.ts +16 -1
  97. data/app/pb_kits/playbook/pb_multi_level_select/_helper_functions.tsx +18 -9
  98. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +3 -1
  99. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_show_checked_children.html.erb +75 -0
  100. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_show_checked_children.jsx +94 -0
  101. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_show_checked_children.md +3 -0
  102. data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +1 -1
  103. data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +3 -0
  104. data/app/pb_kits/playbook/pb_pagination/_pagination.tsx +4 -0
  105. data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default_rails.md +3 -1
  106. data/app/pb_kits/playbook/pb_pagination/docs/_pagination_default_react.md +3 -1
  107. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +14 -1
  108. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_strict_mode.html.erb +10 -0
  109. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_strict_mode.jsx +26 -0
  110. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_strict_mode.md +3 -0
  111. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +2 -0
  112. data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +1 -0
  113. data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
  114. data/app/pb_kits/playbook/pb_select/select.rb +4 -2
  115. data/app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.html.erb +1 -0
  116. data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +49 -1
  117. data/dist/chunks/_line_graph-qk_BN_J0.js +1 -0
  118. data/dist/chunks/_typeahead-ZLTFtAoW.js +6 -0
  119. data/dist/chunks/_weekday_stacked-svceGyvR.js +37 -0
  120. data/dist/chunks/lib-CY5ZPzic.js +29 -0
  121. data/dist/chunks/{pb_form_validation-BUOKwfvW.js → pb_form_validation-D3b0JKHH.js} +1 -1
  122. data/dist/chunks/vendor.js +1 -1
  123. data/dist/menu.yml +3 -10
  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 +41 -26
  130. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_pb_styles.jsx +0 -30
  131. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_pb_styles.md +0 -1
  132. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_pb_styles.jsx +0 -52
  133. data/app/pb_kits/playbook/pb_line_graph/docs/_line_graph_pb_styles.md +0 -1
  134. data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.scss +0 -0
  135. data/app/pb_kits/playbook/pb_walkthrough/_walkthrough.tsx +0 -202
  136. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_continuous.jsx +0 -69
  137. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_default.jsx +0 -71
  138. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_multi_beacon.jsx +0 -110
  139. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_no_beacon.jsx +0 -76
  140. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_no_overlay.jsx +0 -76
  141. data/app/pb_kits/playbook/pb_walkthrough/docs/_walkthrough_styled.jsx +0 -76
  142. data/app/pb_kits/playbook/pb_walkthrough/docs/example.yml +0 -10
  143. data/app/pb_kits/playbook/pb_walkthrough/docs/index.js +0 -6
  144. data/app/pb_kits/playbook/pb_walkthrough/walkthrough.test.jsx +0 -34
  145. data/dist/chunks/_circle_chart-BZmlhBs2.js +0 -1
  146. data/dist/chunks/_typeahead-B1tu_vWi.js +0 -22
  147. data/dist/chunks/_weekday_stacked-CKk0dR5s.js +0 -45
  148. data/dist/chunks/lib-DYpq0k8j.js +0 -29
  149. /data/app/pb_kits/playbook/pb_advanced_table/docs/{_advanced_table_row_styling.md → _advanced_table_row_styling_react.md} +0 -0
  150. /data/app/pb_kits/playbook/pb_gauge/docs/{_gauge_colors.md → _gauge_colors_rails.md} +0 -0
  151. /data/app/pb_kits/playbook/pb_gauge/docs/{_gauge_complex.md → _gauge_complex_rails.md} +0 -0
  152. /data/app/pb_kits/playbook/pb_line_graph/docs/{_line_graph_colors.md → _line_graph_colors_rails.md} +0 -0
@@ -39,6 +39,70 @@ export default class PbAdvancedTable extends PbEnhancedElement {
39
39
  );
40
40
  }
41
41
 
42
+ // Recalculate selected count based on all checked checkboxes
43
+ recalculateSelectedCount() {
44
+ const table = this.element.closest("table");
45
+
46
+ // Get all checkboxes that could be part of the selection
47
+ // This includes row checkboxes and any parent checkboxes that might be programmatically checked
48
+ const rowCheckboxes = table.querySelectorAll(
49
+ 'label[data-row-id] input[type="checkbox"]'
50
+ );
51
+
52
+ // Also get any checkboxes that might be parent checkboxes (those with data-pb-checkbox-indeterminate-main)
53
+ // But exclude the select-all checkbox itself from the count
54
+ const parentCheckboxes = table.querySelectorAll(
55
+ '[data-pb-checkbox-indeterminate-main="true"] input[type="checkbox"]'
56
+ );
57
+
58
+ // Filter out the select-all checkbox from parent checkboxes
59
+ const selectAllCheckbox = table.querySelector('#select-all-rows input[type="checkbox"]');
60
+ const filteredParentCheckboxes = Array.from(parentCheckboxes).filter(checkbox =>
61
+ checkbox !== selectAllCheckbox && !checkbox.id.includes('select-all-rows')
62
+ );
63
+
64
+ // Combine all checkboxes and remove duplicates
65
+ const allCheckboxes = new Set([...rowCheckboxes, ...filteredParentCheckboxes]);
66
+
67
+ // Clear the selectedRows Set and rebuild it from checked checkboxes
68
+ PbAdvancedTable.selectedRows.clear();
69
+
70
+ allCheckboxes.forEach((checkbox) => {
71
+ const rowEl = checkbox.closest("tr");
72
+ const isChecked = checkbox.checked;
73
+
74
+ if (isChecked) {
75
+ PbAdvancedTable.selectedRows.add(checkbox.id);
76
+ // Only apply styling if the checkbox is inside a table row
77
+ if (rowEl) {
78
+ rowEl.classList.add("bg-row-selection");
79
+ rowEl.classList.remove("bg-white", "bg-silver");
80
+ }
81
+ } else {
82
+ // Only apply styling if the checkbox is inside a table row
83
+ if (rowEl) {
84
+ rowEl.classList.remove("bg-row-selection");
85
+
86
+ if (this.isRowExpanded(rowEl)) {
87
+ rowEl.classList.remove("bg-silver");
88
+ rowEl.classList.add("bg-white");
89
+ } else {
90
+ rowEl.classList.remove("bg-white");
91
+ rowEl.classList.add("bg-silver");
92
+ }
93
+ }
94
+ }
95
+ });
96
+
97
+ this.updateTableSelectedRowsAttribute();
98
+ updateSelectionActionBar(table.closest(".pb_advanced_table"), PbAdvancedTable.selectedRows.size);
99
+
100
+ // Sync header select-all state
101
+ if (selectAllCheckbox) {
102
+ selectAllCheckbox.checked = Array.from(rowCheckboxes).every((cb) => cb.checked);
103
+ }
104
+ }
105
+
42
106
  // Check if the row is expanded or collapsed
43
107
  // This is used to determine the background color of the row
44
108
  // when the checkbox is checked or unchecked
@@ -47,75 +111,6 @@ export default class PbAdvancedTable extends PbEnhancedElement {
47
111
  return closeIcon?.style.display === "none" || !closeIcon;
48
112
  }
49
113
 
50
- updateParentCheckboxes(checkbox) {
51
- const rowEl = checkbox.closest("tr");
52
- if (!rowEl) return;
53
-
54
- const table = rowEl.closest("table");
55
- if (!table) return;
56
-
57
- const contentTrail = rowEl.dataset.advancedTableContent;
58
- if (!contentTrail) return;
59
-
60
- const ancestorIds = contentTrail.split("-").slice(0, -1);
61
-
62
- ancestorIds.reverse();
63
- ancestorIds.forEach((ancestorId) => {
64
- const parentRowSelector = `[data-advanced-table-content$="${ancestorId}"]`;
65
- const parentRow = table.querySelector(parentRowSelector);
66
- if (!parentRow) return;
67
-
68
- const parentLabel = parentRow.querySelector("label[data-row-id]");
69
- if (!parentLabel) return;
70
-
71
- const parentCheckbox = parentLabel.querySelector(
72
- "input[type='checkbox']"
73
- );
74
- if (!parentCheckbox) return;
75
-
76
- // Find all immediate children of parent linked to ancestor Id, filter our subrow headers
77
- const children = Array.from(
78
- table.querySelectorAll(`tr[data-row-parent$="_${ancestorId}"]`)
79
- ).filter((child) => {
80
- const content = child.dataset.advancedTableContent;
81
- return !(content && content.endsWith("sr"));
82
- });
83
-
84
- const allChildrenChecked = Array.from(children).every((child) => {
85
- const childLabel = child.querySelector("label[data-row-id]");
86
- if (!childLabel) return false;
87
- const childCheckbox = childLabel.querySelector(
88
- "input[type='checkbox']"
89
- );
90
- if (!childCheckbox) return false;
91
- return childCheckbox.checked;
92
- });
93
-
94
- // Update parent checkbox
95
- parentCheckbox.checked = allChildrenChecked;
96
-
97
- const parentCheckboxId = parentCheckbox.id;
98
- if (allChildrenChecked) {
99
- PbAdvancedTable.selectedRows.add(parentCheckboxId);
100
- parentRow.classList.add("bg-row-selection");
101
- parentRow.classList.remove("bg-white", "bg-silver");
102
- } else {
103
- PbAdvancedTable.selectedRows.delete(parentCheckboxId);
104
- }
105
- if (!allChildrenChecked) {
106
- parentRow.classList.remove("bg-row-selection");
107
-
108
- if (this.isRowExpanded(parentRow)) {
109
- parentRow.classList.remove("bg-silver");
110
- parentRow.classList.add("bg-white");
111
- } else {
112
- parentRow.classList.remove("bg-white");
113
- parentRow.classList.add("bg-silver");
114
- }
115
- }
116
- });
117
- }
118
-
119
114
  handleCheckboxClick(event) {
120
115
  const checkbox = event.currentTarget;
121
116
  const rowId = checkbox.id;
@@ -141,49 +136,6 @@ export default class PbAdvancedTable extends PbEnhancedElement {
141
136
  rowEl.classList.add("bg-silver");
142
137
  }
143
138
  }
144
- if (rowEl) {
145
- const table = rowEl.closest("table");
146
- const rowContent = rowEl.dataset.advancedTableContent;
147
-
148
- if (rowContent) {
149
- const childRows = table.querySelectorAll(
150
- `[data-advanced-table-content^="${rowContent}-"]`
151
- );
152
-
153
- childRows.forEach((childRow) => {
154
- const label = childRow.querySelector("label[data-row-id]");
155
- if (!label) return;
156
-
157
- const childCheckbox = label.querySelector("input[type='checkbox']");
158
- if (!childCheckbox) return;
159
-
160
- childCheckbox.checked = isChecked;
161
-
162
- const childRowId = childCheckbox.id;
163
- const childRowEl = childCheckbox.closest("tr");
164
- if (isChecked) {
165
- PbAdvancedTable.selectedRows.add(childRowId);
166
- childRowEl?.classList.add("bg-row-selection");
167
- childRowEl?.classList.remove("bg-white", "bg-silver");
168
- } else {
169
- PbAdvancedTable.selectedRows.delete(childRowId);
170
- }
171
- if (!isChecked) {
172
- childRowEl?.classList.remove("bg-row-selection");
173
-
174
- if (this.isRowExpanded(childRowEl)) {
175
- childRowEl?.classList.remove("bg-silver");
176
- childRowEl?.classList.add("bg-white");
177
- } else {
178
- childRowEl?.classList.remove("bg-white");
179
- childRowEl?.classList.add("bg-silver");
180
- }
181
- }
182
- });
183
- }
184
- }
185
-
186
- this.updateParentCheckboxes(checkbox);
187
139
 
188
140
  this.updateTableSelectedRowsAttribute();
189
141
 
@@ -249,8 +201,11 @@ export default class PbAdvancedTable extends PbEnhancedElement {
249
201
  this.handleCheckboxClick({ currentTarget: cb });
250
202
  }
251
203
  });
252
- this.updateTableSelectedRowsAttribute();
253
- updateSelectionActionBar(table.closest(".pb_advanced_table"), PbAdvancedTable.selectedRows.size);
204
+
205
+ // Recalculate the count to ensure all checkboxes are properly tracked
206
+ setTimeout(() => {
207
+ this.recalculateSelectedCount();
208
+ }, 0);
254
209
  return;
255
210
  }
256
211
 
@@ -258,17 +213,41 @@ export default class PbAdvancedTable extends PbEnhancedElement {
258
213
  const rowLabel = checkbox.closest("label[data-row-id]");
259
214
  if (rowLabel) {
260
215
  this.handleCheckboxClick({ currentTarget: checkbox });
261
- this.updateTableSelectedRowsAttribute();
216
+
217
+ // Recalculate the count to ensure all checkboxes are properly tracked
218
+ setTimeout(() => {
219
+ this.recalculateSelectedCount();
220
+ }, 0);
221
+ }
222
+ });
262
223
 
263
- // Sync header select-all state
264
- const selectAllInput = table.querySelector(
265
- '#select-all-rows input[type="checkbox"]'
266
- );
267
- if (selectAllInput) {
268
- selectAllInput.checked = Array.from(
269
- table.querySelectorAll('label[data-row-id] input[type="checkbox"]')
270
- ).every((cb) => cb.checked);
271
- }
224
+ // If a parent checkbox changed a checkbox, update styling
225
+ // Listen for programmatic checkbox changes from parent-child relationships
226
+ table.addEventListener("checkbox-programmatic-change", (event) => {
227
+ const checkbox = event.target;
228
+ if (!checkbox || checkbox.type !== 'checkbox') return;
229
+
230
+ // Individual row checkbox logic
231
+ const rowLabel = checkbox.closest("label[data-row-id]");
232
+ if (rowLabel) {
233
+ this.handleCheckboxClick({ currentTarget: checkbox });
234
+ }
235
+
236
+ // Recalculate the count to ensure all programmatically changed checkboxes are included
237
+ setTimeout(() => {
238
+ this.recalculateSelectedCount();
239
+ }, 10); // Slightly longer delay to ensure all changes are processed
240
+ });
241
+
242
+
243
+ // Also listen for all checkbox changes to ensure we catch everything
244
+ table.addEventListener("change", (event) => {
245
+ const checkbox = event.target;
246
+ if (checkbox && checkbox.type === 'checkbox') {
247
+ // Force recalculation after a short delay to ensure all changes are processed
248
+ setTimeout(() => {
249
+ this.recalculateSelectedCount();
250
+ }, 50);
272
251
  }
273
252
  });
274
253
 
@@ -314,12 +293,16 @@ export default class PbAdvancedTable extends PbEnhancedElement {
314
293
  "tr.is-visible, tr:not(.toggle-content)"
315
294
  );
316
295
 
317
- visibleRows.forEach((row) => row.classList.remove("last-visible-row"));
296
+ visibleRows.forEach((row) => {
297
+ row.classList.remove("last-visible-row");
298
+ row.classList.remove("last-row-cell");
299
+ });
318
300
 
319
301
  const lastVisibleRow = visibleRows[visibleRows.length - 1];
320
302
 
321
303
  if (lastVisibleRow) {
322
304
  lastVisibleRow.classList.add("last-visible-row");
305
+ lastVisibleRow.classList.add("last-row-cell");
323
306
  }
324
307
  }
325
308
  }
@@ -79,8 +79,14 @@
79
79
  left: 0;
80
80
  border-radius: unset;
81
81
  z-index: 5;
82
- }
83
82
 
83
+ // Add proper border radius when action bar is visible
84
+ &.is-visible,
85
+ &.show-action-card {
86
+ border-top-left-radius: 4px !important;
87
+ border-top-right-radius: 4px !important;
88
+ }
89
+ }
84
90
  .checkbox-cell {
85
91
  display: table-cell !important;
86
92
  }
@@ -23,6 +23,8 @@ module Playbook
23
23
  default: "scroll"
24
24
  prop :selectable_rows, type: Playbook::Props::Boolean,
25
25
  default: false
26
+ prop :row_styling, type: Playbook::Props::Array,
27
+ default: []
26
28
 
27
29
  def flatten_columns(columns)
28
30
  columns.flat_map do |col|
@@ -38,13 +40,14 @@ module Playbook
38
40
  end.compact
39
41
  end
40
42
 
41
- def render_row_and_children(row, column_definitions, current_depth, first_parent_child, ancestor_ids = [], top_parent_id = nil, additional_classes: "", table_data_attributes: {})
43
+ def render_row_and_children(row, column_definitions, current_depth, first_parent_child, ancestor_ids = [], top_parent_id = nil, additional_classes: "", table_data_attributes: {}, immediate_parent_row_id: nil)
42
44
  top_parent_id ||= row.object_id
43
45
  new_ancestor_ids = ancestor_ids + [row.object_id]
44
46
  leaf_columns = flatten_columns(column_definitions)
45
47
 
46
48
  output = ActiveSupport::SafeBuffer.new
47
49
  is_first_child_of_subrow = current_depth.positive? && first_parent_child && subrow_headers[current_depth - 1].present?
50
+ last_row = subrow_headers.length == current_depth
48
51
 
49
52
  subrow_ancestor_ids = ancestor_ids + ["#{row.object_id}sr"]
50
53
  subrow_data_attributes = {
@@ -53,7 +56,7 @@ module Playbook
53
56
  row_parent: "#{id}_#{ancestor_ids.last}",
54
57
  }
55
58
  # Subrow header if applicable
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"
59
+ 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, last_row: last_row, immediate_parent_row_id: immediate_parent_row_id }) if is_first_child_of_subrow && enable_toggle_expansion == "all"
57
60
 
58
61
  current_data_attributes = if current_depth.zero?
59
62
  {
@@ -66,7 +69,7 @@ module Playbook
66
69
  end
67
70
 
68
71
  # Additional class and data attributes needed for toggle logic
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 })
72
+ 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, row_styling: row_styling, last_row: last_row, immediate_parent_row_id: immediate_parent_row_id })
70
73
 
71
74
  if row[:children].present?
72
75
  row[:children].each do |child_row|
@@ -81,7 +84,7 @@ module Playbook
81
84
  advanced_table_content: data_content,
82
85
  }
83
86
 
84
- output << render_row_and_children(child_row, column_definitions, current_depth + 1, is_first_child, new_ancestor_ids, top_parent_id, additional_classes: "toggle-content", table_data_attributes: child_data_attributes)
87
+ output << render_row_and_children(child_row, column_definitions, current_depth + 1, is_first_child, new_ancestor_ids, top_parent_id, additional_classes: "toggle-content", table_data_attributes: child_data_attributes, immediate_parent_row_id: row[:id])
85
88
  end
86
89
  end
87
90
 
@@ -26,7 +26,11 @@
26
26
  <% end %>
27
27
  <% end %>
28
28
  <% end %>
29
- <%= cell[:label] %>
29
+ <% if object.has_header_renderer?(cell) %>
30
+ <%= raw(object.render_header(cell)) %>
31
+ <% else %>
32
+ <%= cell[:label] %>
33
+ <% end %>
30
34
  <% end %>
31
35
  <% end %>
32
36
  <% end %>
@@ -3,6 +3,8 @@
3
3
  module Playbook
4
4
  module PbAdvancedTable
5
5
  class TableHeader < Playbook::KitBase
6
+ prop :id, type: Playbook::Props::String,
7
+ default: ""
6
8
  prop :column_definitions, type: Playbook::Props::Array,
7
9
  default: []
8
10
  prop :enable_toggle_expansion, type: Playbook::Props::Enum,
@@ -56,8 +58,10 @@ module Playbook
56
58
  classname: additional_classes.join(" "),
57
59
  }) do
58
60
  pb_rails("checkbox", props: {
59
- id: "select-all-rows",
60
- name: "select-all-rows",
61
+ id: "#{id ? "#{id}-" : ''}select-all-rows",
62
+ indeterminate_main: true,
63
+ indeterminate_main_labels: ["", ""],
64
+ name: "#{id ? "#{id}-" : ''}select-all-rows",
61
65
  })
62
66
  end
63
67
  end
@@ -67,8 +71,10 @@ module Playbook
67
71
  def render_select_all_checkbox
68
72
  if selectable_rows
69
73
  pb_rails("checkbox", props: {
70
- id: "select-all-rows",
71
- name: "select-all-rows",
74
+ id: "#{id ? "#{id}-" : ''}select-all-rows",
75
+ indeterminate_main: true,
76
+ indeterminate_main_labels: ["", ""],
77
+ name: "#{id ? "#{id}-" : ''}select-all-rows",
72
78
  data: {
73
79
  action: "click->pb-advanced-table#toggleAllRowSelection",
74
80
  },
@@ -76,6 +82,30 @@ module Playbook
76
82
  end
77
83
  end
78
84
 
85
+ # Get original column definition for custom rendering
86
+ def find_original_column_def(accessor)
87
+ find_column_def_by_accessor(column_definitions, accessor)
88
+ end
89
+
90
+ # Check if a header cell has a custom renderer
91
+ def has_header_renderer?(cell)
92
+ return false unless cell[:accessor].present?
93
+
94
+ original_def = find_original_column_def(cell[:accessor])
95
+ original_def && original_def[:header].present?
96
+ end
97
+
98
+ # Render custom header content
99
+ def render_header(cell)
100
+ return cell[:label] unless has_header_renderer?(cell)
101
+
102
+ original_def = find_original_column_def(cell[:accessor])
103
+ custom_renderer = original_def[:header]
104
+
105
+ # Call the custom renderer with the cell data and label
106
+ custom_renderer.call(cell, cell[:label])
107
+ end
108
+
79
109
  private
80
110
 
81
111
  def compute_max_depth(columns)
@@ -148,6 +178,18 @@ module Playbook
148
178
  end
149
179
  wrapped
150
180
  end
181
+
182
+ def find_column_def_by_accessor(defs, target_accessor)
183
+ defs.each do |col|
184
+ return col if col[:accessor] == target_accessor
185
+
186
+ if col[:columns].is_a?(Array)
187
+ found = find_column_def_by_accessor(col[:columns], target_accessor)
188
+ return found if found
189
+ end
190
+ end
191
+ nil
192
+ end
151
193
  end
152
194
  end
153
195
  end
@@ -1,3 +1,10 @@
1
+ <%
2
+ row_style = object.row_styling.find { |style| style[:row_id].to_s == object.row_id.to_s }
3
+ button_color = row_style&.[](:expand_button_color)
4
+ bg_color = row_style&.[](:background_color)
5
+ font_color = row_style&.[](:font_color)
6
+ %>
7
+
1
8
  <%= pb_content_tag(:tr) do %>
2
9
  <% has_separate_checkbox = object.selectable_rows && object.enable_toggle_expansion == "none" %>
3
10
  <% if has_separate_checkbox %>
@@ -5,7 +12,7 @@
5
12
  <% end %>
6
13
  <% object.column_definitions.each_with_index do |column, index| %>
7
14
  <% next unless column[:accessor].present? %>
8
- <%= pb_rails("table/table_cell", props: { classname:object.td_classname(column, index)}) do %>
15
+ <%= pb_rails("table/table_cell", props: { html_options: { style: { "background-color": bg_color, color: font_color } }, classname:object.td_classname(column, index)}) do %>
9
16
  <%= pb_rails("flex", props:{ align: "center", justify: object.justify_for(column, index), classname: object.loading ? "loading-cell" : "" }) do %>
10
17
  <% if collapsible_trail && index.zero? %>
11
18
  <% (1..depth).each do |i| %>
@@ -28,13 +35,15 @@
28
35
  <button
29
36
  id="<%= "#{object.id}_#{object.row.object_id}" %>"
30
37
  class="gray-icon expand-toggle-icon"
31
- data-advanced-table="true">
38
+ data-advanced-table="true"
39
+ style="color: <%= button_color %>"
40
+ >
32
41
  <%= pb_rails("icon", props: { id: "advanced-table_open_icon", icon: "circle-play", cursor: "pointer" }) %>
33
- <%= pb_rails("icon", props: { id: "advanced-table_close_icon", icon: "circle-play-down", cursor: "pointer" }) %>
42
+ <%= pb_rails("icon", props: { id: "advanced-table_close_icon", icon: "circle-play", cursor: "pointer", rotation: 90 }) %>
34
43
  </button>
35
44
  <% end %>
36
45
  <% end %>
37
- <%= pb_rails("flex/flex_item") do %>
46
+ <%= pb_rails("flex/flex_item") do %>
38
47
  <% if column[:custom_renderer].present? %>
39
48
  <%= raw(column[:custom_renderer].call(object.row, custom_renderer_value(column, index))) %>
40
49
  <% elsif index.zero? %>
@@ -27,6 +27,12 @@ module Playbook
27
27
  prop :enable_toggle_expansion, type: Playbook::Props::Enum,
28
28
  values: %w[all header none],
29
29
  default: "header"
30
+ prop :row_styling, type: Playbook::Props::Array,
31
+ default: []
32
+ prop :last_row, type: Playbook::Props::Boolean,
33
+ default: false
34
+ prop :immediate_parent_row_id, type: Playbook::Props::String,
35
+ default: ""
30
36
 
31
37
  def data
32
38
  Hash(prop(:data)).merge(table_data_attributes)
@@ -37,7 +43,7 @@ module Playbook
37
43
  end
38
44
 
39
45
  def td_classname(column, index)
40
- classes = %w[id-cell chrome-styles]
46
+ classes = %w[id-cell]
41
47
  classes << "last-cell" if column[:is_last_in_group]
42
48
  classes << "pinned-left" if index.zero? && is_pinned_left && responsive == "scroll"
43
49
  classes.join(" ")
@@ -52,12 +58,14 @@ module Playbook
52
58
  # Selectable Rows No Subrows - checkboxes in their own first cell
53
59
  def render_checkbox_cell
54
60
  if selectable_rows
61
+ prefix = id ? "#{id}-" : ""
55
62
  pb_rails("table/table_cell", props: {
56
63
  classname: "checkbox-cell",
57
64
  }) do
58
65
  pb_rails("checkbox", props: {
59
- id: "select-row-#{row_id || row.object_id}",
60
- name: "select-row-#{row_id || row.object_id}",
66
+ id: "#{prefix}select-row-#{row_id || row.object_id}",
67
+ indeterminate_parent: "#{id ? "#{id}-" : ''}select-all-rows",
68
+ name: "#{prefix}select-row-#{row_id || row.object_id}",
61
69
  data: {
62
70
  row_id: row_id || row.object_id.to_s,
63
71
  flat_advanced_table_select: true,
@@ -70,9 +78,20 @@ module Playbook
70
78
  # Selectable Rows w/ Subrows - checkboxes part of toggleable first cell
71
79
  def render_row_checkbox
72
80
  if selectable_rows
81
+ prefix = id ? "#{id}-" : ""
82
+ indeterminate_parent =
83
+ if depth.zero?
84
+ "#{prefix}select-all-rows"
85
+ else
86
+ "#{prefix}select-row-#{immediate_parent_row_id}"
87
+ end
88
+
73
89
  pb_rails("checkbox", props: {
74
- id: "select-row-#{row_id || row.object_id}",
75
- name: "select-row-#{row_id || row.object_id}",
90
+ id: "#{prefix}select-row-#{row_id || row.object_id}",
91
+ indeterminate_main: !last_row,
92
+ indeterminate_main_labels: ["", ""],
93
+ indeterminate_parent: indeterminate_parent,
94
+ name: "#{prefix}select-row-#{row_id || row.object_id}",
76
95
  data: {
77
96
  row_id: row_id || row.object_id.to_s,
78
97
  },
@@ -29,7 +29,7 @@ module Playbook
29
29
  end
30
30
 
31
31
  def td_classname(index)
32
- classes = %w[id-cell chrome-styles]
32
+ classes = %w[id-cell]
33
33
  classes << "pinned-left" if index.zero? && responsive == "scroll"
34
34
  classes.join(" ")
35
35
  end
@@ -1,7 +1,7 @@
1
1
  ##### Prop
2
2
 
3
3
  `align` **Type**: String | **Values**: left | center | right (defaults to center)
4
- `verticalAlign` **Type**: String | **Values**: top | middle | bottom (defaults middle)
4
+ `verticalAlign` **Type**: String | **Values**: top | middle | bottom (defaults to bottom)
5
5
  `layout` **Type**: String | **Values**: horizontal | vertical | proximate (defaults to horizontal)
6
6
  `x` **Type**: Number (defaults to 0)
7
7
  `y` **Type**: Number (defaults to 0)
@@ -6,6 +6,8 @@ module Playbook
6
6
  prop :error, type: Playbook::Props::Boolean, default: false
7
7
  prop :checked, type: Playbook::Props::Boolean, default: false
8
8
  prop :indeterminate_main, type: Playbook::Props::Boolean, default: false
9
+ prop :indeterminate_main_labels, type: Playbook::Props::Array,
10
+ default: []
9
11
  prop :indeterminate_parent
10
12
  prop :text
11
13
  prop :value
@@ -49,10 +51,19 @@ module Playbook
49
51
  end
50
52
 
51
53
  def data
52
- Hash(prop(:data)).merge(
54
+ base_data = Hash(prop(:data)).merge(
53
55
  pb_checkbox_indeterminate_main: indeterminate_main,
54
56
  pb_checkbox_indeterminate_parent: indeterminate_parent
55
57
  )
58
+
59
+ if indeterminate_main && indeterminate_main_labels.size == 2
60
+ base_data.merge!(
61
+ pb_checkbox_indeterminate_main_label_check: indeterminate_main_labels[0],
62
+ pb_checkbox_indeterminate_main_label_uncheck: indeterminate_main_labels[1]
63
+ )
64
+ end
65
+
66
+ base_data
56
67
  end
57
68
 
58
69
  private
@@ -9,10 +9,10 @@
9
9
  <tr>
10
10
  <th>
11
11
  <%= pb_rails("checkbox", props: {
12
- text: "Uncheck All",
13
12
  value: "checkbox-value",
14
13
  name: "main-checkbox",
15
14
  indeterminate_main: true,
15
+ indeterminate_main_labels: ["Check All Ice Cream", "Uncheck All Ice Cream"],
16
16
  id: "indeterminate-checkbox"
17
17
  }) %>
18
18
  </th>
@@ -1 +1,2 @@
1
- If you want to use indeterminate, "check/uncheck all" checkboxes, add `indeterminate_main: true` and an `id` to the main checkbox. Then, add an `indeterminate_parent` prop with the main checkbox's `id` to the children checkboxes.
1
+ If you want to use indeterminate, "check/uncheck all" checkboxes, add `indeterminate_main: true` and an `id` to the main checkbox. Then, add an `indeterminate_parent` prop with the main checkbox's `id` to the children checkboxes.
2
+ If you want to customize the main checkbox labels, set an array `indeterminate_main_labels` with "Check All" and "Uncheck All" labels.