feat(miniprogram): 通用组件 + 页面接入 — Chunk 7
- 创建 EmptyState/ErrorState/Loading 三个通用组件 - 8个列表页面接入通用组件替换内联空状态/loading - app.config.ts 添加 login 页面路由
This commit is contained in:
37
apps/miniprogram/src/components/EmptyState/index.scss
Normal file
37
apps/miniprogram/src/components/EmptyState/index.scss
Normal file
@@ -0,0 +1,37 @@
|
||||
@import '../../styles/variables.scss';
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120px 40px;
|
||||
}
|
||||
|
||||
.empty-state-icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.empty-state-text {
|
||||
font-size: 30px;
|
||||
color: $tx2;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.empty-state-hint {
|
||||
font-size: 24px;
|
||||
color: $tx3;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.empty-state-action {
|
||||
background: $pri;
|
||||
border-radius: 40px;
|
||||
padding: 16px 48px;
|
||||
}
|
||||
|
||||
.empty-state-action-text {
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
}
|
||||
32
apps/miniprogram/src/components/EmptyState/index.tsx
Normal file
32
apps/miniprogram/src/components/EmptyState/index.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import './index.scss';
|
||||
|
||||
interface EmptyStateProps {
|
||||
icon?: string;
|
||||
text: string;
|
||||
hint?: string;
|
||||
actionText?: string;
|
||||
onAction?: () => void;
|
||||
}
|
||||
|
||||
export default function EmptyState({
|
||||
icon = '📭',
|
||||
text,
|
||||
hint,
|
||||
actionText,
|
||||
onAction,
|
||||
}: EmptyStateProps) {
|
||||
return (
|
||||
<View className='empty-state'>
|
||||
<Text className='empty-state-icon'>{icon}</Text>
|
||||
<Text className='empty-state-text'>{text}</Text>
|
||||
{hint && <Text className='empty-state-hint'>{hint}</Text>}
|
||||
{actionText && onAction && (
|
||||
<View className='empty-state-action' onClick={onAction}>
|
||||
<Text className='empty-state-action-text'>{actionText}</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
32
apps/miniprogram/src/components/ErrorState/index.scss
Normal file
32
apps/miniprogram/src/components/ErrorState/index.scss
Normal file
@@ -0,0 +1,32 @@
|
||||
@import '../../styles/variables.scss';
|
||||
|
||||
.error-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120px 40px;
|
||||
}
|
||||
|
||||
.error-state-icon {
|
||||
font-size: 80px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.error-state-text {
|
||||
font-size: 28px;
|
||||
color: $tx2;
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.error-state-retry {
|
||||
background: $pri;
|
||||
border-radius: 40px;
|
||||
padding: 16px 48px;
|
||||
}
|
||||
|
||||
.error-state-retry-text {
|
||||
font-size: 28px;
|
||||
color: #fff;
|
||||
}
|
||||
25
apps/miniprogram/src/components/ErrorState/index.tsx
Normal file
25
apps/miniprogram/src/components/ErrorState/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import './index.scss';
|
||||
|
||||
interface ErrorStateProps {
|
||||
text?: string;
|
||||
onRetry?: () => void;
|
||||
}
|
||||
|
||||
export default function ErrorState({
|
||||
text = '加载失败,请稍后重试',
|
||||
onRetry,
|
||||
}: ErrorStateProps) {
|
||||
return (
|
||||
<View className='error-state'>
|
||||
<Text className='error-state-icon'>⚠️</Text>
|
||||
<Text className='error-state-text'>{text}</Text>
|
||||
{onRetry && (
|
||||
<View className='error-state-retry' onClick={onRetry}>
|
||||
<Text className='error-state-retry-text'>重新加载</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
30
apps/miniprogram/src/components/Loading/index.scss
Normal file
30
apps/miniprogram/src/components/Loading/index.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
@import '../../styles/variables.scss';
|
||||
|
||||
.loading-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80px 40px;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 4px solid $bd;
|
||||
border-top-color: $pri;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-state-text {
|
||||
font-size: 26px;
|
||||
color: $tx3;
|
||||
}
|
||||
16
apps/miniprogram/src/components/Loading/index.tsx
Normal file
16
apps/miniprogram/src/components/Loading/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import './index.scss';
|
||||
|
||||
interface LoadingProps {
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export default function Loading({ text = '加载中...' }: LoadingProps) {
|
||||
return (
|
||||
<View className='loading-state'>
|
||||
<View className='loading-spinner' />
|
||||
<Text className='loading-state-text'>{text}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user