playbook_ui 14.9.0.pre.alpha.play1742globalheightfixes4766 → 14.9.0.pre.alpha.play1742globalheightfixes4925

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +5 -3
  3. data/app/pb_kits/playbook/pb_avatar/_avatar.scss +0 -2
  4. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom.jsx +53 -49
  5. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom_rails.html.erb +29 -36
  6. data/app/pb_kits/playbook/pb_body/_body.scss +14 -13
  7. data/app/pb_kits/playbook/pb_body/_body_mixins.scss +22 -16
  8. data/app/pb_kits/playbook/pb_bread_crumbs/docs/_bread_crumbs_default.jsx +6 -0
  9. data/app/pb_kits/playbook/pb_caption/_caption_mixin.scss +2 -1
  10. data/app/pb_kits/playbook/pb_card/_card_mixin.scss +1 -1
  11. data/app/pb_kits/playbook/pb_collapsible/_collapsible.tsx +9 -4
  12. data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleContent.tsx +2 -2
  13. data/app/pb_kits/playbook/pb_collapsible/child_kits/CollapsibleMain.tsx +2 -2
  14. data/app/pb_kits/playbook/pb_file_upload/_file_upload.scss +5 -0
  15. data/app/pb_kits/playbook/pb_file_upload/_file_upload.tsx +7 -2
  16. data/app/pb_kits/playbook/pb_file_upload/file_upload.html.erb +8 -2
  17. data/app/pb_kits/playbook/pb_link/_link.scss +3 -3
  18. data/app/pb_kits/playbook/pb_nav/_bold_mixin.scss +11 -1
  19. data/app/pb_kits/playbook/pb_nav/_collapsible_nav.scss +16 -2
  20. data/app/pb_kits/playbook/pb_nav/_vertical_nav.scss +1 -1
  21. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +4 -4
  22. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +1 -1
  23. data/app/pb_kits/playbook/pb_stat_change/_stat_change.tsx +44 -36
  24. data/app/pb_kits/playbook/pb_stat_change/stat_change.html.erb +4 -4
  25. data/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns.html.erb +95 -0
  26. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible.jsx +75 -0
  27. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible.md +1 -0
  28. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.jsx +108 -0
  29. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_click.md +2 -0
  30. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content.jsx +94 -0
  31. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_custom_content.md +0 -0
  32. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows.jsx +83 -0
  33. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_rows.md +3 -0
  34. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table.jsx +120 -0
  35. data/app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table.md +1 -0
  36. data/app/pb_kits/playbook/pb_table/docs/example.yml +5 -0
  37. data/app/pb_kits/playbook/pb_table/docs/index.js +5 -0
  38. data/app/pb_kits/playbook/pb_table/index.ts +100 -26
  39. data/app/pb_kits/playbook/pb_table/styles/_all.scss +2 -1
  40. data/app/pb_kits/playbook/pb_table/styles/_collapsible.scss +35 -0
  41. data/app/pb_kits/playbook/pb_table/subcomponents/_table_row.tsx +106 -1
  42. data/app/pb_kits/playbook/pb_table/table.html.erb +1 -1
  43. data/app/pb_kits/playbook/pb_table/table.rb +17 -2
  44. data/app/pb_kits/playbook/pb_title/_title.scss +6 -5
  45. data/app/pb_kits/playbook/pb_title/_title_mixin.scss +13 -0
  46. data/app/pb_kits/playbook/tokens/_titles.scss +0 -8
  47. data/app/pb_kits/playbook/utilities/_hover.scss +11 -2
  48. data/app/pb_kits/playbook/utilities/globalProps.ts +2 -0
  49. data/app/pb_kits/playbook/utilities/test/globalProps/hover.test.js +15 -0
  50. data/dist/chunks/{_typeahead-B8fkIeXA.js → _typeahead-D-DFD48D.js} +3 -3
  51. data/dist/chunks/_weekday_stacked-CCO9Egzl.js +45 -0
  52. data/dist/chunks/{lib-SyD3buPZ.js → lib-CuCy3_xO.js} +3 -3
  53. data/dist/chunks/{pb_form_validation-Dt8UJgrJ.js → pb_form_validation-D37k10a0.js} +1 -1
  54. data/dist/chunks/vendor.js +1 -1
  55. data/dist/menu.yml +1 -1
  56. data/dist/playbook-doc.js +1 -1
  57. data/dist/playbook-rails-react-bindings.js +1 -1
  58. data/dist/playbook-rails.js +1 -1
  59. data/dist/playbook.css +1 -1
  60. data/lib/playbook/hover.rb +7 -1
  61. data/lib/playbook/version.rb +1 -1
  62. metadata +18 -6
  63. data/dist/chunks/_weekday_stacked-DjRTXEi-.js +0 -45
