@homebound/beam 2.141.1 → 2.142.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/Css.d.ts +3 -0
  2. package/dist/Css.js +2 -0
  3. package/dist/components/ButtonDatePicker.js +6 -2
  4. package/dist/components/internal/DatePicker/DatePicker.css +5 -0
  5. package/dist/components/internal/DatePicker/DatePickerOverlay.d.ts +3 -6
  6. package/dist/components/internal/DatePicker/DatePickerOverlay.js +2 -6
  7. package/dist/components/internal/DatePicker/DateRangePicker.d.ts +10 -0
  8. package/dist/components/internal/DatePicker/DateRangePicker.js +23 -0
  9. package/dist/components/internal/DatePicker/Day.js +22 -7
  10. package/dist/components/internal/DatePicker/index.d.ts +1 -0
  11. package/dist/components/internal/DatePicker/index.js +1 -0
  12. package/dist/forms/BoundDateField.js +2 -2
  13. package/dist/forms/BoundDateRangeField.d.ts +10 -0
  14. package/dist/forms/BoundDateRangeField.js +27 -0
  15. package/dist/forms/formStateDomain.d.ts +3 -0
  16. package/dist/forms/formStateDomain.js +2 -1
  17. package/dist/forms/index.d.ts +1 -0
  18. package/dist/forms/index.js +1 -0
  19. package/dist/inputs/DateFields/DateField.d.ts +4 -0
  20. package/dist/inputs/DateFields/DateField.js +9 -0
  21. package/dist/inputs/{DateField.mock.d.ts → DateFields/DateField.mock.d.ts} +1 -1
  22. package/dist/inputs/{DateField.mock.js → DateFields/DateField.mock.js} +1 -1
  23. package/dist/inputs/{DateField.d.ts → DateFields/DateFieldBase.d.ts} +18 -11
  24. package/dist/inputs/{DateField.js → DateFields/DateFieldBase.js} +80 -83
  25. package/dist/inputs/DateFields/DateRangeField.d.ts +4 -0
  26. package/dist/inputs/DateFields/DateRangeField.js +9 -0
  27. package/dist/inputs/DateFields/index.d.ts +5 -0
  28. package/dist/inputs/DateFields/index.js +18 -0
  29. package/dist/inputs/DateFields/utils.d.ts +14 -0
  30. package/dist/inputs/DateFields/utils.js +82 -0
  31. package/dist/inputs/TextFieldBase.js +1 -1
  32. package/dist/inputs/index.d.ts +1 -1
  33. package/dist/inputs/index.js +1 -1
  34. package/dist/types.d.ts +2 -0
  35. package/package.json +2 -2
package/dist/Css.d.ts CHANGED
@@ -2849,6 +2849,9 @@ declare class CssBuilder<T extends Properties1> {
2849
2849
  } & {
2850
2850
  backgroundColor: import("csstype").Property.BackgroundColor | undefined;
2851
2851
  }>;
2852
+ get contentEmpty(): CssBuilder<T & {
2853
+ content: import("csstype").Property.Content | undefined;
2854
+ }>;
2852
2855
  get $(): T;
2853
2856
  if(t: boolean | Breakpoint): CssBuilder<T>;
2854
2857
  get else(): CssBuilder<T>;
package/dist/Css.js CHANGED
@@ -859,6 +859,8 @@ class CssBuilder {
859
859
  get listReset() { return this.add("padding", 0).add("margin", 0).add("listStyle", "none"); }
860
860
  // underlay
861
861
  get underlay() { return this.add("position", "fixed").add("top", 0).add("bottom", 0).add("left", 0).add("right", 0).add("display", "flex").add("alignItems", "center").add("justifyContent", "center").add("backgroundColor", "rgba(36,36,36,0.2)"); }
862
+ // contentEmpty
863
+ get contentEmpty() { return this.add("content", "''"); }
862
864
  // aliases
863
865
  get $() { return maybeImportant(sortObject(this.rules), this.opts.important); }
864
866
  if(t) {
@@ -5,16 +5,20 @@ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const react_aria_1 = require("react-aria");
7
7
  const react_stately_1 = require("react-stately");
8
+ const DatePicker_1 = require("./internal/DatePicker/DatePicker");
8
9
  const DatePickerOverlay_1 = require("./internal/DatePicker/DatePickerOverlay");
9
10
  const OverlayTrigger_1 = require("./internal/OverlayTrigger");
10
11
  const utils_1 = require("../utils");
11
12
  const defaultTestId_1 = require("../utils/defaultTestId");
12
13
  function ButtonDatePicker(props) {
13
- const { defaultOpen, disabled, trigger } = props;
14
+ const { defaultOpen, disabled, trigger, onSelect, ...datePickerProps } = props;
14
15
  const state = (0, react_stately_1.useMenuTriggerState)({ isOpen: defaultOpen });
15
16
  const buttonRef = (0, react_1.useRef)(null);
16
17
  const { menuTriggerProps, menuProps } = (0, react_aria_1.useMenuTrigger)({ isDisabled: !!disabled }, state, buttonRef);
17
18
  const tid = (0, utils_1.useTestIds)(props, (0, OverlayTrigger_1.isTextButton)(trigger) ? (0, defaultTestId_1.defaultTestId)(trigger.label) : trigger.icon);
18
- return ((0, jsx_runtime_1.jsx)(OverlayTrigger_1.OverlayTrigger, Object.assign({}, props, { menuTriggerProps: menuTriggerProps, state: state, buttonRef: buttonRef }, tid, { children: (0, jsx_runtime_1.jsx)(DatePickerOverlay_1.DatePickerOverlay, Object.assign({}, props, { state: state, overlayProps: menuProps }, tid.datePicker), void 0) }), void 0));
19
+ return ((0, jsx_runtime_1.jsx)(OverlayTrigger_1.OverlayTrigger, Object.assign({}, props, { menuTriggerProps: menuTriggerProps, state: state, buttonRef: buttonRef }, tid, { children: (0, jsx_runtime_1.jsx)(DatePickerOverlay_1.DatePickerOverlay, Object.assign({ overlayProps: menuProps }, { children: (0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, Object.assign({}, datePickerProps, { onSelect: (d) => {
20
+ onSelect(d);
21
+ state.close();
22
+ } }, tid.datePicker), void 0) }), void 0) }), void 0));
19
23
  }
20
24
  exports.ButtonDatePicker = ButtonDatePicker;
@@ -14,6 +14,11 @@
14
14
  --rdp-outline-selected: 2px solid rgba(3,105,161,1);
15
15
  }
16
16
 
17
+ /* Added in By Beam */
18
+ .rdp-cell:focus-visible {
19
+ outline: 0;
20
+ }
21
+
17
22
  .rdp {
18
23
  /* Modified by Beam (1em -> 16px) */
19
24
  margin: 16px;
@@ -1,9 +1,6 @@
1
- import { HTMLAttributes } from "react";
2
- import { OverlayTriggerState } from "react-stately";
3
- import { DatePickerProps } from "./DatePicker";
4
- interface DatePickerOverlayProps extends DatePickerProps {
1
+ import { HTMLAttributes, PropsWithChildren } from "react";
2
+ interface DatePickerOverlayProps {
5
3
  overlayProps: HTMLAttributes<HTMLElement>;
6
- state: OverlayTriggerState;
7
4
  }
8
- export declare function DatePickerOverlay({ overlayProps, state, ...datePickerProps }: DatePickerOverlayProps): import("@emotion/react/jsx-runtime").JSX.Element;
5
+ export declare function DatePickerOverlay({ overlayProps, children }: PropsWithChildren<DatePickerOverlayProps>): import("@emotion/react/jsx-runtime").JSX.Element;
9
6
  export {};
@@ -2,16 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DatePickerOverlay = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
- const DatePicker_1 = require("./DatePicker");
6
5
  const Css_1 = require("../../../Css");
7
6
  // Small wrapper around DatePicker to provide necessary styling and state handling when displayed as an overlay.
8
- function DatePickerOverlay({ overlayProps, state, ...datePickerProps }) {
7
+ function DatePickerOverlay({ overlayProps, children }) {
9
8
  return (
10
9
  // Adds `tabIndex` so clicking within the DatePicker will provide a `e.relatedTarget` on blur and focus events.
11
10
  // This allows for components such as the DateField to conditionally trigger their 'onBlur' prop. E.g. If the user leaves the field to interact with the DatePicker, then don't call onBlur
12
- (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.br4.bshModal.$ }, overlayProps, { tabIndex: 0 }, { children: (0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, Object.assign({}, datePickerProps, { onSelect: (d) => {
13
- datePickerProps.onSelect(d);
14
- state.close();
15
- } }), void 0) }), void 0));
11
+ (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.br4.bshModal.$ }, overlayProps, { tabIndex: 0 }, { children: children }), void 0));
16
12
  }
