forked from 77media/video-flow
聚焦创作输入框高度变大
This commit is contained in:
parent
dd63923e97
commit
f6dff7eb49
@ -244,6 +244,11 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
|
||||
}
|
||||
}, []);
|
||||
|
||||
// H5 文本输入框聚焦动画控制
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const [isInputFocused, setIsInputFocused] = useState(false);
|
||||
const [persistedMobileMaxHeight, setPersistedMobileMaxHeight] = useState<number | null>(null);
|
||||
|
||||
const handleCreateVideo = async () => {
|
||||
if (isCreating) return; // 如果正在创建中,直接返回
|
||||
|
||||
@ -342,23 +347,77 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
|
||||
<div data-alt="chat-input-box" className="flex flex-col w-full">
|
||||
{/* 第一行:输入框 */}
|
||||
<div className="video-prompt-editor mb-3 relative flex flex-col gap-3 flex-1 pr-10">
|
||||
{/* 文本输入框 - 改为textarea */}
|
||||
<textarea
|
||||
value={script}
|
||||
onChange={(e) => setScript(e.target.value)}
|
||||
placeholder="Describe the story you want to make..."
|
||||
className="w-full pl-[10px] pr-[10px] py-[14px] rounded-[10px] leading-[20px] text-sm border-none bg-transparent text-white placeholder:text-white/[0.40] focus:outline-none resize-none min-h-[48px] max-h-[120px] overflow-y-auto"
|
||||
style={{
|
||||
minHeight: noData ? "128px": "unset"
|
||||
}}
|
||||
rows={1}
|
||||
onInput={(e) => {
|
||||
const target = e.target as HTMLTextAreaElement;
|
||||
target.style.height = "auto";
|
||||
target.style.height =
|
||||
Math.min(target.scrollHeight, 120) + "px";
|
||||
}}
|
||||
/>
|
||||
{/* 文本输入框 - 改为textarea */}
|
||||
<textarea
|
||||
data-alt="story-input"
|
||||
ref={textareaRef}
|
||||
value={script}
|
||||
onChange={(e) => setScript(e.target.value)}
|
||||
placeholder="Describe the story you want to make..."
|
||||
className={`w-full pl-[10px] pr-[10px] py-[14px] rounded-[10px] leading-[20px] text-sm border-none bg-transparent text-white placeholder:text-white/[0.40] focus:outline-none resize-none overflow-y-auto transition-all duration-300 ease-in-out ${isMobile ? '' : 'max-h-[120px]'}`}
|
||||
style={{
|
||||
minHeight: noData ? "128px" : (isMobile ? (isInputFocused ? "96px" : "48px") : "unset"),
|
||||
maxHeight: isMobile ? (isInputFocused ? "200px" : (persistedMobileMaxHeight ? `${persistedMobileMaxHeight}px` : "120px")) : undefined,
|
||||
}}
|
||||
rows={1}
|
||||
onFocus={() => {
|
||||
if (!isMobile) return;
|
||||
setIsInputFocused(true);
|
||||
const el = textareaRef.current;
|
||||
if (el) {
|
||||
const limit = 200;
|
||||
// 以当前高度为起点,过渡到目标高度
|
||||
const start = `${el.getBoundingClientRect().height}px`;
|
||||
const end = `${Math.min(Math.max(el.scrollHeight, 96), limit)}px`;
|
||||
el.style.height = start;
|
||||
void el.offsetHeight;
|
||||
el.style.height = end;
|
||||
}
|
||||
}}
|
||||
onBlur={() => {
|
||||
if (!isMobile) return;
|
||||
setIsInputFocused(false);
|
||||
const el = textareaRef.current;
|
||||
if (el) {
|
||||
const baseLimit = 120;
|
||||
const contentHeight = el.scrollHeight;
|
||||
const currentHeight = el.getBoundingClientRect().height;
|
||||
// 若内容高度已超过基础高度,则保持较大高度,不回落
|
||||
if (contentHeight > baseLimit || currentHeight > baseLimit) {
|
||||
setPersistedMobileMaxHeight(Math.min(contentHeight, 200));
|
||||
el.style.height = `${Math.min(contentHeight, 200)}px`;
|
||||
} else {
|
||||
const start = `${currentHeight}px`;
|
||||
const end = `${Math.min(contentHeight, baseLimit)}px`;
|
||||
el.style.height = start;
|
||||
void el.offsetHeight;
|
||||
el.style.height = end;
|
||||
setPersistedMobileMaxHeight(null);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onInput={(e) => {
|
||||
const target = e.target as HTMLTextAreaElement;
|
||||
const limit = isMobile && isInputFocused ? 200 : (persistedMobileMaxHeight ?? 120);
|
||||
target.style.height = "auto";
|
||||
target.style.height = Math.min(target.scrollHeight, limit) + "px";
|
||||
}}
|
||||
onTransitionEnd={() => {
|
||||
// 过渡结束后清理高度,避免下次动画受限
|
||||
if (!isMobile) return;
|
||||
if (!isInputFocused) {
|
||||
const el = textareaRef.current;
|
||||
if (el) {
|
||||
// 若已记录持久高度则保持,不清理;否则清理
|
||||
if (persistedMobileMaxHeight) {
|
||||
el.style.height = `${persistedMobileMaxHeight}px`;
|
||||
} else {
|
||||
el.style.height = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 第二行:功能按钮和Action按钮 - 同一行 */}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user