@@ -0,0 +1,83 @@
1
+ import React from 'react'
2
+ import { Table, Background, Icon } from 'playbook-ui'
3
+
4
+ const TableWithCollapsibleWithNestedRows = (props) => {
5
+
6
+ const Content = () => {
7
+ return (
8
+ <Table
9
+ borderRadius="none"
10
+ container={false}
11
+ size="sm"
12
+ {...props}
13
+ >
14
+ <Background tag="tr"
15
+ {...props}
16
+ >
17
+ <Table.Cell>Expanded</Table.Cell>
18
+ <Table.Cell>Expanded</Table.Cell>
19
+ <Table.Cell>Expanded</Table.Cell>
20
+ <Table.Cell>Expanded</Table.Cell>
21
+ <Table.Cell>Expanded</Table.Cell>
22
+ </Background>
23
+ </Table>
24
+ );
25
+ };
26
+
27
+ return (
28
+ <Table
29
+ size="sm"
30
+ {...props}
31
+ >
32
+ <Table.Head>
33
+ <Table.Row>
34
+ <Table.Header>{'Column 1'}</Table.Header>
35
+ <Table.Header>{'Column 2'}</Table.Header>
36
+ <Table.Header>{'Column 3'}</Table.Header>
37
+ <Table.Header>{'Column 4'}</Table.Header>
38
+ <Table.Header>{'Column 5'}</Table.Header>
39
+ <Table.Header>{''}</Table.Header>
40
+ </Table.Row>
41
+
42
+ </Table.Head>
43
+ <Table.Body>
44
+ <Table.Row collapsible
45
+ collapsibleContent={<Content/>}
46
+ collapsibleSideHighlight={false}
47
+ >
48
+ <Table.Cell>{'Value 1'}</Table.Cell>
49
+ <Table.Cell>{'Value 2'}</Table.Cell>
50
+ <Table.Cell>{'Value 3'}</Table.Cell>
51
+ <Table.Cell>{'Value 4'}</Table.Cell>
52
+ <Table.Cell>{'Value 5'}</Table.Cell>
53
+ <Table.Cell textAlign="right">{
54
+ <Icon
55
+ color="primary"
56
+ fixedWidth
57
+ icon="chevron-down"
58
+ />}
59
+ </Table.Cell>
60
+
61
+ </Table.Row>
62
+ <Table.Row>
63
+ <Table.Cell>{'Value 1'}</Table.Cell>
64
+ <Table.Cell>{'Value 2'}</Table.Cell>
65
+ <Table.Cell>{'Value 3'}</Table.Cell>
66
+ <Table.Cell>{'Value 4'}</Table.Cell>
67
+ <Table.Cell>{'Value 5'}</Table.Cell>
68
+ <Table.Cell>{''}</Table.Cell>
69
+ </Table.Row>
70
+ <Table.Row>
71
+ <Table.Cell>{'Value 1'}</Table.Cell>
72
+ <Table.Cell>{'Value 2'}</Table.Cell>
73
+ <Table.Cell>{'Value 3'}</Table.Cell>
74
+ <Table.Cell>{'Value 4'}</Table.Cell>
75
+ <Table.Cell>{'Value 5'}</Table.Cell>
76
+ <Table.Cell>{''}</Table.Cell>
77
+ </Table.Row>
78
+ </Table.Body>
79
+ </Table>
80
+ )
81
+ }
82
+
83
+ export default TableWithCollapsibleWithNestedRows
@@ -0,0 +1,3 @@
1
+ The `collapsibleContent` can display any content, including nested Table Rows.
2
+
3
+ Additionally, the `collapsibleSideHighlight` can also be removed by setting it to false if needed. This prop is set to true by default.
@@ -0,0 +1,120 @@
1
+ import React from 'react'
2
+ import {Pill, Background, Table, Icon} from "playbook-ui"
3
+
4
+ const TableWithCollapsibleWithNestedTable = (props) => {
5
+
6
+ const Content = () => {
7
+ return (
8
+ <Table
9
+ borderRadius="none"
10
+ container={false}
11
+ size="sm"
12
+ {...props}
13
+ >
14
+ <Table.Head>
15
+ <Background
16
+ tag="tr"
17
+ {...props}
18
+ >
19
+ <Table.Header>{"Alt Header"}</Table.Header>
20
+ <Table.Header>{"Alt Header"}</Table.Header>
21
+ <Table.Header>{"Alt Header"}</Table.Header>
22
+ <Table.Header>{"Alt Header"}</Table.Header>
23
+ </Background>
24
+ </Table.Head>
25
+ <Table.Body>
26
+ <Table.Row>
27
+ <Table.Cell>{"Expanded"}</Table.Cell>
28
+ <Table.Cell>{"Expanded"}</Table.Cell>
29
+ <Table.Cell>{"Expanded"}</Table.Cell>
30
+ <Table.Cell>
31
+ <Pill text="Pill"
32
+ variant="primary"
33
+ {...props}
34
+ />
35
+ </Table.Cell>
36
+ </Table.Row>
37
+ <Table.Row>
38
+ <Table.Cell>{"Expanded"}</Table.Cell>
39
+ <Table.Cell>{"Expanded"}</Table.Cell>
40
+ <Table.Cell>{"Expanded"}</Table.Cell>
41
+ <Table.Cell>
42
+ <Pill text="Pill"
43
+ variant="primary"
44
+ {...props}
45
+ />
46
+ </Table.Cell>
47
+ </Table.Row>
48
+ <Table.Row>
49
+ <Table.Cell>{"Expanded"}</Table.Cell>
50
+ <Table.Cell>{"Expanded"}</Table.Cell>
51
+ <Table.Cell>{"Expanded"}</Table.Cell>
52
+ <Table.Cell>
53
+ <Pill text="Pill"
54
+ variant="primary"
55
+ {...props}
56
+ />
57
+ </Table.Cell>
58
+ </Table.Row>
59
+ </Table.Body>
60
+ </Table>
61
+ );
62
+ };
63
+
64
+ return (
65
+ <Table
66
+ size="sm"
67
+ {...props}
68
+ >
69
+ <Table.Head>
70
+ <Table.Row>
71
+ <Table.Header>{'Column 1'}</Table.Header>
72
+ <Table.Header>{'Column 2'}</Table.Header>
73
+ <Table.Header>{'Column 3'}</Table.Header>
74
+ <Table.Header>{'Column 4'}</Table.Header>
75
+ <Table.Header>{'Column 5'}</Table.Header>
76
+ <Table.Header>{''}</Table.Header>
77
+ </Table.Row>
78
+
79
+ </Table.Head>
80
+ <Table.Body>
81
+ <Table.Row collapsible
82
+ collapsibleContent={<Content/>}
83
+ collapsibleSideHighlight={false}
84
+ >
85
+ <Table.Cell>{'Value 1'}</Table.Cell>
86
+ <Table.Cell>{'Value 2'}</Table.Cell>
87
+ <Table.Cell>{'Value 3'}</Table.Cell>
88
+ <Table.Cell>{'Value 4'}</Table.Cell>
89
+ <Table.Cell>{'Value 5'}</Table.Cell>
90
+ <Table.Cell textAlign="right">{
91
+ <Icon
92
+ color="primary"
93
+ fixedWidth
94
+ icon="chevron-down"
95
+ />}
96
+ </Table.Cell>
97
+
98
+ </Table.Row>
99
+ <Table.Row>
100
+ <Table.Cell>{'Value 1'}</Table.Cell>
101
+ <Table.Cell>{'Value 2'}</Table.Cell>
102
+ <Table.Cell>{'Value 3'}</Table.Cell>
103
+ <Table.Cell>{'Value 4'}</Table.Cell>
104
+ <Table.Cell>{'Value 5'}</Table.Cell>
105
+ <Table.Cell>{''}</Table.Cell>
106
+ </Table.Row>
107
+ <Table.Row>
108
+ <Table.Cell>{'Value 1'}</Table.Cell>
109
+ <Table.Cell>{'Value 2'}</Table.Cell>
110
+ <Table.Cell>{'Value 3'}</Table.Cell>
111
+ <Table.Cell>{'Value 4'}</Table.Cell>
112
+ <Table.Cell>{'Value 5'}</Table.Cell>
113
+ <Table.Cell>{''}</Table.Cell>
114
+ </Table.Row>
115
+ </Table.Body>
116
+ </Table>
117
+ )
118
+ }
119
+
120
+ export default TableWithCollapsibleWithNestedTable
@@ -0,0 +1 @@
1
+ The `collapsibleContent` can also be used to display nested Tables within each Row.
@@ -55,3 +55,8 @@ examples:
55
55
  - table_with_subcomponents: Table with Sub Components (Table Elements)
