image.py 3.8 KB

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