PUI Logo
Hex VersionHex DocsMIT

PUI

PUI is a Phoenix LiveView UI toolkit with styled components, headless usage paths, and bundled JavaScript hooks for interactive primitives.

Installation

Add pui to mix.exs:

defp deps do
[
{:pui, "~> 1.0.0-beta.9"}
]
end

Then fetch dependencies:

mix deps.get

Setup in Your Phoenix App

Import PUI CSS in your app stylesheet:

@import "tailwindcss" source(none);
@source "../css";
@source "../js";
@source "../../lib/your_app_web";
@source "../../deps/pui";
@import "../../deps/pui/assets/css/pui.css";

Register PUI hooks in your LiveSocket:

import { Socket } from "phoenix";
import { LiveSocket } from "phoenix_live_view";
import { Hooks as PUIHooks } from "pui";
const csrfToken = document
.querySelector("meta[name='csrf-token']")
.getAttribute("content");
const liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
hooks: { ...PUIHooks },
});
liveSocket.connect();

Use PUI in LiveView modules:

defmodule MyAppWeb.DemoLive do
use MyAppWeb, :live_view
use PUI
def render(assigns) do
~H"""
<div class="space-y-4">
<.button>Click me</.button>
<.input type="text" placeholder="Name" />
</div>
"""
end
end

Components Included by use PUI

Additional modules available directly:

Component Usage Levels

PUI supports three usage levels:

  1. Low-level hooks (direct control):
<.popover_base phx-hook="PUI.Popover" data-placement="bottom">
<.button>Trigger</.button>
<:popup class="custom-popup">Content</:popup>
</.popover_base>
  1. Unstyled variants (behavior, no default visuals):
<.menu_button variant="unstyled" class="my-btn">
Open
<:item class="my-item">Profile</:item>
</.menu_button>
  1. Styled defaults (ready-to-use):
<.menu_button variant="secondary">
Open
<:item>Profile</:item>
</.menu_button>

Guides

Development Commands

Build and setup:

Testing and quality: