@react-stately/layout 3.13.10-nightly.4674 → 3.13.10-nightly.4681
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/ListLayout.main.js +11 -87
- package/dist/ListLayout.main.js.map +1 -1
- package/dist/ListLayout.mjs +11 -87
- package/dist/ListLayout.module.js +11 -87
- package/dist/ListLayout.module.js.map +1 -1
- package/dist/TableLayout.main.js +58 -94
- package/dist/TableLayout.main.js.map +1 -1
- package/dist/TableLayout.mjs +58 -94
- package/dist/TableLayout.module.js +58 -94
- package/dist/TableLayout.module.js.map +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +27 -69
- package/dist/types.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/ListLayout.ts +31 -145
- package/src/TableLayout.ts +81 -125
- package/src/index.ts +2 -1
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Collection, DropTarget, DropTargetDelegate, Key,
|
|
2
|
-
import { InvalidationContext, Layout, LayoutInfo, Rect, Size
|
|
3
|
-
import { ColumnSize, TableCollection } from "@react-types/table";
|
|
1
|
+
import { Collection, DropTarget, DropTargetDelegate, Key, Node } from "@react-types/shared";
|
|
2
|
+
import { InvalidationContext, Layout, LayoutInfo, Rect, Size } from "@react-stately/virtualizer";
|
|
4
3
|
import { GridNode } from "@react-types/grid";
|
|
5
|
-
import {
|
|
4
|
+
import { TableCollection } from "@react-types/table";
|
|
6
5
|
export type ListLayoutOptions<T> = {
|
|
7
6
|
/** The height of a row in px. */
|
|
8
7
|
rowHeight?: number;
|
|
@@ -11,11 +10,10 @@ export type ListLayoutOptions<T> = {
|
|
|
11
10
|
estimatedHeadingHeight?: number;
|
|
12
11
|
padding?: number;
|
|
13
12
|
indentationForItem?: (collection: Collection<Node<T>>, key: Key) => number;
|
|
14
|
-
collator?: Intl.Collator;
|
|
15
13
|
loaderHeight?: number;
|
|
16
14
|
placeholderHeight?: number;
|
|
17
|
-
allowDisabledKeyFocus?: boolean;
|
|
18
15
|
forceSectionHeaders?: boolean;
|
|
16
|
+
enableEmptyState?: boolean;
|
|
19
17
|
};
|
|
20
18
|
export interface LayoutNode {
|
|
21
19
|
node?: Node<unknown>;
|
|
@@ -25,20 +23,20 @@ export interface LayoutNode {
|
|
|
25
23
|
validRect: Rect;
|
|
26
24
|
index?: number;
|
|
27
25
|
}
|
|
28
|
-
interface ListLayoutProps {
|
|
26
|
+
export interface ListLayoutProps {
|
|
29
27
|
isLoading?: boolean;
|
|
30
28
|
}
|
|
31
29
|
/**
|
|
32
|
-
* The ListLayout class is an implementation of a
|
|
30
|
+
* The ListLayout class is an implementation of a virtualizer {@link Layout}
|
|
33
31
|
* it is used for creating lists and lists with indented sub-lists.
|
|
34
32
|
*
|
|
35
33
|
* To configure a ListLayout, you can use the properties to define the
|
|
36
34
|
* layouts and/or use the method for defining indentation.
|
|
37
|
-
* The {@link ListKeyboardDelegate} extends the existing
|
|
35
|
+
* The {@link ListKeyboardDelegate} extends the existing virtualizer
|
|
38
36
|
* delegate with an additional method to do this (it uses the same delegate object as
|
|
39
|
-
* the
|
|
37
|
+
* the virtualizer itself).
|
|
40
38
|
*/
|
|
41
|
-
export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements
|
|
39
|
+
export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements DropTargetDelegate {
|
|
42
40
|
protected rowHeight: number;
|
|
43
41
|
protected estimatedRowHeight: number;
|
|
44
42
|
protected headingHeight: number;
|
|
@@ -49,17 +47,15 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
49
47
|
protected layoutInfos: Map<Key, LayoutInfo>;
|
|
50
48
|
protected layoutNodes: Map<Key, LayoutNode>;
|
|
51
49
|
protected contentSize: Size;
|
|
52
|
-
collection: Collection<Node<T>>;
|
|
53
|
-
|
|
54
|
-
allowDisabledKeyFocus: boolean;
|
|
55
|
-
isLoading: boolean;
|
|
50
|
+
protected collection: Collection<Node<T>>;
|
|
51
|
+
protected isLoading: boolean;
|
|
56
52
|
protected lastWidth: number;
|
|
57
53
|
protected lastCollection: Collection<Node<T>>;
|
|
58
54
|
protected rootNodes: LayoutNode[];
|
|
59
|
-
protected collator: Intl.Collator;
|
|
60
55
|
protected invalidateEverything: boolean;
|
|
61
56
|
protected loaderHeight: number;
|
|
62
57
|
protected placeholderHeight: number;
|
|
58
|
+
protected enableEmptyState: boolean;
|
|
63
59
|
protected lastValidRect: Rect;
|
|
64
60
|
protected validRect: Rect;
|
|
65
61
|
/**
|
|
@@ -69,75 +65,37 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
69
65
|
constructor(options?: ListLayoutOptions<T>);
|
|
70
66
|
getLayoutInfo(key: Key): LayoutInfo;
|
|
71
67
|
getVisibleLayoutInfos(rect: Rect): LayoutInfo[];
|
|
72
|
-
layoutIfNeeded(rect: Rect): void;
|
|
73
|
-
ensureLayoutInfo(key: Key): boolean;
|
|
74
|
-
isVisible(node: LayoutNode, rect: Rect): boolean;
|
|
68
|
+
protected layoutIfNeeded(rect: Rect): void;
|
|
75
69
|
protected shouldInvalidateEverything(invalidationContext: InvalidationContext<ListLayoutProps>): boolean;
|
|
76
70
|
validate(invalidationContext: InvalidationContext<ListLayoutProps>): void;
|
|
77
|
-
buildCollection(): LayoutNode[];
|
|
78
|
-
isValid(node: Node<T>, y: number): boolean;
|
|
79
|
-
buildChild(node: Node<T>, x: number, y: number): LayoutNode;
|
|
80
|
-
buildNode(node: Node<T>, x: number, y: number): LayoutNode;
|
|
81
|
-
buildSection(node: Node<T>, x: number, y: number): LayoutNode;
|
|
82
|
-
buildHeader(node: Node<T>, x: number, y: number): LayoutNode;
|
|
83
|
-
buildItem(node: Node<T>, x: number, y: number): LayoutNode;
|
|
71
|
+
protected buildCollection(): LayoutNode[];
|
|
72
|
+
protected isValid(node: Node<T>, y: number): boolean;
|
|
73
|
+
protected buildChild(node: Node<T>, x: number, y: number, parentKey: Key | null): LayoutNode;
|
|
74
|
+
protected buildNode(node: Node<T>, x: number, y: number): LayoutNode;
|
|
84
75
|
updateItemSize(key: Key, size: Size): boolean;
|
|
85
|
-
updateLayoutNode(key: Key, oldLayoutInfo: LayoutInfo, newLayoutInfo: LayoutInfo): void;
|
|
86
76
|
getContentSize(): Size;
|
|
87
|
-
getKeyAbove(key: Key): Key | null;
|
|
88
|
-
getKeyBelow(key: Key): Key | null;
|
|
89
|
-
getKeyPageAbove(key: Key): Key | null;
|
|
90
|
-
getKeyPageBelow(key: Key): Key | null;
|
|
91
|
-
getFirstKey(): Key | null;
|
|
92
|
-
getLastKey(): Key | null;
|
|
93
|
-
getKeyForSearch(search: string, fromKey?: Key): Key | null;
|
|
94
77
|
getDropTargetFromPoint(x: number, y: number, isValidDropTarget: (target: DropTarget) => boolean): DropTarget;
|
|
95
78
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
79
|
+
export interface TableLayoutOptions<T> extends ListLayoutOptions<T> {
|
|
80
|
+
scrollContainer?: 'table' | 'body';
|
|
81
|
+
}
|
|
82
|
+
export interface TableLayoutProps extends ListLayoutProps {
|
|
83
|
+
columnWidths?: Map<Key, number>;
|
|
84
|
+
}
|
|
100
85
|
export class TableLayout<T> extends ListLayout<T> {
|
|
101
86
|
collection: TableCollection<T>;
|
|
102
87
|
lastCollection: TableCollection<T>;
|
|
103
88
|
columnWidths: Map<Key, number>;
|
|
104
89
|
stickyColumnIndices: number[];
|
|
105
|
-
wasLoading: boolean;
|
|
106
90
|
isLoading: boolean;
|
|
107
91
|
lastPersistedKeys: Set<Key>;
|
|
108
92
|
persistedIndices: Map<Key, number[]>;
|
|
109
|
-
|
|
110
|
-
controlledColumns: Map<Key, GridNode<unknown>>;
|
|
111
|
-
uncontrolledColumns: Map<Key, GridNode<unknown>>;
|
|
112
|
-
uncontrolledWidths: Map<Key, ColumnSize>;
|
|
113
|
-
resizingColumn: Key | null;
|
|
93
|
+
scrollContainer: 'table' | 'body';
|
|
114
94
|
constructor(options: TableLayoutOptions<T>);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
getColumnMinWidth(key: Key): number;
|
|
119
|
-
getColumnMaxWidth(key: Key): number;
|
|
120
|
-
startResize(key: Key): void;
|
|
121
|
-
updateResizedColumns(key: Key, width: number): Map<Key, ColumnSize>;
|
|
122
|
-
endResize(): void;
|
|
123
|
-
buildCollection(): LayoutNode[];
|
|
124
|
-
buildHeader(): LayoutNode;
|
|
125
|
-
buildHeaderRow(headerRow: GridNode<T>, x: number, y: number): LayoutNode;
|
|
126
|
-
setChildHeights(children: LayoutNode[], height: number): void;
|
|
127
|
-
getRenderedColumnWidth(node: GridNode<T>): number;
|
|
128
|
-
getEstimatedHeight(node: GridNode<T>, width: number, height: number, estimatedHeight: number): {
|
|
129
|
-
height: number;
|
|
130
|
-
isEstimated: boolean;
|
|
131
|
-
};
|
|
132
|
-
buildColumn(node: GridNode<T>, x: number, y: number): LayoutNode;
|
|
133
|
-
buildBody(y: number): LayoutNode;
|
|
134
|
-
buildNode(node: GridNode<T>, x: number, y: number): LayoutNode;
|
|
135
|
-
buildRow(node: GridNode<T>, x: number, y: number): LayoutNode;
|
|
136
|
-
buildCell(node: GridNode<T>, x: number, y: number): LayoutNode;
|
|
95
|
+
validate(invalidationContext: InvalidationContext<TableLayoutProps>): void;
|
|
96
|
+
protected buildCollection(): LayoutNode[];
|
|
97
|
+
protected buildNode(node: GridNode<T>, x: number, y: number): LayoutNode;
|
|
137
98
|
getVisibleLayoutInfos(rect: Rect): LayoutInfo[];
|
|
138
|
-
addVisibleLayoutInfos(res: LayoutInfo[], node: LayoutNode, rect: Rect): void;
|
|
139
|
-
binarySearch(items: LayoutNode[], point: Point, axis: 'x' | 'y'): number;
|
|
140
|
-
buildPersistedIndices(): void;
|
|
141
99
|
getDropTargetFromPoint(x: number, y: number, isValidDropTarget: (target: DropTarget) => boolean): DropTarget;
|
|
142
100
|
}
|
|
143
101
|
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-stately/layout/src/packages/@react-stately/layout/src/ListLayout.ts","packages/@react-stately/layout/src/packages/@react-stately/layout/src/TableLayout.ts","packages/@react-stately/layout/src/packages/@react-stately/layout/src/index.ts","packages/@react-stately/layout/src/index.ts"],"sourcesContent":[null,null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\nexport type {ListLayoutOptions, ListLayoutProps, LayoutNode} from './ListLayout';\nexport type {TableLayoutOptions, TableLayoutProps} from './TableLayout';\nexport {ListLayout} from './ListLayout';\nexport {TableLayout} from './TableLayout';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-stately/layout",
|
|
3
|
-
"version": "3.13.10-nightly.
|
|
3
|
+
"version": "3.13.10-nightly.4681+2fd87d9f1",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
"url": "https://github.com/adobe/react-spectrum"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@react-stately/collections": "3.0.0-nightly.
|
|
26
|
-
"@react-stately/table": "3.11.9-nightly.
|
|
27
|
-
"@react-stately/virtualizer": "3.7.2-nightly.
|
|
28
|
-
"@react-types/grid": "3.2.7-nightly.
|
|
29
|
-
"@react-types/shared": "3.0.0-nightly.
|
|
30
|
-
"@react-types/table": "3.9.6-nightly.
|
|
25
|
+
"@react-stately/collections": "3.0.0-nightly.2969+2fd87d9f1",
|
|
26
|
+
"@react-stately/table": "3.11.9-nightly.4681+2fd87d9f1",
|
|
27
|
+
"@react-stately/virtualizer": "3.7.2-nightly.4681+2fd87d9f1",
|
|
28
|
+
"@react-types/grid": "3.2.7-nightly.4681+2fd87d9f1",
|
|
29
|
+
"@react-types/shared": "3.0.0-nightly.2969+2fd87d9f1",
|
|
30
|
+
"@react-types/table": "3.9.6-nightly.4681+2fd87d9f1",
|
|
31
31
|
"@swc/helpers": "^0.5.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
|
|
34
|
+
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "2fd87d9f1d894e6b00a595cce73c6e8828029132"
|
|
40
40
|
}
|
package/src/ListLayout.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import {Collection, DropTarget, DropTargetDelegate, Key,
|
|
13
|
+
import {Collection, DropTarget, DropTargetDelegate, Key, Node} from '@react-types/shared';
|
|
14
14
|
import {getChildNodes} from '@react-stately/collections';
|
|
15
15
|
import {InvalidationContext, Layout, LayoutInfo, Point, Rect, Size} from '@react-stately/virtualizer';
|
|
16
16
|
|
|
@@ -22,11 +22,10 @@ export type ListLayoutOptions<T> = {
|
|
|
22
22
|
estimatedHeadingHeight?: number,
|
|
23
23
|
padding?: number,
|
|
24
24
|
indentationForItem?: (collection: Collection<Node<T>>, key: Key) => number,
|
|
25
|
-
collator?: Intl.Collator,
|
|
26
25
|
loaderHeight?: number,
|
|
27
26
|
placeholderHeight?: number,
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
forceSectionHeaders?: boolean,
|
|
28
|
+
enableEmptyState?: boolean
|
|
30
29
|
};
|
|
31
30
|
|
|
32
31
|
// A wrapper around LayoutInfo that supports hierarchy
|
|
@@ -39,23 +38,23 @@ export interface LayoutNode {
|
|
|
39
38
|
index?: number
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
interface ListLayoutProps {
|
|
41
|
+
export interface ListLayoutProps {
|
|
43
42
|
isLoading?: boolean
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
const DEFAULT_HEIGHT = 48;
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
|
-
* The ListLayout class is an implementation of a
|
|
48
|
+
* The ListLayout class is an implementation of a virtualizer {@link Layout}
|
|
50
49
|
* it is used for creating lists and lists with indented sub-lists.
|
|
51
50
|
*
|
|
52
51
|
* To configure a ListLayout, you can use the properties to define the
|
|
53
52
|
* layouts and/or use the method for defining indentation.
|
|
54
|
-
* The {@link ListKeyboardDelegate} extends the existing
|
|
53
|
+
* The {@link ListKeyboardDelegate} extends the existing virtualizer
|
|
55
54
|
* delegate with an additional method to do this (it uses the same delegate object as
|
|
56
|
-
* the
|
|
55
|
+
* the virtualizer itself).
|
|
57
56
|
*/
|
|
58
|
-
export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements
|
|
57
|
+
export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements DropTargetDelegate {
|
|
59
58
|
protected rowHeight: number;
|
|
60
59
|
protected estimatedRowHeight: number;
|
|
61
60
|
protected headingHeight: number;
|
|
@@ -66,17 +65,15 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
66
65
|
protected layoutInfos: Map<Key, LayoutInfo>;
|
|
67
66
|
protected layoutNodes: Map<Key, LayoutNode>;
|
|
68
67
|
protected contentSize: Size;
|
|
69
|
-
collection: Collection<Node<T>>;
|
|
70
|
-
|
|
71
|
-
allowDisabledKeyFocus: boolean = false;
|
|
72
|
-
isLoading: boolean;
|
|
68
|
+
protected collection: Collection<Node<T>>;
|
|
69
|
+
protected isLoading: boolean;
|
|
73
70
|
protected lastWidth: number;
|
|
74
71
|
protected lastCollection: Collection<Node<T>>;
|
|
75
72
|
protected rootNodes: LayoutNode[];
|
|
76
|
-
protected collator: Intl.Collator;
|
|
77
73
|
protected invalidateEverything: boolean;
|
|
78
74
|
protected loaderHeight: number;
|
|
79
75
|
protected placeholderHeight: number;
|
|
76
|
+
protected enableEmptyState: boolean;
|
|
80
77
|
protected lastValidRect: Rect;
|
|
81
78
|
protected validRect: Rect;
|
|
82
79
|
|
|
@@ -93,15 +90,14 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
93
90
|
this.forceSectionHeaders = options.forceSectionHeaders;
|
|
94
91
|
this.padding = options.padding || 0;
|
|
95
92
|
this.indentationForItem = options.indentationForItem;
|
|
96
|
-
this.collator = options.collator;
|
|
97
93
|
this.loaderHeight = options.loaderHeight;
|
|
98
94
|
this.placeholderHeight = options.placeholderHeight;
|
|
95
|
+
this.enableEmptyState = options.enableEmptyState || false;
|
|
99
96
|
this.layoutInfos = new Map();
|
|
100
97
|
this.layoutNodes = new Map();
|
|
101
98
|
this.rootNodes = [];
|
|
102
99
|
this.lastWidth = 0;
|
|
103
100
|
this.lastCollection = null;
|
|
104
|
-
this.allowDisabledKeyFocus = options.allowDisabledKeyFocus;
|
|
105
101
|
this.lastValidRect = new Rect();
|
|
106
102
|
this.validRect = new Rect();
|
|
107
103
|
this.contentSize = new Size();
|
|
@@ -146,7 +142,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
146
142
|
return res;
|
|
147
143
|
}
|
|
148
144
|
|
|
149
|
-
layoutIfNeeded(rect: Rect) {
|
|
145
|
+
protected layoutIfNeeded(rect: Rect) {
|
|
150
146
|
if (!this.lastCollection) {
|
|
151
147
|
return;
|
|
152
148
|
}
|
|
@@ -165,7 +161,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
165
161
|
}
|
|
166
162
|
}
|
|
167
163
|
|
|
168
|
-
ensureLayoutInfo(key: Key) {
|
|
164
|
+
private ensureLayoutInfo(key: Key) {
|
|
169
165
|
// If the layout info wasn't found, it might be outside the bounds of the area that we've
|
|
170
166
|
// computed layout for so far. This can happen when accessing a random key, e.g pressing Home/End.
|
|
171
167
|
// Compute the full layout and try again.
|
|
@@ -180,7 +176,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
180
176
|
return false;
|
|
181
177
|
}
|
|
182
178
|
|
|
183
|
-
isVisible(node: LayoutNode, rect: Rect) {
|
|
179
|
+
private isVisible(node: LayoutNode, rect: Rect) {
|
|
184
180
|
return node.layoutInfo.rect.intersects(rect) || node.layoutInfo.isSticky || this.virtualizer.isPersistedKey(node.layoutInfo.key);
|
|
185
181
|
}
|
|
186
182
|
|
|
@@ -223,7 +219,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
223
219
|
this.invalidateEverything = false;
|
|
224
220
|
}
|
|
225
221
|
|
|
226
|
-
buildCollection(): LayoutNode[] {
|
|
222
|
+
protected buildCollection(): LayoutNode[] {
|
|
227
223
|
let y = this.padding;
|
|
228
224
|
let skipped = 0;
|
|
229
225
|
let nodes = [];
|
|
@@ -237,7 +233,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
237
233
|
continue;
|
|
238
234
|
}
|
|
239
235
|
|
|
240
|
-
let layoutNode = this.buildChild(node, 0, y);
|
|
236
|
+
let layoutNode = this.buildChild(node, 0, y, null);
|
|
241
237
|
y = layoutNode.layoutInfo.rect.maxY;
|
|
242
238
|
nodes.push(layoutNode);
|
|
243
239
|
|
|
@@ -256,7 +252,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
256
252
|
y = loader.rect.maxY;
|
|
257
253
|
}
|
|
258
254
|
|
|
259
|
-
if (nodes.length === 0) {
|
|
255
|
+
if (nodes.length === 0 && this.enableEmptyState) {
|
|
260
256
|
let rect = new Rect(0, y, this.virtualizer.visibleRect.width,
|
|
261
257
|
this.placeholderHeight ?? this.virtualizer.visibleRect.height);
|
|
262
258
|
let placeholder = new LayoutInfo('placeholder', 'placeholder', rect);
|
|
@@ -269,7 +265,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
269
265
|
return nodes;
|
|
270
266
|
}
|
|
271
267
|
|
|
272
|
-
isValid(node: Node<T>, y: number) {
|
|
268
|
+
protected isValid(node: Node<T>, y: number) {
|
|
273
269
|
let cached = this.layoutNodes.get(node.key);
|
|
274
270
|
return (
|
|
275
271
|
!this.invalidateEverything &&
|
|
@@ -281,7 +277,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
281
277
|
);
|
|
282
278
|
}
|
|
283
279
|
|
|
284
|
-
buildChild(node: Node<T>, x: number, y: number): LayoutNode {
|
|
280
|
+
protected buildChild(node: Node<T>, x: number, y: number, parentKey: Key | null): LayoutNode {
|
|
285
281
|
if (this.isValid(node, y)) {
|
|
286
282
|
return this.layoutNodes.get(node.key);
|
|
287
283
|
}
|
|
@@ -289,7 +285,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
289
285
|
let layoutNode = this.buildNode(node, x, y);
|
|
290
286
|
layoutNode.node = node;
|
|
291
287
|
|
|
292
|
-
layoutNode.layoutInfo.parentKey =
|
|
288
|
+
layoutNode.layoutInfo.parentKey = parentKey ?? null;
|
|
293
289
|
this.layoutInfos.set(layoutNode.layoutInfo.key, layoutNode.layoutInfo);
|
|
294
290
|
if (layoutNode.header) {
|
|
295
291
|
this.layoutInfos.set(layoutNode.header.key, layoutNode.header);
|
|
@@ -299,22 +295,22 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
299
295
|
return layoutNode;
|
|
300
296
|
}
|
|
301
297
|
|
|
302
|
-
buildNode(node: Node<T>, x: number, y: number): LayoutNode {
|
|
298
|
+
protected buildNode(node: Node<T>, x: number, y: number): LayoutNode {
|
|
303
299
|
switch (node.type) {
|
|
304
300
|
case 'section':
|
|
305
301
|
return this.buildSection(node, x, y);
|
|
306
302
|
case 'item':
|
|
307
303
|
return this.buildItem(node, x, y);
|
|
308
304
|
case 'header':
|
|
309
|
-
return this.
|
|
305
|
+
return this.buildSectionHeader(node, x, y);
|
|
310
306
|
}
|
|
311
307
|
}
|
|
312
308
|
|
|
313
|
-
buildSection(node: Node<T>, x: number, y: number): LayoutNode {
|
|
309
|
+
private buildSection(node: Node<T>, x: number, y: number): LayoutNode {
|
|
314
310
|
let width = this.virtualizer.visibleRect.width;
|
|
315
311
|
let header = null;
|
|
316
312
|
if (node.rendered || this.forceSectionHeaders) {
|
|
317
|
-
let headerNode = this.
|
|
313
|
+
let headerNode = this.buildSectionHeader(node, x, y);
|
|
318
314
|
header = headerNode.layoutInfo;
|
|
319
315
|
header.key += ':header';
|
|
320
316
|
header.parentKey = node.key;
|
|
@@ -337,7 +333,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
337
333
|
continue;
|
|
338
334
|
}
|
|
339
335
|
|
|
340
|
-
let layoutNode = this.buildChild(child, x, y);
|
|
336
|
+
let layoutNode = this.buildChild(child, x, y, layoutInfo.key);
|
|
341
337
|
y = layoutNode.layoutInfo.rect.maxY;
|
|
342
338
|
children.push(layoutNode);
|
|
343
339
|
|
|
@@ -358,7 +354,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
358
354
|
};
|
|
359
355
|
}
|
|
360
356
|
|
|
361
|
-
|
|
357
|
+
private buildSectionHeader(node: Node<T>, x: number, y: number): LayoutNode {
|
|
362
358
|
let width = this.virtualizer.visibleRect.width;
|
|
363
359
|
let rectHeight = this.headingHeight;
|
|
364
360
|
let isEstimated = false;
|
|
@@ -366,7 +362,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
366
362
|
// If no explicit height is available, use an estimated height.
|
|
367
363
|
if (rectHeight == null) {
|
|
368
364
|
// If a previous version of this layout info exists, reuse its height.
|
|
369
|
-
// Mark as estimated if the size of the overall
|
|
365
|
+
// Mark as estimated if the size of the overall virtualizer changed,
|
|
370
366
|
// or the content of the item changed.
|
|
371
367
|
let previousLayoutNode = this.layoutNodes.get(node.key);
|
|
372
368
|
let previousLayoutInfo = previousLayoutNode?.header || previousLayoutNode?.layoutInfo;
|
|
@@ -395,7 +391,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
395
391
|
};
|
|
396
392
|
}
|
|
397
393
|
|
|
398
|
-
buildItem(node: Node<T>, x: number, y: number): LayoutNode {
|
|
394
|
+
private buildItem(node: Node<T>, x: number, y: number): LayoutNode {
|
|
399
395
|
let width = this.virtualizer.visibleRect.width;
|
|
400
396
|
let rectHeight = this.rowHeight;
|
|
401
397
|
let isEstimated = false;
|
|
@@ -403,7 +399,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
403
399
|
// If no explicit height is available, use an estimated height.
|
|
404
400
|
if (rectHeight == null) {
|
|
405
401
|
// If a previous version of this layout info exists, reuse its height.
|
|
406
|
-
// Mark as estimated if the size of the overall
|
|
402
|
+
// Mark as estimated if the size of the overall virtualizer changed,
|
|
407
403
|
// or the content of the item changed.
|
|
408
404
|
let previousLayoutNode = this.layoutNodes.get(node.key);
|
|
409
405
|
if (previousLayoutNode) {
|
|
@@ -463,7 +459,7 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
463
459
|
return false;
|
|
464
460
|
}
|
|
465
461
|
|
|
466
|
-
updateLayoutNode(key: Key, oldLayoutInfo: LayoutInfo, newLayoutInfo: LayoutInfo) {
|
|
462
|
+
private updateLayoutNode(key: Key, oldLayoutInfo: LayoutInfo, newLayoutInfo: LayoutInfo) {
|
|
467
463
|
let n = this.layoutNodes.get(key);
|
|
468
464
|
if (n) {
|
|
469
465
|
// Invalidate by reseting validRect.
|
|
@@ -482,116 +478,6 @@ export class ListLayout<T> extends Layout<Node<T>, ListLayoutProps> implements K
|
|
|
482
478
|
return this.contentSize;
|
|
483
479
|
}
|
|
484
480
|
|
|
485
|
-
getKeyAbove(key: Key): Key | null {
|
|
486
|
-
let collection = this.collection;
|
|
487
|
-
|
|
488
|
-
key = collection.getKeyBefore(key);
|
|
489
|
-
while (key != null) {
|
|
490
|
-
let item = collection.getItem(key);
|
|
491
|
-
if (item.type === 'item' && (this.allowDisabledKeyFocus || !this.disabledKeys.has(item.key))) {
|
|
492
|
-
return key;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
key = collection.getKeyBefore(key);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
getKeyBelow(key: Key): Key | null {
|
|
500
|
-
let collection = this.collection;
|
|
501
|
-
|
|
502
|
-
key = collection.getKeyAfter(key);
|
|
503
|
-
while (key != null) {
|
|
504
|
-
let item = collection.getItem(key);
|
|
505
|
-
if (item.type === 'item' && (this.allowDisabledKeyFocus || !this.disabledKeys.has(item.key))) {
|
|
506
|
-
return key;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
key = collection.getKeyAfter(key);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
getKeyPageAbove(key: Key): Key | null {
|
|
514
|
-
let layoutInfo = this.getLayoutInfo(key);
|
|
515
|
-
|
|
516
|
-
if (layoutInfo) {
|
|
517
|
-
let pageY = Math.max(0, layoutInfo.rect.y + layoutInfo.rect.height - this.virtualizer.visibleRect.height);
|
|
518
|
-
while (layoutInfo && layoutInfo.rect.y > pageY) {
|
|
519
|
-
let keyAbove = this.getKeyAbove(layoutInfo.key);
|
|
520
|
-
layoutInfo = this.getLayoutInfo(keyAbove);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
if (layoutInfo) {
|
|
524
|
-
return layoutInfo.key;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
return this.getFirstKey();
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
getKeyPageBelow(key: Key): Key | null {
|
|
532
|
-
let layoutInfo = this.getLayoutInfo(key != null ? key : this.getFirstKey());
|
|
533
|
-
|
|
534
|
-
if (layoutInfo) {
|
|
535
|
-
let pageY = Math.min(this.virtualizer.contentSize.height, layoutInfo.rect.y - layoutInfo.rect.height + this.virtualizer.visibleRect.height);
|
|
536
|
-
while (layoutInfo && layoutInfo.rect.y < pageY) {
|
|
537
|
-
let keyBelow = this.getKeyBelow(layoutInfo.key);
|
|
538
|
-
layoutInfo = this.getLayoutInfo(keyBelow);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
if (layoutInfo) {
|
|
542
|
-
return layoutInfo.key;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
return this.getLastKey();
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
getFirstKey(): Key | null {
|
|
550
|
-
let collection = this.collection;
|
|
551
|
-
let key = collection.getFirstKey();
|
|
552
|
-
while (key != null) {
|
|
553
|
-
let item = collection.getItem(key);
|
|
554
|
-
if (item.type === 'item' && (this.allowDisabledKeyFocus || !this.disabledKeys.has(item.key))) {
|
|
555
|
-
return key;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
key = collection.getKeyAfter(key);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
getLastKey(): Key | null {
|
|
563
|
-
let collection = this.collection;
|
|
564
|
-
let key = collection.getLastKey();
|
|
565
|
-
while (key != null) {
|
|
566
|
-
let item = collection.getItem(key);
|
|
567
|
-
if (item.type === 'item' && (this.allowDisabledKeyFocus || !this.disabledKeys.has(item.key))) {
|
|
568
|
-
return key;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
key = collection.getKeyBefore(key);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
getKeyForSearch(search: string, fromKey?: Key): Key | null {
|
|
576
|
-
if (!this.collator) {
|
|
577
|
-
return null;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
let collection = this.collection;
|
|
581
|
-
let key = fromKey || this.getFirstKey();
|
|
582
|
-
while (key != null) {
|
|
583
|
-
let item = collection.getItem(key);
|
|
584
|
-
let substring = item.textValue.slice(0, search.length);
|
|
585
|
-
if (item.textValue && this.collator.compare(substring, search) === 0) {
|
|
586
|
-
return key;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
key = this.getKeyBelow(key);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
return null;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
481
|
getDropTargetFromPoint(x: number, y: number, isValidDropTarget: (target: DropTarget) => boolean): DropTarget {
|
|
596
482
|
x += this.virtualizer.visibleRect.x;
|
|
597
483
|
y += this.virtualizer.visibleRect.y;
|