@homebound/beam 2.105.6 → 2.105.9

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.
@@ -12,7 +12,7 @@ function multiFilter(props) {
12
12
  exports.multiFilter = multiFilter;
13
13
  class MultiFilter extends BaseFilter_1.BaseFilter {
14
14
  render(value, setValue, tid, inModal, vertical) {
15
- if (inModal && this.props.options.length <= 8) {
15
+ if (inModal && this.props.options.length > 0 && this.props.options.length <= 8) {
16
16
  return ((0, jsx_runtime_1.jsx)(ToggleChipGroup_1.ToggleChipGroup, Object.assign({ label: this.label, options: this.props.options.map((o) => ({
17
17
  label: this.props.getOptionLabel(o),
18
18
  value: this.props.getOptionValue(o),
@@ -48,6 +48,8 @@ export interface GridStyle {
48
48
  /** Default content to put into an empty cell */
49
49
  emptyCell?: ReactNode;
50
50
  presentationSettings?: Pick<PresentationFieldProps, "borderless" | "typeScale"> & Pick<PresentationContextProps, "wrap">;
51
+ /** Minimum table width in pixels. Used when calculating columns sizes */
52
+ minWidthPx?: number;
51
53
  }
52
54
  export declare type NestedCardStyleByKind = Record<string, NestedCardStyle>;
53
55
  export interface NestedCardsStyle {
@@ -164,6 +166,8 @@ export interface GridTableProps<R extends Kinded, S, X> {
164
166
  xss?: X;
165
167
  /** Experimental API allowing one to scroll to a table index. Primarily intended for stories at the moment */
166
168
  api?: MutableRefObject<GridTableApi | undefined>;
169
+ /** Experimental, expecting to be removed - Specify the element in which the table should resize its columns against. If not set, the table will resize columns based on its owns container's width */
170
+ resizeTarget?: MutableRefObject<HTMLElement | null>;
167
171
  }
168
172
  /** NOTE: This API is experimental and primarily intended for story and testing purposes */
169
173
  export declare type GridTableApi = {
@@ -190,7 +194,7 @@ export declare function GridTable<R extends Kinded, S = {}, X extends Only<GridT
190
194
  * Calculates column widths using a flexible `calc()` definition that allows for consistent column alignment without the use of `<table />`, CSS Grid, etc layouts.
191
195
  * Enforces only fixed-sized units (% and px)
192
196
  */
193
- export declare function calcColumnSizes(columns: GridColumn<any>[], firstLastColumnWidth: number | undefined): string[];
197
+ export declare function calcColumnSizes(columns: GridColumn<any>[], firstLastColumnWidth: number | undefined, tableWidth: number | undefined, tableMinWidthPx?: number): string[];
194
198
  /**
195
199
  * Given an ADT of type T, performs a look up and returns the type of kind K.
196
200
  *
@@ -24,6 +24,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.matchesFilter = exports.GridCollapseContext = exports.applyRowFn = exports.calcColumnSizes = exports.GridTable = exports.setGridTableDefaults = exports.setDefaultStyle = exports.setRunningInJest = exports.emptyCell = exports.DESC = exports.ASC = void 0;
26
26
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
27
+ const utils_1 = require("@react-aria/utils");
27
28
  const memoize_one_1 = __importDefault(require("memoize-one"));
28
29
  const mobx_react_1 = require("mobx-react");
29
30
  const react_1 = __importStar(require("react"));
@@ -39,6 +40,7 @@ const sortRows_1 = require("./sortRows");
39
40
  const useSortState_1 = require("./useSortState");
40
41
  const Css_1 = require("../../Css");
41
42
  const tinycolor2_1 = __importDefault(require("tinycolor2"));
43
+ const use_debounce_1 = require("use-debounce");
42
44
  const _1 = require(".");
43
45
  exports.ASC = "ASC";
44
46
  exports.DESC = "DESC";
@@ -81,10 +83,11 @@ exports.setGridTableDefaults = setGridTableDefaults;
81
83
  */
82
84
  function GridTable(props) {
83
85
  var _a, _b, _c, _d, _e;
84
- const { id = "gridTable", as = "div", columns, rows, style = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = "0", xss, sorting, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, setRowCount, observeRows, persistCollapse, api, } = props;
86
+ const { id = "gridTable", as = "div", columns, rows, style = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = "0", xss, sorting, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, setRowCount, observeRows, persistCollapse, api, resizeTarget, } = props;
85
87
  const [collapsedIds, collapseAllContext, collapseRowContext] = useToggleIds(rows, persistCollapse);
86
88
  // We only use this in as=virtual mode, but keep this here for rowLookup to use
87
89
  const virtuosoRef = (0, react_1.useRef)(null);
90
+ const tableRef = (0, react_1.useRef)(null);
88
91
  if (api) {
89
92
  api.current = {
90
93
  scrollToIndex: (index) => virtuosoRef.current && virtuosoRef.current.scrollToIndex(index),
@@ -98,7 +101,21 @@ function GridTable(props) {
98
101
  }
99
102
  return rows;
100
103
  }, [columns, rows, sorting, sortState]);
101
- const columnSizes = (0, react_1.useMemo)(() => { var _a; return calcColumnSizes(columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth); }, [columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth]);
104
+ const [tableWidth, setTableWidth] = (0, react_1.useState)();
105
+ // Calc our initial/first render sizes where we won't have a width yet
106
+ const [columnSizes, setColumnSizes] = (0, react_1.useState)(calcColumnSizes(columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth, tableWidth, style.minWidthPx));
107
+ const setTableWidthDebounced = (0, use_debounce_1.useDebouncedCallback)((width) => {
108
+ var _a;
109
+ setTableWidth(width);
110
+ setColumnSizes(calcColumnSizes(columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth, width, style.minWidthPx));
111
+ }, 100);
112
+ const onResize = (0, react_1.useCallback)(() => {
113
+ const target = (resizeTarget === null || resizeTarget === void 0 ? void 0 : resizeTarget.current) ? resizeTarget.current : tableRef.current;
114
+ if (target && target.clientWidth !== tableWidth) {
115
+ setTableWidthDebounced(target.clientWidth);
116
+ }
117
+ }, [resizeTarget === null || resizeTarget === void 0 ? void 0 : resizeTarget.current, tableRef.current, setTableWidthDebounced]);
118
+ (0, utils_1.useResizeObserver)({ ref: resizeTarget !== null && resizeTarget !== void 0 ? resizeTarget : tableRef, onResize });
102
119
  // Filter + flatten + component-ize the sorted rows.
103
120
  let [headerRows, filteredRows] = (0, react_1.useMemo)(() => {
104
121
  // Break up "foo bar" into `[foo, bar]` and a row must match both `foo` and `bar`
@@ -176,6 +193,7 @@ function GridTable(props) {
176
193
  collapseAllContext,
177
194
  collapseRowContext,
178
195
  observeRows,
196
+ columnSizes,
179
197
  ]);
180
198
  let tooManyClientSideRows = false;
181
199
  if (filterMaxRows && filteredRows.length > filterMaxRows) {
@@ -208,7 +226,7 @@ function GridTable(props) {
208
226
  // just trust the GridTable impl that, at runtime, `as=virtual` will (other than being virtualized)
209
227
  // behave semantically the same as `as=div` did for its tests.
210
228
  const _as = as === "virtual" && runningInJest ? "div" : as;
211
- return ((0, jsx_runtime_1.jsx)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps: fieldProps, wrap: (_d = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _d === void 0 ? void 0 : _d.wrap }, { children: renders[_as](style, id, columns, headerRows, filteredRows, firstRowMessage, stickyHeader, (_e = style.nestedCards) === null || _e === void 0 ? void 0 : _e.firstLastColumnWidth, xss, virtuosoRef) }), void 0));
229
+ return ((0, jsx_runtime_1.jsx)(PresentationContext_1.PresentationProvider, Object.assign({ fieldProps: fieldProps, wrap: (_d = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _d === void 0 ? void 0 : _d.wrap }, { children: renders[_as](style, id, columns, headerRows, filteredRows, firstRowMessage, stickyHeader, (_e = style.nestedCards) === null || _e === void 0 ? void 0 : _e.firstLastColumnWidth, xss, virtuosoRef, tableRef) }), void 0));
212
230
  }
213
231
  exports.GridTable = GridTable;
214
232
  // Determine which HTML element to use to build the GridTable
@@ -218,10 +236,8 @@ const renders = {
218
236
  virtual: renderVirtual,
219
237
  };
220
238
  /** Renders table using divs with flexbox rows, which is the default render */
221
- function renderDiv(style, id, columns, headerRows, filteredRows, firstRowMessage, _stickyHeader, firstLastColumnWidth, xss, _virtuosoRef) {
222
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
223
- // Ensure all rows extend the same width
224
- ...Css_1.Css.mw("fit-content").$,
239
+ function renderDiv(style, id, columns, headerRows, filteredRows, firstRowMessage, _stickyHeader, firstLastColumnWidth, xss, _virtuosoRef, tableRef) {
240
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: tableRef, css: {
225
241
  /*
226
242
  Using (n + 3) here to target all rows that are after the first non-header row. Since n starts at 0, we can use
227
243
  the + operator as an offset.
@@ -230,17 +246,19 @@ function renderDiv(style, id, columns, headerRows, filteredRows, firstRowMessage
230
246
  ...(style.betweenRowsCss ? Css_1.Css.addIn(`& > div:nth-of-type(n+3) > *`, style.betweenRowsCss).$ : {}),
231
247
  ...(style.firstNonHeaderRowCss ? Css_1.Css.addIn(`& > div:nth-of-type(2) > *`, style.firstNonHeaderRowCss).$ : {}),
232
248
  ...style.rootCss,
249
+ ...(style.minWidthPx ? Css_1.Css.mwPx(style.minWidthPx).$ : {}),
233
250
  ...xss,
234
251
  }, "data-testid": id }, { children: [headerRows.map(([, node]) => node), firstRowMessage && ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...style.firstRowMessageCss }, "data-gridrow": true }, { children: firstRowMessage }), void 0)), filteredRows.map(([, node]) => node)] }), void 0));
235
252
  }
236
253
  /** Renders as a table, primarily/solely for good print support. */
237
- function renderTable(style, id, columns, headerRows, filteredRows, firstRowMessage, _stickyHeader, _firstLastColumnWidth, xss, _virtuosoRef) {
238
- return ((0, jsx_runtime_1.jsxs)("table", Object.assign({ css: {
254
+ function renderTable(style, id, columns, headerRows, filteredRows, firstRowMessage, _stickyHeader, _firstLastColumnWidth, xss, _virtuosoRef, tableRef) {
255
+ return ((0, jsx_runtime_1.jsxs)("table", Object.assign({ ref: tableRef, css: {
239
256
  ...Css_1.Css.w100.add("borderCollapse", "collapse").$,
240
257
  ...Css_1.Css.addIn("& > tbody > tr ", style.betweenRowsCss || {})
241
258
  // removes border between header and second row
242
259
  .addIn("& > tbody > tr:first-of-type", style.firstNonHeaderRowCss || {}).$,
243
260
  ...style.rootCss,
261
+ ...(style.minWidthPx ? Css_1.Css.mwPx(style.minWidthPx).$ : {}),
244
262
  ...xss,
245
263
  }, "data-testid": id }, { children: [(0, jsx_runtime_1.jsx)("thead", { children: headerRows.map(([, node]) => node) }, void 0), (0, jsx_runtime_1.jsxs)("tbody", { children: [firstRowMessage && ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", Object.assign({ colSpan: columns.length, css: { ...style.firstRowMessageCss } }, { children: firstRowMessage }), void 0) }, void 0)), filteredRows.map(([, node]) => node)] }, void 0)] }), void 0));
246
264
  }
@@ -264,16 +282,19 @@ function renderTable(style, id, columns, headerRows, filteredRows, firstRowMessa
264
282
  * [2]: https://github.com/tannerlinsley/react-virtual/issues/85
265
283
  * [3]: https://github.com/tannerlinsley/react-virtual/issues/108
266
284
  */
267
- function renderVirtual(style, id, columns, headerRows, filteredRows, firstRowMessage, stickyHeader, firstLastColumnWidth, xss, virtuosoRef) {
285
+ function renderVirtual(style, id, columns, headerRows, filteredRows, firstRowMessage, stickyHeader, firstLastColumnWidth, xss, virtuosoRef, tableRef) {
268
286
  // eslint-disable-next-line react-hooks/rules-of-hooks
269
287
  const { footerStyle, listStyle } = (0, react_1.useMemo)(() => {
270
288
  var _a;
271
289
  const { paddingBottom, ...otherRootStyles } = (_a = style.rootCss) !== null && _a !== void 0 ? _a : {};
272
290
  return { footerStyle: { paddingBottom }, listStyle: { ...style, rootCss: otherRootStyles } };
273
291
  }, [style]);
274
- return ((0, jsx_runtime_1.jsx)(react_virtuoso_1.Virtuoso, { overscan: 5, ref: virtuosoRef,
275
- // Add `minWidth: fit-content` to ensure a sticky header and the virtualized table body maintain same width
276
- style: { minWidth: "fit-content" }, components: {
292
+ return ((0, jsx_runtime_1.jsx)(react_virtuoso_1.Virtuoso, { overscan: 5, ref: virtuosoRef, scrollerRef: (ref) => {
293
+ // This is fired multiple times per render. Only set `tableRef.current` if it has changed
294
+ if (ref && tableRef.current !== ref) {
295
+ tableRef.current = ref;
296
+ }
297
+ }, components: {
277
298
  List: VirtualRoot(listStyle, columns, id, firstLastColumnWidth, xss),
278
299
  Footer: () => (0, jsx_runtime_1.jsx)("div", { css: footerStyle }, void 0),
279
300
  },
@@ -330,6 +351,7 @@ const VirtualRoot = (0, memoize_one_1.default)((gs, _columns, id, _firstLastColu
330
351
  ...Css_1.Css.addIn("& > div:first-of-type > *", gs.firstNonHeaderRowCss).$,
331
352
  }),
332
353
  ...gs.rootCss,
354
+ ...(gs.minWidthPx ? Css_1.Css.mwPx(gs.minWidthPx).$ : {}),
333
355
  ...xss,
334
356
  }, "data-testid": id }, { children: children }), void 0));
335
357
  });
@@ -338,7 +360,7 @@ const VirtualRoot = (0, memoize_one_1.default)((gs, _columns, id, _firstLastColu
338
360
  * Calculates column widths using a flexible `calc()` definition that allows for consistent column alignment without the use of `<table />`, CSS Grid, etc layouts.
339
361
  * Enforces only fixed-sized units (% and px)
340
362
  */
341
- function calcColumnSizes(columns, firstLastColumnWidth) {
363
+ function calcColumnSizes(columns, firstLastColumnWidth, tableWidth, tableMinWidthPx = 0) {
342
364
  // For both default columns (1fr) as well as `w: 4fr` columns, we translate the width into an expression that looks like:
343
365
  // calc((100% - allOtherPercent - allOtherPx) * ((myFr / totalFr))`
344
366
  //
@@ -369,6 +391,14 @@ function calcColumnSizes(columns, firstLastColumnWidth) {
369
391
  }, { claimedPercentages: 0, claimedPixels: 0, totalFr: 0 });
370
392
  // This is our "fake but for some reason it lines up better" fr calc
371
393
  function fr(myFr) {
394
+ // If the tableWidth, then return a pixel value
395
+ if (tableWidth) {
396
+ const widthBasis = Math.max(tableWidth, tableMinWidthPx);
397
+ // When the tableWidth is defined, then we need to account for the `firstLastColumnWidth`s.
398
+ return `(${(widthBasis - (claimedPercentages / 100) * widthBasis - claimedPixels - (firstLastColumnWidth !== null && firstLastColumnWidth !== void 0 ? firstLastColumnWidth : 0) * 2) *
399
+ (myFr / totalFr)}px)`;
400
+ }
401
+ // Otherwise return the `calc()` value
372
402
  return `((100% - ${claimedPercentages}% - ${claimedPixels}px) * (${myFr} / ${totalFr}))`;
373
403
  }
374
404
  let sizes = columns.map(({ w }) => {
@@ -390,13 +420,10 @@ function calcColumnSizes(columns, firstLastColumnWidth) {
390
420
  return fr(w);
391
421
  }
392
422
  });
393
- return maybeAddCardColumns(sizes, firstLastColumnWidth);
394
- }
395
- exports.calcColumnSizes = calcColumnSizes;
396
- // If we're doing nested cards, we add extra 1st/last cells...
397
- function maybeAddCardColumns(sizes, firstLastColumnWidth) {
423
+ // If we're doing nested cards, we add extra 1st/last cells...
398
424
  return !firstLastColumnWidth ? sizes : [`${firstLastColumnWidth}px`, ...sizes, `${firstLastColumnWidth}px`];
399
425
  }
426
+ exports.calcColumnSizes = calcColumnSizes;
400
427
  function getIndentationCss(style, rowStyle, columnIndex, maybeContent) {
401
428
  // Look for cell-specific indent or row-specific indent (row-specific is only one the first column)
402
429
  const indent = (isGridCellContent(maybeContent) && maybeContent.indent) || (columnIndex === 0 && (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.indent));
@@ -484,12 +511,12 @@ function GridRow(props) {
484
511
  // Add any cell specific style overrides
485
512
  ...(isGridCellContent(maybeContent) && maybeContent.typeScale ? Css_1.Css[maybeContent.typeScale].$ : {}),
486
513
  // Define the width of the column on each cell. Supports col spans.
487
- ...(columnSizes && {
514
+ ...{
488
515
  width: `calc(${columnSizes
489
516
  .slice(maybeNestedCardColumnIndex, maybeNestedCardColumnIndex + currentColspan)
490
517
  .join(" + ")})`,
491
- ...(column.mw ? Css_1.Css.mw(column.mw).$ : {}),
492
- }),
518
+ },
519
+ ...(column.mw ? Css_1.Css.mw(column.mw).$ : {}),
493
520
  };
494
521
  const renderFn = (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.renderCell) || (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowLink)
495
522
  ? rowLinkRenderFn(as)
@@ -97,9 +97,8 @@ export declare function getNestedCardStyles(row: GridDataRow<any>, openCardStyle
97
97
  export declare function makeSpacer(height: number, openCards: string[], styles: NestedCardsStyle): Chrome;
98
98
  interface ChromeRowProps {
99
99
  chromeBuffer: ChromeBuffer;
100
- columns: number;
101
100
  }
102
- export declare function ChromeRow({ chromeBuffer, columns }: ChromeRowProps): import("@emotion/react/jsx-runtime").JSX.Element;
101
+ export declare function ChromeRow({ chromeBuffer }: ChromeRowProps): import("@emotion/react/jsx-runtime").JSX.Element;
103
102
  export declare function dropChromeRows<R extends Kinded>(rows: RowTuple<R>[]): [GridDataRow<R>, ReactElement][];
104
103
  export declare function isLeafRow<R extends Kinded>(row: GridDataRow<R>): boolean;
105
104
  export {};
@@ -82,10 +82,7 @@ class NestedCards {
82
82
  */
83
83
  maybeCreateChromeRow() {
84
84
  if (this.chromeBuffer.length > 0) {
85
- this.rows.push([
86
- undefined,
87
- (0, jsx_runtime_1.jsx)(ChromeRow, { chromeBuffer: [...this.chromeBuffer], columns: this.columns.length }, this.chromeRowIndex++),
88
- ]);
85
+ this.rows.push([undefined, (0, jsx_runtime_1.jsx)(ChromeRow, { chromeBuffer: [...this.chromeBuffer] }, this.chromeRowIndex++)]);
89
86
  // clear the Chrome buffer
90
87
  this.chromeBuffer.splice(0, this.chromeBuffer.length);
91
88
  }
@@ -201,10 +198,8 @@ function makeSpacer(height, openCards, styles) {
201
198
  };
202
199
  }
203
200
  exports.makeSpacer = makeSpacer;
204
- function ChromeRow({ chromeBuffer, columns }) {
205
- return (
206
- // We add 2 to account for our dedicated open/close columns
207
- (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.gc(`span ${columns + 2}`).$ }, { children: chromeBuffer.map((c, i) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: c() }, i))) }), void 0));
201
+ function ChromeRow({ chromeBuffer }) {
202
+ 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));
208
203
  }
209
204
  exports.ChromeRow = ChromeRow;
210
205
  function dropChromeRows(rows) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.105.6",
3
+ "version": "2.105.9",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -53,7 +53,8 @@
53
53
  "tinycolor2": "^1.4.2",
54
54
  "tributejs": "^5.1.3",
55
55
  "trix": "^1.3.1",
56
- "use-query-params": "^1.2.2"
56
+ "use-query-params": "^1.2.2",
57
+ "use-debounce": "^7.0.1"
57
58
  },
58
59
  "peerDependencies": {
59
60
  "@emotion/react": ">=11",
@@ -80,6 +81,7 @@
80
81
  "@homebound/rtl-react-router-utils": "^1.0.3",
81
82
  "@homebound/rtl-utils": "^2.51.0",
82
83
  "@homebound/tsconfig": "^1.0.3",
84
+ "@semantic-release/exec": "^6.0.3",
83
85
  "@semantic-release/git": "^9.0.0",
84
86
  "@storybook/addon-essentials": "^6.4.9",
85
87
  "@storybook/addon-interactions": "^6.4.9",