playbook_ui 14.21.2.pre.alpha.PLAY21898327 → 14.21.2.pre.alpha.PLAY22558410
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 +4 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +8 -0
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +30 -5
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/CellRendererUtils.tsx +4 -1
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +4 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +25 -1
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table_action_bar.js +36 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows.jsx +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_pinned_rows_react.md +5 -3
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.jsx +64 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_row_styling.md +7 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/flat_advanced_table.js +60 -84
- data/app/pb_kits/playbook/pb_advanced_table/index.js +114 -223
- data/app/pb_kits/playbook/pb_advanced_table/table_action_bar.html.erb +1 -1
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_blank_selection.jsx +7 -4
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_clear_selection.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_rails.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_default_value.jsx +7 -4
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_error.jsx +7 -4
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select.jsx +19 -10
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display.jsx +19 -10
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_display_rails.html.erb +10 -10
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_rails.html.erb +10 -10
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.html.erb +10 -10
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_autocomplete.jsx +20 -11
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_custom_options.jsx +8 -8
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.html.erb +10 -10
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_multi_select_with_default.jsx +23 -14
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_separators_hidden.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_separators_hidden.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subcomponent_structure.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subcomponent_structure_rails.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_subtle_variant.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.html.erb +4 -4
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_autocomplete_with_subcomponents.jsx +4 -4
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display.jsx +4 -4
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_display_rails.html.erb +4 -4
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options.html.erb +52 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options.jsx +99 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options_rails.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_icon_options_react.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_options_rails.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_padding.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options.html.erb +28 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options.jsx +47 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options_rails.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_radio_options_react.md +1 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_custom_trigger_rails.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_external_control.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_label.jsx +6 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search.jsx +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_search_rails.html.erb +3 -3
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +4 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +3 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns.html.erb +8 -8
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_columns_rails.md +1 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns.html.erb +12 -12
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns_rails.md +2 -2
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns.html.erb +12 -12
- data/app/pb_kits/playbook/pb_table/docs/_table_sticky_right_columns_rails.md +2 -2
- data/app/pb_kits/playbook/pb_table/index.ts +4 -4
- data/app/pb_kits/playbook/pb_table/styles/_vertical_border.scss +4 -0
- data/dist/chunks/{_typeahead-BXD634Vm.js → _typeahead-B80UsDrG.js} +1 -1
- data/dist/chunks/_weekday_stacked-D1bqIne1.js +45 -0
- data/dist/chunks/{lib-9VvC3Rp0.js → lib-CTkMyvfQ.js} +1 -1
- data/dist/chunks/{pb_form_validation-CbyL4Bqa.js → pb_form_validation-BVF3TmcL.js} +1 -1
- data/dist/chunks/vendor.js +1 -1
- data/dist/playbook-doc.js +1 -1
- 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/version.rb +1 -1
- metadata +17 -6
- data/dist/chunks/_weekday_stacked-BxnkrDBG.js +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e74ebcaf8b226f04a617fc63083c59c61951a3f792409c906b7556ef4976f6c0
|
4
|
+
data.tar.gz: 755270c0eee4c986ca9d0534ffd31bec09383994a038ab4a6da7e43740537e10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7329823f5e763a4aa9712a78d7467fde07db90542cb2d6416ade72983d3984651f03fb3bb847f92582293623569a9c24a8756b051eec84a524b525a2164b9ce
|
7
|
+
data.tar.gz: 5fab13b2c33b5ee332beb81aed83254723ed0808a7d0b85cc68acadde24d79f8cdf773c7b97e73025e1a6ed00e118304533fab5581ce7bcfd46db7c7b98a843d
|
@@ -19,6 +19,7 @@ interface CustomCellProps {
|
|
19
19
|
value?: string
|
20
20
|
customRenderer?: (row: Row<GenericObject>, value: string | undefined) => React.ReactNode
|
21
21
|
selectableRows?: boolean
|
22
|
+
customStyle?: GenericObject
|
22
23
|
}
|
23
24
|
|
24
25
|
export const CustomCell = ({
|
@@ -28,6 +29,7 @@ export const CustomCell = ({
|
|
28
29
|
value,
|
29
30
|
customRenderer,
|
30
31
|
selectableRows,
|
32
|
+
customStyle = {},
|
31
33
|
}: CustomCellProps & GlobalProps) => {
|
32
34
|
const { setExpanded, expanded, expandedControl, inlineRowLoading, hasAnySubRows } = useContext(AdvancedTableContext);
|
33
35
|
|
@@ -43,7 +45,7 @@ export const CustomCell = ({
|
|
43
45
|
const renderButton = inlineRowLoading ? RowHasChildren : row.getCanExpand()
|
44
46
|
|
45
47
|
return (
|
46
|
-
<div style={{ paddingLeft: `${row.depth * 1.25}em`
|
48
|
+
<div style={{ paddingLeft: `${row.depth * 1.25}em`}}>
|
47
49
|
<Flex
|
48
50
|
alignItems="center"
|
49
51
|
columnGap="xs"
|
@@ -65,6 +67,7 @@ export const CustomCell = ({
|
|
65
67
|
<button
|
66
68
|
className="gray-icon expand-toggle-icon"
|
67
69
|
onClick={() => handleOnExpand(row)}
|
70
|
+
style={{ color: customStyle?.expandButtonColor }}
|
68
71
|
>
|
69
72
|
{row.getIsExpanded() ? (
|
70
73
|
<Icon cursor="pointer"
|
@@ -27,6 +27,7 @@ const TableCellRenderer = ({
|
|
27
27
|
loading = false,
|
28
28
|
stickyLeftColumn,
|
29
29
|
columnPinning,
|
30
|
+
customRowStyle,
|
30
31
|
columnDefinitions,
|
31
32
|
}: {
|
32
33
|
row: Row<GenericObject>
|
@@ -34,6 +35,7 @@ const TableCellRenderer = ({
|
|
34
35
|
loading?: boolean | string
|
35
36
|
stickyLeftColumn?: string[]
|
36
37
|
columnPinning: { left: string[] }
|
38
|
+
customRowStyle?: GenericObject
|
37
39
|
columnDefinitions?: {[key:string]:any}[]
|
38
40
|
}) => {
|
39
41
|
return (
|
@@ -74,6 +76,8 @@ const TableCellRenderer = ({
|
|
74
76
|
? '180px'
|
75
77
|
: `${column.getStart("left")}px`
|
76
78
|
: undefined,
|
79
|
+
backgroundColor: i === 0 && customRowStyle?.backgroundColor,
|
80
|
+
color: customRowStyle?.fontColor,
|
77
81
|
}}
|
78
82
|
>
|
79
83
|
{collapsibleTrail && i === 0 && row.depth > 0 && renderCollapsibleTrail(row.depth)}
|
@@ -107,6 +111,7 @@ export const RegularTableView = ({
|
|
107
111
|
pinnedRows,
|
108
112
|
headerHeight,
|
109
113
|
rowHeight,
|
114
|
+
rowStyling = [],
|
110
115
|
sampleRowRef,
|
111
116
|
} = useContext(AdvancedTableContext)
|
112
117
|
|
@@ -171,6 +176,7 @@ export const RegularTableView = ({
|
|
171
176
|
const rowBackground = isExpandable && ((!inlineRowLoading && row.getCanExpand()) || (inlineRowLoading && rowHasNoChildren));
|
172
177
|
const rowColor = row.getIsSelected() ? "bg-row-selection" : rowBackground ? "bg-silver" : "bg-white";
|
173
178
|
const isFirstRegularRow = rowIndex === 0 && !row.getIsPinned();
|
179
|
+
const customRowStyle = rowStyling?.length > 0 && rowStyling?.find((s: GenericObject) => s?.rowId === row.id);
|
174
180
|
|
175
181
|
return (
|
176
182
|
<React.Fragment key={`${row.index}-${row.id}-${row.depth}-row`}>
|
@@ -189,6 +195,7 @@ export const RegularTableView = ({
|
|
189
195
|
className={`${rowColor} ${row.depth > 0 ? `depth-sub-row-${row.depth}` : ""}`}
|
190
196
|
id={`${row.index}-${row.id}-${row.depth}-row`}
|
191
197
|
ref={isFirstRegularRow ? sampleRowRef : null}
|
198
|
+
style={{backgroundColor: customRowStyle?.backgroundColor, color: customRowStyle?.fontColor}}
|
192
199
|
>
|
193
200
|
{/* Render custom checkbox column when we want selectableRows for non-expanding tables */}
|
194
201
|
{selectableRows && !hasAnySubRows && (
|
@@ -206,6 +213,7 @@ export const RegularTableView = ({
|
|
206
213
|
collapsibleTrail={collapsibleTrail}
|
207
214
|
columnDefinitions={columnDefinitions}
|
208
215
|
columnPinning={columnPinning}
|
216
|
+
customRowStyle={customRowStyle}
|
209
217
|
loading={loading}
|
210
218
|
row={row}
|
211
219
|
stickyLeftColumn={stickyLeftColumn}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { useState, useCallback, useMemo } from 'react';
|
1
|
+
import { useState, useCallback, useMemo, useEffect } from 'react';
|
2
2
|
import {
|
3
3
|
useReactTable,
|
4
4
|
getCoreRowModel,
|
@@ -32,6 +32,7 @@ interface UseTableStateProps {
|
|
32
32
|
tableOptions?: GenericObject;
|
33
33
|
onRowSelectionChange?: (arg: RowSelectionState) => void;
|
34
34
|
columnVisibilityControl?: GenericObject;
|
35
|
+
rowStyling?: GenericObject;
|
35
36
|
}
|
36
37
|
|
37
38
|
export function useTableState({
|
@@ -49,7 +50,9 @@ export function useTableState({
|
|
49
50
|
tableOptions,
|
50
51
|
columnVisibilityControl,
|
51
52
|
pinnedRows,
|
53
|
+
rowStyling
|
52
54
|
}: UseTableStateProps) {
|
55
|
+
|
53
56
|
// Create a local state for expanded and setExpanded if expandedControl not used
|
54
57
|
const [localExpanded, setLocalExpanded] = useState({});
|
55
58
|
const [loadingStateRowCount, setLoadingStateRowCount] = useState(initialLoadingRowsCount);
|
@@ -63,8 +66,8 @@ export function useTableState({
|
|
63
66
|
const setExpanded = expandedControl ? expandedControl.onChange : setLocalExpanded;
|
64
67
|
const columnVisibility = (columnVisibilityControl && columnVisibilityControl.value) ? columnVisibilityControl.value : localColumnVisibility;
|
65
68
|
const setColumnVisibility = (columnVisibilityControl && columnVisibilityControl.onChange) ? columnVisibilityControl.onChange : setLocalColumnVisibility;
|
66
|
-
const rowPinning = pinnedRows
|
67
|
-
const
|
69
|
+
const rowPinning = pinnedRows?.value ?? localRowPinning
|
70
|
+
const onRowPinningChange = pinnedRows?.onChange ?? setLocalRowPinning
|
68
71
|
|
69
72
|
// Virtualized data handling (chunked loading)
|
70
73
|
const fetchSize = 20; // Number of rows per "page"
|
@@ -102,7 +105,8 @@ export function useTableState({
|
|
102
105
|
column.customRenderer,
|
103
106
|
isFirstColumn,
|
104
107
|
onRowToggleClick,
|
105
|
-
selectableRows
|
108
|
+
selectableRows,
|
109
|
+
rowStyling
|
106
110
|
);
|
107
111
|
}
|
108
112
|
|
@@ -165,7 +169,8 @@ export function useTableState({
|
|
165
169
|
enableSortingRemoval: false,
|
166
170
|
sortDescFirst: true,
|
167
171
|
onRowSelectionChange: setRowSelection,
|
168
|
-
|
172
|
+
onRowPinningChange,
|
173
|
+
getRowId: (selectableRows || pinnedRows || rowStyling) ? row => row.id : undefined,
|
169
174
|
onColumnVisibilityChange: setColumnVisibility,
|
170
175
|
meta: {
|
171
176
|
columnDefinitions
|
@@ -175,6 +180,26 @@ export function useTableState({
|
|
175
180
|
...tableOptions,
|
176
181
|
});
|
177
182
|
|
183
|
+
// Handle row pinning changes
|
184
|
+
useEffect(() => {
|
185
|
+
const topPins = pinnedRows?.value?.top ?? [];
|
186
|
+
if (topPins.length === 0) {
|
187
|
+
onRowPinningChange({ top: [] });
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
const rows = table.getRowModel().rows;
|
191
|
+
const collectAllDescendantIds = (subs: Row<GenericObject>[]): string[] =>
|
192
|
+
subs.flatMap(r => [r.id, ...collectAllDescendantIds(r.subRows)]);
|
193
|
+
const allPinned: string[] = [];
|
194
|
+
topPins.forEach(id => {
|
195
|
+
const parent = rows.find(r => r.id === id && r.depth === 0);
|
196
|
+
if (parent) {
|
197
|
+
allPinned.push(parent.id, ...collectAllDescendantIds(parent.subRows));
|
198
|
+
}
|
199
|
+
});
|
200
|
+
onRowPinningChange({ top: allPinned });
|
201
|
+
}, [table, pinnedRows?.value?.top?.join(',')]);
|
202
|
+
|
178
203
|
// Check if table has any sub-rows
|
179
204
|
const hasAnySubRows = table.getRowModel().rows.some(row => row.subRows && row.subRows.length > 0);
|
180
205
|
const selectedRowsLength = Object.keys(table.getState().rowSelection).length;
|
@@ -17,7 +17,8 @@ export const createCellFunction = (
|
|
17
17
|
customRenderer?: (row: Row<GenericObject>, value: any) => JSX.Element,
|
18
18
|
isFirstColumn?: boolean,
|
19
19
|
onRowToggleClick?: (row: Row<GenericObject>) => void,
|
20
|
-
selectableRows?: boolean
|
20
|
+
selectableRows?: boolean,
|
21
|
+
rowStyling?: GenericObject
|
21
22
|
) => {
|
22
23
|
// Add display name to the returned function
|
23
24
|
const cellRenderer = ({
|
@@ -28,6 +29,7 @@ export const createCellFunction = (
|
|
28
29
|
getValue: Getter<string>
|
29
30
|
}) => {
|
30
31
|
const rowData = row.original;
|
32
|
+
const customStyle = rowStyling?.length > 0 && rowStyling?.find((s:GenericObject) => s?.rowId === row.id);
|
31
33
|
|
32
34
|
if (isFirstColumn) {
|
33
35
|
switch (row.depth) {
|
@@ -35,6 +37,7 @@ export const createCellFunction = (
|
|
35
37
|
return (
|
36
38
|
<CustomCell
|
37
39
|
customRenderer={customRenderer}
|
40
|
+
customStyle={customStyle}
|
38
41
|
getValue={getValue}
|
39
42
|
onRowToggleClick={onRowToggleClick}
|
40
43
|
row={row}
|
@@ -57,6 +57,7 @@ type AdvancedTableProps = {
|
|
57
57
|
onChange?: (value: RowPinningState) => void;
|
58
58
|
};
|
59
59
|
responsive?: "scroll" | "none",
|
60
|
+
rowStyling?: GenericObject[],
|
60
61
|
scrollBarNone?: boolean,
|
61
62
|
selectableRows?: boolean,
|
62
63
|
showActionsBar?: boolean,
|
@@ -98,6 +99,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
98
99
|
paginationProps,
|
99
100
|
pinnedRows,
|
100
101
|
responsive = "scroll",
|
102
|
+
rowStyling,
|
101
103
|
scrollBarNone= false,
|
102
104
|
showActionsBar = true,
|
103
105
|
selectableRows,
|
@@ -144,6 +146,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
144
146
|
onRowSelectionChange,
|
145
147
|
columnVisibilityControl,
|
146
148
|
pinnedRows,
|
149
|
+
rowStyling
|
147
150
|
});
|
148
151
|
|
149
152
|
// Initialize table actions
|
@@ -336,6 +339,7 @@ const AdvancedTable = (props: AdvancedTableProps) => {
|
|
336
339
|
onExpandByDepthClick={onExpandByDepthClick}
|
337
340
|
pinnedRows={pinnedRows}
|
338
341
|
responsive={responsive}
|
342
|
+
rowStyling={rowStyling}
|
339
343
|
selectableRows={selectableRows}
|
340
344
|
setExpanded={setExpanded}
|
341
345
|
showActionsBar={showActionsBar}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React, {useState} from "react"
|
2
2
|
import { render, screen, waitFor } from "../utilities/test-utils"
|
3
3
|
|
4
|
-
import { AdvancedTable, Pill } from "playbook-ui"
|
4
|
+
import { AdvancedTable, Pill, colors } from "playbook-ui"
|
5
5
|
|
6
6
|
global.ResizeObserver = class {
|
7
7
|
observe() {}
|
@@ -652,3 +652,27 @@ test("renders virtualized table rows and header", () => {
|
|
652
652
|
const virtualizedRows = kit.querySelectorAll('.virtualized-table-row')
|
653
653
|
expect(virtualizedRows.length).toBeLessThan(MOCK_DATA_WITH_ID.length)
|
654
654
|
})
|
655
|
+
|
656
|
+
test("rowStyling prop works as expected", () => {
|
657
|
+
const rowStyling = [
|
658
|
+
{
|
659
|
+
rowId: "1",
|
660
|
+
backgroundColor: colors.white,
|
661
|
+
fontColor: colors.black
|
662
|
+
},
|
663
|
+
];
|
664
|
+
|
665
|
+
render(
|
666
|
+
<AdvancedTable
|
667
|
+
columnDefinitions={columnDefinitions}
|
668
|
+
data={{ testid: testId }}
|
669
|
+
rowStyling={rowStyling}
|
670
|
+
tableData={MOCK_DATA_WITH_ID}
|
671
|
+
/>
|
672
|
+
)
|
673
|
+
|
674
|
+
const kit = screen.getByTestId(testId)
|
675
|
+
const tableBody = kit.querySelector('tbody')
|
676
|
+
const row1 = tableBody.querySelector('tr:nth-child(1)')
|
677
|
+
expect(row1).toHaveStyle({backgroundColor: colors.white, color: colors.black})
|
678
|
+
})
|
@@ -0,0 +1,36 @@
|
|
1
|
+
function showActionBar(actionBar, selectedCount) {
|
2
|
+
// Show action bar directly
|
3
|
+
actionBar.style.height = "auto";
|
4
|
+
actionBar.style.overflow = "visible";
|
5
|
+
actionBar.style.opacity = "1";
|
6
|
+
actionBar.style.transitionProperty = "all";
|
7
|
+
actionBar.style.transitionTimingFunction = "ease-in-out";
|
8
|
+
actionBar.classList.remove("p_none");
|
9
|
+
actionBar.classList.add("p_xs", "is-visible", "show-action-card");
|
10
|
+
|
11
|
+
// Update the count
|
12
|
+
const countElement = actionBar.querySelector(".selected-count");
|
13
|
+
if (countElement) {
|
14
|
+
countElement.textContent = `${selectedCount} Selected`;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
function hideActionBar(actionBar) {
|
19
|
+
// Hide action bar directly
|
20
|
+
actionBar.style.height = "0px";
|
21
|
+
actionBar.style.overflow = "hidden";
|
22
|
+
actionBar.style.opacity = "0";
|
23
|
+
actionBar.classList.add("p_none");
|
24
|
+
actionBar.classList.remove("p_xs", "is-visible", "show-action-card");
|
25
|
+
}
|
26
|
+
|
27
|
+
export function updateSelectionActionBar(table, selectedCount) {
|
28
|
+
const actionBar = table.querySelector(".row-selection-actions-card");
|
29
|
+
if (!actionBar) return;
|
30
|
+
|
31
|
+
if (selectedCount > 0) {
|
32
|
+
showActionBar(actionBar, selectedCount);
|
33
|
+
} else {
|
34
|
+
hideActionBar(actionBar);
|
35
|
+
}
|
36
|
+
}
|
@@ -1,5 +1,7 @@
|
|
1
|
-
Use the `pinnedRows` prop to pin specific rows to the top of an Advanced Table. Pinned rows will remain at the top when scrolling through table data and
|
1
|
+
Use the `pinnedRows` prop to pin specific rows to the top of an Advanced Table. Pinned rows will remain at the top when scrolling through table data and will not change position if sorting is used.
|
2
2
|
|
3
|
-
**NOTE:**
|
3
|
+
**NOTE:**
|
4
4
|
- Sticky header required: Pinned rows must be used with `sticky: true` via `tableProps` (works with both responsive and non-responsive tables)
|
5
|
-
- Row ids required:
|
5
|
+
- Row ids required: Each object within the `tableData` Array must contain a unique id in order to attach an id to all Rows for this to function.
|
6
|
+
- `pinnedRows` takes an array of row ids to the `top` property as shown in the code snippet below.
|
7
|
+
- For expandable rows, use the parent id in `pinnedRows`, all its children will automatically be pinned with it. If id for a child is passed in without parent being pinned, nothing will be pinned.
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import React from "react"
|
2
|
+
import AdvancedTable from '../_advanced_table'
|
3
|
+
import MOCK_DATA from "./advanced_table_mock_data_with_id.json"
|
4
|
+
import { colors } from "playbook-ui"
|
5
|
+
|
6
|
+
const AdvancedTableRowStyling = (props) => {
|
7
|
+
const columnDefinitions = [
|
8
|
+
{
|
9
|
+
accessor: "year",
|
10
|
+
label: "Year",
|
11
|
+
cellAccessors: ["quarter", "month", "day"],
|
12
|
+
},
|
13
|
+
{
|
14
|
+
accessor: "newEnrollments",
|
15
|
+
label: "New Enrollments",
|
16
|
+
},
|
17
|
+
{
|
18
|
+
accessor: "scheduledMeetings",
|
19
|
+
label: "Scheduled Meetings",
|
20
|
+
},
|
21
|
+
{
|
22
|
+
accessor: "attendanceRate",
|
23
|
+
label: "Attendance Rate",
|
24
|
+
},
|
25
|
+
{
|
26
|
+
accessor: "completedClasses",
|
27
|
+
label: "Completed Classes",
|
28
|
+
},
|
29
|
+
{
|
30
|
+
accessor: "classCompletionRate",
|
31
|
+
label: "Class Completion Rate",
|
32
|
+
},
|
33
|
+
{
|
34
|
+
accessor: "graduatedStudents",
|
35
|
+
label: "Graduated Students",
|
36
|
+
},
|
37
|
+
]
|
38
|
+
|
39
|
+
const rowStyling = [
|
40
|
+
{
|
41
|
+
rowId: "1",
|
42
|
+
backgroundColor: colors.warning,
|
43
|
+
},
|
44
|
+
{
|
45
|
+
rowId: "8",
|
46
|
+
backgroundColor: colors.category_1,
|
47
|
+
fontColor: colors.white,
|
48
|
+
expandButtonColor: colors.white,
|
49
|
+
},
|
50
|
+
];
|
51
|
+
|
52
|
+
return (
|
53
|
+
<div>
|
54
|
+
<AdvancedTable
|
55
|
+
columnDefinitions={columnDefinitions}
|
56
|
+
rowStyling={rowStyling}
|
57
|
+
tableData={MOCK_DATA}
|
58
|
+
{...props}
|
59
|
+
/>
|
60
|
+
</div>
|
61
|
+
)
|
62
|
+
}
|
63
|
+
|
64
|
+
export default AdvancedTableRowStyling
|
@@ -0,0 +1,7 @@
|
|
1
|
+
The `rowStyling` prop can be used in conjunction with row ids to control certain styling options on individual rows. Currently, `rowStyling` gives you 3 optional controls:
|
2
|
+
|
3
|
+
- `backgroundColor` : use this to control the background color of the row
|
4
|
+
- `fontColor`: use this to control font color for each row if needed, for example if using a darker background color.
|
5
|
+
- `expandButtonColor`: use this to control the color of the expand icon if needed, for example if using a darker background color.
|
6
|
+
|
7
|
+
**NOTE:** Each object within the `tableData` Array must contain a unique id in order to attach an id to all Rows for this to function.
|
@@ -59,6 +59,7 @@ examples:
|
|
59
59
|
- advanced_table_column_visibility_multi: Column Visibility Control with Multi-Header Columns
|
60
60
|
- advanced_table_pinned_rows: Pinned Rows
|
61
61
|
- advanced_table_scrollbar_none: Advanced Table Scrollbar None
|
62
|
+
- advanced_table_row_styling: Row Styling
|
62
63
|
- advanced_table_column_styling: Column Styling
|
63
64
|
- advanced_table_column_styling_column_headers: Column Styling with Multiple Headers
|
64
65
|
- advanced_table_infinite_scroll: Infinite Scroll
|
@@ -34,6 +34,7 @@ export { default as AdvancedTableColumnVisibilityMulti } from './_advanced_table
|
|
34
34
|
export { default as AdvancedTableColumnVisibilityWithState } from './_advanced_table_column_visibility_with_state.jsx'
|
35
35
|
export { default as AdvancedTablePinnedRows } from './_advanced_table_pinned_rows.jsx'
|
36
36
|
export { default as AdvancedTableScrollbarNone} from './_advanced_table_scrollbar_none.jsx'
|
37
|
+
export { default as AdvancedTableRowStyling } from './_advanced_table_row_styling.jsx'
|
37
38
|
export { default as AdvancedTableColumnStyling } from './_advanced_table_column_styling.jsx'
|
38
39
|
export { default as AdvancedTableColumnStylingColumnHeaders } from './_advanced_table_column_styling_column_headers.jsx'
|
39
40
|
export { default as AdvancedTableInfiniteScroll} from './_advanced_table_infinite_scroll.jsx'
|
@@ -1,106 +1,82 @@
|
|
1
1
|
import PbEnhancedElement from "../pb_enhanced_element";
|
2
|
+
import { updateSelectionActionBar } from "./advanced_table_action_bar";
|
2
3
|
|
3
|
-
const
|
4
|
+
const FLAT_SELECTOR = "[data-flat-advanced-table-select='true']";
|
5
|
+
const SELECT_ALL_SELECTOR = "#select-all-rows input[type='checkbox']";
|
4
6
|
|
5
7
|
export default class PbFlatAdvancedTable extends PbEnhancedElement {
|
6
8
|
static get selector() {
|
7
|
-
return
|
9
|
+
return FLAT_SELECTOR;
|
8
10
|
}
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
);
|
12
|
+
constructor(...args) {
|
13
|
+
super(...args);
|
14
|
+
// keep track of selected IDs per-table-instance
|
15
|
+
this.selectedRows = new Set();
|
15
16
|
}
|
16
17
|
|
17
|
-
static selectedRows = new Set();
|
18
|
-
|
19
18
|
connect() {
|
20
19
|
const table = this.element.closest("table");
|
21
|
-
if (!table) return;
|
20
|
+
if (!table || table.dataset.flatAdvancedInit) return;
|
21
|
+
table.dataset.flatAdvancedInit = "true";
|
22
|
+
|
23
|
+
// Reference to outer container for action bar
|
22
24
|
const mainTable = this.element.closest(".pb_advanced_table");
|
23
|
-
//
|
24
|
-
if (
|
25
|
-
|
25
|
+
// This so it is hidden on first render
|
26
|
+
if (mainTable) {
|
27
|
+
updateSelectionActionBar(mainTable, 0);
|
28
|
+
}
|
26
29
|
|
27
|
-
const
|
28
|
-
|
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
|
-
|
30
|
+
const updateCheckboxState = () => {
|
31
|
+
// Sync dataset on main table
|
32
|
+
if (mainTable) {
|
67
33
|
mainTable.dataset.selectedRows = JSON.stringify(
|
68
|
-
Array.from(
|
34
|
+
Array.from(this.selectedRows)
|
69
35
|
);
|
70
|
-
|
71
|
-
|
72
|
-
}
|
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;
|
73
44
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
'input[type="checkbox"]'
|
79
|
-
);
|
80
|
-
selectAllInput.addEventListener("change", () => {
|
81
|
-
const checkAll = selectAllInput.checked;
|
45
|
+
if (rowCb) {
|
46
|
+
const id = rowCb.id;
|
47
|
+
if (rowCb.checked) this.selectedRows.add(id);
|
48
|
+
else this.selectedRows.delete(id);
|
82
49
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
50
|
+
const tr = rowCb.closest("tr");
|
51
|
+
tr?.classList.toggle("bg-row-selection", rowCb.checked);
|
52
|
+
tr?.classList.toggle("bg-white", !rowCb.checked);
|
53
|
+
|
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
|
+
}
|
88
63
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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);
|
98
76
|
});
|
77
|
+
}
|
99
78
|
|
100
|
-
|
101
|
-
|
102
|
-
);
|
103
|
-
});
|
104
|
-
}
|
79
|
+
updateCheckboxState();
|
80
|
+
});
|
105
81
|
}
|
106
82
|
}
|