playbook_ui 14.21.2.pre.alpha.PLAY22558410 → 14.21.2

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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/CustomCell.tsx +2 -5
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +4 -20
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +5 -25
  5. data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +16 -36
  6. data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +5 -18
  7. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +17 -37
  8. data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +5 -30
  9. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableBody.tsx +0 -3
  10. data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +40 -91
  11. data/app/pb_kits/playbook/pb_advanced_table/Utilities/CellRendererUtils.tsx +1 -4
  12. data/app/pb_kits/playbook/pb_advanced_table/Utilities/TableContainerStyles.ts +2 -3
  13. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +4 -49
  14. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +18 -36
  15. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +2 -105
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_sort.html.erb +1 -1
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.html.erb +1 -1
  18. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_border_color_rails.html.erb +1 -1
  19. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_loading.html.erb +1 -1
  20. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows.jsx +1 -1
  21. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_react.md +3 -5
  22. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions.jsx +2 -2
  23. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.html.erb +2 -3
  24. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_table_props_sticky_header.html.erb +1 -1
  25. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +0 -6
  26. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +0 -4
  27. data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +84 -60
  28. data/app/pb_kits/playbook/pb_advanced_table/index.js +213 -125
  29. data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.html.erb +1 -1
  30. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +1 -1
  31. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +0 -5
  32. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -2
  33. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +0 -33
  34. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.html.erb +3 -3
  35. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.jsx +4 -7
  36. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_clear_selection.jsx +3 -6
  37. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.jsx +3 -6
  38. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.html.erb +3 -3
  39. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.html.erb +3 -3
  40. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.jsx +4 -7
  41. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +3 -3
  42. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.jsx +4 -7
  43. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.jsx +10 -19
  44. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.jsx +10 -19
  45. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.html.erb +10 -10
  46. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.html.erb +10 -10
  47. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.html.erb +10 -10
  48. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.jsx +11 -20
  49. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.html.erb +3 -3
  50. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.jsx +8 -8
  51. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.html.erb +10 -10
  52. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.jsx +14 -23
  53. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_separators_hidden.html.erb +3 -3
  54. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_separators_hidden.jsx +3 -6
  55. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subcomponent_structure.jsx +3 -6
  56. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subcomponent_structure_rails.html.erb +3 -3
  57. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.html.erb +3 -3
  58. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.jsx +3 -6
  59. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.html.erb +3 -3
  60. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +3 -3
  61. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.html.erb +4 -4
  62. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.jsx +4 -4
  63. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +4 -4
  64. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +4 -4
  65. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.jsx +3 -3
  66. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options_rails.html.erb +3 -3
  67. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.html.erb +3 -3
  68. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.jsx +3 -3
  69. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger.jsx +3 -3
  70. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger_rails.html.erb +3 -3
  71. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.jsx +3 -3
  72. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.html.erb +3 -3
  73. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.jsx +3 -6
  74. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.jsx +3 -3
  75. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.html.erb +3 -3
  76. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +0 -4
  77. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +1 -3
  78. data/app/pb_kits/playbook/pb_filter/Filter/index.tsx +0 -13
  79. data/app/pb_kits/playbook/pb_filter/_filter.scss +0 -4
  80. data/app/pb_kits/playbook/pb_filter/docs/example.yml +0 -1
  81. data/app/pb_kits/playbook/pb_filter/docs/index.js +0 -1
  82. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns.html.erb +8 -8
  83. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns_rails.md +1 -1
  84. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns.html.erb +12 -12
  85. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns_rails.md +2 -2
  86. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns.html.erb +12 -12
  87. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns_rails.md +2 -2
  88. data/app/pb_kits/playbook/pb_table/index.ts +4 -4
  89. data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +0 -4
  90. data/dist/chunks/_typeahead-BlPRej0F.js +22 -0
  91. data/dist/chunks/_weekday_stacked-CzxoxxCR.js +45 -0
  92. data/dist/chunks/lazysizes-DHz07jlL.js +1 -0
  93. data/dist/chunks/lib-D4vXIZF5.js +29 -0
  94. data/dist/chunks/{pb_form_validation-BVF3TmcL.js → pb_form_validation-DyvJ8iPe.js} +1 -1
  95. data/dist/chunks/vendor.js +1 -1
  96. data/dist/playbook-doc.js +3 -3
  97. data/dist/playbook-rails-react-bindings.js +1 -1
  98. data/dist/playbook-rails.js +1 -1
  99. data/dist/playbook.css +1 -1
  100. data/lib/playbook/version.rb +2 -2
  101. metadata +7 -31
  102. data/app/pb_kits/playbook/pb_advanced_table/Utilities/ColumnStylingHelper.ts +0 -15
  103. data/app/pb_kits/playbook/pb_advanced_table/advanced_table_action_bar.js +0 -36
  104. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.jsx +0 -51
  105. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.md +0 -7
  106. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers.jsx +0 -77
  107. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers.md +0 -1
  108. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers_rails.html.erb +0 -63
  109. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers_rails.md +0 -1
  110. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.html.erb +0 -38
  111. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.md +0 -7
  112. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_infinite_scroll.md +0 -3
  113. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.jsx +0 -64
  114. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.md +0 -7
  115. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options.html.erb +0 -52
  116. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options.jsx +0 -99
  117. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options_rails.md +0 -1
  118. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options_react.md +0 -1
  119. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options.html.erb +0 -28
  120. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options.jsx +0 -47
  121. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options_rails.md +0 -1
  122. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options_react.md +0 -1
  123. data/app/pb_kits/playbook/pb_filter/Filter/FilterSection.tsx +0 -49
  124. data/app/pb_kits/playbook/pb_filter/Filter/FilterSidebar.tsx +0 -69
  125. data/app/pb_kits/playbook/pb_filter/docs/_filter_sidebar.jsx +0 -224
  126. data/dist/chunks/_typeahead-B80UsDrG.js +0 -22
  127. data/dist/chunks/_weekday_stacked-D1bqIne1.js +0 -45
  128. data/dist/chunks/lazysizes-B7xYodB-.js +0 -1
  129. data/dist/chunks/lib-CTkMyvfQ.js +0 -29