17
13
  exports.DatePickerOverlay = DatePickerOverlay;
@@ -0,0 +1,10 @@
1
+ import { Matcher } from "react-day-picker";
2
+ import { DateRange } from "../../../types";
3
+ import "./DatePicker.css";
4
+ export interface DateRangePickerProps {
5
+ range: DateRange | undefined;
6
+ onSelect: (range: DateRange | undefined) => void;
7
+ disabledDays?: Matcher | Matcher[];
8
+ dottedDays?: Matcher[];
9
+ }
10
+ export declare function DateRangePicker(props: DateRangePickerProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DateRangePicker = void 0;
4
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
+ const react_day_picker_1 = require("react-day-picker");
6
+ const Day_1 = require("./Day");
7
+ const Header_1 = require("./Header");
8
+ const WeekHeader_1 = require("./WeekHeader");
9
+ const Css_1 = require("../../../Css");
10
+ const utils_1 = require("../../../utils");
11
+ require("./DatePicker.css");
12
+ function DateRangePicker(props) {
13
+ var _a;
14
+ const { range, onSelect, disabledDays, dottedDays } = props;
15
+ const tid = (0, utils_1.useTestIds)(props, "datePicker");
16
+ return ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.dib.bgWhite.xs.$ }, tid, { children: (0, jsx_runtime_1.jsx)(react_day_picker_1.DayPicker, { mode: "range", selected: range, components: { Caption: Header_1.Header, Head: WeekHeader_1.WeekHeader, Day: Day_1.Day }, defaultMonth: (_a = range === null || range === void 0 ? void 0 : range.to) !== null && _a !== void 0 ? _a : new Date(), onSelect: (selection, day, activeModifiers) => {
17
+ // Disallow returning disabled dates.
18
+ if (activeModifiers.disabled)
19
+ return;
20
+ onSelect(selection);
21
+ }, disabled: disabledDays, modifiers: { indicatorDot: dottedDays !== null && dottedDays !== void 0 ? dottedDays : [] } }, void 0) }), void 0));
22
+ }
23
+ exports.DateRangePicker = DateRangePicker;
@@ -19,22 +19,37 @@ function Day(props) {
19
19
  return (0, jsx_runtime_1.jsx)("div", Object.assign({}, divProps), void 0);
20
20
  }
21
21
  const { className, children, ...otherProps } = buttonProps;
