11import sys
22from abc import ABC , abstractmethod
33from collections .abc import Awaitable , Callable
4+ from dataclasses import dataclass
5+ from enum import Enum , auto
46from typing import Any , ClassVar , Literal , TypeVar , cast , override
57
68from textual import work
@@ -707,6 +709,18 @@ def __init__(self, header: str):
707709 super ().__init__ (group , header )
708710
709711
712+ class InputInfoType (Enum ):
713+ MsgInfo = auto ()
714+ MsgWarning = auto ()
715+ MsgError = auto ()
716+
717+
718+ @dataclass
719+ class InputInfo :
720+ message : str
721+ info_type : InputInfoType
722+
723+
710724class InputScreen (BaseScreen [str ]):
711725 CSS = """
712726 InputScreen {
@@ -728,6 +742,22 @@ class InputScreen(BaseScreen[str]):
728742 color: red;
729743 text-align: center;
730744 }
745+
746+ #input-info {
747+ text-align: center;
748+ }
749+
750+ .input-hint-msg-error {
751+ color: red;
752+ }
753+
754+ .input-hint-msg-warning {
755+ color: yellow;
756+ }
757+
758+ .input-hint-msg-info {
759+ color: green;
760+ }
731761 """
732762
733763 def __init__ (
@@ -739,6 +769,7 @@ def __init__(
739769 allow_reset : bool = False ,
740770 allow_skip : bool = False ,
741771 validator : Validator | None = None ,
772+ info_callback : Callable [[str ], InputInfo | None ] | None = None ,
742773 ):
743774 super ().__init__ (allow_skip , allow_reset )
744775 self ._header = header or ''
@@ -748,6 +779,7 @@ def __init__(
748779 self ._allow_reset = allow_reset
749780 self ._allow_skip = allow_skip
750781 self ._validator = validator
782+ self ._info_callback = info_callback
751783
752784 async def run (self ) -> Result [str ]:
753785 assert TApp .app
@@ -768,6 +800,7 @@ def compose(self) -> ComposeResult:
768800 validate_on = ['submitted' ],
769801 )
770802 yield Label ('' , classes = 'input-failure' , id = 'input-failure' )
803+ yield Label ('' , id = 'input-info' )
771804
772805 yield Footer ()
773806
@@ -784,6 +817,24 @@ def on_input_submitted(self, event: Input.Submitted) -> None:
784817 else :
785818 _ = self .dismiss (Result (ResultType .Selection , _data = event .value ))
786819
820+ def on_input_changed (self , event : Input .Changed ) -> None :
821+ info_label = self .query_one ('#input-info' , Label )
822+ if self ._info_callback :
823+ result = self ._info_callback (event .value )
824+ if result :
825+ css_class = ''
826+ if result .info_type == InputInfoType .MsgError :
827+ css_class = 'input-hint-msg-error'
828+ elif result .info_type == InputInfoType .MsgWarning :
829+ css_class = 'input-hint-msg-warning'
830+ elif result .info_type == InputInfoType .MsgInfo :
831+ css_class = 'input-hint-msg-info'
832+ info_label .update (result .message )
833+ info_label .set_classes (css_class )
834+ else :
835+ info_label .update ('' )
836+ info_label .set_classes ('' )
837+
787838
788839class _DataTable (DataTable [ValueT ]):
789840 BINDINGS : ClassVar = [
0 commit comments