@mkt-loitd/react-table-grid-custom 1.2.5 → 1.2.7
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/README.md +37 -57
- package/dist/index.css +97 -0
- package/dist/index.d.mts +136 -5
- package/dist/index.d.ts +136 -5
- package/dist/index.js +257 -0
- package/dist/index.mjs +256 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,54 +1,42 @@
|
|
|
1
|
-
@mkt-loitd/react-table-grid-custom
|
|
1
|
+
# @mkt-loitd/react-table-grid-custom
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@mkt-loitd/react-table-grid-custom)
|
|
4
|
+
[](https://www.npmjs.com/package/@mkt-loitd/react-table-grid-custom)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
A **flexible and customizable React Table Grid component** built with **TypeScript**, designed for displaying tabular data with custom columns, layouts, and rendering logic.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## ✨ Features
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
- ⚛️ Built for React
|
|
14
|
+
- 🧩 Fully customizable columns
|
|
15
|
+
- 📝 Support for custom cell render
|
|
16
|
+
- 📦 Lightweight & easy to integrate
|
|
17
|
+
- 🛠 Written in TypeScript
|
|
18
|
+
- 🔁 Supports both ESM and CJS
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
---
|
|
14
21
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
🔁 Supports both ESM and CJS
|
|
18
|
-
|
|
19
|
-
📦 Installation
|
|
20
|
-
|
|
21
|
-
Using npm:
|
|
22
|
+
## 📦 Installation
|
|
22
23
|
|
|
24
|
+
```bash
|
|
23
25
|
npm install @mkt-loitd/react-table-grid-custom
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Using yarn:
|
|
27
|
-
|
|
26
|
+
# or
|
|
28
27
|
yarn add @mkt-loitd/react-table-grid-custom
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Using pnpm:
|
|
32
|
-
|
|
28
|
+
# or
|
|
33
29
|
pnpm add @mkt-loitd/react-table-grid-custom
|
|
34
|
-
|
|
35
30
|
🚀 Basic Usage
|
|
31
|
+
tsx
|
|
32
|
+
Copy code
|
|
36
33
|
import React from 'react'
|
|
37
34
|
import { ReactTableGridCustom } from '@mkt-loitd/react-table-grid-custom'
|
|
38
35
|
|
|
39
36
|
const columns = [
|
|
40
|
-
{
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
key: 'email',
|
|
46
|
-
title: 'Email',
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
key: 'age',
|
|
50
|
-
title: 'Age',
|
|
51
|
-
},
|
|
37
|
+
{ key: 'name', title: 'Name' },
|
|
38
|
+
{ key: 'email', title: 'Email' },
|
|
39
|
+
{ key: 'age', title: 'Age' },
|
|
52
40
|
]
|
|
53
41
|
|
|
54
42
|
const data = [
|
|
@@ -57,24 +45,20 @@ const data = [
|
|
|
57
45
|
]
|
|
58
46
|
|
|
59
47
|
export default function App() {
|
|
60
|
-
return
|
|
61
|
-
<ReactTableGridCustom
|
|
62
|
-
columns={columns}
|
|
63
|
-
data={data}
|
|
64
|
-
rowKey="id"
|
|
65
|
-
/>
|
|
66
|
-
)
|
|
48
|
+
return <ReactTableGridCustom columns={columns} data={data} rowKey="id" />
|
|
67
49
|
}
|
|
68
|
-
|
|
69
50
|
🧱 Column Definition
|
|
51
|
+
ts
|
|
52
|
+
Copy code
|
|
70
53
|
interface Column {
|
|
71
|
-
key: string
|
|
72
|
-
title: string
|
|
73
|
-
width?: number | string
|
|
74
|
-
render?: (value: any, row: any, rowIndex: number) => React.ReactNode
|
|
54
|
+
key: string // Column key (unique)
|
|
55
|
+
title: string // Column header title
|
|
56
|
+
width?: number | string // Optional column width
|
|
57
|
+
render?: (value: any, row: any, rowIndex: number) => React.ReactNode // Custom cell render
|
|
75
58
|
}
|
|
76
|
-
|
|
77
|
-
|
|
59
|
+
Example with custom render
|
|
60
|
+
ts
|
|
61
|
+
Copy code
|
|
78
62
|
const columns = [
|
|
79
63
|
{
|
|
80
64
|
key: 'name',
|
|
@@ -89,7 +73,6 @@ const columns = [
|
|
|
89
73
|
),
|
|
90
74
|
},
|
|
91
75
|
]
|
|
92
|
-
|
|
93
76
|
📌 Props
|
|
94
77
|
Prop Type Required Description
|
|
95
78
|
columns Column[] ✅ Table column configuration
|
|
@@ -97,10 +80,11 @@ data any[] ✅ Data source
|
|
|
97
80
|
rowKey string ✅ Unique key for each row
|
|
98
81
|
className string ❌ Custom CSS class
|
|
99
82
|
style CSSProperties ❌ Inline styles
|
|
100
|
-
🎨 Styling
|
|
101
83
|
|
|
102
84
|
You can fully customize the table using your own CSS:
|
|
103
85
|
|
|
86
|
+
css
|
|
87
|
+
Copy code
|
|
104
88
|
.react-table-grid {
|
|
105
89
|
border: 1px solid #e5e7eb;
|
|
106
90
|
}
|
|
@@ -108,12 +92,9 @@ You can fully customize the table using your own CSS:
|
|
|
108
92
|
.react-table-grid-row:hover {
|
|
109
93
|
background-color: #f9fafb;
|
|
110
94
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
95
|
Or wrap it inside your design system (Tailwind, AntD, MUI, etc).
|
|
114
96
|
|
|
115
97
|
📂 Build Output
|
|
116
|
-
|
|
117
98
|
This package is built using tsup:
|
|
118
99
|
|
|
119
100
|
dist/index.esm.js – ES Module
|
|
@@ -123,7 +104,6 @@ dist/index.cjs.js – CommonJS
|
|
|
123
104
|
dist/index.d.ts – Type definitions
|
|
124
105
|
|
|
125
106
|
🧪 Compatibility
|
|
126
|
-
|
|
127
107
|
React >= 17
|
|
128
108
|
|
|
129
109
|
React DOM >= 17
|
|
@@ -131,9 +111,9 @@ React DOM >= 17
|
|
|
131
111
|
Node >= 16
|
|
132
112
|
|
|
133
113
|
🛠 Development
|
|
114
|
+
bash
|
|
115
|
+
Copy code
|
|
134
116
|
npm install
|
|
135
117
|
npm run build
|
|
136
|
-
|
|
137
118
|
📄 License
|
|
138
|
-
|
|
139
119
|
MIT © mkt-loitd
|
package/dist/index.css
CHANGED
|
@@ -55,3 +55,100 @@ div[aria-sort] > span {
|
|
|
55
55
|
position: sticky !important;
|
|
56
56
|
right: 0 !important;
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
/* src/component/ui/ContextMenu/ContextMenu.css */
|
|
60
|
+
.shadow-menu {
|
|
61
|
+
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
|
|
62
|
+
animation: open 0.3s;
|
|
63
|
+
transform-origin: top left;
|
|
64
|
+
}
|
|
65
|
+
.shadow-submenu {
|
|
66
|
+
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
|
|
67
|
+
}
|
|
68
|
+
@keyframes open {
|
|
69
|
+
from {
|
|
70
|
+
transform: scale(0);
|
|
71
|
+
}
|
|
72
|
+
to {
|
|
73
|
+
transform: scale(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* node_modules/tippy.js/dist/tippy.css */
|
|
78
|
+
.tippy-box[data-animation=fade][data-state=hidden] {
|
|
79
|
+
opacity: 0;
|
|
80
|
+
}
|
|
81
|
+
[data-tippy-root] {
|
|
82
|
+
max-width: calc(100vw - 10px);
|
|
83
|
+
}
|
|
84
|
+
.tippy-box {
|
|
85
|
+
position: relative;
|
|
86
|
+
background-color: #333;
|
|
87
|
+
color: #fff;
|
|
88
|
+
border-radius: 4px;
|
|
89
|
+
font-size: 14px;
|
|
90
|
+
line-height: 1.4;
|
|
91
|
+
white-space: normal;
|
|
92
|
+
outline: 0;
|
|
93
|
+
transition-property:
|
|
94
|
+
transform,
|
|
95
|
+
visibility,
|
|
96
|
+
opacity;
|
|
97
|
+
}
|
|
98
|
+
.tippy-box[data-placement^=top] > .tippy-arrow {
|
|
99
|
+
bottom: 0;
|
|
100
|
+
}
|
|
101
|
+
.tippy-box[data-placement^=top] > .tippy-arrow:before {
|
|
102
|
+
bottom: -7px;
|
|
103
|
+
left: 0;
|
|
104
|
+
border-width: 8px 8px 0;
|
|
105
|
+
border-top-color: initial;
|
|
106
|
+
transform-origin: center top;
|
|
107
|
+
}
|
|
108
|
+
.tippy-box[data-placement^=bottom] > .tippy-arrow {
|
|
109
|
+
top: 0;
|
|
110
|
+
}
|
|
111
|
+
.tippy-box[data-placement^=bottom] > .tippy-arrow:before {
|
|
112
|
+
top: -7px;
|
|
113
|
+
left: 0;
|
|
114
|
+
border-width: 0 8px 8px;
|
|
115
|
+
border-bottom-color: initial;
|
|
116
|
+
transform-origin: center bottom;
|
|
117
|
+
}
|
|
118
|
+
.tippy-box[data-placement^=left] > .tippy-arrow {
|
|
119
|
+
right: 0;
|
|
120
|
+
}
|
|
121
|
+
.tippy-box[data-placement^=left] > .tippy-arrow:before {
|
|
122
|
+
border-width: 8px 0 8px 8px;
|
|
123
|
+
border-left-color: initial;
|
|
124
|
+
right: -7px;
|
|
125
|
+
transform-origin: center left;
|
|
126
|
+
}
|
|
127
|
+
.tippy-box[data-placement^=right] > .tippy-arrow {
|
|
128
|
+
left: 0;
|
|
129
|
+
}
|
|
130
|
+
.tippy-box[data-placement^=right] > .tippy-arrow:before {
|
|
131
|
+
left: -7px;
|
|
132
|
+
border-width: 8px 8px 8px 0;
|
|
133
|
+
border-right-color: initial;
|
|
134
|
+
transform-origin: center right;
|
|
135
|
+
}
|
|
136
|
+
.tippy-box[data-inertia][data-state=visible] {
|
|
137
|
+
transition-timing-function: cubic-bezier(.54, 1.5, .38, 1.11);
|
|
138
|
+
}
|
|
139
|
+
.tippy-arrow {
|
|
140
|
+
width: 16px;
|
|
141
|
+
height: 16px;
|
|
142
|
+
color: #333;
|
|
143
|
+
}
|
|
144
|
+
.tippy-arrow:before {
|
|
145
|
+
content: "";
|
|
146
|
+
position: absolute;
|
|
147
|
+
border-color: transparent;
|
|
148
|
+
border-style: solid;
|
|
149
|
+
}
|
|
150
|
+
.tippy-content {
|
|
151
|
+
position: relative;
|
|
152
|
+
padding: 5px 9px;
|
|
153
|
+
z-index: 1;
|
|
154
|
+
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction, Key, ReactNode, JSX, MutableRefObject } from 'react';
|
|
1
|
+
import { Dispatch, SetStateAction, Key, ReactNode, JSX, MutableRefObject, FC } from 'react';
|
|
2
2
|
import { ColumnOrColumnGroup, DataGridProps } from 'react-data-grid';
|
|
3
3
|
export { Column, ColumnOrColumnGroup, DataGridProps } from 'react-data-grid';
|
|
4
4
|
import { PaginationRootProps } from '@mantine/core';
|
|
5
|
+
import { TFunction } from 'i18next';
|
|
6
|
+
import { UseMutateFunction } from '@tanstack/react-query';
|
|
5
7
|
|
|
6
8
|
type TColumnsTable<T = unknown, SR = unknown> = readonly ColumnOrColumnGroup<NoInfer<T>, NoInfer<SR>>[];
|
|
7
9
|
interface IPaginationParams$1 {
|
|
@@ -11,7 +13,7 @@ interface IPaginationParams$1 {
|
|
|
11
13
|
interface IObjectDynamic {
|
|
12
14
|
[key: string]: any;
|
|
13
15
|
}
|
|
14
|
-
interface ISetConfigPagination extends IPaginationParams$1, IObjectDynamic {
|
|
16
|
+
interface ISetConfigPagination$1 extends IPaginationParams$1, IObjectDynamic {
|
|
15
17
|
}
|
|
16
18
|
interface useShowHideColumnParameter<T, SR = unknown> {
|
|
17
19
|
nameLocal?: string;
|
|
@@ -49,7 +51,7 @@ interface IReactTableGridCustom<T = unknown, SR = unknown, K extends Key = Key>
|
|
|
49
51
|
data?: T[];
|
|
50
52
|
/** Nếu hàm onChange nên dùng useCallback */
|
|
51
53
|
onChange?: Pick<PaginationRootProps, 'onChange'>['onChange'];
|
|
52
|
-
setConfigPagination?: Dispatch<SetStateAction<ISetConfigPagination>>;
|
|
54
|
+
setConfigPagination?: Dispatch<SetStateAction<ISetConfigPagination$1>>;
|
|
53
55
|
/** Nếu hàm rowKeyGetter nên dùng useCallback*/
|
|
54
56
|
rowKeyGetter?: string | Maybe<(row: NoInfer<T>) => K>;
|
|
55
57
|
hiddenPaginationText?: boolean;
|
|
@@ -61,7 +63,7 @@ interface IReactTableGridCustom<T = unknown, SR = unknown, K extends Key = Key>
|
|
|
61
63
|
[key: string]: any;
|
|
62
64
|
}
|
|
63
65
|
interface refTablePaginationClient extends Required<IPaginationParams> {
|
|
64
|
-
setConfigSearch: Dispatch<SetStateAction<ISetConfigPagination>>;
|
|
66
|
+
setConfigSearch: Dispatch<SetStateAction<ISetConfigPagination$1>>;
|
|
65
67
|
resetPagition: (conditional?: boolean) => void;
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -76,10 +78,139 @@ interface ReactTableGridCustomPaginationClientProps<T = unknown, SR = unknown, K
|
|
|
76
78
|
}
|
|
77
79
|
declare const ReactTableGridCustomPaginationClient: ReactTableGridCustomPaginationClientComponent;
|
|
78
80
|
|
|
81
|
+
interface ContextMenuProps {
|
|
82
|
+
selector: string;
|
|
83
|
+
children?: ReactNode;
|
|
84
|
+
zIndex?: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface IMainResponse<T = any> {
|
|
88
|
+
success?: boolean;
|
|
89
|
+
status?: 'success' | 'error' | 'warning';
|
|
90
|
+
data?: T;
|
|
91
|
+
payload?: {
|
|
92
|
+
data?: T;
|
|
93
|
+
[key: string]: any;
|
|
94
|
+
};
|
|
95
|
+
message?: {
|
|
96
|
+
key: string;
|
|
97
|
+
[key: string]: any;
|
|
98
|
+
};
|
|
99
|
+
error?: any;
|
|
100
|
+
}
|
|
101
|
+
interface IFieldUpdateAndCheck<T = any, F = any, V = any> {
|
|
102
|
+
id?: string | number;
|
|
103
|
+
field?: F;
|
|
104
|
+
value?: V;
|
|
105
|
+
data?: T;
|
|
106
|
+
[key: string]: any;
|
|
107
|
+
}
|
|
108
|
+
interface Account {
|
|
109
|
+
id?: string | number;
|
|
110
|
+
username?: string;
|
|
111
|
+
password?: string;
|
|
112
|
+
email?: string;
|
|
113
|
+
status?: string;
|
|
114
|
+
[key: string]: any;
|
|
115
|
+
}
|
|
116
|
+
interface Post {
|
|
117
|
+
id?: string | number;
|
|
118
|
+
title?: string;
|
|
119
|
+
content?: string;
|
|
120
|
+
createdAt?: number;
|
|
121
|
+
[key: string]: any;
|
|
122
|
+
}
|
|
123
|
+
interface AppSettings {
|
|
124
|
+
[key: string]: any;
|
|
125
|
+
}
|
|
126
|
+
interface ISetConfigPagination {
|
|
127
|
+
page?: number;
|
|
128
|
+
limit?: number;
|
|
129
|
+
total?: number;
|
|
130
|
+
[key: string]: any;
|
|
131
|
+
}
|
|
132
|
+
type ITaskName = string;
|
|
133
|
+
|
|
134
|
+
interface IActionUiUtilBy {
|
|
135
|
+
action?: string;
|
|
136
|
+
[key: string]: any;
|
|
137
|
+
}
|
|
138
|
+
interface IPayloadStartAction {
|
|
139
|
+
action?: string;
|
|
140
|
+
[key: string]: any;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
interface Proxy {
|
|
144
|
+
id?: string;
|
|
145
|
+
host?: string;
|
|
146
|
+
port?: number;
|
|
147
|
+
username?: string;
|
|
148
|
+
password?: string;
|
|
149
|
+
protocol?: string;
|
|
150
|
+
provider?: string;
|
|
151
|
+
[key: string]: any;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface IPayloadRemoveProxy {
|
|
155
|
+
ids: string[];
|
|
156
|
+
}
|
|
157
|
+
interface IPayloadService {
|
|
158
|
+
updateByClipboard?: UseMutateFunction<IMainResponse<string[]>, Error, IFieldUpdateAndCheck<Account, string[], keyof Account>, unknown>;
|
|
159
|
+
removeFieldBy?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Account, Array<keyof Account>, string[]>, unknown>;
|
|
160
|
+
copyByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Account, string, string[]>, unknown>;
|
|
161
|
+
actionBy?: UseMutateFunction<IMainResponse<string[]>, Error, IFieldUpdateAndCheck<Account, IActionUiUtilBy, string[]>, unknown>;
|
|
162
|
+
updateAccountByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Account, Partial<Account>, string[]>, unknown>;
|
|
163
|
+
deleteProxy?: UseMutateFunction<IMainResponse<boolean>, Error, IPayloadRemoveProxy, unknown>;
|
|
164
|
+
removePostByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Post, undefined, string[]>, unknown>;
|
|
165
|
+
startAction?: UseMutateFunction<IMainResponse<boolean>, Error, IPayloadStartAction, unknown>;
|
|
166
|
+
updateSettings?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<AppSettings, object, boolean>, unknown>;
|
|
167
|
+
useCopyProxyByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Proxy, string, string[]>[], unknown>;
|
|
168
|
+
exportLinkSuccess?: UseMutateFunction<IMainResponse<boolean>, Error, ITaskName, unknown>;
|
|
169
|
+
setAction?: Dispatch<SetStateAction<ITaskName>>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
type IDispatchState<T> = Dispatch<SetStateAction<T>>;
|
|
173
|
+
|
|
174
|
+
interface IExpandValue extends IPayloadService {
|
|
175
|
+
t?: TFunction<any, any>;
|
|
176
|
+
setConfigSearch?: IDispatchState<ISetConfigPagination>;
|
|
177
|
+
setSelectedRecords?: Dispatch<ReadonlySet<string>>;
|
|
178
|
+
setIsShowEdit?: Dispatch<SetStateAction<boolean>>;
|
|
179
|
+
setIsOpenEditContent?: Dispatch<SetStateAction<boolean>>;
|
|
180
|
+
setIsCopy?: Dispatch<SetStateAction<boolean>>;
|
|
181
|
+
setIsChangeCate?: Dispatch<SetStateAction<boolean>>;
|
|
182
|
+
setIsBackup?: Dispatch<SetStateAction<boolean>>;
|
|
183
|
+
}
|
|
184
|
+
type configContextMenuType = {
|
|
185
|
+
Icon: (prop?: any) => ReactNode;
|
|
186
|
+
action: string;
|
|
187
|
+
onClick?: (value: string[], expandValue: IExpandValue) => void;
|
|
188
|
+
children?: configContextMenuType[];
|
|
189
|
+
};
|
|
190
|
+
interface RenderContextMenuProps {
|
|
191
|
+
renderData?: configContextMenuType[];
|
|
192
|
+
valueClickItem?: any;
|
|
193
|
+
expandValue?: IExpandValue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
interface TableStyleWapperProps {
|
|
197
|
+
children?: ReactNode;
|
|
198
|
+
contextMenuProps?: Omit<ContextMenuProps, 'selector' | 'children'> & {
|
|
199
|
+
selector?: string;
|
|
200
|
+
};
|
|
201
|
+
renderContext?: RenderContextMenuProps;
|
|
202
|
+
clsTablecustom?: string;
|
|
203
|
+
idWapper?: string;
|
|
204
|
+
}
|
|
205
|
+
interface TableStyleContextMenuWapperComponent extends FC<TableStyleWapperProps> {
|
|
206
|
+
getIdFromOutside?: (externalId?: string) => string;
|
|
207
|
+
}
|
|
208
|
+
declare const TableStyleContextMenuWapper: TableStyleContextMenuWapperComponent;
|
|
209
|
+
|
|
79
210
|
interface IPaginationParams {
|
|
80
211
|
pageSize?: number;
|
|
81
212
|
page?: number;
|
|
82
213
|
}
|
|
83
214
|
type Maybe<T> = T | undefined | null;
|
|
84
215
|
|
|
85
|
-
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, ReactTableGridCustomPaginationClient, type TColumnsTable, useShowHideColumn };
|
|
216
|
+
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, ReactTableGridCustomPaginationClient, type TColumnsTable, TableStyleContextMenuWapper, type TableStyleWapperProps, useShowHideColumn };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction, Key, ReactNode, JSX, MutableRefObject } from 'react';
|
|
1
|
+
import { Dispatch, SetStateAction, Key, ReactNode, JSX, MutableRefObject, FC } from 'react';
|
|
2
2
|
import { ColumnOrColumnGroup, DataGridProps } from 'react-data-grid';
|
|
3
3
|
export { Column, ColumnOrColumnGroup, DataGridProps } from 'react-data-grid';
|
|
4
4
|
import { PaginationRootProps } from '@mantine/core';
|
|
5
|
+
import { TFunction } from 'i18next';
|
|
6
|
+
import { UseMutateFunction } from '@tanstack/react-query';
|
|
5
7
|
|
|
6
8
|
type TColumnsTable<T = unknown, SR = unknown> = readonly ColumnOrColumnGroup<NoInfer<T>, NoInfer<SR>>[];
|
|
7
9
|
interface IPaginationParams$1 {
|
|
@@ -11,7 +13,7 @@ interface IPaginationParams$1 {
|
|
|
11
13
|
interface IObjectDynamic {
|
|
12
14
|
[key: string]: any;
|
|
13
15
|
}
|
|
14
|
-
interface ISetConfigPagination extends IPaginationParams$1, IObjectDynamic {
|
|
16
|
+
interface ISetConfigPagination$1 extends IPaginationParams$1, IObjectDynamic {
|
|
15
17
|
}
|
|
16
18
|
interface useShowHideColumnParameter<T, SR = unknown> {
|
|
17
19
|
nameLocal?: string;
|
|
@@ -49,7 +51,7 @@ interface IReactTableGridCustom<T = unknown, SR = unknown, K extends Key = Key>
|
|
|
49
51
|
data?: T[];
|
|
50
52
|
/** Nếu hàm onChange nên dùng useCallback */
|
|
51
53
|
onChange?: Pick<PaginationRootProps, 'onChange'>['onChange'];
|
|
52
|
-
setConfigPagination?: Dispatch<SetStateAction<ISetConfigPagination>>;
|
|
54
|
+
setConfigPagination?: Dispatch<SetStateAction<ISetConfigPagination$1>>;
|
|
53
55
|
/** Nếu hàm rowKeyGetter nên dùng useCallback*/
|
|
54
56
|
rowKeyGetter?: string | Maybe<(row: NoInfer<T>) => K>;
|
|
55
57
|
hiddenPaginationText?: boolean;
|
|
@@ -61,7 +63,7 @@ interface IReactTableGridCustom<T = unknown, SR = unknown, K extends Key = Key>
|
|
|
61
63
|
[key: string]: any;
|
|
62
64
|
}
|
|
63
65
|
interface refTablePaginationClient extends Required<IPaginationParams> {
|
|
64
|
-
setConfigSearch: Dispatch<SetStateAction<ISetConfigPagination>>;
|
|
66
|
+
setConfigSearch: Dispatch<SetStateAction<ISetConfigPagination$1>>;
|
|
65
67
|
resetPagition: (conditional?: boolean) => void;
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -76,10 +78,139 @@ interface ReactTableGridCustomPaginationClientProps<T = unknown, SR = unknown, K
|
|
|
76
78
|
}
|
|
77
79
|
declare const ReactTableGridCustomPaginationClient: ReactTableGridCustomPaginationClientComponent;
|
|
78
80
|
|
|
81
|
+
interface ContextMenuProps {
|
|
82
|
+
selector: string;
|
|
83
|
+
children?: ReactNode;
|
|
84
|
+
zIndex?: number;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface IMainResponse<T = any> {
|
|
88
|
+
success?: boolean;
|
|
89
|
+
status?: 'success' | 'error' | 'warning';
|
|
90
|
+
data?: T;
|
|
91
|
+
payload?: {
|
|
92
|
+
data?: T;
|
|
93
|
+
[key: string]: any;
|
|
94
|
+
};
|
|
95
|
+
message?: {
|
|
96
|
+
key: string;
|
|
97
|
+
[key: string]: any;
|
|
98
|
+
};
|
|
99
|
+
error?: any;
|
|
100
|
+
}
|
|
101
|
+
interface IFieldUpdateAndCheck<T = any, F = any, V = any> {
|
|
102
|
+
id?: string | number;
|
|
103
|
+
field?: F;
|
|
104
|
+
value?: V;
|
|
105
|
+
data?: T;
|
|
106
|
+
[key: string]: any;
|
|
107
|
+
}
|
|
108
|
+
interface Account {
|
|
109
|
+
id?: string | number;
|
|
110
|
+
username?: string;
|
|
111
|
+
password?: string;
|
|
112
|
+
email?: string;
|
|
113
|
+
status?: string;
|
|
114
|
+
[key: string]: any;
|
|
115
|
+
}
|
|
116
|
+
interface Post {
|
|
117
|
+
id?: string | number;
|
|
118
|
+
title?: string;
|
|
119
|
+
content?: string;
|
|
120
|
+
createdAt?: number;
|
|
121
|
+
[key: string]: any;
|
|
122
|
+
}
|
|
123
|
+
interface AppSettings {
|
|
124
|
+
[key: string]: any;
|
|
125
|
+
}
|
|
126
|
+
interface ISetConfigPagination {
|
|
127
|
+
page?: number;
|
|
128
|
+
limit?: number;
|
|
129
|
+
total?: number;
|
|
130
|
+
[key: string]: any;
|
|
131
|
+
}
|
|
132
|
+
type ITaskName = string;
|
|
133
|
+
|
|
134
|
+
interface IActionUiUtilBy {
|
|
135
|
+
action?: string;
|
|
136
|
+
[key: string]: any;
|
|
137
|
+
}
|
|
138
|
+
interface IPayloadStartAction {
|
|
139
|
+
action?: string;
|
|
140
|
+
[key: string]: any;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
interface Proxy {
|
|
144
|
+
id?: string;
|
|
145
|
+
host?: string;
|
|
146
|
+
port?: number;
|
|
147
|
+
username?: string;
|
|
148
|
+
password?: string;
|
|
149
|
+
protocol?: string;
|
|
150
|
+
provider?: string;
|
|
151
|
+
[key: string]: any;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interface IPayloadRemoveProxy {
|
|
155
|
+
ids: string[];
|
|
156
|
+
}
|
|
157
|
+
interface IPayloadService {
|
|
158
|
+
updateByClipboard?: UseMutateFunction<IMainResponse<string[]>, Error, IFieldUpdateAndCheck<Account, string[], keyof Account>, unknown>;
|
|
159
|
+
removeFieldBy?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Account, Array<keyof Account>, string[]>, unknown>;
|
|
160
|
+
copyByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Account, string, string[]>, unknown>;
|
|
161
|
+
actionBy?: UseMutateFunction<IMainResponse<string[]>, Error, IFieldUpdateAndCheck<Account, IActionUiUtilBy, string[]>, unknown>;
|
|
162
|
+
updateAccountByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Account, Partial<Account>, string[]>, unknown>;
|
|
163
|
+
deleteProxy?: UseMutateFunction<IMainResponse<boolean>, Error, IPayloadRemoveProxy, unknown>;
|
|
164
|
+
removePostByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Post, undefined, string[]>, unknown>;
|
|
165
|
+
startAction?: UseMutateFunction<IMainResponse<boolean>, Error, IPayloadStartAction, unknown>;
|
|
166
|
+
updateSettings?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<AppSettings, object, boolean>, unknown>;
|
|
167
|
+
useCopyProxyByField?: UseMutateFunction<IMainResponse<boolean>, Error, IFieldUpdateAndCheck<Proxy, string, string[]>[], unknown>;
|
|
168
|
+
exportLinkSuccess?: UseMutateFunction<IMainResponse<boolean>, Error, ITaskName, unknown>;
|
|
169
|
+
setAction?: Dispatch<SetStateAction<ITaskName>>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
type IDispatchState<T> = Dispatch<SetStateAction<T>>;
|
|
173
|
+
|
|
174
|
+
interface IExpandValue extends IPayloadService {
|
|
175
|
+
t?: TFunction<any, any>;
|
|
176
|
+
setConfigSearch?: IDispatchState<ISetConfigPagination>;
|
|
177
|
+
setSelectedRecords?: Dispatch<ReadonlySet<string>>;
|
|
178
|
+
setIsShowEdit?: Dispatch<SetStateAction<boolean>>;
|
|
179
|
+
setIsOpenEditContent?: Dispatch<SetStateAction<boolean>>;
|
|
180
|
+
setIsCopy?: Dispatch<SetStateAction<boolean>>;
|
|
181
|
+
setIsChangeCate?: Dispatch<SetStateAction<boolean>>;
|
|
182
|
+
setIsBackup?: Dispatch<SetStateAction<boolean>>;
|
|
183
|
+
}
|
|
184
|
+
type configContextMenuType = {
|
|
185
|
+
Icon: (prop?: any) => ReactNode;
|
|
186
|
+
action: string;
|
|
187
|
+
onClick?: (value: string[], expandValue: IExpandValue) => void;
|
|
188
|
+
children?: configContextMenuType[];
|
|
189
|
+
};
|
|
190
|
+
interface RenderContextMenuProps {
|
|
191
|
+
renderData?: configContextMenuType[];
|
|
192
|
+
valueClickItem?: any;
|
|
193
|
+
expandValue?: IExpandValue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
interface TableStyleWapperProps {
|
|
197
|
+
children?: ReactNode;
|
|
198
|
+
contextMenuProps?: Omit<ContextMenuProps, 'selector' | 'children'> & {
|
|
199
|
+
selector?: string;
|
|
200
|
+
};
|
|
201
|
+
renderContext?: RenderContextMenuProps;
|
|
202
|
+
clsTablecustom?: string;
|
|
203
|
+
idWapper?: string;
|
|
204
|
+
}
|
|
205
|
+
interface TableStyleContextMenuWapperComponent extends FC<TableStyleWapperProps> {
|
|
206
|
+
getIdFromOutside?: (externalId?: string) => string;
|
|
207
|
+
}
|
|
208
|
+
declare const TableStyleContextMenuWapper: TableStyleContextMenuWapperComponent;
|
|
209
|
+
|
|
79
210
|
interface IPaginationParams {
|
|
80
211
|
pageSize?: number;
|
|
81
212
|
page?: number;
|
|
82
213
|
}
|
|
83
214
|
type Maybe<T> = T | undefined | null;
|
|
84
215
|
|
|
85
|
-
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, ReactTableGridCustomPaginationClient, type TColumnsTable, useShowHideColumn };
|
|
216
|
+
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, ReactTableGridCustomPaginationClient, type TColumnsTable, TableStyleContextMenuWapper, type TableStyleWapperProps, useShowHideColumn };
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ReactTableGridCustom: () => ReactTableGridCustom,
|
|
34
34
|
ReactTableGridCustomPaginationClient: () => ReactTableGridCustomPaginationClient,
|
|
35
|
+
TableStyleContextMenuWapper: () => TableStyleContextMenuWapper,
|
|
35
36
|
useShowHideColumn: () => useShowHideColumn
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -527,9 +528,265 @@ var ReactTableGridCustomPaginationClientInner = ({
|
|
|
527
528
|
var ReactTableGridCustomPaginationClient = (0, import_react5.memo)(
|
|
528
529
|
ReactTableGridCustomPaginationClientInner
|
|
529
530
|
);
|
|
531
|
+
|
|
532
|
+
// src/component/ui/Table/TableStyleContextWapper.tsx
|
|
533
|
+
var import_react10 = require("react");
|
|
534
|
+
|
|
535
|
+
// src/component/ui/ContextMenu/ContextMenu.tsx
|
|
536
|
+
var import_react6 = require("react");
|
|
537
|
+
var import_react_dom = require("react-dom");
|
|
538
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
539
|
+
var ContextMenu = ({ selector, children, zIndex = 40 }) => {
|
|
540
|
+
const menuRef = (0, import_react6.useRef)(null);
|
|
541
|
+
const [mounted, setMounted] = (0, import_react6.useState)(false);
|
|
542
|
+
(0, import_react6.useEffect)(() => {
|
|
543
|
+
setMounted(true);
|
|
544
|
+
}, []);
|
|
545
|
+
const closeMenu = (0, import_react6.useCallback)(() => {
|
|
546
|
+
if (!mounted || typeof document === "undefined") return;
|
|
547
|
+
const contextMenuElem = menuRef.current;
|
|
548
|
+
const elementParent = document.querySelector(selector);
|
|
549
|
+
if (contextMenuElem == null ? void 0 : contextMenuElem.classList.contains("shadow-menu")) {
|
|
550
|
+
contextMenuElem.classList.remove("shadow-menu");
|
|
551
|
+
contextMenuElem.style.opacity = "0";
|
|
552
|
+
contextMenuElem.style.visibility = "hidden";
|
|
553
|
+
}
|
|
554
|
+
elementParent == null ? void 0 : elementParent.style.removeProperty("overflow");
|
|
555
|
+
}, [mounted, selector]);
|
|
556
|
+
(0, import_react6.useEffect)(() => {
|
|
557
|
+
if (!mounted || typeof document === "undefined" || typeof window === "undefined") return;
|
|
558
|
+
const elementParent = document.querySelector(selector);
|
|
559
|
+
if (!elementParent) return;
|
|
560
|
+
const clickMenu = (e) => {
|
|
561
|
+
e.preventDefault();
|
|
562
|
+
const contextMenuElem = menuRef.current;
|
|
563
|
+
if (!contextMenuElem) return;
|
|
564
|
+
contextMenuElem.style.opacity = "1";
|
|
565
|
+
contextMenuElem.style.visibility = "visible";
|
|
566
|
+
const { width, height } = contextMenuElem.getBoundingClientRect();
|
|
567
|
+
elementParent.style.overflow = "hidden";
|
|
568
|
+
const maxWidth = window.innerWidth;
|
|
569
|
+
const maxHeight = window.innerHeight;
|
|
570
|
+
const isLeft = maxWidth - e.clientX >= width;
|
|
571
|
+
const showTop = height + e.clientY <= maxHeight;
|
|
572
|
+
const showBottom = e.clientY - height >= 0;
|
|
573
|
+
const styleOrigin = { x: "left", y: "top" };
|
|
574
|
+
contextMenuElem.style.left = isLeft ? `${e.clientX}px` : `${e.clientX - width}px`;
|
|
575
|
+
styleOrigin.x = isLeft ? "left" : "right";
|
|
576
|
+
if (showTop) {
|
|
577
|
+
contextMenuElem.style.top = `${e.clientY}px`;
|
|
578
|
+
styleOrigin.y = "top";
|
|
579
|
+
} else if (showBottom) {
|
|
580
|
+
contextMenuElem.style.top = `${e.clientY - height}px`;
|
|
581
|
+
styleOrigin.y = "bottom";
|
|
582
|
+
} else {
|
|
583
|
+
let top = e.clientY - height / 2;
|
|
584
|
+
if (top < 0) top = 0;
|
|
585
|
+
if (top + height > maxHeight) top = maxHeight - height;
|
|
586
|
+
contextMenuElem.style.top = `${top}px`;
|
|
587
|
+
styleOrigin.y = "center";
|
|
588
|
+
}
|
|
589
|
+
contextMenuElem.style.transformOrigin = `${styleOrigin.y} ${styleOrigin.x}`;
|
|
590
|
+
contextMenuElem.classList.add("shadow-menu");
|
|
591
|
+
};
|
|
592
|
+
elementParent.addEventListener("contextmenu", clickMenu);
|
|
593
|
+
window.addEventListener("click", closeMenu);
|
|
594
|
+
return () => {
|
|
595
|
+
elementParent.removeEventListener("contextmenu", clickMenu);
|
|
596
|
+
window.removeEventListener("click", closeMenu);
|
|
597
|
+
};
|
|
598
|
+
}, [mounted, selector, closeMenu]);
|
|
599
|
+
if (!mounted || typeof document === "undefined") return null;
|
|
600
|
+
return (0, import_react_dom.createPortal)(
|
|
601
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
602
|
+
"div",
|
|
603
|
+
{
|
|
604
|
+
ref: menuRef,
|
|
605
|
+
className: "fixed w-fit",
|
|
606
|
+
style: { opacity: 0, visibility: "hidden", zIndex },
|
|
607
|
+
children
|
|
608
|
+
}
|
|
609
|
+
),
|
|
610
|
+
document.body
|
|
611
|
+
);
|
|
612
|
+
};
|
|
613
|
+
var ContextMenu_default = ContextMenu;
|
|
614
|
+
|
|
615
|
+
// src/component/ui/ContextMenu/RenderContextMenu.tsx
|
|
616
|
+
var import_react9 = require("react");
|
|
617
|
+
|
|
618
|
+
// src/component/ui/ContextMenu/ContextMenuItem.tsx
|
|
619
|
+
var import_react_i18next3 = require("react-i18next");
|
|
620
|
+
var import_md = require("react-icons/md");
|
|
621
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
622
|
+
var ContextMenuItem = ({
|
|
623
|
+
currentValue,
|
|
624
|
+
expandValue,
|
|
625
|
+
valueClickItem,
|
|
626
|
+
show,
|
|
627
|
+
isArrow
|
|
628
|
+
}) => {
|
|
629
|
+
const { t } = (0, import_react_i18next3.useTranslation)();
|
|
630
|
+
const Icon = currentValue.Icon;
|
|
631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
632
|
+
"div",
|
|
633
|
+
{
|
|
634
|
+
className: `cursor-pointer p-2 flex items-center space-x-2 relative ${show ? "bg-[#555] text-white" : "hover:bg-[#555] hover:text-white"}`,
|
|
635
|
+
onClick: () => {
|
|
636
|
+
var _a;
|
|
637
|
+
expandValue && valueClickItem && (currentValue == null ? void 0 : currentValue.onClick) && ((_a = currentValue == null ? void 0 : currentValue.onClick) == null ? void 0 : _a.call(currentValue, valueClickItem, expandValue));
|
|
638
|
+
},
|
|
639
|
+
children: [
|
|
640
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { size: 20 }),
|
|
641
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm flex-1", children: t(`${currentValue.action}`) }),
|
|
642
|
+
isArrow && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_md.MdKeyboardArrowRight, { size: 20 })
|
|
643
|
+
]
|
|
644
|
+
}
|
|
645
|
+
);
|
|
646
|
+
};
|
|
647
|
+
var ContextMenuItem_default = ContextMenuItem;
|
|
648
|
+
|
|
649
|
+
// src/component/ui/ContextMenu/DropdownContextChild.tsx
|
|
650
|
+
var import_react7 = __toESM(require("@tippyjs/react"));
|
|
651
|
+
var import_react8 = require("react");
|
|
652
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
653
|
+
var DropdownContextChild = ({ button, children, ...rest }) => {
|
|
654
|
+
const id = (0, import_react8.useId)();
|
|
655
|
+
const instanceRef = (0, import_react8.useRef)(null);
|
|
656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
657
|
+
import_react7.default,
|
|
658
|
+
{
|
|
659
|
+
theme: "drop-down",
|
|
660
|
+
className: "!bg-transparent !text-inherit !border-r-0 [&>*]:!p-0",
|
|
661
|
+
appendTo: document.body,
|
|
662
|
+
arrow: false,
|
|
663
|
+
placement: "auto",
|
|
664
|
+
interactive: true,
|
|
665
|
+
allowHTML: true,
|
|
666
|
+
content: children,
|
|
667
|
+
...rest,
|
|
668
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
669
|
+
"div",
|
|
670
|
+
{
|
|
671
|
+
id: `div-${id}`,
|
|
672
|
+
onClick: () => {
|
|
673
|
+
var _a;
|
|
674
|
+
(_a = instanceRef == null ? void 0 : instanceRef.current) == null ? void 0 : _a.show();
|
|
675
|
+
},
|
|
676
|
+
children: button
|
|
677
|
+
}
|
|
678
|
+
)
|
|
679
|
+
}
|
|
680
|
+
);
|
|
681
|
+
};
|
|
682
|
+
var DropdownContextChild_default = DropdownContextChild;
|
|
683
|
+
|
|
684
|
+
// src/component/ui/ContextMenu/RenderContextMenu.tsx
|
|
685
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
686
|
+
var ContextMenuItemWrapper = ({
|
|
687
|
+
menuAction,
|
|
688
|
+
valueClickItem,
|
|
689
|
+
expandValue
|
|
690
|
+
}) => {
|
|
691
|
+
const [isShow, setIsShow] = (0, import_react9.useState)(false);
|
|
692
|
+
if (!menuAction.children) {
|
|
693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
694
|
+
ContextMenuItem_default,
|
|
695
|
+
{
|
|
696
|
+
currentValue: menuAction,
|
|
697
|
+
expandValue,
|
|
698
|
+
valueClickItem
|
|
699
|
+
}
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
703
|
+
DropdownContextChild_default,
|
|
704
|
+
{
|
|
705
|
+
appendTo: "parent",
|
|
706
|
+
placement: "right",
|
|
707
|
+
offset: [0, 5],
|
|
708
|
+
onShow: () => setIsShow(true),
|
|
709
|
+
onHide: () => setIsShow(false),
|
|
710
|
+
button: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
711
|
+
ContextMenuItem_default,
|
|
712
|
+
{
|
|
713
|
+
currentValue: menuAction,
|
|
714
|
+
expandValue,
|
|
715
|
+
valueClickItem,
|
|
716
|
+
show: isShow,
|
|
717
|
+
isArrow: true
|
|
718
|
+
}
|
|
719
|
+
),
|
|
720
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "dropdown-context-child absolute -top-[20px] -left-1", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
721
|
+
RenderContextMenu,
|
|
722
|
+
{
|
|
723
|
+
renderData: menuAction.children,
|
|
724
|
+
expandValue,
|
|
725
|
+
valueClickItem
|
|
726
|
+
}
|
|
727
|
+
) })
|
|
728
|
+
}
|
|
729
|
+
);
|
|
730
|
+
};
|
|
731
|
+
var RenderContextMenu = ({
|
|
732
|
+
renderData,
|
|
733
|
+
valueClickItem,
|
|
734
|
+
expandValue = {}
|
|
735
|
+
}) => {
|
|
736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "bg-white shadow-submenu p-1 min-w-[250px] border", children: renderData == null ? void 0 : renderData.map((menuAction, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
737
|
+
ContextMenuItemWrapper,
|
|
738
|
+
{
|
|
739
|
+
menuAction,
|
|
740
|
+
expandValue,
|
|
741
|
+
valueClickItem
|
|
742
|
+
}
|
|
743
|
+
) }, index)) });
|
|
744
|
+
};
|
|
745
|
+
var RenderContextMenu_default = RenderContextMenu;
|
|
746
|
+
|
|
747
|
+
// src/component/ui/Table/TableStyleContextWapper.tsx
|
|
748
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
749
|
+
var isClient = typeof window !== "undefined";
|
|
750
|
+
var TableStyleContextWapper = ({
|
|
751
|
+
children,
|
|
752
|
+
contextMenuProps,
|
|
753
|
+
clsTablecustom,
|
|
754
|
+
renderContext,
|
|
755
|
+
idWapper: externalId
|
|
756
|
+
}) => {
|
|
757
|
+
if (!isClient) {
|
|
758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children });
|
|
759
|
+
}
|
|
760
|
+
const idWapper = externalId != null ? externalId : (0, import_react10.useId)();
|
|
761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
762
|
+
"div",
|
|
763
|
+
{
|
|
764
|
+
id: `wapper_menu_context-${idWapper}`,
|
|
765
|
+
className: `border border-[#dedede] rounded-xl overflow-hidden bg-white flex-1 h-full flex flex-col min-h-[360px] ${clsTablecustom != null ? clsTablecustom : ""}`,
|
|
766
|
+
children: [
|
|
767
|
+
(renderContext == null ? void 0 : renderContext.renderData) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
768
|
+
ContextMenu_default,
|
|
769
|
+
{
|
|
770
|
+
selector: `[id="wapper_menu_context-${idWapper}"] .rdg`,
|
|
771
|
+
...contextMenuProps,
|
|
772
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RenderContextMenu_default, { ...renderContext })
|
|
773
|
+
}
|
|
774
|
+
),
|
|
775
|
+
children
|
|
776
|
+
]
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
};
|
|
780
|
+
var TableStyleContextMenuWapper = (0, import_react10.memo)(
|
|
781
|
+
TableStyleContextWapper
|
|
782
|
+
);
|
|
783
|
+
TableStyleContextMenuWapper.getIdFromOutside = (externalId) => {
|
|
784
|
+
return `wapper_menu_context-${externalId != null ? externalId : "default-id"}`;
|
|
785
|
+
};
|
|
530
786
|
// Annotate the CommonJS export names for ESM import in node:
|
|
531
787
|
0 && (module.exports = {
|
|
532
788
|
ReactTableGridCustom,
|
|
533
789
|
ReactTableGridCustomPaginationClient,
|
|
790
|
+
TableStyleContextMenuWapper,
|
|
534
791
|
useShowHideColumn
|
|
535
792
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -504,8 +504,264 @@ var ReactTableGridCustomPaginationClientInner = ({
|
|
|
504
504
|
var ReactTableGridCustomPaginationClient = memo2(
|
|
505
505
|
ReactTableGridCustomPaginationClientInner
|
|
506
506
|
);
|
|
507
|
+
|
|
508
|
+
// src/component/ui/Table/TableStyleContextWapper.tsx
|
|
509
|
+
import { memo as memo3, useId as useId2 } from "react";
|
|
510
|
+
|
|
511
|
+
// src/component/ui/ContextMenu/ContextMenu.tsx
|
|
512
|
+
import { useCallback as useCallback4, useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
|
|
513
|
+
import { createPortal } from "react-dom";
|
|
514
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
515
|
+
var ContextMenu = ({ selector, children, zIndex = 40 }) => {
|
|
516
|
+
const menuRef = useRef2(null);
|
|
517
|
+
const [mounted, setMounted] = useState4(false);
|
|
518
|
+
useEffect2(() => {
|
|
519
|
+
setMounted(true);
|
|
520
|
+
}, []);
|
|
521
|
+
const closeMenu = useCallback4(() => {
|
|
522
|
+
if (!mounted || typeof document === "undefined") return;
|
|
523
|
+
const contextMenuElem = menuRef.current;
|
|
524
|
+
const elementParent = document.querySelector(selector);
|
|
525
|
+
if (contextMenuElem == null ? void 0 : contextMenuElem.classList.contains("shadow-menu")) {
|
|
526
|
+
contextMenuElem.classList.remove("shadow-menu");
|
|
527
|
+
contextMenuElem.style.opacity = "0";
|
|
528
|
+
contextMenuElem.style.visibility = "hidden";
|
|
529
|
+
}
|
|
530
|
+
elementParent == null ? void 0 : elementParent.style.removeProperty("overflow");
|
|
531
|
+
}, [mounted, selector]);
|
|
532
|
+
useEffect2(() => {
|
|
533
|
+
if (!mounted || typeof document === "undefined" || typeof window === "undefined") return;
|
|
534
|
+
const elementParent = document.querySelector(selector);
|
|
535
|
+
if (!elementParent) return;
|
|
536
|
+
const clickMenu = (e) => {
|
|
537
|
+
e.preventDefault();
|
|
538
|
+
const contextMenuElem = menuRef.current;
|
|
539
|
+
if (!contextMenuElem) return;
|
|
540
|
+
contextMenuElem.style.opacity = "1";
|
|
541
|
+
contextMenuElem.style.visibility = "visible";
|
|
542
|
+
const { width, height } = contextMenuElem.getBoundingClientRect();
|
|
543
|
+
elementParent.style.overflow = "hidden";
|
|
544
|
+
const maxWidth = window.innerWidth;
|
|
545
|
+
const maxHeight = window.innerHeight;
|
|
546
|
+
const isLeft = maxWidth - e.clientX >= width;
|
|
547
|
+
const showTop = height + e.clientY <= maxHeight;
|
|
548
|
+
const showBottom = e.clientY - height >= 0;
|
|
549
|
+
const styleOrigin = { x: "left", y: "top" };
|
|
550
|
+
contextMenuElem.style.left = isLeft ? `${e.clientX}px` : `${e.clientX - width}px`;
|
|
551
|
+
styleOrigin.x = isLeft ? "left" : "right";
|
|
552
|
+
if (showTop) {
|
|
553
|
+
contextMenuElem.style.top = `${e.clientY}px`;
|
|
554
|
+
styleOrigin.y = "top";
|
|
555
|
+
} else if (showBottom) {
|
|
556
|
+
contextMenuElem.style.top = `${e.clientY - height}px`;
|
|
557
|
+
styleOrigin.y = "bottom";
|
|
558
|
+
} else {
|
|
559
|
+
let top = e.clientY - height / 2;
|
|
560
|
+
if (top < 0) top = 0;
|
|
561
|
+
if (top + height > maxHeight) top = maxHeight - height;
|
|
562
|
+
contextMenuElem.style.top = `${top}px`;
|
|
563
|
+
styleOrigin.y = "center";
|
|
564
|
+
}
|
|
565
|
+
contextMenuElem.style.transformOrigin = `${styleOrigin.y} ${styleOrigin.x}`;
|
|
566
|
+
contextMenuElem.classList.add("shadow-menu");
|
|
567
|
+
};
|
|
568
|
+
elementParent.addEventListener("contextmenu", clickMenu);
|
|
569
|
+
window.addEventListener("click", closeMenu);
|
|
570
|
+
return () => {
|
|
571
|
+
elementParent.removeEventListener("contextmenu", clickMenu);
|
|
572
|
+
window.removeEventListener("click", closeMenu);
|
|
573
|
+
};
|
|
574
|
+
}, [mounted, selector, closeMenu]);
|
|
575
|
+
if (!mounted || typeof document === "undefined") return null;
|
|
576
|
+
return createPortal(
|
|
577
|
+
/* @__PURE__ */ jsx5(
|
|
578
|
+
"div",
|
|
579
|
+
{
|
|
580
|
+
ref: menuRef,
|
|
581
|
+
className: "fixed w-fit",
|
|
582
|
+
style: { opacity: 0, visibility: "hidden", zIndex },
|
|
583
|
+
children
|
|
584
|
+
}
|
|
585
|
+
),
|
|
586
|
+
document.body
|
|
587
|
+
);
|
|
588
|
+
};
|
|
589
|
+
var ContextMenu_default = ContextMenu;
|
|
590
|
+
|
|
591
|
+
// src/component/ui/ContextMenu/RenderContextMenu.tsx
|
|
592
|
+
import { Fragment as Fragment2, useState as useState5 } from "react";
|
|
593
|
+
|
|
594
|
+
// src/component/ui/ContextMenu/ContextMenuItem.tsx
|
|
595
|
+
import { useTranslation as useTranslation3 } from "react-i18next";
|
|
596
|
+
import { MdKeyboardArrowRight } from "react-icons/md";
|
|
597
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
598
|
+
var ContextMenuItem = ({
|
|
599
|
+
currentValue,
|
|
600
|
+
expandValue,
|
|
601
|
+
valueClickItem,
|
|
602
|
+
show,
|
|
603
|
+
isArrow
|
|
604
|
+
}) => {
|
|
605
|
+
const { t } = useTranslation3();
|
|
606
|
+
const Icon = currentValue.Icon;
|
|
607
|
+
return /* @__PURE__ */ jsxs3(
|
|
608
|
+
"div",
|
|
609
|
+
{
|
|
610
|
+
className: `cursor-pointer p-2 flex items-center space-x-2 relative ${show ? "bg-[#555] text-white" : "hover:bg-[#555] hover:text-white"}`,
|
|
611
|
+
onClick: () => {
|
|
612
|
+
var _a;
|
|
613
|
+
expandValue && valueClickItem && (currentValue == null ? void 0 : currentValue.onClick) && ((_a = currentValue == null ? void 0 : currentValue.onClick) == null ? void 0 : _a.call(currentValue, valueClickItem, expandValue));
|
|
614
|
+
},
|
|
615
|
+
children: [
|
|
616
|
+
/* @__PURE__ */ jsx6(Icon, { size: 20 }),
|
|
617
|
+
/* @__PURE__ */ jsx6("span", { className: "text-sm flex-1", children: t(`${currentValue.action}`) }),
|
|
618
|
+
isArrow && /* @__PURE__ */ jsx6(MdKeyboardArrowRight, { size: 20 })
|
|
619
|
+
]
|
|
620
|
+
}
|
|
621
|
+
);
|
|
622
|
+
};
|
|
623
|
+
var ContextMenuItem_default = ContextMenuItem;
|
|
624
|
+
|
|
625
|
+
// src/component/ui/ContextMenu/DropdownContextChild.tsx
|
|
626
|
+
import Tippy from "@tippyjs/react";
|
|
627
|
+
import { useId, useRef as useRef3 } from "react";
|
|
628
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
629
|
+
var DropdownContextChild = ({ button, children, ...rest }) => {
|
|
630
|
+
const id = useId();
|
|
631
|
+
const instanceRef = useRef3(null);
|
|
632
|
+
return /* @__PURE__ */ jsx7(
|
|
633
|
+
Tippy,
|
|
634
|
+
{
|
|
635
|
+
theme: "drop-down",
|
|
636
|
+
className: "!bg-transparent !text-inherit !border-r-0 [&>*]:!p-0",
|
|
637
|
+
appendTo: document.body,
|
|
638
|
+
arrow: false,
|
|
639
|
+
placement: "auto",
|
|
640
|
+
interactive: true,
|
|
641
|
+
allowHTML: true,
|
|
642
|
+
content: children,
|
|
643
|
+
...rest,
|
|
644
|
+
children: /* @__PURE__ */ jsx7(
|
|
645
|
+
"div",
|
|
646
|
+
{
|
|
647
|
+
id: `div-${id}`,
|
|
648
|
+
onClick: () => {
|
|
649
|
+
var _a;
|
|
650
|
+
(_a = instanceRef == null ? void 0 : instanceRef.current) == null ? void 0 : _a.show();
|
|
651
|
+
},
|
|
652
|
+
children: button
|
|
653
|
+
}
|
|
654
|
+
)
|
|
655
|
+
}
|
|
656
|
+
);
|
|
657
|
+
};
|
|
658
|
+
var DropdownContextChild_default = DropdownContextChild;
|
|
659
|
+
|
|
660
|
+
// src/component/ui/ContextMenu/RenderContextMenu.tsx
|
|
661
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
662
|
+
var ContextMenuItemWrapper = ({
|
|
663
|
+
menuAction,
|
|
664
|
+
valueClickItem,
|
|
665
|
+
expandValue
|
|
666
|
+
}) => {
|
|
667
|
+
const [isShow, setIsShow] = useState5(false);
|
|
668
|
+
if (!menuAction.children) {
|
|
669
|
+
return /* @__PURE__ */ jsx8(
|
|
670
|
+
ContextMenuItem_default,
|
|
671
|
+
{
|
|
672
|
+
currentValue: menuAction,
|
|
673
|
+
expandValue,
|
|
674
|
+
valueClickItem
|
|
675
|
+
}
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
return /* @__PURE__ */ jsx8(
|
|
679
|
+
DropdownContextChild_default,
|
|
680
|
+
{
|
|
681
|
+
appendTo: "parent",
|
|
682
|
+
placement: "right",
|
|
683
|
+
offset: [0, 5],
|
|
684
|
+
onShow: () => setIsShow(true),
|
|
685
|
+
onHide: () => setIsShow(false),
|
|
686
|
+
button: /* @__PURE__ */ jsx8(
|
|
687
|
+
ContextMenuItem_default,
|
|
688
|
+
{
|
|
689
|
+
currentValue: menuAction,
|
|
690
|
+
expandValue,
|
|
691
|
+
valueClickItem,
|
|
692
|
+
show: isShow,
|
|
693
|
+
isArrow: true
|
|
694
|
+
}
|
|
695
|
+
),
|
|
696
|
+
children: /* @__PURE__ */ jsx8("div", { className: "dropdown-context-child absolute -top-[20px] -left-1", children: /* @__PURE__ */ jsx8(
|
|
697
|
+
RenderContextMenu,
|
|
698
|
+
{
|
|
699
|
+
renderData: menuAction.children,
|
|
700
|
+
expandValue,
|
|
701
|
+
valueClickItem
|
|
702
|
+
}
|
|
703
|
+
) })
|
|
704
|
+
}
|
|
705
|
+
);
|
|
706
|
+
};
|
|
707
|
+
var RenderContextMenu = ({
|
|
708
|
+
renderData,
|
|
709
|
+
valueClickItem,
|
|
710
|
+
expandValue = {}
|
|
711
|
+
}) => {
|
|
712
|
+
return /* @__PURE__ */ jsx8("div", { className: "bg-white shadow-submenu p-1 min-w-[250px] border", children: renderData == null ? void 0 : renderData.map((menuAction, index) => /* @__PURE__ */ jsx8(Fragment2, { children: /* @__PURE__ */ jsx8(
|
|
713
|
+
ContextMenuItemWrapper,
|
|
714
|
+
{
|
|
715
|
+
menuAction,
|
|
716
|
+
expandValue,
|
|
717
|
+
valueClickItem
|
|
718
|
+
}
|
|
719
|
+
) }, index)) });
|
|
720
|
+
};
|
|
721
|
+
var RenderContextMenu_default = RenderContextMenu;
|
|
722
|
+
|
|
723
|
+
// src/component/ui/Table/TableStyleContextWapper.tsx
|
|
724
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
725
|
+
var isClient = typeof window !== "undefined";
|
|
726
|
+
var TableStyleContextWapper = ({
|
|
727
|
+
children,
|
|
728
|
+
contextMenuProps,
|
|
729
|
+
clsTablecustom,
|
|
730
|
+
renderContext,
|
|
731
|
+
idWapper: externalId
|
|
732
|
+
}) => {
|
|
733
|
+
if (!isClient) {
|
|
734
|
+
return /* @__PURE__ */ jsx9(Fragment3, { children });
|
|
735
|
+
}
|
|
736
|
+
const idWapper = externalId != null ? externalId : useId2();
|
|
737
|
+
return /* @__PURE__ */ jsxs4(
|
|
738
|
+
"div",
|
|
739
|
+
{
|
|
740
|
+
id: `wapper_menu_context-${idWapper}`,
|
|
741
|
+
className: `border border-[#dedede] rounded-xl overflow-hidden bg-white flex-1 h-full flex flex-col min-h-[360px] ${clsTablecustom != null ? clsTablecustom : ""}`,
|
|
742
|
+
children: [
|
|
743
|
+
(renderContext == null ? void 0 : renderContext.renderData) && /* @__PURE__ */ jsx9(
|
|
744
|
+
ContextMenu_default,
|
|
745
|
+
{
|
|
746
|
+
selector: `[id="wapper_menu_context-${idWapper}"] .rdg`,
|
|
747
|
+
...contextMenuProps,
|
|
748
|
+
children: /* @__PURE__ */ jsx9(RenderContextMenu_default, { ...renderContext })
|
|
749
|
+
}
|
|
750
|
+
),
|
|
751
|
+
children
|
|
752
|
+
]
|
|
753
|
+
}
|
|
754
|
+
);
|
|
755
|
+
};
|
|
756
|
+
var TableStyleContextMenuWapper = memo3(
|
|
757
|
+
TableStyleContextWapper
|
|
758
|
+
);
|
|
759
|
+
TableStyleContextMenuWapper.getIdFromOutside = (externalId) => {
|
|
760
|
+
return `wapper_menu_context-${externalId != null ? externalId : "default-id"}`;
|
|
761
|
+
};
|
|
507
762
|
export {
|
|
508
763
|
ReactTableGridCustom,
|
|
509
764
|
ReactTableGridCustomPaginationClient,
|
|
765
|
+
TableStyleContextMenuWapper,
|
|
510
766
|
useShowHideColumn
|
|
511
767
|
};
|