defmodule <%= @module %> do @moduledoc """ The `<%= @module %>` module provides a versatile component for visually highlighting specific areas or elements in your Phoenix application. It is designed to display small, circular indicators that can be used for notifications, status updates, or visual cues on UI elements. This component supports various sizes and colors and can be positioned in multiple areas relative to its parent element. Additionally, it has an optional ping animation for drawing attention to a specific point on the interface. The indicator can be used in diverse scenarios, such as showing the number of unread messages, indicating active states, or displaying connectivity status. It is customizable with different styles, making it adaptable to various design needs. """ use Phoenix.Component @indicator_positions [ "top_left", "top_center", "top_right", "middle_left", "middle_right", "bottom_left", "bottom_center", "bottom_right" ] @doc """ Renders an `indicator` component with customizable size, color, and position. The indicator can be positioned around its parent element and supports various sizes and styles. ## Examples ```elixir <.indicator /> <.indicator color="misc" /> <.indicator size="extra_small" /> <.indicator color="warning" size="extra_small" bottom_left /> ``` """ @doc type: :component attr :id, :string, default: nil, doc: "A unique identifier is used to manage state and interaction" attr :size, :string, default: "small", doc: "Determines the overall size of the elements, including padding, font size, and other items" attr :class, :string, default: nil, doc: "Custom CSS class for additional styling" attr :color, :string, default: "base", doc: "Determines color theme" attr :rest, :global, include: ["pinging"] ++ @indicator_positions, doc: "Global attributes can define defaults which are merged with attributes provided by the caller" def indicator(%{rest: %{top_left: true}} = assigns) do ~H""" """ end def indicator(%{rest: %{top_center: true}} = assigns) do ~H""" """ end def indicator(%{rest: %{top_right: true}} = assigns) do ~H""" """ end def indicator(%{rest: %{middle_left: true}} = assigns) do ~H""" """ end def indicator(%{rest: %{middle_right: true}} = assigns) do ~H""" """ end def indicator(%{rest: %{bottom_left: true}} = assigns) do ~H""" """ end def indicator(%{rest: %{bottom_center: true}} = assigns) do ~H""" """ end def indicator(%{rest: %{bottom_right: true}} = assigns) do ~H""" """ end def indicator(assigns) do ~H""" """ end <%= if is_nil(@size) or "extra_small" in @size do %> defp indicator_size("extra_small"), do: "!size-2" <% end %> <%= if is_nil(@size) or "small" in @size do %> defp indicator_size("small"), do: "!size-2.5" <% end %> <%= if is_nil(@size) or "medium" in @size do %> defp indicator_size("medium"), do: "!size-3" <% end %> <%= if is_nil(@size) or "large" in @size do %> defp indicator_size("large"), do: "!size-3.5" <% end %> <%= if is_nil(@size) or "extra_large" in @size do %> defp indicator_size("extra_large"), do: "!size-4" <% end %> defp indicator_size(params) when is_binary(params), do: params <%= if is_nil(@color) or "base" in @color do %> defp color_class("base"), do: "bg-[#e4e4e7] dark:bg-[#27272a]" <% end %> <%= if is_nil(@color) or "white" in @color do %> defp color_class("white"), do: "bg-white" <% end %> <%= if is_nil(@color) or "natural" in @color do %> defp color_class("natural"), do: "bg-[#4B4B4B] dark:bg-[#DDDDDD]" <% end %> <%= if is_nil(@color) or "primary" in @color do %> defp color_class("primary"), do: "bg-[#007F8C] dark:bg-[#01B8CA]" <% end %> <%= if is_nil(@color) or "secondary" in @color do %> defp color_class("secondary"), do: "bg-[#266EF1] dark:bg-[#6DAAFB]" <% end %> <%= if is_nil(@color) or "success" in @color do %> defp color_class("success"), do: "bg-[#0E8345] dark:bg-[#06C167]" <% end %> <%= if is_nil(@color) or "warning" in @color do %> defp color_class("warning"), do: "bg-[#CA8D01] dark:bg-[#FDC034]" <% end %> <%= if is_nil(@color) or "danger" in @color do %> defp color_class("danger"), do: "bg-[#DE1135] dark:bg-[#FC7F79]" <% end %> <%= if is_nil(@color) or "info" in @color do %> defp color_class("info"), do: "bg-[#0B84BA] dark:bg-[#3EB7ED]" <% end %> <%= if is_nil(@color) or "misc" in @color do %> defp color_class("misc"), do: "bg-[#8750C5] dark:bg-[#BA83F9]" <% end %> <%= if is_nil(@color) or "dawn" in @color do %> defp color_class("dawn"), do: "bg-[#A86438] dark:bg-[#DB976B]" <% end %> <%= if is_nil(@color) or "silver" in @color do %> defp color_class("silver"), do: "bg-[#868686] dark:bg-[#A6A6A6]" <% end %> <%= if is_nil(@color) or "dark" in @color do %> defp color_class("dark"), do: "bg-[#282828]" <% end %> defp color_class(params) when is_binary(params), do: params defp drop_rest(rest) do all_rest = (["pinging"] ++ @indicator_positions) |> Enum.map(&if(is_binary(&1), do: String.to_atom(&1), else: &1)) Map.drop(rest, all_rest) end end