@homebound/beam 2.233.0 → 2.234.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.
Files changed (33) hide show
  1. package/dist/components/AvatarButton.js +2 -2
  2. package/dist/components/Button.js +2 -1
  3. package/dist/components/ButtonGroup.js +1 -1
  4. package/dist/components/IconButton.js +2 -2
  5. package/dist/components/Layout/PreventBrowserScroll.d.ts +2 -2
  6. package/dist/components/Layout/RightPaneLayout/RightPaneContext.d.ts +1 -1
  7. package/dist/components/NavLink.d.ts +7 -6
  8. package/dist/components/Snackbar/SnackbarContext.d.ts +3 -2
  9. package/dist/components/Table/GridTable.d.ts +1 -1
  10. package/dist/components/Table/GridTable.js +3 -1
  11. package/dist/components/Table/components/ExpandableHeader.js +14 -2
  12. package/dist/components/Table/components/Row.d.ts +2 -1
  13. package/dist/components/Table/components/Row.js +5 -2
  14. package/dist/components/Table/components/cell.d.ts +2 -2
  15. package/dist/components/Table/types.d.ts +2 -2
  16. package/dist/components/Table/utils/TableState.d.ts +3 -0
  17. package/dist/components/Table/utils/TableState.js +21 -0
  18. package/dist/components/Table/utils/columns.js +13 -11
  19. package/dist/components/Table/utils/utils.js +1 -1
  20. package/dist/components/Tabs.d.ts +3 -2
  21. package/dist/components/Toast/ToastContext.d.ts +4 -2
  22. package/dist/components/internal/Popover.js +1 -1
  23. package/dist/hooks/useGetRef.d.ts +6 -0
  24. package/dist/hooks/useGetRef.js +13 -0
  25. package/dist/inputs/DateFields/DateFieldBase.d.ts +2 -1
  26. package/dist/inputs/DateFields/DateFieldBase.js +1 -1
  27. package/dist/inputs/DateFields/utils.js +1 -1
  28. package/dist/inputs/TextFieldBase.js +2 -1
  29. package/dist/types.d.ts +5 -0
  30. package/dist/utils/index.d.ts +2 -1
  31. package/dist/utils/index.js +5 -1
  32. package/dist/utils/sb.d.ts +2 -1
  33. package/package.json +1 -1
@@ -7,6 +7,7 @@ const react_aria_1 = require("react-aria");
7
7
  const components_1 = require("./");
8
8
  const Avatar_1 = require("./Avatar");
9
9
  const Css_1 = require("../Css");
10
+ const useGetRef_1 = require("../hooks/useGetRef");
10
11
  const utils_1 = require("../utils");
11
12
  const getInteractiveElement_1 = require("../utils/getInteractiveElement");
12
13
  const useTestIds_1 = require("../utils/useTestIds");
