schummar-table 0.2.0 → 0.3.2

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 (35) hide show
  1. package/dist/cjs/components/cell.d.ts +3 -2
  2. package/dist/cjs/components/cell.js +16 -13
  3. package/dist/cjs/components/columnSelection.js +1 -1
  4. package/dist/cjs/components/expandComponent.js +1 -1
  5. package/dist/cjs/components/export.js +1 -1
  6. package/dist/cjs/components/row.d.ts +2 -1
  7. package/dist/cjs/components/row.js +2 -2
  8. package/dist/cjs/components/textFilterComponent.d.ts +0 -1
  9. package/dist/cjs/components/textFilterComponent.js +0 -1
  10. package/dist/cjs/components/useCommonClasses.d.ts +1 -1
  11. package/dist/cjs/components/useCommonClasses.js +10 -6
  12. package/dist/cjs/components/virtualized.d.ts +1 -1
  13. package/dist/cjs/components/virtualized.js +5 -5
  14. package/dist/cjs/index.d.ts +2 -1
  15. package/dist/cjs/internalState/calcProps.js +23 -6
  16. package/dist/cjs/table.js +1 -1
  17. package/dist/cjs/types.d.ts +5 -0
  18. package/dist/esm/components/cell.d.ts +3 -2
  19. package/dist/esm/components/cell.js +16 -13
  20. package/dist/esm/components/columnSelection.js +1 -1
  21. package/dist/esm/components/expandComponent.js +1 -1
  22. package/dist/esm/components/export.js +2 -2
  23. package/dist/esm/components/row.d.ts +2 -1
  24. package/dist/esm/components/row.js +2 -2
  25. package/dist/esm/components/textFilterComponent.d.ts +0 -1
  26. package/dist/esm/components/textFilterComponent.js +0 -1
  27. package/dist/esm/components/useCommonClasses.d.ts +1 -1
  28. package/dist/esm/components/useCommonClasses.js +10 -6
  29. package/dist/esm/components/virtualized.d.ts +1 -1
  30. package/dist/esm/components/virtualized.js +5 -5
  31. package/dist/esm/index.d.ts +2 -1
  32. package/dist/esm/internalState/calcProps.js +24 -7
  33. package/dist/esm/table.js +1 -1
  34. package/dist/esm/types.d.ts +5 -0
  35. package/package.json +14 -14
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Id } from '..';
3
- export declare const Cell: React.MemoExoticComponent<(<T>({ itemId }: {
3
+ export declare const Cell: React.MemoExoticComponent<(<T>({ itemId, rowIndex }: {
4
4
  itemId: Id;
5
- }) => JSX.Element)>;
5
+ rowIndex: number;
6
+ }) => JSX.Element | null)>;
@@ -7,22 +7,25 @@ const __1 = require("..");
7
7
  const helpers_1 = require("../misc/helpers");
8
8
  const row_1 = require("./row");
9
9
  const useCommonClasses_1 = require("./useCommonClasses");
10
- exports.Cell = (0, react_1.memo)(function Cell({ itemId }) {
10
+ exports.Cell = (0, react_1.memo)(function Cell({ itemId, rowIndex }) {
11
11
  var _a, _b;
12
12
  const commonClasses = (0, useCommonClasses_1.useCommonClasses)();
13
13
  const state = (0, __1.useTableContext)();
14
14
  const columnId = (0, __1.useColumnContext)();
15
- const content = state.useState((state) => {
16
- var _a;
17
- const item = state.activeItemsById.get(itemId);
18
- const column = state.activeColumns.find((column) => column.id === columnId);
19
- if (!item || !column)
20
- return null;
21
- const index = item ? state.activeItems.indexOf(item) : -1;
22
- const className = (0, helpers_1.c)((0, row_1.calcClassName)(state.props.classes, index), (0, row_1.calcClassName)(column === null || column === void 0 ? void 0 : column.classes, index));
23
- const wrapCell = (_a = state.props.wrapCell) !== null && _a !== void 0 ? _a : ((cell) => (0, jsx_runtime_1.jsx)("div", Object.assign({ className: (0, helpers_1.c)(commonClasses.cell, className) }, { children: cell }), void 0));
24
- return wrapCell(column.renderCell(column.value(item), item), item);
25
- }, [itemId, columnId, commonClasses]);
15
+ const column = state.useState((state) => state.activeColumns.find((column) => column.id === columnId), [columnId]);
16
+ const item = state.useState((state) => state.activeItemsById.get(itemId), [itemId]);
17
+ const classes = state.useState('props.classes');
18
+ let wrapCell = state.useState('props.wrapCell');
19
+ if (!column || !item)
20
+ return null;
26
21
  (_b = (_a = state.getState().props).debug) === null || _b === void 0 ? void 0 : _b.call(_a, 'render cell', itemId, columnId);
27
- return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: content }, void 0);
22
+ const className = (0, helpers_1.c)((0, row_1.calcClassName)(classes, rowIndex), (0, row_1.calcClassName)(column === null || column === void 0 ? void 0 : column.classes, rowIndex));
23
+ const content = column.renderCell(column.value(item), item);
24
+ if (!wrapCell && typeof content === 'string') {
25
+ wrapCell = (content) => ((0, jsx_runtime_1.jsx)("div", Object.assign({ className: (0, helpers_1.c)(commonClasses.cell, className) }, { children: (0, jsx_runtime_1.jsx)("span", Object.assign({ className: (0, helpers_1.c)(commonClasses.text) }, { children: content }), void 0) }), void 0));
26
+ }
27
+ else if (!wrapCell) {
28
+ wrapCell = (content) => (0, jsx_runtime_1.jsx)("div", Object.assign({ className: (0, helpers_1.c)(commonClasses.cell, className) }, { children: content }), void 0);
29
+ }
30
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: wrapCell(content, item) }, void 0);
28
31
  });
@@ -32,6 +32,6 @@ function ColumnSelection() {
32
32
  }
33
33
  onHiddenColumnsChange === null || onHiddenColumnsChange === void 0 ? void 0 : onHiddenColumnsChange(newValue);
34
34
  };
35
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.IconButton, Object.assign({ color: "inherit", onClick: (e) => setAnchor(e.currentTarget) }, { children: (0, jsx_runtime_1.jsx)(icons_1.Settings, {}, void 0) }), void 0), (0, jsx_runtime_1.jsx)(core_1.Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'center' } }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: classes.list }, { children: columns.map((column) => ((0, jsx_runtime_1.jsx)(core_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(core_1.Checkbox, { checked: !hiddenColumns.has(column.id), onChange: () => toggle(column), disabled: column.cannotHide }, void 0), label: column.header }, column.id))) }), void 0) }), void 0)] }, void 0));
35
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.IconButton, Object.assign({ color: "inherit", size: "small", onClick: (e) => setAnchor(e.currentTarget) }, { children: (0, jsx_runtime_1.jsx)(icons_1.Settings, {}, void 0) }), void 0), (0, jsx_runtime_1.jsx)(core_1.Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'left' } }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: classes.list }, { children: columns.map((column) => ((0, jsx_runtime_1.jsx)(core_1.FormControlLabel, { control: (0, jsx_runtime_1.jsx)(core_1.Checkbox, { checked: !hiddenColumns.has(column.id), onChange: () => toggle(column), disabled: column.cannotHide }, void 0), label: column.header }, column.id))) }), void 0) }), void 0)] }, void 0));
36
36
  }
