spazio-solazzo/lib/spazio_solazzo_web/live/landing/carousel_live_component.ex
2026-01-10 19:03:02 +01:00

67 lines
2.1 KiB
Elixir

defmodule SpazioSolazzoWeb.CarouselLiveComponent do
@moduledoc """
A LiveComponent for image carousels with navigation controls.
"""
use Phoenix.LiveComponent
import SpazioSolazzoWeb.CoreComponents, only: [icon: 1]
@impl true
def update(assigns, socket) do
{:ok,
socket
|> assign(assigns)
|> assign_new(:carousel_index, fn -> 0 end)}
end
@impl true
def handle_event("carousel_next", _params, socket) do
images_count = length(socket.assigns.images)
new_index = rem(socket.assigns.carousel_index + 1, images_count)
{:noreply, assign(socket, carousel_index: new_index)}
end
@impl true
def handle_event("carousel_prev", _params, socket) do
images_count = length(socket.assigns.images)
new_index = rem(socket.assigns.carousel_index - 1 + images_count, images_count)
{:noreply, assign(socket, carousel_index: new_index)}
end
@impl true
def render(assigns) do
~H"""
<div class="relative w-full h-full">
<div
class="flex h-full transition-transform duration-500 ease-in-out"
style={"transform: translateX(-#{@carousel_index * 100}%);"}
>
<div
:for={image <- @images}
class="w-full flex-shrink-0 bg-cover bg-center"
style={"background-image: url('#{image}');"}
>
</div>
</div>
<%= if length(@images) > 1 do %>
<button
phx-click="carousel_prev"
phx-target={@myself}
aria-label="Previous image"
class="absolute z-999 left-4 top-1/2 -translate-y-1/2 bg-white/20 hover:bg-white/40 backdrop-blur-sm p-2 rounded-full text-white transition-colors cursor-pointer"
>
<.icon name="hero-chevron-left" class="w-6 h-6" />
</button>
<button
phx-click="carousel_next"
phx-target={@myself}
aria-label="Next image"
class="absolute z-999 right-4 top-1/2 -translate-y-1/2 bg-white/20 hover:bg-white/40 backdrop-blur-sm p-2 rounded-full text-white transition-colors cursor-pointer"
>
<.icon name="hero-chevron-right" class="w-6 h-6" />
</button>
<% end %>
</div>
"""
end
end