@1771technologies/lytenyte-pro 2.0.2 → 2.0.4-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +297 -11
  2. package/dist/components/headless/dialog/container.js +1 -2
  3. package/dist/components/select-all.d.ts +1 -1
  4. package/dist/data-source-client/hooks/use-flattened-data.d.ts +1 -1
  5. package/dist/data-source-client/hooks/use-pivot/auxiliary-functions/apply-reference-column.d.ts +1 -1
  6. package/dist/data-source-client/hooks/use-pivot/auxiliary-functions/pivot-paths.d.ts +1 -1
  7. package/dist/data-source-client/hooks/use-pivot/use-agg-model.d.ts +1 -1
  8. package/dist/data-source-client/hooks/use-pivot/use-pivot-columns.d.ts +1 -1
  9. package/dist/data-source-client/hooks/use-pivot/use-pivot-data.d.ts +1 -1
  10. package/dist/data-source-client/hooks/use-pivot/use-pivot-group-fn.d.ts +1 -1
  11. package/dist/data-source-client/use-client-data-source.d.ts +1 -3
  12. package/dist/index.d.ts +1 -3
  13. package/dist/root/root.d.ts +5 -8
  14. package/dist/root/root.js +5 -83
  15. package/dist/types.d.ts +3 -0
  16. package/package.json +27 -6
  17. package/dist/cell-selection/adjust-rect-for-row-and-cell-span.d.ts +0 -2
  18. package/dist/cell-selection/adjust-rect-for-row-and-cell-span.js +0 -43
  19. package/dist/cell-selection/are-rects-equal.d.ts +0 -2
  20. package/dist/cell-selection/are-rects-equal.js +0 -6
  21. package/dist/cell-selection/bound-selection-rect.d.ts +0 -3
  22. package/dist/cell-selection/bound-selection-rect.js +0 -16
  23. package/dist/cell-selection/cell-selection-containers.d.ts +0 -3
  24. package/dist/cell-selection/cell-selection-containers.js +0 -86
  25. package/dist/cell-selection/cell-selection-driver/cell-selection-driver.d.ts +0 -1
  26. package/dist/cell-selection/cell-selection-driver/cell-selection-driver.js +0 -279
  27. package/dist/cell-selection/cell-selection-driver/use-cell-focus-change.d.ts +0 -5
  28. package/dist/cell-selection/cell-selection-driver/use-cell-focus-change.js +0 -34
  29. package/dist/cell-selection/cell-style-row.d.ts +0 -8
  30. package/dist/cell-selection/cell-style-row.js +0 -79
  31. package/dist/cell-selection/data-rect-from-cell-position.d.ts +0 -3
  32. package/dist/cell-selection/data-rect-from-cell-position.js +0 -17
  33. package/dist/cell-selection/deselect-rect-range.d.ts +0 -2
  34. package/dist/cell-selection/deselect-rect-range.js +0 -43
  35. package/dist/cell-selection/expand-selection-down.d.ts +0 -3
  36. package/dist/cell-selection/expand-selection-down.js +0 -78
  37. package/dist/cell-selection/expand-selection-end.d.ts +0 -3
  38. package/dist/cell-selection/expand-selection-end.js +0 -76
  39. package/dist/cell-selection/expand-selection-start.d.ts +0 -3
  40. package/dist/cell-selection/expand-selection-start.js +0 -73
  41. package/dist/cell-selection/expand-selection-up.d.ts +0 -3
  42. package/dist/cell-selection/expand-selection-up.js +0 -74
  43. package/dist/cell-selection/full-width-start-end-index.d.ts +0 -2
  44. package/dist/cell-selection/full-width-start-end-index.js +0 -4
  45. package/dist/cell-selection/get-root-cell.d.ts +0 -3
  46. package/dist/cell-selection/get-root-cell.js +0 -6
  47. package/dist/cell-selection/index.d.ts +0 -11
  48. package/dist/cell-selection/index.js +0 -11
  49. package/dist/cell-selection/is-bottom-rect.d.ts +0 -2
  50. package/dist/cell-selection/is-bottom-rect.js +0 -4
  51. package/dist/cell-selection/is-center-col-rect.d.ts +0 -5
  52. package/dist/cell-selection/is-center-col-rect.js +0 -3
  53. package/dist/cell-selection/is-center-rect.d.ts +0 -2
  54. package/dist/cell-selection/is-center-rect.js +0 -4
  55. package/dist/cell-selection/is-end-rect.d.ts +0 -5
  56. package/dist/cell-selection/is-end-rect.js +0 -3
  57. package/dist/cell-selection/is-fully-within-rect.d.ts +0 -2
  58. package/dist/cell-selection/is-fully-within-rect.js +0 -6
  59. package/dist/cell-selection/is-overlapping-rect.d.ts +0 -2
  60. package/dist/cell-selection/is-overlapping-rect.js +0 -5
  61. package/dist/cell-selection/is-start-rect.d.ts +0 -5
  62. package/dist/cell-selection/is-start-rect.js +0 -3
  63. package/dist/cell-selection/is-top-rect.d.ts +0 -2
  64. package/dist/cell-selection/is-top-rect.js +0 -3
  65. package/dist/cell-selection/is-within-selection-rect.d.ts +0 -2
  66. package/dist/cell-selection/is-within-selection-rect.js +0 -3
  67. package/dist/cell-selection/split-cell-selection-rect.d.ts +0 -41
  68. package/dist/cell-selection/split-cell-selection-rect.js +0 -84
  69. package/dist/cell-selection/update-additive-cell-selection.d.ts +0 -4
  70. package/dist/cell-selection/update-additive-cell-selection.js +0 -21
  71. package/dist/cell-selection/use-edge-scroll.d.ts +0 -6
  72. package/dist/cell-selection/use-edge-scroll.js +0 -71
  73. package/dist/root/context.d.ts +0 -16
  74. package/dist/root/context.js +0 -4
  75. package/dist/root/hooks/use-pro-api.d.ts +0 -2
  76. package/dist/root/hooks/use-pro-api.js +0 -8
  77. package/dist/types/api.d.ts +0 -100
  78. package/dist/types/column.d.ts +0 -73
  79. package/dist/types/column.js +0 -1
  80. package/dist/types/events.d.ts +0 -56
  81. package/dist/types/events.js +0 -1
  82. package/dist/types/grid.d.ts +0 -46
  83. package/dist/types/grid.js +0 -1
  84. package/dist/types/index.d.ts +0 -7
  85. package/dist/types/index.js +0 -1
  86. package/dist/types/props.d.ts +0 -187
  87. package/dist/types/props.js +0 -1
  88. /package/dist/{types/api.js → types.js} +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@1771technologies/lytenyte-pro",