37
37
  exports.ColumnSelection = ColumnSelection;
@@ -30,7 +30,7 @@ function ExpandComponent({ itemId }) {
30
30
  });
31
31
  }
32
32
  }
33
- return ((0, jsx_runtime_1.jsx)(core_1.IconButton, Object.assign({ onClick: toggle }, { children: (0, jsx_runtime_1.jsx)(icons_1.ChevronRight, { style: {
33
+ return ((0, jsx_runtime_1.jsx)(core_1.IconButton, Object.assign({ size: "small", onClick: toggle }, { children: (0, jsx_runtime_1.jsx)(icons_1.ChevronRight, { style: {
34
34
  transition: 'all 500ms',
35
35
  transform: isExpanded ? 'rotate3d(0, 0, 1, 90deg)' : 'none',
36
36
  } }, void 0) }), void 0));
@@ -43,6 +43,6 @@ function Export() {
43
43
  a.click();
44
44
  document.body.removeChild(a);
45
45
  };
46
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.IconButton, Object.assign({ color: "inherit", onClick: (e) => setAnchor(e.currentTarget) }, { children: (0, jsx_runtime_1.jsx)(icons_1.GetApp, {}, void 0) }), void 0), (0, jsx_runtime_1.jsx)(core_1.Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'center' } }, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: classes.dialog }, { children: [(0, jsx_runtime_1.jsx)(core_1.Typography, Object.assign({ variant: "caption" }, { children: textTitle !== null && textTitle !== void 0 ? textTitle : 'Export' }), void 0), (0, jsx_runtime_1.jsx)(core_1.Button, Object.assign({ startIcon: (0, jsx_runtime_1.jsx)(icons_1.AssignmentReturn, {}, void 0), fullWidth: true, onClick: copy }, { children: textCopy !== null && textCopy !== void 0 ? textCopy : 'In die Zwischenablage' }), void 0), (0, jsx_runtime_1.jsx)(core_1.Button, Object.assign({ startIcon: (0, jsx_runtime_1.jsx)(icons_1.CloudDownload, {}, void 0), fullWidth: true, onClick: download }, { children: textDownload !== null && textDownload !== void 0 ? textDownload : 'Herunterladen' }), void 0)] }), void 0) }), void 0)] }, void 0));
46
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.IconButton, Object.assign({ color: "inherit", size: "small", onClick: (e) => setAnchor(e.currentTarget) }, { children: (0, jsx_runtime_1.jsx)(icons_1.CloudDownload, {}, void 0) }), void 0), (0, jsx_runtime_1.jsx)(core_1.Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'left' } }, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: classes.dialog }, { children: [(0, jsx_runtime_1.jsx)(core_1.Typography, Object.assign({ variant: "caption" }, { children: textTitle !== null && textTitle !== void 0 ? textTitle : 'Export' }), void 0), (0, jsx_runtime_1.jsx)(core_1.Button, Object.assign({ startIcon: (0, jsx_runtime_1.jsx)(icons_1.AssignmentReturn, {}, void 0), fullWidth: true, onClick: copy }, { children: textCopy !== null && textCopy !== void 0 ? textCopy : 'In die Zwischenablage' }), void 0), (0, jsx_runtime_1.jsx)(core_1.Button, Object.assign({ startIcon: (0, jsx_runtime_1.jsx)(icons_1.CloudDownload, {}, void 0), fullWidth: true, onClick: download }, { children: textDownload !== null && textDownload !== void 0 ? textDownload : 'Herunterladen' }), void 0)] }), void 0) }), void 0)] }, void 0));
47
47
  }
48
48
  exports.Export = Export;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Id, InternalColumn } from '../types';
3
3
  export declare const calcClassName: (classes: InternalColumn<any, any>['classes'] | undefined, index: number) => string;
4
- export declare const Row: React.MemoExoticComponent<(<T>({ itemId }: {
4
+ export declare const Row: React.MemoExoticComponent<(<T>({ itemId, rowIndex }: {
5
5
  itemId: Id;
6
+ rowIndex: number;
6
7
  }) => JSX.Element | null)>;
@@ -11,7 +11,7 @@ const selectComponent_1 = require("./selectComponent");
11
11
  const useCommonClasses_1 = require("./useCommonClasses");
12
12
  const calcClassName = (classes, index) => (0, helpers_1.c)(classes === null || classes === void 0 ? void 0 : classes.cell, (classes === null || classes === void 0 ? void 0 : classes.evenCell) === undefined ? undefined : { [classes.evenCell]: index % 2 === 0 }, (classes === null || classes === void 0 ? void 0 : classes.oddCell) === undefined ? undefined : { [classes.oddCell]: index % 2 === 1 });
13
13
  exports.calcClassName = calcClassName;
14
- exports.Row = (0, react_1.memo)(function Row({ itemId }) {
14
+ exports.Row = (0, react_1.memo)(function Row({ itemId, rowIndex }) {
15
15
  var _a, _b;
16
16
  const commonClasses = (0, useCommonClasses_1.useCommonClasses)();
17
17
  const state = (0, table_1.useTableContext)();
@@ -44,5 +44,5 @@ exports.Row = (0, react_1.memo)(function Row({ itemId }) {
44
44
  return () => o.disconnect();
45
45
  }, [divRef.current]);
46
46
  (_b = (_a = state.getState().props).debug) === null || _b === void 0 ? void 0 : _b.call(_a, 'render row', itemId);
47
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: (0, helpers_1.c)(commonClasses.cellFill, className), ref: divRef }, void 0), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: (0, helpers_1.c)(commonClasses.cell, commonClasses.firstCell, className) }, { children: [(0, jsx_runtime_1.jsx)("div", { style: { width: indent * 20 } }, void 0), enableSelection && (0, jsx_runtime_1.jsx)(selectComponent_1.SelectComponent, { itemId: itemId }, void 0), (hasChildren || hasDeferredChildren) && (0, jsx_runtime_1.jsx)(expandComponent_1.ExpandComponent, { itemId: itemId }, void 0)] }), void 0), columnIds.map((columnId) => ((0, jsx_runtime_1.jsx)(table_1.ColumnContext.Provider, Object.assign({ value: columnId }, { children: (0, jsx_runtime_1.jsx)(cell_1.Cell, { itemId: itemId }, void 0) }), columnId))), (0, jsx_runtime_1.jsx)("div", { className: (0, helpers_1.c)(commonClasses.cellFill, className) }, void 0)] }, void 0));
47
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: (0, helpers_1.c)(commonClasses.cellFill, className), ref: divRef }, void 0), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: (0, helpers_1.c)(commonClasses.cell, commonClasses.firstCell, className) }, { children: [(0, jsx_runtime_1.jsx)("div", { style: { width: indent * 20 } }, void 0), enableSelection && (0, jsx_runtime_1.jsx)(selectComponent_1.SelectComponent, { itemId: itemId }, void 0), (hasChildren || hasDeferredChildren) && (0, jsx_runtime_1.jsx)(expandComponent_1.ExpandComponent, { itemId: itemId }, void 0)] }), void 0), columnIds.map((columnId) => ((0, jsx_runtime_1.jsx)(table_1.ColumnContext.Provider, Object.assign({ value: columnId }, { children: (0, jsx_runtime_1.jsx)(cell_1.Cell, { itemId: itemId, rowIndex: rowIndex }, void 0) }), columnId))), (0, jsx_runtime_1.jsx)("div", { className: (0, helpers_1.c)(commonClasses.cellFill, className) }, void 0)] }, void 0));
48
48
  });
