@orianatech/pire 0.22.0 → 0.23.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.
@@ -18,8 +18,13 @@ export interface DatePickerProps<TFormat extends 'object' | 'iso' = 'object'> {
18
18
  * `null` for an empty field. Input accepts both shapes in either mode.
19
19
  */
20
20
  valueFormat?: TFormat;
21
- minValue?: DateValue;
22
- maxValue?: DateValue;
21
+ /** Earliest date that can be picked, in either shape `value` accepts. `null` and `undefined`
22
+ * both mean "no bound", so a bound read out of the same state as the value needs no `??
23
+ * undefined` on the way in. An unreadable bound stops applying rather than throwing. */
24
+ minValue?: DateValue | string | null;
25
+ /** Latest date that can be picked — see `minValue`. In a from/to pair each end bounds the
26
+ * other, and both ends come out of the same state in the same shape. */
27
+ maxValue?: DateValue | string | null;
23
28
  /** Return true for dates that cannot be picked — factory calendar, blocked periods. */
24
29
  isDateUnavailable?: (date: DateValue) => boolean;
25
30
  description?: React.ReactNode;
@@ -37,4 +42,4 @@ export interface DatePickerProps<TFormat extends 'object' | 'iso' = 'object'> {
37
42
  /** Date entry with a segmented field and a calendar popover. Segments follow the user's locale,
38
43
  * so a German user types dd.mm.yyyy without any prop change. Wrap the app in React Aria's
39
44
  * I18nProvider to pin a locale. */
40
- export declare function DatePicker<TFormat extends 'object' | 'iso' = 'object'>({ label, description, errorMessage, size, fullWidth, className, style, value, defaultValue, onChange, valueFormat, ...rest }: DatePickerProps<TFormat>): React.JSX.Element;
45
+ export declare function DatePicker<TFormat extends 'object' | 'iso' = 'object'>({ label, description, errorMessage, size, fullWidth, className, style, value, defaultValue, onChange, valueFormat, minValue, maxValue, ...rest }: DatePickerProps<TFormat>): React.JSX.Element;
@@ -18,8 +18,13 @@ export interface DatePickerProps<TFormat extends 'object' | 'iso' = 'object'> {
18
18
  * `null` for an empty field. Input accepts both shapes in either mode.
19
19
  */
20
20
  valueFormat?: TFormat;
21
- minValue?: DateValue;
22
- maxValue?: DateValue;
21
+ /** Earliest date that can be picked, in either shape `value` accepts. `null` and `undefined`
22
+ * both mean "no bound", so a bound read out of the same state as the value needs no `??
23
+ * undefined` on the way in. An unreadable bound stops applying rather than throwing. */
24
+ minValue?: DateValue | string | null;
25
+ /** Latest date that can be picked — see `minValue`. In a from/to pair each end bounds the
26
+ * other, and both ends come out of the same state in the same shape. */
27
+ maxValue?: DateValue | string | null;
23
28
  /** Return true for dates that cannot be picked — factory calendar, blocked periods. */
24
29
  isDateUnavailable?: (date: DateValue) => boolean;
25
30
  description?: React.ReactNode;
@@ -37,5 +42,5 @@ export interface DatePickerProps<TFormat extends 'object' | 'iso' = 'object'> {
37
42
  /** Date entry with a segmented field and a calendar popover. Segments follow the user's locale,
38
43
  * so a German user types dd.mm.yyyy without any prop change. Wrap the app in React Aria's
39
44
  * I18nProvider to pin a locale. */
40
- export declare function DatePicker<TFormat extends 'object' | 'iso' = 'object'>({ label, description, errorMessage, size, fullWidth, className, style, value, defaultValue, onChange, valueFormat, ...rest }: DatePickerProps<TFormat>): React.JSX.Element;
45
+ export declare function DatePicker<TFormat extends 'object' | 'iso' = 'object'>({ label, description, errorMessage, size, fullWidth, className, style, value, defaultValue, onChange, valueFormat, minValue, maxValue, ...rest }: DatePickerProps<TFormat>): React.JSX.Element;
41
46
  //# sourceMappingURL=DatePicker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/components/forms/DatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMvD,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,QAAQ,GAAG,KAAK,GAAG,QAAQ;IAC1E,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;;;wDAIoD;IACpD,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAChF;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IACjD,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAwBD;;oCAEoC;AACpC,wBAAgB,UAAU,CAAC,OAAO,SAAS,QAAQ,GAAG,KAAK,GAAG,QAAQ,EAAE,EAAE,KAAK,EAAE,WAAW,EAC1F,YAAY,EAAE,IAAW,EAAE,SAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAC5F,WAAW,EAAE,GAAG,IAAI,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,qBAoDjD"}
1
+ {"version":3,"file":"DatePicker.d.ts","sourceRoot":"","sources":["../../../src/components/forms/DatePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAIpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMvD,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,QAAQ,GAAG,KAAK,GAAG,QAAQ;IAC1E,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;;;wDAIoD;IACpD,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAChF;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;6FAEyF;IACzF,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACrC;6EACyE;IACzE,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IACrC,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IACjD,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;oCAEoC;AACpC,wBAAgB,UAAU,CAAC,OAAO,SAAS,QAAQ,GAAG,KAAK,GAAG,QAAQ,EAAE,EAAE,KAAK,EAAE,WAAW,EAC1F,YAAY,EAAE,IAAW,EAAE,SAAgB,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAC5F,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,qBAqDrE"}
@@ -1,22 +1,56 @@
1
1
  import type * as React from 'react';
2
2
  import type { DateValue } from 'react-aria-components';
3
+ /** A complete range: what this component emits, and what `rangeLengthInDays` measures. */
3
4
  export interface DateRange {
4
5
  start: DateValue;
5
6
  end: DateValue;
6
7
  }
8
+ /** A complete range as ISO strings — what `onChange` emits under `valueFormat="iso"`. */
9
+ export interface IsoDateRange {
10
+ start: string;
11
+ end: string;
12
+ }
13
+ /**
14
+ * What `value` accepts: either end in either shape, and either end absent.
15
+ *
16
+ * The two ends are read separately on purpose. An unreadable or empty end leaves *that* end
17
+ * without a date instead of voiding the whole range, so a caller can pass the two halves of its
18
+ * state straight through rather than guarding that both parsed before building an object. Deciding
19
+ * what counts as a usable range is this component's job, which is the point of the prop.
20
+ */
21
+ export interface DateRangeInput {
22
+ start?: DateValue | string | null;
23
+ end?: DateValue | string | null;
24
+ }
7
25
  export interface DateRangePreset {
8
26
  id: string;
9
27
  label: string;
10
- /** The app computes the range: Pire cannot know when a customer's fiscal year starts. */
11
- range: () => DateRange;
28
+ /** The app computes the range: Pire cannot know when a customer's fiscal year starts. It also
29
+ * computes in whatever shape it stores, so either shape is accepted here. */
30
+ range: () => DateRangeInput;
12
31
  }
13
- export interface DateRangePickerProps {
32
+ export interface DateRangePickerProps<TFormat extends 'object' | 'iso' = 'object'> {
14
33
  label?: React.ReactNode;
15
- value?: DateRange | null;
16
- defaultValue?: DateRange | null;
17
- onChange?: (value: DateRange | null) => void;
18
- minValue?: DateValue;
19
- maxValue?: DateValue;
34
+ /** Either end in either shape — see `DateRangeInput`. A range whose ends are both empty is an
35
+ * empty field. */
36
+ value?: DateRangeInput | null;
37
+ defaultValue?: DateRangeInput | null;
38
+ onChange?: (value: (TFormat extends 'iso' ? IsoDateRange : DateRange) | null) => void;
39
+ /**
40
+ * The shape `onChange` emits.
41
+ *
42
+ * `'object'` (the default) emits the `DateValue` pair this component has always emitted. `'iso'`
43
+ * emits `{ start: 'YYYY-MM-DD', end: 'YYYY-MM-DD' }`, the shape a consumer sends back to its API.
44
+ *
45
+ * Either way the emitted range is always complete or `null`: React Aria never reports half a
46
+ * range, even though it will happily *display* one while a caller is still filling it in.
47
+ */
48
+ valueFormat?: TFormat;
49
+ /** Earliest date either end can take, in either shape `value` accepts. `null` and `undefined`
50
+ * both mean "no bound". An unreadable bound stops applying rather than throwing. */
51
+ minValue?: DateValue | string | null;
52
+ /** Latest date either end can take — see `minValue`. */
53
+ maxValue?: DateValue | string | null;
20
54
  /** Return true for dates that cannot be picked — blocked periods, closed books. */
21
55
  isDateUnavailable?: (date: DateValue) => boolean;
22
56
  /**
@@ -43,8 +77,15 @@ export interface DateRangePickerProps {
43
77
  className?: string;
44
78
  style?: React.CSSProperties;
45
79
  }
46
- /** Whole days between the two ends, inclusive of both. */
80
+ /**
81
+ * Whole days between the two ends, inclusive of both.
82
+ *
83
+ * A complete `DateRange` measures to a number, which is the signature this has always had. Given
84
+ * the looser shape `value` now takes — either end a string, either end absent — it returns `null`
85
+ * for a range it cannot measure, so a caller holding two strings can pass them straight in.
86
+ */
47
87
  export declare function rangeLengthInDays(range: DateRange): number;
88
+ export declare function rangeLengthInDays(range: DateRangeInput | null | undefined): number | null;
48
89
  /**
49
90
  * Two dates that belong together — the default filter on 24 ERP screens.
50
91
  *
@@ -52,4 +93,4 @@ export declare function rangeLengthInDays(range: DateRange): number;
52
93
  * between them, and locale-driven segment order. Wrap the app in `I18nProvider` to pin a locale:
53
94
  * `es-PY` reads dd/mm/yyyy and `en-US` mm/dd/yyyy off the same value.
54
95
  */
55
- export declare function DateRangePicker({ label, description, errorMessage, maxRangeDays, presets, size, fullWidth, startName, endName, className, style, ...rest }: DateRangePickerProps): React.JSX.Element;
96
+ export declare function DateRangePicker<TFormat extends 'object' | 'iso' = 'object'>({ label, description, errorMessage, maxRangeDays, presets, size, fullWidth, startName, endName, className, style, value, defaultValue, onChange, valueFormat, minValue, maxValue, ...rest }: DateRangePickerProps<TFormat>): React.JSX.Element;
@@ -1,22 +1,56 @@
1
1
  import type * as React from 'react';
2
2
  import type { DateValue } from 'react-aria-components';
3
+ /** A complete range: what this component emits, and what `rangeLengthInDays` measures. */
3
4
  export interface DateRange {
4
5
  start: DateValue;
5
6
  end: DateValue;
6
7
  }
8
+ /** A complete range as ISO strings — what `onChange` emits under `valueFormat="iso"`. */
9
+ export interface IsoDateRange {
10
+ start: string;
11
+ end: string;
12
+ }
13
+ /**
14
+ * What `value` accepts: either end in either shape, and either end absent.
15
+ *
16
+ * The two ends are read separately on purpose. An unreadable or empty end leaves *that* end
17
+ * without a date instead of voiding the whole range, so a caller can pass the two halves of its
18
+ * state straight through rather than guarding that both parsed before building an object. Deciding
19
+ * what counts as a usable range is this component's job, which is the point of the prop.
20
+ */
21
+ export interface DateRangeInput {
22
+ start?: DateValue | string | null;
23
+ end?: DateValue | string | null;
24
+ }
7
25
  export interface DateRangePreset {
8
26
  id: string;
9
27
  label: string;
10
- /** The app computes the range: Pire cannot know when a customer's fiscal year starts. */
11
- range: () => DateRange;
28
+ /** The app computes the range: Pire cannot know when a customer's fiscal year starts. It also
29
+ * computes in whatever shape it stores, so either shape is accepted here. */
30
+ range: () => DateRangeInput;
12
31
  }
13
- export interface DateRangePickerProps {
32
+ export interface DateRangePickerProps<TFormat extends 'object' | 'iso' = 'object'> {
14
33
  label?: React.ReactNode;
15
- value?: DateRange | null;
16
- defaultValue?: DateRange | null;
17
- onChange?: (value: DateRange | null) => void;
18
- minValue?: DateValue;
19
- maxValue?: DateValue;
34
+ /** Either end in either shape — see `DateRangeInput`. A range whose ends are both empty is an
35
+ * empty field. */
36
+ value?: DateRangeInput | null;
37
+ defaultValue?: DateRangeInput | null;
38
+ onChange?: (value: (TFormat extends 'iso' ? IsoDateRange : DateRange) | null) => void;
39
+ /**
40
+ * The shape `onChange` emits.
41
+ *
42
+ * `'object'` (the default) emits the `DateValue` pair this component has always emitted. `'iso'`
43
+ * emits `{ start: 'YYYY-MM-DD', end: 'YYYY-MM-DD' }`, the shape a consumer sends back to its API.
44
+ *
45
+ * Either way the emitted range is always complete or `null`: React Aria never reports half a
46
+ * range, even though it will happily *display* one while a caller is still filling it in.
47
+ */
48
+ valueFormat?: TFormat;
49
+ /** Earliest date either end can take, in either shape `value` accepts. `null` and `undefined`
50
+ * both mean "no bound". An unreadable bound stops applying rather than throwing. */
51
+ minValue?: DateValue | string | null;
52
+ /** Latest date either end can take — see `minValue`. */
53
+ maxValue?: DateValue | string | null;
20
54
  /** Return true for dates that cannot be picked — blocked periods, closed books. */
21
55
  isDateUnavailable?: (date: DateValue) => boolean;
22
56
  /**
@@ -43,8 +77,15 @@ export interface DateRangePickerProps {
43
77
  className?: string;
44
78
  style?: React.CSSProperties;
45
79
  }
46
- /** Whole days between the two ends, inclusive of both. */
80
+ /**
81
+ * Whole days between the two ends, inclusive of both.
82
+ *
83
+ * A complete `DateRange` measures to a number, which is the signature this has always had. Given
84
+ * the looser shape `value` now takes — either end a string, either end absent — it returns `null`
85
+ * for a range it cannot measure, so a caller holding two strings can pass them straight in.
86
+ */
47
87
  export declare function rangeLengthInDays(range: DateRange): number;
88
+ export declare function rangeLengthInDays(range: DateRangeInput | null | undefined): number | null;
48
89
  /**
49
90
  * Two dates that belong together — the default filter on 24 ERP screens.
50
91
  *
@@ -52,5 +93,5 @@ export declare function rangeLengthInDays(range: DateRange): number;
52
93
  * between them, and locale-driven segment order. Wrap the app in `I18nProvider` to pin a locale:
53
94
  * `es-PY` reads dd/mm/yyyy and `en-US` mm/dd/yyyy off the same value.
54
95
  */
55
- export declare function DateRangePicker({ label, description, errorMessage, maxRangeDays, presets, size, fullWidth, startName, endName, className, style, ...rest }: DateRangePickerProps): React.JSX.Element;
96
+ export declare function DateRangePicker<TFormat extends 'object' | 'iso' = 'object'>({ label, description, errorMessage, maxRangeDays, presets, size, fullWidth, startName, endName, className, style, value, defaultValue, onChange, valueFormat, minValue, maxValue, ...rest }: DateRangePickerProps<TFormat>): React.JSX.Element;
56
97
  //# sourceMappingURL=DateRangePicker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangePicker.d.ts","sourceRoot":"","sources":["../../../src/components/forms/DateRangePicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAMpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKvD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,KAAK,EAAE,MAAM,SAAS,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IACjD;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAG1D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,IAAW,EAAE,SAAgB,EACtF,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAC9C,EAAE,oBAAoB,qBAiFtB"}
1
+ {"version":3,"file":"DateRangePicker.d.ts","sourceRoot":"","sources":["../../../src/components/forms/DateRangePicker.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { DateValue } from 'react-aria-components';
2
+ /**
3
+ * What React Aria is given for a date. `undefined` stays `undefined`, since that is what keeps an
4
+ * uncontrolled field uncontrolled — coercing it to `null` would silently disable `defaultValue`
5
+ * and freeze the field.
6
+ *
7
+ * The rest is why this belongs in the library: `parseDate` *throws* on a malformed date, and a bad
8
+ * date arriving from a server must empty one field, never unmount the screen. A datetime is
9
+ * trimmed to its date, because a `DateValue` is a calendar date and holds neither time nor zone.
10
+ */
11
+ export declare function coerceDateValue(value: DateValue | string | null | undefined): DateValue | null | undefined;
12
+ /**
13
+ * The same coercion for `minValue` / `maxValue`, where the two ways of saying "no bound" — `null`
14
+ * and `undefined` — collapse into the one React Aria's own types accept.
15
+ *
16
+ * Worth knowing which way this degrades: an unreadable *value* is visible, because the field shows
17
+ * empty. An unreadable *bound* is not — the constraint simply stops applying, and the user can
18
+ * pick a date the screen meant to forbid. Degrading still beats throwing, since a bound arriving
19
+ * malformed from a server should not take the screen down, but it is the quieter failure of the
20
+ * two.
21
+ */
22
+ export declare function coerceBound(value: DateValue | string | null | undefined): DateValue | undefined;
@@ -0,0 +1,23 @@
1
+ import type { DateValue } from 'react-aria-components';
2
+ /**
3
+ * What React Aria is given for a date. `undefined` stays `undefined`, since that is what keeps an
4
+ * uncontrolled field uncontrolled — coercing it to `null` would silently disable `defaultValue`
5
+ * and freeze the field.
6
+ *
7
+ * The rest is why this belongs in the library: `parseDate` *throws* on a malformed date, and a bad
8
+ * date arriving from a server must empty one field, never unmount the screen. A datetime is
9
+ * trimmed to its date, because a `DateValue` is a calendar date and holds neither time nor zone.
10
+ */
11
+ export declare function coerceDateValue(value: DateValue | string | null | undefined): DateValue | null | undefined;
12
+ /**
13
+ * The same coercion for `minValue` / `maxValue`, where the two ways of saying "no bound" — `null`
14
+ * and `undefined` — collapse into the one React Aria's own types accept.
15
+ *
16
+ * Worth knowing which way this degrades: an unreadable *value* is visible, because the field shows
17
+ * empty. An unreadable *bound* is not — the constraint simply stops applying, and the user can
18
+ * pick a date the screen meant to forbid. Degrading still beats throwing, since a bound arriving
19
+ * malformed from a server should not take the screen down, but it is the quieter failure of the
20
+ * two.
21
+ */
22
+ export declare function coerceBound(value: DateValue | string | null | undefined): DateValue | undefined;
23
+ //# sourceMappingURL=dateValues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dateValues.d.ts","sourceRoot":"","sources":["../../../src/components/forms/dateValues.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAKvD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,SAAS,CAW1G;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAE/F"}
package/dist/index.cjs CHANGED
@@ -1604,8 +1604,9 @@ function NumberField({
1604
1604
 
1605
1605
  // src/components/forms/DatePicker.tsx
1606
1606
  var import_react_aria_components18 = require("react-aria-components");
1607
+
1608
+ // src/components/forms/dateValues.ts
1607
1609
  var import_date = require("@internationalized/date");
1608
- var import_jsx_runtime26 = require("react/jsx-runtime");
1609
1610
  var ISO_DATE = /^(\d{4}-\d{2}-\d{2})(?:[T ].*)?$/;
1610
1611
  function coerceDateValue(value) {
1611
1612
  if (value === void 0) {
@@ -1627,6 +1628,12 @@ function coerceDateValue(value) {
1627
1628
  return null;
1628
1629
  }
1629
1630
  }
1631
+ function coerceBound(value) {
1632
+ return coerceDateValue(value) ?? void 0;
1633
+ }
1634
+
1635
+ // src/components/forms/DatePicker.tsx
1636
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1630
1637
  function DatePicker({
1631
1638
  label,
1632
1639
  description,
@@ -1639,6 +1646,8 @@ function DatePicker({
1639
1646
  defaultValue,
1640
1647
  onChange,
1641
1648
  valueFormat,
1649
+ minValue,
1650
+ maxValue,
1642
1651
  ...rest
1643
1652
  }) {
1644
1653
  const msg = usePireMessages();
@@ -1653,6 +1662,8 @@ function DatePicker({
1653
1662
  validationBehavior: "aria",
1654
1663
  value: coerceDateValue(value),
1655
1664
  defaultValue: coerceDateValue(defaultValue),
1665
+ minValue: coerceBound(minValue),
1666
+ maxValue: coerceBound(maxValue),
1656
1667
  onChange: handleChange,
1657
1668
  ...rest,
1658
1669
  children: [
@@ -1695,8 +1706,24 @@ function DatePicker({
1695
1706
  // src/components/forms/DateRangePicker.tsx
1696
1707
  var import_react_aria_components19 = require("react-aria-components");
1697
1708
  var import_jsx_runtime27 = require("react/jsx-runtime");
1709
+ function coerceRange(range) {
1710
+ if (range === void 0) {
1711
+ return void 0;
1712
+ }
1713
+ if (range === null) {
1714
+ return null;
1715
+ }
1716
+ const start = coerceDateValue(range.start) ?? null;
1717
+ const end = coerceDateValue(range.end) ?? null;
1718
+ return start === null && end === null ? null : { start, end };
1719
+ }
1698
1720
  function rangeLengthInDays(range) {
1699
- return range.end.toDate("UTC").getTime() / 864e5 - range.start.toDate("UTC").getTime() / 864e5 + 1;
1721
+ const start = coerceDateValue(range?.start) ?? null;
1722
+ const end = coerceDateValue(range?.end) ?? null;
1723
+ if (start === null || end === null) {
1724
+ return null;
1725
+ }
1726
+ return end.toDate("UTC").getTime() / 864e5 - start.toDate("UTC").getTime() / 864e5 + 1;
1700
1727
  }
1701
1728
  function DateRangePicker({
1702
1729
  label,
@@ -1710,11 +1737,28 @@ function DateRangePicker({
1710
1737
  endName,
1711
1738
  className,
1712
1739
  style,
1740
+ value,
1741
+ defaultValue,
1742
+ onChange,
1743
+ valueFormat,
1744
+ minValue,
1745
+ maxValue,
1713
1746
  ...rest
1714
1747
  }) {
1715
1748
  const msg = usePireMessages();
1716
- const current = rest.value ?? rest.defaultValue ?? null;
1717
- const tooLong = maxRangeDays != null && current != null && rangeLengthInDays(current) > maxRangeDays;
1749
+ const current = coerceRange(value) ?? coerceRange(defaultValue) ?? null;
1750
+ const span = current === null ? null : rangeLengthInDays(current);
1751
+ const tooLong = maxRangeDays != null && span != null && span > maxRangeDays;
1752
+ const emit = (next) => {
1753
+ if (!onChange) {
1754
+ return;
1755
+ }
1756
+ if (!next?.start || !next.end) {
1757
+ onChange(null);
1758
+ return;
1759
+ }
1760
+ onChange(valueFormat === "iso" ? { start: next.start.toString(), end: next.end.toString() } : { start: next.start, end: next.end });
1761
+ };
1718
1762
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
1719
1763
  import_react_aria_components19.DateRangePicker,
1720
1764
  {
@@ -1723,8 +1767,13 @@ function DateRangePicker({
1723
1767
  startName,
1724
1768
  endName,
1725
1769
  validationBehavior: "aria",
1770
+ value: coerceRange(value),
1771
+ defaultValue: coerceRange(defaultValue),
1772
+ minValue: coerceBound(minValue),
1773
+ maxValue: coerceBound(maxValue),
1774
+ onChange: onChange && emit,
1726
1775
  ...rest,
1727
- isInvalid: rest.isInvalid || tooLong,
1776
+ isInvalid: rest.isInvalid || tooLong || void 0,
1728
1777
  children: [
1729
1778
  label ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_aria_components19.Label, { className: "pire-field-label", children: [
1730
1779
  label,
@@ -1765,7 +1814,7 @@ function DateRangePicker({
1765
1814
  import_react_aria_components19.Button,
1766
1815
  {
1767
1816
  className: "pire-daterange-preset",
1768
- onPress: () => rest.onChange?.(preset.range()),
1817
+ onPress: () => emit(coerceRange(preset.range()) ?? null),
1769
1818
  children: preset.label
1770
1819
  },
1771
1820
  preset.id