import { useMemo, useState } from 'react' import { MODELS, displayAuroc, featureSetLabel, type RealModel } from '../data/models' interface MultiModelPickerProps { selected: Set // model codes onChange: (next: Set) => void } interface Group { key: string species: string models: RealModel[] } /** Checkbox multi-select of detectability models, grouped by species (mirrors the single-select * ModelPicker accordion). Used by the Protein Digestibility tab to screen across several models. */ export default function MultiModelPicker({ selected, onChange }: MultiModelPickerProps) { const groups = useMemo(() => { const byKey = new Map() for (const m of MODELS) { if (!byKey.has(m.speciesKey)) byKey.set(m.speciesKey, { key: m.speciesKey, species: m.species, models: [] }) byKey.get(m.speciesKey)!.models.push(m) } return [...byKey.values()] }, []) const [openGroups, setOpenGroups] = useState>(new Set()) const toggleGroup = (k: string) => setOpenGroups((prev) => { const next = new Set(prev) next.has(k) ? next.delete(k) : next.add(k) return next }) function toggle(code: string) { const next = new Set(selected) next.has(code) ? next.delete(code) : next.add(code) onChange(next) } return (
Detectability models{' '} {selected.size} selected · combined set needs all of them {selected.size > 0 && ( )}
{groups.map((g) => { const isOpen = openGroups.has(g.key) const nSel = g.models.filter((m) => selected.has(m.code)).length return (
{isOpen && (
{g.models.map((m) => { const on = selected.has(m.code) return ( ) })}
)}
) })}
) }