flnxi-Wu/components/ui/PromptDialog.tsx
WuYongJie 8705b9846a
Some checks failed
CI Check / check (push) Has been cancelled
feat: 统一弹窗样式系统与分类管理优化
- 创建统一的Modal组件,采用Apple风格设计
- 实现毛玻璃效果、圆角、动画和细边框描边
- 修复弹窗打开时背景滚动问题
- 修复分类管理中重复卡片和数组字符串显示问题
- 优化选项解析逻辑,添加去重和过滤机制
2025-11-25 09:37:00 +08:00

125 lines
2.9 KiB
TypeScript

/**
* PromptDialog 组件
*
* 输入对话框组件
* 基于 Modal 组件构建,用于获取用户输入
* 支持默认值、占位符、键盘导航等
*
* @created 2025-11-22
* @component
*/
'use client'
import { useState, useEffect, useRef } from 'react'
import Modal from './Modal'
import { useThemeStyles, cn } from '@/lib/ui-styles'
interface PromptDialogProps {
isOpen: boolean
onClose: () => void
onConfirm: (value: string) => void
title: string
message: string
defaultValue?: string
placeholder?: string
confirmText?: string
cancelText?: string
}
export default function PromptDialog({
isOpen,
onClose,
onConfirm,
title,
message,
defaultValue = '',
placeholder = '',
confirmText = '确认',
cancelText = '取消',
}: PromptDialogProps) {
const styles = useThemeStyles()
const [value, setValue] = useState(defaultValue)
const inputRef = useRef<HTMLInputElement>(null)
useEffect(() => {
if (isOpen) {
setValue(defaultValue)
// 延迟聚焦,确保弹窗已渲染
setTimeout(() => {
const input = inputRef.current
if (input) {
input.focus()
const length = input.value.length
input.setSelectionRange(length, length)
}
}, 100)
}
}, [isOpen, defaultValue])
const handleConfirm = () => {
if (value.trim()) {
onConfirm(value.trim())
onClose()
}
}
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleConfirm()
} else if (e.key === 'Escape') {
onClose()
}
}
return (
<Modal
isOpen={isOpen}
onClose={onClose}
title={title}
size="xs"
footer={
<>
<button
type="button"
onClick={onClose}
className={cn(
styles.buttonStyles.secondary,
styles.buttonModifiers.compact,
'bg-white dark:bg-slate-800 border-slate-300 dark:border-slate-600 text-slate-700 dark:text-slate-200' // 显式添加背景色和文字色
)}
>
{cancelText}
</button>
<button
type="button"
onClick={handleConfirm}
disabled={!value.trim()}
className={cn(
styles.buttonStyles.primary,
styles.buttonModifiers.compact,
'bg-indigo-600 hover:bg-indigo-700 text-white' // 显式添加背景色和文字色
)}
>
{confirmText}
</button>
</>
}
>
<div className="py-2 space-y-3">
<p className="text-slate-700 dark:text-slate-200 whitespace-pre-line">{message}</p>
<input
ref={inputRef}
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
onKeyDown={handleKeyDown}
placeholder={placeholder}
className={styles.inputStyles.base}
/>
</div>
</Modal>
)
}