@@ -5,7 +5,11 @@ import ResizeDetector from 'react-resize-detector'
5
5
import ChosenArrow from '../ChosenArrow'
6
6
import IconArrowSmalldown from '../../assets/images/arrow-small-down.svg'
7
7
import IconArrowSmallup from '../../assets/images/arrow-small-up.svg'
8
+ import MagnifyingGlass from '../../assets/images/magnifying_glass.svg'
8
9
import styles from './PrimaryNav.module.scss'
10
+ import { config } from 'topcoder-react-utils'
11
+
12
+ const BASE_URL = config . URL . BASE
9
13
10
14
const PrimaryNav = ( {
11
15
collapsed,
@@ -27,94 +31,147 @@ const PrimaryNav = ({
27
31
createHandleClickMoreItem,
28
32
createSetRef,
29
33
showChosenArrow,
30
- chosenArrowX
34
+ chosenArrowX,
35
+ searchOpened,
36
+ toggleSearchOpen
31
37
} ) => {
32
38
const filterNotInMore = menu => ! ( moreMenu || [ ] ) . find ( x => x . id === menu . id )
33
-
39
+ const activeTrigger = {
40
+ bottom : 50 // The main nav head bottom Y
41
+ }
34
42
return (
35
- < div className = { cn ( styles . primaryNavContainer , showLeftMenu && styles . primaryNavContainerOpen ) } >
36
- < div className = { styles . primaryNav } ref = { createSetRef ( 'primaryNav' ) } >
37
- < a
38
- className = { cn ( styles . tcLogo , collapsed && styles . tcLogoPush ) }
39
- onClick = { onClickLogo }
40
- href = '/'
41
- >
42
- { logo }
43
- </ a >
44
- { menu . map ( ( level1 , i ) => ( [
45
- < span className = { styles . primaryLevel1Separator } key = { `separator-${ i } ` } /> ,
46
- /* Level 1 menu item */
43
+ < div >
44
+ < div className = { cn ( styles . primaryNavContainer , showLeftMenu && styles . primaryNavContainerOpen ) } >
45
+ < div className = { styles . primaryNav } ref = { createSetRef ( 'primaryNav' ) } >
47
46
< a
48
- className = { cn ( styles . primaryLevel1 , ! activeLevel2Id && level1 . id === activeLevel1Id && styles . primaryLevel1Open , level1 . mobileOnly && styles . mobileOnly ) }
49
- href = { level1 . href }
50
- key = { `level1-${ i } ` }
51
- onClick = { createHandleClickLevel1 ( level1 . id , true ) }
52
- ref = { createSetRef ( level1 . id ) }
47
+ className = { cn ( styles . tcLogo , collapsed && styles . tcLogoPush ) }
48
+ onClick = { onClickLogo }
49
+ href = '/'
53
50
>
54
- { level1 . title }
55
- </ a > ,
56
- /* Level 2 menu */
57
- level1 . subMenu && (
58
- < div
59
- className = { cn ( styles . primaryLevel2Container , level1 . id === activeLevel1Id && styles . primaryLevel2ContainerOpen ) }
60
- key = { `level2-${ i } -container` }
61
- ref = { createSetRef ( `level2Container${ i } ` ) }
51
+ { logo }
52
+ </ a >
53
+ { menu . map ( ( level1 , i ) => ( [
54
+ < span className = { styles . primaryLevel1Separator } key = { `separator-${ i } ` } /> ,
55
+ /* Level 1 menu item */
56
+ < a
57
+ className = { cn ( styles . primaryLevel1 , ! activeLevel2Id && level1 . id === activeLevel1Id && styles . primaryLevel1Open , level1 . mobileOnly && styles . mobileOnly ) }
58
+ href = { level1 . href }
59
+ key = { `level1-${ i } ` }
60
+ onClick = { createHandleClickLevel1 ( level1 . id , true ) }
61
+ ref = { createSetRef ( level1 . id ) }
62
62
>
63
- { level1 . subMenu . filter ( filterNotInMore ) . map ( ( level2 , i ) => (
64
- < a
65
- className = { cn ( styles . primaryLevel2 , level2 . id === activeLevel2Id && styles . primaryLevel2Open ) }
66
- href = { level2 . href }
67
- key = { `level2-${ i } ` }
68
- onClick = { createHandleClickLevel2 ( level2 . id , true ) }
69
- ref = { createSetRef ( level2 . id ) }
70
- >
71
- { level2 . title }
72
- </ a >
73
- ) ) }
74
- { /* The More menu */ }
75
- { level1 . id === activeLevel1Id && moreMenu && moreMenu . length > 0 && (
76
- < div className = { cn ( styles . moreBtnContainer , openMore && styles . moreOpen ) } >
77
- < div className = { styles . backdrop } onClick = { onCloseMore } />
78
- < button
79
- className = { cn ( styles . primaryLevel2 , styles . moreBtn ) }
80
- onClick = { handleClickMore }
81
- ref = { createSetRef ( moreId ) }
63
+ { level1 . title }
64
+ </ a > ,
65
+ /* Level 2 menu */
66
+ level1 . subMenu && (
67
+ < div
68
+ className = { cn ( styles . primaryLevel2Container , level1 . id === activeLevel1Id && styles . primaryLevel2ContainerOpen ) }
69
+ key = { `level2-${ i } -container` }
70
+ ref = { createSetRef ( `level2Container${ i } ` ) }
71
+ >
72
+ { level1 . subMenu . filter ( filterNotInMore ) . map ( ( level2 , i ) => (
73
+ < a
74
+ className = { cn ( styles . primaryLevel2 , level2 . id === activeLevel2Id && styles . primaryLevel2Open ) }
75
+ href = { level2 . href }
76
+ key = { `level2-${ i } ` }
77
+ onClick = { createHandleClickLevel2 ( level2 . id , true ) }
78
+ ref = { createSetRef ( level2 . id ) }
82
79
>
83
- < div className = { styles . moreBtnMask } />
84
- < span > More</ span >
85
- { openMore && < IconArrowSmallup /> }
86
- { ! openMore && < IconArrowSmalldown /> }
87
- </ button >
88
- < div className = { styles . moreContentContainer } >
89
- { moreMenu . map ( ( menu , i ) => (
90
- < a
91
- className = { cn ( styles . primaryLevel2 , menu . id === activeLevel2Id && styles . primaryLevel2Open ) }
92
- href = { menu . href }
93
- key = { `more-item-${ i } ` }
94
- onClick = { createHandleClickMoreItem ( menu . id ) }
95
- >
96
- { menu . title }
97
- </ a >
98
- ) ) }
80
+ { level2 . title }
81
+ </ a >
82
+ ) ) }
83
+ { /* The More menu */ }
84
+ { level1 . id === activeLevel1Id && moreMenu && moreMenu . length > 0 && (
85
+ < div className = { cn ( styles . moreBtnContainer , openMore && styles . moreOpen ) } >
86
+ < div className = { styles . backdrop } onClick = { onCloseMore } />
87
+ < button
88
+ className = { cn ( styles . primaryLevel2 , styles . moreBtn ) }
89
+ onClick = { handleClickMore }
90
+ ref = { createSetRef ( moreId ) }
91
+ >
92
+ < div className = { styles . moreBtnMask } />
93
+ < span > More</ span >
94
+ { openMore && < IconArrowSmallup /> }
95
+ { ! openMore && < IconArrowSmalldown /> }
96
+ </ button >
97
+ < div className = { styles . moreContentContainer } >
98
+ { moreMenu . map ( ( menu , i ) => (
99
+ < a
100
+ className = { cn ( styles . primaryLevel2 , menu . id === activeLevel2Id && styles . primaryLevel2Open ) }
101
+ href = { menu . href }
102
+ key = { `more-item-${ i } ` }
103
+ onClick = { createHandleClickMoreItem ( menu . id ) }
104
+ >
105
+ { menu . title }
106
+ </ a >
107
+ ) ) }
108
+ </ div >
99
109
</ div >
100
- </ div >
101
- ) }
110
+ ) }
111
+ </ div >
112
+ )
113
+ ] ) ) }
114
+ < ChosenArrow show = { showChosenArrow } x = { chosenArrowX } />
115
+ </ div >
116
+ < div className = { styles . primaryNavRight } >
117
+ < ResizeDetector
118
+ handleWidth
119
+ onResize = { onRightMenuResize }
120
+ />
121
+ { rightMenu && (
122
+ < div className = { styles . primaryLevel1 } >
123
+ { rightMenu }
102
124
</ div >
103
- )
104
- ] ) ) }
105
- < ChosenArrow show = { showChosenArrow } x = { chosenArrowX } />
125
+ ) }
126
+ < div
127
+ aria-label = 'Find members by username or skill'
128
+ role = 'button'
129
+ tabIndex = { 0 }
130
+ data-menu = 'search'
131
+ className = { cn ( styles . searchIcon , { opened : searchOpened } ) }
132
+ onFocus = { ( ) => toggleSearchOpen ( true ) }
133
+ onBlur = { ( event ) => {
134
+ if ( event . pageY < activeTrigger . bottom ) {
135
+ toggleSearchOpen ( false )
136
+ }
137
+ } }
138
+ onMouseEnter = { ( event ) => toggleSearchOpen ( true ) }
139
+ onMouseLeave = { ( event ) => {
140
+ console . log ( `${ event . clientX } - ${ event . clientY } ` )
141
+ if ( event . pageY < activeTrigger . bottom ) {
142
+ toggleSearchOpen ( false )
143
+ }
144
+ } }
145
+ onTouchStart = { ( event ) => {
146
+ if ( searchOpened ) {
147
+ toggleSearchOpen ( false )
148
+ } else {
149
+ toggleSearchOpen ( true )
150
+ }
151
+ } }
152
+ >
153
+ < MagnifyingGlass />
154
+ </ div >
155
+ </ div >
106
156
</ div >
107
-
108
- < div className = { styles . primaryNavRight } >
109
- < ResizeDetector
110
- handleWidth
111
- onResize = { onRightMenuResize }
157
+ < div
158
+ role = 'search'
159
+ className = { cn ( styles . searchField , { opened : searchOpened , closed : ! searchOpened } ) }
160
+ onMouseLeave = { ( event ) => { toggleSearchOpen ( false ) } }
161
+ >
162
+ < input
163
+ ref = { createSetRef ( 'searchInputBox' ) }
164
+ onKeyPress = { ( event ) => {
165
+ if ( event . key === 'Enter' ) {
166
+ window . location = `${ BASE_URL } /search/members?q=${
167
+ encodeURIComponent ( event . target . value )
168
+ } `
169
+ }
170
+ } }
171
+ onBlur = { ( ) => toggleSearchOpen ( false ) }
172
+ aria-label = 'Find members by username or skill'
173
+ placeholder = 'Find members by username or skill'
112
174
/>
113
- { rightMenu && (
114
- < div className = { styles . primaryLevel1 } >
115
- { rightMenu }
116
- </ div >
117
- ) }
118
175
</ div >
119
176
</ div >
120
177
)
@@ -140,7 +197,9 @@ PrimaryNav.propTypes = {
140
197
createHandleClickMoreItem : PropTypes . func ,
141
198
createSetRef : PropTypes . func ,
142
199
showChosenArrow : PropTypes . bool ,
143
- chosenArrowX : PropTypes . number
200
+ chosenArrowX : PropTypes . number ,
201
+ searchOpened : PropTypes . bool ,
202
+ toggleSearchOpen : PropTypes . func
144
203
}
145
204
146
205
export default PrimaryNav
0 commit comments