@@ -1,5 +1,4 @@
1
1
  /// <reference types="react" />
2
- import '../misc/textMatch';
3
2
  import { Filter } from './filterComponent';
4
3
  export declare class TextFilter<T> implements Filter<T> {
5
4
  readonly query: string;
@@ -6,7 +6,6 @@ const core_1 = require("@material-ui/core");
6
6
  const icons_1 = require("@material-ui/icons");
7
7
  const react_1 = require("react");
8
8
  const helpers_1 = require("../misc/helpers");
9
- require("../misc/textMatch");
10
9
  const textMatch_1 = require("../misc/textMatch");
11
10
  const table_1 = require("../table");
12
11
  class TextFilter {
@@ -1 +1 @@
1
- export declare const useCommonClasses: (props?: any) => import("@material-ui/styles").ClassNameMap<"table" | "cell" | "sticky" | "headerCell" | "cellFill" | "firstCell" | "headerFill" | "deferredPlaceholder">;
1
+ export declare const useCommonClasses: (props?: any) => import("@material-ui/styles").ClassNameMap<"table" | "text" | "cell" | "sticky" | "headerCell" | "cellFill" | "firstCell" | "headerFill" | "deferredPlaceholder">;
@@ -3,14 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCommonClasses = void 0;
4
4
  const core_1 = require("@material-ui/core");
5
5
  const cell = (theme) => ({
6
- padding: theme.spacing(0.5, 1),
7
- display: 'grid',
8
- gridAutoFlow: 'column',
6
+ padding: theme.spacing(0.1, 1),
7
+ display: 'flex',
9
8
  alignItems: 'center',
10
9
  borderBottom: `1px solid ${theme.palette.grey[200]}`,
11
10
  whiteSpace: 'nowrap',
12
11
  overflow: 'hidden',
13
- textOverflow: 'ellipsis',
14
12
  });
15
13
  exports.useCommonClasses = (0, core_1.makeStyles)((theme) => ({
16
14
  table: {
@@ -21,7 +19,7 @@ exports.useCommonClasses = (0, core_1.makeStyles)((theme) => ({
21
19
  cellFill: {
22
20
  borderBottom: `1px solid ${theme.palette.grey[200]}`,
23
21
  },
24
- headerCell: Object.assign(Object.assign({}, cell(theme)), { borderBottom: 'none', gridTemplateColumns: 'minmax(0, 1fr) max-content', background: theme.palette.primary.main, color: theme.palette.primary.contrastText, fontWeight: 'bold', '&:not(:first-child)': {
22
+ headerCell: Object.assign(Object.assign({}, cell(theme)), { borderBottom: `2px solid ${theme.palette.grey[400]}`, gridTemplateColumns: 'minmax(0, 1fr) max-content', background: theme.palette.common.white, '&:not(:first-child)': {
25
23
  borderLeft: `1px solid ${theme.palette.background.default}`,
26
24
  } }),
27
25
  firstCell: {
@@ -33,7 +31,8 @@ exports.useCommonClasses = (0, core_1.makeStyles)((theme) => ({
33
31
  zIndex: 1,
34
32
  },
35
33
  headerFill: {
36
- background: theme.palette.primary.main,
34
+ borderBottom: `3px solid ${theme.palette.grey[200]}`,
35
+ background: theme.palette.common.white,
37
36
  },
38
37
  deferredPlaceholder: {
39
38
  padding: theme.spacing(1),
@@ -42,4 +41,9 @@ exports.useCommonClasses = (0, core_1.makeStyles)((theme) => ({
42
41
  display: 'grid',
43
42
  justifyContent: 'center',
44
43
  },
44
+ text: {
45
+ minWidth: 0,
46
+ overflow: 'hidden',
47
+ textOverflow: 'ellipsis',
48
+ },
45
49
  }));
@@ -2,5 +2,5 @@ import { HTMLProps, ReactNode } from 'react';
2
2
  import { Id } from '../types';
3
3
  export declare function Virtualized<T>({ header, children, ...props }: {
4
4
  header: ReactNode;
5
- children: (itemIds: Id[]) => ReactNode;
5
+ children: (itemIds: Id[], startIndex: number) => ReactNode;
6
6
  } & HTMLProps<HTMLDivElement>): JSX.Element;
@@ -50,7 +50,7 @@ function Virtualized(_a) {
50
50
  const virtual = state.useState('props.virtual');
51
51
  const probeRef = (0, react_1.useRef)(null);
52
52
  const [counter, setCounter] = (0, react_1.useState)(0);
53
- const { itemIds = [], from, to, before = 0, after = 0, } = state.useState((state) => {
53
+ const { itemIds = [], from = 0, to, before = 0, after = 0, } = state.useState((state) => {
54
54
  var _a;
55
55
  const itemIds = state.activeItems.map((item) => item.id);
56
56
  const root = probeRef.current && findScrollRoot(probeRef.current);
@@ -58,7 +58,7 @@ function Virtualized(_a) {
58
58
  return { itemIds };
59
59
  if (!probeRef.current || !root || !document.contains(root))
60
60
  return {};
61
- const { rowHeight, initalRowHeight } = (_a = (state.props.virtual instanceof Object ? state.props.virtual : undefined)) !== null && _a !== void 0 ? _a : {};
61
+ const { rowHeight, initalRowHeight, overscan = 200, overscanTop, overscanBottom, } = (_a = (state.props.virtual instanceof Object ? state.props.virtual : undefined)) !== null && _a !== void 0 ? _a : {};
62
62
  let totalHeight = 0;
63
63
  const rowHeights = itemIds.map((itemId, index) => {
64
64
  var _a, _b;
@@ -72,13 +72,13 @@ function Virtualized(_a) {
72
72
  const bottomOfTable = topOfTable + root.clientHeight - headerHeight;
73
73
  let from = 0, to = itemIds.length, before = 0, after = 0;
74
74
  for (const h of rowHeights) {
75
- if (before + h > topOfTable)
75
+ if (before + h > topOfTable - (overscanTop !== null && overscanTop !== void 0 ? overscanTop : overscan))
76
76
  break;
77
77
  from++;
78
78
  before += h;
79
79
  }
80
80
  for (const h of rowHeights.reverse()) {
81
- if (after + h > totalHeight - bottomOfTable)
81
+ if (after + h > totalHeight - bottomOfTable - (overscanBottom !== null && overscanBottom !== void 0 ? overscanBottom : overscan))
82
82
  break;
83
83
  to--;
84
84
  after += h;
@@ -93,6 +93,6 @@ function Virtualized(_a) {
93
93
  return onAncestorScroll(probeRef.current, incCounter);
94
94
  }, [probeRef.current, incCounter]);
95
95
  (_e = (_d = state.getState().props).debug) === null || _e === void 0 ? void 0 : _e.call(_d, `Virtualalized render ${from} to ${to}`);
96
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, props, { children: [header, virtual && (0, jsx_runtime_1.jsx)("div", { style: { gridColumn: '1 / -1', height: before }, ref: probeRef }, void 0), children(itemIds), virtual && (0, jsx_runtime_1.jsx)("div", { style: { gridColumn: '1 / -1', height: after } }, void 0)] }), void 0));
96
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, props, { children: [header, virtual && (0, jsx_runtime_1.jsx)("div", { style: { gridColumn: '1 / -1', height: before }, ref: probeRef }, void 0), children(itemIds, from), virtual && (0, jsx_runtime_1.jsx)("div", { style: { gridColumn: '1 / -1', height: after } }, void 0)] }), void 0));
97
97
  }
98
98
  exports.Virtualized = Virtualized;
@@ -1,5 +1,6 @@
1
1
  export { DefaultFilter, DefaultFilterComponent } from './components/defaultFilterComponent';
2
+ export { Filter } from './components/filterComponent';
2
3
  export { TextFilter, TextFilterComponent } from './components/textFilterComponent';
3
4
  export { termMatch, textMatch } from './misc/textMatch';
4
5
  export { ColumnContext, Table, TableContext, useColumnContext, useTableContext } from './table';
5
- export type { Column, Id, Rows, Sort, SortDirection, TableProps } from './types';
6
+ export type { Column, Id, InternalColumn, Rows, Sort, SortDirection, TableProps } from './types';
@@ -16,6 +16,7 @@ const react_1 = require("react");
16
16
  const helpers_1 = require("../misc/helpers");
17
17
  const noopParentId = () => undefined;
18
18
  function calcProps(props) {
19
+ const columnCache = (0, react_1.useRef)(new Map());
19
20
  return (0, react_1.useMemo)(() => {
20
21
  var _a, _b;
21
22
  let id;
@@ -40,15 +41,31 @@ function calcProps(props) {
40
41
  inputColumns = props.columns((value, column) => (Object.assign(Object.assign({}, column), { value })));
41
42
  }
42
43
  else {
43
- inputColumns = props.columns;
44
+ inputColumns = props.columns.map((column) => (Object.assign(Object.assign({}, column), { dependecies: undefined })));
44
45
  }
46
+ const newColumnCache = new Map();
45
47
  const columns = inputColumns.map(function (_a, index) {
46
- var { id, header = null, renderCell = helpers_1.asString, exportCell = helpers_1.asString, sortBy = (v) => (typeof v === 'number' || v instanceof Date ? v : String(v)) } = _a, props = __rest(_a, ["id", "header", "renderCell", "exportCell", "sortBy"]);
47
- return Object.assign({ id: id !== null && id !== void 0 ? id : index, header,
48
- renderCell,
49
- exportCell,
50
- sortBy }, props);
48
+ var _b;
49
+ var { id, header = null, renderCell = helpers_1.asString, exportCell = helpers_1.asString, sortBy = (v) => (typeof v === 'number' || v instanceof Date ? v : String(v)), dependencies = [] } = _a, props = __rest(_a, ["id", "header", "renderCell", "exportCell", "sortBy", "dependencies"]);
50
+ const [depsInCache, columnInCache] = (_b = columnCache.current.get(id !== null && id !== void 0 ? id : index)) !== null && _b !== void 0 ? _b : [];
51
+ let column;
52
+ if (depsInCache &&
53
+ columnInCache &&
54
+ depsInCache.length === dependencies.length &&
55
+ depsInCache.every((x, i) => dependencies[i] === x)) {
56
+ column = columnInCache;
57
+ }
58
+ else {
59
+ column = Object.assign({ id: id !== null && id !== void 0 ? id : index, header,
60
+ renderCell,
61
+ exportCell,
62
+ sortBy,
63
+ dependencies }, props);
64
+ }
65
+ newColumnCache.set(id !== null && id !== void 0 ? id : index, [dependencies, column]);
66
+ return column;
51
67
  });
68
+ columnCache.current = newColumnCache;
52
69
  let copy;
53
70
  if (props.enableExport === true || (props.enableExport instanceof Object && props.enableExport.copy === true)) {
54
71
  copy = { separator: '\t' };
package/dist/cjs/table.js CHANGED
@@ -65,5 +65,5 @@ const TableInner = (0, react_1.memo)(function TableInner() {
65
65
  }, header: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: (0, helpers_1.c)(commonClasses.headerFill, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, void 0), (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: (0, helpers_1.c)(commonClasses.headerCell, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, { children: [enableSelection && (0, jsx_runtime_1.jsx)(selectComponent_1.SelectComponent, {}, void 0), enableColumnSelection && (0, jsx_runtime_1.jsx)(columnSelection_1.ColumnSelection, {}, void 0), enableExport && (0, jsx_runtime_1.jsx)(export_1.Export, {}, void 0)] }), void 0), activeColumns.map((column) => {
66
66
  var _a;
67
67
  return ((0, jsx_runtime_1.jsx)(exports.ColumnContext.Provider, Object.assign({ value: column.id }, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: (0, helpers_1.c)(commonClasses.headerCell, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell, (_a = column.classes) === null || _a === void 0 ? void 0 : _a.headerCell) }, { children: [(0, jsx_runtime_1.jsx)(sortComponent_1.SortComponent, { children: column.header }, void 0), (0, jsx_runtime_1.jsx)(filterComponent_1.FilterComponent, {}, void 0)] }), column.id) }), column.id));
68
- }), (0, jsx_runtime_1.jsx)("div", { className: (0, helpers_1.c)(commonClasses.headerFill, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, void 0)] }, void 0) }, { children: (itemIds) => itemIds.map((itemId) => (0, jsx_runtime_1.jsx)(row_1.Row, { itemId: itemId }, itemId)) }), void 0));
68
+ }), (0, jsx_runtime_1.jsx)("div", { className: (0, helpers_1.c)(commonClasses.headerFill, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, void 0)] }, void 0) }, { children: (itemIds, startIndex) => itemIds.map((itemId, index) => (0, jsx_runtime_1.jsx)(row_1.Row, { itemId: itemId, rowIndex: startIndex + index }, itemId)) }), void 0));
69
69
  });
@@ -38,6 +38,9 @@ export declare type TableProps<T> = {
38
38
  rowHeight?: number;
39
39
  initalRowHeight?: number;
40
40
  throttleScroll?: number;
41
+ overscan?: number;
42
+ overscanBottom?: number;
43
+ overscanTop?: number;
41
44
  };
42
45
  text?: {
43
46
  deselectAll?: string;
@@ -97,6 +100,8 @@ export declare type Column<T, V> = {
97
100
  evenCell?: string;
98
101
  oddCell?: string;
99
102
  };
103
+ /** If the column definition changes, supply parameters that it depends on. If not set, the column will not update */
104
+ dependencies?: any[];
100
105
  };
101
106
  export declare type InternalColumn<T, V> = Required<Omit<Column<T, V>, 'id'> & {
102
107
  id: Id;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Id } from '..';
3
- export declare const Cell: React.MemoExoticComponent<(<T>({ itemId }: {
3
+ export declare const Cell: React.MemoExoticComponent<(<T>({ itemId, rowIndex }: {
4
4
  itemId: Id;
5
- }) => JSX.Element)>;
5
+ rowIndex: number;
6
+ }) => JSX.Element | null)>;
@@ -4,22 +4,25 @@ import { useColumnContext, useTableContext } from '..';
4
4
  import { c } from '../misc/helpers';
5
5
  import { calcClassName } from './row';
6
6
  import { useCommonClasses } from './useCommonClasses';
7
- export const Cell = memo(function Cell({ itemId }) {
7
+ export const Cell = memo(function Cell({ itemId, rowIndex }) {
8
8
  var _a, _b;
9
9
  const commonClasses = useCommonClasses();
10
10
  const state = useTableContext();
11
11
  const columnId = useColumnContext();
12
- const content = state.useState((state) => {
13
- var _a;
14
- const item = state.activeItemsById.get(itemId);
15
- const column = state.activeColumns.find((column) => column.id === columnId);
16
- if (!item || !column)
17
- return null;
18
- const index = item ? state.activeItems.indexOf(item) : -1;
19
- const className = c(calcClassName(state.props.classes, index), calcClassName(column === null || column === void 0 ? void 0 : column.classes, index));
20
- const wrapCell = (_a = state.props.wrapCell) !== null && _a !== void 0 ? _a : ((cell) => _jsx("div", Object.assign({ className: c(commonClasses.cell, className) }, { children: cell }), void 0));
21
- return wrapCell(column.renderCell(column.value(item), item), item);
22
- }, [itemId, columnId, commonClasses]);
12
+ const column = state.useState((state) => state.activeColumns.find((column) => column.id === columnId), [columnId]);
13
+ const item = state.useState((state) => state.activeItemsById.get(itemId), [itemId]);
14
+ const classes = state.useState('props.classes');
15
+ let wrapCell = state.useState('props.wrapCell');
16
+ if (!column || !item)
17
+ return null;
23
18
  (_b = (_a = state.getState().props).debug) === null || _b === void 0 ? void 0 : _b.call(_a, 'render cell', itemId, columnId);
24
- return _jsx(_Fragment, { children: content }, void 0);
19
+ const className = c(calcClassName(classes, rowIndex), calcClassName(column === null || column === void 0 ? void 0 : column.classes, rowIndex));
20
+ const content = column.renderCell(column.value(item), item);
21
+ if (!wrapCell && typeof content === 'string') {
22
+ wrapCell = (content) => (_jsx("div", Object.assign({ className: c(commonClasses.cell, className) }, { children: _jsx("span", Object.assign({ className: c(commonClasses.text) }, { children: content }), void 0) }), void 0));
23
+ }
24
+ else if (!wrapCell) {
25
+ wrapCell = (content) => _jsx("div", Object.assign({ className: c(commonClasses.cell, className) }, { children: content }), void 0);
26
+ }
27
+ return _jsx(_Fragment, { children: wrapCell(content, item) }, void 0);
25
28
  });
@@ -29,5 +29,5 @@ export function ColumnSelection() {
29
29
  }
30
30
  onHiddenColumnsChange === null || onHiddenColumnsChange === void 0 ? void 0 : onHiddenColumnsChange(newValue);
31
31
  };
32
- return (_jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({ color: "inherit", onClick: (e) => setAnchor(e.currentTarget) }, { children: _jsx(Settings, {}, void 0) }), void 0), _jsx(Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'center' } }, { children: _jsx("div", Object.assign({ className: classes.list }, { children: columns.map((column) => (_jsx(FormControlLabel, { control: _jsx(Checkbox, { checked: !hiddenColumns.has(column.id), onChange: () => toggle(column), disabled: column.cannotHide }, void 0), label: column.header }, column.id))) }), void 0) }), void 0)] }, void 0));
32
+ return (_jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({ color: "inherit", size: "small", onClick: (e) => setAnchor(e.currentTarget) }, { children: _jsx(Settings, {}, void 0) }), void 0), _jsx(Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'left' } }, { children: _jsx("div", Object.assign({ className: classes.list }, { children: columns.map((column) => (_jsx(FormControlLabel, { control: _jsx(Checkbox, { checked: !hiddenColumns.has(column.id), onChange: () => toggle(column), disabled: column.cannotHide }, void 0), label: column.header }, column.id))) }), void 0) }), void 0)] }, void 0));
33
33
  }
