@vuu-ui/vuu-filters 0.13.78 → 0.13.79

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.
Files changed (73) hide show
  1. package/README.md +95 -0
  2. package/cjs/FilterAggregator.js +150 -0
  3. package/cjs/FilterAggregator.js.map +1 -0
  4. package/cjs/column-filter/ColumnFilter.css.js +6 -0
  5. package/cjs/column-filter/ColumnFilter.css.js.map +1 -0
  6. package/cjs/column-filter/ColumnFilter.js +17 -3
  7. package/cjs/column-filter/ColumnFilter.js.map +1 -1
  8. package/cjs/column-filter/useColumnFilter.js +38 -8
  9. package/cjs/column-filter/useColumnFilter.js.map +1 -1
  10. package/cjs/custom-filters/CustomFilters.js +2 -0
  11. package/cjs/custom-filters/CustomFilters.js.map +1 -1
  12. package/cjs/custom-filters/useCustomFilters.js +7 -3
  13. package/cjs/custom-filters/useCustomFilters.js.map +1 -1
  14. package/cjs/filter-bar/FilterBar.js +3 -0
  15. package/cjs/filter-bar/FilterBar.js.map +1 -1
  16. package/cjs/filter-container/ExtendedSingleValueFilterClause.js +63 -0
  17. package/cjs/filter-container/ExtendedSingleValueFilterClause.js.map +1 -0
  18. package/cjs/filter-container/FilterContainer.js +3 -3
  19. package/cjs/filter-container/FilterContainer.js.map +1 -1
  20. package/cjs/filter-container/useFilterContainer.js +11 -10
  21. package/cjs/filter-container/useFilterContainer.js.map +1 -1
  22. package/cjs/index.js +4 -2
  23. package/cjs/index.js.map +1 -1
  24. package/cjs/inline-filter/InlineFilter.js +3 -10
  25. package/cjs/inline-filter/InlineFilter.js.map +1 -1
  26. package/cjs/inline-filter/useInlineFilter.js +1 -16
  27. package/cjs/inline-filter/useInlineFilter.js.map +1 -1
  28. package/cjs/quick-filters/QuickFilters.js +2 -0
  29. package/cjs/quick-filters/QuickFilters.js.map +1 -1
  30. package/cjs/quick-filters/useQuickFilters.js +9 -14
  31. package/cjs/quick-filters/useQuickFilters.js.map +1 -1
  32. package/esm/FilterAggregator.js +148 -0
  33. package/esm/FilterAggregator.js.map +1 -0
  34. package/esm/column-filter/ColumnFilter.css.js +4 -0
  35. package/esm/column-filter/ColumnFilter.css.js.map +1 -0
  36. package/esm/column-filter/ColumnFilter.js +17 -3
  37. package/esm/column-filter/ColumnFilter.js.map +1 -1
  38. package/esm/column-filter/useColumnFilter.js +39 -9
  39. package/esm/column-filter/useColumnFilter.js.map +1 -1
  40. package/esm/custom-filters/CustomFilters.js +2 -0
  41. package/esm/custom-filters/CustomFilters.js.map +1 -1
  42. package/esm/custom-filters/useCustomFilters.js +8 -4
  43. package/esm/custom-filters/useCustomFilters.js.map +1 -1
  44. package/esm/filter-bar/FilterBar.js +3 -0
  45. package/esm/filter-bar/FilterBar.js.map +1 -1
  46. package/esm/filter-container/ExtendedSingleValueFilterClause.js +60 -0
  47. package/esm/filter-container/ExtendedSingleValueFilterClause.js.map +1 -0
  48. package/esm/filter-container/FilterContainer.js +4 -4
  49. package/esm/filter-container/FilterContainer.js.map +1 -1
  50. package/esm/filter-container/useFilterContainer.js +11 -10
  51. package/esm/filter-container/useFilterContainer.js.map +1 -1
  52. package/esm/index.js +2 -1
  53. package/esm/index.js.map +1 -1
  54. package/esm/inline-filter/InlineFilter.js +3 -10
  55. package/esm/inline-filter/InlineFilter.js.map +1 -1
  56. package/esm/inline-filter/useInlineFilter.js +1 -16
  57. package/esm/inline-filter/useInlineFilter.js.map +1 -1
  58. package/esm/quick-filters/QuickFilters.js +2 -0
  59. package/esm/quick-filters/QuickFilters.js.map +1 -1
  60. package/esm/quick-filters/useQuickFilters.js +10 -15
  61. package/esm/quick-filters/useQuickFilters.js.map +1 -1
  62. package/package.json +11 -11
  63. package/types/FilterAggregator.d.ts +22 -0
  64. package/types/column-filter/useColumnFilter.d.ts +7 -2
  65. package/types/custom-filters/CustomFilters.d.ts +2 -2
  66. package/types/custom-filters/useCustomFilters.d.ts +2 -2
  67. package/types/filter-bar/FilterBar.d.ts +5 -5
  68. package/types/filter-container/ExtendedSingleValueFilterClause.d.ts +21 -0
  69. package/types/index.d.ts +2 -1
  70. package/types/inline-filter/InlineFilter.d.ts +4 -2
  71. package/types/inline-filter/useInlineFilter.d.ts +1 -7
  72. package/types/quick-filters/QuickFilters.d.ts +2 -2
  73. package/types/quick-filters/useQuickFilters.d.ts +2 -2