@@ -1,82 +1,106 @@
1
1
  import PbEnhancedElement from "../pb_enhanced_element";
2
- import { updateSelectionActionBar } from "./advanced_table_action_bar";
3
2
 
4
- const FLAT_SELECTOR = "[data-flat-advanced-table-select='true']";
5
- const SELECT_ALL_SELECTOR = "#select-all-rows input[type='checkbox']";
3
+ const FLAT_ADVANCED_TABLE_SELECTOR = "[data-flat-advanced-table-select]";
6
4
 
7
5
  export default class PbFlatAdvancedTable extends PbEnhancedElement {
8
6
  static get selector() {
9
- return FLAT_SELECTOR;
7
+ return FLAT_ADVANCED_TABLE_SELECTOR;
10
8
  }
11
9
 
12
- constructor(...args) {
13
- super(...args);
14
- // keep track of selected IDs per-table-instance
15
- this.selectedRows = new Set();
10
+ get target() {
11
+ const table = this.element.closest("table");
12
+ return table.querySelectorAll(
13
+ `"label[data-flat-advanced-table-select='true']"`
14
+ );
16
15
  }
17
16
 
17
+ static selectedRows = new Set();
18
+
18
19
  connect() {
19
20
  const table = this.element.closest("table");
20
- if (!table || table.dataset.flatAdvancedInit) return;
21
- table.dataset.flatAdvancedInit = "true";
22
-
23
- // Reference to outer container for action bar
21
+ if (!table) return;
24
22
  const mainTable = this.element.closest(".pb_advanced_table");
25
- // This so it is hidden on first render
26
- if (mainTable) {
27
- updateSelectionActionBar(mainTable, 0);
28
- }
23
+ // Prevent double-init
24
+ if (table.dataset.flatAdvancedTableInitialized) return;
25
+ table.dataset.flatAdvancedTableInitialized = "true";
29
26
 
30
- const updateCheckboxState = () => {
31
- // Sync dataset on main table
32
- if (mainTable) {
27
+ const checkboxLabels = table.querySelectorAll(
28
+ "label[data-flat-advanced-table-select='true']"
29
+ );
30
+ checkboxLabels.forEach((label) => {
31
+ const checkbox = label.querySelector("input[type='checkbox']");
32
+ if (!checkbox) return;
33
+ checkbox.addEventListener("change", () => {
34
+ const rowId = checkbox.id;
35
+ const isChecked = checkbox.checked;
36
+
37
+ if (isChecked) {
38
+ PbFlatAdvancedTable.selectedRows.add(rowId);
39
+ } else {
40
+ PbFlatAdvancedTable.selectedRows.delete(rowId);
41
+ }
42
+
43
+ // Update row background color based on checkbox state
44
+ const rowEl = checkbox.closest("tr");
45
+ if (rowEl) {
46
+ if (isChecked) {
47
+ rowEl.classList.add("bg-row-selection");
48
+ rowEl.classList.remove("bg-white");
49
+ } else {
50
+ rowEl.classList.remove("bg-row-selection");
51
+ rowEl.classList.add("bg-white");
52
+ }
53
+ }
54
+ const allCheckboxes = table.querySelectorAll(
55
+ "label[data-flat-advanced-table-select='true'] input[type='checkbox']"
56
+ );
57
+
58
+ const selectAllInput = table.querySelector(
59
+ "#select-all-rows input[type='checkbox']"
60
+ );
61
+
62
+ if (selectAllInput) {
63
+ const allChecked = Array.from(allCheckboxes).every(cb => cb.checked);
64
+ selectAllInput.checked = allChecked;
65
+ }
66
+
33
67
  mainTable.dataset.selectedRows = JSON.stringify(
34
- Array.from(this.selectedRows)
68
+ Array.from(PbFlatAdvancedTable.selectedRows)
35
69
  );
36
- updateSelectionActionBar(mainTable, this.selectedRows.size);
37
- }
38
- };
39
-
40
- table.addEventListener("change", (e) => {
41
- const rowCb = e.target.closest(FLAT_SELECTOR + " input[type='checkbox']");
42
- const allCb = e.target.closest(SELECT_ALL_SELECTOR);
43
- if (!rowCb && !allCb) return;
44
-
45
- if (rowCb) {
46
- const id = rowCb.id;
47
- if (rowCb.checked) this.selectedRows.add(id);
48
- else this.selectedRows.delete(id);
70
+ });
71
+
72
+ });
49
73
 
50
- const tr = rowCb.closest("tr");
51
- tr?.classList.toggle("bg-row-selection", rowCb.checked);
52
- tr?.classList.toggle("bg-white", !rowCb.checked);
74
+ // Handle select-all checkbox
75
+ const selectAllWrapper = table.querySelector("#select-all-rows");
76
+ if (selectAllWrapper) {
77
+ const selectAllInput = selectAllWrapper.querySelector(
78
+ 'input[type="checkbox"]'
79
+ );
80
+ selectAllInput.addEventListener("change", () => {
81
+ const checkAll = selectAllInput.checked;
53
82
 
54
- // Sync header checkbox
55
- const header = table.querySelector(SELECT_ALL_SELECTOR);
56
- if (header) {
57
- const all = Array.from(
58
- table.querySelectorAll(FLAT_SELECTOR + " input[type='checkbox']")
59
- ).every((cb) => cb.checked);
60
- header.checked = all;
61
- }
62
- }
83
+ checkboxLabels.forEach((label) => {
84
+ const cb = label.querySelector("input[type='checkbox']");
85
+ cb.checked = checkAll;
86
+ const rowId = cb.id;
87
+ const rowEl = cb.closest("tr");
63
88
 
64
- if (allCb) {
65
- const checked = allCb.checked;
66
- Array.from(
67
- table.querySelectorAll(FLAT_SELECTOR + " input[type='checkbox']")
68
- ).forEach((cb) => {
69
- cb.checked = checked;
70
- const tr = cb.closest("tr");
71
- tr?.classList.toggle("bg-row-selection", checked);
72
- tr?.classList.toggle("bg-white", !checked);
73
- const id = cb.id;
74
- if (checked) this.selectedRows.add(id);
75
- else this.selectedRows.delete(id);
89
+ if (checkAll) {
90
+ PbFlatAdvancedTable.selectedRows.add(rowId);
91
+ rowEl?.classList.add("bg-row-selection");
92
+ rowEl?.classList.remove("bg-white");
93
+ } else {
94
+ PbFlatAdvancedTable.selectedRows.delete(rowId);
95
+ rowEl?.classList.remove("bg-row-selection");
96
+ rowEl?.classList.add("bg-white");
97
+ }
76
98
  });
77
- }
78
99
 
79
- updateCheckboxState();
80
- });
100
+ mainTable.dataset.selectedRows = JSON.stringify(
101
+ Array.from(PbFlatAdvancedTable.selectedRows)
102
+ );
103
+ });
104
+ }
81
105
  }
82
106
  }
@@ -1,5 +1,4 @@
1
1
  import PbEnhancedElement from "../pb_enhanced_element";
2
- import { updateSelectionActionBar } from "./advanced_table_action_bar";
3
2
 
4
3
  const ADVANCED_TABLE_SELECTOR = "[data-advanced-table]";
5
4
  const DOWN_ARROW_SELECTOR = "#advanced-table_open_icon";
@@ -10,33 +9,9 @@ export default class PbAdvancedTable extends PbEnhancedElement {
10
9
  return ADVANCED_TABLE_SELECTOR;
11
10
  }
12
11
 
13
- static expandedRows = new Set();
14
- static selectedRows = new Set();
15
- static isCollapsing = false;
16
-
17
- constructor(...args) {
18
- super(...args);
19
- // Map parent row ID to array of its child rows
20
- this.childRowsMap = new Map();
21
- }
22
-
23
- // Fetch and cache child rows for a given parent row ID
24
- childRowsFor(parentId) {
25
- if (!this.childRowsMap.has(parentId)) {
26
- const table = this.element.closest("table");
27
- const rows = Array.from(
28
- table.querySelectorAll(`tr[data-row-parent="${parentId}"]`)
29
- );
30
- this.childRowsMap.set(parentId, rows);
31
- }
32
- return this.childRowsMap.get(parentId);
33
- }
34
-
35
12
  updateTableSelectedRowsAttribute() {
36
13
  const mainTable = this.element.closest(".pb_advanced_table");
37
- mainTable.dataset.selectedRows = JSON.stringify(
38
- Array.from(PbAdvancedTable.selectedRows)
39
- );
14
+ mainTable.dataset.selectedRows = JSON.stringify(Array.from(PbAdvancedTable.selectedRows));
40
15
  }
41
16
 
42
17
  // Check if the row is expanded or collapsed
@@ -129,7 +104,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
129
104
  } else {
130
105
  PbAdvancedTable.selectedRows.delete(rowId);
131
106
  }
132
- // Update background color on row
107
+ // Update background color on row
133
108
  if (!isChecked) {
134
109
  rowEl.classList.remove("bg-row-selection");
135
110
 
@@ -201,129 +176,99 @@ export default class PbAdvancedTable extends PbEnhancedElement {
201
176
  );
202
177
  selectAllInput.checked = allChecked;
203
178
  }
204
- updateSelectionActionBar(table.closest(".pb_advanced_table"), PbAdvancedTable.selectedRows.size);
205
179
  }
206
180
 
207
181
  get target() {
208
- return this.childRowsFor(this.element.id) || [];
182
+ const table = this.element.closest("table");
183
+ return table.querySelectorAll(`[data-row-parent="${this.element.id}"]`);
209
184
  }
210
185
 
186
+ static expandedRows = new Set();
187
+ static selectedRows = new Set();
188
+ static isCollapsing = false;
189
+
211
190
  connect() {
212
- const table = this.element.closest("table");
191
+ this.element.addEventListener("click", () => {
192
+ if (!PbAdvancedTable.isCollapsing) {
193
+ const isExpanded =
194
+ this.element.querySelector(UP_ARROW_SELECTOR).style.display ===
195
+ "inline-block";
196
+ if (!isExpanded) {
197
+ PbAdvancedTable.expandedRows.add(this.element.id);
198
+ } else {
199
+ PbAdvancedTable.expandedRows.delete(this.element.id);
200
+ }
201
+ this.toggleElement(this.target);
202
+ }
203
+ });
213
204
 
214
205
  this.hideCloseIcon();
215
- const mainTable = this.element.closest(".pb_advanced_table");
216
-
217
- // This so it is hidden on first render
218
- if (mainTable) {
219
- updateSelectionActionBar(mainTable);
220
- }
221
206
 
222
- // Precompute parent→child rows mapping once
223
- table.querySelectorAll("tr[data-row-parent]").forEach((row) => {
224
- const parentId = row.dataset.rowParent;
225
- if (!this.childRowsMap.has(parentId)) {
226
- this.childRowsMap.set(parentId, []);
227
- }
228
- this.childRowsMap.get(parentId).push(row);
229
- });
207
+ const table = this.element.closest("table");
230
208
 
231
209
  // Prevent duplicate initialization
232
210
  if (table.dataset.pbAdvancedTableInitialized) return;
233
211
  table.dataset.pbAdvancedTableInitialized = "true";
234
212
 
235
- // Delegate checkbox changes
236
- table.addEventListener("change", (event) => {
237
- const checkbox = event.target.closest('input[type="checkbox"]');
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']");
238
217
  if (!checkbox) return;
239
-
240
- // Header "select-all" logic
241
- if (checkbox.closest("#select-all-rows")) {
242
- const checkAll = checkbox.checked;
243
- const rowCheckboxes = table.querySelectorAll(
244
- 'label[data-row-id] input[type="checkbox"]'
245
- );
246
- rowCheckboxes.forEach((cb) => {
247
- if (cb.checked !== checkAll) {
248
- cb.checked = checkAll;
249
- this.handleCheckboxClick({ currentTarget: cb });
250
- }
251
- });
252
- this.updateTableSelectedRowsAttribute();
253
- updateSelectionActionBar(table.closest(".pb_advanced_table"), PbAdvancedTable.selectedRows.size);
254
- return;
255
- }
256
-
257
- // Individual row checkbox logic
258
- const rowLabel = checkbox.closest("label[data-row-id]");
259
- if (rowLabel) {
260
- this.handleCheckboxClick({ currentTarget: checkbox });
261
- this.updateTableSelectedRowsAttribute();
262
-
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
- }
272
- }
218
+ checkbox.addEventListener("change", (event) => {
219
+ this.handleCheckboxClick(event);
220
+ });
273
221
  });
274
222
 
275
- // Delegate expand/collapse toggles
276
- table.addEventListener("click", (event) => {
277
- const toggleBtn = event.target.closest("[data-advanced-table]");
278
- if (!toggleBtn || PbAdvancedTable.isCollapsing) return;
279
-
280
- // Temporarily bind `this.element` to the clicked toggle
281
- const prevElement = this.element;
282
- this.element = toggleBtn;
283
-
284
- // Update expandedRows set
285
- const isExpanded =
286
- toggleBtn.querySelector(UP_ARROW_SELECTOR).style.display ===
287
- "inline-block";
288
- if (!isExpanded) {
289
- PbAdvancedTable.expandedRows.add(toggleBtn.id);
290
- } else {
291
- PbAdvancedTable.expandedRows.delete(toggleBtn.id);
292
- }
293
-
294
- // Find direct child rows
295
- const childRows = Array.from(
296
- table.querySelectorAll(`[data-row-parent="${toggleBtn.id}"]`)
297
- );
298
- this.toggleElement(childRows);
299
-
300
- // Restore original element context
301
- this.element = prevElement;
223
+ // Bind nested row expansion logic
224
+ const nestedButtons = table.querySelectorAll("[data-advanced-table]");
225
+ nestedButtons.forEach((button) => {
226
+ button.addEventListener("click", () => {
227
+ const isExpanded =
228
+ button.querySelector(UP_ARROW_SELECTOR).style.display === "inline-block";
229
+ if (isExpanded) {
230
+ PbAdvancedTable.expandedRows.add(button.id);
231
+ } else {
232
+ PbAdvancedTable.expandedRows.delete(button.id);
233
+ }
234
+ });
302
235
  });
303
236
 
304
- this.addBorderRadiusOnLastVisibleRow();
305
- }
306
-
307
- addBorderRadiusOnLastVisibleRow() {
308
- const parentElement = this.element.closest(".pb_advanced_table");
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;
309
243
 
310
- const table = document.getElementById(parentElement.id);
244
+ const checkboxes = Array.from(
245
+ table.querySelectorAll("label[data-row-id] input[type='checkbox']")
246
+ );
311
247
 
312
- if (table) {
313
- const visibleRows = table.querySelectorAll(
314
- "tr.is-visible, tr:not(.toggle-content)"
315
- );
248
+ checkboxes.forEach((cb) => {
249
+ cb.checked = checkAll;
250
+ const rowId = cb.id;
251
+ const rowEl = cb.closest("tr");
316
252
 
317
- visibleRows.forEach((row) => row.classList.remove("last-visible-row"));
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
+ });
318
263
 
319
- const lastVisibleRow = visibleRows[visibleRows.length - 1];
264
+ checkboxes.forEach((cb) => this.updateParentCheckboxes(cb));
320
265
 
321
- if (lastVisibleRow) {
322
- lastVisibleRow.classList.add("last-visible-row");
323
- }
266
+ this.updateTableSelectedRowsAttribute();
267
+ });
324
268
  }
325
269
  }
