Files
agent/app/components/MessageInput.tsx
2025-10-16 21:24:18 +08:00

135 lines
3.9 KiB
TypeScript

import React, { useState, useRef } from 'react';
import { TextField, IconButton, Box, Tooltip, CircularProgress, useTheme } from '@mui/material';
import { SendRounded } from '@mui/icons-material';
interface MessageInputProps {
value: string;
onChange: (value: string) => void;
onSend: () => void;
onKeyDown: (e: React.KeyboardEvent) => void;
disabled: boolean;
}
export const MessageInput: React.FC<MessageInputProps> = ({
value,
onChange,
onSend,
onKeyDown,
disabled
}) => {
const theme = useTheme();
const textareaRef = useRef<HTMLDivElement>(null);
const [isFocused, setIsFocused] = useState(false);
const handleFocus = () => setIsFocused(true);
const handleBlur = () => setIsFocused(false);
// 自动调整文本框高度
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
onChange(e.target.value);
// 找到实际的textarea元素
const textarea = e.target as HTMLTextAreaElement;
textarea.style.height = 'auto';
textarea.style.height = Math.min(textarea.scrollHeight, 120) + 'px';
};
return (
<Box
sx={{
p: 2,
backgroundColor: theme.palette.background.paper,
borderTop: `1px solid ${theme.palette.divider}`,
boxShadow: '0 -2px 10px rgba(0, 0, 0, 0.05)',
}}
>
<Box
display="flex"
alignItems="flex-end"
gap={1.5}
sx={{
maxWidth: '100%',
mx: 'auto',
}}
>
<TextField
ref={textareaRef}
fullWidth
variant="outlined"
placeholder="输入您的问题..."
value={value}
onChange={handleChange}
onKeyDown={onKeyDown}
onFocus={handleFocus}
onBlur={handleBlur}
disabled={disabled}
multiline
rows={1}
inputProps={{
style: {
maxHeight: '120px',
overflowY: 'auto',
padding: '10px 14px',
borderRadius: '24px',
lineHeight: 1.5,
}
}}
sx={{
'& .MuiOutlinedInput-root': {
borderRadius: 4,
'& fieldset': {
borderColor: theme.palette.divider,
borderWidth: '2px',
},
'&:hover fieldset': {
borderColor: theme.palette.primary.light,
},
'&.Mui-focused fieldset': {
borderColor: theme.palette.primary.main,
borderWidth: '2px',
},
'&.Mui-disabled fieldset': {
borderColor: theme.palette.divider,
opacity: 0.6,
}
},
transition: 'all 0.3s ease',
transform: isFocused ? 'translateY(-1px)' : 'translateY(0)',
}}
/>
<Tooltip title="发送消息" placement="top">
<IconButton
onClick={onSend}
disabled={disabled || !value.trim()}
sx={{
backgroundColor: (disabled || !value.trim())
? theme.palette.action.disabledBackground
: theme.palette.primary.main,
color: 'white',
width: 48,
height: 48,
'&:hover': {
backgroundColor: (disabled || !value.trim())
? theme.palette.action.disabledBackground
: theme.palette.primary.dark,
transform: 'scale(1.05)',
},
'&:active': {
transform: 'scale(0.95)',
},
transition: 'all 0.2s ease',
boxShadow: theme.shadows[2],
}}
aria-label="发送消息"
>
{disabled ? (
<CircularProgress size={20} color="inherit" />
) : (
<SendRounded fontSize="small" />
)}
</IconButton>
</Tooltip>
</Box>
</Box>
);
};