Making a popup modal out of FIleSelector (almost works, broken when used multiple times)

I’m trying to build a custom widget that makes a popup modal out of FileSelector. I have code that works if I use the class once, but if I try and use it twice it breaks. Doesn’t filter correctly and shows me a dual window when I try and drill down one folder.

pn.Column(csv_file).servable() - Works correctly, single window, shows csv files

pn.Column(csv_file, txt_file).servable() - double window after drilling down does not show csv files

I assume it is something to do with global state of the widget.

Reproducer below for panel 1.6.

import panel as pn
from panel.viewable import Viewer


class FileSelectorModal(Viewer):
    def __init__(self, FileSelectorParams={}, **params):

        super().__init__(**params)

        # Create the FileSelector widget
        self.file_selector = pn.widgets.FileSelector(
            name="Select a File",
            **FileSelectorParams,
        )

        # Create buttons
        self.open_modal_button = pn.widgets.Button(
            name="Select File", button_type="primary"
        )
        self.close_modal_button = pn.widgets.Button(name="Close", button_type="primary")

        # Create a TextInput widget to display the selected file
        self.selected_file = pn.widgets.TextInput(disabled=True)

        # Create the modal content
        self.modal_content = pn.Column(
            self.file_selector,
            self.close_modal_button,
        )

        # Create the modal
        self.modal = pn.Modal(self.modal_content)

        # Attach the button callbacks
        self.open_modal_button.on_click(self.open_modal)
        self.close_modal_button.on_click(self.close_modal)

        # Create the layout
        self.layout = pn.Row(
            f"**{self.name}:**",
            f"{FileSelectorParams}",
            self.selected_file,
            self.open_modal_button,
            self.modal,
        )

    def open_modal(self, event):
        self.modal.open = True

    def close_modal(self, event):
        if self.file_selector.value:
            self.selected_file.value = self.file_selector.value[0]
        self.modal.open = False

    def __panel__(self):
        return self.layout


csv_file = FileSelectorModal(
    name="Enter CSV File",
    FileSelectorParams={"directory": "~/", "file_pattern": "*.csv"},
)

txt_file = FileSelectorModal(
    name="Enter TXT File",
    FileSelectorParams={"directory": "~/", "file_pattern": "*.txt"},
)

pn.Column(csv_file).servable()
# pn.Column(csv_file, txt_file).servable()

For this to work, the modal must be instantiated on demand and discarded on close. This seems to work for me (panel 1.6.0) :

import panel as pn
from panel.viewable import Viewer


class FileSelectorModal(Viewer):
    def __init__(self, FileSelectorParams={}, **params):

        super().__init__(**params)

        # Create the FileSelector widget
        self.file_selector = pn.widgets.FileSelector(
            name="Select a File",
            **FileSelectorParams,
        )

        # Create buttons
        self.open_modal_button = pn.widgets.Button(
            name="Select File", button_type="primary"
        )
        self.close_modal_button = pn.widgets.Button(name="Close", button_type="primary")

        # Create a TextInput widget to display the selected file
        self.selected_file = pn.widgets.TextInput(disabled=True)

        # Create the modal content
        self.modal_content = pn.Column(
            self.file_selector,
            self.close_modal_button,
        )

        # Attach the button callbacks
        self.open_modal_button.on_click(self.open_modal)
        self.close_modal_button.on_click(self.close_modal)

        # Create the layout
        self.layout = pn.Row(
            f"**{self.name}:**",
            f"{FileSelectorParams}",
            self.selected_file,
            self.open_modal_button,
            
        )

    def open_modal(self, event):
        self.modal = pn.Modal(self.modal_content)

        # Add a param watcher to detect when the modal is closed
        self.modal.param.watch(self.modal_open_did_change, "open")
        self.layout.append(self.modal)
        self.modal.open = True

    def close_modal(self, event):
        self.modal.open = False
        
    def modal_open_did_change(self, event):
        if self.modal.open == False:
            if self.file_selector.value:
                self.selected_file.value = self.file_selector.value[0]
            self.layout.remove(self.modal)
            self.modal = None


    def __panel__(self):
        return self.layout


csv_file = FileSelectorModal(
    name="Enter CSV File",
    FileSelectorParams={"directory": "~/", "file_pattern": "*.csv"},
)

txt_file = FileSelectorModal(
    name="Enter TXT File",
    FileSelectorParams={"directory": "~/", "file_pattern": "*.txt"},
)

#pn.Column(csv_file).servable()
pn.Column(csv_file, txt_file).servable()

This works after adding pn.extension("modal") at the top. Otherwise I get a warning and the modal does not appear. In the original code, for some reason I didn’t need it.