package/README.md CHANGED
@@ -0,0 +1,95 @@
1
+ # Life of a filter
2
+
3
+ ## Filter
4
+
5
+ Filters are applied to data and Vuu data is arranged in rows and columns. Filters are defined in terms of tests applied against column values. There are a fixed set of filter operators that the Vuu filter engine supports. A single test applied to a data column is a `FilterClause`, these are examples of `SingleValueFilterClause`
6
+
7
+ - currency = "GBP"
8
+ - price > 1000
9
+ - name starts "Nat"
10
+ - cancelled = false
11
+
12
+ Vuu also supports `MultiValueFilterClause`
13
+
14
+ - status in ["CANCELLED", "REJECTED"]
15
+
16
+ ## ColumnFilter
17
+
18
+ onCommit is a `ColumnFilterCommitHandler`
19
+
20
+ ```typescript
21
+ type ColumnFilterCommitHandler = (
22
+ column: ColumnDescriptor,
23
+ op: FilterClauseOp | "between" | "between-inclusive",
24
+ value: ColumnFilterValue,
25
+ ) => void;
26
+ ```
27
+
28
+ When used with a `FilterContainer` and `FilterProvider`, the `ColumnFilter` is wrapped with a `FilterContainerColumnFilter`. The commit is re-raised to the `FilterContainer` via `useFilterContainer.onCommit`. Here the filter will be added to a `FilterAggregator` and the `onFilterApplied` callback will be invoked, with the combined composite filter incorporating each individual clause created via individual `ColumnFilter` controls. Note, the `Filter` applied is a `FilterContainerFilter`, a slightly constrained variant of a full `Filter`, see definition below. It supports a single clause or an ANDed collection of clauses. The clauses can be the simplest type - `SingleValueFilterClause` or they can be `between` clauses for range filters.
29
+
30
+ A `ColumnFilter` can be used as a standalone control, in which case it can be used in either controlled or uncontrolled mode. It is then entirely the responsibility of the caller to translate the details from the `onCommit` callback to a useable filter and to apply that filter.
31
+
32
+ ```typescript
33
+ type FilterContainerFilter =
34
+ | SingleValueFilterClause
35
+ | MultiClauseFilter<
36
+ "and",
37
+ | SingleValueFilterClause
38
+ | MultiClauseFilter<"and", SingleValueFilterClause>
39
+ >;
40
+
41
+ type FilterAppliedHandler = (filter: FilterContainerFilter) => void;
42
+ ```
43
+
44
+ ## FilterContainer
45
+
46
+ A pure container component that can be used to manage one or more `ColumnFilter` controls. The `onCommit` callback events from nested `ColumnFilter`s will be translated to a higher level commit that combines the details of individual `ColumnFilter`s to a single `Filter`. This higher level commit callback is `onFilterApplied`. Conversely, if filter details have been entirely cleared, an `onFilterCleared` callback will be invoked.
47
+
48
+ ## FilterPanel, InlineFilter
49
+
50
+ These are both container controls thet employ a nested `FilterContainer` to manage a collection of `ColumnFilter`s. The `FilterPanel` renders a panel of filters, with clear and save buttons. The `InlineFilter` renders a Table Row that can be embedded within a data Table. It renders a filter per column, each filter rendered within a Table Cell.
51
+
52
+ ## FilterProvider
53
+
54
+ A `FilterProvider` can be used to orchestrate a filter or filters across the entirety of an application or across a subset of an application.
55
+ It sits higher in the component hierarchy than a `FilterPanel` or `FilterContainer` and allows disparate components to collaborate over the manipulation and application of filters.
56
+
57
+ ## DataSource
58
+
59
+ A `DataSource` is always the ultimate target of a filter. It is by setting the `filter` property of a `DataSource` that we actually filter data.
60
+
61
+ prop `filter` is a `DataSourceFilter`
62
+
63
+ ```typescript
64
+ type VuuFilter = {
65
+ filter: string;
66
+ };
67
+
68
+ interface SingleValueFilterClause
69
+ name?: string
70
+ op: SingleValueFilterClauseOp;
71
+ column: string;
72
+ value: string | number | boolean;
73
+ }
74
+ interface MultiValueFilterClause
75
+ name?: string
76
+ op: MultipleValueFilterClauseOp;
77
+ column: string;
78
+ values: string[] | number[] | boolean[];
79
+ }
80
+
81
+ interface MultiClauseFilter {
82
+ name?: string
83
+ op: FilterCombinatorOp;
84
+ filters: Filter[];
85
+ }
86
+
87
+ type Filter = MultiClauseFilter | SingleValueFilterClause | MultiValueFilterClause;
88
+
89
+ interface DataSourceFilter {
90
+ filter: string;
91
+ filterStruct?: Filter;
92
+ }
93
+ ```
94
+
95
+ ##Saved Filters
@@ -0,0 +1,150 @@
1
+ 'use strict';
2
+
3
+ var vuuUtils = require('@vuu-ui/vuu-utils');
4
+ var ExtendedSingleValueFilterClause = require('./filter-container/ExtendedSingleValueFilterClause.js');
5
+
6
+ var __typeError = (msg) => {
7
+ throw TypeError(msg);
8
+ };
9
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
10
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
11
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
12
+ var _filters;
13
+ function installExtendedFilters(filter, throwIfUndefined = false) {
14
+ if (filter !== void 0) {
15
+ if (vuuUtils.isExtendedFilter(filter)) {
16
+ const { column, op, value, extendedOptions } = filter;
17
+ return new ExtendedSingleValueFilterClause.ExtendedSingleValueFilterClause(
18
+ column,
19
+ op,
20
+ value,
21
+ extendedOptions
22
+ );
23
+ } else if (vuuUtils.isMultiClauseFilter(filter)) {
24
+ if (filter.filters.some(vuuUtils.isExtendedFilter)) {
25
+ return {
26
+ op: filter.op,
27
+ filters: filter.filters.map((f) => installExtendedFilters(f, true))
28
+ };
29
+ } else {
30
+ return filter;
31
+ }
32
+ } else {
33
+ return filter;
34
+ }
35
+ }
36
+ if (throwIfUndefined) {
37
+ throw Error("filter is undefined");
38
+ }
39
+ }
40
+ class FilterAggregator {
41
+ constructor(filter) {
42
+ __privateAdd(this, _filters, /* @__PURE__ */ new Map());
43
+ const runtimeFilter = installExtendedFilters(filter);
44
+ if (vuuUtils.isSingleValueFilter(runtimeFilter)) {
45
+ __privateGet(this, _filters).set(runtimeFilter.column, runtimeFilter);
46
+ } else if (vuuUtils.isBetweenFilter(runtimeFilter)) {
47
+ __privateGet(this, _filters).set(runtimeFilter.filters[0].column, runtimeFilter);
48
+ } else if (vuuUtils.isAndFilter(runtimeFilter)) {
49
+ runtimeFilter.filters.forEach((f) => {
50
+ if (vuuUtils.isBetweenFilter(f)) {
51
+ __privateGet(this, _filters).set(f.filters[0].column, f);
52
+ } else {
53
+ __privateGet(this, _filters).set(f.column, f);
54
+ }
55
+ });
56
+ }
57
+ }
58
+ add(column, value, op, extendedFilterOptions) {
59
+ const { serverDataType = "string", type } = column;
60
+ const isInclusive = op === "between-inclusive";
61
+ const dataType = vuuUtils.isTypeDescriptor(type) ? type.name : type ?? serverDataType;
62
+ if (Array.isArray(value)) {
63
+ const [value1, value2] = vuuUtils.getTypedRange(
64
+ value,
65
+ dataType,
66
+ extendedFilterOptions
67
+ );
68
+ if (value1 !== void 0 && value2 !== void 0) {
69
+ const filter = extendedFilterOptions ? {
70
+ op: "and",
71
+ filters: [
72
+ new ExtendedSingleValueFilterClause.ExtendedSingleValueFilterClause(
73
+ column.name,
74
+ isInclusive ? ">=" : ">",
75
+ value1,
76
+ extendedFilterOptions
77
+ ),
78
+ new ExtendedSingleValueFilterClause.ExtendedSingleValueFilterClause(
79
+ column.name,
80
+ isInclusive ? "<=" : "<",
81
+ value2,
82
+ extendedFilterOptions
83
+ )
84
+ ]
85
+ } : {
86
+ op: "and",
87
+ filters: [
88
+ { column: column.name, op: ">", value: value1 },
89
+ { column: column.name, op: "<", value: value2 }
90
+ ]
91
+ };
92
+ __privateGet(this, _filters).set(column.name, filter);
93
+ } else if (value1 !== void 0) {
94
+ __privateGet(this, _filters).set(column.name, {
95
+ column: column.name,
96
+ op: "=",
97
+ value: value1
98
+ });
99
+ } else if (value2 !== void 0) {
100
+ __privateGet(this, _filters).set(column.name, {
101
+ column: column.name,
102
+ op: "<",
103
+ value: value2
104
+ });
105
+ }
106
+ } else {
107
+ const typedValue = vuuUtils.getTypedValue(value.toString(), dataType, true);
108
+ __privateGet(this, _filters).set(column.name, {
109
+ column: column.name,
110
+ op: "=",
111
+ value: typedValue
112
+ });
113
+ }
114
+ }
115
+ has({ name }) {
116
+ return __privateGet(this, _filters).has(name);
117
+ }
118
+ get({ name }) {
119
+ return __privateGet(this, _filters).get(name);
120
+ }
121
+ /**
122
+ * Remove filter for this column. Return false if no filter found, otw true
123
+ */
124
+ remove(column) {
125
+ if (__privateGet(this, _filters).has(column.name)) {
126
+ __privateGet(this, _filters).delete(column.name);
127
+ return true;
128
+ } else {
129
+ return false;
130
+ }
131
+ }
132
+ get filter() {
133
+ const { size } = __privateGet(this, _filters);
134
+ if (size === 0) {
135
+ return void 0;
136
+ } else if (size === 1) {
137
+ const [filter] = __privateGet(this, _filters).values();
138
+ return filter;
139
+ } else {
140
+ return {
141
+ op: "and",
142
+ filters: Array.from(__privateGet(this, _filters).values())
143
+ };
144
+ }
145
+ }
146
+ }
147
+ _filters = new WeakMap();
148
+
149
+ exports.FilterAggregator = FilterAggregator;
150
+ //# sourceMappingURL=FilterAggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterAggregator.js","sources":["../../../packages/vuu-filters/src/FilterAggregator.ts"],"sourcesContent":["import {\n ColumnFilterValue,\n ExtendedFilterOptions,\n FilterClauseOp,\n FilterContainerFilter,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n getTypedRange,\n getTypedValue,\n isAndFilter,\n isBetweenFilter,\n isExtendedFilter,\n isMultiClauseFilter,\n isSingleValueFilter,\n isTypeDescriptor,\n} from \"@vuu-ui/vuu-utils\";\nimport { ExtendedSingleValueFilterClause } from \"./filter-container/ExtendedSingleValueFilterClause\";\n\nfunction installExtendedFilters<\n F extends FilterContainerFilter = FilterContainerFilter,\n>(filter: F, throwIfUndefined: true): F;\nfunction installExtendedFilters<\n F extends FilterContainerFilter = FilterContainerFilter,\n>(filter: F | undefined, throwIfUndefined?: false): F | undefined;\n\nfunction installExtendedFilters(\n filter: FilterContainerFilter | undefined,\n throwIfUndefined = false,\n): FilterContainerFilter | undefined {\n if (filter !== undefined) {\n if (isExtendedFilter(filter)) {\n const { column, op, value, extendedOptions } = filter;\n return new ExtendedSingleValueFilterClause(\n column,\n op,\n value,\n extendedOptions,\n );\n } else if (isMultiClauseFilter(filter)) {\n if (filter.filters.some(isExtendedFilter)) {\n return {\n op: filter.op,\n filters: filter.filters.map((f) => installExtendedFilters(f, true)),\n };\n } else {\n return filter;\n }\n } else {\n return filter;\n }\n }\n if (throwIfUndefined) {\n throw Error(\"filter is undefined\");\n }\n}\n\n/**\n * Manages a filter that can be updated one clause at a time.\n * Works with FilterContainer to aggregate multiple filter\n * clauses edited via individual controls. It is just a wrapper\n * around a Map, does not support switching filters - create a\n * new FilterAggregator for a new filter.\n *\n */\nexport class FilterAggregator {\n #filters = new Map<string, FilterContainerFilter>();\n\n constructor(filter?: FilterContainerFilter) {\n const runtimeFilter = installExtendedFilters(filter);\n if (isSingleValueFilter(runtimeFilter)) {\n this.#filters.set(runtimeFilter.column, runtimeFilter);\n } else if (isBetweenFilter(runtimeFilter)) {\n this.#filters.set(runtimeFilter.filters[0].column, runtimeFilter);\n } else if (isAndFilter(runtimeFilter)) {\n runtimeFilter.filters.forEach((f) => {\n if (isBetweenFilter(f)) {\n this.#filters.set(f.filters[0].column, f);\n } else {\n this.#filters.set(f.column, f);\n }\n });\n }\n }\n\n add(\n column: ColumnDescriptor,\n value: ColumnFilterValue,\n op: FilterClauseOp | \"between\" | \"between-inclusive\",\n extendedFilterOptions?: ExtendedFilterOptions,\n ) {\n const { serverDataType = \"string\", type } = column;\n const isInclusive = op === \"between-inclusive\";\n const dataType = isTypeDescriptor(type)\n ? type.name\n : (type ?? serverDataType);\n if (Array.isArray(value)) {\n const [value1, value2] = getTypedRange(\n value,\n dataType,\n extendedFilterOptions,\n );\n if (value1 !== undefined && value2 !== undefined) {\n const filter: FilterContainerFilter = extendedFilterOptions\n ? {\n op: \"and\",\n filters: [\n new ExtendedSingleValueFilterClause(\n column.name,\n isInclusive ? \">=\" : \">\",\n value1,\n extendedFilterOptions,\n ),\n new ExtendedSingleValueFilterClause(\n column.name,\n isInclusive ? \"<=\" : \"<\",\n value2,\n extendedFilterOptions,\n ),\n ],\n }\n : {\n op: \"and\",\n filters: [\n { column: column.name, op: \">\", value: value1 },\n { column: column.name, op: \"<\", value: value2 },\n ],\n };\n\n this.#filters.set(column.name, filter);\n } else if (value1 !== undefined) {\n this.#filters.set(column.name, {\n column: column.name,\n op: \"=\",\n value: value1,\n });\n } else if (value2 !== undefined) {\n this.#filters.set(column.name, {\n column: column.name,\n op: \"<\",\n value: value2,\n });\n }\n } else {\n const typedValue = getTypedValue(value.toString(), dataType, true);\n\n this.#filters.set(column.name, {\n column: column.name,\n op: \"=\",\n value: typedValue,\n });\n }\n }\n\n has({ name }: ColumnDescriptor) {\n return this.#filters.has(name);\n }\n\n get({ name }: ColumnDescriptor) {\n return this.#filters.get(name);\n }\n\n /**\n * Remove filter for this column. Return false if no filter found, otw true\n */\n remove(column: ColumnDescriptor) {\n if (this.#filters.has(column.name)) {\n this.#filters.delete(column.name);\n return true;\n } else {\n return false;\n }\n }\n\n get filter(): FilterContainerFilter | undefined {\n const { size } = this.#filters;\n if (size === 0) {\n return undefined;\n } else if (size === 1) {\n const [filter] = this.#filters.values();\n return filter;\n } else {\n return {\n op: \"and\",\n filters: Array.from(this.#filters.values()),\n } as FilterContainerFilter;\n }\n }\n}\n"],"names":["isExtendedFilter","ExtendedSingleValueFilterClause","isMultiClauseFilter","isSingleValueFilter","isBetweenFilter","isAndFilter","isTypeDescriptor","getTypedRange","getTypedValue"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ var columnFilterCss = ".vuuColumnFilter {\n --vuuTimeInput-outline: none;\n \n border: solid 1px var(--salt-editable-borderColor);\n max-width: 200px;\n padding-left: 4px;\n padding-right: 4px;\n width: var(--vuuColumnFilter-width, fit-content);\n\n .vuuColumnFilter-rangeHigh {\n position: relative;\n }\n\n .vuuColumnFilter-rangeHigh::before {\n content: \"\";\n width: 1px;\n position: absolute;\n background: var(--salt-separable-primary-borderColor);\n /* Accomodate button border */\n left: calc(-1 * var(--salt-spacing-100));\n top: -1px;\n bottom: -1px;\n }\n\n .vuuTimePicker {\n border-radius: 6px;\n }\n\n .vuuTimePicker + .vuuTimePicker {\n margin-left: var(--salt-spacing-100);\n }\n\n .vuuTimeInput {\n border: none;\n }\n\n .vuuTimeInput:focus-visible {\n outline: none;\n }\n\n}\n\n.vuuColumnFilter-trigger {\n --saltButton-borderRadius: 4px 0px 0px 4px;\n --saltButton-padding: var(--salt-spacing-200);\n}\n\n.vuuColumnFilter-invalid {\n border-color: red;\n}";
4
+
5
+ module.exports = columnFilterCss;
6
+ //# sourceMappingURL=ColumnFilter.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColumnFilter.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -6,6 +6,10 @@ var vuuDataReact = require('@vuu-ui/vuu-data-react');
6
6
  var cx = require('clsx');
