mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 01:18:34 +00:00
height toggles to work
This commit is contained in:
1 parent
04a5637dc0
commit
3f93fa835e
2 files changed
+29
-17
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faUser } from "@fortawesome/pro-solid-svg-icons";
|
||||
@@ -24,7 +24,6 @@ interface MentionTextareaProps {
|
||||
onBlur?: () => void;
|
||||
disabled?: boolean;
|
||||
colorMap: Record<string, string>;
|
||||
maxHeight?: number;
|
||||
}
|
||||
|
||||
interface MentionState {
|
||||
@@ -241,7 +240,7 @@ function MentionDropdown({
|
||||
// MentionTextarea Component
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export function MentionTextarea({
|
||||
export const MentionTextarea = forwardRef<HTMLDivElement, MentionTextareaProps>(function MentionTextarea({
|
||||
value,
|
||||
onChange,
|
||||
mentionItems,
|
||||
@@ -252,9 +251,9 @@ export function MentionTextarea({
|
||||
onBlur,
|
||||
disabled,
|
||||
colorMap,
|
||||
maxHeight,
|
||||
}: MentionTextareaProps) {
|
||||
}, ref) {
|
||||
const editorRef = useRef<HTMLDivElement>(null);
|
||||
useImperativeHandle(ref, () => editorRef.current!, []);
|
||||
const isInternalUpdate = useRef(false);
|
||||
const isComposing = useRef(false);
|
||||
const pendingCaret = useRef<number | null>(null);
|
||||
@@ -498,6 +497,17 @@ export function MentionTextarea({
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Shift+Enter (or Cmd+Enter on Mac): insert a newline instead of
|
||||
// letting the contentEditable create a <div>
|
||||
if (e.key === "Enter" && (e.shiftKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
document.execCommand("insertLineBreak");
|
||||
// Trigger input handler so the parent value stays in sync
|
||||
handleInput();
|
||||
return;
|
||||
}
|
||||
|
||||
externalOnKeyDown?.(e);
|
||||
},
|
||||
[
|
||||
@@ -506,6 +516,7 @@ export function MentionTextarea({
|
||||
filteredItems,
|
||||
handleSelect,
|
||||
externalOnKeyDown,
|
||||
handleInput,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -553,7 +564,6 @@ export function MentionTextarea({
|
||||
className,
|
||||
"outline-none whitespace-pre-wrap break-words overflow-y-auto",
|
||||
)}
|
||||
style={maxHeight ? { maxHeight } : undefined}
|
||||
/>
|
||||
|
||||
{mentionState.isOpen && filteredItems.length > 0 && (
|
||||
@@ -569,4 +579,4 @@ export function MentionTextarea({
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -172,8 +172,9 @@ export const PromptBoxVideo = ({
|
||||
const toggleExpand = () => {
|
||||
setIsExpanded((prev) => {
|
||||
const next = !prev;
|
||||
if (textareaRef.current) {
|
||||
textareaRef.current.style.height = next ? EXPANDED_HEIGHT : "auto";
|
||||
const el = (mentionEditorRef.current ?? textareaRef.current) as HTMLElement | null;
|
||||
if (el) {
|
||||
el.style.height = next ? EXPANDED_HEIGHT : "auto";
|
||||
}
|
||||
return next;
|
||||
});
|
||||
@@ -226,17 +227,18 @@ export const PromptBoxVideo = ({
|
||||
useState<PopoverItem[]>(aspectRatioOptions);
|
||||
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const mentionEditorRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Apply height constraints to whichever editor element is active
|
||||
useEffect(() => {
|
||||
if (textareaRef.current) {
|
||||
// Hard pixel limit so the resize handle can never exceed viewport
|
||||
const el = (mentionEditorRef.current ?? textareaRef.current) as HTMLElement | null;
|
||||
if (el) {
|
||||
const maxH = isExpanded ? 500 : Math.min(window.innerHeight - 700, 500);
|
||||
textareaRef.current.style.maxHeight = `${Math.max(maxH, 88)}px`;
|
||||
textareaRef.current.style.minHeight = "0";
|
||||
el.style.maxHeight = `${Math.max(maxH, 88)}px`;
|
||||
el.style.minHeight = "0";
|
||||
if (!isExpanded) {
|
||||
// Cap auto-grow at ~5.5em so it doesn't fight with manual resize
|
||||
const capped = Math.min(textareaRef.current.scrollHeight, 88);
|
||||
textareaRef.current.style.minHeight = `${capped}px`;
|
||||
const capped = Math.min(el.scrollHeight, 88);
|
||||
el.style.minHeight = `${capped}px`;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -894,11 +896,11 @@ export const PromptBoxVideo = ({
|
||||
<div className="promptbox-resize-wrap relative flex-1">
|
||||
{hasAnyMentionables ? (
|
||||
<MentionTextarea
|
||||
ref={mentionEditorRef}
|
||||
value={prompt}
|
||||
onChange={setPrompt}
|
||||
mentionItems={allMentionItems}
|
||||
colorMap={mentionColorMap}
|
||||
maxHeight={isExpanded ? 500 : Math.max(Math.min(window.innerHeight - 700, 500), 88)}
|
||||
placeholder={
|
||||
isReferenceMode
|
||||
? "Use @Image1, @Video1, @Audio1... to reference uploads in prompt..."
|
||||
|
||||
Reference in new issue
Block a user