@@ -46,21 +46,24 @@ const propTypes = {
4646 * @param {function } Translation function returning the translated string.
4747 */
4848 t : PropTypes . func ,
49- } ;
5049
51- const defaultProps = {
52- className : "rs-base-layer-switcher" ,
53- altText : "Source not found" ,
54- titles : {
55- button : "Base layers" ,
56- openSwitcher : "Open Baselayer-Switcher" ,
57- closeSwitcher : "Close Baselayer-Switcher" ,
58- } ,
59- closeButtonImage : < FaChevronLeft /> ,
60- layerImages : undefined ,
61- t : ( s ) => {
62- return s ;
63- } ,
50+ /**
51+ * Callback function on close button click.
52+ * @param {function } Callback function triggered when a switcher button is clicked. Takes the event as argument.
53+ */
54+ onCloseButtonClick : PropTypes . func ,
55+
56+ /**
57+ * Callback function on layer button click.
58+ * @param {function } Callback function triggered when a switcher button is clicked. Takes the event and the layer as arguments.
59+ */
60+ onLayerButtonClick : PropTypes . func ,
61+
62+ /**
63+ * Callback function on main switcher button click.
64+ * @param {function } Callback function triggered when a switcher button is clicked. Takes the event as argument.
65+ */
66+ onSwitcherButtonClick : PropTypes . func ,
6467} ;
6568
6669const getVisibleLayer = ( layers ) => {
@@ -90,6 +93,31 @@ const getImageStyle = (url) => {
9093 : null ;
9194} ;
9295
96+ function CloseButton ( { onClick, tabIndex, title, children } ) {
97+ return (
98+ < div
99+ className = "rs-base-layer-switcher-close-btn"
100+ role = "button"
101+ onClick = { onClick }
102+ onKeyPress = { ( e ) => {
103+ return e . which === 13 && onClick ( ) ;
104+ } }
105+ tabIndex = { tabIndex }
106+ aria-label = { title }
107+ title = { title }
108+ >
109+ { children }
110+ </ div >
111+ ) ;
112+ }
113+
114+ CloseButton . propTypes = {
115+ onClick : PropTypes . func . isRequired ,
116+ tabIndex : PropTypes . string . isRequired ,
117+ title : PropTypes . string . isRequired ,
118+ children : PropTypes . node . isRequired ,
119+ } ;
120+
93121/**
94122 * The BaseLayerSwitcher component renders a button interface for switching the visible
95123 * [mobility-toolbox-js layer](https://mobility-toolbox-js.geops.io/api/identifiers%20html#ol-layers)
@@ -98,33 +126,26 @@ const getImageStyle = (url) => {
98126
99127function BaseLayerSwitcher ( {
100128 layers,
101- layerImages,
102- className,
103- altText,
104- titles,
105- closeButtonImage,
106- t,
129+ layerImages = undefined ,
130+ className = "rs-base-layer-switcher" ,
131+ altText = "Source not found" ,
132+ titles = {
133+ button : "Base layers" ,
134+ openSwitcher : "Open Baselayer-Switcher" ,
135+ closeSwitcher : "Close Baselayer-Switcher" ,
136+ } ,
137+ closeButtonImage = < FaChevronLeft /> ,
138+ onCloseButtonClick = null ,
139+ onLayerButtonClick = null ,
140+ onSwitcherButtonClick = null ,
141+ t = ( s ) => s ,
107142} ) {
108143 const [ switcherOpen , setSwitcherOpen ] = useState ( false ) ;
109144 const [ isClosed , setIsClosed ] = useState ( true ) ;
110145 const [ currentLayer , setCurrentLayer ] = useState (
111146 getVisibleLayer ( layers ) || layers [ 0 ] ,
112147 ) ;
113148
114- useEffect ( ( ) => {
115- // Update the layer selected when a visibility changes.
116- const olKeys = ( layers || [ ] ) . map ( ( layer ) => {
117- return layer . on ( "change:visible" , ( evt ) => {
118- if ( evt . target . visible && currentLayer !== evt . target ) {
119- setCurrentLayer ( evt . target ) ;
120- }
121- } ) ;
122- } ) ;
123- return ( ) => {
124- unByKey ( olKeys ) ;
125- } ;
126- } , [ currentLayer , layers ] ) ;
127-
128149 /* Images are loaded from props if provided, fallback from layer */
129150 const images = layerImages
130151 ? Object . keys ( layerImages ) . map ( ( layerImage ) => {
@@ -137,12 +158,17 @@ function BaseLayerSwitcher({
137158 const openClass = switcherOpen ? " rs-open" : "" ;
138159 const hiddenStyle = switcherOpen && ! isClosed ? "visible" : "hidden" ;
139160
140- const handleSwitcherClick = ( ) => {
161+ const handleSwitcherClick = ( evt ) => {
162+ const nextLayer = layers . find ( ( layer ) => {
163+ return ! layer . visible ;
164+ } ) ;
165+ const onButtonClick =
166+ layers . length === 2 ? onLayerButtonClick : onSwitcherButtonClick ;
167+ if ( onButtonClick ) {
168+ onButtonClick ( evt , nextLayer ) ;
169+ }
141170 if ( layers . length === 2 ) {
142171 /* On only two layer options the opener becomes a layer toggle button */
143- const nextLayer = layers . find ( ( layer ) => {
144- return ! layer . visible ;
145- } ) ;
146172 if ( currentLayer . setVisible ) {
147173 currentLayer . setVisible ( false ) ;
148174 } else {
@@ -160,7 +186,10 @@ function BaseLayerSwitcher({
160186 return setSwitcherOpen ( true ) && setIsClosed ( false ) ;
161187 } ;
162188
163- const onLayerSelect = ( layer ) => {
189+ const onLayerSelect = ( layer , evt ) => {
190+ if ( onLayerButtonClick ) {
191+ onLayerButtonClick ( evt , layer ) ;
192+ }
164193 if ( ! switcherOpen ) {
165194 setSwitcherOpen ( true ) ;
166195 return ;
@@ -214,30 +243,24 @@ function BaseLayerSwitcher({
214243 } ;
215244 } , [ switcherOpen ] ) ;
216245
246+ useEffect ( ( ) => {
247+ // Update the layer selected when a visibility changes.
248+ const olKeys = ( layers || [ ] ) . map ( ( layer ) => {
249+ return layer . on ( "change:visible" , ( evt ) => {
250+ if ( evt . target . visible && currentLayer !== evt . target ) {
251+ setCurrentLayer ( evt . target ) ;
252+ }
253+ } ) ;
254+ } ) ;
255+ return ( ) => {
256+ unByKey ( olKeys ) ;
257+ } ;
258+ } , [ currentLayer , layers ] ) ;
259+
217260 if ( ! layers || layers . length < 2 || ! currentLayer ) {
218261 return null ;
219262 }
220263
221- const toggleBtn = (
222- < div className = "rs-base-layer-switcher-btn-wrapper" >
223- < div
224- className = "rs-base-layer-switcher-close-btn"
225- role = "button"
226- onClick = { ( ) => {
227- return setSwitcherOpen ( false ) ;
228- } }
229- onKeyPress = { ( e ) => {
230- return e . which === 13 && setSwitcherOpen ( false ) ;
231- } }
232- tabIndex = { switcherOpen ? "0" : "-1" }
233- aria-label = { titles . closeSwitcher }
234- title = { titles . closeSwitcher }
235- >
236- { closeButtonImage }
237- </ div >
238- </ div >
239- ) ;
240-
241264 return (
242265 < div className = { `${ className } ${ openClass } ` } >
243266 < div
@@ -290,12 +313,12 @@ function BaseLayerSwitcher({
290313 role = "button"
291314 title = { t ( layerName ) }
292315 aria-label = { t ( layerName ) }
293- onClick = { ( ) => {
294- return onLayerSelect ( layer ) ;
316+ onClick = { ( evt ) => {
317+ return onLayerSelect ( layer , evt ) ;
295318 } }
296- onKeyPress = { ( e ) => {
297- if ( e . which === 13 ) {
298- onLayerSelect ( layer ) ;
319+ onKeyPress = { ( evt ) => {
320+ if ( evt . which === 13 ) {
321+ onLayerSelect ( layer , evt ) ;
299322 }
300323 } }
301324 style = { imageStyle }
@@ -311,12 +334,22 @@ function BaseLayerSwitcher({
311334 </ div >
312335 ) ;
313336 } ) }
314- { toggleBtn }
337+ < CloseButton
338+ onClick = { ( evt ) => {
339+ if ( onCloseButtonClick ) {
340+ onCloseButtonClick ( evt ) ;
341+ }
342+ setSwitcherOpen ( false ) ;
343+ } }
344+ tabIndex = { switcherOpen ? "0" : "-1" }
345+ title = { titles . closeSwitcher }
346+ >
347+ { closeButtonImage }
348+ </ CloseButton >
315349 </ div >
316350 ) ;
317351}
318352
319353BaseLayerSwitcher . propTypes = propTypes ;
320- BaseLayerSwitcher . defaultProps = defaultProps ;
321354
322355export default BaseLayerSwitcher ;
0 commit comments