Skip to main content

README.md

![PtahUI](ptahui_logo.svg)

> A Phoenix LiveView component library — ready to use, no reinventing the wheel.

---

## What is it?

**PtahUI** is a component library for [Phoenix LiveView](https://hexdocs.pm/phoenix_live_view) built with [Tailwind CSS](https://tailwindcss.com) and [Heroicons](https://heroicons.com).

The name comes from **Ptah**, the Egyptian god of craftsmen, architects, and creation — a reference to the act of building interfaces by hand.

The library provides 30+ ready-to-use, composable components, highly configurable via attributes, eliminating the need to write repetitive HTML and CSS across every Phoenix project.

---

## Why was it built?

In Phoenix LiveView projects, we always end up writing the same buttons, modals, tables, and forms over and over. Each one slightly different, but never different enough to justify the repetition.

**PtahUI** was born from this frustration: a solid base of reusable components that:

- **Don't hardcode colours** — all components expose class attributes so colours adapt to each project's design.
- **Work natively with LiveView** — no extra JavaScript, no artificial wrappers.
- **Are composable** — slots, global attributes, and variants cover real-world use cases without needing to fork the component.
- **Save time** — one `use PtahUi` in `my_app_web.ex` and all components are available.

---

## Prerequisites

`ptah_ui` uses [Heroicons](https://heroicons.com) via CSS classes generated by Tailwind (e.g. `hero-arrow-right`). In a Phoenix project generated with `mix phx.new` this is already configured by default. If not, add to your project's `mix.exs`:

```elixir
{:heroicons,
 github: "tailwindlabs/heroicons",
 tag: "v2.1.1",
 sparse: "optimized",
 app: false,
 compile: false,
 depth: 1}
```

## Installation

Add to `mix.exs`:

```elixir
def deps do
  [
    {:ptah_ui, "~> 0.1"}
  ]
end
```

In your `my_app_web.ex`, inside `html_helpers/0`:

```elixir
defp html_helpers do
  quote do
    use PtahUi
    # ...
  end
end
```

---

## Available components

| Component | Description |
|---|---|
| `alert/1` | Info, success, warning and error alerts |
| `avatar/1` | Avatar with image or generated initials |
| `banner/1` | Highlight banners for the top of a page |
| `button/1` | General-purpose button with `primary`, `secondary`, `danger`, `ghost` variants |
| `navigate_button/1` | Pill-shaped navigation button with icon |
| `action_button/1` | Wide CTA button with title, subtitle and icon |
| `backoffice_button/1` | Compact button for admin/backoffice UIs |
| `primary_button/1` | Primary action button with icon |
| `secondary_button/1` | Secondary button with configurable icon position |
| `card/1` · `badge/1` | Card with header/footer slots and status badge |
| `calendar/1` | Interactive date picker |
| `carousel/1` | Content carousel |
| `checkbox/1` | Styled checkbox |
| `countdown/1` | Real-time countdown timer |
| `divider/1` | Horizontal/vertical separator |
| `dock/1` | macOS-style navigation dock |
| `dropdown/1` | Dropdown menu with selectable items |
| `fab/1` | Floating Action Button |
| `filter/1` | Filter component for lists |
| `a/1` | Flexible link (navigate/patch/href) |
| `input/1` · `select/1` | Form fields with label and error display |
| `hover_gallery/1` | Image gallery with hover effect |
| `icon/1` | Heroicons with configurable size and colour |
| `image_uploader/1` · `cv_upload/1` | Image and file upload |
| `indicator/1` | Status dot (online, offline, etc.) |
| `info_display/1` | Key-value data display row |
| `label/1` | Coloured tag/label |
| `loading/1` · `skeleton/1` | Loading states and content placeholders |
| `modal/1` | Modal with animation and focus management |
| `pagination/1` | Table and list pagination |
| `progress/1` | Progress bar |
| `rating/1` | Star rating |
| `steps/1` | Step indicator / wizard progress |
| `swap/1` | Visual toggle between two states |
| `table/1` | Table with configurable columns and row actions |
| `table_search/1` | Real-time search for tables |
| `tabs/1` | Tab navigation |
| `text_rotate/1` | Text with rotation animation |
| `timeline/1` | Vertical/horizontal timeline |
| `toggle/1` | Styled on/off switch |
| `tooltip/1` | Tooltip with configurable positioning |

---

## Usage example

```heex
<.button variant="primary" loading={@saving} phx-click="save">
  Save
</.button>

<.card>
  <:header>
    <h2 class="font-semibold text-gray-900">Title</h2>
  </:header>
  Card content.
  <:footer>
    <.button size="sm">Confirm</.button>
  </:footer>
</.card>

<.modal id="confirm-modal">
  <p>Are you sure?</p>
</.modal>
```

---

## Development

The repository includes a demo application (`ptah_ui_demo`) that showcases all components in a real context:

```bash
cd ptah_ui_demo
mix deps.get
mix phx.server
```

Open [http://localhost:4000](http://localhost:4000) to browse the component storybook.

---

## License

MIT — free to use, modify and distribute.