From 0022d807d00533a1c1374263bce66bde55583281 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Fri, 10 Jul 2026 11:44:02 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20shopping=20list=20item=20row=20?= =?UTF-8?q?=E2=80=94=20direct=20buttons=20instead=20of=20"..."=20overflow?= =?UTF-8?q?=20menu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced the hidden dropdown (change category submenu + delete, behind a single unlabeled MoreVertical icon) with two directly visible controls, matching the recipe detail page's icon-row pattern: a compact category Select showing the item's current category at a glance (still supports picking a predefined category, "Other", or typing a new custom one), and a direct trash icon button with a tooltip. Row stays single-line via truncation on the name and a fixed-width category trigger. Co-Authored-By: Claude Sonnet 5 --- .../meal-plan/shopping-list-view.tsx | 125 +++++++++--------- 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/apps/web/components/meal-plan/shopping-list-view.tsx b/apps/web/components/meal-plan/shopping-list-view.tsx index 7f42b86..a484ead 100644 --- a/apps/web/components/meal-plan/shopping-list-view.tsx +++ b/apps/web/components/meal-plan/shopping-list-view.tsx @@ -3,7 +3,7 @@ import { useMemo, useRef, useState } from "react"; import { useTranslations } from "next-intl"; import { cn } from "@/lib/utils"; -import { Check, Package, Loader2, GripVertical, MoreVertical, Trash2, Search, Sparkles } from "lucide-react"; +import { Check, Package, Loader2, GripVertical, Trash2, Search, Sparkles } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -14,16 +14,7 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuTrigger, - DropdownMenuSeparator, -} from "@/components/ui/dropdown-menu"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { AlertDialog, AlertDialogAction, @@ -624,12 +615,12 @@ type ItemRowProps = { function ItemRow({ item, readOnly, categoryOptions, categoryLabel, tShopping, onToggle, onChangeCategory, onDeleteRequest, dragHandle }: ItemRowProps) { const [newCategory, setNewCategory] = useState(""); return ( -
+
{dragHandle} {!readOnly && ( - - - - - - - {tShopping("changeCategory")} - - {categoryOptions.map((category) => ( - onChangeCategory(item, category)}> - {categoryLabel(category)} - - ))} - onChangeCategory(item, null)}> - {tShopping("aisleOther")} - - -
e.stopPropagation()}> - setNewCategory(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Enter" && newCategory.trim()) { - onChangeCategory(item, newCategory.trim()); - setNewCategory(""); - } - }} - placeholder={tShopping("newCategoryPlaceholder")} - className="h-7 text-xs" - /> - -
-
-
- - onDeleteRequest(item)}> - - {tShopping("deleteItem")} - -
-
+
+ setNewCategory(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter" && newCategory.trim()) { + onChangeCategory(item, newCategory.trim()); + setNewCategory(""); + } + }} + placeholder={tShopping("newCategoryPlaceholder")} + className="h-7 text-xs" + /> + +
+ + + + + onDeleteRequest(item)} + > + + + } /> + {tShopping("deleteItem")} + + +
)}
);