docs: add comments to the src/components directory

This commit is contained in:
zhaoying
2026-02-02 16:14:39 +08:00
parent 9a38e8a4a0
commit a191e32f71
55 changed files with 1417 additions and 375 deletions

View File

@@ -1,12 +1,33 @@
/*
* @Author: ZhaoYing
* @Date: 2026-02-02 15:18:19
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-02-03 15:44:42
*/
/**
* PageScrollList Component
*
* An infinite scroll list component with pagination support that:
* - Automatically loads more data when scrolling to bottom
* - Supports grid layout with configurable columns
* - Handles loading and empty states
* - Exposes refresh method via ref
*
* @component
*/
import React, { useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react';
import { List } from 'antd';
import InfiniteScroll from 'react-infinite-scroll-component';
import { request } from '@/utils/request';
import PageEmpty from '@/components/Empty/PageEmpty'
import PageLoading from '@/components/Empty/PageLoading'
/** Default page size for pagination */
const PAGE_SIZE = 20;
/** API response structure with pagination metadata */
interface ApiResponse<T> {
items?: T[];
page: {
@@ -16,18 +37,28 @@ interface ApiResponse<T> {
hasnext: boolean;
};
}
/** Ref methods exposed to parent component */
export interface PageScrollListRef {
refresh: () => void;
}
/** Props interface for PageScrollList component */
interface PageScrollListProps<T, Q = Record<string, unknown>> {
/** API endpoint URL */
url: string;
/** Function to render each list item */
renderItem: (item: T) => React.ReactNode;
/** Query parameters for API request */
query?: Q;
/** Number of columns in grid layout */
column?: number;
/** Additional CSS classes */
className?: string;
needLoading?: boolean;
}
/** Infinite scroll list component with pagination support */
const PageScrollList = forwardRef(<T, Q = Record<string, unknown>>({
renderItem,
query,
@@ -36,6 +67,7 @@ const PageScrollList = forwardRef(<T, Q = Record<string, unknown>>({
className = '',
needLoading = true,
}: PageScrollListProps<T, Q>, ref: React.Ref<PageScrollListRef>) => {
/** Expose refresh method to parent component */
useImperativeHandle(ref, () => ({
refresh,
}));
@@ -45,6 +77,7 @@ const PageScrollList = forwardRef(<T, Q = Record<string, unknown>>({
const [hasMore, setHasMore] = useState(true);
const scrollRef = useRef<HTMLDivElement>(null);
/** Load more data from API with pagination */
const loadMoreData = (flag?: boolean) => {
if (!flag && (loading || !hasMore)) {
return;
@@ -58,6 +91,7 @@ const PageScrollList = forwardRef(<T, Q = Record<string, unknown>>({
.then((res) => {
const response = res as ApiResponse<T>;
const results = Array.isArray(response.items) ? response.items : Array.isArray(response) ? response as T[] : [];
// Replace data if flag is true, otherwise append
if (flag) {
setData(results);
} else {
@@ -78,17 +112,19 @@ const PageScrollList = forwardRef(<T, Q = Record<string, unknown>>({
});
};
// 刷新列表数据
/** Reset list to initial state and reload data */
const refresh = () => {
setPage(1);
setHasMore(true);
setData([]);
}
/** Refresh when query parameters change */
useEffect(() => {
refresh()
}, [query]);
/** Load initial data when list is reset */
useEffect(() => {
if (page === 1 && hasMore && data.length === 0) {
loadMoreData(true);
@@ -111,6 +147,7 @@ const PageScrollList = forwardRef(<T, Q = Record<string, unknown>>({
scrollableTarget="scrollableDiv"
className='rb:h-full!'
>
{/* Render grid list or empty state */}
{data.length > 0 ? (
<List
grid={{ gutter: 16, column: column }}