7
7
  var react = require('react');
8
8
  var useColumnFilter = require('./useColumnFilter.js');
9
+ var styles = require('@salt-ds/styles');
10
+ var window = require('@salt-ds/window');
11
+ var ColumnFilter$1 = require('./ColumnFilter.css.js');
12
+ var vuuUtils = require('@vuu-ui/vuu-utils');
9
13
 
10
14
  const classBase = "vuuColumnFilter";
11
15
  const ColumnFilter = react.forwardRef(function ColumnFilter2({
@@ -14,6 +18,7 @@ const ColumnFilter = react.forwardRef(function ColumnFilter2({
14
18
  className,
15
19
  column,
16
20
  defaultValue,
21
+ extendedFilterOptions,
17
22
  onColumnFilterChange,
18
23
  onColumnRangeFilterChange,
19
24
  onCommit: onCommitProp,
@@ -24,10 +29,17 @@ const ColumnFilter = react.forwardRef(function ColumnFilter2({
24
29
  variant,
25
30
  ...buttonGroupProps
26
31
  }, forwardRef2) {
27
- const { InputProps, InputPropsRange, onCommit, onCommitRange } = useColumnFilter.useColumnFilter({
32
+ const targetWindow = window.useWindow();
33
+ styles.useComponentCssInjection({
34
+ testId: "vuu-filter-editor",
35
+ css: ColumnFilter$1,
36
+ window: targetWindow
37
+ });
38
+ const { InputProps, InputPropsRange, isInvalid, onCommit, onCommitRange } = useColumnFilter.useColumnFilter({
28
39
  InputProps: InputPropsProp,
29
40
  column,
30
41
  defaultValue,
42
+ extendedFilterOptions,
31
43
  onColumnFilterChange,
32
44
  onColumnRangeFilterChange,
33
45
  onCommit: onCommitProp,
@@ -38,7 +50,9 @@ const ColumnFilter = react.forwardRef(function ColumnFilter2({
38
50
  core.SegmentedButtonGroup,
39
51
  {
40
52
  ...buttonGroupProps,
41
- className: cx(classBase, className),
53
+ className: cx(classBase, className, {
54
+ [`${classBase}-invalid`]: isInvalid
55
+ }),
42
56
  ref: forwardRef2,
43
57
  children: [
44
58
  vuuDataReact.getDataItemEditControl({
@@ -51,7 +65,7 @@ const ColumnFilter = react.forwardRef(function ColumnFilter2({
51
65
  values,
52
66
  variant
53
67
  }),
54
- operator === "between" ? vuuDataReact.getDataItemEditControl({
68
+ vuuUtils.isBetweenOperator(operator) ? vuuDataReact.getDataItemEditControl({
55
69
  InputProps: InputPropsRange,
56
70
  className: `${classBase}-rangeHigh`,
57
71
  commitWhenCleared: true,
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/ColumnFilter.tsx"],"sourcesContent":["import {\n SegmentedButtonGroup,\n type SegmentedButtonGroupProps,\n} from \"@salt-ds/core\";\nimport {\n DataItemEditControlProps,\n getDataItemEditControl,\n} from \"@vuu-ui/vuu-data-react\";\nimport cx from \"clsx\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { ColumnFilterHookProps, useColumnFilter } from \"./useColumnFilter\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends ColumnFilterHookProps,\n Omit<SegmentedButtonGroupProps, \"defaultValue\">,\n Pick<\n DataItemEditControlProps,\n \"TypeaheadProps\" | \"table\" | \"values\" | \"variant\"\n > {}\n\nexport const ColumnFilter = forwardRef(function ColumnFilter(\n {\n InputProps: InputPropsProp,\n TypeaheadProps,\n className,\n column,\n defaultValue,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n onCommit: onCommitProp,\n operator = \"=\",\n table,\n value: valueProp,\n values,\n variant,\n ...buttonGroupProps\n }: ColumnFilterProps,\n forwardRef: ForwardedRef<HTMLDivElement>,\n) {\n const { InputProps, InputPropsRange, onCommit, onCommitRange } =\n useColumnFilter({\n InputProps: InputPropsProp,\n column,\n defaultValue,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n onCommit: onCommitProp,\n operator,\n value: valueProp,\n });\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className)}\n ref={forwardRef}\n >\n {getDataItemEditControl({\n InputProps,\n TypeaheadProps,\n commitWhenCleared: true,\n dataDescriptor: column,\n onCommit,\n table,\n values,\n variant,\n })}\n {operator === \"between\"\n ? getDataItemEditControl({\n InputProps: InputPropsRange,\n className: `${classBase}-rangeHigh`,\n commitWhenCleared: true,\n variant,\n dataDescriptor: column,\n onCommit: onCommitRange,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n});\n"],"names":["forwardRef","ColumnFilter","useColumnFilter","jsxs","SegmentedButtonGroup","getDataItemEditControl"],"mappings":";;;;;;;;;AAYA,MAAM,SAAY,GAAA,iBAAA;AAUL,MAAA,YAAA,GAAeA,gBAAW,CAAA,SAASC,aAC9C,CAAA;AAAA,EACE,UAAY,EAAA,cAAA;AAAA,EACZ,cAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,oBAAA;AAAA,EACA,yBAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,QAAW,GAAA,GAAA;AAAA,EACX,KAAA;AAAA,EACA,KAAO,EAAA,SAAA;AAAA,EACP,MAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAG;AACL,CAAA,EACAD,WACA,EAAA;AACA,EAAA,MAAM,EAAE,UAAY,EAAA,eAAA,EAAiB,QAAU,EAAA,aAAA,KAC7CE,+BAAgB,CAAA;AAAA,IACd,UAAY,EAAA,cAAA;AAAA,IACZ,MAAA;AAAA,IACA,YAAA;AAAA,IACA,oBAAA;AAAA,IACA,yBAAA;AAAA,IACA,QAAU,EAAA,YAAA;AAAA,IACV,QAAA;AAAA,IACA,KAAO,EAAA;AAAA,GACR,CAAA;AAEH,EACE,uBAAAC,eAAA;AAAA,IAACC,yBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,GAAKJ,EAAAA,WAAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,QAAuBK,mCAAA,CAAA;AAAA,UACtB,UAAA;AAAA,UACA,cAAA;AAAA,UACA,iBAAmB,EAAA,IAAA;AAAA,UACnB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA,KAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACA,QAAA,KAAa,YACVA,mCAAuB,CAAA;AAAA,UACrB,UAAY,EAAA,eAAA;AAAA,UACZ,SAAA,EAAW,GAAG,SAAS,CAAA,UAAA,CAAA;AAAA,UACvB,iBAAmB,EAAA,IAAA;AAAA,UACnB,OAAA;AAAA,UACA,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAU,EAAA,aAAA;AAAA,UACV;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"ColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/ColumnFilter.tsx"],"sourcesContent":["import {\n SegmentedButtonGroup,\n type SegmentedButtonGroupProps,\n} from \"@salt-ds/core\";\nimport {\n DataItemEditControlProps,\n getDataItemEditControl,\n} from \"@vuu-ui/vuu-data-react\";\nimport cx from \"clsx\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { ColumnFilterHookProps, useColumnFilter } from \"./useColumnFilter\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\n\nimport columnFilterCss from \"./ColumnFilter.css\";\nimport { isBetweenOperator } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends ColumnFilterHookProps,\n Omit<SegmentedButtonGroupProps, \"defaultValue\">,\n Pick<\n DataItemEditControlProps,\n \"TypeaheadProps\" | \"table\" | \"values\" | \"variant\"\n > {}\n\nexport const ColumnFilter = forwardRef(function ColumnFilter(\n {\n InputProps: InputPropsProp,\n TypeaheadProps,\n className,\n column,\n defaultValue,\n extendedFilterOptions,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n onCommit: onCommitProp,\n operator = \"=\",\n table,\n value: valueProp,\n values,\n variant,\n ...buttonGroupProps\n }: ColumnFilterProps,\n forwardRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-filter-editor\",\n css: columnFilterCss,\n window: targetWindow,\n });\n\n const { InputProps, InputPropsRange, isInvalid, onCommit, onCommitRange } =\n useColumnFilter({\n InputProps: InputPropsProp,\n column,\n defaultValue,\n extendedFilterOptions,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n onCommit: onCommitProp,\n operator,\n value: valueProp,\n });\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className, {\n [`${classBase}-invalid`]: isInvalid,\n })}\n ref={forwardRef}\n >\n {getDataItemEditControl({\n InputProps,\n TypeaheadProps,\n commitWhenCleared: true,\n dataDescriptor: column,\n onCommit,\n table,\n values,\n variant,\n })}\n {isBetweenOperator(operator)\n ? getDataItemEditControl({\n InputProps: InputPropsRange,\n className: `${classBase}-rangeHigh`,\n commitWhenCleared: true,\n variant,\n dataDescriptor: column,\n onCommit: onCommitRange,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n});\n"],"names":["forwardRef","ColumnFilter","useWindow","useComponentCssInjection","columnFilterCss","useColumnFilter","jsxs","SegmentedButtonGroup","getDataItemEditControl","isBetweenOperator"],"mappings":";;;;;;;;;;;;;AAiBA,MAAM,SAAY,GAAA,iBAAA;AAUL,MAAA,YAAA,GAAeA,gBAAW,CAAA,SAASC,aAC9C,CAAA;AAAA,EACE,UAAY,EAAA,cAAA;AAAA,EACZ,cAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,qBAAA;AAAA,EACA,oBAAA;AAAA,EACA,yBAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,QAAW,GAAA,GAAA;AAAA,EACX,KAAA;AAAA,EACA,KAAO,EAAA,SAAA;AAAA,EACP,MAAA;AAAA,EACA,OAAA;AAAA,EACA,GAAG;AACL,CAAA,EACAD,WACA,EAAA;AACA,EAAA,MAAM,eAAeE,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,MAAM,EAAE,UAAY,EAAA,eAAA,EAAiB,WAAW,QAAU,EAAA,aAAA,KACxDC,+BAAgB,CAAA;AAAA,IACd,UAAY,EAAA,cAAA;AAAA,IACZ,MAAA;AAAA,IACA,YAAA;AAAA,IACA,qBAAA;AAAA,IACA,oBAAA;AAAA,IACA,yBAAA;AAAA,IACA,QAAU,EAAA,YAAA;AAAA,IACV,QAAA;AAAA,IACA,KAAO,EAAA;AAAA,GACR,CAAA;AAEH,EACE,uBAAAC,eAAA;AAAA,IAACC,yBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAW,EAAA;AAAA,QAClC,CAAC,CAAA,EAAG,SAAS,CAAA,QAAA,CAAU,GAAG;AAAA,OAC3B,CAAA;AAAA,MACD,GAAKP,EAAAA,WAAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,QAAuBQ,mCAAA,CAAA;AAAA,UACtB,UAAA;AAAA,UACA,cAAA;AAAA,UACA,iBAAmB,EAAA,IAAA;AAAA,UACnB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA,KAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACAC,0BAAA,CAAkB,QAAQ,CAAA,GACvBD,mCAAuB,CAAA;AAAA,UACrB,UAAY,EAAA,eAAA;AAAA,UACZ,SAAA,EAAW,GAAG,SAAS,CAAA,UAAA,CAAA;AAAA,UACvB,iBAAmB,EAAA,IAAA;AAAA,UACnB,OAAA;AAAA,UACA,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAU,EAAA,aAAA;AAAA,UACV;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ,CAAC;;;;"}
@@ -2,6 +2,7 @@
2
2
 
3
3
  var core = require('@salt-ds/core');
4
4
  var react = require('react');
5
+ var vuuUtils = require('@vuu-ui/vuu-utils');
5
6
 
6
7
  const injectInputProps = (InputProps2, inputProps) => {
7
8
  if (InputProps2 === void 0) {
@@ -22,12 +23,14 @@ const useColumnFilter = ({
22
23
  InputProps: InputPropsProp,
23
24
  column,
24
25
  defaultValue,
26
+ extendedFilterOptions,
25
27
  onColumnFilterChange,
26
28
  onColumnRangeFilterChange,
27
29
  onCommit,
28
30
  operator = "=",
29
31
  value: valueProp
30
32
  }) => {
33
+ const [isInvalid, setIsInvalid] = react.useState(false);
31
34
  const [value, setValue] = core.useControlled({
32
35
  controlled: valueProp,
33
36
  default: defaultValue,
@@ -37,32 +40,58 @@ const useColumnFilter = ({
37
40
  const handleCommit = react.useCallback(
38
41
  (_e, newValue = "") => {
39
42
  if (Array.isArray(value)) {
40
- setValue([`${newValue}`, value[1]]);
41
- onCommit?.(column, operator, [`${newValue}`, value[1]]);
43
+ if (vuuUtils.isBetweenOperator(operator)) {
44
+ setValue([`${newValue}`, value[1]]);
45
+ onCommit?.(
46
+ column,
47
+ operator,
48
+ [`${newValue}`, value[1]],
49
+ extendedFilterOptions
50
+ );
51
+ } else {
52
+ throw Error(
53
+ `[useColumnFilterNext] value has been initialised incorrectly for non-range filter`
54
+ );
55
+ }
42
56
  } else {
43
57
  setValue(newValue);
44
- onCommit?.(column, operator, `${newValue}`);
58
+ onCommit?.(column, operator, `${newValue}`, extendedFilterOptions);
45
59
  }
46
60
  },
47
- [value, setValue, onCommit, column, operator]
61
+ [value, operator, setValue, onCommit, column, extendedFilterOptions]
48
62
  );
49
63
  const handleRangeCommit = react.useCallback(
50
64
  (_e, newValue = "") => {
51
65
  if (Array.isArray(value)) {
52
66
  const [firstValue] = value;
53
- setValue([value[0], `${newValue}`]);
54
- onCommit?.(column, operator, [firstValue, `${newValue}`]);
67
+ const newRange = [value[0], `${newValue}`];
68
+ setValue(newRange);
69
+ const validRange = vuuUtils.isValidRange(newRange);
70
+ setIsInvalid(!validRange);
71
+ if (validRange) {
72
+ onCommit?.(
73
+ column,
74
+ operator,
75
+ [firstValue, `${newValue}`],
76
+ extendedFilterOptions
77
+ );
78
+ }
55
79
  } else if (value !== "") {
56
80
  const currentValue = `${value}`;
57
81
  setValue([currentValue, `${newValue}`]);
58
- onCommit?.(column, operator, [currentValue, `${newValue}`]);
82
+ onCommit?.(
83
+ column,
84
+ operator,
85
+ [currentValue, `${newValue}`],
86
+ extendedFilterOptions
87
+ );
59
88
  } else {
60
89
  throw Error(
61
90
  `[useColumnFilterNext] value has been initialised incorrectly for range filter`
62
91
  );
63
92
  }
64
93
  },
65
- [value, setValue, onCommit, column, operator]
94
+ [value, setValue, onCommit, column, operator, extendedFilterOptions]
66
95
  );
67
96
  const onChange = react.useCallback(
68
97
  (e) => {
@@ -100,6 +129,7 @@ const useColumnFilter = ({
100
129
  return {
101
130
  InputProps: InputProps2,
102
131
  InputPropsRange,
132
+ isInvalid,
103
133
  onCommit: handleCommit,
104
134
  onCommitRange: handleRangeCommit
105
135
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import {\n ColumnFilterChangeHandler,\n ColumnFilterCommitHandler,\n ColumnFilterOp,\n ColumnFilterValue,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { InputProps, useControlled } from \"@salt-ds/core\";\nimport { ChangeEventHandler, useCallback, useMemo } from \"react\";\nimport { CommitHandler } from \"@vuu-ui/vuu-utils\";\nimport { DataItemEditControlProps } from \"@vuu-ui/vuu-data-react\";\n\nconst injectInputProps = (\n InputProps: InputProps | undefined,\n inputProps: InputProps[\"inputProps\"],\n): InputProps => {\n if (InputProps === undefined) {\n return {\n inputProps,\n };\n } else {\n return {\n ...InputProps,\n inputProps: {\n ...InputProps.inputProps,\n ...inputProps,\n },\n };\n }\n};\n\nexport interface ColumnFilterHookProps\n extends Pick<DataItemEditControlProps, \"InputProps\"> {\n column: ColumnDescriptor;\n /**\n * Filter defaultValue. Pair of values expected when operator is\n * 'between'. If provided, component is uncontrolled\n */\n\n defaultValue?: ColumnFilterValue;\n /**\n * Filter change events.\n */\n onColumnFilterChange?: ColumnFilterChangeHandler;\n /**\n * Filter change events on second control in range filter\n */\n onColumnRangeFilterChange?: ColumnFilterChangeHandler;\n /**\n * Called when user 'commits' filter value, either by pressing enter,\n * tabbing away from control or making selection from list\n */\n onCommit: ColumnFilterCommitHandler;\n operator?: ColumnFilterOp;\n /**\n * Filter value. Pair of values expected when operator is\n * 'between'. If provided, component is controlled.\n */\n value?: ColumnFilterValue;\n}\n\nexport const useColumnFilter = ({\n InputProps: InputPropsProp,\n column,\n defaultValue,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n onCommit,\n operator = \"=\",\n value: valueProp,\n}: ColumnFilterHookProps) => {\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"ColumnFilterNext\",\n state: \"value\",\n });\n\n const handleCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue = \"\") => {\n if (Array.isArray(value)) {\n setValue([`${newValue}`, value[1]]);\n onCommit?.(column, operator, [`${newValue}`, value[1]]);\n } else {\n setValue(newValue as ColumnFilterValue);\n onCommit?.(column, operator, `${newValue}`);\n }\n },\n [value, setValue, onCommit, column, operator],\n );\n\n const handleRangeCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue = \"\") => {\n if (Array.isArray(value)) {\n const [firstValue] = value as [string, string];\n setValue([value[0], `${newValue}`]);\n onCommit?.(column, operator, [firstValue, `${newValue}`]);\n } else if (value !== \"\") {\n // If we have already committed the first value, filter has been\n // saved as a single value '='.\n const currentValue = `${value}`;\n setValue([currentValue, `${newValue}`]);\n onCommit?.(column, operator, [currentValue, `${newValue}`]);\n } else {\n throw Error(\n `[useColumnFilterNext] value has been initialised incorrectly for range filter`,\n );\n }\n },\n [value, setValue, onCommit, column, operator],\n );\n\n const onChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n const { value = \"\" } = e.target;\n setValue((v) => (Array.isArray(v) ? [value, v[1]] : value));\n onColumnFilterChange?.(e.target.value, column, operator);\n },\n [column, onColumnFilterChange, operator, setValue],\n );\n\n const onRangeInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n const { value = \"\" } = e.target;\n setValue((v) => (Array.isArray(v) ? [v[0], value] : value));\n\n onColumnRangeFilterChange?.(value, column, operator);\n },\n [setValue, onColumnRangeFilterChange, column, operator],\n );\n\n const InputProps = useMemo(\n () =>\n injectInputProps(InputPropsProp, {\n onChange,\n value: Array.isArray(value) ? value[0] : value,\n }),\n [InputPropsProp, onChange, value],\n );\n\n const InputPropsRange = useMemo(\n () =>\n injectInputProps(\n InputPropsProp,\n Array.isArray(value)\n ? {\n onChange: onRangeInputChange,\n value: value[1],\n }\n : undefined,\n ),\n [InputPropsProp, onRangeInputChange, value],\n );\n\n return {\n InputProps,\n InputPropsRange,\n onCommit: handleCommit,\n onCommitRange: handleRangeCommit,\n };\n};\n"],"names":["InputProps","useControlled","useCallback","value","useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import {\n ColumnFilterChangeHandler,\n ColumnFilterCommitHandler,\n ColumnFilterOp,\n ColumnFilterValue,\n ExtendedFilterOptions,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { InputProps, useControlled } from \"@salt-ds/core\";\nimport { ChangeEventHandler, useCallback, useMemo, useState } from \"react\";\nimport {\n CommitHandler,\n isBetweenOperator,\n isValidRange,\n} from \"@vuu-ui/vuu-utils\";\nimport { DataItemEditControlProps } from \"@vuu-ui/vuu-data-react\";\n\nconst injectInputProps = (\n InputProps: InputProps | undefined,\n inputProps: InputProps[\"inputProps\"],\n): InputProps => {\n if (InputProps === undefined) {\n return {\n inputProps,\n };\n } else {\n return {\n ...InputProps,\n inputProps: {\n ...InputProps.inputProps,\n ...inputProps,\n },\n };\n }\n};\n\nexport interface ColumnFilterHookProps\n extends Pick<DataItemEditControlProps, \"InputProps\"> {\n column: ColumnDescriptor;\n /**\n * Filter defaultValue. Pair of values expected when operator is\n * 'between'. If provided, component is uncontrolled\n */\n\n defaultValue?: ColumnFilterValue;\n /**\n * Provides for custom filters.\n */\n extendedFilterOptions?: ExtendedFilterOptions;\n\n /**\n * Filter change events.\n */\n onColumnFilterChange?: ColumnFilterChangeHandler;\n /**\n * Filter change events on second control in range filter\n */\n onColumnRangeFilterChange?: ColumnFilterChangeHandler;\n /**\n * Called when user 'commits' filter value, either by pressing enter,\n * tabbing away from control or making selection from list\n */\n onCommit: ColumnFilterCommitHandler;\n operator?: ColumnFilterOp;\n /**\n * Filter value. Pair of values expected when operator is\n * 'between'. If provided, component is controlled.\n */\n value?: ColumnFilterValue;\n}\n\nexport const useColumnFilter = ({\n InputProps: InputPropsProp,\n column,\n defaultValue,\n extendedFilterOptions,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n onCommit,\n operator = \"=\",\n value: valueProp,\n}: ColumnFilterHookProps) => {\n const [isInvalid, setIsInvalid] = useState(false);\n const [value, setValue] = useControlled({\n controlled: valueProp,\n default: defaultValue,\n name: \"ColumnFilterNext\",\n state: \"value\",\n });\n\n const handleCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue = \"\") => {\n if (Array.isArray(value)) {\n if (isBetweenOperator(operator)) {\n setValue([`${newValue}`, value[1]]);\n onCommit?.(\n column,\n operator,\n [`${newValue}`, value[1]],\n extendedFilterOptions,\n );\n } else {\n throw Error(\n `[useColumnFilterNext] value has been initialised incorrectly for non-range filter`,\n );\n }\n } else {\n setValue(newValue as ColumnFilterValue);\n onCommit?.(column, operator, `${newValue}`, extendedFilterOptions);\n }\n },\n [value, operator, setValue, onCommit, column, extendedFilterOptions],\n );\n\n const handleRangeCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue = \"\") => {\n if (Array.isArray(value)) {\n const [firstValue] = value as [string, string];\n const newRange: [string, string] = [value[0], `${newValue}`];\n setValue(newRange);\n const validRange = isValidRange(newRange);\n setIsInvalid(!validRange);\n if (validRange) {\n onCommit?.(\n column,\n operator,\n [firstValue, `${newValue}`],\n extendedFilterOptions,\n );\n }\n } else if (value !== \"\") {\n // If we have already committed the first value, filter has been\n // saved as a single value '='.\n const currentValue = `${value}`;\n setValue([currentValue, `${newValue}`]);\n onCommit?.(\n column,\n operator,\n [currentValue, `${newValue}`],\n extendedFilterOptions,\n );\n } else {\n throw Error(\n `[useColumnFilterNext] value has been initialised incorrectly for range filter`,\n );\n }\n },\n [value, setValue, onCommit, column, operator, extendedFilterOptions],\n );\n\n const onChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n const { value = \"\" } = e.target;\n setValue((v) => (Array.isArray(v) ? [value, v[1]] : value));\n onColumnFilterChange?.(e.target.value, column, operator);\n },\n [column, onColumnFilterChange, operator, setValue],\n );\n\n const onRangeInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n const { value = \"\" } = e.target;\n setValue((v) => (Array.isArray(v) ? [v[0], value] : value));\n\n onColumnRangeFilterChange?.(value, column, operator);\n },\n [setValue, onColumnRangeFilterChange, column, operator],\n );\n\n const InputProps = useMemo(\n () =>\n injectInputProps(InputPropsProp, {\n onChange,\n value: Array.isArray(value) ? value[0] : value,\n }),\n [InputPropsProp, onChange, value],\n );\n\n const InputPropsRange = useMemo(\n () =>\n injectInputProps(\n InputPropsProp,\n Array.isArray(value)\n ? {\n onChange: onRangeInputChange,\n value: value[1],\n }\n : undefined,\n ),\n [InputPropsProp, onRangeInputChange, value],\n );\n\n return {\n InputProps,\n InputPropsRange,\n isInvalid,\n onCommit: handleCommit,\n onCommitRange: handleRangeCommit,\n };\n};\n"],"names":["InputProps","useState","useControlled","useCallback","isBetweenOperator","isValidRange","value","useMemo"],"mappings":"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"}
@@ -14,6 +14,7 @@ const CustomFilters = ({
14
14
  defaultFilterState,
15
15
  filterState,
16
16
  onApplyFilter,
17
+ onClearFilter,
17
18
  onFilterDeleted,
18
19
  onFilterRenamed,
19
20
  onFilterStateChanged,
@@ -36,6 +37,7 @@ const CustomFilters = ({
36
37
  defaultFilterState,
37
38
  filterState,
38
39
  onApplyFilter,
40
+ onClearFilter,
39
41
  onFilterStateChanged,
40
42
  onFilterDeleted,
41
43
  onFilterRenamed
@@ -1 +1 @@
1
- {"version":3,"file":"CustomFilters.js","sources":["../../../../packages/vuu-filters/src/custom-filters/CustomFilters.tsx"],"sourcesContent":["import { Prompt } from \"@vuu-ui/vuu-ui-controls\";\nimport type { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport { HTMLAttributes, ReactElement, useRef } from \"react\";\nimport { type FilterBarProps } from \"../filter-bar\";\nimport { FilterEditor } from \"../filter-editor\";\nimport { FilterPill } from \"../filter-pill\";\nimport { FilterModel } from \"../FilterModel\";\nimport { isEditFilterState, useCustomFilters } from \"./useCustomFilters\";\n\nconst classBase = \"vuuCustomFilters\";\n\nexport interface CustomFilterProps\n extends HTMLAttributes<HTMLDivElement>,\n Pick<\n FilterBarProps,\n | \"defaultFilterState\"\n | \"filterState\"\n | \"onApplyFilter\"\n | \"onFilterDeleted\"\n | \"onFilterRenamed\"\n | \"onFilterStateChanged\"\n | \"vuuTable\"\n > {\n columnDescriptors: ColumnDescriptor[];\n}\n\nexport const CustomFilters = ({\n columnDescriptors,\n defaultFilterState,\n filterState,\n onApplyFilter,\n onFilterDeleted,\n onFilterRenamed,\n onFilterStateChanged,\n vuuTable,\n}: CustomFilterProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n\n const {\n activeFilterIndex,\n addButtonProps,\n columnsByName,\n filters,\n interactedFilterState,\n onCancelEdit,\n onSave,\n FilterPillProps,\n promptProps,\n } = useCustomFilters({\n containerRef: rootRef,\n columnDescriptors,\n defaultFilterState,\n filterState,\n onApplyFilter,\n onFilterStateChanged,\n onFilterDeleted,\n onFilterRenamed,\n });\n\n const indexOfFilterBeingRenamed =\n interactedFilterState?.state === \"rename\"\n ? interactedFilterState.index\n : -1;\n\n const filterModel = isEditFilterState(interactedFilterState?.state)\n ? new FilterModel(interactedFilterState.filter)\n : undefined;\n\n const getFilterPills = () => {\n const items: ReactElement[] = [];\n filters.forEach((filter, i) => {\n items.push(\n <FilterPill\n {...FilterPillProps}\n editing={indexOfFilterBeingRenamed === i}\n columnsByName={columnsByName}\n data-index={i}\n filter={filter}\n key={`filter-${i}`}\n selected={activeFilterIndex.includes(i)}\n />,\n );\n });\n return items;\n };\n\n return (\n <>\n <div className=\"vuuCustomFilters\" ref={rootRef}>\n <div className={`${classBase}-filters`}>{getFilterPills()}</div>\n <IconButton\n {...addButtonProps}\n aria-label=\"Add filter\"\n data-selectable={false}\n icon=\"plus\"\n key=\"filter-add\"\n tabIndex={0}\n variant=\"secondary\"\n />\n\n {promptProps ? <Prompt {...promptProps} open /> : null}\n </div>\n {filterModel && vuuTable && (\n <FilterEditor\n columnDescriptors={columnDescriptors}\n key=\"filter-editor\"\n onCancel={onCancelEdit}\n onSave={onSave}\n filter={interactedFilterState?.filter}\n vuuTable={vuuTable}\n />\n )}\n </>\n );\n};\n"],"names":["useRef","useCustomFilters","isEditFilterState","FilterModel","createElement","FilterPill","jsxs","Fragment","jsx","IconButton","Prompt","FilterEditor"],"mappings":";;;;;;;;;;AAUA,MAAM,SAAY,GAAA,kBAAA;AAiBX,MAAM,gBAAgB,CAAC;AAAA,EAC5B,iBAAA;AAAA,EACA,kBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACF,CAAyB,KAAA;AACvB,EAAM,MAAA,OAAA,GAAUA,aAAuB,IAAI,CAAA;AAE3C,EAAM,MAAA;AAAA,IACJ,iBAAA;AAAA,IACA,cAAA;AAAA,IACA,aAAA;AAAA,IACA,OAAA;AAAA,IACA,qBAAA;AAAA,IACA,YAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,MACEC,iCAAiB,CAAA;AAAA,IACnB,YAAc,EAAA,OAAA;AAAA,IACd,iBAAA;AAAA,IACA,kBAAA;AAAA,IACA,WAAA;AAAA,IACA,aAAA;AAAA,IACA,oBAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,yBACJ,GAAA,qBAAA,EAAuB,KAAU,KAAA,QAAA,GAC7B,sBAAsB,KACtB,GAAA,CAAA,CAAA;AAEN,EAAM,MAAA,WAAA,GAAcC,mCAAkB,qBAAuB,EAAA,KAAK,IAC9D,IAAIC,uBAAA,CAAY,qBAAsB,CAAA,MAAM,CAC5C,GAAA,KAAA,CAAA;AAEJ,EAAA,MAAM,iBAAiB,MAAM;AAC3B,IAAA,MAAM,QAAwB,EAAC;AAC/B,IAAQ,OAAA,CAAA,OAAA,CAAQ,CAAC,MAAA,EAAQ,CAAM,KAAA;AAC7B,MAAM,KAAA,CAAA,IAAA;AAAA,wBACJC,mBAAA;AAAA,UAACC,qBAAA;AAAA,UAAA;AAAA,YACE,GAAG,eAAA;AAAA,YACJ,SAAS,yBAA8B,KAAA,CAAA;AAAA,YACvC,aAAA;AAAA,YACA,YAAY,EAAA,CAAA;AAAA,YACZ,MAAA;AAAA,YACA,GAAA,EAAK,UAAU,CAAC,CAAA,CAAA;AAAA,YAChB,QAAA,EAAU,iBAAkB,CAAA,QAAA,CAAS,CAAC;AAAA;AAAA;AACxC,OACF;AAAA,KACD,CAAA;AACD,IAAO,OAAA,KAAA;AAAA,GACT;AAEA,EAAA,uBAEIC,eAAA,CAAAC,mBAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAAD,eAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAU,kBAAmB,EAAA,GAAA,EAAK,OACrC,EAAA,QAAA,EAAA;AAAA,sBAAAE,cAAA,CAAC,SAAI,SAAW,EAAA,CAAA,EAAG,SAAS,CAAA,QAAA,CAAA,EAAa,0BAAiB,EAAA,CAAA;AAAA,sBAC1DJ,mBAAA;AAAA,QAACK,wBAAA;AAAA,QAAA;AAAA,UACE,GAAG,cAAA;AAAA,UACJ,YAAW,EAAA,YAAA;AAAA,UACX,iBAAiB,EAAA,KAAA;AAAA,UACjB,IAAK,EAAA,MAAA;AAAA,UACL,GAAI,EAAA,YAAA;AAAA,UACJ,QAAU,EAAA,CAAA;AAAA,UACV,OAAQ,EAAA;AAAA;AAAA,OACV;AAAA,MAEC,8BAAeD,cAAA,CAAAE,oBAAA,EAAA,EAAQ,GAAG,WAAa,EAAA,IAAA,EAAI,MAAC,CAAK,GAAA;AAAA,KACpD,EAAA,CAAA;AAAA,IACC,eAAe,QACd,oBAAAF,cAAA;AAAA,MAACG,yBAAA;AAAA,MAAA;AAAA,QACC,iBAAA;AAAA,QAEA,QAAU,EAAA,YAAA;AAAA,QACV,MAAA;AAAA,QACA,QAAQ,qBAAuB,EAAA,MAAA;AAAA,QAC/B;AAAA,OAAA;AAAA,MAJI;AAAA;AAKN,GAEJ,EAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"CustomFilters.js","sources":["../../../../packages/vuu-filters/src/custom-filters/CustomFilters.tsx"],"sourcesContent":["import { Prompt } from \"@vuu-ui/vuu-ui-controls\";\nimport type { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { IconButton } from \"@vuu-ui/vuu-ui-controls\";\nimport { HTMLAttributes, ReactElement, useRef } from \"react\";\nimport { type FilterBarProps } from \"../filter-bar\";\nimport { FilterEditor } from \"../filter-editor\";\nimport { FilterPill } from \"../filter-pill\";\nimport { FilterModel } from \"../FilterModel\";\nimport { isEditFilterState, useCustomFilters } from \"./useCustomFilters\";\n\nconst classBase = \"vuuCustomFilters\";\n\nexport interface CustomFilterProps\n extends HTMLAttributes<HTMLDivElement>,\n Pick<\n FilterBarProps,\n | \"defaultFilterState\"\n | \"filterState\"\n | \"onApplyFilter\"\n | \"onClearFilter\"\n | \"onFilterDeleted\"\n | \"onFilterRenamed\"\n | \"onFilterStateChanged\"\n | \"vuuTable\"\n > {\n columnDescriptors: ColumnDescriptor[];\n}\n\nexport const CustomFilters = ({\n columnDescriptors,\n defaultFilterState,\n filterState,\n onApplyFilter,\n onClearFilter,\n onFilterDeleted,\n onFilterRenamed,\n onFilterStateChanged,\n vuuTable,\n}: CustomFilterProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n\n const {\n activeFilterIndex,\n addButtonProps,\n columnsByName,\n filters,\n interactedFilterState,\n onCancelEdit,\n onSave,\n FilterPillProps,\n promptProps,\n } = useCustomFilters({\n containerRef: rootRef,\n columnDescriptors,\n defaultFilterState,\n filterState,\n onApplyFilter,\n onClearFilter,\n onFilterStateChanged,\n onFilterDeleted,\n onFilterRenamed,\n });\n\n const indexOfFilterBeingRenamed =\n interactedFilterState?.state === \"rename\"\n ? interactedFilterState.index\n : -1;\n\n const filterModel = isEditFilterState(interactedFilterState?.state)\n ? new FilterModel(interactedFilterState.filter)\n : undefined;\n\n const getFilterPills = () => {\n const items: ReactElement[] = [];\n filters.forEach((filter, i) => {\n items.push(\n <FilterPill\n {...FilterPillProps}\n editing={indexOfFilterBeingRenamed === i}\n columnsByName={columnsByName}\n data-index={i}\n filter={filter}\n key={`filter-${i}`}\n selected={activeFilterIndex.includes(i)}\n />,\n );\n });\n return items;\n };\n\n return (\n <>\n <div className=\"vuuCustomFilters\" ref={rootRef}>\n <div className={`${classBase}-filters`}>{getFilterPills()}</div>\n <IconButton\n {...addButtonProps}\n aria-label=\"Add filter\"\n data-selectable={false}\n icon=\"plus\"\n key=\"filter-add\"\n tabIndex={0}\n variant=\"secondary\"\n />\n\n {promptProps ? <Prompt {...promptProps} open /> : null}\n </div>\n {filterModel && vuuTable && (\n <FilterEditor\n columnDescriptors={columnDescriptors}\n key=\"filter-editor\"\n onCancel={onCancelEdit}\n onSave={onSave}\n filter={interactedFilterState?.filter}\n vuuTable={vuuTable}\n />\n )}\n </>\n );\n};\n"],"names":["useRef","useCustomFilters","isEditFilterState","FilterModel","createElement","FilterPill","jsxs","Fragment","jsx","IconButton","Prompt","FilterEditor"],"mappings":"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"}
@@ -13,6 +13,7 @@ const useCustomFilters = ({
13
13
  defaultFilterState,
14
14
  filterState,
15
15
  onApplyFilter,
16
+ onClearFilter,
16
17
  onFilterDeleted,
17
18
  onFilterRenamed,
18
19
  onFilterStateChanged
@@ -43,8 +44,11 @@ const useCustomFilters = ({
43
44
  react.useEffect(() => {
44
45
  const activeFilters = activeFilterIndex.map((i) => filters[i]);
45
46
  const applyFilter = (filter) => {
46
- const query = filter ? vuuUtils.filterAsQuery(filter, { columnsByName }) : "";
47
- onApplyFilter({ filter: query, filterStruct: filter });
47
+ if (filter) {
48
+ onApplyFilter(filter);
49
+ } else {
50
+ onClearFilter();
51
+ }
48
52
  };
49
53
  if (activeFilters.length === 0) {
50
54
  applyFilter();
@@ -54,7 +58,7 @@ const useCustomFilters = ({
54
58
  } else {
55
59
  applyFilter({ op: "and", filters: activeFilters });
56
60
  }
57
- }, [activeFilterIndex, columnsByName, filters, onApplyFilter]);
61
+ }, [activeFilterIndex, columnsByName, filters, onApplyFilter, onClearFilter]);
58
62
  const editPillLabel = react.useCallback((index, filter) => {
59
63
  setTimeout(() => {
60
64
  setInteractedFilterState({