Skip to content

Commit e50fb8c

Browse files
committed
Adjust header
sort/search should not enter the MoreMenu at smaller resolutions
1 parent 0aa2131 commit e50fb8c

File tree

3 files changed

+81
-26
lines changed

3 files changed

+81
-26
lines changed

app/ui/header.tsx

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,23 @@ export default function Header({ sort, setSort, query, setQuery }: HeaderProps)
2323

2424
return (
2525
<header className="sticky top-0 z-40 backdrop-blur-md bg-neutral-900/70 border-b border-neutral-800/60">
26-
<div className="mx-auto max-w-6xl flex items-center justify-between px-4 sm:px-6 h-16">
26+
<div className="mx-auto max-w-6xl flex items-center justify-between gap-4 px-4 sm:px-6 h-16">
27+
2728
{/* title */}
28-
<h1 className="text-lg sm:text-2xl font-bold tracking-wide whitespace-nowrap select-none">
29+
<h1 className="text-lg md:text-xl xl:text-2xl font-bold tracking-wide whitespace-nowrap select-none min-w-0">
2930
Jacob Robbins&rsquo; <span className="font-light">Skybox&nbsp;Library</span>
3031
</h1>
3132

3233
{/* right-side cluster */}
33-
<div className="flex items-center gap-2 sm:gap-3">
34+
<div className="flex justify-end items-center gap-2 sm:gap-3">
3435
{/* Search + Sort: Desktop (>= sm) */}
3536
<div className="hidden sm:flex items-center gap-3">
3637
<input
3738
value={query}
3839
onChange={(e) => setQuery(e.target.value)}
3940
placeholder="Search…"
4041
className="
41-
flex-auto min-w-0 max-w-[40vw]
42+
flex-auto min-w-0 max-w-xs
4243
rounded-md bg-neutral-800/70
4344
px-3 py-1.5 text-sm placeholder:text-neutral-500
4445
focus:outline-none focus:ring-2 focus:ring-amber-500
@@ -57,10 +58,16 @@ export default function Header({ sort, setSort, query, setQuery }: HeaderProps)
5758
))}
5859
</nav>
5960

60-
{/* More Menu Button: Mobile-only (< sm) */}
61-
{/* TODO: Consider moving Search/Sort/Profile Links into MoreMenu content for mobile */}
62-
<div className="sm:hidden">
63-
<MoreMenu />
61+
{/* More Menu Button: Visible below lg */}
62+
{/* Contains items hidden from the main bar at smaller breakpoints */}
63+
<div className="lg:hidden flex-shrink-0">
64+
<MoreMenu
65+
profileLinks={profileLinks}
66+
sort={sort}
67+
setSort={setSort}
68+
query={query}
69+
setQuery={setQuery}
70+
/>
6471
</div>
6572
</div>
6673
</div>

app/ui/iconlink.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
/* app/ui/iconlink.tsx */
22
import Image from 'next/image';
33