22
- const { selected = false, indicatorDot = false, disabled = false, today = false } = activeModifiers;
22
+ const { selected = false, indicatorDot = false, disabled = false, today = false, range_middle = false, range_start = false, range_end = false, } = activeModifiers;
23
+ // It is possible that we have selected only one day for the range. In this case the date will be both the start and end.
24
+ // When this happens, do not show styling as if there is an existing range.
25
+ const showRangeStyles = !(range_end === true && range_start === true);
26
+ const showActiveStyles = !disabled;
23
27
  return ((0, jsx_runtime_1.jsx)("button", Object.assign({}, otherProps, { ref: buttonRef, type: "button", css: {
24
- ...Css_1.Css.overflowHidden.pbPx(4).if(disabled).cursorNotAllowed.$,
28
+ ...Css_1.Css.relative.pbPx(4).outline0.if(disabled).cursorNotAllowed.$,
25
29
  // Do not apply interaction styles for disabled or already selected days.
26
30
  ...(!selected &&
27
31
  !disabled && {
28
32
  "&:hover:not(:active) > div": Css_1.Css.bgGray100.$,
29
- "&:active > div": Css_1.Css.bgGray400.$,
30
33
  }),
34
+ ...(!disabled && { "&:active > div": Css_1.Css.bgGray400.gray900.$ }),
35
+ "&:focus:not(:active) > div": Css_1.Css.ba.bLightBlue700.if(selected).bLightBlue900.$,
36
+ ...(showRangeStyles &&
37
+ range_start &&
38
+ Css_1.Css.addIn(":after", { ...rangeBaseStyles, ...Css_1.Css.rightPx(-2).wPx(8).$ }).$),
39
+ ...(showRangeStyles && range_end && Css_1.Css.addIn(":after", { ...rangeBaseStyles, ...Css_1.Css.wPx(8).leftPx(-2).$ }).$),
40
+ ...(showRangeStyles && range_middle && Css_1.Css.addIn(":after", { ...rangeBaseStyles, ...Css_1.Css.leftPx(-2).$ }).$),
31
41
  } }, tid, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
32
- ...Css_1.Css.relative.br4.df.aic.jcc.wPx(28).hPx(30).mtPx(2).br4.$,
33
- ...(today && Css_1.Css.bgGray100.$),
34
- ...(selected && Css_1.Css.white.bgLightBlue700.$),
42
+ ...Css_1.Css.overflowHidden.gray900.relative.z1.br4.df.aic.jcc.wPx(28).hPx(30).mtPx(2).br4.$,
43
+ ...(today && !range_middle && Css_1.Css.bgGray100.$),
44
+ ...(selected && !range_middle && Css_1.Css.white.bgLightBlue700.$),
35
45
  ...(disabled && Css_1.Css.gray500.$),
36
46
  } }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.mtPx(-2).$ }, { children: children }), void 0), indicatorDot && ((0, jsx_runtime_1.jsx)("div", Object.assign({
37
47
  // Using `absolute` position as to not change the placement of the day's number when this is introduced
38
- css: Css_1.Css.absolute.bottomPx(4).wPx(4).hPx(4).bgLightBlue700.br4.if(selected).bgWhite.$ }, tid.indicatorDot), void 0))] }), void 0) }), void 0));
48
+ css: Css_1.Css.absolute
49
+ .bottomPx(4)
50
+ .wPx(4)
51
+ .hPx(4)
52
+ .bgLightBlue700.br4.if(selected && !range_middle).bgWhite.$ }, tid.indicatorDot), void 0))] }), void 0) }), void 0));
39
53
  }
40
54
  exports.Day = Day;
55
+ const rangeBaseStyles = Css_1.Css.absolute.topPx(2).contentEmpty.hPx(30).wPx(32).bgLightBlue100.$;
@@ -1,2 +1,3 @@
1
1
  export * from "./DatePicker";
2
2
  export * from "./DatePickerOverlay";
3
+ export * from "./DateRangePicker";
@@ -12,3 +12,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  __exportStar(require("./DatePicker"), exports);
14
14
  __exportStar(require("./DatePickerOverlay"), exports);
15
+ __exportStar(require("./DateRangePicker"), exports);
@@ -8,12 +8,12 @@ const utils_1 = require("../utils");
8
8
  const defaultLabel_1 = require("../utils/defaultLabel");
9
9
  /** Wraps `TextField` and binds it to a form field. */
10
10
  function BoundDateField(props) {
11
- const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, onEnter, ...others } = props;
11
+ const { field, readOnly, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, onEnter, ...others } = props;
12
12
  const testId = (0, utils_1.useTestIds)(props, field.key);
13
13
  return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.DateField, Object.assign({ label: label, value: field.value || undefined, onChange: (value) => {
14
14
  onChange(value);
15
15
  field.maybeAutoSave();
16
- }, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, onBlur: () => {
16
+ }, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, onBlur: () => {
17
17
  field.blur();
18
18
  (0, utils_1.maybeCall)(onBlur);
19
19
  }, onFocus: () => {
@@ -0,0 +1,10 @@
1
+ import { FieldState } from "@homebound/form-state";
2
+ import { DateRangeFieldProps } from "../inputs";
3
+ import { DateRange } from "../types";
4
+ export declare type BoundDateRangeFieldProps = Omit<DateRangeFieldProps, "label" | "value" | "onChange"> & {
5
+ field: FieldState<any, DateRange | null | undefined>;
6
+ label?: string;
7
+ onChange?: (value: DateRange) => void;
8
+ };
9
+ /** Wraps `TextField` and binds it to a form field. */
10
+ export declare function BoundDateRangeField(props: BoundDateRangeFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BoundDateRangeField = void 0;
4
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
+ const mobx_react_1 = require("mobx-react");
6
+ const inputs_1 = require("../inputs");
7
+ const utils_1 = require("../utils");
8
+ const defaultLabel_1 = require("../utils/defaultLabel");
9
+ /** Wraps `TextField` and binds it to a form field. */
10
+ function BoundDateRangeField(props) {
11
+ const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, onEnter, ...others } = props;
12
+ const testId = (0, utils_1.useTestIds)(props, field.key);
13
+ return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.DateRangeField, Object.assign({ label: label, value: field.value || undefined, onChange: (value) => {
14
+ onChange(value);
15
+ field.maybeAutoSave();
16
+ }, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, onBlur: () => {
17
+ field.blur();
18
+ (0, utils_1.maybeCall)(onBlur);
19
+ }, onFocus: () => {
20
+ field.focus();
21
+ (0, utils_1.maybeCall)(onFocus);
22
+ }, onEnter: () => {
23
+ (0, utils_1.maybeCall)(onEnter);
24
+ field.maybeAutoSave();
25
+ } }, testId, others), void 0)) }, void 0));
26
+ }
27
+ exports.BoundDateRangeField = BoundDateRangeField;
@@ -1,6 +1,8 @@
1
+ import { DateRange } from "../types";
1
2
  export declare const jan1: Date;