326
270
 
271
+
327
272
  hideCloseIcon() {
328
273
  const closeIcon = this.element.querySelector(UP_ARROW_SELECTOR);
329
274
  closeIcon.style.display = "none";
@@ -422,8 +367,6 @@ export default class PbAdvancedTable extends PbEnhancedElement {
422
367
  row.classList.toggle("bg-silver", !isVisible);
423
368
  row.classList.toggle("bg-white", isVisible);
424
369
  }
425
-
426
- this.addBorderRadiusOnLastVisibleRow();
427
370
  }
428
371
 
429
372
  displayDownArrow() {
@@ -506,6 +449,151 @@ export default class PbAdvancedTable extends PbEnhancedElement {
506
449
  }
507
450
  }
508
451
 
452
+ // Isolate action bar functionality so it doesn't mix with existing functionality
453
+ class PbAdvancedTableActionBar {
454
+ constructor() {
455
+ this.init();
456
+ }
457
+
458
+ init() {
459
+ // Initialize action bars for all advanced tables with action bars
460
+ document.addEventListener('DOMContentLoaded', () => {
461
+ this.setupActionBars();
462
+ });
463
+
464
+ // Also run immediately in case DOM is already loaded
465
+ if (document.readyState === 'loading') {
466
+ // DOM is still loading
467
+ } else {
468
+ // DOM is already loaded
469
+ this.setupActionBars();
470
+ }
471
+ }
472
+
473
+ setupActionBars() {
474
+ const advancedTables = document.querySelectorAll('.pb_advanced_table');
475
+
476
+ advancedTables.forEach(table => {
477
+ // Only proceed if this table has both selectable rows AND an action bar
478
+ if (!this.shouldEnableActionBar(table)) return;
479
+
480
+ const actionBar = table.querySelector('.row-selection-actions-card');
481
+ if (!actionBar) return; // Skip tables without action bars
482
+
483
+ // Initialize action bar styles
484
+ this.initializeActionBar(actionBar);
485
+
486
+ // Set up checkbox listeners for this table
487
+ this.setupCheckboxListeners(table, actionBar);
488
+ });
489
+ }
490
+
491
+ shouldEnableActionBar(table) {
492
+ // Check if the table has selectable rows
493
+ const hasSelectableRows = table.querySelector('input[type="checkbox"]') !== null;
494
+
495
+ // Check if the table has a row selection action bar (not other types of action bars)
496
+ const hasRowSelectionActionBar = table.querySelector('.row-selection-actions-card') !== null;
497
+
498
+ // Additional check: look for the presence of row checkboxes with data-row-id
499
+ const hasRowCheckboxes = table.querySelector('label[data-row-id] input[type="checkbox"]') !== null;
500
+
501
+ // Only enable if ALL conditions are met:
502
+ // 1. Has selectable checkboxes
503
+ // 2. Has the specific row selection action bar
504
+ // 3. Has row checkboxes (not just other types of checkboxes)
505
+ return hasSelectableRows && hasRowSelectionActionBar && hasRowCheckboxes;
506
+ }
507
+
508
+ initializeActionBar(actionBar) {
509
+ // Set initial hidden state
510
+ Object.assign(actionBar.style, {
511
+ height: '0px',
512
+ overflow: 'hidden',
513
+ display: 'block',
514
+ opacity: '0'
515
+ });
516
+
517
+ // Remove any visibility classes
518
+ actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
519
+ actionBar.classList.add("p_none");
520
+ }
521
+
522
+ setupCheckboxListeners(table, actionBar) {
523
+ // Only listen to row checkboxes (those with data-row-id), not all checkboxes
524
+ const rowCheckboxes = table.querySelectorAll('label[data-row-id] input[type="checkbox"]');
525
+
526
+ rowCheckboxes.forEach(checkbox => {
527
+ checkbox.addEventListener('change', () => {
528
+ // Use setTimeout to ensure this runs after the main checkbox logic
529
+ setTimeout(() => {
530
+ this.updateActionBarVisibility(table, actionBar);
531
+ }, 0);
532
+ });
533
+ });
534
+
535
+ // Special handling for select-all checkbox (only if it exists)
536
+ const selectAllCheckbox = table.querySelector("#select-all-rows");
537
+ if (selectAllCheckbox) {
538
+ const selectAllInput = selectAllCheckbox.querySelector('input[type="checkbox"]');
539
+ if (selectAllInput) {
540
+ selectAllInput.addEventListener('change', () => {
541
+ // Use setTimeout to ensure this runs after the main select-all logic
542
+ setTimeout(() => {
543
+ this.updateActionBarVisibility(table, actionBar);
544
+ }, 10); // Slightly longer delay for select-all to ensure all row checkboxes are updated
545
+ });
546
+ }
547
+ }
548
+ }
549
+
550
+ updateActionBarVisibility(table, actionBar) {
551
+ // Only count row checkboxes (those with data-row-id), not all checkboxes
552
+ const rowCheckboxes = table.querySelectorAll('label[data-row-id] input[type="checkbox"]');
553
+
554
+ // Get all checked row checkboxes
555
+ const selectedRowCheckboxes = Array.from(rowCheckboxes).filter(cb => cb.checked);
556
+
557
+ // Get the selected count
558
+ const selectedCount = selectedRowCheckboxes.length;
559
+
560
+ if (selectedCount > 0) {
561
+ this.showActionBar(actionBar, selectedCount);
562
+ } else {
563
+ this.hideActionBar(actionBar);
564
+ }
565
+ }
566
+
567
+ showActionBar(actionBar, selectedCount) {
568
+ // Show action bar directly
569
+ actionBar.style.height = 'auto';
570
+ actionBar.style.overflow = 'visible';
571
+ actionBar.style.opacity = '1';
572
+ actionBar.style.transitionProperty = 'all';
573
+ actionBar.style.transitionTimingFunction = 'ease-in-out';
574
+ actionBar.classList.remove("p_none");
575
+ actionBar.classList.add("p_xs", "is-visible", "show-action-card");
576
+
577
+ // Update the count
578
+ const countElement = actionBar.querySelector(".selected-count");
579
+ if (countElement) {
580
+ countElement.textContent = `${selectedCount} Selected`;
581
+ }
582
+ }
583
+
584
+ hideActionBar(actionBar) {
585
+ // Hide action bar directly
586
+ actionBar.style.height = '0px';
587
+ actionBar.style.overflow = 'hidden';
588
+ actionBar.style.opacity = '0';
589
+ actionBar.classList.add("p_none");
590
+ actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
591
+ }
592
+ }
593
+
594
+ // Initialize the isolated action bar functionality
595
+ new PbAdvancedTableActionBar();
596
+
509
597
  window.expandAllRows = (element) => {
510
598
  PbAdvancedTable.handleToggleAllHeaders(element);
511
599
  };
