playbook_ui 16.3.0 → 16.4.0.pre.alpha.PLAY2846reactadvancedtablecalcheaderpinnedrows15356
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/CustomCell.tsx +17 -4
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +3 -1
- data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +5 -2
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableActions.ts +21 -9
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +5 -2
- data/app/pb_kits/playbook/pb_advanced_table/SubKits/TableHeader.tsx +9 -11
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/ExpansionControlHelpers.tsx +25 -1
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/RowModelUtils.ts +100 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +65 -1
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +12 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.rb +9 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +109 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_cascade_collapse.jsx +50 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_cascade_collapse.md +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_rails.html.erb +57 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_rails.md +7 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_parent_only.jsx +175 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_sort_parent_only.md +5 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +3 -1
- data/app/pb_kits/playbook/pb_advanced_table/index.js +130 -29
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/advanced_table_sticky_mixin.scss +6 -2
- data/app/pb_kits/playbook/pb_advanced_table/table_body.html.erb +21 -4
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +115 -9
- data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +3 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +12 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.html.erb +4 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.rb +9 -1
- data/app/pb_kits/playbook/pb_button/_button_mixins.scss +6 -1
- data/app/pb_kits/playbook/pb_button/docs/_button_full_width_rails.md +19 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_full_width_react.md +23 -0
- data/app/pb_kits/playbook/pb_circle_icon_button/_circle_icon_button.scss +5 -0
- data/app/pb_kits/playbook/pb_collapsible/index.js +15 -26
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +3 -1
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.html.erb +1 -1
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_compound_components.jsx +6 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height.jsx +6 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height_placement.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dialog/docs/_dialog_full_height_placement.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.scss +3 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_closing_options_rails.html.erb +16 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_closing_options_rails.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_event_type.html.erb +224 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_custom_event_type.md +7 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_dropdown/dropdown.rb +8 -1
- data/app/pb_kits/playbook/pb_dropdown/index.js +255 -46
- data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +19 -14
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.scss +4 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +3 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_nav_margin.html.erb +46 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_nav_margin.jsx +42 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_nav_margin_rails.md +1 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_nav_margin_react.md +1 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +7 -1
- data/app/pb_kits/playbook/pb_icon/icon.rb +7 -1
- data/app/pb_kits/playbook/pb_list/_list_mixin.scss +4 -4
- data/app/pb_kits/playbook/pb_multi_level_select/_helper_functions.tsx +1 -1
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +27 -16
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.html.erb +109 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.jsx +127 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_placeholder.md +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_multi_level_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.rb +3 -0
- data/app/pb_kits/playbook/pb_multi_level_select/multi_level_select.test.jsx +27 -0
- data/app/pb_kits/playbook/pb_popover/docs/_popover_placement.jsx +81 -0
- data/app/pb_kits/playbook/pb_popover/docs/_popover_placement_react.md +1 -0
- data/app/pb_kits/playbook/pb_popover/docs/_popover_position.html.erb +128 -0
- data/app/pb_kits/playbook/pb_popover/docs/_popover_position_rails.md +1 -0
- data/app/pb_kits/playbook/pb_popover/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_popover/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +35 -134
- data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_editor.tsx +51 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/_trix_editor.tsx +206 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.jsx +56 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.md +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +13 -21
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/index.js +0 -10
- data/app/pb_kits/playbook/pb_rich_text_editor/inlineFocus.ts +5 -4
- data/app/pb_kits/playbook/pb_selectable_list/_selectable_list.scss +19 -1
- data/app/pb_kits/playbook/pb_table/_table.tsx +24 -21
- data/app/pb_kits/playbook/pb_table/docs/_sections.yml +1 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.html.erb +45 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_external_filter_rails.md +39 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_variant_rails.md +2 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_with_card_title_props.jsx +152 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_with_card_title_props.md +17 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_with_card_title_props_rails.html.erb +121 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_filter_with_card_title_props_rails.md +17 -0
- data/app/pb_kits/playbook/pb_table/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_table/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_table/table.html.erb +17 -13
- data/app/pb_kits/playbook/pb_table/table.rb +8 -0
- data/app/pb_kits/playbook/pb_table/table.test.js +33 -0
- data/app/pb_kits/playbook/pb_textarea/_textarea.scss +4 -1
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.tsx +105 -3
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +20 -8
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.md +3 -0
- data/app/pb_kits/playbook/utilities/_hover.scss +6 -3
- data/app/pb_kits/playbook/utilities/domHelpers.ts +50 -0
- data/dist/chunks/{_pb_line_graph-CKBPxTmM.js → _pb_line_graph-D6s5rymw.js} +1 -1
- data/dist/chunks/_typeahead-BNp_YiTh.js +1 -0
- data/dist/chunks/componentRegistry-DRSp5D_e.js +1 -0
- data/dist/chunks/{globalProps-DLCfJwiU.js → globalProps-Ds_6HBhX.js} +1 -1
- data/dist/chunks/lib-BaO72ugL.js +29 -0
- data/dist/chunks/vendor.js +5 -5
- data/dist/menu.yml +3 -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/pb_forms_helper.rb +3 -0
- data/lib/playbook/version.rb +2 -2
- metadata +42 -32
- data/app/pb_kits/playbook/pb_button/docs/_button_full_width.md +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_attributes.html.erb +0 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_attributes.jsx +0 -15
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_default.html.erb +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_focus.html.erb +0 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_focus.jsx +0 -17
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_inline.html.erb +0 -6
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_inline.jsx +0 -16
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_label.jsx +0 -28
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_label.md +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_preview.html.erb +0 -35
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_preview.jsx +0 -45
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.html.erb +0 -10
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.jsx +0 -22
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_required_indicator.md +0 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_simple.html.erb +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_simple.jsx +0 -13
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_sticky.html.erb +0 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_sticky.jsx +0 -15
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_templates.html.erb +0 -115
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_templates.jsx +0 -42
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_toolbar_bottom.html.erb +0 -4
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_toolbar_bottom.jsx +0 -14
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +0 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +0 -63
- data/dist/chunks/_typeahead-B7bktFm6.js +0 -1
- data/dist/chunks/componentRegistry-DzmmLR2x.js +0 -1
- data/dist/chunks/lib-QT_7rPYf.js +0 -29
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import PbEnhancedElement from "../pb_enhanced_element";
|
|
2
2
|
import { updateSelectionActionBar } from "./advanced_table_action_bar";
|
|
3
|
+
import { setArrowVisibility, toggleVisibility } from "../utilities/domHelpers";
|
|
3
4
|
|
|
4
5
|
const ADVANCED_TABLE_SELECTOR = "[data-advanced-table]";
|
|
5
6
|
const DOWN_ARROW_SELECTOR = "#advanced-table_open_icon";
|
|
@@ -20,10 +21,18 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
20
21
|
this.childRowsMap = new Map();
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
get table() {
|
|
25
|
+
return this.cachedTable || (this.cachedTable = this.element.closest("table"));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get mainTable() {
|
|
29
|
+
return this.cachedMainTable || (this.cachedMainTable = this.element.closest(".pb_advanced_table"));
|
|
30
|
+
}
|
|
31
|
+
|
|
23
32
|
// Fetch and cache child rows for a given parent row ID
|
|
24
33
|
childRowsFor(parentId) {
|
|
25
34
|
if (!this.childRowsMap.has(parentId)) {
|
|
26
|
-
const table = this.
|
|
35
|
+
const table = this.table;
|
|
27
36
|
const rows = Array.from(
|
|
28
37
|
table.querySelectorAll(`tr[data-row-parent="${parentId}"]`)
|
|
29
38
|
);
|
|
@@ -33,7 +42,8 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
33
42
|
}
|
|
34
43
|
|
|
35
44
|
updateTableSelectedRowsAttribute() {
|
|
36
|
-
const mainTable = this.
|
|
45
|
+
const mainTable = this.mainTable;
|
|
46
|
+
if (!mainTable) return;
|
|
37
47
|
mainTable.dataset.selectedRows = JSON.stringify(
|
|
38
48
|
Array.from(PbAdvancedTable.selectedRows)
|
|
39
49
|
);
|
|
@@ -41,7 +51,8 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
41
51
|
|
|
42
52
|
// Recalculate selected count based on all checked checkboxes
|
|
43
53
|
recalculateSelectedCount() {
|
|
44
|
-
const table = this.
|
|
54
|
+
const table = this.table;
|
|
55
|
+
if (!table) return;
|
|
45
56
|
|
|
46
57
|
// Get all checkboxes that could be part of the selection
|
|
47
58
|
// This includes row checkboxes and any parent checkboxes that might be programmatically checked
|
|
@@ -95,7 +106,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
95
106
|
});
|
|
96
107
|
|
|
97
108
|
this.updateTableSelectedRowsAttribute();
|
|
98
|
-
updateSelectionActionBar(
|
|
109
|
+
updateSelectionActionBar(this.mainTable, PbAdvancedTable.selectedRows.size);
|
|
99
110
|
|
|
100
111
|
// Sync header select-all state
|
|
101
112
|
if (selectAllCheckbox) {
|
|
@@ -139,7 +150,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
139
150
|
|
|
140
151
|
this.updateTableSelectedRowsAttribute();
|
|
141
152
|
|
|
142
|
-
const table =
|
|
153
|
+
const table = this.table;
|
|
143
154
|
const selectAllCheckbox = table.querySelector("#select-all-rows");
|
|
144
155
|
|
|
145
156
|
if (selectAllCheckbox) {
|
|
@@ -153,7 +164,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
153
164
|
);
|
|
154
165
|
selectAllInput.checked = allChecked;
|
|
155
166
|
}
|
|
156
|
-
updateSelectionActionBar(
|
|
167
|
+
updateSelectionActionBar(this.mainTable, PbAdvancedTable.selectedRows.size);
|
|
157
168
|
}
|
|
158
169
|
|
|
159
170
|
get target() {
|
|
@@ -161,10 +172,11 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
161
172
|
}
|
|
162
173
|
|
|
163
174
|
connect() {
|
|
164
|
-
const table = this.
|
|
175
|
+
const table = this.table;
|
|
176
|
+
if (!table) return;
|
|
165
177
|
|
|
166
178
|
this.hideCloseIcon();
|
|
167
|
-
const mainTable = this.
|
|
179
|
+
const mainTable = this.mainTable;
|
|
168
180
|
|
|
169
181
|
// This so it is hidden on first render
|
|
170
182
|
if (mainTable) {
|
|
@@ -184,6 +196,17 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
184
196
|
if (table.dataset.pbAdvancedTableInitialized) return;
|
|
185
197
|
table.dataset.pbAdvancedTableInitialized = "true";
|
|
186
198
|
|
|
199
|
+
// Measure header height so pinned rows don't overlap when header wraps (e.g. mobile)
|
|
200
|
+
if (mainTable) {
|
|
201
|
+
PbAdvancedTable.updateStickyHeaderRowHeights(mainTable);
|
|
202
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
203
|
+
PbAdvancedTable.updateStickyHeaderRowHeights(mainTable);
|
|
204
|
+
PbAdvancedTable.updatePinnedRowsStickyTops(mainTable);
|
|
205
|
+
});
|
|
206
|
+
resizeObserver.observe(table);
|
|
207
|
+
mainTable._advancedTableHeaderResizeObserver = resizeObserver;
|
|
208
|
+
}
|
|
209
|
+
|
|
187
210
|
// Delegate checkbox changes
|
|
188
211
|
table.addEventListener("change", (event) => {
|
|
189
212
|
const checkbox = event.target.closest('input[type="checkbox"]');
|
|
@@ -271,9 +294,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
271
294
|
}
|
|
272
295
|
|
|
273
296
|
// Find direct child rows
|
|
274
|
-
const childRows =
|
|
275
|
-
table.querySelectorAll(`[data-row-parent="${toggleBtn.id}"]`)
|
|
276
|
-
);
|
|
297
|
+
const childRows = this.childRowsFor(toggleBtn.id);
|
|
277
298
|
this.toggleElement(childRows);
|
|
278
299
|
|
|
279
300
|
// Restore original element context
|
|
@@ -284,7 +305,8 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
284
305
|
}
|
|
285
306
|
|
|
286
307
|
addBorderRadiusOnLastVisibleRow() {
|
|
287
|
-
const parentElement = this.
|
|
308
|
+
const parentElement = this.mainTable;
|
|
309
|
+
if (!parentElement) return;
|
|
288
310
|
|
|
289
311
|
const table = document.getElementById(parentElement.id);
|
|
290
312
|
|
|
@@ -304,9 +326,64 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
304
326
|
lastVisibleRow.classList.add("last-visible-row");
|
|
305
327
|
lastVisibleRow.classList.add("last-row-cell");
|
|
306
328
|
}
|
|
329
|
+
|
|
330
|
+
PbAdvancedTable.updateStickyHeaderRowHeights(parentElement);
|
|
331
|
+
PbAdvancedTable.updatePinnedRowsStickyTops(table);
|
|
307
332
|
}
|
|
308
333
|
}
|
|
309
334
|
|
|
335
|
+
/**
|
|
336
|
+
* Measure thead height and set --advanced-table-header-height so pinned rows and
|
|
337
|
+
* multi-row sticky headers use the correct offset. Re-run when header wraps (e.g. mobile).
|
|
338
|
+
*/
|
|
339
|
+
static updateStickyHeaderRowHeights(advancedTableWrapper) {
|
|
340
|
+
if (!advancedTableWrapper) return;
|
|
341
|
+
const table = advancedTableWrapper.querySelector("table.pb_table");
|
|
342
|
+
const thead = table?.querySelector("thead");
|
|
343
|
+
if (!thead) return;
|
|
344
|
+
|
|
345
|
+
const rows = Array.from(thead.querySelectorAll("tr"));
|
|
346
|
+
let totalHeight = 0;
|
|
347
|
+
rows.forEach((tr, index) => {
|
|
348
|
+
const h = tr.offsetHeight;
|
|
349
|
+
if (index === 0) {
|
|
350
|
+
advancedTableWrapper.style.setProperty(
|
|
351
|
+
"--advanced-table-header-row-0-height",
|
|
352
|
+
`${h}px`
|
|
353
|
+
);
|
|
354
|
+
} else if (index === 1) {
|
|
355
|
+
advancedTableWrapper.style.setProperty(
|
|
356
|
+
"--advanced-table-header-row-1-height",
|
|
357
|
+
`${h}px`
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
totalHeight += h;
|
|
361
|
+
});
|
|
362
|
+
advancedTableWrapper.style.setProperty(
|
|
363
|
+
"--advanced-table-header-height",
|
|
364
|
+
`${totalHeight}px`
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Recompute sticky top for visible pinned rows so collapsed rows don't leave a gap.
|
|
370
|
+
* Call after expand/collapse and on load.
|
|
371
|
+
*/
|
|
372
|
+
static updatePinnedRowsStickyTops(advancedTableWrapper) {
|
|
373
|
+
const pinnedTbody = advancedTableWrapper?.querySelector("tbody.pinned-rows-tbody");
|
|
374
|
+
if (!pinnedTbody) return;
|
|
375
|
+
|
|
376
|
+
const pinnedRows = Array.from(pinnedTbody.querySelectorAll("tr.pinned-row"));
|
|
377
|
+
const visibleRows = pinnedRows.filter(
|
|
378
|
+
(tr) => tr.style.display !== "none" && tr.offsetParent !== null
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
const headerOffset = "var(--advanced-table-header-height, 44px)";
|
|
382
|
+
visibleRows.forEach((tr, index) => {
|
|
383
|
+
tr.style.top = `calc(${headerOffset} + 2.5em * ${index})`;
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
310
387
|
hideCloseIcon() {
|
|
311
388
|
const closeIcon = this.element.querySelector(UP_ARROW_SELECTOR);
|
|
312
389
|
closeIcon.style.display = "none";
|
|
@@ -316,11 +393,9 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
316
393
|
elements.forEach((elem) => {
|
|
317
394
|
elem.style.display = "table-row";
|
|
318
395
|
elem.classList.add("is-visible");
|
|
319
|
-
const childRowsAll = this.
|
|
320
|
-
.
|
|
321
|
-
|
|
322
|
-
`[data-advanced-table-content^="${elem.dataset.advancedTableContent}-"]`
|
|
323
|
-
);
|
|
396
|
+
const childRowsAll = this.table.querySelectorAll(
|
|
397
|
+
`[data-advanced-table-content^="${elem.dataset.advancedTableContent}-"]`
|
|
398
|
+
);
|
|
324
399
|
|
|
325
400
|
childRowsAll.forEach((childRow) => {
|
|
326
401
|
const dataContent = childRow.dataset.advancedTableContent;
|
|
@@ -382,8 +457,7 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
382
457
|
const currentDepth = parseInt(elem.dataset.rowDepth);
|
|
383
458
|
if (childrenArray.length > currentDepth) {
|
|
384
459
|
// Find the child rows corresponding to this parent row
|
|
385
|
-
const childRows = this.
|
|
386
|
-
.closest("table")
|
|
460
|
+
const childRows = this.table
|
|
387
461
|
.querySelectorAll(
|
|
388
462
|
`[data-advanced-table-content^="${elem.dataset.advancedTableContent}-"]`
|
|
389
463
|
);
|
|
@@ -401,28 +475,39 @@ export default class PbAdvancedTable extends PbEnhancedElement {
|
|
|
401
475
|
|
|
402
476
|
const isVisible = elements[0].classList.contains("is-visible");
|
|
403
477
|
|
|
404
|
-
|
|
405
|
-
|
|
478
|
+
const isExpanded = toggleVisibility({
|
|
479
|
+
isVisible,
|
|
480
|
+
onHide: () => this.hideElement(elements),
|
|
481
|
+
onShow: () => this.showElement(elements),
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
isExpanded ? this.displayUpArrow() : this.displayDownArrow();
|
|
406
485
|
|
|
407
486
|
const row = this.element.closest("tr");
|
|
408
487
|
if (row) {
|
|
409
|
-
row.classList.toggle("bg-silver",
|
|
410
|
-
row.classList.toggle("pb-bg-row-white",
|
|
488
|
+
row.classList.toggle("bg-silver", isExpanded);
|
|
489
|
+
row.classList.toggle("pb-bg-row-white", !isExpanded);
|
|
411
490
|
}
|
|
412
491
|
|
|
413
492
|
this.addBorderRadiusOnLastVisibleRow();
|
|
414
493
|
}
|
|
415
494
|
|
|
416
495
|
displayDownArrow() {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
496
|
+
setArrowVisibility({
|
|
497
|
+
rootElement: this.element,
|
|
498
|
+
downSelector: DOWN_ARROW_SELECTOR,
|
|
499
|
+
upSelector: UP_ARROW_SELECTOR,
|
|
500
|
+
showDownArrow: true,
|
|
501
|
+
});
|
|
420
502
|
}
|
|
421
503
|
|
|
422
504
|
displayUpArrow() {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
505
|
+
setArrowVisibility({
|
|
506
|
+
rootElement: this.element,
|
|
507
|
+
downSelector: DOWN_ARROW_SELECTOR,
|
|
508
|
+
upSelector: UP_ARROW_SELECTOR,
|
|
509
|
+
showDownArrow: false,
|
|
510
|
+
});
|
|
426
511
|
}
|
|
427
512
|
|
|
428
513
|
static handleToggleAllHeaders(element) {
|
|
@@ -500,3 +585,19 @@ window.expandAllRows = (element) => {
|
|
|
500
585
|
window.expandAllSubRows = (element, rowDepth) => {
|
|
501
586
|
PbAdvancedTable.handleToggleAllSubRows(element, rowDepth);
|
|
502
587
|
};
|
|
588
|
+
|
|
589
|
+
// Fix header height and pinned row sticky tops on load (header wrap + collapsed rows)
|
|
590
|
+
function updateAllAdvancedTableStickyHeights() {
|
|
591
|
+
document.querySelectorAll(".pb_advanced_table").forEach((wrapper) => {
|
|
592
|
+
PbAdvancedTable.updateStickyHeaderRowHeights(wrapper);
|
|
593
|
+
PbAdvancedTable.updatePinnedRowsStickyTops(wrapper);
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (typeof document !== "undefined") {
|
|
598
|
+
if (document.readyState === "loading") {
|
|
599
|
+
document.addEventListener("DOMContentLoaded", updateAllAdvancedTableStickyHeights);
|
|
600
|
+
} else {
|
|
601
|
+
updateAllAdvancedTableStickyHeights();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
// Acts as outer “card frame” on the advanced-table wrapper (table-card from Table) is included from `_advanced_table.scss` only when `:not(.advanced-table-no-table-container)`/container: false is not present.
|
|
2
|
+
@mixin advanced-table-sticky-wrapper-frame($border-color) {
|
|
3
|
+
border-radius: 4px;
|
|
4
|
+
box-shadow: 1px 0 0 0px $border-color, -1px 0 0 0px $border-color;
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
@mixin advanced-table-sticky-mixin(
|
|
2
8
|
$border-color,
|
|
3
9
|
$bg-main,
|
|
@@ -5,8 +11,6 @@
|
|
|
5
11
|
$highlight: #E5EEFA,
|
|
6
12
|
$highlight-dark: #202850,
|
|
7
13
|
) {
|
|
8
|
-
border-radius: 4px;
|
|
9
|
-
box-shadow: 1px 0 0 0px $border-color, -1px 0 0 0px $border-color;
|
|
10
14
|
display: block;
|
|
11
15
|
[class^="pb_table"].table-sm.table-card thead tr th:first-child,
|
|
12
16
|
[class^="pb_table"].table-sm:not(.no-hover).table-card
|
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<% table_data = object.table_data || [] %>
|
|
2
|
+
<% if object.has_pinned_rows? %>
|
|
3
|
+
<%= pb_content_tag(:tbody, class: "pinned-rows-tbody") do %>
|
|
4
|
+
<% next_index = 0 %>
|
|
5
|
+
<% object.pinned_root_rows.each do |root_info| %>
|
|
6
|
+
<% row_output, next_index = object.render_row_and_children(root_info[:row], object.column_definitions, root_info[:depth], root_info[:depth] > 0, root_info[:ancestor_ids] || [], root_info[:ancestor_ids]&.first, immediate_parent_row_id: object.row_id_for(root_info[:parent_row]), is_pinned_row: true, pinned_index: next_index, initial_table_data_attributes: root_info[:depth].to_i > 0 ? object.pinned_root_initial_data_attributes(root_info) : nil) %>
|
|
7
|
+
<%= row_output %>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<%= pb_content_tag(:tbody) do %>
|
|
11
|
+
<% table_data.each do |row| %>
|
|
12
|
+
<% result = object.render_row_and_children(row, object.column_definitions, 0, false, skip_pinned_ids: object.pinned_ids_set) %>
|
|
13
|
+
<%= result.is_a?(Array) ? result[0] : result %>
|
|
14
|
+
<% end %>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% else %>
|
|
17
|
+
<%= pb_content_tag(:tbody) do %>
|
|
18
|
+
<% table_data.each do |row| %>
|
|
19
|
+
<%= object.render_row_and_children(row, object.column_definitions, 0, false) %>
|
|
20
|
+
<% end %>
|
|
21
|
+
<% end %>
|
|
5
22
|
<% end %>
|
|
@@ -27,6 +27,8 @@ module Playbook
|
|
|
27
27
|
default: []
|
|
28
28
|
prop :inline_row_loading, type: Playbook::Props::Boolean,
|
|
29
29
|
default: false
|
|
30
|
+
prop :pinned_rows, type: Playbook::Props::HashProp,
|
|
31
|
+
default: {}
|
|
30
32
|
|
|
31
33
|
def flatten_columns(columns)
|
|
32
34
|
columns.flat_map do |col|
|
|
@@ -42,14 +44,21 @@ module Playbook
|
|
|
42
44
|
end.compact
|
|
43
45
|
end
|
|
44
46
|
|
|
45
|
-
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)
|
|
47
|
+
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, is_pinned_row: false, pinned_index: nil, skip_pinned_ids: nil, initial_table_data_attributes: nil)
|
|
48
|
+
if skip_pinned_ids && row_id_for(row) && skip_pinned_ids.include?(row_id_for(row).to_s)
|
|
49
|
+
return is_pinned_row ? [ActiveSupport::SafeBuffer.new, pinned_index] : ActiveSupport::SafeBuffer.new
|
|
50
|
+
end
|
|
51
|
+
|
|
46
52
|
top_parent_id ||= row.object_id
|
|
47
53
|
new_ancestor_ids = ancestor_ids + [row.object_id]
|
|
48
|
-
leaf_columns = flatten_columns(column_definitions)
|
|
54
|
+
leaf_columns = flatten_columns(column_definitions || [])
|
|
49
55
|
|
|
50
56
|
output = ActiveSupport::SafeBuffer.new
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
subrow_headers_arr = subrow_headers || []
|
|
58
|
+
is_first_child_of_subrow = current_depth.positive? && first_parent_child && subrow_headers_arr[current_depth - 1].present?
|
|
59
|
+
last_row = subrow_headers_arr.length == current_depth
|
|
60
|
+
|
|
61
|
+
next_pinned_index = pinned_index
|
|
53
62
|
|
|
54
63
|
subrow_ancestor_ids = ancestor_ids + ["#{row.object_id}sr"]
|
|
55
64
|
subrow_data_attributes = {
|
|
@@ -58,7 +67,16 @@ module Playbook
|
|
|
58
67
|
row_parent: "#{table_id}_#{ancestor_ids.last}",
|
|
59
68
|
}
|
|
60
69
|
# Subrow header if applicable
|
|
61
|
-
|
|
70
|
+
if is_first_child_of_subrow && enable_toggle_expansion == "all"
|
|
71
|
+
subrow_props = { row: row, column_definitions: leaf_columns, depth: current_depth, subrow_header: subrow_headers_arr[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 }
|
|
72
|
+
if is_pinned_row && next_pinned_index
|
|
73
|
+
subrow_props[:is_pinned_row] = true
|
|
74
|
+
subrow_props[:pinned_index] = next_pinned_index
|
|
75
|
+
subrow_props[:html_options] = { style: build_pinned_row_style(next_pinned_index, background: "var(--pb_table_sticky_bg, #f5f5f5)") }
|
|
76
|
+
next_pinned_index += 1
|
|
77
|
+
end
|
|
78
|
+
output << pb_rails("advanced_table/table_subrow_header", props: subrow_props)
|
|
79
|
+
end
|
|
62
80
|
|
|
63
81
|
current_data_attributes = if current_depth.zero?
|
|
64
82
|
{
|
|
@@ -67,11 +85,19 @@ module Playbook
|
|
|
67
85
|
row_parent: nil,
|
|
68
86
|
}
|
|
69
87
|
else
|
|
70
|
-
table_data_attributes
|
|
88
|
+
initial_table_data_attributes || table_data_attributes
|
|
71
89
|
end
|
|
72
90
|
|
|
73
91
|
# Additional class and data attributes needed for toggle logic
|
|
74
|
-
|
|
92
|
+
row_props = { table_id: table_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, inline_row_loading: inline_row_loading }
|
|
93
|
+
if is_pinned_row && next_pinned_index
|
|
94
|
+
row_props[:is_pinned_row] = true
|
|
95
|
+
row_props[:pinned_index] = next_pinned_index
|
|
96
|
+
row_bg = (row_styling || []).find { |s| s[:row_id].to_s == row_id_for(row).to_s }&.[](:background_color) || "white"
|
|
97
|
+
row_props[:html_options] = { style: build_pinned_row_style(next_pinned_index, background: row_bg) }
|
|
98
|
+
next_pinned_index += 1
|
|
99
|
+
end
|
|
100
|
+
output << pb_rails("advanced_table/table_row", props: row_props)
|
|
75
101
|
|
|
76
102
|
# Render inline loading row when inline_row_loading is enabled and row has empty children
|
|
77
103
|
if inline_row_loading
|
|
@@ -103,11 +129,21 @@ module Playbook
|
|
|
103
129
|
advanced_table_content: data_content,
|
|
104
130
|
}
|
|
105
131
|
|
|
106
|
-
|
|
132
|
+
child_opts = { additional_classes: "toggle-content", table_data_attributes: child_data_attributes, immediate_parent_row_id: row[:id] }
|
|
133
|
+
child_opts[:is_pinned_row] = is_pinned_row
|
|
134
|
+
child_opts[:pinned_index] = next_pinned_index if is_pinned_row
|
|
135
|
+
child_opts[:skip_pinned_ids] = skip_pinned_ids if skip_pinned_ids
|
|
136
|
+
|
|
137
|
+
child_output, next_pinned_index = render_row_and_children(child_row, column_definitions, current_depth + 1, is_first_child, new_ancestor_ids, top_parent_id, **child_opts)
|
|
138
|
+
output << child_output
|
|
107
139
|
end
|
|
108
140
|
end
|
|
109
141
|
|
|
110
|
-
|
|
142
|
+
if is_pinned_row
|
|
143
|
+
[output, next_pinned_index]
|
|
144
|
+
else
|
|
145
|
+
output
|
|
146
|
+
end
|
|
111
147
|
end
|
|
112
148
|
|
|
113
149
|
def classname
|
|
@@ -142,6 +178,76 @@ module Playbook
|
|
|
142
178
|
end
|
|
143
179
|
end
|
|
144
180
|
|
|
181
|
+
def row_id_for(row)
|
|
182
|
+
return nil if row.nil?
|
|
183
|
+
|
|
184
|
+
row[:id] || row["id"]
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def pinned_top_ids
|
|
188
|
+
return [] if pinned_rows.nil? || !pinned_rows.respond_to?(:[])
|
|
189
|
+
|
|
190
|
+
top = pinned_rows["top"] || pinned_rows[:top]
|
|
191
|
+
Array(top).map(&:to_s)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def pinned_ids_set
|
|
195
|
+
return Set.new if pinned_top_ids.blank?
|
|
196
|
+
|
|
197
|
+
set = Set.new
|
|
198
|
+
pinned_root_rows.each do |root|
|
|
199
|
+
collect_row_and_descendant_ids(root[:row], set)
|
|
200
|
+
end
|
|
201
|
+
set
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def collect_row_and_descendant_ids(row, set)
|
|
205
|
+
id = row_id_for(row)
|
|
206
|
+
set.add(id.to_s) if id
|
|
207
|
+
row_children_for(row)&.each { |child| collect_row_and_descendant_ids(child, set) }
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def find_row_by_id(data, id, depth: 0, ancestor_ids: [], parent_row: nil)
|
|
211
|
+
id_str = id.to_s
|
|
212
|
+
Array(data).each do |row|
|
|
213
|
+
return { row: row, depth: depth, ancestor_ids: ancestor_ids, parent_row: parent_row } if row_id_for(row).to_s == id_str
|
|
214
|
+
|
|
215
|
+
found = find_row_by_id(row_children_for(row), id_str, depth: depth + 1, ancestor_ids: ancestor_ids + [row.object_id], parent_row: row)
|
|
216
|
+
return found if found
|
|
217
|
+
end
|
|
218
|
+
nil
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def pinned_root_rows
|
|
222
|
+
return [] if pinned_top_ids.blank?
|
|
223
|
+
|
|
224
|
+
pinned_top_ids.filter_map { |id| find_row_by_id(table_data, id) }
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def has_pinned_rows?
|
|
228
|
+
pinned_root_rows.any?
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Build inline style for sticky pinned row (matches React). Pass via html_options so the tr gets the attribute.
|
|
232
|
+
def build_pinned_row_style(pinned_index, background: "white")
|
|
233
|
+
header_offset = "var(--advanced-table-header-height, 44px)"
|
|
234
|
+
row_offset = "calc(2.5em * #{pinned_index})"
|
|
235
|
+
"position: sticky; top: calc(#{header_offset} + #{row_offset}); z-index: 3; background: #{background};"
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def pinned_root_initial_data_attributes(root_info)
|
|
239
|
+
return {} if root_info[:depth].to_i.zero?
|
|
240
|
+
|
|
241
|
+
anc = root_info[:ancestor_ids] || []
|
|
242
|
+
content = (anc + [root_info[:row].object_id]).join("-")
|
|
243
|
+
{
|
|
244
|
+
top_parent: "#{table_id}_#{anc.first}",
|
|
245
|
+
row_depth: root_info[:depth],
|
|
246
|
+
row_parent: "#{table_id}_#{anc.last}",
|
|
247
|
+
advanced_table_content: content,
|
|
248
|
+
}
|
|
249
|
+
end
|
|
250
|
+
|
|
145
251
|
def cell_accessors_length(col_defs)
|
|
146
252
|
first_col = col_defs.first
|
|
147
253
|
return 0 unless first_col
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
button_color = row_style&.[](:expand_button_color)
|
|
4
4
|
bg_color = row_style&.[](:background_color)
|
|
5
5
|
font_color = row_style&.[](:font_color)
|
|
6
|
+
tr_options = (object.html_options || {}).stringify_keys
|
|
7
|
+
tr_options["class"] = [tr_options["class"], object.classname].reject(&:blank?).join(" ")
|
|
6
8
|
%>
|
|
7
9
|
|
|
8
|
-
<%= pb_content_tag(:tr) do %>
|
|
10
|
+
<%= pb_content_tag(:tr, tr_options) do %>
|
|
9
11
|
<% has_separate_checkbox = object.selectable_rows && object.enable_toggle_expansion == "none" %>
|
|
10
12
|
<% if has_separate_checkbox %>
|
|
11
13
|
<%= object.render_checkbox_cell %>
|
|
@@ -35,13 +35,24 @@ module Playbook
|
|
|
35
35
|
default: ""
|
|
36
36
|
prop :inline_row_loading, type: Playbook::Props::Boolean,
|
|
37
37
|
default: false
|
|
38
|
+
prop :is_pinned_row, type: Playbook::Props::Boolean,
|
|
39
|
+
default: false
|
|
40
|
+
prop :pinned_index, type: Playbook::Props::Numeric,
|
|
41
|
+
default: nil
|
|
42
|
+
prop :html_options, type: Playbook::Props::HashProp,
|
|
43
|
+
default: {}
|
|
44
|
+
prop :classname, type: Playbook::Props::String,
|
|
45
|
+
default: ""
|
|
38
46
|
|
|
39
47
|
def data
|
|
40
48
|
Hash(prop(:data)).merge(table_data_attributes)
|
|
41
49
|
end
|
|
42
50
|
|
|
43
51
|
def classname
|
|
44
|
-
|
|
52
|
+
classes = ["pb_table_tr", "pb-bg-row-white", subrow_depth_classname]
|
|
53
|
+
classes << "pinned-row" if is_pinned_row
|
|
54
|
+
classes.reject!(&:blank?)
|
|
55
|
+
generate_classname(*classes, separator: " ")
|
|
45
56
|
end
|
|
46
57
|
|
|
47
58
|
def td_classname(column, index)
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
<% tr_options = (object.html_options || {}).stringify_keys %>
|
|
2
|
+
<% tr_options["class"] = [tr_options["class"], object.classname].reject(&:blank?).join(" ") %>
|
|
3
|
+
|
|
4
|
+
<%= pb_content_tag(:tr, tr_options) do %>
|
|
2
5
|
<% object.column_definitions.each_with_index do |column, index| %>
|
|
3
6
|
<%= pb_rails("table/table_cell", props: { classname: object.td_classname(index) }) do %>
|
|
4
7
|
<%= pb_rails("flex", props:{ align: "center", justify: "start" }) do %>
|
|
@@ -19,13 +19,21 @@ module Playbook
|
|
|
19
19
|
prop :responsive, type: Playbook::Props::Enum,
|
|
20
20
|
values: %w[none scroll],
|
|
21
21
|
default: "scroll"
|
|
22
|
+
prop :is_pinned_row, type: Playbook::Props::Boolean,
|
|
23
|
+
default: false
|
|
24
|
+
prop :pinned_index, type: Playbook::Props::Numeric,
|
|
25
|
+
default: nil
|
|
26
|
+
prop :html_options, type: Playbook::Props::HashProp,
|
|
27
|
+
default: {}
|
|
22
28
|
|
|
23
29
|
def data
|
|
24
30
|
Hash(prop(:data)).merge(subrow_data_attributes)
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
def classname
|
|
28
|
-
|
|
34
|
+
classes = ["pb_table_tr", "bg-silver", "pb_subrow_header", subrow_depth_classname]
|
|
35
|
+
classes << "pinned-row" if is_pinned_row
|
|
36
|
+
generate_classname(*classes, separator: " ")
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
def td_classname(index)
|
|
@@ -57,7 +57,7 @@ $pb_button_border_width: 0px;
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
.loading-icon {
|
|
60
|
-
position:
|
|
60
|
+
position: static;
|
|
61
61
|
display: none;
|
|
62
62
|
}
|
|
63
63
|
.pb_button_content {
|
|
@@ -158,10 +158,15 @@ $pb_button_border_width: 0px;
|
|
|
158
158
|
// Loading =====================
|
|
159
159
|
@mixin pb_button_loading($loading: false) {
|
|
160
160
|
@if $loading == true {
|
|
161
|
+
display: inline-grid;
|
|
162
|
+
place-items: center;
|
|
163
|
+
|
|
161
164
|
.loading-icon {
|
|
165
|
+
grid-area: 1 / 1;
|
|
162
166
|
display: block;
|
|
163
167
|
}
|
|
164
168
|
.pb_button_content {
|
|
169
|
+
grid-area: 1 / 1;
|
|
165
170
|
visibility: hidden;
|
|
166
171
|
}
|
|
167
172
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
This button is used many times for mobile or other things like cards and sidebars.
|
|
2
|
+
|
|
3
|
+
### Responsive `display` and `full_width`
|
|
4
|
+
|
|
5
|
+
`full_width` applies block styling that includes `display: flex` on the **same element** as the button. The **`display` global prop** also sets `display` (via utility classes, often with `!important`).
|
|
6
|
+
|
|
7
|
+
Putting **both** on one button means **two systems control `display` on one node**, which can cause wrong visibility (e.g. both a header and a full-width mobile button showing) or confusing cascade behavior.
|
|
8
|
+
|
|
9
|
+
**Recommended:** Put responsive `display` on a **parent** (e.g. `Flex`, `Card`, or a plain wrapper) and keep `full_width` only on the `Button` inside. The wrapper handles show/hide by breakpoint; the button only handles full-width layout.
|
|
10
|
+
|
|
11
|
+
```erb
|
|
12
|
+
<%= pb_rails("flex", props: {
|
|
13
|
+
display: { xs: "flex", default: "none" },
|
|
14
|
+
orientation: "column",
|
|
15
|
+
width: "100%",
|
|
16
|
+
}) do %>
|
|
17
|
+
<%= pb_rails("button", props: { full_width: true, text: "Add" }) %>
|
|
18
|
+
<% end %>
|
|
19
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
This button is used many times for mobile or other things like cards and sidebars.
|
|
2
|
+
|
|
3
|
+
### Responsive `display` and `full_width`
|
|
4
|
+
|
|
5
|
+
`full_width` applies block styling that includes `display: flex` on the **same element** as the button. The **`display` global prop** also sets `display` (via utility classes, often with `!important`).
|
|
6
|
+
|
|
7
|
+
Putting **both** on one button means **two systems control `display` on one node**, which can cause wrong visibility (e.g. both a header and a full-width mobile button showing) or confusing cascade behavior.
|
|
8
|
+
|
|
9
|
+
**Recommended:** Put responsive `display` on a **parent** (e.g. `Flex`, `Card`, or a plain wrapper) and keep `fullWidth` only on the `Button` inside. The wrapper handles show/hide by breakpoint; the button only handles full-width layout.
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
import { Flex, Button } from "playbook-ui"
|
|
13
|
+
|
|
14
|
+
const Example = () => (
|
|
15
|
+
<Flex
|
|
16
|
+
display={{ xs: "flex", default: "none" }}
|
|
17
|
+
orientation="column"
|
|
18
|
+
width="100%"
|
|
19
|
+
>
|
|
20
|
+
<Button fullWidth text="Add" />
|
|
21
|
+
</Flex>
|
|
22
|
+
)
|
|
23
|
+
```
|