@@ -27,7 +27,7 @@ export function ExpandComponent({ itemId }) {
27
27
  });
28
28
  }
29
29
  }
30
- return (_jsx(IconButton, Object.assign({ onClick: toggle }, { children: _jsx(ChevronRight, { style: {
30
+ return (_jsx(IconButton, Object.assign({ size: "small", onClick: toggle }, { children: _jsx(ChevronRight, { style: {
31
31
  transition: 'all 500ms',
32
32
  transform: isExpanded ? 'rotate3d(0, 0, 1, 90deg)' : 'none',
33
33
  } }, void 0) }), void 0));
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Button, IconButton, makeStyles, Popover, Typography } from '@material-ui/core';
3
- import { AssignmentReturn, CloudDownload, GetApp } from '@material-ui/icons';
3
+ import { AssignmentReturn, CloudDownload } from '@material-ui/icons';
4
4
  import { useState } from 'react';
5
5
  import { csvExport } from '../misc/csvExport';
6
6
  import { useTableContext } from '../table';
@@ -40,5 +40,5 @@ export function Export() {
40
40
  a.click();
41
41
  document.body.removeChild(a);
42
42
  };
43
- return (_jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({ color: "inherit", onClick: (e) => setAnchor(e.currentTarget) }, { children: _jsx(GetApp, {}, void 0) }), void 0), _jsx(Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'center' } }, { children: _jsxs("div", Object.assign({ className: classes.dialog }, { children: [_jsx(Typography, Object.assign({ variant: "caption" }, { children: textTitle !== null && textTitle !== void 0 ? textTitle : 'Export' }), void 0), _jsx(Button, Object.assign({ startIcon: _jsx(AssignmentReturn, {}, void 0), fullWidth: true, onClick: copy }, { children: textCopy !== null && textCopy !== void 0 ? textCopy : 'In die Zwischenablage' }), void 0), _jsx(Button, Object.assign({ startIcon: _jsx(CloudDownload, {}, void 0), fullWidth: true, onClick: download }, { children: textDownload !== null && textDownload !== void 0 ? textDownload : 'Herunterladen' }), void 0)] }), void 0) }), void 0)] }, void 0));
43
+ return (_jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({ color: "inherit", size: "small", onClick: (e) => setAnchor(e.currentTarget) }, { children: _jsx(CloudDownload, {}, void 0) }), void 0), _jsx(Popover, Object.assign({ open: !!anchor, onClose: () => setAnchor(null), anchorEl: anchor, anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'left' } }, { children: _jsxs("div", Object.assign({ className: classes.dialog }, { children: [_jsx(Typography, Object.assign({ variant: "caption" }, { children: textTitle !== null && textTitle !== void 0 ? textTitle : 'Export' }), void 0), _jsx(Button, Object.assign({ startIcon: _jsx(AssignmentReturn, {}, void 0), fullWidth: true, onClick: copy }, { children: textCopy !== null && textCopy !== void 0 ? textCopy : 'In die Zwischenablage' }), void 0), _jsx(Button, Object.assign({ startIcon: _jsx(CloudDownload, {}, void 0), fullWidth: true, onClick: download }, { children: textDownload !== null && textDownload !== void 0 ? textDownload : 'Herunterladen' }), void 0)] }), void 0) }), void 0)] }, void 0));
44
44
  }
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Id, InternalColumn } from '../types';
3
3
  export declare const calcClassName: (classes: InternalColumn<any, any>['classes'] | undefined, index: number) => string;
