JSFiddle - React, Tailwind, and code Playground

by Ravindra Athreya

HTML

<div class="custom-select">
        <div class="select-box">
            <input type="text" class="select-input" placeholder="Select options" readonly>
            <div class="dropdown">
                <ul class="dropdown-list">
                    <!-- Optgroup 1 -->
                    <li class="optgroup">
                        <div class="optgroup-header">
                            <label>
                                <input type="checkbox" class="optgroup-checkbox">
                                <span>Fruits</span>
                            </label>
                            <span class="toggle">[+]</span>
                        </div>
                        <ul class="optgroup-content">
                            <li><label><input type="checkbox" class="option-checkbox"> Apple</label></li>
                            <li><label><input type="checkbox" class="option-checkbox"> Banana</label></li>
                            <li><label><input type="checkbox" class="option-checkbox"> Cherry</label></li>
                        </ul>
                    </li>

                    <!-- Optgroup 2 -->
                    <li class="optgroup">
                        <div class="optgroup-header">
                            <label>
                                <input type="checkbox" class="optgroup-checkbox">
                                <span>Vegetables</span>
                            </label>
                            <span class="toggle">[+]</span>
                        </div>
                        <ul class="optgroup-content">
                            <li><label><input type="checkbox" class="option-checkbox"> Carrot</label></li>
                            <li><label><input type="checkbox" class="option-checkbox"> Broccoli</label></li>
                            <li><label><input type="checkbox" class="option-checkbox"> Spinach</label></li>
                        </ul>
                    </li>
                </ul>
        ...

CSS

/* Custom Select Styling */
.custom-select {
    width: 300px;
    position: relative;
}

.select-box {
    border: 1px solid #ccc;
    border-radius: 5px;
    padding: 10px;
    cursor: pointer;
    position: relative;
}

.select-input {
    width: 100%;
    border: none;
    outline: none;
    background: none;
}

.dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    border: 1px solid #ccc;
    background-color: white;
    max-height: 200px;
    overflow-y: auto;
    z-index: 1;
}

.dropdown-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.dropdown-list li {
    padding: 8px 10px;
}

.optgroup {
    font-weight: bold;
}

.optgroup-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.optgroup-checkbox {
    margin-right: 8px;
}

.option-checkbox {
    margin-right: 8px;
}

.optgroup-content {
    display: none;
    padding-left: 20px;
}

/* Toggle to expand/collapse optgroup */
.toggle {
    cursor: pointer;
}

/* Show dropdown on select box click */
.select-box.open .dropdown {
    display: block;
}

/* Expanded optgroup */
.optgroup-expanded .optgroup-content {
    display: block;
}

JavaScript

document.addEventListener("DOMContentLoaded", function () {
    const selectBox = document.querySelector(".select-box");
    const inputBox = document.querySelector(".select-input");
    const dropdown = document.querySelector(".dropdown");
    const optgroupCheckboxes = document.querySelectorAll(".optgroup-checkbox");
    const optionCheckboxes = document.querySelectorAll(".option-checkbox");
    const toggleButtons = document.querySelectorAll(".toggle");

    // Toggle dropdown visibility on select box click
    selectBox.addEventListener("click", function () {
        selectBox.classList.toggle("open");
    });

    // Handle optgroup checkbox click (Select/Deselect all items within group)
    optgroupCheckboxes.forEach(optgroupCheckbox => {
        optgroupCheckbox.addEventListener("change", function () {
            const group = optgroupCheckbox.closest(".optgroup").querySelectorAll(".option-checkbox");
            group.forEach(optionCheckbox => {
                optionCheckbox.checked = optgroupCheckbox.checked;
            });
            updateSelectionText();
        });
    });

    // Handle individual option checkbox click
    optionCheckboxes.forEach(optionCheckbox => {
        optionCheckbox.addEventListener("change", updateSelectionText);
    });

    // Handle expand/collapse of optgroups
    toggleButtons.forEach(toggleButton => {
        toggleButton.addEventListener("click", function () {
            const optgroup = toggleButton.closest(".optgroup");
            const content = optgroup.querySelector(".optgroup-content");
            const isExpanded = optgroup.classList.toggle("optgroup-expanded");

            toggleButton.textContent = isExpanded ? "[-]" : "[+]";
        });
    });

    // Update the input text based on selected options
    function updateSelectionText() {
        const selectedOptions = [];
        optionCheckboxes.forEach(option => {
            if (option.checked) {
               ...