@homebound/beam 2.102.6 → 2.103.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Button.d.ts +3 -1
- package/dist/components/Button.js +3 -3
- package/dist/components/ButtonDatePicker.d.ts +7 -0
- package/dist/components/ButtonDatePicker.js +20 -0
- package/dist/components/ButtonMenu.d.ts +2 -14
- package/dist/components/ButtonMenu.js +5 -37
- package/dist/components/Table/useSortState.js +5 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/{inputs/DateField.css → components/internal/DatePicker.css} +0 -0
- package/dist/components/internal/DatePicker.d.ts +8 -0
- package/dist/{inputs/internal/DatePickerOverlay.js → components/internal/DatePicker.js} +11 -18
- package/dist/components/internal/DatePickerOverlay.d.ts +9 -0
- package/dist/components/internal/DatePickerOverlay.js +14 -0
- package/dist/components/internal/Menu.d.ts +3 -5
- package/dist/components/internal/Menu.js +18 -4
- package/dist/components/internal/OverlayTrigger.d.ts +29 -0
- package/dist/components/internal/OverlayTrigger.js +32 -0
- package/dist/inputs/DateField.d.ts +0 -1
- package/dist/inputs/DateField.js +4 -4
- package/package.json +1 -1
- package/dist/inputs/internal/DatePickerOverlay.d.ts +0 -12
|
@@ -6,7 +6,7 @@ export interface ButtonProps extends BeamButtonProps, BeamFocusableProps {
|
|
|
6
6
|
label: string;
|
|
7
7
|
variant?: ButtonVariant;
|
|
8
8
|
size?: ButtonSize;
|
|
9
|
-
icon?: IconProps["icon"];
|
|
9
|
+
icon?: IconProps["icon"] | null;
|
|
10
10
|
/** Displays contents after the Button's label. Will be ignored for Buttons rendered as a link with an absolute URL */
|
|
11
11
|
endAdornment?: ReactNode;
|
|
12
12
|
/** HTML attributes to apply to the button element when it is being used to trigger a menu. */
|
|
@@ -14,6 +14,8 @@ export interface ButtonProps extends BeamButtonProps, BeamFocusableProps {
|
|
|
14
14
|
buttonRef?: RefObject<HTMLElement>;
|
|
15
15
|
/** Allow for setting "submit" | "button" | "reset" on button element */
|
|
16
16
|
type?: ButtonHTMLAttributes<HTMLButtonElement>["type"];
|
|
17
|
+
/** Denotes if this button is used to download a resource. Uses the anchor tag with the `download` attribute */
|
|
18
|
+
download?: boolean;
|
|
17
19
|
}
|
|
18
20
|
export declare function Button(props: ButtonProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
19
21
|
declare type ButtonSize = "sm" | "md" | "lg";
|
|
@@ -10,10 +10,10 @@ const Css_1 = require("../Css");
|
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const useTestIds_1 = require("../utils/useTestIds");
|
|
12
12
|
function Button(props) {
|
|
13
|
-
const { onClick: onPress, disabled, endAdornment, menuTriggerProps, tooltip, openInNew, ...otherProps } = props;
|
|
13
|
+
const { onClick: onPress, disabled, endAdornment, menuTriggerProps, tooltip, openInNew, download, ...otherProps } = props;
|
|
14
14
|
const isDisabled = !!disabled;
|
|
15
15
|
const ariaProps = { onPress, isDisabled, ...otherProps, ...menuTriggerProps };
|
|
16
|
-
const { label, icon, variant = "primary", size = "sm", buttonRef } = ariaProps;
|
|
16
|
+
const { label, icon = download ? "download" : undefined, variant = "primary", size = "sm", buttonRef } = ariaProps;
|
|
17
17
|
const ref = buttonRef || (0, react_1.useRef)(null);
|
|
18
18
|
const tid = (0, useTestIds_1.useTestIds)(props, label);
|
|
19
19
|
const { buttonProps, isPressed } = (0, react_aria_1.useButton)({
|
|
@@ -41,7 +41,7 @@ function Button(props) {
|
|
|
41
41
|
},
|
|
42
42
|
...tid,
|
|
43
43
|
};
|
|
44
|
-
const button = typeof onPress === "string" ? ((0, utils_1.isAbsoluteUrl)(onPress) || openInNew ? ((0, jsx_runtime_1.jsxs)("a", Object.assign({}, buttonAttrs, { href: onPress, className: components_1.navLink, target: "_blank", rel: "noreferrer noopener" }, { children: [buttonContent, (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.ml1.$ }, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "linkExternal" }, void 0) }), void 0)] }), void 0)) : ((0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({}, buttonAttrs, { to: onPress, className: components_1.navLink }, { children: buttonContent }), void 0))) : ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonAttrs, { children: buttonContent }), void 0));
|
|
44
|
+
const button = typeof onPress === "string" ? ((0, utils_1.isAbsoluteUrl)(onPress) || openInNew || download ? ((0, jsx_runtime_1.jsxs)("a", Object.assign({}, buttonAttrs, { href: onPress, className: components_1.navLink }, (download ? { download: "" } : { target: "_blank", rel: "noreferrer noopener" }), { children: [buttonContent, !download && ((0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.ml1.$ }, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "linkExternal" }, void 0) }), void 0))] }), void 0)) : ((0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({}, buttonAttrs, { to: onPress, className: components_1.navLink }, { children: buttonContent }), void 0))) : ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonAttrs, { children: buttonContent }), void 0));
|
|
45
45
|
// If we're disabled b/c of a non-boolean ReactNode, or the caller specified tooltip text, then show it in a tooltip
|
|
46
46
|
return (0, components_1.maybeTooltip)({
|
|
47
47
|
title: (0, components_1.resolveTooltip)(disabled, tooltip),
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DatePickerProps } from "./internal/DatePicker";
|
|
2
|
+
import { OverlayTriggerProps } from "./internal/OverlayTrigger";
|
|
3
|
+
interface ButtonDatePickerProps extends DatePickerProps, Pick<OverlayTriggerProps, "trigger" | "placement" | "disabled" | "tooltip"> {
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function ButtonDatePicker(props: ButtonDatePickerProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ButtonDatePicker = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_aria_1 = require("react-aria");
|
|
7
|
+
const react_stately_1 = require("react-stately");
|
|
8
|
+
const DatePickerOverlay_1 = require("./internal/DatePickerOverlay");
|
|
9
|
+
const OverlayTrigger_1 = require("./internal/OverlayTrigger");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
12
|
+
function ButtonDatePicker(props) {
|
|
13
|
+
const { defaultOpen, disabled, trigger } = props;
|
|
14
|
+
const state = (0, react_stately_1.useMenuTriggerState)({ isOpen: defaultOpen });
|
|
15
|
+
const buttonRef = (0, react_1.useRef)(null);
|
|
16
|
+
const { menuTriggerProps, menuProps } = (0, react_aria_1.useMenuTrigger)({ isDisabled: !!disabled }, state, buttonRef);
|
|
17
|
+
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
|
+
}
|
|
20
|
+
exports.ButtonDatePicker = ButtonDatePicker;
|
|
@@ -1,22 +1,10 @@
|
|
|
1
|
-
import { ReactNode } from "react";
|
|
2
|
-
import { ButtonProps } from "./Button";
|
|
3
1
|
import { IconProps } from "./Icon";
|
|
4
|
-
import {
|
|
2
|
+
import { OverlayTriggerProps } from "./internal/OverlayTrigger";
|
|
5
3
|
import { Callback } from "../types";
|
|
6
|
-
interface
|
|
7
|
-
}
|
|
8
|
-
interface IconButtonTriggerProps extends Pick<IconButtonProps, "icon" | "color"> {
|
|
9
|
-
}
|
|
10
|
-
interface ButtonMenuProps {
|
|
11
|
-
trigger: TextButtonTriggerProps | IconButtonTriggerProps;
|
|
4
|
+
interface ButtonMenuProps extends Pick<OverlayTriggerProps, "trigger" | "placement" | "disabled" | "tooltip"> {
|
|
12
5
|
items: MenuItem[];
|
|
13
6
|
persistentItems?: MenuItem[];
|
|
14
|
-
placement?: "left" | "right";
|
|
15
7
|
defaultOpen?: boolean;
|
|
16
|
-
/** Whether the Button is disabled. If a ReactNode, it's treated as a "disabled reason" that's shown in a tooltip. */
|
|
17
|
-
disabled?: boolean | ReactNode;
|
|
18
|
-
/** Text to be shown via a tooltip when the user hovers over the button */
|
|
19
|
-
tooltip?: ReactNode;
|
|
20
8
|
}
|
|
21
9
|
export declare function ButtonMenu(props: ButtonMenuProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
22
10
|
declare type MenuItemBase = {
|
|
@@ -2,51 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ButtonMenu = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
-
const change_case_1 = require("change-case");
|
|
6
5
|
const react_1 = require("react");
|
|
7
6
|
const react_aria_1 = require("react-aria");
|
|
8
7
|
const react_stately_1 = require("react-stately");
|
|
9
|
-
const Button_1 = require("./Button");
|
|
10
|
-
const Icon_1 = require("./Icon");
|
|
11
|
-
const IconButton_1 = require("./IconButton");
|
|
12
|
-
const internal_1 = require("./internal");
|
|
13
8
|
const Menu_1 = require("./internal/Menu");
|
|
14
|
-
const
|
|
9
|
+
const OverlayTrigger_1 = require("./internal/OverlayTrigger");
|
|
15
10
|
const utils_1 = require("../utils");
|
|
16
11
|
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
17
12
|
function ButtonMenu(props) {
|
|
18
|
-
const {
|
|
13
|
+
const { defaultOpen, disabled, items, persistentItems, trigger } = props;
|
|
19
14
|
const state = (0, react_stately_1.useMenuTriggerState)({ isOpen: defaultOpen });
|
|
20
15
|
const buttonRef = (0, react_1.useRef)(null);
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
targetRef: buttonRef,
|
|
25
|
-
overlayRef: popoverRef,
|
|
26
|
-
shouldFlip: true,
|
|
27
|
-
isOpen: state.isOpen,
|
|
28
|
-
onClose: state.close,
|
|
29
|
-
placement: (placement ? `bottom ${placement}` : "bottom left"),
|
|
30
|
-
});
|
|
31
|
-
const tid = (0, utils_1.useTestIds)(props, isTextButton(trigger) ? (0, defaultTestId_1.defaultTestId)(trigger.label) : trigger.icon);
|
|
32
|
-
// Build out the Menu's Tree data to include the Persistent Action, if any. This is a collection of Nodes that is used
|
|
33
|
-
// by React-Aria to keep track of item states such as focus, and provide hooks for calling those actions.
|
|
34
|
-
const tree = (0, react_stately_1.useTreeData)({
|
|
35
|
-
initialItems: [items, persistentItems ? persistentItems : []].map((i, idx) => ({ label: idx === 0 ? "items" : "persistent", items: i })),
|
|
36
|
-
getKey: (item) => (0, change_case_1.camelCase)(item.label),
|
|
37
|
-
getChildren: (item) => { var _a; return (_a = item.items) !== null && _a !== void 0 ? _a : []; },
|
|
38
|
-
});
|
|
39
|
-
// Bulk updates of MenuItems below. If we find this to be of sluggish performance, then we can change to be more surgical in our updating.
|
|
40
|
-
// If our list of items change, update the "items" menu section. (key is based on label in `getKey` above)
|
|
41
|
-
(0, react_1.useEffect)(() => tree.update("items", { label: "items", items }), [items]);
|
|
42
|
-
// NOTE: Not updating persistentItems at the moment as there seems to be a bug with this. Only updates one set of items at a time, will follow up later.
|
|
43
|
-
// If our list of persistentItems change, update the "persistent" menu section.
|
|
44
|
-
// useEffect(() => {
|
|
45
|
-
// tree.update("persistent", { label: "persistent", items: persistentItems || [] } as MenuSection);
|
|
46
|
-
// }, [persistentItems]);
|
|
47
|
-
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.relative.dib.$ }, { children: [isTextButton(trigger) ? ((0, jsx_runtime_1.jsx)(Button_1.Button, Object.assign({ variant: "secondary" }, trigger, { menuTriggerProps: menuTriggerProps, buttonRef: buttonRef, endAdornment: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { icon: state.isOpen ? "chevronUp" : "chevronDown" }, void 0), disabled: disabled, tooltip: tooltip }, tid), void 0)) : ((0, jsx_runtime_1.jsx)(IconButton_1.IconButton, Object.assign({}, trigger, { menuTriggerProps: menuTriggerProps, buttonRef: buttonRef }, tid), void 0)), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: buttonRef, popoverRef: popoverRef, positionProps: positionProps, onClose: () => state.close(), isOpen: state.isOpen }, { children: (0, jsx_runtime_1.jsx)(Menu_1.Menu, Object.assign({ ariaMenuProps: ariaMenuProps, items: tree.items, onClose: () => state.close() }, tid, { children: (s) => ((0, jsx_runtime_1.jsx)(react_stately_1.Section, Object.assign({ title: s.label, items: s.items }, { children: (item) => (0, jsx_runtime_1.jsx)(react_stately_1.Item, { children: item.label }, item.label.replace(/"/g, "")) }), s.label.replace(/"/g, ""))) }), void 0) }), void 0))] }), void 0));
|
|
16
|
+
const { menuTriggerProps, menuProps } = (0, react_aria_1.useMenuTrigger)({ isDisabled: !!disabled }, state, buttonRef);
|
|
17
|
+
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)(Menu_1.Menu, Object.assign({ ariaMenuProps: menuProps, onClose: () => state.close(), items: items, persistentItems: persistentItems }, tid), void 0) }), void 0));
|
|
48
19
|
}
|
|
49
20
|
exports.ButtonMenu = ButtonMenu;
|
|
50
|
-
function isTextButton(trigger) {
|
|
51
|
-
return trigger && typeof trigger === "object" && "label" in trigger;
|
|
52
|
-
}
|
|
@@ -51,6 +51,11 @@ function deriveSortState(currentSortState, clickedKey, initialSortState) {
|
|
|
51
51
|
if (!currentSortState || clickedKey !== currentKey) {
|
|
52
52
|
return [clickedKey, GridTable_1.ASC];
|
|
53
53
|
}
|
|
54
|
+
// If there is an `initialSortState` and we're clicking on that same key, then flip the sort.
|
|
55
|
+
// Handles cases where the initial sort is DESC so that we can allow for DESC to ASC sorting.
|
|
56
|
+
if (initialSortState && initialSortState[0] === clickedKey) {
|
|
57
|
+
return [clickedKey, currentDirection === GridTable_1.ASC ? GridTable_1.DESC : GridTable_1.ASC];
|
|
58
|
+
}
|
|
54
59
|
// Otherwise when clicking the current column, toggle through sort states
|
|
55
60
|
if (currentDirection === GridTable_1.ASC) {
|
|
56
61
|
// if ASC -> go to desc
|
package/dist/components/index.js
CHANGED
|
@@ -20,6 +20,7 @@ __exportStar(require("./Alert"), exports);
|
|
|
20
20
|
var BeamContext_1 = require("./BeamContext");
|
|
21
21
|
Object.defineProperty(exports, "BeamProvider", { enumerable: true, get: function () { return BeamContext_1.BeamProvider; } });
|
|
22
22
|
__exportStar(require("./Button"), exports);
|
|
23
|
+
__exportStar(require("./ButtonDatePicker"), exports);
|
|
23
24
|
__exportStar(require("./ButtonGroup"), exports);
|
|
24
25
|
__exportStar(require("./ButtonMenu"), exports);
|
|
25
26
|
__exportStar(require("./Copy"), exports);
|
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Modifier } from "react-day-picker";
|
|
2
|
+
import "./DatePicker.css";
|
|
3
|
+
export interface DatePickerProps {
|
|
4
|
+
value?: Date;
|
|
5
|
+
onSelect: (value: Date) => void;
|
|
6
|
+
disabledDays?: Modifier;
|
|
7
|
+
}
|
|
8
|
+
export declare function DatePicker(props: DatePickerProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -3,24 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.DatePicker = void 0;
|
|
7
7
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
8
8
|
const react_day_picker_1 = __importDefault(require("react-day-picker"));
|
|
9
|
-
const
|
|
9
|
+
const index_1 = require("../index");
|
|
10
10
|
const Css_1 = require("../../Css");
|
|
11
11
|
const utils_1 = require("../../utils");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const { value,
|
|
15
|
-
// We define some spacing between the Calendar overlay and the trigger element, and depending on where the overlay renders (above or below) we need to adjust the spacing.
|
|
16
|
-
// We can determine if the position was flipped based on what style is defined, `top` (for positioned below the trigger), and `bottom` (for above the trigger).
|
|
17
|
-
// The above assumption regarding `top` and `bottom` is true as long as we use `bottom` as our default `OverlayPosition.placement` (set in DateField).
|
|
18
|
-
// The reason the placement may not be on bottom even though we set `bottom` is because also set `shouldFlip: true`
|
|
19
|
-
const isPositionedAbove = !((_a = positionProps.style) === null || _a === void 0 ? void 0 : _a.top);
|
|
12
|
+
require("./DatePicker.css");
|
|
13
|
+
function DatePicker(props) {
|
|
14
|
+
const { value, onSelect, disabledDays } = props;
|
|
20
15
|
const tid = (0, utils_1.useTestIds)(props, "datePicker");
|
|
21
16
|
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: {
|
|
22
|
-
...Css_1.Css.bgWhite.xs
|
|
23
|
-
...(isPositionedAbove ? Css_1.Css.mbPx(4).$ : Css_1.Css.mtPx(4).$),
|
|
17
|
+
...Css_1.Css.dib.bgWhite.xs.$,
|
|
24
18
|
// The S / M / T / W ... heading
|
|
25
19
|
"& .DayPicker-Weekday": Css_1.Css.pPx(8).xs.gray400.important.$,
|
|
26
20
|
// Un-collapse the borders so we can hover each cell
|
|
@@ -35,23 +29,22 @@ function DatePickerOverlay(props) {
|
|
|
35
29
|
"& .DayPicker-Day:active": Css_1.Css.bgGray400.$,
|
|
36
30
|
// Make the month title, i.e. "May 2021", match figma; pyPx nudge matches the NavbarElement nudging
|
|
37
31
|
"& .DayPicker-Caption > div": Css_1.Css.base.pyPx(2).$,
|
|
38
|
-
// For days that are disabled via `disabledDays`,
|
|
32
|
+
// For days that are disabled via `disabledDays`,
|
|
39
33
|
"& .DayPicker-Day--disabled": Css_1.Css.cursorNotAllowed.$,
|
|
40
34
|
// Override `.DayPicker-Day:active` background when the day is disabled
|
|
41
35
|
"& .DayPicker-Day--disabled:active": Css_1.Css.bgWhite.$,
|
|
42
36
|
} }, tid, { children: (0, jsx_runtime_1.jsx)(react_day_picker_1.default, { navbarElement: NavbarElement, weekdayElement: Weekday, selectedDays: [value], initialMonth: value !== null && value !== void 0 ? value : new Date(), onDayClick: (day, modifiers) => {
|
|
43
37
|
if (modifiers.disabled)
|
|
44
38
|
return;
|
|
45
|
-
// Set the day value
|
|
46
|
-
|
|
47
|
-
state.close();
|
|
39
|
+
// Set the day value
|
|
40
|
+
onSelect(day);
|
|
48
41
|
}, disabledDays: disabledDays }, void 0) }), void 0));
|
|
49
42
|
}
|
|
50
|
-
exports.
|
|
43
|
+
exports.DatePicker = DatePicker;
|
|
51
44
|
/** Customize the prev/next button to be our SVG icons. */
|
|
52
45
|
function NavbarElement(props) {
|
|
53
46
|
const { showPreviousButton, showNextButton, onPreviousClick, onNextClick, classNames } = props;
|
|
54
|
-
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: classNames.navBar }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.absolute.top(2).right(6.5).$ }, { children: (0, jsx_runtime_1.jsx)(
|
|
47
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: classNames.navBar }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.absolute.top(2).right(6.5).$ }, { children: (0, jsx_runtime_1.jsx)(index_1.IconButton, { color: Css_1.Palette.Gray700, disabled: !showPreviousButton, icon: "chevronLeft", onClick: () => onPreviousClick() }, void 0) }), void 0), (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.absolute.top(2).right(3).$ }, { children: (0, jsx_runtime_1.jsx)(index_1.IconButton, { color: Css_1.Palette.Gray700, disabled: !showNextButton, icon: "chevronRight", onClick: () => onNextClick() }, void 0) }), void 0)] }), void 0));
|
|
55
48
|
}
|
|
56
49
|
/** Customize the weekday names to be only the first letter. */
|
|
57
50
|
function Weekday({ weekday, className, localeUtils, locale }) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HTMLAttributes } from "react";
|
|
2
|
+
import { OverlayTriggerState } from "react-stately";
|
|
3
|
+
import { DatePickerProps } from "./DatePicker";
|
|
4
|
+
interface DatePickerOverlayProps extends DatePickerProps {
|
|
5
|
+
overlayProps: HTMLAttributes<HTMLElement>;
|
|
6
|
+
state: OverlayTriggerState;
|
|
7
|
+
}
|
|
8
|
+
export declare function DatePickerOverlay({ overlayProps, state, ...datePickerProps }: DatePickerOverlayProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatePickerOverlay = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const DatePicker_1 = require("./DatePicker");
|
|
6
|
+
const Css_1 = require("../../Css");
|
|
7
|
+
// Small wrapper around DatePicker to provide necessary styling and state handling when displayed as an overlay.
|
|
8
|
+
function DatePickerOverlay({ overlayProps, state, ...datePickerProps }) {
|
|
9
|
+
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.br4.bshModal.$ }, overlayProps, { children: (0, jsx_runtime_1.jsx)(DatePicker_1.DatePicker, Object.assign({}, datePickerProps, { onSelect: (d) => {
|
|
10
|
+
datePickerProps.onSelect(d);
|
|
11
|
+
state.close();
|
|
12
|
+
} }), void 0) }), void 0));
|
|
13
|
+
}
|
|
14
|
+
exports.DatePickerOverlay = DatePickerOverlay;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import type { TreeNode } from "@react-stately/data";
|
|
2
|
-
import type { CollectionChildren } from "@react-types/shared";
|
|
3
1
|
import { HTMLAttributes, PropsWithChildren } from "react";
|
|
4
|
-
import {
|
|
2
|
+
import { MenuItem } from "..";
|
|
5
3
|
import { Callback } from "../../types";
|
|
6
4
|
interface MenuProps<T> {
|
|
7
5
|
ariaMenuProps: HTMLAttributes<HTMLElement>;
|
|
8
|
-
children: CollectionChildren<MenuSection>;
|
|
9
|
-
items: TreeNode<MenuSection>[];
|
|
10
6
|
onClose: Callback;
|
|
7
|
+
items: MenuItem[];
|
|
8
|
+
persistentItems?: MenuItem[];
|
|
11
9
|
}
|
|
12
10
|
export declare function Menu<T>(props: PropsWithChildren<MenuProps<T>>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
13
11
|
export {};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Menu = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const change_case_1 = require("change-case");
|
|
5
6
|
const react_1 = require("react");
|
|
6
7
|
const react_aria_1 = require("react-aria");
|
|
7
8
|
const react_stately_1 = require("react-stately");
|
|
@@ -9,15 +10,28 @@ const MenuSection_1 = require("./MenuSection");
|
|
|
9
10
|
const Css_1 = require("../../Css");
|
|
10
11
|
const utils_1 = require("../../utils");
|
|
11
12
|
function Menu(props) {
|
|
12
|
-
const {
|
|
13
|
-
|
|
13
|
+
const { ariaMenuProps, items, persistentItems, onClose } = props;
|
|
14
|
+
// Build out the Menu's Tree data to include the Persistent Action, if any. This is a collection of Nodes that is used
|
|
15
|
+
// by React-Aria to keep track of item states such as focus, and provide hooks for calling those actions.
|
|
16
|
+
const tree = (0, react_stately_1.useTreeData)({
|
|
17
|
+
initialItems: [items, persistentItems ? persistentItems : []].map((i, idx) => ({ label: idx === 0 ? "items" : "persistent", items: i })),
|
|
18
|
+
getKey: (item) => (0, change_case_1.camelCase)(item.label),
|
|
19
|
+
getChildren: (item) => { var _a; return (_a = item.items) !== null && _a !== void 0 ? _a : []; },
|
|
20
|
+
});
|
|
21
|
+
const menuChildren = (0, react_1.useMemo)(() => {
|
|
22
|
+
return tree.items.map(({ value: s }) => ((0, jsx_runtime_1.jsx)(react_stately_1.Section, Object.assign({ title: s.label, items: s.items }, { children: (item) => (0, jsx_runtime_1.jsx)(react_stately_1.Item, { children: item.label }, item.label.replace(/"/g, "")) }), s.label.replace(/"/g, ""))));
|
|
23
|
+
}, [tree]);
|
|
24
|
+
const state = (0, react_stately_1.useTreeState)({ children: menuChildren, items: tree.items.map((i) => i.value), selectionMode: "none" });
|
|
14
25
|
const menuRef = (0, react_1.useRef)(null);
|
|
15
|
-
const { menuProps } = (0, react_aria_1.useMenu)({ ...ariaMenuProps, children, autoFocus: true }, state, menuRef);
|
|
26
|
+
const { menuProps } = (0, react_aria_1.useMenu)({ ...ariaMenuProps, children: menuChildren, autoFocus: true }, state, menuRef);
|
|
16
27
|
const tid = (0, utils_1.useTestIds)(props);
|
|
28
|
+
// Bulk updates of MenuItems below. If we find this to be of sluggish performance, then we can change to be more surgical in our updating.
|
|
29
|
+
// If our list of items change, update the "items" menu section. (key is based on label in `getKey` above)
|
|
30
|
+
(0, react_1.useEffect)(() => tree.update("items", { label: "items", items }), [items]);
|
|
17
31
|
return ((0, jsx_runtime_1.jsx)(react_aria_1.FocusScope, Object.assign({ restoreFocus: true }, { children: (0, jsx_runtime_1.jsx)("ul", Object.assign({ css: {
|
|
18
32
|
// Using `max-height: inherit` allows us to take advantage of the height set on the overlay container, which updates based on the available space for the overlay within the viewport
|
|
19
33
|
...Css_1.Css.df.fdc.myPx(4).bgWhite.outline0.br4.bshBasic.listReset.maxh("inherit").overflowAuto.$,
|
|
20
34
|
"&:hover, &:focus": Css_1.Css.bshHover.$,
|
|
21
|
-
} }, menuProps, { ref: menuRef }, tid.menu, { children: [...state.collection].map((item) => ((0, jsx_runtime_1.jsx)(MenuSection_1.MenuSectionImpl, Object.assign({ section: item, state: state, onClose:
|
|
35
|
+
} }, menuProps, { ref: menuRef }, tid.menu, { children: [...state.collection].map((item) => ((0, jsx_runtime_1.jsx)(MenuSection_1.MenuSectionImpl, Object.assign({ section: item, state: state, onClose: onClose }, tid), item.key))) }), void 0) }), void 0));
|
|
22
36
|
}
|
|
23
37
|
exports.Menu = Menu;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AriaButtonProps } from "@react-types/button";
|
|
2
|
+
import { MutableRefObject, ReactElement, ReactNode } from "react";
|
|
3
|
+
import { MenuTriggerState } from "react-stately";
|
|
4
|
+
import { ButtonProps } from "../Button";
|
|
5
|
+
import { IconButtonProps } from "../IconButton";
|
|
6
|
+
interface TextButtonTriggerProps extends Pick<ButtonProps, "label" | "variant" | "size" | "icon"> {
|
|
7
|
+
}
|
|
8
|
+
interface IconButtonTriggerProps extends Pick<IconButtonProps, "icon" | "color"> {
|
|
9
|
+
}
|
|
10
|
+
export interface OverlayTriggerProps {
|
|
11
|
+
trigger: TextButtonTriggerProps | IconButtonTriggerProps;
|
|
12
|
+
/** Defaults to "left" */
|
|
13
|
+
placement?: "left" | "right";
|
|
14
|
+
/** Whether the Button is disabled. If a ReactNode, it's treated as a "disabled reason" that's shown in a tooltip. */
|
|
15
|
+
disabled?: boolean | ReactNode;
|
|
16
|
+
/** Text to be shown via a tooltip when the user hovers over the button */
|
|
17
|
+
tooltip?: ReactNode;
|
|
18
|
+
/** The component to be shown within the overlay */
|
|
19
|
+
children: ReactElement;
|
|
20
|
+
/** Props returned by the useMenuTrigger hook to be passed to the button element */
|
|
21
|
+
menuTriggerProps: AriaButtonProps;
|
|
22
|
+
/** Ref for the button element */
|
|
23
|
+
buttonRef: MutableRefObject<HTMLButtonElement | null>;
|
|
24
|
+
/** Result of the useMenuTriggerState hook */
|
|
25
|
+
state: MenuTriggerState;
|
|
26
|
+
}
|
|
27
|
+
export declare function OverlayTrigger(props: OverlayTriggerProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function isTextButton(trigger: TextButtonTriggerProps | IconButtonTriggerProps): trigger is TextButtonTriggerProps;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isTextButton = exports.OverlayTrigger = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_aria_1 = require("react-aria");
|
|
7
|
+
const Button_1 = require("../Button");
|
|
8
|
+
const Icon_1 = require("../Icon");
|
|
9
|
+
const IconButton_1 = require("../IconButton");
|
|
10
|
+
const internal_1 = require("./");
|
|
11
|
+
const Css_1 = require("../../Css");
|
|
12
|
+
const utils_1 = require("../../utils");
|
|
13
|
+
const defaultTestId_1 = require("../../utils/defaultTestId");
|
|
14
|
+
function OverlayTrigger(props) {
|
|
15
|
+
const { trigger, buttonRef, menuTriggerProps, placement, state, disabled, tooltip, children } = props;
|
|
16
|
+
const popoverRef = (0, react_1.useRef)(null);
|
|
17
|
+
const { overlayProps: positionProps } = (0, react_aria_1.useOverlayPosition)({
|
|
18
|
+
targetRef: buttonRef,
|
|
19
|
+
overlayRef: popoverRef,
|
|
20
|
+
shouldFlip: true,
|
|
21
|
+
isOpen: state.isOpen,
|
|
22
|
+
onClose: state.close,
|
|
23
|
+
placement: (placement ? `bottom ${placement}` : "bottom left"),
|
|
24
|
+
});
|
|
25
|
+
const tid = (0, utils_1.useTestIds)(props, isTextButton(trigger) ? (0, defaultTestId_1.defaultTestId)(trigger.label) : trigger.icon);
|
|
26
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.relative.dib.$ }, { children: [isTextButton(trigger) ? ((0, jsx_runtime_1.jsx)(Button_1.Button, Object.assign({ variant: "secondary" }, trigger, { menuTriggerProps: menuTriggerProps, buttonRef: buttonRef, endAdornment: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { icon: state.isOpen ? "chevronUp" : "chevronDown" }, void 0), disabled: disabled, tooltip: tooltip }, tid), void 0)) : ((0, jsx_runtime_1.jsx)(IconButton_1.IconButton, Object.assign({}, trigger, { menuTriggerProps: menuTriggerProps, buttonRef: buttonRef }, tid), void 0)), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: buttonRef, popoverRef: popoverRef, positionProps: positionProps, onClose: () => state.close(), isOpen: state.isOpen }, { children: children }), void 0))] }), void 0));
|
|
27
|
+
}
|
|
28
|
+
exports.OverlayTrigger = OverlayTrigger;
|
|
29
|
+
function isTextButton(trigger) {
|
|
30
|
+
return trigger && typeof trigger === "object" && "label" in trigger;
|
|
31
|
+
}
|
|
32
|
+
exports.isTextButton = isTextButton;
|
|
@@ -2,7 +2,6 @@ import { ReactNode } from "react";
|
|
|
2
2
|
import { Modifier } from "react-day-picker";
|
|
3
3
|
import { TextFieldBaseProps } from "./TextFieldBase";
|
|
4
4
|
import { Callback } from "../types";
|
|
5
|
-
import "./DateField.css";
|
|
6
5
|
export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "hideLabel" | "compact"> {
|
|
7
6
|
value: Date | undefined;
|
|
8
7
|
label: string;
|
package/dist/inputs/DateField.js
CHANGED
|
@@ -9,12 +9,11 @@ const react_day_picker_1 = require("react-day-picker");
|
|
|
9
9
|
const react_stately_1 = require("react-stately");
|
|
10
10
|
const components_1 = require("../components");
|
|
11
11
|
const internal_1 = require("../components/internal");
|
|
12
|
+
const DatePickerOverlay_1 = require("../components/internal/DatePickerOverlay");
|
|
12
13
|
const Css_1 = require("../Css");
|
|
13
|
-
const DatePickerOverlay_1 = require("./internal/DatePickerOverlay");
|
|
14
14
|
const TextFieldBase_1 = require("./TextFieldBase");
|
|
15
15
|
const utils_1 = require("../utils");
|
|
16
16
|
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
17
|
-
require("./DateField.css");
|
|
18
17
|
function DateField(props) {
|
|
19
18
|
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly = false, format = "short", iconLeft = false, disabledDays, onEnter, ...others } = props;
|
|
20
19
|
const inputRef = (0, react_1.useRef)(null);
|
|
@@ -100,6 +99,7 @@ function DateField(props) {
|
|
|
100
99
|
onClose: state.close,
|
|
101
100
|
placement: "bottom left",
|
|
102
101
|
shouldUpdatePosition: true,
|
|
102
|
+
offset: 4,
|
|
103
103
|
});
|
|
104
104
|
// 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)
|
|
105
105
|
// Otherwise the long format can be `undefined`.
|
|
@@ -120,10 +120,10 @@ function DateField(props) {
|
|
|
120
120
|
onChange(parsed);
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
}, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton, tooltip: isDisabled && typeof disabled !== "boolean" ? disabled : undefined }, others), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: inputWrapRef, popoverRef: overlayRef, positionProps:
|
|
123
|
+
}, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton, tooltip: isDisabled && typeof disabled !== "boolean" ? disabled : undefined }, 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) => {
|
|
124
124
|
setInputValue(formatDate(d, dateFormat));
|
|
125
125
|
onChange(d);
|
|
126
|
-
}, disabledDays: disabledDays }, tid.datePicker), void 0) }), void 0))] }, void 0));
|
|
126
|
+
}, state: state, disabledDays: disabledDays, overlayProps: overlayProps }, tid.datePicker), void 0) }), void 0))] }, void 0));
|
|
127
127
|
}
|
|
128
128
|
exports.DateField = DateField;
|
|
129
129
|
function formatDate(date, format) {
|
package/package.json
CHANGED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Modifier } from "react-day-picker";
|
|
3
|
-
import { OverlayTriggerState } from "react-stately";
|
|
4
|
-
interface DatePickerOverlayProps {
|
|
5
|
-
value: Date | undefined;
|
|
6
|
-
state: OverlayTriggerState;
|
|
7
|
-
positionProps: React.HTMLAttributes<Element>;
|
|
8
|
-
onChange: (value: Date) => void;
|
|
9
|
-
disabledDays: Modifier;
|
|
10
|
-
}
|
|
11
|
-
export declare function DatePickerOverlay(props: DatePickerOverlayProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
12
|
-
export {};
|