diff --git a/.changeset/hungry-spiders-cross.md b/.changeset/hungry-spiders-cross.md new file mode 100644 index 000000000000..aa93e30bc084 --- /dev/null +++ b/.changeset/hungry-spiders-cross.md @@ -0,0 +1,10 @@ +--- +"@gradio/chatbot": minor +"@gradio/file": minor +"@gradio/highlightedtext": minor +"@gradio/image": minor +"@gradio/label": minor +"gradio": minor +--- + +feat:Fix selectable prop in the backend diff --git a/gradio/blocks.py b/gradio/blocks.py index 42619997c310..e84e74326f97 100644 --- a/gradio/blocks.py +++ b/gradio/blocks.py @@ -206,7 +206,7 @@ def get_config(self): for e in self.events: to_add = e.config_data() if to_add: - config = {**config, **to_add} + config = {**to_add, **config} config.pop("_skip_init_processing", None) config.pop("render", None) return {**config, "root_url": self.root_url, "name": self.get_block_name()} diff --git a/gradio/components/annotated_image.py b/gradio/components/annotated_image.py index ecf052321358..dc7ed57c6f5a 100644 --- a/gradio/components/annotated_image.py +++ b/gradio/components/annotated_image.py @@ -65,6 +65,7 @@ def __init__( elem_classes: list[str] | str | None = None, render: bool = True, root_url: str | None = None, + _selectable: bool = False, _skip_init_processing: bool = False, ): """ @@ -90,6 +91,7 @@ def __init__( self.height = height self.width = width self.color_map = color_map + self._selectable = _selectable super().__init__( label=label, every=every, diff --git a/gradio/components/base.py b/gradio/components/base.py index 305f13b30f49..f422cdc86c54 100644 --- a/gradio/components/base.py +++ b/gradio/components/base.py @@ -165,7 +165,7 @@ def __init__( elem_classes = [] # This gets overriden when `select` is called - self.selectable = False + self._selectable = False if not hasattr(self, "data_model"): self.data_model: type[GradioDataModel] | None = None self.temp_files: set[str] = set() diff --git a/gradio/components/chatbot.py b/gradio/components/chatbot.py index 066ca80be637..61ce646f4813 100644 --- a/gradio/components/chatbot.py +++ b/gradio/components/chatbot.py @@ -24,11 +24,6 @@ class FileMessage(GradioModel): alt_text: Optional[str] = None -# _Message = Annotated[List[Union[str, FileMessage, None]], Field(min_length=2, max_length=2)] - -# Message = TypeAdapter(_Message) - - class ChatbotData(GradioRootModel): root: List[Tuple[Union[str, FileMessage, None], Union[str, FileMessage, None]]] @@ -76,6 +71,7 @@ def __init__( bubble_full_width: bool = True, line_breaks: bool = True, layout: Literal["panel", "bubble"] | None = None, + _selectable: bool = False, ): """ Parameters: @@ -121,6 +117,7 @@ def __init__( self.bubble_full_width = bubble_full_width self.line_breaks = line_breaks self.layout = layout + self._selectable = _selectable super().__init__( label=label, diff --git a/gradio/components/checkbox.py b/gradio/components/checkbox.py index 823610e6db8c..f73ca021c376 100644 --- a/gradio/components/checkbox.py +++ b/gradio/components/checkbox.py @@ -43,6 +43,7 @@ def __init__( render: bool = True, root_url: str | None = None, _skip_init_processing: bool = False, + _selectable: bool = False, ): """ Parameters: @@ -61,6 +62,7 @@ def __init__( render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. root_url: The remote URL that of the Gradio app that this component belongs to. Used in `gr.load()`. Should not be set manually. """ + self._selectable = _selectable super().__init__( label=label, info=info, diff --git a/gradio/components/checkboxgroup.py b/gradio/components/checkboxgroup.py index 6c1a71befc6f..de8328883306 100644 --- a/gradio/components/checkboxgroup.py +++ b/gradio/components/checkboxgroup.py @@ -44,6 +44,7 @@ def __init__( render: bool = True, root_url: str | None = None, _skip_init_processing: bool = False, + _selectable: bool = False, ): """ Parameters: @@ -64,6 +65,7 @@ def __init__( render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. root_url: The remote URL that of the Gradio app that this component belongs to. Used in `gr.load()`. Should not be set manually. """ + self._selectable = _selectable self.choices = ( # Although we expect choices to be a list of tuples, it can be a list of tuples if the Gradio app # is loaded with gr.load() since Python tuples are converted to lists in JSON. diff --git a/gradio/components/dataframe.py b/gradio/components/dataframe.py index 7ff5038212f4..a427b13a4315 100644 --- a/gradio/components/dataframe.py +++ b/gradio/components/dataframe.py @@ -75,6 +75,7 @@ def __init__( wrap: bool = False, line_breaks: bool = True, column_widths: list[str | int] | None = None, + _selectable: bool = False, ): """ Parameters: @@ -102,7 +103,7 @@ def __init__( line_breaks: If True (default), will enable Github-flavored Markdown line breaks in chatbot messages. If False, single new lines will be ignored. Only applies for columns of type "markdown." column_widths: An optional list representing the width of each column. The elements of the list should be in the format "100px" (ints are also accepted and converted to pixel values) or "10%". If not provided, the column widths will be automatically determined based on the content of the cells. Setting this parameter will cause the browser to try to fit the table within the page width. """ - + self._selectable = _selectable self.wrap = wrap self.row_count = self.__process_counts(row_count) self.col_count = self.__process_counts( diff --git a/gradio/components/dataset.py b/gradio/components/dataset.py index d6d3f81b6914..284fee369e7c 100644 --- a/gradio/components/dataset.py +++ b/gradio/components/dataset.py @@ -44,6 +44,7 @@ def __init__( container: bool = True, scale: int | None = None, min_width: int = 160, + _selectable: bool = False, ): """ Parameters: @@ -69,6 +70,7 @@ def __init__( _skip_init_processing=_skip_init_processing, render=render, ) + self._selectable = _selectable self.container = container self.scale = scale self.min_width = min_width diff --git a/gradio/components/dropdown.py b/gradio/components/dropdown.py index 2ff7fdcab9d3..5caec3897348 100644 --- a/gradio/components/dropdown.py +++ b/gradio/components/dropdown.py @@ -48,6 +48,7 @@ def __init__( elem_classes: list[str] | str | None = None, render: bool = True, root_url: str | None = None, + _selectable: bool = False, _skip_init_processing: bool = False, ): """ @@ -73,6 +74,7 @@ def __init__( render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. root_url: The remote URL that of the Gradio app that this component belongs to. Used in `gr.load()`. Should not be set manually. """ + self._selectable = _selectable self.choices = ( # Although we expect choices to be a list of tuples, it can be a list of tuples if the Gradio app # is loaded with gr.load() since Python tuples are converted to lists in JSON. diff --git a/gradio/components/file.py b/gradio/components/file.py index d67407f0bdee..c4f3a373419e 100644 --- a/gradio/components/file.py +++ b/gradio/components/file.py @@ -53,6 +53,7 @@ def __init__( elem_classes: list[str] | str | None = None, render: bool = True, root_url: str | None = None, + _selectable: bool = False, _skip_init_processing: bool = False, ): """ @@ -75,6 +76,7 @@ def __init__( render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. root_url: The remote URL that of the Gradio app that this component belongs to. Used in `gr.load()`. Should not be set manually. """ + self._selectable = _selectable self.file_count = file_count if self.file_count == "multiple": self.data_model = ListFiles diff --git a/gradio/components/gallery.py b/gradio/components/gallery.py index 0e3339fe60a1..6213f80ebd86 100644 --- a/gradio/components/gallery.py +++ b/gradio/components/gallery.py @@ -68,6 +68,7 @@ def __init__( | None = None, show_share_button: bool | None = None, show_download_button: bool | None = True, + _selectable: bool = False, ): """ Parameters: @@ -92,8 +93,8 @@ def __init__( object_fit: CSS object-fit property for the thumbnail images in the gallery. Can be "contain", "cover", "fill", "none", or "scale-down". show_share_button: If True, will show a share icon in the corner of the component that allows user to share outputs to Hugging Face Spaces Discussions. If False, icon does not appear. If set to None (default behavior), then the icon appears if this Gradio app is launched on Spaces, but not otherwise. show_download_button: If True, will show a download button in the corner of the selected image. If False, the icon does not appear. Default is True. - """ + self._selectable = _selectable self.columns = columns self.rows = rows self.height = height diff --git a/gradio/components/highlighted_text.py b/gradio/components/highlighted_text.py index 00cf79646e3b..c339ee27193f 100644 --- a/gradio/components/highlighted_text.py +++ b/gradio/components/highlighted_text.py @@ -58,6 +58,7 @@ def __init__( root_url: str | None = None, _skip_init_processing: bool = False, interactive: bool | None = None, + _selectable: bool = False, ): """ Parameters: @@ -78,8 +79,8 @@ def __init__( render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. root_url: The remote URL that of the Gradio app that this component belongs to. Used in `gr.load()`. Should not be set manually. interactive: If True, the component will be editable, and allow user to select spans of text and label them. - """ + self._selectable = _selectable self.color_map = color_map self.show_legend = show_legend self.combine_adjacent = combine_adjacent diff --git a/gradio/components/image.py b/gradio/components/image.py index 86e7032d6239..8111424cf0b5 100644 --- a/gradio/components/image.py +++ b/gradio/components/image.py @@ -73,6 +73,7 @@ def __init__( _skip_init_processing: bool = False, mirror_webcam: bool = True, show_share_button: bool | None = None, + _selectable: bool = False, ): """ Parameters: @@ -99,7 +100,7 @@ def __init__( mirror_webcam: If True webcam will be mirrored. Default is True. show_share_button: If True, will show a share icon in the corner of the component that allows user to share outputs to Hugging Face Spaces Discussions. If False, icon does not appear. If set to None (default behavior), then the icon appears if this Gradio app is launched on Spaces, but not otherwise. """ - + self._selectable = _selectable self.mirror_webcam = mirror_webcam valid_types = ["numpy", "pil", "filepath"] if type not in valid_types: diff --git a/gradio/components/label.py b/gradio/components/label.py index d4068091d98f..ec71f6aeb7ac 100644 --- a/gradio/components/label.py +++ b/gradio/components/label.py @@ -59,6 +59,7 @@ def __init__( root_url: str | None = None, _skip_init_processing: bool = False, color: str | None = None, + _selectable: bool = False, ): """ Parameters: @@ -77,6 +78,7 @@ def __init__( root_url: The remote URL that of the Gradio app that this component belongs to. Used in `gr.load()`. Should not be set manually. color: The background color of the label (either a valid css color name or hexadecimal string). """ + self._selectable = _selectable self.num_top_classes = num_top_classes self.color = color super().__init__( diff --git a/gradio/components/radio.py b/gradio/components/radio.py index cd7b4e75c7f9..b7668b62b25a 100644 --- a/gradio/components/radio.py +++ b/gradio/components/radio.py @@ -44,6 +44,7 @@ def __init__( elem_classes: list[str] | str | None = None, render: bool = True, root_url: str | None = None, + _selectable: bool = False, _skip_init_processing: bool = False, ): """ @@ -78,6 +79,7 @@ def __init__( f"Invalid value for parameter `type`: {type}. Please choose from one of: {valid_types}" ) self.type = type + self._selectable = _selectable super().__init__( label=label, info=info, diff --git a/gradio/components/textbox.py b/gradio/components/textbox.py index 23ec6ae3460f..274bda06453d 100644 --- a/gradio/components/textbox.py +++ b/gradio/components/textbox.py @@ -62,6 +62,7 @@ def __init__( text_align: Literal["left", "right"] | None = None, rtl: bool = False, show_copy_button: bool = False, + _selectable: bool = False, ): """ Parameters: @@ -89,6 +90,7 @@ def __init__( show_copy_button: If True, includes a copy button to copy the text in the textbox. Only applies if show_label is True. autoscroll: If True, will automatically scroll to the bottom of the textbox when the value changes, unless the user scrolls up. If False, will not scroll to the bottom of the textbox when the value changes. """ + self._selectable = _selectable if type not in ["text", "password", "email"]: raise ValueError('`type` must be one of "text", "password", or "email".') diff --git a/gradio/events.py b/gradio/events.py index ad453ff6645d..e619983b4ad1 100644 --- a/gradio/events.py +++ b/gradio/events.py @@ -28,9 +28,7 @@ def set_cancel_events( cancel_fn, fn_indices_to_cancel = get_cancel_function(cancels) if Context.root_block is None: - raise AttributeError( - "Cannot cancel {self.event_name} outside of a gradio.Blocks context." - ) + raise AttributeError("Cannot cancel outside of a gradio.Blocks context.") Context.root_block.set_event_trigger( triggers, @@ -119,7 +117,7 @@ def __init__(self, target: Block | None, data: Any): """ The value of the selected item. """ - self.selected: bool = data.get("selected", True) + self.selected: bool = data.get("_selected", True) """ True if the item was selected, False if deselected. """ @@ -489,7 +487,6 @@ class Events: ) select = EventListener( "select", - config_data=lambda: {"selectable": False}, callback=lambda block: setattr(block, "selectable", True), doc="Event listener for when the user selects or deselects the {{ component }}. Uses event data gradio.SelectData to carry `value` referring to the label of the {{ component }}, and `selected` to refer to state of the {{ component }}. See EventData documentation on how to use this event data", ) diff --git a/js/chatbot/Index.svelte b/js/chatbot/Index.svelte index 5059f0c1bf75..d0192f23a113 100644 --- a/js/chatbot/Index.svelte +++ b/js/chatbot/Index.svelte @@ -22,7 +22,7 @@ export let show_label = true; export let root: string; export let root_url: null | string; - export let selectable = false; + export let _selectable = false; export let likeable = false; export let show_share_button = false; export let rtl = false; @@ -112,7 +112,7 @@ {/if} gradio.dispatch("select", detail)} - {selectable} + selectable={_selectable} value={_value} {label} {show_label} @@ -90,7 +90,7 @@ value={_value} {file_count} {file_types} - {selectable} + selectable={_selectable} {root} {height} on:change={({ detail }) => { diff --git a/js/highlightedtext/Index.svelte b/js/highlightedtext/Index.svelte index b69eb91b219a..427dddf7975a 100644 --- a/js/highlightedtext/Index.svelte +++ b/js/highlightedtext/Index.svelte @@ -26,7 +26,7 @@ export let container = true; export let scale: number | null = null; export let min_width: number | undefined = undefined; - export let selectable = false; + export let _selectable = false; export let combine_adjacent = false; export let mode: "static" | "interactive"; @@ -77,7 +77,7 @@ {#if value} gradio.dispatch("select", detail)} - {selectable} + selectable={_selectable} {value} {show_legend} {color_map} @@ -118,7 +118,7 @@ gradio.dispatch("change")} - {selectable} + selectable={_selectable} {show_legend} {color_map} /> diff --git a/js/image/Index.svelte b/js/image/Index.svelte index 678ac4af47fd..724b198b6a75 100644 --- a/js/image/Index.svelte +++ b/js/image/Index.svelte @@ -27,7 +27,7 @@ export let height: number | undefined; export let width: number | undefined; - export let selectable = false; + export let _selectable = false; export let container = true; export let scale: number | null = null; export let min_width: number | undefined = undefined; @@ -94,7 +94,7 @@ {label} {show_label} {show_download_button} - {selectable} + selectable={_selectable} {show_share_button} i18n={gradio.i18n} /> @@ -123,7 +123,7 @@ gradio.dispatch("edit")} diff --git a/js/label/Index.svelte b/js/label/Index.svelte index 8ab1c5a5d5b5..f7b3e2b3f437 100644 --- a/js/label/Index.svelte +++ b/js/label/Index.svelte @@ -24,7 +24,7 @@ export let min_width: number | undefined = undefined; export let loading_status: LoadingStatus; export let show_label = true; - export let selectable = false; + export let _selectable = false; $: ({ confidences, label: _label } = value); $: _label, confidences, gradio.dispatch("change"); @@ -51,7 +51,7 @@ {#if _label !== undefined && _label !== null}