4
- export declare const Row: React.MemoExoticComponent<(<T>({ itemId }: {
4
+ export declare const Row: React.MemoExoticComponent<(<T>({ itemId, rowIndex }: {
5
5
  itemId: Id;
6
+ rowIndex: number;
6
7
  }) => JSX.Element | null)>;
@@ -7,7 +7,7 @@ import { ExpandComponent } from './expandComponent';
7
7
  import { SelectComponent } from './selectComponent';
8
8
  import { useCommonClasses } from './useCommonClasses';
9
9
  export const calcClassName = (classes, index) => c(classes === null || classes === void 0 ? void 0 : classes.cell, (classes === null || classes === void 0 ? void 0 : classes.evenCell) === undefined ? undefined : { [classes.evenCell]: index % 2 === 0 }, (classes === null || classes === void 0 ? void 0 : classes.oddCell) === undefined ? undefined : { [classes.oddCell]: index % 2 === 1 });
10
- export const Row = memo(function Row({ itemId }) {
10
+ export const Row = memo(function Row({ itemId, rowIndex }) {
11
11
  var _a, _b;
12
12
  const commonClasses = useCommonClasses();
13
13
  const state = useTableContext();
@@ -40,5 +40,5 @@ export const Row = memo(function Row({ itemId }) {
40
40
  return () => o.disconnect();
41
41
  }, [divRef.current]);
42
42
  (_b = (_a = state.getState().props).debug) === null || _b === void 0 ? void 0 : _b.call(_a, 'render row', itemId);
43
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: c(commonClasses.cellFill, className), ref: divRef }, void 0), _jsxs("div", Object.assign({ className: c(commonClasses.cell, commonClasses.firstCell, className) }, { children: [_jsx("div", { style: { width: indent * 20 } }, void 0), enableSelection && _jsx(SelectComponent, { itemId: itemId }, void 0), (hasChildren || hasDeferredChildren) && _jsx(ExpandComponent, { itemId: itemId }, void 0)] }), void 0), columnIds.map((columnId) => (_jsx(ColumnContext.Provider, Object.assign({ value: columnId }, { children: _jsx(Cell, { itemId: itemId }, void 0) }), columnId))), _jsx("div", { className: c(commonClasses.cellFill, className) }, void 0)] }, void 0));
43
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: c(commonClasses.cellFill, className), ref: divRef }, void 0), _jsxs("div", Object.assign({ className: c(commonClasses.cell, commonClasses.firstCell, className) }, { children: [_jsx("div", { style: { width: indent * 20 } }, void 0), enableSelection && _jsx(SelectComponent, { itemId: itemId }, void 0), (hasChildren || hasDeferredChildren) && _jsx(ExpandComponent, { itemId: itemId }, void 0)] }), void 0), columnIds.map((columnId) => (_jsx(ColumnContext.Provider, Object.assign({ value: columnId }, { children: _jsx(Cell, { itemId: itemId, rowIndex: rowIndex }, void 0) }), columnId))), _jsx("div", { className: c(commonClasses.cellFill, className) }, void 0)] }, void 0));
44
44
  });
