@homebound/beam 2.179.1 → 2.181.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/Accordion.d.ts +20 -0
- package/dist/components/Accordion.js +42 -0
- package/dist/components/AccordionList.d.ts +9 -0
- package/dist/components/AccordionList.js +15 -0
- package/dist/components/Table/GridRowLookup.js +2 -5
- package/dist/components/Table/GridTable.d.ts +1 -35
- package/dist/components/Table/GridTable.js +28 -60
- package/dist/components/Table/columnSizes.js +2 -4
- package/package.json +1 -1
- package/dist/components/Table/nestedCards.d.ts +0 -111
- package/dist/components/Table/nestedCards.js +0 -230
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Dispatch, ReactNode, SetStateAction } from "react";
|
|
2
|
+
export interface AccordionProps {
|
|
3
|
+
title: ReactNode;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
defaultExpanded?: boolean;
|
|
7
|
+
size?: AccordionSize;
|
|
8
|
+
/** Adds a top border (enabled by default) */
|
|
9
|
+
topBorder?: boolean;
|
|
10
|
+
/** Adds a bottom border (disabled by default) */
|
|
11
|
+
bottomBorder?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Used by AccordionList
|
|
14
|
+
* Allows multiple accordions to be expanded simultaneously (enabled by default)
|
|
15
|
+
*/
|
|
16
|
+
index?: number;
|
|
17
|
+
setExpandedIndex?: Dispatch<SetStateAction<number | undefined>>;
|
|
18
|
+
}
|
|
19
|
+
export declare function Accordion(props: AccordionProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
20
|
+
export declare type AccordionSize = "xs" | "sm" | "md" | "lg";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Accordion = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const utils_1 = require("@react-aria/utils");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const react_aria_1 = require("react-aria");
|
|
8
|
+
const index_1 = require("../index");
|
|
9
|
+
function Accordion(props) {
|
|
10
|
+
const { title, children, size, disabled = false, defaultExpanded = false, topBorder = true, bottomBorder = false, index, setExpandedIndex, } = props;
|
|
11
|
+
const testIds = (0, index_1.useTestIds)(props, "accordion");
|
|
12
|
+
const id = (0, utils_1.useId)();
|
|
13
|
+
const [expanded, setExpanded] = (0, react_1.useState)(defaultExpanded);
|
|
14
|
+
const { isFocusVisible, focusProps } = (0, react_aria_1.useFocusRing)();
|
|
15
|
+
(0, react_1.useEffect)(() => { setExpanded(defaultExpanded); }, [defaultExpanded]);
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, testIds.container, { css: {
|
|
17
|
+
...index_1.Css.bGray400.if(topBorder).bt.if(bottomBorder).bb.$,
|
|
18
|
+
...(size ? index_1.Css.wPx(accordionSizes[size]).$ : {}),
|
|
19
|
+
} }, { children: [(0, jsx_runtime_1.jsxs)("button", Object.assign({}, testIds.title, focusProps, { "aria-controls": id, "aria-expanded": expanded, disabled: disabled, css: {
|
|
20
|
+
...index_1.Css.df.jcsb.gap2.aic.w100.p2.baseEm.outline("none").addIn(":hover", index_1.Css.bgGray100.$).$,
|
|
21
|
+
...(disabled && index_1.Css.gray500.$),
|
|
22
|
+
...(isFocusVisible && index_1.Css.boxShadow(`inset 0 0 0 2px ${index_1.Palette.LightBlue700}`).$),
|
|
23
|
+
}, onClick: () => {
|
|
24
|
+
setExpanded(!expanded);
|
|
25
|
+
if (setExpandedIndex)
|
|
26
|
+
setExpandedIndex(index);
|
|
27
|
+
} }, { children: [(0, jsx_runtime_1.jsx)("span", { children: title }, void 0), (0, jsx_runtime_1.jsx)("span", Object.assign({ css: {
|
|
28
|
+
transition: "transform 250ms linear",
|
|
29
|
+
transform: expanded ? "rotate(180deg)" : "rotate(0deg)",
|
|
30
|
+
} }, { children: (0, jsx_runtime_1.jsx)(index_1.Icon, { icon: "chevronDown" }, void 0) }), void 0)] }), void 0), (0, jsx_runtime_1.jsx)("div", Object.assign({}, testIds.details, { id: id, "aria-hidden": !expanded, css: {
|
|
31
|
+
// Use max-height for grow/shrink animation (remove close animation for AccordionList to avoid delays)
|
|
32
|
+
...index_1.Css.overflowHidden.maxhPx(1000).add("transition", `max-height ${expanded || !index ? "250ms" : "0"} ease-in-out`).$,
|
|
33
|
+
...(!expanded || disabled ? index_1.Css.maxh0.$ : {}),
|
|
34
|
+
} }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ css: index_1.Css.px2.pb2.pt1.$ }, { children: children }), void 0) }), void 0)] }), void 0));
|
|
35
|
+
}
|
|
36
|
+
exports.Accordion = Accordion;
|
|
37
|
+
const accordionSizes = {
|
|
38
|
+
xs: 240,
|
|
39
|
+
sm: 360,
|
|
40
|
+
md: 480,
|
|
41
|
+
lg: 600,
|
|
42
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AccordionProps, AccordionSize } from "./Accordion";
|
|
2
|
+
interface AccordionListProps {
|
|
3
|
+
accordions: AccordionProps[];
|
|
4
|
+
/** Allows multiple accordions to be expanded simultaneously (enabled by default) */
|
|
5
|
+
allowMultipleExpanded?: boolean;
|
|
6
|
+
size?: AccordionSize;
|
|
7
|
+
}
|
|
8
|
+
export declare function AccordionList(props: AccordionListProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AccordionList = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const react_1 = require("@emotion/react");
|
|
6
|
+
const react_2 = require("react");
|
|
7
|
+
const __1 = require("..");
|
|
8
|
+
const Accordion_1 = require("./Accordion");
|
|
9
|
+
function AccordionList(props) {
|
|
10
|
+
const { accordions, size, allowMultipleExpanded = true } = props;
|
|
11
|
+
const [expandedIndex, setExpandedIndex] = (0, react_2.useState)();
|
|
12
|
+
const tid = (0, __1.useTestIds)(props, "accordionList");
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: accordions.map((accordionProps, index, arr) => ((0, react_1.createElement)(Accordion_1.Accordion, { ...accordionProps, ...tid, key: index, size: size, bottomBorder: index === arr.length - 1, defaultExpanded: !allowMultipleExpanded && expandedIndex === index, index: index, setExpandedIndex: setExpandedIndex }))) }, void 0));
|
|
14
|
+
}
|
|
15
|
+
exports.AccordionList = AccordionList;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getKinds = exports.createRowLookup = void 0;
|
|
4
4
|
const GridTable_1 = require("./GridTable");
|
|
5
|
-
const nestedCards_1 = require("./nestedCards");
|
|
6
5
|
function createRowLookup(columns, filteredRows, virtuosoRef) {
|
|
7
6
|
return {
|
|
8
7
|
scrollTo(kind, id) {
|
|
@@ -15,14 +14,12 @@ function createRowLookup(columns, filteredRows, virtuosoRef) {
|
|
|
15
14
|
virtuosoRef.current.scrollToIndex({ index, behavior: "smooth" });
|
|
16
15
|
},
|
|
17
16
|
currentList() {
|
|
18
|
-
return
|
|
17
|
+
return filteredRows.map((r) => r[0]);
|
|
19
18
|
},
|
|
20
19
|
lookup(row, additionalFilter = () => true) {
|
|
21
20
|
var _a, _b;
|
|
22
21
|
var _c;
|
|
23
|
-
const rows = (0
|
|
24
|
-
.map((r) => r[0])
|
|
25
|
-
.filter(additionalFilter);
|
|
22
|
+
const rows = filteredRows.map((r) => r[0]).filter(additionalFilter);
|
|
26
23
|
// Ensure we have `result.kind = {}` for each kind
|
|
27
24
|
const result = Object.fromEntries(getKinds(columns).map((kind) => [kind, {}]));
|
|
28
25
|
// This is an admittedly cute/fancy scan, instead of just `rows.findIndex`, but
|
|
@@ -47,8 +47,6 @@ export interface GridStyle {
|
|
|
47
47
|
firstRowMessageCss?: Properties;
|
|
48
48
|
/** Applied on hover if a row has a rowLink/onClick set. */
|
|
49
49
|
rowHoverColor?: Palette;
|
|
50
|
-
/** Styling for our special "nested card" output mode. */
|
|
51
|
-
nestedCards?: NestedCardsStyle;
|
|
52
50
|
/** Default content to put into an empty cell */
|
|
53
51
|
emptyCell?: ReactNode;
|
|
54
52
|
presentationSettings?: Pick<PresentationFieldProps, "borderless" | "typeScale"> & Pick<PresentationContextProps, "wrap">;
|
|
@@ -62,38 +60,6 @@ export interface GridStyle {
|
|
|
62
60
|
/** Allows for customization of the background color used to denote an "active" row */
|
|
63
61
|
activeBgColor?: Palette;
|
|
64
62
|
}
|
|
65
|
-
export declare type NestedCardStyleByKind = Record<string, NestedCardStyle>;
|
|
66
|
-
export interface NestedCardsStyle {
|
|
67
|
-
/** Space between each card. */
|
|
68
|
-
spacerPx: number;
|
|
69
|
-
/** Width of the first and last "hidden" columns used to align nested columns. */
|
|
70
|
-
firstLastColumnWidth: number;
|
|
71
|
-
/**
|
|
72
|
-
* Per-kind styling for nested cards (see `cardStyle` if you only need a flat list of cards).
|
|
73
|
-
*
|
|
74
|
-
* Entries are optional, i.e. you can leave out kinds and they won't be wrapped/turned into cards.
|
|
75
|
-
*/
|
|
76
|
-
kinds: NestedCardStyleByKind;
|
|
77
|
-
/** Allows for customization of the border color used to denote an "active" row */
|
|
78
|
-
activeBColor?: Palette;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Styles for making cards nested within other cards.
|
|
82
|
-
*
|
|
83
|
-
* Because all of our output renderers (i.e. CSS grid and react-virtuoso) fundamentally need a flat
|
|
84
|
-
* list of elements, to create the look & feel of "nested cards", GridTable creates extra "chrome"
|
|
85
|
-
* elements like open card, close, and card padding.
|
|
86
|
-
*/
|
|
87
|
-
export interface NestedCardStyle {
|
|
88
|
-
/** The card background color. */
|
|
89
|
-
bgColor: string;
|
|
90
|
-
/** The optional border color, assumes 1px solid if set. */
|
|
91
|
-
bColor?: string;
|
|
92
|
-
/** I.e. 4px border radius. */
|
|
93
|
-
brPx: number;
|
|
94
|
-
/** The left/right padding of the card. */
|
|
95
|
-
pxPx: number;
|
|
96
|
-
}
|
|
97
63
|
export interface GridTableDefaults {
|
|
98
64
|
style: GridStyle | GridStyleDef;
|
|
99
65
|
stickyHeader: boolean;
|
|
@@ -216,7 +182,7 @@ export declare function GridTable<R extends Kinded, S = {}, X extends Only<GridT
|
|
|
216
182
|
* Calculates column widths using a flexible `calc()` definition that allows for consistent column alignment without the use of `<table />`, CSS Grid, etc layouts.
|
|
217
183
|
* Enforces only fixed-sized units (% and px)
|
|
218
184
|
*/
|
|
219
|
-
export declare function calcColumnSizes(columns: GridColumn<any>[],
|
|
185
|
+
export declare function calcColumnSizes(columns: GridColumn<any>[], tableWidth: number | undefined, tableMinWidthPx?: number): string[];
|
|
220
186
|
/**
|
|
221
187
|
* Given an ADT of type T, performs a look up and returns the type of kind K.
|
|
222
188
|
*
|
|
@@ -35,7 +35,6 @@ const columnSizes_1 = require("./columnSizes");
|
|
|
35
35
|
const GridRowLookup_1 = require("./GridRowLookup");
|
|
36
36
|
const GridSortContext_1 = require("./GridSortContext");
|
|
37
37
|
const GridTableApi_1 = require("./GridTableApi");
|
|
38
|
-
const nestedCards_1 = require("./nestedCards");
|
|
39
38
|
const RowState_1 = require("./RowState");
|
|
40
39
|
const SortHeader_1 = require("./SortHeader");
|
|
41
40
|
const sortRows_1 = require("./sortRows");
|
|
@@ -88,7 +87,7 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
88
87
|
* special styling to the row that uses `kind: "header"`.)
|
|
89
88
|
*/
|
|
90
89
|
function GridTable(props) {
|
|
91
|
-
var _a, _b, _c
|
|
90
|
+
var _a, _b, _c;
|
|
92
91
|
const { id = "gridTable", as = "div", columns, rows, style: maybeStyle = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = 0, xss, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, setRowCount, persistCollapse, resizeTarget, activeRowId, activeCellId, } = props;
|
|
93
92
|
// We only use this in as=virtual mode, but keep this here for rowLookup to use
|
|
94
93
|
const virtuosoRef = (0, react_1.useRef)(null);
|
|
@@ -143,7 +142,6 @@ function GridTable(props) {
|
|
|
143
142
|
stickyHeader,
|
|
144
143
|
// If we have a totals row then add the height of the totals row (52px) to the `stickyOffset` for the "header" kind
|
|
145
144
|
stickyOffset: hasTotalsRow && row.kind === "header" ? 52 + stickyOffset : stickyOffset,
|
|
146
|
-
openCards: nestedCards ? nestedCards.currentOpenCards() : undefined,
|
|
147
145
|
columnSizes,
|
|
148
146
|
level,
|
|
149
147
|
getCount,
|
|
@@ -156,10 +154,7 @@ function GridTable(props) {
|
|
|
156
154
|
const totalsRows = [];
|
|
157
155
|
const visibleDataRows = [];
|
|
158
156
|
const filteredRowIds = [];
|
|
159
|
-
// Misc state to track our nested card-ification, i.e. interleaved actual rows + chrome rows
|
|
160
|
-
const nestedCards = !!style.nestedCards && new nestedCards_1.NestedCards(columns, visibleDataRows, style.nestedCards);
|
|
161
157
|
function visit([row, children], level, visible) {
|
|
162
|
-
let isCard = visible && nestedCards && nestedCards.maybeOpenCard(row);
|
|
163
158
|
visible && visibleDataRows.push([row, makeRowComponent(row, level)]);
|
|
164
159
|
// This row may be invisible (because it's parent is collapsed), but we still want
|
|
165
160
|
// to consider it matched if it or it's parent matched a filter.
|
|
@@ -167,12 +162,10 @@ function GridTable(props) {
|
|
|
167
162
|
if (children.length) {
|
|
168
163
|
// Consider "isCollapsed" as true if the parent wasn't visible.
|
|
169
164
|
const isCollapsed = !visible || collapsedIds.includes(row.id);
|
|
170
|
-
|
|
171
|
-
visitRows(children, isCard, level + 1, !isCollapsed);
|
|
165
|
+
visitRows(children, level + 1, !isCollapsed);
|
|
172
166
|
}
|
|
173
|
-
visible && !(0, nestedCards_1.isLeafRow)(row) && isCard && nestedCards && nestedCards.closeCard();
|
|
174
167
|
}
|
|
175
|
-
function visitRows(rows,
|
|
168
|
+
function visitRows(rows, level, visible) {
|
|
176
169
|
const length = rows.length;
|
|
177
170
|
rows.forEach((row, i) => {
|
|
178
171
|
if (row[0].kind === "header") {
|
|
@@ -184,14 +177,11 @@ function GridTable(props) {
|
|
|
184
177
|
return;
|
|
185
178
|
}
|
|
186
179
|
visit(row, level, visible);
|
|
187
|
-
visible && addSpacer && nestedCards && i !== length - 1 && nestedCards.addSpacer();
|
|
188
180
|
});
|
|
189
181
|
}
|
|
190
182
|
// Call `visitRows` with our a pre-filtered set list
|
|
191
|
-
// If nestedCards is set, we assume the top-level kind is a card, and so should add spacers between them
|
|
192
183
|
const filteredRows = filterRows(api, columns, maybeSorted, filter);
|
|
193
|
-
visitRows(filteredRows,
|
|
194
|
-
nestedCards && nestedCards.done();
|
|
184
|
+
visitRows(filteredRows, 0, true);
|
|
195
185
|
return [headerRows, visibleDataRows, totalsRows, filteredRowIds];
|
|
196
186
|
}, [
|
|
197
187
|
as,
|
|
@@ -245,7 +235,7 @@ function GridTable(props) {
|
|
|
245
235
|
// behave semantically the same as `as=div` did for its tests.
|
|
246
236
|
const _as = as === "virtual" && runningInJest ? "div" : as;
|
|
247
237
|
const rowStateContext = (0, react_1.useMemo)(() => ({ rowState }), [rowState]);
|
|
248
|
-
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,
|
|
238
|
+
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, xss, virtuosoRef)] }), void 0) }), void 0));
|
|
249
239
|
}
|
|
250
240
|
exports.GridTable = GridTable;
|
|
251
241
|
// Determine which HTML element to use to build the GridTable
|
|
@@ -255,7 +245,7 @@ const renders = {
|
|
|
255
245
|
virtual: renderVirtual,
|
|
256
246
|
};
|
|
257
247
|
/** Renders table using divs with flexbox rows, which is the default render */
|
|
258
|
-
function renderDiv(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, _stickyHeader,
|
|
248
|
+
function renderDiv(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, _stickyHeader, xss, _virtuosoRef) {
|
|
259
249
|
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
260
250
|
// Use `fit-content` to ensure the width of the table takes up the full width of its content.
|
|
261
251
|
// Otherwise, the table's width would be that of its container, which may not be as wide as the table itself.
|
|
@@ -267,7 +257,9 @@ function renderDiv(style, id, columns, headerRows, totalsRows, visibleDataRows,
|
|
|
267
257
|
the + operator as an offset.
|
|
268
258
|
Inspired by: https://stackoverflow.com/a/25005740/2551333
|
|
269
259
|
*/
|
|
270
|
-
...(style.betweenRowsCss
|
|
260
|
+
...(style.betweenRowsCss
|
|
261
|
+
? Css_1.Css.addIn(`& > div:nth-of-type(n+${headerRows.length + totalsRows.length + 2}) > *`, style.betweenRowsCss).$
|
|
262
|
+
: {}),
|
|
271
263
|
...(style.firstNonHeaderRowCss ? Css_1.Css.addIn(`& > div:nth-of-type(2) > *`, style.firstNonHeaderRowCss).$ : {}),
|
|
272
264
|
...style.rootCss,
|
|
273
265
|
...(style.minWidthPx ? Css_1.Css.mwPx(style.minWidthPx).$ : {}),
|
|
@@ -275,7 +267,7 @@ function renderDiv(style, id, columns, headerRows, totalsRows, visibleDataRows,
|
|
|
275
267
|
}, "data-testid": id }, { children: [totalsRows.map(([, node]) => node), headerRows.map(([, node]) => node), firstRowMessage && ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...style.firstRowMessageCss }, "data-gridrow": true }, { children: firstRowMessage }), void 0)), visibleDataRows.map(([, node]) => node)] }), void 0));
|
|
276
268
|
}
|
|
277
269
|
/** Renders as a table, primarily/solely for good print support. */
|
|
278
|
-
function renderTable(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, _stickyHeader,
|
|
270
|
+
function renderTable(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, _stickyHeader, xss, _virtuosoRef) {
|
|
279
271
|
return ((0, jsx_runtime_1.jsxs)("table", Object.assign({ css: {
|
|
280
272
|
...Css_1.Css.w100.add("borderCollapse", "collapse").$,
|
|
281
273
|
...Css_1.Css.addIn("& > tbody > tr ", style.betweenRowsCss || {})
|
|
@@ -306,7 +298,7 @@ function renderTable(style, id, columns, headerRows, totalsRows, visibleDataRows
|
|
|
306
298
|
* [2]: https://github.com/tannerlinsley/react-virtual/issues/85
|
|
307
299
|
* [3]: https://github.com/tannerlinsley/react-virtual/issues/108
|
|
308
300
|
*/
|
|
309
|
-
function renderVirtual(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, stickyHeader,
|
|
301
|
+
function renderVirtual(style, id, columns, headerRows, totalsRows, visibleDataRows, firstRowMessage, stickyHeader, xss, virtuosoRef) {
|
|
310
302
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
311
303
|
const { footerStyle, listStyle } = (0, react_1.useMemo)(() => {
|
|
312
304
|
var _a;
|
|
@@ -316,7 +308,7 @@ function renderVirtual(style, id, columns, headerRows, totalsRows, visibleDataRo
|
|
|
316
308
|
return ((0, jsx_runtime_1.jsx)(react_virtuoso_1.Virtuoso, { overscan: 5, ref: virtuosoRef, components: {
|
|
317
309
|
// Applying a zIndex: 2 to ensure it stays on top of sticky columns
|
|
318
310
|
TopItemList: react_1.default.forwardRef((props, ref) => ((0, jsx_runtime_1.jsx)("div", Object.assign({}, props, { ref: ref, style: { ...props.style, ...{ zIndex: 2 } } }), void 0))),
|
|
319
|
-
List: VirtualRoot(listStyle, columns, id,
|
|
311
|
+
List: VirtualRoot(listStyle, columns, id, xss),
|
|
320
312
|
Footer: () => (0, jsx_runtime_1.jsx)("div", { css: footerStyle }, void 0),
|
|
321
313
|
},
|
|
322
314
|
// Pin/sticky both the header row(s) + firstRowMessage to the top
|
|
@@ -362,7 +354,7 @@ function renderVirtual(style, id, columns, headerRows, totalsRows, visibleDataRo
|
|
|
362
354
|
* different "component" per the given set of props (solely to capture as
|
|
363
355
|
* params that we can't pass through react-virtuoso's API as props).
|
|
364
356
|
*/
|
|
365
|
-
const VirtualRoot = (0, memoize_one_1.default)((gs, _columns, id,
|
|
357
|
+
const VirtualRoot = (0, memoize_one_1.default)((gs, _columns, id, xss) => {
|
|
366
358
|
return react_1.default.forwardRef(function VirtualRoot({ style, children }, ref) {
|
|
367
359
|
// This VirtualRoot list represent the header when no styles are given. The
|
|
368
360
|
// table list generally has styles to scroll the page for windowing.
|
|
@@ -387,7 +379,7 @@ const VirtualRoot = (0, memoize_one_1.default)((gs, _columns, id, _firstLastColu
|
|
|
387
379
|
* Calculates column widths using a flexible `calc()` definition that allows for consistent column alignment without the use of `<table />`, CSS Grid, etc layouts.
|
|
388
380
|
* Enforces only fixed-sized units (% and px)
|
|
389
381
|
*/
|
|
390
|
-
function calcColumnSizes(columns,
|
|
382
|
+
function calcColumnSizes(columns, tableWidth, tableMinWidthPx = 0) {
|
|
391
383
|
// For both default columns (1fr) as well as `w: 4fr` columns, we translate the width into an expression that looks like:
|
|
392
384
|
// calc((100% - allOtherPercent - allOtherPx) * ((myFr / totalFr))`
|
|
393
385
|
//
|
|
@@ -418,12 +410,11 @@ function calcColumnSizes(columns, firstLastColumnWidth, tableWidth, tableMinWidt
|
|
|
418
410
|
}, { claimedPercentages: 0, claimedPixels: 0, totalFr: 0 });
|
|
419
411
|
// This is our "fake but for some reason it lines up better" fr calc
|
|
420
412
|
function fr(myFr) {
|
|
413
|
+
console.log("tableWidth", tableWidth);
|
|
421
414
|
// If the tableWidth, then return a pixel value
|
|
422
415
|
if (tableWidth) {
|
|
423
416
|
const widthBasis = Math.max(tableWidth, tableMinWidthPx);
|
|
424
|
-
|
|
425
|
-
return `(${(widthBasis - (claimedPercentages / 100) * widthBasis - claimedPixels - (firstLastColumnWidth !== null && firstLastColumnWidth !== void 0 ? firstLastColumnWidth : 0) * 2) *
|
|
426
|
-
(myFr / totalFr)}px)`;
|
|
417
|
+
return `(${(widthBasis - (claimedPercentages / 100) * widthBasis - claimedPixels) * (myFr / totalFr)}px)`;
|
|
427
418
|
}
|
|
428
419
|
// Otherwise return the `calc()` value
|
|
429
420
|
return `((100% - ${claimedPercentages}% - ${claimedPixels}px) * (${myFr} / ${totalFr}))`;
|
|
@@ -447,8 +438,7 @@ function calcColumnSizes(columns, firstLastColumnWidth, tableWidth, tableMinWidt
|
|
|
447
438
|
return fr(w);
|
|
448
439
|
}
|
|
449
440
|
});
|
|
450
|
-
|
|
451
|
-
return !firstLastColumnWidth ? sizes : [`${firstLastColumnWidth}px`, ...sizes, `${firstLastColumnWidth}px`];
|
|
441
|
+
return sizes;
|
|
452
442
|
}
|
|
453
443
|
exports.calcColumnSizes = calcColumnSizes;
|
|
454
444
|
exports.nonKindGridColumnKeys = [
|
|
@@ -478,7 +468,7 @@ function getFirstOrLastCellCss(style, columnIndex, columns) {
|
|
|
478
468
|
// We extract GridRow to its own mini-component primarily so we can React.memo'ize it.
|
|
479
469
|
function GridRow(props) {
|
|
480
470
|
var _a;
|
|
481
|
-
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sortOn, sortState, setSortKey,
|
|
471
|
+
const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sortOn, sortState, setSortKey, columnSizes, level, getCount, api, ...others } = props;
|
|
482
472
|
const { rowState } = (0, react_1.useContext)(RowState_1.RowStateContext);
|
|
483
473
|
const rowId = `${row.kind}_${row.id}`;
|
|
484
474
|
const isActive = (0, hooks_1.useComputed)(() => rowState.activeRowId === rowId, [rowId, rowState]);
|
|
@@ -487,12 +477,6 @@ function GridRow(props) {
|
|
|
487
477
|
const isTotals = row.kind === "totals";
|
|
488
478
|
const rowStyle = rowStyles === null || rowStyles === void 0 ? void 0 : rowStyles[row.kind];
|
|
489
479
|
const Row = as === "table" ? "tr" : "div";
|
|
490
|
-
const openCardStyles = typeof openCards === "string"
|
|
491
|
-
? openCards
|
|
492
|
-
.split(":")
|
|
493
|
-
.map((openCardKind) => style.nestedCards.kinds[openCardKind])
|
|
494
|
-
.filter((style) => style)
|
|
495
|
-
: undefined;
|
|
496
480
|
const revealOnRowHoverClass = "revealOnRowHover";
|
|
497
481
|
const rowStyleCellCss = maybeApplyFunction(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.cellCss);
|
|
498
482
|
const rowCss = {
|
|
@@ -505,7 +489,6 @@ function GridRow(props) {
|
|
|
505
489
|
...maybeApplyFunction(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowCss),
|
|
506
490
|
// Maybe add the sticky header styles
|
|
507
491
|
...((isHeader || isTotals) && stickyHeader ? Css_1.Css.sticky.topPx(stickyOffset).z2.$ : undefined),
|
|
508
|
-
...(0, nestedCards_1.getNestedCardStyles)(row, openCardStyles, style, isActive),
|
|
509
492
|
...{
|
|
510
493
|
[` > .${revealOnRowHoverClass} > *`]: Css_1.Css.invisible.$,
|
|
511
494
|
[`:hover > .${revealOnRowHoverClass} > *`]: Css_1.Css.visible.$,
|
|
@@ -513,8 +496,8 @@ function GridRow(props) {
|
|
|
513
496
|
};
|
|
514
497
|
let currentColspan = 1;
|
|
515
498
|
let firstContentColumnStylesApplied = false;
|
|
516
|
-
|
|
517
|
-
var _a, _b, _c, _d, _e
|
|
499
|
+
return ((0, jsx_runtime_1.jsx)(Row, Object.assign({ css: rowCss }, others, { "data-gridrow": true }, getCount(row.id), { children: columns.map((column, columnIndex) => {
|
|
500
|
+
var _a, _b, _c, _d, _e;
|
|
518
501
|
const { wrapAction = true, isAction = false } = column;
|
|
519
502
|
const applyFirstContentColumnStyles = !isHeader && !isAction && !firstContentColumnStylesApplied;
|
|
520
503
|
firstContentColumnStylesApplied || (firstContentColumnStylesApplied = applyFirstContentColumnStyles);
|
|
@@ -538,25 +521,17 @@ function GridRow(props) {
|
|
|
538
521
|
const justificationCss = getJustification(column, maybeContent, as, alignment);
|
|
539
522
|
const content = toContent(maybeContent, isHeader, canSortColumn, sortOn === "client", style, as, alignment);
|
|
540
523
|
(0, sortRows_1.ensureClientSideSortValueIsSortable)(sortOn, isHeader, column, columnIndex, maybeContent);
|
|
541
|
-
const maybeNestedCardColumnIndex = columnIndex + (style.nestedCards ? 1 : 0);
|
|
542
524
|
const maybeSticky = (_b = ((isGridCellContent(maybeContent) && maybeContent.sticky) || column.sticky)) !== null && _b !== void 0 ? _b : undefined;
|
|
543
525
|
const maybeStickyColumnStyles = maybeSticky && columnSizes
|
|
544
526
|
? {
|
|
545
|
-
...Css_1.Css.sticky.z1.$,
|
|
546
|
-
// Need to apply a background to this cell to avoid content beneath it being shown when sticky.
|
|
547
|
-
// Assumes background is white for non-nestedCard styles. This can be overridden via cellCss.
|
|
548
|
-
...(((_c = style.nestedCards) === null || _c === void 0 ? void 0 : _c.kinds)
|
|
549
|
-
? Css_1.Css.bgColor((0, nestedCards_1.getCurrentBgColor)(row, openCardStyles, style.nestedCards.kinds)).$
|
|
550
|
-
: Css_1.Css.bgWhite.$),
|
|
527
|
+
...Css_1.Css.sticky.z1.bgWhite.$,
|
|
551
528
|
...(maybeSticky === "left"
|
|
552
|
-
? Css_1.Css.left(
|
|
553
|
-
? 0
|
|
554
|
-
: `calc(${columnSizes.slice(0, maybeNestedCardColumnIndex).join(" + ")})`).$
|
|
529
|
+
? Css_1.Css.left(columnIndex === 0 ? 0 : `calc(${columnSizes.slice(0, columnIndex).join(" + ")})`).$
|
|
555
530
|
: {}),
|
|
556
531
|
...(maybeSticky === "right"
|
|
557
|
-
? Css_1.Css.right(
|
|
532
|
+
? Css_1.Css.right(columnIndex + 1 === columnSizes.length
|
|
558
533
|
? 0
|
|
559
|
-
: `calc(${columnSizes.slice(
|
|
534
|
+
: `calc(${columnSizes.slice(columnIndex + 1 - columnSizes.length).join(" + ")})`).$
|
|
560
535
|
: {}),
|
|
561
536
|
}
|
|
562
537
|
: {};
|
|
@@ -589,15 +564,13 @@ function GridRow(props) {
|
|
|
589
564
|
// Then apply any totals-specific override
|
|
590
565
|
...(isTotals && style.totalsCellCss),
|
|
591
566
|
// Or level-specific styling
|
|
592
|
-
...(!isHeader && !isTotals && !!style.levels && ((
|
|
567
|
+
...(!isHeader && !isTotals && !!style.levels && ((_c = style.levels[level]) === null || _c === void 0 ? void 0 : _c.cellCss)),
|
|
593
568
|
// Level specific styling for the first content column
|
|
594
|
-
...(applyFirstContentColumnStyles && !!style.levels && ((
|
|
569
|
+
...(applyFirstContentColumnStyles && !!style.levels && ((_d = style.levels[level]) === null || _d === void 0 ? void 0 : _d.firstContentColumn)),
|
|
595
570
|
// The specific cell's css (if any from GridCellContent)
|
|
596
571
|
...rowStyleCellCss,
|
|
597
572
|
// Apply active row styling for non-nested card styles.
|
|
598
|
-
...(style.
|
|
599
|
-
? Css_1.Css.bgColor((_f = style.activeBgColor) !== null && _f !== void 0 ? _f : Css_1.Palette.LightBlue50).$
|
|
600
|
-
: {}),
|
|
573
|
+
...(isActive ? Css_1.Css.bgColor((_e = style.activeBgColor) !== null && _e !== void 0 ? _e : Css_1.Palette.LightBlue50).$ : {}),
|
|
601
574
|
// Add any cell specific style overrides
|
|
602
575
|
...(isGridCellContent(maybeContent) && maybeContent.typeScale ? Css_1.Css[maybeContent.typeScale].$ : {}),
|
|
603
576
|
// And any cell specific css
|
|
@@ -605,11 +578,7 @@ function GridRow(props) {
|
|
|
605
578
|
// Apply cell highlight styles to active cell and hover
|
|
606
579
|
...Css_1.Css.if(applyCellHighlight && isCellActive).br4.boxShadow(`inset 0 0 0 1px ${Css_1.Palette.LightBlue700}`).$,
|
|
607
580
|
// Define the width of the column on each cell. Supports col spans.
|
|
608
|
-
|
|
609
|
-
width: `calc(${columnSizes
|
|
610
|
-
.slice(maybeNestedCardColumnIndex, maybeNestedCardColumnIndex + currentColspan)
|
|
611
|
-
.join(" + ")})`,
|
|
612
|
-
},
|
|
581
|
+
width: `calc(${columnSizes.slice(columnIndex, columnIndex + currentColspan).join(" + ")})`,
|
|
613
582
|
...(column.mw ? Css_1.Css.mw(column.mw).$ : {}),
|
|
614
583
|
};
|
|
615
584
|
const cellClassNames = revealOnRowHover ? revealOnRowHoverClass : undefined;
|
|
@@ -623,7 +592,6 @@ function GridRow(props) {
|
|
|
623
592
|
: defaultRenderFn(as);
|
|
624
593
|
return renderFn(columnIndex, cellCss, content, row, rowStyle, cellClassNames, cellOnClick);
|
|
625
594
|
}) }), void 0));
|
|
626
|
-
return openCardStyles && openCardStyles.length > 0 ? (0, nestedCards_1.wrapCard)(openCardStyles, rowNode) : rowNode;
|
|
627
595
|
}
|
|
628
596
|
/**
|
|
629
597
|
* Memoizes GridRows so that re-rendering the table doesn't re-render every single row.
|
|
@@ -25,18 +25,16 @@ const use_debounce_1 = require("use-debounce");
|
|
|
25
25
|
* Disclaimer that we roll our own `fr` b/c we're not in CSS grid anymore.
|
|
26
26
|
*/
|
|
27
27
|
function useSetupColumnSizes(style, columns, resizeRef) {
|
|
28
|
-
var _a;
|
|
29
28
|
// Calculate the column sizes immediately rather than via the `debounce` method.
|
|
30
29
|
// We do this for Storybook integrations that may use MockDate. MockDate changes the behavior of `new Date()`,
|
|
31
30
|
// which is used internally by `useDebounce`, so the frozen clock means the callback is never called.
|
|
32
31
|
const calculateImmediately = (0, react_1.useRef)(true);
|
|
33
32
|
const [tableWidth, setTableWidth] = (0, react_1.useState)();
|
|
34
33
|
// Calc our initial/first render sizes where we won't have a width yet
|
|
35
|
-
const [columnSizes, setColumnSizes] = (0, react_1.useState)((0, GridTable_1.calcColumnSizes)(columns,
|
|
34
|
+
const [columnSizes, setColumnSizes] = (0, react_1.useState)((0, GridTable_1.calcColumnSizes)(columns, tableWidth, style.minWidthPx));
|
|
36
35
|
const setTableAndColumnWidths = (0, react_1.useCallback)((width) => {
|
|
37
|
-
var _a;
|
|
38
36
|
setTableWidth(width);
|
|
39
|
-
setColumnSizes((0, GridTable_1.calcColumnSizes)(columns,
|
|
37
|
+
setColumnSizes((0, GridTable_1.calcColumnSizes)(columns, width, style.minWidthPx));
|
|
40
38
|
}, [setTableWidth, setColumnSizes, columns, style]);
|
|
41
39
|
// Used to recalculate our columns sizes when columns change
|
|
42
40
|
(0, react_1.useEffect)(() => {
|
package/package.json
CHANGED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { ReactElement } from "react";
|
|
2
|
-
import { GridColumn, GridDataRow, GridStyle, Kinded, NestedCardsStyle, NestedCardStyle, NestedCardStyleByKind, RowTuple } from "./GridTable";
|
|
3
|
-
declare type Chrome = () => JSX.Element;
|
|
4
|
-
declare type ChromeBuffer = Chrome[];
|
|
5
|
-
/**
|
|
6
|
-
* A helper class to create our nested card DOM shenanigans.
|
|
7
|
-
*
|
|
8
|
-
* This acts as a one-off visitor that accepts "begin row", "between row",
|
|
9
|
-
* "end row" calls from GridTable while its translating the user's nested
|
|
10
|
-
* GridDataRows into a flat list of RowTuples, and interjects fake/chrome
|
|
11
|
-
* rows into `filteredRows` as necessary.
|
|
12
|
-
*
|
|
13
|
-
* Note that this class only handles *between row* chrome and that within
|
|
14
|
-
* a content row itself, the nested padding is handled separately by the
|
|
15
|
-
* GridRow component.
|
|
16
|
-
*/
|
|
17
|
-
export declare class NestedCards {
|
|
18
|
-
private readonly columns;
|
|
19
|
-
private readonly rows;
|
|
20
|
-
private readonly styles;
|
|
21
|
-
private readonly openCards;
|
|
22
|
-
private readonly chromeBuffer;
|
|
23
|
-
private chromeRowIndex;
|
|
24
|
-
constructor(columns: GridColumn<any>[], rows: RowTuple<any>[], styles: NestedCardsStyle);
|
|
25
|
-
/**
|
|
26
|
-
* Maybe add an opening Chrome row to the given `row` if its a nested card.
|
|
27
|
-
*
|
|
28
|
-
* @param row The row which will be opened. The open Chrome row will appear
|
|
29
|
-
* above this row.
|
|
30
|
-
*/
|
|
31
|
-
maybeOpenCard(row: GridDataRow<any>): boolean;
|
|
32
|
-
closeCard(): void;
|
|
33
|
-
addSpacer(): void;
|
|
34
|
-
/**
|
|
35
|
-
* Close the remaining open rows with a close Chrome row.
|
|
36
|
-
*
|
|
37
|
-
* @param row The row that is completing/closing nested open Chrome rows.
|
|
38
|
-
*/
|
|
39
|
-
done(): void;
|
|
40
|
-
/** Return a stable copy of the cards, so it won't change as we keep going. */
|
|
41
|
-
currentOpenCards(): string;
|
|
42
|
-
/**
|
|
43
|
-
* Takes the current Chrome row buffer of close row(s), spacers, and open row,
|
|
44
|
-
* and creates a single chrome DOM row.
|
|
45
|
-
*
|
|
46
|
-
* This allows a minimal amount of DOM overhead, insofar as to the css-grid or
|
|
47
|
-
* react-virtuoso we only add 1 extra DOM node between each row of content to
|
|
48
|
-
* achieve our nested card look & feel.
|
|
49
|
-
*
|
|
50
|
-
* i.e.:
|
|
51
|
-
* - chrome row (open)
|
|
52
|
-
* - card1 content row
|
|
53
|
-
* - chrome row (card2 open)
|
|
54
|
-
* - nested card2 content row
|
|
55
|
-
* - chrome row (card2 close, card1 close)
|
|
56
|
-
*/
|
|
57
|
-
maybeCreateChromeRow(): void;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Draws the rounded corners (either open or close) for a new card.
|
|
61
|
-
*
|
|
62
|
-
* We have to do this as synthetic rows to support:
|
|
63
|
-
*
|
|
64
|
-
* - parent card 1 open
|
|
65
|
-
* - parent card 1 content
|
|
66
|
-
* - ...N child cards...
|
|
67
|
-
* - parent card 1 close
|
|
68
|
-
*
|
|
69
|
-
* I.e. due to the flatness of our DOM, we inherently have to add a "close"
|
|
70
|
-
* row separate from the card's actual content.
|
|
71
|
-
*/
|
|
72
|
-
export declare function makeOpenOrCloseCard(openCards: string[], cardStyles: NestedCardStyleByKind, kind: "open" | "close"): Chrome;
|
|
73
|
-
/**
|
|
74
|
-
* Wraps a row within its parent cards. Creates a wrapping div to add the card padding.
|
|
75
|
-
* Adds non-leaf card padding and borders, e.g. if the current row is a non-leaf then it will already be in `openCards`
|
|
76
|
-
* Example:
|
|
77
|
-
* <div parent> <div child> <div grandchild /> </div> </div>
|
|
78
|
-
*/
|
|
79
|
-
export declare function wrapCard(openCards: NestedCardStyle[], row: JSX.Element): JSX.Element;
|
|
80
|
-
export declare function getNestedCardStyles(row: GridDataRow<any>, openCardStyles: NestedCardStyle[] | undefined, style: GridStyle, isActive: boolean): {
|
|
81
|
-
boxShadow?: import("csstype").Property.BoxShadow | undefined;
|
|
82
|
-
paddingTop?: import("csstype").Property.PaddingTop<0 | (string & {})> | undefined;
|
|
83
|
-
paddingBottom?: import("csstype").Property.PaddingBottom<0 | (string & {})> | undefined;
|
|
84
|
-
borderRadius?: import("csstype").Property.BorderRadius<0 | (string & {})> | undefined;
|
|
85
|
-
backgroundColor?: import("csstype").Property.BackgroundColor | undefined;
|
|
86
|
-
borderColor?: import("csstype").Property.BorderColor | undefined;
|
|
87
|
-
borderStyle?: import("csstype").Property.BorderStyle | undefined;
|
|
88
|
-
borderWidth?: import("csstype").Property.BorderWidth<0 | (string & {})> | undefined;
|
|
89
|
-
paddingLeft?: import("csstype").Property.PaddingLeft<0 | (string & {})> | undefined;
|
|
90
|
-
paddingRight?: import("csstype").Property.PaddingRight<0 | (string & {})> | undefined;
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Returns the background color for the row.
|
|
94
|
-
* Either based on the current row's card having a defined background color, or the last opened card's background color
|
|
95
|
-
* Defaults to White.
|
|
96
|
-
*/
|
|
97
|
-
export declare function getCurrentBgColor(row: GridDataRow<any>, openCardStyles: NestedCardStyle[] | undefined, nestedKinds: NestedCardStyleByKind): string;
|
|
98
|
-
/**
|
|
99
|
-
* Create a spacer between rows of children.
|
|
100
|
-
*
|
|
101
|
-
* Our height is not based on `openCards`, b/c for the top-most level, we won't
|
|
102
|
-
* have any open cards, but still want a space between top-level cards.
|
|
103
|
-
*/
|
|
104
|
-
export declare function makeSpacer(height: number, openCards: string[], styles: NestedCardsStyle): Chrome;
|
|
105
|
-
interface ChromeRowProps {
|
|
106
|
-
chromeBuffer: ChromeBuffer;
|
|
107
|
-
}
|
|
108
|
-
export declare function ChromeRow({ chromeBuffer }: ChromeRowProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
109
|
-
export declare function dropChromeRows<R extends Kinded>(rows: RowTuple<R>[]): [GridDataRow<R>, ReactElement][];
|
|
110
|
-
export declare function isLeafRow<R extends Kinded>(row: GridDataRow<R>): boolean;
|
|
111
|
-
export {};
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isLeafRow = exports.dropChromeRows = exports.ChromeRow = exports.makeSpacer = exports.getCurrentBgColor = exports.getNestedCardStyles = exports.wrapCard = exports.makeOpenOrCloseCard = exports.NestedCards = void 0;
|
|
4
|
-
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
-
const react_1 = require("react");
|
|
6
|
-
const Css_1 = require("../../Css");
|
|
7
|
-
/**
|
|
8
|
-
* A helper class to create our nested card DOM shenanigans.
|
|
9
|
-
*
|
|
10
|
-
* This acts as a one-off visitor that accepts "begin row", "between row",
|
|
11
|
-
* "end row" calls from GridTable while its translating the user's nested
|
|
12
|
-
* GridDataRows into a flat list of RowTuples, and interjects fake/chrome
|
|
13
|
-
* rows into `filteredRows` as necessary.
|
|
14
|
-
*
|
|
15
|
-
* Note that this class only handles *between row* chrome and that within
|
|
16
|
-
* a content row itself, the nested padding is handled separately by the
|
|
17
|
-
* GridRow component.
|
|
18
|
-
*/
|
|
19
|
-
class NestedCards {
|
|
20
|
-
constructor(columns,
|
|
21
|
-
// An array of rows which we will add open Chrome rows too to create the table.
|
|
22
|
-
rows, styles) {
|
|
23
|
-
this.columns = columns;
|
|
24
|
-
this.rows = rows;
|
|
25
|
-
this.styles = styles;
|
|
26
|
-
// A stack of the current cards we're showing
|
|
27
|
-
this.openCards = [];
|
|
28
|
-
// A buffer of the open/close/spacer rows we need between each content row.
|
|
29
|
-
this.chromeBuffer = [];
|
|
30
|
-
this.chromeRowIndex = 0;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Maybe add an opening Chrome row to the given `row` if its a nested card.
|
|
34
|
-
*
|
|
35
|
-
* @param row The row which will be opened. The open Chrome row will appear
|
|
36
|
-
* above this row.
|
|
37
|
-
*/
|
|
38
|
-
maybeOpenCard(row) {
|
|
39
|
-
const card = this.styles.kinds[row.kind];
|
|
40
|
-
// If this kind doesn't have a card defined or is a leaf card (which handle their own card styles in GridRow), then don't put it on the card stack
|
|
41
|
-
if (card && !isLeafRow(row)) {
|
|
42
|
-
this.openCards.push(row.kind);
|
|
43
|
-
this.chromeBuffer.push(makeOpenOrCloseCard(this.openCards, this.styles.kinds, "open"));
|
|
44
|
-
}
|
|
45
|
-
// But always close previous cards if needed
|
|
46
|
-
this.maybeCreateChromeRow();
|
|
47
|
-
return !!card;
|
|
48
|
-
}
|
|
49
|
-
closeCard() {
|
|
50
|
-
this.chromeBuffer.push(makeOpenOrCloseCard(this.openCards, this.styles.kinds, "close"));
|
|
51
|
-
this.openCards.pop();
|
|
52
|
-
}
|
|
53
|
-
addSpacer() {
|
|
54
|
-
this.chromeBuffer.push(makeSpacer(this.styles.spacerPx, this.openCards, this.styles));
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Close the remaining open rows with a close Chrome row.
|
|
58
|
-
*
|
|
59
|
-
* @param row The row that is completing/closing nested open Chrome rows.
|
|
60
|
-
*/
|
|
61
|
-
done() {
|
|
62
|
-
this.maybeCreateChromeRow();
|
|
63
|
-
}
|
|
64
|
-
/** Return a stable copy of the cards, so it won't change as we keep going. */
|
|
65
|
-
currentOpenCards() {
|
|
66
|
-
return this.openCards.join(":");
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Takes the current Chrome row buffer of close row(s), spacers, and open row,
|
|
70
|
-
* and creates a single chrome DOM row.
|
|
71
|
-
*
|
|
72
|
-
* This allows a minimal amount of DOM overhead, insofar as to the css-grid or
|
|
73
|
-
* react-virtuoso we only add 1 extra DOM node between each row of content to
|
|
74
|
-
* achieve our nested card look & feel.
|
|
75
|
-
*
|
|
76
|
-
* i.e.:
|
|
77
|
-
* - chrome row (open)
|
|
78
|
-
* - card1 content row
|
|
79
|
-
* - chrome row (card2 open)
|
|
80
|
-
* - nested card2 content row
|
|
81
|
-
* - chrome row (card2 close, card1 close)
|
|
82
|
-
*/
|
|
83
|
-
maybeCreateChromeRow() {
|
|
84
|
-
if (this.chromeBuffer.length > 0) {
|
|
85
|
-
this.rows.push([undefined, (0, jsx_runtime_1.jsx)(ChromeRow, { chromeBuffer: [...this.chromeBuffer] }, this.chromeRowIndex++)]);
|
|
86
|
-
// clear the Chrome buffer
|
|
87
|
-
this.chromeBuffer.splice(0, this.chromeBuffer.length);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
exports.NestedCards = NestedCards;
|
|
92
|
-
/**
|
|
93
|
-
* Draws the rounded corners (either open or close) for a new card.
|
|
94
|
-
*
|
|
95
|
-
* We have to do this as synthetic rows to support:
|
|
96
|
-
*
|
|
97
|
-
* - parent card 1 open
|
|
98
|
-
* - parent card 1 content
|
|
99
|
-
* - ...N child cards...
|
|
100
|
-
* - parent card 1 close
|
|
101
|
-
*
|
|
102
|
-
* I.e. due to the flatness of our DOM, we inherently have to add a "close"
|
|
103
|
-
* row separate from the card's actual content.
|
|
104
|
-
*/
|
|
105
|
-
function makeOpenOrCloseCard(openCards, cardStyles, kind) {
|
|
106
|
-
const scopeCards = [...openCards];
|
|
107
|
-
return () => {
|
|
108
|
-
let div = (0, jsx_runtime_1.jsx)("div", {}, void 0);
|
|
109
|
-
const place = kind === "open" ? "Top" : "Bottom";
|
|
110
|
-
const btOrBb = kind === "open" ? "bt" : "bb";
|
|
111
|
-
// Create nesting for the all open cards, i.e.:
|
|
112
|
-
//
|
|
113
|
-
// | card1 | card2 -------------- card2 | card1 |
|
|
114
|
-
// | card1 | card2 / ... card3 ... \ card2 | card1 |
|
|
115
|
-
// | card1 | card2 | ... card3 ... | card2 | card1 |
|
|
116
|
-
//
|
|
117
|
-
[...scopeCards]
|
|
118
|
-
.map((cardKind) => cardStyles[cardKind])
|
|
119
|
-
.reverse()
|
|
120
|
-
.forEach((card, i) => {
|
|
121
|
-
const first = i === 0;
|
|
122
|
-
div = ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: {
|
|
123
|
-
...Css_1.Css.bgColor(card.bgColor).pxPx(card.pxPx).$,
|
|
124
|
-
// Only the 1st div needs border left/right radius + border top/bottom.
|
|
125
|
-
...(first &&
|
|
126
|
-
Css_1.Css.add({
|
|
127
|
-
[`border${place}RightRadius`]: `${card.brPx}px`,
|
|
128
|
-
[`border${place}LeftRadius`]: `${card.brPx}px`,
|
|
129
|
-
}).hPx(card.brPx).$),
|
|
130
|
-
...(card.bColor && Css_1.Css.bc(card.bColor).bl.br.if(first)[btOrBb].$),
|
|
131
|
-
} }, { children: div }), void 0));
|
|
132
|
-
});
|
|
133
|
-
return div;
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
exports.makeOpenOrCloseCard = makeOpenOrCloseCard;
|
|
137
|
-
/**
|
|
138
|
-
* Wraps a row within its parent cards. Creates a wrapping div to add the card padding.
|
|
139
|
-
* Adds non-leaf card padding and borders, e.g. if the current row is a non-leaf then it will already be in `openCards`
|
|
140
|
-
* Example:
|
|
141
|
-
* <div parent> <div child> <div grandchild /> </div> </div>
|
|
142
|
-
*/
|
|
143
|
-
function wrapCard(openCards, row) {
|
|
144
|
-
let div = row;
|
|
145
|
-
[...openCards].reverse().forEach((card) => {
|
|
146
|
-
div = ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.h100.pxPx(card.pxPx).bgColor(card.bgColor).if(!!card.bColor).bc(card.bColor).bl.br.$ }, { children: div }), void 0));
|
|
147
|
-
});
|
|
148
|
-
return div;
|
|
149
|
-
}
|
|
150
|
-
exports.wrapCard = wrapCard;
|
|
151
|
-
function getNestedCardStyles(row, openCardStyles, style, isActive) {
|
|
152
|
-
var _a, _b, _c, _d, _e;
|
|
153
|
-
const leafCardStyles = isLeafRow(row) ? (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.kinds[row.kind] : undefined;
|
|
154
|
-
// Calculate the horizontal space already allocated by the open cards (paddings and borders)
|
|
155
|
-
const openCardWidth = openCardStyles ? openCardStyles.reduce((acc, o) => acc + o.pxPx + (o.bColor ? 1 : 0), 0) : 0;
|
|
156
|
-
// Subtract the openCardWidth from the `firstLastColumnWidth` to determine the amount of padding to add to this card.
|
|
157
|
-
// Also if it is a leaf card, then we need to additionally subtract out the border width to have it properly line up with the chrome rows
|
|
158
|
-
const currentCardPaddingWidth = ((_c = (_b = style.nestedCards) === null || _b === void 0 ? void 0 : _b.firstLastColumnWidth) !== null && _c !== void 0 ? _c : 0) - openCardWidth - ((leafCardStyles === null || leafCardStyles === void 0 ? void 0 : leafCardStyles.bColor) ? 1 : 0);
|
|
159
|
-
return {
|
|
160
|
-
// Card styles apply a calculated padding to ensure the content lines up properly across all columns
|
|
161
|
-
...(currentCardPaddingWidth ? Css_1.Css.pxPx(currentCardPaddingWidth).$ : undefined),
|
|
162
|
-
// Leaf cards define their own borders + padding
|
|
163
|
-
...(leafCardStyles
|
|
164
|
-
? // We can have versions of the same card as a leaf and not as a leaf.
|
|
165
|
-
// When it is not a leaf then it has chrome rows that create the top and bottom "padding" based on border-radius size. (brPx = "chrome" row height)
|
|
166
|
-
// When it is a leaf, then we need to apply the brPx to the row to ensure consistent spacing between leaf & non-leaf renders
|
|
167
|
-
// Additionally, if the leaf card has a border, then subtract the 1px border width from the padding to keep consistent with the "chrome" row
|
|
168
|
-
{
|
|
169
|
-
...Css_1.Css.pyPx(leafCardStyles.brPx - (leafCardStyles.bColor ? 1 : 0))
|
|
170
|
-
.borderRadius(`${leafCardStyles.brPx}px`)
|
|
171
|
-
.bgColor(leafCardStyles.bgColor)
|
|
172
|
-
.if(!!leafCardStyles.bColor)
|
|
173
|
-
.bc(leafCardStyles.bColor).ba.$,
|
|
174
|
-
...(isActive
|
|
175
|
-
? Css_1.Css.boxShadow(`0px 0px 0px 2px rgba(254,254,254,1), 0px 0px 0px 4px ${(_e = (_d = style.nestedCards) === null || _d === void 0 ? void 0 : _d.activeBColor) !== null && _e !== void 0 ? _e : Css_1.Palette.LightBlue700}`).$
|
|
176
|
-
: {}),
|
|
177
|
-
}
|
|
178
|
-
: undefined),
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
exports.getNestedCardStyles = getNestedCardStyles;
|
|
182
|
-
/**
|
|
183
|
-
* Returns the background color for the row.
|
|
184
|
-
* Either based on the current row's card having a defined background color, or the last opened card's background color
|
|
185
|
-
* Defaults to White.
|
|
186
|
-
*/
|
|
187
|
-
function getCurrentBgColor(row, openCardStyles, nestedKinds) {
|
|
188
|
-
if (nestedKinds[row.kind]) {
|
|
189
|
-
return nestedKinds[row.kind].bgColor;
|
|
190
|
-
}
|
|
191
|
-
if (openCardStyles && openCardStyles.length > 0) {
|
|
192
|
-
return openCardStyles[openCardStyles.length - 1].bgColor;
|
|
193
|
-
}
|
|
194
|
-
return Css_1.Palette.White;
|
|
195
|
-
}
|
|
196
|
-
exports.getCurrentBgColor = getCurrentBgColor;
|
|
197
|
-
/**
|
|
198
|
-
* Create a spacer between rows of children.
|
|
199
|
-
*
|
|
200
|
-
* Our height is not based on `openCards`, b/c for the top-most level, we won't
|
|
201
|
-
* have any open cards, but still want a space between top-level cards.
|
|
202
|
-
*/
|
|
203
|
-
function makeSpacer(height, openCards, styles) {
|
|
204
|
-
const scopeCards = [...openCards];
|
|
205
|
-
return () => {
|
|
206
|
-
let div = (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.hPx(height).$ }, void 0);
|
|
207
|
-
// Start at the current/inside card, and wrap outward padding + borders.
|
|
208
|
-
// | card1 | card2 | ... card3 ... | card2 | card1 |
|
|
209
|
-
[...scopeCards]
|
|
210
|
-
.map((cardKind) => styles.kinds[cardKind])
|
|
211
|
-
.reverse()
|
|
212
|
-
.forEach((card) => {
|
|
213
|
-
div = ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.bgColor(card.bgColor).pxPx(card.pxPx).if(!!card.bColor).bc(card.bColor).bl.br.$ }, { children: div }), void 0));
|
|
214
|
-
});
|
|
215
|
-
return div;
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
exports.makeSpacer = makeSpacer;
|
|
219
|
-
function ChromeRow({ chromeBuffer }) {
|
|
220
|
-
return ((0, jsx_runtime_1.jsx)("div", { children: chromeBuffer.map((c, i) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: c() }, i))) }, void 0));
|
|
221
|
-
}
|
|
222
|
-
exports.ChromeRow = ChromeRow;
|
|
223
|
-
function dropChromeRows(rows) {
|
|
224
|
-
return rows.filter(([r]) => !!r);
|
|
225
|
-
}
|
|
226
|
-
exports.dropChromeRows = dropChromeRows;
|
|
227
|
-
function isLeafRow(row) {
|
|
228
|
-
return row.children === undefined || row.children.length === 0;
|
|
229
|
-
}
|
|
230
|
-
exports.isLeafRow = isLeafRow;
|