feat: Complete Modal and Tab UI/UX optimization

Enhanced Modal Components:
- Optimized DeleteConfirmDialog with beautiful gradients and improved layout
- Enhanced MaterialEditDialog with modern design and better information hierarchy
- Improved TemplateDetailModal with elegant header and refined tab navigation
- Enhanced AiClassificationFormDialog with modern styling

 Unified Tab System:
- Created reusable TabNavigation component with multiple variants (default, pills, underline)
- Implemented consistent tab design across ProjectDetails and other pages
- Added support for icons, counts, and disabled states in tabs
- Improved accessibility and keyboard navigation

 Advanced Animations:
- Added comprehensive modal animations (fade-in, scale-in, slide-in)
- Enhanced backdrop blur effects and smooth transitions
- Implemented proper enter/exit animations for better UX
- Added reduced motion support for accessibility

 Responsive Design:
- Optimized modal layouts for mobile, tablet, and desktop
- Improved touch-friendly interactions for mobile devices
- Enhanced modal sizing and positioning across screen sizes
- Added proper scrolling and overflow handling

 Interaction Improvements:
- Enhanced ESC key support for modal closing
- Improved backdrop click handling
- Better focus management and keyboard navigation
- Consistent button styling and hover effects

All modal and tab components now follow unified design language while maintaining full functionality.
This commit is contained in:
imeepos
2025-07-15 20:09:54 +08:00
parent 5d86a6411f
commit 887f5de793
9 changed files with 886 additions and 269 deletions

View File

@@ -199,11 +199,128 @@
}
}
/* ===== 弹框专用动画 ===== */
/* 弹框淡入动画 */
@keyframes modalFadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 弹框缩放进入动画 */
@keyframes modalScaleIn {
from {
opacity: 0;
transform: scale(0.95) translateY(-10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
/* 弹框滑入动画 */
@keyframes modalSlideIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 弹框淡出动画 */
@keyframes modalFadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
/* 弹框缩放退出动画 */
@keyframes modalScaleOut {
from {
opacity: 1;
transform: scale(1) translateY(0);
}
to {
opacity: 0;
transform: scale(0.95) translateY(-10px);
}
}
/* 弹框动画类 */
.animate-modal-fade-in {
animation: modalFadeIn 0.2s ease-out forwards;
}
.animate-modal-scale-in {
animation: modalScaleIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
.animate-modal-slide-in {
animation: modalSlideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
.animate-modal-fade-out {
animation: modalFadeOut 0.2s ease-in forwards;
}
.animate-modal-scale-out {
animation: modalScaleOut 0.2s ease-in forwards;
}
/* 背景遮罩动画 */
.modal-backdrop {
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(4px);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.modal-backdrop.entering {
background: rgba(0, 0, 0, 0);
backdrop-filter: blur(0px);
}
.modal-backdrop.exiting {
background: rgba(0, 0, 0, 0);
backdrop-filter: blur(0px);
}
/* 弹框容器样式 */
.modal-container {
position: relative;
background: white;
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
transform-origin: center;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.modal-container.large {
border-radius: 1.5rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.3);
}
/* 减少动画偏好设置 */
@media (prefers-reduced-motion: reduce) {
.animate-fade-in-up,
.hover-glow,
.card-interactive {
.card-interactive,
.animate-modal-fade-in,
.animate-modal-scale-in,
.animate-modal-slide-in,
.animate-modal-fade-out,
.animate-modal-scale-out {
animation: none !important;
transition: none !important;
}
@@ -212,6 +329,11 @@
.card-interactive:hover {
transform: none !important;
}
.modal-backdrop,
.modal-container {
transition: none !important;
}
}
.animate-fade-out {

View File

@@ -581,3 +581,106 @@
}
}
}
/* ===== 弹框响应式优化 ===== */
/* 移动端弹框优化 */
@media (max-width: 640px) {
.modal-container {
margin: 1rem;
max-height: calc(100vh - 2rem);
border-radius: 1rem;
}
.modal-container.large {
border-radius: 1rem;
}
/* 移动端弹框头部 */
.modal-header-mobile {
padding: 1rem;
flex-direction: column;
align-items: flex-start;
gap: 0.75rem;
}
/* 移动端弹框内容 */
.modal-content-mobile {
padding: 1rem;
max-height: calc(100vh - 8rem);
overflow-y: auto;
}
/* 移动端按钮区域 */
.modal-actions-mobile {
padding: 1rem;
flex-direction: column;
gap: 0.75rem;
}
.modal-actions-mobile button {
width: 100%;
justify-content: center;
}
}
/* 平板端弹框优化 */
@media (min-width: 641px) and (max-width: 1024px) {
.modal-container {
margin: 2rem;
max-height: calc(100vh - 4rem);
}
.modal-content-tablet {
max-height: calc(100vh - 12rem);
overflow-y: auto;
}
}
/* 大屏幕弹框优化 */
@media (min-width: 1920px) {
.modal-container {
border-radius: 1.5rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.35);
}
.modal-container.large {
border-radius: 2rem;
}
}
/* 弹框内容滚动优化 */
.modal-scroll {
scrollbar-width: thin;
scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
}
.modal-scroll::-webkit-scrollbar {
width: 6px;
}
.modal-scroll::-webkit-scrollbar-track {
background: transparent;
}
.modal-scroll::-webkit-scrollbar-thumb {
background-color: rgba(156, 163, 175, 0.5);
border-radius: 3px;
}
.modal-scroll::-webkit-scrollbar-thumb:hover {
background-color: rgba(156, 163, 175, 0.7);
}
/* 弹框层级管理 */
.modal-z-index {
z-index: 1000;
}
.modal-z-index.high {
z-index: 1100;
}
.modal-z-index.highest {
z-index: 1200;
}