@planningcenter/tapestry 4.10.0-rc.5 → 4.10.0-rc.6
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/dateFilter.d.ts +7 -1
- package/dist/components/DataTable/dateFilter.d.ts.map +1 -1
- package/dist/components/DataTable/dateFilter.js +42 -7
- package/dist/components/DataTable/dateFilter.js.map +1 -1
- package/dist/reactRender.css +1261 -1261
- package/dist/reactRender.css.map +1 -1
- package/dist/reactRenderLegacy.css +1261 -1261
- package/dist/reactRenderLegacy.css.map +1 -1
- package/package.json +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DatePickerDateValue } from "../date-picker";
|
|
1
2
|
import type { FilterItemConfig, FilterNodeItem } from "./FilterTypes";
|
|
2
3
|
/** ISO `YYYY-MM-DD` strings; a pair for `between`. */
|
|
3
4
|
export type DateFilterValue = string | [string, string];
|
|
@@ -81,6 +82,11 @@ declare const ALL_DATE_OPERATORS: ({
|
|
|
81
82
|
readonly name: "between";
|
|
82
83
|
})[];
|
|
83
84
|
export type DateOperatorName = (typeof ALL_DATE_OPERATORS)[number]["name"];
|
|
84
|
-
|
|
85
|
+
/** Inclusive bounds on the dates the filter's pickers allow. */
|
|
86
|
+
export interface DateLimits {
|
|
87
|
+
max?: DatePickerDateValue;
|
|
88
|
+
min?: DatePickerDateValue;
|
|
89
|
+
}
|
|
90
|
+
export declare function dateFilter({ excludes, includes, max, min, ...config }: FilterItemConfig<DateOperatorName> & DateLimits): FilterNodeItem;
|
|
85
91
|
export {};
|
|
86
92
|
//# sourceMappingURL=dateFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dateFilter.d.ts","sourceRoot":"","sources":["../../../src/components/DataTable/dateFilter.tsx"],"names":[],"mappings":"
|
|
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,EAEV,gBAAgB,EAChB,cAAc,EAEf,MAAM,eAAe,CAAA;AAGtB,sDAAsD;AACtD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAIvD,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;AAuB1E,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,mBAAmB,CAAA;IACzB,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"}
|
|
@@ -41,10 +41,32 @@ const ALL_DATE_OPERATORS = [DATE_IS, LT, GT, LTE, GTE, DATE_RANGE];
|
|
|
41
41
|
const DEFAULT_DATE_OPERATORS = [DATE_IS, LT, GT, DATE_RANGE];
|
|
42
42
|
const formatter = new $12a3c853105e5a70$export$ad991b66133851cf(new Intl.DateTimeFormat().resolvedOptions().locale, { dateStyle: "medium" });
|
|
43
43
|
const formatDate = (iso) => formatter.format($58246871e4652552$export$6b862160d295c8e(iso).toDate($ad063034c8620db8$export$aa8b41735afcabd2()));
|
|
44
|
-
|
|
44
|
+
const toDateValue = (date) => typeof date === "string" ? $58246871e4652552$export$6b862160d295c8e(date) : date;
|
|
45
|
+
function earlier(a, b) {
|
|
46
|
+
if (a === undefined || b === undefined)
|
|
47
|
+
return a ?? b;
|
|
48
|
+
return toDateValue(a).compare(toDateValue(b)) <= 0 ? a : b;
|
|
49
|
+
}
|
|
50
|
+
function later(a, b) {
|
|
51
|
+
if (a === undefined || b === undefined)
|
|
52
|
+
return a ?? b;
|
|
53
|
+
return toDateValue(a).compare(toDateValue(b)) >= 0 ? a : b;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The pickers only flag typed dates outside the limits as invalid, so the
|
|
57
|
+
* editors clear the value rather than commit them.
|
|
58
|
+
*/
|
|
59
|
+
function toValidDate(date, { max, min }) {
|
|
60
|
+
if (!date)
|
|
61
|
+
return undefined;
|
|
62
|
+
const isWithinLimits = (min === undefined || date.compare(toDateValue(min)) >= 0) &&
|
|
63
|
+
(max === undefined || date.compare(toDateValue(max)) <= 0);
|
|
64
|
+
return isWithinLimits ? date.toString() : undefined;
|
|
65
|
+
}
|
|
66
|
+
function dateFilter({ excludes, includes, max, min, ...config }) {
|
|
45
67
|
const filter = {
|
|
46
68
|
...config,
|
|
47
|
-
createActiveFilterInstance: (activeFilter, operator) => new DateActiveFilter(filter, operator, activeFilter.value),
|
|
69
|
+
createActiveFilterInstance: (activeFilter, operator) => new DateActiveFilter(filter, operator, activeFilter.value, { max, min }),
|
|
48
70
|
operators: resolveOperators(ALL_DATE_OPERATORS, {
|
|
49
71
|
default: DEFAULT_DATE_OPERATORS,
|
|
50
72
|
excludes,
|
|
@@ -54,6 +76,11 @@ function dateFilter({ excludes, includes, ...config }) {
|
|
|
54
76
|
return filter;
|
|
55
77
|
}
|
|
56
78
|
class DateActiveFilter extends ActiveFilterInstance {
|
|
79
|
+
limits;
|
|
80
|
+
constructor(filter, operator, value, limits) {
|
|
81
|
+
super(filter, operator, value);
|
|
82
|
+
this.limits = limits;
|
|
83
|
+
}
|
|
57
84
|
formatValue() {
|
|
58
85
|
if (Array.isArray(this.value)) {
|
|
59
86
|
const [start, end] = this.value;
|
|
@@ -70,7 +97,7 @@ class DateActiveFilter extends ActiveFilterInstance {
|
|
|
70
97
|
const range = Array.isArray(this.value)
|
|
71
98
|
? this.value
|
|
72
99
|
: [this.value, this.value];
|
|
73
|
-
return (React__default.createElement(DateRangeEditor, { label: label, value: range, onCommit: (value) => {
|
|
100
|
+
return (React__default.createElement(DateRangeEditor, { label: label, max: this.limits.max, min: this.limits.min, value: range, onCommit: (value) => {
|
|
74
101
|
const complete = value.length === 2 && value.every((v) => v !== undefined);
|
|
75
102
|
onChange({ value }, { complete });
|
|
76
103
|
} }));
|
|
@@ -80,18 +107,26 @@ class DateActiveFilter extends ActiveFilterInstance {
|
|
|
80
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
|
|
81
108
|
, {
|
|
82
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
|
|
83
|
-
autoFocus: true, hideLabel: true,
|
|
110
|
+
autoFocus: true, hideLabel: true,
|
|
111
|
+
// Uncontrolled so a typed date outside the limits stays visible
|
|
112
|
+
// (and flagged invalid) after the value is cleared.
|
|
113
|
+
defaultValue: single, label: label, max: this.limits.max, min: this.limits.min, onChange: (date) => {
|
|
114
|
+
const value = toValidDate(date, this.limits);
|
|
115
|
+
onChange({ value }, { complete: value !== undefined });
|
|
116
|
+
} }));
|
|
84
117
|
}
|
|
85
118
|
}
|
|
86
|
-
function DateRangeEditor({ label, onCommit, value: [start, end], }) {
|
|
119
|
+
function DateRangeEditor({ label, max, min, onCommit, value: [start, end], }) {
|
|
120
|
+
const startLimits = { max: earlier(max, end), min };
|
|
121
|
+
const endLimits = { max, min: later(min, start) };
|
|
87
122
|
return (React__default.createElement(Flex, { gap: 1 },
|
|
88
123
|
React__default.createElement(DatePicker
|
|
89
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
|
|
90
125
|
, {
|
|
91
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
|
|
92
|
-
autoFocus: true, hideLabel: true, label: `${label} from`,
|
|
127
|
+
autoFocus: true, hideLabel: true, defaultValue: start, label: `${label} from`, max: startLimits.max, min: startLimits.min, onChange: (date) => onCommit([toValidDate(date, startLimits), end]) }),
|
|
93
128
|
React__default.createElement("div", null, "and"),
|
|
94
|
-
React__default.createElement(DatePicker, { hideLabel: true, label: `${label} to`,
|
|
129
|
+
React__default.createElement(DatePicker, { hideLabel: true, defaultValue: end, label: `${label} to`, max: endLimits.max, min: endLimits.min, onChange: (date) => onCommit([start, toValidDate(date, endLimits)]) })));
|
|
95
130
|
}
|
|
96
131
|
|
|
97
132
|
export { DATE_IS, DATE_RANGE, GT, GTE, LT, LTE, dateFilter };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dateFilter.js","sources":["../../../src/components/DataTable/dateFilter.tsx"],"sourcesContent":["import { DatePicker } from \"@components/date-picker\"\nimport { Flex } from \"@components/flex\"\nimport {\n DateFormatter,\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\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\nexport function dateFilter({\n excludes,\n includes,\n ...config\n}: FilterItemConfig<DateOperatorName>): FilterNodeItem {\n const filter: FilterNodeItem = {\n ...config,\n createActiveFilterInstance: (activeFilter, operator) =>\n new DateActiveFilter(\n filter,\n operator,\n activeFilter.value as DateFilterValue\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 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: [string, string] = Array.isArray(this.value)\n ? this.value\n : [this.value, this.value]\n return (\n <DateRangeEditor\n label={label}\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 label={label}\n value={single}\n onChange={(date) => date && onChange({ value: date.toString() })}\n />\n )\n }\n}\n\nfunction DateRangeEditor({\n label,\n onCommit,\n value: [start, end],\n}: {\n label: string\n onCommit: (value: [string, string]) => void\n value: [string, string]\n}) {\n return (\n <Flex 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 label={`${label} from`}\n value={start}\n onChange={(date) => date && onCommit([date.toString(), end])}\n />\n <div>and</div>\n <DatePicker\n hideLabel\n label={`${label} to`}\n value={end}\n onChange={(date) => date && onCommit([start, date.toString()])}\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 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 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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"}
|