Keyboard Navigation

keyboard-nav.js BEST VERSION YET

// keyboard-nav.js
let lastLetterPressed = null
import { pageWrapper,sideBarBtn } from "../ui/toggle-sidebar.js"

export function keyboardNav({ e, mainContentEls }) {
    const key = (e.key || '').toLowerCase()
    if (!key.match(/^[a-z]$/)) return // only handle letters    
    // all visible anchors (same as you had)
    if(e.metaKey && e.shiftKey && key === 's'){sideBarBtn.focus()}
    // const allEls = [...document.querySelectorAll('a,#sideBarBtn,#mainLandingPage,#darkModeBtn,#findSearchBar')].filter(el => {
    // // // // // // // // // // // // // // // // // // // 
    //** make command shift + f , focus to #findSearchBar */
    const allEls = [...document.querySelectorAll('a,#sideBarBtn,#mainContent,#darkModeBtn,#chatGptMyLink,#programShortcutsLink')].filter(el => {
        const rect = el.getBoundingClientRect()
        if(!el.hasAttribute('tabindex')){
            el.setAttribute('tabindex', '0')
        }
        return isActuallyVisible(el)
    })
    
    // helper: return the first alphabetic character of the element's text (or '')
    const firstAlpha = el => {
        // If element is NOT an anchor, use its ID  
        if (el.tagName !== 'A') {
            const id = (el.id || '').trim().toLowerCase()
            for (let i = 0; i < id.length; i++) {
                const ch = id[i]
                if (/[a-z]/.test(ch)) return ch
            }
            return ''
        }
        // Regular  text logic
        const s = (el.innerText || '').trim().toLowerCase()
        
        for (let i = 0; i < s.length; i++) {
            if (/[a-z]/.test(s[i])) return s[i]
        }
        
        return ''
    }
    // matching anchors whose first alpha char equals the pressed key
    // const matching = allEls.filter(el => firstAlpha(el) === key)
    const matching = allEls.filter(el =>{ 
        return firstAlpha(el) === key
    })
    // matching.forEach(el => console.log(el))
    if (matching.length === 0) return
    const activeEl = document.activeElement
    let iActiveAll = allEls.indexOf(activeEl) // position of focused element among all anchors
    const iActiveMatching = matching.indexOf(activeEl) // -1 if focused element is not one of the matches
    let newIndex

    if (key === 'm' && activeEl?.id === 'mainLandingPage') {
        e.preventDefault()
        // topicsContainer.scrollIntoView({ top: 0, behavior: 'smooth' })
        lastLetterPressed = key
        return
    }
    if(e.metaKey) return
    // --- NEW letter press: choose closest match below unless one is directly before (closer) ---
    if (key !== lastLetterPressed) {
        if (iActiveAll === -1) {
            // nothing focused: pick first/last
            newIndex = e.shiftKey ? matching.length - 1 : 0
        } else {
            const prevEl = allEls[iActiveAll - 1]  // the element directly before
            const nextEl = allEls[iActiveAll + 1]  // the element directly after

            // if the previous element matches the letter, go up one
            if (prevEl && matching.includes(prevEl)) {
                newIndex = matching.indexOf(prevEl)
            } else {
                // otherwise go to the next matching element after current focus
                let foundNext = false
                for (let i = iActiveAll + 1; i < allEls.length; i++) {
                    if (matching.includes(allEls[i])) {
                        newIndex = matching.indexOf(allEls[i])
                        foundNext = true
                        break
                    }
                }
                if (!foundNext) {
                    // fallback to first matching if nothing found below
                    newIndex = 0
                }
            }
        }
    }else {
        if (iActiveMatching === -1) {
            // currently focused element is not one of the matching elements
            newIndex = e.shiftKey ? matching.length - 1 : 0
        } else {
            newIndex = e.shiftKey
                ? (iActiveMatching - 1 + matching.length) % matching.length
                : (iActiveMatching + 1) % matching.length
        }
    }
    let target = matching[newIndex]
    if (!target) return
    lastLetterPressed = key
    
    // let fZone = focusZones(target)
    // if (target == sideBarBtn) {
    //     fZone = 'sidebar'
    //     pageWrapper.classList.remove('collapsed')
    // }
    // if(e.shiftKey && !e.target.classList.contains('copy-code')){
    //     console.log(allEls[iActiveAll].innerText[0])
    //     console.log()
    //     target.focus()
    //     if (key == allEls[iActiveAll].innerText[0].toLowerCase()){
    //         console.log('here', iActiveAll)
    //         iActiveAll += 1
            
    //     }
    //     target = allEls[iActiveAll]
    // }
    
    target.focus()
}
// function focusZones(target){
//     const t = target
//     let focusZone
//     if (t.id == 'mainContent'){
//         // focusZone = 'mainContent'
//     } else if (t.closest('.side-bar') ){
//         // focusZone = 'sidmeBar'
//     }
//     // switch (t){
//     //     case target.id === 'mainContent':
//     //         return focusZone = 'mainContent'
//     //         break
//         // case target.
//     // }
//     return focusZone
// } 
function isActuallyVisible(el) {
    if (!el) return false;

    // 1. Sidebar collapsed → block ALL sidebar descendants
    if (
        pageWrapper.classList.contains('collapsed') &&
        el.closest('.side-bar')
    ) {
        return false;
    }

    // 2. CSS visibility checks
    const style = getComputedStyle(el);
    if (
        style.display === 'none' ||
        style.visibility === 'hidden' ||
        style.opacity === '0'
    ) {
        return false;
    }

    // 3. Zero-size or clipped
    const rect = el.getBoundingClientRect();
    if (rect.width === 0 || rect.height === 0) {
        return false;
    }

    // 4. Any hidden ancestor (dropdowns, containers, etc.)
    let parent = el.parentElement;
    while (parent) {
        const ps = getComputedStyle(parent);
        if (ps.display === 'none' || ps.visibility === 'hidden') {
            return false;
        }
        parent = parent.parentElement;
    }

    return true;
}

              

