Skip to content

Commit

Permalink
input restriction (Textualize#3657)
Browse files Browse the repository at this point in the history
* input restriction

* types

* tweak

* tests

* docstring

* fix lock

* words

* add valid empty

* another test

* fix regex

* doc

* name change

* Fix regex

* force initial value

* force reactive

* test fix

* add plus

* input type literal

* export InputType
  • Loading branch information
willmcgugan authored Nov 10, 2023
1 parent 65bf94a commit c0f299b
Show file tree
Hide file tree
Showing 8 changed files with 1,054 additions and 584 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- CSS error reporting will no longer provide links to the files in question https://github.com/Textualize/textual/pull/3582
- inline CSS error reporting will report widget/class variable where the CSS was read from https://github.com/Textualize/textual/pull/3582
- Added `restrict`, `type`, `max_length`, and `valid_empty` to Input https://github.com/Textualize/textual/pull/3657

## [0.41.0] - 2023-10-31

Expand Down
13 changes: 13 additions & 0 deletions docs/examples/widgets/input_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from textual.app import App, ComposeResult
from textual.widgets import Input


class InputApp(App):
def compose(self) -> ComposeResult:
yield Input(placeholder="An integer", type="integer")
yield Input(placeholder="A number", type="number")


if __name__ == "__main__":
app = InputApp()
app.run()
63 changes: 56 additions & 7 deletions docs/widgets/input.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,47 @@ The example below shows how you might create a simple form using two `Input` wid
--8<-- "docs/examples/widgets/input.py"
```


### Input Types

The `Input` widget supports a `type` parameter which will prevent the user from typing invalid characters.
You can set `type` to any of the following values:


| input.type | Description |
| ----------- | ------------------------------------------- |
| `"integer"` | Restricts input to integers. |
| `"number"` | Restricts input to a floating point number. |
| `"text"` | Allow all text (no restrictions). |

=== "Output"

```{.textual path="docs/examples/widgets/input_types.py" press="1234"}
```

=== "input_types.py"

```python
--8<-- "docs/examples/widgets/input_types.py"
```

If you set `type` to something other than `"text"`, then the `Input` will apply the appropriate [validator](#validating-input).

### Restricting Input

You can limit input to particular characters by supplying the `restrict` parameter, which should be a regular expression.
The `Input` widget will prevent the addition of any characters that would cause the regex to no longer match.
For instance, if you wanted to limit characters to binary you could set `restrict=r"[01]*"`.

!!! note

The `restrict` regular expression is applied to the full value and not just to the new character.

### Maximum Length

You can limit the length of the input by setting `max_length` to a value greater than zero.
This will prevent the user from typing any more characters when the maximum has been reached.

### Validating Input

You can supply one or more *[validators][textual.validation.Validator]* to the `Input` widget to validate the value.
Expand Down Expand Up @@ -71,15 +112,23 @@ Textual offers several [built-in validators][textual.validation] for common requ
but you can easily roll your own by extending [Validator][textual.validation.Validator],
as seen for `Palindrome` in the example above.

#### Validate Empty

If you set `valid_empty=True` then empty values will bypass any validators, and empty values will be considered valid.

## Reactive Attributes

| Name | Type | Default | Description |
|-------------------|--------|---------|-----------------------------------------------------------------|
| `cursor_blink` | `bool` | `True` | True if cursor blinking is enabled. |
| `value` | `str` | `""` | The value currently in the text input. |
| `cursor_position` | `int` | `0` | The index of the cursor in the value string. |
| `placeholder` | `str` | `str` | The dimmed placeholder text to display when the input is empty. |
| `password` | `bool` | `False` | True if the input should be masked. |
| Name | Type | Default | Description |
| ----------------- | ------ | -------- | --------------------------------------------------------------- |
| `cursor_blink` | `bool` | `True` | True if cursor blinking is enabled. |
| `value` | `str` | `""` | The value currently in the text input. |
| `cursor_position` | `int` | `0` | The index of the cursor in the value string. |
| `placeholder` | `str` | `""` | The dimmed placeholder text to display when the input is empty. |
| `password` | `bool` | `False` | True if the input should be masked. |
| `restrict` | `str` | `None` | Optional regular expression to restrict input. |
| `type` | `str` | `"text"` | The type of the input. |
| `max_length` | `int` | `None` | Maximum length of the input value. |
| `valid_empty` | `bool` | `False` | Allow empty values to bypass validation. |

## Messages

Expand Down
Loading

0 comments on commit c0f299b

Please sign in to comment.