Update roadmaps dropdown

feat/roadmap-nav
Kamran Ahmed 2 months ago
parent 7f681408a7
commit a658f4dbb8
  1. 30
      src/components/NavigationDropdown.tsx
  2. 33
      src/components/RoadmapDropdownMenu/RoadmapDropdownMenu.tsx
  3. 3
      src/stores/page.ts

@ -8,9 +8,14 @@ import {
Video, Video,
Waypoints, Waypoints,
} from 'lucide-react'; } from 'lucide-react';
import { useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { cn } from '../lib/classname.ts'; import { cn } from '../lib/classname.ts';
import { useOutsideClick } from '../hooks/use-outside-click.ts'; import { useOutsideClick } from '../hooks/use-outside-click.ts';
import {
navigationDropdownOpen,
roadmapsDropdownOpen,
} from '../stores/page.ts';
import { useStore } from '@nanostores/react';
const links = [ const links = [
{ {
@ -61,22 +66,30 @@ const links = [
export function NavigationDropdown() { export function NavigationDropdown() {
const dropdownRef = useRef<HTMLDivElement>(null); const dropdownRef = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState(false);
const $navigationDropdownOpen = useStore(navigationDropdownOpen);
const $roadmapsDropdownOpen = useStore(roadmapsDropdownOpen);
useOutsideClick(dropdownRef, () => { useOutsideClick(dropdownRef, () => {
setIsOpen(false); navigationDropdownOpen.set(false);
}); });
useEffect(() => {
if ($roadmapsDropdownOpen) {
navigationDropdownOpen.set(false);
}
}, [$roadmapsDropdownOpen]);
return ( return (
<div className="relative flex items-center" ref={dropdownRef}> <div className="relative flex items-center" ref={dropdownRef}>
<button <button
className={cn('text-gray-400 hover:text-white', { className={cn('text-gray-400 hover:text-white', {
'text-white': isOpen, 'text-white': $navigationDropdownOpen,
})} })}
onClick={() => setIsOpen(true)} onClick={() => navigationDropdownOpen.set(true)}
onMouseOver={() => setIsOpen(true)} onMouseOver={() => navigationDropdownOpen.set(true)}
aria-label="Open Navigation Dropdown" aria-label="Open Navigation Dropdown"
aria-expanded={isOpen} aria-expanded={$navigationDropdownOpen}
> >
<Menu className="h-5 w-5" /> <Menu className="h-5 w-5" />
</button> </button>
@ -84,7 +97,8 @@ export function NavigationDropdown() {
className={cn( className={cn(
'pointer-events-none invisible absolute left-0 top-full z-[999] mt-2 w-48 min-w-[320px] -translate-y-1 rounded-lg bg-slate-800 py-2 opacity-0 shadow-xl transition-all duration-100', 'pointer-events-none invisible absolute left-0 top-full z-[999] mt-2 w-48 min-w-[320px] -translate-y-1 rounded-lg bg-slate-800 py-2 opacity-0 shadow-xl transition-all duration-100',
{ {
'pointer-events-auto visible translate-y-2.5 opacity-100': isOpen, 'pointer-events-auto visible translate-y-2.5 opacity-100':
$navigationDropdownOpen,
}, },
)} )}
role="menu" role="menu"

@ -1,7 +1,12 @@
import { ChevronDown, Globe, Menu, Sparkles, Waypoints } from 'lucide-react'; import { ChevronDown, Globe, Menu, Sparkles, Waypoints } from 'lucide-react';
import { useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { useOutsideClick } from '../../hooks/use-outside-click'; import { useOutsideClick } from '../../hooks/use-outside-click';
import { cn } from '../../lib/classname'; import { cn } from '../../lib/classname';
import {
navigationDropdownOpen,
roadmapsDropdownOpen,
} from '../../stores/page.ts';
import { useStore } from '@nanostores/react';
const links = [ const links = [
{ {
@ -26,30 +31,40 @@ const links = [
export function RoadmapDropdownMenu() { export function RoadmapDropdownMenu() {
const dropdownRef = useRef<HTMLDivElement>(null); const dropdownRef = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState(false);
const $roadmapsDropdownOpen = useStore(roadmapsDropdownOpen);
const $navigationDropdownOpen = useStore(navigationDropdownOpen);
useOutsideClick(dropdownRef, () => { useOutsideClick(dropdownRef, () => {
setIsOpen(false); roadmapsDropdownOpen.set(false);
}); });
useEffect(() => {
if ($navigationDropdownOpen) {
roadmapsDropdownOpen.set(false);
}
}, [$navigationDropdownOpen]);
return ( return (
<div className="relative flex items-center" ref={dropdownRef}> <div className="relative flex items-center" ref={dropdownRef}>
<button <button
className={cn('text-gray-400 hover:text-white', { className={cn('text-gray-400 hover:text-white', {
'text-white': isOpen, 'text-white': $roadmapsDropdownOpen,
})} })}
onClick={() => setIsOpen(true)} onClick={() => roadmapsDropdownOpen.set(true)}
onMouseOver={() => setIsOpen(true)} onMouseOver={() => roadmapsDropdownOpen.set(true)}
aria-label="Open Navigation Dropdown" aria-label="Open Navigation Dropdown"
aria-expanded={isOpen} aria-expanded={$roadmapsDropdownOpen}
> >
Roadmaps <ChevronDown className="inline-block h-3 w-3" strokeWidth={4} /> Roadmaps{' '}
<ChevronDown className="inline-block h-3 w-3" strokeWidth={4} />
</button> </button>
<div <div
className={cn( className={cn(
'pointer-events-none invisible absolute left-0 top-full z-[999] mt-2 w-48 min-w-[320px] -translate-y-1 rounded-lg bg-slate-800 py-2 opacity-0 shadow-2xl transition-all duration-100', 'pointer-events-none invisible absolute left-0 top-full z-[999] mt-2 w-48 min-w-[320px] -translate-y-1 rounded-lg bg-slate-800 py-2 opacity-0 shadow-2xl transition-all duration-100',
{ {
'pointer-events-auto visible translate-y-2.5 opacity-100': isOpen, 'pointer-events-auto visible translate-y-2.5 opacity-100':
$roadmapsDropdownOpen,
}, },
)} )}
role="menu" role="menu"

@ -2,3 +2,6 @@ import { atom } from 'nanostores';
export const pageProgressMessage = atom<string | undefined>(undefined); export const pageProgressMessage = atom<string | undefined>(undefined);
export const sponsorHidden = atom(false); export const sponsorHidden = atom(false);
export const roadmapsDropdownOpen = atom(false);
export const navigationDropdownOpen = atom(false);
Loading…
Cancel
Save