@tamagui/react-native-web-lite
Version:
React Native for Web
256 lines (255 loc) • 9.6 kB
JavaScript
import { View } from "../../../View";
import { deepDiffer } from "../deepDiffer";
import { Platform } from "../../../exports/Platform";
import { invariant, StyleSheet } from "@tamagui/react-native-web-internals";
import * as React from "react";
import { VirtualizedList } from "../VirtualizedList";
import { keyExtractor as defaultKeyExtractor } from "../VirtualizeUtils";
import memoizeOne from "memoize-one";
import { jsx } from "react/jsx-runtime";
function removeClippedSubviewsOrDefault(removeClippedSubviews) {
return removeClippedSubviews ?? Platform.OS === "android";
}
function numColumnsOrDefault(numColumns) {
return numColumns ?? 1;
}
function isArrayLike(data) {
return typeof Object(data).length == "number";
}
class FlatList extends React.PureComponent {
/**
* Scrolls to the end of the content. May be janky without `getItemLayout` prop.
*/
scrollToEnd(params) {
this._listRef && this._listRef.scrollToEnd(params);
}
/**
* Scrolls to the item at the specified index such that it is positioned in the viewable area
* such that `viewPosition` 0 places it at the top, 1 at the bottom, and 0.5 centered in the
* middle. `viewOffset` is a fixed number of pixels to offset the final target position.
*
* Note: cannot scroll to locations outside the render window without specifying the
* `getItemLayout` prop.
*/
scrollToIndex(params) {
this._listRef && this._listRef.scrollToIndex(params);
}
/**
* Requires linear scan through data - use `scrollToIndex` instead if possible.
*
* Note: cannot scroll to locations outside the render window without specifying the
* `getItemLayout` prop.
*/
scrollToItem(params) {
this._listRef && this._listRef.scrollToItem(params);
}
/**
* Scroll to a specific content pixel offset in the list.
*
* Check out [scrollToOffset](docs/virtualizedlist.html#scrolltooffset) of VirtualizedList
*/
scrollToOffset(params) {
this._listRef && this._listRef.scrollToOffset(params);
}
/**
* Tells the list an interaction has occurred, which should trigger viewability calculations, e.g.
* if `waitForInteractions` is true and the user has not scrolled. This is typically called by
* taps on items or by navigation actions.
*/
recordInteraction() {
this._listRef && this._listRef.recordInteraction();
}
/**
* Displays the scroll indicators momentarily.
*
* @platform ios
*/
flashScrollIndicators() {
this._listRef && this._listRef.flashScrollIndicators();
}
/**
* Provides a handle to the underlying scroll responder.
*/
getScrollResponder() {
if (this._listRef)
return this._listRef.getScrollResponder();
}
/**
* Provides a reference to the underlying host component
*/
getNativeScrollRef() {
if (this._listRef)
return this._listRef.getScrollRef();
}
getScrollableNode() {
if (this._listRef)
return this._listRef.getScrollableNode();
}
constructor(props) {
super(props), this._checkProps(this.props), this.props.viewabilityConfigCallbackPairs ? this._virtualizedListPairs = this.props.viewabilityConfigCallbackPairs.map((pair) => ({
viewabilityConfig: pair.viewabilityConfig,
onViewableItemsChanged: this._createOnViewableItemsChanged(
pair.onViewableItemsChanged
)
})) : this.props.onViewableItemsChanged && this._virtualizedListPairs.push({
viewabilityConfig: this.props.viewabilityConfig,
onViewableItemsChanged: this._createOnViewableItemsChanged(
this.props.onViewableItemsChanged
)
});
}
componentDidUpdate(prevProps) {
invariant(
prevProps.numColumns === this.props.numColumns,
"Changing numColumns on the fly is not supported. Change the key prop on FlatList when changing the number of columns to force a fresh render of the component."
), invariant(
prevProps.onViewableItemsChanged === this.props.onViewableItemsChanged,
"Changing onViewableItemsChanged on the fly is not supported"
), invariant(
!deepDiffer(prevProps.viewabilityConfig, this.props.viewabilityConfig),
"Changing viewabilityConfig on the fly is not supported"
), invariant(
prevProps.viewabilityConfigCallbackPairs === this.props.viewabilityConfigCallbackPairs,
"Changing viewabilityConfigCallbackPairs on the fly is not supported"
), this._checkProps(this.props);
}
_listRef;
_virtualizedListPairs = [];
_captureRef = (ref) => {
this._listRef = ref;
};
_checkProps(props) {
const {
getItem,
getItemCount,
horizontal,
columnWrapperStyle,
onViewableItemsChanged,
viewabilityConfigCallbackPairs
} = props, numColumns = numColumnsOrDefault(this.props.numColumns);
invariant(
!getItem && !getItemCount,
"FlatList does not support custom data formats."
), numColumns > 1 ? invariant(!horizontal, "numColumns does not support horizontal.") : invariant(
!columnWrapperStyle,
"columnWrapperStyle not supported for single column lists"
), invariant(
!(onViewableItemsChanged && viewabilityConfigCallbackPairs),
"FlatList does not support setting both onViewableItemsChanged and viewabilityConfigCallbackPairs."
);
}
_getItem = (data, index) => {
const numColumns = numColumnsOrDefault(this.props.numColumns);
if (numColumns > 1) {
const ret = [];
for (let kk = 0; kk < numColumns; kk++) {
const itemIndex = index * numColumns + kk;
if (itemIndex < data.length) {
const item = data[itemIndex];
ret.push(item);
}
}
return ret;
} else
return data[index];
};
_getItemCount = (data) => {
if (data != null && isArrayLike(data)) {
const numColumns = numColumnsOrDefault(this.props.numColumns);
return numColumns > 1 ? Math.ceil(data.length / numColumns) : data.length;
} else
return 0;
};
_keyExtractor = (items, index) => {
const numColumns = numColumnsOrDefault(this.props.numColumns), keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor;
return numColumns > 1 ? (invariant(
Array.isArray(items),
"FlatList: Encountered internal consistency error, expected each item to consist of an array with 1-%s columns; instead, received a single item.",
numColumns
), items.map(
(item, kk) => keyExtractor(item, index * numColumns + kk)
).join(":")) : keyExtractor(items, index);
};
_pushMultiColumnViewable(arr, v) {
const numColumns = numColumnsOrDefault(this.props.numColumns), keyExtractor = this.props.keyExtractor ?? defaultKeyExtractor;
v.item.forEach((item, ii) => {
invariant(v.index != null, "Missing index!");
const index = v.index * numColumns + ii;
arr.push({ ...v, item, key: keyExtractor(item, index), index });
});
}
_createOnViewableItemsChanged(onViewableItemsChanged) {
return (info) => {
const numColumns = numColumnsOrDefault(this.props.numColumns);
if (onViewableItemsChanged)
if (numColumns > 1) {
const changed = [], viewableItems = [];
info.viewableItems.forEach(
(v) => this._pushMultiColumnViewable(viewableItems, v)
), info.changed.forEach((v) => this._pushMultiColumnViewable(changed, v)), onViewableItemsChanged({ viewableItems, changed });
} else
onViewableItemsChanged(info);
};
}
_renderer = (ListItemComponent, renderItem, columnWrapperStyle, numColumns, extraData) => {
const cols = numColumnsOrDefault(numColumns), render = (props) => ListItemComponent ? /* @__PURE__ */ jsx(ListItemComponent, { ...props }) : renderItem ? renderItem(props) : null, renderProp = (info) => {
if (cols > 1) {
const { item, index } = info;
return invariant(
Array.isArray(item),
"Expected array of items with numColumns > 1"
), /* @__PURE__ */ jsx(View, { style: [styles.row, columnWrapperStyle], children: item.map((it, kk) => {
const element = render({
item: it,
index: index * cols + kk,
separators: info.separators
});
return element != null ? /* @__PURE__ */ jsx(React.Fragment, { children: element }, kk) : null;
}) });
} else
return render(info);
};
return ListItemComponent ? { ListItemComponent: renderProp } : { renderItem: renderProp };
};
// $FlowFixMe[missing-local-annot]
_memoizedRenderer = memoizeOne(this._renderer);
render() {
const {
numColumns,
columnWrapperStyle,
removeClippedSubviews: _removeClippedSubviews,
strictMode = !1,
...restProps
} = this.props, renderer = strictMode ? this._memoizedRenderer : this._renderer;
return /* @__PURE__ */ jsx(
VirtualizedList,
{
...restProps,
getItem: this._getItem,
getItemCount: this._getItemCount,
keyExtractor: this._keyExtractor,
ref: this._captureRef,
viewabilityConfigCallbackPairs: this._virtualizedListPairs,
removeClippedSubviews: removeClippedSubviewsOrDefault(
_removeClippedSubviews
),
...renderer(
this.props.ListItemComponent,
this.props.renderItem,
columnWrapperStyle,
numColumns,
this.props.extraData
)
}
);
}
}
const styles = StyleSheet.create({
row: { flexDirection: "row" }
});
var FlatList_default = FlatList;
export {
FlatList,
FlatList_default as default
};
//# sourceMappingURL=index.js.map