@megha-ui/react 1.3.102 → 1.3.105
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,58 @@ 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
|
+
const searchType = ((_b = searchQueries[currentKey]) === null || _b === void 0 ? void 0 : _b.type) ||
|
|
699
|
+
defaultSearchOperation ||
|
|
700
|
+
"contains";
|
|
701
|
+
onSearch(currentKey, input, searchType);
|
|
702
|
+
}, onBlur: (e) => {
|
|
703
|
+
var _a, _b;
|
|
704
|
+
const currentKey = ((_a = headerColumns.find((column) => column.key === _groupBy)) === null || _a === void 0 ? void 0 : _a.key) || "";
|
|
705
|
+
const raw = e.target.value;
|
|
706
|
+
const input = raw.replace(/\?/g, "%");
|
|
707
|
+
let searchType = ((_b = searchQueries[currentKey]) === null || _b === void 0 ? void 0 : _b.type) ||
|
|
659
708
|
defaultSearchOperation ||
|
|
660
709
|
"contains";
|
|
661
|
-
if (
|
|
710
|
+
if (input.includes("to")) {
|
|
662
711
|
searchType = "between";
|
|
663
712
|
}
|
|
664
713
|
else if (searchType === "between") {
|
|
665
714
|
searchType = "contains";
|
|
666
715
|
}
|
|
667
|
-
|
|
716
|
+
else if (input.includes("%")) {
|
|
717
|
+
const startsWithPercent = input.startsWith("%");
|
|
718
|
+
const endsWithPercent = input.endsWith("%");
|
|
719
|
+
if (startsWithPercent &&
|
|
720
|
+
endsWithPercent &&
|
|
721
|
+
input.length > 2) {
|
|
722
|
+
searchType = "contains";
|
|
723
|
+
}
|
|
724
|
+
else if (!startsWithPercent && endsWithPercent) {
|
|
725
|
+
searchType = "startsWith";
|
|
726
|
+
}
|
|
727
|
+
else if (startsWithPercent &&
|
|
728
|
+
!endsWithPercent) {
|
|
729
|
+
searchType = "endsWith";
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
let query = input;
|
|
733
|
+
if (query &&
|
|
734
|
+
!query.includes("%") &&
|
|
735
|
+
!query.includes("_")) {
|
|
736
|
+
if (searchType === "contains") {
|
|
737
|
+
query = `%${query}%`;
|
|
738
|
+
}
|
|
739
|
+
else if (searchType === "startsWith") {
|
|
740
|
+
query = `${query}%`;
|
|
741
|
+
}
|
|
742
|
+
else if (searchType === "endsWith") {
|
|
743
|
+
query = `%${query}`;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
onSearch(currentKey, query, searchType);
|
|
668
747
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
669
748
|
background: ((_57 = headerColumns.find((column) => column.key === _groupBy)) === null || _57 === void 0 ? void 0 : _57.search)
|
|
670
749
|
? "var(--background)"
|
|
@@ -826,16 +905,34 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
826
905
|
alignItems: "center",
|
|
827
906
|
}, children: [_jsx(TextInput, { onFocus: () => setActiveSearchColumn(column.key), onChange: (e) => {
|
|
828
907
|
var _a;
|
|
908
|
+
const input = e.target.value;
|
|
829
909
|
let searchType = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.type) ||
|
|
830
910
|
defaultSearchOperation ||
|
|
831
911
|
"contains";
|
|
832
|
-
if (
|
|
912
|
+
if (input.includes("to")) {
|
|
833
913
|
searchType = "between";
|
|
834
914
|
}
|
|
835
915
|
else if (searchType === "between") {
|
|
836
916
|
searchType = "contains";
|
|
837
917
|
}
|
|
838
|
-
|
|
918
|
+
else if (input.includes("%")) {
|
|
919
|
+
const startsWithPercent = input.startsWith("%");
|
|
920
|
+
const endsWithPercent = input.endsWith("%");
|
|
921
|
+
if (startsWithPercent &&
|
|
922
|
+
endsWithPercent &&
|
|
923
|
+
input.length > 2) {
|
|
924
|
+
searchType = "contains";
|
|
925
|
+
}
|
|
926
|
+
else if (!startsWithPercent &&
|
|
927
|
+
endsWithPercent) {
|
|
928
|
+
searchType = "startsWith";
|
|
929
|
+
}
|
|
930
|
+
else if (startsWithPercent &&
|
|
931
|
+
!endsWithPercent) {
|
|
932
|
+
searchType = "endsWith";
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
onSearch(column.key, input, searchType);
|
|
839
936
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
840
937
|
background: column.search
|
|
841
938
|
? "var(--background)"
|
|
@@ -914,16 +1011,34 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
914
1011
|
alignItems: "center",
|
|
915
1012
|
}, children: [_jsx(TextInput, { onFocus: () => setActiveSearchColumn(column.key), onChange: (e) => {
|
|
916
1013
|
var _a;
|
|
1014
|
+
const input = e.target.value;
|
|
917
1015
|
let searchType = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.type) ||
|
|
918
1016
|
defaultSearchOperation ||
|
|
919
1017
|
"contains";
|
|
920
|
-
if (
|
|
1018
|
+
if (input.includes("to")) {
|
|
921
1019
|
searchType = "between";
|
|
922
1020
|
}
|
|
923
1021
|
else if (searchType === "between") {
|
|
924
1022
|
searchType = "contains";
|
|
925
1023
|
}
|
|
926
|
-
|
|
1024
|
+
else if (input.includes("%")) {
|
|
1025
|
+
const startsWithPercent = input.startsWith("%");
|
|
1026
|
+
const endsWithPercent = input.endsWith("%");
|
|
1027
|
+
if (startsWithPercent &&
|
|
1028
|
+
endsWithPercent &&
|
|
1029
|
+
input.length > 2) {
|
|
1030
|
+
searchType = "contains";
|
|
1031
|
+
}
|
|
1032
|
+
else if (!startsWithPercent &&
|
|
1033
|
+
endsWithPercent) {
|
|
1034
|
+
searchType = "startsWith";
|
|
1035
|
+
}
|
|
1036
|
+
else if (startsWithPercent &&
|
|
1037
|
+
!endsWithPercent) {
|
|
1038
|
+
searchType = "endsWith";
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
onSearch(column.key, input, searchType);
|
|
927
1042
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
928
1043
|
background: column.search
|
|
929
1044
|
? "var(--background)"
|
|
@@ -1000,16 +1115,56 @@ const GridHeader = ({ columns, onSearch, searchQueries, sortable, search, resiza
|
|
|
1000
1115
|
alignItems: "center",
|
|
1001
1116
|
}, children: [_jsx(TextInput, { onFocus: () => setActiveSearchColumn(column.key), onChange: (e) => {
|
|
1002
1117
|
var _a;
|
|
1118
|
+
const input = e.target.value;
|
|
1119
|
+
const searchType = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.type) ||
|
|
1120
|
+
defaultSearchOperation ||
|
|
1121
|
+
"contains";
|
|
1122
|
+
onSearch(column.key, input, searchType);
|
|
1123
|
+
}, onBlur: (e) => {
|
|
1124
|
+
var _a;
|
|
1125
|
+
const raw = e.target.value;
|
|
1126
|
+
const input = raw.replace(/\?/g, "%");
|
|
1003
1127
|
let searchType = ((_a = searchQueries[column.key]) === null || _a === void 0 ? void 0 : _a.type) ||
|
|
1004
1128
|
defaultSearchOperation ||
|
|
1005
1129
|
"contains";
|
|
1006
|
-
if (
|
|
1130
|
+
if (input.includes("to")) {
|
|
1007
1131
|
searchType = "between";
|
|
1008
1132
|
}
|
|
1009
1133
|
else if (searchType === "between") {
|
|
1010
1134
|
searchType = "contains";
|
|
1011
1135
|
}
|
|
1012
|
-
|
|
1136
|
+
else if (input.includes("%")) {
|
|
1137
|
+
const startsWithPercent = input.startsWith("%");
|
|
1138
|
+
const endsWithPercent = input.endsWith("%");
|
|
1139
|
+
if (startsWithPercent &&
|
|
1140
|
+
endsWithPercent &&
|
|
1141
|
+
input.length > 2) {
|
|
1142
|
+
searchType = "contains";
|
|
1143
|
+
}
|
|
1144
|
+
else if (!startsWithPercent &&
|
|
1145
|
+
endsWithPercent) {
|
|
1146
|
+
searchType = "startsWith";
|
|
1147
|
+
}
|
|
1148
|
+
else if (startsWithPercent &&
|
|
1149
|
+
!endsWithPercent) {
|
|
1150
|
+
searchType = "endsWith";
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
let query = input;
|
|
1154
|
+
if (query &&
|
|
1155
|
+
!query.includes("%") &&
|
|
1156
|
+
!query.includes("_")) {
|
|
1157
|
+
if (searchType === "contains") {
|
|
1158
|
+
query = `%${query}%`;
|
|
1159
|
+
}
|
|
1160
|
+
else if (searchType === "startsWith") {
|
|
1161
|
+
query = `${query}%`;
|
|
1162
|
+
}
|
|
1163
|
+
else if (searchType === "endsWith") {
|
|
1164
|
+
query = `%${query}`;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
onSearch(column.key, query, searchType);
|
|
1013
1168
|
}, placeholder: "Search", extraWrapperStyle: {
|
|
1014
1169
|
background: column.search
|
|
1015
1170
|
? "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