iter(g44): accordion 标题行方向键导航
This commit is contained in:
@@ -51,5 +51,25 @@ export function accordion(props: AccordionProps): HTMLElement {
|
||||
),
|
||||
);
|
||||
|
||||
return h('div', { class: 'ua-accordion' }, ...rows);
|
||||
const root = h('div', { class: 'ua-accordion' }, ...rows);
|
||||
|
||||
// —— 键盘导航:↑↓ 行间环形移动、Home/End 首尾直达,均跳过禁用行(对齐 tabs/tree 约定) ——
|
||||
const heads = (): HTMLButtonElement[] => rows.map((r) => r.firstElementChild as HTMLButtonElement); // 各行标题按钮
|
||||
const focusFrom = (start: number, dir: 1 | -1): void => {
|
||||
const len = heads().length;
|
||||
for (let n = 1; n <= len; n++) {
|
||||
const cand = heads()[(((start + dir * n) % len) + len) % len]; // 环形取候选:越界回绕保证落在 [0, len)
|
||||
if (!cand.disabled) { cand.focus(); return; } // 跳过禁用行,绕满一圈即止
|
||||
}
|
||||
};
|
||||
root.addEventListener('keydown', (e: KeyboardEvent) => {
|
||||
const list = heads();
|
||||
const idx = list.indexOf(document.activeElement as HTMLButtonElement);
|
||||
if (idx < 0) return; // 卫语句:焦点不在标题行
|
||||
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { e.preventDefault(); focusFrom(idx, e.key === 'ArrowDown' ? 1 : -1); }
|
||||
else if (e.key === 'Home') { e.preventDefault(); focusFrom(-1, 1); } // 从头正向找第一个可用
|
||||
else if (e.key === 'End') { e.preventDefault(); focusFrom(0, -1); } // 从尾反向找最后一个可用
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user