@homebound/beam 2.147.0 → 2.148.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,7 +31,12 @@ function BeamProvider({ children, ...presentationProps }) {
31
31
  const [, tick] = (0, react_1.useReducer)((prev) => prev + 1, 0);
32
32
  const modalRef = (0, react_1.useRef)();
33
33
  const modalHeaderDiv = (0, react_1.useMemo)(() => document.createElement("div"), []);
34
- const modalBodyDiv = (0, react_1.useMemo)(() => document.createElement("div"), []);
34
+ const modalBodyDiv = (0, react_1.useMemo)(() => {
35
+ const el = document.createElement("div");
36
+ // Ensure this wrapping div takes up the full height of its container in the case of a virtualized table within.
37
+ el.style.height = "100%";
38
+ return el;
39
+ }, []);
35
40
  const modalCanCloseChecksRef = (0, react_1.useRef)([]);
36
41
  const modalFooterDiv = (0, react_1.useMemo)(() => document.createElement("div"), []);
37
42
  const drawerContentStackRef = (0, react_1.useRef)([]);
@@ -1,4 +1,4 @@
1
- import { MutableRefObject, ReactNode } from "react";
1
+ import { MutableRefObject, PropsWithChildren, ReactNode } from "react";
2
2
  import { Only, Xss } from "../../Css";
3
3
  export declare type ModalSize = "sm" | "md" | "lg" | "xl";
4
4
  export interface ModalProps {
@@ -36,9 +36,9 @@ export declare function ModalHeader({ children }: {
36
36
  children: ReactNode;
37
37
  }): JSX.Element;
38
38
  /** Provides consistent styling and the scrolling behavior for a modal's primary content. */
39
- export declare function ModalBody({ children }: {
40
- children: ReactNode;
41
- }): JSX.Element;
39
+ export declare function ModalBody({ children, virtualized, }: PropsWithChildren<{
40
+ virtualized?: boolean;
41
+ }>): JSX.Element;
42
42
  declare type ModalFooterXss = Xss<"justifyContent" | "alignItems">;
43
43
  /** Provides consistent styling for modal footers, i.e. where actions are placed. */
44
44
  export declare function ModalFooter<X extends Only<ModalFooterXss, X>>({ children, xss, }: {
@@ -39,7 +39,6 @@ function Modal(props) {
39
39
  const { modalProps } = (0, react_aria_1.useModal)();
40
40
  const { dialogProps, titleProps } = (0, react_aria_1.useDialog)({ role: "dialog" }, ref);
41
41
  const [[width, height], setSize] = (0, react_1.useState)(getSize(size));
42
- const contentRef = (0, react_1.useRef)(null);
43
42
  const modalBodyRef = (0, react_1.useRef)(null);
44
43
  const modalFooterRef = (0, react_1.useRef)(null);
45
44
  const modalHeaderRef = (0, react_1.useRef)(null);
@@ -49,7 +48,7 @@ function Modal(props) {
49
48
  api.current = { setSize: (size = "md") => setSize(getSize(size)) };
50
49
  }
51
50
  const [hasScroll, setHasScroll] = (0, react_1.useState)(forceScrolling !== null && forceScrolling !== void 0 ? forceScrolling : false);
52
- (0, resize_observer_1.default)(contentRef, ({ target }) => {
51
+ (0, resize_observer_1.default)(modalBodyRef, ({ target }) => {
53
52
  if (forceScrolling === undefined && !isFixedHeight) {
54
53
  setHasScroll(target.scrollHeight > target.clientHeight);
55
54
  }
@@ -68,9 +67,9 @@ function Modal(props) {
68
67
  return ((0, jsx_runtime_1.jsx)(react_aria_1.OverlayContainer, { children: (0, jsx_runtime_1.jsx)(form_state_1.AutoSaveStatusProvider, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.underlay.z4.$ }, underlayProps, testId.underlay, { children: (0, jsx_runtime_1.jsx)(react_aria_1.FocusScope, Object.assign({ contain: true, restoreFocus: true, autoFocus: true }, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.br24.bgWhite.bshModal.overflowHidden
69
68
  .maxh("90vh")
70
69
  .df.fdc.wPx(width)
71
- .mh((0, Css_1.px)(defaultMinHeight))
70
+ .mhPx(defaultMinHeight)
72
71
  .if(isFixedHeight)
73
- .hPx(height).$, ref: ref }, overlayProps, dialogProps, modalProps, testId, { children: [(0, jsx_runtime_1.jsxs)("header", Object.assign({ css: Css_1.Css.df.p3.fs0.if(drawHeaderBorder).bb.bGray200.$ }, { children: [(0, jsx_runtime_1.jsx)("h1", Object.assign({ css: Css_1.Css.fg1.xl2Em.gray900.$, ref: modalHeaderRef }, titleProps, testId.title), void 0), (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.fs0.pl1.$ }, { children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, Object.assign({ icon: "x", onClick: closeModal }, testId.titleClose), void 0) }), void 0)] }), void 0), (0, jsx_runtime_1.jsxs)("main", Object.assign({ ref: contentRef, css: Css_1.Css.fg1.overflowYAuto.if(hasScroll).bb.bGray200.if(!!forceScrolling).overflowYScroll.$ }, { children: [content, (0, jsx_runtime_1.jsx)("div", { ref: modalBodyRef }, void 0)] }), void 0), (0, jsx_runtime_1.jsx)("footer", Object.assign({ css: Css_1.Css.fs0.$ }, { children: (0, jsx_runtime_1.jsx)("div", { ref: modalFooterRef }, void 0) }), void 0)] }), void 0) }), void 0) }), void 0) }, void 0) }, void 0));
72
+ .hPx(height).$, ref: ref }, overlayProps, dialogProps, modalProps, testId, { children: [(0, jsx_runtime_1.jsxs)("header", Object.assign({ css: Css_1.Css.df.p3.fs0.if(drawHeaderBorder).bb.bGray200.$ }, { children: [(0, jsx_runtime_1.jsx)("h1", Object.assign({ css: Css_1.Css.fg1.xl2Em.gray900.$, ref: modalHeaderRef }, titleProps, testId.title), void 0), (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.fs0.pl1.$ }, { children: (0, jsx_runtime_1.jsx)(IconButton_1.IconButton, Object.assign({ icon: "x", onClick: closeModal }, testId.titleClose), void 0) }), void 0)] }), void 0), (0, jsx_runtime_1.jsx)("main", Object.assign({ ref: modalBodyRef, css: Css_1.Css.fg1.overflowYAuto.if(hasScroll).bb.bGray200.if(!!forceScrolling).overflowYScroll.$ }, { children: content }), void 0), (0, jsx_runtime_1.jsx)("footer", Object.assign({ css: Css_1.Css.fs0.$ }, { children: (0, jsx_runtime_1.jsx)("div", { ref: modalFooterRef }, void 0) }), void 0)] }), void 0) }), void 0) }), void 0) }, void 0) }, void 0));
74
73
  }