4-
export default function IconLink({ href, label, svg }: { href: string; label: string; svg: string }) {
4+
interface IconLinkProps {
5+
href: string;
6+
label: string;
7+
svg: string;
8+
menuMode?: boolean; // Add optional prop
9+
}
10+
11+
export default function IconLink({ href, label, svg, menuMode = false }: IconLinkProps) {
512
return (
613
<a
714
href={href}
815
aria-label={label}
916
target="_blank"
1017
rel="noreferrer"
11-
className="
12-
flex-none /* never shrink */
13-
p-2 rounded-md
14-
bg-neutral-800/70 hover:bg-neutral-800
15-
focus:outline-none focus:ring-2 focus:ring-amber-500
16-
"
18+
// Apply different styles based on menuMode
19+
className={`
20+
${menuMode
21+
? 'flex items-center gap-3 w-full px-3 py-2 text-sm text-neutral-200 hover:bg-neutral-800'
22+
: 'flex-none p-2 rounded-md bg-neutral-800/70 hover:bg-neutral-800'
23+
}
24+
focus:outline-none focus:ring-2 focus:ring-amber-500 transition-colors
25+
`}
1726
>
18-
<Image src={svg} alt={label} width={20} height={20} />
27+
<Image src={svg} alt="" width={20} height={20} className="flex-shrink-0" />
28+
{/* Show label only in menu mode */}
29+
{menuMode && <span className="flex-grow">{label}</span>}
1930
</a>
2031
);
2132
}

app/ui/moremenu.tsx

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
11
/* app/ui/moremenu.tsx */
22
'use client';
33

4+
import type { Dispatch, SetStateAction } from 'react';
45
import { useState } from 'react';
56
import IconLink from './iconlink';
6-
import { profileLinks } from './profile-links';
7+
import SortSelect from './sort-select'; // Import SortSelect
78

8-
export default function MoreMenu() {
9+
// Types matching those in Header/Page
10+
type SortOption = 'alpha' | 'alpha-desc' | 'published-date-desc' | 'published-date-asc';
11+
interface ProfileLink {
12+
href: string;
13+
label: string;
14+
svg: string;
15+
}
16+
17+
interface MoreMenuProps {
18+
profileLinks: ProfileLink[];
19+
sort: SortOption;
20+
setSort: Dispatch<SetStateAction<SortOption>>;
21+
query: string;
22+
setQuery: Dispatch<SetStateAction<string>>;
23+
}
24+
25+
export default function MoreMenu({ profileLinks, sort, setSort, query, setQuery }: MoreMenuProps) {
926
const [open, setOpen] = useState(false);
1027

1128
return (
1229
<div className="relative flex-shrink-0">
1330
<button
1431
onClick={() => setOpen(!open)}
15-
aria-label="Open links"
16-
className="sm:hidden p-2 rounded-md bg-neutral-800/70 hover:bg-neutral-800 focus:outline-none focus:ring-2 focus:ring-amber-500"
32+
aria-label="Open menu"
33+
className="p-2 rounded-md bg-neutral-800/70 hover:bg-neutral-800 focus:outline-none focus:ring-2 focus:ring-amber-500 lg:hidden"
1734
>
1835
<svg viewBox="0 0 24 24" className="w-4 h-4 fill-neutral-300">
1936
<circle cx="5" cy="12" r="2" />
@@ -23,12 +40,32 @@ export default function MoreMenu() {
2340
</button>
2441

2542
{open && (
26-
<div className="absolute right-0 mt-2 w-40 rounded-md bg-neutral-900 shadow-lg ring-1 ring-neutral-700/60">
27-
<nav className="flex flex-col divide-y divide-neutral-700/60">
28-
{profileLinks.map((l) => (
29-
<IconLink key={l.label} {...l} />
30-
))}
31-
</nav>
43+
<div className="absolute right-0 mt-2 w-56 rounded-md bg-neutral-900 shadow-lg ring-1 ring-neutral-700/60 z-50">
44+
<div className="flex flex-col p-2 gap-2 divide-y divide-neutral-700/60">
45+
46+
{/* Search Input - Shown below sm */}
47+
<div className="sm:hidden px-2 pt-1 pb-2">
48+
<input
49+
value={query}
50+
onChange={(e) => setQuery(e.target.value)}
51+
placeholder="Search…"
52+
className="w-full rounded-md bg-neutral-800 px-3 py-1.5 text-sm placeholder:text-neutral-500 focus:outline-none focus:ring-2 focus:ring-amber-500"
53+
/>
54+
</div>
55+
56+
{/* Sort Select - Shown below md */}
57+
<div className="md:hidden px-2 pt-2 pb-1">
58+
<label className="block text-xs text-neutral-400 mb-1">Sort by:</label>
59+
<SortSelect value={sort} onChange={setSort} />
60+
</div>
61+
62+
{/* Profile Links - Shown below lg */}
63+
<nav className="lg:hidden flex flex-col pt-2">
64+
{profileLinks.map((l) => (
65+
<IconLink key={l.label} {...l} menuMode={true} />
66+
))}
67+
</nav>
68+
</div>
3269
</div>
3370
)}
3471
</div>

0 commit comments

Comments
 (0)