@homebound/beam 2.187.0 → 2.187.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/components/SuperDrawer/ConfirmCloseModal.js +1 -1
  2. package/dist/components/SuperDrawer/SuperDrawer.js +4 -10
  3. package/dist/components/Table/GridTable.d.ts +11 -218
  4. package/dist/components/Table/GridTable.js +15 -426
  5. package/dist/components/Table/GridTableApi.d.ts +3 -2
  6. package/dist/components/Table/GridTableApi.js +2 -2
  7. package/dist/components/Table/TableStyles.d.ts +86 -0
  8. package/dist/components/Table/{styles.js → TableStyles.js} +55 -34
  9. package/dist/components/Table/{CollapseToggle.d.ts → components/CollapseToggle.d.ts} +1 -1
  10. package/dist/components/Table/{CollapseToggle.js → components/CollapseToggle.js} +4 -4
  11. package/dist/components/Table/{EditColumnsButton.d.ts → components/EditColumnsButton.d.ts} +2 -2
  12. package/dist/components/Table/{EditColumnsButton.js → components/EditColumnsButton.js} +5 -5
  13. package/dist/components/Table/components/Row.d.ts +71 -0
  14. package/dist/components/Table/components/Row.js +177 -0
  15. package/dist/components/Table/{SelectToggle.d.ts → components/SelectToggle.d.ts} +0 -0
  16. package/dist/components/Table/{SelectToggle.js → components/SelectToggle.js} +5 -5
  17. package/dist/components/Table/{SortHeader.d.ts → components/SortHeader.d.ts} +1 -1
  18. package/dist/components/Table/{SortHeader.js → components/SortHeader.js} +5 -5
  19. package/dist/components/Table/components/cell.d.ts +41 -0
  20. package/dist/components/Table/components/cell.js +46 -0
  21. package/dist/components/Table/{useColumns.d.ts → hooks/useColumns.d.ts} +1 -1
  22. package/dist/components/Table/{useColumns.js → hooks/useColumns.js} +1 -1
  23. package/dist/components/Table/{columnSizes.d.ts → hooks/useSetupColumnSizes.d.ts} +2 -1
  24. package/dist/components/Table/{columnSizes.js → hooks/useSetupColumnSizes.js} +3 -3
  25. package/dist/components/Table/{useSortState.d.ts → hooks/useSortState.d.ts} +2 -1
  26. package/dist/components/Table/{useSortState.js → hooks/useSortState.js} +6 -6
  27. package/dist/components/Table/index.d.ts +30 -14
  28. package/dist/components/Table/index.js +38 -24
  29. package/dist/components/Table/types.d.ts +83 -0
  30. package/dist/components/Table/types.js +16 -0
  31. package/dist/components/Table/{GridRowLookup.d.ts → utils/GridRowLookup.d.ts} +2 -1
  32. package/dist/components/Table/{GridRowLookup.js → utils/GridRowLookup.js} +2 -2
  33. package/dist/components/Table/{GridSortContext.d.ts → utils/GridSortContext.d.ts} +0 -0
  34. package/dist/components/Table/{GridSortContext.js → utils/GridSortContext.js} +0 -0
  35. package/dist/components/Table/{RowState.d.ts → utils/RowState.d.ts} +1 -1
  36. package/dist/components/Table/{RowState.js → utils/RowState.js} +0 -0
  37. package/dist/components/Table/{columns.d.ts → utils/columns.d.ts} +6 -1
  38. package/dist/components/Table/utils/columns.js +149 -0
  39. package/dist/components/Table/{simpleHelpers.d.ts → utils/simpleHelpers.d.ts} +1 -1
  40. package/dist/components/Table/{simpleHelpers.js → utils/simpleHelpers.js} +0 -0
  41. package/dist/components/Table/{sortRows.d.ts → utils/sortRows.d.ts} +4 -2
  42. package/dist/components/Table/{sortRows.js → utils/sortRows.js} +3 -3
  43. package/dist/components/Table/utils/utils.d.ts +23 -0
  44. package/dist/components/Table/utils/utils.js +148 -0
  45. package/dist/components/Table/{visitor.d.ts → utils/visitor.d.ts} +1 -1
  46. package/dist/components/Table/{visitor.js → utils/visitor.js} +0 -0
  47. package/package.json +1 -1
  48. package/dist/components/Table/columns.js +0 -84
  49. package/dist/components/Table/styles.d.ts +0 -15
@@ -1,8 +1,44 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getTableStyles = exports.cardStyle = exports.condensedStyle = exports.defaultStyle = void 0;
3
+ exports.resolveStyles = exports.tableRowStyles = exports.cardStyle = exports.condensedStyle = exports.defaultStyle = exports.getTableStyles = void 0;
4
4
  const Css_1 = require("../../Css");
5
5
  const utils_1 = require("../../utils");
6
+ // Returns a "blessed" style of GridTable
7
+ function memoizedTableStyles() {
8
+ const cache = {};
9
+ return (props = {}) => {
10
+ const { inlineEditing = false, grouped = false, rowHeight = "flexible", cellHighlight = false } = props;
11
+ const key = (0, utils_1.safeKeys)(props)
12
+ .sort()
13
+ .map((k) => `${k}_${props[k]}`)
14
+ .join("|");
15
+ if (!cache[key]) {
16
+ const groupedLevels = {
17
+ 0: {
18
+ cellCss: Css_1.Css.xsMd.mhPx(56).gray700.bgGray100.boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`).$,
19
+ firstContentColumn: Css_1.Css.smMd.$,
20
+ },
21
+ 2: { firstContentColumn: Css_1.Css.tiny.pl3.$ },
22
+ };
23
+ const defaultLevels = { 1: { firstContentColumn: Css_1.Css.tiny.pl3.$ } };
24
+ cache[key] = {
25
+ emptyCell: "-",
26
+ firstRowMessageCss: Css_1.Css.tc.py3.$,
27
+ headerCellCss: Css_1.Css.gray700.xsMd.bgGray200.aic.nowrap.pxPx(12).hPx(40).$,
28
+ totalsCellCss: Css_1.Css.bgWhite.gray700.smMd.hPx(52).pt0.pbPx(12).boxShadow("none").$,
29
+ cellCss: {
30
+ ...Css_1.Css.gray900.xs.bgWhite.aic.pxPx(12).boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`).$,
31
+ ...(rowHeight === "flexible" ? Css_1.Css.pyPx(12).$ : Css_1.Css.nowrap.hPx(inlineEditing ? 48 : 36).$),
32
+ ...(cellHighlight ? { "&:hover": Css_1.Css.bgGray100.$ } : {}),
33
+ },
34
+ presentationSettings: { borderless: true, typeScale: "xs", wrap: rowHeight === "flexible" },
35
+ levels: grouped ? groupedLevels : defaultLevels,
36
+ };
37
+ }
38
+ return cache[key];
39
+ };
40
+ }
41
+ exports.getTableStyles = memoizedTableStyles();
6
42
  /** Our original table look & feel/style. */
7
43
  exports.defaultStyle = {
8
44
  rootCss: Css_1.Css.gray700.$,
@@ -42,38 +78,23 @@ exports.cardStyle = {
42
78
  }).p1.m0.xsMd.gray700.$,
43
79
  },
44
80
  };
45
- function memoizedTableStyles() {
46
- const cache = {};
47
- return (props = {}) => {
48
- const { inlineEditing = false, grouped = false, rowHeight = "flexible", cellHighlight = false } = props;
49
- const key = (0, utils_1.safeKeys)(props)
50
- .sort()
51
- .map((k) => `${k}_${props[k]}`)
52
- .join("|");
53
- if (!cache[key]) {
54
- const groupedLevels = {
55
- 0: {
56
- cellCss: Css_1.Css.xsMd.mhPx(56).gray700.bgGray100.boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`).$,
57
- firstContentColumn: Css_1.Css.smMd.$,
58
- },
59
- 2: { firstContentColumn: Css_1.Css.tiny.pl3.$ },
60
- };
61
- const defaultLevels = { 1: { firstContentColumn: Css_1.Css.tiny.pl3.$ } };
62
- cache[key] = {
63
- emptyCell: "-",
64
- firstRowMessageCss: Css_1.Css.tc.py3.$,
65
- headerCellCss: Css_1.Css.gray700.xsMd.bgGray200.aic.nowrap.pxPx(12).hPx(40).$,
66
- totalsCellCss: Css_1.Css.bgWhite.gray700.smMd.hPx(52).pt0.pbPx(12).boxShadow("none").$,
67
- cellCss: {
68
- ...Css_1.Css.gray900.xs.bgWhite.aic.pxPx(12).boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray200}`).$,
69
- ...(rowHeight === "flexible" ? Css_1.Css.pyPx(12).$ : Css_1.Css.nowrap.hPx(inlineEditing ? 48 : 36).$),
70
- ...(cellHighlight ? { "&:hover": Css_1.Css.bgGray100.$ } : {}),
71
- },
72
- presentationSettings: { borderless: true, typeScale: "xs", wrap: rowHeight === "flexible" },
73
- levels: grouped ? groupedLevels : defaultLevels,
74
- };
81
+ /** GridTable as Table utility to apply <tr> element override styles. */
82
+ function tableRowStyles(as, column) {
83
+ const thWidth = column === null || column === void 0 ? void 0 : column.w;
84
+ return as === "table"
85
+ ? {
86
+ ...Css_1.Css.dtc.$,
87
+ ...(thWidth ? Css_1.Css.w(thWidth).$ : {}),
75
88
  }
76
- return cache[key];
77
- };
89
+ : {};
78
90
  }
79
- exports.getTableStyles = memoizedTableStyles();
91
+ exports.tableRowStyles = tableRowStyles;
92
+ function resolveStyles(style) {
93
+ const defKeys = ["inlineEditing", "grouped", "rowHeight", "cellHighlight"];
94
+ const keys = (0, utils_1.safeKeys)(style);
95
+ if (keys.length === 0 || keys.some((k) => defKeys.includes(k))) {
96
+ return (0, exports.getTableStyles)(style);
97
+ }
98
+ return style;
99
+ }
100
+ exports.resolveStyles = resolveStyles;
@@ -1,4 +1,4 @@
1
- import { GridDataRow, IconButtonProps } from "..";
1
+ import { GridDataRow, IconButtonProps } from "../../index";
2
2
  export interface GridTableCollapseToggleProps extends Pick<IconButtonProps, "compact"> {
3
3
  row: GridDataRow<any>;
4
4
  }
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CollapseToggle = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const components_1 = require("..");
7
- const hooks_1 = require("../../hooks");
6
+ const index_1 = require("../../index");
7
+ const hooks_1 = require("../../../hooks");
8
8
  /** Provides a chevron icons to collapse/un-collapse for parent/child tables. */
9
9
  function CollapseToggle(props) {
10
10
  const { row, compact } = props;
11
- const { rowState } = (0, react_1.useContext)(components_1.RowStateContext);
11
+ const { rowState } = (0, react_1.useContext)(index_1.RowStateContext);
12
12
  const isCollapsed = (0, hooks_1.useComputed)(() => rowState.isCollapsed(row.id), [rowState]);
13
13
  const iconKey = isCollapsed ? "chevronRight" : "chevronDown";
14
14
  const headerIconKey = isCollapsed ? "chevronsRight" : "chevronsDown";
@@ -17,6 +17,6 @@ function CollapseToggle(props) {
17
17
  if (!isHeader && (!row.children || row.children.length === 0)) {
18
18
  return null;
19
19
  }
20
- return ((0, jsx_runtime_1.jsx)(components_1.IconButton, { onClick: () => rowState.toggleCollapsed(row.id), icon: isHeader ? headerIconKey : iconKey, compact: compact }, void 0));
20
+ return ((0, jsx_runtime_1.jsx)(index_1.IconButton, { onClick: () => rowState.toggleCollapsed(row.id), icon: isHeader ? headerIconKey : iconKey, compact: compact }, void 0));
21
21
  }
22
22
  exports.CollapseToggle = CollapseToggle;
@@ -1,6 +1,6 @@
1
1
  import { Dispatch, SetStateAction } from "react";
2
- import { OverlayTriggerProps } from "../internal/OverlayTrigger";
3
- import { GridColumn, Kinded } from "./GridTable";
2
+ import { OverlayTriggerProps } from "../../internal/OverlayTrigger";
3
+ import { GridColumn, Kinded } from "../types";
4
4
  interface EditColumnsButtonProps<R extends Kinded, S> extends Pick<OverlayTriggerProps, "trigger" | "placement" | "disabled" | "tooltip"> {
5
5
  allColumns: GridColumn<R, S>[];
6
6
  selectedColumns: GridColumn<R, S>[];
@@ -5,11 +5,11 @@ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const react_aria_1 = require("react-aria");
7
7
  const react_stately_1 = require("react-stately");
8
- const inputs_1 = require("../../inputs");
9
- const Css_1 = require("../../Css");
10
- const utils_1 = require("../../utils");
11
- const Button_1 = require("../Button");
12
- const OverlayTrigger_1 = require("../internal/OverlayTrigger");
8
+ const Button_1 = require("../../Button");
9
+ const OverlayTrigger_1 = require("../../internal/OverlayTrigger");
10
+ const Css_1 = require("../../../Css");
11
+ const inputs_1 = require("../../../inputs");
12
+ const utils_1 = require("../../../utils");
13
13
  function EditColumnsButton(props) {
14
14
  const { defaultOpen, disabled, allColumns, setSelectedColumns, trigger, title, selectedColumns } = props;
15
15
  const state = (0, react_stately_1.useMenuTriggerState)({ isOpen: defaultOpen });
@@ -0,0 +1,71 @@
1
+ import { ReactElement } from "react";
2
+ import { GridTableApi } from "../GridTableApi";
3
+ import { SortOn, SortState } from "../hooks/useSortState";
4
+ import { GridStyle, RowStyles } from "../TableStyles";
5
+ import { DiscriminateUnion, GridColumn, IfAny, Kinded, Pin, RenderAs } from "../types";
6
+ interface RowProps<R extends Kinded, S> {
7
+ as: RenderAs;
8
+ columns: GridColumn<R>[];
9
+ row: GridDataRow<R>;
10
+ style: GridStyle;
11
+ rowStyles: RowStyles<R> | undefined;
12
+ stickyHeader: boolean;
13
+ stickyOffset: number;
14
+ sortOn: SortOn;
15
+ sortState?: SortState<S>;
16
+ setSortKey?: (value: S) => void;
17
+ columnSizes: string[];
18
+ level: number;
19
+ getCount: (id: string) => object;
20
+ api: GridTableApi<R>;
21
+ cellHighlight: boolean;
22
+ }
23
+ declare function RowImpl<R extends Kinded, S>(props: RowProps<R, S>): ReactElement;
24
+ /**
25
+ * Memoizes Rows so that re-rendering the table doesn't re-render every single row.
26
+ *
27
+ * We use a custom `propsAreEqual` for the `RowProps.row` property, which we memoize
28
+ * based on the `GridDataRow.data` prop, such that if a table re-renders (i.e. for a cache
29
+ * updated) and technically creates new row instances, but a row's `row.data` points to the
30
+ * same/unchanged Apollo cache fragment, then we won't re-render that row.
31
+ *
32
+ * Note that if you're using virtualization, it can be surprising how unnoticeable broken row
33
+ * memoization is.
34
+ */
35
+ export declare const Row: typeof RowImpl;
36
+ /** A specific kind of row, including the GridDataRow props. */
37
+ export declare type GridRowKind<R extends Kinded, P extends R["kind"]> = DiscriminateUnion<R, "kind", P> & {
38
+ id: string;
39
+ children: GridDataRow<R>[];
40
+ selectable?: false;
41
+ };
42
+ /**
43
+ * The data for any row in the table, marked by `kind` so that each column knows how to render it.
44
+ *
45
+ * Each `kind` should contain very little presentation logic, i.e. mostly just off-the-wire data from
46
+ * a GraphQL query.
47
+ *
48
+ * The presentation concerns instead mainly live in each GridColumn definition, which will format/render
49
+ * each kind's data for that specific row+column (i.e. cell) combination.
50
+ */
51
+ export declare type GridDataRow<R extends Kinded> = {
52
+ kind: R["kind"];
53
+ /** Combined with the `kind` to determine a table wide React key. */
54
+ id: string;
55
+ /** A list of parent/grand-parent ids for collapsing parent/child rows. */
56
+ children?: GridDataRow<R>[];
57
+ /** * Whether to pin this sort to the first/last of its parent's children.
58
+ *
59
+ * By default, pinned rows are always shown/not filtered out, however providing
60
+ * the pin `filter: true` property will allow pinned rows to be hidden
61
+ * while filtering.*/
62
+ pin?: "first" | "last" | Pin;
63
+ data: unknown;
64
+ /** Whether to have the row collapsed (children not visible) on initial load. This will be ignore in subsequent re-renders of the table */
65
+ initCollapsed?: boolean;
66
+ /** Whether to have the row selected on initial load. This will be ignore in subsequent re-renders of the table */
67
+ initSelected?: boolean;
68
+ /** Whether row can be selected */
69
+ selectable?: false;
70
+ } & IfAny<R, {}, DiscriminateUnion<R, "kind", R["kind"]>>;
71
+ export {};
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.Row = void 0;
23
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
24
+ const mobx_react_1 = require("mobx-react");
25
+ const react_1 = __importStar(require("react"));
26
+ const cell_1 = require("./cell");
27
+ const RowState_1 = require("../utils/RowState");
28
+ const sortRows_1 = require("../utils/sortRows");
29
+ const utils_1 = require("../utils/utils");
30
+ const Css_1 = require("../../../Css");
31
+ const hooks_1 = require("../../../hooks");
32
+ const shallowEqual_1 = require("../../../utils/shallowEqual");
33
+ // We extract Row to its own mini-component primarily so we can React.memo'ize it.
34
+ function RowImpl(props) {
35
+ var _a;
36
+ const { as, columns, row, style, rowStyles, stickyHeader, stickyOffset, sortOn, sortState, setSortKey, columnSizes, level, getCount, api, cellHighlight, ...others } = props;
37
+ const { rowState } = (0, react_1.useContext)(RowState_1.RowStateContext);
38
+ const rowId = `${row.kind}_${row.id}`;
39
+ const isActive = (0, hooks_1.useComputed)(() => rowState.activeRowId === rowId, [rowId, rowState]);
40
+ // We treat the "header" and "totals" kind as special for "good defaults" styling
41
+ const isHeader = row.kind === "header";
42
+ const isTotals = row.kind === "totals";
43
+ const rowStyle = rowStyles === null || rowStyles === void 0 ? void 0 : rowStyles[row.kind];
44
+ const RowTag = as === "table" ? "tr" : "div";
45
+ const revealOnRowHoverClass = "revealOnRowHover";
46
+ const rowStyleCellCss = (0, utils_1.maybeApplyFunction)(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.cellCss);
47
+ const rowCss = {
48
+ // For virtual tables use `display: flex` to keep all cells on the same row. For each cell in the row use `flexNone` to ensure they stay their defined widths
49
+ ...(as === "table" ? {} : Css_1.Css.relative.df.fg1.fs1.addIn("&>*", Css_1.Css.flexNone.$).$),
50
+ ...(((rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowLink) || (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.onClick)) && {
51
+ // Even though backgroundColor is set on the cellCss, the hover target is the row.
52
+ "&:hover > *": Css_1.Css.cursorPointer.bgColor((_a = style.rowHoverColor) !== null && _a !== void 0 ? _a : Css_1.Palette.LightBlue100).$,
53
+ }),
54
+ ...(0, utils_1.maybeApplyFunction)(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowCss),
55
+ // Maybe add the sticky header styles
56
+ ...((isHeader || isTotals) && stickyHeader ? Css_1.Css.sticky.topPx(stickyOffset).z2.$ : undefined),
57
+ ...{
58
+ [` > .${revealOnRowHoverClass} > *`]: Css_1.Css.invisible.$,
59
+ [`:hover > .${revealOnRowHoverClass} > *`]: Css_1.Css.visible.$,
60
+ },
61
+ };
62
+ let currentColspan = 1;
63
+ let firstContentColumnStylesApplied = false;
64
+ return ((0, jsx_runtime_1.jsx)(RowTag, Object.assign({ css: rowCss }, others, { "data-gridrow": true }, getCount(row.id), { children: columns.map((column, columnIndex) => {
65
+ var _a, _b, _c, _d, _e;
66
+ const { wrapAction = true, isAction = false } = column;
67
+ const applyFirstContentColumnStyles = !isHeader && !isAction && !firstContentColumnStylesApplied;
68
+ firstContentColumnStylesApplied || (firstContentColumnStylesApplied = applyFirstContentColumnStyles);
69
+ if (column.mw) {
70
+ // Validate the column's minWidth definition if set.
71
+ if (!column.mw.endsWith("px") && !column.mw.endsWith("%")) {
72
+ throw new Error("Beam Table column min-width definition only supports px or percentage values");
73
+ }
74
+ }
75
+ // Decrement colspan count and skip if greater than 1.
76
+ if (currentColspan > 1) {
77
+ currentColspan -= 1;
78
+ return null;
79
+ }
80
+ const maybeContent = (0, utils_1.applyRowFn)(column, row, api, level);
81
+ currentColspan = (0, utils_1.isGridCellContent)(maybeContent) ? (_a = maybeContent.colspan) !== null && _a !== void 0 ? _a : 1 : 1;
82
+ const revealOnRowHover = (0, utils_1.isGridCellContent)(maybeContent) ? maybeContent.revealOnRowHover : false;
83
+ const canSortColumn = (sortOn === "client" && column.clientSideSort !== false) ||
84
+ (sortOn === "server" && !!column.serverSideSortKey);
85
+ const alignment = (0, utils_1.getAlignment)(column, maybeContent);
86
+ const justificationCss = (0, utils_1.getJustification)(column, maybeContent, as, alignment);
87
+ const content = (0, utils_1.toContent)(maybeContent, isHeader, canSortColumn, sortOn === "client", style, as, alignment);
88
+ (0, sortRows_1.ensureClientSideSortValueIsSortable)(sortOn, isHeader, column, columnIndex, maybeContent);
89
+ const maybeSticky = (_b = (((0, utils_1.isGridCellContent)(maybeContent) && maybeContent.sticky) || column.sticky)) !== null && _b !== void 0 ? _b : undefined;
90
+ const maybeStickyColumnStyles = maybeSticky && columnSizes
91
+ ? {
92
+ ...Css_1.Css.sticky.z1.bgWhite.$,
93
+ ...(maybeSticky === "left"
94
+ ? Css_1.Css.left(columnIndex === 0 ? 0 : `calc(${columnSizes.slice(0, columnIndex).join(" + ")})`).$
95
+ : {}),
96
+ ...(maybeSticky === "right"
97
+ ? Css_1.Css.right(columnIndex + 1 === columnSizes.length
98
+ ? 0
99
+ : `calc(${columnSizes.slice(columnIndex + 1 - columnSizes.length).join(" + ")})`).$
100
+ : {}),
101
+ }
102
+ : {};
103
+ const cellId = `${row.kind}_${row.id}_${column.name}`;
104
+ const applyCellHighlight = cellHighlight && !!column.name && !isHeader && !isTotals;
105
+ const isCellActive = rowState.activeCellId === cellId;
106
+ // Note that it seems expensive to calc a per-cell class name/CSS-in-JS output,
107
+ // vs. setting global/table-wide CSS like `style.cellCss` on the root grid div with
108
+ // a few descendent selectors. However, that approach means the root grid-applied
109
+ // CSS has a high-specificity and so its harder for per-page/per-cell business logic
110
+ // to override it. So, we just calc the combined table-wide+per-cell-overridden CSS here,
111
+ // in a very CSS-in-JS idiomatic manner.
112
+ //
113
+ // In practice we've not seen any performance issues with this from our "large but
114
+ // not Google spreadsheets" tables.
115
+ const cellCss = {
116
+ // Adding display flex so we can align content within the cells
117
+ ...Css_1.Css.df.$,
118
+ // Apply sticky column/cell styles
119
+ ...maybeStickyColumnStyles,
120
+ // Apply any static/all-cell styling
121
+ ...style.cellCss,
122
+ // Then override with first/last cell styling
123
+ ...(0, utils_1.getFirstOrLastCellCss)(style, columnIndex, columns),
124
+ // Then override with per-cell/per-row justification/indentation
125
+ ...justificationCss,
126
+ ...(0, utils_1.getIndentationCss)(style, rowStyle, columnIndex, maybeContent),
127
+ // Then apply any header-specific override
128
+ ...(isHeader && style.headerCellCss),
129
+ // Then apply any totals-specific override
130
+ ...(isTotals && style.totalsCellCss),
131
+ // Or level-specific styling
132
+ ...(!isHeader && !isTotals && !!style.levels && ((_c = style.levels[level]) === null || _c === void 0 ? void 0 : _c.cellCss)),
133
+ // Level specific styling for the first content column
134
+ ...(applyFirstContentColumnStyles && !!style.levels && ((_d = style.levels[level]) === null || _d === void 0 ? void 0 : _d.firstContentColumn)),
135
+ // The specific cell's css (if any from GridCellContent)
136
+ ...rowStyleCellCss,
137
+ // Apply active row styling for non-nested card styles.
138
+ ...(isActive ? Css_1.Css.bgColor((_e = style.activeBgColor) !== null && _e !== void 0 ? _e : Css_1.Palette.LightBlue50).$ : {}),
139
+ // Add any cell specific style overrides
140
+ ...((0, utils_1.isGridCellContent)(maybeContent) && maybeContent.typeScale ? Css_1.Css[maybeContent.typeScale].$ : {}),
141
+ // And any cell specific css
142
+ ...((0, utils_1.isGridCellContent)(maybeContent) && maybeContent.css ? maybeContent.css : {}),
143
+ // Apply cell highlight styles to active cell and hover
144
+ ...Css_1.Css.if(applyCellHighlight && isCellActive).br4.boxShadow(`inset 0 0 0 1px ${Css_1.Palette.LightBlue700}`).$,
145
+ // Define the width of the column on each cell. Supports col spans.
146
+ width: `calc(${columnSizes.slice(columnIndex, columnIndex + currentColspan).join(" + ")})`,
147
+ ...(column.mw ? Css_1.Css.mw(column.mw).$ : {}),
148
+ };
149
+ const cellClassNames = revealOnRowHover ? revealOnRowHoverClass : undefined;
150
+ const cellOnClick = applyCellHighlight ? () => api.setActiveCellId(cellId) : undefined;
151
+ const renderFn = ((rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.renderCell) || (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.rowLink)) && wrapAction
152
+ ? (0, cell_1.rowLinkRenderFn)(as)
153
+ : isHeader
154
+ ? (0, cell_1.headerRenderFn)(columns, column, sortState, setSortKey, as)
155
+ : (rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.onClick) && wrapAction
156
+ ? (0, cell_1.rowClickRenderFn)(as, api)
157
+ : (0, cell_1.defaultRenderFn)(as);
158
+ return renderFn(columnIndex, cellCss, content, row, rowStyle, cellClassNames, cellOnClick);
159
+ }) }), void 0));
160
+ }
161
+ /**
162
+ * Memoizes Rows so that re-rendering the table doesn't re-render every single row.
163
+ *
164
+ * We use a custom `propsAreEqual` for the `RowProps.row` property, which we memoize
165
+ * based on the `GridDataRow.data` prop, such that if a table re-renders (i.e. for a cache
166
+ * updated) and technically creates new row instances, but a row's `row.data` points to the
167
+ * same/unchanged Apollo cache fragment, then we won't re-render that row.
168
+ *
169
+ * Note that if you're using virtualization, it can be surprising how unnoticeable broken row
170
+ * memoization is.
171
+ */
172
+ // Declared as a const + `as typeof RowImpl` to work with generics, see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/37087#issuecomment-656596623
173
+ exports.Row = react_1.default.memo((0, mobx_react_1.observer)(RowImpl), (one, two) => {
174
+ const { row: row1, ...others1 } = one;
175
+ const { row: row2, ...others2 } = two;
176
+ return (0, shallowEqual_1.shallowEqual)(row1, row2) && (0, shallowEqual_1.shallowEqual)(others1, others2);
177
+ });
@@ -3,15 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SelectToggle = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const RowState_1 = require("./RowState");
7
- const index_1 = require("../../hooks/index");
8
- const index_2 = require("../../inputs/index");
6
+ const RowState_1 = require("../utils/RowState");
7
+ const hooks_1 = require("../../../hooks");
8
+ const inputs_1 = require("../../../inputs");
9
9
  /** Provides a checkbox to show/drive this row's selected state. */
10
10
  function SelectToggle({ id, disabled }) {
11
11
  const { rowState } = (0, react_1.useContext)(RowState_1.RowStateContext);
12
- const state = (0, index_1.useComputed)(() => rowState.getSelected(id), [rowState]);
12
+ const state = (0, hooks_1.useComputed)(() => rowState.getSelected(id), [rowState]);
13
13
  const selected = state === "checked" ? true : state === "unchecked" ? false : "indeterminate";
14
- return ((0, jsx_runtime_1.jsx)(index_2.Checkbox, { checkboxOnly: true, disabled: disabled, label: "Select", onChange: (selected) => {
14
+ return ((0, jsx_runtime_1.jsx)(inputs_1.Checkbox, { checkboxOnly: true, disabled: disabled, label: "Select", onChange: (selected) => {
15
15
  rowState.selectRow(id, selected);
16
16
  }, selected: selected }, void 0));
17
17
  }
@@ -1,4 +1,4 @@
1
- import { Properties } from "../../Css";
1
+ import { Properties } from "../../../Css";
2
2
  /**
3
3
  * Wraps column header names with up/down sorting icons.
4
4
  *
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SortHeader = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const react_1 = require("react");
6
- const Icon_1 = require("../Icon");
7
- const GridSortContext_1 = require("./GridSortContext");
8
- const Css_1 = require("../../Css");
9
- const hooks_1 = require("../../hooks");
10
- const useTestIds_1 = require("../../utils/useTestIds");
6
+ const Icon_1 = require("../../Icon");
7
+ const GridSortContext_1 = require("../utils/GridSortContext");
8
+ const Css_1 = require("../../../Css");
9
+ const hooks_1 = require("../../../hooks");
10
+ const useTestIds_1 = require("../../../utils/useTestIds");
11
11
  /**
12
12
  * Wraps column header names with up/down sorting icons.
13
13
  *
@@ -0,0 +1,41 @@
1
+ import { ReactNode } from "react";
2
+ import { GridTableApi } from "../GridTableApi";
3
+ import { SortState } from "../hooks/useSortState";
4
+ import { RowStyle } from "../TableStyles";
5
+ import { GridCellAlignment, GridColumn, Kinded, MaybeFn, RenderAs } from "../types";
6
+ import { Properties, Typography } from "../../../Css";
7
+ /**
8
+ * Allows a cell to be more than just a RectNode, i.e. declare its alignment or
9
+ * primitive value for filtering and sorting.
10
+ */
11
+ export declare type GridCellContent = {
12
+ /** The JSX content of the cell. Virtual tables that client-side sort should use a function to avoid perf overhead. */
13
+ content: ReactNode | (() => ReactNode);
14
+ alignment?: GridCellAlignment;
15
+ /** Allow value to be a function in case it's a dynamic value i.e. reading from an inline-edited proxy. */
16
+ value?: MaybeFn<number | string | Date | boolean | null | undefined>;
17
+ /** The value to use specifically for sorting (i.e. if `value` is used for filtering); defaults to `value`. */
18
+ sortValue?: MaybeFn<number | string | Date | boolean | null | undefined>;
19
+ /** Whether to indent the cell. */
20
+ indent?: 1 | 2;
21
+ colspan?: number;
22
+ typeScale?: Typography;
23
+ /** Allows the cell to stay in place when the user scrolls horizontally, i.e. frozen columns. */
24
+ sticky?: "left" | "right";
25
+ /** If provided, content of the cell will be wrapped within a <button /> or <a /> tag depending on if the value is a function or a string. */
26
+ onClick?: () => {} | string;
27
+ /** Custom css to apply directly to this cell, i.e. cell-specific borders. */
28
+ css?: Properties;
29
+ /** Allows cell to reveal content when the user hovers over a row. Content must be wrapped in an element in order to be hidden. IE <div>{value}</div>*/
30
+ revealOnRowHover?: true;
31
+ };
32
+ /** Allows rendering a specific cell. */
33
+ export declare type RenderCellFn<R extends Kinded> = (idx: number, css: Properties, content: ReactNode, row: R, rowStyle: RowStyle<R> | undefined, classNames: string | undefined, onClick: (() => void) | undefined) => ReactNode;
34
+ /** Renders our default cell element, i.e. if no row links and no custom renderCell are used. */
35
+ export declare const defaultRenderFn: (as: RenderAs) => RenderCellFn<any>;
36
+ /** Sets up the `GridContext` so that header cells can access the current sort settings. */
37
+ export declare const headerRenderFn: (columns: GridColumn<any>[], column: GridColumn<any>, sortState: SortState<any> | undefined, setSortKey: Function | undefined, as: RenderAs) => RenderCellFn<any>;
38
+ /** Renders a cell element when a row link is in play. */
39
+ export declare const rowLinkRenderFn: (as: RenderAs) => RenderCellFn<any>;
40
+ /** Renders a cell that will fire the RowStyle.onClick. */
41
+ export declare const rowClickRenderFn: (as: RenderAs, api: GridTableApi<any>) => RenderCellFn<any>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rowClickRenderFn = exports.rowLinkRenderFn = exports.headerRenderFn = exports.defaultRenderFn = void 0;
4
+ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
+ const react_router_dom_1 = require("react-router-dom");
6
+ const CssReset_1 = require("../../CssReset");
7
+ const TableStyles_1 = require("../TableStyles");
8
+ const GridSortContext_1 = require("../utils/GridSortContext");
9
+ const Css_1 = require("../../../Css");
10
+ /** Renders our default cell element, i.e. if no row links and no custom renderCell are used. */
11
+ const defaultRenderFn = (as) => (key, css, content, row, rowStyle, classNames, onClick) => {
12
+ const Cell = as === "table" ? "td" : "div";
13
+ return ((0, jsx_runtime_1.jsx)(Cell, Object.assign({ css: { ...css, ...(0, TableStyles_1.tableRowStyles)(as) }, className: classNames, onClick: onClick }, { children: content }), key));
14
+ };
15
+ exports.defaultRenderFn = defaultRenderFn;
16
+ /** Sets up the `GridContext` so that header cells can access the current sort settings. */
17
+ const headerRenderFn = (columns, column, sortState, setSortKey, as) => (key, css, content, row, rowStyle, classNames) => {
18
+ const [currentKey, direction] = sortState || [];
19
+ // If server-side sorting, use the user's key for this column; client-side sorting, use the index.
20
+ const ourSortKey = column.serverSideSortKey || columns.indexOf(column);
21
+ const context = {
22
+ sorted: ourSortKey === currentKey ? direction : undefined,
23
+ toggleSort: () => setSortKey(ourSortKey),
24
+ };
25
+ const Cell = as === "table" ? "th" : "div";
26
+ return ((0, jsx_runtime_1.jsx)(GridSortContext_1.GridSortContext.Provider, Object.assign({ value: context }, { children: (0, jsx_runtime_1.jsx)(Cell, Object.assign({ css: { ...css, ...(0, TableStyles_1.tableRowStyles)(as, column) }, className: classNames }, { children: content }), void 0) }), key));
27
+ };
28
+ exports.headerRenderFn = headerRenderFn;
29
+ /** Renders a cell element when a row link is in play. */
30
+ const rowLinkRenderFn = (as) => (key, css, content, row, rowStyle, classNames) => {
31
+ const to = rowStyle.rowLink(row);
32
+ if (as === "table") {
33
+ return ((0, jsx_runtime_1.jsx)("td", Object.assign({ css: { ...css, ...(0, TableStyles_1.tableRowStyles)(as) }, className: classNames }, { children: (0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({ to: to, css: Css_1.Css.noUnderline.color("unset").db.$, className: CssReset_1.navLink }, { children: content }), void 0) }), key));
34
+ }
35
+ return ((0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({ to: to, css: { ...Css_1.Css.noUnderline.color("unset").$, ...css }, className: `${CssReset_1.navLink} ${classNames}` }, { children: content }), key));
36
+ };
37
+ exports.rowLinkRenderFn = rowLinkRenderFn;
38
+ /** Renders a cell that will fire the RowStyle.onClick. */
39
+ const rowClickRenderFn = (as, api) => (key, css, content, row, rowStyle, classNames, onClick) => {
40
+ const Row = as === "table" ? "tr" : "div";
41
+ return ((0, jsx_runtime_1.jsx)(Row, Object.assign({}, { key }, { css: { ...css, ...(0, TableStyles_1.tableRowStyles)(as) }, className: classNames, onClick: (e) => {
42
+ rowStyle.onClick(row, api);
43
+ onClick && onClick();
44
+ } }, { children: content }), void 0));
45
+ };
46
+ exports.rowClickRenderFn = rowClickRenderFn;
@@ -1,3 +1,3 @@
1
1
  import { Dispatch, SetStateAction } from "react";
2
- import { GridColumn, Kinded } from "./GridTable";
2
+ import { GridColumn, Kinded } from "../types";
3
3
  export declare function useColumns<R extends Kinded, S = {}>(tableColumns: GridColumn<R, S>[], maybeStorageKey?: string): [GridColumn<R, S>[], Dispatch<SetStateAction<GridColumn<R, S>[]>>];
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useColumns = void 0;
4
4
  const change_case_1 = require("change-case");
5
5
  const react_1 = require("react");
6
- const useSessionStorage_1 = require("../../hooks/useSessionStorage");
6
+ const useSessionStorage_1 = require("../../../hooks/useSessionStorage");
7
7
  function useColumns(tableColumns, maybeStorageKey) {
8
8
  const { selectedColumns, hideColumns } = tableColumns.reduce((acc, column) => {
9
9
  // Only include options that can be hidden and have the `name` property defined.
@@ -1,5 +1,6 @@
1
1
  import { MutableRefObject } from "react";
2
- import { GridColumn, GridStyle } from "./GridTable";
2
+ import { GridStyle } from "../TableStyles";
3
+ import { GridColumn } from "../types";
3
4
  /**
4
5
  * Calculates an array of sizes for each of our columns.
5
6
  *
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useSetupColumnSizes = void 0;
4
4
  const utils_1 = require("@react-aria/utils");
5
5
  const react_1 = require("react");
6
- const GridTable_1 = require("./GridTable");
6
+ const columns_1 = require("../utils/columns");
7
7
  const use_debounce_1 = require("use-debounce");
8
8
  /**
9
9
  * Calculates an array of sizes for each of our columns.
@@ -31,10 +31,10 @@ function useSetupColumnSizes(style, columns, resizeRef) {
31
31
  const calculateImmediately = (0, react_1.useRef)(true);
32
32
  const [tableWidth, setTableWidth] = (0, react_1.useState)();
33
33
  // Calc our initial/first render sizes where we won't have a width yet
34
- const [columnSizes, setColumnSizes] = (0, react_1.useState)((0, GridTable_1.calcColumnSizes)(columns, tableWidth, style.minWidthPx));
34
+ const [columnSizes, setColumnSizes] = (0, react_1.useState)((0, columns_1.calcColumnSizes)(columns, tableWidth, style.minWidthPx));
35
35
  const setTableAndColumnWidths = (0, react_1.useCallback)((width) => {
36
36
  setTableWidth(width);
37
- setColumnSizes((0, GridTable_1.calcColumnSizes)(columns, width, style.minWidthPx));
37
+ setColumnSizes((0, columns_1.calcColumnSizes)(columns, width, style.minWidthPx));
38
38
  }, [setTableWidth, setColumnSizes, columns, style]);
39
39
  // Used to recalculate our columns sizes when columns change
40
40
  (0, react_1.useEffect)(() => {
@@ -1,4 +1,5 @@
1
- import { Direction, GridColumn, GridSortConfig, Kinded } from "./GridTable";
1
+ import { GridSortConfig } from "../GridTable";
2
+ import { Direction, GridColumn, Kinded } from "../types";
2
3
  /**
3
4
  * Our internal sorting state.
4
5
  *