style: skeleton for search result

This commit is contained in:
jialin
2025-06-25 14:35:00 +08:00
parent adfdf41e85
commit a4d1d3b16c
4 changed files with 77 additions and 29 deletions
@@ -8,13 +8,24 @@ const Wrapper = styled(Flex)`
background-color: var(--ant-color-bg-container);
`;
const FileSkeleton = () => {
const FileSkeleton: React.FC<{ counts: number; itemHeight?: number }> = ({
counts = 2,
itemHeight
}) => {
return (
<Wrapper vertical justify={'space-between'}>
<Wrapper
vertical
justify={'space-between'}
style={{ height: itemHeight || 'auto' }}
>
<Skeleton paragraph={{ rows: 1, width: '100%' }} title={false}></Skeleton>
<Space>
<Skeleton.Node style={{ width: 60, height: 22 }}></Skeleton.Node>
<Skeleton.Node style={{ width: 60, height: 22 }}></Skeleton.Node>
{Array.from({ length: counts }).map((_, index) => (
<Skeleton.Node
style={{ width: 60, height: 22 }}
key={index}
></Skeleton.Node>
))}
</Space>
</Wrapper>
);
@@ -385,7 +385,7 @@ const HFModelFile: React.FC<HFModelFileProps> = forwardRef((props, ref) => {
{dataSource.loading ? (
<ItemFileWrapper>
{_.times(5, (index: number) => {
return <FileSkeleton key={index}></FileSkeleton>;
return <FileSkeleton key={index} counts={3}></FileSkeleton>;
})}
</ItemFileWrapper>
) : dataSource.fileList.length ? (
+57 -24
View File
@@ -2,11 +2,14 @@ import IconFont from '@/components/icon-font';
import SimpleOverlay from '@/components/simple-overlay';
import { SearchOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Col, Empty, Row, Spin } from 'antd';
import { Button, Empty, Spin } from 'antd';
import _ from 'lodash';
import React, { useMemo } from 'react';
import 'simplebar-react/dist/simplebar.min.css';
import styled from 'styled-components';
import { modelSourceMap } from '../config';
import '../style/search-result.less';
import FileSkeleton from './file-skeleton';
import HFModelItem from './hf-model-item';
interface SearchResultProps {
@@ -20,6 +23,25 @@ interface SearchResultProps {
isEvaluating?: boolean;
}
const ItemFileWrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
gap: 24px;
`;
const SpinWrapper = styled.div`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
bottom: 0;
display: flex;
justify-content: center;
`;
const SearchResult: React.FC<SearchResultProps> = (props) => {
const { resultList, onSelect, isEvaluating, source, networkError } = props;
const intl = useIntl();
@@ -94,32 +116,43 @@ const SearchResult: React.FC<SearchResultProps> = (props) => {
<Spin spinning={props.loading}>
<div style={{ minHeight: 200 }}>
{resultList.length ? (
<Row gutter={[16, 24]}>
<ItemFileWrapper>
{resultList.map((item, index) => (
<Col span={24} key={item.name}>
<div
onClick={(e) => handleSelect(e, item)}
onKeyDown={(e) => handleOnEnter(e, item)}
>
<HFModelItem
source={source}
tags={item.tags}
key={index}
title={item.name}
downloads={item.downloads}
likes={item.likes}
task={item.task}
updatedAt={item.updatedAt}
evaluateResult={item.evaluateResult}
active={item.id === props.current}
isEvaluating={isEvaluating}
/>
</div>
</Col>
<div
key={item.name}
onClick={(e) => handleSelect(e, item)}
onKeyDown={(e) => handleOnEnter(e, item)}
>
<HFModelItem
source={source}
tags={item.tags}
key={index}
title={item.name}
downloads={item.downloads}
likes={item.likes}
task={item.task}
updatedAt={item.updatedAt}
evaluateResult={item.evaluateResult}
active={item.id === props.current}
isEvaluating={isEvaluating}
/>
</div>
))}
</Row>
</ItemFileWrapper>
) : props.loading ? (
<ItemFileWrapper>
{_.times(10, (index: number) => {
return (
<FileSkeleton
key={index}
counts={3}
itemHeight={82}
></FileSkeleton>
);
})}
</ItemFileWrapper>
) : (
!props.loading && renderEmpty
renderEmpty
)}
</div>
</Spin>
@@ -3,6 +3,10 @@
.search-result-wrap {
padding: 16px @padding;
border-radius: 0 0 var(--border-radius-base) var(--border-radius-base);
.ant-spin-container.ant-spin-blur {
opacity: unset;
}
}
.gguf-tips {