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
JavaScript
"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