diff --git a/apps/web/src/features/recipes/IngredientPicker.tsx b/apps/web/src/features/recipes/IngredientPicker.tsx
index 3357e39..79c18fc 100644
--- a/apps/web/src/features/recipes/IngredientPicker.tsx
+++ b/apps/web/src/features/recipes/IngredientPicker.tsx
@@ -7,7 +7,7 @@ import {
} from "@batch-cooking/shared";
import { useState } from "react";
import { useTranslation } from "react-i18next";
-import { AllergenIcon, DietPreferencesIcon } from "../../layouts/nav-icons";
+import { SettingsIcon } from "../../layouts/nav-icons";
import { AllergenBadges } from "./AllergenBadges";
import { DietBadges } from "./DietBadges";
import { CategoryIcon, IngredientTypeIcon, SubcategoryIcon } from "./ingredient-icons";
@@ -32,10 +32,12 @@ const ALL = "ALL" as const;
* ingredients — a recipe's ingredient list, or a profile's disliked list)
* keeps the same one from being added twice.
*
- * The two toggle buttons trailing the search input show/hide the
- * allergen/diet badge rows on every card — a display preference local to
- * this picker (not persisted), for whoever finds two rows of badges per
- * card too noisy while just browsing/searching by name.
+ * The settings menu trailing the search input shows/hides the allergen/diet
+ * badge rows on every card — a display preference local to this picker (not
+ * persisted), for whoever finds two rows of badges per card too noisy while
+ * just browsing/searching by name. A labeled checkbox menu rather than two
+ * bare icon-only toggle buttons — those turned out too ambiguous on their
+ * own (unclear what each icon meant without a label attached).
*/
export function IngredientPicker({
ingredients,
@@ -57,6 +59,7 @@ export function IngredientPicker({
// badges per card too noisy while just browsing/searching by name.
const [showAllergens, setShowAllergens] = useState(true);
const [showDiets, setShowDiets] = useState(true);
+ const [isDisplayMenuOpen, setIsDisplayMenuOpen] = useState(false);
function selectCategory(next: IngredientCategory | typeof ALL) {
setCategory(next);
@@ -90,25 +93,38 @@ export function IngredientPicker({
onChange={(e) => setQuery(e.target.value)}
placeholder={t("recipes.form.searchIngredientPlaceholder")}
/>
-
diff --git a/apps/web/src/features/recipes/recipes.scss b/apps/web/src/features/recipes/recipes.scss
index dcc46a1..e87b36e 100644
--- a/apps/web/src/features/recipes/recipes.scss
+++ b/apps/web/src/features/recipes/recipes.scss
@@ -726,20 +726,19 @@
}
}
- // Show/hide toggles for the allergen/diet badge rows on every card below
- // — trailing the search input, same "icon button with an active state"
- // pattern as `FavoriteStarButton`.
- &__search-toggles {
- display: flex;
+ // Settings menu for the allergen/diet badge rows on every card below —
+ // trailing the search input. A single gear button + labeled checkboxes
+ // (not two bare icon-only toggles, the earlier design here) — an icon
+ // alone couldn't say clearly enough which badge row it hid.
+ &__display-options {
+ position: relative;
flex-shrink: 0;
- gap: var(--space-xs);
}
- &__search-toggle {
+ &__display-toggle {
display: flex;
align-items: center;
justify-content: center;
- flex-shrink: 0;
width: 2.25rem;
height: 2.25rem;
padding: 0;
@@ -765,6 +764,31 @@
}
}
+ // Anchored below-right of the toggle — same transient-overlay reasoning
+ // as `.app-sidebar__account-menu` (AppLayout.scss).
+ &__display-menu {
+ position: absolute;
+ z-index: 10;
+ top: calc(100% + var(--space-xs));
+ right: 0;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-sm);
+ padding: var(--space-sm);
+ background: var(--color-surface);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-base);
+ box-shadow: var(--shadow-md);
+
+ // Box/checkmark look comes from the app-wide "selectable card" rule in
+ // global.scss (`label:has(> input[type="checkbox"])`) — this only adds
+ // what's specific to sitting inside a dropdown menu.
+ label {
+ font-size: var(--font-size-sm);
+ white-space: nowrap;
+ }
+ }
+
&__categories {
display: flex;
gap: var(--space-xs);
diff --git a/apps/web/src/layouts/nav-icons.tsx b/apps/web/src/layouts/nav-icons.tsx
index 25de06d..90adceb 100644
--- a/apps/web/src/layouts/nav-icons.tsx
+++ b/apps/web/src/layouts/nav-icons.tsx
@@ -128,14 +128,3 @@ export function PublicIcon() {
);
}
-
-/** Allergens — the show/hide allergen-badges toggle on `IngredientPicker`'s search bar. */
-export function AllergenIcon() {
- return (
-
-
-
-
-
- );
-}
diff --git a/apps/web/src/locales/fr/translation.json b/apps/web/src/locales/fr/translation.json
index 3598b17..2d0c7f0 100644
--- a/apps/web/src/locales/fr/translation.json
+++ b/apps/web/src/locales/fr/translation.json
@@ -166,8 +166,9 @@
},
"dietsLabel": "Régime(s) associé(s)",
"searchIngredientPlaceholder": "Rechercher un ingrédient…",
- "toggleDiets": "Afficher/masquer les régimes alimentaires",
- "toggleAllergens": "Afficher/masquer les allergènes",
+ "displayOptions": "Options d'affichage",
+ "showDietsLabel": "Régimes alimentaires",
+ "showAllergensLabel": "Allergènes",
"allCategories": "Tout",
"allSubcategories": "Tout",
"noIngredientFound": "Aucun ingrédient trouvé.",