input.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. """An input component."""
  2. from typing import Any, Dict
  3. from reflex.components.component import Component
  4. from reflex.components.forms.debounce import DebounceInput
  5. from reflex.components.libs.chakra import ChakraComponent
  6. from reflex.constants import EventTriggers
  7. from reflex.utils import imports
  8. from reflex.vars import ImportVar, Var
  9. class Input(ChakraComponent):
  10. """The Input component is a component that is used to get user input in a text field."""
  11. tag = "Input"
  12. # State var to bind the input.
  13. value: Var[str]
  14. # The default value of the input.
  15. default_value: Var[str]
  16. # The placeholder text.
  17. placeholder: Var[str]
  18. # The type of input.
  19. type_: Var[str] = "text" # type: ignore
  20. # The border color when the input is invalid.
  21. error_border_color: Var[str]
  22. # The border color when the input is focused.
  23. focus_border_color: Var[str]
  24. # If true, the form control will be disabled. This has 2 side effects - The FormLabel will have `data-disabled` attribute - The form element (e.g, Input) will be disabled
  25. is_disabled: Var[bool]
  26. # If true, the form control will be invalid. This has 2 side effects - The FormLabel and FormErrorIcon will have `data-invalid` set to true - The form element (e.g, Input) will have `aria-invalid` set to true
  27. is_invalid: Var[bool]
  28. # If true, the form control will be readonly.
  29. is_read_only: Var[bool]
  30. # If true, the form control will be required. This has 2 side effects - The FormLabel will show a required indicator - The form element (e.g, Input) will have `aria-required` set to true
  31. is_required: Var[bool]
  32. # "outline" | "filled" | "flushed" | "unstyled"
  33. variant: Var[str]
  34. # "lg" | "md" | "sm" | "xs"
  35. size: Var[str]
  36. def _get_imports(self) -> imports.ImportDict:
  37. return imports.merge_imports(
  38. super()._get_imports(),
  39. {"/utils/state": {ImportVar(tag="set_val")}},
  40. )
  41. def get_event_triggers(self) -> Dict[str, Any]:
  42. """Get the event triggers that pass the component's value to the handler.
  43. Returns:
  44. A dict mapping the event trigger to the var that is passed to the handler.
  45. """
  46. return {
  47. **super().get_event_triggers(),
  48. EventTriggers.ON_CHANGE: lambda e0: [e0.target.value],
  49. EventTriggers.ON_FOCUS: lambda e0: [e0.target.value],
  50. EventTriggers.ON_BLUR: lambda e0: [e0.target.value],
  51. EventTriggers.ON_KEY_DOWN: lambda e0: [e0.key],
  52. EventTriggers.ON_KEY_UP: lambda e0: [e0.key],
  53. }
  54. @classmethod
  55. def create(cls, *children, **props) -> Component:
  56. """Create an Input component.
  57. Args:
  58. *children: The children of the component.
  59. **props: The properties of the component.
  60. Returns:
  61. The component.
  62. """
  63. if (
  64. isinstance(props.get("value"), Var) and props.get("on_change")
  65. ) or "debounce_timeout" in props:
  66. # Currently default to 50ms, which appears to be a good balance
  67. debounce_timeout = props.pop("debounce_timeout", 50)
  68. # create a debounced input if the user requests full control to avoid typing jank
  69. return DebounceInput.create(
  70. super().create(*children, **props), debounce_timeout=debounce_timeout
  71. )
  72. return super().create(*children, **props)
  73. class InputGroup(ChakraComponent):
  74. """The InputGroup component is a component that is used to group a set of inputs."""
  75. tag = "InputGroup"
  76. class InputLeftAddon(ChakraComponent):
  77. """The InputLeftAddon component is a component that is used to add an addon to the left of an input."""
  78. tag = "InputLeftAddon"
  79. class InputRightAddon(ChakraComponent):
  80. """The InputRightAddon component is a component that is used to add an addon to the right of an input."""
  81. tag = "InputRightAddon"
  82. class InputLeftElement(ChakraComponent):
  83. """The InputLeftElement component is a component that is used to add an element to the left of an input."""
  84. tag = "InputLeftElement"
  85. class InputRightElement(ChakraComponent):
  86. """The InputRightElement component is a component that is used to add an element to the right of an input."""
  87. tag = "InputRightElement"