Current section
Files
Jump to
Current section
Files
lib/doggo/components/image.ex
defmodule Doggo.Components.Image do
@moduledoc false
@behaviour Doggo.Component
use Phoenix.Component
@impl true
def doc do
"""
Renders an image with an optional caption.
"""
end
@impl true
def usage do
"""
```heex
<.image
src="https://github.com/woylie/doggo/blob/main/assets/dog_poncho.jpg?raw=true"
alt="A dog wearing a colorful poncho walks down a fashion show runway."
ratio={{16, 9}}
>
<:caption>
Spotlight on canine couture: A dog fashion show where four-legged models
dazzle the runway with the latest in pet apparel.
</:caption>
</.image>
```
"""
end
@impl true
def config do
[
type: :media,
since: "0.6.0",
maturity: :developing,
modifiers: [
ratio: [
values: [
nil,
"1-by-1",
"3-by-2",
"2-by-3",
"4-by-3",
"3-by-4",
"5-by-4",
"4-by-5",
"16-by-9",
"9-by-16"
],
default: nil
]
]
]
end
@impl true
def nested_classes(base_class) do
[
"#{base_class}-frame"
]
end
@impl true
def attrs_and_slots do
quote do
attr :src, :string,
required: true,
doc: "The URL of the image to render."
attr :srcset, :any,
default: nil,
doc: """
A set of image URLs in different sizes. Can be passed as a string or a map.
For example, this map:
%{
"1x" => "images/image-1x.jpg",
"2x" => "images/image-2x.jpg"
}
Will result in this `srcset`:
"images/image-1x.jpg 1x, images/image-2x.jpg 2x"
See https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset.
"""
attr :sizes, :string,
default: nil,
doc: """
Specifies media conditions for the image widths, if the `srcset` attribute
uses intrinsic widths.
See https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes.
"""
attr :alt, :string,
required: true,
doc: """
A text description of the image for screen reader users and those with slow
internet. Effective alt text should concisely capture the image's essence
and function, considering its context within the content. Aim for clarity
and inclusivity without repeating information already conveyed by
surrounding text, and avoid starting with "Image of" as screen readers
automatically announce image presence.
"""
attr :width, :integer, default: nil
attr :height, :integer, default: nil
attr :loading, :string, values: ["eager", "lazy"], default: "lazy"
attr :rest, :global, doc: "Any additional HTML attributes."
slot :caption
end
end
@impl true
def init_block(_opts, _extra) do
[]
end
@impl true
def render(assigns) do
~H"""
<figure class={@class} {@rest}>
<div class={"#{@base_class}-frame"}>
<img
src={@src}
width={@width}
height={@height}
alt={@alt}
loading={@loading}
srcset={build_srcset(@srcset)}
sizes={@sizes}
/>
</div>
<figcaption :if={@caption != []}><%= render_slot(@caption) %></figcaption>
</figure>
"""
end
defp build_srcset(nil), do: nil
defp build_srcset(srcset) when is_binary(srcset), do: srcset
defp build_srcset(%{} = srcset) do
Enum.map_join(srcset, ", ", fn {width_or_density, url} ->
"#{url} #{width_or_density}"
end)
end
end