@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
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { ActiveFilterInstance } from "./ActiveFilterInstance";
|
|
2
|
+
import type { CollectionFilterValue } from "./CollectionEditorsShared";
|
|
3
|
+
import type { DateFilterValue } from "./dateFilter";
|
|
4
|
+
import type { DayFilterValue } from "./dayFilter";
|
|
5
|
+
import type { NumberFilterValue } from "./numberFilter";
|
|
6
|
+
import type { PresenceFilterValue } from "./presenceFilter";
|
|
7
|
+
import type { TextFilterValue } from "./textFilter";
|
|
2
8
|
export interface FilterNodeBase {
|
|
3
9
|
/** Extra search terms beyond the label. */
|
|
4
10
|
keywords?: string[];
|
|
@@ -11,6 +17,19 @@ export interface Operator {
|
|
|
11
17
|
label: string;
|
|
12
18
|
name: string;
|
|
13
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* One segment of a filter chip. Plain strings are the field and operator.
|
|
22
|
+
* Scope and value segments hold user-created text, so they're marked by kind.
|
|
23
|
+
* A value's `count` is shown when its list of items is truncated.
|
|
24
|
+
*/
|
|
25
|
+
export type FilterChipSegment = string | {
|
|
26
|
+
kind: "scope";
|
|
27
|
+
label: string;
|
|
28
|
+
} | {
|
|
29
|
+
count?: number;
|
|
30
|
+
kind: "value";
|
|
31
|
+
label: string;
|
|
32
|
+
};
|
|
14
33
|
export interface FilterNodeItem extends FilterNodeBase {
|
|
15
34
|
/** Whether multiple instances of this filter can be active simultaneously. `scopedFilter` defaults this to true. */
|
|
16
35
|
allowMultiple?: boolean;
|
|
@@ -61,11 +80,13 @@ export interface FilterNodeGroup extends FilterNodeBase {
|
|
|
61
80
|
renderChildrenInSubmenu?: boolean;
|
|
62
81
|
}
|
|
63
82
|
export type FilterNode = FilterNodeItem | FilterNodeGroup;
|
|
64
|
-
/** Narrow a factory's operator set by name. `includes` keeps only the named operators, in the order given; `excludes` drops them. */
|
|
83
|
+
/** Narrow a factory's operator set by name. `includes` keeps only the named operators, in the order given; `excludes` drops them. The first remaining operator is the default for new filters. */
|
|
65
84
|
export type OperatorSelection<Name extends string = string> = {
|
|
66
85
|
excludes?: never;
|
|
86
|
+
/** Keeps only these operators, in this order. Can't be combined with `excludes`. */
|
|
67
87
|
includes?: Name[];
|
|
68
88
|
} | {
|
|
89
|
+
/** Drops these operators from the defaults. Can't be combined with `includes`. */
|
|
69
90
|
excludes?: Name[];
|
|
70
91
|
includes?: never;
|
|
71
92
|
};
|
|
@@ -83,13 +104,19 @@ export type FilterChange = (updates: Partial<ActiveFilter>, state?: {
|
|
|
83
104
|
complete?: boolean;
|
|
84
105
|
}) => void;
|
|
85
106
|
export type ActiveFilterLabel = string | string[] | undefined;
|
|
86
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Every value a built-in filter can hold. Values follow the filter, not the
|
|
109
|
+
* operator: switching operators keeps the old value, and ranges can be
|
|
110
|
+
* partially filled.
|
|
111
|
+
*/
|
|
112
|
+
export type ActiveFilterValue = CollectionFilterValue | DateFilterValue | DayFilterValue | NumberFilterValue | PresenceFilterValue | TextFilterValue;
|
|
113
|
+
export interface ActiveFilter<Value = ActiveFilterValue, OperatorName extends string = string> {
|
|
87
114
|
/** The human-readable label for the applied filter, if available. */
|
|
88
115
|
label?: ActiveFilterLabel;
|
|
89
116
|
/** The HTML name of the applied filter. Connects to the name of the filter. */
|
|
90
117
|
name: string;
|
|
91
118
|
/** The operator used by the applied filter. Corresponds to the name of the operator in the filter configuration. */
|
|
92
|
-
operator:
|
|
119
|
+
operator: OperatorName;
|
|
93
120
|
/**
|
|
94
121
|
* For scoped filters only: which of the parent's scopes is selected. The
|
|
95
122
|
* `operator` and `value` then belong to the parent's `scopeFilter`, so both
|
|
@@ -101,11 +128,8 @@ export interface ActiveFilter<T = unknown> {
|
|
|
101
128
|
* the chip renders without loading the scopes.
|
|
102
129
|
*/
|
|
103
130
|
scopeLabel?: string;
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
* TODO: Add more specific typing based on the operator and input type.
|
|
107
|
-
*/
|
|
108
|
-
value: T;
|
|
131
|
+
/** The value of the applied filter. Its shape depends on the filter type. */
|
|
132
|
+
value: Value;
|
|
109
133
|
}
|
|
110
134
|
export type AddPendingFilterFn = (filter: ActiveFilter) => void;
|
|
111
135
|
//# sourceMappingURL=FilterTypes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterTypes.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/FilterTypes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"FilterTypes.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/FilterTypes.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focuses the first control in a chip popover when it opens, so keyboard and
|
|
3
|
+
* screen reader users meet the controls in order, operator first.
|
|
4
|
+
*/
|
|
5
|
+
export declare function FocusFirstControl(): null;
|
|
6
|
+
/**
|
|
7
|
+
* Focuses the first control once lazy content loads, when the popover opened
|
|
8
|
+
* with nothing focusable in it. Focus the user has already moved stays put.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useFocusFirstControlAfterLoad(loading: boolean): void;
|
|
11
|
+
//# sourceMappingURL=FocusFirstControl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FocusFirstControl.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/FocusFirstControl.tsx"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,iBAAiB,SAMhC;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,QAO7D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useFocusManager } from 'react-aria';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Focuses the first control in a chip popover when it opens, so keyboard and
|
|
6
|
+
* screen reader users meet the controls in order, operator first.
|
|
7
|
+
*/
|
|
8
|
+
function FocusFirstControl() {
|
|
9
|
+
const focusManager = useFocusManager();
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
focusManager?.focusFirst({ tabbable: true });
|
|
12
|
+
}, [focusManager]);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Focuses the first control once lazy content loads, when the popover opened
|
|
17
|
+
* with nothing focusable in it. Focus the user has already moved stays put.
|
|
18
|
+
*/
|
|
19
|
+
function useFocusFirstControlAfterLoad(loading) {
|
|
20
|
+
const focusManager = useFocusManager();
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (loading)
|
|
23
|
+
return;
|
|
24
|
+
if (document.activeElement?.getAttribute("role") !== "dialog")
|
|
25
|
+
return;
|
|
26
|
+
focusManager?.focusFirst({ tabbable: true });
|
|
27
|
+
}, [focusManager, loading]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { FocusFirstControl, useFocusFirstControlAfterLoad };
|
|
31
|
+
//# sourceMappingURL=FocusFirstControl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FocusFirstControl.js","sources":["../../../src/components/DataTable/FocusFirstControl.tsx"],"sourcesContent":["import { useEffect } from \"react\"\nimport { useFocusManager } from \"react-aria\"\n\n/**\n * Focuses the first control in a chip popover when it opens, so keyboard and\n * screen reader users meet the controls in order, operator first.\n */\nexport function FocusFirstControl() {\n const focusManager = useFocusManager()\n useEffect(() => {\n focusManager?.focusFirst({ tabbable: true })\n }, [focusManager])\n return null\n}\n\n/**\n * Focuses the first control once lazy content loads, when the popover opened\n * with nothing focusable in it. Focus the user has already moved stays put.\n */\nexport function useFocusFirstControlAfterLoad(loading: boolean) {\n const focusManager = useFocusManager()\n useEffect(() => {\n if (loading) return\n if (document.activeElement?.getAttribute(\"role\") !== \"dialog\") return\n focusManager?.focusFirst({ tabbable: true })\n }, [focusManager, loading])\n}\n"],"names":[],"mappings":";;;AAGA;;;AAGG;SACa,iBAAiB,GAAA;AAC/B,IAAA,MAAM,YAAY,GAAG,eAAe,EAAE;IACtC,SAAS,CAAC,MAAK;QACb,YAAY,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC9C,IAAA,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;AAClB,IAAA,OAAO,IAAI;AACb;AAEA;;;AAGG;AACG,SAAU,6BAA6B,CAAC,OAAgB,EAAA;AAC5D,IAAA,MAAM,YAAY,GAAG,eAAe,EAAE;IACtC,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,OAAO;YAAE;QACb,IAAI,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,QAAQ;YAAE;QAC/D,YAAY,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC9C,IAAA,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC7B;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableSearch.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/TableSearch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;IACf,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;2CAKrB,gBAAgB;;
|
|
1
|
+
{"version":3,"file":"TableSearch.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/TableSearch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;IACf,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,eAAO,MAAM,WAAW;2CAKrB,gBAAgB;;CAUlB,CAAA"}
|
|
@@ -4,7 +4,7 @@ import React__default from 'react';
|
|
|
4
4
|
/**
|
|
5
5
|
* Renders the search input displayed above the table.
|
|
6
6
|
*/
|
|
7
|
-
const TableSearch = ({ label, onChange, tableId, value, }) => (React__default.createElement(SearchInput, { "aria-controls": tableId, label: label, hideLabel: true, placeholder: "Search", value: value, onChange: (event) => onChange(event.target.value) }));
|
|
7
|
+
const TableSearch = ({ label, onChange, tableId, value, }) => (React__default.createElement(SearchInput, { "aria-controls": tableId, className: "tds-data-table-search", label: label, hideLabel: true, placeholder: "Search", value: value, onChange: (event) => onChange(event.target.value) }));
|
|
8
8
|
TableSearch.displayName = "TableSearch";
|
|
9
9
|
|
|
10
10
|
export { TableSearch };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableSearch.js","sources":["../../../src/components/DataTable/TableSearch.tsx"],"sourcesContent":["import { SearchInput } from \"@components/search-input\"\nimport React from \"react\"\n\nexport interface TableSearchProps {\n /** Accessible label for the search input. The label is visually hidden. */\n label: string\n /** Called with the input's text on every change. */\n onChange: (query: string) => void\n /** The `id` of the table the search input controls. */\n tableId: string\n /** The input's text. */\n value: string\n}\n\n/**\n * Renders the search input displayed above the table.\n */\nexport const TableSearch = ({\n label,\n onChange,\n tableId,\n value,\n}: TableSearchProps) => (\n <SearchInput\n aria-controls={tableId}\n label={label}\n hideLabel\n placeholder=\"Search\"\n value={value}\n onChange={(event) => onChange(event.target.value)}\n />\n)\n\nTableSearch.displayName = \"TableSearch\"\n"],"names":["React"],"mappings":";;;AAcA;;AAEG;AACI,MAAM,WAAW,GAAG,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,KAAK,GACY,MACjBA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAA,eAAA,EACK,OAAO,EACtB,KAAK,EAAE,KAAK,EACZ,SAAS,EAAA,IAAA,EACT,WAAW,EAAC,QAAQ,EACpB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAA,CACjD;AAGJ,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
|
|
1
|
+
{"version":3,"file":"TableSearch.js","sources":["../../../src/components/DataTable/TableSearch.tsx"],"sourcesContent":["import { SearchInput } from \"@components/search-input\"\nimport React from \"react\"\n\nexport interface TableSearchProps {\n /** Accessible label for the search input. The label is visually hidden. */\n label: string\n /** Called with the input's text on every change. */\n onChange: (query: string) => void\n /** The `id` of the table the search input controls. */\n tableId: string\n /** The input's text. */\n value: string\n}\n\n/**\n * Renders the search input displayed above the table.\n */\nexport const TableSearch = ({\n label,\n onChange,\n tableId,\n value,\n}: TableSearchProps) => (\n <SearchInput\n aria-controls={tableId}\n className=\"tds-data-table-search\"\n label={label}\n hideLabel\n placeholder=\"Search\"\n value={value}\n onChange={(event) => onChange(event.target.value)}\n />\n)\n\nTableSearch.displayName = \"TableSearch\"\n"],"names":["React"],"mappings":";;;AAcA;;AAEG;AACI,MAAM,WAAW,GAAG,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,KAAK,GACY,MACjBA,cAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EAAA,eAAA,EACK,OAAO,EACtB,SAAS,EAAC,uBAAuB,EACjC,KAAK,EAAE,KAAK,EACZ,SAAS,EAAA,IAAA,EACT,WAAW,EAAC,QAAQ,EACpB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAA,CACjD;AAGJ,WAAW,CAAC,WAAW,GAAG,aAAa;;;;"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { CollectionOptions } from "./CollectionEditorsShared";
|
|
2
|
-
import type { FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
1
|
+
import type { CollectionFilterValue, CollectionOptions } from "./CollectionEditorsShared";
|
|
2
|
+
import type { ActiveFilter, FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
3
3
|
export type CollectionOption = {
|
|
4
4
|
label: string;
|
|
5
5
|
value: string;
|
|
6
6
|
};
|
|
7
|
-
export type CollectionDisplay = "checkboxes" | "combobox" | "select";
|
|
7
|
+
export type CollectionDisplay = "checkboxes" | "combobox" | "radios" | "select";
|
|
8
8
|
export declare const COLLECTION_IS: {
|
|
9
9
|
readonly inputType: {
|
|
10
10
|
readonly type: "collection";
|
|
@@ -33,15 +33,21 @@ declare const ALL_COLLECTION_OPERATORS: ({
|
|
|
33
33
|
readonly name: "not";
|
|
34
34
|
})[];
|
|
35
35
|
export type CollectionOperatorName = (typeof ALL_COLLECTION_OPERATORS)[number]["name"];
|
|
36
|
+
export type CollectionActiveFilter = ActiveFilter<CollectionFilterValue | undefined, CollectionOperatorName>;
|
|
36
37
|
export type CollectionFilterConfig = FilterItemConfig<CollectionOperatorName> & {
|
|
38
|
+
/** How the editor presents the options. Defaults to `select`. */
|
|
39
|
+
display?: CollectionDisplay;
|
|
40
|
+
/** Allows picking more than one option. Only supported with the `combobox` display; `checkboxes` always allows multiple and `radios` never does. */
|
|
41
|
+
multiple?: boolean;
|
|
42
|
+
/** The choices, or a function that loads them. A function receives the combobox's search query and, inside a `scopedFilter`, the chosen scope. */
|
|
37
43
|
options: CollectionOptions;
|
|
38
44
|
} & ({
|
|
39
|
-
display?: CollectionDisplay
|
|
40
|
-
multiple?:
|
|
45
|
+
display?: Exclude<CollectionDisplay, "combobox">;
|
|
46
|
+
multiple?: never;
|
|
41
47
|
} | {
|
|
42
|
-
display
|
|
43
|
-
multiple
|
|
48
|
+
display: "combobox";
|
|
49
|
+
multiple?: boolean;
|
|
44
50
|
});
|
|
45
|
-
export declare function collectionFilter({ display, excludes, includes, multiple, options, ...config }: CollectionFilterConfig): FilterNodeItem;
|
|
51
|
+
export declare function collectionFilter({ display, excludes, includes, multiple: multipleCombobox, options, ...config }: CollectionFilterConfig): FilterNodeItem;
|
|
46
52
|
export {};
|
|
47
53
|
//# sourceMappingURL=collectionFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectionFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"collectionFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,2BAA2B,CAAA;AAElC,OAAO,KAAK,EACV,YAAY,EAGZ,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAItB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE/E,eAAO,MAAM,aAAa;;;;;;CAIG,CAAA;AAC7B,eAAO,MAAM,cAAc;;;;;;CAIE,CAAA;AAE7B,QAAA,MAAM,wBAAwB;;;;;;;;;;;;IAAkC,CAAA;AAGhE,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnD,MAAM,MAAM,sBAAsB,GAAG,YAAY,CAC/C,qBAAqB,GAAG,SAAS,EACjC,sBAAsB,CACvB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAChC,gBAAgB,CAAC,sBAAsB,CAAC,GAAG;IACzC,iEAAiE;IACjE,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,oJAAoJ;IACpJ,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kJAAkJ;IAClJ,OAAO,EAAE,iBAAiB,CAAA;CAC3B,GAAG,CACE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GACtE;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAC9C,CAAA;AAEL,wBAAgB,gBAAgB,CAAC,EAC/B,OAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,QAAQ,EAAE,gBAAwB,EAClC,OAAO,EACP,GAAG,MAAM,EACV,EAAE,sBAAsB,GAAG,cAAc,CAoBzC"}
|
|
@@ -16,10 +16,11 @@ const COLLECTION_NOT = {
|
|
|
16
16
|
};
|
|
17
17
|
const ALL_COLLECTION_OPERATORS = [COLLECTION_IS, COLLECTION_NOT];
|
|
18
18
|
const DEFAULT_COLLECTION_OPERATORS = [COLLECTION_IS];
|
|
19
|
-
function collectionFilter({ display = "select", excludes, includes, multiple = false, options, ...config }) {
|
|
19
|
+
function collectionFilter({ display = "select", excludes, includes, multiple: multipleCombobox = false, options, ...config }) {
|
|
20
|
+
const multiple = display === "checkboxes" || multipleCombobox;
|
|
20
21
|
const filter = {
|
|
21
22
|
...config,
|
|
22
|
-
createActiveFilterInstance: (activeFilter, operator) => new
|
|
23
|
+
createActiveFilterInstance: (activeFilter, operator) => new CollectionActiveFilterInstance(filter, operator, activeFilter.value, activeFilter.label, activeFilter.scope, { display, multiple, options }),
|
|
23
24
|
operators: resolveOperators(ALL_COLLECTION_OPERATORS, {
|
|
24
25
|
default: DEFAULT_COLLECTION_OPERATORS,
|
|
25
26
|
excludes,
|
|
@@ -28,7 +29,7 @@ function collectionFilter({ display = "select", excludes, includes, multiple = f
|
|
|
28
29
|
};
|
|
29
30
|
return filter;
|
|
30
31
|
}
|
|
31
|
-
class
|
|
32
|
+
class CollectionActiveFilterInstance extends ActiveFilterInstance {
|
|
32
33
|
label;
|
|
33
34
|
scope;
|
|
34
35
|
config;
|
|
@@ -39,12 +40,15 @@ class CollectionActiveFilter extends ActiveFilterInstance {
|
|
|
39
40
|
this.config = config;
|
|
40
41
|
this.label = label;
|
|
41
42
|
}
|
|
43
|
+
get valueCount() {
|
|
44
|
+
return [this.value].flat().length;
|
|
45
|
+
}
|
|
42
46
|
formatValue() {
|
|
43
47
|
if (this.label)
|
|
44
|
-
return
|
|
48
|
+
return [this.label].flat().join(", ");
|
|
45
49
|
const values = Array.isArray(this.value) ? this.value : [this.value];
|
|
46
50
|
if (typeof this.config.options === "function")
|
|
47
|
-
return
|
|
51
|
+
return "";
|
|
48
52
|
return values
|
|
49
53
|
.map((value) => this.config.options.find((option) => option.value === value)?.label ?? value)
|
|
50
54
|
.join(", ");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectionFilter.js","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"sourcesContent":["import React from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport { CollectionFilterEditorLazy } from \"./CollectionEditorsLazy\"\nimport type {\n CollectionFilterValue,\n CollectionOptions,\n} from \"./CollectionEditorsShared\"\nimport { CollectionFilterEditorStatic } from \"./CollectionEditorsStatic\"\nimport type {\n ActiveFilterLabel,\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\n\n// A type alias (not an interface) so it satisfies `Select`'s `data-*` index signature.\nexport type CollectionOption = {\n label: string\n value: string\n}\n\nexport type CollectionDisplay = \"checkboxes\" | \"combobox\" | \"select\"\n\nexport const COLLECTION_IS = {\n inputType: { type: \"collection\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const COLLECTION_NOT = {\n inputType: { type: \"collection\" },\n label: \"is not\",\n name: \"not\",\n} as const satisfies Operator\n\nconst ALL_COLLECTION_OPERATORS = [COLLECTION_IS, COLLECTION_NOT]\nconst DEFAULT_COLLECTION_OPERATORS = [COLLECTION_IS]\n\nexport type CollectionOperatorName =\n (typeof ALL_COLLECTION_OPERATORS)[number][\"name\"]\n\nexport type CollectionFilterConfig =\n FilterItemConfig<CollectionOperatorName> & {\n options: CollectionOptions\n } & (\n | { display?: CollectionDisplay
|
|
1
|
+
{"version":3,"file":"collectionFilter.js","sources":["../../../src/components/DataTable/collectionFilter.tsx"],"sourcesContent":["import React from \"react\"\n\nimport { ActiveFilterInstance } from \"./ActiveFilterInstance\"\nimport { CollectionFilterEditorLazy } from \"./CollectionEditorsLazy\"\nimport type {\n CollectionFilterValue,\n CollectionOptions,\n} from \"./CollectionEditorsShared\"\nimport { CollectionFilterEditorStatic } from \"./CollectionEditorsStatic\"\nimport type {\n ActiveFilter,\n ActiveFilterLabel,\n FilterChange,\n FilterItemConfig,\n FilterNodeItem,\n Operator,\n} from \"./FilterTypes\"\nimport { resolveOperators } from \"./resolveOperators\"\n\n// A type alias (not an interface) so it satisfies `Select`'s `data-*` index signature.\nexport type CollectionOption = {\n label: string\n value: string\n}\n\nexport type CollectionDisplay = \"checkboxes\" | \"combobox\" | \"radios\" | \"select\"\n\nexport const COLLECTION_IS = {\n inputType: { type: \"collection\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const COLLECTION_NOT = {\n inputType: { type: \"collection\" },\n label: \"is not\",\n name: \"not\",\n} as const satisfies Operator\n\nconst ALL_COLLECTION_OPERATORS = [COLLECTION_IS, COLLECTION_NOT]\nconst DEFAULT_COLLECTION_OPERATORS = [COLLECTION_IS]\n\nexport type CollectionOperatorName =\n (typeof ALL_COLLECTION_OPERATORS)[number][\"name\"]\n\nexport type CollectionActiveFilter = ActiveFilter<\n CollectionFilterValue | undefined,\n CollectionOperatorName\n>\n\nexport type CollectionFilterConfig =\n FilterItemConfig<CollectionOperatorName> & {\n /** How the editor presents the options. Defaults to `select`. */\n display?: CollectionDisplay\n /** Allows picking more than one option. Only supported with the `combobox` display; `checkboxes` always allows multiple and `radios` never does. */\n multiple?: boolean\n /** The choices, or a function that loads them. A function receives the combobox's search query and, inside a `scopedFilter`, the chosen scope. */\n options: CollectionOptions\n } & (\n | { display?: Exclude<CollectionDisplay, \"combobox\">; multiple?: never }\n | { display: \"combobox\"; multiple?: boolean }\n )\n\nexport function collectionFilter({\n display = \"select\",\n excludes,\n includes,\n multiple: multipleCombobox = false,\n options,\n ...config\n}: CollectionFilterConfig): FilterNodeItem {\n const multiple = display === \"checkboxes\" || multipleCombobox\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new CollectionActiveFilterInstance(\n filter,\n operator,\n activeFilter.value as CollectionFilterValue,\n activeFilter.label,\n activeFilter.scope,\n { display, multiple, options }\n ),\n operators: resolveOperators(ALL_COLLECTION_OPERATORS, {\n default: DEFAULT_COLLECTION_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\nclass CollectionActiveFilterInstance extends ActiveFilterInstance<CollectionFilterValue> {\n constructor(\n filter: FilterNodeItem,\n operator: FilterNodeItem[\"operators\"][number],\n value: CollectionFilterValue,\n private readonly label: ActiveFilterLabel,\n private readonly scope: string | undefined,\n private readonly config: {\n display: CollectionDisplay\n multiple: boolean\n options: CollectionOptions\n }\n ) {\n super(filter, operator, value)\n this.label = label\n }\n\n get valueCount() {\n return [this.value].flat().length\n }\n\n formatValue() {\n if (this.label) return [this.label].flat().join(\", \")\n const values = Array.isArray(this.value) ? this.value : [this.value]\n if (typeof this.config.options === \"function\") return \"\"\n return values\n .map(\n (value) =>\n (this.config.options as CollectionOption[]).find(\n (option) => option.value === value\n )?.label ?? value\n )\n .join(\", \")\n }\n\n renderEditor(onChange: FilterChange) {\n const hasLazyOptions = typeof this.config.options === \"function\"\n const Editor = hasLazyOptions\n ? CollectionFilterEditorLazy\n : CollectionFilterEditorStatic\n\n return (\n <Editor\n config={this.config}\n onChange={onChange}\n operator={this.operator}\n value={this.value}\n label={this.label}\n filter={this.filter}\n scope={this.scope}\n />\n )\n }\n}\n"],"names":["React"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type DatePickerDateValue } from "../date-picker";
|
|
2
|
-
import type { FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
3
|
-
|
|
4
|
-
export type DateFilterValue = string | [string, string];
|
|
2
|
+
import type { ActiveFilter, FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
3
|
+
type DateRange = [string | undefined, string | undefined];
|
|
5
4
|
export declare const DATE_IS: {
|
|
6
5
|
readonly inputType: {
|
|
7
6
|
readonly type: "date";
|
|
@@ -82,9 +81,14 @@ declare const ALL_DATE_OPERATORS: ({
|
|
|
82
81
|
readonly name: "between";
|
|
83
82
|
})[];
|
|
84
83
|
export type DateOperatorName = (typeof ALL_DATE_OPERATORS)[number]["name"];
|
|
84
|
+
/** An ISO `YYYY-MM-DD` string; a pair for `between`, either side of which may still be empty. */
|
|
85
|
+
export type DateFilterValue = string | DateRange | undefined;
|
|
86
|
+
export type DateActiveFilter = ActiveFilter<DateFilterValue, DateOperatorName>;
|
|
85
87
|
/** Inclusive bounds on the dates the filter's pickers allow. */
|
|
86
88
|
export interface DateLimits {
|
|
89
|
+
/** Latest selectable date, as a `DateValue` or ISO date string. */
|
|
87
90
|
max?: DatePickerDateValue;
|
|
91
|
+
/** Earliest selectable date, as a `DateValue` or ISO date string. */
|
|
88
92
|
min?: DatePickerDateValue;
|
|
89
93
|
}
|
|
90
94
|
export declare function dateFilter({ excludes, includes, max, min, ...config }: FilterItemConfig<DateOperatorName> & DateLimits): FilterNodeItem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dateFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/dateFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAW9E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"dateFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/dateFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAW9E,OAAO,KAAK,EACV,YAAY,EAEZ,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAGtB,KAAK,SAAS,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;AAEzD,eAAO,MAAM,OAAO;;;;;;CAIS,CAAA;AAC7B,eAAO,MAAM,EAAE;;;;;;CAIc,CAAA;AAC7B,eAAO,MAAM,EAAE;;;;;;CAIc,CAAA;AAC7B,eAAO,MAAM,GAAG;;;;;;CAIa,CAAA;AAC7B,eAAO,MAAM,GAAG;;;;;;CAIa,CAAA;AAC7B,eAAO,MAAM,UAAU;;;;;;CAIM,CAAA;AAE7B,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAA0C,CAAA;AAGlE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1E,iGAAiG;AACjG,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;AAE5D,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAA;AAuB9E,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,GAAG,CAAC,EAAE,mBAAmB,CAAA;IACzB,qEAAqE;IACrE,GAAG,CAAC,EAAE,mBAAmB,CAAA;CAC1B;AAcD,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,QAAQ,EACR,GAAG,EACH,GAAG,EACH,GAAG,MAAM,EACV,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GAAG,UAAU,GAAG,cAAc,CAiBlE"}
|
|
@@ -66,7 +66,7 @@ function toValidDate(date, { max, min }) {
|
|
|
66
66
|
function dateFilter({ excludes, includes, max, min, ...config }) {
|
|
67
67
|
const filter = {
|
|
68
68
|
...config,
|
|
69
|
-
createActiveFilterInstance: (activeFilter, operator) => new
|
|
69
|
+
createActiveFilterInstance: (activeFilter, operator) => new DateActiveFilterInstance(filter, operator, activeFilter.value, { max, min }),
|
|
70
70
|
operators: resolveOperators(ALL_DATE_OPERATORS, {
|
|
71
71
|
default: DEFAULT_DATE_OPERATORS,
|
|
72
72
|
excludes,
|
|
@@ -75,7 +75,7 @@ function dateFilter({ excludes, includes, max, min, ...config }) {
|
|
|
75
75
|
};
|
|
76
76
|
return filter;
|
|
77
77
|
}
|
|
78
|
-
class
|
|
78
|
+
class DateActiveFilterInstance extends ActiveFilterInstance {
|
|
79
79
|
limits;
|
|
80
80
|
constructor(filter, operator, value, limits) {
|
|
81
81
|
super(filter, operator, value);
|
|
@@ -85,9 +85,12 @@ class DateActiveFilter extends ActiveFilterInstance {
|
|
|
85
85
|
if (Array.isArray(this.value)) {
|
|
86
86
|
const [start, end] = this.value;
|
|
87
87
|
if (start === undefined || end === undefined) {
|
|
88
|
-
return [start, end]
|
|
88
|
+
return [start, end]
|
|
89
|
+
.filter((date) => date !== undefined)
|
|
90
|
+
.map(formatDate)
|
|
91
|
+
.join("");
|
|
89
92
|
}
|
|
90
|
-
return [formatDate(start), "and", formatDate(end)];
|
|
93
|
+
return [formatDate(start), "and", formatDate(end)].join(" ");
|
|
91
94
|
}
|
|
92
95
|
return this.value === undefined ? "" : formatDate(this.value);
|
|
93
96
|
}
|
|
@@ -103,11 +106,7 @@ class DateActiveFilter extends ActiveFilterInstance {
|
|
|
103
106
|
} }));
|
|
104
107
|
}
|
|
105
108
|
const single = Array.isArray(this.value) ? this.value[0] : this.value;
|
|
106
|
-
return (React__default.createElement(DatePicker
|
|
107
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
108
|
-
, {
|
|
109
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
110
|
-
autoFocus: true, hideLabel: true,
|
|
109
|
+
return (React__default.createElement(DatePicker, { hideLabel: true,
|
|
111
110
|
// Uncontrolled so a typed date outside the limits stays visible
|
|
112
111
|
// (and flagged invalid) after the value is cleared.
|
|
113
112
|
defaultValue: single, label: label, max: this.limits.max, min: this.limits.min, onChange: (date) => {
|
|
@@ -120,11 +119,7 @@ function DateRangeEditor({ label, max, min, onCommit, value: [start, end], }) {
|
|
|
120
119
|
const startLimits = { max: earlier(max, end), min };
|
|
121
120
|
const endLimits = { max, min: later(min, start) };
|
|
122
121
|
return (React__default.createElement(Flex, { align: "center", gap: 1 },
|
|
123
|
-
React__default.createElement(DatePicker
|
|
124
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
125
|
-
, {
|
|
126
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
127
|
-
autoFocus: true, hideLabel: true, defaultValue: start, label: `${label} from`, max: startLimits.max, min: startLimits.min, onChange: (date) => onCommit([toValidDate(date, startLimits), end]) }),
|
|
122
|
+
React__default.createElement(DatePicker, { hideLabel: true, defaultValue: start, label: `${label} from`, max: startLimits.max, min: startLimits.min, onChange: (date) => onCommit([toValidDate(date, startLimits), end]) }),
|
|
128
123
|
React__default.createElement("div", null, "and"),
|
|
129
124
|
React__default.createElement(DatePicker, { hideLabel: true, defaultValue: end, label: `${label} to`, max: endLimits.max, min: endLimits.min, onChange: (date) => onCommit([start, toValidDate(date, endLimits)]) })));
|
|
130
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dateFilter.js","sources":["../../../src/components/DataTable/dateFilter.tsx"],"sourcesContent":["import { DatePicker, type DatePickerDateValue } from \"@components/date-picker\"\nimport { Flex } from \"@components/flex\"\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n parseDate,\n} from \"@internationalized/date\"\nimport React 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\n/** ISO `YYYY-MM-DD` strings; a pair for `between`. */\nexport type DateFilterValue = string | [string, string]\n\ntype DateRange = [string | undefined, string | undefined]\n\nexport const DATE_IS = {\n inputType: { type: \"date\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const LT = {\n inputType: { type: \"date\" },\n label: \"is before\",\n name: \"lt\",\n} as const satisfies Operator\nexport const GT = {\n inputType: { type: \"date\" },\n label: \"is after\",\n name: \"gt\",\n} as const satisfies Operator\nexport const LTE = {\n inputType: { type: \"date\" },\n label: \"is on or before\",\n name: \"lte\",\n} as const satisfies Operator\nexport const GTE = {\n inputType: { type: \"date\" },\n label: \"is on or after\",\n name: \"gte\",\n} as const satisfies Operator\nexport const DATE_RANGE = {\n inputType: { type: \"date-range\" },\n label: \"is between\",\n name: \"between\",\n} as const satisfies Operator\n\nconst ALL_DATE_OPERATORS = [DATE_IS, LT, GT, LTE, GTE, DATE_RANGE]\nconst DEFAULT_DATE_OPERATORS = [DATE_IS, LT, GT, DATE_RANGE]\n\nexport type DateOperatorName = (typeof ALL_DATE_OPERATORS)[number][\"name\"]\n\nconst formatter = new DateFormatter(\n new Intl.DateTimeFormat().resolvedOptions().locale,\n { dateStyle: \"medium\" }\n)\n\nconst formatDate = (iso: string) =>\n formatter.format(parseDate(iso).toDate(getLocalTimeZone()))\n\nconst toDateValue = (date: DatePickerDateValue) =>\n typeof date === \"string\" ? parseDate(date) : date\n\nfunction earlier(a?: DatePickerDateValue, b?: DatePickerDateValue) {\n if (a === undefined || b === undefined) return a ?? b\n return toDateValue(a).compare(toDateValue(b)) <= 0 ? a : b\n}\n\nfunction later(a?: DatePickerDateValue, b?: DatePickerDateValue) {\n if (a === undefined || b === undefined) return a ?? b\n return toDateValue(a).compare(toDateValue(b)) >= 0 ? a : b\n}\n\n/** Inclusive bounds on the dates the filter's pickers allow. */\nexport interface DateLimits {\n max?: DatePickerDateValue\n min?: DatePickerDateValue\n}\n\n/**\n * The pickers only flag typed dates outside the limits as invalid, so the\n * editors clear the value rather than commit them.\n */\nfunction toValidDate(date: DateValue | null, { max, min }: DateLimits) {\n if (!date) return undefined\n const isWithinLimits =\n (min === undefined || date.compare(toDateValue(min)) >= 0) &&\n (max === undefined || date.compare(toDateValue(max)) <= 0)\n return isWithinLimits ? date.toString() : undefined\n}\n\nexport function dateFilter({\n excludes,\n includes,\n max,\n min,\n ...config\n}: FilterItemConfig<DateOperatorName> & DateLimits): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new DateActiveFilter(\n filter,\n operator,\n activeFilter.value as DateFilterValue,\n { max, min }\n ),\n operators: resolveOperators(ALL_DATE_OPERATORS, {\n default: DEFAULT_DATE_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\nclass DateActiveFilter extends ActiveFilterInstance<DateFilterValue> {\n constructor(\n filter: FilterNodeItem,\n operator: Operator,\n value: DateFilterValue,\n readonly limits: DateLimits\n ) {\n super(filter, operator, value)\n }\n\n formatValue() {\n if (Array.isArray(this.value)) {\n const [start, end] = this.value\n if (start === undefined || end === undefined) {\n return [start, end].filter((date) => date !== undefined).map(formatDate)\n }\n return [formatDate(start), \"and\", formatDate(end)]\n }\n return this.value === undefined ? \"\" : formatDate(this.value)\n }\n\n renderEditor(onChange: FilterChange) {\n const { label } = this.operator\n\n if (this.operator.inputType.type === \"date-range\") {\n const range: DateRange = Array.isArray(this.value)\n ? this.value\n : [this.value, this.value]\n return (\n <DateRangeEditor\n label={label}\n max={this.limits.max}\n min={this.limits.min}\n value={range}\n onCommit={(value) => {\n const complete =\n value.length === 2 && value.every((v) => v !== undefined)\n onChange({ value }, { complete })\n }}\n />\n )\n }\n const single = Array.isArray(this.value) ? this.value[0] : this.value\n return (\n <DatePicker\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\n hideLabel\n // Uncontrolled so a typed date outside the limits stays visible\n // (and flagged invalid) after the value is cleared.\n defaultValue={single}\n label={label}\n max={this.limits.max}\n min={this.limits.min}\n onChange={(date) => {\n const value = toValidDate(date, this.limits)\n onChange({ value }, { complete: value !== undefined })\n }}\n />\n )\n }\n}\n\nfunction DateRangeEditor({\n label,\n max,\n min,\n onCommit,\n value: [start, end],\n}: DateLimits & {\n label: string\n onCommit: (value: DateRange) => void\n value: DateRange\n}) {\n const startLimits = { max: earlier(max, end), min }\n const endLimits = { max, min: later(min, start) }\n\n return (\n <Flex align=\"center\" gap={1}>\n <DatePicker\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\n hideLabel\n defaultValue={start}\n label={`${label} from`}\n max={startLimits.max}\n min={startLimits.min}\n onChange={(date) => onCommit([toValidDate(date, startLimits), end])}\n />\n <div>and</div>\n <DatePicker\n hideLabel\n defaultValue={end}\n label={`${label} to`}\n max={endLimits.max}\n min={endLimits.min}\n onChange={(date) => onCommit([start, toValidDate(date, endLimits)])}\n />\n </Flex>\n )\n}\n"],"names":["DateFormatter","parseDate","getLocalTimeZone","React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dateFilter.js","sources":["../../../src/components/DataTable/dateFilter.tsx"],"sourcesContent":["import { DatePicker, type DatePickerDateValue } from \"@components/date-picker\"\nimport { Flex } from \"@components/flex\"\nimport {\n DateFormatter,\n type DateValue,\n getLocalTimeZone,\n parseDate,\n} from \"@internationalized/date\"\nimport React 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\ntype DateRange = [string | undefined, string | undefined]\n\nexport const DATE_IS = {\n inputType: { type: \"date\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const LT = {\n inputType: { type: \"date\" },\n label: \"is before\",\n name: \"lt\",\n} as const satisfies Operator\nexport const GT = {\n inputType: { type: \"date\" },\n label: \"is after\",\n name: \"gt\",\n} as const satisfies Operator\nexport const LTE = {\n inputType: { type: \"date\" },\n label: \"is on or before\",\n name: \"lte\",\n} as const satisfies Operator\nexport const GTE = {\n inputType: { type: \"date\" },\n label: \"is on or after\",\n name: \"gte\",\n} as const satisfies Operator\nexport const DATE_RANGE = {\n inputType: { type: \"date-range\" },\n label: \"is between\",\n name: \"between\",\n} as const satisfies Operator\n\nconst ALL_DATE_OPERATORS = [DATE_IS, LT, GT, LTE, GTE, DATE_RANGE]\nconst DEFAULT_DATE_OPERATORS = [DATE_IS, LT, GT, DATE_RANGE]\n\nexport type DateOperatorName = (typeof ALL_DATE_OPERATORS)[number][\"name\"]\n\n/** An ISO `YYYY-MM-DD` string; a pair for `between`, either side of which may still be empty. */\nexport type DateFilterValue = string | DateRange | undefined\n\nexport type DateActiveFilter = ActiveFilter<DateFilterValue, DateOperatorName>\n\nconst formatter = new DateFormatter(\n new Intl.DateTimeFormat().resolvedOptions().locale,\n { dateStyle: \"medium\" }\n)\n\nconst formatDate = (iso: string) =>\n formatter.format(parseDate(iso).toDate(getLocalTimeZone()))\n\nconst toDateValue = (date: DatePickerDateValue) =>\n typeof date === \"string\" ? parseDate(date) : date\n\nfunction earlier(a?: DatePickerDateValue, b?: DatePickerDateValue) {\n if (a === undefined || b === undefined) return a ?? b\n return toDateValue(a).compare(toDateValue(b)) <= 0 ? a : b\n}\n\nfunction later(a?: DatePickerDateValue, b?: DatePickerDateValue) {\n if (a === undefined || b === undefined) return a ?? b\n return toDateValue(a).compare(toDateValue(b)) >= 0 ? a : b\n}\n\n/** Inclusive bounds on the dates the filter's pickers allow. */\nexport interface DateLimits {\n /** Latest selectable date, as a `DateValue` or ISO date string. */\n max?: DatePickerDateValue\n /** Earliest selectable date, as a `DateValue` or ISO date string. */\n min?: DatePickerDateValue\n}\n\n/**\n * The pickers only flag typed dates outside the limits as invalid, so the\n * editors clear the value rather than commit them.\n */\nfunction toValidDate(date: DateValue | null, { max, min }: DateLimits) {\n if (!date) return undefined\n const isWithinLimits =\n (min === undefined || date.compare(toDateValue(min)) >= 0) &&\n (max === undefined || date.compare(toDateValue(max)) <= 0)\n return isWithinLimits ? date.toString() : undefined\n}\n\nexport function dateFilter({\n excludes,\n includes,\n max,\n min,\n ...config\n}: FilterItemConfig<DateOperatorName> & DateLimits): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new DateActiveFilterInstance(\n filter,\n operator,\n activeFilter.value as DateFilterValue,\n { max, min }\n ),\n operators: resolveOperators(ALL_DATE_OPERATORS, {\n default: DEFAULT_DATE_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\nclass DateActiveFilterInstance extends ActiveFilterInstance<DateFilterValue> {\n constructor(\n filter: FilterNodeItem,\n operator: Operator,\n value: DateFilterValue,\n readonly limits: DateLimits\n ) {\n super(filter, operator, value)\n }\n\n formatValue() {\n if (Array.isArray(this.value)) {\n const [start, end] = this.value\n if (start === undefined || end === undefined) {\n return [start, end]\n .filter((date) => date !== undefined)\n .map(formatDate)\n .join(\"\")\n }\n return [formatDate(start), \"and\", formatDate(end)].join(\" \")\n }\n return this.value === undefined ? \"\" : formatDate(this.value)\n }\n\n renderEditor(onChange: FilterChange) {\n const { label } = this.operator\n\n if (this.operator.inputType.type === \"date-range\") {\n const range: DateRange = Array.isArray(this.value)\n ? this.value\n : [this.value, this.value]\n return (\n <DateRangeEditor\n label={label}\n max={this.limits.max}\n min={this.limits.min}\n value={range}\n onCommit={(value) => {\n const complete =\n value.length === 2 && value.every((v) => v !== undefined)\n onChange({ value }, { complete })\n }}\n />\n )\n }\n const single = Array.isArray(this.value) ? this.value[0] : this.value\n return (\n <DatePicker\n hideLabel\n // Uncontrolled so a typed date outside the limits stays visible\n // (and flagged invalid) after the value is cleared.\n defaultValue={single}\n label={label}\n max={this.limits.max}\n min={this.limits.min}\n onChange={(date) => {\n const value = toValidDate(date, this.limits)\n onChange({ value }, { complete: value !== undefined })\n }}\n />\n )\n }\n}\n\nfunction DateRangeEditor({\n label,\n max,\n min,\n onCommit,\n value: [start, end],\n}: DateLimits & {\n label: string\n onCommit: (value: DateRange) => void\n value: DateRange\n}) {\n const startLimits = { max: earlier(max, end), min }\n const endLimits = { max, min: later(min, start) }\n\n return (\n <Flex align=\"center\" gap={1}>\n <DatePicker\n hideLabel\n defaultValue={start}\n label={`${label} from`}\n max={startLimits.max}\n min={startLimits.min}\n onChange={(date) => onCommit([toValidDate(date, startLimits), end])}\n />\n <div>and</div>\n <DatePicker\n hideLabel\n defaultValue={end}\n label={`${label} to`}\n max={endLimits.max}\n min={endLimits.min}\n onChange={(date) => onCommit([start, toValidDate(date, endLimits)])}\n />\n </Flex>\n )\n}\n"],"names":["DateFormatter","parseDate","getLocalTimeZone","React"],"mappings":"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"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type { FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
2
|
-
/** `MM-DD` strings with no year; a pair for `between`. */
|
|
3
|
-
export type DayFilterValue = string | [string, string];
|
|
1
|
+
import type { ActiveFilter, FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
4
2
|
export declare const DAY_IS: {
|
|
5
3
|
readonly inputType: {
|
|
6
4
|
readonly type: "day";
|
|
@@ -29,6 +27,9 @@ declare const DAY_OPERATORS: ({
|
|
|
29
27
|
readonly name: "between";
|
|
30
28
|
})[];
|
|
31
29
|
export type DayOperatorName = (typeof DAY_OPERATORS)[number]["name"];
|
|
30
|
+
/** An `MM-DD` string with no year; a pair for `between`, either side of which may still be empty. */
|
|
31
|
+
export type DayFilterValue = string | [string | undefined, string | undefined] | undefined;
|
|
32
|
+
export type DayActiveFilter = ActiveFilter<DayFilterValue, DayOperatorName>;
|
|
32
33
|
export declare function dayFilter({ excludes, includes, ...config }: FilterItemConfig<DayOperatorName>): FilterNodeItem;
|
|
33
34
|
export {};
|
|
34
35
|
//# sourceMappingURL=dayFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dayFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/dayFilter.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"dayFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/dayFilter.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EAEZ,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAGtB,eAAO,MAAM,MAAM;;;;;;CAIU,CAAA;AAC7B,eAAO,MAAM,SAAS;;;;;;CAIO,CAAA;AAE7B,QAAA,MAAM,aAAa;;;;;;;;;;;;IAAsB,CAAA;AAEzC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpE,qGAAqG;AACrG,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,CAAC,MAAM,GAAG,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,GACxC,SAAS,CAAA;AAEb,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,cAAc,EAAE,eAAe,CAAC,CAAA;AA2C3E,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,QAAQ,EACR,GAAG,MAAM,EACV,EAAE,gBAAgB,CAAC,eAAe,CAAC,GAAG,cAAc,CAgBpD"}
|
|
@@ -50,7 +50,7 @@ const dayOptions = (month) => Array.from({ length: month ? daysInMonth(month) :
|
|
|
50
50
|
function dayFilter({ excludes, includes, ...config }) {
|
|
51
51
|
const filter = {
|
|
52
52
|
...config,
|
|
53
|
-
createActiveFilterInstance: (activeFilter, operator) => new
|
|
53
|
+
createActiveFilterInstance: (activeFilter, operator) => new DayActiveFilterInstance(filter, operator, activeFilter.value),
|
|
54
54
|
operators: resolveOperators(DAY_OPERATORS, {
|
|
55
55
|
default: DAY_OPERATORS,
|
|
56
56
|
excludes,
|
|
@@ -59,14 +59,17 @@ function dayFilter({ excludes, includes, ...config }) {
|
|
|
59
59
|
};
|
|
60
60
|
return filter;
|
|
61
61
|
}
|
|
62
|
-
class
|
|
62
|
+
class DayActiveFilterInstance extends ActiveFilterInstance {
|
|
63
63
|
formatValue() {
|
|
64
64
|
if (Array.isArray(this.value)) {
|
|
65
65
|
const [start, end] = this.value;
|
|
66
66
|
if (start === undefined || end === undefined) {
|
|
67
|
-
return [start, end]
|
|
67
|
+
return [start, end]
|
|
68
|
+
.filter((day) => day !== undefined)
|
|
69
|
+
.map(formatDay)
|
|
70
|
+
.join("");
|
|
68
71
|
}
|
|
69
|
-
return [formatDay(start), "and", formatDay(end)];
|
|
72
|
+
return [formatDay(start), "and", formatDay(end)].join(" ");
|
|
70
73
|
}
|
|
71
74
|
return this.value === undefined ? "" : formatDay(this.value);
|
|
72
75
|
}
|
|
@@ -77,15 +80,15 @@ class DayActiveFilter extends ActiveFilterInstance {
|
|
|
77
80
|
? this.value
|
|
78
81
|
: [this.value, this.value];
|
|
79
82
|
return (React__default.createElement(Flex, { gap: 1 },
|
|
80
|
-
React__default.createElement(DayEditor, {
|
|
83
|
+
React__default.createElement(DayEditor, { label: `${label} from`, value: start, onCommit: (day) => onChange({ value: [day, end] }, { complete: end !== undefined }) }),
|
|
81
84
|
React__default.createElement("div", null, "and"),
|
|
82
85
|
React__default.createElement(DayEditor, { label: `${label} to`, value: end, onCommit: (day) => onChange({ value: [start, day] }, { complete: start !== undefined }) })));
|
|
83
86
|
}
|
|
84
87
|
const single = Array.isArray(this.value) ? this.value[0] : this.value;
|
|
85
|
-
return (React__default.createElement(DayEditor, {
|
|
88
|
+
return (React__default.createElement(DayEditor, { label: label, value: single, onCommit: (day) => onChange({ value: day }) }));
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
|
-
function DayEditor({
|
|
91
|
+
function DayEditor({ label, onCommit, value, }) {
|
|
89
92
|
const [selection, setSelection] = useState(() => parseDay(value));
|
|
90
93
|
const update = (next) => {
|
|
91
94
|
const day = next.month && next.day
|
|
@@ -96,11 +99,7 @@ function DayEditor({ focusOnOpen, label, onCommit, value, }) {
|
|
|
96
99
|
onCommit(`${pad(next.month)}-${pad(day)}`);
|
|
97
100
|
};
|
|
98
101
|
return (React__default.createElement(Flex, { gap: 1 },
|
|
99
|
-
React__default.createElement(Select
|
|
100
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
101
|
-
, {
|
|
102
|
-
// eslint-disable-next-line jsx-a11y/no-autofocus -- the editor only ever renders inside a chip popover that just opened, per ARIA dialog practices
|
|
103
|
-
autoFocus: focusOnOpen, hideLabel: true, label: `${label} month`, options: monthOptions, placeholder: "Month", value: selection.month ? String(selection.month) : "", onChange: (e) => update({ ...selection, month: Number(e.target.value) || undefined }) }),
|
|
102
|
+
React__default.createElement(Select, { hideLabel: true, label: `${label} month`, options: monthOptions, placeholder: "Month", value: selection.month ? String(selection.month) : "", onChange: (e) => update({ ...selection, month: Number(e.target.value) || undefined }) }),
|
|
104
103
|
React__default.createElement(Select, { hideLabel: true, label: `${label} day`, options: dayOptions(selection.month), placeholder: "Day", value: selection.day ? String(selection.day) : "", onChange: (e) => update({ ...selection, day: Number(e.target.value) || undefined }) })));
|
|
105
104
|
}
|
|
106
105
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dayFilter.js","sources":["../../../src/components/DataTable/dayFilter.tsx"],"sourcesContent":["import { Flex } from \"@components/flex\"\nimport { Select } from \"@components/select\"\nimport React, { 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\"\n\n/** `MM-DD` strings with no year; a pair for `between`. */\nexport type DayFilterValue = string | [string, string]\n\nexport const DAY_IS = {\n inputType: { type: \"day\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const DAY_RANGE = {\n inputType: { type: \"day-range\" },\n label: \"is between\",\n name: \"between\",\n} as const satisfies Operator\n\nconst DAY_OPERATORS = [DAY_IS, DAY_RANGE]\n\nexport type DayOperatorName = (typeof DAY_OPERATORS)[number][\"name\"]\n\n// A leap year, so Feb 29 is always selectable.\nconst REFERENCE_YEAR = 2000\n\nconst locale = new Intl.DateTimeFormat().resolvedOptions().locale\nconst dayFormatter = new Intl.DateTimeFormat(locale, {\n calendar: \"gregory\",\n day: \"numeric\",\n month: \"short\",\n})\nconst monthFormatter = new Intl.DateTimeFormat(locale, {\n calendar: \"gregory\",\n month: \"long\",\n})\n\nconst pad = (n: number) => String(n).padStart(2, \"0\")\n\nconst daysInMonth = (month: number) =>\n new Date(REFERENCE_YEAR, month, 0).getDate()\n\nconst parseDay = (value: string | undefined) => {\n const [month, day] = (value ?? \"\").split(\"-\").map(Number)\n return { day: day || undefined, month: month || undefined }\n}\n\nconst formatDay = (value: string) => {\n const { day, month } = parseDay(value)\n if (!month || !day) return \"\"\n return dayFormatter.format(new Date(REFERENCE_YEAR, month - 1, day))\n}\n\nconst monthOptions = Array.from({ length: 12 }, (_, index) => ({\n label: monthFormatter.format(new Date(REFERENCE_YEAR, index, 1)),\n value: String(index + 1),\n}))\n\nconst dayOptions = (month: number | undefined) =>\n Array.from({ length: month ? daysInMonth(month) : 31 }, (_, index) => ({\n label: String(index + 1),\n value: String(index + 1),\n }))\n\nexport function dayFilter({\n excludes,\n includes,\n ...config\n}: FilterItemConfig<DayOperatorName>): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new DayActiveFilter(\n filter,\n operator,\n activeFilter.value as DayFilterValue\n ),\n operators: resolveOperators(DAY_OPERATORS, {\n default: DAY_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\nclass DayActiveFilter extends ActiveFilterInstance<DayFilterValue> {\n formatValue() {\n if (Array.isArray(this.value)) {\n const [start, end] = this.value\n if (start === undefined || end === undefined) {\n return [start, end].filter((day) => day !== undefined).map(formatDay)\n }\n return [formatDay(start), \"and\", formatDay(end)]\n }\n return this.value === undefined ? \"\" : formatDay(this.value)\n }\n\n renderEditor(onChange: FilterChange) {\n const { label } = this.operator\n\n if (this.operator.inputType.type === \"day-range\") {\n const [start, end] = Array.isArray(this.value)\n ? this.value\n : [this.value, this.value]\n return (\n <Flex gap={1}>\n <DayEditor\n focusOnOpen\n label={`${label} from`}\n value={start}\n onCommit={(day) =>\n onChange({ value: [day, end] }, { complete: end !== undefined })\n }\n />\n <div>and</div>\n <DayEditor\n label={`${label} to`}\n value={end}\n onCommit={(day) =>\n onChange(\n { value: [start, day] },\n { complete: start !== undefined }\n )\n }\n />\n </Flex>\n )\n }\n const single = Array.isArray(this.value) ? this.value[0] : this.value\n return (\n <DayEditor\n focusOnOpen\n label={label}\n value={single}\n onCommit={(day) => onChange({ value: day })}\n />\n )\n }\n}\n\nfunction DayEditor({\n focusOnOpen,\n label,\n onCommit,\n value,\n}: {\n focusOnOpen?: boolean\n label: string\n onCommit: (value: string) => void\n value: string | undefined\n}) {\n const [selection, setSelection] = useState(() => parseDay(value))\n\n const update = (next: typeof selection) => {\n const day =\n next.month && next.day\n ? Math.min(next.day, daysInMonth(next.month))\n : next.day\n setSelection({ ...next, day })\n if (next.month && day) onCommit(`${pad(next.month)}-${pad(day)}`)\n }\n\n return (\n <Flex gap={1}>\n <Select\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={focusOnOpen}\n hideLabel\n label={`${label} month`}\n options={monthOptions}\n placeholder=\"Month\"\n value={selection.month ? String(selection.month) : \"\"}\n onChange={(e) =>\n update({ ...selection, month: Number(e.target.value) || undefined })\n }\n />\n <Select\n hideLabel\n label={`${label} day`}\n options={dayOptions(selection.month)}\n placeholder=\"Day\"\n value={selection.day ? String(selection.day) : \"\"}\n onChange={(e) =>\n update({ ...selection, day: Number(e.target.value) || undefined })\n }\n />\n </Flex>\n )\n}\n"],"names":["React"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dayFilter.js","sources":["../../../src/components/DataTable/dayFilter.tsx"],"sourcesContent":["import { Flex } from \"@components/flex\"\nimport { Select } from \"@components/select\"\nimport React, { 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 DAY_IS = {\n inputType: { type: \"day\" },\n label: \"is\",\n name: \"eq\",\n} as const satisfies Operator\nexport const DAY_RANGE = {\n inputType: { type: \"day-range\" },\n label: \"is between\",\n name: \"between\",\n} as const satisfies Operator\n\nconst DAY_OPERATORS = [DAY_IS, DAY_RANGE]\n\nexport type DayOperatorName = (typeof DAY_OPERATORS)[number][\"name\"]\n\n/** An `MM-DD` string with no year; a pair for `between`, either side of which may still be empty. */\nexport type DayFilterValue =\n | string\n | [string | undefined, string | undefined]\n | undefined\n\nexport type DayActiveFilter = ActiveFilter<DayFilterValue, DayOperatorName>\n\n// A leap year, so Feb 29 is always selectable.\nconst REFERENCE_YEAR = 2000\n\nconst locale = new Intl.DateTimeFormat().resolvedOptions().locale\nconst dayFormatter = new Intl.DateTimeFormat(locale, {\n calendar: \"gregory\",\n day: \"numeric\",\n month: \"short\",\n})\nconst monthFormatter = new Intl.DateTimeFormat(locale, {\n calendar: \"gregory\",\n month: \"long\",\n})\n\nconst pad = (n: number) => String(n).padStart(2, \"0\")\n\nconst daysInMonth = (month: number) =>\n new Date(REFERENCE_YEAR, month, 0).getDate()\n\nconst parseDay = (value: string | undefined) => {\n const [month, day] = (value ?? \"\").split(\"-\").map(Number)\n return { day: day || undefined, month: month || undefined }\n}\n\nconst formatDay = (value: string) => {\n const { day, month } = parseDay(value)\n if (!month || !day) return \"\"\n return dayFormatter.format(new Date(REFERENCE_YEAR, month - 1, day))\n}\n\nconst monthOptions = Array.from({ length: 12 }, (_, index) => ({\n label: monthFormatter.format(new Date(REFERENCE_YEAR, index, 1)),\n value: String(index + 1),\n}))\n\nconst dayOptions = (month: number | undefined) =>\n Array.from({ length: month ? daysInMonth(month) : 31 }, (_, index) => ({\n label: String(index + 1),\n value: String(index + 1),\n }))\n\nexport function dayFilter({\n excludes,\n includes,\n ...config\n}: FilterItemConfig<DayOperatorName>): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new DayActiveFilterInstance(\n filter,\n operator,\n activeFilter.value as DayFilterValue\n ),\n operators: resolveOperators(DAY_OPERATORS, {\n default: DAY_OPERATORS,\n excludes,\n includes,\n }),\n }\n return filter\n}\n\nclass DayActiveFilterInstance extends ActiveFilterInstance<DayFilterValue> {\n formatValue() {\n if (Array.isArray(this.value)) {\n const [start, end] = this.value\n if (start === undefined || end === undefined) {\n return [start, end]\n .filter((day) => day !== undefined)\n .map(formatDay)\n .join(\"\")\n }\n return [formatDay(start), \"and\", formatDay(end)].join(\" \")\n }\n return this.value === undefined ? \"\" : formatDay(this.value)\n }\n\n renderEditor(onChange: FilterChange) {\n const { label } = this.operator\n\n if (this.operator.inputType.type === \"day-range\") {\n const [start, end] = Array.isArray(this.value)\n ? this.value\n : [this.value, this.value]\n return (\n <Flex gap={1}>\n <DayEditor\n label={`${label} from`}\n value={start}\n onCommit={(day) =>\n onChange({ value: [day, end] }, { complete: end !== undefined })\n }\n />\n <div>and</div>\n <DayEditor\n label={`${label} to`}\n value={end}\n onCommit={(day) =>\n onChange(\n { value: [start, day] },\n { complete: start !== undefined }\n )\n }\n />\n </Flex>\n )\n }\n const single = Array.isArray(this.value) ? this.value[0] : this.value\n return (\n <DayEditor\n label={label}\n value={single}\n onCommit={(day) => onChange({ value: day })}\n />\n )\n }\n}\n\nfunction DayEditor({\n label,\n onCommit,\n value,\n}: {\n label: string\n onCommit: (value: string) => void\n value: string | undefined\n}) {\n const [selection, setSelection] = useState(() => parseDay(value))\n\n const update = (next: typeof selection) => {\n const day =\n next.month && next.day\n ? Math.min(next.day, daysInMonth(next.month))\n : next.day\n setSelection({ ...next, day })\n if (next.month && day) onCommit(`${pad(next.month)}-${pad(day)}`)\n }\n\n return (\n <Flex gap={1}>\n <Select\n hideLabel\n label={`${label} month`}\n options={monthOptions}\n placeholder=\"Month\"\n value={selection.month ? String(selection.month) : \"\"}\n onChange={(e) =>\n update({ ...selection, month: Number(e.target.value) || undefined })\n }\n />\n <Select\n hideLabel\n label={`${label} day`}\n options={dayOptions(selection.month)}\n placeholder=\"Day\"\n value={selection.day ? String(selection.day) : \"\"}\n onChange={(e) =>\n update({ ...selection, day: Number(e.target.value) || undefined })\n }\n />\n </Flex>\n )\n}\n"],"names":["React"],"mappings":"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"}
|