56
56
  - table_with_subcomponents_as_divs: Table with Sub Components (Divs)
57
57
  - table_outer_padding: Outer Padding
58
+ - table_with_collapsible: Table with Collapsible
59
+ - table_with_collapsible_with_custom_click: Table with Collapsible with Custom Click
60
+ - table_with_collapsible_with_custom_content: Table with Collapsible with Custom Content
61
+ - table_with_collapsible_with_nested_rows: Table with Collapsible with Nested Rows
62
+ - table_with_collapsible_with_nested_table: Table with Collapsible with Nested Table
@@ -26,3 +26,8 @@ export { default as TableWithSubcomponents } from './_table_with_subcomponents.j
26
26
  export { default as TableWithSubcomponentsAsDivs } from './_table_with_subcomponents_as_divs.jsx'
27
27
  export { default as TableOuterPadding } from './_table_outer_padding.jsx'
28
28
  export { default as TableStickyLeftColumns } from './_table_sticky_left_columns.jsx'
29
+ export { default as TableWithCollapsible } from './_table_with_collapsible.jsx'
30
+ export { default as TableWithCollapsibleWithCustomContent } from './_table_with_collapsible_with_custom_content.jsx'
31
+ export { default as TableWithCollapsibleWithNestedTable } from './_table_with_collapsible_with_nested_table.jsx'
32
+ export { default as TableWithCollapsibleWithNestedRows } from './_table_with_collapsible_with_nested_rows.jsx'
33
+ export { default as TableWithCollapsibleWithCustomClick } from './_table_with_collapsible_with_custom_click.jsx'
@@ -1,32 +1,106 @@
1
1
  import PbEnhancedElement from '../pb_enhanced_element'
