"use client"; import { useEffect, useRef, useState, type CSSProperties } from "react"; import "./fraction-checkbox.css"; /** * Fraction Checkbox * A standard tri-state 'select all' (checked / indeterminate / unchecked), * but its box is a small gauge: the fill rises to exactly the fraction of * children checked, and the tick only appears at 100%. Children are ordinary * checkboxes with a drawn tick. */ export type Option = { id: string; label: string; meta?: string }; type Props = { title: string; options: Option[]; initial?: string[]; accent?: string; className?: string }; export function FractionCheckbox({ title, options, initial = [], accent = "#b9cce4", className = "" }: Props) { const [on, setOn] = useState>(new Set(initial)); const all = useRef(null); const frac = on.size / options.length; useEffect(() => { if (all.current) all.current.indeterminate = frac > 0 && frac < 1; }, [frac]); const toggle = (id: string) => setOn((s) => { const n = new Set(s); if (n.has(id)) n.delete(id); else n.add(id); return n; }); const toggleAll = () => setOn(frac === 1 ? new Set() : new Set(options.map((o) => o.id))); return (
{title}
    {options.map((o) => (
  • ))}
); }