75
74
  exports.Modal = Modal;
76
75
  function ModalHeader({ children }) {
@@ -79,10 +78,12 @@ function ModalHeader({ children }) {
79
78
  }
80
79
  exports.ModalHeader = ModalHeader;
81
80
  /** Provides consistent styling and the scrolling behavior for a modal's primary content. */
82
- function ModalBody({ children }) {
81
+ function ModalBody({ children, virtualized = false, }) {
83
82
  const { modalBodyDiv } = (0, BeamContext_1.useBeamContext)();
84
83
  const testId = (0, utils_1.useTestIds)({}, testIdPrefix);
85
- return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.px3.$ }, testId.content, { children: children }), void 0), modalBodyDiv);
84
+ return (0, react_dom_1.createPortal)(
85
+ // If `virtualized`, then we are expecting the `children` will handle their own scrollbar, so have the overflow hidden and adjust padding
86
+ (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.h100.if(virtualized).overflowHidden.pl3.else.px3.$ }, testId.content, { children: children }), void 0), modalBodyDiv);
86
87
  }
87
88
  exports.ModalBody = ModalBody;
88
89
  /** Provides consistent styling for modal footers, i.e. where actions are placed. */
@@ -8,3 +8,4 @@ export interface TestModalContentProps {
8
8
  /** A fake modal content component that we share across the modal and superdrawer stories. */
9
9
  export declare function TestModalContent(props: TestModalContentProps): import("@emotion/react/jsx-runtime").JSX.Element;
10
10
  export declare function TestModalFilterTable(): import("@emotion/react/jsx-runtime").JSX.Element;
11
+ export declare function VirtualizedTable(): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TestModalFilterTable = exports.TestModalContent = void 0;
3
+ exports.VirtualizedTable = exports.TestModalFilterTable = exports.TestModalContent = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const addon_actions_1 = require("@storybook/addon-actions");
6
6
  const react_1 = require("react");
7
7
  const Button_1 = require("../Button");
8
+ const Layout_1 = require("../Layout");
8
9
  const Modal_1 = require("./Modal");
9
10
  const useModal_1 = require("./useModal");
10
11
  const Table_1 = require("../Table");
@@ -30,6 +31,12 @@ function TestModalFilterTable() {
30
31
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Modal_1.ModalHeader, { children: "Filterable table" }, void 0), (0, jsx_runtime_1.jsxs)(Modal_1.ModalBody, { children: [(0, jsx_runtime_1.jsx)(inputs_1.TextField, { label: "Search", value: filter, onChange: setFilter }, void 0), (0, jsx_runtime_1.jsx)(Table_1.GridTable, { columns: columns, rows: rows, filter: filter, xss: Css_1.Css.mt1.$ }, void 0)] }, void 0), (0, jsx_runtime_1.jsx)(Modal_1.ModalFooter, { children: (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Cancel", onClick: closeModal, variant: "tertiary" }, void 0) }, void 0)] }, void 0));
31
32
  }
32
33
  exports.TestModalFilterTable = TestModalFilterTable;
34
+ function VirtualizedTable() {
35
+ const [filter, setFilter] = (0, react_1.useState)();
36
+ const { closeModal } = (0, useModal_1.useModal)();
37
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Modal_1.ModalHeader, { children: "Filterable table" }, void 0), (0, jsx_runtime_1.jsx)(Modal_1.ModalBody, Object.assign({ virtualized: true }, { children: (0, jsx_runtime_1.jsxs)(Layout_1.ScrollableParent, Object.assign({ xss: Css_1.Css.h100.$ }, { children: [(0, jsx_runtime_1.jsx)(inputs_1.TextField, { label: "Search", value: filter, onChange: setFilter }, void 0), (0, jsx_runtime_1.jsx)(Layout_1.ScrollableContent, Object.assign({ virtualized: true }, { children: (0, jsx_runtime_1.jsx)(Table_1.GridTable, { as: "virtual", columns: columns, rows: rows, filter: filter, xss: Css_1.Css.mt1.$ }, void 0) }), void 0)] }), void 0) }), void 0), (0, jsx_runtime_1.jsx)(Modal_1.ModalFooter, { children: (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Cancel", onClick: closeModal, variant: "tertiary" }, void 0) }, void 0)] }, void 0));
38
+ }
39
+ exports.VirtualizedTable = VirtualizedTable;
33
40
  const users = [
34
41
  { id: "1", name: "Iron Man", role: "Leader" },
35
42
  { id: "2", name: "Captain America", role: "Carries the cool shield" },
@@ -243,7 +243,7 @@ function GridTable(props) {
243
243
  // behave semantically the same as `as=div` did for its tests.
244
244
  const _as = as === "virtual" && runningInJest ? "div" : as;
245
245
  const rowStateContext = (0, react_1.useMemo)(() => ({ rowState }), [rowState]);
246
- return ((0, jsx_runtime_1.jsx)(RowState_1.RowStateContext.Provider, Object.assign({ value: rowStateContext }, { children: (0, jsx_runtime_1.jsxs)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps: fieldProps, wrap: (_c = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _c === void 0 ? void 0 : _c.wrap }, { children: [(0, jsx_runtime_1.jsx)("div", { ref: resizeRef, css: Css_1.Css.w100.$ }, void 0), renders[_as](style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, stickyHeader, (_d = style.nestedCards) === null || _d === void 0 ? void 0 : _d.firstLastColumnWidth, xss, virtuosoRef)] }), void 0) }), void 0));
246
+ return ((0, jsx_runtime_1.jsx)(RowState_1.RowStateContext.Provider, Object.assign({ value: rowStateContext }, { children: (0, jsx_runtime_1.jsxs)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps: fieldProps, wrap: (_c = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _c === void 0 ? void 0 : _c.wrap }, { children: [(0, jsx_runtime_1.jsx)("div", { ref: resizeRef, css: Css_1.Css.w100.if(as === "virtual").w("calc(100% - 20px)").$ }, void 0), renders[_as](style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, stickyHeader, (_d = style.nestedCards) === null || _d === void 0 ? void 0 : _d.firstLastColumnWidth, xss, virtuosoRef)] }), void 0) }), void 0));
247
247
  }
248
248
  exports.GridTable = GridTable;
249
249
  // Determine which HTML element to use to build the GridTable
@@ -814,14 +814,13 @@ function filterRows(api, columns, rows, filter) {
814
814
  const matches = row.kind === "header" ||
815
815
  row.kind === "totals" ||
816
816
  filters.length === 0 ||
817
- !!row.pin ||
818
817
  filters.every((f) => columns.map((c) => applyRowFn(c, row, api, 0)).some((maybeContent) => matchesFilter(maybeContent, f)));
819
818
  if (matches) {
820
819
  return acc.concat([[row, (_b = (_a = row.children) === null || _a === void 0 ? void 0 : _a.reduce(acceptAll, [])) !== null && _b !== void 0 ? _b : []]]);
821
820
  }
822
821
  else {
823
822
  const matchedChildren = (_d = (_c = row.children) === null || _c === void 0 ? void 0 : _c.reduce(filterFn, [])) !== null && _d !== void 0 ? _d : [];
824
- if (matchedChildren.length > 0) {
823
+ if (matchedChildren.length > 0 || row.pin) {
825
824
  return acc.concat([[row, matchedChildren]]);
826
825
  }
827
826
  else {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "./Css";
2
- export type { HasIdAndName, CheckFn } from "./types";
2
+ export type { HasIdAndName, CheckFn, DateRange } from "./types";
3
3
  export * from "./components";
4
4
  export * from "./forms";
5
5
  export * from "./hooks";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.147.0",
3
+ "version": "2.148.1",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",