@@ -3,7 +3,7 @@ import classNames from 'classnames'
33import AccountMenu from 'components/account/AccountMenu'
44import AccountSummary from 'components/account/AccountSummary'
55import Card from 'components/common/Card'
6- import { ChevronDown , Discord , Telegram , Twitter } from 'components/common/Icons'
6+ import { Check , ChevronDown , Discord , Telegram , Twitter } from 'components/common/Icons'
77import Settings from 'components/common/Settings'
88import Text from 'components/common/Text'
99import ChainSelect from 'components/header/ChainSelect'
@@ -13,7 +13,7 @@ import useAccountId from 'hooks/accounts/useAccountId'
1313import useAccountTitle from 'hooks/accounts/useAccountTitle'
1414import useChainConfig from 'hooks/chain/useChainConfig'
1515import useV1Account from 'hooks/v1/useV1Account'
16- import { useCallback , useEffect , useMemo } from 'react'
16+ import { useCallback , useEffect , useMemo , useRef , useState } from 'react'
1717import { useLocation , useNavigate , useSearchParams } from 'react-router-dom'
1818import useStore from 'store'
1919import { DocURL } from 'types/enums'
@@ -55,10 +55,33 @@ function Content(props: Props & { account?: Account }) {
5555 const address = useStore ( ( s ) => s . address )
5656 const { pathname } = useLocation ( )
5757 const currentPage = getPage ( pathname , chainConfig )
58+ const [ isDropdownOpen , setIsDropdownOpen ] = useState ( false )
59+ const dropdownRef = useRef < HTMLDivElement > ( null )
5860
5961 const menu = useMemo ( ( ) => menuTree ( chainConfig ) , [ chainConfig , menuTree ] )
6062 const accountTitle = useAccountTitle ( account , true )
6163
64+ const menuItems = useMemo ( ( ) => {
65+ const items : Array < { value : string ; label : string } > = [ ]
66+ for ( const item of menu ) {
67+ if ( item . submenu ) {
68+ const filteredItems = item . submenu . filter ( ( subItem ) => ! subItem . isSeparator )
69+ for ( const subItem of filteredItems ) {
70+ const value = subItem . page || subItem . externalUrl || ''
71+ items . push ( { value, label : subItem . label } )
72+ }
73+ } else {
74+ items . push ( { value : item . pages [ 0 ] , label : item . label } )
75+ }
76+ }
77+ return items
78+ } , [ menu ] )
79+
80+ const currentPageLabel = useMemo ( ( ) => {
81+ const item = menuItems . find ( ( item ) => item . value === currentPage )
82+ return item ?. label || 'Select Page'
83+ } , [ menuItems , currentPage ] )
84+
6285 useEffect ( ( ) => {
6386 if ( mobileNavExpanded ) {
6487 document . body . classList . add ( 'h-screen-full' , 'overflow-hidden' )
@@ -71,8 +94,26 @@ function Content(props: Props & { account?: Account }) {
7194 }
7295 } , [ mobileNavExpanded ] )
7396
97+ // Close dropdown when clicking outside
98+ useEffect ( ( ) => {
99+ const handleClickOutside = ( event : MouseEvent ) => {
100+ if ( dropdownRef . current && ! dropdownRef . current . contains ( event . target as Node ) ) {
101+ setIsDropdownOpen ( false )
102+ }
103+ }
104+
105+ if ( isDropdownOpen ) {
106+ document . addEventListener ( 'mousedown' , handleClickOutside )
107+ }
108+
109+ return ( ) => {
110+ document . removeEventListener ( 'mousedown' , handleClickOutside )
111+ }
112+ } , [ isDropdownOpen ] )
113+
74114 const selectPage = useCallback (
75115 ( page : Page ) => {
116+ setIsDropdownOpen ( false )
76117 window . scrollTo ( 0 , 0 )
77118 if ( typeof window !== 'undefined' ) setTimeout ( ( ) => window . scrollTo ( 0 , 0 ) , 200 )
78119 useStore . setState ( { mobileNavExpanded : false } )
@@ -101,38 +142,32 @@ function Content(props: Props & { account?: Account }) {
101142 </ div >
102143 < div className = 'flex items-center justify-between w-full' >
103144 < Text size = 'sm' > Page:</ Text >
104- < div className = 'relative' >
105- < select
106- className = 'py-1.5 pl-2 pr-6 text-sm text-white bg-transparent border rounded-sm appearance-none border-white/30 focus:outline-none active:outline-none'
107- onChange = { ( event : React . ChangeEvent < HTMLSelectElement > ) =>
108- selectPage ( event . target . value as Page )
109- }
110- defaultValue = { currentPage }
145+ < div className = 'relative' ref = { dropdownRef } >
146+ < button
147+ className = 'py-1.5 pl-2 pr-6 text-sm text-white bg-transparent border rounded-sm border-white/30 focus:outline-none active:outline-none leading-normal min-w-[140px] text-left'
148+ onClick = { ( ) => setIsDropdownOpen ( ! isDropdownOpen ) }
111149 >
112- { menu . map ( ( item ) => {
113- if ( item . submenu ) {
114- return item . submenu
115- . filter ( ( subItem ) => ! subItem . isSeparator && ! subItem . icon )
116- . map ( ( subItem ) => {
117- const value = subItem . page || subItem . externalUrl || ''
118- return (
119- < option key = { value } value = { value } >
120- { `${ item . label } - ${ subItem . label } ` }
121- </ option >
122- )
123- } )
124- }
125-
126- return (
127- < option key = { item . pages [ 0 ] } value = { item . pages [ 0 ] } >
128- { item . label }
129- </ option >
130- )
131- } ) }
132- </ select >
133- < div className = 'absolute w-3 -translate-y-1/2 right-2 top-1/2 -z-1' >
150+ { currentPageLabel }
151+ </ button >
152+ < div className = 'absolute w-3 -translate-y-1/2 right-2 top-1/2 pointer-events-none' >
134153 < ChevronDown />
135154 </ div >
155+ { isDropdownOpen && (
156+ < div className = 'absolute top-full left-0 right-0 mt-1 bg-white/10 backdrop-blur-md border border-white/30 rounded-sm max-h-[400px] overflow-y-auto z-50' >
157+ { menuItems . map ( ( item ) => (
158+ < button
159+ key = { item . value }
160+ className = 'w-full px-2 py-2 text-sm text-left hover:bg-white/20 transition-colors flex items-center gap-2'
161+ onClick = { ( ) => selectPage ( item . value as Page ) }
162+ >
163+ < span className = 'w-4 h-4 flex items-center justify-center flex-shrink-0' >
164+ { item . value === currentPage && < Check className = 'w-4 h-4 text-white' /> }
165+ </ span >
166+ < span className = 'text-white flex-1' > { item . label } </ span >
167+ </ button >
168+ ) ) }
169+ </ div >
170+ ) }
136171 </ div >
137172 </ div >
138173 { ! isV1 && address && (
0 commit comments