defmodule PUI.Alert do @moduledoc """ Alert component for displaying important messages and status updates. ## Basic Usage <.alert>

This is an alert message.

## With Icon <.alert> <:icon> <.icon name="hero-information-circle" class="size-5" />

Alert with an icon.

## With Title and Description <.alert> <:icon> <.icon name="hero-check-circle" class="size-5" /> <:title>Success! <:description>Your changes have been saved successfully. ## Destructive Variant Use the destructive variant for errors and warnings: <.alert variant="destructive"> <:icon> <.icon name="hero-exclamation-triangle" class="size-5" /> <:title>Error <:description>Something went wrong. ## Without Description <.alert> <:icon> <.icon name="hero-exclamation-triangle" class="size-5" /> <:title>Warning ## Attributes | Attribute | Type | Default | Description | |-----------|------|---------|-------------| | `variant` | `string` | `"default"` | Alert style: "default" or "destructive" | | `class` | `string` | `""` | Additional CSS classes | ## Slots | Slot | Description | |------|-------------| | `icon` | Optional icon displayed at the start | | `title` | Alert title text | | `description` | Detailed description text | | `inner_block` | Custom content (alternative to slots) | """ use Phoenix.Component attr :class, :string, default: "" attr :variant, :string, values: ["default", "destructive", "unstyled"], default: "default" attr :role, :string, default: nil attr :rest, :global slot :icon, required: false slot :title, required: false do attr :class, :string end slot :description, required: false do attr :class, :string end slot :inner_block def alert(%{variant: variant} = assigns) do is_unstyled = variant == "unstyled" variant_class = if is_unstyled do "" else case assigns[:variant] do "default" -> "bg-card text-card-foreground" "destructive" -> "text-destructive bg-card [&>svg]:text-current *:data-[alert-desc]:text-destructive/90" end end role = case assigns[:role] do nil -> if assigns[:variant] == "destructive", do: "alert", else: "status" value -> value end assigns = assign(assigns, variant_class: variant_class, is_unstyled: is_unstyled, role: role) ~H"""
[data-icon]]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>[data-icon]]:gap-x-3 [&>[data-icon]]:size-4 [&>[data-icon]]:text-current", @variant_class, @class ] end } >
{render_slot(@icon)}
<.alert_title :if={@title !== []} is_unstyled={@is_unstyled}> {render_slot(@title)} <.alert_description :if={@description !== []} is_unstyled={@is_unstyled}> {render_slot(@description)} {render_slot(@inner_block)}
""" end @doc """ Renders the title of an alert. """ attr :class, :string, default: "" attr :is_unstyled, :boolean, default: false slot :inner_block def alert_title(%{is_unstyled: is_unstyled} = assigns) do assigns = assign(assigns, :is_unstyled, is_unstyled) ~H"""
{render_slot(@inner_block)}
""" end @doc """ Renders the description of an alert. """ attr :class, :string, default: "" attr :is_unstyled, :boolean, default: false slot :inner_block def alert_description(%{is_unstyled: is_unstyled} = assigns) do assigns = assign(assigns, :is_unstyled, is_unstyled) ~H"""
{render_slot(@inner_block)}
""" end end