playbook_ui 14.21.1 → 14.21.2.pre.alpha.PLAY18938263

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/Components/CustomCell.tsx +1 -1
  3. data/app/pb_kits/playbook/pb_advanced_table/Components/RegularTableView.tsx +12 -4
  4. data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +25 -5
  5. data/app/pb_kits/playbook/pb_advanced_table/Utilities/ColumnStylingHelper.ts +15 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +1 -3
  7. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +61 -1
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.jsx +51 -0
  9. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling.md +7 -0
  10. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers.jsx +77 -0
  11. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers.md +1 -0
  12. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers_rails.html.erb +63 -0
  13. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_column_headers_rails.md +1 -0
  14. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.html.erb +38 -0
  15. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_column_styling_rails.md +7 -0
  16. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +4 -0
  17. data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +2 -0
  18. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +1 -1
  19. data/app/pb_kits/playbook/pb_advanced_table/table_header.rb +5 -0
  20. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +2 -2
  21. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +33 -0
  22. data/app/pb_kits/playbook/pb_checkbox/checkbox.rb +18 -1
  23. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom.html.erb +1 -0
  24. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_custom_rails.md +1 -0
  25. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_form.html.erb +22 -0
  26. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_form.md +5 -0
  27. data/app/pb_kits/playbook/pb_checkbox/docs/_checkbox_options.html.erb +1 -0
  28. data/app/pb_kits/playbook/pb_checkbox/docs/example.yml +1 -0
  29. data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +3 -12
  30. data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +0 -2
  31. data/app/pb_kits/playbook/pb_dropdown/docs/index.js +1 -2
  32. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownOption.tsx +10 -14
  33. data/app/pb_kits/playbook/pb_dropdown/subcomponents/DropdownTrigger.tsx +15 -26
  34. data/app/pb_kits/playbook/pb_form/docs/_form_form_with_validate.html.erb +1 -1
  35. data/app/pb_kits/playbook/pb_section_separator/docs/_description.md +3 -1
  36. data/dist/chunks/{_typeahead-BlPRej0F.js → _typeahead-CoOpeYom.js} +2 -2
  37. data/dist/chunks/_weekday_stacked-JnoR3mIy.js +45 -0
  38. data/dist/chunks/lib-D7Va7yqa.js +29 -0
  39. data/dist/chunks/{pb_form_validation-DyvJ8iPe.js → pb_form_validation-DSkdRDMf.js} +1 -1
  40. data/dist/chunks/vendor.js +1 -1
  41. data/dist/playbook-doc.js +1 -1
  42. data/dist/playbook-rails-react-bindings.js +1 -1
  43. data/dist/playbook-rails.js +1 -1
  44. data/dist/playbook.css +1 -1
  45. data/lib/playbook/version.rb +2 -2
  46. metadata +18 -8
  47. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.jsx +0 -42
  48. data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_close_on_select.md +0 -1
  49. data/dist/chunks/_weekday_stacked-LCNJiSQ3.js +0 -45
  50. data/dist/chunks/lib-D4vXIZF5.js +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0737c92ce3c158f4a4d593ab763d9a708bf1ea647fdaea8476164b892b257b5
4
- data.tar.gz: b7eadcb56f9e3082b04d22e91e8da3576141e9e84651a5081399dde83de8eac5
3
+ metadata.gz: 79e1418032e3a7ddebd1c367b0623b34c597d5f3bdd150dcf1b674fc37249634
4
+ data.tar.gz: 745eed5d73220bcf2599935c70f19a103c52344f640afad7ad9fb0baceba5e79
5
5
  SHA512:
