Create a TextInputMultiChoice

Allows users to input custom values and select from them

import panel as pn
import param
from panel.custom import PyComponent
pn.extension()

class TextInputMultiChoice(PyComponent):
    """
    A composite component combining a text input with a MultiChoice widget.
    When users type text and press Enter, it adds to options and value of the MultiChoice.
    """

    value = param.List(default=[], doc="List of currently selected values")

    options = param.List(
        default=[], doc="List of available options for the MultiChoice"
    )

    placeholder = param.String(
        default="Type and press <Enter> to add", doc="Placeholder text for the input"
    )

    _input_value = param.String(
        default="", doc="Current value of the text input"
    )

    def __init__(self, **params):
        super().__init__(**params)

        self._text_input = pn.widgets.TextInput.from_param(
            self.param._input_value, placeholder=self.param.placeholder, name="Input", description=None
        )

        # Create MultiChoice component with reactive parameters
        self._multi_choice = pn.widgets.MultiChoice.from_param(
            self.param.value,
            options=self.param.options,
            description=None,
        )

    @param.depends("_input_value", watch=True)
    def _add_option(self):
        text = self._input_value
        if text and text not in self.options:
            self.options = list(self.options) + [text]
            self.value = list(self.value) + [text]

        # Clear the text input
        self._input_value = ""

    def __panel__(self):
        return pn.Column(self._text_input, self._multi_choice, sizing_mode="stretch_both")


ti = TextInputMultiChoice()