@vuu-ui/vuu-filters 3.5.14 → 3.5.15
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 +40 -0
- package/package.json +12 -12
- package/src/FilterAggregator.js +7 -3
- package/src/column-filter/ColumnFilter.css.js +23 -0
- package/src/column-filter/ColumnFilter.js +31 -8
- package/src/column-filter/column-filter-utils.js +40 -0
- package/src/column-filter/useColumnFilter.js +68 -16
- package/src/filter-clause/operator-picker/OperatorPicker.js +30 -3
- package/src/filter-container/FilterContainer.js +75 -5
- package/src/filter-container/useFilterContainer.js +7 -0
- package/types/column-filter/column-filter-utils.d.ts +8 -0
- package/types/column-filter/useColumnFilter.d.ts +15 -1
- package/types/filter-clause/operator-picker/OperatorPicker.d.ts +17 -7
- package/types/filter-container/FilterContainer.d.ts +1 -1
- package/types/filter-container/useFilterContainer.d.ts +3 -1
- package/types/index.d.ts +1 -0
package/README.md
CHANGED
|
@@ -15,6 +15,46 @@ Vuu also supports `MultiValueFilterClause`
|
|
|
15
15
|
|
|
16
16
|
## ColumnFilter
|
|
17
17
|
|
|
18
|
+
Set `showOperatorPicker` to render a compact operator dropdown before the value.
|
|
19
|
+
It is opt-in; existing fixed-operator filters are unchanged.
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<ColumnFilter
|
|
23
|
+
column={{ name: "price", serverDataType: "double" }}
|
|
24
|
+
showOperatorPicker
|
|
25
|
+
operators={["=", ">", ">=", "between-inclusive"]}
|
|
26
|
+
defaultValue=""
|
|
27
|
+
onCommit={handleCommit}
|
|
28
|
+
/>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`operators` replaces the default options and preserves their order. Numeric
|
|
32
|
+
(including scaled-decimal) and temporal columns default to `=`, `!=`, `>`, `>=`,
|
|
33
|
+
`<`, `<=`; text columns to `=`, `!=`, `starts`, `ends`, `contains`; boolean
|
|
34
|
+
columns to `=`, `!=`. Numeric and temporal filters can also opt into `between`
|
|
35
|
+
and `between-inclusive`. Multi-value `in` filters are not supported by this
|
|
36
|
+
control. Empty lists, incompatible operators, and selections outside the list
|
|
37
|
+
raise an error.
|
|
38
|
+
|
|
39
|
+
Use `defaultOperator` for an uncontrolled picker, or `operator` together with
|
|
40
|
+
`onOperatorChange(event, operator)` for a controlled picker. The initial operator
|
|
41
|
+
is `=` if allowed, otherwise the first option. Operator control is independent
|
|
42
|
+
of value control (`value` / `defaultValue`).
|
|
43
|
+
|
|
44
|
+
Selecting a different operator preserves the value and immediately commits a
|
|
45
|
+
populated, valid filter using the new operator. An already empty value only changes the
|
|
46
|
+
selection. Switching to a range retains the lower value and starts with an empty
|
|
47
|
+
upper value; switching back retains the lower value (and clears a filter if only
|
|
48
|
+
the upper value was populated). Incomplete ranges use the
|
|
49
|
+
existing partial-range commit behaviour. The operator picker respects
|
|
50
|
+
`InputProps.disabled` and `InputProps.readOnly`.
|
|
51
|
+
|
|
52
|
+
`FilterContainerColumnFilter` accepts the same picker options, manages selection
|
|
53
|
+
internally, and restores operators and values from externally loaded or saved
|
|
54
|
+
filters. A loaded operator must be included in the configured options. Clearing
|
|
55
|
+
an external filter resets the operator to its default; clearing a value locally
|
|
56
|
+
keeps the selected operator.
|
|
57
|
+
|
|
18
58
|
onCommit is a `ColumnFilterCommitHandler`
|
|
19
59
|
|
|
20
60
|
```typescript
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.5.
|
|
2
|
+
"version": "3.5.15",
|
|
3
3
|
"main": "./src/index.js",
|
|
4
4
|
"author": "heswell",
|
|
5
5
|
"license": "Apache-2.0",
|
|
@@ -10,19 +10,19 @@
|
|
|
10
10
|
"type-defs": "node ../../scripts/build-type-defs.mjs"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
|
-
"@vuu-ui/vuu-data-types": "3.5.
|
|
14
|
-
"@vuu-ui/vuu-protocol-types": "3.5.
|
|
15
|
-
"@vuu-ui/vuu-table-types": "3.5.
|
|
16
|
-
"@vuu-ui/vuu-filter-types": "3.5.
|
|
13
|
+
"@vuu-ui/vuu-data-types": "3.5.15",
|
|
14
|
+
"@vuu-ui/vuu-protocol-types": "3.5.15",
|
|
15
|
+
"@vuu-ui/vuu-table-types": "3.5.15",
|
|
16
|
+
"@vuu-ui/vuu-filter-types": "3.5.15"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@vuu-ui/vuu-context-menu": "3.5.
|
|
20
|
-
"@vuu-ui/vuu-data-react": "3.5.
|
|
21
|
-
"@vuu-ui/vuu-filter-parser": "3.5.
|
|
22
|
-
"@vuu-ui/vuu-popups": "3.5.
|
|
23
|
-
"@vuu-ui/vuu-ui-controls": "3.5.
|
|
24
|
-
"@vuu-ui/vuu-table": "3.5.
|
|
25
|
-
"@vuu-ui/vuu-utils": "3.5.
|
|
19
|
+
"@vuu-ui/vuu-context-menu": "3.5.15",
|
|
20
|
+
"@vuu-ui/vuu-data-react": "3.5.15",
|
|
21
|
+
"@vuu-ui/vuu-filter-parser": "3.5.15",
|
|
22
|
+
"@vuu-ui/vuu-popups": "3.5.15",
|
|
23
|
+
"@vuu-ui/vuu-ui-controls": "3.5.15",
|
|
24
|
+
"@vuu-ui/vuu-table": "3.5.15",
|
|
25
|
+
"@vuu-ui/vuu-utils": "3.5.15",
|
|
26
26
|
"@salt-ds/core": "1.54.1",
|
|
27
27
|
"@salt-ds/lab": "1.0.0-alpha.83",
|
|
28
28
|
"@salt-ds/styles": "0.2.1",
|
package/src/FilterAggregator.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EpochTimestamp, getTemporalInfo, getTypedValueForDescriptor, isAndFilter, isBetweenFilter, isExtendedFilter, isMultiClauseFilter, isSingleValueFilter } from "@vuu-ui/vuu-utils";
|
|
1
|
+
import { EpochTimestamp, getTemporalInfo, getTypedValueForDescriptor, isAndFilter, isBetweenFilter, isBetweenOperator, isExtendedFilter, isMultiClauseFilter, isSingleValueFilter } from "@vuu-ui/vuu-utils";
|
|
2
2
|
import { ExtendedSingleValueFilterClause } from "./filter-container/ExtendedSingleValueFilterClause.js";
|
|
3
3
|
function installExtendedFilters(filter, throwIfUndefined = false) {
|
|
4
4
|
if (void 0 !== filter) if (isExtendedFilter(filter)) {
|
|
@@ -52,7 +52,11 @@ const singleValueOps = [
|
|
|
52
52
|
"starts",
|
|
53
53
|
"ends"
|
|
54
54
|
];
|
|
55
|
-
const asSingleValueOp = (op)=>
|
|
55
|
+
const asSingleValueOp = (op)=>{
|
|
56
|
+
const operator = singleValueOps.find((candidate)=>candidate === op);
|
|
57
|
+
if (void 0 === operator) throw Error(`[FilterAggregator] unsupported single-value operator ${op}`);
|
|
58
|
+
return operator;
|
|
59
|
+
};
|
|
56
60
|
class FilterAggregator {
|
|
57
61
|
#filters = new Map();
|
|
58
62
|
constructor(filter){
|
|
@@ -87,7 +91,7 @@ class FilterAggregator {
|
|
|
87
91
|
} else {
|
|
88
92
|
const typedValue = getFilterValue(column, value.toString(), temporalInfo, options, true);
|
|
89
93
|
if (void 0 === typedValue) this.#filters.delete(column.name);
|
|
90
|
-
else this.#filters.set(column.name, createClause(
|
|
94
|
+
else this.#filters.set(column.name, createClause(isBetweenOperator(op) ? "=" : asSingleValueOp(op), typedValue));
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
has({ name }) {
|
|
@@ -51,6 +51,29 @@ const css = `
|
|
|
51
51
|
border-color: red;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
.vuuColumnFilter.vuuColumnFilter-withOperator {
|
|
55
|
+
max-width: none;
|
|
56
|
+
|
|
57
|
+
& [data-field="operator"] {
|
|
58
|
+
border-right: 1px solid var(--salt-separable-primary-borderColor);
|
|
59
|
+
margin-right: var(--salt-spacing-100);
|
|
60
|
+
align-self: stretch;
|
|
61
|
+
display: flex;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
& .vuuColumnFilter-operator {
|
|
65
|
+
background: none;
|
|
66
|
+
border: none;
|
|
67
|
+
width: auto;
|
|
68
|
+
min-width: 60px;
|
|
69
|
+
|
|
70
|
+
&.saltDropdown .saltDropdown-toggle {
|
|
71
|
+
flex-shrink: 0;
|
|
72
|
+
display: block;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
54
77
|
|
|
55
78
|
`;
|
|
56
79
|
export default css;
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { SegmentedButtonGroup } from "@salt-ds/core";
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SegmentedButtonGroup, useForkRef } from "@salt-ds/core";
|
|
3
3
|
import { getDataItemEditControl } from "@vuu-ui/vuu-data-react";
|
|
4
4
|
import clsx from "clsx";
|
|
5
|
-
import { forwardRef as external_react_forwardRef, useMemo } from "react";
|
|
5
|
+
import { forwardRef as external_react_forwardRef, useMemo, useRef } from "react";
|
|
6
6
|
import { useColumnFilter } from "./useColumnFilter.js";
|
|
7
7
|
import { useComponentCssInjection } from "@salt-ds/styles";
|
|
8
8
|
import { useWindow } from "@salt-ds/window";
|
|
9
9
|
import ColumnFilter_0 from "./ColumnFilter.css";
|
|
10
10
|
import { isBetweenOperator, withDateTimePattern } from "@vuu-ui/vuu-utils";
|
|
11
|
+
import { OperatorPicker } from "../filter-clause/operator-picker/OperatorPicker.js";
|
|
11
12
|
const classBase = "vuuColumnFilter";
|
|
12
|
-
const ColumnFilter_ColumnFilter = /*#__PURE__*/ external_react_forwardRef(function({ InputProps: InputPropsProp, TypeaheadProps, className, column, defaultValue, extendedFilterOptions, labels, onColumnFilterChange, onColumnRangeFilterChange, onCommit: onCommitProp, operator =
|
|
13
|
+
const ColumnFilter_ColumnFilter = /*#__PURE__*/ external_react_forwardRef(function({ InputProps: InputPropsProp, TypeaheadProps, className, column, defaultValue, defaultOperator, extendedFilterOptions, labels, onColumnFilterChange, onColumnRangeFilterChange, onCommit: onCommitProp, onOperatorChange, operator: operatorProp, operators: operatorsProp, showOperatorPicker = false, pattern, table, value: valueProp, values, variant, ...buttonGroupProps }, forwardRef) {
|
|
14
|
+
const rootRef = useRef(null);
|
|
15
|
+
const ref = useForkRef(rootRef, forwardRef);
|
|
13
16
|
const targetWindow = useWindow();
|
|
14
17
|
useComponentCssInjection({
|
|
15
18
|
testId: "vuu-filter-editor",
|
|
@@ -25,25 +28,45 @@ const ColumnFilter_ColumnFilter = /*#__PURE__*/ external_react_forwardRef(functi
|
|
|
25
28
|
date,
|
|
26
29
|
time
|
|
27
30
|
]);
|
|
28
|
-
const { InputProps, InputPropsRange, isInvalid, onCommit, onCommitRange } = useColumnFilter({
|
|
31
|
+
const { InputProps, InputPropsRange, isInvalid, onCommit, onCommitRange, operator, operators, onOperatorSelect } = useColumnFilter({
|
|
29
32
|
InputProps: InputPropsProp,
|
|
30
33
|
column: controlDescriptor,
|
|
31
34
|
defaultValue,
|
|
35
|
+
defaultOperator,
|
|
32
36
|
extendedFilterOptions,
|
|
33
37
|
onColumnFilterChange,
|
|
34
38
|
onColumnRangeFilterChange,
|
|
35
39
|
onCommit: onCommitProp,
|
|
36
|
-
|
|
40
|
+
onOperatorChange,
|
|
41
|
+
operator: operatorProp,
|
|
42
|
+
operators: operatorsProp,
|
|
43
|
+
showOperatorPicker,
|
|
37
44
|
value: valueProp
|
|
38
45
|
});
|
|
39
46
|
return /*#__PURE__*/ jsxs(SegmentedButtonGroup, {
|
|
40
47
|
...buttonGroupProps,
|
|
41
48
|
className: clsx(classBase, className, {
|
|
42
49
|
[`${classBase}-invalid`]: isInvalid,
|
|
43
|
-
[`${classBase}-toggle`]: "toggle" === variant
|
|
50
|
+
[`${classBase}-toggle`]: "toggle" === variant,
|
|
51
|
+
[`${classBase}-withOperator`]: showOperatorPicker
|
|
44
52
|
}),
|
|
45
|
-
ref:
|
|
53
|
+
ref: ref,
|
|
46
54
|
children: [
|
|
55
|
+
operators ? /*#__PURE__*/ jsx(OperatorPicker, {
|
|
56
|
+
"aria-label": `${column.label ?? column.name} operator`,
|
|
57
|
+
className: `${classBase}-operator`,
|
|
58
|
+
disabled: InputProps?.disabled,
|
|
59
|
+
readOnly: InputProps?.readOnly,
|
|
60
|
+
operators: operators,
|
|
61
|
+
onSelect: (event, operator)=>{
|
|
62
|
+
onOperatorSelect(event, operator);
|
|
63
|
+
requestAnimationFrame(()=>{
|
|
64
|
+
rootRef.current?.querySelector("input:not(:disabled)")?.focus();
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
value: operator,
|
|
68
|
+
variant: "dropdown"
|
|
69
|
+
}) : null,
|
|
47
70
|
getDataItemEditControl({
|
|
48
71
|
InputProps,
|
|
49
72
|
TypeaheadProps,
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { extractFilterForColumn, isBetweenFilter, isBetweenOperator, isNumericColumn, isSingleValueFilter, isTemporalColumn, isTextColumn } from "@vuu-ui/vuu-utils";
|
|
2
|
+
import { numericOperators, textOperators } from "../filter-clause/operator-picker/operator-utils.js";
|
|
3
|
+
const getColumnFilterOperators = (column, operators)=>{
|
|
4
|
+
let supported;
|
|
5
|
+
if (isTextColumn(column)) supported = textOperators.filter((op)=>"in" !== op);
|
|
6
|
+
else if (isNumericColumn(column) || isTemporalColumn(column) || column.serverDataType?.startsWith("scaleddecimal")) supported = [
|
|
7
|
+
...numericOperators,
|
|
8
|
+
"between",
|
|
9
|
+
"between-inclusive"
|
|
10
|
+
];
|
|
11
|
+
else if ("boolean" === column.serverDataType) supported = [
|
|
12
|
+
"=",
|
|
13
|
+
"!="
|
|
14
|
+
];
|
|
15
|
+
else throw Error(`[ColumnFilter] unsupported column type for ${column.name}`);
|
|
16
|
+
if (operators) {
|
|
17
|
+
if (0 === operators.length || operators.some((op)=>!supported.includes(op))) throw Error(`[ColumnFilter] invalid operators for ${column.name}`);
|
|
18
|
+
return operators;
|
|
19
|
+
}
|
|
20
|
+
return supported.filter((op)=>!isBetweenOperator(op));
|
|
21
|
+
};
|
|
22
|
+
const getDefaultColumnFilterOperator = (operators, operator)=>{
|
|
23
|
+
const selected = void 0 === operator ? operators.find((op)=>"=" === op) ?? operators[0] : operators.find((op)=>op === operator);
|
|
24
|
+
if (void 0 === selected) throw Error(`[ColumnFilter] operator ${operator} is not in the configured operators`);
|
|
25
|
+
return selected;
|
|
26
|
+
};
|
|
27
|
+
const getColumnFilterOperator = (column, filter)=>{
|
|
28
|
+
const clause = getColumnFilterClause(column, filter);
|
|
29
|
+
if (isBetweenFilter(clause)) return ">=" === clause.filters[0].op ? "between-inclusive" : "between";
|
|
30
|
+
if (isSingleValueFilter(clause)) return clause.op;
|
|
31
|
+
};
|
|
32
|
+
const getColumnFilterClause = (column, filter)=>{
|
|
33
|
+
const clause = extractFilterForColumn(filter, column.name);
|
|
34
|
+
return isSingleValueFilter(clause) || isBetweenFilter(clause) ? clause : void 0;
|
|
35
|
+
};
|
|
36
|
+
const normalizeColumnFilterValue = (operator, value = "")=>isBetweenOperator(operator) ? Array.isArray(value) ? value : [
|
|
37
|
+
`${value}`,
|
|
38
|
+
""
|
|
39
|
+
] : Array.isArray(value) ? value[0] : value;
|
|
40
|
+
export { getColumnFilterClause, getColumnFilterOperator, getColumnFilterOperators, getDefaultColumnFilterOperator, normalizeColumnFilterValue };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useControlled } from "@salt-ds/core";
|
|
2
2
|
import { useCallback, useMemo, useState } from "react";
|
|
3
3
|
import { isBetweenOperator, isValidRange } from "@vuu-ui/vuu-utils";
|
|
4
|
+
import { getColumnFilterOperators, getDefaultColumnFilterOperator, normalizeColumnFilterValue } from "./column-filter-utils.js";
|
|
4
5
|
const injectInputProps = (InputProps, inputProps)=>{
|
|
5
6
|
if (void 0 === InputProps) return {
|
|
6
7
|
inputProps
|
|
@@ -13,20 +14,59 @@ const injectInputProps = (InputProps, inputProps)=>{
|
|
|
13
14
|
}
|
|
14
15
|
};
|
|
15
16
|
};
|
|
16
|
-
const useColumnFilter = ({ InputProps: InputPropsProp, column, defaultValue, extendedFilterOptions, onColumnFilterChange, onColumnRangeFilterChange, onCommit, operator =
|
|
17
|
+
const useColumnFilter = ({ InputProps: InputPropsProp, column, defaultValue, defaultOperator, extendedFilterOptions, onColumnFilterChange, onColumnRangeFilterChange, onCommit, onOperatorChange, operator: operatorProp, operators: operatorsProp, showOperatorPicker = false, value: valueProp })=>{
|
|
17
18
|
const [isInvalid, setIsInvalid] = useState(false);
|
|
18
|
-
const
|
|
19
|
+
const operators = useMemo(()=>showOperatorPicker ? getColumnFilterOperators(column, operatorsProp) : void 0, [
|
|
20
|
+
column,
|
|
21
|
+
operatorsProp,
|
|
22
|
+
showOperatorPicker
|
|
23
|
+
]);
|
|
24
|
+
const [selectedOperator, setOperator] = useControlled({
|
|
25
|
+
controlled: operatorProp,
|
|
26
|
+
default: operators ? getDefaultColumnFilterOperator(operators, defaultOperator) : defaultOperator ?? "=",
|
|
27
|
+
name: "ColumnFilter",
|
|
28
|
+
state: "operator"
|
|
29
|
+
});
|
|
30
|
+
const operator = operators ? getDefaultColumnFilterOperator(operators, selectedOperator) : selectedOperator;
|
|
31
|
+
const [rawValue, setValue] = useControlled({
|
|
19
32
|
controlled: valueProp,
|
|
20
33
|
default: defaultValue,
|
|
21
|
-
name: "
|
|
34
|
+
name: "ColumnFilter",
|
|
22
35
|
state: "value"
|
|
23
36
|
});
|
|
37
|
+
const value = showOperatorPicker ? normalizeColumnFilterValue(operator, rawValue) : rawValue;
|
|
38
|
+
const handleOperatorSelect = useCallback((event, newOperator)=>{
|
|
39
|
+
if (newOperator === operator) return;
|
|
40
|
+
const newValue = normalizeColumnFilterValue(newOperator, value);
|
|
41
|
+
setOperator(newOperator);
|
|
42
|
+
setValue(newValue);
|
|
43
|
+
setIsInvalid(false);
|
|
44
|
+
onOperatorChange?.(event, newOperator);
|
|
45
|
+
const hadValue = Array.isArray(value) ? value.some((v)=>"" !== v) : void 0 !== value && "" !== value;
|
|
46
|
+
if (hadValue) {
|
|
47
|
+
const valid = !Array.isArray(newValue) || isValidRange(newValue);
|
|
48
|
+
setIsInvalid(!valid);
|
|
49
|
+
if (valid) onCommit(column, newOperator, newValue, extendedFilterOptions);
|
|
50
|
+
}
|
|
51
|
+
}, [
|
|
52
|
+
column,
|
|
53
|
+
extendedFilterOptions,
|
|
54
|
+
onCommit,
|
|
55
|
+
onOperatorChange,
|
|
56
|
+
operator,
|
|
57
|
+
setOperator,
|
|
58
|
+
setValue,
|
|
59
|
+
value
|
|
60
|
+
]);
|
|
24
61
|
const handleCommit = useCallback((_e, newValue = "")=>{
|
|
25
62
|
if (Array.isArray(value)) if (isBetweenOperator(operator)) {
|
|
26
|
-
|
|
63
|
+
const newRange = [
|
|
27
64
|
`${newValue}`,
|
|
28
65
|
value[1]
|
|
29
|
-
]
|
|
66
|
+
];
|
|
67
|
+
setValue(newRange);
|
|
68
|
+
if (showOperatorPicker && !isValidRange(newRange)) return void setIsInvalid(true);
|
|
69
|
+
setIsInvalid(false);
|
|
30
70
|
onCommit?.(column, operator, [
|
|
31
71
|
`${newValue}`,
|
|
32
72
|
value[1]
|
|
@@ -42,7 +82,8 @@ const useColumnFilter = ({ InputProps: InputPropsProp, column, defaultValue, ext
|
|
|
42
82
|
setValue,
|
|
43
83
|
onCommit,
|
|
44
84
|
column,
|
|
45
|
-
extendedFilterOptions
|
|
85
|
+
extendedFilterOptions,
|
|
86
|
+
showOperatorPicker
|
|
46
87
|
]);
|
|
47
88
|
const handleRangeCommit = useCallback((_e, newValue = "")=>{
|
|
48
89
|
if (Array.isArray(value)) {
|
|
@@ -79,29 +120,37 @@ const useColumnFilter = ({ InputProps: InputPropsProp, column, defaultValue, ext
|
|
|
79
120
|
]);
|
|
80
121
|
const onChange = useCallback((e)=>{
|
|
81
122
|
const { value = "" } = e.target;
|
|
82
|
-
setValue((v)=>
|
|
123
|
+
setValue((v)=>{
|
|
124
|
+
const current = showOperatorPicker ? normalizeColumnFilterValue(operator, v) : v;
|
|
125
|
+
return Array.isArray(current) ? [
|
|
83
126
|
value,
|
|
84
|
-
|
|
85
|
-
] : value
|
|
127
|
+
current[1]
|
|
128
|
+
] : value;
|
|
129
|
+
});
|
|
86
130
|
onColumnFilterChange?.(e.target.value, column, operator);
|
|
87
131
|
}, [
|
|
88
132
|
column,
|
|
89
133
|
onColumnFilterChange,
|
|
90
134
|
operator,
|
|
91
|
-
setValue
|
|
135
|
+
setValue,
|
|
136
|
+
showOperatorPicker
|
|
92
137
|
]);
|
|
93
138
|
const onRangeInputChange = useCallback((e)=>{
|
|
94
139
|
const { value = "" } = e.target;
|
|
95
|
-
setValue((v)=>
|
|
96
|
-
|
|
140
|
+
setValue((v)=>{
|
|
141
|
+
const current = showOperatorPicker ? normalizeColumnFilterValue(operator, v) : v;
|
|
142
|
+
return Array.isArray(current) ? [
|
|
143
|
+
current[0],
|
|
97
144
|
value
|
|
98
|
-
] : value
|
|
145
|
+
] : value;
|
|
146
|
+
});
|
|
99
147
|
onColumnRangeFilterChange?.(value, column, operator);
|
|
100
148
|
}, [
|
|
101
149
|
setValue,
|
|
102
150
|
onColumnRangeFilterChange,
|
|
103
151
|
column,
|
|
104
|
-
operator
|
|
152
|
+
operator,
|
|
153
|
+
showOperatorPicker
|
|
105
154
|
]);
|
|
106
155
|
const InputProps = useMemo(()=>injectInputProps(InputPropsProp, {
|
|
107
156
|
onChange,
|
|
@@ -122,9 +171,12 @@ const useColumnFilter = ({ InputProps: InputPropsProp, column, defaultValue, ext
|
|
|
122
171
|
return {
|
|
123
172
|
InputProps,
|
|
124
173
|
InputPropsRange,
|
|
125
|
-
isInvalid,
|
|
174
|
+
isInvalid: showOperatorPicker ? Array.isArray(value) && !isValidRange(value) : isInvalid,
|
|
126
175
|
onCommit: handleCommit,
|
|
127
|
-
onCommitRange: handleRangeCommit
|
|
176
|
+
onCommitRange: handleRangeCommit,
|
|
177
|
+
operator,
|
|
178
|
+
operators,
|
|
179
|
+
onOperatorSelect: handleOperatorSelect
|
|
128
180
|
};
|
|
129
181
|
};
|
|
130
182
|
export { useColumnFilter };
|
|
@@ -1,10 +1,37 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Option, useForkRef } from "@salt-ds/core";
|
|
2
|
+
import { Dropdown, Option, useForkRef } from "@salt-ds/core";
|
|
3
3
|
import { forwardRef } from "react";
|
|
4
4
|
import { ExpandoCombobox } from "../ExpandoCombobox.js";
|
|
5
5
|
import { getOperators } from "./operator-utils.js";
|
|
6
6
|
import { useOperatorPicker } from "./useOperatorPicker.js";
|
|
7
|
-
const OperatorPicker_OperatorPicker = /*#__PURE__*/ forwardRef(function(
|
|
7
|
+
const OperatorPicker_OperatorPicker = /*#__PURE__*/ forwardRef(function(props, forwardedRef) {
|
|
8
|
+
if ("dropdown" === props.variant) {
|
|
9
|
+
const { operators, value, onSelect, variant: _variant, ...dropdownProps } = props;
|
|
10
|
+
return /*#__PURE__*/ jsx("div", {
|
|
11
|
+
ref: forwardedRef,
|
|
12
|
+
"data-field": "operator",
|
|
13
|
+
children: /*#__PURE__*/ jsx(Dropdown, {
|
|
14
|
+
...dropdownProps,
|
|
15
|
+
value: value,
|
|
16
|
+
selected: [
|
|
17
|
+
value
|
|
18
|
+
],
|
|
19
|
+
onSelectionChange: (evt, [operator])=>{
|
|
20
|
+
if (void 0 !== operator) onSelect(evt, operator);
|
|
21
|
+
},
|
|
22
|
+
children: operators.map((op)=>/*#__PURE__*/ jsx(Option, {
|
|
23
|
+
value: op,
|
|
24
|
+
children: op
|
|
25
|
+
}, op))
|
|
26
|
+
})
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return /*#__PURE__*/ jsx(OperatorPicker_OperatorCombobox, {
|
|
30
|
+
...props,
|
|
31
|
+
ref: forwardedRef
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
const OperatorPicker_OperatorCombobox = /*#__PURE__*/ forwardRef(function({ className, column, dropdownOnAutofocus = true, inputProps, onSelect, operators, value: valueProp }, forwardedRef) {
|
|
8
35
|
const { ref, ...comboProps } = useOperatorPicker({
|
|
9
36
|
onSelect,
|
|
10
37
|
value: valueProp?.toString() ?? ""
|
|
@@ -17,7 +44,7 @@ const OperatorPicker_OperatorPicker = /*#__PURE__*/ forwardRef(function({ classN
|
|
|
17
44
|
inputProps: inputProps,
|
|
18
45
|
ref: useForkRef(forwardedRef, ref),
|
|
19
46
|
title: "operator",
|
|
20
|
-
children: getOperators(column).filter((op)=>op.toLowerCase().includes(comboProps.value.toLowerCase())).map((op)=>/*#__PURE__*/ jsx(Option, {
|
|
47
|
+
children: (operators ?? getOperators(column)).filter((op)=>op.toLowerCase().includes(comboProps.value.toLowerCase())).map((op)=>/*#__PURE__*/ jsx(Option, {
|
|
21
48
|
value: op
|
|
22
49
|
}, op))
|
|
23
50
|
});
|
|
@@ -3,14 +3,16 @@ import clsx from "clsx";
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { ColumnFilterContext, useFilterContainer, useFilterContext } from "./useFilterContainer.js";
|
|
5
5
|
import { ColumnFilter } from "../column-filter/ColumnFilter.js";
|
|
6
|
-
import { filterDescriptorHasFilter, isNullFilter, useColumnFilterRegistry, useSavedFilters } from "../filter-provider/FilterContext.js";
|
|
6
|
+
import { UNSAVED_FILTER, filterDescriptorHasFilter, isNullFilter, useColumnFilterRegistry, useSavedFilters } from "../filter-provider/FilterContext.js";
|
|
7
7
|
import { filtersAreEqual, getColumnValueFromFilter, getDefaultTimeRange, isBetweenOperator, isTimeDataValue, withDateTimePattern } from "@vuu-ui/vuu-utils";
|
|
8
|
+
import { useControlled } from "@salt-ds/core";
|
|
9
|
+
import { getColumnFilterClause, getColumnFilterOperator, getColumnFilterOperators, getDefaultColumnFilterOperator, normalizeColumnFilterValue } from "../column-filter/column-filter-utils.js";
|
|
8
10
|
import { useComponentCssInjection } from "@salt-ds/styles";
|
|
9
11
|
import { useWindow } from "@salt-ds/window";
|
|
10
12
|
import FilterContainer from "./FilterContainer.css";
|
|
11
13
|
const classBase = "vuuFilterContainer";
|
|
12
14
|
const notEmpty = (value)=>Array.isArray(value) ? "" !== value[0] && "" !== value[1] : "" !== value;
|
|
13
|
-
const FilterContainerColumnFilter = ({ column: columnProp, operator =
|
|
15
|
+
const FilterContainerColumnFilter = ({ column: columnProp, operator: operatorProp, defaultOperator, showOperatorPicker = false, operators, onOperatorChange, pattern: patternProp, variant, ...props })=>{
|
|
14
16
|
const { getColumnFilterPattern } = useColumnFilterRegistry();
|
|
15
17
|
const pattern = patternProp ?? getColumnFilterPattern(columnProp);
|
|
16
18
|
const { date, time } = pattern ?? {};
|
|
@@ -22,7 +24,20 @@ const FilterContainerColumnFilter = ({ column: columnProp, operator = "=", patte
|
|
|
22
24
|
date,
|
|
23
25
|
time
|
|
24
26
|
]);
|
|
25
|
-
const { filterProviderKey, onChange: onFilterContextChange, onCommit: onFilterContextCommit, register } = useFilterContext(column, true);
|
|
27
|
+
const { filter: containerFilter, getFilter, filterProviderKey, onChange: onFilterContextChange, onCommit: onFilterContextCommit, register } = useFilterContext(column, true);
|
|
28
|
+
const availableOperators = useMemo(()=>showOperatorPicker ? getColumnFilterOperators(column, operators) : void 0, [
|
|
29
|
+
column,
|
|
30
|
+
operators,
|
|
31
|
+
showOperatorPicker
|
|
32
|
+
]);
|
|
33
|
+
const [initialOperator] = useState(()=>availableOperators ? getDefaultColumnFilterOperator(availableOperators, operatorProp ?? getColumnFilterOperator(column, containerFilter) ?? defaultOperator) : defaultOperator ?? "=");
|
|
34
|
+
const [selectedOperator, setOperator] = useControlled({
|
|
35
|
+
controlled: operatorProp,
|
|
36
|
+
default: initialOperator,
|
|
37
|
+
name: "FilterContainerColumnFilter",
|
|
38
|
+
state: "operator"
|
|
39
|
+
});
|
|
40
|
+
const operator = selectedOperator;
|
|
26
41
|
const { registerColumnFilterColumn } = useColumnFilterRegistry(filterProviderKey);
|
|
27
42
|
useEffect(()=>registerColumnFilterColumn(column), [
|
|
28
43
|
column,
|
|
@@ -35,10 +50,50 @@ const FilterContainerColumnFilter = ({ column: columnProp, operator = "=", patte
|
|
|
35
50
|
]);
|
|
36
51
|
const [value, setValue] = useState(initialValue);
|
|
37
52
|
const valueRef = useRef(initialValue);
|
|
53
|
+
if (showOperatorPicker) {
|
|
54
|
+
const normalizedValue = normalizeColumnFilterValue(operator, value);
|
|
55
|
+
if (normalizedValue !== value) {
|
|
56
|
+
valueRef.current = normalizedValue;
|
|
57
|
+
setValue(normalizedValue);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
38
60
|
const { currentFilter } = useSavedFilters(filterProviderKey);
|
|
39
61
|
const currentFilterRef = useRef(currentFilter);
|
|
62
|
+
const containerFilterRef = useRef(containerFilter);
|
|
63
|
+
const localFilterRef = useRef(containerFilter);
|
|
64
|
+
useMemo(()=>{
|
|
65
|
+
if (!showOperatorPicker) return;
|
|
66
|
+
const containerChanged = !filtersAreEqual(containerFilterRef.current, containerFilter);
|
|
67
|
+
const savedChanged = currentFilterRef.current.id !== currentFilter.id || !filtersAreEqual(currentFilterRef.current.filter, currentFilter.filter);
|
|
68
|
+
if (containerChanged || savedChanged) {
|
|
69
|
+
const savedIdChanged = currentFilterRef.current.id !== currentFilter.id;
|
|
70
|
+
const filter = containerChanged ? containerFilter : currentFilter.filter ?? void 0;
|
|
71
|
+
containerFilterRef.current = containerFilter;
|
|
72
|
+
currentFilterRef.current = currentFilter;
|
|
73
|
+
const savedFilterActivated = savedIdChanged && filterDescriptorHasFilter(currentFilter) && currentFilter.id !== UNSAVED_FILTER;
|
|
74
|
+
const clause = getColumnFilterClause(column, filter);
|
|
75
|
+
if (savedFilterActivated || !filtersAreEqual(clause, getColumnFilterClause(column, localFilterRef.current))) {
|
|
76
|
+
const nextOperator = operatorProp ?? (availableOperators ? getDefaultColumnFilterOperator(availableOperators, getColumnFilterOperator(column, filter) ?? defaultOperator) : operator);
|
|
77
|
+
const nextValue = normalizeColumnFilterValue(nextOperator, getColumnValueFromFilter(column, nextOperator, clause));
|
|
78
|
+
setOperator(nextOperator);
|
|
79
|
+
valueRef.current = nextValue;
|
|
80
|
+
setValue(nextValue);
|
|
81
|
+
localFilterRef.current = filter;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, [
|
|
85
|
+
availableOperators,
|
|
86
|
+
column,
|
|
87
|
+
containerFilter,
|
|
88
|
+
currentFilter,
|
|
89
|
+
defaultOperator,
|
|
90
|
+
operator,
|
|
91
|
+
operatorProp,
|
|
92
|
+
setOperator,
|
|
93
|
+
showOperatorPicker
|
|
94
|
+
]);
|
|
40
95
|
useMemo(()=>{
|
|
41
|
-
if (currentFilterRef.current.id !== currentFilter.id || !filtersAreEqual(currentFilterRef.current.filter, currentFilter.filter)) {
|
|
96
|
+
if (!showOperatorPicker && (currentFilterRef.current.id !== currentFilter.id || !filtersAreEqual(currentFilterRef.current.filter, currentFilter.filter))) {
|
|
42
97
|
currentFilterRef.current = currentFilter;
|
|
43
98
|
if (isNullFilter(currentFilter) && notEmpty(valueRef.current)) {
|
|
44
99
|
if (Array.isArray(valueRef.current)) if (isTimeDataValue(column)) valueRef.current = getDefaultTimeRange(column);
|
|
@@ -66,13 +121,16 @@ const FilterContainerColumnFilter = ({ column: columnProp, operator = "=", patte
|
|
|
66
121
|
}
|
|
67
122
|
}, [
|
|
68
123
|
column,
|
|
69
|
-
currentFilter
|
|
124
|
+
currentFilter,
|
|
125
|
+
showOperatorPicker
|
|
70
126
|
]);
|
|
71
127
|
const handleCommit = useCallback((column, op, value, extendedFilterOptions)=>{
|
|
72
128
|
valueRef.current = value;
|
|
73
129
|
setValue(value);
|
|
74
130
|
onFilterContextCommit(column, op, value, extendedFilterOptions);
|
|
131
|
+
localFilterRef.current = getFilter();
|
|
75
132
|
}, [
|
|
133
|
+
getFilter,
|
|
76
134
|
onFilterContextCommit
|
|
77
135
|
]);
|
|
78
136
|
const handleColumnFilterChange = useCallback((value, column, op)=>{
|
|
@@ -83,7 +141,9 @@ const FilterContainerColumnFilter = ({ column: columnProp, operator = "=", patte
|
|
|
83
141
|
] : value;
|
|
84
142
|
setValue(valueRef.current);
|
|
85
143
|
onFilterContextChange(valueRef.current, column, op);
|
|
144
|
+
localFilterRef.current = getFilter();
|
|
86
145
|
}, [
|
|
146
|
+
getFilter,
|
|
87
147
|
onFilterContextChange
|
|
88
148
|
]);
|
|
89
149
|
const handleColumnRangeFilterChange = useCallback((value, column, op)=>{
|
|
@@ -94,7 +154,9 @@ const FilterContainerColumnFilter = ({ column: columnProp, operator = "=", patte
|
|
|
94
154
|
] : value;
|
|
95
155
|
setValue(valueRef.current);
|
|
96
156
|
onFilterContextChange(valueRef.current, column, op);
|
|
157
|
+
localFilterRef.current = getFilter();
|
|
97
158
|
}, [
|
|
159
|
+
getFilter,
|
|
98
160
|
onFilterContextChange
|
|
99
161
|
]);
|
|
100
162
|
return /*#__PURE__*/ jsx(ColumnFilter, {
|
|
@@ -104,6 +166,14 @@ const FilterContainerColumnFilter = ({ column: columnProp, operator = "=", patte
|
|
|
104
166
|
onColumnRangeFilterChange: handleColumnRangeFilterChange,
|
|
105
167
|
onCommit: handleCommit,
|
|
106
168
|
operator: operator,
|
|
169
|
+
onOperatorChange: (event, op)=>{
|
|
170
|
+
setOperator(op);
|
|
171
|
+
valueRef.current = normalizeColumnFilterValue(op, valueRef.current);
|
|
172
|
+
setValue(valueRef.current);
|
|
173
|
+
onOperatorChange?.(event, op);
|
|
174
|
+
},
|
|
175
|
+
operators: operators,
|
|
176
|
+
showOperatorPicker: showOperatorPicker,
|
|
107
177
|
value: value,
|
|
108
178
|
variant: variant
|
|
109
179
|
});
|
|
@@ -7,6 +7,8 @@ const ColumnFilterContext = createContext({
|
|
|
7
7
|
function useFilterContext(column, throwIfNoContainer = false) {
|
|
8
8
|
const ctx = useContext(ColumnFilterContext);
|
|
9
9
|
if (ctx) return {
|
|
10
|
+
filter: ctx.filter,
|
|
11
|
+
getFilter: ctx.getFilter,
|
|
10
12
|
filterProviderKey: ctx.filterProviderKey,
|
|
11
13
|
register: ctx.register,
|
|
12
14
|
getValue: ctx.getValue,
|
|
@@ -29,6 +31,9 @@ const useFilterContainer = ({ filter, filterProviderKey = "GLOBAL", onFilterAppl
|
|
|
29
31
|
const filterAggregator = useMemo(()=>new FilterAggregator(filter), [
|
|
30
32
|
filter
|
|
31
33
|
]);
|
|
34
|
+
const getFilter = useCallback(()=>filterAggregator.filter, [
|
|
35
|
+
filterAggregator
|
|
36
|
+
]);
|
|
32
37
|
const register = useCallback((column, op)=>valueRef.current[column.name] = getColumnValueFromFilter(column, op, filterRef.current), []);
|
|
33
38
|
const getValue = useCallback((column, fallbackValue)=>{
|
|
34
39
|
const value = valueRef.current[column.name];
|
|
@@ -72,6 +77,8 @@ const useFilterContainer = ({ filter, filterProviderKey = "GLOBAL", onFilterAppl
|
|
|
72
77
|
]);
|
|
73
78
|
return {
|
|
74
79
|
filterContainerInstalled: true,
|
|
80
|
+
filter,
|
|
81
|
+
getFilter,
|
|
75
82
|
filterProviderKey,
|
|
76
83
|
onChange: handleInputChange,
|
|
77
84
|
onCommit: handleCommit,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ColumnFilterOp, ColumnFilterValue, FilterContainerFilter } from "@vuu-ui/vuu-filter-types";
|
|
2
|
+
import type { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
|
+
export type SelectableColumnFilterOp = Exclude<ColumnFilterOp, "in">;
|
|
4
|
+
export declare const getColumnFilterOperators: (column: ColumnDescriptor, operators?: readonly SelectableColumnFilterOp[]) => readonly SelectableColumnFilterOp[];
|
|
5
|
+
export declare const getDefaultColumnFilterOperator: (operators: readonly SelectableColumnFilterOp[], operator?: ColumnFilterOp) => SelectableColumnFilterOp;
|
|
6
|
+
export declare const getColumnFilterOperator: (column: ColumnDescriptor, filter?: FilterContainerFilter) => SelectableColumnFilterOp | undefined;
|
|
7
|
+
export declare const getColumnFilterClause: (column: ColumnDescriptor, filter?: FilterContainerFilter) => FilterContainerFilter | undefined;
|
|
8
|
+
export declare const normalizeColumnFilterValue: (operator: ColumnFilterOp, value?: ColumnFilterValue) => ColumnFilterValue;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ColumnFilterChangeHandler, ColumnFilterCommitHandler, ColumnFilterOp, ColumnFilterValue, ExtendedFilterOptions } from "@vuu-ui/vuu-filter-types";
|
|
2
2
|
import { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
3
|
import { InputProps } from "@salt-ds/core";
|
|
4
|
+
import { SyntheticEvent } from "react";
|
|
4
5
|
import { CommitHandler } from "@vuu-ui/vuu-utils";
|
|
5
6
|
import { DataItemEditControlProps } from "@vuu-ui/vuu-data-react";
|
|
7
|
+
import { type SelectableColumnFilterOp } from "./column-filter-utils";
|
|
6
8
|
export interface ColumnFilterHookProps extends Pick<DataItemEditControlProps, "InputProps"> {
|
|
7
9
|
column: ColumnDescriptor;
|
|
8
10
|
/**
|
|
@@ -27,17 +29,29 @@ export interface ColumnFilterHookProps extends Pick<DataItemEditControlProps, "I
|
|
|
27
29
|
* tabbing away from control or making selection from list
|
|
28
30
|
*/
|
|
29
31
|
onCommit: ColumnFilterCommitHandler;
|
|
32
|
+
/** Controlled operator. Defaults to '=' when the picker is hidden. */
|
|
30
33
|
operator?: ColumnFilterOp;
|
|
34
|
+
/** Initial operator for an uncontrolled picker. Defaults to '=' or the first option. */
|
|
35
|
+
defaultOperator?: ColumnFilterOp;
|
|
36
|
+
/** Render an operator dropdown before the value. Defaults to false. */
|
|
37
|
+
showOperatorPicker?: boolean;
|
|
38
|
+
/** Ordered operator options, replacing the column-type defaults. 'in' is not supported. */
|
|
39
|
+
operators?: readonly SelectableColumnFilterOp[];
|
|
40
|
+
/** Called before committing the current value with the newly selected operator. */
|
|
41
|
+
onOperatorChange?: (event: SyntheticEvent, operator: ColumnFilterOp) => void;
|
|
31
42
|
/**
|
|
32
43
|
* Filter value. Pair of values expected when operator is
|
|
33
44
|
* 'between'. If provided, component is controlled.
|
|
34
45
|
*/
|
|
35
46
|
value?: ColumnFilterValue;
|
|
36
47
|
}
|
|
37
|
-
export declare const useColumnFilter: ({ InputProps: InputPropsProp, column, defaultValue, extendedFilterOptions, onColumnFilterChange, onColumnRangeFilterChange, onCommit, operator, value: valueProp, }: ColumnFilterHookProps) => {
|
|
48
|
+
export declare const useColumnFilter: ({ InputProps: InputPropsProp, column, defaultValue, defaultOperator, extendedFilterOptions, onColumnFilterChange, onColumnRangeFilterChange, onCommit, onOperatorChange, operator: operatorProp, operators: operatorsProp, showOperatorPicker, value: valueProp, }: ColumnFilterHookProps) => {
|
|
38
49
|
InputProps: InputProps;
|
|
39
50
|
InputPropsRange: InputProps;
|
|
40
51
|
isInvalid: boolean;
|
|
41
52
|
onCommit: CommitHandler<HTMLElement>;
|
|
42
53
|
onCommitRange: CommitHandler<HTMLElement>;
|
|
54
|
+
operator: "in" | SelectableColumnFilterOp;
|
|
55
|
+
operators: readonly SelectableColumnFilterOp[] | undefined;
|
|
56
|
+
onOperatorSelect: (event: SyntheticEvent, newOperator: ColumnFilterOp) => void;
|
|
43
57
|
};
|
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import type { FilterClauseOp } from "@vuu-ui/vuu-filter-types";
|
|
1
|
+
import type { ColumnFilterOp, FilterClauseOp } from "@vuu-ui/vuu-filter-types";
|
|
2
2
|
import type { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
3
|
import { ComboBoxProps } from "@salt-ds/core";
|
|
4
4
|
import { SyntheticEvent } from "react";
|
|
5
|
-
|
|
5
|
+
type OperatorComboboxProps = Pick<ComboBoxProps, "className" | "inputProps" | "value"> & {
|
|
6
6
|
column: ColumnDescriptor;
|
|
7
7
|
onSelect: (evt: SyntheticEvent, operator: FilterClauseOp) => void;
|
|
8
8
|
dropdownOnAutofocus?: boolean;
|
|
9
|
+
variant?: "combobox";
|
|
10
|
+
operators?: readonly FilterClauseOp[];
|
|
9
11
|
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
type OperatorDropdownProps = {
|
|
13
|
+
variant: "dropdown";
|
|
14
|
+
className?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
readOnly?: boolean;
|
|
17
|
+
operators: readonly ColumnFilterOp[];
|
|
18
|
+
value: ColumnFilterOp;
|
|
19
|
+
onSelect: (evt: SyntheticEvent, operator: ColumnFilterOp) => void;
|
|
20
|
+
"aria-label"?: string;
|
|
21
|
+
};
|
|
22
|
+
export type OperatorPickerProps = OperatorComboboxProps | OperatorDropdownProps;
|
|
23
|
+
export declare const OperatorPicker: import("react").ForwardRefExoticComponent<OperatorPickerProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
24
|
+
export {};
|
|
@@ -16,7 +16,7 @@ export interface FilterContainerColumnFilterProps extends Omit<ColumnFilterProps
|
|
|
16
16
|
*/
|
|
17
17
|
pattern?: DateTimePattern;
|
|
18
18
|
}
|
|
19
|
-
export declare const FilterContainerColumnFilter: ({ column: columnProp, operator, pattern: patternProp, variant, ...props }: FilterContainerColumnFilterProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare const FilterContainerColumnFilter: ({ column: columnProp, operator: operatorProp, defaultOperator, showOperatorPicker, operators, onOperatorChange, pattern: patternProp, variant, ...props }: FilterContainerColumnFilterProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
/**
|
|
21
21
|
* FilterContainer is a generic UI container for a collection of Filter
|
|
22
22
|
* controls. Each control manages a single filter clause and the Filter
|
|
@@ -2,6 +2,8 @@ import { ColumnFilterChangeHandler, ColumnFilterCommitHandler, ColumnFilterOp, C
|
|
|
2
2
|
import { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
3
|
export interface ColumnFilterContextProps {
|
|
4
4
|
filterContainerInstalled: boolean;
|
|
5
|
+
filter?: FilterContainerFilter;
|
|
6
|
+
getFilter?: () => FilterContainerFilter | undefined;
|
|
5
7
|
filterProviderKey?: string;
|
|
6
8
|
onChange?: ColumnFilterChangeHandler;
|
|
7
9
|
onCommit?: ColumnFilterCommitHandler;
|
|
@@ -10,7 +12,7 @@ export interface ColumnFilterContextProps {
|
|
|
10
12
|
}
|
|
11
13
|
export declare const ColumnFilterContext: import("react").Context<ColumnFilterContextProps>;
|
|
12
14
|
export declare function useFilterContext(column: ColumnDescriptor, throwIfNoContainer?: false): ColumnFilterContextProps;
|
|
13
|
-
export declare function useFilterContext(column: ColumnDescriptor, throwIfNoContainer: true): Required<ColumnFilterContextProps>;
|
|
15
|
+
export declare function useFilterContext(column: ColumnDescriptor, throwIfNoContainer: true): Required<Omit<ColumnFilterContextProps, "filter">> & Pick<ColumnFilterContextProps, "filter">;
|
|
14
16
|
export type FilterAppliedHandler<F extends Filter = Filter> = (filter: F) => void;
|
|
15
17
|
export type ColumnFilterContainerHookProps = {
|
|
16
18
|
filter?: FilterContainerFilter;
|
package/types/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ColumnFilter, type ColumnFilterProps, } from "./column-filter/ColumnFilter";
|
|
2
|
+
export type { SelectableColumnFilterOp } from "./column-filter/column-filter-utils";
|
|
2
3
|
export * from "./filter-bar";
|
|
3
4
|
export * from "./filter-clause";
|
|
4
5
|
export { ExtendedSingleValueFilterClause } from "./filter-container/ExtendedSingleValueFilterClause";
|