fix(canvas): 创作引用 - 收敛引用范围并修复参考图任务提交

This commit is contained in:
ddCat
2026-08-02 23:20:38 +08:00
parent 78d8928b45
commit c1561df720
4 changed files with 55 additions and 132 deletions

View File

@@ -36,11 +36,12 @@ type Props = Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, "onChange" | "val
onSubmit?: () => void;
containerClassName?: string;
highlightLabels?: boolean;
mentionMenuWidth?: number;
onContentSizeChange?: (height: number) => void;
};
export const CanvasResourceMentionTextarea = forwardRef<HTMLTextAreaElement, Props>(function CanvasResourceMentionTextarea(
{ value, references, onChange, onSubmit, onKeyDown, className, containerClassName, style, highlightLabels = true, onContentSizeChange, ...props },
{ value, references, onChange, onSubmit, onKeyDown, className, containerClassName, style, highlightLabels = true, mentionMenuWidth = 256, onContentSizeChange, ...props },
forwardedRef,
) {
const theme = canvasThemes[useThemeStore((state) => state.theme)];
@@ -182,7 +183,7 @@ export const CanvasResourceMentionTextarea = forwardRef<HTMLTextAreaElement, Pro
caretColor: style?.color || theme.node.text,
} as CSSProperties;
const menuAnchor = useRichEditor ? editorRef.current : textareaRef.current;
const menu = mention && candidates.length && menuAnchor ? <MentionMenu anchor={menuAnchor} references={candidates} activeIndex={Math.min(activeIndex, candidates.length - 1)} theme={theme} onSelect={insertReference} /> : null;
const menu = mention && candidates.length && menuAnchor ? <MentionMenu anchor={menuAnchor} references={candidates} activeIndex={Math.min(activeIndex, candidates.length - 1)} theme={theme} preferredWidth={mentionMenuWidth} onSelect={insertReference} /> : null;
if (useRichEditor) {
return (
@@ -388,11 +389,11 @@ function createInlinePreview(reference: CanvasResourceReference) {
return fallback;
}
function MentionMenu({ anchor, references, activeIndex, theme, onSelect }: { anchor: HTMLElement; references: CanvasResourceReference[]; activeIndex: number; theme: (typeof canvasThemes)[keyof typeof canvasThemes]; onSelect: (reference: CanvasResourceReference) => void }) {
function MentionMenu({ anchor, references, activeIndex, theme, preferredWidth, onSelect }: { anchor: HTMLElement; references: CanvasResourceReference[]; activeIndex: number; theme: (typeof canvasThemes)[keyof typeof canvasThemes]; preferredWidth: number; onSelect: (reference: CanvasResourceReference) => void }) {
const selectedRef = useRef(false);
const rect = anchor.getBoundingClientRect();
const boundary = anchor.closest(".ant-modal-content")?.getBoundingClientRect() || { left: 8, top: 8, right: window.innerWidth - 8, bottom: window.innerHeight - 8 };
const menuWidth = 256;
const menuWidth = Math.min(preferredWidth, Math.max(0, boundary.right - boundary.left - 16));
const maxMenuHeight = 224;
const gap = 6;
const left = clamp(rect.left, boundary.left + 8, boundary.right - menuWidth - 8);
@@ -411,8 +412,8 @@ function MentionMenu({ anchor, references, activeIndex, theme, onSelect }: { anc
return createPortal(
<div
data-canvas-resource-mention-menu="true"
className="fixed z-[1300] max-h-56 w-64 overflow-y-auto rounded-xl border p-1 shadow-2xl backdrop-blur-md"
style={{ left, top, background: theme.toolbar.panel, borderColor: theme.toolbar.border, color: theme.node.text }}
className="fixed z-[1300] max-h-56 overflow-y-auto rounded-xl border p-1 shadow-2xl backdrop-blur-md"
style={{ left, top, width: menuWidth, background: theme.toolbar.panel, borderColor: theme.toolbar.border, color: theme.node.text }}
onPointerDown={stopCanvasInteraction}
onMouseDown={stopCanvasInteraction}
onClick={(event) => event.stopPropagation()}
@@ -436,7 +437,7 @@ function MentionMenu({ anchor, references, activeIndex, theme, onSelect }: { anc
>
<ReferencePreview reference={reference} />
<span className="min-w-0 flex-1">
<span className="block font-medium">{reference.label}</span>
<span className="block truncate font-medium" title={reference.label}>{reference.label}</span>
{reference.kind !== "skill" ? <span className="block truncate opacity-65">{reference.text || reference.title}</span> : null}
</span>
</button>