3
3
  "description": "Blazingly fast headless React data grid with 100s of features.",
4
- "version": "2.0.2",
4
+ "version": "2.0.4-dev.0",
5
5
  "type": "module",
6
6
  "license": "COMMERCIAL",
7
7
  "files": [
@@ -13,9 +13,25 @@
13
13
  ],
14
14
  "keywords": [
15
15
  "react",
16
+ "reactjs",
17
+ "table",
18
+ "grid",
16
19
  "data-grid",
20
+ "datagrid",
21
+ "data-table",
22
+ "datatable",
17
23
  "react-table",
18
- "headless",
24
+ "react-grid",
25
+ "react-component",
26
+ "grid-component",
27
+ "table-component",
28
+ "headless-table",
29
+ "headless-component",
30
+ "infinite-scrolling",
31
+ "virtual-scrolling",
32
+ "pagination",
33
+ "pivots",
34
+ "filtering",
19
35
  "virtualized"
20
36
  ],
21
37
  "homepage": "https://1771technologies.com",
@@ -33,6 +49,11 @@
33
49
  "import": "./dist/index.js",
34
50
  "require": "./dist/index.js"
35
51
  },
52
+ "./types": {
53
+ "types": "./src/types.d.ts",
54
+ "import": "./src/types.js",
55
+ "require": "./src/types.js"
56
+ },
36
57
  "./components": {
37
58
  "types": "./dist/components.d.ts",
38
59
  "import": "./dist/components.js",
@@ -58,12 +79,12 @@
58
79
  "access": "public"
59
80
  },
60
81
  "dependencies": {
61
- "@1771technologies/lytenyte-core": "2.0.2",
62
- "@1771technologies/lytenyte-design": "2.0.2",
63
- "@1771technologies/lytenyte-shared": "2.0.2"
82
+ "@1771technologies/lytenyte-shared": "2.0.4-dev.0",
83
+ "@1771technologies/lytenyte-core": "2.0.4-dev.0",
84
+ "@1771technologies/lytenyte-design": "2.0.4-dev.0"
64
85
  },
65
86
  "devDependencies": {
66
- "@1771technologies/grid-sample-data": "2.0.2"
87
+ "@1771technologies/grid-sample-data": "2.0.4-dev.0"
67
88
  },
