feat: enhance loading component with skeleton items for better UX

This commit is contained in:
twwu 2025-03-07 14:57:55 +08:00
parent 6c451ed53c
commit 3cd6d03d9e
3 changed files with 52 additions and 9 deletions

View File

@ -211,9 +211,7 @@ const VersionHistoryPanel = () => {
<div className="flex-1 relative px-3 py-2 overflow-y-auto">
{(isFetching && !versionHistory?.pages?.length)
? (
<div className='flex items-center justify-center h-full'>
<Loading />
</div>
<Loading />
)
: (
<>

View File

@ -1,7 +1,19 @@
import random from 'lodash-es/random'
import Item from './item'
const Loading = () => {
return <div className='w-full h-full'>
{/* // TODO skeleton */}
loading...
const itemConfig = Array.from({ length: 8 }).map((_, index) => {
return {
isFirst: index === 0,
isLast: index === 7,
titleWidth: `w-[${random(50, 80)}%]`,
releaseNotesWidth: `w-[${random(50, 80)}%]`,
}
})
return <div className='relative w-full h-[420px] overflow-y-hidden'>
<div className='absolute top-0 left-0 w-full h-full bg-dataset-chunk-list-mask-bg' />
{itemConfig.map((config, index) => <Item key={index} {...config} />)}
</div>
}

View File

@ -1,7 +1,40 @@
import React from 'react'
import React, { type FC } from 'react'
import cn from '@/utils/classnames'
const Item = () => {
return <div className='h-2 w-full bg-gray-500' />
type ItemProps = {
titleWidth: string
releaseNotesWidth: string
isFirst: boolean
isLast: boolean
}
const Item: FC<ItemProps> = ({
titleWidth,
releaseNotesWidth,
isFirst,
isLast,
}) => {
return (
<div className='flex gap-x-1 relative p-2' >
{!isLast && <div className='absolute w-0.5 h-[calc(100%-0.75rem)] left-4 top-6 bg-divider-subtle' />}
<div className=' flex items-center justify-center shrink-0 w-[18px] h-5'>
<div className='w-2 h-2 border-[2px] rounded-lg border-text-quaternary' />
</div>
<div className='flex flex-col gap-y-0.5'>
<div className='flex items-center py-1'>
<div className={cn('h-2 w-full bg-text-quaternary rounded-sm opacity-20', titleWidth)} />
</div>
{
!isFirst && (
<div className='flex items-center py-1'>
<div className={cn('h-1.5 w-full bg-text-quaternary rounded-sm opacity-20', releaseNotesWidth)} />
</div>
)
}
</div>
</div>
)
}
export default React.memo(Item)