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 () => {
|
const handleCreateVideo = async () => {
|
||||||
if (isCreating) return; // 如果正在创建中,直接返回
|
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 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">
|
<div className="video-prompt-editor mb-3 relative flex flex-col gap-3 flex-1 pr-10">
|
||||||
{/* 文本输入框 - 改为textarea */}
|
{/* 文本输入框 - 改为textarea */}
|
||||||
<textarea
|
<textarea
|
||||||
value={script}
|
data-alt="story-input"
|
||||||
onChange={(e) => setScript(e.target.value)}
|
ref={textareaRef}
|
||||||
placeholder="Describe the story you want to make..."
|
value={script}
|
||||||
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"
|
onChange={(e) => setScript(e.target.value)}
|
||||||
style={{
|
placeholder="Describe the story you want to make..."
|
||||||
minHeight: noData ? "128px": "unset"
|
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={{
|
||||||
rows={1}
|
minHeight: noData ? "128px" : (isMobile ? (isInputFocused ? "96px" : "48px") : "unset"),
|
||||||
onInput={(e) => {
|
maxHeight: isMobile ? (isInputFocused ? "200px" : (persistedMobileMaxHeight ? `${persistedMobileMaxHeight}px` : "120px")) : undefined,
|
||||||
const target = e.target as HTMLTextAreaElement;
|
}}
|
||||||
target.style.height = "auto";
|
rows={1}
|
||||||
target.style.height =
|
onFocus={() => {
|
||||||
Math.min(target.scrollHeight, 120) + "px";
|
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>
|
</div>
|
||||||
|
|
||||||
{/* 第二行:功能按钮和Action按钮 - 同一行 */}
|
{/* 第二行:功能按钮和Action按钮 - 同一行 */}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user