letter-focus.js find & add good one

Add Good letter focus here
                                

drop-downs

drop-down.js not the best( best is used on this page)

// drop-downs.js

export function initDropDowns() {   
    hideAllCodeCmds()
    if(!document.listenersAdded){

        document.addEventListener("click", handleToggle);
        document.addEventListener("keydown", handleToggle);
        document.listenersAdded = true
    }
    // const dropChilds = document.querySelectorAll('.code-cmd') ? document.querySelectorAll('.code-cmd') : document.querySelectorAll('.topic-snips')
    
    function handleToggle(e) {
        let target;        
        if (e.type === "keydown") {
            if ((e.key === "Enter" || e.key === " ") && (document.activeElement.classList.contains("drop-down") || document.activeElement.classList.contains("drop-code-cmd"))) {
                e.preventDefault();
                target = document.activeElement;
            } else {
                return; // ignore other keys
            }
        } else if (e.type === "click") {
            // Ignore clicks triggered by keyboard
            if (e.detail === 0) return;
            target = e.target.closest(".drop-down") || e.target.closest(".drop-code-cmd");
            if (!target) return;
        }

        // Unified toggle logic
        const topic = target.closest(".topic");
        const snip = target.closest(".snip");
        // console.log("Toggled dropdown:", topic);
        // if (!topic || !snip) return;
        console.log(snip)
        if (snip){
            toggleCodeSnips(snip)
            return
        } 
        if(topic){
            toggleTopicSnips(topic)
            return 
        } 
    }
}

function toggleCodeSnips(snip) {
    const codeCmd = snip.querySelector('.code-cmd')
    codeCmd.classList.toggle('hide')

}
function hideAllCodeCmds() {
    const codeCmds = document.querySelectorAll('.code-cmd')
    codeCmds.forEach(el => {
        if(!el.classList.contains('show')){
            el.classList.add('hide')
        }
    })
    

}
function toggleTopicSnips(topic) {
    const topicSnips = topic.querySelector('.topic-snips')
    topicSnips.classList.toggle("hide"); // example toggle
}

                                

Drop

2

    // This page has really good letter focus cycle
    if(letter == 'c' && !e.metaKey){
        if(!e.shiftKey){
        copyCodes[iCopyCodes].focus()
        iCopyCodes = (iCopyCodes + 1) % copyCodes.length
        } else{
            iCopyCodes = (iCopyCodes - 1 + copyCodes.length) % copyCodes.length
        }
        copyCodes[iCopyCodes].focus()
        console.log(iLetter)
    }

CamelCase function

    function toCamelCase(str) {
        return str
        .toLowerCase()
        .replace(/[^a-zA-Z0-9]+(.)/g, (match, chr) => chr.toUpperCase());
    }

Drop downs

Incrementing / Decrements Letter Focus

    function hideTopics(){

    }

CamelCase function

    function toCamelCase(str) {
        return str
        .toLowerCase()
        .replace(/[^a-zA-Z0-9]+(.)/g, (match, chr) => chr.toUpperCase());
    }