Skip to content

Instantly share code, notes, and snippets.

@pvrt
Created May 23, 2026 10:15
Show Gist options
  • Select an option

  • Save pvrt/b4f7eadca1fbe3e852a7adcf8ed09956 to your computer and use it in GitHub Desktop.

Select an option

Save pvrt/b4f7eadca1fbe3e852a7adcf8ed09956 to your computer and use it in GitHub Desktop.
PrimerLive Cheatsheet

PrimerLive Cheatsheet

Documentation


1. Styling Cheatsheet

Base Concept

PrimerLive is based on GitHub Primer Design System.

Most components support:

  • class
  • classes

Example:

<.box class="my-class">

class vs classes

class

Adds classes to the root component element.

<.box class="border rounded">

classes

Allows styling internal component parts.

<.box classes={%{
  box: "my-box",
  header: "my-header",
  row: "my-row"
}}>

Common keys:

  • box
  • header
  • row
  • content
  • toggle

Primer CSS Variables

Prefer Primer variables instead of hardcoded colors.

Bad

background: white;
color: #333;

Good

background: var(--bgColor-default);
color: var(--fgColor-muted);

Benefits:

  • dark mode support
  • accessibility
  • theme compatibility

Utility Classes

Borders

Class Size
pl-border-thin 1px
pl-border-thick 2px
pl-border-thicker 4px

Example:

<.box class="pl-border-thick">

Gap Utilities

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">

Alignment

Class Description
pl-aligned-start align start
pl-aligned-end align end

Offset

pl-offset-x-2

= 8px horizontal offset.

Example:

class="pl-offset-x-2 pl-aligned-end"

Text Utilities

Class Description
pl-text-underline-hover underline on hover
pl-text-monospace monospace font

Wrapper Components

Recommended for reusable styles.

def styled_box(assigns) do
  ~H"""
  <.box classes={%{
    box: "pl-border-thick",
    header: "bgColor-default",
    row: "bgColor-muted"
  }} {assigns} />
  """
end

Usage:

<.styled_box>
  <:header>Title</:header>
  <:row>Content</:row>
</.styled_box>

RTL Support

<html dir="rtl">

PrimerLive supports RTL automatically.


Theme Support

Supports:

  • light
  • dark
  • high contrast

2. Menus & Dialogs Cheatsheet

Components

Component Purpose
dropdown simple menu
action_menu action list
select_menu select UI
dialog modal
drawer sidebar

Basic Dropdown

<.dropdown>
  <:toggle>
    Menu
  </:toggle>

  Content
</.dropdown>

<:toggle> is required.


Basic Dialog

<.dialog id="my-dialog">
  <:header_title>
    Title
  </:header_title>

  <:body>
    Content
  </:body>
</.dialog>

Open / Close Dialog

Open

phx-click={open_dialog("my-dialog")}

Close

phx-click={close_dialog("my-dialog")}

Toggle

phx-click={toggle_dialog("my-dialog")}

Appearance Attributes

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

Behavior Attributes

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 Management

Focus after open

focus_after_opening_selector="#my-input"

Focus after close

focus_after_closing_selector="#open-button"

Modal Behavior

Prevent outside click close:

is_modal

Conditional Rendering

<.dialog
  :if={@show_dialog}
  is_show
>

Persistent Drawers

Useful for:

  • mobile navigation
  • app sidebars
  • global menus

show_state

State Meaning
"default" normal
"onset" prepare persistence
"hold" persist between navigation

Example

show_state =
  case params["menu"] do
    "1" -> "onset"
    "2" -> "hold"
    _ -> "default"
  end

on_cancel Navigation

on_cancel={JS.navigate(~p"/posts")}

Status Callback

<.dialog
  id="my-dialog"
  status_callback_selector="#status_events"
>

Handler:

handle_event(
  "primer_live:prompt",
  %{"status" => status},
  socket
)

z-index Layers

Layer z-index
backdrop 98
touch 99
menus 100
drawer 200
dialog 300

Best Practices

Use wrapper components

Avoid repeating classes everywhere.


Use Primer CSS variables

var(--bgColor-default)

instead of hardcoded colors.


Always set dialog IDs

<.dialog id="settings-dialog">

Use show_state for global drawers

Prevents flickering during navigation.


Keep ESC enabled

Avoid disabling is_escapable.


Quick Snippets

Dropdown

<.dropdown>
  <:toggle>
    Actions
  </:toggle>

  <:item>Item 1</:item>
</.dropdown>

Modal Dialog

<.dialog
  id="confirm-dialog"
  is_backdrop
  is_modal
>
  <:header_title>
    Confirm
  </:header_title>

  <:body>
    Are you sure?
  </:body>
</.dialog>

Drawer

<.drawer
  id="sidebar"
  is_backdrop
  is_show={@show_sidebar}
>
  Content
</.drawer>

Open Button

<.button phx-click={open_dialog("confirm-dialog")}>
  Open
</.button>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment