@homebound/beam 2.146.2 → 2.148.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/BeamContext.js +6 -1
- package/dist/components/Modal/Modal.d.ts +4 -4
- package/dist/components/Modal/Modal.js +7 -6
- package/dist/components/Modal/TestModalContent.d.ts +1 -0
- package/dist/components/Modal/TestModalContent.js +8 -1
- package/dist/components/Table/GridTable.js +16 -10
- package/dist/components/Table/sortRows.js +2 -2
- package/package.json +1 -1
|
@@ -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)(() =>
|
|
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
|
-
|
|
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)(
|
|
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
|
-
.
|
|
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.
|
|
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)(
|
|
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
|
|
@@ -802,25 +802,31 @@ function resolveStyles(style) {
|
|
|
802
802
|
* We return a copy of `[Parent, [Child]]` tuples so that we don't modify the `GridDataRow.children`.
|
|
803
803
|
*/
|
|
804
804
|
function filterRows(api, columns, rows, filter) {
|
|
805
|
-
// Make a
|
|
806
|
-
function
|
|
805
|
+
// Make a functions to do recursion
|
|
806
|
+
function acceptAll(acc, row) {
|
|
807
807
|
var _a, _b;
|
|
808
|
+
return acc.concat([[row, (_b = (_a = row.children) === null || _a === void 0 ? void 0 : _a.reduce(acceptAll, [])) !== null && _b !== void 0 ? _b : []]]);
|
|
809
|
+
}
|
|
810
|
+
function filterFn(acc, row) {
|
|
811
|
+
var _a, _b, _c, _d;
|
|
808
812
|
// Break up "foo bar" into `[foo, bar]` and a row must match both `foo` and `bar`
|
|
809
813
|
const filters = (filter && filter.split(/ +/)) || [];
|
|
810
814
|
const matches = row.kind === "header" ||
|
|
811
815
|
row.kind === "totals" ||
|
|
812
816
|
filters.length === 0 ||
|
|
813
|
-
!!row.pin ||
|
|
814
817
|
filters.every((f) => columns.map((c) => applyRowFn(c, row, api, 0)).some((maybeContent) => matchesFilter(maybeContent, f)));
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
if (matches || matchedChildren.length > 0) {
|
|
818
|
-
return acc.concat([[row, matchedChildren]]);
|
|
818
|
+
if (matches) {
|
|
819
|
+
return acc.concat([[row, (_b = (_a = row.children) === null || _a === void 0 ? void 0 : _a.reduce(acceptAll, [])) !== null && _b !== void 0 ? _b : []]]);
|
|
819
820
|
}
|
|
820
821
|
else {
|
|
821
|
-
|
|
822
|
+
const matchedChildren = (_d = (_c = row.children) === null || _c === void 0 ? void 0 : _c.reduce(filterFn, [])) !== null && _d !== void 0 ? _d : [];
|
|
823
|
+
if (matchedChildren.length > 0 || row.pin) {
|
|
824
|
+
return acc.concat([[row, matchedChildren]]);
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
return acc;
|
|
828
|
+
}
|
|
822
829
|
}
|
|
823
830
|
}
|
|
824
|
-
;
|
|
825
831
|
return rows.reduce(filterFn, []);
|
|
826
832
|
}
|
|
@@ -25,9 +25,9 @@ function sortBatch(columns, batch, sortState, caseSensitive) {
|
|
|
25
25
|
const v2 = sortValue((0, GridTable_1.applyRowFn)(column, b, {}, 0), caseSensitive);
|
|
26
26
|
const v1e = v1 === null || v1 === undefined;
|
|
27
27
|
const v2e = v2 === null || v2 === undefined;
|
|
28
|
-
if (a.pin || b.pin) {
|
|
28
|
+
if ((a.pin || b.pin) && !(a.pin === b.pin)) {
|
|
29
29
|
const ap = a.pin === "first" ? -1 : a.pin === "last" ? 1 : 0;
|
|
30
|
-
const bp = b.pin === "first" ? -1 :
|
|
30
|
+
const bp = b.pin === "first" ? -1 : b.pin === "last" ? 1 : 0;
|
|
31
31
|
return ap === bp ? 0 : ap < bp ? -1 : 1;
|
|
32
32
|
}
|
|
33
33
|
else if ((v1e && v2e) || v1 === v2) {
|