@@ -8,7 +8,7 @@
8
8
  }) do %>
9
9
  <%= pb_rails("flex", props: { align_items: "center", justify: "between" }) do %>
10
10
  <%= pb_rails("caption", props: { color: "light", padding_left: "xs", size: "xs" }) do %>
11
- <span class="selected-count"></span>
11
+ <span class="selected-count"><%= object.selected_count %> Selected</span>
12
12
  <% end %>
13
13
  <%= pb_rails("flex/flex_item") do %>
14
14
  <%= pb_rails("flex") do %>
@@ -7,7 +7,7 @@
7
7
  <% header_row.each_with_index do |cell, cell_index| %>
8
8
  <% header_id = cell[:accessor].present? ? cell[:accessor] : "header_#{row_index}_#{cell_index}" %>
9
9
  <%= pb_rails("table/table_header", props: { id: header_id, colspan: cell[:colspan], classname: [object.th_classname(is_first_column: cell_index.zero?), ('last-header-cell' if cell[:is_last_in_group] && cell_index != 0)].compact.join(' '), sort_menu: cell[:accessor] ? cell[:sort_menu] : nil }) do %>
10
- <%= pb_rails("flex", props: { align: "center", justify: cell_index.zero? ? "start" : row_index === header_rows.size - 1 ? "end" : "center", text_align: (cell[:header_alignment] || "end") }) do %>
10
+ <%= pb_rails("flex", props: { align: "center", justify: cell_index.zero? ? "start" : row_index === header_rows.size - 1 ? "end" : "center", text_align: "end" }) do %>
11
11
  <% if cell_index.zero? && row_index === header_rows.size - 1 %>
