Packages
phoenix_duskmoon
9.14.0
9.14.0
9.13.1
9.13.0
9.12.3
9.12.2
9.12.1
9.12.0
9.11.0
9.10.1
9.10.0
9.9.10
9.9.9
9.9.8
9.9.7
9.9.6
9.9.4
9.9.3
9.9.2
9.9.1
9.9.0
9.8.0
9.7.1
9.7.0
9.6.4
9.6.3
9.6.2
9.6.1
9.6.0
9.5.4
9.5.3
9.5.2
9.5.1
9.5.0
9.4.3
9.4.2
9.4.1
9.4.0
9.3.0
9.2.0
9.1.4
9.1.3
9.1.1
9.1.1-rc.1
retired
9.0.1
9.0.0-rc.3
9.0.0-rc.2
9.0.0-rc.1
8.0.0
7.2.1
7.2.0
7.1.3
7.1.2
7.1.1
6.3.2
6.3.1
6.3.0
6.2.0
6.1.3
6.1.2
6.1.1
6.1.0
6.0.10
6.0.9
6.0.8
6.0.7
6.0.6
6.0.5
6.0.4
6.0.3
6.0.2
6.0.1
6.0.0
5.2.0-beta.5
5.2.0-beta.4
5.2.0-beta.3
5.2.0-beta.2
5.2.0-beta.1
5.1.0
5.0.6
5.0.5
5.0.4
5.0.3
5.0.2
5.0.1
5.0.0
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.4
4.4.3
4.4.2
4.4.1
4.4.0
4.3.2
4.3.1
4.3.0
4.2.0
4.1.1
4.1.0
4.0.0
Duskmoon UI component library for Phoenix LiveView
Current section
Files
Jump to
Current section
Files
phoenix_duskmoon
README.md
README.md
# PhoenixDuskmoon
[](https://github.com/duskmoon-dev/phoenix-duskmoon-ui/actions/workflows/ci.yml)
[](https://github.com/duskmoon-dev/phoenix-duskmoon-ui/actions/workflows/release.yml)
[](https://hex.pm/packages/phoenix_duskmoon)
[](https://hexdocs.pm/phoenix_duskmoon/)
[](https://www.npmjs.com/package/phoenix_duskmoon)
Duskmoon UI component library for Phoenix LiveView applications.
**v9**: Uses `@duskmoon-dev/core` CSS design system, HTML Custom Elements (`@duskmoon-dev/elements`), and Art Custom Elements (`@duskmoon-dev/art-elements`).
Requires `tailwindcss >= 4.0`
See the [docs](https://hexdocs.pm/phoenix_duskmoon/) for more information.
## Install
Add to `mix.exs`:
```elixir
{:phoenix_duskmoon, "~> 9.0"},
```
Install frontend packages:
```bash
bun add @duskmoon-dev/core @duskmoon-dev/elements
```
Optionally, add CSS Art and Art Custom Elements support:
```bash
bun add @duskmoon-dev/css-art @duskmoon-dev/art-elements
```
### View Helpers
Add to your Phoenix view helpers (e.g. `lib/my_app_web.ex`):
```elixir
defp html_helpers do
quote do
# Standard UI components (buttons, cards, forms, navigation, etc.)
use PhoenixDuskmoon.Component
# CSS Art decorative components (snow, plasma ball, eclipse, etc.)
use PhoenixDuskmoon.ArtComponent
end
end
```
### CSS Setup
In your CSS entry file (e.g. `assets/css/app.css`):
```css
@import "tailwindcss";
@plugin "@duskmoon-dev/core/plugin";
@import "phoenix_duskmoon/components";
```
### JavaScript Setup
Register the custom elements in `assets/js/app.js`:
```javascript
import "@duskmoon-dev/elements/register";
// Optionally, register art custom elements
import "@duskmoon-dev/art-elements/register";
```
### Hooks Setup
Some components require LiveView hooks. Add them when creating 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
})
```
Components that require hooks:
- `<.dm_theme_switcher>` — theme switching with localStorage
- `<.dmf_spotlight>` — keyboard shortcut handling (Cmd/Ctrl+K)
- `<.dm_page_header>` — scroll-based intersection observer
## Usage
### Buttons
```heex
<.dm_btn variant="primary">Click me</.dm_btn>
<.dm_btn variant="secondary" loading={@loading}>Loading</.dm_btn>
<.dm_btn variant="error" shape="circle">×</.dm_btn>
<.dm_btn native_submit variant="primary">Submit without JavaScript</.dm_btn>
```
### Cards
```heex
<.dm_card class="p-6">
<:title><h3>Title</h3></:title>
<p>Content here</p>
<:footer><.dm_btn>Action</.dm_btn></:footer>
</.dm_card>
```
### Icons
```heex
<.dm_mdi name="home" />
<.dm_bsi name="house" />
```
### Forms
```heex
<.dm_form for={@form} phx-submit="save">
<.dmf_input field={@form[:email]} label="Email" />
<.dm_btn variant="primary" type="submit">Save</.dm_btn>
</.dm_form>
```
### Common Attributes
| Attribute | Values |
|-----------|--------|
| `variant` | `primary`, `secondary`, `accent`, `info`, `success`, `warning`, `error`, `ghost`, `link`, `outline` |
| `size` | `xs`, `sm`, `md`, `lg` |
| `shape` | `square`, `circle` |
| `loading` | boolean |
| `disabled`| boolean |
| `native_submit` | boolean; render a native no-JavaScript submit control |
| `class` | additional CSS classes |
## Available Components
- **Action**: buttons, dropdowns, floating actions, links, menus, swaps, toggles
- **Data Display**: accordion, avatar, badge, card, carousel, chat, chat scroll, chip, collapse, countdown, datetime, diff, keyboard keys, flash, git repository, list, markdown, markdown body, pagination, popover, progress, radial progress, skeleton, stat, table, timeline, tooltip
- **Data Entry**: autocomplete, cascader, checkbox, compact input, file upload, filter group, form, input, multi-select, OTP input, PIN input, radio, rating, segment control, select, slider, switch, textarea, time input, tree select
- **Feedback**: dialog, loading, snackbar, toast
- **Navigation**: actionbar, appbar, bottom nav, breadcrumb, left menu, megamenu, navbar, nested menu, page footer, page header, stepper, steps, tabs
- **Layout**: bottom sheet, divider, drawer, hero, indicator, join, mask, sidebar layout, stack, theme switcher
- **CSS Art**: button noise, eclipse, plasma ball, signature, snow, spotlight search
## Upstream design alignment
The current frontend uses Core/CSS Art 1.19.9 and Elements/Art Elements 1.7.6.
Individually published element dependencies are pinned to their current versions;
see the [contract audit](apps/phoenix_duskmoon/guides/upstream-design-alignment.md) for the exact set.
The new Core primitives render native HTML and use the packaged CSS. Applications
own countdown timing, filter state, progress values and layout state. Carousel uses
native scrolling, swap uses a checkbox, floating actions and megamenu
use the browser Popover API. No element registration is needed for these primitives.
```heex
<.dm_indicator>
<:indicator><span class="badge badge-primary">3</span></:indicator>
<button type="button" class="btn">Inbox</button>
</.dm_indicator>
<.dm_sidebar_layout>
<:sidebar><nav aria-label="Workspace">Workspace links</nav></:sidebar>
<main>Page content</main>
</.dm_sidebar_layout>
```
Existing `dm_menu`, `dm_drawer` and `dm_bottom_sheet` retain their Elements methods
and events. `dm_loading_spinner` now follows Core's reduced-motion behavior, and
`dm_stat` uses its semantic stat layout. Chat scroll and chip event examples are
available in Storybook. Browser `File` objects from chat events require the
application's upload mechanism; they cannot be sent as LiveView JSON payloads.
## Live Storybook
[Live Storybook](https://duskmoon-storybook.gsmlg.dev)



