JSFiddle - React, Tailwind, and code Playground

by grammar

HTML

<ul>
    <li>
        <input type="checkbox" id="chkAll" checked/>
        <label for="chkAll">Select All</label>
    </li>
    <li class="has-nested-list">
        <ul class="nested">
            <li class="has-nested-list">
                <input type="checkbox" id="chkGroup1" class="group-leader" checked/>
                <label for="chkGroup1">Group 1</label>
                <ul class="nested">
                    <li>
                        <input type="checkbox" id="chkGp1-Item1" checked/>
                        <label for="chkGp1-Item1">Item 1</label>
                    </li>
                    <li>
                        <input type="checkbox" id="chkGp1-Item2" checked/>
                        <label for="chkGp1-Item2">Item 2</label>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li class="has-nested-list">
        <ul class="nested">
            <li>
                <input type="checkbox" id="chkGroup2" class="group-leader" checked/>
                <label for="chkGroup2">Group 2</label>
                <ul class="nested">
                    <li>
                        <input type="checkbox" id="chkGp2-Item1" checked/>
                        <label for="chkGp2-Item1">Item 1</label>
                    </li>
                    <li>
                        <input type="checkbox" id="chkGp2-Item2" checked/>
                        <label for="chkGp2-Item2">Item 2</label>
                    </li>
                    <li>
                        <input type="checkbox" id="chkGp2-Item3" checked/>
                        <label for="chkGp2-Item3">Item 3</label>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

CSS

/* to get rid of double bullets */
.has-nested-list {
    list-style-type: none;
}

JavaScript

$( function() {
    
        // Store the checkboxes to manage scope
    var $allCheckboxes = $('ul input[type=checkbox]'),
        // Store a quick reference to the 'check-all' button for comparison
        $checkAllCheckbox = $allCheckboxes.filter('#chkAll'),
        // A cache of all the checkboxes except the check-all
        // Useful when altering the check-all
        $allNestedCheckboxes = $allCheckboxes.not( $checkAllCheckbox );

    // Listen to change event on all checkboxes
    $allCheckboxes.on( 'change', function( event ) {

            // Store what changed and what it changed to
        var $this = $(this),
            value = $this.prop('checked'),
            // Because val returns true or false, we have to store
            // something that the input tag understands
            checkedValue = value ? 'checked' : '',
            // Placeholder for parent and children elements
            $parent, $children;
        
        // If this was the 'check-all' checkmark, then simply alter all
        if( $this.is( $checkAllCheckbox ) ) {

            $allCheckboxes.each( function( idx, item ) {
                $(item).prop( 'checked', value );
                // Reset disabled property just in case
                $(item).prop( 'disabled', '' );
            });

        // Otherwise, check if this was a 'group-leader' alter the checkboxes
        // inside its nested list
        } else if( $this.hasClass('group-leader') ) {
            
            // Only works with one level of nesting at this time
            $children = $this.siblings('ul').find('input[type=checkbox]');
            
            $children.each( function( idx, item ) {
                $(item).prop( 'checked', checkedValue );
            });
        
        // Otherwise, it was a singular checkbox, which affects only its parent
        // 'group-leader', which must be checked when all siblings are checked,
        // 'disabled' when some are checked, and unchecked when none are...