ImageUrlInput.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import React from 'react';
  2. import {
  3. Input,
  4. Typography,
  5. Button,
  6. } from '@douyinfe/semi-ui';
  7. import { IconFile } from '@douyinfe/semi-icons';
  8. import {
  9. FileText,
  10. Plus,
  11. X,
  12. } from 'lucide-react';
  13. const ImageUrlInput = ({ imageUrls, onImageUrlsChange }) => {
  14. const handleAddImageUrl = () => {
  15. const newUrls = [...imageUrls, ''];
  16. onImageUrlsChange(newUrls);
  17. };
  18. const handleUpdateImageUrl = (index, value) => {
  19. const newUrls = [...imageUrls];
  20. newUrls[index] = value;
  21. onImageUrlsChange(newUrls);
  22. };
  23. const handleRemoveImageUrl = (index) => {
  24. const newUrls = imageUrls.filter((_, i) => i !== index);
  25. onImageUrlsChange(newUrls);
  26. };
  27. return (
  28. <div>
  29. <div className="flex items-center justify-between mb-2">
  30. <div className="flex items-center gap-2">
  31. <FileText size={16} className="text-gray-500" />
  32. <Typography.Text strong className="text-sm">
  33. 图片地址
  34. </Typography.Text>
  35. <Typography.Text className="text-xs text-gray-400">
  36. (多模态对话)
  37. </Typography.Text>
  38. </div>
  39. <Button
  40. icon={<Plus size={14} />}
  41. size="small"
  42. theme="solid"
  43. type="primary"
  44. onClick={handleAddImageUrl}
  45. className="!rounded-full !w-4 !h-4 !p-0 !min-w-0"
  46. disabled={imageUrls.length >= 5}
  47. />
  48. </div>
  49. {imageUrls.length === 0 ? (
  50. <Typography.Text className="text-xs text-gray-500 mb-2 block">
  51. 点击 + 按钮添加图片URL,支持最多5张图片
  52. </Typography.Text>
  53. ) : (
  54. <Typography.Text className="text-xs text-gray-500 mb-2 block">
  55. 已添加 {imageUrls.length}/5 张图片
  56. </Typography.Text>
  57. )}
  58. <div className="space-y-2 max-h-32 overflow-y-auto">
  59. {imageUrls.map((url, index) => (
  60. <div key={index} className="flex items-center gap-2">
  61. <div className="flex-1">
  62. <Input
  63. placeholder={`https://example.com/image${index + 1}.jpg`}
  64. value={url}
  65. onChange={(value) => handleUpdateImageUrl(index, value)}
  66. className="!rounded-lg"
  67. size="small"
  68. prefix={<IconFile size='small' />}
  69. />
  70. </div>
  71. <Button
  72. icon={<X size={12} />}
  73. size="small"
  74. theme="borderless"
  75. type="danger"
  76. onClick={() => handleRemoveImageUrl(index)}
  77. className="!rounded-full !w-6 !h-6 !p-0 !min-w-0 !text-red-500 hover:!bg-red-50 flex-shrink-0"
  78. />
  79. </div>
  80. ))}
  81. </div>
  82. </div>
  83. );
  84. };
  85. export default ImageUrlInput;