@vuu-ui/vuu-table 0.8.94 → 0.8.96

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 (108) hide show
  1. package/cjs/Row.css.js +1 -1
  2. package/cjs/Row.js +1 -1
  3. package/cjs/Row.js.map +1 -1
  4. package/cjs/Table.css.js +1 -1
  5. package/cjs/Table.js +113 -31
  6. package/cjs/Table.js.map +1 -1
  7. package/cjs/cell-block/CellBlock.css.js +6 -0
  8. package/cjs/cell-block/CellBlock.css.js.map +1 -0
  9. package/cjs/cell-block/CellBlock.js +41 -0
  10. package/cjs/cell-block/CellBlock.js.map +1 -0
  11. package/cjs/cell-block/cellblock-utils.js +140 -0
  12. package/cjs/cell-block/cellblock-utils.js.map +1 -0
  13. package/cjs/cell-block/useCellBlockSelection.js +232 -0
  14. package/cjs/cell-block/useCellBlockSelection.js.map +1 -0
  15. package/cjs/index.js +5 -0
  16. package/cjs/index.js.map +1 -1
  17. package/cjs/moving-window.js +21 -9
  18. package/cjs/moving-window.js.map +1 -1
  19. package/cjs/pagination/PaginationControl.css.js +6 -0
  20. package/cjs/pagination/PaginationControl.css.js.map +1 -0
  21. package/cjs/pagination/PaginationControl.js +38 -0
  22. package/cjs/pagination/PaginationControl.js.map +1 -0
  23. package/cjs/pagination/usePagination.js +38 -0
  24. package/cjs/pagination/usePagination.js.map +1 -0
  25. package/cjs/table-dom-utils.js +67 -10
  26. package/cjs/table-dom-utils.js.map +1 -1
  27. package/cjs/table-header/useTableHeader.js +1 -1
  28. package/cjs/table-header/useTableHeader.js.map +1 -1
  29. package/cjs/useCellFocus.js +56 -0
  30. package/cjs/useCellFocus.js.map +1 -0
  31. package/cjs/useControlledTableNavigation.js +3 -1
  32. package/cjs/useControlledTableNavigation.js.map +1 -1
  33. package/cjs/useDataSource.js +13 -0
  34. package/cjs/useDataSource.js.map +1 -1
  35. package/cjs/useKeyboardNavigation.js +8 -82
  36. package/cjs/useKeyboardNavigation.js.map +1 -1
  37. package/cjs/useMeasuredHeight.js +5 -5
  38. package/cjs/useMeasuredHeight.js.map +1 -1
  39. package/cjs/useTable.js +63 -16
  40. package/cjs/useTable.js.map +1 -1
  41. package/cjs/useTableContextMenu.js +2 -1
  42. package/cjs/useTableContextMenu.js.map +1 -1
  43. package/cjs/useTableScroll.js.map +1 -1
  44. package/cjs/useTableViewport.js +31 -13
  45. package/cjs/useTableViewport.js.map +1 -1
  46. package/esm/Row.css.js +1 -1
  47. package/esm/Row.js +1 -1
  48. package/esm/Row.js.map +1 -1
  49. package/esm/Table.css.js +1 -1
  50. package/esm/Table.js +115 -33
  51. package/esm/Table.js.map +1 -1
  52. package/esm/cell-block/CellBlock.css.js +4 -0
  53. package/esm/cell-block/CellBlock.css.js.map +1 -0
  54. package/esm/cell-block/CellBlock.js +39 -0
  55. package/esm/cell-block/CellBlock.js.map +1 -0
  56. package/esm/cell-block/cellblock-utils.js +131 -0
  57. package/esm/cell-block/cellblock-utils.js.map +1 -0
  58. package/esm/cell-block/useCellBlockSelection.js +230 -0
  59. package/esm/cell-block/useCellBlockSelection.js.map +1 -0
  60. package/esm/index.js +2 -1
  61. package/esm/index.js.map +1 -1
  62. package/esm/moving-window.js +21 -9
  63. package/esm/moving-window.js.map +1 -1
  64. package/esm/pagination/PaginationControl.css.js +4 -0
  65. package/esm/pagination/PaginationControl.css.js.map +1 -0
  66. package/esm/pagination/PaginationControl.js +36 -0
  67. package/esm/pagination/PaginationControl.js.map +1 -0
  68. package/esm/pagination/usePagination.js +36 -0
  69. package/esm/pagination/usePagination.js.map +1 -0
  70. package/esm/table-dom-utils.js +64 -10
  71. package/esm/table-dom-utils.js.map +1 -1
  72. package/esm/table-header/useTableHeader.js +1 -1
  73. package/esm/table-header/useTableHeader.js.map +1 -1
  74. package/esm/useCellFocus.js +54 -0
  75. package/esm/useCellFocus.js.map +1 -0
  76. package/esm/useControlledTableNavigation.js +3 -2
  77. package/esm/useControlledTableNavigation.js.map +1 -1
  78. package/esm/useDataSource.js +13 -0
  79. package/esm/useDataSource.js.map +1 -1
  80. package/esm/useKeyboardNavigation.js +8 -82
  81. package/esm/useKeyboardNavigation.js.map +1 -1
  82. package/esm/useMeasuredHeight.js +5 -5
  83. package/esm/useMeasuredHeight.js.map +1 -1
  84. package/esm/useTable.js +63 -16
  85. package/esm/useTable.js.map +1 -1
  86. package/esm/useTableContextMenu.js +2 -1
  87. package/esm/useTableContextMenu.js.map +1 -1
  88. package/esm/useTableScroll.js.map +1 -1
  89. package/esm/useTableViewport.js +31 -13
  90. package/esm/useTableViewport.js.map +1 -1
  91. package/package.json +9 -9
  92. package/types/Table.d.ts +40 -0
  93. package/types/cell-block/CellBlock.d.ts +6 -0
  94. package/types/cell-block/cellblock-utils.d.ts +37 -0
  95. package/types/cell-block/useCellBlockSelection.d.ts +16 -0
  96. package/types/index.d.ts +1 -0
  97. package/types/moving-window.d.ts +3 -1
  98. package/types/pagination/PaginationControl.d.ts +6 -0
  99. package/types/pagination/index.d.ts +1 -0
  100. package/types/pagination/usePagination.d.ts +9 -0
  101. package/types/table-dom-utils.d.ts +6 -1
  102. package/types/useCellFocus.d.ts +13 -0
  103. package/types/useControlledTableNavigation.d.ts +1 -0
  104. package/types/useKeyboardNavigation.d.ts +5 -5
  105. package/types/useMeasuredHeight.d.ts +2 -2
  106. package/types/useTable.d.ts +13 -11
  107. package/types/useTableScroll.d.ts +1 -0
  108. package/types/useTableViewport.d.ts +3 -2
