playbook_ui 16.7.0.pre.alpha.play2924tooltipmisalignment16298 → 16.7.0.pre.alpha.tablewidths16407
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 +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/VirtualizedTableView.tsx +5 -1
- data/app/pb_kits/playbook/pb_advanced_table/Hooks/useTableState.ts +24 -0
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/ColumnLayoutHelper.ts +123 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +76 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.jsx +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.md +10 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.json +182 -5839
- data/app/pb_kits/playbook/pb_advanced_table/docs/_playground.overrides.json +5 -30
- data/app/pb_kits/playbook/pb_advanced_table/docs/advanced_table_column_definitions_styling.json +6 -1
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +1 -19
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +5 -8
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +0 -12
- data/app/pb_kits/playbook/pb_date_picker/date_picker.test.js +0 -26
- data/app/pb_kits/playbook/pb_date_range_stacked/docs/_playground.json +1 -1
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +0 -58
- data/app/pb_kits/playbook/pb_dropdown/dropdown.html.erb +0 -2
- data/app/pb_kits/playbook/pb_dropdown/dropdown.test.jsx +1 -7
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +262 -43
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.html.erb +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +12 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.html.erb +9 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.md +8 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/kit.schema.json +18 -9
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +162 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +71 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +202 -0
- data/app/pb_kits/playbook/pb_select/select.rb +0 -9
- data/app/pb_kits/playbook/pb_text_input/text_input.rb +0 -9
- data/dist/chunks/vendor.js +2 -2
- data/dist/menu.yml +1 -2
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8da495f79107327990243768d12d0c686b02cd3c9139be2021b1a2502ac1091b
|
|
4
|
+
data.tar.gz: b87d04b9c001d89e1f25889e19ec812d5e882eb04b06df284bcb3feb963567ce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b65bd11a250d2eb7de7f99b7e9c1209ef8d425244886afb6dfc744866172989ba223a981d78b92621f880c46fdb2ee3a3167776204754a430a847f1198ea71f
|
|
7
|
+
data.tar.gz: 91f38760a01e16eaaf16db868791168edbe57581cd05057e443ac3eeaffef513ebbc37451c716d65bb0591bfa0ebd022dc019c88d9cc15f62c74f5e5a78dfb25
|
|
@@ -5,6 +5,7 @@ import { flexRender, Row, Cell } from "@tanstack/react-table"
|
|
|
5
5
|
import { GenericObject } from "../../types"
|
|
6
6
|
import { isChrome } from "../Utilities/BrowserCheck"
|
|
7
7
|
import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
|
|
8
|
+
import { playbookColumnLayoutStylesFromMeta } from "../Utilities/ColumnLayoutHelper"
|
|
8
9
|
import { getRowColorClass, shouldShowLoadingIndicator } from "../Utilities/RowUtils"
|
|
9
10
|
|
|
10
11
|
import LoadingInline from "../../pb_loading_inline/_loading_inline"
|
|
@@ -94,6 +95,7 @@ const TableCellRenderer = ({
|
|
|
94
95
|
)}
|
|
95
96
|
key={`${cell.id}-data`}
|
|
96
97
|
style={{
|
|
98
|
+
...playbookColumnLayoutStylesFromMeta(column.columnDef),
|
|
97
99
|
left: isPinnedLeft
|
|
98
100
|
? i === 1 // Accounting for set min-width for first column
|
|
99
101
|
? '180px'
|
|
@@ -16,6 +16,7 @@ import { SortIconButton } from "./SortIconButton"
|
|
|
16
16
|
import { ToggleIconButton } from "./ToggleIconButton"
|
|
17
17
|
import { displayIcon } from "../Utilities/IconHelpers"
|
|
18
18
|
import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
|
|
19
|
+
import { playbookColumnLayoutStylesFromMeta } from "../Utilities/ColumnLayoutHelper"
|
|
19
20
|
import { updateExpandAndCollapseState } from "../Utilities/ExpansionControlHelpers"
|
|
20
21
|
|
|
21
22
|
import { isChrome } from "../Utilities/BrowserCheck"
|
|
@@ -198,6 +199,7 @@ const isToggleExpansionEnabled =
|
|
|
198
199
|
id={cellId}
|
|
199
200
|
key={`${header?.id}-header`}
|
|
200
201
|
style={{
|
|
202
|
+
...playbookColumnLayoutStylesFromMeta(header?.column?.columnDef),
|
|
201
203
|
backgroundColor: headerBackgroundColor,
|
|
202
204
|
color: headerFontColor,
|
|
203
205
|
left: isPinnedLeft
|
|
@@ -19,6 +19,7 @@ import { LoadingCell } from "../Components/LoadingCell"
|
|
|
19
19
|
import { renderCollapsibleTrail } from "../Components/CollapsibleTrail"
|
|
20
20
|
|
|
21
21
|
import AdvancedTableContext from "../Context/AdvancedTableContext"
|
|
22
|
+
import { playbookColumnLayoutStylesFromMeta } from "../Utilities/ColumnLayoutHelper"
|
|
22
23
|
|
|
23
24
|
type VirtualizedTableViewProps = {
|
|
24
25
|
collapsibleTrail?: boolean
|
|
@@ -224,7 +225,10 @@ export const VirtualizedTableView = ({
|
|
|
224
225
|
isLastCell && 'last-cell',
|
|
225
226
|
)}
|
|
226
227
|
key={`${cell.id}-data`}
|
|
227
|
-
style={{
|
|
228
|
+
style={{
|
|
229
|
+
...playbookColumnLayoutStylesFromMeta(cell.column.columnDef),
|
|
230
|
+
width: cellWidth,
|
|
231
|
+
}}
|
|
228
232
|
>
|
|
229
233
|
{collapsibleTrail && i === 0 && row.depth > 0 && renderCollapsibleTrail(row.depth)}
|
|
230
234
|
<span id={`${cell.id}-span`}>
|
|
@@ -12,6 +12,10 @@ import {
|
|
|
12
12
|
import { GenericObject } from "../../types";
|
|
13
13
|
import { createColumnHelper } from "@tanstack/react-table";
|
|
14
14
|
import { createCellFunction } from "../Utilities/CellRendererUtils";
|
|
15
|
+
import {
|
|
16
|
+
buildPlaybookColumnLayoutStyles,
|
|
17
|
+
buildTanStackSizingFromColumn,
|
|
18
|
+
} from "../Utilities/ColumnLayoutHelper";
|
|
15
19
|
import { getParentOnlySortedRowModel } from "../Utilities/RowModelUtils";
|
|
16
20
|
|
|
17
21
|
interface UseTableStateProps {
|
|
@@ -105,11 +109,31 @@ export function useTableState({
|
|
|
105
109
|
columns: buildColumns(column.columns, false),
|
|
106
110
|
};
|
|
107
111
|
}
|
|
112
|
+
const tanStackSizing = buildTanStackSizingFromColumn(column);
|
|
113
|
+
const layoutStyles = buildPlaybookColumnLayoutStyles(column, tanStackSizing);
|
|
114
|
+
const userMeta =
|
|
115
|
+
column.meta &&
|
|
116
|
+
typeof column.meta === "object" &&
|
|
117
|
+
!Array.isArray(column.meta)
|
|
118
|
+
? column.meta
|
|
119
|
+
: {};
|
|
120
|
+
const hasLayoutStyles =
|
|
121
|
+
layoutStyles.width !== undefined ||
|
|
122
|
+
layoutStyles.minWidth !== undefined ||
|
|
123
|
+
layoutStyles.maxWidth !== undefined;
|
|
124
|
+
|
|
108
125
|
// Define the base column structure
|
|
109
126
|
const columnStructure = {
|
|
110
127
|
...columnHelper.accessor(column.accessor, {
|
|
111
128
|
header: column.header ?? column.label ?? "",
|
|
112
129
|
enableSorting: isFirstColumn || column.enableSort === true,
|
|
130
|
+
...tanStackSizing,
|
|
131
|
+
meta: {
|
|
132
|
+
...userMeta,
|
|
133
|
+
...(hasLayoutStyles
|
|
134
|
+
? { playbookColumnLayoutStyles: layoutStyles }
|
|
135
|
+
: {}),
|
|
136
|
+
},
|
|
113
137
|
}),
|
|
114
138
|
};
|
|
115
139
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type { CSSProperties } from "react"
|
|
2
|
+
|
|
3
|
+
import { GenericObject } from "../../types"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Converts a Playbook column width value to a CSS length string.
|
|
7
|
+
* Numbers are treated as pixels; strings are passed through (e.g. `"12rem"`, `"200px"`).
|
|
8
|
+
*/
|
|
9
|
+
export function cssLength(
|
|
10
|
+
value: number | string | undefined | null
|
|
11
|
+
): string | undefined {
|
|
12
|
+
if (value === undefined || value === null || value === "") return undefined
|
|
13
|
+
if (typeof value === "number" && Number.isFinite(value)) return `${value}px`
|
|
14
|
+
return String(value)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const columnStylingKeys = (column: GenericObject) =>
|
|
18
|
+
(column.columnStyling || column.column_styling || {}) as GenericObject
|
|
19
|
+
|
|
20
|
+
function readStylingLength(
|
|
21
|
+
styling: GenericObject,
|
|
22
|
+
camel: string,
|
|
23
|
+
snake?: string
|
|
24
|
+
): string | number | undefined {
|
|
25
|
+
if (snake) return styling[camel] ?? styling[snake]
|
|
26
|
+
return styling[camel] as string | number | undefined
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* TanStack Table v8 `ColumnDef` sizing fields we forward from each `columnDefinitions` entry.
|
|
31
|
+
* See AdvancedTable kit docs for precedence with `columnStyling` width keys.
|
|
32
|
+
*/
|
|
33
|
+
export const PLAYBOOK_FORWARDED_COLUMN_DEF_SIZING_KEYS = [
|
|
34
|
+
"size",
|
|
35
|
+
"minSize",
|
|
36
|
+
"maxSize",
|
|
37
|
+
] as const
|
|
38
|
+
|
|
39
|
+
export type PlaybookForwardedColumnSizing = Partial<
|
|
40
|
+
Record<(typeof PLAYBOOK_FORWARDED_COLUMN_DEF_SIZING_KEYS)[number], number>
|
|
41
|
+
>
|
|
42
|
+
|
|
43
|
+
export function buildTanStackSizingFromColumn(
|
|
44
|
+
column: GenericObject
|
|
45
|
+
): PlaybookForwardedColumnSizing {
|
|
46
|
+
const out: PlaybookForwardedColumnSizing = {}
|
|
47
|
+
PLAYBOOK_FORWARDED_COLUMN_DEF_SIZING_KEYS.forEach((key) => {
|
|
48
|
+
const v = column[key]
|
|
49
|
+
if (typeof v === "number" && Number.isFinite(v)) out[key] = v
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const styling = columnStylingKeys(column)
|
|
53
|
+
|
|
54
|
+
if (out.size === undefined && readStylingLength(styling, "width") !== undefined) {
|
|
55
|
+
const w = readStylingLength(styling, "width")
|
|
56
|
+
if (typeof w === "number" && Number.isFinite(w)) out.size = w
|
|
57
|
+
}
|
|
58
|
+
if (out.minSize === undefined && readStylingLength(styling, "minWidth", "min_width") !== undefined) {
|
|
59
|
+
const w = readStylingLength(styling, "minWidth", "min_width")
|
|
60
|
+
if (typeof w === "number" && Number.isFinite(w)) out.minSize = w
|
|
61
|
+
}
|
|
62
|
+
if (out.maxSize === undefined && readStylingLength(styling, "maxWidth", "max_width") !== undefined) {
|
|
63
|
+
const w = readStylingLength(styling, "maxWidth", "max_width")
|
|
64
|
+
if (typeof w === "number" && Number.isFinite(w)) out.maxSize = w
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return out
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Inline width styles for `<th>` / `<td>` so `table-layout: fixed` tables keep stable
|
|
72
|
+
* columns when row content changes (e.g. expand/collapse). Values mirror TanStack sizing
|
|
73
|
+
* and/or `columnStyling` width keys; string values in `columnStyling` win over numeric
|
|
74
|
+
* TanStack fields when both describe the same axis.
|
|
75
|
+
*/
|
|
76
|
+
export function buildPlaybookColumnLayoutStyles(
|
|
77
|
+
column: GenericObject,
|
|
78
|
+
tanStackSizing: PlaybookForwardedColumnSizing
|
|
79
|
+
): CSSProperties {
|
|
80
|
+
const styling = columnStylingKeys(column)
|
|
81
|
+
const styles: CSSProperties = {}
|
|
82
|
+
|
|
83
|
+
const widthFromStyling = cssLength(
|
|
84
|
+
readStylingLength(styling, "width") as string | number | undefined
|
|
85
|
+
)
|
|
86
|
+
const minFromStyling = cssLength(
|
|
87
|
+
readStylingLength(styling, "minWidth", "min_width") as string | number | undefined
|
|
88
|
+
)
|
|
89
|
+
const maxFromStyling = cssLength(
|
|
90
|
+
readStylingLength(styling, "maxWidth", "max_width") as string | number | undefined
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
const widthFromTanStack =
|
|
94
|
+
tanStackSizing.size !== undefined
|
|
95
|
+
? cssLength(tanStackSizing.size)
|
|
96
|
+
: undefined
|
|
97
|
+
const minFromTanStack =
|
|
98
|
+
tanStackSizing.minSize !== undefined
|
|
99
|
+
? cssLength(tanStackSizing.minSize)
|
|
100
|
+
: undefined
|
|
101
|
+
const maxFromTanStack =
|
|
102
|
+
tanStackSizing.maxSize !== undefined
|
|
103
|
+
? cssLength(tanStackSizing.maxSize)
|
|
104
|
+
: undefined
|
|
105
|
+
|
|
106
|
+
if (widthFromStyling !== undefined) styles.width = widthFromStyling
|
|
107
|
+
else if (widthFromTanStack !== undefined) styles.width = widthFromTanStack
|
|
108
|
+
|
|
109
|
+
if (minFromStyling !== undefined) styles.minWidth = minFromStyling
|
|
110
|
+
else if (minFromTanStack !== undefined) styles.minWidth = minFromTanStack
|
|
111
|
+
|
|
112
|
+
if (maxFromStyling !== undefined) styles.maxWidth = maxFromStyling
|
|
113
|
+
else if (maxFromTanStack !== undefined) styles.maxWidth = maxFromTanStack
|
|
114
|
+
|
|
115
|
+
return styles
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function playbookColumnLayoutStylesFromMeta(
|
|
119
|
+
columnDef: GenericObject | undefined
|
|
120
|
+
): CSSProperties {
|
|
121
|
+
const meta = columnDef?.meta as GenericObject | undefined
|
|
122
|
+
return (meta?.playbookColumnLayoutStyles || {}) as CSSProperties
|
|
123
|
+
}
|
|
@@ -774,6 +774,82 @@ test("columnStyling.cellPadding sets cell padding", () => {
|
|
|
774
774
|
expect(firstEnrollmentCell).toHaveClass('p_none')
|
|
775
775
|
});
|
|
776
776
|
|
|
777
|
+
test("columnStyling minWidth, width, and maxWidth apply to header and body cells", () => {
|
|
778
|
+
const styledColumnDefs = [
|
|
779
|
+
{
|
|
780
|
+
accessor: "year",
|
|
781
|
+
label: "Year",
|
|
782
|
+
cellAccessors: ["quarter", "month", "day"],
|
|
783
|
+
columnStyling: { minWidth: 240, width: 260, maxWidth: 400 },
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
accessor: "newEnrollments",
|
|
787
|
+
label: "New Enrollments",
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
accessor: "scheduledMeetings",
|
|
791
|
+
label: "Scheduled Meetings",
|
|
792
|
+
},
|
|
793
|
+
];
|
|
794
|
+
|
|
795
|
+
render(
|
|
796
|
+
<AdvancedTable
|
|
797
|
+
columnDefinitions={styledColumnDefs}
|
|
798
|
+
data={{ testid: testId }}
|
|
799
|
+
tableData={MOCK_DATA}
|
|
800
|
+
/>
|
|
801
|
+
);
|
|
802
|
+
|
|
803
|
+
const yearHeader = screen.getByText("Year").closest("th");
|
|
804
|
+
expect(yearHeader).toHaveStyle({ minWidth: "240px", width: "260px", maxWidth: "400px" });
|
|
805
|
+
|
|
806
|
+
const yearCell = screen.getAllByText("2021")[0].closest("td");
|
|
807
|
+
expect(yearCell).toHaveStyle({ minWidth: "240px", width: "260px", maxWidth: "400px" });
|
|
808
|
+
});
|
|
809
|
+
|
|
810
|
+
test("columnDefinitions size, minSize, and maxSize apply layout styles", () => {
|
|
811
|
+
const styledColumnDefs = [
|
|
812
|
+
{
|
|
813
|
+
accessor: "year",
|
|
814
|
+
label: "Year",
|
|
815
|
+
cellAccessors: ["quarter", "month", "day"],
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
accessor: "newEnrollments",
|
|
819
|
+
label: "New Enrollments",
|
|
820
|
+
size: 180,
|
|
821
|
+
minSize: 160,
|
|
822
|
+
maxSize: 320,
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
accessor: "scheduledMeetings",
|
|
826
|
+
label: "Scheduled Meetings",
|
|
827
|
+
},
|
|
828
|
+
];
|
|
829
|
+
|
|
830
|
+
render(
|
|
831
|
+
<AdvancedTable
|
|
832
|
+
columnDefinitions={styledColumnDefs}
|
|
833
|
+
data={{ testid: testId }}
|
|
834
|
+
tableData={MOCK_DATA}
|
|
835
|
+
/>
|
|
836
|
+
);
|
|
837
|
+
|
|
838
|
+
const enrollmentsHeader = screen.getByText("New Enrollments").closest("th");
|
|
839
|
+
expect(enrollmentsHeader).toHaveStyle({
|
|
840
|
+
width: "180px",
|
|
841
|
+
minWidth: "160px",
|
|
842
|
+
maxWidth: "320px",
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
const enrollmentsCell = screen.getAllByText("20")[0].closest("td");
|
|
846
|
+
expect(enrollmentsCell).toHaveStyle({
|
|
847
|
+
width: "180px",
|
|
848
|
+
minWidth: "160px",
|
|
849
|
+
maxWidth: "320px",
|
|
850
|
+
});
|
|
851
|
+
});
|
|
852
|
+
|
|
777
853
|
test("columnStyling.fontColor sets cell font color", () => {
|
|
778
854
|
const styledColumnDefs = [
|
|
779
855
|
{
|
|
@@ -10,6 +10,8 @@ const AdvancedTableColumnStyling = (props) => {
|
|
|
10
10
|
accessor: "year",
|
|
11
11
|
label: "Year",
|
|
12
12
|
cellAccessors: ["quarter", "month", "day"],
|
|
13
|
+
// Keeps the hierarchy column narrow and stable when rows expand (see kit docs).
|
|
14
|
+
columnStyling: { minWidth: 108, width: 124, maxWidth: 168 },
|
|
13
15
|
},
|
|
14
16
|
{
|
|
15
17
|
accessor: "newEnrollments",
|
|
@@ -6,4 +6,14 @@ The `columnStyling` prop is an optional item that can be used within `columnDefi
|
|
|
6
6
|
|
|
7
7
|
3) `fontColor`: This will allow you to control the font color for a given column.
|
|
8
8
|
|
|
9
|
+
4) **Column width (layout stability)** — optional keys on `columnStyling` (numbers are treated as **pixels**; you may also use CSS length strings such as `"12rem"` or `"200px"`):
|
|
10
|
+
|
|
11
|
+
- `minWidth`: minimum width for the column’s header and body cells (helps prevent horizontal “jump” when row content or expansion depth changes on tables using fixed layout).
|
|
12
|
+
- `width`: preferred column width.
|
|
13
|
+
- `maxWidth`: maximum column width.
|
|
14
|
+
|
|
15
|
+
The live example below narrows the **Year** column (`minWidth` / `width` / `maxWidth`) so the first column stays compact while leaving room for expand and sort controls.
|
|
16
|
+
|
|
17
|
+
The same sizing can be expressed with TanStack `ColumnDef` fields on each column definition object (merged into the underlying table model): `size` (width), `minSize`, and `maxSize` (numbers, pixels). If both are present for the same axis, **`columnStyling` string values take precedence**; otherwise `columnStyling` numeric/string values override TanStack numbers when only one source sets that axis. **Grouped columns:** apply width controls on **leaf** column definitions (the columns that have an `accessor`).
|
|
18
|
+
|
|
9
19
|
`columnStyling` can be used within the columnDefinition of all the columns or some of them, as shown. Each column has its own individual control in this way.
|