defmodule PineUi do @moduledoc """ # Pine UI 🌲 Pine UI is a comprehensive collection of UI components for Phoenix applications, built with AlpineJS and TailwindCSS. The library provides interactive, accessible, and customizable components to speed up development of modern web interfaces. ## Installation Add Pine UI to your `mix.exs`: ```elixir def deps do [ {:pine_ui_phoenix, "~> 0.1.0"} ] end ``` After running `mix deps.get`, make sure your project includes: 1. **TailwindCSS** - For component styling 2. **AlpineJS** - For component interactivity ## Component Categories Pine UI offers components organized in the following categories: ### Text & Animation - `typing_effect/1` - Creates a typing animation with multiple text items - `text_animation_blow/1` - Letter-by-letter animation that scales in - `text_animation_fade/1` - Letter-by-letter fade-in animation ### Interactive Elements - `tooltip/1` - Interactive tooltip with different positions - `button_primary/1`, `button_secondary/1`, `button_danger/1` - Button variants with loading states ### Content Organization - `card/1` - Basic card component for content organization - `card_interactive/1` - Interactive card with hover effects - `card_collapsible/1` - Collapsible card for expandable content ### Form Elements - `text_input/1` - Basic text input component - `text_input_with_icon/1` - Text input with icon - `textarea/1` - Multiline text input component - `select/1` - Basic select dropdown component - `select_grouped/1` - Select dropdown with option groups - `select_searchable/1` - Searchable select dropdown with filtering ### Status Indicators - `badge/1` - Simple badge component with various colors - `badge_dot/1` - Badge with dot indicator - `badge_dismissible/1` - Badge that can be dismissed/removed ## Basic Usage ```heex
Pine UI makes it easy to build interactive Phoenix applications.
Card content goes here
<.card class="mt-4" footer="Last updated: Yesterday">Multiple paragraphs can go here
With any content structure
This card has 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 card_interactive(assigns) do Card.interactive(assigns) end @doc """ Renders a collapsible card component. This component creates a card that can be expanded/collapsed when clicked. ## Examples <.card_collapsible title="Click to expand" open={true}>This content can be hidden or shown
## 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 card_collapsible(assigns) do Card.collapsible(assigns) end @doc """ Renders a basic select dropdown component. ## Examples <.select id="country" label="Country" options={[{"us", "United States"}, {"ca", "Canada"}, {"mx", "Mexico"}]} selected="us" placeholder="Select a country" hint="Choose your country of residence" /> ## Options * `:id` - The ID for the select element (required) * `:name` - The name attribute (optional, defaults to ID) * `:label` - Label text (optional) * `:options` - List of {value, label} tuples for the options (required) * `:selected` - The currently selected value (optional) * `:placeholder` - Placeholder text for empty selection (optional) * `:hint` - Help text displayed below the select (optional) * `:error` - Error message displayed below the select (optional) * `:required` - Whether the field is required (optional, defaults to false) * `:disabled` - Whether the field is disabled (optional, defaults to false) * `:phx_change` - Phoenix change event name (optional) * `:class` - Additional CSS classes for the select element (optional) * `:container_class` - CSS classes for the container div (optional) """ def select(assigns) do Select.basic(assigns) end @doc """ Renders a select dropdown with option groups. ## Examples <.select_grouped id="continent" label="Country" option_groups={[ {"North America", [{"us", "United States"}, {"ca", "Canada"}]}, {"Europe", [{"fr", "France"}, {"de", "Germany"}]} ]} selected="fr" /> ## Options * `:id` - The ID for the select element (required) * `:name` - The name attribute (optional, defaults to ID) * `:label` - Label text (optional) * `:option_groups` - List of {group_label, options} tuples where options is a list of {value, label} tuples (required) * `:selected` - The currently selected value (optional) * `:placeholder` - Placeholder text for empty selection (optional) * `:hint` - Help text displayed below the select (optional) * `:error` - Error message displayed below the select (optional) * `:required` - Whether the field is required (optional, defaults to false) * `:disabled` - Whether the field is disabled (optional, defaults to false) * `:phx_change` - Phoenix change event name (optional) * `:class` - Additional CSS classes for the select element (optional) * `:container_class` - CSS classes for the container div (optional) """ def select_grouped(assigns) do Select.grouped(assigns) end @doc """ Renders a searchable select dropdown with filtering. ## Examples <.select_searchable id="country" label="Country" options={[{"us", "United States"}, {"ca", "Canada"}, {"mx", "Mexico"}]} selected="us" selected_label="United States" placeholder="Search countries..." /> ## Options * `:id` - The ID for the select element (required) * `:name` - The name attribute (optional, defaults to ID) * `:label` - Label text (optional) * `:options` - List of {value, label} tuples for the options (required) * `:selected` - The currently selected value (optional) * `:selected_label` - The label for the currently selected value (optional, should match the label in options) * `:placeholder` - Placeholder text for the search input (optional) * `:hint` - Help text displayed below the select (optional) * `:error` - Error message displayed below the select (optional) * `:required` - Whether the field is required (optional, defaults to false) * `:disabled` - Whether the field is disabled (optional, defaults to false) * `:phx_change` - Phoenix change event name (optional) * `:class` - Additional CSS classes for the select element (optional) * `:container_class` - CSS classes for the container div (optional) """ def select_searchable(assigns) do Select.searchable(assigns) end @doc """ Renders a basic text input component. ## Examples <.text_input id="email" label="Email Address" type="email" placeholder="you@example.com" required={true} /> <.text_input id="price" label="Price" type="number" prefix="$" suffix="USD" hint="Enter amount in dollars" error={@form_errors[:price]} /> ## Options * `:id` - The ID for the input element (required) * `:name` - The name attribute (optional, defaults to ID) * `:label` - Label text (optional) * `:type` - Input type (optional, defaults to "text") * `:value` - Current input value (optional) * `:placeholder` - Placeholder text (optional) * `:prefix` - Text to display before the input (optional) * `:suffix` - Text to display after the input (optional) * `:hint` - Help text displayed below the input (optional) * `:error` - Error message displayed below the input (optional) * `:required` - Whether the field is required (optional, defaults to false) * `:disabled` - Whether the field is disabled (optional, defaults to false) * `:readonly` - Whether the field is read only (optional, defaults to false) * `:autofocus` - Whether the field should autofocus (optional, defaults to false) * `:phx_change` - Phoenix change event name (optional) * `:phx_blur` - Phoenix blur event name (optional) * `:phx_focus` - Phoenix focus event name (optional) * `:phx_debounce` - Phoenix debounce setting (optional) * `:class` - Additional CSS classes for the input element (optional) * `:container_class` - CSS classes for the container div (optional) """ def text_input(assigns) do TextInput.basic(assigns) end @doc """ Renders a text input with an icon on the left. ## Examples <.text_input_with_icon id="search" placeholder="Search..." icon={~H""} /> ## Options * `:id` - The ID for the input element (required) * `:name` - The name attribute (optional, defaults to ID) * `:label` - Label text (optional) * `:type` - Input type (optional, defaults to "text") * `:value` - Current input value (optional) * `:placeholder` - Placeholder text (optional) * `:icon` - SVG or HTML for the icon (required) * `:hint` - Help text displayed below the input (optional) * `:error` - Error message displayed below the input (optional) * `:required` - Whether the field is required (optional, defaults to false) * `:disabled` - Whether the field is disabled (optional, defaults to false) * `:readonly` - Whether the field is read only (optional, defaults to false) * `:autofocus` - Whether the field should autofocus (optional, defaults to false) * `:phx_change` - Phoenix change event name (optional) * `:phx_blur` - Phoenix blur event name (optional) * `:phx_focus` - Phoenix focus event name (optional) * `:phx_debounce` - Phoenix debounce setting (optional) * `:class` - Additional CSS classes for the input element (optional) * `:container_class` - CSS classes for the container div (optional) """ def text_input_with_icon(assigns) do TextInput.with_icon(assigns) end @doc """ Renders a textarea component for multiline text input. ## Examples <.textarea id="description" label="Description" rows={6} placeholder="Enter a detailed description..." hint="Markdown formatting is supported" /> ## Options * `:id` - The ID for the textarea element (required) * `:name` - The name attribute (optional, defaults to ID) * `:label` - Label text (optional) * `:value` - Current textarea value (optional) * `:placeholder` - Placeholder text (optional) * `:rows` - Number of visible rows (optional, defaults to 4) * `:hint` - Help text displayed below the textarea (optional) * `:error` - Error message displayed below the textarea (optional) * `:required` - Whether the field is required (optional, defaults to false) * `:disabled` - Whether the field is disabled (optional, defaults to false) * `:readonly` - Whether the field is read only (optional, defaults to false) * `:autofocus` - Whether the field should autofocus (optional, defaults to false) * `:phx_change` - Phoenix change event name (optional) * `:phx_blur` - Phoenix blur event name (optional) * `:phx_debounce` - Phoenix debounce setting (optional) * `:class` - Additional CSS classes for the textarea element (optional) * `:container_class` - CSS classes for the container div (optional) """ def textarea(assigns) do TextInput.textarea(assigns) end end