# Prompt

> Asks for a line of text. A native Pyzed component for Python desktop GUIs, with a live preview, code examples and its API.

Source: https://albakore.github.io/pyzed/library/prompt/

:::tip[In plain words]
A small box that asks you to type something, like a new name for a file.
:::

Asks for a line of text: a controlled input plus Cancel and OK. Enter or the button calls `on_submit`.

`ui.prompt` · Category: [Dialogs](https://albakore.github.io/pyzed/library/#dialogs) · [Full reference →](https://albakore.github.io/pyzed/reference/ui/#prompt)

**Code:**

```python
ui.dialog_layer(main_view(), ui.prompt(
    "Rename", "notes.py", on_input, on_submit, on_cancel,
    message="New name for the file:", width=360,
))
```

:::note[New]
This component was added recently. Tell us how it works for you in the [issue tracker](https://github.com/albakore/pyzed/issues).
:::

## When to use

- For quick names: rename a file, name a new branch, save a view.

## Usage

```python
import pyzed as pz
from pyzed import ui

class Files(pz.App):
    def __init__(self):
        self.new_name = None

    def view(self):
        dialog = None
        if self.new_name is not None:
            dialog = ui.prompt("Rename", self.new_name, lambda t: setattr(self, "new_name", t),
                               self.rename, lambda: setattr(self, "new_name", None))
        return ui.dialog_layer(self.main_view(), dialog)
```

## Variants

:::note[About these captures]
Each capture is recorded by pyzed itself, off-screen at 2x, in One Dark or One Light to match this site's theme, and cropped to the component so it shows at its real size. The pointer hovers, presses or types into it; a component that does not react to the pointer cycles through a few themes. With reduced motion you see the first frame. Open **Code** under a capture to see the snippet that draws it; free names such as `on_save` stand for your own callbacks.
:::

### Content

```python
ui.prompt("New branch", "", on_input, on_submit, on_cancel, placeholder="feature/…", width=340)
```

```python
ui.prompt("Rename", "notes.py", on_input, on_submit, on_cancel, message="New name for the file:",
          width=340)
```

```python
ui.prompt("Save view", "My view", on_input, on_submit, on_cancel, submit_label="Save", width=340)
```

## Events

Prompt has **3 events of its own**, listed below. Like every widget it also has the **18 common events** (`click`, `double_click`, `right_click`, `mouse_enter`, `drag`, `key_down`, `resize`…), attached with `.on(...)`: see [Events](https://albakore.github.io/pyzed/guides/events/) and [Events of every component](https://albakore.github.io/pyzed/library/events/).

| Event | Handler gets | When |
| --- | --- | --- |
| `on_input` | `(text)` | Receives each edit. |
| `on_submit` | `()` | Enter or the submit button. |
| `on_cancel` | `()` | Cancel, the close icon. |

**Handler gets** is what Pyzed passes to your callable: `()` means nothing. Any handler can also be a message (a value that is not callable), which goes to `update()`.

### Handling the events

The same events written three ways. **Imperative**: methods of the app change `self`. **Declarative**: the handlers produce messages and one `update()` decides. **Functional**: a pure function draws an immutable state and asks for changes with `set_state(...)`. See [Imperative, declarative and functional](https://albakore.github.io/pyzed/guides/code-styles/).

**Imperative:**

```python
class Files(pz.App):
    def __init__(self):
        self.name = "notes.py"
        self.new_name = "notes.py"       # None while the dialog is closed

    def rename(self):                    # on_submit: Enter or the button
        self.name, self.new_name = self.new_name, None

    def view(self):
        dialog = None
        if self.new_name is not None:
            dialog = ui.prompt("Rename", self.new_name,
                               lambda text: setattr(self, "new_name", text),     # on_input
                               self.rename,
                               lambda: setattr(self, "new_name", None),          # on_cancel
                               message="New name for the file:")
        return ui.dialog_layer(main_view(), dialog)
```

**Declarative:**

```python
from dataclasses import dataclass

@dataclass
class Typed:
    text: str

class Files(pz.App):
    name, new_name = "notes.py", "notes.py"

    def update(self, message):
        match message:
            case Typed(text):
                self.new_name = text
            case "rename":
                self.name, self.new_name = self.new_name, None
            case "cancel":
                self.new_name = None

    def view(self):
        dialog = ui.prompt("Rename", self.new_name, Typed, "rename", "cancel") \
            if self.new_name is not None else None
        return ui.dialog_layer(main_view(), dialog)
```

**Functional:**

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class State:
    name: str = "notes.py"
    draft: str = "notes.py"
    renaming: bool = True

def view(state, set_state):
    if not state.renaming:
        return ui.label(state.name)
    return ui.dialog_layer(main_view(), ui.prompt(
        "Rename", state.draft, lambda text: set_state(draft=text),
        lambda: set_state(name=state.draft, renaming=False), lambda: set_state(renaming=False)))
```

## Properties and API

### `ui.prompt`

```python
prompt(
    title,
    value,
    on_input,
    on_submit,
    on_cancel,
    *,
    message=None,
    placeholder='',
    submit_label=None,
    cancel_label=None,
    id=None,
    width=440,
    theme=None,
)
```

Asks for a line of text.

| Property | Default | Description |
| --- | --- | --- |
| `title` | *required* | Title. |
| `value` | *required* | Current text. |
| `message` | `None` | Text above the field. |
| `placeholder` | `""` | Hint text shown when empty. |
| `submit_label` | `None` | Submit button text. |
| `cancel_label` | `None` | Cancel button text. |
| `id` | `None` | Field id (for `Command.focus`). |
| `width` | `440` | Width: pixels, `"fill"`, `"shrink"` or `"fill:N"` (proportion). |
| `theme` | `None` | Theme to use instead of the current one (`pyzed.theme.current()`). |

Events: `on_input`, `on_submit`, `on_cancel` ([events](#events)).

[Full reference →](https://albakore.github.io/pyzed/reference/ui/#prompt)

## Related

- [Confirm](https://albakore.github.io/pyzed/library/confirm/): A yes/no question, red for destructive actions.
- [Input](https://albakore.github.io/pyzed/library/input/): A controlled text field with icon, placeholder and password mode.
- [Dialog layer](https://albakore.github.io/pyzed/library/dialog-layer/): Centers a dialog over your view with a dimmed backdrop.
