110 lines
2.5 KiB
TypeScript
110 lines
2.5 KiB
TypeScript
import React, { useEffect, useState } from "react";
|
|
import { Input, Button } from "antd";
|
|
import { DeleteOutlined } from "@ant-design/icons";
|
|
|
|
interface InputListProps {
|
|
value?: string[];
|
|
onChange?: (value: string[]) => void;
|
|
placeholder?: string;
|
|
}
|
|
|
|
const InputList: React.FC<InputListProps> = ({
|
|
value,
|
|
onChange,
|
|
placeholder = "请输入内容",
|
|
}) => {
|
|
// Internal state management with fallback to initial value or empty array
|
|
const [inputValues, setInputValues] = useState<string[]>([""]);
|
|
|
|
// Update inputValues when value changes
|
|
useEffect(() => {
|
|
if (value && value.length > 0) {
|
|
setInputValues(value);
|
|
} else {
|
|
setInputValues([""]);
|
|
}
|
|
}, [value]);
|
|
|
|
// Handle individual input value change
|
|
const handleInputChange = (index: number, newValue: string) => {
|
|
const newValues = [...inputValues];
|
|
newValues[index] = newValue;
|
|
|
|
// Update internal state
|
|
setInputValues(newValues);
|
|
|
|
// Call external onChange if provided
|
|
onChange?.(newValues);
|
|
};
|
|
|
|
// Handle delete operation
|
|
const handleDelete = (index: number) => {
|
|
const newValues = inputValues.filter((_, i) => i !== index);
|
|
|
|
// Ensure at least one input remains
|
|
const finalValues = newValues.length === 0 ? [""] : newValues;
|
|
|
|
// Update internal state
|
|
setInputValues(finalValues);
|
|
|
|
// Call external onChange if provided
|
|
onChange?.(finalValues);
|
|
};
|
|
|
|
// Add new input field
|
|
const handleAdd = () => {
|
|
const newValues = [...inputValues, ""];
|
|
|
|
// Update internal state
|
|
setInputValues(newValues);
|
|
|
|
// Call external onChange if provided
|
|
onChange?.(newValues);
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-2">
|
|
{inputValues.map((item, index) => (
|
|
<div key={index} className="flex items-center space-x-2 group">
|
|
<Input
|
|
value={item}
|
|
onChange={(e) =>
|
|
handleInputChange(index, e.target.value)
|
|
}
|
|
placeholder={placeholder}
|
|
className="flex-grow"
|
|
/>
|
|
{inputValues.length > 1 && (
|
|
<Button
|
|
type="text"
|
|
icon={<DeleteOutlined />}
|
|
danger
|
|
className="opacity-0 group-hover:opacity-100"
|
|
onClick={() => handleDelete(index)}
|
|
/>
|
|
)}
|
|
</div>
|
|
))}
|
|
<div className="flex items-center space-x-2 group">
|
|
<Button
|
|
type="dashed"
|
|
block
|
|
onClick={handleAdd}
|
|
className="w-full">
|
|
添加输入框
|
|
</Button>
|
|
{inputValues.length > 1 && (
|
|
<Button
|
|
type="text"
|
|
icon={<DeleteOutlined />}
|
|
danger
|
|
className="opacity-0"
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default InputList;
|