gbs-add-block 0.0.88 → 0.0.92
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 +2 -2
- package/package.json +1 -1
- package/source/components/datagrid/context/GridContext.tsx +10 -3
- package/source/components/datagrid/hooks/GridHooks.tsx +4 -0
- package/source/components/datagrid/layout/GridBody.tsx +4 -1
- package/source/components/datagrid/layout/GridPagination.tsx +4 -2
- package/source/components/datagrid/layout/GridToolbar.tsx +1 -1
- package/source/components/datagrid/type.ts +2 -1
- package/source/components/datepicker/index.tsx +65 -56
- package/source/globalStyle.ts +1 -1
- package/source/components/skeleton/index.tsx +0 -95
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GBS Building Blocks 2.0 (v0.0.
|
|
1
|
+
# GBS Building Blocks 2.0 (v0.0.92)
|
|
2
2
|
|
|
3
3
|
Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ Latest and upgraded version of GBS building blocks with headless UI and removed
|
|
|
6
6
|
|
|
7
7
|
For detailed documentation on usage and props, Please visit: [Building Block Documentation v2.0](https://blackmax-designs.gitbook.io/building-block-v2.0)
|
|
8
8
|
|
|
9
|
-
## What's New 🎉 (Ver 0.0.
|
|
9
|
+
## What's New 🎉 (Ver 0.0.92)
|
|
10
10
|
|
|
11
11
|
- Updated for bug fixes.
|
|
12
12
|
|
package/package.json
CHANGED
|
@@ -31,6 +31,7 @@ interface GridContextType {
|
|
|
31
31
|
goToEndPage: () => void;
|
|
32
32
|
goToFirstPage: () => void;
|
|
33
33
|
goToPage: (page: number) => void;
|
|
34
|
+
lazy: boolean;
|
|
34
35
|
|
|
35
36
|
// Search methods
|
|
36
37
|
handleSearchInput: (e: any) => void;
|
|
@@ -93,6 +94,7 @@ export const GridProvider: React.FC<{
|
|
|
93
94
|
rowChange = () => {},
|
|
94
95
|
pageStatus = () => {},
|
|
95
96
|
activeFilterArrayValue = [],
|
|
97
|
+
searchParamValue = () => {},
|
|
96
98
|
} = props;
|
|
97
99
|
|
|
98
100
|
// States Handling Grid
|
|
@@ -137,8 +139,8 @@ export const GridProvider: React.FC<{
|
|
|
137
139
|
|
|
138
140
|
// if lazy is true, then totalPages will be taken from pageSettings
|
|
139
141
|
const totalPages =
|
|
140
|
-
lazy && pageSettings.
|
|
141
|
-
? pageSettings.
|
|
142
|
+
lazy && pageSettings.totalCount
|
|
143
|
+
? Math.ceil(pageSettings.totalCount / pageSettings.pageNumber)
|
|
142
144
|
: Math.ceil(dataSource.length / pageSettings.pageNumber);
|
|
143
145
|
|
|
144
146
|
setTotalPages(totalPages);
|
|
@@ -163,6 +165,7 @@ export const GridProvider: React.FC<{
|
|
|
163
165
|
}
|
|
164
166
|
}, [columns]);
|
|
165
167
|
|
|
168
|
+
// Adds Search Column
|
|
166
169
|
useEffect(() => {
|
|
167
170
|
if (!columns || columns.length === 0) {
|
|
168
171
|
if (
|
|
@@ -233,9 +236,12 @@ export const GridProvider: React.FC<{
|
|
|
233
236
|
|
|
234
237
|
// *** Search Functions
|
|
235
238
|
const handleSearchInput = (e: any) => {
|
|
239
|
+
const searchValue = e.target.value;
|
|
240
|
+
if (searchParamValue) searchParamValue(searchValue);
|
|
241
|
+
|
|
236
242
|
if (!lazy) {
|
|
237
|
-
const searchValue = e.target.value;
|
|
238
243
|
setSearchParam(searchValue);
|
|
244
|
+
|
|
239
245
|
if (searchValue === "") {
|
|
240
246
|
setWorkingDataSource(
|
|
241
247
|
fallbackSourceData.length > 0 ? fallbackSourceData : dataSource
|
|
@@ -379,6 +385,7 @@ export const GridProvider: React.FC<{
|
|
|
379
385
|
goToEndPage,
|
|
380
386
|
goToFirstPage,
|
|
381
387
|
goToPage,
|
|
388
|
+
lazy,
|
|
382
389
|
|
|
383
390
|
// Search methods
|
|
384
391
|
handleSearchInput,
|
|
@@ -13,6 +13,8 @@ export const useGridPagination = () => {
|
|
|
13
13
|
nextPage,
|
|
14
14
|
goToEndPage,
|
|
15
15
|
workingDataSource,
|
|
16
|
+
lazy,
|
|
17
|
+
pageSettings,
|
|
16
18
|
} = useGridContext();
|
|
17
19
|
|
|
18
20
|
return {
|
|
@@ -26,6 +28,8 @@ export const useGridPagination = () => {
|
|
|
26
28
|
nextPage,
|
|
27
29
|
goToEndPage,
|
|
28
30
|
workingDataSource,
|
|
31
|
+
lazy,
|
|
32
|
+
pageSettings,
|
|
29
33
|
};
|
|
30
34
|
};
|
|
31
35
|
|
|
@@ -17,6 +17,7 @@ const GridBody = () => {
|
|
|
17
17
|
gridColumnStyle,
|
|
18
18
|
gridColumnStyleSelectAll,
|
|
19
19
|
rowChange,
|
|
20
|
+
lazy,
|
|
20
21
|
} = useGridContext();
|
|
21
22
|
|
|
22
23
|
const renderCell = (rowData: any, column: Column, rowIndex: number) => {
|
|
@@ -53,7 +54,9 @@ const GridBody = () => {
|
|
|
53
54
|
|
|
54
55
|
const displayStart = currentPage * pageSettings.pageNumber;
|
|
55
56
|
const displayEnd = displayStart + pageSettings.pageNumber;
|
|
56
|
-
const displayData =
|
|
57
|
+
const displayData = lazy
|
|
58
|
+
? workingDataSource
|
|
59
|
+
: workingDataSource.slice(displayStart, displayEnd);
|
|
57
60
|
|
|
58
61
|
return (
|
|
59
62
|
<div className="overflow-x-auto">
|
|
@@ -20,6 +20,8 @@ const Pagination = () => {
|
|
|
20
20
|
nextPage,
|
|
21
21
|
goToEndPage,
|
|
22
22
|
workingDataSource,
|
|
23
|
+
lazy,
|
|
24
|
+
pageSettings,
|
|
23
25
|
} = useGridPagination();
|
|
24
26
|
|
|
25
27
|
return (
|
|
@@ -96,8 +98,8 @@ const Pagination = () => {
|
|
|
96
98
|
</div>
|
|
97
99
|
|
|
98
100
|
<div className="flex text-xs">
|
|
99
|
-
{currentPage + 1} of {totalPages} pages (
|
|
100
|
-
items
|
|
101
|
+
{currentPage + 1} of {totalPages} pages (
|
|
102
|
+
{lazy ? pageSettings?.totalCount : workingDataSource.length}) items
|
|
101
103
|
</div>
|
|
102
104
|
</div>
|
|
103
105
|
);
|
|
@@ -33,7 +33,7 @@ const GridToolbar = () => {
|
|
|
33
33
|
<div className="flex">
|
|
34
34
|
<input
|
|
35
35
|
type="search"
|
|
36
|
-
|
|
36
|
+
defaultValue={searchParam}
|
|
37
37
|
onChange={handleSearchInput}
|
|
38
38
|
placeholder="Search..."
|
|
39
39
|
className="outline-none p-2 text-xs rounded-lg max-sm:hidden dark:bg-zinc-800 bg-zinc-200"
|
|
@@ -2,7 +2,7 @@ import { ChangeEvent } from "react";
|
|
|
2
2
|
|
|
3
3
|
interface PageSettingsProps {
|
|
4
4
|
pageNumber: number;
|
|
5
|
-
|
|
5
|
+
totalCount?: number;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
interface ActiveFilterArrayValue {
|
|
@@ -37,6 +37,7 @@ export type GridProps = {
|
|
|
37
37
|
rowChange?: any;
|
|
38
38
|
pageStatus?: any;
|
|
39
39
|
activeFilterArrayValue?: ActiveFilterArrayValue[] | any;
|
|
40
|
+
searchParamValue?: (value: string) => void;
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
interface GridColumn {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React, {
|
|
8
|
+
import React, { useRef } from "react";
|
|
9
9
|
import {
|
|
10
10
|
useDatePickerState,
|
|
11
11
|
useYearMonthNavigation,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
applyScrollbarStyles,
|
|
16
16
|
} from "@grampro/headless-helpers";
|
|
17
17
|
import Icon from "../icon/Icon";
|
|
18
|
-
import { calender, down,
|
|
18
|
+
import { calender, down, leftArrow, rightArrow, x } from "../icon/iconPaths";
|
|
19
19
|
import type { DatePickerProps } from "./types";
|
|
20
20
|
import { iconClass, popUp, primary } from "../globalStyle";
|
|
21
21
|
|
|
@@ -139,7 +139,7 @@ export const DatePicker = ({
|
|
|
139
139
|
type="button"
|
|
140
140
|
onClick={toggleDatepicker}
|
|
141
141
|
disabled={disabled}
|
|
142
|
-
className="flex items-center gap-2 w-full"
|
|
142
|
+
className="flex items-center gap-2 w-full cursor-pointer"
|
|
143
143
|
>
|
|
144
144
|
<Icon
|
|
145
145
|
dimensions={{ width: "20", height: "20" }}
|
|
@@ -147,9 +147,11 @@ export const DatePicker = ({
|
|
|
147
147
|
svgClass={iconClass["grey-common"]}
|
|
148
148
|
/>
|
|
149
149
|
<span className={!selectedDate ? "text-gray-400 text-sm" : ""}>
|
|
150
|
-
{selectedDate
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
{selectedDate ? (
|
|
151
|
+
<span className="text-sm">{selectedDate.toLocaleDateString("en-GB")}</span>
|
|
152
|
+
) : (
|
|
153
|
+
placeholder
|
|
154
|
+
)}
|
|
153
155
|
</span>
|
|
154
156
|
</button>
|
|
155
157
|
|
|
@@ -173,33 +175,6 @@ export const DatePicker = ({
|
|
|
173
175
|
{showDatepicker && !disabled && (
|
|
174
176
|
<div className={popUp["pop-up-style"]}>
|
|
175
177
|
<div className="flex justify-between items-center p-2">
|
|
176
|
-
<button
|
|
177
|
-
type="button"
|
|
178
|
-
onClick={prevMonth}
|
|
179
|
-
disabled={isAtYearLimit(
|
|
180
|
-
"prev",
|
|
181
|
-
currentMonth,
|
|
182
|
-
currentYear,
|
|
183
|
-
yearLimitStart,
|
|
184
|
-
yearLimitEnd
|
|
185
|
-
)}
|
|
186
|
-
className={`text-gray-500 hover:text-gray-700 w-8 h-8 rounded-full flex items-center justify-center hover:bg-gray-100 ${
|
|
187
|
-
isAtYearLimit(
|
|
188
|
-
"prev",
|
|
189
|
-
currentMonth,
|
|
190
|
-
currentYear,
|
|
191
|
-
yearLimitStart,
|
|
192
|
-
yearLimitEnd
|
|
193
|
-
)
|
|
194
|
-
? "opacity-50"
|
|
195
|
-
: ""
|
|
196
|
-
}`}
|
|
197
|
-
>
|
|
198
|
-
<Icon
|
|
199
|
-
elements={leftArrows}
|
|
200
|
-
svgClass={"stroke-black fill-none dark:stroke-white"}
|
|
201
|
-
/>
|
|
202
|
-
</button>
|
|
203
178
|
<div className="flex items-center space-x-2">
|
|
204
179
|
<span className="text-md font-semibold">
|
|
205
180
|
{new Date(currentYear, currentMonth).toLocaleString("default", {
|
|
@@ -215,36 +190,70 @@ export const DatePicker = ({
|
|
|
215
190
|
<Icon
|
|
216
191
|
elements={down}
|
|
217
192
|
svgClass={"stroke-black fill-none dark:stroke-white"}
|
|
193
|
+
dimensions={{ width: "20", height: "20" }}
|
|
218
194
|
/>
|
|
219
195
|
</button>
|
|
220
196
|
</div>
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
197
|
+
|
|
198
|
+
<div className="flex items-center space-x-2">
|
|
199
|
+
<button
|
|
200
|
+
type="button"
|
|
201
|
+
onClick={prevMonth}
|
|
202
|
+
disabled={isAtYearLimit(
|
|
203
|
+
"prev",
|
|
204
|
+
currentMonth,
|
|
205
|
+
currentYear,
|
|
206
|
+
yearLimitStart,
|
|
207
|
+
yearLimitEnd
|
|
208
|
+
)}
|
|
209
|
+
className={`text-gray-500 hover:text-gray-700 w-8 h-8 rounded-full flex items-center justify-center hover:bg-gray-100 ${
|
|
210
|
+
isAtYearLimit(
|
|
211
|
+
"prev",
|
|
212
|
+
currentMonth,
|
|
213
|
+
currentYear,
|
|
214
|
+
yearLimitStart,
|
|
215
|
+
yearLimitEnd
|
|
216
|
+
)
|
|
217
|
+
? "opacity-50"
|
|
218
|
+
: ""
|
|
219
|
+
}`}
|
|
220
|
+
>
|
|
221
|
+
<Icon
|
|
222
|
+
elements={leftArrow}
|
|
223
|
+
svgClass={"stroke-black fill-none dark:stroke-white"}
|
|
224
|
+
dimensions={{ width: "20", height: "20" }}
|
|
225
|
+
/>
|
|
226
|
+
</button>
|
|
227
|
+
|
|
228
|
+
<button
|
|
229
|
+
type="button"
|
|
230
|
+
onClick={nextMonth}
|
|
231
|
+
disabled={isAtYearLimit(
|
|
233
232
|
"next",
|
|
234
233
|
currentMonth,
|
|
235
234
|
currentYear,
|
|
236
235
|
yearLimitStart,
|
|
237
236
|
yearLimitEnd
|
|
238
|
-
)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
237
|
+
)}
|
|
238
|
+
className={`text-gray-500 hover:text-gray-700 w-8 h-8 rounded-full flex items-center justify-center hover:bg-gray-100 ${
|
|
239
|
+
isAtYearLimit(
|
|
240
|
+
"next",
|
|
241
|
+
currentMonth,
|
|
242
|
+
currentYear,
|
|
243
|
+
yearLimitStart,
|
|
244
|
+
yearLimitEnd
|
|
245
|
+
)
|
|
246
|
+
? "opacity-50"
|
|
247
|
+
: ""
|
|
248
|
+
}`}
|
|
249
|
+
>
|
|
250
|
+
<Icon
|
|
251
|
+
elements={rightArrow}
|
|
252
|
+
svgClass={"stroke-black fill-none dark:stroke-white"}
|
|
253
|
+
dimensions={{ width: "20", height: "20" }}
|
|
254
|
+
/>
|
|
255
|
+
</button>
|
|
256
|
+
</div>
|
|
248
257
|
</div>
|
|
249
258
|
{showYearMonthPicker ? (
|
|
250
259
|
<div className="flex p-2 h-[224px] scrollbar">
|
|
@@ -351,4 +360,4 @@ export const DatePicker = ({
|
|
|
351
360
|
)}
|
|
352
361
|
</div>
|
|
353
362
|
);
|
|
354
|
-
};
|
|
363
|
+
};
|
package/source/globalStyle.ts
CHANGED
|
@@ -9,7 +9,7 @@ export const popUp = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export const iconClass = {
|
|
12
|
-
"grey-common": "h-4 w-4 stroke-gray-500 fill-none dark:stroke-
|
|
12
|
+
"grey-common": "h-4 w-4 stroke-gray-500 fill-none dark:stroke-white",
|
|
13
13
|
"error-icon": "h-4 w-4 stroke-red-500 fill-none dark:stroke-red-500",
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Grampro Business Services and affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import React, { useMemo, memo } from "react";
|
|
9
|
-
|
|
10
|
-
type SkeletonType = "text" | "circle" | "rectangle";
|
|
11
|
-
|
|
12
|
-
interface SkeletonProps {
|
|
13
|
-
type?: SkeletonType;
|
|
14
|
-
lines?: number;
|
|
15
|
-
height?: string | number;
|
|
16
|
-
width?: string | number;
|
|
17
|
-
className?: string;
|
|
18
|
-
style?: React.CSSProperties;
|
|
19
|
-
animationDuration?: number;
|
|
20
|
-
keyframes?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const Skeleton: React.FC<SkeletonProps> = memo(
|
|
24
|
-
({
|
|
25
|
-
type = "text",
|
|
26
|
-
lines = 1,
|
|
27
|
-
height,
|
|
28
|
-
width,
|
|
29
|
-
className = "",
|
|
30
|
-
style = {},
|
|
31
|
-
animationDuration = 1.5,
|
|
32
|
-
keyframes = `
|
|
33
|
-
@keyframes pulse {
|
|
34
|
-
0% { opacity: 0.6; }
|
|
35
|
-
50% { opacity: 1; }
|
|
36
|
-
100% { opacity: 0.6; }
|
|
37
|
-
}
|
|
38
|
-
`,
|
|
39
|
-
}) => {
|
|
40
|
-
const getStyle = useMemo(() => {
|
|
41
|
-
const baseStyle: React.CSSProperties = {
|
|
42
|
-
backgroundColor: "#e0e0e0",
|
|
43
|
-
borderRadius: "4px",
|
|
44
|
-
animation: `pulse ${animationDuration}s ease-in-out 0.5s infinite`,
|
|
45
|
-
width: width || "100%",
|
|
46
|
-
...style,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
switch (type) {
|
|
50
|
-
case "text":
|
|
51
|
-
return {
|
|
52
|
-
...baseStyle,
|
|
53
|
-
height: height || "16px",
|
|
54
|
-
marginBottom: "8px",
|
|
55
|
-
};
|
|
56
|
-
case "circle":
|
|
57
|
-
return {
|
|
58
|
-
...baseStyle,
|
|
59
|
-
height: height || "48px",
|
|
60
|
-
width: width || "48px",
|
|
61
|
-
borderRadius: "50%",
|
|
62
|
-
};
|
|
63
|
-
case "rectangle":
|
|
64
|
-
return {
|
|
65
|
-
...baseStyle,
|
|
66
|
-
height: height || "120px",
|
|
67
|
-
};
|
|
68
|
-
default:
|
|
69
|
-
return baseStyle;
|
|
70
|
-
}
|
|
71
|
-
}, [type, height, width, style, animationDuration]);
|
|
72
|
-
|
|
73
|
-
const renderLines = useMemo(() => {
|
|
74
|
-
if (type !== "text" || lines <= 1) return null;
|
|
75
|
-
|
|
76
|
-
return Array.from({ length: lines - 1 }, (_, index) => (
|
|
77
|
-
<div
|
|
78
|
-
key={index}
|
|
79
|
-
className={`skeleton-line ${className}`}
|
|
80
|
-
style={getStyle}
|
|
81
|
-
/>
|
|
82
|
-
));
|
|
83
|
-
}, [type, lines, className, getStyle]);
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<div className="skeleton-wrapper" style={{ width: "100%" }}>
|
|
87
|
-
<style>{keyframes}</style>
|
|
88
|
-
<div className={`skeleton ${className}`} style={getStyle} />
|
|
89
|
-
{renderLines}
|
|
90
|
-
</div>
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
Skeleton.displayName = "Skeleton";
|