UNPKG

uicore-ts

Version:

UICore is a library to build native-like user interfaces using pure Typescript. No HTML is needed at all. Components are described as TS classes and all user interactions are handled explicitly. This library is strongly inspired by the UIKit framework tha

823 lines (822 loc) 31.8 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var UITableView_exports = {}; __export(UITableView_exports, { UITableView: () => UITableView }); module.exports = __toCommonJS(UITableView_exports); var import_UIButton = require("./UIButton"); var import_UINativeScrollView = require("./UINativeScrollView"); var import_UIObject = require("./UIObject"); var import_UIView = require("./UIView"); class UITableView extends import_UINativeScrollView.UINativeScrollView { constructor(elementID) { super(elementID); this.allRowsHaveEqualHeight = import_UIObject.NO; this._visibleRows = []; this._rowPositions = []; this._highestValidRowPositionIndex = 0; this._unusedReusableViews = {}; this._rowIDIndex = 0; this.reloadsOnLanguageChange = import_UIObject.YES; this.sidePadding = 0; this._persistedData = []; this._needsDrawingOfVisibleRowsBeforeLayout = import_UIObject.NO; this._isDrawVisibleRowsScheduled = import_UIObject.NO; this.usesVirtualLayoutingForIntrinsicSizing = import_UIObject.NO; this.animationDuration = 0.25; this._keyboardFocusedRowIndex = void 0; this._keyboardFocusedCellIndex = 0; this._columnCount = 0; this._keyboardListenersAttached = false; this._keyboardListenerElement = this.viewHTMLElement; this._windowScrollHandler = () => { if (!this.isMemberOfViewTree) { return; } this._scheduleDrawVisibleRows(); }; this._resizeHandler = () => { if (!this.isMemberOfViewTree) { return; } this._rowPositions.everyElement.isValid = import_UIObject.NO; this._highestValidRowPositionIndex = -1; this._scheduleDrawVisibleRows(); }; this._equalRowHeightCacheIdentifier = (elementID != null ? elementID : (0, import_UIObject.MAKE_ID)()) + "_rowHeight"; this._fullHeightView = new import_UIView.UIView(); this._fullHeightView.hidden = import_UIObject.YES; this._fullHeightView.userInteractionEnabled = import_UIObject.NO; this.addSubview(this._fullHeightView); this.scrollsX = import_UIObject.NO; this._setupViewportScrollAndResizeHandlersIfNeeded(); this._setupGridAccessibility(); this._setupKeyboardNavigation(); } get _reusableViews() { const result = {}; const addView = (view) => { const identifier = view._UITableViewReusabilityIdentifier; if (!identifier) { return; } if (!result[identifier]) { result[identifier] = []; } result[identifier].push(view); }; this._visibleRows.forEach(addView); this._unusedReusableViews.forEach((views) => views.forEach(addView)); return result; } _setupGridAccessibility() { const el = this._keyboardListenerElement; el.setAttribute("role", "grid"); el.setAttribute("aria-rowcount", "0"); el.setAttribute("aria-colcount", "0"); el.tabIndex = 0; } setColumnCount(count) { this._columnCount = count; this._keyboardListenerElement.setAttribute("aria-colcount", String(count)); } setRowCount(count) { this._keyboardListenerElement.setAttribute("aria-rowcount", String(count)); } _setupKeyboardNavigation() { this._keydownHandler = (event) => { var _a; if (!this.isMemberOfViewTree) { return; } const target = event.target; if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") { return; } const rowCount = this.numberOfRows(); const hasHeader = this._keyboardFocusedRowIndex !== void 0; if (event.key === "ArrowDown") { event.preventDefault(); if (this._keyboardFocusedRowIndex === void 0) { this._setKeyboardFocus(0, this._keyboardFocusedCellIndex); } else if (event.metaKey || event.ctrlKey) { this._setKeyboardFocus(rowCount - 1, this._keyboardFocusedCellIndex); } else if (event.altKey) { const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50))); const next = Math.min( (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) + pageSize, rowCount - 1 ); this._setKeyboardFocus(next, this._keyboardFocusedCellIndex); } else if (this._keyboardFocusedRowIndex === -1) { this._setKeyboardFocus(0, this._keyboardFocusedCellIndex); } else if (this._keyboardFocusedRowIndex < rowCount - 1) { this._setKeyboardFocus(this._keyboardFocusedRowIndex + 1, this._keyboardFocusedCellIndex); } } else if (event.key === "ArrowUp") { event.preventDefault(); if (this._keyboardFocusedRowIndex === void 0) { this._setKeyboardFocus(rowCount - 1, this._keyboardFocusedCellIndex); } else if (event.metaKey || event.ctrlKey) { this._setKeyboardFocus(-1, this._keyboardFocusedCellIndex); } else if (event.altKey) { const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50))); const prev = Math.max( (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) - pageSize, -1 ); this._setKeyboardFocus(prev, this._keyboardFocusedCellIndex); } else if (this._keyboardFocusedRowIndex === 0) { this._setKeyboardFocus(-1, this._keyboardFocusedCellIndex); } else if (this._keyboardFocusedRowIndex > 0) { this._setKeyboardFocus(this._keyboardFocusedRowIndex - 1, this._keyboardFocusedCellIndex); } } else if (event.key === "ArrowRight") { event.preventDefault(); if (this._keyboardFocusedRowIndex !== void 0 && this._columnCount > 0) { const nextCell = event.metaKey || event.ctrlKey ? this._columnCount - 1 : Math.min(this._keyboardFocusedCellIndex + 1, this._columnCount - 1); this._setKeyboardFocus(this._keyboardFocusedRowIndex, nextCell); } } else if (event.key === "ArrowLeft") { event.preventDefault(); if (this._keyboardFocusedRowIndex !== void 0 && this._columnCount > 0) { const prevCell = event.metaKey || event.ctrlKey ? 0 : Math.max(this._keyboardFocusedCellIndex - 1, 0); this._setKeyboardFocus(this._keyboardFocusedRowIndex, prevCell); } } else if (event.key === "Home") { event.preventDefault(); if (this._keyboardFocusedRowIndex !== void 0) { this._setKeyboardFocus(this._keyboardFocusedRowIndex, 0); } } else if (event.key === "End") { event.preventDefault(); if (this._keyboardFocusedRowIndex !== void 0 && this._columnCount > 0) { this._setKeyboardFocus(this._keyboardFocusedRowIndex, this._columnCount - 1); } } else if (event.key === "PageDown") { event.preventDefault(); if (this._keyboardFocusedRowIndex !== void 0) { const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50))); const next = Math.min( (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) + pageSize, rowCount - 1 ); this._setKeyboardFocus(next, this._keyboardFocusedCellIndex); } } else if (event.key === "PageUp") { event.preventDefault(); if (this._keyboardFocusedRowIndex !== void 0) { const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50))); const prev = Math.max( (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) - pageSize, -1 ); this._setKeyboardFocus(prev, this._keyboardFocusedCellIndex); } } else if (event.key === "Enter" || event.key === " ") { if (this._keyboardFocusedRowIndex !== void 0 && this._keyboardFocusedRowIndex >= 0) { event.preventDefault(); (_a = this.keyboardDidActivateCell) == null ? void 0 : _a.call(this, this._keyboardFocusedRowIndex, this._keyboardFocusedCellIndex); } } else if (event.key === "Escape") { this._clearKeyboardFocus(); this._keyboardListenerElement.blur(); } }; } _setKeyboardFocus(rowIndex, cellIndex) { var _a; const previousRowIndex = this._keyboardFocusedRowIndex; const previousCellIndex = this._keyboardFocusedCellIndex; if (rowIndex >= 0 && rowIndex !== previousRowIndex) { const row = this.visibleRowWithIndex(rowIndex); if (row && typeof row.firstButtonCellIndex === "function") { cellIndex = row.firstButtonCellIndex(); } } this._keyboardFocusedRowIndex = rowIndex; this._keyboardFocusedCellIndex = cellIndex; if (previousRowIndex !== void 0 && previousRowIndex !== rowIndex) { this._clearKeyboardFocusOnRow(previousRowIndex); } else if (previousRowIndex === rowIndex && previousCellIndex !== cellIndex) { this._clearKeyboardFocusOnRow(rowIndex); } if (rowIndex >= 0) { this._scrollRowIntoView(rowIndex); } this._applyKeyboardFocusToVisibleRows(); (_a = this.keyboardFocusDidChange) == null ? void 0 : _a.call(this, rowIndex, cellIndex); } _clearKeyboardFocus() { var _a; const previous = this._keyboardFocusedRowIndex; this._keyboardFocusedRowIndex = void 0; if (previous !== void 0) { this._clearKeyboardFocusOnRow(previous); } (_a = this.keyboardFocusDidChange) == null ? void 0 : _a.call(this, void 0, this._keyboardFocusedCellIndex); } _clearKeyboardFocusOnRow(rowIndex) { var _a; if (rowIndex === -1) { (_a = this.keyboardFocusDidChange) == null ? void 0 : _a.call(this, -1, -1); return; } const row = this.visibleRowWithIndex(rowIndex); if (row && typeof row.setKeyboardFocusedCellIndex === "function") { row.setKeyboardFocusedCellIndex(void 0); } } _applyKeyboardFocusToVisibleRows(clearAll = false) { this._visibleRows.forEach((row) => { if (typeof row.setKeyboardFocusedCellIndex !== "function") { return; } if (clearAll || row._UITableViewRowIndex !== this._keyboardFocusedRowIndex) { row.setKeyboardFocusedCellIndex(void 0); } else { row.setKeyboardFocusedCellIndex(this._keyboardFocusedCellIndex); } }); } _scrollRowIntoView(rowIndex) { const position = this._rowPositionWithIndex(rowIndex); if (!position) { return; } const offsetY = this.contentOffset.y; const visibleHeight = this.bounds.height; if (position.topY < offsetY) { const duration = this.animationDuration; this.animationDuration = 0; this.contentOffset = this.contentOffset.pointWithY(position.topY); this.animationDuration = duration; } else if (position.bottomY > offsetY + visibleHeight) { const duration = this.animationDuration; this.animationDuration = 0; this.contentOffset = this.contentOffset.pointWithY(position.bottomY - visibleHeight); this.animationDuration = duration; } } focusRowAtIndex(rowIndex, cellIndex = 0) { this._setKeyboardFocus(rowIndex, cellIndex); this._keyboardListenerElement.focus({ preventScroll: true }); } _setupViewportScrollAndResizeHandlersIfNeeded() { if (this._intersectionObserver) { return; } window.addEventListener("scroll", this._windowScrollHandler, { passive: true }); window.addEventListener("resize", this._resizeHandler, { passive: true }); this._intersectionObserver = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting && this.isMemberOfViewTree) { this._scheduleDrawVisibleRows(); } }); }, { root: null, rootMargin: "100% 0px", threshold: 0 } ); this._intersectionObserver.observe(this.viewHTMLElement); } _cleanupViewportScrollListeners() { window.removeEventListener("scroll", this._windowScrollHandler); window.removeEventListener("resize", this._resizeHandler); if (this._intersectionObserver) { this._intersectionObserver.disconnect(); this._intersectionObserver = void 0; } } wasRemovedFromViewTree() { super.wasRemovedFromViewTree(); this._cleanupViewportScrollListeners(); if (this._keydownHandler) { this.viewHTMLElement.removeEventListener("keydown", this._keydownHandler); } this._keyboardListenersAttached = false; } loadData() { this._persistedData = []; this._calculatePositionsUntilIndex(this.numberOfRows() - 1); this._needsDrawingOfVisibleRowsBeforeLayout = import_UIObject.YES; this.setNeedsLayout(); } reloadData() { this._removeVisibleRows(); this._removeAllReusableRows(); this._rowPositions = []; this._highestValidRowPositionIndex = -1; if (this.allRowsHaveEqualHeight) { import_UIView.UIView.invalidateSharedIntrinsicSizeCache(this._equalRowHeightCacheIdentifier); } this.loadData(); } highlightChanges(previousData, newData) { previousData = previousData.map((dataPoint) => JSON.stringify(dataPoint)); newData = newData.map((dataPoint) => JSON.stringify(dataPoint)); const newIndexes = []; newData.forEach((value, index) => { if (!previousData.contains(value)) { newIndexes.push(index); } }); newIndexes.forEach((index) => { var _a; if (this.isRowWithIndexVisible(index)) { this.highlightRowAsNew( (_a = this.visibleRowWithIndex(index)) != null ? _a : this.viewForRowWithIndex(index) ); } }); } highlightRowAsNew(row) { } invalidateSizeOfRowWithIndex(index, animateChange = import_UIObject.NO) { var _a; if ((_a = this._rowPositions) == null ? void 0 : _a[index]) { (0, import_UIObject.FIRST_OR_NIL)(this._rowPositions[index]).isValid = import_UIObject.NO; this._rowPositions.slice(index).everyElement.isValid = import_UIObject.NO; } this._highestValidRowPositionIndex = Math.min(this._highestValidRowPositionIndex, index - 1); this._needsDrawingOfVisibleRowsBeforeLayout = import_UIObject.YES; this._shouldAnimateNextLayout = animateChange; } _rowPositionWithIndex(index, positions = this._rowPositions) { if (this.allRowsHaveEqualHeight && index > 0) { const firstPositionObject = positions[0]; const rowHeight = firstPositionObject.bottomY - firstPositionObject.topY; const result = { bottomY: rowHeight * (index + 1), topY: rowHeight * index, isValid: firstPositionObject.isValid }; return result; } return positions[index]; } _calculateAllPositions() { this._calculatePositionsUntilIndex(this.numberOfRows() - 1); } _calculatePositionsUntilIndex(maxIndex) { if (this.allRowsHaveEqualHeight) { const positionObject = { bottomY: this._heightForAnyRow(), topY: 0, isValid: import_UIObject.YES }; this._rowPositions = [positionObject]; return; } let validPositionObject = this._rowPositions[this._highestValidRowPositionIndex]; if (!(0, import_UIObject.IS)(validPositionObject)) { validPositionObject = { bottomY: 0, topY: 0, isValid: import_UIObject.YES }; } let previousBottomY = validPositionObject.bottomY; if (!this._rowPositions.length) { this._highestValidRowPositionIndex = -1; } for (let i = this._highestValidRowPositionIndex + 1; i <= maxIndex; i++) { let height; const rowPositionObject = this._rowPositions[i]; if ((0, import_UIObject.IS)((rowPositionObject || import_UIObject.nil).isValid)) { height = rowPositionObject.bottomY - rowPositionObject.topY; } else if (this.allRowsHaveEqualHeight && i > 0) { height = this._rowPositions[0].bottomY - this._rowPositions[0].topY; } else { height = this.heightForRowWithIndex(i); } const positionObject = { bottomY: previousBottomY + height, topY: previousBottomY, isValid: import_UIObject.YES }; if (i < this._rowPositions.length) { this._rowPositions[i] = positionObject; } else { this._rowPositions.push(positionObject); } this._highestValidRowPositionIndex = i; previousBottomY = previousBottomY + height; } } _heightForAnyRow(calculateVisibleRows = import_UIObject.YES) { var _a, _b, _c; return this.heightForRowWithIndex( (_c = (_b = (_a = this._visibleRows.firstElement) == null ? void 0 : _a._UITableViewRowIndex) != null ? _b : calculateVisibleRows ? this.indexesForVisibleRows().firstElement : 0) != null ? _c : 0 ); } indexesForVisibleRows(paddingRatio = 0.5) { const tableRect = this.viewHTMLElement.getBoundingClientRect(); const viewportHeight = window.innerHeight; const pageScale = import_UIView.UIView.pageScale; const visibleFrameTop = Math.max(0, -tableRect.top / pageScale); const visibleFrameBottom = Math.min( this.bounds.height, (viewportHeight - tableRect.top) / pageScale ); if (visibleFrameBottom <= visibleFrameTop) { return []; } let firstVisibleY = this.contentOffset.y + visibleFrameTop; let lastVisibleY = this.contentOffset.y + visibleFrameBottom; const paddingPx = viewportHeight / pageScale * paddingRatio; firstVisibleY = Math.max(0, firstVisibleY - paddingPx); lastVisibleY = lastVisibleY + paddingPx; const numberOfRows = this.numberOfRows(); if (this.allRowsHaveEqualHeight) { const rowHeight = this._heightForAnyRow(import_UIObject.NO); let firstIndex = Math.floor(firstVisibleY / rowHeight); let lastIndex = Math.floor(lastVisibleY / rowHeight); firstIndex = Math.max(0, Math.min(firstIndex, numberOfRows - 1)); lastIndex = Math.max(0, Math.min(lastIndex, numberOfRows - 1)); const result2 = []; for (let i = firstIndex; i <= lastIndex; i++) { result2.push(i); } return result2; } this._calculateAllPositions(); const result = []; const totalContentHeight = (0, import_UIObject.IF)(this._rowPositions.lastElement)( () => this._rowPositions.lastElement.bottomY ).ELSE( () => 0 ); firstVisibleY = Math.min(firstVisibleY, totalContentHeight); for (let i = 0; i < numberOfRows; i++) { const position = this._rowPositionWithIndex(i); if (!position) { break; } const rowTop = position.topY; const rowBottom = position.bottomY; if (rowBottom >= firstVisibleY && rowTop <= lastVisibleY) { result.push(i); } if (rowTop > lastVisibleY) { break; } } return result; } _removeVisibleRows() { this._visibleRows.forEach((row) => { this._persistedData[row._UITableViewRowIndex] = this.persistenceDataItemForRowWithIndex( row._UITableViewRowIndex, row ); row.removeFromSuperview(); this._markReusableViewAsUnused(row); }); this._visibleRows = []; } _removeAllReusableRows() { this._unusedReusableViews.forEach( (rows) => rows.forEach((row) => { this._persistedData[row._UITableViewRowIndex] = this.persistenceDataItemForRowWithIndex( row._UITableViewRowIndex, row ); row.removeFromSuperview(); }) ); this._unusedReusableViews = {}; } _markReusableViewAsUnused(row) { const identifier = row._UITableViewReusabilityIdentifier; if (!this._unusedReusableViews[identifier]) { this._unusedReusableViews[identifier] = []; } if (!this._unusedReusableViews[identifier].contains(row)) { this._unusedReusableViews[identifier].push(row); } } _scheduleDrawVisibleRows() { if (!this._isDrawVisibleRowsScheduled) { this._isDrawVisibleRowsScheduled = import_UIObject.YES; import_UIView.UIView.runFunctionBeforeNextFrame(() => { this._calculateAllPositions(); this._drawVisibleRows(); this.setNeedsLayout(); this._isDrawVisibleRowsScheduled = import_UIObject.NO; }); } } _drawVisibleRows() { if (!this.isMemberOfViewTree) { return; } const visibleIndexes = this.indexesForVisibleRows(); if (visibleIndexes.length === 0) { this._removeVisibleRows(); return; } const minIndex = visibleIndexes[0]; const maxIndex = visibleIndexes[visibleIndexes.length - 1]; const removedViews = []; const visibleRows = []; this._visibleRows.forEach((row) => { if ((0, import_UIObject.IS_DEFINED)(row._UITableViewRowIndex) && (row._UITableViewRowIndex < minIndex || row._UITableViewRowIndex > maxIndex)) { this._persistedData[row._UITableViewRowIndex] = this.persistenceDataItemForRowWithIndex( row._UITableViewRowIndex, row ); this._markReusableViewAsUnused(row); removedViews.push(row); } else { visibleRows.push(row); } }); this._visibleRows = visibleRows; visibleIndexes.forEach((rowIndex) => { if (this.isRowWithIndexVisible(rowIndex)) { return; } const view = this.viewForRowWithIndex(rowIndex); this._visibleRows.push(view); this.addSubview(view); view.tabIndex = -1; view.forEachViewInSubtree((subview) => { subview.tabIndex = -1; }); }); removedViews.forEach((row) => { if (this._visibleRows.indexOf(row) == -1) { row.removeFromSuperview(); } }); this._applyKeyboardFocusToVisibleRows(); } visibleRowWithIndex(rowIndex) { for (let i = 0; i < this._visibleRows.length; i++) { const row = this._visibleRows[i]; if (row._UITableViewRowIndex == rowIndex) { return row; } } } isRowWithIndexVisible(rowIndex) { return (0, import_UIObject.IS)(this.visibleRowWithIndex(rowIndex)); } reusableViewForIdentifier(identifier, rowIndex) { var _a; const visibleRowView = this.visibleRowWithIndex(rowIndex); if ((visibleRowView == null ? void 0 : visibleRowView._UITableViewReusabilityIdentifier) === identifier) { return visibleRowView; } if (!this._unusedReusableViews[identifier]) { this._unusedReusableViews[identifier] = []; } let view; if ((_a = this._unusedReusableViews[identifier]) == null ? void 0 : _a.length) { view = this._unusedReusableViews[identifier].pop(); view._UITableViewRowIndex = rowIndex; Object.assign(view, this._persistedData[rowIndex] || this.defaultRowPersistenceDataItem()); } else { view = this.newReusableViewForIdentifier(identifier, this._rowIDIndex); this._rowIDIndex = this._rowIDIndex + 1; view.configureWithObject({ _UITableViewReusabilityIdentifier: identifier, _UITableViewRowIndex: rowIndex, clearIntrinsicSizeCache: (0, import_UIObject.EXTEND)(() => { const currentRowIndex = view._UITableViewRowIndex; if ((0, import_UIObject.IS_DEFINED)(currentRowIndex) && view.isMemberOfViewTree) { this.invalidateSizeOfRowWithIndex(currentRowIndex); this.setNeedsLayout(); } }) }); Object.assign(view, this._persistedData[rowIndex] || this.defaultRowPersistenceDataItem()); } if (this.allRowsHaveEqualHeight) { view.sharedIntrinsicSizeCacheIdentifier = this._equalRowHeightCacheIdentifier; } else { view.sharedIntrinsicSizeCacheIdentifier = void 0; } return view; } newReusableViewForIdentifier(identifier, rowIDIndex) { const view = new import_UIButton.UIButton(this.elementID + "Row" + rowIDIndex); view.stopsPointerEventPropagation = import_UIObject.NO; view.pausesPointerEvents = import_UIObject.NO; return view; } heightForRowWithIndex(index) { return 50; } numberOfRows() { return 1e4; } defaultRowPersistenceDataItem() { } persistenceDataItemForRowWithIndex(rowIndex, row) { } viewForRowWithIndex(rowIndex) { const row = this.reusableViewForIdentifier("Row", rowIndex); row._UITableViewRowIndex = rowIndex; (0, import_UIObject.FIRST_OR_NIL)(row.titleLabel).text = "Row " + rowIndex; return row; } didScrollToPosition(offsetPosition) { super.didScrollToPosition(offsetPosition); this.forEachViewInSubtree((view) => { view._isPointerValid = import_UIObject.NO; }); this._scheduleDrawVisibleRows(); } willMoveToSuperview(superview) { super.willMoveToSuperview(superview); if ((0, import_UIObject.IS)(superview)) { this._setupViewportScrollAndResizeHandlersIfNeeded(); } else { this._cleanupViewportScrollListeners(); } } wasAddedToViewTree() { super.wasAddedToViewTree(); this.loadData(); this._setupViewportScrollAndResizeHandlersIfNeeded(); if (!this._keyboardListenersAttached) { this._keyboardListenersAttached = true; const el = this._keyboardListenerElement; el.addEventListener("keydown", this._keydownHandler); el.addEventListener("pointerdown", (event) => { const target = event.target; if ((target == null ? void 0 : target.tagName) === "INPUT" || (target == null ? void 0 : target.tagName) === "TEXTAREA") { return; } let walkedTarget = target; while (walkedTarget && walkedTarget !== el) { const viewObject = walkedTarget.UIViewObject; if ((viewObject == null ? void 0 : viewObject._UITableViewRowIndex) !== void 0) { el.focus({ preventScroll: true }); this._setKeyboardFocus(viewObject._UITableViewRowIndex, this._keyboardFocusedCellIndex); return; } walkedTarget = walkedTarget.parentElement; } el.focus({ preventScroll: true }); }); el.addEventListener("focus", () => { if (this._keyboardFocusedRowIndex === void 0 && this.numberOfRows() > 0) { this._setKeyboardFocus(0, this._keyboardFocusedCellIndex); } else if (this._keyboardFocusedRowIndex !== void 0) { this._applyKeyboardFocusToVisibleRows(); } }); el.addEventListener("blur", (event) => { if (!el.contains(event.relatedTarget)) { this._applyKeyboardFocusToVisibleRows(true); } }); } this.forEachViewInSubtree((view) => { if (view !== this) { view.tabIndex = -1; } }); this._keyboardListenerElement.tabIndex = 0; } setFrame(rectangle, zIndex, performUncheckedLayout) { const frame = this.frame; super.setFrame(rectangle, zIndex, performUncheckedLayout); if (frame.isEqualTo(rectangle) && !performUncheckedLayout) { return; } this._needsDrawingOfVisibleRowsBeforeLayout = import_UIObject.YES; } didReceiveBroadcastEvent(event) { super.didReceiveBroadcastEvent(event); if (event.name == import_UIView.UIView.broadcastEventName.LanguageChanged && this.reloadsOnLanguageChange) { this.reloadData(); } } clearIntrinsicSizeCache() { super.clearIntrinsicSizeCache(); if (this.allRowsHaveEqualHeight) { import_UIView.UIView.invalidateSharedIntrinsicSizeCache(this._equalRowHeightCacheIdentifier); } this.invalidateSizeOfRowWithIndex(0); } _layoutAllRows(positions = this._rowPositions) { const bounds = this.bounds; const sortedRows = this._visibleRows.sort( (rowA, rowB) => rowA._UITableViewRowIndex - rowB._UITableViewRowIndex ); sortedRows.forEach((row, i) => { var _a, _b, _c; const frame = bounds.copy(); const positionObject = this._rowPositionWithIndex(row._UITableViewRowIndex, positions); frame.min.y = positionObject.topY; frame.max.y = positionObject.bottomY; row.frame = frame; row.style.width = "" + (bounds.width - this.sidePadding * 2).integerValue + "px"; row.style.left = "" + this.sidePadding.integerValue + "px"; row.viewHTMLElement.setAttribute("aria-rowindex", String(((_a = row._UITableViewRowIndex) != null ? _a : 0) + 1)); const nextSiblingElement = (_c = (_b = sortedRows[i + 1]) == null ? void 0 : _b.viewHTMLElement) != null ? _c : this._fullHeightView.viewHTMLElement; if (row.viewHTMLElement.nextSibling !== nextSiblingElement) { this.viewHTMLElement.insertBefore(row.viewHTMLElement, nextSiblingElement); } }); const numberOfRows = this.numberOfRows(); const fullContentHeight = numberOfRows ? this._rowPositionWithIndex(numberOfRows - 1, positions).bottomY : 0; this._fullHeightView.frame = bounds.rectangleWithHeight(fullContentHeight).rectangleWithWidth(bounds.width * 0.5); } _animateLayoutAllRows() { import_UIView.UIView.animateViewOrViewsWithDurationDelayAndFunction( this._visibleRows, this.animationDuration, 0, void 0, () => { this._layoutAllRows(); }, () => { } ); } didLayoutSubviews() { var _a; (_a = this.viewController) == null ? void 0 : _a.viewDidLayoutSubviews(); if (!this.isVirtualLayouting && (0, import_UIObject.IS)(this.superview) && this.isMemberOfViewTree) { const currentContentHeight = this.intrinsicContentHeight(); if (currentContentHeight !== this._lastReportedHeight) { this._lastReportedHeight = currentContentHeight; this.clearIntrinsicSizeCache(); this.superview.setNeedsLayout(); } } } layoutSubviews() { if (this.isVirtualLayouting) { console.error("layout subviews called during virtual layouting on UITableView, indicating a possible error in the layout system."); return; } const previousPositions = JSON.parse( JSON.stringify(this._rowPositions) ); const previousVisibleRowsLength = this._visibleRows.length; if (this._needsDrawingOfVisibleRowsBeforeLayout) { this._drawVisibleRows(); this._needsDrawingOfVisibleRowsBeforeLayout = import_UIObject.NO; } super.layoutSubviews(); if (!this.numberOfRows() || !this.isMemberOfViewTree) { return; } if (this._shouldAnimateNextLayout) { this._layoutAllRows(previousPositions); if (previousVisibleRowsLength < this._visibleRows.length) { import_UIView.UIView.runFunctionBeforeNextFrame(() => { this._animateLayoutAllRows(); }); } else { this._animateLayoutAllRows(); } this._shouldAnimateNextLayout = import_UIObject.NO; } else { this._calculateAllPositions(); this._layoutAllRows(); } } intrinsicContentHeight(constrainingWidth = 0) { let result = 0; this._calculateAllPositions(); const numberOfRows = this.numberOfRows(); if (numberOfRows) { result = this._rowPositionWithIndex(numberOfRows - 1).bottomY; } return result; } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { UITableView }); //# sourceMappingURL=UITableView.js.map