2
3
  export declare const jan2: Date;
3
4
  export declare const jan10: Date;
5
+ export declare const jan19: Date;
4
6
  export declare const jan29: Date;
5
7
  export declare const dd100: DeweyDecimalClassification;
6
8
  export declare const dd200: DeweyDecimalClassification;
@@ -20,6 +22,7 @@ export interface AuthorInput {
20
22
  isAvailable?: boolean | null;
21
23
  animals?: string[] | null;
22
24
  bio?: string | null;
25
+ saleDates?: DateRange | null;
23
26
  }
24
27
  export interface AuthorAddress {
25
28
  street?: string | null;
@@ -3,10 +3,11 @@
3
3
  // by a GraphQL schema for a `saveAuthor` mutation that takes an author
4
4
  // plus the author's books.
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DateOnly = exports.dd200 = exports.dd100 = exports.jan29 = exports.jan10 = exports.jan2 = exports.jan1 = void 0;
6
+ exports.DateOnly = exports.dd200 = exports.dd100 = exports.jan29 = exports.jan19 = exports.jan10 = exports.jan2 = exports.jan1 = void 0;
7
7
  exports.jan1 = new Date(2020, 0, 1);
8
8
  exports.jan2 = new Date(2020, 0, 2);
9
9
  exports.jan10 = new Date(2020, 0, 10);
10
+ exports.jan19 = new Date(2020, 0, 19);
10
11
  exports.jan29 = new Date(2020, 0, 29);
11
12
  exports.dd100 = { number: "100", category: "Philosophy" };
12
13
  exports.dd200 = { number: "200", category: "Religion" };
@@ -2,6 +2,7 @@ export * from "./BoundCheckboxField";
2
2
  export * from "./BoundCheckboxGroupField";
3
3
  export * from "./BoundChipSelectField";
4
4
  export * from "./BoundDateField";
5
+ export * from "./BoundDateRangeField";
5
6
  export * from "./BoundMultiSelectField";
6
7
  export * from "./BoundNumberField";
7
8
  export * from "./BoundRadioGroupField";
@@ -14,6 +14,7 @@ __exportStar(require("./BoundCheckboxField"), exports);
14
14
  __exportStar(require("./BoundCheckboxGroupField"), exports);
15
15
  __exportStar(require("./BoundChipSelectField"), exports);
16
16
  __exportStar(require("./BoundDateField"), exports);
17
+ __exportStar(require("./BoundDateRangeField"), exports);
17
18
  __exportStar(require("./BoundMultiSelectField"), exports);
18
19
  __exportStar(require("./BoundNumberField"), exports);
19
20
  __exportStar(require("./BoundRadioGroupField"), exports);
@@ -0,0 +1,4 @@
1
+ import { DateSingleFieldBaseProps } from "./DateFieldBase";
2
+ export interface DateFieldProps extends Omit<DateSingleFieldBaseProps, "mode"> {
3
+ }
4
+ export declare function DateField(props: DateFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DateField = void 0;
4
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
+ const DateFieldBase_1 = require("./DateFieldBase");
6
+ function DateField(props) {
7
+ return (0, jsx_runtime_1.jsx)(DateFieldBase_1.DateFieldBase, Object.assign({}, props, { mode: "single" }), void 0);
8
+ }
9
+ exports.DateField = DateField;
@@ -1,3 +1,3 @@
1
- import { DateFieldProps } from "./";
1
+ import { DateFieldProps } from "..";
2
2
  /** Mocks out `DateField` as a text `<input>` field. */
3
3
  export declare function DateField(props: DateFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -4,7 +4,7 @@ exports.DateField = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const date_fns_1 = require("date-fns");
6
6
  const react_1 = require("react");
7
- const utils_1 = require("../utils");
7
+ const utils_1 = require("../../utils");
8
8
  /** Mocks out `DateField` as a text `<input>` field. */
9
9
  function DateField(props) {
10
10
  const { onChange = () => { }, errorMsg, onBlur, onFocus } = props;
@@ -1,10 +1,10 @@
1
1
  import { ReactNode } from "react";
2
2
  import { Matcher } from "react-day-picker";
3
- import { TextFieldBaseProps } from "./TextFieldBase";
4
- export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "hideLabel" | "compact"> {
5
- value: Date | undefined;
3
+ import { DateFieldMode, dateFormats } from "./utils";
4
+ import { TextFieldBaseProps } from "../TextFieldBase";
5
+ import { DateRange } from "../../types";
6
+ export interface DateFieldBaseProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "hideLabel" | "compact"> {
6
7
  label: string;
7
- onChange: (value: Date) => void;
8
8
  /** Called when the component loses focus */
9
9
  onBlur?: () => void;
10
10
  /** Called when the component is in focus. */
@@ -27,12 +27,19 @@ export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless
27
27
  */
28
28
  disabledDays?: Matcher | Matcher[];
29
29
  onEnter?: VoidFunction;
30
+ /** for storybook */
30
31
  defaultOpen?: boolean;
32
+ onChange: ((value: Date) => void) | ((value: DateRange) => void);
33
+ mode: DateFieldMode;
34
+ }
35
+ export interface DateSingleFieldBaseProps extends DateFieldBaseProps {
36
+ mode: "single";
37
+ value: Date | undefined;
38
+ onChange: (value: Date) => void;
39
+ }
40
+ export interface DateRangeFieldBaseProps extends DateFieldBaseProps {
41
+ mode: "range";
42
+ value: DateRange | undefined;
43
+ onChange: (value: DateRange) => void;
31
44
  }
32
- export declare function DateField(props: DateFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
33
- declare const dateFormats: {
34
- short: string;
35
- medium: string;
36
- long: string;
37
- };
38
- export {};
45
+ export declare function DateFieldBase(props: DateRangeFieldBaseProps | DateSingleFieldBaseProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -1,20 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DateField = void 0;
3
+ exports.DateFieldBase = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
- const date_fns_1 = require("date-fns");
6
5
  const react_1 = require("react");
7
6
  const react_aria_1 = require("react-aria");
7
+ const react_day_picker_1 = require("react-day-picker");
8
8
  const react_stately_1 = require("react-stately");
9
- const components_1 = require("../components");
10
- const internal_1 = require("../components/internal");
11
- const DatePickerOverlay_1 = require("../components/internal/DatePicker/DatePickerOverlay");
12
- const Css_1 = require("../Css");
13
- const TextFieldBase_1 = require("./TextFieldBase");
14
- const utils_1 = require("../utils");
15
- const defaultTestId_1 = require("../utils/defaultTestId");
16
- function DateField(props) {
17
- const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly, format = "short", iconLeft = false, disabledDays, onEnter, defaultOpen, ...others } = props;
9
+ const components_1 = require("../../components");
10
+ const internal_1 = require("../../components/internal");
11
+ const DatePickerOverlay_1 = require("../../components/internal/DatePicker/DatePickerOverlay");
12
+ const Css_1 = require("../../Css");
13
+ const utils_1 = require("./utils");
14
+ const TextFieldBase_1 = require("../TextFieldBase");
15
+ const utils_2 = require("../../utils");
16
+ const defaultTestId_1 = require("../../utils/defaultTestId");
17
+ function DateFieldBase(props) {
18
+ var _a;
19
+ const { label, disabled, required, value, onFocus, onBlur,
20
+ // Pull `onChange` out of the props, but we're not directly using it. Do not want to keep it in `...others`
21
+ onChange: _onChange, errorMsg, helperText, inlineLabel = false, readOnly, format = "short", iconLeft = false, disabledDays, onEnter, defaultOpen, mode, ...others } = props;
18
22
  const inputRef = (0, react_1.useRef)(null);
19
23
  const inputWrapRef = (0, react_1.useRef)(null);
20
24
  const buttonRef = (0, react_1.useRef)(null);
@@ -22,19 +26,14 @@ function DateField(props) {
22
26
  // Local focus state to conditionally call onBlur when the date picker closes.
23
27
  // E.g. If the picker closes due to focus going back to the input field then don't call onBlur. Also used to avoid updating WIP values
24
28
  const [isFocused, setIsFocused] = (0, react_1.useState)(false);
25
- const dateFormat = getDateFormat(format);
26
- const [inputValue, setInputValue] = (0, react_1.useState)(value ? formatDate(value, dateFormat) : "");
27
- const tid = (0, utils_1.useTestIds)(props, (0, defaultTestId_1.defaultTestId)(label));
29
+ const dateFormat = (0, utils_1.getDateFormat)(format);
30
+ // The `wipValue` allows the "range" mode to set the value to `undefined`, even if the `onChange` response cannot be undefined.
31
+ // This makes working within the DateRangePicker much more user friendly.
32
+ const [wipValue, setWipValue] = (0, react_1.useState)(value);
33
+ const [inputValue, setInputValue] = (0, react_1.useState)((_a = (props.mode === "range" ? (0, utils_1.formatDateRange)(props.value, dateFormat) : (0, utils_1.formatDate)(props.value, dateFormat))) !== null && _a !== void 0 ? _a : "");
34
+ const tid = (0, utils_2.useTestIds)(props, (0, defaultTestId_1.defaultTestId)(label));
28
35
  const isDisabled = !!disabled;
29
36
  const isReadOnly = !!readOnly;
30
- // Handle case where the input value is updated from outside the component.
31
- (0, react_1.useEffect)(() => {
32
- // Avoid updating any WIP values.
33
- if (!isFocused) {
34
- setInputValue(value ? formatDate(value, dateFormat) : "");
35
- }
36
- // eslint-disable-next-line react-hooks/exhaustive-deps - Do not include `isFocused`, we don't want to update the internal `inputValue` back to `value` just because focus state changes
37
- }, [value, dateFormat]);
38
37
  const textFieldProps = {
39
38
  ...others,
40
39
  label,
@@ -47,7 +46,7 @@ function DateField(props) {
47
46
  onOpenChange: (isOpen) => {
48
47
  // Handles calling `onBlur` for the case where the user interacts with the overlay, removing focus from the input field, and eventually closes the overlay (whether clicking away, or selecting a date)
49
48
  if (!isOpen && !isFocused) {
50
- (0, utils_1.maybeCall)(onBlur);
49
+ (0, utils_2.maybeCall)(onBlur);
51
50
  }
52
51
  },
53
52
  isOpen: defaultOpen,
@@ -55,16 +54,20 @@ function DateField(props) {
55
54
  const { labelProps, inputProps } = (0, react_aria_1.useTextField)({
56
55
  ...textFieldProps,
57
56
  onFocus: () => {
57
+ var _a;
58
58
  // Open overlay on focus of the input.
59
59
  state.open();
60
60
  setIsFocused(true);
61
- (0, utils_1.maybeCall)(onFocus);
62
- if (value) {
61
+ (0, utils_2.maybeCall)(onFocus);
62
+ if (wipValue && dateFormat !== utils_1.dateFormats.short) {
63
63
  // When focused, change to use the "short" date format, as it is simpler to update by hand and parse.
64
- setInputValue(formatDate(value, dateFormats.short));
64
+ setInputValue((_a = (props.mode === "range"
65
+ ? (0, utils_1.formatDateRange)(props.value, utils_1.dateFormats.short)
66
+ : (0, utils_1.formatDate)(props.value, utils_1.dateFormats.short))) !== null && _a !== void 0 ? _a : "");
65
67
  }
66
68
  },
67
69
  onBlur: (e) => {
70
+ var _a, _b;
68
71
  setIsFocused(false);
69
72
  // If we are interacting any other part of `inputWrap` ref (such as the calendar button) return early as clicking anywhere within there will push focus to the input field.
70
73
  // Or if interacting with the DatePicker then also return early. The overlay will handle calling `onBlur` once it closes.
@@ -72,22 +75,23 @@ function DateField(props) {
72
75
  (overlayRef.current && overlayRef.current.contains(e.relatedTarget))) {
73
76
  return;
74
77
  }
75
- const parsedDate = parseDate(inputValue, dateFormats.short);
78
+ const parsedDate = mode === "range" ? (0, utils_1.parseDateRange)(inputValue, utils_1.dateFormats.short) : (0, utils_1.parseDate)(inputValue, utils_1.dateFormats.short);
76
79
  // If the user leaves the input and has an invalid date, reset to previous value.
77
- if (!parsedDate) {
78
- setInputValue(value ? formatDate(value, dateFormat) : "");
80
+ if (!isParsedDateValid(parsedDate)) {
81
+ setWipValue(value);
82
+ setInputValue((_a = (props.mode === "range" ? (0, utils_1.formatDateRange)(props.value, dateFormat) : (0, utils_1.formatDate)(props.value, dateFormat))) !== null && _a !== void 0 ? _a : "");
79
83
  }
80
- else if (dateFormat !== dateFormats.short) {
84
+ else if (dateFormat !== utils_1.dateFormats.short) {
81
85
  // Or if we need to reset the dateFormat back from `short` to whatever the user specified
82
- setInputValue(formatDate(parsedDate, dateFormat));
86
+ setInputValue((_b = (props.mode === "range" ? (0, utils_1.formatDateRange)(props.value, dateFormat) : (0, utils_1.formatDate)(props.value, dateFormat))) !== null && _b !== void 0 ? _b : "");
83
87
  }
84
88
  state.close();
85
- (0, utils_1.maybeCall)(onBlur);
89
+ (0, utils_2.maybeCall)(onBlur);
86
90
  },
87
91
  onKeyDown: (e) => {
88
92
  var _a;
89
93
  if (e.key === "Enter") {
90
- (0, utils_1.maybeCall)(onEnter);
94
+ (0, utils_2.maybeCall)(onEnter);
91
95
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
92
96
  }
93
97
  },
@@ -110,13 +114,38 @@ function DateField(props) {
110
114
  shouldUpdatePosition: true,
111
115
  offset: 4,
112
116
  });
117
+ // Handle case where the input value is updated from outside the component.
118
+ (0, react_1.useEffect)(() => {
119
+ var _a;
120
+ // Avoid updating any WIP values.
121
+ if (!isFocused && !state.isOpen) {
122
+ setWipValue(value);
123
+ setInputValue((_a = (props.mode === "range" ? (0, utils_1.formatDateRange)(props.value, dateFormat) : (0, utils_1.formatDate)(props.value, dateFormat))) !== null && _a !== void 0 ? _a : "");
124
+ }
125
+ // eslint-disable-next-line react-hooks/exhaustive-deps - Do not include `isFocused` or `state.isOpen`.
126
+ // We don't want to update the internal `wipValue` or `inputValue` back to `value` just because focus state changes or the overlay opens
127
+ }, [value, dateFormat]);
128
+ // Create a type safe `onChange` to handle both Single and Range date fields.
129
+ const onChange = (0, react_1.useCallback)((d) => {
130
+ setWipValue(d);
131
+ if (d && isParsedDateValid(d)) {
132
+ if (props.mode === "range" && (0, react_day_picker_1.isDateRange)(d)) {
133
+ props.onChange(d);
134
+ return;
135
+ }
136
+ if (props.mode === "single" && !(0, react_day_picker_1.isDateRange)(d)) {
137
+ props.onChange(d);
138
+ return;
139
+ }
140
+ }
141
+ }, [mode, props.onChange]);
113
142
  // If showing the short date format, "01/01/20", so set size to 8. If medium (Wed, Nov 23) use 10 characters (leaving out the `,` character in the count because it is so small)
114
143
  // Otherwise the long format can be `undefined`.
115
144
  // Setting the size attribute only impacts the fields when displayed in a container that doesn't allow the field to grow to its max width, such as in an inline container.
116
145
  // TODO: figure this out... seems weird to have now that we support multiple dates formats....
117
146
  // How do other applications handle this defined sizing? Appears they use hard coded widths depending on format, which is similar here (using `size` instead of css `width`).
118
147
  // But would also need to allow for the input to be `fullWidth`, which is basically also what we're accomplishing here... so maybe fine?
119
- const inputSize = format === "short" ? 8 : format === "medium" ? 10 : undefined;
148
+ const inputSize = mode !== "range" ? (format === "short" ? 8 : format === "medium" ? 10 : undefined) : undefined;
120
149
  const calendarButton = ((0, jsx_runtime_1.jsx)("button", Object.assign({ ref: buttonRef }, buttonProps, { disabled: isDisabled, css: Css_1.Css.if(isDisabled).cursorNotAllowed.$, tabIndex: -1 }, tid.calendarButton, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "calendar", color: Css_1.Palette.Gray700 }, void 0) }), void 0));
121
150
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, textFieldProps, { errorMsg: errorMsg, helperText: helperText, required: required, labelProps: labelProps, inputProps: { ...triggerProps, ...inputProps, size: inputSize }, inputRef: inputRef, inputWrapRef: inputWrapRef, inlineLabel: inlineLabel, onChange: (v) => {
122
151
  // hide the calendar if the user is manually entering the date
@@ -124,55 +153,23 @@ function DateField(props) {
124
153
  if (v) {
125
154
  setInputValue(v);
126
155
  // If changing the value directly (vs using the DatePicker), then we always use the short format
127
- const parsed = parseDate(v, dateFormats.short);
128
- if (parsed) {
129
- onChange(parsed);
130
- }
156
+ const parsed = mode === "range" ? (0, utils_1.parseDateRange)(v, utils_1.dateFormats.short) : (0, utils_1.parseDate)(v, utils_1.dateFormats.short);
157
+ onChange(parsed);
131
158
  }
132
- }, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly) }, others), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: inputWrapRef, popoverRef: overlayRef, positionProps: positionProps, onClose: state.close, isOpen: state.isOpen }, { children: (0, jsx_runtime_1.jsx)(DatePickerOverlay_1.DatePickerOverlay, Object.assign({ value: value, onSelect: (d) => {
133
- setInputValue(formatDate(d, dateFormat));
134
- onChange(d);
135
- }, state: state, disabledDays: disabledDays, overlayProps: overlayProps }, tid.datePicker), void 0) }), void 0))] }, void 0));
136
- }
137
- exports.DateField = DateField;
138
- function formatDate(date, format) {
139
- return (0, date_fns_1.format)(date, format);
140
- }
141
- function parseDate(str, format) {
142
- // Copy/pasted from react-day-picker so that typing "2/2/2" doesn't turn into "02/02/0002"
143
- const split = str.split("/");
144
- if (split.length !== 3) {
145
- return undefined;
146
- }
147
- // Wait for the year to be 2 chars
148
- if (split[2].length !== 2) {
149
- return undefined;
150
- }
151
- const month = parseInt(split[0], 10) - 1;
152
- const day = parseInt(split[1], 10);
153
- let year = parseInt(split[2], 10);
154
- // This is also ~verbatim copy/pasted from react-day-picker
155
- if (isNaN(year) ||
156
- String(year).length > 4 ||
157
- isNaN(month) ||
158
- isNaN(day) ||
159
- day <= 0 ||
160
- day > 31 ||
161
- month < 0 ||
162
- month >= 12) {
163
- return undefined;
164
- }
165
- const parsed = (0, date_fns_1.parse)(str, format, new Date());
166
- if (!(0, date_fns_1.isDate)(parsed)) {
167
- return undefined;
168
- }
169
- return parsed;
159
+ }, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly) }, others), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: inputWrapRef, popoverRef: overlayRef, positionProps: positionProps, onClose: state.close, isOpen: state.isOpen }, { children: (0, jsx_runtime_1.jsx)(DatePickerOverlay_1.DatePickerOverlay, Object.assign({ overlayProps: overlayProps }, { children: props.mode === "range" ? ((0, jsx_runtime_1.jsx)(internal_1.DateRangePicker, Object.assign({ range: wipValue, disabledDays: disabledDays, onSelect: (dr) => {
160
+ var _a;
161
+ // Note: Do not close date range picker on select to allow the user to select multiple dates at a time
162
+ setInputValue((_a = (0, utils_1.formatDateRange)(dr, utils_1.dateFormats.short)) !== null && _a !== void 0 ? _a : "");
163
+ onChange(dr);
164
+ } }, tid.datePicker), void 0)) : ((0, jsx_runtime_1.jsx)(internal_1.DatePicker, Object.assign({ value: wipValue, disabledDays: disabledDays, onSelect: (d) => {
165
+ var _a;
166
+ setInputValue((_a = (0, utils_1.formatDate)(d, utils_1.dateFormats.short)) !== null && _a !== void 0 ? _a : "");
167
+ onChange(d);
168
+ state.close();
169
+ } }, tid.datePicker), void 0)) }), void 0) }), void 0))] }, void 0));
170
170
  }
