import { Button } from "@/components/ui/button"; import { useDataset } from "../hooks/useDataset.ts"; import { digitsFor } from "../../domain/currencies.ts"; import { Input } from "@/components/ui/input"; import { NativeSelect } from "@/components/ui/native-select"; import { Label } from "@/components/ui/label"; import { Segmented } from "./Segmented.tsx"; import { formatAmount } from "../format.ts"; import type { PurchaseDraft, SplitDraft } from "../purchaseForm.ts"; import { splitBalance } from "../purchaseForm.ts"; import type { Post } from "../../domain/types.ts"; interface Props { draft: PurchaseDraft; posts: Post[]; onChange: (next: PurchaseDraft) => void; } export function SplitEditor({ draft, posts, onChange }: Props) { const balance = splitBalance(draft, digitsFor(useDataset().currencies, draft.currency)); const unit = draft.splitMode === "percent" ? "%" : draft.currency; function updateSplit(index: number, changes: Partial) { const splits = draft.splits.map((split, i) => i === index ? { ...split, ...changes } : split, ); onChange({ ...draft, splits }); } function setAbsorber(index: number) { onChange({ ...draft, splits: draft.splits.map((split, i) => ({ ...split, absorbsRemainder: i === index, })), }); } return (
onChange({ ...draft, splitMode })} options={[ { value: "percent", label: "Percentages" }, { value: "fixed", label: "Amounts" }, ]} />
{draft.splits.map((split, index) => (
{/* `min-w-0` comes from NativeSelect. Without it `flex-1` could not shrink below the widest option, and this row's min-content width was what pushed the whole dialog past its own padding. */} updateSplit(index, { postId: event.target.value })} > {posts.map((post) => ( ))} updateSplit(index, { value: Number(event.target.value) || 0 }) } /> {unit}
))}
{balance === 0 ? "Splits balance exactly." : `${formatAmount(balance)} ${unit} unassigned — the rounding post absorbs it.`}
); }