12
12
  <% if object.selectable_rows && object.enable_toggle_expansion != "none" %>
13
13
  <%= pb_rails("flex/flex_item", props: { padding_right: "xs" }) do %>
@@ -98,9 +98,6 @@ module Playbook
98
98
 
99
99
  process_columns(col[:columns], rows, current_depth + 1, max_depth)
100
100
  else
101
- raw_styling = col[:column_styling] || {}
102
- header_alignment = raw_styling[:header_alignment]
103
-
104
101
  colspan = 1
105
102
  rows[current_depth] << {
106
103
  label: col[:label],
@@ -108,7 +105,6 @@ module Playbook
108
105
  accessor: col[:accessor],
109
106
  sort_menu: col[:sort_menu],
110
107
  is_last_in_group: is_last && current_depth.positive?,
111
- header_alignment: header_alignment,
112
108
  }
113
109
  end
114
110
  end
@@ -141,7 +137,6 @@ module Playbook
141
137
  accessor: col[:accessor],
142
138
  label: col[:label] || "",
143
139
  sort_menu: col[:sort_menu] || nil,
144
- column_styling: col[:column_styling] || {},
145
140
  }
146
141
  (max_depth - 1).times do
147
142
  wrapped = { label: "", columns: [wrapped] }
@@ -6,7 +6,7 @@
6
6
  <% object.column_definitions.each_with_index do |column, index| %>
7
7
  <% next unless column[:accessor].present? %>
8
8
  <%= pb_rails("table/table_cell", props: { classname:object.td_classname(column, index)}) do %>
9
- <%= pb_rails("flex", props:{ align: "center", justify: object.justify_for(column, index), classname: object.loading ? "loading-cell" : "" }) do %>
9
+ <%= pb_rails("flex", props:{ align: "center", justify: index.zero? ? "start" : "end", classname: object.loading ? "loading-cell" : "" }) do %>
10
10
  <% if collapsible_trail && index.zero? %>
11
11
  <% (1..depth).each do |i| %>
12
12
  <% additional_offset = i > 1 ? (i - 1) * 0.25 : 0 %>
@@ -34,7 +34,7 @@
34
34
  </button>
35
35
  <% end %>
36
36
  <% end %>
37
- <%= pb_rails("flex/flex_item") do %>
37
+ <%= pb_rails("flex/flex_item", props:{padding_left: index.zero? && (object.row[:children].present? || has_integrated_checkbox) ? "none" : "xs"}) do %>
38
38
  <% if column[:custom_renderer].present? %>
39
39
  <%= raw(column[:custom_renderer].call(object.row, custom_renderer_value(column, index))) %>
40
40
  <% elsif index.zero? %>