holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.81k stars 520 forks source link

FileSelector remains partly hidden if shown hidden first #7510

Open pierrotsmnrd opened 4 days ago

pierrotsmnrd commented 4 days ago

ALL software version info

Software Version Info ```plaintext panel==1.5.4 MacOS 14.6.1 ```

Description of expected behavior and the observed behavior

Complete, minimal, self-contained example code that reproduces the issue

import panel as pn
pn.extension()

file_selector = pn.widgets.FileSelector('~/', name='Select Files', visible=False)
toggle_button = pn.widgets.Button(name='Show File Selector', button_type='primary')

def toggle_visibility(event):
    file_selector.visible = not file_selector.visible
    toggle_button.name = 'Hide File Selector' if file_selector.visible else 'Show File Selector'

toggle_button.on_click(toggle_visibility)
layout = pn.panel(pn.Column(toggle_button, file_selector))
layout.servable()

Diagnostic

FileSelector is a composite widget. After investigating the HTML structure, it appears that several components inside the _composite property remain with visible=False despite setting the FileSelector's visible property to True

Workaround

Updating the toggle_visibility function to this illustrates the diagnostic and gives the expected behavior

def toggle_visibility(event):
    file_selector.visible = not file_selector.visible
    file_selector._composite[0].visible =  file_selector.visible
    file_selector._composite[-1].visible = file_selector.visible
    toggle_button.name = 'Hide File Selector' if file_selector.visible else 'Show File Selector'

Stack traceback and/or browser JavaScript console output

None

Screenshots or screencasts of the bug in action

https://github.com/user-attachments/assets/8855d4f7-60ce-4f1d-ab11-9ae15b21dede

holovizbot commented 4 days ago

This issue has been mentioned on HoloViz Discourse. There might be relevant details there:

https://discourse.holoviz.org/t/fileselector-widget-doesnt-display-dynamically-if-visible-kwarg-is-initially-set-as-false/8404/4

hoxbro commented 4 days ago

Adding self.link here will also solve the issue.

        self.link(self._selector, size='size', visible='visible')
        self.link(self._nav_bar, visible='visible')

https://github.com/holoviz/panel/blob/1f821d651d8ad2b874fb90cbc2f29277f6817464/panel/widgets/file_selector.py#L137

hoxbro commented 4 days ago

I think the underlying widgets have never been synced. This is only really a problem with the False to True combination.

file_selector = pn.widgets.FileSelector(visible=False)
print(file_selector._composite.visible, [f.visible for f in file_selector._composite])
file_selector = pn.widgets.FileSelector(visible=True)
print(file_selector._composite.visible, [f.visible for f in file_selector._composite])
file_selector = pn.widgets.FileSelector(visible=False)
file_selector.visible = True
print(file_selector._composite.visible, [f.visible for f in file_selector._composite])
file_selector = pn.widgets.FileSelector(visible=True)
file_selector.visible = False
print(file_selector._composite.visible, [f.visible for f in file_selector._composite])
False [False, True, False]  # False, all should be false, but do not matter as everything is hidden)
True [True, True, True]   # True, works as intended
True [False, True, False]  # False -> True, Everything should be hidden - the bad combination
False [True, True, True]  # True -> False, all should be false, but do not matter as everything is hidden