171
- const dateFormats = {
172
- short: "MM/dd/yy",
173
- medium: "EEE, MMM d",
174
- long: "EEEE LLLL d, uuuu",
175
- };
176
- function getDateFormat(format) {
177
- return format ? dateFormats[format] : dateFormats.short;
171
+ exports.DateFieldBase = DateFieldBase;
172
+ function isParsedDateValid(d) {
173
+ // Only consider a DateRange valid when both `from` and `to` values are valid dates
174
+ return d !== undefined && (!(0, react_day_picker_1.isDateRange)(d) || ((0, react_day_picker_1.isDateRange)(d) && (0, utils_1.isValidDate)(d.from) && (0, utils_1.isValidDate)(d.to)));
178
175
  }
@@ -0,0 +1,4 @@
1
+ import { DateRangeFieldBaseProps } from "./DateFieldBase";
2
+ export interface DateRangeFieldProps extends Omit<DateRangeFieldBaseProps, "mode"> {
3
+ }
4
+ export declare function DateRangeField(props: DateRangeFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DateRangeField = void 0;
4
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
+ const DateFieldBase_1 = require("./DateFieldBase");
6
+ function DateRangeField(props) {
7
+ return (0, jsx_runtime_1.jsx)(DateFieldBase_1.DateFieldBase, Object.assign({}, props, { mode: "range" }), void 0);
8
+ }
9
+ exports.DateRangeField = DateRangeField;
@@ -0,0 +1,5 @@
1
+ export { DateField } from "./DateField";
2
+ export type { DateFieldProps } from "./DateField";
3
+ export { DateRangeField } from "./DateRangeField";
4
+ export type { DateRangeFieldProps } from "./DateRangeField";
5
+ export * from "./utils";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.DateRangeField = exports.DateField = void 0;
14
+ var DateField_1 = require("./DateField");
15
+ Object.defineProperty(exports, "DateField", { enumerable: true, get: function () { return DateField_1.DateField; } });
16
+ var DateRangeField_1 = require("./DateRangeField");
17
+ Object.defineProperty(exports, "DateRangeField", { enumerable: true, get: function () { return DateRangeField_1.DateRangeField; } });
18
+ __exportStar(require("./utils"), exports);
@@ -0,0 +1,14 @@
1
+ import { DateRange } from "../../types";
2
+ export declare type DateFieldModeTuple = readonly ["range", DateRange] | readonly ["single", Date];
3
+ export declare type DateFieldMode = "single" | "range";
4
+ export declare const dateFormats: {
5
+ short: string;
6
+ medium: string;
7
+ long: string;
8
+ };
9
+ export declare function getDateFormat(format: keyof typeof dateFormats | undefined): string;
10
+ export declare function formatDate(date: Date | undefined, format: string): string;
11
+ export declare function formatDateRange(date: DateRange | undefined, format: string): string | undefined;
12
+ export declare function parseDate(str: string, format: string): Date | undefined;
13
+ export declare function parseDateRange(str: string, format: string): DateRange | undefined;
14
+ export declare function isValidDate(d: Date | undefined): boolean;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidDate = exports.parseDateRange = exports.parseDate = exports.formatDateRange = exports.formatDate = exports.getDateFormat = exports.dateFormats = void 0;
4
+ const date_fns_1 = require("date-fns");
5
+ exports.dateFormats = {
6
+ short: "MM/dd/yy",
7
+ medium: "EEE, MMM d",
8
+ long: "EEEE LLLL d, uuuu",
9
+ };
10
+ function getDateFormat(format) {
11
+ return format ? exports.dateFormats[format] : exports.dateFormats.short;
12
+ }
13
+ exports.getDateFormat = getDateFormat;
14
+ function formatDate(date, format) {
15
+ if (!date)
16
+ return "";
17
+ return (0, date_fns_1.format)(date, format);
18
+ }
19
+ exports.formatDate = formatDate;
20
+ function formatDateRange(date, format) {
21
+ if (!date)
22
+ return "";
23
+ const { from, to } = date;
24
+ const fromFormatted = from ? (0, date_fns_1.format)(from, format) : "";
25
+ const toFormatted = to ? (0, date_fns_1.format)(to, format) : "";
26
+ // return `undefined` if both dates are improperly formatted
27
+ return !fromFormatted && !toFormatted ? undefined : `${fromFormatted} - ${toFormatted}`;
28
+ }
29
+ exports.formatDateRange = formatDateRange;
30
+ function parseDate(str, format) {
31
+ return parseDateString(str, format);
32
+ }
33
+ exports.parseDate = parseDate;
34
+ function parseDateRange(str, format) {
35
+ const [from = "", to = ""] = str.split("-");
36
+ const fromDate = parseDateString(from.trim(), format);
37
+ const toDate = parseDateString(to.trim(), format);
38
+ // In the event the user mixes up the to/from dates then correct them.
39
+ if (toDate && fromDate && toDate < fromDate) {
40
+ return { from: toDate, to: fromDate };
41
+ }
42
+ // If both dates are undefined, return undefined rather than { from: undefined; to: undefined }
43
+ if (toDate === undefined && fromDate === undefined) {
44
+ return undefined;
45
+ }
46
+ return { from: fromDate, to: toDate };
47
+ }
48
+ exports.parseDateRange = parseDateRange;
49
+ function parseDateString(str, format) {
50
+ // Copy/pasted from react-day-picker so that typing "2/2/2" doesn't turn into "02/02/0002"
51
+ const split = str.split("/");
52
+ if (split.length !== 3) {
53
+ return undefined;
54
+ }
55
+ // Wait for the year to be 2 chars
56
+ if (split[2].length !== 2) {
57
+ return undefined;
58
+ }
59
+ const month = parseInt(split[0], 10) - 1;
60
+ const day = parseInt(split[1], 10);
61
+ let year = parseInt(split[2], 10);
62
+ // This is also ~verbatim copy/pasted from react-day-picker
63
+ if (isNaN(year) ||
64
+ String(year).length > 4 ||
65
+ isNaN(month) ||
66
+ isNaN(day) ||
67
+ day <= 0 ||
68
+ day > 31 ||
69
+ month < 0 ||
70
+ month >= 12) {
71
+ return undefined;
72
+ }
73
+ const parsed = (0, date_fns_1.parse)(str, format, new Date());
74
+ if (!isValidDate(parsed)) {
75
+ return undefined;
76
+ }
77
+ return parsed;
78
+ }
79
+ function isValidDate(d) {
80
+ return d !== undefined && (0, date_fns_1.isDate)(d) && d.toString() !== "Invalid Date";
81
+ }
82
+ exports.isValidDate = isValidDate;
@@ -117,6 +117,6 @@ function TextFieldBase(props) {
117
117
  // Reset focus to input element
118
118
  (_a = fieldRef.current) === null || _a === void 0 ? void 0 : _a.focus();
119
119
  } }, void 0)), !multiline && endAdornment && (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.df.aic.pl1.fs0.$ }, { children: endAdornment }), void 0)] }), void 0)),
