|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import React, { useState } from 'react'; |
|
|
import { Card, Divider, Typography, Button } from '@douyinfe/semi-ui'; |
|
|
import PropTypes from 'prop-types'; |
|
|
import { useIsMobile } from '../../../hooks/common/useIsMobile'; |
|
|
import { IconEyeOpened, IconEyeClosed } from '@douyinfe/semi-icons'; |
|
|
|
|
|
const { Text } = Typography; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const CardPro = ({ |
|
|
type = 'type1', |
|
|
className = '', |
|
|
children, |
|
|
// 各个区域的内容 |
|
|
statsArea, |
|
|
descriptionArea, |
|
|
tabsArea, |
|
|
actionsArea, |
|
|
searchArea, |
|
|
paginationArea, // 新增分页区域 |
|
|
// 卡片属性 |
|
|
shadows = '', |
|
|
bordered = true, |
|
|
// 自定义样式 |
|
|
style, |
|
|
// 国际化函数 |
|
|
t = (key) => key, |
|
|
...props |
|
|
}) => { |
|
|
const isMobile = useIsMobile(); |
|
|
const [showMobileActions, setShowMobileActions] = useState(false); |
|
|
|
|
|
const toggleMobileActions = () => { |
|
|
setShowMobileActions(!showMobileActions); |
|
|
}; |
|
|
|
|
|
const hasMobileHideableContent = actionsArea || searchArea; |
|
|
|
|
|
const renderHeader = () => { |
|
|
const hasContent = |
|
|
statsArea || descriptionArea || tabsArea || actionsArea || searchArea; |
|
|
if (!hasContent) return null; |
|
|
|
|
|
return ( |
|
|
<div className='flex flex-col w-full'> |
|
|
{/* 统计信息区域 - 用于type2 */} |
|
|
{type === 'type2' && statsArea && <>{statsArea}</>} |
|
|
|
|
|
{} |
|
|
{(type === 'type1' || type === 'type3') && descriptionArea && ( |
|
|
<>{descriptionArea}</> |
|
|
)} |
|
|
|
|
|
{} |
|
|
{((type === 'type1' || type === 'type3') && descriptionArea) || |
|
|
(type === 'type2' && statsArea) ? ( |
|
|
<Divider margin='12px' /> |
|
|
) : null} |
|
|
|
|
|
{} |
|
|
{type === 'type3' && tabsArea && <>{tabsArea}</>} |
|
|
|
|
|
{} |
|
|
{isMobile && hasMobileHideableContent && ( |
|
|
<> |
|
|
<div className='w-full mb-2'> |
|
|
<Button |
|
|
onClick={toggleMobileActions} |
|
|
icon={showMobileActions ? <IconEyeClosed /> : <IconEyeOpened />} |
|
|
type='tertiary' |
|
|
size='small' |
|
|
theme='outline' |
|
|
block |
|
|
> |
|
|
{showMobileActions ? t('隐藏操作项') : t('显示操作项')} |
|
|
</Button> |
|
|
</div> |
|
|
</> |
|
|
)} |
|
|
|
|
|
{} |
|
|
<div |
|
|
className={`flex flex-col gap-2 ${isMobile && !showMobileActions ? 'hidden' : ''}`} |
|
|
> |
|
|
{} |
|
|
{(type === 'type1' || type === 'type3') && |
|
|
actionsArea && |
|
|
(Array.isArray(actionsArea) ? ( |
|
|
actionsArea.map((area, idx) => ( |
|
|
<React.Fragment key={idx}> |
|
|
{idx !== 0 && <Divider />} |
|
|
<div className='w-full'>{area}</div> |
|
|
</React.Fragment> |
|
|
)) |
|
|
) : ( |
|
|
<div className='w-full'>{actionsArea}</div> |
|
|
))} |
|
|
|
|
|
{} |
|
|
{actionsArea && searchArea && <Divider />} |
|
|
|
|
|
{} |
|
|
{searchArea && <div className='w-full'>{searchArea}</div>} |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|
|
|
const headerContent = renderHeader(); |
|
|
|
|
|
|
|
|
const renderFooter = () => { |
|
|
if (!paginationArea) return null; |
|
|
|
|
|
return ( |
|
|
<div |
|
|
className={`flex w-full pt-4 border-t ${isMobile ? 'justify-center' : 'justify-between items-center'}`} |
|
|
style={{ borderColor: 'var(--semi-color-border)' }} |
|
|
> |
|
|
{paginationArea} |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|
|
|
const footerContent = renderFooter(); |
|
|
|
|
|
return ( |
|
|
<Card |
|
|
className={`table-scroll-card !rounded-2xl ${className}`} |
|
|
title={headerContent} |
|
|
footer={footerContent} |
|
|
shadows={shadows} |
|
|
bordered={bordered} |
|
|
style={style} |
|
|
{...props} |
|
|
> |
|
|
{children} |
|
|
</Card> |
|
|
); |
|
|
}; |
|
|
|
|
|
CardPro.propTypes = { |
|
|
|
|
|
type: PropTypes.oneOf(['type1', 'type2', 'type3']), |
|
|
|
|
|
className: PropTypes.string, |
|
|
style: PropTypes.object, |
|
|
shadows: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), |
|
|
bordered: PropTypes.bool, |
|
|
|
|
|
statsArea: PropTypes.node, |
|
|
descriptionArea: PropTypes.node, |
|
|
tabsArea: PropTypes.node, |
|
|
actionsArea: PropTypes.oneOfType([ |
|
|
PropTypes.node, |
|
|
PropTypes.arrayOf(PropTypes.node), |
|
|
]), |
|
|
searchArea: PropTypes.node, |
|
|
paginationArea: PropTypes.node, |
|
|
|
|
|
children: PropTypes.node, |
|
|
|
|
|
t: PropTypes.func, |
|
|
}; |
|
|
|
|
|
export default CardPro; |
|
|
|