Moved all nav items inside the mobile menu.
This commit is contained in:
parent
a2dab4d72f
commit
a1d89dd0d3
@ -49,6 +49,8 @@ export default function Navbar({ selectedRole, onRoleSelect }: NavbarProps) {
|
|||||||
const ref = useRef<HTMLDivElement>(null)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
||||||
const mobileMenuRef = useRef<HTMLDivElement>(null)
|
const mobileMenuRef = useRef<HTMLDivElement>(null)
|
||||||
|
const [mobileRoleOpen, setMobileRoleOpen] = useState(false)
|
||||||
|
const mobileRoleRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) return
|
if (!open) return
|
||||||
@ -72,9 +74,20 @@ export default function Navbar({ selectedRole, onRoleSelect }: NavbarProps) {
|
|||||||
return () => document.removeEventListener('mousedown', handleClick)
|
return () => document.removeEventListener('mousedown', handleClick)
|
||||||
}, [mobileMenuOpen])
|
}, [mobileMenuOpen])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!mobileRoleOpen) return
|
||||||
|
function handleClick(e: MouseEvent) {
|
||||||
|
if (mobileRoleRef.current && !mobileRoleRef.current.contains(e.target as Node)) {
|
||||||
|
setMobileRoleOpen(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('mousedown', handleClick)
|
||||||
|
return () => document.removeEventListener('mousedown', handleClick)
|
||||||
|
}, [mobileRoleOpen])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="fixed top-0 left-0 right-0 z-50 bg-background/80 backdrop-blur-xl border-b border-border/40 transition-all duration-300">
|
<header className="fixed top-0 left-0 right-0 z-50 bg-background/80 backdrop-blur-xl border-b border-border/40 transition-all duration-300">
|
||||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 h-16 flex items-center gap-6">
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 h-16 flex items-center justify-between gap-6">
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
aria-label="BTCPay Contribute home"
|
aria-label="BTCPay Contribute home"
|
||||||
@ -122,29 +135,105 @@ export default function Navbar({ selectedRole, onRoleSelect }: NavbarProps) {
|
|||||||
<div
|
<div
|
||||||
role="menu"
|
role="menu"
|
||||||
aria-label="Navigation menu"
|
aria-label="Navigation menu"
|
||||||
className="absolute left-0 top-full mt-1.5 w-48 rounded-xl border border-border/60 bg-background/95 backdrop-blur-xl shadow-lg overflow-hidden"
|
className="absolute right-0 top-full mt-1.5 w-56 rounded-xl border border-border/60 bg-background/95 backdrop-blur-xl shadow-lg overflow-hidden"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="#issues"
|
href="#issues"
|
||||||
onClick={() => setMobileMenuOpen(false)}
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
className="block w-full px-4 py-2.5 text-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors duration-100"
|
className="block w-full px-4 py-4 text-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors duration-100"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
>
|
>
|
||||||
Contribute
|
Contribute
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div className="border-t border-border/40" />
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href="#how-it-works"
|
href="#how-it-works"
|
||||||
onClick={() => setMobileMenuOpen(false)}
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
className="block w-full px-4 py-2.5 text-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors duration-100"
|
className="block w-full px-4 py-4 text-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors duration-100"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
>
|
>
|
||||||
How it works
|
How it works
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div className="border-t border-border/40" />
|
||||||
|
|
||||||
|
<div ref={mobileRoleRef} className="px-4 py-2.5 relative">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setMobileRoleOpen((v) => !v)}
|
||||||
|
aria-haspopup="listbox"
|
||||||
|
aria-expanded={mobileRoleOpen}
|
||||||
|
aria-label="Change contribution role"
|
||||||
|
className="w-full flex items-center justify-between gap-1.5 py-1.5 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors duration-100"
|
||||||
|
>
|
||||||
|
<span className="flex items-center gap-1.5">
|
||||||
|
<span className="text-primary">{ROLE_ICON[selectedRole]}</span>
|
||||||
|
{ROLE_LABEL[selectedRole]}
|
||||||
|
</span>
|
||||||
|
<ChevronDown
|
||||||
|
size={12}
|
||||||
|
className={`text-muted-foreground transition-transform duration-150 ${mobileRoleOpen ? 'rotate-180' : ''}`}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{mobileRoleOpen && (
|
||||||
|
<div
|
||||||
|
role="listbox"
|
||||||
|
aria-label="Select role"
|
||||||
|
className="mt-1.5 rounded-lg border border-border/60 bg-muted/50 overflow-hidden"
|
||||||
|
>
|
||||||
|
{ROLES.map((role) => (
|
||||||
|
<button
|
||||||
|
key={role}
|
||||||
|
type="button"
|
||||||
|
role="option"
|
||||||
|
aria-selected={role === selectedRole}
|
||||||
|
onClick={() => { onRoleSelect(role); setMobileRoleOpen(false); setMobileMenuOpen(false) }}
|
||||||
|
className={`w-full flex items-center gap-2 px-3 py-2 text-sm transition-colors duration-100 hover:bg-muted ${
|
||||||
|
role === selectedRole
|
||||||
|
? 'text-primary font-medium'
|
||||||
|
: 'text-muted-foreground'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<span className={role === selectedRole ? 'text-primary' : 'text-muted-foreground'}>
|
||||||
|
{ROLE_ICON[role]}
|
||||||
|
</span>
|
||||||
|
{ROLE_LABEL[role]}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border-t border-border/40" />
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://github.com/btcpayserver/btcpay-contribute"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
className="flex items-center justify-between gap-2 w-full px-4 py-4 text-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors duration-100"
|
||||||
|
role="menuitem"
|
||||||
|
>
|
||||||
|
GitHub
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||||||
|
<path fillRule="evenodd" clipRule="evenodd" d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div className="border-t border-border/40" />
|
||||||
|
|
||||||
|
<div className="pl-4 pr-1.5 py-2 flex items-center justify-between">
|
||||||
|
<span className="text-sm text-muted-foreground">Theme</span>
|
||||||
|
<ThemeToggle />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div className="flex items-center gap-1.5 ml-auto">
|
<div className="hidden sm:flex items-center gap-1.5 ml-auto">
|
||||||
<div ref={ref} className="relative block">
|
<div ref={ref} className="relative block">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user