playbook_ui 13.15.0.pre.alpha.1132globalpropdatepickerspacing1929 → 13.16.0.pre.alpha.PBNTR177NewAdvancedTableKit2010
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/_playbook.scss +14 -12
- data/app/pb_kits/playbook/index.js +2 -1
- data/app/pb_kits/playbook/pb_advanced_table/Components/CollapsibleTrail.tsx +30 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/CustomCell.tsx +59 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/LoadingCell.tsx +5 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/SortIconButton.tsx +30 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/SubRowHeaderRow.tsx +61 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/TableHeaderCell.tsx +120 -0
- data/app/pb_kits/playbook/pb_advanced_table/Components/ToggleIconButton.tsx +28 -0
- data/app/pb_kits/playbook/pb_advanced_table/Context/AdvancedTableContext.tsx +5 -0
- data/app/pb_kits/playbook/pb_advanced_table/SubComponents/TableBody.tsx +95 -0
- data/app/pb_kits/playbook/pb_advanced_table/SubComponents/TableHeader.tsx +51 -0
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/helper_functions.tsx +77 -0
- data/app/pb_kits/playbook/pb_advanced_table/Utilities/types.ts +8 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.scss +97 -0
- data/app/pb_kits/playbook/pb_advanced_table/_advanced_table.tsx +237 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.test.jsx +56 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_default.jsx +52 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_mock_data.js +278 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +5 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/_loading.scss +60 -0
- data/app/pb_kits/playbook/pb_advanced_table/scss_partials/_pseudo_states.scss +12 -0
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +3 -2
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +1 -43
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +1 -2
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +1 -15
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +40 -33
- data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.tsx +4 -4
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_input_styles.scss +2 -1
- data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.tsx +44 -30
- data/app/pb_kits/playbook/pb_flex/_flex.tsx +5 -5
- data/app/pb_kits/playbook/pb_form_group/_form_group.tsx +3 -2
- data/app/pb_kits/playbook/pb_form_pill/_form_pill.tsx +7 -4
- data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +10 -10
- data/app/pb_kits/playbook/pb_home_address_street/_home_address_street.tsx +10 -9
- data/app/pb_kits/playbook/pb_icon_stat_value/_icon_stat_value.tsx +3 -2
- data/app/pb_kits/playbook/pb_icon_value/_icon_value.tsx +3 -2
- data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +1 -1
- data/app/pb_kits/playbook/pb_layout/_layout.tsx +2 -1
- data/app/pb_kits/playbook/pb_layout/layout.test.js +8 -4
- data/app/pb_kits/playbook/pb_legend/_legend.tsx +6 -6
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Slides.tsx +4 -4
- data/app/pb_kits/playbook/pb_lightbox/Carousel/Thumbnail.tsx +1 -1
- data/app/pb_kits/playbook/pb_lightbox/Carousel/index.tsx +3 -3
- data/app/pb_kits/playbook/pb_lightbox/Header/_lightbox_header.tsx +30 -22
- data/app/pb_kits/playbook/pb_lightbox/_lightbox.tsx +5 -5
- data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +4 -4
- data/app/pb_kits/playbook/pb_list/_list.tsx +15 -15
- data/app/pb_kits/playbook/pb_list/_list_item.tsx +1 -1
- data/app/pb_kits/playbook/pb_loading_inline/_loading_inline.tsx +9 -9
- data/app/pb_kits/playbook/pb_map/_map.tsx +8 -8
- data/app/pb_kits/playbook/pb_map/_map_controls.tsx +15 -7
- data/app/pb_kits/playbook/pb_map/_map_custom_button.tsx +4 -2
- data/app/pb_kits/playbook/pb_message/_message.tsx +1 -1
- data/app/pb_kits/playbook/pb_message/_message_mention.tsx +6 -6
- data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +46 -42
- data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.tsx +20 -20
- data/app/pb_kits/playbook/pb_nav/_item.tsx +56 -47
- data/app/pb_kits/playbook/pb_nav/_nav.tsx +15 -15
- data/app/pb_kits/playbook/pb_passphrase/_passphrase.tsx +51 -50
- data/app/pb_kits/playbook/pb_person_contact/_person_contact.tsx +20 -19
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +4 -3
- data/app/pb_kits/playbook/pb_popover/_popover.tsx +6 -4
- data/app/pb_kits/playbook/pb_progress_pills/_progress_pills.tsx +20 -20
- data/app/pb_kits/playbook/pb_progress_simple/_progress_simple.tsx +4 -4
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorButton.tsx +19 -17
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorTypes.ts +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/MoreExtensionsDropdown.tsx +23 -21
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +18 -10
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +46 -23
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarHistory.tsx +8 -8
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarNodes.tsx +7 -7
- data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.tsx +17 -15
- data/app/pb_kits/playbook/pb_section_separator/_section_separator.tsx +9 -7
- data/app/pb_kits/playbook/pb_select/_select.scss +13 -4
- data/app/pb_kits/playbook/pb_select/_select.tsx +7 -4
- data/app/pb_kits/playbook/pb_select/docs/_select_inline_show_arrow.html.erb +24 -0
- data/app/pb_kits/playbook/pb_select/docs/_select_inline_show_arrow.jsx +38 -0
- data/app/pb_kits/playbook/pb_select/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_select/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_select/select.rb +6 -1
- data/app/pb_kits/playbook/pb_selectable_card_icon/_selectable_card_icon.tsx +25 -24
- data/app/pb_kits/playbook/pb_selectable_icon/_selectable_icon.tsx +27 -26
- data/app/pb_kits/playbook/pb_selectable_list/_selectable_list.tsx +2 -1
- data/app/pb_kits/playbook/pb_source/_source.tsx +15 -15
- data/app/pb_kits/playbook/pb_table/_table.tsx +29 -29
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +1 -0
- data/app/pb_kits/playbook/pb_text_input/_text_input.tsx +1 -4
- data/app/pb_kits/playbook/pb_text_input/text_input.rb +1 -5
- data/app/pb_kits/playbook/pb_typeahead/_typeahead.scss +1 -1
- data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_highlight.jsx +4 -2
- data/app/pb_kits/playbook/playbook-doc.js +2 -0
- data/app/pb_kits/playbook/utilities/globalProps.ts +1 -1
- data/dist/menu.yml +4 -1
- data/dist/playbook-rails.js +14 -6
- data/lib/playbook/version.rb +2 -2
- metadata +25 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f15a8ac0110aaa64e75c62164518fb815e028873c5909c72a57b6322c2b98661
|
4
|
+
data.tar.gz: fbe1cc5a5f53f2c9387b9b2ff209abe5c9f808d16f248a285e20bb9ab980c33e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab28994eae8dd6bcceb5d9ca44a65ec378060cba26a86c519742e892fc721b13ff6fca4a1f526385c942f4db7b30e9f8f3a96d37b6e7c1571bf84e76bf6f9a40
|
7
|
+
data.tar.gz: a23907ecbcf8a0afa5a3abca06e60b9c18e227a0f5bac019731d9be43f209ef689159e2d5b067d4a511ed8d1245739372689385d2e6830ff17dac8363d866d61
|
@@ -1,16 +1,17 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
@import 'pb_advanced_table/advanced_table';
|
4
|
+
@import 'pb_avatar/avatar';
|
5
|
+
@import 'pb_avatar_action_button/avatar_action_button';
|
1
6
|
@import 'pb_background/background';
|
7
|
+
@import 'pb_badge/badge';
|
8
|
+
@import 'pb_bar_graph/bar_graph';
|
2
9
|
@import 'pb_body/body';
|
3
10
|
@import 'pb_bread_crumbs/bread_crumbs';
|
4
11
|
@import 'pb_button/button';
|
5
12
|
@import 'pb_button_toolbar/button_toolbar';
|
6
13
|
@import 'pb_caption/caption';
|
7
14
|
@import 'pb_card/card';
|
8
|
-
@import 'pb_detail/detail';
|
9
|
-
@import 'pb_title/title';
|
10
|
-
@import 'pb_avatar/avatar';
|
11
|
-
@import 'pb_avatar_action_button/avatar_action_button';
|
12
|
-
@import 'pb_badge/badge';
|
13
|
-
@import 'pb_bar_graph/bar_graph';
|
14
15
|
@import 'pb_checkbox/checkbox';
|
15
16
|
@import 'pb_circle_chart/circle_chart';
|
16
17
|
@import 'pb_circle_icon_button/circle_icon_button';
|
@@ -20,21 +21,22 @@
|
|
20
21
|
@import 'pb_dashboard_value/dashboard_value';
|
21
22
|
@import 'pb_date/date';
|
22
23
|
@import 'pb_date_picker/date_picker';
|
23
|
-
@import 'pb_date_time/date_time';
|
24
24
|
@import 'pb_date_range_inline/date_range_inline';
|
25
25
|
@import 'pb_date_range_stacked/date_range_stacked';
|
26
26
|
@import 'pb_date_stacked/date_stacked';
|
27
|
+
@import 'pb_date_time/date_time';
|
27
28
|
@import 'pb_date_time_stacked/date_time_stacked';
|
28
29
|
@import 'pb_date_year_stacked/date_year_stacked';
|
30
|
+
@import 'pb_detail/detail';
|
29
31
|
@import 'pb_dialog/dialog';
|
30
32
|
@import 'pb_distribution_bar/distribution_bar';
|
31
33
|
@import 'pb_file_upload/file_upload';
|
32
34
|
@import 'pb_filter/filter';
|
33
35
|
@import 'pb_fixed_confirmation_toast/fixed_confirmation_toast';
|
36
|
+
@import 'pb_flex/flex';
|
34
37
|
@import 'pb_form/form';
|
35
38
|
@import 'pb_form_group/form_group';
|
36
39
|
@import 'pb_form_pill/form_pill';
|
37
|
-
@import 'pb_flex/flex';
|
38
40
|
@import 'pb_gauge/gauge';
|
39
41
|
@import 'pb_hashtag/hashtag';
|
40
42
|
@import 'pb_highlight/highlight';
|
@@ -55,6 +57,7 @@
|
|
55
57
|
@import 'pb_map/map';
|
56
58
|
@import 'pb_map/pb_map_button_mixin';
|
57
59
|
@import 'pb_message/message';
|
60
|
+
@import 'pb_multi_level_select/multi_level_select';
|
58
61
|
@import 'pb_multiple_users/multiple_users';
|
59
62
|
@import 'pb_multiple_users_stacked/multiple_users_stacked';
|
60
63
|
@import 'pb_nav/nav';
|
@@ -85,9 +88,11 @@
|
|
85
88
|
@import 'pb_text_input/text_input';
|
86
89
|
@import 'pb_textarea/textarea';
|
87
90
|
@import 'pb_time/time';
|
88
|
-
@import 'pb_timeline/timeline';
|
89
91
|
@import 'pb_time_range_inline/time_range_inline';
|
92
|
+
@import 'pb_time_stacked/time_stacked';
|
93
|
+
@import 'pb_timeline/timeline';
|
90
94
|
@import 'pb_timestamp/timestamp';
|
95
|
+
@import 'pb_title/title';
|
91
96
|
@import 'pb_title_count/title_count';
|
92
97
|
@import 'pb_title_detail/title_detail';
|
93
98
|
@import 'pb_toggle/toggle';
|
@@ -96,7 +101,6 @@
|
|
96
101
|
@import 'pb_typeahead/typeahead';
|
97
102
|
@import 'pb_user/user';
|
98
103
|
@import 'pb_user_badge/user_badge';
|
99
|
-
@import 'pb_time_stacked/time_stacked';
|
100
104
|
@import 'pb_walkthrough/walkthrough';
|
101
105
|
@import 'pb_weekday_stacked/weekday_stacked';
|
102
106
|
@import './utilities/mixins';
|
@@ -115,5 +119,3 @@
|
|
115
119
|
@import './utilities/text_align';
|
116
120
|
@import './utilities/overflow';
|
117
121
|
@import './utilities/truncate';
|
118
|
-
|
119
|
-
@import 'pb_multi_level_select/multi_level_select';
|
@@ -4,6 +4,7 @@ import 'lazysizes/plugins/attrchange/ls.attrchange'
|
|
4
4
|
import 'lazysizes'
|
5
5
|
|
6
6
|
// vvv React Component JSX Imports from the React Kits vvv
|
7
|
+
export { default as AdvancedTable} from './pb_advanced_table/_advanced_table'
|
7
8
|
export { default as Avatar } from './pb_avatar/_avatar'
|
8
9
|
export { default as AvatarActionButton } from './pb_avatar_action_button/_avatar_action_button'
|
9
10
|
export { default as Background } from './pb_background/_background'
|
@@ -59,8 +60,8 @@ export { default as LineGraph } from './pb_line_graph/_line_graph'
|
|
59
60
|
export { default as List } from './pb_list/_list'
|
60
61
|
export { default as ListItem } from './pb_list/_list_item'
|
61
62
|
export { default as LoadingInline } from './pb_loading_inline/_loading_inline'
|
62
|
-
export { default as Map} from './pb_map/_map'
|
63
63
|
export { default as MapCustomButton } from './pb_map/_map_custom_button'
|
64
|
+
export { default as Map} from './pb_map/_map'
|
64
65
|
export { default as Message } from './pb_message/_message'
|
65
66
|
export { default as MultiLevelSelect} from './pb_multi_level_select/_multi_level_select'
|
66
67
|
export { default as MultipleUsers } from './pb_multiple_users/_multiple_users'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import React from "react"
|
2
|
+
|
3
|
+
//CollapsibleTrail component
|
4
|
+
const CollapsibleTrail = ({ leftOffset }: { leftOffset: number }) => {
|
5
|
+
const style: { [key: string]: string | number } = {
|
6
|
+
position: "absolute",
|
7
|
+
left: `${leftOffset}rem`,
|
8
|
+
top: 0,
|
9
|
+
bottom: 0,
|
10
|
+
width: "2px",
|
11
|
+
backgroundColor: "#E4E8F0",
|
12
|
+
}
|
13
|
+
|
14
|
+
return <div style={style} />
|
15
|
+
}
|
16
|
+
|
17
|
+
// Updated function to render multiple trails depending on depth
|
18
|
+
export const renderCollapsibleTrail = (currentDepth: number) => {
|
19
|
+
const lines = []
|
20
|
+
for (let i = 1; i <= currentDepth; i++) {
|
21
|
+
// Calculate leftOffset with additional 0.4rem for each depth level above 1
|
22
|
+
const additionalOffset = i > 1 ? (i - 1) * 0.4 : 0
|
23
|
+
const leftOffset = i * 1.6 + additionalOffset
|
24
|
+
lines.push(<CollapsibleTrail key={i}
|
25
|
+
leftOffset={leftOffset}
|
26
|
+
/>
|
27
|
+
)
|
28
|
+
}
|
29
|
+
return lines
|
30
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import React, { useContext } from "react";
|
2
|
+
|
3
|
+
import Flex from "../../pb_flex/_flex";
|
4
|
+
import FlexItem from "../../pb_flex/_flex_item";
|
5
|
+
import Icon from "../../pb_icon/_icon";
|
6
|
+
import { GlobalProps } from "../../utilities/globalProps";
|
7
|
+
|
8
|
+
import { Getter, Row } from "@tanstack/react-table";
|
9
|
+
import { DataType } from "../Utilities/types";
|
10
|
+
import AdvancedTableContext from "../Context/AdvancedTableContext";
|
11
|
+
|
12
|
+
interface CustomCellProps {
|
13
|
+
row: Row<DataType>;
|
14
|
+
getValue?: Getter<string>;
|
15
|
+
value?: string;
|
16
|
+
onRowToggleClick?: (arg: Row<DataType>) => void;
|
17
|
+
}
|
18
|
+
|
19
|
+
export const CustomCell = ({
|
20
|
+
row,
|
21
|
+
getValue,
|
22
|
+
value,
|
23
|
+
onRowToggleClick,
|
24
|
+
}: CustomCellProps & GlobalProps) => {
|
25
|
+
const { setExpanded, expanded } = useContext(AdvancedTableContext);
|
26
|
+
const RowWithoutChildren = row.originalSubRows === undefined;
|
27
|
+
|
28
|
+
const handleOnExpand = (row: Row<DataType>) => {
|
29
|
+
onRowToggleClick && onRowToggleClick(row);
|
30
|
+
setExpanded({ ...expanded, [row.id]: !row.getIsExpanded() });
|
31
|
+
};
|
32
|
+
|
33
|
+
return (
|
34
|
+
<div style={{ paddingLeft: `${row.depth * 2}rem` }}>
|
35
|
+
<Flex alignItems="center"
|
36
|
+
columnGap="xs"
|
37
|
+
orientation="row"
|
38
|
+
>
|
39
|
+
{!RowWithoutChildren ? (
|
40
|
+
<button
|
41
|
+
className="gray-icon expand-toggle-icon"
|
42
|
+
onClick={() => handleOnExpand(row)}
|
43
|
+
>
|
44
|
+
{row.getIsExpanded() ? (
|
45
|
+
<Icon icon="circle-play"
|
46
|
+
rotation={90}
|
47
|
+
/>
|
48
|
+
) : (
|
49
|
+
<Icon icon="circle-play" />
|
50
|
+
)}
|
51
|
+
</button>
|
52
|
+
) : null}
|
53
|
+
<FlexItem paddingLeft={!RowWithoutChildren ? "none" : "xs"}>
|
54
|
+
{row.depth === 0 ? getValue() : value}
|
55
|
+
</FlexItem>
|
56
|
+
</Flex>
|
57
|
+
</div>
|
58
|
+
);
|
59
|
+
};
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import React from "react"
|
2
|
+
import Icon from "../../pb_icon/_icon"
|
3
|
+
import { Header } from "@tanstack/react-table"
|
4
|
+
import { DataType } from "../Utilities/types"
|
5
|
+
import { displayIcon } from "../Utilities/helper_functions"
|
6
|
+
|
7
|
+
type SortIconButtonProps = {
|
8
|
+
header: Header<DataType, unknown>
|
9
|
+
sortIcon?: string | string[]
|
10
|
+
}
|
11
|
+
export const SortIconButton = ({ header, sortIcon }: SortIconButtonProps) => {
|
12
|
+
|
13
|
+
return (
|
14
|
+
<>
|
15
|
+
{header.column.getIsSorted() === "desc" ? (
|
16
|
+
<div className="year-sort-icon"
|
17
|
+
key={displayIcon(sortIcon)[0]}
|
18
|
+
>
|
19
|
+
<Icon icon={displayIcon(sortIcon)[0]} />
|
20
|
+
</div>
|
21
|
+
) : (
|
22
|
+
<div className="year-sort-icon"
|
23
|
+
key={displayIcon(sortIcon)[1]}
|
24
|
+
>
|
25
|
+
<Icon icon={displayIcon(sortIcon)[1]} />
|
26
|
+
</div>
|
27
|
+
)}
|
28
|
+
</>
|
29
|
+
)
|
30
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import React from "react"
|
2
|
+
import Flex from "../../pb_flex/_flex"
|
3
|
+
import Caption from "../../pb_caption/_caption"
|
4
|
+
import { Row, Table } from "@tanstack/react-table"
|
5
|
+
|
6
|
+
import { ToggleIconButton } from "./ToggleIconButton"
|
7
|
+
import { renderCollapsibleTrail } from "./CollapsibleTrail"
|
8
|
+
|
9
|
+
import { isChrome } from "../Utilities/helper_functions"
|
10
|
+
import { DataType } from "../Utilities/types"
|
11
|
+
import { GlobalProps } from "../../utilities/globalProps"
|
12
|
+
|
13
|
+
interface SubRowHeaderRowProps {
|
14
|
+
onClick: (row: Row<DataType>) => void
|
15
|
+
row: Row<DataType>
|
16
|
+
table: Table<DataType>
|
17
|
+
collapsibleTrail?: boolean
|
18
|
+
subRowHeaders?: string[]
|
19
|
+
enableToggleExpansion?: "all" | "header"
|
20
|
+
}
|
21
|
+
|
22
|
+
export const SubRowHeaderRow = ({
|
23
|
+
row,
|
24
|
+
table,
|
25
|
+
onClick,
|
26
|
+
collapsibleTrail,
|
27
|
+
subRowHeaders,
|
28
|
+
enableToggleExpansion,
|
29
|
+
}: SubRowHeaderRowProps & GlobalProps) => {
|
30
|
+
const numberOfColumns = table.getAllFlatColumns().length
|
31
|
+
|
32
|
+
return (
|
33
|
+
<tr className="custom-row bg-silver">
|
34
|
+
<td
|
35
|
+
className={`custom-row-first-column ${
|
36
|
+
isChrome() ? "chrome-styles" : ""
|
37
|
+
}`}
|
38
|
+
colSpan={1}
|
39
|
+
>
|
40
|
+
{collapsibleTrail && row.depth > 0 && renderCollapsibleTrail(row.depth)}
|
41
|
+
<div style={{ paddingLeft: `${row.depth * 2}rem` }}>
|
42
|
+
<Flex align="center"
|
43
|
+
columnGap="xs"
|
44
|
+
>
|
45
|
+
{enableToggleExpansion === "all" && row.getCanExpand() ? (
|
46
|
+
<ToggleIconButton onClick={onClick}
|
47
|
+
row={row}
|
48
|
+
/>
|
49
|
+
) : null}
|
50
|
+
<Caption
|
51
|
+
marginLeft={row.getCanExpand() ? "none" : "xs"}
|
52
|
+
text={subRowHeaders[row.depth - 1]}
|
53
|
+
/>
|
54
|
+
</Flex>
|
55
|
+
</div>
|
56
|
+
</td>
|
57
|
+
|
58
|
+
<td colSpan={numberOfColumns - 1} />
|
59
|
+
</tr>
|
60
|
+
)
|
61
|
+
}
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import React, { useContext } from "react"
|
2
|
+
import Flex from "../../pb_flex/_flex"
|
3
|
+
import { flexRender, Header } from "@tanstack/react-table"
|
4
|
+
|
5
|
+
import { SortIconButton } from "./SortIconButton"
|
6
|
+
import { ToggleIconButton } from "./ToggleIconButton"
|
7
|
+
import { isChrome } from "../Utilities/helper_functions"
|
8
|
+
import { DataType } from "../Utilities/types"
|
9
|
+
import AdvancedTableContext from "../Context/AdvancedTableContext"
|
10
|
+
import { GlobalProps } from "../../utilities/globalProps"
|
11
|
+
|
12
|
+
type TableHeaderCellProps = {
|
13
|
+
headerChildren?: React.ReactNode | React.ReactNode[]
|
14
|
+
enableSorting?: boolean
|
15
|
+
enableToggleExpansion?: "all" | "header"
|
16
|
+
handleExpandOrCollapse?: () => void
|
17
|
+
header?: Header<DataType, unknown>
|
18
|
+
headerId?: string
|
19
|
+
loading?: boolean
|
20
|
+
sortIcon?: string | string[]
|
21
|
+
} & GlobalProps
|
22
|
+
|
23
|
+
export const TableHeaderCell = ({
|
24
|
+
header,
|
25
|
+
headerId,
|
26
|
+
enableSorting,
|
27
|
+
sortIcon,
|
28
|
+
headerChildren,
|
29
|
+
loading,
|
30
|
+
enableToggleExpansion,
|
31
|
+
handleExpandOrCollapse,
|
32
|
+
}: TableHeaderCellProps) => {
|
33
|
+
const { sortControl } = useContext(AdvancedTableContext)
|
34
|
+
|
35
|
+
const toggleSortButton = (event: React.SyntheticEvent) => {
|
36
|
+
if (sortControl) {
|
37
|
+
const sortIsDesc = header.column.getIsSorted() === "desc"
|
38
|
+
sortIsDesc
|
39
|
+
? sortControl.onChange({ desc: true })
|
40
|
+
: sortControl.onChange({ desc: false })
|
41
|
+
} else {
|
42
|
+
header.column.getToggleSortingHandler()(event)
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
return (
|
47
|
+
<th
|
48
|
+
align="right"
|
49
|
+
className={`table-header-cells ${isChrome() ? "chrome-styles" : ""}`}
|
50
|
+
id={`${
|
51
|
+
loading
|
52
|
+
? `loading-${header.id}-${headerId}`
|
53
|
+
: `${header.id}-${headerId}`
|
54
|
+
}`}
|
55
|
+
key={`${header.id}-header`}
|
56
|
+
>
|
57
|
+
{header.isPlaceholder ? null : headerChildren && header.index === 0 ? (
|
58
|
+
<Flex alignItems="center">
|
59
|
+
{headerChildren}
|
60
|
+
<div>
|
61
|
+
{flexRender(header.column.columnDef.header, header.getContext())}
|
62
|
+
</div>
|
63
|
+
</Flex>
|
64
|
+
) : (
|
65
|
+
<Flex
|
66
|
+
alignItems="center"
|
67
|
+
justify={header.index === 0 ? "between" : "none"}
|
68
|
+
paddingLeft={loading ? "sm" : "none"}
|
69
|
+
>
|
70
|
+
{header.index === 0 &&
|
71
|
+
!loading &&
|
72
|
+
(enableToggleExpansion === "all" || "header") && (
|
73
|
+
<ToggleIconButton onClick={handleExpandOrCollapse} />
|
74
|
+
)}
|
75
|
+
|
76
|
+
{header.index === 0 &&
|
77
|
+
loading &&
|
78
|
+
(enableToggleExpansion === "all" || "header") && (
|
79
|
+
<div className="loading-toggle-icon header-toggle-icon" />
|
80
|
+
)}
|
81
|
+
|
82
|
+
<Flex
|
83
|
+
className={`${header.index === 0 &&
|
84
|
+
enableSorting &&
|
85
|
+
"header-sort-button pb_th_link"}`}
|
86
|
+
cursor={header.index === 0 && enableSorting ? "pointer" : "default"}
|
87
|
+
{...(header.index === 0 &&
|
88
|
+
enableSorting && {
|
89
|
+
htmlOptions: {
|
90
|
+
onClick: (event: React.MouseEvent) => toggleSortButton(event),
|
91
|
+
onKeyDown: (event: React.KeyboardEvent) => {
|
92
|
+
if (event.key === "Enter") {
|
93
|
+
toggleSortButton(event)
|
94
|
+
}
|
95
|
+
},
|
96
|
+
tabIndex: 0,
|
97
|
+
},
|
98
|
+
})}
|
99
|
+
justify={header.index === 0 && enableSorting ? "between" : "none"}
|
100
|
+
>
|
101
|
+
<div>
|
102
|
+
{flexRender(header.column.columnDef.header, header.getContext())}
|
103
|
+
</div>
|
104
|
+
|
105
|
+
{header.index === 0 &&
|
106
|
+
header.column.getCanSort() &&
|
107
|
+
enableSorting &&
|
108
|
+
(loading ? (
|
109
|
+
<div className="loading-toggle-icon header-sort-icon" />
|
110
|
+
) : (
|
111
|
+
<SortIconButton header={header}
|
112
|
+
sortIcon={sortIcon}
|
113
|
+
/>
|
114
|
+
))}
|
115
|
+
</Flex>
|
116
|
+
</Flex>
|
117
|
+
)}
|
118
|
+
</th>
|
119
|
+
)
|
120
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import React, { useContext } from "react"
|
2
|
+
import Icon from "../../pb_icon/_icon"
|
3
|
+
import { Row } from "@tanstack/react-table"
|
4
|
+
import AdvancedTableContext from "../Context/AdvancedTableContext"
|
5
|
+
import { DataType } from "../Utilities/types"
|
6
|
+
import { displayIcon } from "../Utilities/helper_functions"
|
7
|
+
|
8
|
+
interface ToggleIconButtonProps {
|
9
|
+
row?: Row<DataType>
|
10
|
+
onClick: (row: Row<DataType>) => void
|
11
|
+
}
|
12
|
+
|
13
|
+
export const ToggleIconButton = ({ row, onClick }: ToggleIconButtonProps) => {
|
14
|
+
const { toggleExpansionIcon } = useContext(AdvancedTableContext)
|
15
|
+
return (
|
16
|
+
<button
|
17
|
+
className="gray-icon time-period-toggle-icon"
|
18
|
+
key={displayIcon(toggleExpansionIcon)[0]}
|
19
|
+
onClick={() => onClick(row)}
|
20
|
+
>
|
21
|
+
<Icon
|
22
|
+
cursor="pointer"
|
23
|
+
fixedWidth
|
24
|
+
icon={displayIcon(toggleExpansionIcon)[0]}
|
25
|
+
/>
|
26
|
+
</button>
|
27
|
+
)
|
28
|
+
}
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import React, { useContext } from "react"
|
2
|
+
import LoadingInline from "../../pb_loading_inline/_loading_inline"
|
3
|
+
import { flexRender, Row } from "@tanstack/react-table"
|
4
|
+
|
5
|
+
import { SubRowHeaderRow } from "../Components/SubRowHeaderRow"
|
6
|
+
import { LoadingCell } from "../Components/LoadingCell"
|
7
|
+
import { renderCollapsibleTrail } from "../Components/CollapsibleTrail"
|
8
|
+
import AdvancedTableContext from "../Context/AdvancedTableContext"
|
9
|
+
import { isChrome } from "../Utilities/helper_functions"
|
10
|
+
import { DataType } from "../Utilities/types"
|
11
|
+
|
12
|
+
type TableBodyProps = {
|
13
|
+
collapsibleTrail?: boolean
|
14
|
+
subRowHeaders?: string[]
|
15
|
+
}
|
16
|
+
|
17
|
+
export const TableBody = ({
|
18
|
+
collapsibleTrail = true,
|
19
|
+
subRowHeaders,
|
20
|
+
}: TableBodyProps) => {
|
21
|
+
const {
|
22
|
+
table,
|
23
|
+
handleExpandOrCollapse,
|
24
|
+
loading,
|
25
|
+
enableToggleExpansion,
|
26
|
+
} = useContext(AdvancedTableContext)
|
27
|
+
return (
|
28
|
+
<>
|
29
|
+
<tbody>
|
30
|
+
{table.getRowModel().rows.map((row: Row<DataType>) => {
|
31
|
+
const isExpandable = row.getIsExpanded()
|
32
|
+
const isFirstChildofSubrow = row.depth > 0 && row.index === 0
|
33
|
+
const rowHasNoChildren = !row.original.children?.length
|
34
|
+
const numberOfColumns = table.getAllFlatColumns().length
|
35
|
+
|
36
|
+
return (
|
37
|
+
<React.Fragment key={`${row.index}-${row.id}-${row.depth}-row`}>
|
38
|
+
{isFirstChildofSubrow && subRowHeaders && (
|
39
|
+
<SubRowHeaderRow
|
40
|
+
collapsibleTrail={collapsibleTrail}
|
41
|
+
enableToggleExpansion={enableToggleExpansion}
|
42
|
+
onClick={handleExpandOrCollapse}
|
43
|
+
row={row}
|
44
|
+
subRowHeaders={subRowHeaders}
|
45
|
+
table={table}
|
46
|
+
/>
|
47
|
+
)}
|
48
|
+
|
49
|
+
<tr
|
50
|
+
className={`${isExpandable ? "bg-silver" : "bg-white"} ${
|
51
|
+
row.depth > 0 ? `depth-sub-row-${row.depth}` : ""
|
52
|
+
}`}
|
53
|
+
id={`${row.index}-${row.id}-${row.depth}-row`}
|
54
|
+
>
|
55
|
+
{row.getVisibleCells().map((cell, i) => (
|
56
|
+
<td
|
57
|
+
align="right"
|
58
|
+
className={`${cell.id}-cell position_relative ${
|
59
|
+
isChrome() ? "chrome-styles" : ""
|
60
|
+
}`}
|
61
|
+
key={`${cell.id}-data`}
|
62
|
+
>
|
63
|
+
{collapsibleTrail &&
|
64
|
+
i === 0 &&
|
65
|
+
row.depth > 0 &&
|
66
|
+
renderCollapsibleTrail(row.depth)}
|
67
|
+
<span id={`${cell.id}-span`}>
|
68
|
+
{loading ? (
|
69
|
+
<LoadingCell />
|
70
|
+
) : (
|
71
|
+
flexRender(
|
72
|
+
cell.column.columnDef.cell,
|
73
|
+
cell.getContext()
|
74
|
+
)
|
75
|
+
)}
|
76
|
+
</span>
|
77
|
+
</td>
|
78
|
+
))}
|
79
|
+
</tr>
|
80
|
+
|
81
|
+
{/* Display LoadingInline if getYearData is querying and there are no children already */}
|
82
|
+
{isExpandable && rowHasNoChildren && row.depth === 0 ? (
|
83
|
+
<tr key={`${row.id}-row`}>
|
84
|
+
<td colSpan={numberOfColumns}>
|
85
|
+
<LoadingInline />
|
86
|
+
</td>
|
87
|
+
</tr>
|
88
|
+
) : null}
|
89
|
+
</React.Fragment>
|
90
|
+
)
|
91
|
+
})}
|
92
|
+
</tbody>
|
93
|
+
</>
|
94
|
+
)
|
95
|
+
}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import React, { useContext } from "react"
|
2
|
+
import { HeaderGroup } from "@tanstack/react-table"
|
3
|
+
import AdvancedTableContext from "../Context/AdvancedTableContext"
|
4
|
+
import { TableHeaderCell } from "../Components/TableHeaderCell"
|
5
|
+
import { DataType } from "../Utilities/types"
|
6
|
+
|
7
|
+
type TableHeaderProps = {
|
8
|
+
headerId?: string
|
9
|
+
enableSorting?: boolean
|
10
|
+
sortIcon?: string | string[]
|
11
|
+
children?: React.ReactNode | React.ReactNode[]
|
12
|
+
}
|
13
|
+
|
14
|
+
export const TableHeader = ({
|
15
|
+
headerId,
|
16
|
+
enableSorting = false,
|
17
|
+
children,
|
18
|
+
sortIcon = ["arrow-up-short-wide", "arrow-down-short-wide"],
|
19
|
+
}: TableHeaderProps) => {
|
20
|
+
const {
|
21
|
+
table,
|
22
|
+
handleExpandOrCollapse,
|
23
|
+
loading,
|
24
|
+
enableToggleExpansion,
|
25
|
+
} = useContext(AdvancedTableContext)
|
26
|
+
|
27
|
+
return (
|
28
|
+
<>
|
29
|
+
<thead>
|
30
|
+
{/* Get the header groups (only one in this example) */}
|
31
|
+
{table.getHeaderGroups().map((headerGroup: HeaderGroup<DataType>) => (
|
32
|
+
<tr key={`${headerGroup.id}-headerGroup`}>
|
33
|
+
{headerGroup.headers.map(header => (
|
34
|
+
<TableHeaderCell
|
35
|
+
enableSorting={enableSorting}
|
36
|
+
enableToggleExpansion={enableToggleExpansion}
|
37
|
+
handleExpandOrCollapse={handleExpandOrCollapse}
|
38
|
+
header={header}
|
39
|
+
headerChildren={children}
|
40
|
+
headerId={headerId}
|
41
|
+
key={`${header.id}-header`}
|
42
|
+
loading={loading}
|
43
|
+
sortIcon={sortIcon}
|
44
|
+
/>
|
45
|
+
))}
|
46
|
+
</tr>
|
47
|
+
))}
|
48
|
+
</thead>
|
49
|
+
</>
|
50
|
+
)
|
51
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import { RowModel } from "@tanstack/react-table"
|
2
|
+
import { DataType, ExpandedStateObject } from "./types"
|
3
|
+
|
4
|
+
const filterExpandableRows = (expandedState: Record<string, boolean>) => {
|
5
|
+
for (const expandedRow in expandedState) {
|
6
|
+
if (expandedState[expandedRow] === false) {
|
7
|
+
delete expandedState[expandedRow]
|
8
|
+
}
|
9
|
+
}
|
10
|
+
return expandedState
|
11
|
+
}
|
12
|
+
|
13
|
+
export const updateExpandAndCollapseState = (
|
14
|
+
tableRows: RowModel<DataType>,
|
15
|
+
expanded: Record<string, boolean>,
|
16
|
+
targetParent: string
|
17
|
+
) => {
|
18
|
+
const updateExpandedRows: Record<string, boolean> = {}
|
19
|
+
const rows = tableRows.flatRows
|
20
|
+
// Variable checks if all rows in a section have same expansion state or not
|
21
|
+
let isExpansionConsistent = true
|
22
|
+
const areRowsExpanded = new Set<boolean>()
|
23
|
+
|
24
|
+
// Update isExpansionConsistent variable
|
25
|
+
for (const row of rows) {
|
26
|
+
if (
|
27
|
+
row.getCanExpand() &&
|
28
|
+
(targetParent === undefined
|
29
|
+
? row.depth === 0
|
30
|
+
: targetParent === row.parentId)
|
31
|
+
) {
|
32
|
+
areRowsExpanded.add(row.getIsExpanded())
|
33
|
+
if (areRowsExpanded.size > 1) {
|
34
|
+
isExpansionConsistent = false
|
35
|
+
break
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
// The if statement runs only for row depth 0, the else statement for the rest
|
41
|
+
if (targetParent === undefined) {
|
42
|
+
rows.forEach(row => {
|
43
|
+
if (row.depth === 0) {
|
44
|
+
updateExpandedRows[row.id] = !isExpansionConsistent
|
45
|
+
? true
|
46
|
+
: !row.getIsExpanded()
|
47
|
+
}
|
48
|
+
})
|
49
|
+
} else {
|
50
|
+
for (const row of rows) {
|
51
|
+
if (row.getCanExpand() && targetParent === row.parentId) {
|
52
|
+
updateExpandedRows[row.id] = !isExpansionConsistent
|
53
|
+
? true
|
54
|
+
: !row.getIsExpanded()
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
return filterExpandableRows({
|
60
|
+
...(expanded as ExpandedStateObject),
|
61
|
+
...updateExpandedRows,
|
62
|
+
})
|
63
|
+
}
|
64
|
+
|
65
|
+
//Checking browser. Using this to add classname and css for browser specific issues with table borders
|
66
|
+
export const isChrome = () => {
|
67
|
+
const userAgent = navigator.userAgent.toLowerCase()
|
68
|
+
return userAgent.includes("chrome") && !userAgent.includes("edg")
|
69
|
+
}
|
70
|
+
|
71
|
+
// Logic for handling icons related props to allow for string or array of strings
|
72
|
+
export const displayIcon = (icon: string | string[]) => {
|
73
|
+
if (typeof icon === "string") {
|
74
|
+
return [icon, icon]
|
75
|
+
}
|
76
|
+
return icon
|
77
|
+
}
|