@@ -1 +1 @@
1
- {"version":3,"file":"useTableViewport.js","sources":["../src/useTableViewport.ts"],"sourcesContent":["/**\n * This hook measures and calculates the values needed to manage layout\n * and virtualisation of the table. This includes measurements required\n * to support pinned columns.\n */\nimport { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { MeasuredSize } from \"@vuu-ui/vuu-ui-controls\";\nimport {\n actualRowPositioning,\n measurePinnedColumns,\n RowAtPositionFunc,\n RowOffsetFunc,\n RowPositioning,\n virtualRowPositioning,\n} from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useMemo, useRef } from \"react\";\n\nexport interface TableViewportHookProps {\n columns: RuntimeColumnDescriptor[];\n headerHeight: number;\n rowCount: number;\n rowHeight: number;\n /**\n * this is the solid left/right `border` rendered on the selection block\n */\n selectionEndSize?: number;\n size: MeasuredSize | undefined;\n}\n\nexport interface ViewportMeasurements {\n appliedPageSize: number;\n contentHeight: number;\n horizontalScrollbarHeight: number;\n isVirtualScroll: boolean;\n pinnedWidthLeft: number;\n pinnedWidthRight: number;\n rowCount: number;\n contentWidth: number;\n totalHeaderHeight: number;\n usesMeasuredHeaderHeight: boolean;\n verticalScrollbarWidth: number;\n viewportBodyHeight: number;\n viewportWidth: number;\n}\n\nexport interface TableViewportHookResult extends ViewportMeasurements {\n getRowAtPosition: RowAtPositionFunc;\n getRowOffset: RowOffsetFunc;\n setInSituRowOffset: (rowIndexOffset: number) => void;\n setScrollTop: (scrollTop: number, scrollPct: number) => void;\n}\n\n// Too simplistic, it depends on rowHeight\nconst MAX_PIXEL_HEIGHT = 10_000_000;\n\nconst UNMEASURED_VIEWPORT: TableViewportHookResult = {\n appliedPageSize: 0,\n contentHeight: 0,\n contentWidth: 0,\n getRowAtPosition: () => -1,\n getRowOffset: () => -1,\n horizontalScrollbarHeight: 0,\n isVirtualScroll: false,\n pinnedWidthLeft: 0,\n pinnedWidthRight: 0,\n rowCount: 0,\n setInSituRowOffset: () => undefined,\n setScrollTop: () => undefined,\n totalHeaderHeight: 0,\n usesMeasuredHeaderHeight: false,\n verticalScrollbarWidth: 0,\n viewportBodyHeight: 0,\n viewportWidth: 0,\n};\n\nexport const useTableViewport = ({\n columns,\n headerHeight,\n rowCount,\n rowHeight,\n selectionEndSize = 4,\n size,\n}: TableViewportHookProps): TableViewportHookResult => {\n const inSituRowOffsetRef = useRef(0);\n const pctScrollTopRef = useRef(0);\n // TODO we are limited by pixels not an arbitrary number of rows\n const virtualContentHeight = rowCount * rowHeight;\n const pixelContentHeight = Math.min(virtualContentHeight, MAX_PIXEL_HEIGHT);\n const virtualisedExtent = virtualContentHeight - pixelContentHeight;\n\n const { pinnedWidthLeft, pinnedWidthRight, unpinnedWidth } = useMemo(\n () => measurePinnedColumns(columns, selectionEndSize),\n [columns, selectionEndSize],\n );\n\n const [getRowOffset, getRowAtPosition, isVirtualScroll] =\n useMemo<RowPositioning>(() => {\n if (virtualisedExtent) {\n const [_getRowOffset, getRowAtPosition, _isVirtual] =\n virtualRowPositioning(rowHeight, virtualisedExtent, pctScrollTopRef);\n const getOffset: RowOffsetFunc = (row) => {\n return _getRowOffset(row, inSituRowOffsetRef.current);\n };\n return [getOffset, getRowAtPosition, _isVirtual];\n } else {\n return actualRowPositioning(rowHeight);\n }\n }, [virtualisedExtent, rowHeight]);\n\n const setScrollTop = useCallback((_: number, scrollPct: number) => {\n pctScrollTopRef.current = scrollPct;\n }, []);\n\n /**\n * The inSituRowOffset is used to simulate scrolling through a very large dataset\n * without actually moving the scroll position. It is triggered by keyboard\n * navigation. A simulated scroll operation will always be of one or more rows.\n * A value of zero is a request to reset the offset.\n */\n const setInSituRowOffset = useCallback((rowIndexOffset: number) => {\n if (rowIndexOffset === 0) {\n inSituRowOffsetRef.current = 0;\n } else {\n inSituRowOffsetRef.current = Math.max(\n 0,\n inSituRowOffsetRef.current + rowIndexOffset,\n );\n }\n }, []);\n\n return useMemo(() => {\n if (size) {\n // TODO determine this at runtime\n const scrollbarSize = 10;\n const contentWidth = pinnedWidthLeft + unpinnedWidth + pinnedWidthRight;\n const horizontalScrollbarHeight =\n contentWidth > size.width ? scrollbarSize : 0;\n const measuredHeaderHeight = headerHeight === -1 ? 0 : headerHeight;\n const visibleRows = (size.height - measuredHeaderHeight) / rowHeight;\n const count = Number.isInteger(visibleRows)\n ? visibleRows\n : Math.ceil(visibleRows);\n const viewportBodyHeight = size.height - measuredHeaderHeight;\n const verticalScrollbarWidth =\n pixelContentHeight > viewportBodyHeight ? scrollbarSize : 0;\n\n const appliedPageSize =\n count * rowHeight * (pixelContentHeight / virtualContentHeight);\n\n const viewportWidth = size.width;\n\n return {\n usesMeasuredHeaderHeight: headerHeight !== -1,\n appliedPageSize,\n contentHeight: pixelContentHeight,\n contentWidth,\n getRowAtPosition,\n getRowOffset,\n isVirtualScroll,\n horizontalScrollbarHeight,\n pinnedWidthLeft,\n pinnedWidthRight,\n rowCount: count,\n setInSituRowOffset,\n setScrollTop,\n totalHeaderHeight: headerHeight,\n verticalScrollbarWidth,\n viewportBodyHeight,\n viewportWidth,\n };\n } else {\n return UNMEASURED_VIEWPORT;\n }\n }, [\n getRowAtPosition,\n getRowOffset,\n headerHeight,\n isVirtualScroll,\n pinnedWidthLeft,\n unpinnedWidth,\n pinnedWidthRight,\n pixelContentHeight,\n rowHeight,\n setInSituRowOffset,\n setScrollTop,\n size,\n virtualContentHeight,\n ]);\n};\n"],"names":["getRowAtPosition"],"mappings":"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"}
1
+ {"version":3,"file":"useTableViewport.js","sources":["../src/useTableViewport.ts"],"sourcesContent":["/**\n * This hook measures and calculates the values needed to manage layout\n * and virtualisation of the table. This includes measurements required\n * to support pinned columns.\n */\nimport { RuntimeColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { MeasuredSize } from \"@vuu-ui/vuu-ui-controls\";\nimport {\n actualRowPositioning,\n measurePinnedColumns,\n RowAtPositionFunc,\n RowOffsetFunc,\n RowPositioning,\n virtualRowPositioning,\n} from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useMemo, useRef } from \"react\";\n\nexport interface TableViewportHookProps {\n columns: RuntimeColumnDescriptor[];\n headerHeight: number;\n rowCount: number;\n rowHeight: number;\n /**\n * this is the solid left/right `border` rendered on the selection block\n */\n selectionEndSize?: number;\n showPaginationControls?: boolean;\n size: MeasuredSize;\n}\n\nexport interface ViewportMeasurements {\n appliedPageSize: number;\n contentHeight: number;\n horizontalScrollbarHeight: number;\n isVirtualScroll: boolean;\n pinnedWidthLeft: number;\n pinnedWidthRight: number;\n rowCount: number;\n contentWidth: number;\n totalHeaderHeight: number;\n usesMeasuredHeaderHeight: boolean;\n verticalScrollbarWidth: number;\n viewportBodyHeight: number;\n viewportWidth: number;\n}\n\nexport interface TableViewportHookResult extends ViewportMeasurements {\n getRowAtPosition: RowAtPositionFunc;\n getRowOffset: RowOffsetFunc;\n setInSituRowOffset: (rowIndexOffset: number) => void;\n setScrollTop: (scrollTop: number, scrollPct: number) => void;\n}\n\n// Too simplistic, it depends on rowHeight\nconst MAX_PIXEL_HEIGHT = 10_000_000;\n\nconst UNMEASURED_VIEWPORT: TableViewportHookResult = {\n appliedPageSize: 0,\n contentHeight: 0,\n contentWidth: 0,\n getRowAtPosition: () => -1,\n getRowOffset: () => -1,\n horizontalScrollbarHeight: 0,\n isVirtualScroll: false,\n pinnedWidthLeft: 0,\n pinnedWidthRight: 0,\n rowCount: 0,\n setInSituRowOffset: () => undefined,\n setScrollTop: () => undefined,\n totalHeaderHeight: 0,\n usesMeasuredHeaderHeight: false,\n verticalScrollbarWidth: 0,\n viewportBodyHeight: 0,\n viewportWidth: 0,\n};\n\nconst getViewportHeightProps = (\n rowCount: number,\n rowHeight: number,\n size: MeasuredSize,\n showPaginationControls = false,\n) => {\n if (showPaginationControls) {\n return {\n pixelContentHeight: size.height,\n virtualContentHeight: size.height,\n virtualisedExtent: 0,\n };\n } else {\n const virtualContentHeight = rowCount * rowHeight;\n const pixelContentHeight = Math.min(virtualContentHeight, MAX_PIXEL_HEIGHT);\n const virtualisedExtent = virtualContentHeight - pixelContentHeight;\n return {\n pixelContentHeight,\n virtualContentHeight,\n virtualisedExtent,\n };\n }\n};\n\nexport const useTableViewport = ({\n columns,\n headerHeight,\n rowCount,\n rowHeight,\n selectionEndSize = 4,\n showPaginationControls,\n size,\n}: TableViewportHookProps): TableViewportHookResult => {\n const inSituRowOffsetRef = useRef(0);\n const pctScrollTopRef = useRef(0);\n\n const { virtualContentHeight, pixelContentHeight, virtualisedExtent } =\n getViewportHeightProps(rowCount, rowHeight, size, showPaginationControls);\n\n const { pinnedWidthLeft, pinnedWidthRight, unpinnedWidth } = useMemo(\n () => measurePinnedColumns(columns, selectionEndSize),\n [columns, selectionEndSize],\n );\n\n const [getRowOffset, getRowAtPosition, isVirtualScroll] =\n useMemo<RowPositioning>(() => {\n if (virtualisedExtent) {\n const [_getRowOffset, getRowAtPosition, _isVirtual] =\n virtualRowPositioning(rowHeight, virtualisedExtent, pctScrollTopRef);\n const getOffset: RowOffsetFunc = (row) => {\n return _getRowOffset(row, inSituRowOffsetRef.current);\n };\n return [getOffset, getRowAtPosition, _isVirtual];\n } else {\n return actualRowPositioning(rowHeight);\n }\n }, [virtualisedExtent, rowHeight]);\n\n const setScrollTop = useCallback((_: number, scrollPct: number) => {\n pctScrollTopRef.current = scrollPct;\n }, []);\n\n /**\n * The inSituRowOffset is used to simulate scrolling through a very large dataset\n * without actually moving the scroll position. It is triggered by keyboard\n * navigation. A simulated scroll operation will always be of one or more rows.\n * A value of zero is a request to reset the offset.\n */\n const setInSituRowOffset = useCallback((rowIndexOffset: number) => {\n if (rowIndexOffset === 0) {\n inSituRowOffsetRef.current = 0;\n } else {\n inSituRowOffsetRef.current = Math.max(\n 0,\n inSituRowOffsetRef.current + rowIndexOffset,\n );\n }\n }, []);\n\n return useMemo(() => {\n if (size) {\n // TODO determine this at runtime\n const scrollbarSize = 10;\n const contentWidth = pinnedWidthLeft + unpinnedWidth + pinnedWidthRight;\n const horizontalScrollbarHeight =\n contentWidth > size.width ? scrollbarSize : 0;\n const measuredHeaderHeight = headerHeight === -1 ? 0 : headerHeight;\n const visibleRows = showPaginationControls\n ? Math.floor((pixelContentHeight - headerHeight) / rowHeight)\n : (size.height - headerHeight) / rowHeight;\n const count = Number.isInteger(visibleRows)\n ? visibleRows\n : Math.ceil(visibleRows);\n const viewportBodyHeight = size.height - measuredHeaderHeight;\n const verticalScrollbarWidth = showPaginationControls\n ? 0\n : pixelContentHeight > viewportBodyHeight\n ? scrollbarSize\n : 0;\n\n const appliedPageSize =\n count * rowHeight * (pixelContentHeight / virtualContentHeight);\n\n const viewportWidth = size.width;\n\n return {\n usesMeasuredHeaderHeight: headerHeight !== -1,\n appliedPageSize,\n contentHeight: pixelContentHeight,\n contentWidth,\n getRowAtPosition,\n getRowOffset,\n isVirtualScroll,\n horizontalScrollbarHeight,\n pinnedWidthLeft,\n pinnedWidthRight,\n rowCount: count,\n setInSituRowOffset,\n setScrollTop,\n totalHeaderHeight: headerHeight,\n verticalScrollbarWidth,\n viewportBodyHeight,\n viewportWidth,\n };\n } else {\n return UNMEASURED_VIEWPORT;\n }\n }, [\n size,\n pinnedWidthLeft,\n unpinnedWidth,\n pinnedWidthRight,\n headerHeight,\n rowHeight,\n showPaginationControls,\n pixelContentHeight,\n virtualContentHeight,\n getRowAtPosition,\n getRowOffset,\n isVirtualScroll,\n setInSituRowOffset,\n setScrollTop,\n ]);\n};\n"],"names":["getRowAtPosition"],"mappings":"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"}
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
- "version": "0.8.94",
2
+ "version": "0.8.96",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "devDependencies": {
6
- "@vuu-ui/vuu-data-types": "0.8.94",
7
- "@vuu-ui/vuu-table-types": "0.8.94",
8
- "@vuu-ui/vuu-protocol-types": "0.8.94"
6
+ "@vuu-ui/vuu-data-types": "0.8.96",
7
+ "@vuu-ui/vuu-table-types": "0.8.96",
8
+ "@vuu-ui/vuu-protocol-types": "0.8.96"
9
9
  },
