Question presented to candidate: "Build a checkbox tree, like the one for picking permissions or grocery categories. Checking a parent checks everything under it, unchecking clears it, and a parent whose children are only partly checked should show the half-checked dash. Changing children must update every parent above them."
Requirements:
- Render an arbitrarily deep tree of labelled checkboxes, indented by level.
- Clicking a parent that is fully checked unchecks all its descendants; clicking an unchecked or partly checked parent checks all of them.
- A parent shows checked when all its leaves are checked, unchecked when none are, and indeterminate (the dash) when some are, at every level up to the root.
- The indeterminate look must come from the real
indeterminateproperty of the input, so assistive technology sees a mixed state. - A summary line: "3 of 8 selected: Orange, Lemon, Lime".
What a strong answer should cover:
- A single source of truth: store only the checked leaves (a
Setof ids); derive every parent state from them in one post-order pass. - Why storing a
checkedflag on every node leads to drift, and how propagation down (toggle) and up (derive) both fall out of the leaf-only model. indeterminateis a DOM property with no HTML attribute, so each framework sets it differently (React: ref plus effect; Vue and Angular: property binding).- What a native click does to an indeterminate checkbox and how that matches the rule "mixed becomes checked".
- Complexity: O(n) per change; when to memoize.
Clarifying questions expected:
- "When I click a partly checked parent, should it select all or clear all?"
- "Can items be disabled, and should a parent click skip them?"
- "Does the parent itself carry a value, or only the leaves?"
Code / implementation expected: Yes. A working recursive checkbox tree with correct tri-state behaviour.