@@ -9,114 +9,156 @@ import useSiteMetadata from '../hooks/use-site-metadata'
9
9
import { HEADER_BAR , HEADER_HEIGHT } from '../constants'
10
10
import { LightTheme } from '../theme'
11
11
12
- function MobileSearch ( { onDismiss , ...props } ) {
12
+ function MobileSearch ( { open , setOpen , ...props } ) {
13
13
const siteMetadata = useSiteMetadata ( )
14
- const { reset, results, isOpen, getInputProps, getItemProps, getMenuProps, highlightedIndex} = props
14
+ const { reset, results, isOpen : resultsOpen , getInputProps, getItemProps, getMenuProps, highlightedIndex} = props
15
15
16
16
const handleDismiss = ( ) => {
17
17
reset ( )
18
- onDismiss ( )
18
+ setOpen ( false )
19
19
}
20
20
21
21
return (
22
- < FocusOn returnFocus = { true } onEscapeKey = { handleDismiss } >
23
- < Box
24
- sx = { {
25
- position : 'fixed' ,
26
- top : `${ HEADER_BAR } px` ,
27
- left : 0 ,
28
- right : 0 ,
29
- bottom : 0 ,
30
- zIndex : 1 ,
31
- } }
32
- >
33
- < Box
34
- sx = { {
35
- position : 'absolute' ,
36
- top : 0 ,
37
- left : 0 ,
38
- right : 0 ,
39
- bottom : 0 ,
40
- bg : 'canvas.backdrop' ,
41
- zIndex : - 1 ,
42
- } }
43
- as = { motion . div }
44
- initial = { { opacity : 0 } }
45
- animate = { { opacity : 1 } }
46
- exit = { { opacity : 0 } }
47
- onClick = { handleDismiss }
48
- />
49
- < Box sx = { { display : 'flex' , flexDirection : 'column' , height : isOpen ? '100%' : 'auto' } } >
22
+ < AnimatePresence >
23
+ { open ? (
24
+ < FocusOn returnFocus = { true } onEscapeKey = { handleDismiss } >
50
25
< Box
51
26
sx = { {
52
- display : 'flex' ,
53
- bg : 'canvas.default' ,
54
- color : 'fg.default' ,
55
- height : `${ HEADER_HEIGHT } px` ,
56
- flex : '0 0 auto' ,
57
- px : 3 ,
58
- alignItems : 'center' ,
59
- border : '1px solid' ,
60
- borderTopWidth : 0 ,
61
- borderLeftWidth : 0 ,
62
- borderRightWidth : 0 ,
63
- borderColor : 'border.muted' ,
27
+ position : 'fixed' ,
28
+ top : `${ HEADER_BAR } px` ,
29
+ left : 0 ,
30
+ right : 0 ,
31
+ bottom : 0 ,
32
+ zIndex : 1 ,
64
33
} }
65
34
>
66
- < motion . div
67
- initial = { { scaleX : 0.1 } }
68
- animate = { { scaleX : 1 } }
69
- exit = { { scaleX : 0.1 , transition : { duration : 0.1 } } }
70
- transition = { { type : 'tween' , duration : 0.2 } }
71
- style = { { width : '100%' , originX : '100%' } }
72
- >
73
- < TextInput
74
- leadingVisual = { SearchIcon }
75
- placeholder = { `Search ${ siteMetadata . title } ` }
76
- aria-label = { `Search ${ siteMetadata . title } ` }
77
- sx = { { width : '100%' } }
78
- { ...getInputProps ( ) }
79
- />
80
- </ motion . div >
81
- < Button sx = { { ml : 3 } } aria-label = "Cancel" onClick = { handleDismiss } >
82
- < XIcon />
83
- </ Button >
84
- </ Box >
85
- < LightTheme >
86
35
< Box
87
36
sx = { {
88
- display : 'flex' ,
89
- bg : 'canvas.default' ,
90
- py : isOpen ? 1 : 0 ,
91
- flexDirection : 'column' ,
92
- flex : '1 1 auto' ,
93
- overflow : 'auto' ,
94
- } }
95
- style = { {
96
- WebkitOverflowScrolling : 'touch' ,
37
+ position : 'absolute' ,
38
+ top : 0 ,
39
+ left : 0 ,
40
+ right : 0 ,
41
+ bottom : 0 ,
42
+ bg : 'overlay.backdrop' ,
43
+ zIndex : - 1 ,
97
44
} }
98
- { ...getMenuProps ( ) }
99
- >
100
- { isOpen ? < SearchResults { ...{ results, getItemProps, highlightedIndex} } /> : null }
45
+ key = "search-backdrop"
46
+ as = { motion . div }
47
+ initial = { { opacity : 0 } }
48
+ animate = { { opacity : 1 } }
49
+ exit = { { opacity : 0 } }
50
+ transition = { { type : 'tween' } }
51
+ onClick = { handleDismiss }
52
+ />
53
+ < Box sx = { { display : 'flex' , flexDirection : 'column' , height : resultsOpen ? '100%' : 'auto' } } >
54
+ < Box
55
+ sx = { {
56
+ display : 'flex' ,
57
+ color : 'fg.default' ,
58
+ height : `${ HEADER_HEIGHT } px` ,
59
+ flex : '0 0 auto' ,
60
+ px : 3 ,
61
+ alignItems : 'center' ,
62
+ border : '1px solid' ,
63
+ borderTopWidth : 0 ,
64
+ borderLeftWidth : 0 ,
65
+ borderRightWidth : 0 ,
66
+ borderColor : 'border.muted' ,
67
+ position : 'relative' ,
68
+ } }
69
+ >
70
+ < motion . div
71
+ key = "search-box"
72
+ initial = { { scaleX : 0 } }
73
+ animate = { { scaleX : 1 } }
74
+ exit = { { scaleX : 0 } }
75
+ transition = { { type : 'tween' , ease : 'easeOut' , duration : 0.2 } }
76
+ style = { { width : '100%' , originX : '100%' } }
77
+ >
78
+ < Box
79
+ sx = { {
80
+ position : 'absolute' ,
81
+ top : 0 ,
82
+ bottom : 0 ,
83
+ left : 0 ,
84
+ width : '70px' ,
85
+ bg : 'canvas.default' ,
86
+ zIndex : '-1' ,
87
+ } }
88
+ />
89
+ < TextInput
90
+ leadingVisual = { SearchIcon }
91
+ placeholder = { `Search ${ siteMetadata . title } ` }
92
+ aria-label = { `Search ${ siteMetadata . title } ` }
93
+ sx = { { width : '100%' } }
94
+ { ...getInputProps ( ) }
95
+ />
96
+ </ motion . div >
97
+ < Box
98
+ key = "button-blocker"
99
+ as = { motion . div }
100
+ initial = { { opacity : 0 } }
101
+ animate = { { opacity : 1 } }
102
+ exit = { { opacity : 0 } }
103
+ transition = { { type : 'tween' , ease : 'easeOut' , duration : 0.2 } }
104
+ sx = { {
105
+ position : 'absolute' ,
106
+ top : 0 ,
107
+ bottom : 0 ,
108
+ right : 0 ,
109
+ width : '70px' ,
110
+ bg : 'canvas.default' ,
111
+ zIndex : '-1' ,
112
+ } }
113
+ />
114
+ < Box
115
+ key = "button"
116
+ as = { motion . div }
117
+ initial = { { opacity : 0 } }
118
+ animate = { { opacity : 1 } }
119
+ exit = { { opacity : 0 } }
120
+ transition = { { type : 'tween' , ease : 'easeOut' , duration : 0.2 } }
121
+ >
122
+ < Button sx = { { ml : 3 } } aria-label = "Cancel" onClick = { handleDismiss } >
123
+ < XIcon />
124
+ </ Button >
125
+ </ Box >
126
+ </ Box >
127
+ < LightTheme >
128
+ < Box
129
+ sx = { {
130
+ display : 'flex' ,
131
+ bg : 'canvas.default' ,
132
+ py : resultsOpen ? 1 : 0 ,
133
+ flexDirection : 'column' ,
134
+ flex : '1 1 auto' ,
135
+ overflow : 'auto' ,
136
+ } }
137
+ style = { {
138
+ WebkitOverflowScrolling : 'touch' ,
139
+ } }
140
+ { ...getMenuProps ( ) }
141
+ >
142
+ { resultsOpen ? < SearchResults { ...{ results, getItemProps, highlightedIndex} } /> : null }
143
+ </ Box >
144
+ </ LightTheme >
101
145
</ Box >
102
- </ LightTheme >
103
- </ Box >
104
- </ Box >
105
- </ FocusOn >
146
+ </ Box >
147
+ </ FocusOn >
148
+ ) : null }
149
+ </ AnimatePresence >
106
150
)
107
151
}
108
152
109
153
function MobileSearchWrapper ( props ) {
110
- const [ isOpen , setIsOpen ] = React . useState ( false )
154
+ const [ open , setOpen ] = React . useState ( false )
111
155
112
156
return (
113
157
< >
114
- < Button aria-label = "Search" aria-expanded = { isOpen } onClick = { ( ) => setIsOpen ( true ) } >
158
+ < Button aria-label = "Search" aria-expanded = { open } onClick = { ( ) => setOpen ( true ) } >
115
159
< SearchIcon />
116
160
</ Button >
117
- < AnimatePresence >
118
- { isOpen ? < MobileSearch onDismiss = { ( ) => setIsOpen ( false ) } { ...props } /> : null }
119
- </ AnimatePresence >
161
+ < MobileSearch open = { open } setOpen = { setOpen } { ...props } />
120
162
</ >
121
163
)
122
164
}
0 commit comments