@homebound/beam 2.141.0 → 2.142.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Css.d.ts +3 -0
- package/dist/Css.js +2 -0
- package/dist/components/ButtonDatePicker.js +6 -2
- package/dist/components/NavLink.d.ts +1 -1
- package/dist/components/NavLink.js +3 -3
- package/dist/components/internal/DatePicker/DatePicker.css +5 -0
- package/dist/components/internal/DatePicker/DatePickerOverlay.d.ts +3 -6
- package/dist/components/internal/DatePicker/DatePickerOverlay.js +2 -6
- package/dist/components/internal/DatePicker/DateRangePicker.d.ts +10 -0
- package/dist/components/internal/DatePicker/DateRangePicker.js +23 -0
- package/dist/components/internal/DatePicker/Day.js +22 -7
- package/dist/components/internal/DatePicker/index.d.ts +1 -0
- package/dist/components/internal/DatePicker/index.js +1 -0
- package/dist/forms/BoundDateField.js +2 -2
- package/dist/forms/BoundDateRangeField.d.ts +10 -0
- package/dist/forms/BoundDateRangeField.js +27 -0
- package/dist/forms/formStateDomain.d.ts +3 -0
- package/dist/forms/formStateDomain.js +2 -1
- package/dist/forms/index.d.ts +1 -0
- package/dist/forms/index.js +1 -0
- package/dist/inputs/DateFields/DateField.d.ts +4 -0
- package/dist/inputs/DateFields/DateField.js +9 -0
- package/dist/inputs/{DateField.mock.d.ts → DateFields/DateField.mock.d.ts} +1 -1
- package/dist/inputs/{DateField.mock.js → DateFields/DateField.mock.js} +1 -1
- package/dist/inputs/{DateField.d.ts → DateFields/DateFieldBase.d.ts} +18 -11
- package/dist/inputs/{DateField.js → DateFields/DateFieldBase.js} +80 -83
- package/dist/inputs/DateFields/DateRangeField.d.ts +4 -0
- package/dist/inputs/DateFields/DateRangeField.js +9 -0
- package/dist/inputs/DateFields/index.d.ts +5 -0
- package/dist/inputs/DateFields/index.js +18 -0
- package/dist/inputs/DateFields/utils.d.ts +14 -0
- package/dist/inputs/DateFields/utils.js +82 -0
- package/dist/inputs/index.d.ts +1 -1
- package/dist/inputs/index.js +1 -1
- package/dist/types.d.ts +2 -0
- 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({},
|
|
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;
|
|
@@ -13,7 +13,7 @@ export interface NavLinkProps extends BeamFocusableProps {
|
|
|
13
13
|
}
|
|
14
14
|
declare type NavLinkVariant = "side" | "global";
|
|
15
15
|
export declare function NavLink(props: NavLinkProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
16
|
-
export declare function getNavLinkStyles(variant: NavLinkVariant, contrast
|
|
16
|
+
export declare function getNavLinkStyles(variant: NavLinkVariant, contrast: boolean): {
|
|
17
17
|
baseStyles: {};
|
|
18
18
|
hoverStyles: {};
|
|
19
19
|
disabledStyles: {};
|
|
@@ -10,7 +10,7 @@ const Css_1 = require("../Css");
|
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const Icon_1 = require("./Icon");
|
|
12
12
|
function NavLink(props) {
|
|
13
|
-
const { disabled: isDisabled, label, openInNew, ...otherProps } = props;
|
|
13
|
+
const { disabled: isDisabled, label, openInNew, contrast = false, ...otherProps } = props;
|
|
14
14
|
const ariaProps = { children: label, isDisabled, ...otherProps };
|
|
15
15
|
const { href, active = false, icon = false, variant } = ariaProps;
|
|
16
16
|
const ref = (0, react_1.useRef)();
|
|
@@ -19,7 +19,7 @@ function NavLink(props) {
|
|
|
19
19
|
const { type, ...otherButtonProps } = buttonProps;
|
|
20
20
|
const { hoverProps, isHovered } = (0, react_aria_1.useHover)({ isDisabled });
|
|
21
21
|
const { isFocusVisible, focusProps } = (0, react_aria_1.useFocusRing)(ariaProps);
|
|
22
|
-
const { baseStyles, activeStyles, focusRingStyles, hoverStyles, disabledStyles, pressedStyles } = (0, react_1.useMemo)(() => getNavLinkStyles(variant), [variant]);
|
|
22
|
+
const { baseStyles, activeStyles, focusRingStyles, hoverStyles, disabledStyles, pressedStyles } = (0, react_1.useMemo)(() => getNavLinkStyles(variant, contrast), [variant, contrast]);
|
|
23
23
|
const external = (0, utils_1.isAbsoluteUrl)(href) || openInNew;
|
|
24
24
|
const linkAttributes = {
|
|
25
25
|
className: components_1.navLink,
|
|
@@ -43,7 +43,7 @@ function NavLink(props) {
|
|
|
43
43
|
return external ? ((0, jsx_runtime_1.jsx)("a", Object.assign({ href: href }, (0, react_aria_1.mergeProps)(otherButtonProps, focusProps, hoverProps), linkAttributes, { children: linkContent }), void 0)) : ((0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({ to: href }, (0, react_aria_1.mergeProps)(otherButtonProps, focusProps, hoverProps), linkAttributes, { children: linkContent }), void 0));
|
|
44
44
|
}
|
|
45
45
|
exports.NavLink = NavLink;
|
|
46
|
-
function getNavLinkStyles(variant, contrast
|
|
46
|
+
function getNavLinkStyles(variant, contrast) {
|
|
47
47
|
return navLinkVariantStyles(contrast)[variant];
|
|
48
48
|
}
|
|
49
49
|
exports.getNavLinkStyles = getNavLinkStyles;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { HTMLAttributes } from "react";
|
|
2
|
-
|
|
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,
|
|
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,
|
|
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:
|
|
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.
|
|
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
|
|
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.$;
|
|
@@ -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" };
|
package/dist/forms/index.d.ts
CHANGED
|
@@ -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";
|
package/dist/forms/index.js
CHANGED
|
@@ -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,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;
|
|
@@ -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("
|
|
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 {
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
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.
|
|
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("
|
|
10
|
-
const internal_1 = require("
|
|
11
|
-
const DatePickerOverlay_1 = require("
|
|
12
|
-
const Css_1 = require("
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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,
|
|
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,
|
|
62
|
-
if (
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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,
|
|
89
|
+
(0, utils_2.maybeCall)(onBlur);
|
|
86
90
|
},
|
|
87
91
|
onKeyDown: (e) => {
|
|
88
92
|
var _a;
|
|
89
93
|
if (e.key === "Enter") {
|
|
90
|
-
(0,
|
|
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
|
-
|
|
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({
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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,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,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;
|
package/dist/inputs/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export * from "./Checkbox";
|
|
2
2
|
export * from "./CheckboxGroup";
|
|
3
3
|
export * from "./ChipSelectField";
|
|
4
|
-
export * from "./
|
|
4
|
+
export * from "./DateFields";
|
|
5
5
|
export * from "./MultiSelectField";
|
|
6
6
|
export * from "./NumberField";
|
|
7
7
|
export type { NumberFieldProps } from "./NumberField";
|
package/dist/inputs/index.js
CHANGED
|
@@ -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("./
|
|
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homebound/beam",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.142.0",
|
|
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.
|
|
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",
|