import { StyleProp, ViewStyle, TextStyle, FlatListProps, FlatList } from 'react-native'; import { ReactNode } from 'react'; export type LoadingState = 'idle' | 'loading' | 'refreshing' | 'loadingMore' | 'noMore' | 'error'; /** DbInfiniteList 暴露的 ref 方法 */ export interface DbInfiniteListRef { /** 滚动到指定偏移量 */ scrollToOffset: (params: { offset: number; animated?: boolean; }) => void; /** 滚动到底部 */ scrollToEnd: (params?: { animated?: boolean; }) => void; /** 滚动到顶部 */ scrollToTop: (animated?: boolean) => void; /** 获取 FlatList 实例(用于更复杂的操作) */ getFlatListRef: () => FlatList | null; } export interface DbInfiniteListProps extends Omit, 'data' | 'renderItem' | 'onRefresh' | 'refreshing' | 'onEndReached'> { /** 列表数据 */ data: T[]; /** 渲染列表项 */ renderItem: (item: T, index: number) => ReactNode; /** 唯一键提取器 */ keyExtractor: (item: T, index: number) => string; /** 下拉刷新回调 */ onRefresh?: () => Promise; /** 加载更多回调 */ onLoadMore?: () => Promise; /** 是否开启下拉刷新 */ refreshable?: boolean; /** 是否有更多数据 */ hasMore?: boolean; /** 当前加载状态 */ loadingState?: LoadingState; /** 触发加载更多的阈值 (0-1),默认为 0.3 */ loadMoreThreshold?: number; /** 距离底部多少像素触发加载更多(优先级高于 loadMoreThreshold) */ loadMoreOffset?: number; /** 是否在初始加载时自动触发加载更多,默认为 false */ autoLoadOnMount?: boolean; /** 空数据时显示的组件 */ emptyComponent?: ReactNode; /** 加载中显示的组件 */ loadingComponent?: ReactNode; /** 加载更多时显示的组件 */ loadingMoreComponent?: ReactNode; /** 没有更多数据时显示的组件 */ noMoreComponent?: ReactNode; /** 错误时显示的组件 */ errorComponent?: ReactNode; /** 头部组件 */ headerComponent?: ReactNode; /** 尾部组件 (会在加载状态之前显示) */ footerComponent?: ReactNode; /** 列表分隔线 */ separatorComponent?: ReactNode; /** 容器样式 */ style?: StyleProp; /** 内容容器样式 */ contentContainerStyle?: StyleProp; /** 空数据文案 */ emptyText?: string; /** 没有更多数据文案 */ noMoreText?: string; /** 加载中文案 */ loadingText?: string; /** 加载更多文案 */ loadingMoreText?: string; /** 错误文案 */ errorText?: string; /** 重试按钮文案 */ retryText?: string; /** 错误时重试回调 */ onRetry?: () => void; /** 是否显示滚动到顶部按钮 */ showScrollToTop?: boolean; /** 滚动多少距离后显示返回顶部按钮 */ scrollToTopThreshold?: number; /** 是否使用骨架屏 */ useSkeleton?: boolean; /** 骨架屏数量 */ skeletonCount?: number; /** 自定义骨架屏组件 */ skeletonComponent?: ReactNode; /** 列表背景色,默认白色 */ backgroundColor?: string; /** 下拉刷新指示器标题(iOS 生效) */ refreshTitle?: string; /** 下拉刷新指示器标题样式(iOS 生效) */ refreshTitleStyle?: StyleProp; /** 自定义下拉刷新指示器(完全替换 RefreshControl) */ refreshControlComponent?: ReactNode; /** 是否显示垂直滚动条,默认 true */ showsVerticalScrollIndicator?: boolean; /** 空状态时是否显示加载更多,默认 false */ showLoadMoreOnEmpty?: boolean; /** 是否显示"没有更多了"提示,默认 true */ showNoMore?: boolean; /** * 是否启用列表项懒加载,默认 false * * 开启后,列表项只有在滚动进入可视区域时才真正渲染内容, * 未进入可视区域的 item 显示占位组件,适用于含有大量图片或复杂子组件的列表。 * * 注意:开启后需配合 lazyItemHeight 使用,以保证占位区域高度正确。 * * @example * ```tsx * } * /> * ``` */ lazyLoad?: boolean; /** * 懒加载占位区域高度(像素),默认 100 * * 当 lazyLoad 开启时,未进入可视区域的 item 会以此高度渲染占位区域。 * 建议设置为实际列表项的估算高度,避免滚动时产生跳动。 */ lazyItemHeight?: number; /** * 自定义懒加载占位组件 * * 开启 lazyLoad 时,未进入可视区域的 item 显示的占位内容。 * 默认显示一个灰色骨架块,可自定义为 Skeleton、Loading 等。 * * @example * ```tsx * } * ... * /> * ``` */ lazyPlaceholder?: ReactNode; /** * 懒加载可见性判定百分比,默认 1 * * item 有多少百分比进入可视区域时判定为"可见"并开始真正渲染。 * 值越小越提前触发渲染(0 = 刚露出边缘就渲染,100 = 完全可见才渲染)。 */ lazyViewabilityPercent?: number; /** * 是否启用懒加载淡入动画,默认 true * * 开启后,item 从占位状态切换到真实内容时会有一个淡入过渡效果。 */ lazyFadeIn?: boolean; /** * 懒加载淡入动画时长(毫秒),默认 300 */ lazyFadeInDuration?: number; /** * item 离开可视区域后是否回收(重新变为占位),默认 false * * 开启后可进一步节省内存,但会导致反复滚动时重新渲染。 * 适用于超长列表且 item 包含大量图片的场景。 */ lazyRecycle?: boolean; }