make entire product card image area clickable
All checks were successful
deploy / deploy (push) Successful in 1m18s

The stretched-link::after overlay (z-index: 0) was blocked by
product-card-image-wrap (z-index: 1), so only the title text was
actually clickable. Wrapping the image area in a <.link> component
directly fixes this — taps/clicks bubble up to the link naturally,
and touch-scroll on the image carousel still works on mobile.

Also corrects the mode check: ThemeHook sets mode: :shop on shop pages,
not :live, so the condition is now mode != :preview (consistent with
how the title link already worked).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey 2026-02-24 15:22:43 +00:00
parent e7656cf0b3
commit 12d87998ee
2 changed files with 26 additions and 2 deletions

View File

@ -50,6 +50,7 @@
} }
.product-card-image-wrap { .product-card-image-wrap {
display: block;
z-index: 1; z-index: 1;
overflow: hidden; overflow: hidden;
position: relative; position: relative;

View File

@ -96,14 +96,20 @@ defmodule BerrypodWeb.ShopComponents.Product do
primary_image = Product.primary_image(product) primary_image = Product.primary_image(product)
hover_image = Product.hover_image(product) hover_image = Product.hover_image(product)
product_url =
if assigns.clickable && assigns.mode != :preview do
"/products/#{Map.get(assigns.product, :slug) || Map.get(assigns.product, :id)}"
end
assigns = assigns =
assigns assigns
|> assign(:primary_image, primary_image) |> assign(:primary_image, primary_image)
|> assign(:hover_image, hover_image) |> assign(:hover_image, hover_image)
|> assign(:has_hover_image, assigns.theme_settings.hover_image && hover_image != nil) |> assign(:has_hover_image, assigns.theme_settings.hover_image && hover_image != nil)
|> assign(:product_url, product_url)
~H""" ~H"""
<div class="product-card-image-wrap"> <.product_card_image_wrap href={@product_url}>
<%= if @show_badges do %> <%= if @show_badges do %>
<.product_badge product={@product} /> <.product_badge product={@product} />
<% end %> <% end %>
@ -142,7 +148,7 @@ defmodule BerrypodWeb.ShopComponents.Product do
<span class="product-image-dot"></span> <span class="product-image-dot"></span>
</div> </div>
<% end %> <% end %>
</div> </.product_card_image_wrap>
<div class="product-card-content"> <div class="product-card-content">
<%= if @show_category && Map.get(@product, :category) do %> <%= if @show_category && Map.get(@product, :category) do %>
<%= if @mode == :preview do %> <%= if @mode == :preview do %>
@ -193,6 +199,23 @@ defmodule BerrypodWeb.ShopComponents.Product do
""" """
end end
attr :href, :string, default: nil
slot :inner_block, required: true
defp product_card_image_wrap(assigns) do
~H"""
<%= if @href do %>
<.link navigate={@href} class="product-card-image-wrap" tabindex="-1" aria-hidden="true">
{render_slot(@inner_block)}
</.link>
<% else %>
<div class="product-card-image-wrap">
{render_slot(@inner_block)}
</div>
<% end %>
"""
end
attr :image, :map, default: nil attr :image, :map, default: nil
attr :alt, :string, required: true attr :alt, :string, required: true
attr :variant, :atom, required: true attr :variant, :atom, required: true