@@ -1,5 +1,4 @@
1
1
  /// <reference types="react" />
2
- import '../misc/textMatch';
3
2
  import { Filter } from './filterComponent';
4
3
  export declare class TextFilter<T> implements Filter<T> {
5
4
  readonly query: string;
@@ -3,7 +3,6 @@ import { IconButton, makeStyles, TextField } from '@material-ui/core';
3
3
  import { Clear, Search } from '@material-ui/icons';
4
4
  import { useEffect, useState } from 'react';
5
5
  import { asString } from '../misc/helpers';
6
- import '../misc/textMatch';
7
6
  import { textMatch } from '../misc/textMatch';
8
7
  import { useColumnContext, useTableContext } from '../table';
9
8
  export class TextFilter {
@@ -1 +1 @@
1
- export declare const useCommonClasses: (props?: any) => import("@material-ui/styles").ClassNameMap<"table" | "cell" | "sticky" | "headerCell" | "cellFill" | "firstCell" | "headerFill" | "deferredPlaceholder">;
1
+ export declare const useCommonClasses: (props?: any) => import("@material-ui/styles").ClassNameMap<"table" | "text" | "cell" | "sticky" | "headerCell" | "cellFill" | "firstCell" | "headerFill" | "deferredPlaceholder">;
@@ -1,13 +1,11 @@
1
1
  import { makeStyles } from '@material-ui/core';
2
2
  const cell = (theme) => ({
3
- padding: theme.spacing(0.5, 1),
4
- display: 'grid',
5
- gridAutoFlow: 'column',
3
+ padding: theme.spacing(0.1, 1),
4
+ display: 'flex',
6
5
  alignItems: 'center',
7
6
  borderBottom: `1px solid ${theme.palette.grey[200]}`,
8
7
  whiteSpace: 'nowrap',
9
8
  overflow: 'hidden',
10
- textOverflow: 'ellipsis',
11
9
  });
12
10
  export const useCommonClasses = makeStyles((theme) => ({
13
11
  table: {
@@ -18,7 +16,7 @@ export const useCommonClasses = makeStyles((theme) => ({
18
16
  cellFill: {
19
17
  borderBottom: `1px solid ${theme.palette.grey[200]}`,
20
18
  },
21
- headerCell: Object.assign(Object.assign({}, cell(theme)), { borderBottom: 'none', gridTemplateColumns: 'minmax(0, 1fr) max-content', background: theme.palette.primary.main, color: theme.palette.primary.contrastText, fontWeight: 'bold', '&:not(:first-child)': {
19
+ headerCell: Object.assign(Object.assign({}, cell(theme)), { borderBottom: `2px solid ${theme.palette.grey[400]}`, gridTemplateColumns: 'minmax(0, 1fr) max-content', background: theme.palette.common.white, '&:not(:first-child)': {
22
20
  borderLeft: `1px solid ${theme.palette.background.default}`,
23
21
  } }),
24
22
  firstCell: {
@@ -30,7 +28,8 @@ export const useCommonClasses = makeStyles((theme) => ({
30
28
  zIndex: 1,
31
29
  },
32
30
  headerFill: {
33
- background: theme.palette.primary.main,
31
+ borderBottom: `3px solid ${theme.palette.grey[200]}`,
32
+ background: theme.palette.common.white,
34
33
  },
35
34
  deferredPlaceholder: {
36
35
  padding: theme.spacing(1),
@@ -39,4 +38,9 @@ export const useCommonClasses = makeStyles((theme) => ({
39
38
  display: 'grid',
40
39
  justifyContent: 'center',
41
40
  },
41
+ text: {
42
+ minWidth: 0,
43
+ overflow: 'hidden',
44
+ textOverflow: 'ellipsis',
45
+ },
42
46
  }));
@@ -2,5 +2,5 @@ import { HTMLProps, ReactNode } from 'react';
2
2
  import { Id } from '../types';
3
3
  export declare function Virtualized<T>({ header, children, ...props }: {
4
4
  header: ReactNode;
5
- children: (itemIds: Id[]) => ReactNode;
5
+ children: (itemIds: Id[], startIndex: number) => ReactNode;
6
6
  } & HTMLProps<HTMLDivElement>): JSX.Element;
@@ -47,7 +47,7 @@ export function Virtualized(_a) {
47
47
  const virtual = state.useState('props.virtual');
48
48
  const probeRef = useRef(null);
49
49
  const [counter, setCounter] = useState(0);
50
- const { itemIds = [], from, to, before = 0, after = 0, } = state.useState((state) => {
50
+ const { itemIds = [], from = 0, to, before = 0, after = 0, } = state.useState((state) => {
51
51
  var _a;
52
52
  const itemIds = state.activeItems.map((item) => item.id);
53
53
  const root = probeRef.current && findScrollRoot(probeRef.current);
@@ -55,7 +55,7 @@ export function Virtualized(_a) {
55
55
  return { itemIds };
56
56
  if (!probeRef.current || !root || !document.contains(root))
57
57
  return {};
58
- const { rowHeight, initalRowHeight } = (_a = (state.props.virtual instanceof Object ? state.props.virtual : undefined)) !== null && _a !== void 0 ? _a : {};
58
+ const { rowHeight, initalRowHeight, overscan = 200, overscanTop, overscanBottom, } = (_a = (state.props.virtual instanceof Object ? state.props.virtual : undefined)) !== null && _a !== void 0 ? _a : {};
59
59
  let totalHeight = 0;
60
60
  const rowHeights = itemIds.map((itemId, index) => {
61
61
  var _a, _b;
@@ -69,13 +69,13 @@ export function Virtualized(_a) {
69
69
  const bottomOfTable = topOfTable + root.clientHeight - headerHeight;
70
70
  let from = 0, to = itemIds.length, before = 0, after = 0;
71
71
  for (const h of rowHeights) {
72
- if (before + h > topOfTable)
72
+ if (before + h > topOfTable - (overscanTop !== null && overscanTop !== void 0 ? overscanTop : overscan))
73
73
  break;
74
74
  from++;
75
75
  before += h;
76
76
  }
77
77
  for (const h of rowHeights.reverse()) {
78
- if (after + h > totalHeight - bottomOfTable)
78
+ if (after + h > totalHeight - bottomOfTable - (overscanBottom !== null && overscanBottom !== void 0 ? overscanBottom : overscan))
79
79
  break;
80
80
  to--;
81
81
  after += h;
@@ -90,5 +90,5 @@ export function Virtualized(_a) {
90
90
  return onAncestorScroll(probeRef.current, incCounter);
91
91
  }, [probeRef.current, incCounter]);
92
92
  (_e = (_d = state.getState().props).debug) === null || _e === void 0 ? void 0 : _e.call(_d, `Virtualalized render ${from} to ${to}`);
93
- return (_jsxs("div", Object.assign({}, props, { children: [header, virtual && _jsx("div", { style: { gridColumn: '1 / -1', height: before }, ref: probeRef }, void 0), children(itemIds), virtual && _jsx("div", { style: { gridColumn: '1 / -1', height: after } }, void 0)] }), void 0));
93
+ return (_jsxs("div", Object.assign({}, props, { children: [header, virtual && _jsx("div", { style: { gridColumn: '1 / -1', height: before }, ref: probeRef }, void 0), children(itemIds, from), virtual && _jsx("div", { style: { gridColumn: '1 / -1', height: after } }, void 0)] }), void 0));
94
94
  }
@@ -1,5 +1,6 @@
1
1
  export { DefaultFilter, DefaultFilterComponent } from './components/defaultFilterComponent';
2
+ export { Filter } from './components/filterComponent';
2
3
  export { TextFilter, TextFilterComponent } from './components/textFilterComponent';
3
4
  export { termMatch, textMatch } from './misc/textMatch';
4
5
  export { ColumnContext, Table, TableContext, useColumnContext, useTableContext } from './table';
5
- export type { Column, Id, Rows, Sort, SortDirection, TableProps } from './types';
6
+ export type { Column, Id, InternalColumn, Rows, Sort, SortDirection, TableProps } from './types';
@@ -9,10 +9,11 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { useMemo } from 'react';
12
+ import { useMemo, useRef } from 'react';
13
13
  import { asString } from '../misc/helpers';
14
14
  const noopParentId = () => undefined;
15
15
  export function calcProps(props) {
16
+ const columnCache = useRef(new Map());
16
17
  return useMemo(() => {
17
18
  var _a, _b;
18
19
  let id;
@@ -37,15 +38,31 @@ export function calcProps(props) {
37
38
  inputColumns = props.columns((value, column) => (Object.assign(Object.assign({}, column), { value })));
38
39
  }
39
40
  else {
40
- inputColumns = props.columns;
41
+ inputColumns = props.columns.map((column) => (Object.assign(Object.assign({}, column), { dependecies: undefined })));
41
42
  }
43
+ const newColumnCache = new Map();
42
44
  const columns = inputColumns.map(function (_a, index) {
43
- var { id, header = null, renderCell = asString, exportCell = asString, sortBy = (v) => (typeof v === 'number' || v instanceof Date ? v : String(v)) } = _a, props = __rest(_a, ["id", "header", "renderCell", "exportCell", "sortBy"]);
44
- return Object.assign({ id: id !== null && id !== void 0 ? id : index, header,
45
- renderCell,
46
- exportCell,
47
- sortBy }, props);
45
+ var _b;
46
+ var { id, header = null, renderCell = asString, exportCell = asString, sortBy = (v) => (typeof v === 'number' || v instanceof Date ? v : String(v)), dependencies = [] } = _a, props = __rest(_a, ["id", "header", "renderCell", "exportCell", "sortBy", "dependencies"]);
47
+ const [depsInCache, columnInCache] = (_b = columnCache.current.get(id !== null && id !== void 0 ? id : index)) !== null && _b !== void 0 ? _b : [];
48
+ let column;
49
+ if (depsInCache &&
50
+ columnInCache &&
51
+ depsInCache.length === dependencies.length &&
52
+ depsInCache.every((x, i) => dependencies[i] === x)) {
53
+ column = columnInCache;
54
+ }
55
+ else {
56
+ column = Object.assign({ id: id !== null && id !== void 0 ? id : index, header,
57
+ renderCell,
58
+ exportCell,
59
+ sortBy,
60
+ dependencies }, props);
61
+ }
62
+ newColumnCache.set(id !== null && id !== void 0 ? id : index, [dependencies, column]);
63
+ return column;
48
64
  });
65
+ columnCache.current = newColumnCache;
49
66
  let copy;
50
67
  if (props.enableExport === true || (props.enableExport instanceof Object && props.enableExport.copy === true)) {
51
68
  copy = { separator: '\t' };
package/dist/esm/table.js CHANGED
@@ -59,5 +59,5 @@ const TableInner = memo(function TableInner() {
59
59
  }, header: _jsxs(_Fragment, { children: [_jsx("div", { className: c(commonClasses.headerFill, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, void 0), _jsxs("div", Object.assign({ className: c(commonClasses.headerCell, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, { children: [enableSelection && _jsx(SelectComponent, {}, void 0), enableColumnSelection && _jsx(ColumnSelection, {}, void 0), enableExport && _jsx(Export, {}, void 0)] }), void 0), activeColumns.map((column) => {
60
60
  var _a;
61
61
  return (_jsx(ColumnContext.Provider, Object.assign({ value: column.id }, { children: _jsxs("div", Object.assign({ className: c(commonClasses.headerCell, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell, (_a = column.classes) === null || _a === void 0 ? void 0 : _a.headerCell) }, { children: [_jsx(SortComponent, { children: column.header }, void 0), _jsx(FilterComponent, {}, void 0)] }), column.id) }), column.id));
62
- }), _jsx("div", { className: c(commonClasses.headerFill, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, void 0)] }, void 0) }, { children: (itemIds) => itemIds.map((itemId) => _jsx(Row, { itemId: itemId }, itemId)) }), void 0));
62
+ }), _jsx("div", { className: c(commonClasses.headerFill, { [commonClasses.sticky]: !!stickyHeader }, classes === null || classes === void 0 ? void 0 : classes.headerCell) }, void 0)] }, void 0) }, { children: (itemIds, startIndex) => itemIds.map((itemId, index) => _jsx(Row, { itemId: itemId, rowIndex: startIndex + index }, itemId)) }), void 0));
63
63
  });
@@ -38,6 +38,9 @@ export declare type TableProps<T> = {
38
38
  rowHeight?: number;
39
39
  initalRowHeight?: number;
40
40
  throttleScroll?: number;
41
+ overscan?: number;
42
+ overscanBottom?: number;
43
+ overscanTop?: number;
41
44
  };
42
45
  text?: {
43
46
  deselectAll?: string;
@@ -97,6 +100,8 @@ export declare type Column<T, V> = {
97
100
  evenCell?: string;
98
101
  oddCell?: string;
99
102
  };
103
+ /** If the column definition changes, supply parameters that it depends on. If not set, the column will not update */
104
+ dependencies?: any[];
100
105
  };
101
106
  export declare type InternalColumn<T, V> = Required<Omit<Column<T, V>, 'id'> & {
102
107
  id: Id;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "schummar-table",
3
3
  "repository": "schummar/schummar-table",
4
- "version": "0.2.0",
4
+ "version": "0.3.2",
5
5
  "description": "",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -18,7 +18,7 @@
18
18
  "license": "ISC",
19
19
  "scripts": {
20
20
  "start": "npm --prefix example run dev",
21
- "dev": "run-p start:*",
21
+ "dev": "run-p dev:*",
22
22
  "dev:esm": "tsc --watch",
23
23
  "dev:cjs": "tsc -p tsconfig-cjs.json --watch",
24
24
  "build": "npm-run-all -s build:clean -p build:compile:*",
@@ -36,30 +36,30 @@
36
36
  "peerDependencies": {
37
37
  "@material-ui/core": ">=4.11.4",
38
38
  "@material-ui/icons": ">=4.11.2",
39
- "@types/react": "^17.0.11",
40
- "immer": "^9.0.3",
39
+ "@types/react": ">=17.0.11",
40
+ "immer": ">=9.0.3",
41
41
  "react": ">=16.8.0",
42
- "schummar-state": "^0.0.36"
42
+ "schummar-state": ">=0.0.36"
43
43
  },
44
44
  "devDependencies": {
45
- "@testing-library/react": "^12.0.0",
45
+ "@testing-library/react": "^12.1.2",
46
46
  "@types/react": "*",
47
- "@typescript-eslint/eslint-plugin": "^4.31.0",
48
- "@typescript-eslint/parser": "^4.31.0",
47
+ "@typescript-eslint/eslint-plugin": "^5.4.0",
48
+ "@typescript-eslint/parser": "^5.4.0",
49
49
  "ava": "^3.15.0",
50
- "eslint": "^7.32.0",
51
- "global-jsdom": "^8.2.0",
50
+ "eslint": "^8.2.0",
51
+ "global-jsdom": "^8.3.0",
52
52
  "immer": "*",
53
- "jsdom": "^17.0.0",
53
+ "jsdom": "^18.1.0",
54
54
  "npm-run-all": "^4.1.5",
55
55
  "nyc": "^15.1.0",
56
- "prettier": "^2.4.0",
56
+ "prettier": "^2.4.1",
57
57
  "react": "^17.0.2",
58
58
  "react-dom": "^17.0.2",
59
59
  "rimraf": "^3.0.2",
60
60
  "schummar-state": "*",
61
- "ts-node": "^9.1.1",
62
- "typescript": "^4.4.2"
61
+ "ts-node": "^10.4.0",
62
+ "typescript": "^4.5.2"
63
63
  },
64
64
  "files": [
65
65
  "dist"