fix: recipes page wasted too much vertical space above content on mobile
Search bar forced its own full-width row (w-full), pushing Sort/Filter to a second row below it — on mobile that's title + action buttons + search row + sort/filter row + toolbar row before any recipe appears. Sort/Filter now go icon-only below sm: (text labels hidden, matching the convention already used for compact-view badges), letting Search share one row with both instead of forcing its own. Also tightened the title size and inter-section spacing on mobile (unchanged at sm: and up). Verified at a real 390px mobile viewport: first recipe card now clears with room to spare, versus barely visible at the same viewport height before. Desktop screenshot confirms zero visual change there.
This commit is contained in:
@@ -104,7 +104,7 @@ export default async function RecipesPage({ searchParams }: { searchParams: Sear
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-4 sm:space-y-6">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<span className="rounded-full bg-accent px-3 py-1 font-medium">{m.recipes.tabMine}</span>
|
||||
<Link href="/recipes/favorites" className="rounded-full px-3 py-1 text-muted-foreground hover:bg-accent">
|
||||
|
||||
@@ -127,11 +127,11 @@ export function RecipesHeader({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div className="space-y-3 sm:space-y-4">
|
||||
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between sm:gap-3">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold tracking-tight">{t("title")}</h1>
|
||||
<p className="text-muted-foreground mt-1">
|
||||
<h1 className="text-2xl sm:text-3xl font-bold tracking-tight">{t("title")}</h1>
|
||||
<p className="text-muted-foreground text-sm sm:text-base mt-0.5 sm:mt-1">
|
||||
{count === 0
|
||||
? t("subtitle")
|
||||
: t(count !== 1 ? "resultPlural" : "resultSingular", { count })}
|
||||
@@ -154,8 +154,9 @@ export function RecipesHeader({
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{/* Search */}
|
||||
<div className="relative w-full sm:flex-1 sm:min-w-[200px] sm:max-w-sm">
|
||||
{/* Search — shares the row with Sort/Filter even on mobile now that
|
||||
those are icon-only there, instead of forcing a whole row to itself. */}
|
||||
<div className="relative flex-1 min-w-[120px] sm:min-w-[200px] sm:max-w-sm">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
|
||||
<Input
|
||||
value={query}
|
||||
@@ -178,11 +179,11 @@ export function RecipesHeader({
|
||||
<DropdownMenuTrigger
|
||||
className={cn(
|
||||
buttonVariants({ variant: sortChanged ? "secondary" : "outline", size: "sm" }),
|
||||
"gap-1.5"
|
||||
"gap-1.5 shrink-0"
|
||||
)}
|
||||
>
|
||||
<ArrowUpDown className="h-4 w-4" />
|
||||
{SORT_KEYS[initialSort] ? t(SORT_KEYS[initialSort]) : t("sort")}
|
||||
<span className="hidden sm:inline">{SORT_KEYS[initialSort] ? t(SORT_KEYS[initialSort]) : t("sort")}</span>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuGroup>
|
||||
@@ -206,11 +207,11 @@ export function RecipesHeader({
|
||||
<DropdownMenuTrigger
|
||||
className={cn(
|
||||
buttonVariants({ variant: activeFilterCount > 0 ? "secondary" : "outline", size: "sm" }),
|
||||
"gap-1.5"
|
||||
"gap-1.5 shrink-0"
|
||||
)}
|
||||
>
|
||||
<SlidersHorizontal className="h-4 w-4" />
|
||||
{t("filter")}
|
||||
<span className="hidden sm:inline">{t("filter")}</span>
|
||||
{activeFilterCount > 0 && (
|
||||
<Badge variant="secondary" className="ml-1 h-4 min-w-4 px-1 text-xs">
|
||||
{activeFilterCount}
|
||||
|
||||
Reference in New Issue
Block a user