File size: 4,068 Bytes
5f5d58c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
""" Predefined buttons with bound events that can be included in a gr.Blocks for convenience. """

from __future__ import annotations

import copy
import json
from typing import Any, Literal

from gradio_client.documentation import document, set_documentation_group

from gradio.components import Button, Component
from gradio.data_classes import GradioModel, GradioRootModel
from gradio.utils import resolve_singleton

set_documentation_group("component")


@document("add")
class ClearButton(Button):
    """
    Button that clears the value of a component or a list of components when clicked. It is instantiated with the list of components to clear.
    Preprocessing: passes the button value as a {str} into the function
    Postprocessing: expects a {str} to be returned from a function, which is set as the label of the button
    """

    is_template = True

    def __init__(
        self,
        components: None | list[Component] | Component = None,
        *,
        value: str = "Clear",
        every: float | None = None,
        variant: Literal["primary", "secondary", "stop"] = "secondary",
        size: Literal["sm", "lg"] | None = None,
        icon: str | None = None,
        link: str | None = None,
        visible: bool = True,
        interactive: bool = True,
        elem_id: str | None = None,
        elem_classes: list[str] | str | None = None,
        render: bool = True,
        scale: int | None = None,
        min_width: int | None = None,
        api_name: str | None | Literal["False"] = None,
        show_api: bool = False,
    ):
        super().__init__(
            value,
            every=every,
            variant=variant,
            size=size,
            icon=icon,
            link=link,
            visible=visible,
            interactive=interactive,
            elem_id=elem_id,
            elem_classes=elem_classes,
            render=render,
            scale=scale,
            min_width=min_width,
        )
        self.api_name = api_name
        self.show_api = show_api
        self.add(components)

    def add(self, components: None | Component | list[Component]) -> ClearButton:
        """
        Adds a component or list of components to the list of components that will be cleared when the button is clicked.
        """
        from gradio.components import State  # Avoid circular import

        if not components:
            # This needs to be here because when the ClearButton is created in an gr.Interface, we don't
            # want to create dependencies for it before we have created the dependencies for the submit function.
            # We generally assume that the submit function dependency is the first thing created in an gr.Interface.
            return self

        if isinstance(components, Component):
            components = [components]
        none_values = []
        state_components = []
        initial_states = []
        for component in components:
            if isinstance(component, State):
                state_components.append(component)
                initial_states.append(copy.deepcopy(component.value))
            none = component.postprocess(None)
            if isinstance(none, (GradioModel, GradioRootModel)):
                none = none.model_dump()
            none_values.append(none)
        clear_values = json.dumps(none_values)
        self.click(
            None,
            [],
            components,
            js=f"() => {clear_values}",
            api_name=self.api_name,
            show_api=self.show_api,
        )
        if state_components:
            self.click(
                lambda: resolve_singleton(initial_states),
                None,
                state_components,
                api_name=self.api_name,
                show_api=self.show_api,
            )
        return self

    def postprocess(self, value: str | None) -> str | None:
        return value

    def preprocess(self, payload: str | None) -> str | None:
        return payload

    def example_inputs(self) -> Any:
        return None