@planningcenter/tapestry 4.10.0-rc.9 → 4.10.0
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/dist/components/DataTable/ActiveFilterInstance.d.ts +6 -4
- package/dist/components/DataTable/ActiveFilterInstance.d.ts.map +1 -1
- package/dist/components/DataTable/ActiveFilterInstance.js +8 -2
- package/dist/components/DataTable/ActiveFilterInstance.js.map +1 -1
- package/dist/components/DataTable/ActiveFilters.d.ts.map +1 -1
- package/dist/components/DataTable/ActiveFilters.js +3 -1
- package/dist/components/DataTable/ActiveFilters.js.map +1 -1
- package/dist/components/DataTable/CollectionEditorsLazy.d.ts.map +1 -1
- package/dist/components/DataTable/CollectionEditorsLazy.js +7 -5
- package/dist/components/DataTable/CollectionEditorsLazy.js.map +1 -1
- package/dist/components/DataTable/CollectionEditorsShared.d.ts.map +1 -1
- package/dist/components/DataTable/CollectionEditorsShared.js +1 -5
- package/dist/components/DataTable/CollectionEditorsShared.js.map +1 -1
- package/dist/components/DataTable/CollectionEditorsStatic.d.ts +1 -1
- package/dist/components/DataTable/CollectionEditorsStatic.d.ts.map +1 -1
- package/dist/components/DataTable/CollectionEditorsStatic.js +8 -17
- package/dist/components/DataTable/CollectionEditorsStatic.js.map +1 -1
- package/dist/components/DataTable/DataTable.js +14 -11
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/FilterChip.d.ts +4 -3
- package/dist/components/DataTable/FilterChip.d.ts.map +1 -1
- package/dist/components/DataTable/FilterChip.js +24 -3
- package/dist/components/DataTable/FilterChip.js.map +1 -1
- package/dist/components/DataTable/FilterControls.d.ts.map +1 -1
- package/dist/components/DataTable/FilterControls.js +1 -1
- package/dist/components/DataTable/FilterControls.js.map +1 -1
- package/dist/components/DataTable/FilterTypes.d.ts +32 -8
- package/dist/components/DataTable/FilterTypes.d.ts.map +1 -1
- package/dist/components/DataTable/FocusFirstControl.d.ts +11 -0
- package/dist/components/DataTable/FocusFirstControl.d.ts.map +1 -0
- package/dist/components/DataTable/FocusFirstControl.js +31 -0
- package/dist/components/DataTable/FocusFirstControl.js.map +1 -0
- package/dist/components/DataTable/TableSearch.d.ts.map +1 -1
- package/dist/components/DataTable/TableSearch.js +1 -1
- package/dist/components/DataTable/TableSearch.js.map +1 -1
- package/dist/components/DataTable/collectionFilter.d.ts +14 -8
- package/dist/components/DataTable/collectionFilter.d.ts.map +1 -1
- package/dist/components/DataTable/collectionFilter.js +9 -5
- package/dist/components/DataTable/collectionFilter.js.map +1 -1
- package/dist/components/DataTable/dateFilter.d.ts +7 -3
- package/dist/components/DataTable/dateFilter.d.ts.map +1 -1
- package/dist/components/DataTable/dateFilter.js +9 -14
- package/dist/components/DataTable/dateFilter.js.map +1 -1
- package/dist/components/DataTable/dayFilter.d.ts +4 -3
- package/dist/components/DataTable/dayFilter.d.ts.map +1 -1
- package/dist/components/DataTable/dayFilter.js +11 -12
- package/dist/components/DataTable/dayFilter.js.map +1 -1
- package/dist/components/DataTable/filterKeys.d.ts +1 -1
- package/dist/components/DataTable/filterKeys.d.ts.map +1 -1
- package/dist/components/DataTable/index.d.ts +8 -3
- package/dist/components/DataTable/index.d.ts.map +1 -1
- package/dist/components/DataTable/numberFilter.d.ts +16 -3
- package/dist/components/DataTable/numberFilter.d.ts.map +1 -1
- package/dist/components/DataTable/numberFilter.js +41 -13
- package/dist/components/DataTable/numberFilter.js.map +1 -1
- package/dist/components/DataTable/presenceFilter.d.ts +4 -1
- package/dist/components/DataTable/presenceFilter.d.ts.map +1 -1
- package/dist/components/DataTable/presenceFilter.js +3 -3
- package/dist/components/DataTable/presenceFilter.js.map +1 -1
- package/dist/components/DataTable/scopedFilter.d.ts +2 -0
- package/dist/components/DataTable/scopedFilter.d.ts.map +1 -1
- package/dist/components/DataTable/scopedFilter.js +6 -3
- package/dist/components/DataTable/scopedFilter.js.map +1 -1
- package/dist/components/DataTable/textFilter.d.ts +3 -1
- package/dist/components/DataTable/textFilter.d.ts.map +1 -1
- package/dist/components/DataTable/textFilter.js +5 -9
- package/dist/components/DataTable/textFilter.js.map +1 -1
- package/dist/components/DataTable/useSearchFilter.d.ts +1 -1
- package/dist/components/DataTable/utils.d.ts +1 -0
- package/dist/components/DataTable/utils.d.ts.map +1 -1
- package/dist/components/DataTable/utils.js +1 -1
- package/dist/components/DataTable/utils.js.map +1 -1
- package/dist/components/segmented-control/IconSegment.d.ts +6 -1
- package/dist/components/segmented-control/IconSegment.d.ts.map +1 -1
- package/dist/components/segmented-control/IconSegment.js +1 -1
- package/dist/components/segmented-control/IconSegment.js.map +1 -1
- package/dist/components/segmented-control/Segment.d.ts +6 -1
- package/dist/components/segmented-control/Segment.d.ts.map +1 -1
- package/dist/components/segmented-control/Segment.js +1 -1
- package/dist/components/segmented-control/Segment.js.map +1 -1
- package/dist/components/segmented-control/SegmentBase.d.ts +1 -5
- package/dist/components/segmented-control/SegmentBase.d.ts.map +1 -1
- package/dist/components/segmented-control/SegmentBase.js.map +1 -1
- package/dist/components/segmented-control/SegmentedControl.d.ts +3 -9
- package/dist/components/segmented-control/SegmentedControl.d.ts.map +1 -1
- package/dist/components/segmented-control/SegmentedControl.js +3 -9
- package/dist/components/segmented-control/SegmentedControl.js.map +1 -1
- package/dist/components/segmented-control/index.d.ts +1 -0
- package/dist/components/segmented-control/index.d.ts.map +1 -1
- package/dist/index.css +155 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/reactRender.css +1537 -1395
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRenderLegacy.css +1537 -1395
- package/dist/reactRenderLegacy.css.map +1 -1
- package/dist/unstable.css +171 -29
- package/dist/unstable.css.map +1 -1
- package/dist/unstable.d.ts +0 -1
- package/dist/unstable.d.ts.map +1 -1
- package/dist/unstable.js +3 -3
- package/package.json +2 -2
|
@@ -2,5 +2,5 @@ import type { ActiveFilter } from "./FilterTypes";
|
|
|
2
2
|
export declare function createFilterKey(filter: ActiveFilter): void;
|
|
3
3
|
export declare function getFilterKey(filter: ActiveFilter): string | undefined;
|
|
4
4
|
export declare function getFilterSequence(filter: ActiveFilter): number | undefined;
|
|
5
|
-
export declare function keepFilterKey(oldFilter: ActiveFilter, newFilter: ActiveFilter): ActiveFilter<
|
|
5
|
+
export declare function keepFilterKey(oldFilter: ActiveFilter, newFilter: ActiveFilter): ActiveFilter<import("./FilterTypes").ActiveFilterValue, string>;
|
|
6
6
|
//# sourceMappingURL=filterKeys.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterKeys.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/filterKeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAOjD,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,QAEnD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,sBAGhD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,sBAErD;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"filterKeys.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/filterKeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAOjD,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,QAEnD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,sBAGhD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,sBAErD;AAED,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,YAAY,mEAKxB"}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import "./index.css";
|
|
2
2
|
import "./filters.css";
|
|
3
|
+
export type { CollectionFilterValue } from "./CollectionEditorsShared";
|
|
4
|
+
export type { CollectionActiveFilter, CollectionOperatorName, } from "./collectionFilter";
|
|
3
5
|
export type { DataTableElementProps, DataTableLoadingState, DataTableProps, DataTableSelection, } from "./DataTable";
|
|
4
6
|
export { DataTable } from "./DataTable";
|
|
5
7
|
export type { BooleanColumn, CurrencyColumn, CustomColumn, DataTableColumn, DataTableColumnAlign, DataTableColumnType, DateColumn, DateTimeColumn, EnumColumn, NumberColumn, StringColumn, } from "./DataTableColumn";
|
|
8
|
+
export type { DateActiveFilter, DateFilterValue, DateOperatorName, } from "./dateFilter";
|
|
9
|
+
export type { DayActiveFilter, DayFilterValue, DayOperatorName, } from "./dayFilter";
|
|
6
10
|
export * from "./filters";
|
|
7
|
-
export type { ActiveFilter, FilterItemConfig, FilterNode, FilterNodeGroup, FilterNodeItem, FilterNodeScoped, Operator, } from "./FilterTypes";
|
|
8
|
-
export type { NumberFilterValue } from "./numberFilter";
|
|
9
|
-
export type { PresenceFilterConfig } from "./presenceFilter";
|
|
11
|
+
export type { ActiveFilter, ActiveFilterValue, FilterItemConfig, FilterNode, FilterNodeGroup, FilterNodeItem, FilterNodeScoped, Operator, } from "./FilterTypes";
|
|
12
|
+
export type { NumberActiveFilter, NumberFilterValue, NumberOperatorName, } from "./numberFilter";
|
|
13
|
+
export type { PresenceActiveFilter, PresenceFilterConfig, PresenceFilterValue, PresenceOperatorName, } from "./presenceFilter";
|
|
10
14
|
export type { ScopedFilterConfig, ScopedFilterOptions } from "./scopedFilter";
|
|
15
|
+
export type { TextActiveFilter, TextFilterValue, TextOperatorName, } from "./textFilter";
|
|
11
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AACpB,OAAO,eAAe,CAAA;AAEtB,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,GACnB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,mBAAmB,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,QAAQ,GACT,MAAM,eAAe,CAAA;AACtB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AACpB,OAAO,eAAe,CAAA;AAEtB,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACtE,YAAY,EACV,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,GACnB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,eAAe,EACf,cAAc,EACd,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,cAAc,WAAW,CAAA;AACzB,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,QAAQ,GACT,MAAM,eAAe,CAAA;AACtB,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAC7E,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAA"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
2
|
-
export type NumberFilterValue = number | [number, number];
|
|
1
|
+
import type { ActiveFilter, FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
3
2
|
export declare const GTE: {
|
|
4
3
|
readonly inputType: {
|
|
5
4
|
readonly type: "number";
|
|
@@ -80,6 +79,20 @@ declare const ALL_NUMBER_OPERATORS: ({
|
|
|
80
79
|
readonly name: "between";
|
|
81
80
|
})[];
|
|
82
81
|
export type NumberOperatorName = (typeof ALL_NUMBER_OPERATORS)[number]["name"];
|
|
83
|
-
|
|
82
|
+
/** A number; a pair for `between`, either side of which may still be empty. */
|
|
83
|
+
export type NumberFilterValue = number | [number | undefined, number | undefined] | undefined;
|
|
84
|
+
export type NumberActiveFilter = ActiveFilter<NumberFilterValue, NumberOperatorName>;
|
|
85
|
+
/** Constraints applied to every input of the filter, including both sides of a range. */
|
|
86
|
+
export interface NumberConstraints {
|
|
87
|
+
/** Number of decimal places allowed, always shown (e.g. `2` shows `5` as `5.00`). */
|
|
88
|
+
decimalPlaces?: number;
|
|
89
|
+
/** Highest value allowed. Typed values above it are clamped. */
|
|
90
|
+
max?: number;
|
|
91
|
+
/** Lowest value allowed. Typed values below it are clamped. */
|
|
92
|
+
min?: number;
|
|
93
|
+
/** Increment for the stepper buttons and arrow keys. Typed values snap to it. */
|
|
94
|
+
step?: number;
|
|
95
|
+
}
|
|
96
|
+
export declare function numberFilter({ decimalPlaces, excludes, includes, max, min, step, ...config }: FilterItemConfig<NumberOperatorName> & NumberConstraints): FilterNodeItem;
|
|
84
97
|
export {};
|
|
85
98
|
//# sourceMappingURL=numberFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/numberFilter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"numberFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/numberFilter.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,YAAY,EAEZ,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAGtB,eAAO,MAAM,GAAG;;;;;;CAIa,CAAA;AAC7B,eAAO,MAAM,EAAE;;;;;;CAIc,CAAA;AAC7B,eAAO,MAAM,EAAE;;;;;;CAIc,CAAA;AAC7B,eAAO,MAAM,EAAE;;;;;;CAIc,CAAA;AAC7B,eAAO,MAAM,GAAG;;;;;;CAIa,CAAA;AAC7B,eAAO,MAAM,YAAY;;;;;;CAII,CAAA;AAE7B,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAuC,CAAA;AAGjE,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9E,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,CAAC,MAAM,GAAG,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,GACxC,SAAS,CAAA;AAEb,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAC3C,iBAAiB,EACjB,kBAAkB,CACnB,CAAA;AAED,yFAAyF;AACzF,MAAM,WAAW,iBAAiB;IAChC,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,YAAY,CAAC,EAC3B,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,GAAG,EACH,GAAG,EACH,IAAI,EACJ,GAAG,MAAM,EACV,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,GAAG,iBAAiB,GAAG,cAAc,CA4B3E"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Flex } from '../flex/Flex.js';
|
|
2
2
|
import { NumberStepper } from '../number-stepper/NumberStepper.js';
|
|
3
|
-
import React__default, { useRef } from 'react';
|
|
3
|
+
import React__default, { useRef, useState } from 'react';
|
|
4
4
|
import { ActiveFilterInstance } from './ActiveFilterInstance.js';
|
|
5
5
|
import { resolveOperators } from './resolveOperators.js';
|
|
6
6
|
|
|
@@ -36,10 +36,20 @@ const NUMBER_RANGE = {
|
|
|
36
36
|
};
|
|
37
37
|
const ALL_NUMBER_OPERATORS = [EQ, GT, GTE, LT, LTE, NUMBER_RANGE];
|
|
38
38
|
const DEFAULT_NUMBER_OPERATORS = [GTE, LTE, NUMBER_RANGE];
|
|
39
|
-
function numberFilter({ excludes, includes, ...config }) {
|
|
39
|
+
function numberFilter({ decimalPlaces, excludes, includes, max, min, step, ...config }) {
|
|
40
40
|
const filter = {
|
|
41
41
|
...config,
|
|
42
|
-
createActiveFilterInstance: (activeFilter, operator) => new
|
|
42
|
+
createActiveFilterInstance: (activeFilter, operator) => new NumberActiveFilterInstance(filter, operator, activeFilter.value, {
|
|
43
|
+
formatOptions: decimalPlaces === undefined
|
|
44
|
+
? undefined
|
|
45
|
+
: {
|
|
46
|
+
maximumFractionDigits: decimalPlaces,
|
|
47
|
+
minimumFractionDigits: decimalPlaces,
|
|
48
|
+
},
|
|
49
|
+
max,
|
|
50
|
+
min,
|
|
51
|
+
step,
|
|
52
|
+
}),
|
|
43
53
|
operators: resolveOperators(ALL_NUMBER_OPERATORS, {
|
|
44
54
|
default: DEFAULT_NUMBER_OPERATORS,
|
|
45
55
|
excludes,
|
|
@@ -48,11 +58,18 @@ function numberFilter({ excludes, includes, ...config }) {
|
|
|
48
58
|
};
|
|
49
59
|
return filter;
|
|
50
60
|
}
|
|
51
|
-
class
|
|
61
|
+
class NumberActiveFilterInstance extends ActiveFilterInstance {
|
|
62
|
+
constraints;
|
|
63
|
+
constructor(filter, operator, value, constraints) {
|
|
64
|
+
super(filter, operator, value);
|
|
65
|
+
this.constraints = constraints;
|
|
66
|
+
}
|
|
52
67
|
formatValue() {
|
|
68
|
+
const formatter = new Intl.NumberFormat(undefined, this.constraints.formatOptions);
|
|
53
69
|
return [this.value]
|
|
54
70
|
.flat()
|
|
55
71
|
.filter((value) => value !== undefined)
|
|
72
|
+
.map((value) => formatter.format(value))
|
|
56
73
|
.join(" and ");
|
|
57
74
|
}
|
|
58
75
|
renderEditor(onChange) {
|
|
@@ -62,21 +79,35 @@ class NumberActiveFilter extends ActiveFilterInstance {
|
|
|
62
79
|
? {
|
|
63
80
|
initialValues: [start, end],
|
|
64
81
|
labels: [`${label} from`, `${label} to`],
|
|
65
|
-
toValue: (
|
|
82
|
+
toValue: ([from, to]) => [
|
|
83
|
+
from,
|
|
84
|
+
to,
|
|
85
|
+
],
|
|
66
86
|
}
|
|
67
87
|
: {
|
|
68
88
|
initialValues: [start],
|
|
69
89
|
labels: [label],
|
|
70
|
-
toValue: (
|
|
90
|
+
toValue: ([value]) => value,
|
|
71
91
|
};
|
|
72
|
-
return (React__default.createElement(NumberEditor, { key: name, labels: labels, values: initialValues, onCommit: (committed) => onChange({ value: toValue(committed) }, { complete: committed.every((value) => value !== undefined) }) }));
|
|
92
|
+
return (React__default.createElement(NumberEditor, { key: name, constraints: this.constraints, labels: labels, values: initialValues, onCommit: (committed) => onChange({ value: toValue(committed) }, { complete: committed.every((value) => value !== undefined) }) }));
|
|
73
93
|
}
|
|
74
94
|
}
|
|
95
|
+
function lower(a, b) {
|
|
96
|
+
if (a === undefined || b === undefined)
|
|
97
|
+
return a ?? b;
|
|
98
|
+
return Math.min(a, b);
|
|
99
|
+
}
|
|
100
|
+
function higher(a, b) {
|
|
101
|
+
if (a === undefined || b === undefined)
|
|
102
|
+
return a ?? b;
|
|
103
|
+
return Math.max(a, b);
|
|
104
|
+
}
|
|
75
105
|
// React Aria parses typed text in its own blur and Enter handlers, after ours,
|
|
76
106
|
// so parsed values go in a ref and commit from the wrapper's blur (which
|
|
77
107
|
// bubbles after parsing) or Enter's keyup.
|
|
78
|
-
function NumberEditor({ labels, onCommit, values: initialValues, }) {
|
|
108
|
+
function NumberEditor({ constraints, labels, onCommit, values: initialValues, }) {
|
|
79
109
|
const values = useRef(initialValues);
|
|
110
|
+
const [[start, end], setRange] = useState(initialValues);
|
|
80
111
|
const lastCommitted = useRef(initialValues);
|
|
81
112
|
const shouldCommitOnKeyUp = useRef(false);
|
|
82
113
|
const commit = () => {
|
|
@@ -92,14 +123,11 @@ function NumberEditor({ labels, onCommit, values: initialValues, }) {
|
|
|
92
123
|
commit();
|
|
93
124
|
} }, labels.map((label, index) => (React__default.createElement(React__default.Fragment, { key: label },
|
|
94
125
|
index > 0 && React__default.createElement("span", null, "and"),
|
|
95
|
-
React__default.createElement(NumberStepper
|
|
96
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
97
|
-
, {
|
|
98
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
99
|
-
autoFocus: index === 0, defaultValue: initialValues[index], hideLabel: true, label: label, onChange: (value) => {
|
|
126
|
+
React__default.createElement(NumberStepper, { defaultValue: initialValues[index], ...constraints, hideLabel: true, label: label, max: index === 0 ? lower(constraints.max, end) : constraints.max, min: index === 1 ? higher(constraints.min, start) : constraints.min, onChange: (value) => {
|
|
100
127
|
const next = [...values.current];
|
|
101
128
|
next[index] = Number.isNaN(value) ? undefined : value;
|
|
102
129
|
values.current = next;
|
|
130
|
+
setRange(next);
|
|
103
131
|
}, onKeyDown: (e) => {
|
|
104
132
|
shouldCommitOnKeyUp.current =
|
|
105
133
|
e.key === "Enter" && !e.nativeEvent.isComposing;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberFilter.js","sources":["../../../src/components/DataTable/numberFilter.tsx"],"sourcesContent":["import { Flex } from \"@components/flex\"\nimport { NumberStepper } from \"@components/number-stepper\"\nimport React, { useRef } from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type {\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\n\nexport type NumberFilterValue = number | [number, number]\n\nexport const GTE = {\n inputType: { type: \"number\" },\n label: \">=\",\n name: \"gte\",\n} as const satisfies Operator\nexport const GT = {\n inputType: { type: \"number\" },\n label: \">\",\n name: \"gt\",\n} as const satisfies Operator\nexport const LT = {\n inputType: { type: \"number\" },\n label: \"<\",\n name: \"lt\",\n} as const satisfies Operator\nexport const EQ = {\n inputType: { type: \"number\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const LTE = {\n inputType: { type: \"number\" },\n label: \"<=\",\n name: \"lte\",\n} as const satisfies Operator\nexport const NUMBER_RANGE = {\n inputType: { type: \"number-range\" },\n label: \"between\",\n name: \"between\",\n} as const satisfies Operator\n\nconst ALL_NUMBER_OPERATORS = [EQ, GT, GTE, LT, LTE, NUMBER_RANGE]\nconst DEFAULT_NUMBER_OPERATORS = [GTE, LTE, NUMBER_RANGE]\n\nexport type NumberOperatorName = (typeof ALL_NUMBER_OPERATORS)[number][\"name\"]\n\nexport function numberFilter({\n excludes,\n includes,\n ...config\n}: FilterItemConfig<NumberOperatorName>): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new NumberActiveFilter(\n filter,\n operator,\n activeFilter.value as NumberFilterValue\n ),\n operators: resolveOperators(ALL_NUMBER_OPERATORS, {\n default: DEFAULT_NUMBER_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\nclass NumberActiveFilter extends ActiveFilterInstance<NumberFilterValue> {\n formatValue() {\n return [this.value]\n .flat()\n .filter((value) => value !== undefined)\n .join(\" and \")\n }\n\n renderEditor(onChange: FilterChange) {\n const { inputType, label, name } = this.operator\n const [start, end] = [this.value].flat()\n const { initialValues, labels, toValue } =\n inputType.type === \"number-range\"\n ? {\n initialValues: [start, end],\n labels: [`${label} from`, `${label} to`],\n toValue: (committed: NumberInputValue[]) => committed,\n }\n : {\n initialValues: [start],\n labels: [label],\n toValue: (committed: NumberInputValue[]) => committed[0],\n }\n return (\n <NumberEditor\n key={name}\n labels={labels}\n values={initialValues}\n onCommit={(committed) =>\n onChange(\n { value: toValue(committed) },\n { complete: committed.every((value) => value !== undefined) }\n )\n }\n />\n )\n }\n}\n\ntype NumberInputValue = number | undefined\n\n// React Aria parses typed text in its own blur and Enter handlers, after ours,\n// so parsed values go in a ref and commit from the wrapper's blur (which\n// bubbles after parsing) or Enter's keyup.\nfunction NumberEditor({\n labels,\n onCommit,\n values: initialValues,\n}: {\n labels: string[]\n onCommit: (values: NumberInputValue[]) => void\n values: NumberInputValue[]\n}) {\n const values = useRef(initialValues)\n const lastCommitted = useRef(initialValues)\n const shouldCommitOnKeyUp = useRef(false)\n const commit = () => {\n lastCommitted.current = values.current\n onCommit(values.current)\n }\n const changed = () =>\n values.current.some(\n (value, index) => value !== lastCommitted.current[index]\n )\n const isRange = labels.length > 1\n return (\n <Flex\n align=\"center\"\n // Popover content aligns to start; stretch so both inputs fit\n alignSelf={isRange ? \"stretch\" : undefined}\n className={isRange ? \"tds-data-table-filters-number-range\" : undefined}\n gap={1}\n onBlur={() => {\n if (changed()) commit()\n }}\n >\n {labels.map((label, index) => (\n <React.Fragment key={label}>\n {index > 0 && <span>and</span>}\n <NumberStepper\n // eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices\n autoFocus={index === 0}\n defaultValue={initialValues[index]}\n hideLabel\n label={label}\n onChange={(value) => {\n const next = [...values.current]\n next[index] = Number.isNaN(value) ? undefined : value\n values.current = next\n }}\n onKeyDown={(e) => {\n shouldCommitOnKeyUp.current =\n e.key === \"Enter\" && !e.nativeEvent.isComposing\n }}\n onKeyUp={(e) => {\n if (e.key !== \"Enter\" || !shouldCommitOnKeyUp.current) return\n shouldCommitOnKeyUp.current = false\n commit()\n }}\n />\n </React.Fragment>\n ))}\n </Flex>\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"numberFilter.js","sources":["../../../src/components/DataTable/numberFilter.tsx"],"sourcesContent":["import { Flex } from \"@components/flex\"\nimport {\n NumberStepper,\n type NumberStepperElementProps,\n} from \"@components/number-stepper\"\nimport React, { useRef, useState } from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type {\n ActiveFilter,\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\n\nexport const GTE = {\n inputType: { type: \"number\" },\n label: \">=\",\n name: \"gte\",\n} as const satisfies Operator\nexport const GT = {\n inputType: { type: \"number\" },\n label: \">\",\n name: \"gt\",\n} as const satisfies Operator\nexport const LT = {\n inputType: { type: \"number\" },\n label: \"<\",\n name: \"lt\",\n} as const satisfies Operator\nexport const EQ = {\n inputType: { type: \"number\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const LTE = {\n inputType: { type: \"number\" },\n label: \"<=\",\n name: \"lte\",\n} as const satisfies Operator\nexport const NUMBER_RANGE = {\n inputType: { type: \"number-range\" },\n label: \"between\",\n name: \"between\",\n} as const satisfies Operator\n\nconst ALL_NUMBER_OPERATORS = [EQ, GT, GTE, LT, LTE, NUMBER_RANGE]\nconst DEFAULT_NUMBER_OPERATORS = [GTE, LTE, NUMBER_RANGE]\n\nexport type NumberOperatorName = (typeof ALL_NUMBER_OPERATORS)[number][\"name\"]\n\n/** A number; a pair for `between`, either side of which may still be empty. */\nexport type NumberFilterValue =\n | number\n | [number | undefined, number | undefined]\n | undefined\n\nexport type NumberActiveFilter = ActiveFilter<\n NumberFilterValue,\n NumberOperatorName\n>\n\n/** Constraints applied to every input of the filter, including both sides of a range. */\nexport interface NumberConstraints {\n /** Number of decimal places allowed, always shown (e.g. `2` shows `5` as `5.00`). */\n decimalPlaces?: number\n /** Highest value allowed. Typed values above it are clamped. */\n max?: number\n /** Lowest value allowed. Typed values below it are clamped. */\n min?: number\n /** Increment for the stepper buttons and arrow keys. Typed values snap to it. */\n step?: number\n}\n\nexport function numberFilter({\n decimalPlaces,\n excludes,\n includes,\n max,\n min,\n step,\n ...config\n}: FilterItemConfig<NumberOperatorName> & NumberConstraints): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new NumberActiveFilterInstance(\n filter,\n operator,\n activeFilter.value as NumberFilterValue,\n {\n formatOptions:\n decimalPlaces === undefined\n ? undefined\n : {\n maximumFractionDigits: decimalPlaces,\n minimumFractionDigits: decimalPlaces,\n },\n max,\n min,\n step,\n }\n ),\n operators: resolveOperators(ALL_NUMBER_OPERATORS, {\n default: DEFAULT_NUMBER_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\ntype NumberInputConstraints = Pick<\n NumberStepperElementProps,\n \"formatOptions\" | \"max\" | \"min\" | \"step\"\n>\n\nclass NumberActiveFilterInstance extends ActiveFilterInstance<NumberFilterValue> {\n constructor(\n filter: FilterNodeItem,\n operator: Operator,\n value: NumberFilterValue,\n readonly constraints: NumberInputConstraints\n ) {\n super(filter, operator, value)\n }\n\n formatValue() {\n const formatter = new Intl.NumberFormat(\n undefined,\n this.constraints.formatOptions\n )\n return [this.value]\n .flat()\n .filter((value) => value !== undefined)\n .map((value) => formatter.format(value))\n .join(\" and \")\n }\n\n renderEditor(onChange: FilterChange) {\n const { inputType, label, name } = this.operator\n const [start, end] = [this.value].flat()\n const { initialValues, labels, toValue } =\n inputType.type === \"number-range\"\n ? {\n initialValues: [start, end],\n labels: [`${label} from`, `${label} to`],\n toValue: ([from, to]: NumberInputValue[]): NumberFilterValue => [\n from,\n to,\n ],\n }\n : {\n initialValues: [start],\n labels: [label],\n toValue: ([value]: NumberInputValue[]): NumberFilterValue => value,\n }\n return (\n <NumberEditor\n key={name}\n constraints={this.constraints}\n labels={labels}\n values={initialValues}\n onCommit={(committed) =>\n onChange(\n { value: toValue(committed) },\n { complete: committed.every((value) => value !== undefined) }\n )\n }\n />\n )\n }\n}\n\ntype NumberInputValue = number | undefined\n\nfunction lower(a: NumberInputValue, b: NumberInputValue) {\n if (a === undefined || b === undefined) return a ?? b\n return Math.min(a, b)\n}\n\nfunction higher(a: NumberInputValue, b: NumberInputValue) {\n if (a === undefined || b === undefined) return a ?? b\n return Math.max(a, b)\n}\n\n// React Aria parses typed text in its own blur and Enter handlers, after ours,\n// so parsed values go in a ref and commit from the wrapper's blur (which\n// bubbles after parsing) or Enter's keyup.\nfunction NumberEditor({\n constraints,\n labels,\n onCommit,\n values: initialValues,\n}: {\n constraints: NumberInputConstraints\n labels: string[]\n onCommit: (values: NumberInputValue[]) => void\n values: NumberInputValue[]\n}) {\n const values = useRef(initialValues)\n const [[start, end], setRange] = useState(initialValues)\n const lastCommitted = useRef(initialValues)\n const shouldCommitOnKeyUp = useRef(false)\n const commit = () => {\n lastCommitted.current = values.current\n onCommit(values.current)\n }\n const changed = () =>\n values.current.some(\n (value, index) => value !== lastCommitted.current[index]\n )\n const isRange = labels.length > 1\n return (\n <Flex\n align=\"center\"\n // Popover content aligns to start; stretch so both inputs fit\n alignSelf={isRange ? \"stretch\" : undefined}\n className={isRange ? \"tds-data-table-filters-number-range\" : undefined}\n gap={1}\n onBlur={() => {\n if (changed()) commit()\n }}\n >\n {labels.map((label, index) => (\n <React.Fragment key={label}>\n {index > 0 && <span>and</span>}\n <NumberStepper\n defaultValue={initialValues[index]}\n {...constraints}\n hideLabel\n label={label}\n max={index === 0 ? lower(constraints.max, end) : constraints.max}\n min={index === 1 ? higher(constraints.min, start) : constraints.min}\n onChange={(value) => {\n const next = [...values.current]\n next[index] = Number.isNaN(value) ? undefined : value\n values.current = next\n setRange(next)\n }}\n onKeyDown={(e) => {\n shouldCommitOnKeyUp.current =\n e.key === \"Enter\" && !e.nativeEvent.isComposing\n }}\n onKeyUp={(e) => {\n if (e.key !== \"Enter\" || !shouldCommitOnKeyUp.current) return\n shouldCommitOnKeyUp.current = false\n commit()\n }}\n />\n </React.Fragment>\n ))}\n </Flex>\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type { FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
1
|
+
import type { ActiveFilter, FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
2
|
+
export type PresenceOperatorName = "not_present" | "present";
|
|
3
|
+
export type PresenceFilterValue = undefined;
|
|
4
|
+
export type PresenceActiveFilter = ActiveFilter<PresenceFilterValue, PresenceOperatorName>;
|
|
2
5
|
export type PresenceFilterConfig = Omit<FilterItemConfig, "excludes" | "includes"> & {
|
|
3
6
|
/** Adds a `not_present` operator, labeling its chip and option. */
|
|
4
7
|
negatedLabel?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presenceFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/presenceFilter.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"presenceFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/presenceFilter.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAEtB,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,SAAS,CAAA;AAE5D,MAAM,MAAM,mBAAmB,GAAG,SAAS,CAAA;AAE3C,MAAM,MAAM,oBAAoB,GAAG,YAAY,CAC7C,mBAAmB,EACnB,oBAAoB,CACrB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,gBAAgB,EAChB,UAAU,GAAG,UAAU,CACxB,GAAG;IACF,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,YAAY,EACZ,GAAG,MAAM,EACV,EAAE,oBAAoB,GAAG,cAAc,CAkBvC"}
|
|
@@ -12,13 +12,13 @@ function presenceFilter({ label, negatedLabel, ...config }) {
|
|
|
12
12
|
});
|
|
13
13
|
const filter = {
|
|
14
14
|
...config,
|
|
15
|
-
createActiveFilterInstance: (_activeFilter, operator) => new
|
|
15
|
+
createActiveFilterInstance: (_activeFilter, operator) => new PresenceActiveFilterInstance(filter, operator, undefined),
|
|
16
16
|
label,
|
|
17
17
|
operators,
|
|
18
18
|
};
|
|
19
19
|
return filter;
|
|
20
20
|
}
|
|
21
|
-
class
|
|
21
|
+
class PresenceActiveFilterInstance extends ActiveFilterInstance {
|
|
22
22
|
get isCompleteWithoutInput() {
|
|
23
23
|
return true;
|
|
24
24
|
}
|
|
@@ -26,7 +26,7 @@ class PresenceActiveFilter extends ActiveFilterInstance {
|
|
|
26
26
|
return [this.operator.label];
|
|
27
27
|
}
|
|
28
28
|
formatValue() {
|
|
29
|
-
return
|
|
29
|
+
return "";
|
|
30
30
|
}
|
|
31
31
|
renderEditor() {
|
|
32
32
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presenceFilter.js","sources":["../../../src/components/DataTable/presenceFilter.tsx"],"sourcesContent":["import { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type {
|
|
1
|
+
{"version":3,"file":"presenceFilter.js","sources":["../../../src/components/DataTable/presenceFilter.tsx"],"sourcesContent":["import { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type {\n ActiveFilter,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\n\nexport type PresenceOperatorName = \"not_present\" | \"present\"\n\nexport type PresenceFilterValue = undefined\n\nexport type PresenceActiveFilter = ActiveFilter<\n PresenceFilterValue,\n PresenceOperatorName\n>\n\nexport type PresenceFilterConfig = Omit<\n FilterItemConfig,\n \"excludes\" | \"includes\"\n> & {\n /** Adds a `not_present` operator, labeling its chip and option. */\n negatedLabel?: string\n}\n\nexport function presenceFilter({\n label,\n negatedLabel,\n ...config\n}: PresenceFilterConfig): FilterNodeItem {\n const operators: Operator[] = [\n { inputType: { type: \"presence\" }, label, name: \"present\" },\n ]\n if (negatedLabel)\n operators.push({\n inputType: { type: \"presence\" },\n label: negatedLabel,\n name: \"not_present\",\n })\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (_activeFilter, operator) =>\n new PresenceActiveFilterInstance(filter, operator, undefined),\n label,\n operators,\n }\n return filter\n}\n\nclass PresenceActiveFilterInstance extends ActiveFilterInstance<PresenceFilterValue> {\n get isCompleteWithoutInput() {\n return true\n }\n\n toSegments() {\n return [this.operator.label]\n }\n\n formatValue() {\n return \"\"\n }\n\n renderEditor() {\n return null\n }\n}\n"],"names":[],"mappings":";;AAyBM,SAAU,cAAc,CAAC,EAC7B,KAAK,EACL,YAAY,EACZ,GAAG,MAAM,EACY,EAAA;AACrB,IAAA,MAAM,SAAS,GAAe;AAC5B,QAAA,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE;KAC5D;AACD,IAAA,IAAI,YAAY;QACd,SAAS,CAAC,IAAI,CAAC;AACb,YAAA,SAAS,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;AAC/B,YAAA,KAAK,EAAE,YAAY;AACnB,YAAA,IAAI,EAAE,aAAa;AACpB,SAAA,CAAC;AACJ,IAAA,MAAM,MAAM,GAAmB;AAC7B,QAAA,GAAG,MAAM;AACT,QAAA,0BAA0B,EAAE,CAAC,aAAa,EAAE,QAAQ,KAClD,IAAI,4BAA4B,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC/D,KAAK;QACL,SAAS;KACV;AACD,IAAA,OAAO,MAAM;AACf;AAEA,MAAM,4BAA6B,SAAQ,oBAAyC,CAAA;AAClF,IAAA,IAAI,sBAAsB,GAAA;AACxB,QAAA,OAAO,IAAI;IACb;IAEA,UAAU,GAAA;AACR,QAAA,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC9B;IAEA,WAAW,GAAA;AACT,QAAA,OAAO,EAAE;IACX;IAEA,YAAY,GAAA;AACV,QAAA,OAAO,IAAI;IACb;AACD;;;;"}
|
|
@@ -2,7 +2,9 @@ import type { FilterItemConfig, FilterNodeItem, FilterNodeScoped, ScopeOption }
|
|
|
2
2
|
export type ScopedFilterOptions = ScopeOption[];
|
|
3
3
|
export type ScopedFilterOptionsLoader = () => Promise<ScopedFilterOptions> | ScopedFilterOptions;
|
|
4
4
|
export type ScopedFilterConfig = Omit<FilterItemConfig, "excludes" | "includes"> & Pick<FilterNodeScoped, "allowMultiplePerScope"> & {
|
|
5
|
+
/** The filter applied within the chosen scope, usually a `collectionFilter`. */
|
|
5
6
|
filter: FilterNodeItem;
|
|
7
|
+
/** The scopes to pick from, or a function that loads them when the editor opens. */
|
|
6
8
|
options: ScopedFilterOptions | ScopedFilterOptionsLoader;
|
|
7
9
|
};
|
|
8
10
|
export declare function scopedFilter({ allowMultiple, filter: scopeFilter, options, ...config }: ScopedFilterConfig): FilterNodeScoped;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopedFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/scopedFilter.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAEhB,WAAW,EACZ,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"scopedFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/scopedFilter.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAEhB,WAAW,EACZ,MAAM,eAAe,CAAA;AAYtB,MAAM,MAAM,mBAAmB,GAAG,WAAW,EAAE,CAAA;AAE/C,MAAM,MAAM,yBAAyB,GAAG,MACpC,OAAO,CAAC,mBAAmB,CAAC,GAC5B,mBAAmB,CAAA;AAEvB,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,gBAAgB,EAChB,UAAU,GAAG,UAAU,CACxB,GACC,IAAI,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,GAAG;IAChD,gFAAgF;IAChF,MAAM,EAAE,cAAc,CAAA;IACtB,oFAAoF;IACpF,OAAO,EAAE,mBAAmB,GAAG,yBAAyB,CAAA;CACzD,CAAA;AAEH,wBAAgB,YAAY,CAAC,EAC3B,aAAoB,EACpB,MAAM,EAAE,WAAW,EACnB,OAAO,EACP,GAAG,MAAM,EACV,EAAE,kBAAkB,GAAG,gBAAgB,CAYvC"}
|
|
@@ -3,6 +3,7 @@ import React__default from 'react';
|
|
|
3
3
|
import { ActiveFilterInstance } from './ActiveFilterInstance.js';
|
|
4
4
|
import { Loading, LoadError } from './CollectionEditorsLazy.js';
|
|
5
5
|
import { useHasFilterInstancesChecker } from './FilterContext.js';
|
|
6
|
+
import { useFocusFirstControlAfterLoad } from './FocusFirstControl.js';
|
|
6
7
|
import { OperatorSelect } from './OperatorSelect.js';
|
|
7
8
|
import { useLazyOptions } from './useLazyOptions.js';
|
|
8
9
|
import { isEmptyValue, getDefaultOperatorName } from './utils.js';
|
|
@@ -58,18 +59,19 @@ class ScopedActiveFilter extends ActiveFilterInstance {
|
|
|
58
59
|
const { scopeLabel } = this;
|
|
59
60
|
if (!scopeLabel)
|
|
60
61
|
return [this.filter.label];
|
|
62
|
+
const scopeSegment = { kind: "scope", label: scopeLabel };
|
|
61
63
|
if (this.activeFilter.value === undefined)
|
|
62
|
-
return [this.filter.label,
|
|
64
|
+
return [this.filter.label, scopeSegment];
|
|
63
65
|
const SKIP_SCOPE_FILTER_LABEL = 1;
|
|
64
66
|
return [
|
|
65
67
|
this.filter.label,
|
|
66
|
-
|
|
68
|
+
scopeSegment,
|
|
67
69
|
...this.scopeFilterInstance.toSegments().slice(SKIP_SCOPE_FILTER_LABEL),
|
|
68
70
|
];
|
|
69
71
|
}
|
|
70
72
|
formatValue() {
|
|
71
73
|
if (!this.scopeLabel)
|
|
72
|
-
return
|
|
74
|
+
return "";
|
|
73
75
|
return this.scopeFilterInstance.formatValue();
|
|
74
76
|
}
|
|
75
77
|
renderEditor(onChange) {
|
|
@@ -90,6 +92,7 @@ class ScopedActiveFilter extends ActiveFilterInstance {
|
|
|
90
92
|
}
|
|
91
93
|
function LazyScopeEditor({ loadOptions, ...props }) {
|
|
92
94
|
const { error, loading, options } = useLazyOptions(loadOptions);
|
|
95
|
+
useFocusFirstControlAfterLoad(loading);
|
|
93
96
|
if (loading)
|
|
94
97
|
return React__default.createElement(Loading, null);
|
|
95
98
|
if (error)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopedFilter.js","sources":["../../../src/components/DataTable/scopedFilter.tsx"],"sourcesContent":["import { Select } from \"@components/select\"\nimport React from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport { LoadError, Loading } from \"./CollectionEditorsLazy\"\nimport { useHasFilterInstancesChecker } from \"./FilterContext\"\nimport type {\n ActiveFilter,\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n FilterNodeScoped,\n Operator,\n ScopeOption,\n} from \"./FilterTypes\"\nimport { OperatorSelect } from \"./OperatorSelect\"\nimport { useLazyOptions } from \"./useLazyOptions\"\nimport { getDefaultOperatorName, isEmptyValue } from \"./utils\"\n\nconst SCOPED_DEFAULT = {\n inputType: { type: \"scoped\" },\n label: \"\",\n name: \"scoped\",\n} as const satisfies Operator\n\nexport type ScopedFilterOptions = ScopeOption[]\n\nexport type ScopedFilterOptionsLoader = () =>\n | Promise<ScopedFilterOptions>\n | ScopedFilterOptions\n\nexport type ScopedFilterConfig = Omit<\n FilterItemConfig,\n \"excludes\" | \"includes\"\n> &\n Pick<FilterNodeScoped, \"allowMultiplePerScope\"> & {\n filter: FilterNodeItem\n options: ScopedFilterOptions | ScopedFilterOptionsLoader\n }\n\nexport function scopedFilter({\n allowMultiple = true,\n filter: scopeFilter,\n options,\n ...config\n}: ScopedFilterConfig): FilterNodeScoped {\n const loadOptions = typeof options === \"function\" ? options : undefined\n const filter: FilterNodeScoped = {\n ...config,\n allowMultiple,\n createActiveFilterInstance: (activeFilter, operator) =>\n new ScopedActiveFilter(filter, operator, activeFilter, loadOptions),\n operators: [SCOPED_DEFAULT],\n options: typeof options === \"function\" ? [] : options,\n scopeFilter,\n }\n return filter\n}\n\nfunction defaultScopedActiveFilter(\n parentName: string,\n scopeFilter: FilterNodeItem,\n option: ScopeOption\n): ActiveFilter {\n return {\n label: undefined,\n name: parentName,\n operator: getDefaultOperatorName(scopeFilter),\n scope: option.value,\n value: undefined,\n }\n}\n\nclass ScopedActiveFilter extends ActiveFilterInstance<unknown> {\n private readonly activeFilter: ActiveFilter\n\n constructor(\n private readonly scopedFilter: FilterNodeScoped,\n operator: Operator,\n activeFilter: ActiveFilter,\n private readonly loadOptions: ScopedFilterOptionsLoader | undefined\n ) {\n super(scopedFilter, operator, activeFilter.value)\n this.activeFilter = activeFilter\n }\n\n private get scopeLabel() {\n const { scope, scopeLabel } = this.activeFilter\n if (scope === undefined) return undefined\n if (this.loadOptions) return scopeLabel ?? scope\n return this.scopedFilter.options.find(({ value }) => value === scope)?.label\n }\n\n private get scopeFilterInstance() {\n return this.scopedFilter.scopeFilter.createActiveFilterInstance(\n this.activeFilter,\n this.operator\n )\n }\n\n toSegments() {\n const { scopeLabel } = this\n if (!scopeLabel) return [this.filter.label]\n\n if (this.activeFilter.value === undefined)\n return [this.filter.label, scopeLabel]\n\n const SKIP_SCOPE_FILTER_LABEL = 1\n return [\n this.filter.label,\n scopeLabel,\n ...this.scopeFilterInstance.toSegments().slice(SKIP_SCOPE_FILTER_LABEL),\n ]\n }\n\n formatValue() {\n if (!this.scopeLabel) return []\n return this.scopeFilterInstance.formatValue()\n }\n\n renderEditor(onChange: FilterChange) {\n const props = {\n activeFilter: this.activeFilter,\n allowMultiplePerScope: this.scopedFilter.allowMultiplePerScope,\n label: this.filter.label,\n onChange,\n scopeFilter: this.scopedFilter.scopeFilter,\n scopeFilterInstance:\n this.activeFilter.scope === undefined\n ? undefined\n : this.scopeFilterInstance,\n }\n\n if (this.loadOptions)\n return <LazyScopeEditor {...props} loadOptions={this.loadOptions} />\n\n return <ScopeEditor {...props} options={this.scopedFilter.options} />\n }\n}\n\ntype ScopeEditorProps = {\n activeFilter: ActiveFilter\n allowMultiplePerScope: boolean | undefined\n label: string\n onChange: FilterChange\n scopeFilter: FilterNodeItem\n scopeFilterInstance: ActiveFilterInstance | undefined\n}\n\nfunction LazyScopeEditor({\n loadOptions,\n ...props\n}: ScopeEditorProps & { loadOptions: ScopedFilterOptionsLoader }) {\n const { error, loading, options } = useLazyOptions(loadOptions)\n if (loading) return <Loading />\n if (error) return <LoadError />\n\n const { activeFilter } = props\n const isScopeMissing =\n activeFilter.scope !== undefined &&\n !options.some(({ value }) => value === activeFilter.scope)\n\n const reset = isScopeMissing && {\n activeFilter: {\n name: activeFilter.name,\n operator: SCOPED_DEFAULT.name,\n value: undefined,\n },\n scopeFilterInstance: undefined,\n }\n\n return <ScopeEditor {...props} {...reset} options={options} storeScopeLabel />\n}\n\nfunction ScopeEditor({\n activeFilter,\n allowMultiplePerScope,\n label,\n onChange,\n options,\n scopeFilter,\n scopeFilterInstance,\n storeScopeLabel = false,\n}: ScopeEditorProps & {\n options: ScopedFilterOptions\n /** Lazy scopes only: the chip can't look the label up, so it's stored. */\n storeScopeLabel?: boolean\n}) {\n const remembered = React.useRef<\n Record<string, Pick<ActiveFilter, \"label\" | \"operator\" | \"value\">>\n >({})\n const hasFilterInstances = useHasFilterInstancesChecker()\n const scopeOptions = allowMultiplePerScope\n ? options\n : options.map((option) => ({\n ...option,\n disabled:\n option.value !== activeFilter.scope &&\n hasFilterInstances(activeFilter.name, option.value),\n }))\n\n return (\n <>\n <Select\n hideLabel\n label={label}\n options={scopeOptions}\n placeholder={`Select a ${label.toLowerCase()}`}\n value={activeFilter.scope ?? \"\"}\n onChange={(e) => {\n const { label: valueLabel, operator, scope, value } = activeFilter\n if (scope !== undefined) {\n if (isEmptyValue(value)) {\n delete remembered.current[scope]\n } else {\n remembered.current[scope] = {\n operator,\n value,\n ...(valueLabel !== undefined && { label: valueLabel }),\n }\n }\n }\n const next = options.find((option) => option.value === e.target.value)\n if (!next) return\n const restored = remembered.current[next.value]\n const scoped = {\n ...defaultScopedActiveFilter(activeFilter.name, scopeFilter, next),\n ...(storeScopeLabel && { scopeLabel: next.label }),\n ...restored,\n }\n onChange(scoped, { complete: !isEmptyValue(scoped.value) })\n }}\n />\n {scopeFilterInstance && (\n <SelectedScopeEditor\n activeFilter={activeFilter}\n instance={scopeFilterInstance}\n scopeFilter={scopeFilter}\n onChange={onChange}\n />\n )}\n </>\n )\n}\n\nfunction SelectedScopeEditor({\n activeFilter,\n instance,\n scopeFilter,\n onChange,\n}: {\n activeFilter: ActiveFilter\n instance: ActiveFilterInstance\n onChange: FilterChange\n scopeFilter: FilterNodeItem\n}) {\n return (\n <>\n <OperatorSelect\n operator={instance.operator}\n relatedFilter={scopeFilter}\n updateActiveFilter={(updates) => {\n if (updates.operator && updates.operator !== activeFilter.operator) {\n onChange({ ...updates, value: undefined }, { complete: false })\n return\n }\n onChange(updates, { complete: false })\n }}\n />\n <React.Fragment key={`${activeFilter.scope}:${instance.operator.name}`}>\n {instance.renderEditor(onChange)}\n </React.Fragment>\n </>\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scopedFilter.js","sources":["../../../src/components/DataTable/scopedFilter.tsx"],"sourcesContent":["import { Select } from \"@components/select\"\nimport React from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport { LoadError, Loading } from \"./CollectionEditorsLazy\"\nimport { useHasFilterInstancesChecker } from \"./FilterContext\"\nimport type {\n ActiveFilter,\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n FilterNodeScoped,\n Operator,\n ScopeOption,\n} from \"./FilterTypes\"\nimport { useFocusFirstControlAfterLoad } from \"./FocusFirstControl\"\nimport { OperatorSelect } from \"./OperatorSelect\"\nimport { useLazyOptions } from \"./useLazyOptions\"\nimport { getDefaultOperatorName, isEmptyValue } from \"./utils\"\n\nconst SCOPED_DEFAULT = {\n inputType: { type: \"scoped\" },\n label: \"\",\n name: \"scoped\",\n} as const satisfies Operator\n\nexport type ScopedFilterOptions = ScopeOption[]\n\nexport type ScopedFilterOptionsLoader = () =>\n | Promise<ScopedFilterOptions>\n | ScopedFilterOptions\n\nexport type ScopedFilterConfig = Omit<\n FilterItemConfig,\n \"excludes\" | \"includes\"\n> &\n Pick<FilterNodeScoped, \"allowMultiplePerScope\"> & {\n /** The filter applied within the chosen scope, usually a `collectionFilter`. */\n filter: FilterNodeItem\n /** The scopes to pick from, or a function that loads them when the editor opens. */\n options: ScopedFilterOptions | ScopedFilterOptionsLoader\n }\n\nexport function scopedFilter({\n allowMultiple = true,\n filter: scopeFilter,\n options,\n ...config\n}: ScopedFilterConfig): FilterNodeScoped {\n const loadOptions = typeof options === \"function\" ? options : undefined\n const filter: FilterNodeScoped = {\n ...config,\n allowMultiple,\n createActiveFilterInstance: (activeFilter, operator) =>\n new ScopedActiveFilter(filter, operator, activeFilter, loadOptions),\n operators: [SCOPED_DEFAULT],\n options: typeof options === \"function\" ? [] : options,\n scopeFilter,\n }\n return filter\n}\n\nfunction defaultScopedActiveFilter(\n parentName: string,\n scopeFilter: FilterNodeItem,\n option: ScopeOption\n): ActiveFilter {\n return {\n label: undefined,\n name: parentName,\n operator: getDefaultOperatorName(scopeFilter),\n scope: option.value,\n value: undefined,\n }\n}\n\nclass ScopedActiveFilter extends ActiveFilterInstance<unknown> {\n private readonly activeFilter: ActiveFilter\n\n constructor(\n private readonly scopedFilter: FilterNodeScoped,\n operator: Operator,\n activeFilter: ActiveFilter,\n private readonly loadOptions: ScopedFilterOptionsLoader | undefined\n ) {\n super(scopedFilter, operator, activeFilter.value)\n this.activeFilter = activeFilter\n }\n\n private get scopeLabel() {\n const { scope, scopeLabel } = this.activeFilter\n if (scope === undefined) return undefined\n if (this.loadOptions) return scopeLabel ?? scope\n return this.scopedFilter.options.find(({ value }) => value === scope)?.label\n }\n\n private get scopeFilterInstance() {\n return this.scopedFilter.scopeFilter.createActiveFilterInstance(\n this.activeFilter,\n this.operator\n )\n }\n\n toSegments() {\n const { scopeLabel } = this\n if (!scopeLabel) return [this.filter.label]\n\n const scopeSegment = { kind: \"scope\", label: scopeLabel } as const\n if (this.activeFilter.value === undefined)\n return [this.filter.label, scopeSegment]\n\n const SKIP_SCOPE_FILTER_LABEL = 1\n return [\n this.filter.label,\n scopeSegment,\n ...this.scopeFilterInstance.toSegments().slice(SKIP_SCOPE_FILTER_LABEL),\n ]\n }\n\n formatValue() {\n if (!this.scopeLabel) return \"\"\n return this.scopeFilterInstance.formatValue()\n }\n\n renderEditor(onChange: FilterChange) {\n const props = {\n activeFilter: this.activeFilter,\n allowMultiplePerScope: this.scopedFilter.allowMultiplePerScope,\n label: this.filter.label,\n onChange,\n scopeFilter: this.scopedFilter.scopeFilter,\n scopeFilterInstance:\n this.activeFilter.scope === undefined\n ? undefined\n : this.scopeFilterInstance,\n }\n\n if (this.loadOptions)\n return <LazyScopeEditor {...props} loadOptions={this.loadOptions} />\n\n return <ScopeEditor {...props} options={this.scopedFilter.options} />\n }\n}\n\ntype ScopeEditorProps = {\n activeFilter: ActiveFilter\n allowMultiplePerScope: boolean | undefined\n label: string\n onChange: FilterChange\n scopeFilter: FilterNodeItem\n scopeFilterInstance: ActiveFilterInstance | undefined\n}\n\nfunction LazyScopeEditor({\n loadOptions,\n ...props\n}: ScopeEditorProps & { loadOptions: ScopedFilterOptionsLoader }) {\n const { error, loading, options } = useLazyOptions(loadOptions)\n useFocusFirstControlAfterLoad(loading)\n if (loading) return <Loading />\n if (error) return <LoadError />\n\n const { activeFilter } = props\n const isScopeMissing =\n activeFilter.scope !== undefined &&\n !options.some(({ value }) => value === activeFilter.scope)\n\n const reset = isScopeMissing && {\n activeFilter: {\n name: activeFilter.name,\n operator: SCOPED_DEFAULT.name,\n value: undefined,\n },\n scopeFilterInstance: undefined,\n }\n\n return <ScopeEditor {...props} {...reset} options={options} storeScopeLabel />\n}\n\nfunction ScopeEditor({\n activeFilter,\n allowMultiplePerScope,\n label,\n onChange,\n options,\n scopeFilter,\n scopeFilterInstance,\n storeScopeLabel = false,\n}: ScopeEditorProps & {\n options: ScopedFilterOptions\n /** Lazy scopes only: the chip can't look the label up, so it's stored. */\n storeScopeLabel?: boolean\n}) {\n const remembered = React.useRef<\n Record<string, Pick<ActiveFilter, \"label\" | \"operator\" | \"value\">>\n >({})\n const hasFilterInstances = useHasFilterInstancesChecker()\n const scopeOptions = allowMultiplePerScope\n ? options\n : options.map((option) => ({\n ...option,\n disabled:\n option.value !== activeFilter.scope &&\n hasFilterInstances(activeFilter.name, option.value),\n }))\n\n return (\n <>\n <Select\n hideLabel\n label={label}\n options={scopeOptions}\n placeholder={`Select a ${label.toLowerCase()}`}\n value={activeFilter.scope ?? \"\"}\n onChange={(e) => {\n const { label: valueLabel, operator, scope, value } = activeFilter\n if (scope !== undefined) {\n if (isEmptyValue(value)) {\n delete remembered.current[scope]\n } else {\n remembered.current[scope] = {\n operator,\n value,\n ...(valueLabel !== undefined && { label: valueLabel }),\n }\n }\n }\n const next = options.find((option) => option.value === e.target.value)\n if (!next) return\n const restored = remembered.current[next.value]\n const scoped = {\n ...defaultScopedActiveFilter(activeFilter.name, scopeFilter, next),\n ...(storeScopeLabel && { scopeLabel: next.label }),\n ...restored,\n }\n onChange(scoped, { complete: !isEmptyValue(scoped.value) })\n }}\n />\n {scopeFilterInstance && (\n <SelectedScopeEditor\n activeFilter={activeFilter}\n instance={scopeFilterInstance}\n scopeFilter={scopeFilter}\n onChange={onChange}\n />\n )}\n </>\n )\n}\n\nfunction SelectedScopeEditor({\n activeFilter,\n instance,\n scopeFilter,\n onChange,\n}: {\n activeFilter: ActiveFilter\n instance: ActiveFilterInstance\n onChange: FilterChange\n scopeFilter: FilterNodeItem\n}) {\n return (\n <>\n <OperatorSelect\n operator={instance.operator}\n relatedFilter={scopeFilter}\n updateActiveFilter={(updates) => {\n if (updates.operator && updates.operator !== activeFilter.operator) {\n onChange({ ...updates, value: undefined }, { complete: false })\n return\n }\n onChange(updates, { complete: false })\n }}\n />\n <React.Fragment key={`${activeFilter.scope}:${instance.operator.name}`}>\n {instance.renderEditor(onChange)}\n </React.Fragment>\n </>\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
1
|
+
import type { ActiveFilter, FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
2
2
|
export declare const EQ: {
|
|
3
3
|
readonly inputType: {
|
|
4
4
|
readonly type: "text";
|
|
@@ -53,6 +53,8 @@ declare const ALL_TEXT_OPERATORS: ({
|
|
|
53
53
|
readonly name: "starts_with";
|
|
54
54
|
})[];
|
|
55
55
|
export type TextOperatorName = (typeof ALL_TEXT_OPERATORS)[number]["name"];
|
|
56
|
+
export type TextFilterValue = string | undefined;
|
|
57
|
+
export type TextActiveFilter = ActiveFilter<TextFilterValue, TextOperatorName>;
|
|
56
58
|
export declare function textFilter({ excludes, includes, ...config }: FilterItemConfig<TextOperatorName>): FilterNodeItem;
|
|
57
59
|
export {};
|
|
58
60
|
//# sourceMappingURL=textFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/textFilter.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"textFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/textFilter.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EAEZ,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAItB,eAAO,MAAM,EAAE;;;;;;CAIc,CAAA;AAC7B,eAAO,MAAM,QAAQ;;;;;;CAIQ,CAAA;AAC7B,eAAO,MAAM,GAAG;;;;;;CAIa,CAAA;AAC7B,eAAO,MAAM,WAAW;;;;;;CAIK,CAAA;AAE7B,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;IAAmC,CAAA;AAG3D,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1E,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,CAAA;AAEhD,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAA;AAE9E,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,QAAQ,EACR,GAAG,MAAM,EACV,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAgBrD"}
|
|
@@ -29,7 +29,7 @@ const DEFAULT_TEXT_OPERATORS = [CONTAINS];
|
|
|
29
29
|
function textFilter({ excludes, includes, ...config }) {
|
|
30
30
|
const filter = {
|
|
31
31
|
...config,
|
|
32
|
-
createActiveFilterInstance: (activeFilter, operator) => new
|
|
32
|
+
createActiveFilterInstance: (activeFilter, operator) => new TextActiveFilterInstance(filter, operator, activeFilter.value),
|
|
33
33
|
operators: resolveOperators(ALL_TEXT_OPERATORS, {
|
|
34
34
|
default: DEFAULT_TEXT_OPERATORS,
|
|
35
35
|
excludes,
|
|
@@ -38,26 +38,22 @@ function textFilter({ excludes, includes, ...config }) {
|
|
|
38
38
|
};
|
|
39
39
|
return filter;
|
|
40
40
|
}
|
|
41
|
-
class
|
|
41
|
+
class TextActiveFilterInstance extends ActiveFilterInstance {
|
|
42
42
|
formatValue() {
|
|
43
|
-
return this.value;
|
|
43
|
+
return this.value ?? "";
|
|
44
44
|
}
|
|
45
45
|
renderEditor(onChange) {
|
|
46
46
|
return (React__default.createElement(TextEditor, { label: this.operator.label, value: this.value, onCommit: (value) => onChange({ value }, { complete: !isEmptyValue(value) }) }));
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
function TextEditor({ label, onCommit, value: initialValue, }) {
|
|
49
|
+
function TextEditor({ label, onCommit, value: initialValue = "", }) {
|
|
50
50
|
const [value, setValue] = useState(initialValue);
|
|
51
51
|
const lastCommitted = useRef(initialValue);
|
|
52
52
|
const commit = () => {
|
|
53
53
|
lastCommitted.current = value;
|
|
54
54
|
onCommit(value);
|
|
55
55
|
};
|
|
56
|
-
return (React__default.createElement(Input
|
|
57
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
58
|
-
, {
|
|
59
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
60
|
-
autoFocus: true, hideLabel: true, label: label, value: value, onChange: (e) => setValue(e.target.value), onBlur: () => {
|
|
56
|
+
return (React__default.createElement(Input, { hideLabel: true, label: label, value: value, onChange: (e) => setValue(e.target.value), onBlur: () => {
|
|
61
57
|
if (value !== lastCommitted.current)
|
|
62
58
|
commit();
|
|
63
59
|
}, onKeyDown: (e) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"textFilter.js","sources":["../../../src/components/DataTable/textFilter.tsx"],"sourcesContent":["import { Input } from \"@components/input\"\nimport React, { useRef, useState } from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type {\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\nimport { isEmptyValue } from \"./utils\"\n\nexport const EQ = {\n inputType: { type: \"text\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const CONTAINS = {\n inputType: { type: \"text\" },\n label: \"contains\",\n name: \"contains\",\n} as const satisfies Operator\nexport const NOT = {\n inputType: { type: \"text\" },\n label: \"is not\",\n name: \"not\",\n} as const satisfies Operator\nexport const STARTS_WITH = {\n inputType: { type: \"text\" },\n label: \"starts with\",\n name: \"starts_with\",\n} as const satisfies Operator\n\nconst ALL_TEXT_OPERATORS = [EQ, CONTAINS, NOT, STARTS_WITH]\nconst DEFAULT_TEXT_OPERATORS = [CONTAINS]\n\nexport type TextOperatorName = (typeof ALL_TEXT_OPERATORS)[number][\"name\"]\n\nexport function textFilter({\n excludes,\n includes,\n ...config\n}: FilterItemConfig<TextOperatorName>): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new
|
|
1
|
+
{"version":3,"file":"textFilter.js","sources":["../../../src/components/DataTable/textFilter.tsx"],"sourcesContent":["import { Input } from \"@components/input\"\nimport React, { useRef, useState } from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport type {\n ActiveFilter,\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\nimport { isEmptyValue } from \"./utils\"\n\nexport const EQ = {\n inputType: { type: \"text\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const CONTAINS = {\n inputType: { type: \"text\" },\n label: \"contains\",\n name: \"contains\",\n} as const satisfies Operator\nexport const NOT = {\n inputType: { type: \"text\" },\n label: \"is not\",\n name: \"not\",\n} as const satisfies Operator\nexport const STARTS_WITH = {\n inputType: { type: \"text\" },\n label: \"starts with\",\n name: \"starts_with\",\n} as const satisfies Operator\n\nconst ALL_TEXT_OPERATORS = [EQ, CONTAINS, NOT, STARTS_WITH]\nconst DEFAULT_TEXT_OPERATORS = [CONTAINS]\n\nexport type TextOperatorName = (typeof ALL_TEXT_OPERATORS)[number][\"name\"]\n\nexport type TextFilterValue = string | undefined\n\nexport type TextActiveFilter = ActiveFilter<TextFilterValue, TextOperatorName>\n\nexport function textFilter({\n excludes,\n includes,\n ...config\n}: FilterItemConfig<TextOperatorName>): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new TextActiveFilterInstance(\n filter,\n operator,\n activeFilter.value as TextFilterValue\n ),\n operators: resolveOperators(ALL_TEXT_OPERATORS, {\n default: DEFAULT_TEXT_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\nclass TextActiveFilterInstance extends ActiveFilterInstance<TextFilterValue> {\n formatValue() {\n return this.value ?? \"\"\n }\n\n renderEditor(onChange: FilterChange) {\n return (\n <TextEditor\n label={this.operator.label}\n value={this.value}\n onCommit={(value) =>\n onChange({ value }, { complete: !isEmptyValue(value) })\n }\n />\n )\n }\n}\n\nfunction TextEditor({\n label,\n onCommit,\n value: initialValue = \"\",\n}: {\n label: string\n onCommit: (value: string) => void\n value: TextFilterValue\n}) {\n const [value, setValue] = useState(initialValue)\n const lastCommitted = useRef(initialValue)\n const commit = () => {\n lastCommitted.current = value\n onCommit(value)\n }\n return (\n <Input\n hideLabel\n label={label}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onBlur={() => {\n if (value !== lastCommitted.current) commit()\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.repeat && !e.nativeEvent.isComposing) {\n commit()\n }\n }}\n />\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ export declare const SEARCH_FILTER_NAME = "q";
|
|
|
4
4
|
export declare const SEARCH_FILTER_OPERATOR = "contains";
|
|
5
5
|
export declare const isSearchFilter: (filter: ActiveFilter) => boolean;
|
|
6
6
|
export declare function useSearchFilter(activeFilters: ActiveFilter[], onActiveFiltersChange: (activeFilters: ActiveFilter[]) => void): {
|
|
7
|
-
chipFilters: ActiveFilter<
|
|
7
|
+
chipFilters: ActiveFilter<import("./FilterTypes").ActiveFilterValue, string>[];
|
|
8
8
|
clearFilters: () => void;
|
|
9
9
|
onChipFiltersChange: (chipFilters: ActiveFilter[]) => void;
|
|
10
10
|
onSearchChange: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FilterNodeItem, FilterNodeScoped } from "./FilterTypes";
|
|
2
|
+
/** A new filter starts on its first operator; order operators with `includes` to choose it. */
|
|
2
3
|
export declare function getDefaultOperatorName(node: FilterNodeItem): string;
|
|
3
4
|
export declare function isEmptyValue(value: unknown): boolean;
|
|
4
5
|
/** Whether a filter delegates to scoped options. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAErE,+FAA+F;AAC/F,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAGnE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGpD;AAED,oDAAoD;AACpD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,cAAc,GACrB,MAAM,IAAI,gBAAgB,CAE5B;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,WAMzC;AAED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,WAInE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/** A new filter starts on its first operator; order operators with `includes` to choose it. */
|
|
2
2
|
function getDefaultOperatorName(node) {
|
|
3
3
|
const operatorName = node.operators?.[0]?.name;
|
|
4
4
|
return typeof operatorName === "string" ? operatorName : "default";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/components/DataTable/utils.ts"],"sourcesContent":["import type { FilterNodeItem, FilterNodeScoped } from \"./FilterTypes\"\n\n
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/components/DataTable/utils.ts"],"sourcesContent":["import type { FilterNodeItem, FilterNodeScoped } from \"./FilterTypes\"\n\n/** A new filter starts on its first operator; order operators with `includes` to choose it. */\nexport function getDefaultOperatorName(node: FilterNodeItem): string {\n const operatorName = node.operators?.[0]?.name\n return typeof operatorName === \"string\" ? operatorName : \"default\"\n}\n\nexport function isEmptyValue(value: unknown): boolean {\n if (value === undefined || value === null || value === \"\") return true\n return Array.isArray(value) && value.length === 0\n}\n\n/** Whether a filter delegates to scoped options. */\nexport function isScopedFilter(\n filter: FilterNodeItem\n): filter is FilterNodeScoped {\n return Array.isArray((filter as FilterNodeScoped).options)\n}\n\n/** Lazy scopes aren't known until the editor loads them, so any one might be free. */\nexport function hasAvailableScope(\n filter: FilterNodeScoped,\n isScopeTaken: (scope: string) => boolean\n) {\n return (\n isLazyScoped(filter) ||\n filter.options.some(({ value }) => !isScopeTaken(value))\n )\n}\n\n/** Whether `scope` is one of the filter's scopes. Lazy scopes are assumed to be. */\nexport function isKnownScope(filter: FilterNodeScoped, scope: string) {\n return (\n isLazyScoped(filter) || filter.options.some(({ value }) => value === scope)\n )\n}\n\nfunction isLazyScoped(filter: FilterNodeScoped) {\n return filter.options.length === 0\n}\n"],"names":[],"mappings":"AAEA;AACM,SAAU,sBAAsB,CAAC,IAAoB,EAAA;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,IAAI;AAC9C,IAAA,OAAO,OAAO,YAAY,KAAK,QAAQ,GAAG,YAAY,GAAG,SAAS;AACpE;AAEM,SAAU,YAAY,CAAC,KAAc,EAAA;IACzC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,IAAI;AACtE,IAAA,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;AACnD;AAEA;AACM,SAAU,cAAc,CAC5B,MAAsB,EAAA;IAEtB,OAAO,KAAK,CAAC,OAAO,CAAE,MAA2B,CAAC,OAAO,CAAC;AAC5D;AAEA;AACM,SAAU,iBAAiB,CAC/B,MAAwB,EACxB,YAAwC,EAAA;AAExC,IAAA,QACE,YAAY,CAAC,MAAM,CAAC;AACpB,QAAA,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AAE5D;AAEA;AACM,SAAU,YAAY,CAAC,MAAwB,EAAE,KAAa,EAAA;IAClE,QACE,YAAY,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,KAAK,KAAK,CAAC;AAE/E;AAEA,SAAS,YAAY,CAAC,MAAwB,EAAA;AAC5C,IAAA,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;AACpC;;;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "./index.css";
|
|
2
2
|
import React, { type ButtonHTMLAttributes } from "react";
|
|
3
|
+
import { type SegmentKind } from "./SegmentBase";
|
|
3
4
|
export interface IconSegmentProps {
|
|
4
5
|
/** Accessible label — required since there's no visible text. */
|
|
5
6
|
"aria-label": string;
|
|
@@ -7,6 +8,10 @@ export interface IconSegmentProps {
|
|
|
7
8
|
disabled?: boolean;
|
|
8
9
|
/** The icon to display. */
|
|
9
10
|
icon: React.ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* This segment's color when selected. Default `'interaction-subtle'`.
|
|
13
|
+
*/
|
|
14
|
+
kind?: SegmentKind;
|
|
10
15
|
/** Unique identifier for this item. */
|
|
11
16
|
value: string;
|
|
12
17
|
}
|
|
@@ -17,7 +22,7 @@ export type IconSegmentElementProps = Omit<ButtonHTMLAttributes<HTMLButtonElemen
|
|
|
17
22
|
* selection state, group `disabled`, and roving tabindex from that context.
|
|
18
23
|
*
|
|
19
24
|
* @component
|
|
20
|
-
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/
|
|
25
|
+
* @see {@link https://planningcenter.github.io/tapestry/?path=/docs/forms-segmentedcontrol--docs | Storybook Documentation}
|
|
21
26
|
*/
|
|
22
27
|
export declare const IconSegment: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children" | "tabIndex" | "role" | "aria-checked" | "onKeyDown" | "onClick" | "type" | keyof IconSegmentProps> & IconSegmentProps & React.RefAttributes<HTMLButtonElement>>;
|
|
23
28
|
//# sourceMappingURL=IconSegment.d.ts.map
|