@johly/bits-ui 2.18.9 → 2.18.10

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() && value.getTime() <= endOfDay(d2).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() || value.getTime() > endOfDay(d2).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) {
@@ -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",
@@ -143,7 +143,12 @@ function getOperatorRecord(column) {
143
143
  export function createOperatorNodes({ filter, column, actions, locale, }) {
144
144
  const operators = getOperatorRecord(column);
145
145
  const currentOperator = operators[filter.operator];
146
- const relatedOperators = Object.values(operators).filter((operator) => currentOperator && operator.target === currentOperator.target);
146
+ const currentTarget = currentOperator?.target === "any"
147
+ ? filter.values.length > 1
148
+ ? "multiple"
149
+ : "single"
150
+ : currentOperator?.target;
151
+ const relatedOperators = Object.values(operators).filter((operator) => currentTarget && (operator.target === currentTarget || operator.target === "any"));
147
152
  return [
148
153
  {
149
154
  kind: "radio-group",
@@ -185,7 +190,8 @@ export function createColumnNodes({ columns, filters, actions, locale, strategy,
185
190
  };
186
191
  }
187
192
  if (isNumberColumn(column)) {
188
- const unit = column.meta?.number?.unit;
193
+ const unit = column.meta
194
+ ?.number?.unit;
189
195
  return {
190
196
  kind: "submenu",
191
197
  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: ["is", "is not", "is greater than", "is less than", "is greater than or equal to"],
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]) ? nextVals[0].length : nextVals.length;
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];
@@ -106,7 +106,7 @@ export type BigIntFilterOperator = NumberFilterOperator;
106
106
  export type DateFilterOperator = "is" | "is not" | "is before" | "is on or after" | "is after" | "is on or before" | "is between" | "is not between";
107
107
  export type BooleanFilterOperator = "is" | "is not";
108
108
  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";
109
+ export type MultiOptionFilterOperator = "include" | "exclude" | "include any of" | "include all of" | "include exactly" | "exclude if any of" | "exclude if all" | "exclude exactly";
110
110
  export type FilterOperators = {
111
111
  text: TextFilterOperator;
112
112
  number: NumberFilterOperator;
@@ -126,7 +126,7 @@ export type FiltersState = FilterModel[];
126
126
  export type FilterDetails<T extends ColumnDataType> = {
127
127
  [key in FilterOperators[T]]: FilterOperatorDetails<key, T>;
128
128
  };
129
- export type FilterOperatorTarget = "single" | "multiple";
129
+ export type FilterOperatorTarget = "single" | "multiple" | "any";
130
130
  export type FilterOperatorDetailsBase<OperatorValue, T extends ColumnDataType> = {
131
131
  key: string;
132
132
  value: OperatorValue;
@@ -141,6 +141,10 @@ export type FilterOperatorDetailsBase<OperatorValue, T extends ColumnDataType> =
141
141
  export type FilterOperatorDetails<OperatorValue, T extends ColumnDataType> = FilterOperatorDetailsBase<OperatorValue, T> & ({
142
142
  singularOf?: never;
143
143
  pluralOf?: never;
144
+ } | {
145
+ target: "any";
146
+ singularOf?: never;
147
+ pluralOf?: never;
144
148
  } | {
145
149
  target: "single";
146
150
  singularOf: FilterOperators[T];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johly/bits-ui",
3
- "version": "2.18.9",
3
+ "version": "2.18.10",
4
4
  "license": "MIT",
5
5
  "repository": "github:johanohly/bits-ui",
6
6
  "funding": "https://github.com/sponsors/huntabyte",