@@ -14,8 +15,7 @@ function AvatarButton(props) {
14
15
  const { onClick: onPress, disabled, autoFocus, buttonRef, tooltip, menuTriggerProps, openInNew, forceFocusStyles = false, ...avatarProps } = props;
15
16
  const isDisabled = !!disabled;
16
17
  const ariaProps = { onPress, isDisabled, autoFocus, ...menuTriggerProps };
17
- // eslint-disable-next-line react-hooks/rules-of-hooks
18
- const ref = buttonRef || (0, react_1.useRef)(null);
18
+ const ref = (0, useGetRef_1.useGetRef)(buttonRef);
19
19
  const { buttonProps, isPressed } = (0, react_aria_1.useButton)({
20
20
  ...ariaProps,
21
21
  onPress: typeof onPress === "string" ? utils_1.noop : onPress,
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const react_aria_1 = require("react-aria");
7
7
  const components_1 = require("./");
8
8
  const Css_1 = require("../Css");
9
+ const useGetRef_1 = require("../hooks/useGetRef");
9
10
  const utils_1 = require("../utils");
10
11
  const getInteractiveElement_1 = require("../utils/getInteractiveElement");
11
12
  const useTestIds_1 = require("../utils/useTestIds");
@@ -20,7 +21,7 @@ function Button(props) {
20
21
  const { label,
21
22
  // Default the icon based on other properties.
22
23
  icon = download ? "download" : showExternalLinkIcon ? "linkExternal" : undefined, variant = "primary", size = "sm", buttonRef, } = ariaProps;
23
- const ref = buttonRef || (0, react_1.useRef)(null);
24
+ const ref = (0, useGetRef_1.useGetRef)(buttonRef);
24
25
  const tid = (0, useTestIds_1.useTestIds)(props, (0, OverlayTrigger_1.labelOr)(ariaProps, "button"));
25
26
  const { buttonProps, isPressed } = (0, react_aria_1.useButton)({
26
27
  ...ariaProps,
@@ -14,7 +14,7 @@ function ButtonGroup(props) {
14
14
  const tid = (0, utils_1.useTestIds)(props, "buttonGroup");
15
15
  return (
16
16
  // Adding `line-height: 0` prevent inheriting line-heights that might throw off sizing within the button group.
17
- (0, jsx_runtime_1.jsx)("div", { ...tid, css: Css_1.Css.df.lh(0).add(sizeStyles[size]).$, children: buttons.map(({ disabled: buttonDisabled, ...buttonProps }, i) => (
17
+ (0, jsx_runtime_1.jsx)("div", { ...tid, css: Css_1.Css.df.lh(0).add({ ...sizeStyles[size] }).$, children: buttons.map(({ disabled: buttonDisabled, ...buttonProps }, i) => (
18
18
  // Disable the button if the ButtonGroup is disabled or if the current button is disabled.
19
19
  (0, jsx_runtime_1.jsx)(GroupButton, { ...buttonProps, disabled: disabled || buttonDisabled, size: size, ...tid }, i))) }));
20
20
  }
@@ -6,6 +6,7 @@ const react_1 = require("react");
6
6
  const react_aria_1 = require("react-aria");
7
7
  const components_1 = require("./");
8
8
  const Css_1 = require("../Css");
9
+ const useGetRef_1 = require("../hooks/useGetRef");
9
10
  const utils_1 = require("../utils");
10
11
  const getInteractiveElement_1 = require("../utils/getInteractiveElement");
11
12
  const useTestIds_1 = require("../utils/useTestIds");
@@ -13,8 +14,7 @@ function IconButton(props) {
13
14
  const { onClick: onPress, disabled, color, icon, autoFocus, inc, buttonRef, tooltip, menuTriggerProps, openInNew, compact = false, contrast = false, download = false, forceFocusStyles = false, } = props;
14
15
  const isDisabled = !!disabled;
15
16
  const ariaProps = { onPress, isDisabled, autoFocus, ...menuTriggerProps };
16
- // eslint-disable-next-line react-hooks/rules-of-hooks
17
- const ref = buttonRef || (0, react_1.useRef)(null);
17
+ const ref = (0, useGetRef_1.useGetRef)(buttonRef);
18
18
  const { buttonProps } = (0, react_aria_1.useButton)({
19
19
  ...ariaProps,
20
20
  onPress: typeof onPress === "string" ? utils_1.noop : onPress,
@@ -1,3 +1,3 @@
1
- import { PropsWithChildren } from "react";
1
+ import { ChildrenOnly } from "../../types";
2
2
  /** Intended to wrap the whole application to prevent the browser's native scrolling behavior while also taking the full height of the viewport */
3
- export declare function PreventBrowserScroll({ children }: PropsWithChildren<{}>): import("@emotion/react/jsx-runtime").JSX.Element;
3
+ export declare function PreventBrowserScroll({ children }: ChildrenOnly): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -6,7 +6,7 @@ export type RightPaneLayoutContextProps = {
6
6
  openInPane: (opts: OpenRightPaneOpts) => void;
7
7
  closePane: () => void;
8
8
  clearPane: () => void;
9
- isRightPaneOpen: Boolean;
9
+ isRightPaneOpen: boolean;
10
10
  rightPaneContent: ReactNode;
11
11
  };
12
12
  export declare const RightPaneContext: React.Context<RightPaneLayoutContextProps>;
@@ -1,4 +1,5 @@
1
1
  import type { IconKey } from "./";
2
+ import { Properties } from "../Css";
2
3
  import { BeamFocusableProps } from "../interfaces";
3
4
  export interface NavLinkProps extends BeamFocusableProps {
4
5
  /** active indicates the user is on the current page */
@@ -14,11 +15,11 @@ export interface NavLinkProps extends BeamFocusableProps {
14
15
  type NavLinkVariant = "side" | "global";
15
16
  export declare function NavLink(props: NavLinkProps): import("@emotion/react/jsx-runtime").JSX.Element;
16
17
  export declare function getNavLinkStyles(variant: NavLinkVariant, contrast: boolean): {
17
- baseStyles: {};
18
- hoverStyles: {};
19
- disabledStyles: {};
20
- focusRingStyles: {};
21
- activeStyles: {};
22
- pressedStyles: {};
18
+ baseStyles: Properties;
19
+ hoverStyles: Properties;
20
+ disabledStyles: Properties;
21
+ focusRingStyles: Properties;
22
+ activeStyles: Properties;
23
+ pressedStyles: Properties;
23
24
  };
24
25
  export {};
@@ -1,10 +1,11 @@
1
- import React, { PropsWithChildren } from "react";
1
+ import React from "react";
2
2
  import { SnackbarNoticeProps } from "./SnackbarNotice";
3
+ import { ChildrenOnly } from "../../types";
3
4
  import { Offset } from "./Snackbar";
4
5
  export type SnackbarContextProps = {
5
6
  setNotices: React.Dispatch<React.SetStateAction<SnackbarNoticeProps[]>>;
6
7
  setOffset: React.Dispatch<React.SetStateAction<Offset>>;
7
8
  };
8
9
  export declare const SnackbarContext: React.Context<SnackbarContextProps>;
9
- export declare function SnackbarProvider(props: PropsWithChildren<{}>): import("@emotion/react/jsx-runtime").JSX.Element;
10
+ export declare function SnackbarProvider(props: ChildrenOnly): import("@emotion/react/jsx-runtime").JSX.Element;
10
11
  export declare function useSnackbarContext(): SnackbarContextProps;
@@ -126,7 +126,7 @@ export interface GridTableProps<R extends Kinded, X> {
126
126
  * row `kind` along with the data rows. (Admittedly, out of pragmatism, we do apply some
127
127
  * special styling to the row that uses `kind: "header"`.)
128
128
  */
129
- export declare function GridTable<R extends Kinded, X extends Only<GridTableXss, X> = {}>(props: GridTableProps<R, X>): import("@emotion/react/jsx-runtime").JSX.Element;
129
+ export declare function GridTable<R extends Kinded, X extends Only<GridTableXss, X> = any>(props: GridTableProps<R, X>): import("@emotion/react/jsx-runtime").JSX.Element;
130
130
  /**
131
131
  * Filters rows given a client-side text `filter.
132
132
  *
@@ -103,7 +103,9 @@ function GridTable(props) {
103
103
  tableState.setColumns(columnsWithIds, visibleColumnsStorageKey);
104
104
  const columns = (0, hooks_1.useComputed)(() => tableState.columns
105
105
  .filter((c) => tableState.visibleColumnIds.includes(c.id))
106
- .flatMap((c) => c.expandColumns && tableState.expandedColumnIds.includes(c.id) ? [c, ...c.expandColumns] : [c]), [tableState]);
106
+ .flatMap((c) => c.expandColumns && tableState.expandedColumnIds.includes(c.id)
107
+ ? [c, ...tableState.getExpandedColumns(c)]
108
+ : [c]), [tableState]);
107
109
  // Initialize the sort state. This will only happen on the first render.
108
110
  // Once the `TableState.sort` is defined, it will not re-initialize.
109
111
  tableState.initSortState(props.sorting, columns);
@@ -8,18 +8,30 @@ const TableState_1 = require("../utils/TableState");
8
8
  const utils_1 = require("../utils/utils");
9
9
  const Css_1 = require("../../../Css");
10
10
  const hooks_1 = require("../../../hooks");
11
+ const utils_2 = require("../../../utils");
12
+ const Loader_1 = require("../../Loader");
11
13
  function ExpandableHeader(props) {
12
14
  const { title, column, minStickyLeftOffset, as } = props;
13
15
  const { tableState } = (0, react_1.useContext)(TableState_1.TableStateContext);
14
16
  const expandedColumnIds = (0, hooks_1.useComputed)(() => tableState.expandedColumnIds, [tableState]);
15
17
  const isExpanded = expandedColumnIds.includes(column.id);
18
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
16
19
  // Do not apply sticky styles when rendering as table. Currently the table does not properly respect column widths, causing the sticky offsets to be incorrect
17
20
  const applyStickyStyles = isExpanded && as !== "table";
18
21
  const { hoverProps, isHovered } = (0, hooks_1.useHover)({});
19
- return ((0, jsx_runtime_1.jsxs)("button", { ...hoverProps, css: Css_1.Css.df.xsMd.aic.jcsb.gap2.px1.hPx(32).mxPx(-8).w("calc(100% + 16px)").br4.lightBlue700.if(isHovered).bgGray100.$, onClick: () => tableState.toggleExpandedColumn(column.id), "data-testid": "expandableColumn", children: [(0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.tl.lineClamp2
22
+ return ((0, jsx_runtime_1.jsxs)("button", { ...hoverProps, css: Css_1.Css.df.xsMd.aic.jcsb.gap2.px1.hPx(32).mxPx(-8).w("calc(100% + 16px)").br4.lightBlue700.if(isHovered).bgGray100.$, onClick: async () => {
23
+ if ((0, utils_2.isFunction)(column.expandColumns)) {
24
+ setIsLoading(true);
25
+ await tableState.loadExpandedColumns(column);
26
+ setIsLoading(false);
27
+ }
28
+ else {
29
+ tableState.toggleExpandedColumn(column.id);
30
+ }
31
+ }, "data-testid": "expandableColumn", children: [(0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.tl.lineClamp2
20
32
  .if(applyStickyStyles)
21
33
  .sticky.leftPx(minStickyLeftOffset + 12)
22
34
  .pr2.mr2.bgWhite.z(utils_1.zIndices.expandableHeaderTitle)
23
- .if(isHovered).bgGray100.$, children: title }), (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.if(applyStickyStyles).sticky.rightPx(12).z(utils_1.zIndices.expandableHeaderIcon).$, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { icon: isExpanded ? "chevronLeft" : "chevronRight", inc: 2 }) })] }));
35
+ .if(isHovered).bgGray100.$, children: title }), (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.if(applyStickyStyles).sticky.rightPx(12).z(utils_1.zIndices.expandableHeaderIcon).$, children: isLoading ? (0, jsx_runtime_1.jsx)(Loader_1.Loader, { size: "xs" }) : (0, jsx_runtime_1.jsx)(Icon_1.Icon, { icon: isExpanded ? "chevronLeft" : "chevronRight", inc: 2 }) })] }));
24
36
  }
25
37
  exports.ExpandableHeader = ExpandableHeader;
@@ -3,6 +3,7 @@ import { GridTableApi } from "../GridTableApi";
3
3
  import { GridStyle, RowStyles } from "../TableStyles";
4
4
  import { DiscriminateUnion, GridColumnWithId, IfAny, Kinded, Pin, RenderAs } from "../types";
5
5
  import { SortOn } from "../utils/TableState";
6
+ import { AnyObject } from "../../../types";
6
7
  interface RowProps<R extends Kinded> {
7
8
  as: RenderAs;
8
9
  columns: GridColumnWithId<R>[];
@@ -67,5 +68,5 @@ export type GridDataRow<R extends Kinded> = {
67
68
  selectable?: false;
68
69
  /** Whether this row should infer its selected state based on its children's selected state */
69
70
  inferSelectedState?: false;
70
- } & IfAny<R, {}, DiscriminateUnion<R, "kind", R["kind"]>>;
71
+ } & IfAny<R, AnyObject, DiscriminateUnion<R, "kind", R["kind"]>>;
71
72
  export {};
@@ -33,6 +33,7 @@ const TableState_1 = require("../utils/TableState");
33
33
  const utils_1 = require("../utils/utils");
34
34
  const Css_1 = require("../../../Css");
35
35
  const hooks_1 = require("../../../hooks");
36
+ const utils_2 = require("../../../utils");
36
37
  const shallowEqual_1 = require("../../../utils/shallowEqual");
37
38
  // We extract Row to its own mini-component primarily so we can React.memo'ize it.
38
39
  function RowImpl(props) {
@@ -75,7 +76,7 @@ function RowImpl(props) {
75
76
  var _a, _b, _c, _d, _e, _f;
76
77
  // Need to keep track of the expanded columns so we can add borders as expected for the header rows
77
78
  const isExpanded = tableState.expandedColumnIds.includes(column.id);
78
- const numExpandedColumns = isExpanded ? (_b = (_a = column.expandColumns) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0 : 0;
79
+ const numExpandedColumns = isExpanded ? (_b = (_a = tableState.getExpandedColumns(column)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0 : 0;
79
80
  const { wrapAction = true, isAction = false } = column;
80
81
  const applyFirstContentColumnStyles = !isHeader && !isAction && !firstContentColumnStylesApplied;
81
82
  firstContentColumnStylesApplied || (firstContentColumnStylesApplied = applyFirstContentColumnStyles);
@@ -116,7 +117,9 @@ function RowImpl(props) {
116
117
  (sortOn === "server" && !!column.serverSideSortKey);
117
118
  const alignment = (0, utils_1.getAlignment)(column, maybeContent);
118
119
  const justificationCss = (0, utils_1.getJustification)(column, maybeContent, as, alignment);
119
- const isExpandable = (column.expandColumns && column.expandColumns.length > 0) || column.expandedWidth !== undefined;
120
+ const isExpandable = (0, utils_2.isFunction)(column.expandColumns) ||
121
+ (column.expandColumns && column.expandColumns.length > 0) ||
122
+ column.expandedWidth !== undefined;
120
123
  const content = (0, utils_1.toContent)(maybeContent, isHeader, canSortColumn, sortOn === "client", style, as, alignment, column, isExpandableHeader, isExpandable, minStickyLeftOffset);
121
124
  (0, sortRows_1.ensureClientSideSortValueIsSortable)(sortOn, isHeader || isTotals || isExpandableHeader, column, columnIndex, maybeContent);
122
125
  const maybeSticky = (_c = (((0, utils_1.isGridCellContent)(maybeContent) && maybeContent.sticky) || column.sticky)) !== null && _c !== void 0 ? _c : undefined;
@@ -22,14 +22,14 @@ export type GridCellContent = {
22
22
  /** Allows the cell to stay in place when the user scrolls horizontally, i.e. frozen columns. */
23
23
  sticky?: "left" | "right";
24
24
  /** If provided, content of the cell will be wrapped within a <button /> or <a /> tag depending on if the value is a function or a string. */
25
- onClick?: () => {} | string;
25
+ onClick?: VoidFunction | string;
26
26
  /** Custom css to apply directly to this cell, i.e. cell-specific borders. */
27
27
  css?: Properties;
28
28
  /** Allows cell to reveal content when the user hovers over a row. Content must be wrapped in an element in order to be hidden. IE <div>{value}</div>*/
29
29
  revealOnRowHover?: true;
30
30
  };
31
31
  /** Allows rendering a specific cell. */
32
- export type RenderCellFn<R extends Kinded> = (idx: number, css: Properties, content: ReactNode, row: R, rowStyle: RowStyle<R> | undefined, classNames: string | undefined, onClick: (() => void) | undefined) => ReactNode;
32
+ export type RenderCellFn<R extends Kinded> = (idx: number, css: Properties, content: ReactNode, row: R, rowStyle: RowStyle<R> | undefined, classNames: string | undefined, onClick: VoidFunction | undefined) => ReactNode;
33
33
  /** Renders our default cell element, i.e. if no row links and no custom renderCell are used. */
34
34
  export declare const defaultRenderFn: (as: RenderAs) => RenderCellFn<any>;
35
35
  /**
@@ -79,13 +79,13 @@ export type GridColumn<R extends Kinded> = {
79
79
  /** Flag that will allow to know which hide-able columns are visible on initial load */
80
80
  initVisible?: boolean;
81
81
  /** A list of columns that should only be shown when this column is "expanded" */
82
- expandColumns?: GridColumn<R>[];
82
+ expandColumns?: GridColumn<R>[] | (() => Promise<GridColumn<R>[]>);
83
83
  /** Determines whether the group should initially be expanded on load of the table */
84
84
  initExpanded?: boolean;
85
85
  };
86
86
  export type GridColumnWithId<R extends Kinded> = GridColumn<R> & {
87
87
  id: string;
88
- expandColumns?: GridColumnWithId<R>[];
88
+ expandColumns?: GridColumnWithId<R>[] | (() => Promise<GridColumn<R>[]>);
89
89
  };
90
90
  export declare const nonKindGridColumnKeys: string[];
91
91
  /**
@@ -35,6 +35,7 @@ export declare class TableState {
35
35
  private expandedColumns;
36
36
  visibleColumns: ObservableSet<string>;
37
37
  private visibleColumnsStorageKey;
38
+ private loadedColumns;
38
39
  /**
39
40
  * Creates the `RowState` for a given `GridTable`.
40
41
  */
@@ -46,6 +47,8 @@ export declare class TableState {
46
47
  get sortState(): SortState | undefined;
47
48
  setRows(rows: GridDataRow<any>[]): void;
48
49
  setColumns(columns: GridColumnWithId<any>[], visibleColumnsStorageKey: string | undefined): void;
50
+ loadExpandedColumns(column: GridColumnWithId<any>): Promise<void>;
51
+ getExpandedColumns(column: GridColumnWithId<any>): GridColumnWithId<any>[];
49
52
  setVisibleColumns(ids: string[]): void;
50
53
  get visibleColumnIds(): string[];
51
54
  get expandedColumnIds(): string[];
@@ -9,6 +9,8 @@ const mobx_1 = require("mobx");
9
9
  const react_1 = __importDefault(require("react"));
10
10
  const utils_1 = require("./utils");
11
11
  const visitor_1 = require("./visitor");
12
+ const utils_2 = require("../../../utils");
13
+ const columns_1 = require("./columns");
12
14
  /**
13
15
  * Stores the collapsed & selected state of rows.
14
16
  *
@@ -49,6 +51,8 @@ class TableState {
49
51
  // An observable set of column ids to keep track of which columns are visible
50
52
  this.visibleColumns = new mobx_1.ObservableSet();
51
53
  this.visibleColumnsStorageKey = "";
54
+ // Cache for already loaded expandable columns
55
+ this.loadedColumns = new Map();
52
56
  // Make ourselves an observable so that mobx will do caching of .collapseIds so
53
57
  // that it'll be a stable identity for GridTable to useMemo against.
54
58
  (0, mobx_1.makeAutoObservable)(this, {
@@ -185,6 +189,23 @@ class TableState {
185
189
  this.expandedColumns.replace(expandedColumnIds);
186
190
  }
187
191
  }
192
+ // load and trigger column to be expanded
193
+ async loadExpandedColumns(column) {
194
+ // if we dont have anything in our cache and our expanded columns are a function
195
+ if (!this.loadedColumns.has(column.id) && (0, utils_2.isFunction)(column.expandColumns)) {
196
+ // set our result to the function call of expandColumns
197
+ const result = await column.expandColumns();
198
+ // once we have the loaded columns, add result to local cache
199
+ this.loadedColumns.set(column.id, (0, columns_1.assignDefaultColumnIds)(result));
200
+ }
201
+ // once column is in local cache, then toggle
202
+ this.toggleExpandedColumn(column.id);
203
+ }
204
+ // if there is a promise, then load the expandable columns from the cache, if not then return the expandedColumns
205
+ getExpandedColumns(column) {
206
+ var _a, _b;
207
+ return (0, utils_2.isFunction)(column.expandColumns) ? (_a = this.loadedColumns.get(column.id)) !== null && _a !== void 0 ? _a : [] : (_b = column.expandColumns) !== null && _b !== void 0 ? _b : [];
208
+ }
188
209
  setVisibleColumns(ids) {
189
210
  sessionStorage.setItem(this.visibleColumnsStorageKey, JSON.stringify(ids));
190
211
  this.visibleColumns.replace(ids);
@@ -137,7 +137,7 @@ function calcColumnSizes(columns, tableWidth, tableMinWidthPx = 0, expandedColum
137
137
  // Otherwise return the `calc()` value
138
138
  return `((100% - ${claimedPercentages}% - ${claimedPixels}px) * (${myFr} / ${totalFr}))`;
139
139
  }
140
- let sizes = columns.map(({ id, expandedWidth, w: _w }) => {
140
+ const sizes = columns.map(({ id, expandedWidth, w: _w }) => {
141
141
  const w = expandedColumnIds.includes(id) && expandedWidth !== undefined ? expandedWidth : _w;
142
142
  if (typeof w === "undefined") {
143
143
  return fr(1);
@@ -167,17 +167,19 @@ function assignDefaultColumnIds(columns) {
167
167
  return columns.map((c, idx) => {
168
168
  var _a;
169
169
  const { expandColumns } = c;
170
- const expandColumnsWithId = expandColumns === null || expandColumns === void 0 ? void 0 : expandColumns.map((ec, ecIdx) => {
171
- var _a;
172
- return ({
173
- ...ec,
174
- id: (_a = ec.id) !== null && _a !== void 0 ? _a : `${(0, exports.generateColumnId)(idx)}_${ecIdx}`,
175
- // Defining this as undefined to make TS happy for now.
176
- // If we do not explicitly set to `undefined`, TS thinks `expandColumns` could still be of type GridColumn<T> (not WithId).
177
- // We only support a single level of expanding columns, so this is safe to do.
178
- expandColumns: undefined,
170
+ const expandColumnsWithId = (0, utils_2.isFunction)(expandColumns)
171
+ ? expandColumns
172
+ : expandColumns === null || expandColumns === void 0 ? void 0 : expandColumns.map((ec, ecIdx) => {
173
+ var _a;
174
+ return ({
175
+ ...ec,
176
+ id: (_a = ec.id) !== null && _a !== void 0 ? _a : `${(0, exports.generateColumnId)(idx)}_${ecIdx}`,
177
+ // Defining this as undefined to make TS happy for now.
178
+ // If we do not explicitly set to `undefined`, TS thinks `expandColumns` could still be of type GridColumn<T> (not WithId).
179
+ // We only support a single level of expanding columns, so this is safe to do.
180
+ expandColumns: undefined,
181
+ });
179
182
  });
180
- });
181
183
  return Object.assign(c, { id: (_a = c.id) !== null && _a !== void 0 ? _a : (0, exports.generateColumnId)(idx), expandColumns: expandColumnsWithId });
182
184
  });
183
185
  }
@@ -143,7 +143,7 @@ function maybeApplyFunction(row, maybeFn) {
143
143
  }
144
144
  exports.maybeApplyFunction = maybeApplyFunction;
145
145
  function matchesFilter(maybeContent, filter) {
146
- let value = filterValue(maybeContent);
146
+ const value = filterValue(maybeContent);
147
147
  if (typeof value === "string") {
148
148
  return value.toLowerCase().includes(filter.toLowerCase());
149
149
  }
@@ -1,6 +1,7 @@
1
1
  import { ReactNode } from "react";
2
2
  import type { IconKey } from "./";
3
3
  import { Margin, Only, Padding, Xss } from "../Css";
4
+ import { AnyObject } from "../types";
4
5
  export interface Tab<V extends string = string> {
5
6
  name: string;
6
7
  value: V;
@@ -48,9 +49,9 @@ interface RequiredRenderRouteTabs<V extends string, X> extends Omit<RouteTabsPro
48
49
  * and `TabContent` components directly.
49
50
  */
50
51
  export declare function TabsWithContent<V extends string, X extends Only<TabsContentXss, X>>(props: RequiredRenderTabs<V, X> | RequiredRenderRouteTabs<V, X>): import("@emotion/react/jsx-runtime").JSX.Element;
51
- export declare function TabContent<V extends string>(props: Omit<RequiredRenderTabs<V, {}>, "onChange"> | RequiredRenderRouteTabs<V, {}>): import("@emotion/react/jsx-runtime").JSX.Element;
52
+ export declare function TabContent<V extends string>(props: Omit<RequiredRenderTabs<V, AnyObject>, "onChange"> | RequiredRenderRouteTabs<V, AnyObject>): import("@emotion/react/jsx-runtime").JSX.Element;
52
53
  /** The top list of tabs. */
53
- export declare function Tabs<V extends string>(props: TabsProps<V, {}> | RouteTabsProps<V, {}>): import("@emotion/react/jsx-runtime").JSX.Element;
54
+ export declare function Tabs<V extends string>(props: TabsProps<V, AnyObject> | RouteTabsProps<V, AnyObject>): import("@emotion/react/jsx-runtime").JSX.Element;
54
55
  export declare function getTabStyles(): {
55
56
  baseStyles: {
56
57
  display: import("csstype").Property.Display | undefined;
@@ -1,4 +1,4 @@
1
- import React, { PropsWithChildren, ReactNode } from "react";
1
+ import React, { ReactNode } from "react";
2
2
  import { ToastTypes } from "./Toast";
3
3
  export interface ToastNoticeProps {
4
4
  type: ToastTypes;
@@ -9,5 +9,7 @@ export type ToastContextProps = {
9
9
  setNotice: React.Dispatch<React.SetStateAction<ToastNoticeProps | undefined>>;
10
10
  };
11
11
  export declare const ToastContext: React.Context<ToastContextProps>;
12
- export declare function ToastProvider(props: PropsWithChildren<{}>): import("@emotion/react/jsx-runtime").JSX.Element;
12
+ export declare function ToastProvider(props: {
13
+ children: ReactNode;
14
+ }): import("@emotion/react/jsx-runtime").JSX.Element;
13
15
  export declare function useToastContext(): ToastContextProps;
@@ -21,7 +21,7 @@ function Popover(props) {
21
21
  if ((_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.contains(e)) {
22
22
  return true;
23
23
  }
24
- //Do not close the Popover if the user is interacting with a tribute menu, dialog or alert on top of it, otherwise close it.
24
+ // Do not close the Popover if the user is interacting with a tribute menu, dialog or alert on top of it, otherwise close it.
25
25
  return !(e.closest(".tribute-container") || e.closest("[role='dialog']") || e.closest("[role='alert']"));
26
26
  },
27
27
  ...others,
@@ -0,0 +1,6 @@
1
+ import { MutableRefObject, RefObject } from "react";
2
+ /**
3
+ * Replaces code like `const ref = passedRef || useRef(null)` which was triggering rules-of-hooks violations. Used
4
+ * to sometimes accept a caller's ref, or if they did not pass one, use an internal one anyway.
5
+ */
6
+ export declare const useGetRef: <T extends HTMLElement>(maybeRef: RefObject<T> | undefined) => MutableRefObject<T | null>;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useGetRef = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Replaces code like `const ref = passedRef || useRef(null)` which was triggering rules-of-hooks violations. Used
7
+ * to sometimes accept a caller's ref, or if they did not pass one, use an internal one anyway.
8
+ */
9
+ const useGetRef = (maybeRef) => {
10
+ const newRef = (0, react_1.useRef)(null);
11
+ return maybeRef || newRef;
12
+ };
13
+ exports.useGetRef = useGetRef;
@@ -1,9 +1,10 @@
1
1
  import { ReactNode } from "react";
2
2
  import { Matcher } from "react-day-picker";
3
+ import { Properties } from "../../Css";
3
4
  import { DateFieldMode, dateFormats } from "./utils";
4
5
  import { TextFieldBaseProps } from "../TextFieldBase";
5
6
  import { DateRange } from "../../types";
6
- export interface DateFieldBaseProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "labelStyle" | "compact"> {
7
+ export interface DateFieldBaseProps extends Pick<TextFieldBaseProps<Properties>, "borderless" | "visuallyDisabled" | "labelStyle" | "compact"> {
7
8
  label: string;
8
9
  /** Called when the component loses focus */
9
10
  onBlur?: () => void;
@@ -125,8 +125,8 @@ function DateFieldBase(props) {
125
125
  setWipValue(value);
126
126
  setInputValue((_a = (isRangeMode ? (0, utils_1.formatDateRange)(props.value, dateFormat) : (0, utils_1.formatDate)(props.value, dateFormat))) !== null && _a !== void 0 ? _a : "");
127
127
  }
128
- // eslint-disable-next-line react-hooks/exhaustive-deps
129
128
  // We don't want to update the internal `wipValue` or `inputValue` back to `value` just because focus state changes or the overlay opens
129
+ // eslint-disable-next-line react-hooks/exhaustive-deps
130
130
  }, [value, dateFormat]);
131
131
  // Create a type safe `onChange` to handle both Single and Range date fields.
132
132
  const onChange = (0, react_1.useCallback)((d) => {
@@ -58,7 +58,7 @@ function parseDateString(str, format) {
58
58
  }
59
59
  const month = parseInt(split[0], 10) - 1;
60
60
  const day = parseInt(split[1], 10);
61
- let year = parseInt(split[2], 10);
61
+ const year = parseInt(split[2], 10);
62
62
  // This is also ~verbatim copy/pasted from react-day-picker
63
63
  if (isNaN(year) ||
64
64
  String(year).length > 4 ||
@@ -10,6 +10,7 @@ const Label_1 = require("../components/Label");
10
10
  const PresentationContext_1 = require("../components/PresentationContext");
11
11
  const Css_1 = require("../Css");
12
12
  const labelUtils_1 = require("../forms/labelUtils");
13
+ const useGetRef_1 = require("../hooks/useGetRef");
13
14
  const ErrorMessage_1 = require("./ErrorMessage");
14
15
  const defaultTestId_1 = require("../utils/defaultTestId");
15
16
  const useTestIds_1 = require("../utils/useTestIds");
@@ -28,7 +29,7 @@ function TextFieldBase(props) {
28
29
  const [isFocused, setIsFocused] = (0, react_1.useState)(false);
29
30
  const { hoverProps, isHovered } = (0, react_aria_1.useHover)({});
30
31
  const { focusWithinProps } = (0, react_aria_1.useFocusWithin)({ onFocusWithinChange: setIsFocused });
31
- const fieldRef = inputRef !== null && inputRef !== void 0 ? inputRef : (0, react_1.useRef)();
32
+ const fieldRef = (0, useGetRef_1.useGetRef)(inputRef);
32
33
  const maybeSmaller = compound ? 2 : 0;
33
34
  const fieldHeight = 40;
34
35
  const compactFieldHeight = 32;
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import { DateRange as _DateRange } from "react-day-picker";
2
3
  export type { _DateRange as DateRange };
3
4
  export type HasIdAndName<V = string> = {
@@ -12,3 +13,7 @@ export type CanCloseCheck = {
12
13
  continueText?: string;
13
14
  } | CheckFn;
14
15
  export declare function assertNever(x: never): never;
16
+ export type AnyObject = Record<string, unknown>;
17
+ export type ChildrenOnly = {
18
+ children: React.ReactNode;
19
+ };
@@ -28,4 +28,5 @@ export declare class EmptyRef<T> implements MutableRefObject<T> {
28
28
  }
29
29
  export declare const isAbsoluteUrl: (url: string) => boolean;
30
30
  export declare function areArraysEqual(a: any[], b: any[]): boolean;
31
- export declare function isPromise(obj: void | Promise<void>): obj is Promise<void>;
31
+ export declare function isPromise(obj: any | Promise<any>): obj is Promise<any>;
32
+ export declare function isFunction(f: any): f is Function;
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.isPromise = exports.areArraysEqual = exports.isAbsoluteUrl = exports.EmptyRef = exports.safeEntries = exports.noop = exports.omitKey = exports.safeKeys = exports.maybeCall = exports.toGroupState = exports.toToggleState = void 0;
17
+ exports.isFunction = exports.isPromise = exports.areArraysEqual = exports.isAbsoluteUrl = exports.EmptyRef = exports.safeEntries = exports.noop = exports.omitKey = exports.safeKeys = exports.maybeCall = exports.toGroupState = exports.toToggleState = void 0;
18
18
  /** Adapts our state to what useToggleState returns in a stateless manner. */
19
19
  function toToggleState(isSelected, onChange) {
20
20
  return {
@@ -86,3 +86,7 @@ function isPromise(obj) {
86
86
  return typeof obj === "object" && "then" in obj && typeof obj.then === "function";
87
87
  }
88
88
  exports.isPromise = isPromise;
89
+ function isFunction(f) {
90
+ return typeof f === "function";
91
+ }
92
+ exports.isFunction = isFunction;
@@ -1,5 +1,6 @@
1
1
  import { DecoratorFn } from "@storybook/react";
2
2
  import { ReactNode } from "react";
3
+ import { Properties } from "../Css";
3
4
  export declare function withRouter(url?: string, path?: string): DecoratorFn;
4
5
  type StoryParameters = {
5
6
  chromatic?: {
@@ -21,5 +22,5 @@ export declare const withBeamDecorator: (Story: () => JSX.Element) => import("@e
21
22
  * Decorator to set explicit width and height dimensions for a story.
22
23
  * Used to help Chromatic properly render positioned `fixed` components.
23
24
  */
24
- export declare const withDimensions: (width?: number | string, height?: number | string, xss?: {}) => (Story: () => JSX.Element) => import("@emotion/react/jsx-runtime").JSX.Element;
25
+ export declare const withDimensions: (width?: number | string, height?: number | string, xss?: Properties) => (Story: () => JSX.Element) => import("@emotion/react/jsx-runtime").JSX.Element;
25
26
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.233.0",
3
+ "version": "2.234.0",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",