const keyToCoord = {
    ArrowUp: { x: 0, y: -1 },
    ArrowDown: { x: 0, y: 1 },
    ArrowLeft: { x: -1, y: 0 },
    ArrowRight: { x: 1, y: 0 },
};
/**
 * Maps keyboard events to navigation actions.
 * Supports arrow keys, Home/End (row navigation), Ctrl/Cmd+Home/End (table navigation).
 */
function getNavigationAction(event) {
    const key = event.key;
    /* Arrow keys -> directional navigation */
    if (key in keyToCoord) {
        return { type: "delta", delta: keyToCoord[key] };
    }
    if (key === "Home") {
        return event.ctrlKey || event.metaKey
            ? { type: "tableStart" }
            : { type: "home" };
    }
    if (key === "End") {
        return event.ctrlKey || event.metaKey
            ? { type: "tableEnd" }
            : { type: "end" };
    }
    return null;
}
/**
 * Determines if keyboard navigation should be blocked based on the current focus context.
 * Allows for custom blocking logic via an optional callback.
 *
 * Tries to make assumptions of what the user is currently doing inside a table cell
 * Should block navigation if:
 * - Input has selection, caret is not at start/end
 * - Select arrow down/up for opening popup
 * - User is navigating inside multiline textarea
 * - contenteditable attrb is in use
 */
function shouldBlockNavigation(event) {
    const key = event.key;
    const el = event.target;
    if (!el) {
        return false;
    }
    if (el.dataset.disableKeyboardNav === "true") {
        return true;
    }
    if (el.isContentEditable) {
        return true;
    }
    /* If not any of these elements, assume "safe" to navigate */
    const editable = el.closest('input, textarea, select, [contenteditable="true"]');
    if (!editable) {
        return false;
    }
    if (editable instanceof HTMLInputElement) {
        return shouldBlockInputArrow(editable, key);
    }
    if (editable instanceof HTMLTextAreaElement) {
        return shouldBlockTextAreaArrow(editable, key);
    }
    if (editable instanceof HTMLSelectElement) {
        if (key === "ArrowDown" || key === "ArrowUp") {
            return true;
        }
        return false;
    }
    return editable.hasAttribute("contenteditable");
}
function shouldBlockInputArrow(input, key) {
    if (input.type === "checkbox" || input.type === "radio") {
        return false;
    }
    if (!isTextInputType(input.type)) {
        return false;
    }
    const start = input.selectionStart;
    const end = input.selectionEnd;
    if (start === null || end === null) {
        return true;
    }
    return shouldBlockBySelection(key, start, end, input.value.length);
}
function shouldBlockTextAreaArrow(textarea, key) {
    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    return shouldBlockBySelection(key, start, end, textarea.value.length);
}
function shouldBlockBySelection(key, start, end, valueLength) {
    if (key === "ArrowLeft" || key === "ArrowUp") {
        return start > 0 || end > 0;
    }
    if (key === "ArrowRight" || key === "ArrowDown") {
        return end < valueLength;
    }
    return false;
}
function isTextInputType(type) {
    switch (type) {
        case "text":
        case "search":
        case "url":
        case "tel":
        case "password":
        case "email":
        case "number":
            return true;
        default:
            return false;
    }
}
export { getNavigationAction, shouldBlockNavigation };
//# sourceMappingURL=table-keyboard.js.map