input.py 4.4 KB

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