qbs-react-grid 2.2.17 → 2.2.19
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.
- package/dist/css/qbs-react-grid.css +1 -1
- package/dist/css/qbs-react-grid.min.css +1 -1
- package/dist/css/qbs-react-grid.min.css.map +1 -1
- package/es/Cell.js +2 -1
- package/es/Pagination.d.ts +3 -0
- package/es/Pagination.js +8 -3
- package/es/Table.d.ts +3 -0
- package/es/Table.js +18 -12
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/less/pagination.less +9 -9
- package/es/qbsTable/QbsTable.js +110 -73
- package/es/qbsTable/TableCardList.js +2 -0
- package/es/qbsTable/Toolbar.js +6 -3
- package/es/qbsTable/commontypes.d.ts +21 -12
- package/es/qbsTable/labels.d.ts +6 -2
- package/es/qbsTable/labels.js +10 -1
- package/es/qbsTable/utilities/CardComponent.d.ts +2 -0
- package/es/qbsTable/utilities/CardComponent.js +7 -3
- package/es/qbsTable/utilities/CardMenuDropdown.d.ts +2 -0
- package/es/qbsTable/utilities/CardMenuDropdown.js +7 -7
- package/es/qbsTable/utilities/SearchInput.d.ts +1 -0
- package/es/qbsTable/utilities/SearchInput.js +3 -1
- package/es/qbsTable/utilities/VerticalDropDownMenu.js +36 -23
- package/es/qbsTable/utilities/empty.js +1 -1
- package/es/qbsTable/utilities/tablecalc.d.ts +1 -1
- package/es/qbsTable/utilities/tablecalc.js +7 -2
- package/es/utils/useCellDescriptor.js +0 -1
- package/es/utils/useScrollListener.d.ts +1 -0
- package/es/utils/useScrollListener.js +5 -3
- package/lib/Cell.js +2 -1
- package/lib/Pagination.d.ts +3 -0
- package/lib/Pagination.js +8 -3
- package/lib/Table.d.ts +3 -0
- package/lib/Table.js +18 -12
- package/lib/index.d.ts +1 -1
- package/lib/index.js +3 -1
- package/lib/less/pagination.less +9 -9
- package/lib/qbsTable/QbsTable.js +110 -73
- package/lib/qbsTable/TableCardList.js +2 -0
- package/lib/qbsTable/Toolbar.js +6 -3
- package/lib/qbsTable/commontypes.d.ts +21 -12
- package/lib/qbsTable/labels.d.ts +6 -2
- package/lib/qbsTable/labels.js +13 -2
- package/lib/qbsTable/utilities/CardComponent.d.ts +2 -0
- package/lib/qbsTable/utilities/CardComponent.js +7 -3
- package/lib/qbsTable/utilities/CardMenuDropdown.d.ts +2 -0
- package/lib/qbsTable/utilities/CardMenuDropdown.js +6 -5
- package/lib/qbsTable/utilities/SearchInput.d.ts +1 -0
- package/lib/qbsTable/utilities/SearchInput.js +3 -1
- package/lib/qbsTable/utilities/VerticalDropDownMenu.js +36 -23
- package/lib/qbsTable/utilities/empty.js +1 -1
- package/lib/qbsTable/utilities/tablecalc.d.ts +1 -1
- package/lib/qbsTable/utilities/tablecalc.js +7 -2
- package/lib/utils/useCellDescriptor.js +0 -1
- package/lib/utils/useScrollListener.d.ts +1 -0
- package/lib/utils/useScrollListener.js +5 -3
- package/package.json +2 -2
- package/src/Cell.tsx +3 -1
- package/src/HeaderCell.tsx +0 -1
- package/src/Pagination.tsx +10 -3
- package/src/Table.tsx +23 -10
- package/src/customSelect.tsx +88 -88
- package/src/index.ts +2 -0
- package/src/less/pagination.less +9 -9
- package/src/qbsTable/QbsTable.tsx +84 -39
- package/src/qbsTable/TableCardList.tsx +2 -0
- package/src/qbsTable/Toolbar.tsx +4 -2
- package/src/qbsTable/commontypes.ts +21 -12
- package/src/qbsTable/labels.ts +9 -2
- package/src/qbsTable/utilities/CardComponent.tsx +7 -2
- package/src/qbsTable/utilities/CardMenuDropdown.tsx +11 -6
- package/src/qbsTable/utilities/SearchInput.tsx +3 -1
- package/src/qbsTable/utilities/VerticalDropDownMenu.tsx +42 -30
- package/src/qbsTable/utilities/empty.tsx +2 -2
- package/src/qbsTable/utilities/tablecalc.ts +8 -2
- package/src/utils/useCellDescriptor.ts +0 -1
- package/src/utils/useScrollListener.ts +13 -3
- package/src/utils/useTableRows.ts +1 -1
package/src/qbsTable/Toolbar.tsx
CHANGED
|
@@ -230,11 +230,12 @@ const ToolBar: React.FC<QbsTableToolbarProps> = ({
|
|
|
230
230
|
{handleHide(actions) && (
|
|
231
231
|
<button
|
|
232
232
|
type="button"
|
|
233
|
-
className=
|
|
233
|
+
className={`btn ${actions?.buttonClassName ?? ''}`}
|
|
234
234
|
disabled={actions.disabled}
|
|
235
235
|
onClick={() => actions?.action(checkedKeys)}
|
|
236
236
|
>
|
|
237
|
-
{actions.
|
|
237
|
+
{actions?.icon && <span className="mr-2">{actions.icon}</span>}
|
|
238
|
+
<span>{actions.actionTitle}</span>
|
|
238
239
|
</button>
|
|
239
240
|
)}
|
|
240
241
|
</React.Fragment>
|
|
@@ -249,6 +250,7 @@ const ToolBar: React.FC<QbsTableToolbarProps> = ({
|
|
|
249
250
|
paginationProps.total ?? 0,
|
|
250
251
|
paginationProps.rowsPerPage ?? 0,
|
|
251
252
|
paginationProps.currentPage ?? 0,
|
|
253
|
+
labels.showingRange,
|
|
252
254
|
)}
|
|
253
255
|
</div>
|
|
254
256
|
)}
|
|
@@ -45,7 +45,7 @@ export interface PaginationProps {
|
|
|
45
45
|
export interface ActionProps {
|
|
46
46
|
title?: string;
|
|
47
47
|
action?: (row: any) => void;
|
|
48
|
-
icon
|
|
48
|
+
icon?: React.ReactNode;
|
|
49
49
|
toolTip?: string;
|
|
50
50
|
hidden?: boolean;
|
|
51
51
|
hide?: (data: any, index?: number) => boolean;
|
|
@@ -76,6 +76,7 @@ export interface QbsTableProps {
|
|
|
76
76
|
searchValue?: string;
|
|
77
77
|
handleSearchValue?: (value?: string) => void;
|
|
78
78
|
theme?: string;
|
|
79
|
+
rtl?: boolean;
|
|
79
80
|
onRowClick?: (data: any) => void;
|
|
80
81
|
cellBordered?: boolean;
|
|
81
82
|
bordered?: boolean;
|
|
@@ -89,9 +90,8 @@ export interface QbsTableProps {
|
|
|
89
90
|
expandedRowKeys?: readonly number[];
|
|
90
91
|
setExpandedRowKeys?: (value: readonly number[]) => void;
|
|
91
92
|
handleMenuActions?: (actions: ActionProps, rowData: any) => void;
|
|
92
|
-
dropType?: 'vertical' | string;
|
|
93
|
+
dropType?: 'horizondal' | 'vertical' | string;
|
|
93
94
|
labels?: QbsTableLabels;
|
|
94
|
-
rtl?: boolean;
|
|
95
95
|
handleRowExpanded?: (rowData: any) => React.ReactNode;
|
|
96
96
|
shouldUpdateScroll?: boolean;
|
|
97
97
|
rowExpand?: boolean;
|
|
@@ -105,6 +105,8 @@ export interface QbsTableProps {
|
|
|
105
105
|
disabled?: boolean;
|
|
106
106
|
hidden?: boolean;
|
|
107
107
|
customHide?: string;
|
|
108
|
+
buttonClassName?: string;
|
|
109
|
+
icon?: ReactElement | ReactNode;
|
|
108
110
|
}[];
|
|
109
111
|
selectedRows?: (number | string)[];
|
|
110
112
|
classes?: { [key: string]: any };
|
|
@@ -135,13 +137,18 @@ export interface QbsTableProps {
|
|
|
135
137
|
handleTableCardView?: (data: any) => React.ReactNode;
|
|
136
138
|
isCustomTableCardView?: boolean;
|
|
137
139
|
handleCustomCardLoader?: () => React.ReactNode;
|
|
140
|
+
hasMoreData?: boolean;
|
|
141
|
+
loadMoreData?: () => void;
|
|
142
|
+
infiniteScroll?: boolean;
|
|
143
|
+
infiniteLoading?: boolean;
|
|
144
|
+
viewMode?: string;
|
|
138
145
|
rowViewToggle?: boolean;
|
|
139
146
|
defaultRowView?: boolean;
|
|
140
147
|
fullWidthView?: boolean;
|
|
141
148
|
setTableFullView?: (value: boolean) => void;
|
|
142
149
|
setRowViewToggle?: (value: boolean) => void;
|
|
143
|
-
isFullScreen?: boolean;
|
|
144
150
|
rowHeight?: number;
|
|
151
|
+
isFullScreen?: boolean;
|
|
145
152
|
showHeader?: boolean;
|
|
146
153
|
}
|
|
147
154
|
|
|
@@ -168,23 +175,25 @@ export interface QbsTableToolbarProps {
|
|
|
168
175
|
dataLength: number;
|
|
169
176
|
headerHeight?: number;
|
|
170
177
|
searchPlaceholder?: string;
|
|
178
|
+
labels?: QbsTableLabels;
|
|
179
|
+
rtl?: boolean;
|
|
171
180
|
tableView?: boolean;
|
|
172
181
|
enableTableToggle?: boolean;
|
|
173
182
|
tableViewToggle?: boolean;
|
|
174
183
|
setTableViewToggle?: (value: boolean) => void;
|
|
175
|
-
rowViewToggle?: boolean;
|
|
176
|
-
defaultRowView?: boolean;
|
|
177
|
-
fullWidthView?: boolean;
|
|
178
|
-
setTableFullView?: (value: boolean) => void;
|
|
179
|
-
setRowViewToggle?: (value: boolean) => void;
|
|
180
|
-
isFullScreen?: boolean;
|
|
181
|
-
labels?: QbsTableLabels;
|
|
182
|
-
rtl?: boolean;
|
|
183
184
|
selectedRowActions?: {
|
|
184
185
|
actionTitle?: string;
|
|
185
186
|
action: (checked: (number | string)[]) => void;
|
|
186
187
|
disabled?: boolean;
|
|
187
188
|
hidden?: boolean;
|
|
188
189
|
customHide?: string;
|
|
190
|
+
buttonClassName?: string;
|
|
191
|
+
icon?: ReactElement | ReactNode;
|
|
189
192
|
}[];
|
|
193
|
+
rowViewToggle?: boolean;
|
|
194
|
+
defaultRowView?: boolean;
|
|
195
|
+
fullWidthView?: boolean;
|
|
196
|
+
setTableFullView?: (value: boolean) => void;
|
|
197
|
+
setRowViewToggle?: (value: boolean) => void;
|
|
198
|
+
isFullScreen?: boolean;
|
|
190
199
|
}
|
package/src/qbsTable/labels.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface QbsTableLabels {
|
|
2
2
|
search?: string;
|
|
3
3
|
searchAriaLabel?: string;
|
|
4
4
|
clear?: string;
|
|
@@ -19,7 +19,7 @@ export type QbsTableLabels = {
|
|
|
19
19
|
viewMore?: string;
|
|
20
20
|
viewLess?: string;
|
|
21
21
|
actions?: string;
|
|
22
|
-
}
|
|
22
|
+
}
|
|
23
23
|
|
|
24
24
|
export const defaultQbsTableLabels: QbsTableLabels = {
|
|
25
25
|
search: 'Search',
|
|
@@ -44,11 +44,18 @@ export const defaultQbsTableLabels: QbsTableLabels = {
|
|
|
44
44
|
actions: 'Actions',
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
+
/** @deprecated Use defaultQbsTableLabels */
|
|
48
|
+
export const DEFAULT_QBS_TABLE_LABELS = defaultQbsTableLabels;
|
|
49
|
+
|
|
47
50
|
export const mergeQbsTableLabels = (overrides?: QbsTableLabels): QbsTableLabels => ({
|
|
48
51
|
...defaultQbsTableLabels,
|
|
49
52
|
...overrides,
|
|
53
|
+
showingRange: overrides?.showingRange ?? defaultQbsTableLabels.showingRange,
|
|
50
54
|
});
|
|
51
55
|
|
|
56
|
+
/** @deprecated Use mergeQbsTableLabels */
|
|
57
|
+
export const mergeLabels = mergeQbsTableLabels;
|
|
58
|
+
|
|
52
59
|
export const formatSelectedItems = (count: number, labels?: QbsTableLabels): string => {
|
|
53
60
|
const merged = mergeQbsTableLabels(labels);
|
|
54
61
|
return `${merged.selectedItems} (${count})`;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { QbsColumnProps } from '../commontypes';
|
|
4
|
+
import { mergeLabels, type QbsTableLabels } from '../labels';
|
|
4
5
|
import CardMenuDropdown from './CardMenuDropdown';
|
|
5
6
|
import { handleCellFormat } from './handleFormatCell';
|
|
6
7
|
import { ArrowUpIcon } from './icons';
|
|
@@ -17,6 +18,7 @@ type Props = {
|
|
|
17
18
|
handleMenuActions?: () => void;
|
|
18
19
|
cardColumLimit?: number;
|
|
19
20
|
childDetailHeading?: string;
|
|
21
|
+
labels?: QbsTableLabels;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
const CardComponent: React.FC<Props> = ({
|
|
@@ -27,8 +29,10 @@ const CardComponent: React.FC<Props> = ({
|
|
|
27
29
|
index,
|
|
28
30
|
cardColumLimit = 5,
|
|
29
31
|
handleMenuActions,
|
|
30
|
-
childDetailHeading = ''
|
|
32
|
+
childDetailHeading = '',
|
|
33
|
+
labels: labelsProp
|
|
31
34
|
}) => {
|
|
35
|
+
const labels = mergeLabels(labelsProp);
|
|
32
36
|
const [viewMore, setViewMore] = useState(false);
|
|
33
37
|
const initialDisplayCount = cardColumLimit;
|
|
34
38
|
|
|
@@ -102,13 +106,14 @@ const CardComponent: React.FC<Props> = ({
|
|
|
102
106
|
iconName="more"
|
|
103
107
|
rowIndex={index}
|
|
104
108
|
handleMenuActions={handleMenuActions}
|
|
109
|
+
labels={labels}
|
|
105
110
|
/>
|
|
106
111
|
</div>
|
|
107
112
|
|
|
108
113
|
{columns.length > initialDisplayCount && (
|
|
109
114
|
<TooltipComponent
|
|
110
115
|
tableBodyRef={useCardRef}
|
|
111
|
-
title={viewMore ?
|
|
116
|
+
title={viewMore ? labels.viewLess : labels.viewMore}
|
|
112
117
|
enabled={false}
|
|
113
118
|
>
|
|
114
119
|
<button
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
|
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
4
2
|
import { ActionProps } from '../commontypes';
|
|
3
|
+
import { mergeLabels, type QbsTableLabels } from '../labels';
|
|
5
4
|
import { ThreeDotIcon } from './icons';
|
|
6
5
|
import TooltipComponent from './ToolTip';
|
|
7
6
|
|
|
@@ -13,9 +12,16 @@ type Props = {
|
|
|
13
12
|
dataTheme?: string;
|
|
14
13
|
tableBodyRef: React.RefObject<HTMLDivElement>;
|
|
15
14
|
rowIndex?: number;
|
|
15
|
+
labels?: QbsTableLabels;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
const CardMenuDropdown: React.FC<Props> = ({
|
|
18
|
+
const CardMenuDropdown: React.FC<Props> = ({
|
|
19
|
+
actionDropDown,
|
|
20
|
+
handleMenuActions,
|
|
21
|
+
rowData,
|
|
22
|
+
labels: labelsProp
|
|
23
|
+
}) => {
|
|
24
|
+
const labels = mergeLabels(labelsProp);
|
|
19
25
|
const [openMenu, setOpenMenu] = useState(false);
|
|
20
26
|
const [menuPositionStyles, setMenuPositionStyles] = useState<{
|
|
21
27
|
top?: string;
|
|
@@ -46,7 +52,6 @@ const CardMenuDropdown: React.FC<Props> = ({ actionDropDown, handleMenuActions,
|
|
|
46
52
|
const dropdownHeight = 200; // Adjust this if your dropdown height varies
|
|
47
53
|
const spaceBelow = window.innerHeight - buttonRect.bottom;
|
|
48
54
|
const spaceAbove = buttonRect.top;
|
|
49
|
-
console.log(spaceAbove, spaceBelow, dropdownHeight);
|
|
50
55
|
if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
|
|
51
56
|
setMenuPositionStyles({
|
|
52
57
|
bottom: '30px',
|
|
@@ -76,7 +81,7 @@ const CardMenuDropdown: React.FC<Props> = ({ actionDropDown, handleMenuActions,
|
|
|
76
81
|
return (
|
|
77
82
|
<div className="dropdown text-black dark:text-white dark:bg-[#424242] bg-white" ref={menuRef}>
|
|
78
83
|
<button className="dropdown-toggle" onClick={toggleMenu} ref={menuButtonRef}>
|
|
79
|
-
<TooltipComponent title=
|
|
84
|
+
<TooltipComponent title={labels.actions} enabled={false}>
|
|
80
85
|
<ThreeDotIcon />
|
|
81
86
|
</TooltipComponent>
|
|
82
87
|
</button>
|
|
@@ -2,12 +2,14 @@ import React, { memo, useCallback } from 'react';
|
|
|
2
2
|
|
|
3
3
|
export interface SearchProps {
|
|
4
4
|
placeholder: string;
|
|
5
|
+
searchAriaLabel?: string;
|
|
5
6
|
handleChange: (value: string) => void;
|
|
6
7
|
searchValue: string | undefined;
|
|
7
8
|
handleSearch: (value?: string) => void;
|
|
8
9
|
}
|
|
9
10
|
const SearchInput: React.FC<SearchProps> = ({
|
|
10
11
|
placeholder,
|
|
12
|
+
searchAriaLabel = 'Search',
|
|
11
13
|
handleChange,
|
|
12
14
|
searchValue,
|
|
13
15
|
handleSearch
|
|
@@ -37,7 +39,7 @@ const SearchInput: React.FC<SearchProps> = ({
|
|
|
37
39
|
placeholder={placeholder}
|
|
38
40
|
value={searchValue ?? ''}
|
|
39
41
|
onChange={handleInputChange}
|
|
40
|
-
aria-label=
|
|
42
|
+
aria-label={searchAriaLabel}
|
|
41
43
|
/>
|
|
42
44
|
<button
|
|
43
45
|
className="search-button absolute left-1 bottom-1.5 bg-white text-grey-dark"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { useEffect, useId, useRef, useState } from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
|
|
4
|
+
import type { ActionProps } from '../commontypes';
|
|
4
5
|
import { ThreeDotIcon } from './icons';
|
|
5
6
|
import TooltipComponent from './ToolTip';
|
|
6
|
-
import type { ActionProps } from '../commontypes';
|
|
7
7
|
import {
|
|
8
8
|
closeOtherVerticalMenus,
|
|
9
9
|
VERTICAL_MENU_CLOSE_OTHERS,
|
|
@@ -18,6 +18,12 @@ type VerticalMenuDropdownProps = {
|
|
|
18
18
|
rowIndex?: number;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
const isActionVisible = (
|
|
22
|
+
item: ActionProps,
|
|
23
|
+
rowData: any,
|
|
24
|
+
rowIndex?: number,
|
|
25
|
+
): boolean => !item.hidden && !(item.hide?.(rowData, rowIndex) ?? false);
|
|
26
|
+
|
|
21
27
|
const VerticalMenuDropdown: React.FC<VerticalMenuDropdownProps> = ({
|
|
22
28
|
actionDropDown,
|
|
23
29
|
handleMenuActions,
|
|
@@ -49,16 +55,12 @@ const VerticalMenuDropdown: React.FC<VerticalMenuDropdownProps> = ({
|
|
|
49
55
|
const rect = menuButtonRef.current.getBoundingClientRect();
|
|
50
56
|
const viewportPadding = 8;
|
|
51
57
|
const menuGap = 4;
|
|
52
|
-
const visibleItems =
|
|
53
|
-
actionDropDown?.filter(
|
|
54
|
-
item =>
|
|
55
|
-
!item.hidden && !(item.hide?.call(item, rowData, rowIndex) ?? false),
|
|
56
|
-
) ?? [];
|
|
58
|
+
const visibleItems = actionDropDown?.filter(item => isActionVisible(item, rowData, rowIndex)) ?? [];
|
|
57
59
|
const menuWidth =
|
|
58
60
|
menuRef.current && menuRef.current.offsetWidth > 0
|
|
59
61
|
? menuRef.current.offsetWidth
|
|
60
62
|
: Math.max(120, visibleItems.length * 48);
|
|
61
|
-
const menuHeight = visibleItems.length * 40;
|
|
63
|
+
const menuHeight = Math.max(visibleItems.length, 1) * 40;
|
|
62
64
|
const spaceBelow = window.innerHeight - rect.bottom;
|
|
63
65
|
const openBelow = spaceBelow >= menuHeight + menuGap;
|
|
64
66
|
|
|
@@ -83,6 +85,7 @@ const VerticalMenuDropdown: React.FC<VerticalMenuDropdownProps> = ({
|
|
|
83
85
|
|
|
84
86
|
useEffect(() => {
|
|
85
87
|
if (!openMenu) return;
|
|
88
|
+
|
|
86
89
|
updateMenuPosition();
|
|
87
90
|
const frame = requestAnimationFrame(() => updateMenuPosition());
|
|
88
91
|
const resizeObserver =
|
|
@@ -96,33 +99,37 @@ const VerticalMenuDropdown: React.FC<VerticalMenuDropdownProps> = ({
|
|
|
96
99
|
cancelAnimationFrame(frame);
|
|
97
100
|
resizeObserver?.disconnect();
|
|
98
101
|
};
|
|
99
|
-
}, [openMenu]);
|
|
102
|
+
}, [openMenu, actionDropDown, rowData, rowIndex]);
|
|
100
103
|
|
|
101
104
|
useEffect(() => {
|
|
102
105
|
if (!openMenu) return;
|
|
103
106
|
|
|
104
|
-
const
|
|
107
|
+
const handlePointerDown = (event: MouseEvent) => {
|
|
105
108
|
const target = event.target as Node;
|
|
106
|
-
if (
|
|
107
|
-
menuRef.current?.contains(target) ||
|
|
108
|
-
menuButtonRef.current?.contains(target)
|
|
109
|
-
) {
|
|
109
|
+
if (menuRef.current?.contains(target) || menuButtonRef.current?.contains(target)) {
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
112
|
setOpenMenu(false);
|
|
113
113
|
};
|
|
114
114
|
const handleScroll = () => setOpenMenu(false);
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
// Defer so the opening click does not immediately close the menu.
|
|
117
|
+
const timeoutId = window.setTimeout(() => {
|
|
118
|
+
document.addEventListener('mousedown', handlePointerDown);
|
|
119
|
+
}, 0);
|
|
120
|
+
|
|
117
121
|
window.addEventListener('scroll', handleScroll, true);
|
|
118
122
|
|
|
119
123
|
return () => {
|
|
120
|
-
|
|
124
|
+
window.clearTimeout(timeoutId);
|
|
125
|
+
document.removeEventListener('mousedown', handlePointerDown);
|
|
121
126
|
window.removeEventListener('scroll', handleScroll, true);
|
|
122
127
|
};
|
|
123
128
|
}, [openMenu]);
|
|
124
129
|
|
|
125
130
|
useEffect(() => {
|
|
131
|
+
if (!openMenu) return;
|
|
132
|
+
|
|
126
133
|
const scrollbarHandle = document.querySelector('.rs-table-scrollbar-handle');
|
|
127
134
|
if (!scrollbarHandle) return;
|
|
128
135
|
|
|
@@ -149,12 +156,22 @@ const VerticalMenuDropdown: React.FC<VerticalMenuDropdownProps> = ({
|
|
|
149
156
|
};
|
|
150
157
|
|
|
151
158
|
const visibleCount =
|
|
152
|
-
actionDropDown?.filter(
|
|
153
|
-
|
|
154
|
-
|
|
159
|
+
actionDropDown?.filter(item => isActionVisible(item, rowData, rowIndex)).length ?? 0;
|
|
160
|
+
|
|
161
|
+
const portalTarget = document.getElementById('portal-root');
|
|
155
162
|
|
|
156
|
-
const
|
|
157
|
-
|
|
163
|
+
const toggleMenu = () => {
|
|
164
|
+
if (openMenu) {
|
|
165
|
+
setOpenMenu(false);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
closeOtherVerticalMenus(menuId);
|
|
169
|
+
updateMenuPosition();
|
|
170
|
+
// Delay open so table/document click handlers do not close it immediately.
|
|
171
|
+
window.setTimeout(() => {
|
|
172
|
+
setOpenMenu(true);
|
|
173
|
+
}, 0);
|
|
174
|
+
};
|
|
158
175
|
|
|
159
176
|
const dropdownContent = (
|
|
160
177
|
<div
|
|
@@ -170,13 +187,13 @@ const VerticalMenuDropdown: React.FC<VerticalMenuDropdownProps> = ({
|
|
|
170
187
|
>
|
|
171
188
|
<div className="py-1">
|
|
172
189
|
{actionDropDown?.map(item =>
|
|
173
|
-
|
|
190
|
+
isActionVisible(item, rowData, rowIndex) ? (
|
|
174
191
|
<div
|
|
175
192
|
key={item.title}
|
|
176
193
|
className="vertical-menu-item px-4 py-2 text-sm text-base-black hover:bg-gray-light-1 cursor-pointer flex items-center gap-2 transition-colors"
|
|
177
194
|
onClick={e => {
|
|
178
195
|
e.preventDefault();
|
|
179
|
-
|
|
196
|
+
e.stopPropagation();
|
|
180
197
|
handleMenuItemClick(item);
|
|
181
198
|
}}
|
|
182
199
|
>
|
|
@@ -199,16 +216,11 @@ const VerticalMenuDropdown: React.FC<VerticalMenuDropdownProps> = ({
|
|
|
199
216
|
{visibleCount > 0 && (
|
|
200
217
|
<button
|
|
201
218
|
type="button"
|
|
202
|
-
className="vertical-menu-trigger-button"
|
|
219
|
+
className="vertical-menu-trigger-button p-2 rounded text-base-gray hover:bg-gray-light-1 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
|
203
220
|
onClick={event => {
|
|
204
221
|
event.stopPropagation();
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
closeOtherVerticalMenus(menuId);
|
|
210
|
-
updateMenuPosition();
|
|
211
|
-
setOpenMenu(true);
|
|
222
|
+
event.preventDefault();
|
|
223
|
+
toggleMenu();
|
|
212
224
|
}}
|
|
213
225
|
ref={menuButtonRef}
|
|
214
226
|
>
|
|
@@ -18,7 +18,7 @@ const NoData: React.FC<props> = ({ title, subtitle }) => {
|
|
|
18
18
|
}}
|
|
19
19
|
>
|
|
20
20
|
<div style={{ width: 145, marginBottom: 20 }} className="nodata-img">
|
|
21
|
-
|
|
21
|
+
<svg
|
|
22
22
|
xmlns="http://www.w3.org/2000/svg"
|
|
23
23
|
width="148"
|
|
24
24
|
height="132"
|
|
@@ -71,7 +71,7 @@ const NoData: React.FC<props> = ({ title, subtitle }) => {
|
|
|
71
71
|
fill="#797979"
|
|
72
72
|
d="M47.365 57.417a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 57.417a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 52.974a.926.926 0 00.926-.927V50.27a.926.926 0 00-1.852 0v1.777c0 .512.415.927.926.927zM104.183 52.974a.926.926 0 00.926-.927V50.27a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 44.088a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 44.088a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 39.645a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 39.645a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 35.202a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 35.202a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 30.758a.926.926 0 00.926-.926v-.888c0-.248.02-.49.057-.726a.926.926 0 00-1.83-.288c-.052.33-.08.67-.08 1.014v.888c0 .512.416.926.927.926zM104.183 30.758a.926.926 0 00.926-.926v-.888c0-.345-.027-.683-.079-1.014a.926.926 0 10-1.83.288c.037.236.057.478.057.726v.888c0 .512.414.926.926.926zM47.881 26.426a.926.926 0 001.294-.204c.286-.394.633-.74 1.026-1.026a.926.926 0 00-1.09-1.498c-.55.4-1.034.884-1.434 1.434a.926.926 0 00.204 1.294zM103.667 26.426a.926.926 0 00.204-1.294 6.509 6.509 0 00-1.434-1.434.926.926 0 00-1.09 1.498c.393.286.74.632 1.026 1.026a.926.926 0 001.294.204zM51.138 23.597c.08.506.554.851 1.059.772a4.67 4.67 0 01.726-.057h.914a.926.926 0 000-1.852h-.914c-.344 0-.683.026-1.014.078a.926.926 0 00-.77 1.06zM100.41 23.597a.927.927 0 00-.771-1.059 6.522 6.522 0 00-1.014-.078h-.914a.926.926 0 100 1.852h.914c.248 0 .49.02.726.057a.926.926 0 001.059-.772zM55.653 23.386c0 .511.415.926.926.926h1.828a.926.926 0 000-1.852H56.58a.926.926 0 00-.926.926zM60.223 23.386c0 .511.415.926.926.926h1.828a.926.926 0 000-1.852H61.15a.926.926 0 00-.926.926zM64.793 23.386c0 .511.415.926.926.926h1.829a.926.926 0 000-1.852h-1.829a.926.926 0 00-.926.926zM69.364 23.386c0 .511.414.926.926.926h1.828a.926.926 0 000-1.852H70.29a.926.926 0 00-.927.926zM73.934 23.386c0 .511.414.926.926.926h1.828a.926.926 0 000-1.852H74.86a.926.926 0 00-.926.926zM78.504 23.386c0 .511.415.926.926.926h1.828a.926.926 0 000-1.852H79.43a.926.926 0 00-.926.926zM83.074 23.386c0 .511.415.926.927.926h1.828a.926.926 0 000-1.852H84a.926.926 0 00-.927.926zM87.644 23.386c0 .511.415.926.927.926h1.828a.926.926 0 000-1.852H88.57a.926.926 0 00-.927.926zM92.215 23.386c0 .511.414.926.926.926h1.828a.926.926 0 000-1.852h-1.828a.926.926 0 00-.926.926zM72.178 36.453a1.39 1.39 0 10-1.965 1.965l3.797 3.797-3.797 3.798a1.39 1.39 0 001.965 1.965l3.797-3.798 3.798 3.798a1.39 1.39 0 001.965-1.965l-3.798-3.798 3.798-3.797a1.39 1.39 0 10-1.965-1.965l-3.798 3.797-3.797-3.797z"
|
|
73
73
|
></path>
|
|
74
|
-
</svg>
|
|
74
|
+
</svg>{' '}
|
|
75
75
|
</div>
|
|
76
76
|
<p className="text-center text-common font-bold text-blackAlt nodata-title">{title}</p>
|
|
77
77
|
<span className="text-xxs font-medium text-grey-medium nodata-sub-title">{subtitle}</span>
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
export function getRowDisplayRange(
|
|
1
|
+
export function getRowDisplayRange(
|
|
2
|
+
totalRows: number,
|
|
3
|
+
rowsPerPage: number,
|
|
4
|
+
pageNumber: number,
|
|
5
|
+
formatRange: (start: number, end: number, total: number) => string = (start, end, total) =>
|
|
6
|
+
`Showing ${start} to ${end} of ${total}`
|
|
7
|
+
) {
|
|
2
8
|
const start = (pageNumber - 1) * rowsPerPage + 1;
|
|
3
9
|
const end = Math.min(pageNumber * rowsPerPage, totalRows);
|
|
4
10
|
|
|
5
|
-
return
|
|
11
|
+
return formatRange(start ?? 0, end ?? 0, totalRows ?? 0);
|
|
6
12
|
}
|
|
@@ -205,7 +205,6 @@ const useCellDescriptor = <Row extends RowDataType>(
|
|
|
205
205
|
if (treeCol) {
|
|
206
206
|
hasCustomTreeCol = true;
|
|
207
207
|
}
|
|
208
|
-
console.log(columns);
|
|
209
208
|
|
|
210
209
|
if (columnChildren?.length !== 2) {
|
|
211
210
|
throw new Error(`Component <HeaderCell> and <Cell> is required, column index: ${index} `);
|
|
@@ -4,6 +4,7 @@ import scrollLeft from 'dom-lib/scrollLeft';
|
|
|
4
4
|
import scrollTop from 'dom-lib/scrollTop';
|
|
5
5
|
import WheelHandler from 'dom-lib/WheelHandler';
|
|
6
6
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
7
|
+
|
|
7
8
|
import type { ListenerCallback, RowDataType } from '../@types/common';
|
|
8
9
|
import { BEZIER, SCROLLBAR_WIDTH, TRANSITION_DURATION } from '../constants';
|
|
9
10
|
import type { ScrollbarInstance } from '../Scrollbar';
|
|
@@ -50,6 +51,7 @@ interface ScrollListenerProps {
|
|
|
50
51
|
onTouchStart?: (event: React.TouchEvent) => void;
|
|
51
52
|
onTouchMove?: (event: React.TouchEvent) => void;
|
|
52
53
|
onTouchEnd?: (event: React.TouchEvent) => void;
|
|
54
|
+
handleInfiniteScroll?: (value: number) => void;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
/**
|
|
@@ -106,7 +108,8 @@ const useScrollListener = (props: ScrollListenerProps) => {
|
|
|
106
108
|
contentHeight,
|
|
107
109
|
headerHeight,
|
|
108
110
|
rtl,
|
|
109
|
-
tableKey
|
|
111
|
+
tableKey,
|
|
112
|
+
handleInfiniteScroll
|
|
110
113
|
} = props;
|
|
111
114
|
|
|
112
115
|
const wheelListener = useRef<ListenerCallback>(null);
|
|
@@ -187,6 +190,15 @@ const useScrollListener = (props: ScrollListenerProps) => {
|
|
|
187
190
|
setScrollX(x);
|
|
188
191
|
setScrollY(y);
|
|
189
192
|
|
|
193
|
+
if (
|
|
194
|
+
typeof handleInfiniteScroll === 'function' &&
|
|
195
|
+
deltaY !== 0 &&
|
|
196
|
+
!loading &&
|
|
197
|
+
Math.abs(y) + getTableHeight() >= contentHeight.current - 12
|
|
198
|
+
) {
|
|
199
|
+
handleInfiniteScroll(scrollY.current);
|
|
200
|
+
}
|
|
201
|
+
|
|
190
202
|
onScroll?.(Math.abs(x), Math.abs(y));
|
|
191
203
|
|
|
192
204
|
if (virtualized) {
|
|
@@ -297,7 +309,6 @@ const useScrollListener = (props: ScrollListenerProps) => {
|
|
|
297
309
|
if (!isTouching.current) {
|
|
298
310
|
return;
|
|
299
311
|
}
|
|
300
|
-
console.log('handleTouchMove');
|
|
301
312
|
|
|
302
313
|
const { pageX, pageY } = event.touches[0];
|
|
303
314
|
const deltaX = touchX.current - pageX;
|
|
@@ -338,7 +349,6 @@ const useScrollListener = (props: ScrollListenerProps) => {
|
|
|
338
349
|
if (!isTouching.current) {
|
|
339
350
|
return;
|
|
340
351
|
}
|
|
341
|
-
console.log('handleTouchEnd');
|
|
342
352
|
isTouching.current = false;
|
|
343
353
|
const touchDuration = new Date().getTime() - momentumStartTime.current;
|
|
344
354
|
const absDeltaY = Math.abs(scrollY.current - momentumStartY.current);
|
|
@@ -8,7 +8,7 @@ import defer from './defer';
|
|
|
8
8
|
|
|
9
9
|
interface TableRowsProps<Row, Key> {
|
|
10
10
|
prefix: (str: string) => string;
|
|
11
|
-
wordWrap?: boolean | 'break-all' | 'break-word' | 'keep-all'| 'fit-content';
|
|
11
|
+
wordWrap?: boolean | 'break-all' | 'break-word' | 'keep-all' | 'fit-content';
|
|
12
12
|
data: readonly Row[];
|
|
13
13
|
expandedRowKeys: readonly Key[];
|
|
14
14
|
}
|