@johly/bits-ui 2.18.9 → 2.18.11
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.
|
@@ -16,6 +16,11 @@ function isSameDay(a, b) {
|
|
|
16
16
|
a.getMonth() === b.getMonth() &&
|
|
17
17
|
a.getDate() === b.getDate());
|
|
18
18
|
}
|
|
19
|
+
function setEquals(a, b) {
|
|
20
|
+
const aSet = new Set(a);
|
|
21
|
+
const bSet = new Set(b);
|
|
22
|
+
return aSet.size === bSet.size && [...aSet].every((value) => bSet.has(value));
|
|
23
|
+
}
|
|
19
24
|
export function optionFilterFn(inputData, filterValue) {
|
|
20
25
|
if (!inputData)
|
|
21
26
|
return false;
|
|
@@ -50,6 +55,10 @@ export function multiOptionFilterFn(inputData, filterValue) {
|
|
|
50
55
|
return intersection(values, filterValues).length === filterValues.length;
|
|
51
56
|
case "exclude if all":
|
|
52
57
|
return intersection(values, filterValues).length !== filterValues.length;
|
|
58
|
+
case "include exactly":
|
|
59
|
+
return setEquals(values, filterValues);
|
|
60
|
+
case "exclude exactly":
|
|
61
|
+
return !setEquals(values, filterValues);
|
|
53
62
|
}
|
|
54
63
|
}
|
|
55
64
|
export function dateFilterFn(inputData, filterValue) {
|
|
@@ -80,9 +89,11 @@ export function dateFilterFn(inputData, filterValue) {
|
|
|
80
89
|
case "is on or before":
|
|
81
90
|
return isSameDay(value, d1) || value.getTime() < startOfDay(d1).getTime();
|
|
82
91
|
case "is between":
|
|
83
|
-
return value.getTime() >= startOfDay(d1).getTime() &&
|
|
92
|
+
return (value.getTime() >= startOfDay(d1).getTime() &&
|
|
93
|
+
value.getTime() <= endOfDay(d2).getTime());
|
|
84
94
|
case "is not between":
|
|
85
|
-
return value.getTime() < startOfDay(d1).getTime() ||
|
|
95
|
+
return (value.getTime() < startOfDay(d1).getTime() ||
|
|
96
|
+
value.getTime() > endOfDay(d2).getTime());
|
|
86
97
|
}
|
|
87
98
|
}
|
|
88
99
|
export function textFilterFn(inputData, filterValue) {
|
package/dist/bits/filter/i18n.js
CHANGED
|
@@ -19,8 +19,10 @@ const en = {
|
|
|
19
19
|
"filters.multiOption.includeAnyOf": "includes any of",
|
|
20
20
|
"filters.multiOption.excludeAllOf": "excludes all of",
|
|
21
21
|
"filters.multiOption.includeAllOf": "includes all of",
|
|
22
|
+
"filters.multiOption.includeExactly": "includes exactly",
|
|
22
23
|
"filters.multiOption.excludeIfAnyOf": "excludes if any of",
|
|
23
24
|
"filters.multiOption.excludeIfAll": "excludes if all of",
|
|
25
|
+
"filters.multiOption.excludeExactly": "excludes exactly",
|
|
24
26
|
"filters.date.is": "is",
|
|
25
27
|
"filters.date.isNot": "is not",
|
|
26
28
|
"filters.date.isBefore": "is before",
|
|
@@ -91,12 +91,13 @@ function createSelectableMenuInternal({ column, actions, filter, }) {
|
|
|
91
91
|
label: option.label,
|
|
92
92
|
icon: option.icon,
|
|
93
93
|
count: counts?.get(option.value) ?? option.count ?? 0,
|
|
94
|
+
keywords: option.keywords,
|
|
94
95
|
};
|
|
95
96
|
return {
|
|
96
97
|
kind: "checkbox-item",
|
|
97
98
|
id: option.value,
|
|
98
99
|
label: option.label,
|
|
99
|
-
keywords: [option.value, option.label],
|
|
100
|
+
keywords: [option.value, option.label, ...(option.keywords ?? [])],
|
|
100
101
|
checked: selected,
|
|
101
102
|
onCheckedChange: (checked) => {
|
|
102
103
|
if (checked) {
|
|
@@ -143,7 +144,12 @@ function getOperatorRecord(column) {
|
|
|
143
144
|
export function createOperatorNodes({ filter, column, actions, locale, }) {
|
|
144
145
|
const operators = getOperatorRecord(column);
|
|
145
146
|
const currentOperator = operators[filter.operator];
|
|
146
|
-
const
|
|
147
|
+
const currentTarget = currentOperator?.target === "any"
|
|
148
|
+
? filter.values.length > 1
|
|
149
|
+
? "multiple"
|
|
150
|
+
: "single"
|
|
151
|
+
: currentOperator?.target;
|
|
152
|
+
const relatedOperators = Object.values(operators).filter((operator) => currentTarget && (operator.target === currentTarget || operator.target === "any"));
|
|
147
153
|
return [
|
|
148
154
|
{
|
|
149
155
|
kind: "radio-group",
|
|
@@ -185,7 +191,8 @@ export function createColumnNodes({ columns, filters, actions, locale, strategy,
|
|
|
185
191
|
};
|
|
186
192
|
}
|
|
187
193
|
if (isNumberColumn(column)) {
|
|
188
|
-
const unit = column.meta
|
|
194
|
+
const unit = column.meta
|
|
195
|
+
?.number?.unit;
|
|
189
196
|
return {
|
|
190
197
|
kind: "submenu",
|
|
191
198
|
id: column.id,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ColumnDataType, FilterOperatorTarget, FilterOperators, FilterTypeOperatorDetails, FilterValues } from "./types.js";
|
|
2
|
-
export declare const DEFAULT_OPERATORS: Record<ColumnDataType, Record<FilterOperatorTarget, FilterOperators[ColumnDataType]>>;
|
|
2
|
+
export declare const DEFAULT_OPERATORS: Record<ColumnDataType, Record<Exclude<FilterOperatorTarget, "any">, FilterOperators[ColumnDataType]>>;
|
|
3
3
|
export declare const optionFilterOperators: {
|
|
4
4
|
readonly is: {
|
|
5
5
|
readonly key: "filters.option.is";
|
|
@@ -80,19 +80,35 @@ export declare const multiOptionFilterOperators: {
|
|
|
80
80
|
readonly value: "include all of";
|
|
81
81
|
readonly target: "multiple";
|
|
82
82
|
readonly pluralOf: "include";
|
|
83
|
-
readonly relativeOf: ["include any of", "exclude if all", "exclude if any of"];
|
|
83
|
+
readonly relativeOf: ["include any of", "exclude if all", "include exactly", "exclude if any of"];
|
|
84
84
|
readonly isNegated: false;
|
|
85
85
|
readonly negation: "exclude if any of";
|
|
86
86
|
};
|
|
87
|
+
readonly "include exactly": {
|
|
88
|
+
readonly key: "filters.multiOption.includeExactly";
|
|
89
|
+
readonly value: "include exactly";
|
|
90
|
+
readonly target: "any";
|
|
91
|
+
readonly relativeOf: ["include", "include any of", "include all of", "exclude exactly"];
|
|
92
|
+
readonly isNegated: false;
|
|
93
|
+
readonly negation: "exclude exactly";
|
|
94
|
+
};
|
|
87
95
|
readonly "exclude if any of": {
|
|
88
96
|
readonly key: "filters.multiOption.excludeIfAnyOf";
|
|
89
97
|
readonly value: "exclude if any of";
|
|
90
98
|
readonly target: "multiple";
|
|
91
99
|
readonly pluralOf: "exclude";
|
|
92
|
-
readonly relativeOf: ["include any of", "exclude if all", "include all of"];
|
|
100
|
+
readonly relativeOf: ["include any of", "exclude if all", "include all of", "exclude exactly"];
|
|
93
101
|
readonly isNegated: true;
|
|
94
102
|
readonly negationOf: "include all of";
|
|
95
103
|
};
|
|
104
|
+
readonly "exclude exactly": {
|
|
105
|
+
readonly key: "filters.multiOption.excludeExactly";
|
|
106
|
+
readonly value: "exclude exactly";
|
|
107
|
+
readonly target: "any";
|
|
108
|
+
readonly relativeOf: ["exclude", "exclude if any of", "exclude if all", "include exactly"];
|
|
109
|
+
readonly isNegated: true;
|
|
110
|
+
readonly negationOf: "include exactly";
|
|
111
|
+
};
|
|
96
112
|
};
|
|
97
113
|
export declare const dateFilterOperators: {
|
|
98
114
|
readonly is: {
|
|
@@ -108,19 +108,35 @@ export const multiOptionFilterOperators = {
|
|
|
108
108
|
value: "include all of",
|
|
109
109
|
target: "multiple",
|
|
110
110
|
pluralOf: "include",
|
|
111
|
-
relativeOf: ["include any of", "exclude if all", "exclude if any of"],
|
|
111
|
+
relativeOf: ["include any of", "exclude if all", "include exactly", "exclude if any of"],
|
|
112
112
|
isNegated: false,
|
|
113
113
|
negation: "exclude if any of",
|
|
114
114
|
},
|
|
115
|
+
"include exactly": {
|
|
116
|
+
key: "filters.multiOption.includeExactly",
|
|
117
|
+
value: "include exactly",
|
|
118
|
+
target: "any",
|
|
119
|
+
relativeOf: ["include", "include any of", "include all of", "exclude exactly"],
|
|
120
|
+
isNegated: false,
|
|
121
|
+
negation: "exclude exactly",
|
|
122
|
+
},
|
|
115
123
|
"exclude if any of": {
|
|
116
124
|
key: "filters.multiOption.excludeIfAnyOf",
|
|
117
125
|
value: "exclude if any of",
|
|
118
126
|
target: "multiple",
|
|
119
127
|
pluralOf: "exclude",
|
|
120
|
-
relativeOf: ["include any of", "exclude if all", "include all of"],
|
|
128
|
+
relativeOf: ["include any of", "exclude if all", "include all of", "exclude exactly"],
|
|
121
129
|
isNegated: true,
|
|
122
130
|
negationOf: "include all of",
|
|
123
131
|
},
|
|
132
|
+
"exclude exactly": {
|
|
133
|
+
key: "filters.multiOption.excludeExactly",
|
|
134
|
+
value: "exclude exactly",
|
|
135
|
+
target: "any",
|
|
136
|
+
relativeOf: ["exclude", "exclude if any of", "exclude if all", "include exactly"],
|
|
137
|
+
isNegated: true,
|
|
138
|
+
negationOf: "include exactly",
|
|
139
|
+
},
|
|
124
140
|
};
|
|
125
141
|
export const dateFilterOperators = {
|
|
126
142
|
is: {
|
|
@@ -289,7 +305,13 @@ export const numberFilterOperators = {
|
|
|
289
305
|
value: "is less than or equal to",
|
|
290
306
|
target: "single",
|
|
291
307
|
singularOf: "is between",
|
|
292
|
-
relativeOf: [
|
|
308
|
+
relativeOf: [
|
|
309
|
+
"is",
|
|
310
|
+
"is not",
|
|
311
|
+
"is greater than",
|
|
312
|
+
"is less than",
|
|
313
|
+
"is greater than or equal to",
|
|
314
|
+
],
|
|
293
315
|
isNegated: false,
|
|
294
316
|
negation: "is greater than or equal to",
|
|
295
317
|
},
|
|
@@ -344,7 +366,9 @@ export const filterTypeOperatorDetails = {
|
|
|
344
366
|
};
|
|
345
367
|
export function determineNewOperator(type, oldVals, nextVals, currentOperator) {
|
|
346
368
|
const a = Array.isArray(oldVals) && Array.isArray(oldVals[0]) ? oldVals[0].length : oldVals.length;
|
|
347
|
-
const b = Array.isArray(nextVals) && Array.isArray(nextVals[0])
|
|
369
|
+
const b = Array.isArray(nextVals) && Array.isArray(nextVals[0])
|
|
370
|
+
? nextVals[0].length
|
|
371
|
+
: nextVals.length;
|
|
348
372
|
if (a === b || (a >= 2 && b >= 2) || (a <= 1 && b <= 1))
|
|
349
373
|
return currentOperator;
|
|
350
374
|
const opDetails = filterTypeOperatorDetails[type][currentOperator];
|
|
@@ -20,6 +20,7 @@ export interface ColumnOption {
|
|
|
20
20
|
value: string;
|
|
21
21
|
icon?: FilterIcon;
|
|
22
22
|
count?: number;
|
|
23
|
+
keywords?: string[];
|
|
23
24
|
}
|
|
24
25
|
export interface ColumnOptionExtended extends ColumnOption {
|
|
25
26
|
selected?: boolean;
|
|
@@ -106,7 +107,7 @@ export type BigIntFilterOperator = NumberFilterOperator;
|
|
|
106
107
|
export type DateFilterOperator = "is" | "is not" | "is before" | "is on or after" | "is after" | "is on or before" | "is between" | "is not between";
|
|
107
108
|
export type BooleanFilterOperator = "is" | "is not";
|
|
108
109
|
export type OptionFilterOperator = "is" | "is not" | "is any of" | "is none of";
|
|
109
|
-
export type MultiOptionFilterOperator = "include" | "exclude" | "include any of" | "include all of" | "exclude if any of" | "exclude if all";
|
|
110
|
+
export type MultiOptionFilterOperator = "include" | "exclude" | "include any of" | "include all of" | "include exactly" | "exclude if any of" | "exclude if all" | "exclude exactly";
|
|
110
111
|
export type FilterOperators = {
|
|
111
112
|
text: TextFilterOperator;
|
|
112
113
|
number: NumberFilterOperator;
|
|
@@ -126,7 +127,7 @@ export type FiltersState = FilterModel[];
|
|
|
126
127
|
export type FilterDetails<T extends ColumnDataType> = {
|
|
127
128
|
[key in FilterOperators[T]]: FilterOperatorDetails<key, T>;
|
|
128
129
|
};
|
|
129
|
-
export type FilterOperatorTarget = "single" | "multiple";
|
|
130
|
+
export type FilterOperatorTarget = "single" | "multiple" | "any";
|
|
130
131
|
export type FilterOperatorDetailsBase<OperatorValue, T extends ColumnDataType> = {
|
|
131
132
|
key: string;
|
|
132
133
|
value: OperatorValue;
|
|
@@ -141,6 +142,10 @@ export type FilterOperatorDetailsBase<OperatorValue, T extends ColumnDataType> =
|
|
|
141
142
|
export type FilterOperatorDetails<OperatorValue, T extends ColumnDataType> = FilterOperatorDetailsBase<OperatorValue, T> & ({
|
|
142
143
|
singularOf?: never;
|
|
143
144
|
pluralOf?: never;
|
|
145
|
+
} | {
|
|
146
|
+
target: "any";
|
|
147
|
+
singularOf?: never;
|
|
148
|
+
pluralOf?: never;
|
|
144
149
|
} | {
|
|
145
150
|
target: "single";
|
|
146
151
|
singularOf: FilterOperators[T];
|