|
10 | 10 | * governing permissions and limitations under the License. |
11 | 11 | */ |
12 | 12 |
|
13 | | -import {Direction, DisabledBehavior, Key, KeyboardDelegate, Node} from '@react-types/shared'; |
| 13 | +import {Direction, DisabledBehavior, Key, KeyboardDelegate, LayoutDelegate, Node} from '@react-types/shared'; |
| 14 | +import {DOMLayoutDelegate} from '@react-aria/selection'; |
14 | 15 | import {getChildNodes, getFirstItem, getLastItem, getNthItem} from '@react-stately/collections'; |
15 | 16 | import {GridCollection} from '@react-types/grid'; |
16 | | -import {Layout, Rect} from '@react-stately/virtualizer'; |
17 | 17 | import {RefObject} from 'react'; |
18 | 18 |
|
19 | | -export interface GridKeyboardDelegateOptions<T, C> { |
| 19 | +export interface GridKeyboardDelegateOptions<C> { |
20 | 20 | collection: C, |
21 | 21 | disabledKeys: Set<Key>, |
22 | 22 | disabledBehavior?: DisabledBehavior, |
23 | 23 | ref?: RefObject<HTMLElement | null>, |
24 | 24 | direction: Direction, |
25 | 25 | collator?: Intl.Collator, |
26 | | - layout?: Layout<Node<T>>, |
| 26 | + layoutDelegate?: LayoutDelegate, |
27 | 27 | focusMode?: 'row' | 'cell' |
28 | 28 | } |
29 | 29 |
|
30 | 30 | export class GridKeyboardDelegate<T, C extends GridCollection<T>> implements KeyboardDelegate { |
31 | 31 | collection: C; |
32 | 32 | protected disabledKeys: Set<Key>; |
33 | 33 | protected disabledBehavior: DisabledBehavior; |
34 | | - protected ref: RefObject<HTMLElement | null>; |
35 | 34 | protected direction: Direction; |
36 | 35 | protected collator: Intl.Collator; |
37 | | - protected layout: Layout<Node<T>>; |
| 36 | + protected layoutDelegate: LayoutDelegate; |
38 | 37 | protected focusMode; |
39 | 38 |
|
40 | | - constructor(options: GridKeyboardDelegateOptions<T, C>) { |
| 39 | + constructor(options: GridKeyboardDelegateOptions<C>) { |
41 | 40 | this.collection = options.collection; |
42 | 41 | this.disabledKeys = options.disabledKeys; |
43 | 42 | this.disabledBehavior = options.disabledBehavior || 'all'; |
44 | | - this.ref = options.ref; |
45 | 43 | this.direction = options.direction; |
46 | 44 | this.collator = options.collator; |
47 | | - this.layout = options.layout; |
| 45 | + this.layoutDelegate = options.layoutDelegate || new DOMLayoutDelegate(options.ref); |
48 | 46 | this.focusMode = options.focusMode || 'row'; |
49 | 47 | } |
50 | 48 |
|
@@ -276,66 +274,35 @@ export class GridKeyboardDelegate<T, C extends GridCollection<T>> implements Key |
276 | 274 | return key; |
277 | 275 | } |
278 | 276 |
|
279 | | - private getItem(key: Key): HTMLElement { |
280 | | - return this.ref.current.querySelector(`[data-key="${CSS.escape(key.toString())}"]`); |
281 | | - } |
282 | | - |
283 | | - private getItemRect(key: Key): Rect { |
284 | | - if (this.layout) { |
285 | | - return this.layout.getLayoutInfo(key)?.rect; |
286 | | - } |
287 | | - |
288 | | - let item = this.getItem(key); |
289 | | - if (item) { |
290 | | - return new Rect(item.offsetLeft, item.offsetTop, item.offsetWidth, item.offsetHeight); |
291 | | - } |
292 | | - } |
293 | | - |
294 | | - private getPageHeight(): number { |
295 | | - if (this.layout) { |
296 | | - return this.layout.virtualizer?.visibleRect.height; |
297 | | - } |
298 | | - |
299 | | - return this.ref?.current?.offsetHeight; |
300 | | - } |
301 | | - |
302 | | - private getContentHeight(): number { |
303 | | - if (this.layout) { |
304 | | - return this.layout.getContentSize().height; |
305 | | - } |
306 | | - |
307 | | - return this.ref?.current?.scrollHeight; |
308 | | - } |
309 | | - |
310 | 277 | getKeyPageAbove(key: Key) { |
311 | | - let itemRect = this.getItemRect(key); |
| 278 | + let itemRect = this.layoutDelegate.getItemRect(key); |
312 | 279 | if (!itemRect) { |
313 | 280 | return null; |
314 | 281 | } |
315 | 282 |
|
316 | | - let pageY = Math.max(0, itemRect.maxY - this.getPageHeight()); |
| 283 | + let pageY = Math.max(0, itemRect.y + itemRect.height - this.layoutDelegate.getVisibleRect().height); |
317 | 284 |
|
318 | 285 | while (itemRect && itemRect.y > pageY) { |
319 | 286 | key = this.getKeyAbove(key); |
320 | | - itemRect = this.getItemRect(key); |
| 287 | + itemRect = this.layoutDelegate.getItemRect(key); |
321 | 288 | } |
322 | 289 |
|
323 | 290 | return key; |
324 | 291 | } |
325 | 292 |
|
326 | 293 | getKeyPageBelow(key: Key) { |
327 | | - let itemRect = this.getItemRect(key); |
| 294 | + let itemRect = this.layoutDelegate.getItemRect(key); |
328 | 295 |
|
329 | 296 | if (!itemRect) { |
330 | 297 | return null; |
331 | 298 | } |
332 | 299 |
|
333 | | - let pageHeight = this.getPageHeight(); |
334 | | - let pageY = Math.min(this.getContentHeight(), itemRect.y + pageHeight); |
| 300 | + let pageHeight = this.layoutDelegate.getVisibleRect().height; |
| 301 | + let pageY = Math.min(this.layoutDelegate.getContentSize().height, itemRect.y + pageHeight); |
335 | 302 |
|
336 | | - while (itemRect && itemRect.maxY < pageY) { |
| 303 | + while (itemRect && (itemRect.y + itemRect.height) < pageY) { |
337 | 304 | let nextKey = this.getKeyBelow(key); |
338 | | - itemRect = this.getItemRect(nextKey); |
| 305 | + itemRect = this.layoutDelegate.getItemRect(nextKey); |
339 | 306 |
|
340 | 307 | // Guard against case where maxY of the last key is barely less than pageY due to rounding |
341 | 308 | // and thus it attempts to set key to null |
|
0 commit comments