68
89
  "peerDependencies": {
69
90
  "react": "18.0.0 || ^19.0.0",
@@ -1,2 +0,0 @@
1
- import type { API, DataRect } from "../types/api.js";
2
- export declare function adjustRectForRowAndCellSpan(cellRoot: API["cellRoot"], rect: DataRect): DataRect;
@@ -1,43 +0,0 @@
1
- import { getRootCell } from "./get-root-cell.js";
2
- export function adjustRectForRowAndCellSpan(cellRoot, rect) {
3
- let { rowStart, rowEnd, columnStart, columnEnd } = rect;
4
- // Check the top row of the rect.
5
- for (let i = columnStart; i < columnEnd; i++) {
6
- let cell = getRootCell(cellRoot, rowStart, i);
7
- if (cell) {
8
- columnStart = Math.min(columnStart, cell.colIndex);
9
- columnEnd = Math.max(columnEnd, cell.colIndex + cell.colSpan);
10
- rowStart = Math.min(rowStart, cell.rowIndex);
11
- rowEnd = Math.max(rowEnd, cell.rowIndex + cell.rowSpan);
12
- }
13
- cell = getRootCell(cellRoot, rowEnd - 1, i);
14
- if (cell) {
15
- columnStart = Math.min(columnStart, cell.colIndex);
16
- columnEnd = Math.max(columnEnd, cell.colIndex + cell.colSpan);
17
- rowStart = Math.min(rowStart, cell.rowIndex);
18
- rowEnd = Math.max(rowEnd, cell.rowIndex + cell.rowSpan);
19
- }
20
- }
21
- for (let i = rowStart; i < rowEnd; i++) {
22
- let cell = getRootCell(cellRoot, i, columnStart);
23
- if (cell) {
24
- columnStart = Math.min(columnStart, cell.colIndex);
25
- columnEnd = Math.max(columnEnd, cell.colIndex + cell.colSpan);
26
- rowStart = Math.min(rowStart, cell.rowIndex);
27
- rowEnd = Math.max(rowEnd, cell.rowIndex + cell.rowSpan);
28
- }
29
- cell = getRootCell(cellRoot, i, columnEnd - 1);
30
- if (cell) {
31
- columnStart = Math.min(columnStart, cell.colIndex);
32
- columnEnd = Math.max(columnEnd, cell.colIndex + cell.colSpan);
33
- rowStart = Math.min(rowStart, cell.rowIndex);
34
- rowEnd = Math.max(rowEnd, cell.rowIndex + cell.rowSpan);
35
- }
36
- }
37
- return {
38
- rowStart,
39
- rowEnd,
40
- columnStart,
41
- columnEnd,
42
- };
43
- }
@@ -1,2 +0,0 @@
1
- import type { DataRect } from "../types/api.js";
2
- export declare function areRectsEqual(left: DataRect, right: DataRect): boolean;
@@ -1,6 +0,0 @@
1
- export function areRectsEqual(left, right) {
2
- return (left.rowStart === right.rowStart &&
3
- left.rowEnd === right.rowEnd &&
4
- left.columnStart === right.columnStart &&
5
- left.columnEnd === right.columnEnd);
6
- }
@@ -1,3 +0,0 @@
1
- import { type ColumnView } from "@1771technologies/lytenyte-shared";
2
- import type { DataRect } from "../types";
3
- export declare function boundSelectionRect(view: ColumnView, rowCount: number, rect: DataRect): DataRect;
@@ -1,16 +0,0 @@
1
- import { clamp } from "@1771technologies/lytenyte-shared";
2
- export function boundSelectionRect(view, rowCount, rect) {
3
- const maxRow = rowCount;
4
- const minRow = 0;
5
- const maxColumn = view.visibleColumns.length;
6
- const minColumn = 0;
7
- const rowStartMaybe = clamp(minRow, rect.rowStart, maxRow);
8
- const rowEndMaybe = clamp(minRow, rect.rowEnd, maxRow);
9
- const colStartMaybe = clamp(minColumn, rect.columnStart, maxColumn);
10
- const colEndMaybe = clamp(minColumn, rect.columnEnd, maxColumn);
11
- const rowStart = Math.min(rowStartMaybe, rowEndMaybe);
12
- const rowEnd = Math.max(rowStartMaybe, rowEndMaybe);
13
- const columnStart = Math.min(colStartMaybe, colEndMaybe);
14
- const columnEnd = Math.max(colStartMaybe, colEndMaybe);
15
- return { rowStart, rowEnd, columnStart, columnEnd };
16
- }
@@ -1,3 +0,0 @@
1
- export declare const CellSelectionTop: import("react").NamedExoticComponent<object>;
2
- export declare const CellSelectionCenter: import("react").NamedExoticComponent<object>;
3
- export declare const CellSelectionBottom: import("react").NamedExoticComponent<object>;
@@ -1,86 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { memo, useMemo } from "react";
3
- import { CellStyleRow } from "./cell-style-row.js";
4
- import { isTopRect } from "./is-top-rect.js";
5
- import { isCenterRect } from "./is-center-rect.js";
6
- import { isBottomRect } from "./is-bottom-rect.js";
7
- import { useRoot } from "@1771technologies/lytenyte-core/internal";
8
- import { useProRoot } from "../root/context.js";
9
- export const CellSelectionTop = memo(function CellSelectionTop() {
10
- const { source } = useRoot();
11
- const { cellSelectionSplits: allRects, cellSelectionAdditiveRects: additive, cellSelectionIsDeselect, } = useProRoot();
12
- const topCount = source.useTopCount();
13
- const topRects = useMemo(() => {
14
- return allRects.filter((rect) => isTopRect(topCount, rect));
15
- }, [allRects, topCount]);
16
- const isDeselect = cellSelectionIsDeselect.current;
17
- const additiveRects = useMemo(() => {
18
- if (!additive)
19
- return [];
20
- return additive.filter((rect) => isTopRect(topCount, rect));
21
- }, [additive, topCount]);
22
- return (_jsxs("div", { role: "presentation", style: {
23
- width: "100%",
24
- height: 0,
25
- display: "grid",
26
- gridTemplateRows: "0px",
27
- gridTemplateColumns: "0px",
28
- }, children: [topRects.map((rect, i) => {
29
- return _jsx(CellStyleRow, { rect: rect, isRowPinnedTop: true }, i);
30
- }), additiveRects.map((rect) => {
31
- return _jsx(CellStyleRow, { rect: rect, isDeselect: isDeselect }, rect.columnStart);
32
- })] }));
33
- });
34
- export const CellSelectionCenter = memo(function CellSelectionCenter() {
35
- const { source } = useRoot();
36
- const { cellSelectionSplits: allRects, cellSelectionAdditiveRects: additive, cellSelectionIsDeselect, } = useProRoot();
37
- const topCount = source.useTopCount();
38
- const rowCount = source.useRowCount();
39
- const botCount = source.useBottomCount();
40
- const centerRects = useMemo(() => {
41
- return allRects.filter((rect) => isCenterRect(rowCount, botCount, topCount, rect));
42
- }, [allRects, botCount, rowCount, topCount]);
43
- const isDeselect = cellSelectionIsDeselect.current;
44
- const additiveRects = useMemo(() => {
45
- if (!additive)
46
- return [];
47
- return additive.filter((rect) => isCenterRect(rowCount, botCount, topCount, rect));
48
- }, [additive, botCount, rowCount, topCount]);
49
- return (_jsxs("div", { role: "presentation", style: {
50
- width: "100%",
51
- height: 0,
52
- display: "grid",
53
- gridTemplateRows: "0px",
54
- gridTemplateColumns: "0px",
55
- }, children: [centerRects.map((rect, i) => {
56
- return _jsx(CellStyleRow, { rect: rect }, i);
57
- }), additiveRects.map((rect) => {
58
- return _jsx(CellStyleRow, { rect: rect, isDeselect: isDeselect }, rect.columnStart);
59
- })] }));
60
- });
61
- export const CellSelectionBottom = memo(function CellSelectionBottom() {
62
- const { source } = useRoot();
63
- const { cellSelectionSplits: allRects, cellSelectionAdditiveRects: additive, cellSelectionIsDeselect, } = useProRoot();
64
- const rowCount = source.useRowCount();
65
- const botCount = source.useBottomCount();
66
- const bottomRects = useMemo(() => {
67
- return allRects.filter((rect) => isBottomRect(rowCount, botCount, rect));
68
- }, [allRects, botCount, rowCount]);
69
- const isDeselect = cellSelectionIsDeselect.current;
70
- const additiveRects = useMemo(() => {
71
- if (!additive)
72
- return [];
73
- return additive.filter((rect) => isBottomRect(rowCount, botCount, rect));
74
- }, [additive, botCount, rowCount]);
75
- return (_jsxs("div", { role: "presentation", style: {
76
- width: "100%",
77
- height: 0,
78
- display: "grid",
79
- gridTemplateRows: "0px",
80
- gridTemplateColumns: "0px",
81
- }, children: [bottomRects.map((rect, i) => {
82
- return _jsx(CellStyleRow, { rect: rect, isRowPinnedBottom: true }, i);
83
- }), additiveRects.map((rect) => {
84
- return _jsx(CellStyleRow, { rect: rect, isDeselect: isDeselect }, rect.columnStart);
85
- })] }));
86
- });
@@ -1 +0,0 @@
1
- export declare function CellSelectionDriver(): import("react/jsx-runtime").JSX.Element;
@@ -1,279 +0,0 @@
1
- import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect } from "react";
3
- import { useEdgeScroll } from "../use-edge-scroll.js";
4
- import { getClientX, getClientY, getRelativeXPosition, getRelativeYPosition, } from "@1771technologies/lytenyte-shared";
5
- import { getNearestFocusable, getPositionFromFocusable } from "@1771technologies/lytenyte-shared";
6
- import { isHTMLElement } from "@1771technologies/lytenyte-shared";
7
- import { updateAdditiveCellSelection } from "../update-additive-cell-selection.js";
8
- import { deselectRectRange } from "../deselect-rect-range.js";
9
- import { isWithinSelectionRect } from "../is-within-selection-rect.js";
10
- import { useProRoot } from "../../root/context.js";
11
- import { useRoot } from "@1771technologies/lytenyte-core/internal";
12
- import { useCellFocusChange } from "./use-cell-focus-change.js";
13
- import { adjustRectForRowAndCellSpan } from "../adjust-rect-for-row-and-cell-span.js";
14
- import { expandSelectionUp } from "../expand-selection-up.js";
15
- import { expandSelectionDown } from "../expand-selection-down.js";
16
- import { expandSelectionStart } from "../expand-selection-start.js";
17
- import { expandSelectionEnd } from "../expand-selection-end.js";
18
- function isNormalClick(event) {
19
- return event.button === 0 && !event.altKey;
20
- }
21
- export function CellSelectionDriver() {
22
- const { rtl, view, source, viewport, focusActive, id } = useRoot();
23
- const { cellSelectionMode: mode, onCellSelectionChange, api, cellSelectionAdditiveRects, setCellSelectionAdditiveRects, cellSelections, cellSelectionIsDeselect, } = useProRoot();
24
- const { excludeMarker, keepSelection } = useProRoot();
25
- const { cancelX, cancelY, edgeScrollX, edgeScrollY } = useEdgeScroll();
26
- const topCount = source.useTopCount();
27
- const rowCount = source.useRowCount();
28
- const botCount = source.useBottomCount();
29
- useEffect(() => {
30
- if (!viewport || mode === "none")
31
- return;
32
- const isMultiRange = mode === "multi-range";
33
- let isAdditive = false;
34
- let start = null;
35
- let lastRect = null;
36
- let animFrame = null;
37
- let startY = null;
38
- const gridId = id;
39
- const pointerMove = (event) => {
40
- if (animFrame)
41
- cancelAnimationFrame(animFrame);
42
- animFrame = requestAnimationFrame(() => {
43
- animFrame = null;
44
- if (!start)
45
- return;
46
- const clientX = getClientX(event);
47
- const clientY = getClientY(event);
48
- // Check the target we moved over and ensure it is an HTML element.
49
- if (!isHTMLElement(event.target))
50
- return;
51
- // Get the focusable position for the currently hovered cell.
52
- const focusable = getNearestFocusable(gridId, event.target);
53
- if (!focusable)
54
- return;
55
- const position = getPositionFromFocusable(gridId, focusable);
56
- if (position.kind !== "cell" && position.kind !== "full-width")
57
- return;
58
- const startCount = view.startCount;
59
- const firstEnd = view.centerCount + startCount;
60
- const centerCount = rowCount - topCount - botCount;
61
- const firstEndRow = centerCount + topCount;
62
- const relativeX = getRelativeXPosition(viewport, clientX);
63
- const isRtl = rtl;
64
- const visualX = isRtl ? relativeX.right : relativeX.left;
65
- const rowIndex = position.rowIndex;
66
- const columnIndex = position.colIndex;
67
- const startColSection = start.columnStart < startCount ? "start" : start.columnStart >= firstEnd ? "end" : "center";
68
- const colSection = columnIndex < startCount ? "start" : columnIndex >= firstEnd ? "end" : "center";
69
- const rowSection = rowIndex < topCount ? "top" : rowIndex >= firstEnd ? "bottom" : "center";
70
- const startRowSection = start.rowStart < topCount ? "top" : start.rowStart >= firstEndRow ? "bottom" : "center";
71
- const isSameColPin = startColSection === colSection;
72
- const isSameRowPin = startRowSection === rowSection;
73
- edgeScrollX(visualX, isRtl);
74
- const relativeY = getRelativeYPosition(viewport, clientY);
75
- edgeScrollY(relativeY.top, startY);
76
- const scrollY = viewport.scrollTop;
77
- if (!isSameRowPin && rowIndex < topCount && scrollY > 0)
78
- return;
79
- const maxScroll = viewport.scrollHeight - viewport.clientHeight - 4;
80
- if (!isSameRowPin && rowIndex > topCount + centerCount - 1 && scrollY < maxScroll)
81
- return;
82
- const scrollX = Math.abs(viewport.scrollLeft);
83
- if (!isSameColPin && columnIndex < startCount && scrollX > 0)
84
- return;
85
- const maxScrollX = viewport.scrollWidth - viewport.clientWidth - 4;
86
- if (!isSameColPin && columnIndex >= firstEnd && scrollX < maxScrollX)
87
- return;
88
- const rowSpan = position.kind === "full-width" || !position.root ? 1 : position.root.rowSpan;
89
- const colSpan = position.kind === "full-width" || !position.root ? 1 : position.root.colSpan;
90
- const rs = Math.min(rowIndex, start.rowStart);
91
- const re = Math.max(rowIndex + rowSpan, start.rowEnd);
92
- const ce = Math.max(columnIndex + colSpan, start.columnEnd);
93
- let cs = Math.min(columnIndex, start.columnStart);
94
- if (excludeMarker)
95
- cs = Math.max(cs, 1);
96
- const active = { rowStart: rs, rowEnd: re, columnStart: cs, columnEnd: ce };
97
- if (isAdditive) {
98
- updateAdditiveCellSelection(api, view, topCount, rowCount, botCount, active, cellSelectionAdditiveRects, setCellSelectionAdditiveRects);
99
- }
100
- else {
101
- onCellSelectionChange([adjustRectForRowAndCellSpan(api.cellRoot, active)]);
102
- }
103
- lastRect = active;
104
- });
105
- };
106
- const pointerDown = (event) => {
107
- if (!isNormalClick(event)) {
108
- document.removeEventListener("pointermove", pointerMove);
109
- // Prevent the default for the context menu, otherwise the cell
110
- // right clicked will be focused,
111
- // resulting in the cell selection changing.
112
- if (event.button == 2)
113
- event.preventDefault();
114
- return;
115
- }
116
- isAdditive = isMultiRange && (event.ctrlKey || event.metaKey);
117
- const target = event.target;
118
- if (!isHTMLElement(target))
119
- return;
120
- const focusable = getNearestFocusable(gridId, target);
121
- if (!focusable)
122
- return;
123
- const position = getPositionFromFocusable(gridId, focusable);
124
- if (position.kind !== "cell" && position.kind !== "full-width")
125
- return;
126
- const rowIndex = position.rowIndex;
127
- const columnIndex = position.colIndex;
128
- if (excludeMarker && columnIndex === 0)
129
- return;
130
- // If the columnIndex or rowIndex is null then we haven't clicked a valid cell position.
131
- // This ends the row selection.
132
- if (columnIndex == null || rowIndex == null) {
133
- onCellSelectionChange([]);
134
- return;
135
- }
136
- const isSelected = cellSelections.some((c) => isWithinSelectionRect(c, rowIndex, columnIndex));
137
- const isDeselect = isAdditive && isSelected;
138
- const rowSpan = position.kind === "full-width" || !position.root ? 1 : position.root.rowSpan;
139
- const colSpan = position.kind === "full-width" || !position.root ? 1 : position.root.colSpan;
140
- startY = getRelativeYPosition(viewport, event.clientY).top;
141
- start = {
142
- columnStart: columnIndex,
143
- columnEnd: columnIndex + colSpan,
144
- rowStart: rowIndex,
145
- rowEnd: rowIndex + rowSpan,
146
- };
147
- // If shift key down we select an area. We can only select an area if a pivot has been established.
148
- // The pivot will always expand the last cell selection rect if there are multiple ones.
149
- if (event.shiftKey) {
150
- const position = focusActive.get();
151
- if (position?.kind !== "cell")
152
- return;
153
- const pivot = {
154
- rowStart: position.root ? position.root.rowIndex : position.rowIndex,
155
- rowEnd: position.root ? position.root.rowIndex + position.root.rowSpan : position.rowIndex + 1,
156
- columnStart: position.root ? position.root.colIndex : position.colIndex,
157
- columnEnd: position.root ? position.root.colIndex + position.root.colSpan : position.colIndex,
158
- };
159
- const active = { ...pivot };
160
- active.columnStart = Math.min(columnIndex, active.columnStart);
161
- active.columnEnd = Math.max(columnIndex + 1, active.columnEnd);
162
- active.rowStart = Math.min(rowIndex, active.rowStart);
163
- active.rowEnd = Math.max(rowIndex + 1, active.rowEnd);
164
- onCellSelectionChange([active]);
165
- // We need to prevent the default otherwise the cell to go to will be
166
- // focused. This leads to awkward behavior around the cell selection pivot
167
- event.preventDefault();
168
- return;
169
- }
170
- // We need to prevent the default for multi
171
- if (mode === "multi-range" && (event.metaKey || event.ctrlKey)) {
172
- event.preventDefault();
173
- }
174
- cellSelectionIsDeselect.current = isDeselect;
175
- if (isAdditive) {
176
- updateAdditiveCellSelection(api, view, topCount, rowCount, botCount, start, cellSelectionAdditiveRects, setCellSelectionAdditiveRects);
177
- }
178
- else {
179
- onCellSelectionChange([adjustRectForRowAndCellSpan(api.cellRoot, start)]);
180
- }
181
- lastRect = start;
182
- document.addEventListener("pointermove", pointerMove);
183
- document.addEventListener("contextmenu", pointerUp);
184
- document.addEventListener("pointerup", pointerUp);
185
- };
186
- const pointerUp = () => {
187
- start = null;
188
- if (isAdditive) {
189
- const isDeselect = cellSelectionIsDeselect.current;
190
- const rects = isDeselect
191
- ? cellSelections.flatMap((r) => deselectRectRange(r, lastRect))
192
- : [...cellSelections, lastRect];
193
- onCellSelectionChange(rects);
194
- setCellSelectionAdditiveRects(null);
195
- cellSelectionIsDeselect.current = false;
196
- isAdditive = false;
197
- }
198
- cancelX();
199
- cancelY();
200
- document.removeEventListener("pointerup", pointerUp);
201
- document.removeEventListener("contextmenu", pointerUp);
202
- document.removeEventListener("pointermove", pointerMove);
203
- };
204
- viewport.addEventListener("pointerdown", pointerDown);
205
- const handleKey = (ev) => {
206
- const start = rtl ? "ArrowRight" : "ArrowLeft";
207
- const end = rtl ? "ArrowLeft" : "ArrowRight";
208
- const position = focusActive.get();
209
- // Select all
210
- if (ev.key === "a" && (ev.ctrlKey || ev.metaKey)) {
211
- if (!cellSelections.at(-1))
212
- return;
213
- const next = {
214
- columnStart: excludeMarker ? 1 : 0,
215
- columnEnd: view.visibleColumns.length,
216
- rowStart: 0,
217
- rowEnd: rowCount,
218
- };
219
- const nextSelections = [...cellSelections];
220
- nextSelections[nextSelections.length - 1] = next;
221
- onCellSelectionChange(nextSelections);
222
- ev.preventDefault();
223
- ev.stopPropagation();
224
- return;
225
- }
226
- if (!ev.shiftKey || position?.kind !== "cell")
227
- return;
228
- let handled = false;
229
- if (ev.key === "ArrowUp") {
230
- expandSelectionUp(api, cellSelections, onCellSelectionChange, ev.ctrlKey || ev.metaKey, position, rowCount);
231
- handled = true;
232
- }
233
- else if (ev.key === "ArrowDown") {
234
- expandSelectionDown(api, cellSelections, onCellSelectionChange, ev.ctrlKey || ev.metaKey, position, rowCount);
235
- handled = true;
236
- }
237
- else if (ev.key === start) {
238
- expandSelectionStart(api, cellSelections, onCellSelectionChange, ev.ctrlKey || ev.metaKey, position, excludeMarker, view);
239
- handled = true;
240
- }
241
- else if (ev.key === end) {
242
- expandSelectionEnd(api, cellSelections, onCellSelectionChange, ev.ctrlKey || ev.metaKey, position, view);
243
- handled = true;
244
- }
245
- if (handled) {
246
- ev.preventDefault();
247
- ev.stopPropagation();
248
- }
249
- };
250
- viewport.addEventListener("keydown", handleKey);
251
- return () => {
252
- viewport.removeEventListener("pointerdown", pointerDown);
253
- viewport.removeEventListener("keydown", handleKey);
254
- };
255
- }, [
256
- api,
257
- botCount,
258
- cancelX,
259
- cancelY,
260
- cellSelectionAdditiveRects,
261
- cellSelectionIsDeselect,
262
- cellSelections,
263
- edgeScrollX,
264
- edgeScrollY,
265
- excludeMarker,
266
- focusActive,
267
- id,
268
- mode,
269
- onCellSelectionChange,
270
- rowCount,
271
- rtl,
272
- setCellSelectionAdditiveRects,
273
- topCount,
274
- view,
275
- viewport,
276
- ]);
277
- useCellFocusChange(focusActive, excludeMarker, keepSelection, onCellSelectionChange, setCellSelectionAdditiveRects, api);
278
- return _jsx(_Fragment, {});
279
- }
@@ -1,5 +0,0 @@
1
- import type { PieceWritable } from "@1771technologies/lytenyte-core";
2
- import { type PositionUnion } from "@1771technologies/lytenyte-shared";
3
- import { type Dispatch, type SetStateAction } from "react";
4
- import type { API, DataRect, DataRectSplit } from "../../types";
5
- export declare function useCellFocusChange(focusActive: PieceWritable<PositionUnion | null>, excludeMarker: boolean, keepSelection: boolean, onCellSelectionChange: (c: DataRect[]) => void, setCellSelectionAdditiveRects: Dispatch<SetStateAction<DataRectSplit[] | null>>, api: API): void;
@@ -1,34 +0,0 @@
1
- import { equal } from "@1771technologies/lytenyte-shared";
2
- import { useEffect, useRef } from "react";
3
- import { dataRectFromCellPosition } from "../data-rect-from-cell-position.js";
4
- import { adjustRectForRowAndCellSpan } from "../adjust-rect-for-row-and-cell-span.js";
5
- export function useCellFocusChange(focusActive, excludeMarker, keepSelection, onCellSelectionChange, setCellSelectionAdditiveRects, api) {
6
- const focus = focusActive.useValue();
7
- const prevRef = useRef(null);
8
- useEffect(() => {
9
- if (!focus)
10
- return;
11
- const prev = prevRef.current;
12
- if (equal(prev, focus))
13
- return;
14
- prevRef.current = focus;
15
- if (focus.colIndex === 0 && excludeMarker) {
16
- return;
17
- }
18
- if (!keepSelection && focus?.kind !== "cell" && focus?.kind !== "full-width") {
19
- onCellSelectionChange([]);
20
- setCellSelectionAdditiveRects([]);
21
- }
22
- else if (focus.kind === "cell" || focus.kind === "full-width") {
23
- const rect = focus.kind === "full-width"
24
- ? {
25
- rowStart: focus.rowIndex,
26
- rowEnd: focus.rowIndex + 1,
27
- columnStart: focus.colIndex,
28
- columnEnd: focus.colIndex + 1,
29
- }
30
- : dataRectFromCellPosition(focus);
31
- onCellSelectionChange([adjustRectForRowAndCellSpan(api.cellRoot, rect)]);
32
- }
33
- }, [api, excludeMarker, focus, keepSelection, onCellSelectionChange, setCellSelectionAdditiveRects]);
34
- }
@@ -1,8 +0,0 @@
1
- import type { DataRectSplit } from "../types/grid";
2
- export declare function CellStyleRow({ rect, isRowPinnedTop, isDeselect, isRowPinnedBottom, isPivot, }: {
3
- rect: DataRectSplit;
4
- isRowPinnedTop?: boolean;
5
- isDeselect?: boolean;
6
- isRowPinnedBottom?: boolean;
7
- isPivot?: boolean;
8
- }): import("react/jsx-runtime").JSX.Element;
@@ -1,79 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useMemo } from "react";
3
- import { getTranslate, sizeFromCoord } from "@1771technologies/lytenyte-shared";
4
- import { useRoot } from "@1771technologies/lytenyte-core/internal";
5
- export function CellStyleRow({ rect, isRowPinnedTop, isDeselect, isRowPinnedBottom, isPivot, }) {
6
- const { xPositions, yPositions, rtl, view, source, dimensions } = useRoot();
7
- const startCount = view.startCount;
8
- const centerCount = view.centerCount;
9
- const rowCount = source.useRowCount();
10
- const rowTopCount = source.useTopCount();
11
- const rowBotCount = source.useBottomCount();
12
- const vpWidth = dimensions.innerWidth;
13
- const style = useMemo(() => {
14
- const columnStart = rect.columnStart;
15
- const columnEnd = rect.columnEnd;
16
- const isStart = columnStart < startCount;
17
- const isEnd = columnStart >= startCount + centerCount;
18
- const isTop = isRowPinnedTop;
19
- const isBot = isRowPinnedBottom;
20
- const columnIndex = columnStart;
21
- const rowIndex = rect.rowStart;
22
- const width = sizeFromCoord(columnStart, xPositions, columnEnd - columnStart);
23
- const height = sizeFromCoord(rect.rowStart, yPositions, rect.rowEnd - rect.rowStart);
24
- const firstBotIndex = rowCount - rowBotCount;
25
- const x = isEnd ? xPositions[columnIndex] - xPositions.at(-1) + vpWidth : xPositions[columnIndex];
26
- let y;
27
- if (isBot)
28
- y = yPositions[rowIndex] - yPositions[firstBotIndex];
29
- else if (isTop)
30
- y = yPositions[rowIndex];
31
- else {
32
- y = `calc(${yPositions[rowIndex] - yPositions[rowTopCount]}px - var(--ln-y-offset, 0px))`;
33
- }
34
- const transform = getTranslate(x * (rtl ? -1 : 1), y);
35
- const pinnedRow = isTop || isBot;
36
- const pinnedCell = isStart || isEnd;
37
- const style = {
38
- height: height - 1, // Minus 1 because the bottom border is not included in cell heights.
39
- width,
40
- transform,
41
- position: "absolute",
42
- pointerEvents: "none",
43
- top: 0,
44
- zIndex: 1,
45
- gridRowStart: "1",
46
- gridRowEnd: "2",
47
- gridColumnStart: "1",
48
- gridColumnEnd: "2",
49
- };
50
- if (pinnedCell) {
51
- style.insetInlineStart = "0px";
52
- style.position = "sticky";
53
- style.zIndex = pinnedRow ? 6 : 3;
54
- }
55
- if (pinnedRow) {
56
- style.position = "sticky";
57
- style.top = "0px";
58
- style.zIndex = pinnedCell ? 6 : 3;
59
- }
60
- return style;
61
- }, [
62
- rect.columnStart,
63
- rect.columnEnd,
64
- rect.rowStart,
65
- rect.rowEnd,
66
- startCount,
67
- centerCount,
68
- isRowPinnedTop,
69
- isRowPinnedBottom,
70
- rowCount,
71
- rowBotCount,
72
- xPositions,
73
- vpWidth,
74
- yPositions,
75
- rowTopCount,
76
- rtl,
77
- ]);
78
- return (_jsx("div", { style: style, "data-ln-cell-selection-rect": true, "data-ln-cell-selection-is-deselect": isDeselect, "data-ln-cell-selection-is-pivot": isPivot, "data-ln-cell-selection-border-top": rect.borderTop, "data-ln-cell-selection-border-bottom": rect.borderBottom, "data-ln-cell-selection-border-start": rect.borderStart, "data-ln-cell-selection-border-end": rect.borderEnd }));
79
- }
@@ -1,3 +0,0 @@
1
- import type { PositionGridCell } from "@1771technologies/lytenyte-shared";
2
- import type { DataRect } from "../types";
3
- export declare function dataRectFromCellPosition(position: PositionGridCell): DataRect;