JSFiddle - React, Tailwind, and code Playground

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>event test</title>
</head>
<body>
<h1>event test</h1>
                <side-nav>
                    <nav-item id="1">1</nav-item>
                    <nav-item id="2">2</nav-item>
                    <nav-item id="3">3</nav-item>
                    <nav-item id="4">4</nav-item>
                </side-nav>
</body>
</html>

JavaScript

const sideNavTemplate = document.createElement("template");
sideNavTemplate.innerHTML = `

<style>
:host {
    display: block;
}
:host([hidden]) {
 display: none 
}

.root {
    display: flex;
    justify-content: space-between;
}

</style>

<div class="root"><slot>Item Display</slot></div>`;
class SideNav extends HTMLElement {

    constructor()
    {
        super();
        this.attachShadow({mode: 'open'});
        this.shadowRoot.appendChild(sideNavTemplate.content.cloneNode(true));
    }

    async connectedCallback() {

    }
}
window.customElements.define('side-nav', SideNav);


const navItemTemplate = document.createElement("template");
navItemTemplate.innerHTML = `

<style>
:host {
    display: block;
}
:host([hidden]) {
 display: none 
}

.root {
    display: flex;
    justify-content: space-between;
    padding: 16px;
}
.root:hover{
    background-color: aliceblue;
}
.selected{
    background-color: teal;
    color: white;
}
</style>

<div class="root"><slot>Item Display</slot></div>`;
class NavItem extends HTMLElement {

    id;
    constructor()
    {
        super();
        this.attachShadow({mode: 'open'});
        this.shadowRoot.appendChild(navItemTemplate.content.cloneNode(true));
    }

    static get observedAttributes() {
        return ['id', 'selected'];
    }

    attributeChangedCallback(name, oldValue, newValue) {
        if(name == 'id'){
            this.id = newValue;
        }
        if(name == 'selected')
        {
            if(newValue){
                this.shadowRoot.querySelector('.root').classList.add('selected');
            } else {
                this.shadowRoot.querySelector('.root').classList.remove('selected');
            }
        }
    }

    async connectedCallback() {
        this.addEventListener('click' , (event) => {
            this.dispatchEvent(new CustomEvent('navitem-selected', { bubbles: true, composed: true , detail: { id: this.id} }));
        });
        const hostNode =...