drop-downs

drop-down.js

Best way so far

// 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
}

                                

Keyboard Navigation

Letter Focus Code

**create pop up with extra info on filter() and findIndex() **make a dropCode like dropTopic so each code example can collapse... great job keep going, you're doing great with implementing the new letterFocus incrementation !!😎

Chat Question: does filter() work the same as findIndex()?
ChatGPT said: Awesome question filter is similar to findIndex, but with one big difference in what it returns.
✅ Both:

  • * Take a callback function that checks a condition.
  • * Go through the array element by element.
  • * Use the callback to test each item.

🔍 Difference: Method Returns findIndex The index of the first matching item filter A new array of all matching items


    const as = document.querySelectorAll('a')
    let asTxtArr = [...as]
    let lastPressedLetter = "";
    let iLetter = 0;
    function updateAsTxtArr(){
        asTxtArr = Array.from(document.querySelectorAll('a'))
    }
    addEventListener('keydown', e => {
        let letter = e.key.toLowerCase()
        let letteredAs = asTxtArr.filter((el) => el.innerText.toLowerCase().startsWith(letter))
        let activeEl = document.activeElement // current focused element
        let activeIndex = [...asTxtArr].indexOf(activeEl)
        if(letter != lastPressedLetter){
            let closestIndex = letteredAs.findIndex((el) => asTxtArr.indexOf(el) > activeIndex)
            iLetter = closestIndex !== -1 ? closestIndex : 0
        } else {
            iLetter = (letteredAs.indexOf(activeEl) + 1) % letteredAs.length
        }
        if(e.shiftKey){
            iLetter = (letteredAs.indexOf(activeEl) - 1 + letteredAs.length)  % letteredAs.length
        }
        if(letteredAs[iLetter]){
            letteredAs[iLetter].focus()
        }
        lastPressedLetter = letter
    })

Incrementing / Decrements Letter Focus

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

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());
    }