PrimerLive is based on GitHub Primer Design System.
Most components support:
classclasses
Example:
<.box class="my-class">
Adds classes to the root component element.
<.box class="border rounded">
Allows styling internal component parts.
<.box classes={%{
box: "my-box",
header: "my-header",
row: "my-row"
}}>
Common keys:
boxheaderrowcontenttoggle
Prefer Primer variables instead of hardcoded colors.
background: white;
color: #333;background: var(--bgColor-default);
color: var(--fgColor-muted);Benefits:
- dark mode support
- accessibility
- theme compatibility
| Class | Size |
|---|---|
pl-border-thin |
1px |
pl-border-thick |
2px |
pl-border-thicker |
4px |
Example:
<.box class="pl-border-thick">
| Class | Size |
|---|---|
pl-gap-0 |
0 |
pl-gap-1 |
4px |
pl-gap-2 |
8px |
pl-gap-3 |
16px |
pl-gap-4 |
24px |
pl-gap-5 |
32px |
Example:
<div class="d-flex pl-gap-3">
| Class | Description |
|---|---|
pl-aligned-start |
align start |
pl-aligned-end |
align end |
pl-offset-x-2= 8px horizontal offset.
Example:
class="pl-offset-x-2 pl-aligned-end"| Class | Description |
|---|---|
pl-text-underline-hover |
underline on hover |
pl-text-monospace |
monospace font |
Recommended for reusable styles.
def styled_box(assigns) do
~H"""
<.box classes={%{
box: "pl-border-thick",
header: "bgColor-default",
row: "bgColor-muted"
}} {assigns} />
"""
endUsage:
<.styled_box>
<:header>Title</:header>
<:row>Content</:row>
</.styled_box><html dir="rtl">PrimerLive supports RTL automatically.
Supports:
- light
- dark
- high contrast
| Component | Purpose |
|---|---|
dropdown |
simple menu |
action_menu |
action list |
select_menu |
select UI |
dialog |
modal |
drawer |
sidebar |
<.dropdown>
<:toggle>
Menu
</:toggle>
Content
</.dropdown><:toggle> is required.
<.dialog id="my-dialog">
<:header_title>
Title
</:header_title>
<:body>
Content
</:body>
</.dialog>
phx-click={open_dialog("my-dialog")}phx-click={close_dialog("my-dialog")}phx-click={toggle_dialog("my-dialog")}| Attr | Description |
|---|---|
is_backdrop |
backdrop enabled |
backdrop_strength |
backdrop intensity |
backdrop_tint |
dark/light |
transition_duration |
animation duration |
is_fast |
fast transitions |
is_dropdown_caret |
caret icon |
| Attr | Description |
|---|---|
id |
required for dialogs |
is_escapable |
ESC closes |
on_cancel |
JS action on close |
is_show |
visible state |
is_show_on_mount |
auto show |
show_state |
persistent state |
focus_after_opening_selector="#my-input"focus_after_closing_selector="#open-button"Prevent outside click close:
is_modal<.dialog
:if={@show_dialog}
is_show
>Useful for:
- mobile navigation
- app sidebars
- global menus
| State | Meaning |
|---|---|
"default" |
normal |
"onset" |
prepare persistence |
"hold" |
persist between navigation |
show_state =
case params["menu"] do
"1" -> "onset"
"2" -> "hold"
_ -> "default"
endon_cancel={JS.navigate(~p"/posts")}<.dialog
id="my-dialog"
status_callback_selector="#status_events"
>
Handler:
handle_event(
"primer_live:prompt",
%{"status" => status},
socket
)| Layer | z-index |
|---|---|
| backdrop | 98 |
| touch | 99 |
| menus | 100 |
| drawer | 200 |
| dialog | 300 |
Avoid repeating classes everywhere.
var(--bgColor-default)instead of hardcoded colors.
<.dialog id="settings-dialog">
Prevents flickering during navigation.
Avoid disabling is_escapable.
<.dropdown>
<:toggle>
Actions
</:toggle>
<:item>Item 1</:item>
</.dropdown><.dialog
id="confirm-dialog"
is_backdrop
is_modal
>
<:header_title>
Confirm
</:header_title>
<:body>
Are you sure?
</:body>
</.dialog>
<.drawer
id="sidebar"
is_backdrop
is_show={@show_sidebar}
>
Content
</.drawer>
<.button phx-click={open_dialog("confirm-dialog")}>
Open
</.button>