@@ -35,7 +35,7 @@ export function createDropdown(
35
35
const makeWidget = instantsearch . widgets . panel ( {
36
36
cssClasses,
37
37
templates : {
38
- header : ( options ) => {
38
+ header : options => {
39
39
const { widgetParams } = options ;
40
40
41
41
let text ;
@@ -51,7 +51,7 @@ export function createDropdown(
51
51
: '' ;
52
52
// Get the number of refinements if the widget has `items`
53
53
const nbRefinements = ( options . items || [ ] ) . filter (
54
- ( item ) => item . isRefined
54
+ item => item . isRefined
55
55
) . length ;
56
56
// Format the button text
57
57
text =
@@ -63,7 +63,7 @@ export function createDropdown(
63
63
classNames . push ( buttonClassName ) ;
64
64
} else if ( typeof buttonClassName === 'function' ) {
65
65
classNames . push ( buttonClassName ( options ) ) ;
66
- } else if ( ( options . items || [ ] ) . find ( ( item ) => item . isRefined ) ) {
66
+ } else if ( ( options . items || [ ] ) . find ( item => item . isRefined ) ) {
67
67
classNames . push ( cssClasses . buttonRefined ) ;
68
68
}
69
69
@@ -77,73 +77,80 @@ export function createDropdown(
77
77
} ,
78
78
} ) ( baseWidget ) ;
79
79
80
- return ( widgetParams ) => {
80
+ return widgetParams => {
81
81
const widget = makeWidget ( widgetParams ) ;
82
- let cleanUp ;
83
82
let state = { } ;
83
+ let rootElem , headerElem , closeButtonElem ;
84
+
85
+ const open = ( ) => {
86
+ addClassName ( rootElem , CLASS_OPENED ) ;
87
+ // This 'click' event is still being propagated,
88
+ // so we add this event listener in the next tick.
89
+ // Otherwise, it will immediately close the panel again.
90
+ setTimeout ( ( ) => {
91
+ state . windowClickListener = event => {
92
+ // Close if the outside is clicked
93
+ if ( ! rootElem . contains ( event . target ) ) {
94
+ close ( ) ;
95
+ }
96
+ } ;
97
+ // Add an event listener when the panel is opened
98
+ window . addEventListener ( 'click' , state . windowClickListener ) ;
99
+ } , 0 ) ;
100
+ } ;
101
+ const close = ( ) => {
102
+ removeClassName ( rootElem , CLASS_OPENED ) ;
103
+ // Remove the event listener when the panel is closed
104
+ window . removeEventListener ( 'click' , state . windowClickListener ) ;
105
+ delete state . windowClickListener ;
106
+ } ;
107
+ const isOpened = ( ) => hasClassName ( rootElem , CLASS_OPENED ) ;
108
+ const toggle = ( ) => {
109
+ if ( isOpened ( ) ) {
110
+ close ( ) ;
111
+ } else {
112
+ open ( ) ;
113
+ }
114
+ } ;
115
+
116
+ // Add a click listener to the header (button)
117
+ const buttonListener = event => {
118
+ if ( ! event . target . matches ( '.' + CLASS_BUTTON ) ) {
119
+ return ;
120
+ }
121
+ toggle ( ) ;
122
+ } ;
123
+
124
+ // Setup a clean-up function, which will be called in `dispose`.
125
+ const cleanUp = ( ) => {
126
+ headerElem . removeEventListener ( 'click' , buttonListener ) ;
127
+ if ( state . windowClickListener ) {
128
+ window . removeEventListener ( 'click' , state . windowClickListener ) ;
129
+ }
130
+ } ;
84
131
85
132
// Return a modified version of the widget
86
133
return {
87
134
...widget ,
88
135
$$widgetType : 'cmty.facetDropdown' ,
89
- init : ( options ) => {
90
- const rootElem = document
91
- . querySelector ( widgetParams . container )
92
- . querySelector ( '.ais-Panel' ) ;
93
- const headerElem = rootElem . querySelector ( '.ais-Panel-header' ) ;
94
- const closeButtonElem = rootElem . querySelector (
95
- '.' + CLASS_CLOSE_BUTTON
96
- ) ;
97
-
98
- const open = ( ) => {
99
- addClassName ( rootElem , CLASS_OPENED ) ;
100
- // This 'click' event is still being propagated,
101
- // so we add this event listener in the next tick.
102
- // Otherwise, it will immediately close the panel again.
103
- setTimeout ( ( ) => {
104
- state . windowClickListener = ( event ) => {
105
- // Close if the outside is clicked
106
- if ( ! rootElem . contains ( event . target ) ) {
107
- close ( ) ;
108
- }
109
- } ;
110
- // Add an event listener when the panel is opened
111
- window . addEventListener ( 'click' , state . windowClickListener ) ;
112
- } , 0 ) ;
113
- } ;
114
- const close = ( ) => {
115
- removeClassName ( rootElem , CLASS_OPENED ) ;
116
- // Remove the event listener when the panel is closed
117
- window . removeEventListener ( 'click' , state . windowClickListener ) ;
118
- delete state . windowClickListener ;
119
- } ;
120
- const isOpened = ( ) => hasClassName ( rootElem , CLASS_OPENED ) ;
121
- const toggle = ( ) => {
122
- if ( isOpened ( ) ) {
123
- close ( ) ;
124
- } else {
125
- open ( ) ;
126
- }
127
- } ;
136
+ render : options => {
137
+ if ( ! rootElem ) {
138
+ rootElem = document
139
+ . querySelector ( widgetParams . container )
140
+ . querySelector ( '.ais-Panel' ) ;
141
+ }
128
142
129
- // Add a click listener to the header (button)
130
- const buttonListener = ( event ) => {
131
- if ( ! event . target . matches ( '.' + CLASS_BUTTON ) ) {
132
- return ;
133
- }
134
- toggle ( ) ;
135
- } ;
136
- headerElem . addEventListener ( 'click' , buttonListener ) ;
143
+ if ( ! headerElem ) {
144
+ headerElem = rootElem . querySelector ( '.ais-Panel-header' ) ;
137
145
138
- closeButtonElem . addEventListener ( 'click' , close ) ;
146
+ headerElem . addEventListener ( 'click' , buttonListener ) ;
147
+ }
139
148
140
- // Setup a clean-up function, which will be called in `dispose`.
141
- cleanUp = ( ) => {
142
- headerElem . removeEventListener ( 'click' , buttonListener ) ;
143
- if ( state . windowClickListener ) {
144
- window . removeEventListener ( 'click' , state . windowClickListener ) ;
145
- }
146
- } ;
149
+ if ( ! closeButtonElem ) {
150
+ closeButtonElem = rootElem . querySelector ( '.' + CLASS_CLOSE_BUTTON ) ;
151
+
152
+ closeButtonElem . addEventListener ( 'click' , close ) ;
153
+ }
147
154
148
155
// Whenever uiState changes, it closes the panel.
149
156
options . instantSearchInstance . use ( ( ) => ( {
@@ -160,12 +167,14 @@ export function createDropdown(
160
167
}
161
168
} ,
162
169
} ) ) ;
163
- return widget . init . call ( widget , options ) ;
170
+
171
+ return widget . render . call ( widget , options ) ;
164
172
} ,
165
- dispose : ( options ) => {
173
+ dispose : options => {
166
174
if ( typeof cleanUp === 'function' ) {
167
175
cleanUp ( ) ;
168
176
}
177
+
169
178
return widget . dispose . call ( widget , options ) ;
170
179
} ,
171
180
} ;
0 commit comments