iter(g291): 下拉族七处弹层接上滚动跟随
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { Signal } from '@ui-arch/frame';
|
||||
import { bindOutside, pushOverlay } from './overlay.js';
|
||||
import { flip } from './position.js';
|
||||
import { flip, trackShift } from './position.js';
|
||||
import type { AutoCompleteOption, AutoCompleteProps } from './types.js';
|
||||
|
||||
let seq = 0; // 实例序号:给弹层列表一个稳定 id,供 aria-controls 关联
|
||||
@@ -108,6 +108,15 @@ export function autoComplete(props: AutoCompleteProps): HTMLElement {
|
||||
if (open()) releaseEsc ??= pushOverlay(() => { open(false); input.focus(); }); // 入栈逐层关闭
|
||||
else { releaseEsc?.(); releaseEsc = null; }
|
||||
});
|
||||
effect(() => { if (open()) place(flip(input, pop, 'bottom')); }); // 空间不足自动翻转
|
||||
let releaseShift: (() => void) | null = null; // 展开期间的位移跟随释放函数(滚动 / 缩放重算翻转)
|
||||
effect(() => {
|
||||
if (!open()) { // 收起即摘监听:弹层不在,重算方位没有意义
|
||||
releaseShift?.();
|
||||
releaseShift = null;
|
||||
return;
|
||||
}
|
||||
place(flip(input, pop, 'bottom')); // 打开先算一次:空间不足自动翻转
|
||||
releaseShift ??= trackShift(() => place(flip(input, pop, 'bottom'))); // 展开期间跟着滚动重算:视口空间会变
|
||||
}); // 空间不足自动翻转
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { Signal } from '@ui-arch/frame';
|
||||
import { bindOutside, pushOverlay } from './overlay.js';
|
||||
import { flip } from './position.js';
|
||||
import { flip, trackShift } from './position.js';
|
||||
import type { CascaderOption, CascaderProps } from './types.js';
|
||||
|
||||
/*** 沿路径解析节点链:路径失效时在断点截断,避免脏数据把列算错 ***/
|
||||
@@ -138,6 +138,15 @@ export function cascader(props: CascaderProps): HTMLElement {
|
||||
if (open()) releaseEsc ??= pushOverlay(() => { open(false); trigger.focus(); }); // 入栈:与弹窗/抽屉共用逐层关闭
|
||||
else { releaseEsc?.(); 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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { Signal } from '@ui-arch/frame';
|
||||
import { bindOutside, pushOverlay } from './overlay.js';
|
||||
import { flip } from './position.js';
|
||||
import { flip, trackShift } from './position.js';
|
||||
import type { ColorPickerProps } from './types.js';
|
||||
|
||||
// 缺省色板:直接取语义令牌,天然跟随暗色主题切换,不写死任何十六进制
|
||||
@@ -91,6 +91,15 @@ export function colorPicker(props: ColorPickerProps): HTMLElement {
|
||||
if (open()) releaseEsc ??= pushOverlay(() => { open(false); trigger.focus(); }); // 入栈逐层关闭
|
||||
else { releaseEsc?.(); 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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { Signal } from '@ui-arch/frame';
|
||||
import { bindOutside, pushOverlay } from './overlay.js';
|
||||
import { flip } from './position.js';
|
||||
import { flip, trackShift } from './position.js';
|
||||
import type { DatePickerProps, DatePreset } from './types.js';
|
||||
import { fmt, pad, parse, shiftDay, today } from './dateKit.js';
|
||||
|
||||
@@ -170,6 +170,15 @@ export function datePicker(props: DatePickerProps): HTMLElement {
|
||||
if (open()) releaseEsc ??= pushOverlay(() => { open(false); trigger.focus(); }); // 入栈逐层关闭
|
||||
else { releaseEsc?.(); 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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { MenuItem, MenuProps } from './types.js';
|
||||
import { flip } from './position.js';
|
||||
import { flip, trackShift } from './position.js';
|
||||
import { bindOutside, pushOverlay } from './overlay.js';
|
||||
|
||||
/*** 下拉菜单:触发器 + 自绘弹层,项支持禁用 / 危险 / 分隔线;点项 / 点外部 / Esc 关闭,↑↓ 环形导航 + Home/End 跳转 + 键入快跳 ***/
|
||||
@@ -101,6 +101,15 @@ export function menu(props: MenuProps): 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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { Signal } from '@ui-arch/frame';
|
||||
import { bindOutside, pushOverlay } from './overlay.js';
|
||||
import { flip } from './position.js';
|
||||
import { flip, trackShift } from './position.js';
|
||||
import type { MultiSelectProps } from './types.js';
|
||||
|
||||
/*** 多选下拉:标签式回显 + 可搜索弹层,value 数组信号双向绑定,到 max 未选项自动禁用 ***/
|
||||
@@ -119,6 +119,15 @@ export function multiSelect(props: MultiSelectProps): HTMLElement {
|
||||
if (open()) releaseEsc ??= pushOverlay(() => { open(false); input.focus(); }); // 入栈逐层关闭
|
||||
else { releaseEsc?.(); releaseEsc = null; }
|
||||
});
|
||||
effect(() => { if (open()) place(flip(box, pop, 'bottom')); });
|
||||
let releaseShift: (() => void) | null = null; // 展开期间的位移跟随释放函数(滚动 / 缩放重算翻转)
|
||||
effect(() => {
|
||||
if (!open()) { // 收起即摘监听:弹层不在,重算方位没有意义
|
||||
releaseShift?.();
|
||||
releaseShift = null;
|
||||
return;
|
||||
}
|
||||
place(flip(box, pop, 'bottom')); // 打开先算一次:空间不足自动翻转
|
||||
releaseShift ??= trackShift(() => place(flip(box, pop, 'bottom'))); // 展开期间跟着滚动重算:视口空间会变
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { effect, h, signal } from '@ui-arch/frame';
|
||||
import type { Signal } from '@ui-arch/frame';
|
||||
import type { TimePickerProps } from './types.js';
|
||||
import { flip } from './position.js';
|
||||
import { flip, trackShift } from './position.js';
|
||||
import { bindOutside, pushOverlay } from './overlay.js';
|
||||
|
||||
/*** 两位补零:时钟显示固定宽度,避免 9:5 这类不对齐的写法 ***/
|
||||
@@ -156,6 +156,15 @@ export function timePicker(props: TimePickerProps): 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user