collect-system/apps/web/src/components/common/input/InputList.tsx

110 lines
2.5 KiB
TypeScript
Raw Normal View History

2025-02-23 18:59:32 +08:00
import React, { useEffect, useState } from "react";
2025-02-21 16:57:22 +08:00
import { Input, Button } from "antd";
import { DeleteOutlined } from "@ant-design/icons";
interface InputListProps {
2025-02-23 18:59:32 +08:00
value?: string[];
2025-02-21 16:57:22 +08:00
onChange?: (value: string[]) => void;
placeholder?: string;
}
const InputList: React.FC<InputListProps> = ({
2025-02-23 18:59:32 +08:00
value,
2025-02-21 16:57:22 +08:00
onChange,
placeholder = "请输入内容",
}) => {
// Internal state management with fallback to initial value or empty array
2025-02-23 18:59:32 +08:00
const [inputValues, setInputValues] = useState<string[]>([""]);
// Update inputValues when value changes
useEffect(() => {
if (value && value.length > 0) {
setInputValues(value);
} else {
setInputValues([""]);
}
}, [value]);
2025-02-21 16:57:22 +08:00
// 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;