Some checks failed
CI Check / check (push) Has been cancelled
- 创建统一的Modal组件,采用Apple风格设计 - 实现毛玻璃效果、圆角、动画和细边框描边 - 修复弹窗打开时背景滚动问题 - 修复分类管理中重复卡片和数组字符串显示问题 - 优化选项解析逻辑,添加去重和过滤机制
125 lines
2.9 KiB
TypeScript
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>
|
|
)
|
|
}
|
|
|