@homebound/beam 2.102.8 → 2.105.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 -3
- 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/Chip.js +5 -1
- package/dist/components/Chips.js +7 -1
- package/dist/components/PresentationContext.d.ts +1 -0
- package/dist/components/Table/GridTable.d.ts +2 -0
- package/dist/components/Table/GridTable.js +17 -4
- package/dist/components/Table/columns.d.ts +2 -0
- package/dist/components/Table/columns.js +7 -1
- package/dist/components/Table/styles.d.ts +3 -0
- package/dist/components/Table/styles.js +15 -8
- 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/forms/formStateDomain.d.ts +1 -0
- package/dist/forms/formStateDomain.js +2 -1
- package/dist/inputs/DateField.d.ts +2 -2
- package/dist/inputs/DateField.js +6 -5
- package/dist/inputs/TextFieldBase.js +1 -1
- 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,8 +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
|
-
/**
|
|
18
|
-
|
|
17
|
+
/** Denotes if this button is used to download a resource. Uses the anchor tag with the `download` attribute */
|
|
18
|
+
download?: boolean;
|
|
19
19
|
}
|
|
20
20
|
export declare function Button(props: ButtonProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
21
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,
|
|
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, !
|
|
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
|
-
}
|
package/dist/components/Chip.js
CHANGED
|
@@ -2,14 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Chip = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const PresentationContext_1 = require("./PresentationContext");
|
|
5
6
|
const Css_1 = require("../Css");
|
|
6
7
|
const useTestIds_1 = require("../utils/useTestIds");
|
|
7
8
|
/** Kinda like a chip, but read-only, so no `onClick` or `hover`. */
|
|
8
9
|
function Chip(props) {
|
|
10
|
+
var _a;
|
|
9
11
|
const { text, xss = {} } = props;
|
|
12
|
+
const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
|
|
13
|
+
const typeScale = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.typeScale) !== null && _a !== void 0 ? _a : "sm";
|
|
10
14
|
const tid = (0, useTestIds_1.useTestIds)(props, "chip");
|
|
11
15
|
return ((0, jsx_runtime_1.jsx)("span", Object.assign({ css: {
|
|
12
|
-
...Css_1.Css.dif.aic.br16.
|
|
16
|
+
...Css_1.Css[typeScale].dif.aic.br16.pl1.px1.pyPx(2).gray900.bgGray200.$,
|
|
13
17
|
...xss,
|
|
14
18
|
} }, tid, { title: text }, { children: (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.lineClamp1.breakAll.$ }, { children: text }), void 0) }), void 0));
|
|
15
19
|
}
|
package/dist/components/Chips.js
CHANGED
|
@@ -3,10 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Chips = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
5
|
const Chip_1 = require("./Chip");
|
|
6
|
+
const PresentationContext_1 = require("./PresentationContext");
|
|
6
7
|
const Css_1 = require("../Css");
|
|
7
8
|
/** Renders a list of `Chip`s, with wrapping & appropriate margin between each `Chip`. */
|
|
8
9
|
function Chips(props) {
|
|
10
|
+
const { wrap } = (0, PresentationContext_1.usePresentationContext)();
|
|
9
11
|
const { values, xss = {} } = props;
|
|
10
|
-
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: {
|
|
12
|
+
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: {
|
|
13
|
+
...Css_1.Css.df.gap1.whiteSpace("normal").$,
|
|
14
|
+
...(wrap !== false ? Css_1.Css.add({ flexWrap: "wrap" }).$ : {}),
|
|
15
|
+
...xss,
|
|
16
|
+
} }, { children: values.map((value, i) => ((0, jsx_runtime_1.jsx)(Chip_1.Chip, { text: value }, i))) }), void 0));
|
|
11
17
|
}
|
|
12
18
|
exports.Chips = Chips;
|
|
@@ -13,6 +13,7 @@ export interface PresentationFieldProps {
|
|
|
13
13
|
export declare type PresentationContextProps = {
|
|
14
14
|
fieldProps?: PresentationFieldProps;
|
|
15
15
|
gridTableStyle?: GridStyle;
|
|
16
|
+
wrap?: boolean;
|
|
16
17
|
};
|
|
17
18
|
export declare const PresentationContext: import("react").Context<PresentationContextProps>;
|
|
18
19
|
export declare function PresentationProvider(props: PropsWithChildren<PresentationContextProps>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { MutableRefObject, ReactElement, ReactNode } from "react";
|
|
2
|
+
import { PresentationContextProps, PresentationFieldProps } from "../PresentationContext";
|
|
2
3
|
import { GridRowLookup } from "./GridRowLookup";
|
|
3
4
|
import { Margin, Only, Properties, Xss } from "../../Css";
|
|
4
5
|
export declare type Kinded = {
|
|
@@ -46,6 +47,7 @@ export interface GridStyle {
|
|
|
46
47
|
nestedCards?: NestedCardsStyle;
|
|
47
48
|
/** Default content to put into an empty cell */
|
|
48
49
|
emptyCell?: ReactNode;
|
|
50
|
+
presentationSettings?: Pick<PresentationFieldProps, "borderless" | "typeScale"> & Pick<PresentationContextProps, "wrap">;
|
|
49
51
|
}
|
|
50
52
|
export declare type NestedCardStyleByKind = Record<string, NestedCardStyle>;
|
|
51
53
|
export interface NestedCardsStyle {
|
|
@@ -80,7 +80,7 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
80
80
|
* special styling to the row that uses `kind: "header"`.)
|
|
81
81
|
*/
|
|
82
82
|
function GridTable(props) {
|
|
83
|
-
var _a;
|
|
83
|
+
var _a, _b, _c, _d, _e;
|
|
84
84
|
const { id = "gridTable", as = "div", columns, rows, style = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = "0", xss, sorting, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, setRowCount, observeRows, persistCollapse, api, } = props;
|
|
85
85
|
const [collapsedIds, collapseAllContext, collapseRowContext] = useToggleIds(rows, persistCollapse);
|
|
86
86
|
// We only use this in as=virtual mode, but keep this here for rowLookup to use
|
|
@@ -98,12 +98,11 @@ function GridTable(props) {
|
|
|
98
98
|
}
|
|
99
99
|
return rows;
|
|
100
100
|
}, [columns, rows, sorting, sortState]);
|
|
101
|
+
const columnSizes = (0, react_1.useMemo)(() => { var _a; return calcColumnSizes(columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth); }, [columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth]);
|
|
101
102
|
// Filter + flatten + component-ize the sorted rows.
|
|
102
103
|
let [headerRows, filteredRows] = (0, react_1.useMemo)(() => {
|
|
103
|
-
var _a;
|
|
104
104
|
// Break up "foo bar" into `[foo, bar]` and a row must match both `foo` and `bar`
|
|
105
105
|
const filters = (filter && filter.split(/ +/)) || [];
|
|
106
|
-
const columnSizes = calcColumnSizes(columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth);
|
|
107
106
|
function makeRowComponent(row) {
|
|
108
107
|
// We only pass sortState to header rows, b/c non-headers rows shouldn't have to re-render on sorting
|
|
109
108
|
// changes, and so by not passing the sortProps, it means the data rows' React.memo will still cache them.
|
|
@@ -194,12 +193,22 @@ function GridTable(props) {
|
|
|
194
193
|
}, [filteredRows === null || filteredRows === void 0 ? void 0 : filteredRows.length, setRowCount]);
|
|
195
194
|
const noData = filteredRows.length === 0;
|
|
196
195
|
const firstRowMessage = (noData && fallbackMessage) || (tooManyClientSideRows && "Hiding some rows, use filter...") || infoMessage;
|
|
196
|
+
const borderless = (_b = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _b === void 0 ? void 0 : _b.borderless;
|
|
197
|
+
const typeScale = (_c = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _c === void 0 ? void 0 : _c.typeScale;
|
|
198
|
+
const fieldProps = (0, react_1.useMemo)(() => ({
|
|
199
|
+
hideLabel: true,
|
|
200
|
+
numberAlignment: "right",
|
|
201
|
+
compact: true,
|
|
202
|
+
// Avoid passing `undefined` as it will unset existing PresentationContext settings
|
|
203
|
+
...(borderless !== undefined ? { borderless } : {}),
|
|
204
|
+
...(typeScale !== undefined ? { typeScale } : {}),
|
|
205
|
+
}), [borderless, typeScale]);
|
|
197
206
|
// If we're running in Jest, force using `as=div` b/c jsdom doesn't support react-virtuoso.
|
|
198
207
|
// This enables still putting the application's business/rendering logic under test, and letting it
|
|
199
208
|
// just trust the GridTable impl that, at runtime, `as=virtual` will (other than being virtualized)
|
|
200
209
|
// behave semantically the same as `as=div` did for its tests.
|
|
201
210
|
const _as = as === "virtual" && runningInJest ? "div" : as;
|
|
202
|
-
return ((0, jsx_runtime_1.jsx)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps:
|
|
211
|
+
return ((0, jsx_runtime_1.jsx)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps: fieldProps, wrap: (_d = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _d === void 0 ? void 0 : _d.wrap }, { children: renders[_as](style, id, columns, headerRows, filteredRows, firstRowMessage, stickyHeader, (_e = style.nestedCards) === null || _e === void 0 ? void 0 : _e.firstLastColumnWidth, xss, virtuosoRef) }), void 0));
|
|
203
212
|
}
|
|
204
213
|
exports.GridTable = GridTable;
|
|
205
214
|
// Determine which HTML element to use to build the GridTable
|
|
@@ -497,6 +506,7 @@ function isJSX(content) {
|
|
|
497
506
|
}
|
|
498
507
|
/** If a column def return just string text for a given row, apply some default styling. */
|
|
499
508
|
function toContent(content, isHeader, canSortColumn, isClientSideSorting, style, as, alignment) {
|
|
509
|
+
var _a;
|
|
500
510
|
content = isGridCellContent(content) ? content.content : content;
|
|
501
511
|
if (typeof content === "function") {
|
|
502
512
|
// Actually create the JSX by calling `content()` here (which should be as late as
|
|
@@ -517,6 +527,9 @@ function toContent(content, isHeader, canSortColumn, isClientSideSorting, style,
|
|
|
517
527
|
if (content && typeof content === "string" && isHeader && canSortColumn) {
|
|
518
528
|
return (0, jsx_runtime_1.jsx)(SortHeader_1.SortHeader, { content: content, iconOnLeft: alignment === "right" }, void 0);
|
|
519
529
|
}
|
|
530
|
+
else if (content && typeof content === "string" && ((_a = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _a === void 0 ? void 0 : _a.wrap) === false) {
|
|
531
|
+
return ((0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.mw0.truncate.$, title: content }, { children: content }), void 0));
|
|
532
|
+
}
|
|
520
533
|
else if (style.emptyCell && isContentEmpty(content)) {
|
|
521
534
|
// If the content is empty and the user specified an `emptyCell` node, return that.
|
|
522
535
|
return style.emptyCell;
|
|
@@ -10,3 +10,5 @@ export declare function numericColumn<T extends Kinded, S = {}>(columnDef: GridC
|
|
|
10
10
|
export declare function actionColumn<T extends Kinded, S = {}>(columnDef: GridColumn<T, S>): GridColumn<T, S>;
|
|
11
11
|
/** Provides default styling for a GridColumn containing a checkbox. */
|
|
12
12
|
export declare function selectColumn<T extends Kinded, S = {}>(columnDef: GridColumn<T, S>): GridColumn<T, S>;
|
|
13
|
+
/** Provides default styling for a GridColumn containing the CollapseToggle component. */
|
|
14
|
+
export declare function collapseColumn<T extends Kinded, S = {}>(columnDef: GridColumn<T, S>): GridColumn<T, S>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.selectColumn = exports.actionColumn = exports.numericColumn = exports.dateColumn = exports.column = void 0;
|
|
3
|
+
exports.collapseColumn = exports.selectColumn = exports.actionColumn = exports.numericColumn = exports.dateColumn = exports.column = void 0;
|
|
4
4
|
/** Provides default styling for a GridColumn representing a Date. */
|
|
5
5
|
function column(columnDef) {
|
|
6
6
|
return { ...columnDef };
|
|
@@ -28,3 +28,9 @@ function selectColumn(columnDef) {
|
|
|
28
28
|
return { clientSideSort: false, ...columnDef, align: "center", w: "48px" };
|
|
29
29
|
}
|
|
30
30
|
exports.selectColumn = selectColumn;
|
|
31
|
+
/** Provides default styling for a GridColumn containing the CollapseToggle component. */
|
|
32
|
+
function collapseColumn(columnDef) {
|
|
33
|
+
// Defining `w: 38px` based on the designs
|
|
34
|
+
return { ...columnDef, clientSideSort: false, align: "center", w: "38px" };
|
|
35
|
+
}
|
|
36
|
+
exports.collapseColumn = collapseColumn;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Properties } from "../../Css";
|
|
1
2
|
import { GridStyle } from ".";
|
|
2
3
|
/** Our original table look & feel/style. */
|
|
3
4
|
export declare const defaultStyle: GridStyle;
|
|
@@ -7,3 +8,5 @@ export declare const condensedStyle: GridStyle;
|
|
|
7
8
|
export declare const cardStyle: GridStyle;
|
|
8
9
|
export declare const beamFixedStyle: GridStyle;
|
|
9
10
|
export declare const beamFlexibleStyle: GridStyle;
|
|
11
|
+
export declare const beamGroupRowStyle: Properties;
|
|
12
|
+
export declare const beamTotalsRowStyle: Properties;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.beamFlexibleStyle = exports.beamFixedStyle = exports.cardStyle = exports.condensedStyle = exports.defaultStyle = void 0;
|
|
3
|
+
exports.beamTotalsRowStyle = exports.beamGroupRowStyle = exports.beamFlexibleStyle = exports.beamFixedStyle = exports.cardStyle = exports.condensedStyle = exports.defaultStyle = void 0;
|
|
4
4
|
const Css_1 = require("../../Css");
|
|
5
5
|
/** Our original table look & feel/style. */
|
|
6
6
|
exports.defaultStyle = {
|
|
@@ -41,11 +41,18 @@ exports.cardStyle = {
|
|
|
41
41
|
};
|
|
42
42
|
// Once completely rolled out across all tables in Blueprint, this will change to be the `defaultStyle`.
|
|
43
43
|
exports.beamFixedStyle = {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
headerCellCss: Css_1.Css.gray700.xsEm.bgGray200.aic.nowrap.pxPx(12).hPx(40).$,
|
|
45
|
+
cellCss: Css_1.Css.gray900.xs.bgWhite.aic.nowrap.pxPx(12).hPx(36).boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray100}`).$,
|
|
46
|
+
emptyCell: "-",
|
|
47
|
+
presentationSettings: { borderless: true, typeScale: "xs", wrap: false },
|
|
48
|
+
rowHoverColor: Css_1.Palette.Gray200,
|
|
49
|
+
};
|
|
50
|
+
exports.beamFlexibleStyle = {
|
|
51
|
+
...exports.beamFixedStyle,
|
|
52
|
+
cellCss: Css_1.Css.xs.bgWhite.aic.p2.boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray100}`).$,
|
|
53
|
+
presentationSettings: { borderless: false, typeScale: "xs", wrap: true },
|
|
49
54
|
};
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
exports.beamGroupRowStyle = Css_1.Css.smEm
|
|
56
|
+
.mhPx(56)
|
|
57
|
+
.gray700.bgGray100.boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`).$;
|
|
58
|
+
exports.beamTotalsRowStyle = Css_1.Css.gray700.smEm.hPx(40).mb1.bgWhite.boxShadow("none").$;
|
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 | 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;
|
|
@@ -3,9 +3,10 @@
|
|
|
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.jan2 = exports.jan1 = void 0;
|
|
6
|
+
exports.DateOnly = exports.dd200 = exports.dd100 = 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
|
+
exports.jan10 = new Date(2020, 0, 10);
|
|
9
10
|
exports.dd100 = { number: "100", category: "Philosophy" };
|
|
10
11
|
exports.dd200 = { number: "200", category: "Religion" };
|
|
11
12
|
class DateOnly {
|
|
@@ -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;
|
|
@@ -25,8 +24,9 @@ export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless
|
|
|
25
24
|
* Set custom logic for individual dates or date ranges to be disabled in the picker
|
|
26
25
|
* exposed from `react-day-picker`: https://react-day-picker.js.org/api/DayPicker#modifiers
|
|
27
26
|
*/
|
|
28
|
-
disabledDays?: Modifier;
|
|
27
|
+
disabledDays?: Modifier | Modifier[];
|
|
29
28
|
onEnter?: Callback;
|
|
29
|
+
defaultOpen?: boolean;
|
|
30
30
|
}
|
|
31
31
|
export declare function DateField(props: DateFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
32
32
|
declare const dateFormats: {
|
package/dist/inputs/DateField.js
CHANGED
|
@@ -9,14 +9,13 @@ 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
|
-
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly = false, format = "short", iconLeft = false, disabledDays, onEnter, ...others } = props;
|
|
18
|
+
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly = false, format = "short", iconLeft = false, disabledDays, onEnter, defaultOpen, ...others } = props;
|
|
20
19
|
const inputRef = (0, react_1.useRef)(null);
|
|
21
20
|
const inputWrapRef = (0, react_1.useRef)(null);
|
|
22
21
|
const buttonRef = (0, react_1.useRef)(null);
|
|
@@ -48,6 +47,7 @@ function DateField(props) {
|
|
|
48
47
|
(0, utils_1.maybeCall)(onBlur);
|
|
49
48
|
}
|
|
50
49
|
},
|
|
50
|
+
isOpen: defaultOpen,
|
|
51
51
|
});
|
|
52
52
|
const { labelProps, inputProps } = (0, react_aria_1.useTextField)({
|
|
53
53
|
...textFieldProps,
|
|
@@ -100,6 +100,7 @@ function DateField(props) {
|
|
|
100
100
|
onClose: state.close,
|
|
101
101
|
placement: "bottom left",
|
|
102
102
|
shouldUpdatePosition: true,
|
|
103
|
+
offset: 4,
|
|
103
104
|
});
|
|
104
105
|
// 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
106
|
// Otherwise the long format can be `undefined`.
|
|
@@ -120,10 +121,10 @@ function DateField(props) {
|
|
|
120
121
|
onChange(parsed);
|
|
121
122
|
}
|
|
122
123
|
}
|
|
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:
|
|
124
|
+
}, 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
125
|
setInputValue(formatDate(d, dateFormat));
|
|
125
126
|
onChange(d);
|
|
126
|
-
}, disabledDays: disabledDays }, tid.datePicker), void 0) }), void 0))] }, void 0));
|
|
127
|
+
}, state: state, disabledDays: disabledDays, overlayProps: overlayProps }, tid.datePicker), void 0) }), void 0))] }, void 0));
|
|
127
128
|
}
|
|
128
129
|
exports.DateField = DateField;
|
|
129
130
|
function formatDate(date, format) {
|
|
@@ -56,7 +56,7 @@ function TextFieldBase(props) {
|
|
|
56
56
|
...(!contrast ? Css_1.Css.bgWhite.$ : Css_1.Css.bgGray700.addIn("&::selection", Css_1.Css.bgGray800.$).$),
|
|
57
57
|
},
|
|
58
58
|
hover: Css_1.Css.bgGray100.if(contrast).bgGray600.bGray600.$,
|
|
59
|
-
focus: borderless ? Css_1.Css.bshFocus.$ : Css_1.Css.bLightBlue700.if(contrast).bLightBlue500.$,
|
|
59
|
+
focus: borderless ? Css_1.Css.bshFocus.z1.$ : Css_1.Css.bLightBlue700.if(contrast).bLightBlue500.$,
|
|
60
60
|
disabled: visuallyDisabled
|
|
61
61
|
? Css_1.Css.cursorNotAllowed.gray400.bgGray100.if(contrast).gray500.bgGray700.$
|
|
62
62
|
: Css_1.Css.cursorNotAllowed.$,
|
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 {};
|