JSFiddle - React, Tailwind, and code Playground
HTML
<ul>
<li>
<input type="checkbox" id="chkAll" checked/>
<label for="chkAll">Select All</label>
</li>
<ul>
<li>
<input type="checkbox" id="chkGroup1" checked/>
<label for="chkGroup1">Group 1</label>
</li>
<ul>
<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>
</ul>
</ul>
JavaScript
$("input[type=checkbox]:not(:disabled)").on("change", function () {
$(this).parent().next("ul").find("li input[type=checkbox]:not(:disabled)").prop("checked", $(this).prop("checked"));
// Looping 3 times to cover all sublevels. THERE HAS GOT TO BE A BETTER WAY THAN THIS.
for (var i = 0; i < 3; i++) {
$("input[type=checkbox]:not(:disabled)").each(function () {
var uncheckedkidcount = $(this).parent().next("ul").find("li input[type=checkbox]:not(:disabled):not(:checked)").length;
var kidcount = $(this).parent().next("ul").find("li input[type=checkbox]:not(:disabled)").length;
if (kidcount > 0) {
$(this).prop("checked", uncheckedkidcount == 0);
}
});
}
});