@@ -1445,13 +1445,22 @@ def set_frame(self, native_view: Any, x: float, y: float, width: float, height:
14451445 return
14461446
14471447 def _apply (self , placeholder : Any , props : Dict [str , Any ], * , mounting : bool ) -> None :
1448- visible = bool (props .get ("visible" , False ))
14491448 state = _pn_modal_states .get (id (placeholder ))
1450- if visible and state is None :
1451- self ._present (placeholder , props )
1452- elif not visible and state is not None :
1453- self ._dismiss (placeholder )
1454- elif visible and state is not None :
1449+ # ``update`` only delivers the *changed* props. When ``visible`` is
1450+ # not among them the presentation state must be left untouched: a
1451+ # re-render that happens while the modal is open (e.g. an
1452+ # ``on_show`` callback bumping some state) must NOT be read as
1453+ # ``visible=False`` and tear the dialog down. So only react to an
1454+ # explicitly supplied ``visible`` value.
1455+ if "visible" in props :
1456+ visible = bool (props ["visible" ])
1457+ if visible and state is None :
1458+ self ._present (placeholder , props )
1459+ elif not visible and state is not None :
1460+ self ._dismiss (placeholder )
1461+ # Forward live prop updates to an already-presented dialog.
1462+ state = _pn_modal_states .get (id (placeholder ))
1463+ if state is not None :
14551464 if "on_dismiss" in props :
14561465 state ["on_dismiss" ] = props .get ("on_dismiss" )
14571466 dialog = state .get ("dialog" )
0 commit comments