1
0

props.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. """A class that holds props to be passed or applied to a component."""
  2. from __future__ import annotations
  3. from pydantic import ValidationError
  4. from reflex.base import Base
  5. from reflex.utils import format
  6. from reflex.utils.exceptions import InvalidPropValueError
  7. from reflex.vars.object import LiteralObjectVar
  8. class PropsBase(Base):
  9. """Base for a class containing props that can be serialized as a JS object."""
  10. def json(self) -> str:
  11. """Convert the object to a json-like string.
  12. Vars will be unwrapped so they can represent actual JS var names and functions.
  13. Keys will be converted to camelCase.
  14. Returns:
  15. The object as a Javascript Object literal.
  16. """
  17. return LiteralObjectVar.create(
  18. {format.to_camel_case(key): value for key, value in self.dict().items()}
  19. ).json()
  20. def dict(self, *args, **kwargs):
  21. """Convert the object to a dictionary.
  22. Keys will be converted to camelCase.
  23. Args:
  24. *args: Arguments to pass to the parent class.
  25. **kwargs: Keyword arguments to pass to the parent class.
  26. Returns:
  27. The object as a dictionary.
  28. """
  29. return {
  30. format.to_camel_case(key): value
  31. for key, value in super().dict(*args, **kwargs).items()
  32. }
  33. class NoExtrasAllowedProps(Base):
  34. """A class that holds props to be passed or applied to a component with no extra props allowed."""
  35. def __init__(self, component_name: str | None = None, **kwargs):
  36. """Initialize the props.
  37. Args:
  38. component_name: The custom name of the component.
  39. kwargs: Kwargs to initialize the props.
  40. Raises:
  41. InvalidPropValueError: If invalid props are passed on instantiation.
  42. """
  43. component_name = component_name or type(self).__name__
  44. try:
  45. super().__init__(**kwargs)
  46. except ValidationError as e:
  47. invalid_fields = ", ".join([error["loc"][0] for error in e.errors()]) # pyright: ignore [reportCallIssue, reportArgumentType]
  48. supported_props_str = ", ".join(f'"{field}"' for field in self.get_fields())
  49. raise InvalidPropValueError(
  50. f"Invalid prop(s) {invalid_fields} for {component_name!r}. Supported props are {supported_props_str}"
  51. ) from None
  52. class Config: # pyright: ignore [reportIncompatibleVariableOverride]
  53. """Pydantic config."""
  54. arbitrary_types_allowed = True
  55. use_enum_values = True
  56. extra = "forbid"