120
- }), errorMsg && !compound && !errorInTooltip && ((0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, Object.assign({ id: errorMessageId, errorMsg: errorMsg }, tid.errorMsg), void 0)), helperText && !compound && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, Object.assign({ helperText: helperText }, tid.helperText), void 0)] }), void 0));
120
+ }), !compound && !inputProps.disabled && !inputProps.readOnly && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [errorMsg && !errorInTooltip && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, Object.assign({ id: errorMessageId, errorMsg: errorMsg }, tid.errorMsg), void 0), helperText && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, Object.assign({ helperText: helperText }, tid.helperText), void 0)] }, void 0))] }), void 0));
121
121
  }
122
122
  exports.TextFieldBase = TextFieldBase;
@@ -1,7 +1,7 @@
1
1
  export * from "./Checkbox";
2
2
  export * from "./CheckboxGroup";
3
3
  export * from "./ChipSelectField";
4
- export * from "./DateField";
4
+ export * from "./DateFields";
5
5
  export * from "./MultiSelectField";
6
6
  export * from "./NumberField";
7
7
  export type { NumberFieldProps } from "./NumberField";
@@ -14,7 +14,7 @@ exports.RadioGroupField = void 0;
14
14
  __exportStar(require("./Checkbox"), exports);
15
15
  __exportStar(require("./CheckboxGroup"), exports);
16
16
  __exportStar(require("./ChipSelectField"), exports);
17
- __exportStar(require("./DateField"), exports);
17
+ __exportStar(require("./DateFields"), exports);
18
18
  __exportStar(require("./MultiSelectField"), exports);
19
19
  __exportStar(require("./NumberField"), exports);
20
20
  var RadioGroupField_1 = require("./RadioGroupField");
package/dist/types.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { DateRange as _DateRange } from "react-day-picker";
2
+ export type { _DateRange as DateRange };
1
3
  export declare type HasIdAndName<V = string> = {
2
4
  id: V;
3
5
  name: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.141.1",
3
+ "version": "2.142.1",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -43,7 +43,7 @@
43
43
  "framer-motion": "^4.1.11",
44
44
  "memoize-one": "^5.2.1",
45
45
  "react-aria": "^3.14.1",
46
- "react-day-picker": "^8.0.6",
46
+ "react-day-picker": "^8.0.7",
47
47
  "react-popper": "^2.2.5",
48
48
  "react-router": "^5.2.0",
49
49
  "react-router-dom": "^5.2.0",