10
10
  "dependencies": {
11
11
  "@salt-ds/core": "1.34.0",
12
12
  "@salt-ds/styles": "0.2.1",
13
13
  "@salt-ds/window": "0.1.1",
14
- "@vuu-ui/vuu-data-react": "0.8.94",
15
- "@vuu-ui/vuu-layout": "0.8.94",
16
- "@vuu-ui/vuu-popups": "0.8.94",
17
- "@vuu-ui/vuu-ui-controls": "0.8.94",
18
- "@vuu-ui/vuu-utils": "0.8.94"
14
+ "@vuu-ui/vuu-data-react": "0.8.96",
15
+ "@vuu-ui/vuu-layout": "0.8.96",
16
+ "@vuu-ui/vuu-popups": "0.8.96",
17
+ "@vuu-ui/vuu-ui-controls": "0.8.96",
18
+ "@vuu-ui/vuu-utils": "0.8.96"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "clsx": "^2.0.0",
package/types/Table.d.ts CHANGED
@@ -4,9 +4,14 @@ import type { DragDropState } from "@vuu-ui/vuu-ui-controls";
4
4
  import { DragStartHandler, MeasuredContainerProps, dragStrategy } from "@vuu-ui/vuu-ui-controls";
5
5
  import { FC, ForwardedRef } from "react";
6
6
  import { ScrollingAPI } from "./useTableScroll";
7
+ import { TableCellBlock } from "./cell-block/cellblock-utils";
7
8
  export type TableNavigationStyle = "none" | "cell" | "row";
8
9
  export interface TableProps extends Omit<MeasuredContainerProps, "onDragStart" | "onDrop" | "onSelect"> {
9
10
  Row?: FC<RowProps>;
11
+ /**
12
+ * Allow a block of cells to be selected. Typically to be copied.
13
+ */
14
+ allowCellBlockSelection?: boolean;
10
15
  allowConfigEditing?: boolean;
11
16
  /**
12
17
  * Allow column headers to be dragged to re-arrange
@@ -39,6 +44,15 @@ export interface TableProps extends Omit<MeasuredContainerProps, "onDragStart" |
39
44
  * Default is cell.
40
45
  */
41
46
  highlightedIndex?: number;
47
+ /**
48
+ * Behaves in most respects like viewportRowLimit except that, when there are fewer
49
+ * rows available than the limit set here, the Table height will reduce. This can be
50
+ * useful where a Table is used in a dropdown control.
51
+ */
52
+ maxViewportRowLimit?: number;
53
+ /**
54
+ * Determines bahaviour of keyboard navigation , either row focused or cell focused.
55
+ */
42
56
  navigationStyle?: TableNavigationStyle;
43
57
  /**
44
58
  * required if a fully featured column picker is to be available.
@@ -61,6 +75,16 @@ export interface TableProps extends Omit<MeasuredContainerProps, "onDragStart" |
61
75
  */
62
76
  onRowClick?: TableRowClickHandler;
63
77
  onSelect?: TableRowSelectHandler;
78
+ /**
79
+ * Triggered when a block of cells is selected. CellBlock selection can be
80
+ * effected with either mouse or keyboard.
81
+ * - mouse: hold down mouse and drag over selection area
82
+ * - keyboard: press and hold shift key from start cell, then use arrow keys
83
+ * to extend selection block.
84
+ *
85
+ * This callback is invoked when mouse is released or shift key released.
86
+ */
87
+ onSelectCellBlock?: (cellBlock: TableCellBlock) => void;
64
88
  onSelectionChange?: SelectionChangeHandler;
65
89
  renderBufferSize?: number;
66
90
  /**
@@ -96,5 +120,21 @@ export interface TableProps extends Omit<MeasuredContainerProps, "onDragStart" |
96
120
  * from contexct menu
97
121
  */
98
122
  showColumnHeaderMenus?: boolean;
123
+ /**
124
+ * if true, pagination will be used to navigate data, scrollbars will not be rendered
125
+ */
126
+ showPaginationControls?: boolean;
127
+ /**
128
+ * As an alternative to sizing the Table height via CSS or via an explicit height value,
129
+ * specify the number of rows to be displayed within the Viewport. The actual height
130
+ * will then be the product of viewportRowLimit and rowHeight. Row Height will be
131
+ * determined in the usual way, it can be specified explicitly in a prop or set via
132
+ * CSS. If both explicit height and viewportRowLimit are provided by props, rowHeight
133
+ * will be derived from these. Do not pass props for all three values - height,
134
+ * rowHeight and viewportRowLimit. That will be rejected.
135
+ * Use maxViewportRowLimit rather than viewportRowLimit if the height of the table
136
+ * should be reduced when fewer rows are actually available than the limit specified.
137
+ */
138
+ viewportRowLimit?: number;
99
139
  }
100
140
  export declare const Table: import("react").ForwardRefExoticComponent<TableProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,6 @@
1
+ import { HTMLAttributes } from "react";
2
+ export interface CellBlockProps extends Omit<HTMLAttributes<HTMLDivElement>, "onCopy"> {
3
+ debugName?: string;
4
+ onCopy?: () => void;
5
+ }
6
+ export declare const CellBlock: import("react").ForwardRefExoticComponent<CellBlockProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,37 @@
1
+ import { VuuRange } from "@vuu-ui/vuu-protocol-types";
2
+ export type TableCellBlock = {
3
+ columnRange: VuuRange;
4
+ rowRange: VuuRange;
5
+ };
6
+ export type CellBox = {
7
+ bottom: number;
8
+ left: number;
9
+ right: number;
10
+ top: number;
11
+ };
12
+ export declare const isNullCellBox: ({ bottom, left, right, top }: CellBox) => boolean;
13
+ type EndCellDirection = "self" | "n" | "ne" | "e" | "se" | "s" | "sw" | "w" | "nw";
14
+ export declare const getEndCellDirection: (startBox: CellBox, endBox: CellBox) => EndCellDirection;
15
+ export declare const setElementBox: (el: HTMLElement, box: CellBox) => void;
16
+ export declare const outsideBox: ({ bottom, left, right, top }: CellBox, x: number, y: number) => boolean;
17
+ export declare const getTableCellBlock: (startCell: HTMLDivElement, endCell: HTMLDivElement) => TableCellBlock;
18
+ export type RefState = {
19
+ dragState: "pending" | "active";
20
+ cellBlock: HTMLDivElement | null;
21
+ cellBlockClassName: string;
22
+ endBox: CellBox;
23
+ endCell: HTMLDivElement | null;
24
+ endPos: PosTuple;
25
+ mousePosX: number;
26
+ mousePosY: number;
27
+ mouseStartX: number;
28
+ mouseStartY: number;
29
+ startCell: HTMLDivElement | null;
30
+ startBox: CellBox;
31
+ startPos: PosTuple;
32
+ };
33
+ export type PosTuple = [number, number];
34
+ export declare const refState: RefState;
35
+ export declare const updateCellBlockClassName: (state: RefState) => void;
36
+ export declare const getTextFromCells: (startCell: HTMLDivElement, endCell: HTMLDivElement) => string;
37
+ export {};
@@ -0,0 +1,16 @@
1
+ import { KeyboardEventHandler, MouseEventHandler, ReactElement, RefObject } from "react";
2
+ import { FocusCell } from "../useCellFocus";
3
+ import { TableCellBlock } from "./cellblock-utils";
4
+ export interface CellblockSelectionHookProps {
5
+ allowCellBlockSelection?: boolean;
6
+ columnCount?: number;
7
+ containerRef: RefObject<HTMLElement>;
8
+ focusCell: FocusCell;
9
+ onSelectCellBlock?: (cellBlock: TableCellBlock) => void;
10
+ rowCount?: number;
11
+ }
12
+ export declare const useCellBlockSelection: ({ allowCellBlockSelection, columnCount, containerRef, focusCell, onSelectCellBlock, rowCount, }: CellblockSelectionHookProps) => {
13
+ cellBlock: ReactElement<any, string | import("react").JSXElementConstructor<any>> | null;
14
+ onKeyDown: KeyboardEventHandler | undefined;
15
+ onMouseDown: MouseEventHandler | undefined;
16
+ };
package/types/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export * from "./table-cell";
7
7
  export * from "./table-config";
8
8
  export * from "./table-header";
9
9
  export * from "./useControlledTableNavigation";
10
+ export * from "./useKeyboardNavigation";
10
11
  export * from "./useTableModel";
11
12
  export * from "./useTableScroll";
12
13
  export * from "./useTableViewport";
@@ -1,9 +1,10 @@
1
1
  import { DataSourceRow } from "@vuu-ui/vuu-data-types";
2
+ import { WindowRange } from "@vuu-ui/vuu-utils";
2
3
  import { VuuRange } from "@vuu-ui/vuu-protocol-types";
3
4
  export declare class MovingWindow {
5
+ #private;
4
6
  data: DataSourceRow[];
5
7
  rowCount: number;
6
- private range;
7
8
  constructor({ from, to }: VuuRange);
8
9
  setRowCount: (rowCount: number) => void;
9
10
  add(data: DataSourceRow): void;
@@ -11,4 +12,5 @@ export declare class MovingWindow {
11
12
  isWithinRange(index: number): boolean;
12
13
  setRange({ from, to }: VuuRange): void;
13
14
  getSelectedRows(): DataSourceRow[];
15
+ get range(): WindowRange;
14
16
  }
@@ -0,0 +1,6 @@
1
+ import { HtmlHTMLAttributes } from "react";
2
+ import { DataSource } from "@vuu-ui/vuu-data-types";
3
+ export interface PaginationControlProps extends HtmlHTMLAttributes<HTMLDivElement> {
4
+ dataSource: DataSource;
5
+ }
6
+ export declare const PaginationControl: import("react").ForwardRefExoticComponent<PaginationControlProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1 @@
1
+ export * from "./PaginationControl";
@@ -0,0 +1,9 @@
1
+ import { SyntheticEvent } from "react";
2
+ import { DataSource } from "@vuu-ui/vuu-data-types";
3
+ export interface PaginationHookProps {
4
+ dataSource: DataSource;
5
+ }
6
+ export declare const usePagination: ({ dataSource }: PaginationHookProps) => {
7
+ onPageChange: (_evt: SyntheticEvent, page: number) => void;
8
+ pageCount: number;
9
+ };
@@ -1,15 +1,20 @@
1
1
  import { RefObject } from "react";
2
2
  import { ScrollDirection } from "./useTableScroll";
3
+ import type { ArrowKey, PageKey } from "@vuu-ui/vuu-utils";
3
4
  /**
4
5
  * [rowIndex, colIndex
5
6
  */
6
7
  export type CellPos = [number, number];
8
+ export type NavigationKey = PageKey | ArrowKey;
7
9
  export declare const headerCellQuery: (colIdx: number) => string;
8
10
  export declare const dataCellQuery: (rowIdx: number, colIdx: number) => string;
9
11
  export declare const getTableCell: (containerRef: RefObject<HTMLElement>, [rowIdx, colIdx]: CellPos) => HTMLElement;
10
12
  export declare const cellIsEditable: (cell: HTMLDivElement | null) => boolean | undefined;
11
13
  export declare const cellDropdownShowing: (cell: HTMLDivElement | null) => boolean;
12
14
  export declare const cellIsTextInput: (cell: HTMLElement) => boolean;
13
- export declare function getRowIndex(rowEl?: HTMLElement): number;
15
+ export declare const getIndexFromRowElement: (rowElement: HTMLElement | null) => number;
16
+ export declare const getIndexFromCellElement: (cellElement: HTMLElement | null) => number;
17
+ export declare const getTableCellPos: (tableCell: HTMLDivElement) => CellPos;
14
18
  export declare const closestRowIndex: (el: HTMLElement) => number;
19
+ export declare function getNextCellPos(key: ArrowKey, [rowIdx, colIdx]: CellPos, columnCount: number, rowCount: number): CellPos;
15
20
  export declare const howFarIsRowOutsideViewport: (rowEl: HTMLElement, totalHeaderHeight: number, contentContainer?: Element | null) => readonly [ScrollDirection | undefined, number | undefined];
@@ -0,0 +1,13 @@
1
+ import { RefCallback, RefObject } from "react";
2
+ import { CellPos } from "./table-dom-utils";
3
+ import { ScrollRequestHandler } from "./useTableScroll";
4
+ export interface CellFocusHookProps {
5
+ containerRef: RefObject<HTMLElement>;
6
+ disableFocus?: boolean;
7
+ requestScroll?: ScrollRequestHandler;
8
+ }
9
+ export type FocusCell = (cellPos: CellPos) => void;
10
+ export declare const useCellFocus: ({ containerRef, disableFocus, requestScroll, }: CellFocusHookProps) => {
11
+ focusCell: FocusCell;
12
+ tableBodyRef: RefCallback<HTMLDivElement>;
13
+ };
@@ -1,4 +1,5 @@
1
1
  import { KeyboardEventHandler } from "react";
2
+ export declare const isRowSelectionKey: (key: string) => boolean;
2
3
  export declare const useControlledTableNavigation: (initialValue: number, rowCount: number) => {
3
4
  highlightedIndexRef: import("react").MutableRefObject<number | undefined>;
4
5
  onHighlight: (idx: number) => void;
@@ -1,11 +1,11 @@
1
1
  import { VuuRange } from "@vuu-ui/vuu-protocol-types";
2
+ import { PageKey } from "@vuu-ui/vuu-utils";
2
3
  import { KeyboardEvent, MouseEvent, RefObject } from "react";
3
4
  import { TableNavigationStyle } from "./Table";
5
+ import { NavigationKey } from "./table-dom-utils";
4
6
  import { ScrollRequestHandler } from "./useTableScroll";
7
+ import { FocusCell } from "./useCellFocus";
5
8
  export declare const isNavigationKey: (key: string, navigationStyle: TableNavigationStyle) => key is NavigationKey;
6
- type ArrowKey = "ArrowUp" | "ArrowDown" | "ArrowLeft" | "ArrowRight";
7
- type PageKey = "Home" | "End" | "PageUp" | "PageDown";
8
- type NavigationKey = PageKey | ArrowKey;
9
9
  export declare const isPagingKey: (key: string) => key is PageKey;
10
10
  export interface NavigationHookProps {
11
11
  containerRef: RefObject<HTMLElement>;
@@ -13,6 +13,7 @@ export interface NavigationHookProps {
13
13
  defaultHighlightedIndex?: number;
14
14
  disableFocus?: boolean;
15
15
  disableHighlightOnFocus?: boolean;
16
+ focusCell: FocusCell;
16
17
  highlightedIndex?: number;
17
18
  label?: string;
18
19
  navigationStyle: TableNavigationStyle;
@@ -24,7 +25,7 @@ export interface NavigationHookProps {
24
25
  selected?: unknown;
25
26
  viewportRowCount: number;
26
27
  }
27
- export declare const useKeyboardNavigation: ({ columnCount, containerRef, disableFocus, defaultHighlightedIndex, disableHighlightOnFocus, highlightedIndex: highlightedIndexProp, navigationStyle, requestScroll, onHighlight, rowCount, viewportRowCount, }: NavigationHookProps) => {
28
+ export declare const useKeyboardNavigation: ({ columnCount, containerRef, defaultHighlightedIndex, disableHighlightOnFocus, focusCell, highlightedIndex: highlightedIndexProp, navigationStyle, requestScroll, onHighlight, rowCount, viewportRowCount, }: NavigationHookProps) => {
28
29
  highlightedIndexRef: import("react").MutableRefObject<number | undefined>;
29
30
  navigate: () => void;
30
31
  onClick: (evt: MouseEvent) => void;
@@ -33,4 +34,3 @@ export declare const useKeyboardNavigation: ({ columnCount, containerRef, disabl
33
34
  onMouseLeave: (() => void) | undefined;
34
35
  onMouseMove: ((evt: MouseEvent) => void) | undefined;
35
36
  };
36
- export {};
@@ -4,7 +4,7 @@ interface MeasuredHeightHookProps {
4
4
  height?: number;
5
5
  }
6
6
  export declare const useMeasuredHeight: ({ onHeightMeasured, height: heightProp, }: MeasuredHeightHookProps) => {
7
- rowHeight: number;
8
- rowRef: RefCallback<HTMLDivElement>;
7
+ measuredHeight: number;
8
+ measuredRef: RefCallback<HTMLDivElement>;
9
9
  };
10
10
  export {};
@@ -1,33 +1,33 @@
1
1
  import { DataSourceRow } from "@vuu-ui/vuu-data-types";
2
- import { ColumnDescriptor, DataCellEditHandler, TableRowClickHandlerInternal, RuntimeColumnDescriptor, TableColumnResizeHandler, TableConfig, TableSelectionModel } from "@vuu-ui/vuu-table-types";
3
2
  import { VuuSortType } from "@vuu-ui/vuu-protocol-types";
3
+ import { ColumnDescriptor, DataCellEditHandler, RuntimeColumnDescriptor, TableColumnResizeHandler, TableConfig, TableRowClickHandlerInternal, TableSelectionModel } from "@vuu-ui/vuu-table-types";
4
4
  import { MeasuredProps, MeasuredSize } from "@vuu-ui/vuu-ui-controls";
5
- import { FocusEvent, KeyboardEvent, RefObject } from "react";
5
+ import { FocusEvent, KeyboardEvent, MouseEventHandler, RefObject } from "react";
6
6
  import { TableProps } from "./Table";
7
- export interface TableHookProps extends MeasuredProps, Pick<TableProps, "allowDragDrop" | "availableColumns" | "config" | "dataSource" | "disableFocus" | "highlightedIndex" | "id" | "navigationStyle" | "onAvailableColumnsChange" | "onConfigChange" | "onDragStart" | "onDrop" | "onHighlight" | "onSelect" | "onSelectionChange" | "onRowClick" | "renderBufferSize" | "scrollingApiRef"> {
7
+ export interface TableHookProps extends MeasuredProps, Pick<TableProps, "allowCellBlockSelection" | "allowDragDrop" | "availableColumns" | "config" | "dataSource" | "disableFocus" | "highlightedIndex" | "id" | "navigationStyle" | "onAvailableColumnsChange" | "onConfigChange" | "onDragStart" | "onDrop" | "onHighlight" | "onSelect" | "onSelectCellBlock" | "onSelectionChange" | "onRowClick" | "renderBufferSize" | "scrollingApiRef" | "showColumnHeaders" | "showPaginationControls"> {
8
8
  containerRef: RefObject<HTMLDivElement>;
9
9
  rowHeight: number;
10
10
  selectionModel: TableSelectionModel;
11
11
  size: MeasuredSize;
12
12
  }
13
- export declare const useTable: ({ allowDragDrop, availableColumns, config, containerRef, dataSource, disableFocus, highlightedIndex: highlightedIndexProp, id, navigationStyle, onAvailableColumnsChange, onConfigChange, onDragStart, onDrop, onHighlight, onRowClick: onRowClickProp, onSelect, onSelectionChange, renderBufferSize, rowHeight, scrollingApiRef, selectionModel, size, }: TableHookProps) => {
13
+ export declare const useTable: ({ allowCellBlockSelection, allowDragDrop, availableColumns, config, containerRef, dataSource, disableFocus, highlightedIndex: highlightedIndexProp, id, navigationStyle, onAvailableColumnsChange, onConfigChange, onDragStart, onDrop, onHighlight, onRowClick: onRowClickProp, onSelect, onSelectCellBlock, onSelectionChange, renderBufferSize, rowHeight, scrollingApiRef, selectionModel, showColumnHeaders, showPaginationControls, size, }: TableHookProps) => {
14
14
  "aria-rowcount": number;
15
- rowClassNameGenerator: import("@vuu-ui/vuu-utils").RowClassNameGenerator | undefined;
16
- draggableRow: JSX.Element | undefined;
17
- onBlur: import("react").FocusEventHandler;
18
- onDoubleClick: (e: import("react").MouseEvent<HTMLElement, MouseEvent>) => void;
19
- onFocus: (e: FocusEvent<HTMLElement>) => void;
20
- onKeyDown: (e: KeyboardEvent<HTMLElement>) => void;
21
- onMouseDown: import("react").MouseEventHandler | undefined;
15
+ cellBlock: import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | null;
22
16
  columnMap: import("@vuu-ui/vuu-utils").ColumnMap;
23
17
  columns: RuntimeColumnDescriptor[];
24
18
  data: DataSourceRow[];
19
+ draggableRow: JSX.Element | undefined;
25
20
  getRowOffset: import("@vuu-ui/vuu-utils").RowOffsetFunc;
26
21
  handleContextMenuAction: import("@vuu-ui/vuu-data-types").MenuActionHandler;
27
22
  headerHeight: number;
28
23
  headings: import("@vuu-ui/vuu-table-types").TableHeadings;
29
24
  highlightedIndex: number | undefined;
30
25
  menuBuilder: import("@vuu-ui/vuu-data-types").MenuBuilder;
26
+ onBlur: import("react").FocusEventHandler;
27
+ onDoubleClick: (e: import("react").MouseEvent<HTMLElement, MouseEvent>) => void;
28
+ onFocus: (e: FocusEvent<HTMLElement>) => void;
29
+ onKeyDown: (e: KeyboardEvent<HTMLElement>) => void;
30
+ onMouseDown: MouseEventHandler;
31
31
  onContextMenu: (evt: import("react").MouseEvent<HTMLElement, MouseEvent>) => void;
32
32
  onDataEdited: DataCellEditHandler;
33
33
  onHeaderHeightMeasured: (height: number) => void;
@@ -38,6 +38,7 @@ export declare const useTable: ({ allowDragDrop, availableColumns, config, conta
38
38
  onSortColumn: (column: ColumnDescriptor, extendSort?: any, sortType?: VuuSortType) => void;
39
39
  onResizeColumn: TableColumnResizeHandler;
40
40
  onToggleGroup: (row: DataSourceRow, column: RuntimeColumnDescriptor) => void;
41
+ rowClassNameGenerator: import("@vuu-ui/vuu-utils").RowClassNameGenerator | undefined;
41
42
  scrollProps: {
42
43
  columnsWithinViewport: RuntimeColumnDescriptor[];
43
44
  scrollbarContainerRef: (el: HTMLDivElement | null) => void;
@@ -53,6 +54,7 @@ export declare const useTable: ({ allowDragDrop, availableColumns, config, conta
53
54
  rowSeparators?: boolean | undefined;
54
55
  zebraStripes?: boolean | undefined;
55
56
  };
57
+ tableBodyRef: import("react").RefCallback<HTMLDivElement>;
56
58
  tableConfig: Readonly<TableConfig>;
57
59
  viewportMeasurements: {
58
60
  appliedPageSize: number;
@@ -42,6 +42,7 @@ export interface TableScrollHookProps {
42
42
  rowHeight: number;
43
43
  scrollingApiRef?: ForwardedRef<ScrollingAPI>;
44
44
  setRange: (range: VuuRange) => void;
45
+ showPaginationControls?: boolean;
45
46
  viewportMeasurements: ViewportMeasurements;
46
47
  }
47
48
  export declare const useTableScroll: ({ columns, getRowAtPosition, onHorizontalScroll, onVerticalScroll, onVerticalScrollInSitu, rowHeight, scrollingApiRef, setRange, viewportMeasurements, }: TableScrollHookProps) => {
@@ -15,7 +15,8 @@ export interface TableViewportHookProps {
15
15
  * this is the solid left/right `border` rendered on the selection block
16
16
  */
17
17
  selectionEndSize?: number;
18
- size: MeasuredSize | undefined;
18
+ showPaginationControls?: boolean;
19
+ size: MeasuredSize;
19
20
  }
20
21
  export interface ViewportMeasurements {
21
22
  appliedPageSize: number;
@@ -38,4 +39,4 @@ export interface TableViewportHookResult extends ViewportMeasurements {
38
39
  setInSituRowOffset: (rowIndexOffset: number) => void;
39
40
  setScrollTop: (scrollTop: number, scrollPct: number) => void;
40
41
  }
41
- export declare const useTableViewport: ({ columns, headerHeight, rowCount, rowHeight, selectionEndSize, size, }: TableViewportHookProps) => TableViewportHookResult;
42
+ export declare const useTableViewport: ({ columns, headerHeight, rowCount, rowHeight, selectionEndSize, showPaginationControls, size, }: TableViewportHookProps) => TableViewportHookResult;