@kermodes/grid 0.0.0-stage → 0.3.13-dev.68.g32b767a
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.
- package/dist/ColumnHeaderGroup.d.ts +8 -0
- package/dist/ContextMenu.d.ts +15 -0
- package/dist/EventHandlerResult.d.ts +16 -0
- package/dist/FilterBar.d.ts +32 -0
- package/dist/Grid.d.ts +458 -0
- package/dist/GridAxisRange.d.ts +9 -0
- package/dist/GridMetricCalculator.d.ts +509 -0
- package/dist/GridMetrics.d.ts +125 -0
- package/dist/GridModel.d.ts +96 -0
- package/dist/GridMouseHandler.d.ts +29 -0
- package/dist/GridRange.d.ts +268 -0
- package/dist/GridRenderer.d.ts +159 -0
- package/dist/GridRendererTypes.d.ts +25 -0
- package/dist/GridSelectionUtils.d.ts +97 -0
- package/dist/GridStyles.d.ts +2 -0
- package/dist/GridTheme.d.ts +96 -0
- package/dist/GridUtils.d.ts +457 -0
- package/dist/KeyHandler.d.ts +33 -0
- package/dist/RangedSelection.d.ts +118 -0
- package/dist/Selection.d.ts +218 -0
- package/dist/TableViewer.d.ts +16 -0
- package/dist/TableViewerGrid.d.ts +16 -0
- package/dist/TextCellRenderer.d.ts +8 -0
- package/dist/ThemeContext.d.ts +5 -0
- package/dist/ValuePopover.d.ts +23 -0
- package/dist/ViewportGridModel.d.ts +92 -0
- package/dist/cellValue.d.ts +11 -0
- package/dist/copy.d.ts +29 -0
- package/dist/cover.d.ts +16 -0
- package/dist/errors/AssertionError.d.ts +4 -0
- package/dist/errors/assertIsDefined.d.ts +2 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/fastMemoize.d.ts +50 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +7909 -0
- package/dist/key-handlers/SelectionKeyHandler.d.ts +11 -0
- package/dist/key-handlers/index.d.ts +1 -0
- package/dist/menuItems.d.ts +53 -0
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.d.ts +50 -0
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.d.ts +27 -0
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.d.ts +24 -0
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.d.ts +14 -0
- package/dist/mouse-handlers/GridSelectionMouseHandler.d.ts +19 -0
- package/dist/mouse-handlers/GridSeparatorMouseHandler.d.ts +61 -0
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.d.ts +24 -0
- package/dist/mouse-handlers/index.d.ts +8 -0
- package/dist/sorting.d.ts +19 -0
- package/dist/utils.d.ts +15 -0
- package/package.json +28 -3
- package/README.md +0 -3
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { IColumnHeaderGroup } from './ColumnHeaderGroup';
|
|
2
|
+
import { type ModelIndex } from './GridMetrics';
|
|
3
|
+
import { type GridColor, type GridTheme, type NullableGridColor } from './GridTheme';
|
|
4
|
+
/**
|
|
5
|
+
* Model for a Grid
|
|
6
|
+
* All of these methods should return very quickly, as they will be called many times in the render cycle.
|
|
7
|
+
* If data needs to be loaded asynchronously, return something immediately, then redraw the grid when it arrives.
|
|
8
|
+
*/
|
|
9
|
+
declare abstract class GridModel {
|
|
10
|
+
/** Count of rows in the grid */
|
|
11
|
+
abstract get rowCount(): number;
|
|
12
|
+
/** Count of columns in the grid */
|
|
13
|
+
abstract get columnCount(): number;
|
|
14
|
+
/** Count of rows that are frozen (or 'floating') at the top */
|
|
15
|
+
get floatingTopRowCount(): number;
|
|
16
|
+
/** Count of rows that are frozen at the bottom */
|
|
17
|
+
get floatingBottomRowCount(): number;
|
|
18
|
+
/** Count of columns that are frozen (or 'floating') at the left */
|
|
19
|
+
get floatingLeftColumnCount(): number;
|
|
20
|
+
/** Count of columns that are frozen (or 'floating') at the right */
|
|
21
|
+
get floatingRightColumnCount(): number;
|
|
22
|
+
/**
|
|
23
|
+
* How many columns header levels are in the grid
|
|
24
|
+
* Used for column grouping where columns at depth 0 are the base columns
|
|
25
|
+
*
|
|
26
|
+
* A grid with 1-level grouping would have a columnHeaderDepth of 2
|
|
27
|
+
* and column headers at depths 0 and 1
|
|
28
|
+
*/
|
|
29
|
+
get columnHeaderMaxDepth(): number;
|
|
30
|
+
/**
|
|
31
|
+
* Get the text for the specified cell
|
|
32
|
+
* @param column Column to get the text for
|
|
33
|
+
* @param row Row to get the text for
|
|
34
|
+
* @returns Text for the specified cell
|
|
35
|
+
*/
|
|
36
|
+
abstract textForCell(column: ModelIndex, row: ModelIndex): string;
|
|
37
|
+
/**
|
|
38
|
+
* Get the character to replace text when truncated for a specific cell.
|
|
39
|
+
* Leave undefined to show text truncated with ellipsis
|
|
40
|
+
* @param column Column to get the truncation character for
|
|
41
|
+
* @param row Row to get the truncation character for
|
|
42
|
+
* @returns Truncation character for the specified cell
|
|
43
|
+
*/
|
|
44
|
+
truncationCharForCell(column: ModelIndex, row: ModelIndex): string | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Get the text alignment for the specified cell
|
|
47
|
+
* @param column Column to get the alignment for
|
|
48
|
+
* @param row Row to get the alignment for
|
|
49
|
+
* @returns Text alignment for the specified cell
|
|
50
|
+
*/
|
|
51
|
+
textAlignForCell(column: ModelIndex, row: ModelIndex): CanvasTextAlign;
|
|
52
|
+
/**
|
|
53
|
+
* Get the color for the text in the specified cell
|
|
54
|
+
* @param column Column to get the color for
|
|
55
|
+
* @param row Row to get the color for
|
|
56
|
+
* @param theme Theme applied to the grid
|
|
57
|
+
* @returns Color for the text in the cell
|
|
58
|
+
*/
|
|
59
|
+
colorForCell(column: ModelIndex, row: ModelIndex, theme: GridTheme): GridColor;
|
|
60
|
+
/**
|
|
61
|
+
* Get the background color for the cell
|
|
62
|
+
* @param column Column to get the background color for
|
|
63
|
+
* @param row Row to get the background color for
|
|
64
|
+
* @param theme Theme applied to the grid
|
|
65
|
+
* @returns Background color for the cell
|
|
66
|
+
*/
|
|
67
|
+
backgroundColorForCell(column: ModelIndex, row: ModelIndex, theme: GridTheme): NullableGridColor;
|
|
68
|
+
/**
|
|
69
|
+
* Text for the column header
|
|
70
|
+
* @param column Column to get the header for
|
|
71
|
+
* @param depth Depth to get the header text for. 0 is base columns
|
|
72
|
+
* @returns Text to put in the column header
|
|
73
|
+
*/
|
|
74
|
+
abstract textForColumnHeader(column: ModelIndex, depth?: number): string | undefined;
|
|
75
|
+
/** Color for column header
|
|
76
|
+
* @param column Column to get the color for
|
|
77
|
+
* @param depth Header depth to get the color for
|
|
78
|
+
* @returns Color for the header at the depth or null
|
|
79
|
+
*/
|
|
80
|
+
colorForColumnHeader(column: ModelIndex, depth?: number): string | null;
|
|
81
|
+
/**
|
|
82
|
+
* Text for the row header
|
|
83
|
+
* @param row Row to get the header for
|
|
84
|
+
* @returns Text to put in the row header
|
|
85
|
+
*/
|
|
86
|
+
textForRowHeader(row: ModelIndex): string;
|
|
87
|
+
/**
|
|
88
|
+
* Text for the row footer
|
|
89
|
+
* @param row Row to get the footer for
|
|
90
|
+
* @returns Text to put in the row footer
|
|
91
|
+
*/
|
|
92
|
+
textForRowFooter(row: ModelIndex): string;
|
|
93
|
+
getColumnHeaderGroup(modelIndex: ModelIndex, depth: number): IColumnHeaderGroup | undefined;
|
|
94
|
+
getColumnHeaderParentGroup(modelIndex: ModelIndex, depth: number): IColumnHeaderGroup | undefined;
|
|
95
|
+
}
|
|
96
|
+
export default GridModel;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type EventHandlerResult } from './EventHandlerResult';
|
|
2
|
+
import type Grid from './Grid';
|
|
3
|
+
import { type GridPoint } from './GridUtils';
|
|
4
|
+
/**
|
|
5
|
+
* Some events we listen to are a native mouse event, and others are wrapped with React's SyntheticEvent.
|
|
6
|
+
* The GridMouseHandler shouldn't care though - the properties it accesses should be common on both types of events.
|
|
7
|
+
*/
|
|
8
|
+
export type GridMouseEvent = MouseEvent | React.MouseEvent;
|
|
9
|
+
export type GridWheelEvent = WheelEvent | React.WheelEvent;
|
|
10
|
+
export type GridMouseHandlerFunctionName = 'onDown' | 'onMove' | 'onDrag' | 'onLeave' | 'onClick' | 'onContextMenu' | 'onDoubleClick' | 'onUp' | 'onWheel';
|
|
11
|
+
/**
|
|
12
|
+
* Define a region in the grid that interacts with the mouse on a grid.
|
|
13
|
+
* Return true from any of the events to indicate they're consumed, and stopPropagation/preventDefault will be called.
|
|
14
|
+
*/
|
|
15
|
+
export declare class GridMouseHandler {
|
|
16
|
+
order: number;
|
|
17
|
+
constructor(order?: number);
|
|
18
|
+
cursor: string | null;
|
|
19
|
+
onDown(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
20
|
+
onMove(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
21
|
+
onDrag(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
22
|
+
onLeave(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
23
|
+
onClick(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
24
|
+
onContextMenu(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
25
|
+
onDoubleClick(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
26
|
+
onUp(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
27
|
+
onWheel(gridPoint: GridPoint, grid: Grid, event: GridMouseEvent): EventHandlerResult;
|
|
28
|
+
}
|
|
29
|
+
export default GridMouseHandler;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
export type GridRangeIndex = number | null;
|
|
2
|
+
export type RequiredGridRangeIndex = number;
|
|
3
|
+
type LeftIndex = GridRangeIndex;
|
|
4
|
+
type RightIndex = GridRangeIndex;
|
|
5
|
+
type TopIndex = GridRangeIndex;
|
|
6
|
+
type BottomIndex = GridRangeIndex;
|
|
7
|
+
export type GridCell = {
|
|
8
|
+
column: RequiredGridRangeIndex;
|
|
9
|
+
row: RequiredGridRangeIndex;
|
|
10
|
+
};
|
|
11
|
+
export interface BoundedGridRange extends GridRange {
|
|
12
|
+
startColumn: RequiredGridRangeIndex;
|
|
13
|
+
startRow: RequiredGridRangeIndex;
|
|
14
|
+
endColumn: RequiredGridRangeIndex;
|
|
15
|
+
endRow: RequiredGridRangeIndex;
|
|
16
|
+
}
|
|
17
|
+
export declare enum SELECTION_DIRECTION {
|
|
18
|
+
DOWN = "DOWN",
|
|
19
|
+
UP = "UP",
|
|
20
|
+
LEFT = "LEFT",
|
|
21
|
+
RIGHT = "RIGHT"
|
|
22
|
+
}
|
|
23
|
+
export declare class GridRange {
|
|
24
|
+
startColumn: GridRangeIndex;
|
|
25
|
+
startRow: GridRangeIndex;
|
|
26
|
+
endColumn: GridRangeIndex;
|
|
27
|
+
endRow: GridRangeIndex;
|
|
28
|
+
static SELECTION_DIRECTION: typeof SELECTION_DIRECTION;
|
|
29
|
+
/**
|
|
30
|
+
* Returns a normalized array of indexes ensuring left <= right and top <= bottom
|
|
31
|
+
* @param startColumn Start column index
|
|
32
|
+
* @param startRow Start row index
|
|
33
|
+
* @param endColumn End column index
|
|
34
|
+
* @param endRow End row index
|
|
35
|
+
* @returns Array containing normalized indexes [left, top, right, bottom]
|
|
36
|
+
*/
|
|
37
|
+
static normalize(startColumn: GridRangeIndex, startRow: GridRangeIndex, endColumn: GridRangeIndex, endRow: GridRangeIndex): [LeftIndex, TopIndex, RightIndex, BottomIndex];
|
|
38
|
+
/**
|
|
39
|
+
* Makes a GridRange ensuring startColumn <= endColumn, startRow <= endRow
|
|
40
|
+
* @param startColumn Start column index
|
|
41
|
+
* @param startRow Start row index
|
|
42
|
+
* @param endColumn End column index
|
|
43
|
+
* @param endRow End row index
|
|
44
|
+
* @returns Normalized GridRange
|
|
45
|
+
*/
|
|
46
|
+
static makeNormalized(startColumn: GridRangeIndex, startRow: GridRangeIndex, endColumn: GridRangeIndex, endRow: GridRangeIndex): GridRange;
|
|
47
|
+
/**
|
|
48
|
+
* Creates a GridRange representing a single cell
|
|
49
|
+
* @param column Column index
|
|
50
|
+
* @param row Row index
|
|
51
|
+
* @returns GridRange representing the cell
|
|
52
|
+
*/
|
|
53
|
+
static makeCell(column: GridRangeIndex, row: GridRangeIndex): GridRange;
|
|
54
|
+
/**
|
|
55
|
+
* Creates a GridRange representing an infinite length column
|
|
56
|
+
* @param column Column index
|
|
57
|
+
* @returns GridRange representing the column
|
|
58
|
+
*/
|
|
59
|
+
static makeColumn(column: GridRangeIndex): GridRange;
|
|
60
|
+
/**
|
|
61
|
+
* Creates a GridRange representing an infinite length row
|
|
62
|
+
* @param row Row index
|
|
63
|
+
* @returns GridRange representing the row
|
|
64
|
+
*/
|
|
65
|
+
static makeRow(row: GridRangeIndex): GridRange;
|
|
66
|
+
/**
|
|
67
|
+
* Returns the minimum value between 2 range indexes or null if at least 1 is null
|
|
68
|
+
* @param index1 First grid range index
|
|
69
|
+
* @param index2 Second grid range index
|
|
70
|
+
* @returns Minimum index or null if either index is null
|
|
71
|
+
*/
|
|
72
|
+
static minOrNull(index1: GridRangeIndex, index2: GridRangeIndex): number | null;
|
|
73
|
+
/**
|
|
74
|
+
* Returns the maximum value between 2 range indexes or null if at least 1 is null
|
|
75
|
+
* @param index1 First grid range index
|
|
76
|
+
* @param index2 Second grid range index
|
|
77
|
+
* @returns Maximum index or null if either index is null
|
|
78
|
+
*/
|
|
79
|
+
static maxOrNull(index1: GridRangeIndex, index2: GridRangeIndex): number | null;
|
|
80
|
+
/**
|
|
81
|
+
* Consolidate the passed in ranges to the minimum set, merging overlapping ranges.
|
|
82
|
+
* @param ranges The ranges to consolidate
|
|
83
|
+
* @returns Consolidated ranges
|
|
84
|
+
*/
|
|
85
|
+
static consolidate(ranges: readonly GridRange[]): GridRange[];
|
|
86
|
+
/**
|
|
87
|
+
* Checks if the 1-D ranges between 2 index pairs overlap or are continuous.
|
|
88
|
+
* For example ranges [0, 1] and [2, 3] are continuous and will return true.
|
|
89
|
+
* [0, 1] and [1, 3] overlap and return true.
|
|
90
|
+
* [0, 1] and [3, 4] do not overlap and have a gap so this will return false.
|
|
91
|
+
* @param start1 Start of 1st range
|
|
92
|
+
* @param end1 End of 1st range
|
|
93
|
+
* @param start2 Start of 2nd range
|
|
94
|
+
* @param end2 End of 2nd range
|
|
95
|
+
* @returns True if the ranges overlap or touch, else false
|
|
96
|
+
*/
|
|
97
|
+
static isAxisRangeTouching(start1: GridRangeIndex, end1: GridRangeIndex, start2: GridRangeIndex, end2: GridRangeIndex): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Checks if 2 arrays of ranges are the same ranges
|
|
100
|
+
* @param ranges1 First array of ranges
|
|
101
|
+
* @param ranges2 Second array of ranges
|
|
102
|
+
* @returns True if the arrays contain the same ranges in the same order
|
|
103
|
+
*/
|
|
104
|
+
static rangeArraysEqual(ranges1: readonly GridRange[], ranges2: readonly GridRange[]): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Get the intersection (overlapping area) of two ranges
|
|
107
|
+
* @param range One range to check for the intersection
|
|
108
|
+
* @param otherRange The other range to check for the intersection
|
|
109
|
+
* @returns Intersection of the two ranges. If they do not intersect, returns `null`.
|
|
110
|
+
*/
|
|
111
|
+
static intersection(range: GridRange, otherRange: GridRange): GridRange | null;
|
|
112
|
+
/**
|
|
113
|
+
* Subtracts 1 range from another
|
|
114
|
+
* @param range The range to be subtracted from
|
|
115
|
+
* @param subtractRange The range to subtract from within this range
|
|
116
|
+
* @returns The ranges needed to represent the remaining
|
|
117
|
+
*/
|
|
118
|
+
static subtractFromRange(range: GridRange, subtractRange: GridRange): GridRange[];
|
|
119
|
+
/**
|
|
120
|
+
* Subtract a range from multiple ranges
|
|
121
|
+
* @param ranges The ranges to be subtracted from
|
|
122
|
+
* @param subtractRange The range to subtract from within these ranges
|
|
123
|
+
* @returns The ranges needed to represent the remaining
|
|
124
|
+
*/
|
|
125
|
+
static subtractFromRanges(ranges: readonly GridRange[], subtractRange: GridRange): GridRange[];
|
|
126
|
+
/**
|
|
127
|
+
* Subtract multiple ranges from multiple ranges
|
|
128
|
+
* @param ranges The ranges to be subtracted from
|
|
129
|
+
* @param subtractRanges The ranges to subtract from within these ranges
|
|
130
|
+
* @returns The ranges needed to represent the remaining
|
|
131
|
+
*/
|
|
132
|
+
static subtractRangesFromRanges(ranges: readonly GridRange[], subtractRanges: readonly GridRange[]): GridRange[];
|
|
133
|
+
/**
|
|
134
|
+
* Test if a given range is bounded (all values are non-null)
|
|
135
|
+
* @param range The range to test
|
|
136
|
+
* @returns True if this range is bounded, false otherwise
|
|
137
|
+
*/
|
|
138
|
+
static isBounded(range: GridRange): range is BoundedGridRange;
|
|
139
|
+
/**
|
|
140
|
+
* Converts any GridRange passed in that is a full row or column selection to be bound
|
|
141
|
+
* to the `columnCount` and `rowCount` passed in
|
|
142
|
+
*
|
|
143
|
+
* @param range The range to get the bounded range of
|
|
144
|
+
* @param columnCount The number of columns
|
|
145
|
+
* @param rowCount The number of rows
|
|
146
|
+
* @returns The passed in GridRange with any null values filled in
|
|
147
|
+
*/
|
|
148
|
+
static boundedRange(range: GridRange, columnCount: number, rowCount: number): BoundedGridRange;
|
|
149
|
+
/**
|
|
150
|
+
* Converts the GridRanges passed in to be bound to the `columnCount` and `rowCount` passed in
|
|
151
|
+
*
|
|
152
|
+
* @param ranges The ranges to get the bounded ranges of
|
|
153
|
+
* @param columnCount The number of columns
|
|
154
|
+
* @param rowCount The number of rows
|
|
155
|
+
* @returns The passed in GridRange with any null values filled in
|
|
156
|
+
*/
|
|
157
|
+
static boundedRanges(ranges: readonly GridRange[], columnCount: number, rowCount: number): BoundedGridRange[];
|
|
158
|
+
/**
|
|
159
|
+
* Offsets a GridRange by the specified amount in the x and y directions
|
|
160
|
+
*
|
|
161
|
+
* @param range The range to offset
|
|
162
|
+
* @param columnOffset The number of columns to offset
|
|
163
|
+
* @param rowOffset The number of rows to offset
|
|
164
|
+
* @returns The new grid range offset from the original
|
|
165
|
+
*/
|
|
166
|
+
static offset(range: GridRange, columnOffset: number, rowOffset: number): GridRange;
|
|
167
|
+
/**
|
|
168
|
+
* Get the next cell given the selected ranges and the current cell
|
|
169
|
+
* @param ranges The selected bounded ranges within the grid
|
|
170
|
+
* @param column The cursor column, or null if none focused
|
|
171
|
+
* @param row The cursor row, or null if none focused
|
|
172
|
+
* @param direction The direction in which to select next
|
|
173
|
+
* @returns The next cell to focus, or null if there should be no more focus
|
|
174
|
+
*/
|
|
175
|
+
static nextCell(ranges: readonly GridRange[], column?: GridRangeIndex, row?: GridRangeIndex, direction?: SELECTION_DIRECTION): GridCell | null;
|
|
176
|
+
/**
|
|
177
|
+
* Count the number of cells in the provided grid ranges
|
|
178
|
+
* @param ranges The ranges to count the rows of
|
|
179
|
+
* @returns The number of cells in the ranges, or `NaN` if any of the ranges were unbounded
|
|
180
|
+
*/
|
|
181
|
+
static cellCount(ranges: readonly GridRange[]): number;
|
|
182
|
+
/**
|
|
183
|
+
* Count the number of rows in the provided grid ranges
|
|
184
|
+
* @param ranges The ranges to count the rows of
|
|
185
|
+
* @returns The number of rows in the ranges, or `NaN` if any of the ranges were unbounded
|
|
186
|
+
*/
|
|
187
|
+
static rowCount(ranges: readonly GridRange[]): number;
|
|
188
|
+
/**
|
|
189
|
+
* Count the number of columns in the provided grid ranges
|
|
190
|
+
* @param ranges The ranges to count the columns of
|
|
191
|
+
* @returns The number of columns in the ranges, or `NaN` if any of the ranges were unbounded
|
|
192
|
+
*/
|
|
193
|
+
static columnCount(ranges: readonly GridRange[]): number;
|
|
194
|
+
/**
|
|
195
|
+
* Check if the provided ranges contain the provided cell
|
|
196
|
+
* @param ranges The ranges to check
|
|
197
|
+
* @param column The column index
|
|
198
|
+
* @param row The row index
|
|
199
|
+
* @returns True if the cell is within the provided ranges, false otherwise.
|
|
200
|
+
*/
|
|
201
|
+
static containsCell(ranges: readonly GridRange[], column: GridRangeIndex, row: GridRangeIndex): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Iterate through each cell in the provided ranges
|
|
204
|
+
* @param ranges The ranges to iterate through
|
|
205
|
+
* @param callback The callback to execute. `index` is the index within that range
|
|
206
|
+
* @param direction The direction to iterate in
|
|
207
|
+
*/
|
|
208
|
+
static forEachCell(ranges: readonly GridRange[], callback: (column: number, row: number, index: number) => void, direction?: SELECTION_DIRECTION): void;
|
|
209
|
+
constructor(startColumn: GridRangeIndex, startRow: GridRangeIndex, endColumn: GridRangeIndex, endRow: GridRangeIndex);
|
|
210
|
+
/**
|
|
211
|
+
* Checks if the provided range is equivalent to this range (same start and end column/row indexes)
|
|
212
|
+
* @param other Grid range to check against
|
|
213
|
+
* @returns True if the ranges cover the same area
|
|
214
|
+
*/
|
|
215
|
+
equals(other: GridRange): boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Checks if this GridRange contains another range
|
|
218
|
+
* @param other The range to check
|
|
219
|
+
* @returns True if this GridRange completely contains `other`
|
|
220
|
+
* */
|
|
221
|
+
contains(other: GridRange): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Check if the provided cell is in this range
|
|
224
|
+
* @param column The column to check
|
|
225
|
+
* @param row The row to check
|
|
226
|
+
* @returns True if this cell is within this range
|
|
227
|
+
*/
|
|
228
|
+
containsCell(column: GridRangeIndex, row: GridRangeIndex): boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Check if the provided range touches (or overlaps) this GridRange
|
|
231
|
+
* Effectively checks if the 2 ranges could be represented by 1 continuous range
|
|
232
|
+
* @param other The range to check
|
|
233
|
+
* @returns True if this GridRange touches `other`
|
|
234
|
+
* */
|
|
235
|
+
touches(other: GridRange): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Subtracts a range from this range
|
|
238
|
+
* @param other The range to deselect from within this range
|
|
239
|
+
* @returns The ranges needed to represent the remaining
|
|
240
|
+
*/
|
|
241
|
+
subtract(other: GridRange): GridRange[];
|
|
242
|
+
/**
|
|
243
|
+
* Get the first cell in this range. Throws if this range is unbounded.
|
|
244
|
+
*
|
|
245
|
+
* @param direction The direction to get the starting cell in. Defaults to DOWN
|
|
246
|
+
* @returns The first cell in this range in the direction specified
|
|
247
|
+
*/
|
|
248
|
+
startCell(direction?: SELECTION_DIRECTION): GridCell;
|
|
249
|
+
/**
|
|
250
|
+
* Get the next cell in the direction specified. Throws if this range is unbounded.
|
|
251
|
+
* If already at the bounds of the range in that direction, wrap to the next column or row
|
|
252
|
+
* If at the end of the entire range, return null
|
|
253
|
+
* If outside of the range, returns the next cell closest within this range.
|
|
254
|
+
*
|
|
255
|
+
* @param column The cursor column
|
|
256
|
+
* @param row The cursor row
|
|
257
|
+
* @param direction The direction to go in
|
|
258
|
+
* @returns The next cell in the direction specified, or `null` if at the end of the range
|
|
259
|
+
*/
|
|
260
|
+
nextCell(column: GridRangeIndex, row: GridRangeIndex, direction: SELECTION_DIRECTION): GridCell | null;
|
|
261
|
+
/**
|
|
262
|
+
* Iterate through each cell in the range
|
|
263
|
+
* @param callback Callback to execute. `index` is the index within this range
|
|
264
|
+
* @param direction The direction to iterate in
|
|
265
|
+
*/
|
|
266
|
+
forEach(callback: (column: number, row: number, index: number) => void, direction?: SELECTION_DIRECTION): void;
|
|
267
|
+
}
|
|
268
|
+
export default GridRange;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { type GridColorWay, type NullableGridColor } from './GridTheme';
|
|
2
|
+
import { type Coordinate, type VisibleIndex } from './GridMetrics';
|
|
3
|
+
import { type BoundedAxisRange } from './GridAxisRange';
|
|
4
|
+
import { type GridRenderState } from './GridRendererTypes';
|
|
5
|
+
import TextCellRenderer from './TextCellRenderer';
|
|
6
|
+
/**
|
|
7
|
+
* A GridRenderer handles rendering the different parts of the grid
|
|
8
|
+
* This default rendering just renders a basic grid. Extend this class and implement
|
|
9
|
+
* your own methods to customize drawing of the grid (eg. Draw icons or special features)
|
|
10
|
+
*/
|
|
11
|
+
export declare class GridRenderer {
|
|
12
|
+
static DEFAULT_EDGE_RADIUS: number;
|
|
13
|
+
protected textCellRenderer: TextCellRenderer;
|
|
14
|
+
/**
|
|
15
|
+
* Truncate a string to the specified length and add ellipses if necessary
|
|
16
|
+
* @param str The string to truncate
|
|
17
|
+
* @param len The length to truncate the string to. If longer than the actual string, just returns the string
|
|
18
|
+
* @returns The truncated string
|
|
19
|
+
*/
|
|
20
|
+
static truncate(str: string, len: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Uses binary search to truncate a string to fit in the provided width
|
|
23
|
+
* @param context The drawing context to measure the text in
|
|
24
|
+
* @param str The string to get the maximum length it can draw
|
|
25
|
+
* @param width The width to truncate it to
|
|
26
|
+
* @param start The low boundary to start the search
|
|
27
|
+
* @param end The high boundary to start the search
|
|
28
|
+
* @param truncationChar This char will be repeated as the display string if the string is truncated instead of just adding an ellipsis
|
|
29
|
+
* @returns The truncated string
|
|
30
|
+
*/
|
|
31
|
+
static binaryTruncateToWidth(context: CanvasRenderingContext2D, str: string, width: number, start?: number, end?: number, truncationChar?: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* The most characters of a string that can be drawn within a width, based on
|
|
34
|
+
* the estimated width of the narrowest character. `truncateToWidth` never
|
|
35
|
+
* reads past this many characters.
|
|
36
|
+
* @param width The width to truncate within
|
|
37
|
+
* @param fontWidthLower The estimated width of the narrowest character
|
|
38
|
+
* @returns The maximum number of characters that can fit
|
|
39
|
+
*/
|
|
40
|
+
static getMaxTruncatedLength(width: number, fontWidthLower?: number): number;
|
|
41
|
+
/**
|
|
42
|
+
* Truncate a string (if necessary) to fit in the specified width.
|
|
43
|
+
* First uses the estimated font width to calculate a lower/upper bound
|
|
44
|
+
* Then uses binary search within those bounds to find the exact max length
|
|
45
|
+
* @param context The drawing context
|
|
46
|
+
* @param str The string to calculate max length for
|
|
47
|
+
* @param width The width to truncate within
|
|
48
|
+
* @param fontWidth The estimated width of each character
|
|
49
|
+
* @param truncationChar This char will be repeated as the display string if the string is truncated instead of just adding an ellipsis
|
|
50
|
+
* @returns The truncated string that fits within the width provided
|
|
51
|
+
*/
|
|
52
|
+
static truncateToWidth(context: CanvasRenderingContext2D, str: string, width: number, fontWidthLower?: number, fontWidthUpper?: number, truncationChar?: string): string;
|
|
53
|
+
/** Split a space separated list of row background colors, cached for the last value */
|
|
54
|
+
static getCachedBackgroundColors: import("memoize-one").MemoizedFn<(backgroundColors: GridColorWay) => string[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Draw the grid canvas with the state provided
|
|
57
|
+
* @param state The state of the grid
|
|
58
|
+
*/
|
|
59
|
+
drawCanvas(state: GridRenderState): void;
|
|
60
|
+
configureContext(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
61
|
+
drawBackground(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
62
|
+
drawGrid(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
63
|
+
drawFloatingRows(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
64
|
+
drawFloatingColumns(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
65
|
+
drawFloatingBorders(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
66
|
+
drawGridBackground(context: CanvasRenderingContext2D, state: GridRenderState, drawHover?: boolean): void;
|
|
67
|
+
drawRowStripes(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
68
|
+
drawRowStripesForRows(context: CanvasRenderingContext2D, state: GridRenderState, rows: readonly VisibleIndex[], rowBackgroundColors: GridColorWay, minX?: number, maxX?: number): void;
|
|
69
|
+
drawMouseColumnHover(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
70
|
+
drawMouseRowHover(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
71
|
+
drawFloatingMouseRowHover(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
72
|
+
/** Tints the whole row of the cursor cell, so a clicked cell's row stands out */
|
|
73
|
+
drawCursorRow(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
74
|
+
drawMouseRowHoverForRow(context: CanvasRenderingContext2D, state: GridRenderState, row: VisibleIndex): void;
|
|
75
|
+
drawGridLines(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
76
|
+
drawGridLinesForItems(context: CanvasRenderingContext2D, state: GridRenderState, columns: readonly VisibleIndex[], rows: readonly VisibleIndex[], columnColor: NullableGridColor, rowColor: NullableGridColor): void;
|
|
77
|
+
drawGridLinesForColumns(context: CanvasRenderingContext2D, state: GridRenderState, columns: readonly VisibleIndex[]): void;
|
|
78
|
+
drawGridLinesForRows(context: CanvasRenderingContext2D, state: GridRenderState, rows: readonly VisibleIndex[]): void;
|
|
79
|
+
drawCellBackgrounds(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
80
|
+
drawCellBackgroundsForItems(context: CanvasRenderingContext2D, state: GridRenderState, columns: readonly VisibleIndex[], rows: readonly VisibleIndex[]): void;
|
|
81
|
+
drawCellBackground(context: CanvasRenderingContext2D, state: GridRenderState, column: VisibleIndex, row: VisibleIndex): void;
|
|
82
|
+
drawCellContents(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
83
|
+
drawColumnCellContents(context: CanvasRenderingContext2D, state: GridRenderState, column: VisibleIndex): void;
|
|
84
|
+
drawCellContent(context: CanvasRenderingContext2D, state: GridRenderState, column: VisibleIndex, row: VisibleIndex): void;
|
|
85
|
+
drawHeaders(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
86
|
+
/**
|
|
87
|
+
* The row between the headers and the cells that holds the filter inputs: a header-coloured
|
|
88
|
+
* band divided like the columns below it, so each input reads as a cell of the grid.
|
|
89
|
+
*/
|
|
90
|
+
drawFilterBar(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
91
|
+
drawFooters(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
92
|
+
drawColumnHeaders(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
93
|
+
drawColumnHeadersForRange(context: CanvasRenderingContext2D, state: GridRenderState, range: BoundedAxisRange, bounds: {
|
|
94
|
+
minX: number;
|
|
95
|
+
maxX: number;
|
|
96
|
+
}): void;
|
|
97
|
+
drawColumnHeadersAtDepth(context: CanvasRenderingContext2D, state: GridRenderState, range: BoundedAxisRange, bounds: {
|
|
98
|
+
minX: number;
|
|
99
|
+
maxX: number;
|
|
100
|
+
}, depth: number): void;
|
|
101
|
+
/**
|
|
102
|
+
* Draws the column header for the given visible index
|
|
103
|
+
* @param context Canvas context
|
|
104
|
+
* @param state Grid render state
|
|
105
|
+
* @param index Visible index of the column header to draw
|
|
106
|
+
* @param bounds The horizontal bounds the header can be drawn in
|
|
107
|
+
*/
|
|
108
|
+
drawColumnHeaderAtIndex(context: CanvasRenderingContext2D, state: GridRenderState, index: VisibleIndex, bounds: {
|
|
109
|
+
minX: number;
|
|
110
|
+
maxX: number;
|
|
111
|
+
}): void;
|
|
112
|
+
drawColumnHeader(context: CanvasRenderingContext2D, state: GridRenderState, columnText: string, columnX: Coordinate, columnWidth: number, style?: {
|
|
113
|
+
backgroundColor?: string;
|
|
114
|
+
textColor?: string;
|
|
115
|
+
separatorColor?: string;
|
|
116
|
+
textInsetRight?: number;
|
|
117
|
+
}, bounds?: {
|
|
118
|
+
minX?: number;
|
|
119
|
+
maxX?: number;
|
|
120
|
+
}): void;
|
|
121
|
+
drawRowHeaders(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
122
|
+
drawRowHeader(context: CanvasRenderingContext2D, state: GridRenderState, row: VisibleIndex, rowY: Coordinate, rowHeight: number): void;
|
|
123
|
+
drawRowFooters(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
124
|
+
drawSelectedRanges(context: CanvasRenderingContext2D, state: GridRenderState, viewport?: {
|
|
125
|
+
left?: VisibleIndex;
|
|
126
|
+
top?: VisibleIndex;
|
|
127
|
+
right?: VisibleIndex;
|
|
128
|
+
bottom?: VisibleIndex;
|
|
129
|
+
minX?: Coordinate;
|
|
130
|
+
minY?: Coordinate;
|
|
131
|
+
maxX?: Coordinate;
|
|
132
|
+
maxY?: Coordinate;
|
|
133
|
+
}): void;
|
|
134
|
+
drawActiveCell(context: CanvasRenderingContext2D, state: GridRenderState, column: VisibleIndex, row: VisibleIndex): void;
|
|
135
|
+
/**
|
|
136
|
+
* Draws an outline around the in-flight ctrl+click / ctrl+shift+click drag
|
|
137
|
+
* rectangle. Uses `selection.cursor` (mouse-down anchor) and
|
|
138
|
+
* `selection.selectionEnd` (current drag position) for the bounds. For row
|
|
139
|
+
* selection themes only the top and bottom horizontal strokes are drawn
|
|
140
|
+
* (row-boundary preview); for column selection only left/right; for cell
|
|
141
|
+
* selection all four sides.
|
|
142
|
+
*/
|
|
143
|
+
drawGestureDragOutline(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
144
|
+
/**
|
|
145
|
+
* Draws a rounded rectangle using the current state of the canvas.
|
|
146
|
+
*
|
|
147
|
+
* @param context The canvas context
|
|
148
|
+
* @param x coordinate of the left side
|
|
149
|
+
* @param y coordinate of the top side
|
|
150
|
+
* @param w width of the rectangle
|
|
151
|
+
* @param h height of the rectangle
|
|
152
|
+
* @param r corner radius of the rectangle
|
|
153
|
+
*/
|
|
154
|
+
drawRoundedRect(context: CanvasRenderingContext2D, x: Coordinate, y: Coordinate, w: number, h: number, r?: number): void;
|
|
155
|
+
drawDraggingColumn(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
156
|
+
drawScrollBars(context: CanvasRenderingContext2D, state: GridRenderState): void;
|
|
157
|
+
getCachedHeaderWidth: (context: CanvasRenderingContext2D, text: string) => number;
|
|
158
|
+
}
|
|
159
|
+
export default GridRenderer;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Coordinate } from './GridMetrics';
|
|
2
|
+
import type GridMetrics from './GridMetrics';
|
|
3
|
+
import type GridModel from './GridModel';
|
|
4
|
+
import { type GridTheme } from './GridTheme';
|
|
5
|
+
import { type GridSeparator } from './mouse-handlers/GridSeparatorMouseHandler';
|
|
6
|
+
import { type DraggingColumn } from './mouse-handlers/GridColumnMoveMouseHandler';
|
|
7
|
+
import type { GestureMode, Selection } from './Selection';
|
|
8
|
+
export declare const DEFAULT_FONT_WIDTH = 10;
|
|
9
|
+
export type GridRenderState = {
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
context: CanvasRenderingContext2D;
|
|
13
|
+
theme: GridTheme;
|
|
14
|
+
model: GridModel;
|
|
15
|
+
metrics: GridMetrics;
|
|
16
|
+
mouseX: Coordinate | null;
|
|
17
|
+
mouseY: Coordinate | null;
|
|
18
|
+
selection: Selection;
|
|
19
|
+
draggingColumn: DraggingColumn | null;
|
|
20
|
+
draggingColumnSeparator: GridSeparator | null;
|
|
21
|
+
isDraggingHorizontalScrollBar: boolean;
|
|
22
|
+
isDraggingVerticalScrollBar: boolean;
|
|
23
|
+
isDragging: boolean;
|
|
24
|
+
gestureMode: GestureMode | null;
|
|
25
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import GridRange, { type GridRangeIndex, type SELECTION_DIRECTION } from './GridRange';
|
|
2
|
+
import type { CommitGestureOptions, GestureExtendOptions, GestureMode, Selection } from './Selection';
|
|
3
|
+
/**
|
|
4
|
+
* Maps modifier-key state on a mouse event to the appropriate `GestureMode`.
|
|
5
|
+
* The four modifier combinations partition the gesture space:
|
|
6
|
+
* - shift + ctrl/meta → `maximize`
|
|
7
|
+
* - shift alone → `extend`
|
|
8
|
+
* - ctrl/meta alone → `add`
|
|
9
|
+
* - no modifiers → `replace`
|
|
10
|
+
*/
|
|
11
|
+
export declare function gestureModeFromModifiers(modifiers: {
|
|
12
|
+
isShiftKey: boolean;
|
|
13
|
+
isModifierKey: boolean;
|
|
14
|
+
}): GestureMode;
|
|
15
|
+
/**
|
|
16
|
+
* Shape describing how a mouse gesture should mutate the selection's ranges.
|
|
17
|
+
* Consumed by each `Selection` implementation's `withGestureExtend` to install
|
|
18
|
+
* the transient overlay.
|
|
19
|
+
*/
|
|
20
|
+
export type GestureExtendResult = {
|
|
21
|
+
/** The new range list to install as the transient overlay. */
|
|
22
|
+
newRanges: readonly GridRange[];
|
|
23
|
+
/**
|
|
24
|
+
* True when the caller should drop any previously-committed selection state
|
|
25
|
+
* (relevant to `KeyedSelection.selectedKeys`; ignored by `RangedSelection`).
|
|
26
|
+
*/
|
|
27
|
+
isReplacing: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* True when the caller should trim to the last committed range before
|
|
30
|
+
* installing the new ranges. Applies to `extend` mode.
|
|
31
|
+
*/
|
|
32
|
+
trimBefore: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* True when the caller should reset the gesture anchor to `cursor` after
|
|
35
|
+
* installing. False preserves the existing anchor.
|
|
36
|
+
*/
|
|
37
|
+
resetAnchor: boolean;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Compute the geometry for a mouse gesture. Given the current active ranges,
|
|
41
|
+
* gesture anchor, cursor position, and mode, returns the new overlay ranges
|
|
42
|
+
* plus the flags describing how the caller should install them.
|
|
43
|
+
*
|
|
44
|
+
* This is the shared arithmetic used by both `RangedSelection` and
|
|
45
|
+
* `KeyedSelection` for their `withGestureExtend` implementations.
|
|
46
|
+
*/
|
|
47
|
+
export declare function computeGestureExtend(activeRanges: readonly GridRange[], anchor: {
|
|
48
|
+
row: GridRangeIndex;
|
|
49
|
+
column: GridRangeIndex;
|
|
50
|
+
} | null, cursor: {
|
|
51
|
+
row: GridRangeIndex;
|
|
52
|
+
column: GridRangeIndex;
|
|
53
|
+
}, opts: GestureExtendOptions): GestureExtendResult;
|
|
54
|
+
/**
|
|
55
|
+
* Returns the next cursor cell in `direction` walking through `ranges`.
|
|
56
|
+
* Falls back to walking the full grid when the ranges are empty or contain
|
|
57
|
+
* exactly one cell — matches Tab/Enter behavior for single-cell selections.
|
|
58
|
+
* Shared by `RangedSelection` and `KeyedSelection` implementations of
|
|
59
|
+
* `getNextCursorInDirection`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function nextCursorInRanges(ranges: readonly GridRange[], current: {
|
|
62
|
+
row: GridRangeIndex;
|
|
63
|
+
column: GridRangeIndex;
|
|
64
|
+
}, direction: SELECTION_DIRECTION, bounds: {
|
|
65
|
+
columnCount: number;
|
|
66
|
+
rowCount: number;
|
|
67
|
+
}): {
|
|
68
|
+
row: GridRangeIndex;
|
|
69
|
+
column: GridRangeIndex;
|
|
70
|
+
} | null;
|
|
71
|
+
/**
|
|
72
|
+
* Returns the first cell of `ranges` bounded to `[columnCount, rowCount]`.
|
|
73
|
+
* Shared by `RangedSelection` and `KeyedSelection` implementations of
|
|
74
|
+
* `getCursorLandingCell`.
|
|
75
|
+
*/
|
|
76
|
+
export declare function cursorLandingCellForRanges(ranges: readonly GridRange[], bounds: {
|
|
77
|
+
columnCount: number;
|
|
78
|
+
rowCount: number;
|
|
79
|
+
}): {
|
|
80
|
+
row: GridRangeIndex;
|
|
81
|
+
column: GridRangeIndex;
|
|
82
|
+
} | null;
|
|
83
|
+
/**
|
|
84
|
+
* Returns `settled` with the post-commit cursor placed. Uses `opts.cursor`
|
|
85
|
+
* as the target; substitutes `landing` when the target falls outside a
|
|
86
|
+
* non-empty settled selection; preserves the target when settled is empty
|
|
87
|
+
* (matches Escape's "cursor survives clear" semantics).
|
|
88
|
+
*
|
|
89
|
+
* Callers pass `landing` precomputed from the pre-commit selection so this
|
|
90
|
+
* helper doesn't need to reach back into the caller's overlay state.
|
|
91
|
+
* Returns `settled` unchanged when the cursor is already correct so
|
|
92
|
+
* mouseUp no-ops preserve reference equality.
|
|
93
|
+
*/
|
|
94
|
+
export declare function withCommittedCursor<S extends Selection>(settled: S, landing: {
|
|
95
|
+
row: GridRangeIndex;
|
|
96
|
+
column: GridRangeIndex;
|
|
97
|
+
} | null, opts: CommitGestureOptions): S;
|