stem-separator / frontend /src /components /StemCheckboxes.tsx
sourav-das's picture
Upload folder using huggingface_hub
7dfae77 verified
import { ALL_STEMS, STEM_CONFIG } from "../types";
interface StemCheckboxesProps {
selected: string[];
onChange: (stems: string[]) => void;
disabled?: boolean;
}
export function StemCheckboxes({
selected,
onChange,
disabled,
}: StemCheckboxesProps) {
const toggle = (stem: string) => {
if (selected.includes(stem)) {
onChange(selected.filter((s) => s !== stem));
} else {
onChange([...selected, stem]);
}
};
const allSelected = selected.length === ALL_STEMS.length;
const toggleAll = () => {
onChange(allSelected ? [] : [...ALL_STEMS]);
};
return (
<div className="space-y-3">
<div className="flex items-center justify-between">
<span className="text-sm font-medium text-text-secondary">
Select stems to separate
</span>
<button
onClick={toggleAll}
disabled={disabled}
className="text-xs text-text-secondary hover:text-text-primary transition-colors disabled:opacity-50"
>
{allSelected ? "Deselect All" : "Select All"}
</button>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 gap-2">
{ALL_STEMS.map((stem) => {
const config = STEM_CONFIG[stem];
const checked = selected.includes(stem);
return (
<button
key={stem}
onClick={() => toggle(stem)}
disabled={disabled}
className={`
flex items-center gap-2 px-3 py-2.5 rounded-lg border transition-all text-sm
${
checked
? "border-transparent"
: "border-border hover:border-text-secondary"
}
disabled:opacity-50
`}
style={
checked
? {
backgroundColor: config.color + "15",
borderColor: config.color + "40",
}
: undefined
}
>
<span
className="w-3 h-3 rounded-full flex-shrink-0"
style={{ backgroundColor: checked ? config.color : "#4a4a5a" }}
/>
<span
className="font-medium"
style={{ color: checked ? config.color : undefined }}
>
{config.label}
</span>
</button>
);
})}
</div>
</div>
);
}