import type { PackerOption } from "@/types/memshell"; import { Check, ChevronRight } from "lucide-react"; import { useEffect, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Badge } from "@/components/ui/badge"; import { ScrollArea } from "@/components/ui/scroll-area"; import { cn } from "@/lib/utils"; /** A leading radio-style indicator shared by every list item for a consistent look. */ function RadioDot({ active }: Readonly<{ active: boolean }>) { return ( ); } function ListItem({ label, active, onClick, trailing, }: Readonly<{ label: string; active: boolean; onClick: () => void; trailing?: React.ReactNode; }>) { return ( ); } /** * packer 选择器。 * - 左侧分类(父)+ 右侧变体(子)的主从布局,选中某个具体子变体。 * * 通过受控的 `value` / `onChange` 与表单字段 `packingMethod` 双向同步, * `value` 始终是单一来源;UI 状态(当前激活的父)由 `value` 推导,避免状态不一致。 */ export default function PackerSelector({ parents, value, onChange, }: Readonly<{ parents: PackerOption[]; value: string; onChange: (value: string) => void; }>) { const { t } = useTranslation("common"); const values = useMemo(() => { return parents.flatMap((parent) => parent.children.length > 0 ? parent.children : [parent.name], ); }, [parents]); useEffect(() => { if (values.length === 0) { return; } const selectedParent = parents.find((parent) => parent.name === value); if (selectedParent?.children.length) { onChange(selectedParent.children[0]); return; } if (!value || !values.includes(value)) { const firstParent = parents[0]; onChange(firstParent?.children[0] ?? firstParent?.name ?? values[0]); } }, [parents, values, value, onChange]); const activeParent = useMemo( () => parents.find((parent) => parent.name === value || parent.children.includes(value)) ?? parents[0], [parents, value], ); const selectParent = (parent: PackerOption) => { onChange(parent.children[0] ?? parent.name); }; const isParentActive = (parent: PackerOption) => activeParent?.name === parent.name; return (
{t("packerMode.advancedDesc")}