fix: 约束 AGC 素材候选弹层到输入框范围

- 类型提示改为固定定位并按输入框宽度约束

- 根据上下可用空间选择展开方向

- 避免弹层越过聊天栏覆盖其它区域
This commit is contained in:
2026-09-08 19:45:12 +08:00
parent 5f36ab8081
commit e726dc41b8
@@ -367,15 +367,48 @@ function ResourceReferenceEditor({
);
const renderMentionMenu: MenuRenderFn<ResourceMentionOption> = useCallback(
(anchorElementRef, itemProps) => {
if (!anchorElementRef.current || itemProps.options.length === 0) {
(_anchorElementRef, itemProps) => {
const inputRect = rootRef.current?.getBoundingClientRect();
if (!inputRect || itemProps.options.length === 0) {
return null;
}
const viewportPadding = 12;
const menuWidth = Math.min(
Math.max(280, inputRect.width),
Math.min(420, window.innerWidth - viewportPadding * 2),
);
const left = Math.min(
Math.max(viewportPadding, inputRect.left),
Math.max(
viewportPadding,
window.innerWidth - menuWidth - viewportPadding,
),
);
const availableAbove = Math.max(0, inputRect.top - viewportPadding - 8);
const availableBelow = Math.max(
0,
window.innerHeight - inputRect.bottom - viewportPadding - 8,
);
const openAbove = availableBelow < 160 && availableAbove > availableBelow;
const maxHeight = Math.max(
120,
Math.min(240, openAbove ? availableAbove : availableBelow),
);
const top = openAbove
? Math.max(viewportPadding, inputRect.top - maxHeight - 8)
: inputRect.bottom + 8;
return createPortal(
<div
className="resource-reference-menu"
role="listbox"
aria-label="候选素材"
style={{
position: 'fixed',
top: `${top}px`,
left: `${left}px`,
width: `${menuWidth}px`,
maxHeight: `${maxHeight}px`,
}}
>
{itemProps.options.map((option, index) => (
<button
@@ -396,7 +429,7 @@ function ResourceReferenceEditor({
</button>
))}
</div>,
anchorElementRef.current,
document.body,
);
},
[],