6
- metadata.gz: 51d6ccdd8b41cf5109dfe7b357c3c839889980d69116018901ae974629aaa96178f9622698e0f331310137b8437b2e3ad82936e1df193829ba613af6aeefeec6
7
- data.tar.gz: d03ea7ef7a82b1caa0f1eed79e107cfa287a9d4e47559c562f27958532ccde311c75158d7635f6163357937836185123cdcdaee68a093f9aad35d316d9dbeb5d
6
+ metadata.gz: 3e048fea08b7564b2886bcad5151b1528a92f55e35bd7661fc058582be2b64851353f9c398634021197e860550ea0f7cb13d0bafefc7e5b1a9bc92ee15c7d431
7
+ data.tar.gz: a34cc6f295dcf69a9315853f1ba9c079154b83cd4f94e49b06ffbb810d405b522850ebd4673843ae580b862522cd038ddc4acfd4f05aeb3917b06ad61ec80225
@@ -47,7 +47,7 @@ export const CustomCell = ({
47
47
  <Flex
48
48
  alignItems="center"
49
49
  columnGap="xs"
50
- justify={"start"}
50
+ justify="start"
51
51
  orientation="row"
52
52
  >
53
53
  {
@@ -4,6 +4,7 @@ import { flexRender, Row, Cell } from "@tanstack/react-table"
4
4
 
5
5
  import { GenericObject } from "../../types"
6
6
  import { isChrome } from "../Utilities/BrowserCheck"
7
+ import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
7
8
 
8
9
  import LoadingInline from "../../pb_loading_inline/_loading_inline"
9
10
  import Checkbox from "../../pb_checkbox/_checkbox"
@@ -25,13 +26,15 @@ const TableCellRenderer = ({
25
26
  collapsibleTrail = true,
26
27
  loading = false,
27
28
  stickyLeftColumn,
28
- columnPinning
29
+ columnPinning,
30
+ columnDefinitions,
29
31
  }: {
30
32
  row: Row<GenericObject>
31
33
  collapsibleTrail?: boolean
32
34
  loading?: boolean | string
33
35
  stickyLeftColumn?: string[]
34
36
  columnPinning: { left: string[] }
37
+ columnDefinitions?: {[key:string]:any}[]
35
38
  }) => {
36
39
  return (
37
40
  <>
@@ -49,10 +52,14 @@ const TableCellRenderer = ({
49
52
  })();
50
53
 
51
54
  const { column } = cell;
52
-
55
+
56
+ // Find the “owning” colDefinition by accessor. Needed for multi column logic
57
+ const colDef = findColumnDefByAccessor(columnDefinitions ?? [], column.id)
58
+ const cellAlignment = colDef?.columnStyling?.cellAlignment ?? "right"
59
+
53
60
  return (
54
61
  <td
55
- align="right"
62
+ align={cellAlignment}
56
63
  className={classnames(
57
64
  `${cell.id}-cell position_relative`,
58
65
  isChrome() ? "chrome-styles" : "",
@@ -117,7 +124,6 @@ export const RegularTableView = ({
117
124
 
118
125
  const columnPinning = table.getState().columnPinning || { left: [] };
119
126
  const columnDefinitions = table.options.meta?.columnDefinitions || [];
120
-
121
127
  // Row pinning
122
128
  function PinnedRow({ row }: { row: Row<any> }) {
123
129
  return (
@@ -137,6 +143,7 @@ export const RegularTableView = ({
137
143
  >
138
144
  <TableCellRenderer
139
145
  collapsibleTrail={collapsibleTrail}
146
+ columnDefinitions={columnDefinitions}
140
147
  columnPinning={columnPinning}
141
148
  loading={loading}
142
149
  row={row}
@@ -197,6 +204,7 @@ export const RegularTableView = ({
197
204
  )}
198
205
  <TableCellRenderer
199
206
  collapsibleTrail={collapsibleTrail}
207
+ columnDefinitions={columnDefinitions}
200
208
  columnPinning={columnPinning}
201
209
  loading={loading}
202
210
  row={row}
@@ -15,6 +15,7 @@ import Icon from "../../pb_icon/_icon"
15
15
  import { SortIconButton } from "./SortIconButton"
16
16
  import { ToggleIconButton } from "./ToggleIconButton"
17
17
  import { displayIcon } from "../Utilities/IconHelpers"
18
+ import { findColumnDefByAccessor } from "../Utilities/ColumnStylingHelper"
18
19
  import { updateExpandAndCollapseState } from "../Utilities/ExpansionControlHelpers"
19
20
 
20
21
  import { isChrome } from "../Utilities/BrowserCheck"
@@ -45,6 +46,7 @@ export const TableHeaderCell = ({
45
46
  table
46
47
  }: TableHeaderCellProps) => {
47
48
  const {
49
+ columnDefinitions,
48
50
  expanded,
49
51
  setExpanded,
50
52
  expandByDepth,
@@ -72,6 +74,18 @@ export const TableHeaderCell = ({
72
74
  header?.column.getToggleSortingHandler()(event)
73
75
  }
74
76
  }
77
+ const alignmentMap: Record<string, "start" | "center" | "end"> = {
78
+ left: "start",
79
+ center: "center",
80
+ right: "end",
81
+ };
82
+
83
+ // Look up the “owning” columnDefinition by accessor. Needed for multi column logic
84
+ const colDef = header
85
+ ? findColumnDefByAccessor(columnDefinitions, header.column.id)
86
+ : undefined
87
+
88
+ const headerAlignment = colDef?.columnStyling?.headerAlignment ?? colDef?.columnStyling?.headerAligment
75
89
 
76
90
  const isLeafColumn =
77
91
  header?.column.getLeafColumns().length === 1 &&
@@ -126,9 +140,15 @@ const isToggleExpansionEnabled =
126
140
  (enableToggleExpansion === "all" || "header") &&
127
141
  enableToggleExpansion !== "none"
128
142
 
129
- let justifyHeader:justifyTypes;
143
+ let justifyHeader: justifyTypes;
130
144
 
131
- if (header?.index === 0 && hasAnySubRows || (header?.index === 0 && inlineRowLoading) || (header?.index === 0 && isToggleExpansionEnabled)) {
145
+ if (headerAlignment && alignmentMap[headerAlignment]) {
146
+ justifyHeader = alignmentMap[headerAlignment];
147
+ } else if (
148
+ (header?.index === 0 && hasAnySubRows) ||
149
+ (header?.index === 0 && inlineRowLoading) ||
150
+ (header?.index === 0 && isToggleExpansionEnabled)
151
+ ) {
132
152
  justifyHeader = enableSorting ? "between" : "start";
133
153
  } else {
134
154
  justifyHeader = isLeafColumn ? "end" : "center";
@@ -165,7 +185,7 @@ const isToggleExpansionEnabled =
165
185
 
166
186
  return (
167
187
  <th
168
- align="right"
188
+ align={headerAlignment ? headerAlignment : "right"}
169
189
  className={cellClassName}
170
190
  colSpan={header?.colSpan}
171
191
  id={cellId}
@@ -253,8 +273,8 @@ const isToggleExpansionEnabled =
253
273
  tabIndex: 0,
254
274
  },
255
275
  })}
256
- justify={header?.index === 0 && enableSorting ? "between" : "none"}
257
- paddingLeft={enableSorting ? "xxs" : "xs"}
276
+ justify={header?.index === 0 && enableSorting ? "between" : headerAlignment ? alignmentMap[headerAlignment] : "none"}
277
+ paddingLeft={header?.index === 0 ? enableSorting ? "xxs" : "xs" : "none"}
258
278
  >
259
279
  <div>
260
280
  {flexRender(header?.column.columnDef.header, header?.getContext())}
@@ -0,0 +1,15 @@
1
+ export const findColumnDefByAccessor = (
2
+ defs: any[],
3
+ targetAccessor: string
4
+ ): any | undefined => {
5
+ for (const def of defs) {
6
+ if (def.accessor === targetAccessor) {
7
+ return def;
8
+ }
9
+ if (Array.isArray(def.columns) && def.columns.length) {
10
+ const found = findColumnDefByAccessor(def.columns, targetAccessor);
11
+ if (found) return found;
12
+ }
13
+ }
14
+ return undefined;
15
+ };
@@ -39,7 +39,7 @@
39
39
  }
40
40
 
41
41
  -ms-overflow-style: none !important;
42
- scrollbar-width: thin !important;
42
+ scrollbar-width: thin;
43
43
  scrollbar-color: #00000033 transparent !important;
44
44
  }
45
45
 
@@ -410,7 +410,6 @@
410
410
 
411
411
  // Make sure all horizontal borders use the default border color
412
412
  tr, th, td {
413
- border-top-color: $border_light !important;
414
413
  border-bottom-color: $border_light !important;
415
414
  }
416
415
 
@@ -633,7 +632,6 @@
633
632
 
634
633
  // Make sure all horizontal borders use the default border color in dark mode
635
634
  tr, th, td {
636
- border-top-color: $border_dark !important;
637
635
  border-bottom-color: $border_dark !important;
638
636
  }
639
637
 
@@ -572,4 +572,64 @@ test("pinnedRows prop renders pinned rows at top", () => {
572
572
  const firstPinnedRow = pinnedRows[0]
573
573
  expect(firstPinnedRow).toHaveStyle("position: sticky")
574
574
  expect(firstPinnedRow).toHaveStyle("background-color: white")
575
- })
575
+ })
576
+
577
+ test("columnStyling.headerAlignment aligns header as expected", () => {
578
+ const styledColumnDefs = [
579
+ {
580
+ accessor: "year",
581
+ label: "Year",
582
+ cellAccessors: ["quarter", "month", "day"],
583
+ },
584
+ {
585
+ accessor: "newEnrollments",
586
+ label: "New Enrollments",
587
+ columnStyling: { headerAlignment: "left" },
588
+ },
589
+ {
590
+ accessor: "scheduledMeetings",
591
+ label: "Scheduled Meetings",
592
+ },
593
+ ];
594
+
595
+ render(
596
+ <AdvancedTable
597
+ columnDefinitions={styledColumnDefs}
598
+ data={{ testid: testId }}
599
+ tableData={MOCK_DATA}
600
+ />
601
+ );
602
+
603
+ const headerCell = screen.getByText("New Enrollments").closest("th");
604
+ expect(headerCell).toHaveAttribute("align", "left");
605
+ });
606
+
607
+ test("columnStyling.cellAlignment sets each <td> align attribute as expected", () => {
608
+ const styledColumnDefs = [
609
+ {
610
+ accessor: "year",
611
+ label: "Year",
612
+ cellAccessors: ["quarter", "month", "day"],
613
+ },
614
+ {
615
+ accessor: "newEnrollments",
616
+ label: "New Enrollments",
617
+ columnStyling: { cellAlignment: "left" },
618
+ },
619
+ {
620
+ accessor: "scheduledMeetings",
621
+ label: "Scheduled Meetings",
622
+ },
623
+ ];
624
+
625
+ render(
626
+ <AdvancedTable
627
+ columnDefinitions={styledColumnDefs}
628
+ data={{ testid: testId }}
629
+ tableData={MOCK_DATA}
630
+ />
631
+ );
632
+
633
+ const firstEnrollmentCell = screen.getAllByText("20")[0].closest("td");
634
+ expect(firstEnrollmentCell).toHaveAttribute("align", "left");
635
+ });
@@ -0,0 +1,51 @@
1
+ import React from "react"
2
+ import AdvancedTable from '../../pb_advanced_table/_advanced_table'
3
+ import MOCK_DATA from "./advanced_table_mock_data.json"
4
+
5
+ const AdvancedTableColumnStyling = (props) => {
6
+ const columnDefinitions = [
7
+ {
8
+ accessor: "year",
9
+ label: "Year",
10
+ cellAccessors: ["quarter", "month", "day"],
11
+ },
12
+ {
13
+ accessor: "newEnrollments",
14
+ label: "New Enrollments",
15
+ columnStyling:{headerAlignment: "left", cellAlignment: "left"},
16
+ },
17
+ {
18
+ accessor: "scheduledMeetings",
19
+ label: "Scheduled Meetings",
20
+ columnStyling:{headerAlignment: "center", cellAlignment: "center"},
21
+ },
22
+ {
23
+ accessor: "attendanceRate",
24
+ label: "Attendance Rate",
25
+ },
26
+ {
27
+ accessor: "completedClasses",
28
+ label: "Completed Classes",
29
+ },
30
+ {
31
+ accessor: "classCompletionRate",
32
+ label: "Class Completion Rate",
33
+ },
34
+ {
35
+ accessor: "graduatedStudents",
36
+ label: "Graduated Students",
37
+ },
38
+ ]
39
+
40
+ return (
41
+ <div>
42
+ <AdvancedTable
43
+ columnDefinitions={columnDefinitions}
44
+ tableData={MOCK_DATA}
45
+ {...props}
46
+ />
47
+ </div>
48
+ )
49
+ }
50
+
51
+ export default AdvancedTableColumnStyling
@@ -0,0 +1,7 @@
1
+ The `columnStyling` prop is an optional item that can be used within `columnDefinitions` as shown in the code snippet below. It is an object that has 2 optional key/value pairs:
2
+
3
+ 1) `headerAlignment`: This will allow you to control alignment of header content which is set to right aligned by default. you can set this to `left`, `right` or `center`.
4
+
5
+ 2) `cellAlignment`: This will allow you to control alignment of content within all cells in the given column. This is set to right aligned by default. you can set this to `left`, `right` or `center`.
6
+
7
+ `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.
@@ -0,0 +1,77 @@
1
+ import React from "react";
2
+ import AdvancedTable from '../../pb_advanced_table/_advanced_table';
3
+ import MOCK_DATA from "./advanced_table_mock_data.json";
4
+
5
+ const AdvancedTableColumnStylingColumnHeaders = (props) => {
6
+ const columnDefinitions = [
7
+ {
8
+ accessor: "year",
9
+ label: "Year",
10
+ cellAccessors: ["quarter", "month", "day"],
11
+ },
12
+ {
13
+ label: "Enrollment Data",
14
+ columns: [
15
+ {
16
+ label: "Enrollment Stats",
17
+ columns: [
18
+ {
19
+ accessor: "newEnrollments",
20
+ label: "New Enrollments",
21
+ columnStyling:{headerAlignment: "left", cellAlignment: "left"},
22
+
23
+ },
24
+ {
25
+ accessor: "scheduledMeetings",
26
+ label: "Scheduled Meetings",
27
+ },
28
+ ],
29
+ },
30
+ ],
31
+ },
32
+ {
33
+ label: "Performance Data",
34
+ columns: [
35
+ {
36
+ label: "Completion Metrics",
37
+ columns: [
38
+ {
39
+ accessor: "completedClasses",
40
+ label: "Completed Classes",
41
+ columnStyling:{headerAlignment: "center", cellAlignment: "center"},
42
+ },
43
+ {
44
+ accessor: "classCompletionRate",
45
+ label: "Class Completion Rate",
46
+ },
47
+ ],
48
+ },
49
+ {
50
+ label: "Attendance",
51
+ columns: [
52
+ {
53
+ accessor: "attendanceRate",
54
+ label: "Attendance Rate",
55
+ },
56
+ {
57
+ accessor: "scheduledMeetings",
58
+ label: "Scheduled Meetings",
59
+ },
60
+ ],
61
+ },
62
+ ],
63
+ },
64
+ ];
65
+
66
+ return (
67
+ <>
68
+ <AdvancedTable
69
+ columnDefinitions={columnDefinitions}
70
+ tableData={MOCK_DATA}
71
+ {...props}
72
+ />
73
+ </>
74
+ );
75
+ };
76
+
77
+ export default AdvancedTableColumnStylingColumnHeaders
@@ -0,0 +1 @@
1
+ `columnStyling` can also be used with the multi column logic. When used in this way, `columnStyling` must be used within the leaf column's columnDefinition as shown.
@@ -0,0 +1,63 @@
1
+ <% column_definitions = [
2
+ {
3
+ accessor: "year",
4
+ label: "Year",
5
+ cellAccessors: ["quarter", "month", "day"],
6
+ },
7
+ {
8
+ label: "Enrollment Data",
9
+ columns: [
10
+ {
11
+ label: "Enrollment Stats",
12
+ columns: [
13
+ {
14
+ accessor: "newEnrollments",
15
+ label: "New Enrollments",
16
+ column_styling:{header_alignment:"left", cell_alignment:"left"}
17
+ },
18
+ {
19
+ accessor: "scheduledMeetings",
20
+ label: "Scheduled Meetings",
21
+ },
22
+ ],
23
+ },
24
+ ],
25
+ },
26
+ {
27
+ label: "Performance Data",
28
+ columns: [
29
+ {
30
+ label: "Completion Metrics",
31
+ columns: [
32
+ {
33
+ accessor: "completedClasses",
34
+ label: "Completed Classes",
35
+ column_styling:{header_alignment:"center", cell_alignment:"center"}
36
+ },
37
+ {
38
+ accessor: "classCompletionRate",
39
+ label: "Class Completion Rate",
40
+ },
41
+ ],
42
+ },
43
+ {
44
+ label: "Attendance",
45
+ columns: [
46
+ {
47
+ accessor: "attendanceRate",
48
+ label: "Attendance Rate",
49
+ },
50
+ {
51
+ accessor: "scheduledMeetings",
52
+ label: "Scheduled Meetings",
53
+ },
54
+ ],
55
+ },
56
+ ],
57
+ },
58
+ ] %>
59
+
60
+ <%= pb_rails("advanced_table", props: { id: "column-styling-multi", table_data: @table_data, column_definitions: column_definitions }) do %>
61
+ <%= pb_rails("advanced_table/table_header", props: { column_definitions: column_definitions }) %>
62
+ <%= pb_rails("advanced_table/table_body", props: { table_data: @table_data, column_definitions: column_definitions }) %>
63
+ <% end %>
@@ -0,0 +1 @@
1
+ `column_styling` can also be used with the multi column logic. When used in this way, `column_styling` must be used within the leaf column's column_definition as shown.
@@ -0,0 +1,38 @@
1
+ <% column_definitions = [
2
+ {
3
+ accessor: "year",
4
+ label: "Year",
5
+ cellAccessors: ["quarter", "month", "day"],
6
+ },
7
+ {
8
+ accessor: "newEnrollments",
9
+ label: "New Enrollments",
10
+ column_styling:{header_alignment:"left", cell_alignment:"left"}
11
+ },
12
+ {
13
+ accessor: "scheduledMeetings",
14
+ label: "Scheduled Meetings",
15
+ column_styling:{header_alignment:"center", cell_alignment:"center"}
16
+ },
17
+ {
18
+ accessor: "attendanceRate",
19
+ label: "Attendance Rate",
20
+ },
21
+ {
22
+ accessor: "completedClasses",
23
+ label: "Completed Classes",
24
+ },
25
+ {
26
+ accessor: "classCompletionRate",
27
+ label: "Class Completion Rate",
28
+ },
29
+ {
30
+ accessor: "graduatedStudents",
31
+ label: "Graduated Students",
32
+ }
33
+ ] %>
34
+
35
+ <%= pb_rails("advanced_table", props: { id: "column-styling", table_data: @table_data, column_definitions: column_definitions }) do %>
36
+ <%= pb_rails("advanced_table/table_header", props: { column_definitions: column_definitions }) %>
37
+ <%= pb_rails("advanced_table/table_body", props: { table_data: @table_data, column_definitions: column_definitions }) %>
38
+ <% end %>
@@ -0,0 +1,7 @@
1
+ The `column_styling` prop is an optional item that can be used within `column_definitions` as shown in the code snippet below. It is an object that has 2 optional key/value pairs:
2
+
3
+ 1) `header_alignment`: This will allow you to control alignment of header content which is set to right aligned by default. you can set this to `left`, `right` or `center`.
4
+
5
+ 2) `cell_alignment`: This will allow you to control alignment of content within all cells in the given column. This is set to right aligned by default. you can set this to `left`, `right` or `center`.
6
+
7
+ `column_styling` can be used within the column_definition of all the columns or some of them, as shown. Each column has its own individual control in this way.
@@ -19,6 +19,8 @@ examples:
19
19
  - advanced_table_selectable_rows_actions_rails: Selectable Rows (With Actions)
20
20
  - advanced_table_selectable_rows_header_rails: Selectable Rows (No Actions Bar)
21
21
  - advanced_table_scrollbar_none: Advanced Table Scrollbar None
22
+ # - advanced_table_column_styling_rails: Column Styling
23
+ # - advanced_table_column_styling_column_headers_rails: Column Styling with Multiple Headers
22
24
 
23
25
  react:
24
26
  - advanced_table_default: Default (Required Props)
@@ -57,3 +59,5 @@ examples:
57
59
  - advanced_table_column_visibility_multi: Column Visibility Control with Multi-Header Columns
58
60
  - advanced_table_pinned_rows: Pinned Rows
59
61
  - advanced_table_scrollbar_none: Advanced Table Scrollbar None
62
+ - advanced_table_column_styling: Column Styling
63
+ - advanced_table_column_styling_column_headers: Column Styling with Multiple Headers
@@ -34,3 +34,5 @@ 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 AdvancedTableColumnStyling } from './_advanced_table_column_styling.jsx'
38
+ export { default as AdvancedTableColumnStylingColumnHeaders } from './_advanced_table_column_styling_column_headers.jsx'
@@ -7,7 +7,7 @@
7
7
  <% header_row.each_with_index do |cell, cell_index| %>
8
8
  <% header_id = cell[:accessor].present? ? cell[:accessor] : "header_#{row_index}_#{cell_index}" %>
9
9
  <%= pb_rails("table/table_header", props: { id: header_id, colspan: cell[:colspan], classname: [object.th_classname(is_first_column: cell_index.zero?), ('last-header-cell' if cell[:is_last_in_group] && cell_index != 0)].compact.join(' '), sort_menu: cell[:accessor] ? cell[:sort_menu] : nil }) do %>
10
- <%= pb_rails("flex", props: { align: "center", justify: cell_index.zero? ? "start" : row_index === header_rows.size - 1 ? "end" : "center", text_align: "end" }) do %>
10
+ <%= pb_rails("flex", props: { align: "center", justify: cell_index.zero? ? "start" : row_index === header_rows.size - 1 ? "end" : "center", text_align: (cell[:header_alignment] || "end") }) do %>
11
11
  <% if cell_index.zero? && row_index === header_rows.size - 1 %>
12
12
  <% if object.selectable_rows && object.enable_toggle_expansion != "none" %>
13
13
  <%= pb_rails("flex/flex_item", props: { padding_right: "xs" }) do %>
@@ -98,6 +98,9 @@ module Playbook
98
98
 
99
99
  process_columns(col[:columns], rows, current_depth + 1, max_depth)
100
100
  else
101
+ raw_styling = col[:column_styling] || {}
102
+ header_alignment = raw_styling[:header_alignment]
103
+
101
104
  colspan = 1
102
105
  rows[current_depth] << {
103
106
  label: col[:label],
@@ -105,6 +108,7 @@ module Playbook
105
108
  accessor: col[:accessor],
106
109
  sort_menu: col[:sort_menu],
107
110
  is_last_in_group: is_last && current_depth.positive?,
111
+ header_alignment: header_alignment,
108
112
  }
109
113
  end
110
114
  end
@@ -137,6 +141,7 @@ module Playbook
137
141
  accessor: col[:accessor],
138
142
  label: col[:label] || "",
139
143
  sort_menu: col[:sort_menu] || nil,
144
+ column_styling: col[:column_styling] || {},
140
145
  }
141
146
  (max_depth - 1).times do
142
147
  wrapped = { label: "", columns: [wrapped] }
@@ -6,7 +6,7 @@
6
6
  <% object.column_definitions.each_with_index do |column, index| %>
7
7
  <% next unless column[:accessor].present? %>
8
8
  <%= pb_rails("table/table_cell", props: { classname:object.td_classname(column, index)}) do %>
9
- <%= pb_rails("flex", props:{ align: "center", justify: index.zero? ? "start" : "end", classname: object.loading ? "loading-cell" : "" }) do %>
9
+ <%= pb_rails("flex", props:{ align: "center", justify: object.justify_for(column, index), classname: object.loading ? "loading-cell" : "" }) do %>
10
10
  <% if collapsible_trail && index.zero? %>
11
11
  <% (1..depth).each do |i| %>
12
12
  <% additional_offset = i > 1 ? (i - 1) * 0.25 : 0 %>
@@ -34,7 +34,7 @@
34
34
  </button>
35
35
  <% end %>
36
36
  <% end %>
37
- <%= pb_rails("flex/flex_item", props:{padding_left: index.zero? && (object.row[:children].present? || has_integrated_checkbox) ? "none" : "xs"}) do %>
37
+ <%= pb_rails("flex/flex_item") do %>
38
38
  <% if column[:custom_renderer].present? %>
39
39
  <%= raw(column[:custom_renderer].call(object.row, custom_renderer_value(column, index))) %>
40
40
  <% elsif index.zero? %>
@@ -80,6 +80,20 @@ module Playbook
80
80
  end
81
81
  end
82
82
 
83
+ def justify_for(column, index)
84
+ if index.zero?
85
+ "start"
86
+ else
87
+ case cell_alignment_for(column)
88
+ when "left" then "start"
89
+ when "center" then "center"
90
+ when "right" then "end"
91
+ else
92
+ "end"
93
+ end
94
+ end
95
+ end
96
+
83
97
  private
84
98
 
85
99
  def custom_renderer_value(column, index)
@@ -103,6 +117,25 @@ module Playbook
103
117
  def subrow_depth_classname
104
118
  depth.positive? ? "depth-sub-row-#{depth}" : ""
105
119
  end
120
+
121
+ def find_column_def_by_accessor(defs, target_accessor)
122
+ defs.each do |col|
123
+ return col if col[:accessor] == target_accessor
124
+
125
+ if col[:columns].is_a?(Array)
126
+ found = find_column_def_by_accessor(col[:columns], target_accessor)
127
+ return found if found
128
+ end
129
+ end
130
+ nil
131
+ end
132
+
133
+ def cell_alignment_for(column)
134
+ return nil unless column[:accessor]
135
+
136
+ orig_def = find_column_def_by_accessor(column_definitions, column[:accessor])
137
+ orig_def[:column_styling][:cell_alignment] if orig_def && orig_def[:column_styling].is_a?(Hash)
138
+ end
106
139
  end
107
140
  end
108
141
  end