fix(ui): 抽屉/对话框内 Select 等弹层不再误关抽屉

抽屉内 Radix 弹层(Select 下拉等)portal 到抽屉外,开着弹层时点遮罩,同一次
pointerdown 被 Select 与 Sheet 两个 DismissableLayer 处理:Select 先关闭且是
discrete 事件、React 同步 flush,轮到 Sheet 判断时弹层 data-state 已翻成 closed,
"当下检测弹层是否打开"不可靠,导致抽屉被连带关闭。

改为在 pointerdown 的 capture 阶段(早于 Radix 冒泡监听)先记录"此刻有无弹层开着",
onInteractOutside 据此:开着弹层时点遮罩→只收弹层不关抽屉;无弹层时点遮罩→正常关闭。
下沉到 sheet.tsx/dialog.tsx 基础组件,一次覆盖所有含下拉的抽屉/对话框;移除 agents
页此前重复的 per-callsite 处理。已用无头浏览器验证三种场景(点选项/点遮罩收下拉/
无弹层点遮罩关闭)均正确。

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Autumn-27andClaude Opus 4.8 committed 2026-08-09 03:17:49 -04:00
1 parent f86885ec3d
commit aab6b9c948
4 files changed
+68 -11

No files matched your search

@@ -258,15 +258,6 @@ export default function AgentsPage() {
<SheetContent
side="right"
className="flex flex-col gap-0 p-0 data-[side=right]:w-[45vw] data-[side=right]:sm:max-w-[45vw]"
// 抽屉内的下拉/弹出层(Select 等)会 portal 到抽屉外;交互源自这些弹出层时
// 不要把它当成「点击外部」而关闭抽屉。注意:Radix 的 onInteractOutside 里
// e.target 是层节点本身,真正被点的元素在 e.detail.originalEvent.target。
onInteractOutside={(e) => {
const t = e.detail.originalEvent.target as Element | null;
if (t?.closest?.("[data-radix-popper-content-wrapper],[data-radix-select-content],[role='listbox']")) {
e.preventDefault();
}
}}
>
{editing && (
<>