image.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. """Image component from next/image."""
  2. from typing import Any, Dict, Literal, Optional, Union
  3. from reflex.utils import types
  4. from reflex.vars import Var
  5. from .base import NextComponent
  6. class Image(NextComponent):
  7. """Display an image."""
  8. tag = "Image"
  9. library = "next/image"
  10. is_default = True
  11. # This can be either an absolute external URL, or an internal path
  12. src: Var[Any]
  13. # Represents the rendered width in pixels, so it will affect how large the image appears.
  14. width: Var[Any]
  15. # Represents the rendered height in pixels, so it will affect how large the image appears.
  16. height: Var[Any]
  17. # Used to describe the image for screen readers and search engines.
  18. alt: Var[str]
  19. # A custom function used to resolve image URLs.
  20. loader: Var[Any]
  21. # A boolean that causes the image to fill the parent element, which is useful when the width and height are unknown. Default to True
  22. fill: Var[bool]
  23. # A string, similar to a media query, that provides information about how wide the image will be at different breakpoints.
  24. sizes: Var[str]
  25. # The quality of the optimized image, an integer between 1 and 100, where 100 is the best quality and therefore largest file size. Defaults to 75.
  26. quality: Var[int]
  27. # When true, the image will be considered high priority and preload. Lazy loading is automatically disabled for images using priority.
  28. priority: Var[bool]
  29. # A placeholder to use while the image is loading. Possible values are blur, empty, or data:image/.... Defaults to empty.
  30. placeholder: Var[str]
  31. # Allows passing CSS styles to the underlying image element.
  32. # style: Var[Any]
  33. # The loading behavior of the image. Defaults to lazy. Can hurt performance, recommended to use `priority` instead.
  34. loading: Var[Literal["lazy", "eager"]]
  35. # A Data URL to be used as a placeholder image before the src image successfully loads. Only takes effect when combined with placeholder="blur".
  36. blurDataURL: Var[str]
  37. def get_event_triggers(self) -> Dict[str, Any]:
  38. """The event triggers of the component.
  39. Returns:
  40. The dict describing the event triggers.
  41. """
  42. return {
  43. **super().get_event_triggers(),
  44. "on_load": lambda: [],
  45. "on_error": lambda: [],
  46. }
  47. @classmethod
  48. def create(
  49. cls,
  50. *children,
  51. width: Optional[Union[int, str]] = None,
  52. height: Optional[Union[int, str]] = None,
  53. **props,
  54. ):
  55. """Create an Image component from next/image.
  56. Args:
  57. *children: The children of the component.
  58. width: The width of the image.
  59. height: The height of the image.
  60. **props:The props of the component.
  61. Returns:
  62. _type_: _description_
  63. """
  64. style = props.get("style", {})
  65. DEFAULT_W_H = "100%"
  66. def check_prop_type(prop_name, prop_value):
  67. if types.check_prop_in_allowed_types(prop_value, allowed_types=[int]):
  68. props[prop_name] = prop_value
  69. elif types.check_prop_in_allowed_types(prop_value, allowed_types=[str]):
  70. props[prop_name] = 0
  71. style[prop_name] = prop_value
  72. else:
  73. props[prop_name] = 0
  74. style[prop_name] = DEFAULT_W_H
  75. check_prop_type("width", width)
  76. check_prop_type("height", height)
  77. props["style"] = style
  78. # mysteriously, following `sizes` prop is needed to avoid blury images.
  79. props["sizes"] = "100vw"
  80. src = props.get("src", None)
  81. if src is not None and not isinstance(src, (Var)):
  82. props["src"] = Var.create(value=src, _var_is_string=True)
  83. return super().create(*children, **props)