2
2
 
3
3
  export default class PbTable extends PbEnhancedElement {
4
- static get selector(): string {
5
- return '.table-responsive-collapse'
6
- }
7
-
8
- connect(): void {
9
- const tables = document.querySelectorAll('.table-responsive-collapse');
10
-
11
- // Each Table
12
- [].forEach.call(tables, (table: HTMLTableElement) => {
13
- // Header Titles
14
- const headers: string[] = [];
15
- [].forEach.call(table.querySelectorAll('th'), (header: HTMLTableCellElement) => {
16
- const colSpan = header.colSpan
17
- for (let i = 0; i < colSpan; i++) {
18
- headers.push(header.textContent.replace(/\r?\n|\r/, ''));
4
+ private stickyLeftColumns: string[] = [];
5
+ private handleStickyColumnsRef: () => void;
6
+
7
+ static get selector(): string {
8
+ return '.table-responsive-collapse'
9
+ }
10
+
11
+ connect(): void {
12
+ const tables = document.querySelectorAll('.table-responsive-collapse');
13
+ // Each Table
14
+ [].forEach.call(tables, (table: HTMLTableElement) => {
15
+ // Header Titles
16
+ const headers: string[] = [];
17
+ [].forEach.call(table.querySelectorAll('th'), (header: HTMLTableCellElement) => {
18
+ const colSpan = header.colSpan
19
+ for (let i = 0; i < colSpan; i++) {
20
+ headers.push(header.textContent.replace(/\r?\n|\r/, ''));
21
+ }
22
+ });
23
+ // for each row in tbody
24
+ [].forEach.call(table.querySelectorAll('tbody tr'), (row: HTMLTableRowElement) => {
25
+ // for each cell
26
+ [].forEach.call(row.cells, (cell: HTMLTableCellElement, headerIndex: number) => {
27
+ // apply the attribute
28
+ cell.setAttribute('data-title', headers[headerIndex])
29
+ })
30
+ })
31
+ });
32
+
33
+ // New sticky columns logic
34
+ this.initStickyColumns();
35
+ }
36
+
37
+ private initStickyColumns(): void {
38
+ // Find tables with sticky-left-column class
39
+ const tables = document.querySelectorAll('.sticky-left-column');
40
+
41
+ tables.forEach((table) => {
42
+ // Extract sticky left column IDs by looking at the component's class
43
+ const classList = Array.from(table.classList);
44
+
45
+ // Look for classes in the format sticky-left-column-{ids}
46
+ const stickyColumnClass = classList.find(cls => cls.startsWith('sticky-columns-'));
47
+ if (stickyColumnClass) {
48
+ // Extract the IDs from the class name
49
+ this.stickyLeftColumns = stickyColumnClass
50
+ .replace('sticky-columns-', '')
51
+ .split('-');
52
+
53
+ if (this.stickyLeftColumns.length > 0) {
54
+ this.handleStickyColumnsRef = this.handleStickyColumns.bind(this);
55
+ this.handleStickyColumns();
56
+ window.addEventListener('resize', this.handleStickyColumnsRef);
57
+ }
19
58
  }
20
59
  });
60
+ }
21
61
 
22
- // for each row in tbody
23
- [].forEach.call(table.querySelectorAll('tbody tr'), (row: HTMLTableRowElement) => {
24
- // for each cell
25
- [].forEach.call(row.cells, (cell: HTMLTableCellElement, headerIndex: number) => {
26
- // apply the attribute
27
- cell.setAttribute('data-title', headers[headerIndex])
28
- })
29
- })
30
- })
31
- }
32
- }
62
+ private handleStickyColumns(): void {
63
+ let accumulatedWidth = 0;
64
+
65
+ this.stickyLeftColumns.forEach((colId, index) => {
66
+ const isLastColumn = index === this.stickyLeftColumns.length - 1;
67
+ const header = document.querySelector(`th[id="${colId}"]`);
68
+ const cells = document.querySelectorAll(`td[id="${colId}"]`);
69
+
70
+ if (header) {
71
+ header.classList.add('sticky');
72
+ (header as HTMLElement).style.left = `${accumulatedWidth}px`;
73
+
74
+ if (!isLastColumn) {
75
+ header.classList.add('with-border');
76
+ header.classList.remove('sticky-shadow');
77
+ } else {
78
+ header.classList.remove('with-border');
79
+ header.classList.add('sticky-shadow');
80
+ }
81
+
82
+ accumulatedWidth += (header as HTMLElement).offsetWidth;
83
+ }
84
+
85
+ cells.forEach((cell) => {
86
+ cell.classList.add('sticky');
87
+ (cell as HTMLElement).style.left = `${accumulatedWidth - (header as HTMLElement).offsetWidth}px`;
88
+
89
+ if (!isLastColumn) {
90
+ cell.classList.add('with-border');
91
+ cell.classList.remove('sticky-shadow');
92
+ } else {
93
+ cell.classList.remove('with-border');
94
+ cell.classList.add('sticky-shadow');
95
+ }
96
+ });
97
+ });
98
+ }
99
+
100
+ // Cleanup method to remove event listener
101
+ disconnect(): void {
102
+ if (this.handleStickyColumnsRef) {
103
+ window.removeEventListener('resize', this.handleStickyColumnsRef);
104
+ }
105
+ }
106
+ }
@@ -21,4 +21,5 @@
21
21
  @import "striped";
22
22
  @import "outer_padding";
23
23
  @import "sticky_columns";
24
- @import "scroll";
24
+ @import "scroll";
25
+ @import "collapsible";
@@ -0,0 +1,35 @@
1
+ @import "../../tokens/colors";
2
+
3
+ .table_collapsible_side_highlight {
4
+ border-left: 4px solid $primary;
5
+ &.dark {
6
+ border-left: 4px solid $active_dark;
7
+ }
8
+ }
9
+
10
+ [class^="pb_table"] {
11
+ &.table-sm,
12
+ &.table-md,
13
+ &.table-lg {
14
+ &.table-card {
15
+ tbody,
16
+ .pb_table_tbody {
17
+ tr,
18
+ .pb_table_tr {
19
+ &.collapsible_table_row {
20
+ td,
21
+ .pb_table_td {
22
+ border-bottom-color: transparent;
23
+ }
24
+ &:hover {
25
+ td,
26
+ .pb_table_td {
27
+ border-bottom-color: darken($border_light, 10%);
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
@@ -7,14 +7,21 @@ import {
7
7
  buildHtmlProps,
8
8
  } from "../../utilities/props";
9
9
  import { globalProps } from "../../utilities/globalProps";
10
+ import Collapsible from "../../pb_collapsible/_collapsible";
11
+ import useCollapsible from "../../pb_collapsible/useCollapsible";
10
12
 
11
13
  type TableRowPropTypes = {
12
14
  aria?: { [key: string]: string };
13
15
  children: React.ReactNode[] | React.ReactNode;
14
16
  className: string;
17
+ collapsible?: boolean;
18
+ collapsibleContent?: React.ReactNode[] | React.ReactNode;
19
+ collapsibleSideHighlight?: boolean;
15
20
  data?: { [key: string]: string };
21
+ dark?: boolean;
16
22
  htmlOptions?: { [key: string]: string | number | boolean | (() => void) };
17
23
  id?: string;
24
+ toggleCellId?: string;
18
25
  sideHighlightColor: string;
19
26
  tag?: "table" | "div";
20
27
  };
@@ -23,10 +30,15 @@ const TableRow = (props: TableRowPropTypes): React.ReactElement => {
23
30
  const {
24
31
  aria = {},
25
32
  children,
33
+ collapsible,
34
+ collapsibleContent,
35
+ collapsibleSideHighlight = true,
26
36
  className,
27
37
  data = {},
38
+ dark = false,
28
39
  htmlOptions = {},
29
40
  id,
41
+ toggleCellId,
30
42
  sideHighlightColor = "none",
31
43
  tag = "table",
32
44
  } = props;
@@ -36,17 +48,110 @@ const TableRow = (props: TableRowPropTypes): React.ReactElement => {
36
48
  const htmlProps = buildHtmlProps(htmlOptions);
37
49
  const sideHighlightClass =
38
50
  sideHighlightColor != "" ? `side_highlight_${sideHighlightColor}` : null;
51
+
52
+ const [isCollapsed, setIsCollapsed] = useCollapsible(true);
53
+
54
+ const collapsibleRow = collapsible && isCollapsed === true ? "collapsible_table_row" : null;
39
55
  const classes = classnames(
40
56
  buildCss("pb_table_row_kit", sideHighlightClass),
41
57
  "pb_table_tr",
58
+ collapsibleRow,
42
59
  globalProps(props),
43
60
  className
44
61
  );
45
62
  const isTableTag = tag === "table";
46
63
 
64
+ // const [isCollapsed, setIsCollapsed] = useCollapsible(true);
65
+
66
+ const colSpan = React.Children.count(children);
67
+
68
+ const handleRowClick = (event: React.MouseEvent) => {
69
+ if (toggleCellId) {
70
+ const target = event.target as HTMLElement;
71
+ const clickedCell = target.closest(`#${toggleCellId}`);
72
+ const isIconClick =
73
+ target instanceof SVGElement &&
74
+ (target.matches("svg.pb_custom_icon") || target.closest("svg.pb_custom_icon"));
75
+
76
+ if (clickedCell || isIconClick) {
77
+ setIsCollapsed(!isCollapsed);
78
+ }
79
+ } else {
80
+ setIsCollapsed(!isCollapsed);
81
+ }
82
+ };
83
+
47
84
  return (
48
85
  <>
49
- {isTableTag ? (
86
+ {collapsible ? (
87
+ isTableTag ? (
88
+ <>
89
+ <tr
90
+ {...ariaProps}
91
+ {...dataProps}
92
+ {...htmlProps}
93
+ className={classes}
94
+ id={id}
95
+ onClick={(e)=>handleRowClick(e)}
96
+ style={{ cursor: toggleCellId ? "default" : "pointer" }}
97
+ >
98
+ {children}
99
+ </tr>
100
+ <tr>
101
+ <Collapsible
102
+ collapsed={isCollapsed}
103
+ dark={dark}
104
+ htmlOptions={{ colSpan: colSpan }}
105
+ padding="none"
106
+ tag="td"
107
+ >
108
+ <tr/>
109
+ <Collapsible.Content
110
+ className={collapsibleSideHighlight ? `table_collapsible_side_highlight` : ''}
111
+ dark={dark}
112
+ margin="none"
113
+ padding="none"
114
+ >
115
+ {collapsibleContent}
116
+ </Collapsible.Content>
117
+ </Collapsible>
118
+ </tr>
119
+ </>
120
+ ) : (
121
+ <>
122
+ <div
123
+ {...ariaProps}
124
+ {...dataProps}
125
+ {...htmlProps}
126
+ className={classes}
127
+ id={id}
128
+ onClick={handleRowClick}
129
+ style={{ cursor: "pointer" }}
130
+ >
131
+ {children}
132
+ </div>
133
+ <tr>
134
+ <Collapsible
135
+ collapsed={isCollapsed}
136
+ dark={dark}
137
+ htmlOptions={{ colSpan: colSpan }}
138
+ padding="none"
139
+ tag="td"
140
+ >
141
+ <tr/>
142
+ <Collapsible.Content
143
+ className={collapsibleSideHighlight ? `table_collapsible_side_highlight` : ''}
144
+ dark={dark}
145
+ margin="none"
146
+ padding="none"
147
+ >
148
+ {collapsibleContent}
149
+ </Collapsible.Content>
150
+ </Collapsible>
151
+ </tr>
152
+ </>
153
+ )
154
+ ) : isTableTag ? (
50
155
  <tr
51
156
  {...ariaProps}
52
157
  {...dataProps}
@@ -18,4 +18,4 @@
18
18
  <%= content.presence %>
19
19
  <% end %>
20
20
  <% end %>
21
- <% end %>
21
+ <% end %>
@@ -23,6 +23,8 @@ module Playbook
23
23
  prop :text
24
24
  prop :sticky, type: Playbook::Props::Boolean,
25
25
  default: false
26
+ prop :sticky_left_column, type: Playbook::Props::Array,
27
+ default: []
26
28
  prop :vertical_border, type: Playbook::Props::Boolean,
27
29
  default: false
28
30
  prop :striped, type: Playbook::Props::Boolean,
@@ -37,8 +39,8 @@ module Playbook
37
39
  def classname
38
40
  generate_classname(
39
41
  "pb_table", "table-#{size}", single_line_class, dark_class,
40
- disable_hover_class, container_class, data_table_class, sticky_class, collapse_class,
41
- vertical_border_class, striped_class, outer_padding_class,
42
+ disable_hover_class, container_class, data_table_class, sticky_class, sticky_left_column_class,
43
+ collapse_class, vertical_border_class, striped_class, outer_padding_class,
42
44
  "table-responsive-#{responsive}", separator: " "
43
45
  )
44
46
  end
@@ -73,6 +75,19 @@ module Playbook
73
75
  sticky ? "sticky-header" : nil
74
76
  end
75
77
 
78
+ def sticky_left_column_class
79
+ if sticky_left_column.empty?
80
+ nil
81
+ else
82
+ sticky_col_classname = "sticky-left-column sticky-columns"
83
+ sticky_left_column.each do |id|
84
+ sticky_col_classname += "-#{id}"
85
+ end
86
+
87
+ sticky_col_classname
88
+ end
89
+ end
90
+
76
91
  def striped_class
77
92
  striped ? "striped" : nil
78
93
  end
@@ -49,10 +49,11 @@
49
49
  }
50
50
 
51
51
  &.dark {
52
- @include pb_title_dark;
53
- }
54
-
55
- &.dark[class*=_link] {
56
- @include pb_title_dark_link;
52
+ @include title_dark;
53
+ @each $name, $color in $pb_dark_title_colors {
54
+ &[class*="_#{$name}"] {
55
+ color: $color;
56
+ }
57
+ }
57
58
  }
58
59
  }
@@ -9,6 +9,15 @@ $pb_title_colors: (
9
9
  link: $primary
10
10
  );
11
11
 
12
+ $pb_dark_title_colors: (
13
+ default: $text_dk_default,
14
+ light: $text_dk_light,
15
+ lighter: $text_dk_lighter,
16
+ success: $success,
17
+ error: $error_dark,
18
+ link: $active_dark
19
+ );
20
+
12
21
  @mixin title_colors {
13
22
  @each $name, $color in $pb_title_colors {
14
23
  &[class*=_#{$name}] {
@@ -16,3 +25,7 @@ $pb_title_colors: (
16
25
  }
17
26
  }
18
27
  }
28
+
29
+ @mixin title_dark {
30
+ color: $text_dk_default;
31
+ }
@@ -33,14 +33,6 @@
33
33
  @include pb_title($heading_4, $bolder, $letterSpacing: $lspace_normal);
34
34
  }
35
35
 
36
- @mixin pb_title_dark {
37
- color: $text_dk_default;
38
- }
39
-
40
- @mixin pb_title_dark_link {
41
- color: $active_dark;
42
- }
43
-
44
36
  @mixin pb_title_bold {
45
37
  font-weight: $bolder;
46
38
  }