diff --git a/CHANGELOG.md b/CHANGELOG.md index 8485d941df..77df2a06ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added `Select.type_to_search` which allows you to type to move the cursor to a matching option https://github.com/Textualize/textual/pull/5403 - Updated `TextArea` and `Input` behavior when there is a selection and the user presses left or right https://github.com/Textualize/textual/pull/5400 - Added `from_app_focus` to `Focus` event to indicate if a widget is being focused because the app itself has regained focus or not https://github.com/Textualize/textual/pull/5379 +- Added `Blurred` message to `Input` widget (matching `Submitted` and `Changed`) to make it easier to synchronize with `validate_on` parameter when set to 'blur'. - Added `Offset.transpose` https://github.com/Textualize/textual/pull/5409 - Added `screen--selection` component class to define style for selection https://github.com/Textualize/textual/pull/5409 - Added `Widget.select_container` property https://github.com/Textualize/textual/pull/5409 @@ -33,6 +34,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- The content of an `Input` will now only be automatically selected when the widget is focused by the user, not when the app itself has regained focus (similar to web browsers). https://github.com/Textualize/textual/pull/5379 +- Updated `TextArea` and `Input` behavior when there is a selection and the user presses left or right https://github.com/Textualize/textual/pull/5400 +- Footer can now be scrolled horizontally without holding `shift` https://github.com/Textualize/textual/pull/5404 +- Modified _on_blur method in `Input` to post a `Blurred` message - Fixed `Pilot.click` not working with `times` parameter https://github.com/Textualize/textual/pull/5398 - Fixed select refocusing itself too late https://github.com/Textualize/textual/pull/5420 - Fixed Log widget not refreshing on resize https://github.com/Textualize/textual/pull/5460 diff --git a/src/textual/widgets/_input.py b/src/textual/widgets/_input.py index 463f9e13c8..62f8f81d00 100644 --- a/src/textual/widgets/_input.py +++ b/src/textual/widgets/_input.py @@ -284,6 +284,29 @@ def control(self) -> Input: """Alias for self.input.""" return self.input + @dataclass + class Blurred(Message): + """Posted when the widget is blurred (loses focus). + + Can be handled using `on_input_blurred` in a subclass of `Input` or in a parent + widget in the DOM. + """ + + input: Input + """The `Input` widget that was changed.""" + + value: str + """The value that the input was changed to.""" + + validation_result: ValidationResult | None = None + """The result of validating the value (formed by combining the results from each validator), or None + if validation was not performed (for example when no validators are specified in the `Input`s init)""" + + @property + def control(self) -> Input: + """Alias for self.input.""" + return self.input + def __init__( self, value: str | None = None, @@ -636,8 +659,10 @@ def _on_mount(self, event: Mount) -> None: def _on_blur(self, event: Blur) -> None: self._pause_blink() - if "blur" in self.validate_on: - self.validate(self.value) + validation_result = ( + self.validate(self.value) if "blur" in self.validate_on else None + ) + self.post_message(self.Blurred(self, self.value, validation_result)) def _on_focus(self, event: Focus) -> None: self._restart_blink()