select.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. """A select component."""
  2. from typing import Any, Set
  3. from pynecone import utils
  4. from pynecone.components.component import EVENT_ARG, Component
  5. from pynecone.components.libs.chakra import ChakraComponent
  6. from pynecone.components.tags import Tag
  7. from pynecone.components.typography.text import Text
  8. from pynecone.var import Var
  9. class Select(ChakraComponent):
  10. """Select component is a component that allows users pick a value from predefined options. Ideally, it should be used when there are more than 5 options, otherwise you might consider using a radio group instead."""
  11. tag = "Select"
  12. # State var to bind the the select.
  13. value: Var[str]
  14. # The default value of the select.
  15. default_value: Var[str]
  16. # The placeholder text.
  17. placeholder: Var[str]
  18. # The border color when the select is invalid.
  19. error_border_color: Var[str]
  20. # The border color when the select is focused.
  21. focus_border_color: Var[str]
  22. # If true, the select will be disabled.
  23. is_disabled: Var[bool]
  24. # 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
  25. is_invalid: Var[bool]
  26. # If true, the form control will be readonly
  27. is_read_only: Var[bool]
  28. # 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
  29. is_required: Var[bool]
  30. # "outline" | "filled" | "flushed" | "unstyled"
  31. variant: Var[str]
  32. @classmethod
  33. def get_controlled_triggers(cls) -> Set[str]:
  34. """Get the event triggers that pass the component's value to the handler.
  35. Returns:
  36. The controlled event triggers.
  37. """
  38. return {"on_change"}
  39. @classmethod
  40. def get_controlled_value(cls) -> Var:
  41. """Get the var that is passed to the event handler for controlled triggers.
  42. Returns:
  43. The controlled value.
  44. """
  45. return EVENT_ARG.target.value
  46. @classmethod
  47. def create(cls, *children, **props) -> Component:
  48. """Create a select component.
  49. If a list is provided as the first children, a default component
  50. will be created for each item in the list.
  51. Args:
  52. *children: The children of the component.
  53. **props: The props of the component.
  54. Returns:
  55. The component.
  56. """
  57. if len(children) == 1 and isinstance(children[0], list):
  58. children = [Option.create(child) for child in children[0]]
  59. return super().create(*children, **props)
  60. class Option(Text):
  61. """A select option."""
  62. tag = "option"
  63. value: Var[Any]
  64. @classmethod
  65. def create(cls, *children, **props) -> Component:
  66. """Create a select option component.
  67. By default, the value of the option is the text of the option.
  68. Args:
  69. *children: The children of the component.
  70. **props: The props of the component.
  71. Returns:
  72. The component.
  73. """
  74. if "value" not in props:
  75. assert len(children) == 1
  76. props["value"] = children[0]
  77. return super().create(*children, **props)