| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import { useEffect, useRef, useState } from 'react';
- import { Input, Modal } from 'antd';
- import type { InputRef } from 'antd';
- import { useTranslation } from 'react-i18next';
- import JsonEditor from '@/components/form/JsonEditor';
- interface PromptModalProps {
- open: boolean;
- onClose: () => void;
- title: string;
- okText?: string;
- type?: 'input' | 'textarea';
- initialValue?: string;
- loading?: boolean;
- json?: boolean;
- onConfirm: (value: string) => void;
- }
- export default function PromptModal({
- open,
- onClose,
- title,
- okText,
- type = 'input',
- initialValue = '',
- loading = false,
- json = false,
- onConfirm,
- }: PromptModalProps) {
- const { t } = useTranslation();
- const [value, setValue] = useState('');
- const textareaRef = useRef<HTMLTextAreaElement | null>(null);
- const inputRef = useRef<InputRef | null>(null);
- const [openedWith, setOpenedWith] = useState<string | null>(null);
- const openKey = open ? `${type}\u0000${initialValue}` : null;
- if (openKey !== openedWith) {
- setOpenedWith(openKey);
- if (open) setValue(initialValue);
- }
- useEffect(() => {
- if (!open) return;
- const id = setTimeout(() => {
- if (type === 'textarea') textareaRef.current?.focus();
- else inputRef.current?.focus();
- }, 50);
- return () => clearTimeout(id);
- }, [open, type]);
- function onKeydown(e: React.KeyboardEvent<HTMLTextAreaElement | HTMLInputElement>) {
- if (type !== 'textarea' && e.key === 'Enter') {
- e.preventDefault();
- onConfirm(value);
- return;
- }
- if (type === 'textarea' && e.ctrlKey && e.key.toLowerCase() === 's') {
- e.preventDefault();
- onConfirm(value);
- }
- }
- return (
- <Modal
- open={open}
- title={title}
- okText={okText ?? t('confirm')}
- cancelText={t('cancel')}
- mask={{ closable: false }}
- confirmLoading={loading}
- onOk={() => onConfirm(value)}
- onCancel={onClose}
- destroyOnHidden
- >
- {json ? (
- <JsonEditor value={value} onChange={setValue} minHeight="240px" maxHeight="60vh" />
- ) : type === 'textarea' ? (
- <Input.TextArea
- ref={(el) => {
- textareaRef.current =
- (el as unknown as { resizableTextArea?: { textArea: HTMLTextAreaElement } })
- ?.resizableTextArea?.textArea ?? null;
- }}
- aria-label={title}
- value={value}
- onChange={(e) => setValue(e.target.value)}
- autoSize={{ minRows: 10, maxRows: 20 }}
- onKeyDown={onKeydown}
- />
- ) : (
- <Input
- ref={inputRef}
- aria-label={title}
- value={value}
- onChange={(e) => setValue(e.target.value)}
- onKeyDown={onKeydown}
- />
- )}
- </Modal>
- );
- }
|