playbook_ui 14.19.0 → 14.20.0.pre.alpha.PLAY2170checkboxrailsindeterminatelogicinkitPOC7980
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +11 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableActionBar.tsx +175 -16
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +56 -25
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +23 -13
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/VisibilityTree.ts +47 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +6 -10
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +7 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +16 -8
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +9 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta.md +6 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.jsx +57 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility.md +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.jsx +62 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_custom.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.jsx +82 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_multi.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.jsx +66 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_visibility_with_state.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_default.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.html.erb +137 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_actions_rails.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.html.erb +40 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_selectable_rows_header_rails.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +6 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +5 -1
- data/app/pb_kits/playbook/pb_advanced_table/index.js +155 -12
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.html.erb +23 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.rb +19 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +4 -0
- data/app/pb_kits/playbook/pb_checkbox/checkbox.html.erb +8 -12
- data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +3 -6
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate.html.erb +2 -48
- data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_indeterminate_rails.md +1 -0
- data/app/pb_kits/playbook/pb_checkbox/index.js +56 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +1 -1
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +77 -19
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.html.erb +31 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.md +5 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.jsx +56 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.jsx +58 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.html.erb +20 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.html.erb +19 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.html.erb +20 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.jsx +57 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.html.erb +50 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.jsx +105 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.html.erb +22 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.jsx +67 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +11 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.md +1 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +33 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.md +3 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +11 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +5 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +16 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +108 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.html.erb +34 -13
- data/app/pb_kits/playbook/pb_dropdown/dropdown_trigger.rb +3 -1
- data/app/pb_kits/playbook/pb_dropdown/hooks/useHandleOnKeydown.tsx +0 -6
- data/app/pb_kits/playbook/pb_dropdown/index.js +336 -30
- data/app/pb_kits/playbook/pb_dropdown/keyboard_accessibility.js +39 -12
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownContainer.tsx +2 -2
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +16 -12
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +79 -13
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/MultiSelectTriggerDisplay.tsx +58 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +13 -0
- data/app/pb_kits/playbook/pb_file_upload/_file_upload.tsx +11 -1
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.html.erb +1 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/_file_upload_error.jsx +41 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_file_upload/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +1 -0
- data/app/pb_kits/playbook/pb_file_upload/file_upload.rb +7 -1
- data/app/pb_kits/playbook/pb_file_upload/fileupload.test.js +18 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +1 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -0
- data/app/pb_kits/playbook/pb_form_group/_error_state_mixin.scss +2 -2
- data/app/pb_kits/playbook/pb_form_pill/_form_pill.scss +19 -12
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +13 -7
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +2 -2
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_color.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_color.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent_default.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_disabled_options_parent_default.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_error.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_label.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_react_hook.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_reset.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_return_all_selected.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.html.erb +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids.md +2 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids_react.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_selected_ids_react.md +3 -1
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.html.erb +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single.jsx +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single_children_only.html.erb +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_single_children_only.jsx +22 -22
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_children_with_radios.jsx +11 -11
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_with_form.html.erb +11 -11
- data/app/pb_kits/playbook/pb_person/_person.tsx +12 -2
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.scss +9 -9
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +4 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.html.erb +4 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.jsx +15 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_exclude_countries.md +1 -0
- data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_only_countries.jsx +1 -1
- data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +4 -3
- data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_phone_number_input/phone_number_input.rb +3 -0
- data/app/pb_kits/playbook/pb_section_separator/_section_separator.tsx +2 -2
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.html.erb +12 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.jsx +31 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_custom_select_subheaders.md +1 -0
- data/app/pb_kits/playbook/pb_select/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +4 -2
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +73 -3
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_preserve_input.jsx +23 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_preserve_input.md +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_typeahead/docs/index.js +1 -0
- data/dist/chunks/_typeahead-CRW6dJbW.js +22 -0
- data/dist/chunks/_weekday_stacked-C4d17aYW.js +45 -0
- data/dist/chunks/lazysizes-B7xYodB-.js +1 -0
- data/dist/chunks/lib-D5R1BjUn.js +29 -0
- data/dist/chunks/{pb_form_validation-BioH7DWv.js → pb_form_validation-BZ2AVAi_.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/menu.yml +1 -1
- data/dist/playbook-doc.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/kit_base.rb +3 -3
- data/lib/playbook/version.rb +2 -2
- metadata +52 -8
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.html.erb +0 -10
- data/dist/chunks/_typeahead-D62OcwsT.js +0 -22
- data/dist/chunks/_weekday_stacked-Ceh9N0ow.js +0 -45
- data/dist/chunks/lazysizes-DHz07jlL.js +0 -1
- data/dist/chunks/lib-CeKZrPmu.js +0 -29
@@ -79,7 +79,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
79
79
|
}
|
80
80
|
if (!allChildrenChecked) {
|
81
81
|
parentRow.classList.remove("bg-row-selection");
|
82
|
-
|
82
|
+
|
83
83
|
if (this.isRowExpanded(parentRow)) {
|
84
84
|
parentRow.classList.remove("bg-silver");
|
85
85
|
parentRow.classList.add("bg-white");
|
@@ -201,15 +201,15 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
201
201
|
this.toggleElement(this.target);
|
202
202
|
}
|
203
203
|
});
|
204
|
-
|
204
|
+
|
205
205
|
this.hideCloseIcon();
|
206
|
-
|
206
|
+
|
207
207
|
const table = this.element.closest("table");
|
208
|
-
|
208
|
+
|
209
209
|
// Prevent duplicate initialization
|
210
210
|
if (table.dataset.pbAdvancedTableInitialized) return;
|
211
211
|
table.dataset.pbAdvancedTableInitialized = "true";
|
212
|
-
|
212
|
+
|
213
213
|
// Bind checkbox change handlers for all row checkboxes
|
214
214
|
const checkboxLabels = table.querySelectorAll("label[data-row-id]");
|
215
215
|
checkboxLabels.forEach((label) => {
|
@@ -219,7 +219,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
219
219
|
this.handleCheckboxClick(event);
|
220
220
|
});
|
221
221
|
});
|
222
|
-
|
222
|
+
|
223
223
|
// Bind nested row expansion logic
|
224
224
|
const nestedButtons = table.querySelectorAll("[data-advanced-table]");
|
225
225
|
nestedButtons.forEach((button) => {
|
@@ -233,18 +233,18 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
233
233
|
}
|
234
234
|
});
|
235
235
|
});
|
236
|
-
|
236
|
+
|
237
237
|
// Bind select-all logic for this table
|
238
238
|
const selectAllCheckbox = table.querySelector("#select-all-rows");
|
239
239
|
if (selectAllCheckbox) {
|
240
240
|
selectAllCheckbox.addEventListener("change", () => {
|
241
241
|
const checkboxInput = selectAllCheckbox.querySelector('input[type="checkbox"]');
|
242
242
|
const checkAll = checkboxInput.checked;
|
243
|
-
|
243
|
+
|
244
244
|
const checkboxes = Array.from(
|
245
245
|
table.querySelectorAll("label[data-row-id] input[type='checkbox']")
|
246
246
|
);
|
247
|
-
|
247
|
+
|
248
248
|
checkboxes.forEach((cb) => {
|
249
249
|
cb.checked = checkAll;
|
250
250
|
const rowId = cb.id;
|
@@ -260,14 +260,14 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
260
260
|
rowEl?.classList.add("bg-white");
|
261
261
|
}
|
262
262
|
});
|
263
|
-
|
263
|
+
|
264
264
|
checkboxes.forEach((cb) => this.updateParentCheckboxes(cb));
|
265
|
-
|
265
|
+
|
266
266
|
this.updateTableSelectedRowsAttribute();
|
267
267
|
});
|
268
268
|
}
|
269
269
|
}
|
270
|
-
|
270
|
+
|
271
271
|
|
272
272
|
hideCloseIcon() {
|
273
273
|
const closeIcon = this.element.querySelector(UP_ARROW_SELECTOR);
|
@@ -449,6 +449,149 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
449
449
|
}
|
450
450
|
}
|
451
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.classList.remove("p_none");
|
573
|
+
actionBar.classList.add("p_xs", "is-visible", "show-action-card");
|
574
|
+
|
575
|
+
// Update the count
|
576
|
+
const countElement = actionBar.querySelector(".selected-count");
|
577
|
+
if (countElement) {
|
578
|
+
countElement.textContent = `${selectedCount} Selected`;
|
579
|
+
}
|
580
|
+
}
|
581
|
+
|
582
|
+
hideActionBar(actionBar) {
|
583
|
+
// Hide action bar directly
|
584
|
+
actionBar.style.height = '0px';
|
585
|
+
actionBar.style.overflow = 'hidden';
|
586
|
+
actionBar.style.opacity = '0';
|
587
|
+
actionBar.classList.add("p_none");
|
588
|
+
actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
|
589
|
+
}
|
590
|
+
}
|
591
|
+
|
592
|
+
// Initialize the isolated action bar functionality
|
593
|
+
new PbAdvancedTableActionBar();
|
594
|
+
|
452
595
|
window.expandAllRows = (element) => {
|
453
596
|
PbAdvancedTable.handleToggleAllHeaders(element);
|
454
597
|
};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<%= pb_rails("card", props: {
|
2
|
+
border_none: object.is_visible,
|
3
|
+
classname: object.classname,
|
4
|
+
padding: object.is_visible ? "xs" : "none",
|
5
|
+
data: {
|
6
|
+
action_bar: true
|
7
|
+
}
|
8
|
+
}) do %>
|
9
|
+
<%= pb_rails("flex", props: { align_items: "center", justify: "between" }) do %>
|
10
|
+
<%= pb_rails("caption", props: { color: "light", padding_left: "xs", size: "xs" }) do %>
|
11
|
+
<span class="selected-count"><%= object.selected_count %> Selected</span>
|
12
|
+
<% end %>
|
13
|
+
<%= pb_rails("flex/flex_item") do %>
|
14
|
+
<%= pb_rails("flex") do %>
|
15
|
+
<% if object.actions.present? %>
|
16
|
+
<% object.actions.each do |action| %>
|
17
|
+
<%= action %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
23
|
+
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Playbook
|
4
|
+
module PbAdvancedTable
|
5
|
+
class TableActionBar < Playbook::KitBase
|
6
|
+
prop :actions, type: Playbook::Props::Array,
|
7
|
+
default: []
|
8
|
+
prop :is_visible, type: Playbook::Props::Boolean,
|
9
|
+
default: false
|
10
|
+
prop :selected_count, type: Playbook::Props::Number,
|
11
|
+
default: 0
|
12
|
+
|
13
|
+
def classname
|
14
|
+
# Just use row-selection-actions-card as the base class
|
15
|
+
generate_classname("row-selection-actions-card", separator: " ")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -15,6 +15,8 @@ module Playbook
|
|
15
15
|
default: "scroll"
|
16
16
|
prop :selectable_rows, type: Playbook::Props::Boolean,
|
17
17
|
default: false
|
18
|
+
prop :show_actions_bar, type: Playbook::Props::Boolean,
|
19
|
+
default: true
|
18
20
|
|
19
21
|
def classname
|
20
22
|
additional_classes = []
|
@@ -27,6 +29,7 @@ module Playbook
|
|
27
29
|
def th_classname(is_first_column: false)
|
28
30
|
additional_classes = []
|
29
31
|
additional_classes << "pinned-left" if is_first_column && responsive == "scroll" && !selectable_rows
|
32
|
+
additional_classes << "header-cells-with-actions" if selectable_rows && show_actions_bar
|
30
33
|
|
31
34
|
generate_classname("table-header-cells", *additional_classes, separator: " ")
|
32
35
|
end
|
@@ -46,6 +49,7 @@ module Playbook
|
|
46
49
|
if selectable_rows
|
47
50
|
additional_classes = []
|
48
51
|
additional_classes << "table-header-cells-custom"
|
52
|
+
additional_classes << "header-cells-with-actions" if show_actions_bar
|
49
53
|
additional_classes << "checkbox-cell-header"
|
50
54
|
additional_classes << "pinned-left" if responsive == "scroll"
|
51
55
|
pb_rails("table/table_header", props: {
|
@@ -1,16 +1,12 @@
|
|
1
|
-
<%= pb_content_tag(:label
|
1
|
+
<%= pb_content_tag(:label, data: {
|
2
|
+
pb_checkbox_indeterminate_main: object.indeterminate_main,
|
3
|
+
pb_checkbox_indeterminate_parent: object.indeterminate_parent,
|
4
|
+
}) do %>
|
2
5
|
<%= content.presence || object.input %>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
</span>
|
8
|
-
<% else %>
|
9
|
-
<span data-pb-checkbox-icon-span="true" class="pb_checkbox_checkmark">
|
10
|
-
<%= pb_rails("icon", props: { icon: "check", classname: "check_icon", fixed_width: true}) %>
|
11
|
-
<%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon hidden", fixed_width: true}) %>
|
12
|
-
</span>
|
13
|
-
<% end %>
|
6
|
+
<span data-pb-checkbox-icon-span="true" class="pb_checkbox_checkmark">
|
7
|
+
<%= pb_rails("icon", props: { icon: "check", classname: "check_icon", fixed_width: true}) %>
|
8
|
+
<%= pb_rails("icon", props: { icon: "minus", classname: "indeterminate_icon hidden", fixed_width: true}) %>
|
9
|
+
</span>
|
14
10
|
<span class="pb_checkbox_label">
|
15
11
|
<%= pb_rails("body", props: { status: object.checkbox_label_status, text: object.text, dark: object.dark, margin_right: object.form_spacing ? "xs" : "" }) %>
|
16
12
|
</span>
|
@@ -5,7 +5,8 @@ module Playbook
|
|
5
5
|
class Checkbox < Playbook::KitBase
|
6
6
|
prop :error, type: Playbook::Props::Boolean, default: false
|
7
7
|
prop :checked, type: Playbook::Props::Boolean, default: false
|
8
|
-
prop :
|
8
|
+
prop :indeterminate_main, type: Playbook::Props::Boolean, default: false
|
9
|
+
prop :indeterminate_parent
|
9
10
|
prop :text
|
10
11
|
prop :value
|
11
12
|
prop :name
|
@@ -19,7 +20,7 @@ module Playbook
|
|
19
20
|
default: false
|
20
21
|
|
21
22
|
def classname
|
22
|
-
generate_classname("pb_checkbox_kit", checked_class) +
|
23
|
+
generate_classname("pb_checkbox_kit", checked_class) + error_class
|
23
24
|
end
|
24
25
|
|
25
26
|
def input
|
@@ -39,10 +40,6 @@ module Playbook
|
|
39
40
|
def checked_class
|
40
41
|
checked ? "on" : "off"
|
41
42
|
end
|
42
|
-
|
43
|
-
def indeterminate_class
|
44
|
-
indeterminate ? " indeterminate" : ""
|
45
|
-
end
|
46
43
|
end
|
47
44
|
end
|
48
45
|
end
|
@@ -9,11 +9,10 @@
|
|
9
9
|
<tr>
|
10
10
|
<th>
|
11
11
|
<%= pb_rails("checkbox", props: {
|
12
|
-
checked: true,
|
13
12
|
text: "Uncheck All",
|
14
13
|
value: "checkbox-value",
|
15
14
|
name: "main-checkbox",
|
16
|
-
|
15
|
+
indeterminate_main: true,
|
17
16
|
id: "indeterminate-checkbox"
|
18
17
|
}) %>
|
19
18
|
</th>
|
@@ -30,55 +29,10 @@
|
|
30
29
|
value: checkbox[:id],
|
31
30
|
name: "#{checkbox[:id]}-indeterminate-checkbox",
|
32
31
|
id: "#{checkbox[:id]}-indeterminate-checkbox",
|
32
|
+
indeterminate_parent: "indeterminate-checkbox",
|
33
33
|
}) %>
|
34
34
|
</td>
|
35
35
|
</tr>
|
36
36
|
<% end %>
|
37
37
|
</tbody>
|
38
38
|
<% end %>
|
39
|
-
|
40
|
-
<script>
|
41
|
-
document.addEventListener('DOMContentLoaded', function() {
|
42
|
-
const mainCheckboxWrapper = document.getElementById('indeterminate-checkbox');
|
43
|
-
const mainCheckbox = document.getElementsByName("main-checkbox")[0];
|
44
|
-
const childCheckboxes = document.querySelectorAll('input[type="checkbox"][id$="indeterminate-checkbox"]');
|
45
|
-
|
46
|
-
const updateMainCheckbox = () => {
|
47
|
-
// Count the number of checked child checkboxes
|
48
|
-
const checkedCount = Array.from(childCheckboxes).filter(cb => cb.checked).length;
|
49
|
-
// Determine if the main checkbox should be in an indeterminate state
|
50
|
-
const indeterminate = checkedCount > 0 && checkedCount < childCheckboxes.length;
|
51
|
-
|
52
|
-
// Set the main checkbox states
|
53
|
-
mainCheckbox.indeterminate = indeterminate;
|
54
|
-
mainCheckbox.checked = checkedCount > 0;
|
55
|
-
|
56
|
-
// Determine the main checkbox label based on the number of checked checkboxes
|
57
|
-
const text = checkedCount === 0 ? 'Check All' : 'Uncheck All';
|
58
|
-
|
59
|
-
// Determine the icon class to add and remove based on the number of checked checkboxes
|
60
|
-
const iconClassToAdd = checkedCount === 0 ? 'pb_checkbox_checkmark' : 'pb_checkbox_indeterminate';
|
61
|
-
const iconClassToRemove = checkedCount === 0 ? 'pb_checkbox_indeterminate' : 'pb_checkbox_checkmark';
|
62
|
-
|
63
|
-
// Update main checkbox label
|
64
|
-
mainCheckboxWrapper.getElementsByClassName('pb_body_kit')[0].textContent = text;
|
65
|
-
|
66
|
-
// Add and remove the icon class to the main checkbox wrapper
|
67
|
-
mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.add(iconClassToAdd);
|
68
|
-
mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.remove(iconClassToRemove);
|
69
|
-
|
70
|
-
// Toggle the visibility of the checkbox icon based on the indeterminate state
|
71
|
-
mainCheckboxWrapper.getElementsByClassName("indeterminate_icon")[0].classList.toggle('hidden', !indeterminate);
|
72
|
-
mainCheckboxWrapper.getElementsByClassName("check_icon")[0].classList.toggle('hidden', indeterminate);
|
73
|
-
};
|
74
|
-
|
75
|
-
mainCheckbox.addEventListener('change', function() {
|
76
|
-
childCheckboxes.forEach(cb => cb.checked = this.checked);
|
77
|
-
updateMainCheckbox();
|
78
|
-
});
|
79
|
-
|
80
|
-
childCheckboxes.forEach(cb => {
|
81
|
-
cb.addEventListener('change', updateMainCheckbox);
|
82
|
-
});
|
83
|
-
});
|
84
|
-
</script>
|
@@ -0,0 +1 @@
|
|
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.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import PbEnhancedElement from "../pb_enhanced_element"
|
2
|
+
|
3
|
+
const INDETERMINATE_MAIN_CHECKBOX_SELECTOR = "[data-pb-checkbox-indeterminate-main='true']"
|
4
|
+
|
5
|
+
export default class PbCheckbox extends PbEnhancedElement {
|
6
|
+
static get selector() {
|
7
|
+
return INDETERMINATE_MAIN_CHECKBOX_SELECTOR
|
8
|
+
}
|
9
|
+
|
10
|
+
connect() {
|
11
|
+
const mainCheckboxWrapper = this.element;
|
12
|
+
const mainCheckbox = mainCheckboxWrapper.querySelector('input')
|
13
|
+
const childCheckboxes = document.querySelectorAll(`[data-pb-checkbox-indeterminate-parent="${this.element.id}"] input[type="checkbox"]`);
|
14
|
+
|
15
|
+
const updateMainCheckbox = () => {
|
16
|
+
// Count the number of checked child checkboxes
|
17
|
+
const checkedCount = Array.from(childCheckboxes).filter(cb => cb.checked).length;
|
18
|
+
// Determine if the main checkbox should be in an indeterminate state
|
19
|
+
const indeterminate = checkedCount > 0 && checkedCount < childCheckboxes.length;
|
20
|
+
|
21
|
+
// Set the main checkbox states
|
22
|
+
mainCheckbox.indeterminate = indeterminate;
|
23
|
+
mainCheckbox.checked = checkedCount > 0;
|
24
|
+
|
25
|
+
// Determine the main checkbox label based on the number of checked checkboxes
|
26
|
+
const text = checkedCount === 0 ? 'Check All' : 'Uncheck All';
|
27
|
+
|
28
|
+
// Determine the icon class to add and remove based on the number of checked checkboxes
|
29
|
+
const iconClassToAdd = checkedCount === 0 ? 'pb_checkbox_checkmark' : 'pb_checkbox_indeterminate';
|
30
|
+
const iconClassToRemove = checkedCount === 0 ? 'pb_checkbox_indeterminate' : 'pb_checkbox_checkmark';
|
31
|
+
|
32
|
+
// Update main checkbox label
|
33
|
+
mainCheckboxWrapper.getElementsByClassName('pb_body_kit')[0].textContent = text;
|
34
|
+
|
35
|
+
// Add and remove the icon class to the main checkbox wrapper
|
36
|
+
mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.add(iconClassToAdd);
|
37
|
+
mainCheckboxWrapper.querySelector('[data-pb-checkbox-icon-span]').classList.remove(iconClassToRemove);
|
38
|
+
|
39
|
+
// Toggle the visibility of the checkbox icon based on the indeterminate state
|
40
|
+
mainCheckboxWrapper.getElementsByClassName("indeterminate_icon")[0].classList.toggle('hidden', !indeterminate);
|
41
|
+
mainCheckboxWrapper.getElementsByClassName("check_icon")[0].classList.toggle('hidden', indeterminate);
|
42
|
+
};
|
43
|
+
|
44
|
+
// Set indeterminate icon on main checkbox if initial children checkboxes are checked
|
45
|
+
updateMainCheckbox();
|
46
|
+
|
47
|
+
this.element.querySelector('input').addEventListener('change', function() {
|
48
|
+
childCheckboxes.forEach(cb => cb.checked = this.checked);
|
49
|
+
updateMainCheckbox();
|
50
|
+
});
|
51
|
+
|
52
|
+
childCheckboxes.forEach(cb => {
|
53
|
+
cb.addEventListener('change', updateMainCheckbox);
|
54
|
+
});
|
55
|
+
}
|
56
|
+
}
|