iter(g290): 抽出 trackShift 并接到下拉弹层

This commit is contained in:
HIsheR
2026-10-26 23:20:05 +08:00
parent da166af7c3
commit 9e72607952
6 changed files with 51 additions and 36 deletions
+11 -2
View File
@@ -1,6 +1,6 @@
import { effect, h, signal } from '@ui-arch/frame';
import type { SelectProps } from './types.js';
import { flip } from './position.js';
import { flip, trackShift } from './position.js';
import { bindOutside, pushOverlay } from './overlay.js';
/*** 下拉选择:自绘弹层替代原生 select,value 信号双向绑定;searchable 时弹层顶部带搜索框,支持 ↑↓/Home/End 导航与 Esc 关闭 ***/
@@ -165,6 +165,15 @@ export function select(props: SelectProps): HTMLElement {
releaseEsc = null;
}
});
effect(() => { if (open()) place(flip(trigger, pop, 'bottom')); }); // 每次打开重算方位:空间不足自动翻转
let releaseShift: (() => void) | null = null; // 展开期间的位移跟随释放函数(滚动 / 缩放重算翻转)
effect(() => {
if (!open()) { // 收起即摘监听:弹层不在,重算方位没有意义
releaseShift?.();
releaseShift = null;
return;
}
place(flip(trigger, pop, 'bottom')); // 打开先算一次:空间不足自动翻转
releaseShift ??= trackShift(() => place(flip(trigger, pop, 'bottom'))); // 展开期间跟着滚动重算:视口空间会变
});
return root;
}