@homebound/beam 2.100.0 → 2.101.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.
@@ -185,18 +185,10 @@ export declare type GridTableApi = {
185
185
  */
186
186
  export declare function GridTable<R extends Kinded, S = {}, X extends Only<GridTableXss, X> = {}>(props: GridTableProps<R, S, X>): import("@emotion/react/jsx-runtime").JSX.Element;
187
187
  /**
188
- * Creates a `grid-template-column` specific to our virtual output.
189
- *
190
- * Because of two things:
191
- *
192
- * a) react-virtuoso puts the header in a different div than the normal rows, and
193
- *
194
- * b) content-aware sizing just in general look janky/constantly resize while scrolling
195
- *
196
- * When we're as=virtual, we change our default + enforce only fixed-sized units (% and px)
188
+ * Calculates column widths using a flexible `calc()` definition that allows for consistent column alignment without the use of `<table />`, CSS Grid, etc layouts.
189
+ * Enforces only fixed-sized units (% and px)
197
190
  */
198
- export declare function calcVirtualGridColumns(columns: GridColumn<any>[], firstLastColumnWidth: number | undefined): string[];
199
- export declare function calcDivGridColumns(columns: GridColumn<any>[], firstLastColumnWidth: number | undefined): string;
191
+ export declare function calcColumnSizes(columns: GridColumn<any>[], firstLastColumnWidth: number | undefined): string[];
200
192
  /**
201
193
  * Given an ADT of type T, performs a look up and returns the type of kind K.
202
194
  *
@@ -225,21 +217,8 @@ export declare type GridColumn<R extends Kinded, S = {}> = {
225
217
  } ? (data: D, row: GridRowKind<R, K>) => ReactNode | GridCellContent : (row: GridRowKind<R, K>) => ReactNode | GridCellContent);
226
218
  } & {
227
219
  /**
228
- * The column's grid column width.
229
- *
230
- * For `as=div` output:
231
- *
232
- * - Any CSS grid units are supported
233
- * - Numbers are treated as `fr` units
234
- * - The default value is `auto`, which in CSS grid will do content-aware/responsive layout.
235
- *
236
- * For `as=virtual` output:
237
- *
238
- * - Only px, percentage, or fr units are supported, due to a) react-virtuoso puts the sticky header
239
- * rows in a separate `div` and so we end up with two `grid-template-columns`, so cannot rely on
240
- * any content-aware sizing, and b) content-aware sizing in a scrolling/virtual table results in
241
- * a ~janky experience as the columns will constantly resize as new/different content is put in/out
242
- * of the DOM.
220
+ * The column's width.
221
+ * - Only px, percentage, or fr units are supported, due to each GridRow acting as an independent table. This ensures consistent alignment between rows.
243
222
  * - Numbers are treated as `fr` units
244
223
  * - The default value is `1fr`
245
224
  */
@@ -277,7 +256,7 @@ export declare type GridCellAlignment = "left" | "right" | "center";
277
256
  * primitive value for filtering and sorting.
278
257
  */
279
258
  export declare type GridCellContent = {
280
- /** The JSX content of the cell. Virtual tables that client-side sort should use a function to avaid perf overhead. */
259
+ /** The JSX content of the cell. Virtual tables that client-side sort should use a function to avoid perf overhead. */
281
260
  content: ReactNode | (() => ReactNode);
282
261
  alignment?: GridCellAlignment;
283
262
  /** Allow value to be a function in case it's a dynamic value i.e. reading from an inline-edited proxy. */
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
22
22
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.matchesFilter = exports.GridCollapseContext = exports.applyRowFn = exports.calcDivGridColumns = exports.calcVirtualGridColumns = exports.GridTable = exports.setGridTableDefaults = exports.setDefaultStyle = exports.setRunningInJest = exports.emptyCell = exports.DESC = exports.ASC = void 0;
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
27
  const memoize_one_1 = __importDefault(require("memoize-one"));
28
28
  const mobx_react_1 = require("mobx-react");
@@ -104,7 +104,7 @@ function GridTable(props) {
104
104
  var _a;
105
105
  // Break up "foo bar" into `[foo, bar]` and a row must match both `foo` and `bar`
106
106
  const filters = (filter && filter.split(/ +/)) || [];
107
- const columnSizes = as === "virtual" ? calcVirtualGridColumns(columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth) : undefined;
107
+ const columnSizes = calcColumnSizes(columns, (_a = style.nestedCards) === null || _a === void 0 ? void 0 : _a.firstLastColumnWidth);
108
108
  function makeRowComponent(row) {
109
109
  // We only pass sortState to header rows, b/c non-headers rows shouldn't have to re-render on sorting
110
110
  // changes, and so by not passing the sortProps, it means the data rows' React.memo will still cache them.
@@ -217,11 +217,11 @@ exports.GridTable = GridTable;
217
217
  // Determine which HTML element to use to build the GridTable
218
218
  const renders = {
219
219
  table: renderTable,
220
- div: renderCssGrid,
220
+ div: renderDiv,
221
221
  virtual: renderVirtual,
222
222
  };
223
- /** Renders as a CSS Grid, which is the default / most well-supported rendered. */
224
- function renderCssGrid(style, id, columns, headerRows, filteredRows, firstRowMessage, _stickyHeader, firstLastColumnWidth, xss, _virtuosoRef) {
223
+ /** Renders table using divs with flexbox rows, which is the default render */
224
+ function renderDiv(style, id, columns, headerRows, filteredRows, firstRowMessage, _stickyHeader, firstLastColumnWidth, xss, _virtuosoRef) {
225
225
  var _a;
226
226
  // We must determine if the header is using nested card styles to account for
227
227
  // the opening and closing Chrome rows.
@@ -247,7 +247,6 @@ function renderCssGrid(style, id, columns, headerRows, filteredRows, firstRowMes
247
247
  */
248
248
  const firstNonHeaderRowIndex = (!isNestedCardStyleHeader ? 1 : 3) + 1;
249
249
  return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
250
- ...Css_1.Css.dg.gtc(calcDivGridColumns(columns, firstLastColumnWidth)).$,
251
250
  /*
252
251
  Using n + (firstNonHeaderRowIndex + 1) here to target all rows that
253
252
  are after the first non-header row. Since n starts at 0, we can use
@@ -263,7 +262,7 @@ function renderCssGrid(style, id, columns, headerRows, filteredRows, firstRowMes
263
262
  : {}),
264
263
  ...style.rootCss,
265
264
  ...xss,
266
- }, "data-testid": id }, { children: [headerRows.map(([, node]) => node), firstRowMessage && ((0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.add("gridColumn", `${columns.length} span`).$ }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...style.firstRowMessageCss } }, { children: firstRowMessage }), void 0) }), void 0)), filteredRows.map(([, node]) => node)] }), void 0));
265
+ }, "data-testid": id }, { children: [headerRows.map(([, node]) => node), firstRowMessage && (0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...style.firstRowMessageCss } }, { children: firstRowMessage }), void 0), filteredRows.map(([, node]) => node)] }), void 0));
267
266
  }
268
267
  /** Renders as a table, primarily/solely for good print support. */
269
268
  function renderTable(style, id, columns, headerRows, filteredRows, firstRowMessage, _stickyHeader, _firstLastColumnWidth, xss, _virtuosoRef) {
@@ -346,7 +345,7 @@ function renderVirtual(style, id, columns, headerRows, filteredRows, firstRowMes
346
345
  * rows and the second represents the non-header rows (list rows).
347
346
  *
348
347
  * The main goal of this custom component is to:
349
- * - Customize the list wrapper to our css grid logic styles
348
+ * - Customize the list wrapper to our styles
350
349
  *
351
350
  * We wrap this in memoizeOne so that React.createElement sees a
352
351
  * consistent/stable component identity, even though technically we have a
@@ -374,17 +373,10 @@ const VirtualRoot = (0, memoize_one_1.default)((gs, _columns, id, _firstLastColu
374
373
  });
375
374
  });
376
375
  /**
377
- * Creates a `grid-template-column` specific to our virtual output.
378
- *
379
- * Because of two things:
380
- *
381
- * a) react-virtuoso puts the header in a different div than the normal rows, and
382
- *
383
- * b) content-aware sizing just in general look janky/constantly resize while scrolling
384
- *
385
- * When we're as=virtual, we change our default + enforce only fixed-sized units (% and px)
376
+ * Calculates column widths using a flexible `calc()` definition that allows for consistent column alignment without the use of `<table />`, CSS Grid, etc layouts.
377
+ * Enforces only fixed-sized units (% and px)
386
378
  */
387
- function calcVirtualGridColumns(columns, firstLastColumnWidth) {
379
+ function calcColumnSizes(columns, firstLastColumnWidth) {
388
380
  // For both default columns (1fr) as well as `w: 4fr` columns, we translate the width into an expression that looks like:
389
381
  // calc((100% - allOtherPercent - allOtherPx) * ((myFr / totalFr))`
390
382
  //
@@ -410,7 +402,7 @@ function calcVirtualGridColumns(columns, firstLastColumnWidth) {
410
402
  return { ...acc, claimedPercentages: acc.claimedPercentages + Number(w.replace("%", "")) };
411
403
  }
412
404
  else {
413
- throw new Error("as=virtual only supports px, percentage, or fr units");
405
+ throw new Error("Beam Table column width definition only supports px, percentage, or fr units");
414
406
  }
415
407
  }, { claimedPercentages: 0, claimedPixels: firstLastColumnWidth ? firstLastColumnWidth * 2 : 0, totalFr: 0 });
416
408
  // This is our "fake but for some reason it lines up better" fr calc
@@ -429,7 +421,7 @@ function calcVirtualGridColumns(columns, firstLastColumnWidth) {
429
421
  return fr(Number(w.replace("fr", "")));
430
422
  }
431
423
  else {
432
- throw new Error("as=virtual only supports px, percentage, or fr units");
424
+ throw new Error("Beam Table column width definition only supports px, percentage, or fr units");
433
425
  }
434
426
  }
435
427
  else {
@@ -438,25 +430,7 @@ function calcVirtualGridColumns(columns, firstLastColumnWidth) {
438
430
  });
439
431
  return maybeAddCardColumns(sizes, firstLastColumnWidth);
440
432
  }
441
- exports.calcVirtualGridColumns = calcVirtualGridColumns;
442
- function calcDivGridColumns(columns, firstLastColumnWidth) {
443
- const sizes = columns.map(({ w }) => {
444
- if (typeof w === "undefined") {
445
- // Hrm, I waffle between 'auto' or '1fr' being the better default here...
446
- return "auto";
447
- }
448
- else if (typeof w === "string") {
449
- // Use whatever the user passed in
450
- return w;
451
- }
452
- else {
453
- // Otherwise assume fr units
454
- return `${w}fr`;
455
- }
456
- });
457
- return maybeAddCardColumns(sizes, firstLastColumnWidth).join(" ");
458
- }
459
- exports.calcDivGridColumns = calcDivGridColumns;
433
+ exports.calcColumnSizes = calcColumnSizes;
460
434
  // If we're doing nested cards, we add extra 1st/last cells...
461
435
  function maybeAddCardColumns(sizes, firstLastColumnWidth) {
462
436
  return !firstLastColumnWidth ? sizes : [`${firstLastColumnWidth}px`, ...sizes, `${firstLastColumnWidth}px`];
@@ -480,19 +454,15 @@ function GridRow(props) {
480
454
  const rowStyle = rowStyles === null || rowStyles === void 0 ? void 0 : rowStyles[row.kind];
481
455
  const rowStyleCellCss = maybeApplyFunction(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.cellCss);
482
456
  const rowCss = {
483
- // We add a display-contents so that we can have "row-level" div elements in our
484
- // DOM structure. I.e. grid is normally root-element > cell-elements, but we want
485
- // root-element > row-element > cell-elements, so that we can have a hook for
486
- // hovers and styling. In theory this would change with subgrids.
487
- // Only enable when using div as elements
488
457
  // For virtual tables use `display: flex` to keep all cells on the same row, but use `flexNone` to ensure the cells stay their defined widths
489
- ...(as === "table" ? {} : as === "virtual" ? Css_1.Css.df.addIn("&>*", Css_1.Css.flexNone.$).$ : Css_1.Css.display("contents").$),
458
+ ...(as === "table" ? {} : Css_1.Css.df.addIn("&>*", Css_1.Css.flexNone.$).$),
490
459
  ...(((rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowLink) || (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.onClick)) &&
491
460
  style.rowHoverColor && {
492
461
  // Even though backgroundColor is set on the cellCss (due to display: content), the hover target is the row.
493
462
  "&:hover > *": Css_1.Css.cursorPointer.bgColor(maybeDarken(rowStyleCellCss === null || rowStyleCellCss === void 0 ? void 0 : rowStyleCellCss.backgroundColor, style.rowHoverColor)).$,
494
463
  }),
495
464
  ...maybeApplyFunction(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowCss),
465
+ ...(isHeader && stickyHeader ? Css_1.Css.sticky.top(stickyOffset).z1.$ : undefined),
496
466
  };
497
467
  const Row = as === "table" ? "tr" : "div";
498
468
  const openCardStyles = typeof openCards === "string"
@@ -543,18 +513,11 @@ function GridRow(props) {
543
513
  ...getIndentationCss(style, rowStyle, columnIndex, maybeContent),
544
514
  // Then apply any header-specific override
545
515
  ...(isHeader && style.headerCellCss),
546
- // Non-virtualized tables use h100 so that all cells are the same height across the row.
547
- // Virtualized table rows use `display: flex;`, so the flex children are set to `align-self: stretch` by default, which achieves the same goal.
548
- // Though, we need to omit setting `h100` on the flex children, as a flex container needs a defined height set for `h100` to work on flex children
549
- ...(isHeader && as !== "virtual" ? Css_1.Css.h100.$ : undefined),
550
- ...maybeStickyHeaderStyles,
551
516
  // If we're within a card, use its background color
552
517
  ...(currentCard && Css_1.Css.bgColor(currentCard.bgColor).$),
553
- // Add in colspan css if needed
554
- ...(currentColspan > 1 ? Css_1.Css.gc(`span ${currentColspan}`).$ : {}),
555
518
  // And finally the specific cell's css (if any from GridCellContent)
556
519
  ...rowStyleCellCss,
557
- // For virtual tables we define the width of the column on each cell. Supports col spans.
520
+ // Define the width of the column on each cell. Supports col spans.
558
521
  ...(columnSizes && {
559
522
  width: `calc(${columnSizes
560
523
  .slice(maybeNestedCardColumnIndex, maybeNestedCardColumnIndex + currentColspan)
@@ -641,8 +604,8 @@ function applyRowFn(column, row) {
641
604
  exports.applyRowFn = applyRowFn;
642
605
  /** Renders our default cell element, i.e. if no row links and no custom renderCell are used. */
643
606
  const defaultRenderFn = (as) => (key, css, content) => {
644
- const Row = as === "table" ? "td" : "div";
645
- return ((0, jsx_runtime_1.jsx)(Row, Object.assign({ css: { ...css, ...tableRowStyles(as) } }, { children: content }), key));
607
+ const Cell = as === "table" ? "td" : "div";
608
+ return ((0, jsx_runtime_1.jsx)(Cell, Object.assign({ css: { ...css, ...tableRowStyles(as) } }, { children: content }), key));
646
609
  };
647
610
  exports.GridCollapseContext = react_1.default.createContext({
648
611
  headerCollapsed: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.100.0",
3
+ "version": "2.101.0",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",