crush-level-web/src/app/(main)/character/[id]/chat/Input.tsx

105 lines
3.1 KiB
TypeScript
Raw Normal View History

2025-12-09 09:13:46 +00:00
'use client'
import { IconButton } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import { useState, useRef, useEffect } from 'react'
const AuthHeightTextarea = (props: React.ComponentProps<'textarea'> & { maxHeight?: number }) => {
const { maxHeight = 200, className, value, onChange, ...restProps } = props
const textareaRef = useRef<HTMLTextAreaElement>(null)
// 调整高度的函数
const adjustHeight = () => {
const textarea = textareaRef.current
if (!textarea) return
// 先重置高度为 0这样才能获取真实的 scrollHeight
textarea.style.height = '0px'
// 获取内容实际需要的高度
const scrollHeight = textarea.scrollHeight
// 计算新高度:取 scrollHeight 和 maxHeight 的较小值
const newHeight = Math.min(scrollHeight, maxHeight)
textarea.style.height = `${newHeight}px`
// 如果内容超过最大高度,显示滚动条
textarea.style.overflowY = scrollHeight > maxHeight ? 'auto' : 'hidden'
}
// 监听内容变化,自动调整高度
useEffect(() => {
adjustHeight()
}, [value, maxHeight])
return (
<textarea
ref={textareaRef}
value={value}
onChange={onChange}
className={cn(
'w-full resize-none',
// 移除所有默认样式
'border-none outline-none focus:outline-none',
'bg-transparent',
// 自定义滚动条样式(可选)
'scrollbar-thin scrollbar-thumb-white/20 scrollbar-track-transparent',
className
)}
style={{
minHeight: '24px', // 最小高度,一行文字的高度
height: '24px', // 初始高度
overflow: 'hidden', // 初始隐藏滚动条
}}
{...restProps}
/>
)
}
export default function Input() {
const [isRecording, setIsRecording] = useState(false)
const [inputValue, setInputValue] = useState('')
return (
<div className="flex mb-6 items-end gap-4">
<div></div>
<div className="flex w-full items-end gap-4">
{/* 打电话按钮 */}
<IconButton onClick={() => {}} iconfont="icon-gift-border" />
<div className="flex-1 flex items-end gap-2 min-h-12 py-2 px-2 bg-white/15 rounded-3xl">
{/* 语音录制按钮 */}
<IconButton
variant="ghost"
size="small"
iconfont="icon-voice_msg"
className="flex-shrink-0"
/>
<AuthHeightTextarea
placeholder="Chat"
maxHeight={70}
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
className="py-1"
/>
{/* 提示词提示按钮 */}
<IconButton
variant="ghost"
size="small"
onClick={() => {}}
className={cn('bg-surface-element-hover flex-shrink-0')}
iconfont="icon-prompt"
/>
</div>
<IconButton
size="large"
loading={false}
iconfont="icon-icon-send"
onClick={() => {}}
disabled={false}
className="flex-shrink-0"
/>
</div>
</div>
)
}