guides/getting-started.md

# Getting Started

This guide walks through adding Phoenix Duskmoon UI to a Phoenix LiveView project.

## Prerequisites

- Elixir ~> 1.15
- Phoenix ~> 1.8.1
- Phoenix LiveView ~> 1.1.0
- TailwindCSS >= 4.0
- [Bun](https://bun.sh) (for frontend package management)

## Installation

### 1. Add the Hex dependency

```elixir
# mix.exs
defp deps do
  [
    {:phoenix_duskmoon, "~> 9.0"}
  ]
end
```

```bash
mix deps.get
```

### 2. Install frontend packages

```bash
bun add @duskmoon-dev/core @duskmoon-dev/elements
```

`@duskmoon-dev/core` provides the CSS design system (theme variables, component
classes, design tokens). `@duskmoon-dev/elements` is a meta-package that installs
all `el-dm-*` custom element packages.

### 3. Import components in your view helpers

In your `lib/my_app_web.ex`, add the component imports to `html_helpers/0`:

```elixir
defp html_helpers do
  quote do
    # Import all Duskmoon UI components (dm_btn, dm_card, dm_input, etc.)
    use PhoenixDuskmoon.Component

    # Import CSS art components (dm_art_snow, dm_art_plasma_ball, etc.)
    use PhoenixDuskmoon.ArtComponent

    # ... your other imports
  end
end
```

### 4. Configure CSS

In your `assets/css/app.css`:

```css
@source "../js/**/*.js";
@source "../../lib/**/*.exs";
@source "../../lib/**/*.ex";

@import "tailwindcss";
@plugin "@duskmoon-dev/core/plugin";
```

The `@plugin` directive registers the Duskmoon design system with Tailwind v4,
providing all theme variables, component classes, and design tokens.

### 5. Register custom elements

In your `assets/js/app.js`, import the element packages you use:

```javascript
// Register individual elements
import "@duskmoon-dev/el-button/register";
import "@duskmoon-dev/el-card/register";
import "@duskmoon-dev/el-input/register";
// ... add more as needed

// Or register all elements at once
import "@duskmoon-dev/elements/register";
```

Each custom element must be explicitly registered for its tag to be defined in
the browser. Without registration, content inside the element's `<template>` is
inert and invisible.

### 6. Set up LiveView hooks

Some components require JavaScript hooks for client-side interactions. Import and
register them with your LiveSocket:

```javascript
import { LiveSocket } from "phoenix_live_view";
import * as DuskmoonHooks from "phoenix_duskmoon/hooks";

let liveSocket = new LiveSocket("/live", Socket, {
  params: { _csrf_token: csrfToken },
  hooks: DuskmoonHooks,
});
```

To merge with your own hooks:

```javascript
import * as DuskmoonHooks from "phoenix_duskmoon/hooks";
import MyHooks from "./my_hooks";

let hooks = { ...DuskmoonHooks, ...MyHooks };

let liveSocket = new LiveSocket("/live", Socket, {
  params: { _csrf_token: csrfToken },
  hooks: hooks,
});
```

See the [Hooks](hooks.md) guide for details on each hook.

## Usage

All components use the `dm_` prefix:

```heex
<%!-- Buttons --%>
<.dm_btn variant="primary">Save</.dm_btn>
<.dm_btn variant="error" shape="circle">×</.dm_btn>

<%!-- Cards with slots --%>
<.dm_card>
  <:title>Card Title</:title>
  Content goes here
  <:footer><.dm_btn variant="primary">Action</.dm_btn></:footer>
</.dm_card>

<%!-- Icons --%>
<.dm_mdi name="home" />
<.dm_bsi name="house" />

<%!-- Forms with field binding --%>
<.dm_form for={@form} phx-submit="save">
  <.dm_input field={@form[:name]} label="Name" />
  <.dm_select field={@form[:role]} label="Role" options={[{"admin", "Admin"}, {"user", "User"}]} />
  <.dm_btn variant="primary" type="submit">Save</.dm_btn>
</.dm_form>
```

### Common attributes

| Attribute | Values | Description |
|-----------|--------|-------------|
| `variant` | `primary`, `secondary`, `accent`, `info`, `success`, `warning`, `error`, `ghost`, `link`, `outline` | Color variant |
| `size` | `xs`, `sm`, `md`, `lg` | Size variant |
| `shape` | `square`, `circle` | Shape variant |
| `loading` | boolean | Shows loading spinner |
| `disabled` | boolean | Disables interaction |
| `class` | string or list | Additional CSS classes |

### Form field binding

Data entry components support direct `Phoenix.HTML.FormField` binding via the
`field` attribute, which automatically sets `name`, `id`, `value`, and error state:

```heex
<.dm_input field={@form[:email]} label="Email" type="email" />
<.dm_checkbox field={@form[:terms]} label="I agree to the terms" />
<.dm_switch field={@form[:notifications]} label="Enable notifications" />
```