@megha-ui/react 1.3.102 → 1.3.104
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.
|
@@ -18,7 +18,7 @@ import { getTotalPages } from "./utils/pagination";
|
|
|
18
18
|
import { useSort } from "./hooks/useSort";
|
|
19
19
|
import { usePagination } from "./hooks/usePagination";
|
|
20
20
|
import { useBulkSelect } from "./hooks/useBulkSelect";
|
|
21
|
-
import { createRegexFromWildcard, isValidDateFormat } from "./utils/regexUtils";
|
|
21
|
+
import { createRegexFromWildcard, isValidDateFormat, matchSqlLikePattern, } from "./utils/regexUtils";
|
|
22
22
|
import { FiEye, FiShare, FiChevronsLeft, FiChevronsRight, } from "react-icons/fi";
|
|
23
23
|
import { MdFilterAltOff, MdGroupOff, MdSave, MdLayers, MdLayersClear, } from "react-icons/md";
|
|
24
24
|
import GlobalSearchChiProps from "./utils/globalSearchChips";
|
|
@@ -186,6 +186,9 @@ withCard = false, cardClassName, cardHeader, title, headerLeft, headerRight, sub
|
|
|
186
186
|
const regex = createRegexFromWildcard(query);
|
|
187
187
|
return regex.test(value);
|
|
188
188
|
}
|
|
189
|
+
if (query.includes("%") || query.includes("_")) {
|
|
190
|
+
return matchSqlLikePattern(query, value);
|
|
191
|
+
}
|
|
189
192
|
switch ((_c = searchQueries[column.key]) === null || _c === void 0 ? void 0 : _c.type) {
|
|
190
193
|
case "contains":
|
|
191
194
|
return value.toLowerCase().includes(query.toLowerCase());
|
|
@@ -255,7 +258,7 @@ withCard = false, cardClassName, cardHeader, title, headerLeft, headerRight, sub
|
|
|
255
258
|
: orData.length > 0
|
|
256
259
|
? orData.some((column) => {
|
|
257
260
|
var _a, _b, _c;
|
|
258
|
-
const query = (_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.text;
|
|
261
|
+
const query = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.text) || "";
|
|
259
262
|
const queryData = query.toLowerCase().split(",");
|
|
260
263
|
const value = item[column.key] && item[column.key].value
|
|
261
264
|
? (_b = item[column.key].value) === null || _b === void 0 ? void 0 : _b.toString()
|
|
@@ -264,6 +267,9 @@ withCard = false, cardClassName, cardHeader, title, headerLeft, headerRight, sub
|
|
|
264
267
|
const regex = createRegexFromWildcard(query);
|
|
265
268
|
return regex.test(value);
|
|
266
269
|
}
|
|
270
|
+
if (query.includes("%") || query.includes("_")) {
|
|
271
|
+
return matchSqlLikePattern(query, value);
|
|
272
|
+
}
|
|
267
273
|
switch ((_c = searchQueries[column.key]) === null || _c === void 0 ? void 0 : _c.type) {
|
|
268
274
|
case "contains":
|
|
269
275
|
return value.toLowerCase().includes(query.toLowerCase());
|
|
@@ -160,41 +160,41 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
160
160
|
};
|
|
161
161
|
const menuOptions = [{ label: "Group by", groupBy: setGroupBy }];
|
|
162
162
|
const searchOptions = [
|
|
163
|
-
{ label: "
|
|
163
|
+
{ label: "∈", value: "contains", action: handleSearchOptionSelect },
|
|
164
164
|
{
|
|
165
|
-
label: "
|
|
165
|
+
label: "∉",
|
|
166
166
|
value: "doesNotContain",
|
|
167
167
|
action: handleSearchOptionSelect,
|
|
168
168
|
},
|
|
169
|
-
{ label: "
|
|
169
|
+
{ label: "=", value: "equals", action: handleSearchOptionSelect },
|
|
170
170
|
{
|
|
171
|
-
label: "
|
|
171
|
+
label: "≠",
|
|
172
172
|
value: "doesNotEqual",
|
|
173
173
|
action: handleSearchOptionSelect,
|
|
174
174
|
},
|
|
175
|
-
{ label: "
|
|
176
|
-
{ label: "
|
|
177
|
-
{ label: "
|
|
175
|
+
{ label: ">", value: "after", action: handleSearchOptionSelect },
|
|
176
|
+
{ label: "<", value: "before", action: handleSearchOptionSelect },
|
|
177
|
+
{ label: ">", value: "gt", action: handleSearchOptionSelect },
|
|
178
178
|
{
|
|
179
|
-
label: "
|
|
179
|
+
label: "≥",
|
|
180
180
|
value: "gte",
|
|
181
181
|
action: handleSearchOptionSelect,
|
|
182
182
|
},
|
|
183
|
-
{ label: "
|
|
183
|
+
{ label: "<", value: "lt", action: handleSearchOptionSelect },
|
|
184
184
|
{
|
|
185
|
-
label: "
|
|
185
|
+
label: "≤",
|
|
186
186
|
value: "lte",
|
|
187
187
|
action: handleSearchOptionSelect,
|
|
188
188
|
},
|
|
189
|
-
{ label: "
|
|
189
|
+
{ label: "↔︎", value: "between", action: handleSearchOptionSelect },
|
|
190
190
|
{
|
|
191
|
-
label: "
|
|
191
|
+
label: "⇢",
|
|
192
192
|
value: "startsWith",
|
|
193
193
|
action: handleSearchOptionSelect,
|
|
194
194
|
},
|
|
195
|
-
{ label: "
|
|
196
|
-
{ label: "
|
|
197
|
-
{ label: "
|
|
195
|
+
{ label: "⇠", value: "endsWith", action: handleSearchOptionSelect },
|
|
196
|
+
{ label: "Ø", value: "blank", action: handleSearchOptionSelect },
|
|
197
|
+
{ label: "≠Ø", value: "notBlank", action: handleSearchOptionSelect },
|
|
198
198
|
];
|
|
199
199
|
const textTypeSearch = [
|
|
200
200
|
"contains",
|
|
@@ -402,17 +402,36 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
402
402
|
var _a;
|
|
403
403
|
return setActiveSearchColumn(((_a = headerColumns.find((column) => column.key === _groupBy)) === null || _a === void 0 ? void 0 : _a.key) || "");
|
|
404
404
|
}, onChange: (e) => {
|
|
405
|
-
var _a, _b
|
|
406
|
-
|
|
405
|
+
var _a, _b;
|
|
406
|
+
const currentKey = ((_a = headerColumns.find((column) => column.key === _groupBy)) === null || _a === void 0 ? void 0 : _a.key) || "";
|
|
407
|
+
const input = e.target.value;
|
|
408
|
+
let searchType = ((_b = searchQueries[currentKey]) === null || _b === void 0 ? void 0 : _b.type) ||
|
|
407
409
|
defaultSearchOperation ||
|
|
408
410
|
"contains";
|
|
409
|
-
if (
|
|
411
|
+
if (input.includes("to")) {
|
|
410
412
|
searchType = "between";
|
|
411
413
|
}
|
|
412
414
|
else if (searchType === "between") {
|
|
413
415
|
searchType = "contains";
|
|
414
416
|
}
|
|
415
|
-
|
|
417
|
+
else if (input.includes("%")) {
|
|
418
|
+
const startsWithPercent = input.startsWith("%");
|
|
419
|
+
const endsWithPercent = input.endsWith("%");
|
|
420
|
+
if (startsWithPercent &&
|
|
421
|
+
endsWithPercent &&
|
|
422
|
+
input.length > 2) {
|
|
423
|
+
searchType = "contains";
|
|
424
|
+
}
|
|
425
|
+
else if (!startsWithPercent &&
|
|
426
|
+
endsWithPercent) {
|
|
427
|
+
searchType = "startsWith";
|
|
428
|
+
}
|
|
429
|
+
else if (startsWithPercent &&
|
|
430
|
+
!endsWithPercent) {
|
|
431
|
+
searchType = "endsWith";
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
onSearch(currentKey, input, searchType);
|
|
416
435
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
417
436
|
background: ((_r = headerColumns.find((column) => column.key === _groupBy)) === null || _r === void 0 ? void 0 : _r.search)
|
|
418
437
|
? "var(--background)"
|
|
@@ -528,17 +547,36 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
528
547
|
var _a;
|
|
529
548
|
return setActiveSearchColumn(((_a = headerColumns.find((column) => column.key === _groupBy)) === null || _a === void 0 ? void 0 : _a.key) || "");
|
|
530
549
|
}, onChange: (e) => {
|
|
531
|
-
var _a, _b
|
|
532
|
-
|
|
550
|
+
var _a, _b;
|
|
551
|
+
const currentKey = ((_a = headerColumns.find((column) => column.key === _groupBy)) === null || _a === void 0 ? void 0 : _a.key) || "";
|
|
552
|
+
const input = e.target.value;
|
|
553
|
+
let searchType = ((_b = searchQueries[currentKey]) === null || _b === void 0 ? void 0 : _b.type) ||
|
|
533
554
|
defaultSearchOperation ||
|
|
534
555
|
"contains";
|
|
535
|
-
if (
|
|
556
|
+
if (input.includes("to")) {
|
|
536
557
|
searchType = "between";
|
|
537
558
|
}
|
|
538
559
|
else if (searchType === "between") {
|
|
539
560
|
searchType = "contains";
|
|
540
561
|
}
|
|
541
|
-
|
|
562
|
+
else if (input.includes("%")) {
|
|
563
|
+
const startsWithPercent = input.startsWith("%");
|
|
564
|
+
const endsWithPercent = input.endsWith("%");
|
|
565
|
+
if (startsWithPercent &&
|
|
566
|
+
endsWithPercent &&
|
|
567
|
+
input.length > 2) {
|
|
568
|
+
searchType = "contains";
|
|
569
|
+
}
|
|
570
|
+
else if (!startsWithPercent &&
|
|
571
|
+
endsWithPercent) {
|
|
572
|
+
searchType = "startsWith";
|
|
573
|
+
}
|
|
574
|
+
else if (startsWithPercent &&
|
|
575
|
+
!endsWithPercent) {
|
|
576
|
+
searchType = "endsWith";
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
onSearch(currentKey, input, searchType);
|
|
542
580
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
543
581
|
background: ((_24 = headerColumns.find((column) => column.key === _groupBy)) === null || _24 === void 0 ? void 0 : _24.search)
|
|
544
582
|
? "var(--background)"
|
|
@@ -654,17 +692,35 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
654
692
|
var _a;
|
|
655
693
|
return setActiveSearchColumn(((_a = headerColumns.find((column) => column.key === _groupBy)) === null || _a === void 0 ? void 0 : _a.key) || "");
|
|
656
694
|
}, onChange: (e) => {
|
|
657
|
-
var _a, _b
|
|
658
|
-
|
|
695
|
+
var _a, _b;
|
|
696
|
+
const currentKey = ((_a = headerColumns.find((column) => column.key === _groupBy)) === null || _a === void 0 ? void 0 : _a.key) || "";
|
|
697
|
+
const input = e.target.value;
|
|
698
|
+
let searchType = ((_b = searchQueries[currentKey]) === null || _b === void 0 ? void 0 : _b.type) ||
|
|
659
699
|
defaultSearchOperation ||
|
|
660
700
|
"contains";
|
|
661
|
-
if (
|
|
701
|
+
if (input.includes("to")) {
|
|
662
702
|
searchType = "between";
|
|
663
703
|
}
|
|
664
704
|
else if (searchType === "between") {
|
|
665
705
|
searchType = "contains";
|
|
666
706
|
}
|
|
667
|
-
|
|
707
|
+
else if (input.includes("%")) {
|
|
708
|
+
const startsWithPercent = input.startsWith("%");
|
|
709
|
+
const endsWithPercent = input.endsWith("%");
|
|
710
|
+
if (startsWithPercent &&
|
|
711
|
+
endsWithPercent &&
|
|
712
|
+
input.length > 2) {
|
|
713
|
+
searchType = "contains";
|
|
714
|
+
}
|
|
715
|
+
else if (!startsWithPercent && endsWithPercent) {
|
|
716
|
+
searchType = "startsWith";
|
|
717
|
+
}
|
|
718
|
+
else if (startsWithPercent &&
|
|
719
|
+
!endsWithPercent) {
|
|
720
|
+
searchType = "endsWith";
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
onSearch(currentKey, input, searchType);
|
|
668
724
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
669
725
|
background: ((_57 = headerColumns.find((column) => column.key === _groupBy)) === null || _57 === void 0 ? void 0 : _57.search)
|
|
670
726
|
? "var(--background)"
|
|
@@ -826,16 +882,34 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
826
882
|
alignItems: "center",
|
|
827
883
|
}, children: [_jsx(TextInput, { onFocus: () => setActiveSearchColumn(column.key), onChange: (e) => {
|
|
828
884
|
var _a;
|
|
885
|
+
const input = e.target.value;
|
|
829
886
|
let searchType = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.type) ||
|
|
830
887
|
defaultSearchOperation ||
|
|
831
888
|
"contains";
|
|
832
|
-
if (
|
|
889
|
+
if (input.includes("to")) {
|
|
833
890
|
searchType = "between";
|
|
834
891
|
}
|
|
835
892
|
else if (searchType === "between") {
|
|
836
893
|
searchType = "contains";
|
|
837
894
|
}
|
|
838
|
-
|
|
895
|
+
else if (input.includes("%")) {
|
|
896
|
+
const startsWithPercent = input.startsWith("%");
|
|
897
|
+
const endsWithPercent = input.endsWith("%");
|
|
898
|
+
if (startsWithPercent &&
|
|
899
|
+
endsWithPercent &&
|
|
900
|
+
input.length > 2) {
|
|
901
|
+
searchType = "contains";
|
|
902
|
+
}
|
|
903
|
+
else if (!startsWithPercent &&
|
|
904
|
+
endsWithPercent) {
|
|
905
|
+
searchType = "startsWith";
|
|
906
|
+
}
|
|
907
|
+
else if (startsWithPercent &&
|
|
908
|
+
!endsWithPercent) {
|
|
909
|
+
searchType = "endsWith";
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
onSearch(column.key, input, searchType);
|
|
839
913
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
840
914
|
background: column.search
|
|
841
915
|
? "var(--background)"
|
|
@@ -914,16 +988,34 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
914
988
|
alignItems: "center",
|
|
915
989
|
}, children: [_jsx(TextInput, { onFocus: () => setActiveSearchColumn(column.key), onChange: (e) => {
|
|
916
990
|
var _a;
|
|
991
|
+
const input = e.target.value;
|
|
917
992
|
let searchType = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.type) ||
|
|
918
993
|
defaultSearchOperation ||
|
|
919
994
|
"contains";
|
|
920
|
-
if (
|
|
995
|
+
if (input.includes("to")) {
|
|
921
996
|
searchType = "between";
|
|
922
997
|
}
|
|
923
998
|
else if (searchType === "between") {
|
|
924
999
|
searchType = "contains";
|
|
925
1000
|
}
|
|
926
|
-
|
|
1001
|
+
else if (input.includes("%")) {
|
|
1002
|
+
const startsWithPercent = input.startsWith("%");
|
|
1003
|
+
const endsWithPercent = input.endsWith("%");
|
|
1004
|
+
if (startsWithPercent &&
|
|
1005
|
+
endsWithPercent &&
|
|
1006
|
+
input.length > 2) {
|
|
1007
|
+
searchType = "contains";
|
|
1008
|
+
}
|
|
1009
|
+
else if (!startsWithPercent &&
|
|
1010
|
+
endsWithPercent) {
|
|
1011
|
+
searchType = "startsWith";
|
|
1012
|
+
}
|
|
1013
|
+
else if (startsWithPercent &&
|
|
1014
|
+
!endsWithPercent) {
|
|
1015
|
+
searchType = "endsWith";
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
onSearch(column.key, input, searchType);
|
|
927
1019
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
928
1020
|
background: column.search
|
|
929
1021
|
? "var(--background)"
|
|
@@ -1000,16 +1092,34 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
1000
1092
|
alignItems: "center",
|
|
1001
1093
|
}, children: [_jsx(TextInput, { onFocus: () => setActiveSearchColumn(column.key), onChange: (e) => {
|
|
1002
1094
|
var _a;
|
|
1095
|
+
const input = e.target.value;
|
|
1003
1096
|
let searchType = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.type) ||
|
|
1004
1097
|
defaultSearchOperation ||
|
|
1005
1098
|
"contains";
|
|
1006
|
-
if (
|
|
1099
|
+
if (input.includes("to")) {
|
|
1007
1100
|
searchType = "between";
|
|
1008
1101
|
}
|
|
1009
1102
|
else if (searchType === "between") {
|
|
1010
1103
|
searchType = "contains";
|
|
1011
1104
|
}
|
|
1012
|
-
|
|
1105
|
+
else if (input.includes("%")) {
|
|
1106
|
+
const startsWithPercent = input.startsWith("%");
|
|
1107
|
+
const endsWithPercent = input.endsWith("%");
|
|
1108
|
+
if (startsWithPercent &&
|
|
1109
|
+
endsWithPercent &&
|
|
1110
|
+
input.length > 2) {
|
|
1111
|
+
searchType = "contains";
|
|
1112
|
+
}
|
|
1113
|
+
else if (!startsWithPercent &&
|
|
1114
|
+
endsWithPercent) {
|
|
1115
|
+
searchType = "startsWith";
|
|
1116
|
+
}
|
|
1117
|
+
else if (startsWithPercent &&
|
|
1118
|
+
!endsWithPercent) {
|
|
1119
|
+
searchType = "endsWith";
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
onSearch(column.key, input, searchType);
|
|
1013
1123
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
1014
1124
|
background: column.search
|
|
1015
1125
|
? "var(--background)"
|
|
@@ -3,6 +3,37 @@ export const createRegexFromWildcard = (query) => {
|
|
|
3
3
|
const regexPattern = "^" + escapedQuery.replace(/\*/g, ".*").replace(/\?/g, ".") + ".*$";
|
|
4
4
|
return new RegExp(regexPattern, "i");
|
|
5
5
|
};
|
|
6
|
+
// SQL-like pattern matcher for column search.
|
|
7
|
+
// Supports:
|
|
8
|
+
// - %value% -> substring match
|
|
9
|
+
// - %value -> endsWith
|
|
10
|
+
// - value% -> startsWith
|
|
11
|
+
// - _ -> single digit wildcard (0-9) when used in pattern
|
|
12
|
+
// Falls back to case-insensitive "contains" when no wildcards present.
|
|
13
|
+
export const matchSqlLikePattern = (pattern, value) => {
|
|
14
|
+
if (!value)
|
|
15
|
+
return false;
|
|
16
|
+
let v = value.toLowerCase();
|
|
17
|
+
let p = pattern.toLowerCase();
|
|
18
|
+
// Percent-based wildcards
|
|
19
|
+
if (p.startsWith("%") && p.endsWith("%") && p.length > 2) {
|
|
20
|
+
return v.includes(p.slice(1, -1));
|
|
21
|
+
}
|
|
22
|
+
if (p.startsWith("%")) {
|
|
23
|
+
return v.endsWith(p.slice(1));
|
|
24
|
+
}
|
|
25
|
+
if (p.endsWith("%")) {
|
|
26
|
+
return v.startsWith(p.slice(0, -1));
|
|
27
|
+
}
|
|
28
|
+
// Underscore: single digit wildcard
|
|
29
|
+
if (p.includes("_")) {
|
|
30
|
+
const escaped = p.replace(/([.+^${}()|[\]\\])/g, "\\$1");
|
|
31
|
+
const regexPattern = "^" + escaped.replace(/_/g, "\\d") + "$";
|
|
32
|
+
return new RegExp(regexPattern, "i").test(value);
|
|
33
|
+
}
|
|
34
|
+
// Default: simple contains
|
|
35
|
+
return v.includes(p);
|
|
36
|
+
};
|
|
6
37
|
export function isValidDateFormat(dateStr) {
|
|
7
38
|
if (!dateStr || typeof dateStr !== "string")
|
|
8
39
|
return false;
|
package/package.json
CHANGED