defmodule PineUi.Card do @moduledoc """ Provides card components for organizing content with various behaviors. The Card module offers three main variants: - `basic/1` - Simple card with title, subtitle, content area, and optional footer - `interactive/1` - Card with hover animation effects - `collapsible/1` - Expandable/collapsible card with toggle functionality ## Examples

Card content here

This card has hover effects

This content can be hidden

## Styling Cards use TailwindCSS for styling and can be customized using the `class` parameter. """ use Phoenix.Component import Phoenix.HTML @doc """ Renders a basic card component. ## Examples <.basic title="Card Title">

Content goes here

<.basic title="Card with Footer" subtitle="With explanation" footer="Last updated: Yesterday">

Content goes here

## Options * `:title` - Card title text (optional) * `:subtitle` - Card subtitle text (optional) * `:footer` - Footer content (optional) * `:padded` - Whether to add padding to the body (optional, defaults to true) * `:class` - Additional CSS classes for the card container (optional) """ def basic(assigns) do assigns = assigns |> assign_new(:class, fn -> "" end) |> assign_new(:padded, fn -> true end) ~H"""
<%= if Map.get(assigns, :title, nil) || Map.get(assigns, :subtitle, nil) do %>
<%= if Map.get(assigns, :title, nil) do %>

<%= @title %>

<% end %> <%= if Map.get(assigns, :subtitle, nil) do %>

<%= @subtitle %>

<% end %>
<% end %>
<%= render_slot(@inner_block) %>
<%= if Map.get(assigns, :footer, nil) do %>
<%= @footer %>
<% end %>
""" end defp get_body_padding(true), do: "px-4 py-5 sm:p-6" defp get_body_padding(false), do: "" @doc """ Renders an interactive card component with hover effects. This card variant adds subtle animation effects when hovered, making it ideal for clickable cards or emphasizing important content. ## Examples <.interactive>

Hover over me to see effects

<.interactive title="Interactive Card" subtitle="With animations">

Content with hover effects

## Options * `:title` - Card title text (optional) * `:subtitle` - Card subtitle text (optional) * `:footer` - Footer content (optional) * `:padded` - Whether to add padding to the body (optional, defaults to true) * `:class` - Additional CSS classes for the card container (optional) """ def interactive(assigns) do assigns = assigns |> assign_new(:class, fn -> "" end) |> assign_new(:padded, fn -> true end) ~H"""
<%= if Map.get(assigns, :title, nil) || Map.get(assigns, :subtitle, nil) do %>
<%= if Map.get(assigns, :title, nil) do %>

<%= @title %>

<% end %> <%= if Map.get(assigns, :subtitle, nil) do %>

<%= @subtitle %>

<% end %>
<% end %>
<%= render_slot(@inner_block) %>
<%= if Map.get(assigns, :footer, nil) do %>
<%= @footer %>
<% end %>
""" end @doc """ Renders a collapsible card component with expand/collapse functionality. This card can be toggled between expanded and collapsed states by clicking on the header. Uses AlpineJS for the toggle functionality. ## Examples <.collapsible title="Click to toggle">

This content can be hidden

<.collapsible title="Initially expanded" open={true}>

This content is visible by default

## Options * `:title` - Card title text (optional) * `:subtitle` - Card subtitle text (optional) * `:footer` - Footer content (optional) * `:padded` - Whether to add padding to the body (optional, defaults to true) * `:open` - Whether the card is expanded on initial render (optional, defaults to false) * `:class` - Additional CSS classes for the card container (optional) """ def collapsible(assigns) do assigns = assigns |> assign_new(:class, fn -> "" end) |> assign_new(:padded, fn -> true end) |> assign_new(:open, fn -> false end) ~H"""
<%= if Map.get(assigns, :title, nil) do %>

<%= @title %>

<% end %> <%= if Map.get(assigns, :subtitle, nil) do %>

<%= @subtitle %>

<% end %>
<%= render_slot(@inner_block) %>
<%= if Map.get(assigns, :footer, nil) do %>
<%= @footer %>
<% end %>
""" end end