优化Modal弹框布局和尺寸控制
- 修复Modal组件尺寸类冲突问题,确保max-w-*正确生效 - 优化CreateDynamicModal表单布局,使其在小尺寸弹框中更紧凑 - 减少表单元素间距和内边距,提升视觉密度 - 优化图片预览、按钮等组件尺寸,适配sm尺寸弹框 - 移除CSS中可能干扰Tailwind尺寸类的样式设置 主要改进: - Modal组件getSizeClasses函数优化,确保w-full和max-w-*正确配合 - CreateDynamicModal表单元素紧凑化,提升小屏幕体验 - 统一弹框尺寸控制逻辑,解决宽度限制不生效问题
This commit is contained in:
parent
4da48c3281
commit
e7b48d0a7d
|
|
@ -119,8 +119,8 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
closeOnBackdropClick={false}
|
||||
>
|
||||
{/* 表单内容 */}
|
||||
<form onSubmit={handleSubmit} className="flex flex-col h-full ">
|
||||
<div className="flex-1 p-6 space-y-6 overflow-y-auto">
|
||||
<form onSubmit={handleSubmit} className="flex flex-col h-full">
|
||||
<div className="flex-1 p-4 space-y-4 overflow-y-auto">
|
||||
|
||||
{/* 提示词 */}
|
||||
<div>
|
||||
|
|
@ -132,8 +132,8 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
value={formData.prompt}
|
||||
onChange={(e) => handleInputChange('prompt', e.target.value)}
|
||||
placeholder="描述您希望生成的视频内容..."
|
||||
rows={4}
|
||||
className={`w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition-colors resize-none ${errors.prompt ? 'border-red-300' : 'border-gray-300'
|
||||
rows={3}
|
||||
className={`w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition-colors resize-none text-sm ${errors.prompt ? 'border-red-300' : 'border-gray-300'
|
||||
}`}
|
||||
/>
|
||||
{errors.prompt && (
|
||||
|
|
@ -147,18 +147,18 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
<PhotoIcon className="h-4 w-4" />
|
||||
源图片 *
|
||||
</label>
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleImageSelect}
|
||||
className={`w-full p-4 border-2 border-dashed rounded-lg transition-colors ${errors.source_image_path
|
||||
className={`w-full p-3 border-2 border-dashed rounded-lg transition-colors ${errors.source_image_path
|
||||
? 'border-red-300 bg-red-50'
|
||||
: 'border-gray-300 hover:border-primary-400 hover:bg-primary-50'
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<PhotoIcon className="h-8 w-8 text-gray-400" />
|
||||
<span className="text-sm text-gray-600">点击选择图片</span>
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<PhotoIcon className="h-5 w-5 text-gray-400" />
|
||||
<span className="text-sm text-gray-600">选择图片</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
|
|
@ -167,14 +167,14 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
<img
|
||||
src={formData.source_image_path}
|
||||
alt="源图片预览"
|
||||
className="w-full h-48 object-contain bg-gray-50 rounded-lg"
|
||||
className="w-full h-32 object-contain bg-gray-50 rounded-lg"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleInputChange('source_image_path', '')}
|
||||
className="absolute top-2 right-2 p-1 bg-red-500 text-white rounded-full hover:bg-red-600 transition-colors"
|
||||
className="absolute top-1 right-1 p-1 bg-red-500 text-white rounded-full hover:bg-red-600 transition-colors"
|
||||
>
|
||||
<XMarkIcon className="h-4 w-4" />
|
||||
<XMarkIcon className="h-3 w-3" />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -194,7 +194,7 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
<select
|
||||
value={formData.ai_model}
|
||||
onChange={(e) => handleInputChange('ai_model', e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition-colors"
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition-colors text-sm"
|
||||
>
|
||||
{aiModelOptions.map((option) => (
|
||||
<option key={option.id} value={option.name} disabled={!option.is_available}>
|
||||
|
|
@ -210,7 +210,7 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
<VideoCameraIcon className="h-4 w-4" />
|
||||
生成视频个数
|
||||
</label>
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<input
|
||||
type="range"
|
||||
min="1"
|
||||
|
|
@ -219,9 +219,12 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
onChange={(e) => handleInputChange('video_count', parseInt(e.target.value))}
|
||||
className="flex-1"
|
||||
/>
|
||||
<span className="text-sm font-medium text-gray-700 min-w-[2rem]">
|
||||
{formData.video_count}
|
||||
</span>
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
{formData.video_count}
|
||||
</span>
|
||||
<span className="text-xs text-gray-500">个</span>
|
||||
</div>
|
||||
</div>
|
||||
{errors.video_count && (
|
||||
<p className="mt-1 text-sm text-red-600">{errors.video_count}</p>
|
||||
|
|
@ -230,18 +233,18 @@ const CreateDynamicModal: React.FC<CreateDynamicModalProps> = ({
|
|||
</div>
|
||||
|
||||
{/* 底部按钮 */}
|
||||
<div className="flex items-center justify-end gap-3 p-6 border-t border-gray-200">
|
||||
<div className="flex items-center justify-end gap-3 p-4 border-t border-gray-200">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onCancel}
|
||||
className="px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
|
||||
className="px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 rounded-lg transition-colors"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
disabled={isSubmitting}
|
||||
className="px-6 py-2 bg-gradient-to-r from-primary-500 to-primary-600 text-white rounded-lg hover:from-primary-600 hover:to-primary-700 transition-all duration-200 shadow-sm hover:shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
className="px-4 py-2 text-sm bg-gradient-to-r from-primary-500 to-primary-600 text-white rounded-lg hover:from-primary-600 hover:to-primary-700 transition-all duration-200 shadow-sm hover:shadow-md font-medium disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{isSubmitting ? '生成中...' : '开始生成'}
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -88,11 +88,11 @@ export const Modal: React.FC<ModalProps> = ({
|
|||
|
||||
const getSizeClasses = () => {
|
||||
const sizeMap = {
|
||||
sm: 'max-w-md',
|
||||
md: 'max-w-lg',
|
||||
lg: 'max-w-2xl',
|
||||
xl: 'max-w-4xl',
|
||||
full: 'max-w-7xl',
|
||||
sm: 'w-full max-w-md',
|
||||
md: 'w-full max-w-lg',
|
||||
lg: 'w-full max-w-2xl',
|
||||
xl: 'w-full max-w-4xl',
|
||||
full: 'w-full max-w-7xl',
|
||||
};
|
||||
return sizeMap[size];
|
||||
};
|
||||
|
|
@ -141,7 +141,7 @@ export const Modal: React.FC<ModalProps> = ({
|
|||
{/* 弹框容器 */}
|
||||
<div
|
||||
ref={modalRef}
|
||||
className={`modal-container ${size === 'xl' || size === 'full' ? 'large' : ''} ${getSizeClasses()} w-full max-h-[90vh] animate-modal-scale-in relative z-10 ${className}`}
|
||||
className={`modal-container ${size === 'xl' || size === 'full' ? 'large' : ''} ${getSizeClasses()} max-h-[90vh] animate-modal-scale-in relative z-10 ${className}`}
|
||||
>
|
||||
{/* 头部 */}
|
||||
{(title || subtitle || icon || showCloseButton) && (
|
||||
|
|
|
|||
|
|
@ -907,7 +907,6 @@
|
|||
overflow: hidden;
|
||||
transform-origin: center;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
z-index: 1;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue