UNPKG

react-aria

Version:
283 lines (278 loc) • 13.5 kB
import {DOMLayoutDelegate as $a83747cc3f035330$export$8f5ed9ff9f511381} from "../selection/DOMLayoutDelegate.mjs"; import {getChildNodes as $94u1a$getChildNodes, getLastItem as $94u1a$getLastItem, getFirstItem as $94u1a$getFirstItem, getNthItem as $94u1a$getNthItem} from "react-stately/private/collections/getChildNodes"; /* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ class $c7bb87e55e1ab755$export$de9feff04fda126e { constructor(options){ this.collection = options.collection; this.disabledKeys = options.disabledKeys; this.disabledBehavior = options.disabledBehavior || 'all'; this.direction = options.direction; this.collator = options.collator; if (!options.layout && !options.ref) throw new Error('Either a layout or a ref must be specified.'); this.layoutDelegate = options.layoutDelegate || (options.layout ? new $c7bb87e55e1ab755$var$DeprecatedLayoutDelegate(options.layout) : new (0, $a83747cc3f035330$export$8f5ed9ff9f511381)(options.ref)); this.focusMode = options.focusMode ?? 'row'; } isCell(node) { return node.type === 'cell'; } isRow(node) { return node.type === 'row' || node.type === 'item'; } isDisabled(item) { return this.disabledBehavior === 'all' && (item.props?.isDisabled || this.disabledKeys.has(item.key)) && item.props?.disabledBehavior !== 'selection'; } findPreviousKey(fromKey, pred, includeDisabled = false) { let key = fromKey != null ? this.collection.getKeyBefore(fromKey) : this.collection.getLastKey(); while(key != null){ let item = this.collection.getItem(key); if (!item) return null; if ((includeDisabled || !this.isDisabled(item)) && (!pred || pred(item))) return key; key = this.collection.getKeyBefore(key); } return null; } findNextKey(fromKey, pred, includeDisabled = false) { let key = fromKey != null ? this.collection.getKeyAfter(fromKey) : this.collection.getFirstKey(); while(key != null){ let item = this.collection.getItem(key); if (!item) return null; if ((includeDisabled || !this.isDisabled(item)) && (!pred || pred(item))) return key; key = this.collection.getKeyAfter(key); if (key == null) return null; } return null; } getKeyForItemInRowByIndex(key, index = 0) { if (index < 0) return null; let item = this.collection.getItem(key); if (!item) return null; let i = 0; for (let child of (0, $94u1a$getChildNodes)(item, this.collection)){ if (child.colSpan && child.colSpan + i > index) return child.key ?? null; if (child.colSpan) i = i + child.colSpan - 1; if (i === index) return child.key ?? null; i++; } return null; } getKeyBelow(fromKey, options) { let key = fromKey; let startItem = this.collection.getItem(key); if (!startItem) return null; // If focus was on a cell, start searching from the parent row if (this.isCell(startItem)) key = startItem.parentKey ?? null; if (key == null) return null; // Find the next item key = this.findNextKey(key, (item)=>item.type === 'item', options?.includeDisabled); if (key != null) { // If focus was on a cell, focus the cell with the same index in the next row. if (this.isCell(startItem)) { let startIndex = startItem.colIndex ? startItem.colIndex : startItem.index; return this.getKeyForItemInRowByIndex(key, startIndex); } // Otherwise, focus the next row if (this.focusMode === 'row') return key; } return null; } getKeyAbove(fromKey, options) { let key = fromKey; let startItem = this.collection.getItem(key); if (!startItem) return null; // If focus is on a cell, start searching from the parent row if (this.isCell(startItem)) key = startItem.parentKey ?? null; if (key == null) return null; // Find the previous item key = this.findPreviousKey(key, (item)=>item.type === 'item', options?.includeDisabled); if (key != null) { // If focus was on a cell, focus the cell with the same index in the previous row. if (this.isCell(startItem)) { let startIndex = startItem.colIndex ? startItem.colIndex : startItem.index; return this.getKeyForItemInRowByIndex(key, startIndex); } // Otherwise, focus the previous row if (this.focusMode === 'row') return key; } return null; } getKeyRightOf(key) { let item = this.collection.getItem(key); if (!item) return null; // If focus is on a row, focus the first child cell. if (this.isRow(item)) { let children = (0, $94u1a$getChildNodes)(item, this.collection); return (this.direction === 'rtl' ? (0, $94u1a$getLastItem)(children)?.key : (0, $94u1a$getFirstItem)(children)?.key) ?? null; } // If focus is on a cell, focus the next cell if any, // otherwise focus the parent row. if (this.isCell(item) && item.parentKey != null) { let parent = this.collection.getItem(item.parentKey); if (!parent) return null; let children = (0, $94u1a$getChildNodes)(parent, this.collection); let next = (this.direction === 'rtl' ? (0, $94u1a$getNthItem)(children, item.index - 1) : (0, $94u1a$getNthItem)(children, item.index + 1)) ?? null; if (next) return next.key ?? null; // focus row only if focusMode is set to row if (this.focusMode === 'row') return item.parentKey ?? null; return (this.direction === 'rtl' ? this.getFirstKey(key) : this.getLastKey(key)) ?? null; } return null; } getKeyLeftOf(key) { let item = this.collection.getItem(key); if (!item) return null; // If focus is on a row, focus the last child cell. if (this.isRow(item)) { let children = (0, $94u1a$getChildNodes)(item, this.collection); return (this.direction === 'rtl' ? (0, $94u1a$getFirstItem)(children)?.key : (0, $94u1a$getLastItem)(children)?.key) ?? null; } // If focus is on a cell, focus the previous cell if any, // otherwise focus the parent row. if (this.isCell(item) && item.parentKey != null) { let parent = this.collection.getItem(item.parentKey); if (!parent) return null; let children = (0, $94u1a$getChildNodes)(parent, this.collection); let prev = (this.direction === 'rtl' ? (0, $94u1a$getNthItem)(children, item.index + 1) : (0, $94u1a$getNthItem)(children, item.index - 1)) ?? null; if (prev) return prev.key ?? null; // focus row only if focusMode is set to row if (this.focusMode === 'row') return item.parentKey ?? null; return (this.direction === 'rtl' ? this.getLastKey(key) : this.getFirstKey(key)) ?? null; } return null; } getFirstKey(fromKey, global) { let key = fromKey ?? null; let item; if (key != null) { item = this.collection.getItem(key); if (!item) return null; // If global flag is not set, and a cell is currently focused, // move focus to the first cell in the parent row. if (this.isCell(item) && !global && item.parentKey != null) { let parent = this.collection.getItem(item.parentKey); if (!parent) return null; return (0, $94u1a$getFirstItem)((0, $94u1a$getChildNodes)(parent, this.collection))?.key ?? null; } } // Find the first row key = this.findNextKey(undefined, (item)=>item.type === 'item'); // If global flag is set (or if focus mode is cell), focus the first cell in the first row. if (key != null && (item && this.isCell(item) && global || this.focusMode === 'cell')) { let item = this.collection.getItem(key); if (!item) return null; key = (0, $94u1a$getFirstItem)((0, $94u1a$getChildNodes)(item, this.collection))?.key ?? null; } // Otherwise, focus the row itself. return key; } getLastKey(fromKey, global) { let key = fromKey ?? null; let item; if (key != null) { item = this.collection.getItem(key); if (!item) return null; // If global flag is not set, and a cell is currently focused, // move focus to the last cell in the parent row. if (this.isCell(item) && !global && item.parentKey != null) { let parent = this.collection.getItem(item.parentKey); if (!parent) return null; let children = (0, $94u1a$getChildNodes)(parent, this.collection); return (0, $94u1a$getLastItem)(children)?.key ?? null; } } // Find the last row key = this.findPreviousKey(undefined, (item)=>item.type === 'item'); // If global flag is set (or if focus mode is cell), focus the last cell in the last row. if (key != null && (item && this.isCell(item) && global || this.focusMode === 'cell')) { let item = this.collection.getItem(key); if (!item) return null; let children = (0, $94u1a$getChildNodes)(item, this.collection); key = (0, $94u1a$getLastItem)(children)?.key ?? null; } // Otherwise, focus the row itself. return key; } getKeyPageAbove(fromKey) { let key = fromKey; let itemRect = this.layoutDelegate.getItemRect(key); if (!itemRect) return null; let pageY = Math.max(0, itemRect.y + itemRect.height - this.layoutDelegate.getVisibleRect().height); while(itemRect && itemRect.y > pageY && key != null){ key = this.getKeyAbove(key) ?? null; if (key == null) break; itemRect = this.layoutDelegate.getItemRect(key); } return key; } getKeyPageBelow(fromKey) { let key = fromKey; let itemRect = this.layoutDelegate.getItemRect(key); if (!itemRect) return null; let pageHeight = this.layoutDelegate.getVisibleRect().height; let pageY = Math.min(this.layoutDelegate.getContentSize().height, itemRect.y + pageHeight); while(itemRect && itemRect.y + itemRect.height < pageY){ let nextKey = this.getKeyBelow(key); // If nextKey is undefined, we've reached the last row already if (nextKey == null) break; itemRect = this.layoutDelegate.getItemRect(nextKey); key = nextKey; } return key; } getKeyForSearch(search, fromKey) { let key = fromKey ?? null; if (!this.collator) return null; let collection = this.collection; key = fromKey ?? this.getFirstKey(); if (key == null) return null; // If the starting key is a cell, search from its parent row. let startItem = collection.getItem(key); if (!startItem) return null; if (startItem.type === 'cell') key = startItem.parentKey ?? null; let hasWrapped = false; while(key != null){ let item = collection.getItem(key); if (!item) return null; // check row text value for match if (item.textValue) { let substring = item.textValue.slice(0, search.length); if (this.collator.compare(substring, search) === 0) { if (this.isRow(item) && this.focusMode === 'cell') return (0, $94u1a$getFirstItem)((0, $94u1a$getChildNodes)(item, this.collection))?.key ?? null; return item.key; } } key = this.findNextKey(key, (item)=>item.type === 'item'); // Wrap around when reaching the end of the collection if (key == null && !hasWrapped) { key = this.getFirstKey(); hasWrapped = true; } } return null; } } class $c7bb87e55e1ab755$var$DeprecatedLayoutDelegate { constructor(layout){ this.layout = layout; } getContentSize() { return this.layout.getContentSize(); } getItemRect(key) { return this.layout.getLayoutInfo(key)?.rect || null; } getVisibleRect() { return this.layout.virtualizer.visibleRect; } } export {$c7bb87e55e1ab755$export$de9feff04fda126e as GridKeyboardDelegate}; //# sourceMappingURL=GridKeyboardDelegate.mjs.map