测试: - secure-storage: 26 tests (AES 加解密/明文 fallback/迁移/Base64 边界) - request.ts: 16 tests (扩展 ResponseCache/patientId 隔离/requestUnlimited) - mock-api: 修复 getCachedPatientId 缺失导致 health 测试失败 UX 无障碍 (10 组件): - SegmentTabs/DoctorTabBar: role=tablist/tab + aria-selected - PrimaryButton/SecondaryButton: role=button + aria-disabled/aria-busy - Loading/LoadingCard: role=status + aria-live=polite - EmptyState: role=status + aria-live=polite - ErrorState: role=alert + aria-live=assertive - TrendChart tooltip: role=tooltip + aria-live=polite - FormInput: aria-invalid + aria-label 焦点管理: - 新增 _focus-ring.scss mixin (focus + focus-visible) - 5 组件 SCSS 应用 focus-ring
49 lines
1.7 KiB
TypeScript
49 lines
1.7 KiB
TypeScript
import React from 'react';
|
|
import { View } from '@tarojs/components';
|
|
import './index.scss';
|
|
|
|
interface LoadingCardProps {
|
|
count?: number;
|
|
layout?: 'card' | 'list' | 'detail';
|
|
}
|
|
|
|
const LoadingCard: React.FC<LoadingCardProps> = ({
|
|
count = 3,
|
|
layout = 'card',
|
|
}) => {
|
|
return (
|
|
<View className={`loading-card-group loading-card-group--${layout}`} role="status" aria-label="内容加载中">
|
|
{Array.from({ length: count }, (_, i) => (
|
|
<View key={i} className="loading-card">
|
|
{layout === 'card' && (
|
|
<>
|
|
<View className="loading-card__line loading-card__line--title" />
|
|
<View className="loading-card__line loading-card__line--text" />
|
|
<View className="loading-card__line loading-card__line--short" />
|
|
</>
|
|
)}
|
|
{layout === 'list' && (
|
|
<View className="loading-card__row">
|
|
<View className="loading-card__circle" />
|
|
<View className="loading-card__lines">
|
|
<View className="loading-card__line loading-card__line--title" />
|
|
<View className="loading-card__line loading-card__line--short" />
|
|
</View>
|
|
</View>
|
|
)}
|
|
{layout === 'detail' && (
|
|
<>
|
|
<View className="loading-card__line loading-card__line--title" />
|
|
<View className="loading-card__line loading-card__line--text" />
|
|
<View className="loading-card__line loading-card__line--text" />
|
|
<View className="loading-card__line loading-card__line--short" />
|
|
</>
|
|
)}
|
|
</View>
|
|
))}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
export default React.memo(LoadingCard);
|