"use client"; import { Plus, X } from "lucide-react"; import { Button } from "@/components/ui/Button"; import { TextInput } from "@/components/ui/TextInput"; import { MAX_CHARACTER_COUNT, MIN_CHARACTER_COUNT, roleMixTotal, sanitizeRoleMix, } from "@/lib/generation/cards"; // 单行配比:某定位 + 该定位要生成的数量。 export interface RoleMixRow { role: string; count: number; } interface RoleMixEditorProps { rows: RoleMixRow[]; onChange: (rows: RoleMixRow[]) => void; } // 群像按定位配比编辑器(⑦):一组「定位 + 数量」行;合计封顶 MAX_CHARACTER_COUNT。 // 不可变更新——每次编辑返回新数组,不改入参。 export function RoleMixEditor({ rows, onChange }: RoleMixEditorProps) { // 有效合计 = sanitize 后的总数(已按 MAX 截断),即实际会生成的张数。 const effectiveTotal = roleMixTotal(sanitizeRoleMix(rows)); const updateRow = (index: number, patch: Partial): void => { onChange(rows.map((r, i) => (i === index ? { ...r, ...patch } : r))); }; const addRow = (): void => onChange([...rows, { role: "", count: 1 }]); const removeRow = (index: number): void => onChange(rows.filter((_, i) => i !== index)); return (
{rows.map((row, i) => (
updateRow(i, { role: e.target.value })} placeholder="定位:主角 / 对手 / 配角" aria-label={`第 ${i + 1} 行定位`} className="min-w-[10rem] flex-1" /> updateRow(i, { count: Math.round(Number(e.target.value)) }) } aria-label={`第 ${i + 1} 行数量`} className="w-20" />
))}
合计 {effectiveTotal} / {MAX_CHARACTER_COUNT} 张
); }