Open kleynjan opened 8 months ago
Hi @kleynjan,
This is indeed an annoying bug we also noticed in one of our projects. I took the opportunity to further investigate different methods to show and hide a Leaflet map:
ui.label('Map 1: set_visibility')
ui.button('Show', on_click=lambda: m1.set_visibility(True))
ui.button('Hide', on_click=lambda: m1.set_visibility(False))
with ui.card() as m1:
ui.leaflet(center=(51.505, -0.09)).classes('w-96 h-64')
m1.set_visibility(False)
ui.label('Map 2: classes "visible" and "hidden"')
ui.button('Show', on_click=lambda: m2.classes('visible', remove='hidden'))
ui.button('Hide', on_click=lambda: m2.classes('hidden', remove='visible'))
with ui.card() as m2:
ui.leaflet(center=(51.505, -0.09)).classes('w-96 h-64')
m2.classes('hidden')
ui.label('Map 3: CSS display "block" and "none"')
ui.button('Show', on_click=lambda: m3.style('display: block'))
ui.button('Hide', on_click=lambda: m3.style('display: none'))
with ui.card() as m3:
ui.leaflet(center=(51.505, -0.09)).classes('w-96 h-64')
m3.style('display: none')
ui.label('Map 4: classes "visible" and "invisible"')
ui.button('Show', on_click=lambda: m4.classes('visible', remove='invisible'))
ui.button('Hide', on_click=lambda: m4.classes('invisible', remove='visible'))
with ui.card() as m4:
ui.leaflet(center=(51.505, -0.09)).classes('w-96 h-64')
m4.classes('invisible')
ui.label('Map 5: CSS visibility "visible" and "hidden"')
ui.button('Show', on_click=lambda: m5.style('visibility: visible'))
ui.button('Hide', on_click=lambda: m5.style('visibility: hidden'))
with ui.card() as m5:
ui.leaflet(center=(51.505, -0.09)).classes('w-96 h-64')
m5.style('visibility: hidden')
The first three methods are basically the same: set_visibility
sets classes visible
and hidden
which change the visibility
CSS property. The Leaflet map is broken like in your screenshot.
The last two methods change the display
CSS property. The Leaflet map looks ok, but occupies space while hidden. This might be a useful workaround, unless you really need the map to be gone without taking up space.
In this StackOverflow post I found a workaround using the CSS height
property:
ui.button('Show', on_click=lambda: m.style(remove='height: 0px;'))
ui.button('Hide', on_click=lambda: m.style('height: 0px;'))
with ui.element() as m:
ui.leaflet(center=(51.505, -0.09)).classes('w-96 h-64')
m.style('height: 0px; overflow: hidden')
Oh and here is another workaround using the map method invalidateSize
:
ui.button('Show', on_click=lambda: (e.set_visibility(True), m.run_map_method('invalidateSize')))
ui.button('Hide', on_click=lambda: e.set_visibility(False))
with ui.element() as e:
m = ui.leaflet(center=(51.505, -0.09)).classes('w-96 h-64')
e.set_visibility(False)
It seems like this issue will be fixed in Leaflet 2.0: https://github.com/Leaflet/Leaflet/issues/9010 So I think we need to sit and wait for its release.
Of course, Falko, that's fine. For the time being there are workarounds available.
Thanks for investigating, -Peter
Description
There seems to be a known issue with Leaflet when the container size is not known when initializing, but I don't know how to further isolate it for Nicegui. Likely a CSS issue?
See example below. Both maps are initially hidden. The left map is then made visible using tailwind classes, that works. Visibility for the map on the right hand side is enabled with bind_visibility; the map tiles are not correctly shown.
The flex classes are only for display here, AFAICT the difference between the two methods remains with all styling I've tried. As a workaround I can work with the Tailwind classes, but that is of course a bit more clumsy.