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,19 +1,41 @@
/*
* @Author: ZhaoYing
* @Date: 2026-02-02 15:02:47
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-02-02 15:47:24
*/
/**
* BodyWrapper Component
*
* A wrapper component that conditionally renders loading, empty, or content states.
* Simplifies state management for data-driven components.
*
* @component
*/
import type { FC, ReactNode } from 'react'
import PageEmpty from './PageEmpty'
import PageLoading from './PageLoading'
interface BodyWrapperProps {
/** Content to render when not loading or empty */
children: ReactNode
/** Whether to show loading state */
loading?: boolean
/** Whether the content is empty */
empty: boolean
}
const BodyWrapper: FC<BodyWrapperProps> = ({ children, loading = false, empty }) => {
// Show loading spinner while data is being fetched
if (loading) {
return <PageLoading />
}
// Show empty state when no data is available
if (!loading && empty) {
return <PageEmpty />
}
// Render actual content when data is loaded and available
return children
}
export default BodyWrapper

View File

@@ -1,7 +1,28 @@
/*
* @Author: ZhaoYing
* @Date: 2026-02-02 15:03:52
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-02-02 15:48:41
*/
/**
* Loading Component
*
* A specialized empty state component that displays a loading animation.
* Uses the Empty component with a loading icon and localized loading messages.
*
* @component
*/
import { type FC } from 'react';
import { useTranslation } from 'react-i18next'
import LoadingIcon from '@/assets/images/loading.svg'
import Empty from './index'
const Loading = ({ size = 200 }: { size?: number }) => {
/**
* @param size - Icon size in pixels (default: 200)
*/
const Loading: FC<{ size?: number }> = ({ size = 200 }) => {
const { t } = useTranslation()
return (
<Empty

View File

@@ -1,7 +1,28 @@
/*
* @Author: ZhaoYing
* @Date: 2026-02-02 15:04:18
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-02-02 15:49:01
*/
/**
* PageEmpty Component
*
* A full-page empty state component that displays when no content is available.
* Uses the Empty component with a page-specific empty icon and messages.
*
* @component
*/
import { type FC } from 'react';
import { useTranslation } from 'react-i18next'
import pageEmptyIcon from '@/assets/images/empty/pageEmpty.png'
import Empty from './index'
const PageEmpty = ({ size = [240, 210] }: { size?: number | number[] }) => {
/**
* @param size - Icon size in pixels - single number or [width, height] array (default: [240, 210])
*/
const PageEmpty: FC<{ size?: number | number[] }> = ({ size = [240, 210] }) => {
const { t } = useTranslation()
return (
<Empty

View File

@@ -1,7 +1,28 @@
/*
* @Author: ZhaoYing
* @Date: 2026-02-02 15:04:43
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-02-02 15:49:49
*/
/**
* PageLoading Component
*
* A full-page loading state component that displays while content is being fetched.
* Uses the Empty component with a loading icon and localized loading messages.
*
* @component
*/
import { type FC } from 'react';
import { useTranslation } from 'react-i18next'
import LoadingIcon from '@/assets/images/empty/pageLoading.png'
import Empty from './index'
const PageLoading = ({ size = [240, 210] }: { size?: number | number[] }) => {
/**
* @param size - Icon size in pixels - single number or [width, height] array (default: [240, 210])
*/
const PageLoading: FC<{ size?: number | number[] }> = ({ size = [240, 210] }) => {
const { t } = useTranslation()
return (
<Empty

View File

@@ -1,13 +1,35 @@
/*
* @Author: ZhaoYing
* @Date: 2026-02-02 15:03:25
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-02-02 15:47:31
*/
/**
* Empty Component
*
* A customizable empty state component that displays an icon with optional title and subtitle.
* Used to indicate when no data or content is available.
*
* @component
*/
import { type FC } from 'react';
import { useTranslation } from 'react-i18next';
import emptyIcon from '@/assets/images/empty/empty.svg';
interface EmptyProps {
/** Custom icon URL for the empty state */
url?: string;
/** Icon size - single number or [width, height] array */
size?: number | number[];
/** Main title text */
title?: string;
/** Whether to show subtitle */
isNeedSubTitle?: boolean;
/** Custom subtitle text */
subTitle?: string;
/** Additional CSS classes */
className?: string;
}
const Empty: FC<EmptyProps> = ({
@@ -19,14 +41,19 @@ const Empty: FC<EmptyProps> = ({
className = '',
}) => {
const { t } = useTranslation();
// Calculate width and height from size prop (supports single value or [width, height] array)
const width = Array.isArray(size) ? size[0] : size ? size : url ? 200 : 88;
const height = Array.isArray(size) ? size[1] : size ? size : url ? 200 : 88;
// Use custom subtitle or default translation if subtitle is needed
const curSubTitle = isNeedSubTitle ? (subTitle || t('empty.tableEmpty')) : null;
return (
<div className={`rb:flex rb:items-center rb:justify-center rb:flex-col ${className}`}>
{/* Empty state icon */}
<img src={url || emptyIcon} alt="404" style={{ width: `${width}px`, height: `${height}px` }} />
{/* Optional title */}
{title && <div className="rb:mt-2 rb:leading-5">{title}</div>}
{/* Optional subtitle with conditional styling */}
{curSubTitle && <div className={`rb:mt-[${url ? 8 : 5}px] rb:leading-4 rb:text-[12px] rb:text-[#A8A9AA]`}>{curSubTitle}</div>}
</div>
);