/**
 * 无障碍（a11y）工具集
 * 统一 ARIA 属性辅助、焦点陷阱、列表键盘导航等在交互组件（Dialog / Drawer / Menu /
 * Dropdown / Select 等）中重复出现且容易写错的可访问性逻辑。
 *
 * 参考标准：WAI-ARIA Authoring Practices 1.2。
 */
/** 判定按键是否为「激活」键（Enter / Space），用于自定义可聚焦元素的点击替代 */
function isActivationKey(key) {
    return key === 'Enter' || key === ' ' || key === 'Spacebar';
}
/** 查询容器内可聚焦的元素顺序（tabindex >= 0 的语义元素） */
const FOCUSABLE_SELECTOR = [
    'a[href]',
    'button:not([disabled])',
    'textarea:not([disabled])',
    'input:not([disabled])',
    'select:not([disabled])',
    '[tabindex]:not([tabindex="-1"])',
    '[contenteditable="true"]',
].join(',');
function getFocusableElements(container) {
    return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter((el) => el.getAttribute('aria-hidden') !== 'true' && el.style.display !== 'none');
}
/**
 * 创建焦点陷阱（Dialog / Drawer 打开时把 Tab 循环限制在容器内）。
 * 关键点：Tab 与 Shift+Tab 在容器边界时回环到另一端，防止焦点逃逸到背景。
 * 返回句柄，组件在打开时 connect()、关闭时 disconnect()。
 */
function createFocusTrap(options) {
    const { container, autoFocus = true, returnFocusTo } = options;
    let active = false;
    let previouslyFocused = null;
    const handleKeydown = (e) => {
        if (e.key !== 'Tab')
            return;
        const focusable = getFocusableElements(container);
        if (focusable.length === 0) {
            e.preventDefault();
            container.focus();
            return;
        }
        const first = focusable[0];
        const last = focusable[focusable.length - 1];
        const activeEl = document.activeElement;
        if (e.shiftKey) {
            if (activeEl === first || !container.contains(activeEl)) {
                e.preventDefault();
                last.focus();
            }
        }
        else {
            if (activeEl === last) {
                e.preventDefault();
                first.focus();
            }
        }
    };
    const connect = () => {
        if (active)
            return;
        active = true;
        previouslyFocused = (returnFocusTo ?? document.activeElement);
        container.addEventListener('keydown', handleKeydown);
        if (autoFocus) {
            const focusable = getFocusableElements(container);
            (focusable[0] ?? container).focus();
        }
    };
    const disconnect = () => {
        if (!active)
            return;
        active = false;
        container.removeEventListener('keydown', handleKeydown);
        if (previouslyFocused && typeof previouslyFocused.focus === 'function') {
            previouslyFocused.focus();
        }
        previouslyFocused = null;
    };
    return { connect, disconnect };
}
/**
 * 列表 / 菜单 / 下拉选项的键盘导航核心逻辑（listbox / menu / combobox 通用）。
 * 返回应执行的动作，由调用方据此更新 activeIndex / 触发选中 / 关闭。
 *
 * 支持：ArrowDown/ArrowUp（竖排）/ArrowRight/ArrowLeft（横排）移动、Home/End 跳首尾、
 * Enter/Space 选中、Escape 关闭。
 */
function handleListKeyboard(event, options) {
    const { activeIndex, itemCount, loop = true } = options;
    if (itemCount <= 0)
        return { type: 'none' };
    const clamp = (idx) => (idx + itemCount) % itemCount;
    const within = (idx) => Math.max(0, Math.min(idx, itemCount - 1));
    switch (event.key) {
        case 'ArrowDown':
        case 'ArrowRight':
            return { type: 'navigate', index: loop ? clamp(activeIndex + 1) : within(activeIndex + 1) };
        case 'ArrowUp':
        case 'ArrowLeft':
            return { type: 'navigate', index: loop ? clamp(activeIndex - 1) : within(activeIndex - 1) };
        case 'Home':
            return { type: 'navigate', index: 0 };
        case 'End':
            return { type: 'navigate', index: itemCount - 1 };
        case 'Enter':
        case ' ':
        case 'Spacebar':
            return activeIndex >= 0 ? { type: 'select', index: activeIndex } : { type: 'none' };
        case 'Escape':
            return { type: 'close' };
        default:
            return { type: 'none' };
    }
}

export { createFocusTrap as c, handleListKeyboard as h, isActivationKey as i };

//# sourceMappingURL=a11y-f9ab2964.js.map