PrimerLive.Component (PrimerLive v0.9.0)

PrimerLive component documentation.

Summary

Alerts

Flash alert informs users of successful or pending actions.

Wrapper to render a vertical stack of alert/1 messages with spacing in between.

Avatars

User profile image.

Generates a larger "parent" avatar with a smaller "child" overlaid on top.

Generates a badge-like icon or logo.

Deprecated: use avatar_pair/1. Since 0.5.1.

Blankslate

Blankslate is used as placeholder to tell users why content is missing.

Box

A box is a simple container with rounded corners, a white background, and a light gray border. It can be used to display a single item or a list of items, with an optional header and footer.

Branch name

Branch name is a label-type component rendered as a link that displays the name of a branch.

Breadcrumbs

Breadcrumb navigation to navigate a hierarchy of pages.

Buttons

Generates a button.

Generates a group of buttons.

Dialog

Dialog is a floating surface used to display transient content such as confirmation actions, selection options, and more.

Dialog functions

Cancels a dialog: closes the dialog after executing the on_cancel attribute.

Cancels a dialog as part of a Phoenix.LiveView.JS command chain.

Closes a dialog. Note that this won't call on_cancel. Any time on_cancel is provided and you still need a close button, cancel_dialog/1 will be a better choice.

Closes a dialog as part of a Phoenix.LiveView.JS command chain.

Opens a dialog.

Opens a dialog as part of a Phoenix.LiveView.JS command chain.

Toggles the open state of the dialog.

Toggles a dialog as part of a Phoenix.LiveView.JS command chain.

Drawer

Generates a drawer with configuration options for backdrop, position and behavior.

Drawer content. Deprecated: use :body slot with drawer/1. Since 0.4.0.

Drawer functions

Cancels a drawer: closes the drawer after executing the on_cancel attribute.

Cancels a drawer as part of a Phoenix.LiveView.JS command chain.

Closes a drawer. Note that this won't call on_cancel. Any time on_cancel is provided and you still need a close button, cancel_drawer/1 will be a better choice.

Closes a drawer as part of a Phoenix.LiveView.JS command chain.

Opens a drawer.

Opens a drawer as part of a Phoenix.LiveView.JS command chain.

Toggles the open state of the drawer.

Toggles a drawer as part of a Phoenix.LiveView.JS command chain.

Styled HTML

Adds styling to HTML. This can be used to format HTML generated by a Markdown library, or to create consistent layout of HTML content.

Forms

Generates a checkbox.

Checkbox group renders a set of checkboxes and wraps it in a fieldset. The label attribute generates a legend element.

Convenience checkbox component for use inside checkbox_group/1.

Deprecated: use a form input component with attr: is_form_control. Since 0.9.0.

Generates a validation message for a form input. It can be used as standalone component for inputs where the position of the validation feedback is not so obvious.

Generates a radio button.

Radio group renders a set of radio buttons and wraps it in a fieldset. The label attribute generates a legend element.

Groups radio buttons in a tab-like row. Note that this component is not updated for RTL-display.

Generates a single or multiple select input.

Generates a text input field.

Generates a textarea.

Toggle switch is used to immediately toggle a setting on or off.

Header

Generates a navigational header, to be placed at the top of the page.

Icons

Renders an icon from the set of GitHub icons, 643 including all size variations.

Labels

Adds a count label to navigational elements and buttons.

Issue labels are used for adding labels to issues and pull requests. They also come with emoji support.

Generates a label element to add metadata or indicate status of items and navigational elements.

Shows an item's status.

Layout

Layout provides foundational patterns for responsive pages.

Loaders

Adds animated ellipsis to indicate progress.

Indicator to show that content is being loaded.

Menus

Action list is a vertical list of interactive actions or options. It's composed of items presented in a consistent, single-column format, with room for icons, descriptions, side information, and other rich visuals.

Action list item. See action_list/1.

Action list section divider for separating groups of content. See action_list/1.

Action menu is composed of action list and overlay patterns used for quick actions and selections.

Generates a dropdown menu - a small context menu that can be used for navigation and actions. It is a simple alternative to select menus.

Generates a select menu.

Menu functions

Cancels a menu: closes the menu after executing the on_cancel attribute.

Cancels a menu as part of a Phoenix.LiveView.JS command chain.

Closes a menu. Note that this won't call on_cancel. Any time on_cancel is provided and you still need a close button, cancel_menu/1 will be a better choice.

Closes a menu as part of a Phoenix.LiveView.JS command chain.

Opens a menu.

Opens a menu as part of a Phoenix.LiveView.JS command chain.

Toggles the open state of the menu.

Toggles a menu as part of a Phoenix.LiveView.JS command chain.

Navigation

Generates a vertical list of filters.

Generates a vertical list of navigational links.

Generates a vertical list of navigational links.

Use the sub nav component for navigation on a dashboard-type interface with another set of navigation components above it.

Subnav link row. See subnav/1.

Subnav search field. See subnav/1.

Subnav search filter adjacent to the search field. See subnav/1.

Tab nav contains a set of links that let users navigate between different views in the same context.

Generates a tab navigation with minimal underlined selected state, typically used for navigation placed at the top of the page.

Pagination

Pagination is a horizontal set of links to navigate paginated content.

Progress

Generates a progress bar to visualise task completion.

Subhead

Configurable and styled h2 heading.

Theme

Creates a wrapper that sets the light/dark color mode and theme, with support for color blindness.

Generates theme menu options as an action_list/1, to be used inside an action_menu/1.

Timeline

Generates a timeline item to display items on a vertical timeline.

Truncate

Shortens text with ellipsis.

Alerts

Flash alert informs users of successful or pending actions.

<.alert>
  Flash message goes here.
</.alert>

Examples

Add color to the alert by using attribute state. Possible states:

  • "default" - light blue
  • "info" - same as default
  • "success" - light green
  • "warning" - light yellow
  • "error" - pink

Add a success color to the alert:

<.alert state="success">
  You're done!
</.alert>

Multiline message:

<.alert state="success">
  <p>You're done!</p>
  <p>You may close this message</p>
</.alert>

To add an extra bottom margin to a stack of alerts, wrap the alerts in alert_messages/1.

Attributes

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for the alert element and alert states.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      alert: "",         # Outer container
      state_default: "", # Alert color modifier
      state_info: "",    # Alert color modifier
      state_success: "", # Alert color modifier
      state_warning: "", # Alert color modifier
      state_error: "",   # Alert color modifier
    }

    Defaults to %{alert: nil, state_default: nil, state_info: nil, state_success: nil, state_warning: nil, state_error: nil}.

  • state (:string) - Color mapping:

    • "default" - light blue
    • "info" - same as default
    • "success" - light green
    • "warning" - light yellow
    • "error" - pink Must be one of "default", "info", "success", "warning", or "error".
  • is_full_width (:boolean) - Renders the alert full width, with border and border radius removed. Defaults to false.

  • is_full (:boolean) - Deprecated: use is_full_width.

  • Global attributes are accepted.

Slots

  • inner_block (required) - Alert content.

Reference

Primer Flash

Link to this function

alert_messages(assigns)

Wrapper to render a vertical stack of alert/1 messages with spacing in between.

<.alert_messages>
  <.alert is_success>
    Message 1
  </.alert>
  <.alert class="mt-4">
    Message 2
  </.alert>
</.alert_messages>
Rest of content

Attributes

  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required) - Alert messages content.

Reference

Primer Alert

Avatars

Link to this function

avatar(assigns)

User profile image.

A simple wrapper function that returns an img element, styled square and rounded. For correct rendering, the input image must be square.

<.avatar src="user.jpg" />

Examples

Set the size (possible values: 1 - 8):

<.avatar size="1" src="user.jpg" />

Or set the size using regular img tags:

<.avatar src="user.jpg" width="20" height="20" />

Attributes

  • src (:string) - Image source attribute. Defaults to nil.

  • width (:string) - Image width attribute. Defaults to nil.

  • height (:string) - Image height attribute. Defaults to nil.

  • alt (:string) - Image alt attribute. Defaults to nil.

  • is_round (:boolean) - Creates a round avatar. Defaults to false.

  • size (:any) - Avatar size (number or number as string).

    Values translate to sizes:

    • 1: 16px
    • 2: 20px
    • 3: 24px (default)
    • 4: 28px
    • 5: 32px
    • 6: 40px
    • 7: 48px
    • 8: 64px

    Defaults to 3.

  • class (:any) - Additional classname. Defaults to nil.

  • Global attributes are accepted.

Reference

Primer Avatar

Link to this function

avatar_pair(assigns)

Generates a larger "parent" avatar with a smaller "child" overlaid on top.

Examples

Use slots parent and child to create the avatars using avatar/1 attributes:

<.avatar_pair>
  <:parent src="emma.jpg" size="7" />
  <:child src="kim.jpg" size="2" />
</.avatar_pair>

Attributes

  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • parent - Generates a parent avatar. Accepts attributes:
    • size (:any) - Avatar image size - see avatar/1.
    • src (:any) - Avatar image source - see avatar/1.
    • is_round (:any) - Rounded avatar - see avatar/1.
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • child - Generates a child avatar. Accepts attributes:
    • size (:any) - Avatar size - see avatar/1.
    • src (:any) - Avatar image source - see avatar/1.
    • is_round (:any) - Rounded avatar - see avatar/1.
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)

Reference

Link to this function

circle_badge(assigns)

Generates a badge-like icon or logo.

<.circle_badge>
  <:octicon name="alert-16" />
</.circle_badge>

Examples

Use slot octicon to create an octicon/1 icon

<.circle_badge>
  <:octicon name="alert-16" />
</.circle_badge>

Use slot img to create an image icon

<.circle_badge>
  <:img src="https://github.com/travis-ci.png" />
</.circle_badge>

Create a large badge (size "medium" or "large"):

<.circle_badge size="medium">
  <:octicon name="alert-24" />
</.circle_badge>

Badges are by default rendered as div elements. To create link elements, pass attribute href, navigate or patch. Link examples:

<.circle_badge href="#url">...</.circle_badge>
<.circle_badge navigate={Routes.page_path(@socket, :index)}>...</.circle_badge>
<.circle_badge patch={Routes.page_path(@socket, :index, :details)}>...</.circle_badge>

Attributes

  • size (:string) - Badge size: "small", "medium" or "large".

    Sizes:

    • small: 56px (default)
    • medium: 96px
    • large: 128px

    Defaults to "small".

  • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other attributes to the link.

  • patch (:string) - Link attribute - see href.

  • navigate (:string) - Link attribute - see href.

  • class (:any) - Additional classname. Defaults to nil.

  • Global attributes are accepted.

Slots

  • octicon - Generates a badge icon with octicon/1. Accepts attributes:
    • name (:string) - Octicon name.
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • img - Generates a badge icon with an img tag. Accepts attributes:
    • src (:any) - Image source attribute.
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)

Reference

Primer Circle badge

Link to this function

parent_child_avatar(assigns)

Deprecated: use avatar_pair/1. Since 0.5.1.

Blankslate

Link to this function

blankslate(assigns)

Blankslate is used as placeholder to tell users why content is missing.

<.blankslate>
  <:heading>
    This is a blank slate
  </:heading>
  <p>Use it to provide information when no dynamic content exists.</p>
</.blankslate>

Blankslate is created with slots that are applied in this order:

  1. octicon or img
  2. heading
  3. inner_block
  4. action (multiple)

Examples

With an octicon/1:

<.blankslate>
  <:octicon name="rocket-24" />
  ...
</.blankslate>

With an image:

<.blankslate>
  <:img src="https://ghicons.github.com/assets/images/blue/png/Pull%20request.png" alt="" />
  ...
</.blankslate>

With an action:

<.blankslate>
  <:action>
    <.button is_primary>New project</.button>
  </:action>
  ...
</.blankslate>

Narrow layout:

<.blankslate is_narrow>
  ...
</.blankslate>

Large text:

<.blankslate is_large>
  ...
</.blankslate>

Combined slots, in a box/1:

<.box>
  <.blankslate>
    <:heading>
      This is a blank slate
    </:heading>
    <:img
      src="https://ghicons.github.com/assets/images/blue/png/Pull%20request.png"
      alt=""
    />
    <:action>
      <.button is_primary>New project</.button>
    </:action>
    <:action>
      <.button is_link>Learn more</.button>
    </:action>
    <p>Use it to provide information when no dynamic content exists.</p>
  </.blankslate>
</.box>

Attributes

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for blankslate elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      blankslate: "", # Blankslate wrapper
      octicon: ""     # Icon element
      img: "",        # Image element
      heading: "",    # Heading element
      action: "",     # Action element
    }

    Defaults to %{action: nil, blankslate: nil, heading: nil, octicon: nil, img: nil}.

  • is_narrow (:boolean) - Narrows the blankslate container to not occupy the entire available width. Defaults to false.

  • is_large (:boolean) - Increases the size of the text in the blankslate. Defaults to false.

  • is_spacious (:boolean) - Significantly increases the vertical padding. Defaults to false.

  • Global attributes are accepted.

Slots

  • heading - Heading. Accepts attributes:
    • tag (:string) - HTML tag used for the heading.

      Default: "h3".

    • class (:any) - Additional classname.

    • style (:string) - Additional CSS styles.

    • rest (:any)

  • octicon - Adds a top icon with octicon/1. Accepts attributes:
    • name (:string) - Octicon name.
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • img - Adds a top image with an img tag. Accepts attributes:
    • src (:string) - Image source attribute.
    • alt (:string) - Image alt attribute.
    • width (:string) - Image width attribute.
    • height (:string) - Image height attribute.
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • action - Adds a wrapper for a button or link. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • inner_block - Regular content.

Reference

Primer Blankslate

Box

A box is a simple container with rounded corners, a white background, and a light gray border. It can be used to display a single item or a list of items, with an optional header and footer.

Rows can be populated using streams.

Examples

Basic structure

<.box>
  Content
</.box>

A box containing a blankslate/1:

<.box>
  <.blankslate>
    <:heading>
      No Data Available
    </:heading>
    <p>
      Info
    </p>
  </.blankslate>
</.box>

A box containing a header, a list of rows and a footer:

<.box>
  <:header>Header</:header>
  <:row>Row</:row>
  <:row>Row</:row>
  <:row>Row</:row>
  <:footer>Footer</:footer>
</.box>

Streams

To generate rows using streams:

  • Pass an id.
  • Provide a single row slot for displaying the stream data, using :let to get the stream data.
  • When displaying multiple components with the same stream data, provide a unique id generation function for row_id attribute.
<.box stream={@streams.clients} id="clients">
  <:row :let={{_dom_id, data}}>
    <%= data.name %>
  </:row>
</.box>

Other attributes

Row themes:

<.box>
  <:row is_gray>Row</:row>
  <:row is_hover_gray>Row</:row>
  <:row is_yellow>Row</:row>
  <:row is_hover_blue>Row</:row>
  <:row is_blue>Row</:row>
</.box>

Box theme - "danger box":

<.box is_danger>
  <:row>Row</:row>
  <:row>Row</:row>
</.box>

Header theme - blue header:

<.box>
  <:header is_blue>Blue header</:header>
</.box>

Render a row for each search result:

<.box>
  <:row :for={result <- @results}>
    <%= result %>
  </:row>
</.box>

Conditionally show an alert:

 <.box>
  <.alert :if={@show_alert}>Alert message</.alert>
  <:body>
    Body
  </:body>
</.box>

Header title. Slot header can be omitted:

<.box>
  <:header_title>
    Title
  </:header_title>
  Content
</.box>

Header with a button, using both header and header_title slots. The title will be inserted as first header element:

<.box>
  <:header class="d-flex flex-items-center">
    <.button is_primary is_smmall>
      Button
    </.button>
  </:header>
  <:header_title class="flex-auto">
    Title
  </:header_title>
  <:body>
    Rest
  </:body>
</.box>

Header with icon button:

<.box>
  <:header class="d-flex flex-justify-between flex-items-start">
    <.button is_close_button aria-label="Close" class="flex-shrink-0 pl-4">
      <.octicon name="x-16" />
    </.button>
  </:header>
  <:header_title>
    A very long title that wraps onto multiple lines without overlapping
    or wrapping underneath the icon to it's right
  </:header_title>
  <:body>Content</:body>
</.box>

Links can be placed inside rows. Use :let to get access to the classes.link class. With Phoenix.Component.link/1:

<.box>
  <:row :let={%{classes: classes}}>
    <.link href="/" class={classes.link}>Home</.link>
  </:row>
</.box>

To make the entire row a link, pass attribute href, navigate or patch. Tweak the link behaviour with row attrs is_hover_gray, is_hover_blue and/or Primer CSS modifier class "no-underline". Link examples:

<:row href="#url">href link</:row>
<:row navigate={Routes.page_path(@socket, :index)}>navigate link</:row>
<:row patch={Routes.page_path(@socket, :index)}>patch link</:row>
<:row href="#url" class="no-underline" is_hover_gray>Link, no underline, hover gray</:row>

Box can be used inside dialogs. To make the box content scrollable within the confined space of the dialog, use is_scrollable. This will make all inner content (inner_block, body and rows) scrollable between header and footer.

To limit the height of the box, either:

  • Use class "Box--scrollable" to limit the height to 324px
  • Add style "max-height"
<.box is_scrollable class="Box--scrollable">
  <:header>Fixed header</:header>
  <:body>Scrollable body</:body>
  <:row>Scrollable row</:row>
  <:row>Scrollable row</:row>
  ...
  <:footer>Fixed footer</:footer>
</.box>
<.box is_scrollable style="max-height: 80vh">
  <:header>Fixed header</:header>
  <:body>Scrollable body</:body>
  <:row>Scrollable row</:row>
  <:row>Scrollable row</:row>
  ...
  <:footer>Fixed footer</:footer>
</.box>

Attributes

  • id (:string) - Component DOM id. Defaults to nil.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for layout elements.

    Any provided value will be appended to the default classname.

    Default map:

      %{
        box: "",          # Box element
        header: "",       # Box header row element
        row: "",          # Box content row element
        body: "",         # Content element
        footer: "",       # Footer row element
        header_title: "", # Title element within a header row
        link: "",         # Class for links
      }

    Defaults to %{link: nil, header: nil, body: nil, box: nil, row: nil, footer: nil, header_title: nil}.

  • is_blue (:boolean) - Generates a blue box theme. Defaults to false.

  • is_danger (:boolean) - Generates a danger color box theme. Only works with slots row and body. Use class "color-border-danger" for a lighter danger color. Defaults to false.

  • is_border_dashed (:boolean) - Applies a dashed border to the box. Defaults to false.

  • is_condensed (:boolean) - Condenses line-height and reduces the padding on the Y axis. Defaults to false.

  • is_spacious (:boolean) - Increases padding and increases the title font size. Defaults to false.

  • is_scrollable (:boolean) - Makes inner content (consistent of inner_block, body and rows) scrollable in a box with maximum height. Defaults to false.

  • stream (:list) - An enumerable of stream items to insert. Defaults to nil.

  • row_id (:any) - The function for generating the row id. Defaults to nil.

  • row_item (:any) - The function for mapping each row. Defaults to &Function.identity/1.

  • row_click (:any) - The function for handling phx-click on each row. Defaults to nil.

  • Global attributes are accepted.

Slots

  • header - Generates a header row element. Accepts attributes:
    • class (:any) - Additional classname.
    • is_blue (:boolean) - Change the header border and background to blue.
  • header_title - Generates a title within the header. If no header slot is passed, the header title will be wrapped inside a header element. Accepts attributes:
    • class (:any) - Additional classname.
  • row - Generates a content row element.
    • To create a link element, pass attribute href, navigate or patch.
    • To pass event data, use phx-click and phx-value-item.
    Accepts attributes:
    • is_blue (:boolean) - Blue row theme.

    • is_gray (:boolean) - Gray row theme.

    • is_yellow (:boolean) - Yellow row theme.

    • is_hover_blue (:boolean) - Changes to blue row theme on hover.

    • is_hover_gray (:boolean) - Changes to gray row theme on hover.

    • is_focus_blue (:boolean) - Changes to blue row theme on focus.

    • is_focus_gray (:boolean) - Changes to gray row theme on focus.

    • is_navigation_focus (:boolean) - Combine with a theme color to highlight the row when using keyboard commands.

    • is_unread (:boolean) - Apply a blue vertical line highlight for indicating a row contains unread items.

    • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other slot attributes to the link.

    • patch (:string) - Link attribute - see href.

    • navigate (:string) - Link attribute - see href.

    • phx-click (:string)

    • phx-target (:any)

    • phx-value-item (:any) - The payload parameter for the selected value to be sent with an event.

      Examples:

      <:row
        phx-click="select_row"
        phx-value-item={row_id}
      >     
        ...
      
      def handle_event(
        "select_row", %{"item" => row_id}, socket) do
        ...
    • class (:any) - Additional classname.

    • style (:string) - Additional CSS styles.

    • rest (:any)

  • body - Generates a body element. Accepts attributes:
    • class (:any) - Additional classname.
  • footer - Generates a footer row element. Accepts attributes:
    • class (:any) - Additional classname.
  • inner_block - Unstructured content.

Reference

Branch name

Link to this function

branch_name(assigns)

Branch name is a label-type component rendered as a link that displays the name of a branch.

<.branch_name>development</.branch_name>

Examples

A branch name may be a link. Links are created with Phoenix.Component.link/1, passing all other attributes to the link. Link examples:

<.branch_name href="#url">some-name</.branch_name>
<.branch_name navigate={Routes.page_path(@socket, :index)}>some-name</.branch_name>
<.branch_name patch={Routes.page_path(@socket, :index, :details)}>some-name</.branch_name>

Add an icon before the branch name:

<.branch_name>
  <.octicon name="git-branch-16" />
  some-name
</.branch_name>

Attributes

  • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other attributes to the link.
  • patch (:string) - Link attribute - see href.
  • navigate (:string) - Link attribute - see href.
  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required) - The branch name text and optionally an icon.

Reference

Primer Branch name

Buttons

Link to this function

button(assigns)

Generates a button.

<.button>Click me</.button>

Examples

Optionally create an anchor link rendered as a button. Anchor links are created with Phoenix.Component.link/1, passing all other slot attributes to the link. Link examples:

<.button href="#url">href link</.button>
<.button navigate={Routes.page_path(@socket, :index)}>navigate link</.button>
<.button patch={Routes.page_path(@socket, :index)}>patch link</.button>

Primary button:

<.button is_primary>Sign in</.button>

Small button:

<.button is_small>Edit</.button>

Selected button:

<.button is_selected>Unread</.button>

With a dropdown caret:

<.button is_dropdown_caret>Menu</.button>

With a leading icon:

<.button is_primary>
  <.octicon name="download-16" />
  <span>Clone</span>
</.button>

With a trailing icon:

<.button is_primary>
  <span>Clone</span>
  <.octicon name="download-16" />
</.button>

Icon button (a button with an icon, similar to Primer React's IconButton):

<.button is_icon_button aria-label="Desktop">
  <.octicon name="device-desktop-16" />
</.button>

Icon as button (reduced padding):

<.button is_icon_only aria-label="Desktop">
  <.octicon name="device-desktop-16" />
</.button>

Use button_group/1 to create a group of buttons:

<.button_group>
  <.button>Button 1</.button>
  <.button>Button 2</.button>
  <.button>Button 3</.button>
</.button_group>

Attributes

  • is_full_width (:boolean) - Generates a full-width button. Defaults to false.

  • is_close_button (:boolean) - Use when enclosing icon "x-16". This setting removes the default padding. Defaults to false.

  • is_dropdown_caret (:boolean) - Adds a dropdown caret icon. Defaults to false.

  • is_danger (:boolean) - Generates a danger button (red label, turns the button red on hover). Defaults to false.

  • is_disabled (:boolean) - Generates a disabled button. Defaults to false.

  • is_icon_button (:boolean) - Generates an icon button without a label (similar to Primer React's IconButton). Add is_danger to create a danger icon (turns the icon red on hover). Defaults to false.

  • is_icon_only (:boolean) - Generates an icon that functions as a button. Add is_danger to create a danger icon (turns the icon red on hover). Defaults to false.

  • is_invisible (:boolean) - Create a button that looks like a link, maintaining the paddings of a regular button. Defaults to false.

  • is_aligned_start (:boolean) - Aligns contents to the start (at the left in left-to-right languages), while the dropdown caret (if any) is placed at the far end. Use this when the button is used for selecting items from a list.

    By default contents is center aligned.

    Defaults to false.

  • is_large (:boolean) - Generates a large button. Defaults to false.

  • is_link (:boolean) - Create a button that looks like a link. Defaults to false.

  • is_outline (:boolean) - Generates an outline button. Defaults to false.

  • is_primary (:boolean) - Generates a primary colored button. Defaults to false.

  • is_selected (:boolean) - Generates a selected button. Defaults to false.

  • is_small (:boolean) - Generates a small button. Defaults to false.

  • is_submit (:boolean) - Generates a button with type="submit". Defaults to false.

  • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other attributes to the link.

  • patch (:string) - Link attribute - see href.

  • navigate (:string) - Link attribute - see href.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for button elements. Any provided value will be appended to the default classname.

    Default map:

    %{
      button: "",  # Button element
      content: "", # Content (icons and label)
      caret: "",   # Dropdown icon
    }

    Defaults to %{content: nil, caret: nil, button: nil}.

  • Global attributes are accepted. Supports all globals plus: ["name", "type", "disabled", "form", "method"].

Slots

  • inner_block - Button content.

Reference

Primer Button Primer Button group Primer Icon button

Link to this function

button_group(assigns)

Generates a group of buttons.

<.button_group>
  <.button>Button 1</.button>
  <.button>Button 2</.button>
  <.button>Button 3</.button>
</.button_group>

Examples

Use button/1 children to create the button row:

<.button_group>
  <.button>Button 1</.button>
  <.button is_selected>Button 2</.button>
  <.button is_danger>Button 3</.button>
  <.button class="my-button">Button 4</.button>
</.button_group>

Attributes

  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • button - Deprecated: use button/1 as children. Since 0.5.0.Deprecation support: use button/1 attributes to configure the button appearance and behaviour.Accepts attributes:
    • class (:any) - Additional classname.
    • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other slot attributes to the link.
    • navigate (:string) - Link attribute - see href.
    • patch (:string) - Link attribute - see href.
    • is_close_button (:boolean) - See button/1.
    • is_danger (:boolean) - See button/1.
    • is_disabled (:boolean) - See button/1.
    • is_dropdown_caret (:boolean) - See button/1.
    • is_full_width (:boolean) - See button/1.
    • is_icon_button (:boolean) - See button/1.
    • is_icon_only (:boolean) - See button/1.
    • is_invisible (:boolean) - See button/1.
    • is_large (:boolean) - See button/1.
    • is_link (:boolean) - See button/1.
    • is_outline (:boolean) - See button/1.
    • is_primary (:boolean) - See button/1.
    • is_selected (:boolean) - See button/1.
    • is_small (:boolean) - See button/1.
    • is_submit (:boolean) - See button/1.
  • inner_block - Buttons as children of group button.

Reference

Dialog

Link to this function

dialog(assigns)

Dialog is a floating surface used to display transient content such as confirmation actions, selection options, and more.

A dialog is created with box/1 slots.

<.dialog>
  <:header_title>Title</:header_title>
  <:body>
    Message in a dialog
  </:body>
</.dialog>

Opening and closing the dialog

Invoking open and close

Functions open_dialog/1 and close_dialog/1 can be called with phx-click, passing the dialog's id (the alternative approach is to conditionally render - see below).

<.button phx-click={open_dialog("my-dialog")}>Open</.button>

<.dialog id="my-dialog">
  <:body>
    Message in a dialog
    <.button phx-click={close_dialog("my-dialog")}>Close</.button>
  </:body>
</.dialog>

Clicking the backdrop will automatically invoke cancel_dialog.

Pressing Escape will close the open dialog (unless is_escapable is explicitly set to false). In case of stacked dialogs, the included Prompt hook ensures that only the top dialog will be closed.

Routes and other conditionals

To show the dialog at a specific route (or with any other condition), use Phoenix's :if attribute, combined with is_show. The on_cancel attribute can then be used to redirect to the originating route:

<.dialog
  id="new-post-dialog"
  :if={@live_action == :create}
  is_show
  on_cancel={JS.patch(~p"/posts")}
>
  <:body>
    Post form
  </:body>
</.dialog>

To display the dialog on page load without a fade-in transition, add attribute is_show_on_mount. See PrimerLive.StatefulConditionComponent for an example.

Other attributes

Add a backdrop. Optionally add backdrop_strength with value "strong" or "light":

<.dialog is_backdrop backdrop_strength="light">
  ...
</.dialog>

Create a modal dialog; clicking the backdrop (if used) or outside of the dialog will not close the dialog:

<.dialog is_modal>
  ...
</.dialog>

Create faster fade in and out:

<.dialog is_fast>
  ...
</.dialog>

A narrow dialog:

<.dialog is_narrow>
  ...
</.dialog>

A wide dialog:

<.dialog is_wide>
  ...
</.dialog>

The dialog will focus the first element after opening. Pass focus_after_opening_selector with a selector to give focus to a different element.

<.dialog focus_after_opening_selector="#login_first_name">
  ...
</.dialog>

After closing the dialog, return the focus to the originating element. Improve accessibility by implementing this ARIA Dialog Pattern.

<.button id="opens-dialog" phx-click={open_dialog("my-dialog")}>Open</.button>

<.dialog id="my-dialog" focus_after_closing_selector="#opens-dialog">
  ...
</.dialog>

Long content will automatically show a scrollbar. To change the maxium height of the dialog, use a CSS value. Use unit vh or %.

<.dialog max_height="50vh">
  ...
</.dialog>

Add a header title and a footer.

box slot header slot is automatically added when header_title is used.

<.dialog>
  <:header_title>Title</:header_title>
  ...
  <:footer>Footer</:footer>
</.dialog>

A dialog with rows:

 <.dialog>
  <:header_title>Title</:header_title>
  <:row>Row 1</:row>
  <:row>Row 2</:row>
  <:row>Row 3</:row>
  <:row>Row 4</:row>
  <:footer>Footer</:footer>
</.dialog>

Dialog content is automatically wrapped inside a Phoenix.Component.focus_wrap/1 so that navigating with Tab won't leave the dialog.

<.dialog is_backdrop is_modal>
  <:header_title>Title</:header_title>
  <:body>
  <.text_input form={:user} field={:first_name} is_form_control />
  <.text_input form={:user} field={:last_name} is_form_control />
  </:body>
</.dialog>

Attributes

  • focus_after_closing_selector (:string) - Returns focus to the specified element after closing the dialog. Pass the element selector. Improve accessibility by implementing this ARIA Dialog Pattern.

    Defaults to nil.

  • focus_after_opening_selector (:string) - By default, the first interactive element gets focus after opening the dialog. Use to set focus to a different element after opening. Pass the element selector.

    Defaults to nil.

  • id (:string) (required) - Dialog element id, used for opening and closing from the outside.

  • is_backdrop (:boolean) - Generates a backdrop background with a default strength and tint values.

    Default backdrop strenght:

    • dialog and drawer: "medium"
    • menus: "light"

    Default tint: "dark".

    Defaults to false.

  • backdrop_strength (:string) - Backdrop strenght. Overrides the default value from is_backdrop. Defaults to nil.

  • backdrop_tint (:string) - Backdrop tint. Overrides the default value from is_backdrop. Defaults to nil.

  • is_escapable (:boolean) - Closes the content when the Escape key is pressed. Set to false to prevent this. Defaults to true.

  • is_fast (:boolean) - Generates fast fade transitions for backdrop and content. Defaults to false.

  • is_modal (:boolean) - Sets modal behavior: the dialog can only be closed with Escape or by clicking a close button. Defaults to false.

  • is_show (:boolean) - Sets the display state of the dialog. Control conditional display by using Phoenix's :if attribute.

    Example:

    <dialog is_show :if={@live_action in [:new, :edit]}>
      ...
    </dialog>

    Defaults to false.

  • show_state (:string) - Use when the dialog is already displayed, and should be persisted when navigating to another LiveViews (for example to hide the dialog with a transition after having navigated to a new route). This method does require that the dialog is available on the other LiveView page, so it is best suited for "global" components such as navigation panels and app header menus.

    Use together with is_show.

    Values:

    • "default": No change.
    • "onset": Preparation for the "hold" state. Removes the "phx-remove" attribute so that navigating away doesn't cause a close transition.
    • "hold": Removes the "phx-remove" attribute as well as opening transitions and first focus.

    Defaults to "default".

  • is_show_on_mount (:boolean) - Displays the dialog on mount without fade-in transition. Control conditional display by using Phoenix's :if attribute.

    Example:

    <dialog is_show is_show_on_mount :if={@live_action in [:new, :edit]}>
      ...
    </dialog>

    Defaults to false.

  • on_cancel (Phoenix.LiveView.JS) - Phoenix.LiveView.JS command to configure the closing/cancel event of the dialog, for example: on_cancel={JS.navigate(~p"/posts")}. Defaults to nil.

  • status_callback_selector (:string) - Receiver to get status callback events. Events are passed from the Prompt hook using pushEventTo. Pass the HTML selector of the receiver of the LiveComponent or LiveView the element is defined in.

    The event sends the object named "primer_live:prompt" with payload:

    %{
      "selector" => "",  # callback selector
      "elementId" => "", # the dialog id
      "status" => ""     # possible values: "opening", "opened", "closing", "closed"
    }

    Defaults to nil.

  • transition_duration (:integer) - The number of milliseconds to fade-in/out the dialog. Adds a CSS style attribute to the dialog HTML. Defaults to 170.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for dialog elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      # Dialog classes
      dialog_wrapper: "",  # The outer element
      dialog: "",          # Dialog element
      # Box classes - see box component:
      box: "",
      header: "",
      row: "",
      body: "",
      footer: "",
      header_title: "",
      link: "",
    }

    Defaults to %{link: nil, header: nil, body: nil, box: nil, dialog: nil, row: nil, footer: nil, header_title: nil, dialog_wrapper: nil}.

  • is_narrow (:boolean) - Generates a smaller dialog, width: 320px (default: 440px). Defaults to false.

  • is_wide (:boolean) - Generates a wider dialog, width: 640px (default: 440px). Defaults to false.

  • max_height (:string) - Maximum height of the dialog as CSS value. Use unit vh or %. Defaults to "80vh".

  • max_width (:string) - Maximum width of the dialog as CSS value. Use unit vh or %. Defaults to "90vw".

  • Global attributes are accepted.

Slots

  • header_title - Dialog header title. Uses box/1 header_title slot.Note that slot header is automatically created to ensure the correct close button.Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • body - Dialog body. Uses box/1 body slot. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • row - Dialog row. Uses box/1 row slot. Accepts attributes:
    • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other slot attributes to the link.

    • patch (:string) - Link attribute - see href.

    • navigate (:string) - Link attribute - see href.

    • phx-click (:string)

    • phx-target (:any)

    • phx-value-item (:any) - The payload parameter for the selected value to be sent with an event.

      Examples:

      <:row
        phx-click="select_row"
        phx-value-item={row_id}
      >     
        ...
      
      def handle_event(
        "select_row", %{"item" => row_id}, socket) do
        ...
    • class (:any) - Additional classname.

    • style (:string) - Additional CSS styles.

    • rest (:any)

  • footer - Dialog footer. Uses box/1 footer slot. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • inner_block - Unstructured dialog content. Uses box/1 inner_block slot.

Reference

Primer Dialog

Dialog functions

Link to this function

cancel_dialog(id)

Cancels a dialog: closes the dialog after executing the on_cancel attribute.

Examples

<.button phx-click={cancel_dialog("my-dialog")}>Cancel</.button>
Link to this function

cancel_dialog(js, id)

Cancels a dialog as part of a Phoenix.LiveView.JS command chain.

Link to this function

close_dialog(id)

Closes a dialog. Note that this won't call on_cancel. Any time on_cancel is provided and you still need a close button, cancel_dialog/1 will be a better choice.

Examples

<.button phx-click={close_dialog("my-dialog")}>Close</.button>
Link to this function

close_dialog(js, id)

Closes a dialog as part of a Phoenix.LiveView.JS command chain.

Examples

<.button phx-click={
  close_dialog("confirmation-dialog")
  |> close_dialog("base-dialog")
}>Open</.button>
Link to this function

open_dialog(id)

Opens a dialog.

Examples

<.button phx-click={open_dialog("my-dialog")}>Open</.button>
Link to this function

open_dialog(js, id)

Opens a dialog as part of a Phoenix.LiveView.JS command chain.

Examples

<.button phx-click={
  open_dialog("base-dialog")
  |> open_dialog("confirmation-dialog")
}>Open</.button>
Link to this function

toggle_dialog(id)

Toggles the open state of the dialog.

Link to this function

toggle_dialog(js, id)

Toggles a dialog as part of a Phoenix.LiveView.JS command chain.

Drawer

Link to this function

drawer(assigns)

Generates a drawer with configuration options for backdrop, position and behavior.

<.drawer>
  <:body>
    Content
  </:body>
</.drawer>

Opening and closing the drawer

Invoking open and close

Functions open_drawer/1 and close_drawer/1 can be called with phx-click, passing the drawer's id (the alternative approach is to conditionally render - see below). Alternatively use toggle_drawer/1 for simply toggling open and close.

<.button phx-click={open_drawer("my-drawer")}>Open</.button>

<.drawer id="my-drawer">
  <:body width="300px">
    <.button phx-click={close_drawer("my-drawer")}>Close</.button>
  </:body>
</.drawer>

Clicking the backdrop will automatically invoke cancel_drawer.

Pressing Escape will close the open drawer (unless is_escapable is explicitly set to false).

Routes and other conditionals

To show the drawer at a specific route (or with any other condition), use Phoenix's :if attribute, combined with is_show. The on_cancel attribute can then be used to redirect to the originating route:

<.drawer
  id="my-drawer"
  :if={@live_action == :create}
  is_show
  on_cancel={JS.patch(~p"/posts")}
>
  <:body>
    Post form
  </:body>
</.drawer>

To display the drawer on page load without a fade-in transition, add attribute is_show_on_mount. See PrimerLive.StatefulConditionComponent for an example.

Other attributes

By default the drawer width is defined by its content. To set an explicit width of the drawer content:

<.drawer>
  <:body width="300px">
    ...
  </:body>
</.drawer>

Add a backdrop. Optionally add backdrop_strength with value "strong" or "light":

<.drawer is_backdrop backdrop_strength="strong">
  ...
</.drawer>

Create a modal drawer; clicking the backdrop (if used) or outside of the drawer will not close the drawer:

<.drawer is_modal>
  ...
</.drawer>

Create faster slide in and out:

<.drawer is_fast>
  ...
</.drawer>

The drawer will focus the first element after opening. Pass focus_after_opening_selector with a selector to give focus to a different element.

<.drawer focus_after_opening_selector="#login_first_name">
  ...
</.drawer>

Create a local drawer (inside a container) with is_local:

<div style="position: relative; overflow-x: hidden;">
  Page content
  <.drawer is_local>
    <:body>
      Content
    </:body>
  </.drawer>
</div>

Create a push drawer - where the drawer content pushes the adjacent content aside when it opens - with attr is_push and the content to be pushed inside <.drawer>:

<div style="position: relative; overflow-x: hidden;">
  <.drawer is_push>
    Page content
    <:body>
      Content
    </:body>
  </.drawer>
</div>

Attributes

  • focus_after_closing_selector (:string) - Returns focus to the specified element after closing the drawer. Pass the element selector. Improve accessibility by implementing this ARIA Dialog Pattern.

    Defaults to nil.

  • focus_after_opening_selector (:string) - By default, the first interactive element gets focus after opening the drawer. Use to set focus to a different element after opening. Pass the element selector.

    Defaults to nil.

  • id (:string) (required) - Drawer element id, used for opening and closing from the outside.

  • is_backdrop (:boolean) - Generates a backdrop background with a default strength and tint values.

    Default backdrop strenght:

    • dialog and drawer: "medium"
    • menus: "light"

    Default tint: "dark".

    Defaults to false.

  • backdrop_strength (:string) - Backdrop strenght. Overrides the default value from is_backdrop. Defaults to nil.

  • backdrop_tint (:string) - Backdrop tint. Overrides the default value from is_backdrop. Defaults to nil.

  • is_escapable (:boolean) - Closes the content when the Escape key is pressed. Set to false to prevent this. Defaults to true.

  • is_fast (:boolean) - Generates fast fade transitions for backdrop and content. Defaults to false.

  • is_modal (:boolean) - Sets modal behavior: the drawer can only be closed with Escape or by clicking a close button. Defaults to false.

  • is_show (:boolean) - Sets the display state of the drawer. Control conditional display by using Phoenix's :if attribute.

    Example:

    <drawer is_show :if={@live_action in [:new, :edit]}>
      ...
    </drawer>

    Defaults to false.

  • show_state (:string) - Use when the drawer is already displayed, and should be persisted when navigating to another LiveViews (for example to hide the drawer with a transition after having navigated to a new route). This method does require that the drawer is available on the other LiveView page, so it is best suited for "global" components such as navigation panels and app header menus.

    Use together with is_show.

    Values:

    • "default": No change.
    • "onset": Preparation for the "hold" state. Removes the "phx-remove" attribute so that navigating away doesn't cause a close transition.
    • "hold": Removes the "phx-remove" attribute as well as opening transitions and first focus.

    Defaults to "default".

  • is_show_on_mount (:boolean) - Displays the drawer on mount without fade-in transition. Control conditional display by using Phoenix's :if attribute.

    Example:

    <drawer is_show is_show_on_mount :if={@live_action in [:new, :edit]}>
      ...
    </drawer>

    Defaults to false.

  • on_cancel (Phoenix.LiveView.JS) - Phoenix.LiveView.JS command to configure the closing/cancel event of the drawer, for example: on_cancel={JS.navigate(~p"/posts")}. Defaults to nil.

  • status_callback_selector (:string) - Receiver to get status callback events. Events are passed from the Prompt hook using pushEventTo. Pass the HTML selector of the receiver of the LiveComponent or LiveView the element is defined in.

    The event sends the object named "primer_live:prompt" with payload:

    %{
      "selector" => "",  # callback selector
      "elementId" => "", # the drawer id
      "status" => ""     # possible values: "opening", "opened", "closing", "closed"
    }

    Defaults to nil.

  • transition_duration (:integer) - The number of milliseconds to fade-in/out the drawer. Adds a CSS style attribute to the drawer HTML. Defaults to 170.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for drawer elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      drawer_wrapper: "",  # The outer element
      drawer: "",          # Drawer element
      body: "",            # Drawer content element
    }

    Defaults to %{body: nil, drawer: nil, drawer_wrapper: nil}.

  • is_far_side (:boolean) - Opens the drawer at the far end of the reading direction. Defaults to false.

  • is_local (:boolean) - Adds styles for a drawer inside a a container. Defaults to false.

  • is_push (:boolean) - Adds styles for a push drawer inside a a container. Defaults to false.

  • Global attributes are accepted.

Slots

  • body - Drawer body. Accepts attributes:
    • class (:any) - Additional classname.

    • width (:string) - Sets the width of the drawer as CSS value. Add unit px or rem or other size unit.

      By default the drawer width is defined by its content.

    • style (:string)

    • rest (:any)

  • inner_block - Drawer content and any adjacent elements. Use slot body for the content to be displayed inside the drawer.

Reference

Neither Primer CSS nor Primer React provide a drawer component. However, a drawer is used on their documentation site (mobile view).

Link to this function

drawer_content(assigns)

Drawer content. Deprecated: use :body slot with drawer/1. Since 0.4.0.

Attributes

  • width (:string) - Sets the width of the drawer as CSS value. Add unit px or rem or other size unit.

    By default the drawer width is defined by its content.

    Defaults to nil.

  • class (:any) - Additional classname. Defaults to nil.

  • Global attributes are accepted.

Slots

  • inner_block - Drawer content.

Drawer functions

Link to this function

cancel_drawer(id)

Cancels a drawer: closes the drawer after executing the on_cancel attribute.

Examples

<.button phx-click={cancel_drawer("my-drawer")}>Cancel</.button>
Link to this function

cancel_drawer(js, id)

Cancels a drawer as part of a Phoenix.LiveView.JS command chain.

Link to this function

close_drawer(id)

Closes a drawer. Note that this won't call on_cancel. Any time on_cancel is provided and you still need a close button, cancel_drawer/1 will be a better choice.

Examples

<.button phx-click={close_drawer("my-drawer")}>Close</.button>
Link to this function

close_drawer(js, id)

Closes a drawer as part of a Phoenix.LiveView.JS command chain.

Examples

<.button phx-click={
  close_drawer("confirmation-drawer")
  |> close_drawer("base-drawer")
}>Open</.button>
Link to this function

open_drawer(id)

Opens a drawer.

Examples

<.button phx-click={open_drawer("my-drawer")}>Open</.button>
Link to this function

open_drawer(js, id)

Opens a drawer as part of a Phoenix.LiveView.JS command chain.

Examples

<.button phx-click={
  open_drawer("base-drawer")
  |> open_drawer("confirmation-drawer")
}>Open</.button>
Link to this function

toggle_drawer(id)

Toggles the open state of the drawer.

Link to this function

toggle_drawer(js, id)

Toggles a drawer as part of a Phoenix.LiveView.JS command chain.

Styled HTML

Link to this function

styled_html(assigns)

Adds styling to HTML. This can be used to format HTML generated by a Markdown library, or to create consistent layout of HTML content.

<.styled_html>
  Content
</.styled_html>

Attributes

  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required) - Content to be formatted.

Reference

Primer Markdown

Forms

Link to this function

checkbox(assigns)

Generates a checkbox.

Wrapper around PhoenixHTMLHelpers.Form.checkbox/3.

<.checkbox name="available_for_hire" />

To create a group of checkboxes, see checkbox_group/1.

Examples

Set the checked state:

<.checkbox name="available_for_hire" checked />

Using the checkbox with form data. This will automatically create the checkbox label:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.checkbox form={f} field={:available_for_hire} />
</.form>

Pass a custom checkbox label with the label slot:

<.checkbox form={:user} field={:available_for_hire}>
  <:label>Some label</:label>
</.checkbox>

Add emphasis to the label:

<.checkbox name="available_for_hire" is_emphasised_label />

Add a hint below the label:

<.checkbox name="available_for_hire">
  <:label>Some label</:label>
  <:hint>
    Add your <strong>resume</strong> below
  </:hint>
</.checkbox>

Reveal extra details when the checkbox is checked:

<.checkbox name="available_for_hire">
  <:label>Some label</:label>
  <:disclosure>
    <span class="d-block mb-1">Available hours per week</span>
    <.text_input is_contrast size="3" />
    <span class="text-small color-fg-muted pl-2">hours per week</span>
  </:disclosure>
</.checkbox>

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • name (:string) - Input name attribute (when not using form and field).

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • checked (:boolean) - The state of the checkbox (when not using form and field).

  • checked_value (:string) - The value to be sent when the checkbox is checked. If checked_value equals value, the checkbox is marked checked. Defaults to "true". Defaults to nil.

  • hidden_input (:string) - Controls if the component will generate a hidden input to submit the unchecked checkbox value or not. Defaults to "true". Defaults to "true".

  • value (:string) - Checkbox value attribute (overrides field value when using form and field).

  • is_multiple (:boolean) - When creating a list of checkboxes. Appends [] to the input name so that a list of values is passed to the form events.

    Alternatively, use checkbox_in_group/1 to set this automatically.

    Defaults to false.

  • is_emphasised_label (:boolean) - Adds emphasis to the label. Defaults to false.

  • is_omit_label (:boolean) - Omits the label. Defaults to false.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for checkbox elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      container: "",       # Checkbox container
      label_container: "", # Input label container
      label: "",           # Input label
      input: "",           # Checkbox input element
      caption: "",         # Hint message element
      hint: "",            # Deprecation support: identical to "caption"
      disclosure: ""       # Disclosure container (inline)
    }

    Defaults to %{input: nil, label: nil, hint: nil, container: nil, caption: nil, label_container: nil, disclosure: nil}.

  • Global attributes are accepted. Supports all globals plus: ["disabled"].

Slots

  • label - Custom checkbox label. Overides the derived label when using a form and field. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • caption - Adds text below checkbox label. Enabled when a label is displayed. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • hint - Deprecated: use caption. As of 0.5.0. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • disclosure - Extra label content to be revealed when checkbox is checked. Enabled when a label is displayed.Note that the label element can only contain inline child elements.Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)

Reference

Link to this function

checkbox_group(assigns)

Checkbox group renders a set of checkboxes and wraps it in a fieldset. The label attribute generates a legend element.

<.checkbox_group>
  <.checkbox name="roles[]" checked_value="admin" />
  <.checkbox name="roles[]" checked_value="editor" />
</.checkbox_group>

Examples

Another convenience component - checkbox variant checkbox_in_group/1 - sets attr is_multiple to true, so that the server receives an array of strings for the checked values.

<.form :let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.checkbox_group
    form={f}
    field={@field}
    caption="Select one"
  >
    <.checkbox_in_group
      :for={{label, value} <- @options}
      form={f}
      field={@field}
      checked_value={value}
      checked={value in @values}
    >
      <:label>
        <%= label %>
      </:label>
    </.checkbox_in_group>
  </.checkbox_group>
</.form>

Reference

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • validation_message (:any) - Function to write a custom validation message (in case of error or success).

    The function receives a PrimerLive.FieldState struct and returns a validation message or nil.

    A validation message is shown:

    • If form is a Phoenix.HTML.Form, containing a changeset
    • The validation_message function does not return nil

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    Conditional error message:

    fn field_state ->
      if !field_state.valid?, do: "Please enter your first name"
    end

    Conditional success message, only shown when changeset.action is :validate:

    fn field_state ->
      if field_state.valid? && field_state.changeset.action == :validate, do: "Is available"
    end

    Defaults to nil.

  • caption (:any) - Hint message below the checkbox group label.

    Pass a string, or a function that returns a string.

    The function receives a PrimerLive.FieldState struct and returns a message or nil (which omits the caption element).

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    To conditionally show a caption, use field_state. To show the caption when field state is valid:

    fn field_state ->
      if !field_state.valid?, do: nil, else: "Caption"
    end

    For additional markup, use the H sigil:

    fn ->
      ~H'''
      Caption with <a href="/">link</a>
      '''
    end

    Defaults to nil.

  • label (:string) - Fieldset legend label. Defaults to nil.

  • is_hide_label (:boolean) - Omits the automatically generated label (when using field). Defaults to false.

  • is_disabled (:boolean) - Adjusts the styling to indicate disabled state. Defaults to false.

  • required_marker (:string) - Required field marking. This will be shown for all required fields (when using Phoenix.HTML.Form). Pass an empty string to remove the indicator. Defaults to "*".

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for checkbox group elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      control: "",               # Checkbox group wrapper
      group: "",                 # Deprecation support: identical to "control"
      header: "",                # Header element containing the group label
      label: "",                 # Checkbox group label
      input_group_container: "", # Input group container (for checkbox_group and radio_group)
      caption: "",               # Checkbox group caption
      fieldset: "",              # Fieldset wrapper (for checkbox_group and radio_group) 
      legend: "",                # Legend (for checkbox_group and radio_group)
    }

    Defaults to %{control: nil, label: nil, header: nil, group: nil, caption: nil, input_group_container: nil, fieldset: nil, legend: nil}.

  • Global attributes are accepted.

Slots

  • inner_block (required) - The checkbox group content.
Link to this function

checkbox_in_group(assigns)

Convenience checkbox component for use inside checkbox_group/1.

Sets attribute is_multiple to true, so that the server receives an array of strings for the checked values.

<.checkbox_in_group form={@form} field={@field} />

Inside a form and checkbox group:

<.form :let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.checkbox_group
    form={f}
    field={@field}
  >
    <.checkbox_in_group
      :for={{label, value} <- @options}
      form={f}
      field={@field}
      checked_value={value}
      checked={value in @values}
    />
  </.checkbox_group>
</.form>

Attributes

Use checkbox/1 attributes.

Link to this function

form_control(assigns)

Deprecated: use a form input component with attr: is_form_control. Since 0.9.0.

Attributes

  • caption (:any) - Hint message below the form control label.

    Pass a string, or a function that returns a string.

    The function receives a PrimerLive.FieldState struct and returns a message or nil (which omits the caption element).

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    To conditionally show a caption, use field_state. To show the caption when field state is valid:

    fn field_state ->
      if !field_state.valid?, do: nil, else: "Caption"
    end

    For additional markup, use the H sigil:

    fn ->
      ~H'''
      Caption with <a href="/">link</a>
      '''
    end

    Defaults to nil.

  • is_multiple (:boolean) - When creating a list of checkboxes. Appends [] to the input name so that a list of values is passed to the form events.

    Alternatively, use checkbox_in_group/1 to set this automatically.

    Defaults to false.

  • class (:any) - Additional classname. Defaults to nil.

  • common_input_attrs (:map) - Used to pass calculated attributes from an input component to the form control. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • classes (:map) - Additional classnames for form control elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      control: "",               # Form control wrapper
      group: "",                 # Deprecation support: identical to "control"
      header: "",                # Header element containing the group label
      label: "",                 # Form control label
      input_group_container: "", # Input group container (for checkbox_group and radio_group)
      caption: "",               # Form control caption
      fieldset: "",              # Fieldset wrapper (for checkbox_group and radio_group) 
      legend: "",                # Legend (for checkbox_group and radio_group)
    }

    Defaults to %{control: nil, label: nil, header: nil, group: nil, caption: nil, input_group_container: nil, fieldset: nil, legend: nil}.

  • for (:string) - Internally used by text_input/1 and textarea/1 when using is_form_control or form_control. Label attribute to associate the label with the input. for should be the same as the input's id. Defaults to nil.

  • is_disabled (:boolean) - Adjusts the styling to indicate disabled state. Defaults to false.

  • is_hide_label (:boolean) - Omits the automatically generated label (when using field). Defaults to false.

  • is_input_group (:boolean) - Creates styling for checkbox_group/1 and radio_group/1: a larger label font size, and layout for inputs, captions and validation. Defaults to false.

  • label (:string) - Custom label. Note that a label is automatically generated when using field. Defaults to nil.

  • required_marker (:string) - Required field marking. This will be shown for all required fields (when using Phoenix.HTML.Form). Pass an empty string to remove the indicator. Defaults to "*".

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • validation_message_id (:string) - Message ID that is usually passed from the form element component to input_validation_message. If not used, the ID will be generated. Defaults to nil.

  • validation_message (:any) - Function to write a custom validation message (in case of error or success).

    The function receives a PrimerLive.FieldState struct and returns a validation message or nil.

    A validation message is shown:

    • If form is a Phoenix.HTML.Form, containing a changeset
    • The validation_message function does not return nil

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    Conditional error message:

    fn field_state ->
      if !field_state.valid?, do: "Please enter your first name"
    end

    Conditional success message, only shown when changeset.action is :validate:

    fn field_state ->
      if field_state.valid? && field_state.changeset.action == :validate, do: "Is available"
    end

    Defaults to nil.

  • is_wrap_in_fieldset (:boolean) - Defaults to false.

  • is_full_width (:boolean) - Full width control. Defaults to false.

  • Global attributes are accepted.

Slots

  • inner_block (required) - The form control content.
Link to this function

input_validation_message(assigns)

Generates a validation message for a form input. It can be used as standalone component for inputs where the position of the validation feedback is not so obvious.

This component is incorporated in "singular inputs" text_input/1, textarea/1 and select/1.

A validation error message is automatically added when using a changeset with an error state. The message text is taken from the changeset errors.

To show the default validation message:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <!-- INPUTS -->
  <.input_validation_message form={@form} field={:availability} />
</.form>

To show a custom error message:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <!-- INPUTS -->
  <.input_validation_message
    form={@form}
    field={:availability}
    validation_message={
      fn field_state ->
        if !field_state.valid?, do: "Please select your availability"
      end
    }
  />
</.form>

Similarly, to show a custom validation success message:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <!-- INPUTS -->
  <.input_validation_message
    form={@form}
    field={:availability}
    validation_message={
      fn field_state ->
        if field_state.valid?, do: "Great!"
      end
    }
  />
</.form>

Reference

Primer Form control

Attributes

  • common_input_attrs (:map) - Used to pass calculated attributes from an input component to the form control. Defaults to nil.

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • validation_message (:any) - Function to write a custom validation message (in case of error or success).

    The function receives a PrimerLive.FieldState struct and returns a validation message or nil.

    A validation message is shown:

    • If form is a Phoenix.HTML.Form, containing a changeset
    • The validation_message function does not return nil

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    Conditional error message:

    fn field_state ->
      if !field_state.valid?, do: "Please enter your first name"
    end

    Conditional success message, only shown when changeset.action is :validate:

    fn field_state ->
      if field_state.valid? && field_state.changeset.action == :validate, do: "Is available"
    end

    Defaults to nil.

  • validation_message_id (:string) - Message ID that is usually passed from the form element component to input_validation_message. If not used, the ID will be generated. Defaults to nil.

  • is_multiple (:boolean) - Set to true when the validation message refers to a "multiple" field, to that the generated ID will include suffix []. Defaults to false.

  • class (:any) - Additional classname. Defaults to nil.

  • Global attributes are accepted.

Link to this function

radio_button(assigns)

Generates a radio button.

Wrapper around PhoenixHTMLHelpers.Form.radio_button/4.

<.radio_button name="role" value="admin" />
<.radio_button name="role" value="editor" />

To create a group of radio buttons, see radio_group/1.

Examples

Set the checked state:

<.radio_button name="role" value="admin" />
<.radio_button name="role" value="editor" checked />

Using the radio button with form data. This will automatically create the radio button label:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.radio_button form={f} field={:role} value="admin" />
  <.radio_button form={f} field={:role} value="editor" />
</.form>

Pass a custom radio button label with the label slot:

<.radio_button form={:user} field={:role}>
  <:label>Some label</:label>
</.radio_button>

Add emphasis to the label:

<.radio_button name="role" is_emphasised_label />

Add a hint below the label:

<.radio_button name="role">
  <:label>Some label</:label>
  <:hint>
    Add your <strong>resume</strong> below
  </:hint>
</.radio_button>

Reveal extra details when the radio button is checked:

<.radio_button name="role">
  <:label>Some label</:label>
  <:disclosure>
    <span class="d-block mb-1">Available hours per week</span>
    <.text_input is_contrast size="3" />
    <span class="text-small color-fg-muted pl-2">hours per week</span>
  </:disclosure>
</.radio_button>

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • name (:string) - Input name attribute (when not using form and field).

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • checked (:boolean) - The state of the radio button (when not using form and field).

  • checked_value (:string) - For internal use to ensure compatibility with "single select" radio buttons in action_list/1. Defaults to nil.

  • value (:string) - Radio button value attribute (overrides field value when using form and field).

  • is_emphasised_label (:boolean) - Adds emphasis to the label. Defaults to false.

  • is_omit_label (:boolean) - Omits the label. Defaults to false.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for radio button elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      container: "",       # Radio button container
      label_container: "", # Input label container
      label: "",           # Input label
      input: "",           # Radio button input element
      caption: "",         # Hint message element
      hint: "",            # Deprecation support: identical to "caption"
      disclosure: ""       # Disclosure container (inline)
    }

    Defaults to %{input: nil, label: nil, hint: nil, container: nil, caption: nil, label_container: nil, disclosure: nil}.

  • Global attributes are accepted. Supports all globals plus: ["disabled"].

Slots

  • label - Custom radio button label. Overides the derived label when using a form and field. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • caption - Adds text below radio button label. Enabled when a label is displayed. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • hint - Deprecated: use caption. As of 0.5.0. Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • disclosure - Extra label content to be revealed when radio button is checked. Enabled when a label is displayed.Note that the label element can only contain inline child elements.Accepts attributes:
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)

Reference

Link to this function

radio_group(assigns)

Radio group renders a set of radio buttons and wraps it in a fieldset. The label attribute generates a legend element.

<.radio_group>
  <.radio_button name="role" value="admin" />
  <.radio_button name="role" value="editor" />
</.radio_group>

Examples

<.form :let={f} for={@changeset}>
  <.radio_group form={f} field={@field} caption="Select one">
    <.radio_button
      :for={{label, value} <- @options}
      form={f}
      field={@field}
      value={value}
    >
      <:label>
        <%= label %>
      </:label>
    </.radio_button>
  </.radio_group>
</.form>

Reference

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • validation_message (:any) - Function to write a custom validation message (in case of error or success).

    The function receives a PrimerLive.FieldState struct and returns a validation message or nil.

    A validation message is shown:

    • If form is a Phoenix.HTML.Form, containing a changeset
    • The validation_message function does not return nil

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    Conditional error message:

    fn field_state ->
      if !field_state.valid?, do: "Please enter your first name"
    end

    Conditional success message, only shown when changeset.action is :validate:

    fn field_state ->
      if field_state.valid? && field_state.changeset.action == :validate, do: "Is available"
    end

    Defaults to nil.

  • caption (:any) - Hint message below the radio group label.

    Pass a string, or a function that returns a string.

    The function receives a PrimerLive.FieldState struct and returns a message or nil (which omits the caption element).

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    To conditionally show a caption, use field_state. To show the caption when field state is valid:

    fn field_state ->
      if !field_state.valid?, do: nil, else: "Caption"
    end

    For additional markup, use the H sigil:

    fn ->
      ~H'''
      Caption with <a href="/">link</a>
      '''
    end

    Defaults to nil.

  • label (:string) - Fieldset legend label. Defaults to nil.

  • is_hide_label (:boolean) - Omits the automatically generated label (when using field). Defaults to false.

  • is_disabled (:boolean) - Adjusts the styling to indicate disabled state. Defaults to false.

  • required_marker (:string) - Required field marking. This will be shown for all required fields (when using Phoenix.HTML.Form). Pass an empty string to remove the indicator. Defaults to "*".

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for radio group elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      control: "",               # Radio group wrapper
      group: "",                 # Deprecation support: identical to "control"
      header: "",                # Header element containing the group label
      label: "",                 # Radio group label
      input_group_container: "", # Input group container (for checkbox_group and radio_group)
      caption: "",               # Radio group caption
      fieldset: "",              # Fieldset wrapper (for checkbox_group and radio_group) 
      legend: "",                # Legend (for checkbox_group and radio_group)
    }

    Defaults to %{control: nil, label: nil, header: nil, group: nil, caption: nil, input_group_container: nil, fieldset: nil, legend: nil}.

  • Global attributes are accepted.

Slots

  • inner_block (required) - The radio group content.
Link to this function

radio_tabs(assigns)

Groups radio buttons in a tab-like row. Note that this component is not updated for RTL-display.

Radio buttons are generated from the radio_button slot:

<.radio_tabs>
  <:radio_button name="role" value="admin"></:radio_button>
  <:radio_button name="role" value="editor"></:radio_button>
</.radio_tabs>

Examples

Using a PhoenixHTMLHelpers.Form, attributes form and field are passed from radio group to the radio buttons, and labels are generated automatically:

<.form let={f} for={@changeset}>
  <.radio_tabs form={f} field={:role}>
    <:radio_button value="admin"></:radio_button>
    <:radio_button value="editor"></:radio_button>
  </.radio_tabs>
</.form>

Generates:

<form method="post" errors="">
  <div class="radio-group">
    <input class="radio-input" id="demo_user_role_admin"
      name="demo_user[role]" type="radio" value="admin">
    <label class="radio-label" for="demo_user_role_admin">Admin</label>
    <input class="radio-input" id="demo_user_role_editor"
      name="demo_user[role]" type="radio" value="editor">
    <label class="radio-label" for="demo_user_role_editor">Editor</label>
  </div>
</form>

Use custom label with the radio_button slot attr label:

<.radio_tabs>
  <:radio_button name="role" value="admin" label="My role is Admin"></:radio_button>
  <:radio_button name="role" value="editor" label="My role is Editor"></:radio_button>
</.radio_tabs>

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for radio group elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      radio_group_wrapper: "", # RTL-wrapper
      radio_group: "",         # Radio group containe
      label: "",               # Radio button label
      radio_input: "",         # Radio button input
    }

    Defaults to %{label: nil, radio_group: nil, radio_input: nil}.

  • id_prefix (:string) - Attribute id prefix to create unique ids. Defaults to nil.

  • Global attributes are accepted.

Slots

  • radio_button - Generates a radio button. Accepts attributes:

Reference

This component was created based on Primer CSS documentation. It is not mentioned in the Primer Style specification.

Link to this function

select(assigns)

Generates a single or multiple select input.

Wrapper around PhoenixHTMLHelpers.Form.select/4 and PhoenixHTMLHelpers.Form.multiple_select/4.

<.select name="age" options={25..35} />

Examples

Options can contain:

  • A list:
    • 25..35
    • ["male", "female", "won't say"]
  • A keyword list:
    • ["Admin": "admin", "User": "user"]
  • A nested keyword list with option attributes:
    • [[key: "Admin", value: "admin", disabled: true], [key: "User", value: "user"]]

Create a small select input:

<.select name="age" options={25..35} is_small />

Set the selected item:

<.select name="age" options={25..35} selected="30" />

Add a prompt:

<.select name="age" options={25..35} prompt="Choose your age" />

Set attributes to the prompt option:

<.select
  name="age"
  options={25..35}
  prompt={[key: "Choose your age", disabled: true, selected: true]}
/>

Create a multiple select with is_multiple.

  • Use is_auto_height to set the height of the select input to the number of options.
  • From the Phoenix documentation: Values are expected to be an Enumerable containing two-item tuples (like maps and keyword lists) or any Enumerable where the element will be used both as key and value for the generated select.
  • selected should contain a list of selected options.
<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.select
    form={f}
    field={:role}
    options={["Admin": "admin", "User": "user", "Editor": "editor"]}
    is_multiple
    is_auto_height
    selected={["user", "tester"]}
  />
</.form>

Place the select inside a form control wrapper with is_form_control. See text_input/1 for examples.

A validation error message is automatically added when using a changeset with an error state. See text_input/1 how to customise the validation messages.

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • name (:string) - Input name attribute (when not using form and field).

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • caption (:any) - Hint message below the select input.

    Pass a string, or a function that returns a string.

    The function receives a PrimerLive.FieldState struct and returns a message or nil (which omits the caption element).

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    To conditionally show a caption, use field_state. To show the caption when field state is valid:

    fn field_state ->
      if !field_state.valid?, do: nil, else: "Caption"
    end

    For additional markup, use the H sigil:

    fn ->
      ~H'''
      Caption with <a href="/">link</a>
      '''
    end

    Defaults to nil.

  • options (:any) (required) - Selectable options (list, map or keyword list).

  • selected (:any) - Selected option or options (string for single select, list when using is_multiple).

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for select elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      select_container: "",   # Select container element
      select: "",             # Select element
      validation_message: "", # Validation message,
      caption: "",            # Hint message element
    }

    Defaults to %{select: nil, caption: nil, validation_message: nil, select_container: nil}.

  • prompt (:any) - The default option that is displayed in the select options before the user makes a selection. See PhoenixHTMLHelpers.Form.multiple_select/4.

    Can't be used with a multiple select - this attribute will be ignored.

    Pass a string or a keyword list.

    Examples:

    <.select name="age" options={25..35} prompt="Choose your age" />

    Set attributes to the prompt option:

    <.select
      name="age"
      options={25..35}
      prompt={[key: "Choose your age", disabled: true, selected: true]}
    />
  • is_multiple (:boolean) - Creates a multiple select. Uses PhoenixHTMLHelpers.Form.multiple_select/4.

    From the Phoenix documentation:

    Values are expected to be an Enumerable containing two-item tuples (like maps and keyword lists) or any Enumerable where the element will be used both as key and value for the generated select.

    Defaults to false.

  • is_small (:boolean) - Creates a small (less high) select. Defaults to false.

  • is_large (:boolean) - Creates a large (higher) select. Defaults to false.

  • is_full_width (:boolean) - Full width select. Defaults to false.

  • is_auto_height (:boolean) - When using is_multiple: sets the size to the number of options. Defaults to false.

  • is_monospace (:boolean) - Uses a monospace font. Defaults to false.

  • form_control (:map) - Form control attributes. Places the select input inside a form_control/1 component with given attributes, alongside form and field to generate a form control label.

    If only a automatically generated label is required, use convenience attr is_form_control instead.

    Defaults to nil.

  • is_form_control (:boolean) - Places the select input inside a form_control/1 component. Attributes form and field are automatically passed to form_control to generate a form control label. If the field is required, its label will show a required marker.

    To configure the form control and label, use attr form_control.

    Defaults to false.

  • validation_message (:any) - Function to write a custom validation message (in case of error or success).

    The function receives a PrimerLive.FieldState struct and returns a validation message or nil.

    A validation message is shown:

    • If form is a Phoenix.HTML.Form, containing a changeset
    • The validation_message function does not return nil

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    Conditional error message:

    fn field_state ->
      if !field_state.valid?, do: "Please enter your first name"
    end

    Conditional success message, only shown when changeset.action is :validate:

    fn field_state ->
      if field_state.valid? && field_state.changeset.action == :validate, do: "Is available"
    end

    Defaults to nil.

  • validation_message_id (:string) - Message ID that is usually passed from the form element component to input_validation_message. If not used, the ID will be generated. Defaults to nil.

  • Global attributes are accepted. Supports all globals plus: ["disabled"].

Reference

Link to this function

text_input(assigns)

Generates a text input field.

Wrapper around PhoenixHTMLHelpers.Form.text_input/3, optionally wrapped itself inside a "form control" to add a field label.

<.text_input field="first_name" />

Examples

Set the input type:

<.text_input type="password" />
<.text_input type="hidden" />
<.text_input type="email" />

Set the placeholder. By default, the value of the placeholder attribute is used to fill in the aria-label attribute:

<.text_input placeholder="Enter your first name" />

Using the input with form data:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.text_input form={f} field={:first_name} />
  <.text_input form={f} field={:last_name} />
</.form>

Attach a button to the input with slot group_button:

<.text_input>
  <:group_button>
    <.button>Send</.button>
  </:group_button>
</.text_input>

or use an icon button:

<.text_input>
  <:group_button>
    <.button aria-label="Copy">
      <.octicon name="paste-16" />
    </.button>
  </:group_button>
</.text_input>

Add a button to the text input with slot trailing_action:

<.text_input>
  <:trailing_action>
    <.button is_icon_only aria-label="Clear">
      <.octicon name="x-16" />
    </.button>
  </:trailing_action>
</.text_input>

Only show the trailing action when the input has a value:

<.text_input>
  <:trailing_action is_visible_with_value>
    <.button is_icon_only aria-label="Clear">
      <.octicon name="x-16" />
    </.button>
  </:trailing_action>
</.text_input>

Add a leading visual with slot leading_visual:

<.text_input>
  <:leading_visual>
    <.octicon name="mail-16" />
  </:leading_visual>
</.text_input>

Place the input inside a form control wrapper with is_form_control. Attributes form and field are passed to the form control to generate a control label. If the field is required, its label will show a required marker.

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.text_input form={f} field={:first_name} is_form_control />
</.form>

To configure the form control and label, use attr form_control. See form_control/1 for supported attributes.

A validation error message is automatically added when using a changeset with an error state. The message text is taken from the changeset errors. To show a custom validation error message, supply function validation_message:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.text_input
    form={f}
    field={:first_name}
    form_control={%{
      label: "Custom label",
      validation_message:
        fn field_state ->
          if !field_state.valid?, do: "Please enter your first name"
        end
    }}
  />
</.form>

Similarly, to show a custom validation success message:

<.form let={f} for={@changeset} phx-change="validate" phx-submit="save">
  <.text_input
    form={f}
    field={:first_name}
    validation_message={
      fn field_state ->
        if field_state.valid?, do: "Available!"
      end
    }
  />
</.form>

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • caption (:any) - Hint message below the input element.

    Pass a string, or a function that returns a string.

    The function receives a PrimerLive.FieldState struct and returns a message or nil (which omits the caption element).

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    To conditionally show a caption, use field_state. To show the caption when field state is valid:

    fn field_state ->
      if !field_state.valid?, do: nil, else: "Caption"
    end

    For additional markup, use the H sigil:

    fn ->
      ~H'''
      Caption with <a href="/">link</a>
      '''
    end

    Defaults to nil.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for input elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      input: "",              # Input element
      caption: "",            # Caption element
      input_group: "",        # Wrapper around the grouped input and group button
      input_group_button: "", # Wrapper around slot group_button
      validation_message: "", # Validation message
      input_wrap: "",         # Input wrapper when leading or trailing visual is used
    }

    Defaults to %{input: nil, caption: nil, validation_message: nil, input_group: nil, input_group_button: nil, input_wrap: nil}.

  • name (:string) - Input name attribute (when not using form and field).

  • value (:string) - Text input value attribute (overrides field value when using form and field).

  • type (:string) - Text input type. Defaults to "text".

  • size (:any) - Defines the width of the input (number or number as string).

  • is_contrast (:boolean) - Changes the background color to light gray. Defaults to false.

  • is_full_width (:boolean) - Full width input. Defaults to false.

  • is_hide_webkit_autofill (:boolean) - Hide WebKit's contact info autofill icon. Defaults to false.

  • is_large (:boolean) - Additional padding creates a higher input box. If no width is specified, the input box is slightly wider. Defaults to false.

  • is_small (:boolean) - Smaller (less high) input with smaller text size. Defaults to false.

  • is_monospace (:boolean) - Uses a monospace font. Defaults to false.

  • form_control (:map) - Form control attributes. Places the input inside a form_control/1 component with given attributes, alongside form and field to generate a form control label.

    If only a automatically generated label is required, use convenience attr is_form_control instead.

    Defaults to nil.

  • is_form_control (:boolean) - Places the input inside a form_control/1 component. Attributes form and field are automatically passed to form_control to generate a form control label. If the field is required, its label will show a required marker.

    To configure the form control and label, use attr form_control.

    Defaults to false.

  • validation_message (:any) - Function to write a custom validation message (in case of error or success).

    The function receives a PrimerLive.FieldState struct and returns a validation message or nil.

    A validation message is shown:

    • If form is a Phoenix.HTML.Form, containing a changeset
    • The validation_message function does not return nil

    Function signatures:

    • fun () -> string | nil

    • fun (field_state) -> string | nil

    Conditional error message:

    fn field_state ->
      if !field_state.valid?, do: "Please enter your first name"
    end

    Conditional success message, only shown when changeset.action is :validate:

    fn field_state ->
      if field_state.valid? && field_state.changeset.action == :validate, do: "Is available"
    end

    Defaults to nil.

  • validation_message_id (:string) - Message ID that is usually passed from the form element component to input_validation_message. If not used, the ID will be generated. Defaults to nil.

  • Global attributes are accepted. Supports all globals plus: ["disabled", "max", "maxlength", "min", "minlength", "autocomplete", "pattern", "placeholder", "readonly", "required"].

Slots

  • group_button - Primer CSS "Input group". Attaches a button at the end of the input.

    Example:

    <.text_input>
      <:group_button>
        <.button aria-label="Copy">
          <.octicon name="paste-16" />
        </.button>
      </:group_button>
    </.text_input>
  • leading_visual - Container for a leading visual. Commonly a octicon/1 component is used.

  • trailing_action - Container for a trailing action. Commonly a octicon/1 component, or a button/1 component with an icon (no label) is used. Accepts attributes:

    • is_divider (:boolean) - Adds a separator line.
    • is_visible_with_value (:boolean) - Only show the trailing action when the input has a value.
    • class (:any) - Additional classname.

Reference

Link to this function

textarea(assigns)

Generates a textarea.

<.textarea name="comments" />

Attributes

Use text_input/1 attributes.

Reference

Link to this function

toggle_switch(assigns)

Toggle switch is used to immediately toggle a setting on or off.

<.toggle_switch />

Examples

Add an On/Off label:

<.toggle_switch status_on_label="On" status_off_label="Off" />

When using a PhoenixHTMLHelpers.Form, the label can be derived from the field:

<.toggle_switch form={f} field={:terms_accepted} is_derived_label />

Create a small toggle switch:

<.toggle_switch status_on_label="On" status_off_label="Off" is_small />

Add a loading spinner:

<.toggle_switch status_on_label="On" status_off_label="Off" is_loading />

Attributes

  • form (:any) - Either a Phoenix.HTML.Form or an atom. Defaults to nil.

  • field (:any) - Field name (atom or string). Defaults to nil.

  • name (:string) - Input name attribute (when not using form and field).

  • input_id (:string) - When using form/field. Custom input ID to be used in case the generated IDs cause "Multiple IDs detected" errors. Defaults to nil.

  • checked (:boolean) - The state of the toggle switch (when not using form and field).

  • checked_value (:string) - The value to be sent when the toggle switch is checked. If checked_value equals value, the toggle switch is marked checked. Defaults to "true". Defaults to nil.

  • hidden_input (:string) - Controls if the component will generate a hidden input to submit the unchecked checkbox value or not. Defaults to "true". Defaults to "true".

  • value (:string) - Toggle switch value attribute (overrides field value when using form and field).

  • status_on_label (:string) - Status label for on state.

  • status_off_label (:string) - Status label for off state.

  • is_small (:boolean) - Creates a small toggle switch. Defaults to false.

  • is_loading (:boolean) - Adds a loading spinner. Defaults to false.

  • is_derived_label (:boolean) - Uses a single a label (for both on and off state) derived from the field name (when using field). Defaults to false.

  • is_label_position_end (:boolean) - Places the label after the switch control. Defaults to false.

  • classes (:map) - Additional classnames for toggle switch elements. Any provided value will be appended to the default classname.

    Default map:

    %{
      container: "",
      status_icon: "",
      status_labels_container: "",
      status_label: "",
      status_on_label: "",
      status_off_label: "",
      track: "",
      icons_container: "",
      circle_icon: "",
      line_icon: "",
      loading_icon: "",
      toggle_knob: "",
    }

    Defaults to %{container: nil, status_on_label: nil, status_off_label: nil, status_icon: nil, status_labels_container: nil, status_label: nil, track: nil, icons_container: nil, circle_icon: nil, line_icon: nil, loading_icon: nil, toggle_knob: nil}.

  • class (:any) - Additional classname. Defaults to nil.

  • Global attributes are accepted. Supports all globals plus: ["disabled"].

Reference

Primer Toggle switch

Icons

Link to this function

octicon(assigns)

Renders an icon from the set of GitHub icons, 643 including all size variations.

<.octicon name="comment-16" />

Examples

Pass the icon name with the size: icon "alert-fill" with size "12" becomes "alert-fill-12":

<.octicon name="alert-fill-12" />

Icon "pencil" with size 24:

<.octicon name="pencil-24" />

Custom class:

<.octicon name="pencil-24" class="app-icon" />

Attributes

  • name (:string) (required) - Icon name, e.g. "arrow-left-24". See available icons.
  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Reference

Labels

Link to this function

counter(assigns)

Adds a count label to navigational elements and buttons.

<.counter>12</.counter>

Examples

Apply primary state:

<.counter is_primary>12</.counter>

With an icon:

<.counter><.octicon name="comment-16" /> 1.5K</.counter>

Add an emoji:

<.counter>👍 2</.counter>

Attributes

  • is_primary (:boolean) - Primary color. Defaults to false.
  • is_secondary (:boolean) - Secondary color. Defaults to false.
  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required) - Label content.

Reference

Primer Counter label

Link to this function

issue_label(assigns)

Issue labels are used for adding labels to issues and pull requests. They also come with emoji support.

And issue label is basically labels without a border. It expects background and foreground colors.

<.issue_label>Label</.issue_label>

Examples

Add colors:

<.issue_label color-bg-accent-emphasis color-fg-on-emphasis>Label</.issue_label>

Larger label:

<.issue_label is_big>Label</.issue_label>

Attributes

  • is_big (:boolean) - Larger issue label. Defaults to false.
  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required) - Label content.

Reference

No longer referenced on https://primer.style/design/components

Generates a label element to add metadata or indicate status of items and navigational elements.

<.label>Label</.label>

When using label alongside PhoenixHTMLHelpers.Form.label/2, use a prefix, for example:

use PrimerLive
alias PrimerLive.Component, as: Primer
...
<Primer.label>Label</Primer.label>

Examples

Create a colored label:

<.label is_success>Label</.label>

Create a larger label:

<.label is_large>Label</.label>

Create an inline label:

<p>Lorem Ipsum is simply <.label is_inline>dummy text</.label> of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.</p>

Attributes

  • is_primary (:boolean) - Generates a label with a stronger border. Defaults to false.
  • is_secondary (:boolean) - Generates a label with a subtler text color. Defaults to false.
  • is_accent (:boolean) - Accent color. Defaults to false.
  • is_success (:boolean) - Success color. Defaults to false.
  • is_attention (:boolean) - Attention color. Defaults to false.
  • is_severe (:boolean) - Severe color. Defaults to false.
  • is_danger (:boolean) - Danger color. Defaults to false.
  • is_open (:boolean) - Open color. Defaults to false.
  • is_closed (:boolean) - Closed color. Defaults to false.
  • is_done (:boolean) - Done color. Defaults to false.
  • is_sponsors (:boolean) - Sponsors color. Defaults to false.
  • is_large (:boolean) - Larger label. Defaults to false.
  • is_inline (:boolean) - For use in running text. Adapts line height and font size to text. Defaults to false.
  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required) - Label content.

Reference

Primer Label

Link to this function

state_label(assigns)

Shows an item's status.

State labels are larger and styled with bolded text. Attribute settings allows to apply colors.

<.state_label>Label</.state_label>

Examples

Set a state (applying a background color):

<.state_label is_open>Label</.state_label>

Smaller label:

<.state_label is_small>Label</.state_label>

With an icon:

<.state_label is_open><.octicon name="git-pull-request-16" />Label</.state_label>

Attributes

  • is_draft (:boolean) - Draft state color. Defaults to false.
  • is_open (:boolean) - Open state color. Defaults to false.
  • is_merged (:boolean) - Merged state color. Defaults to false.
  • is_closed (:boolean) - Closed state color. Defaults to false.
  • is_small (:boolean) - Smaller state label. Defaults to false.
  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required) - Label content.

Reference

Primer State label

Layout

Link to this function

layout(assigns)

Layout provides foundational patterns for responsive pages.

<.layout>
  <:main>
    Main content
  </:main>
  <:sidebar>
    Sidebar content
  </:sidebar>
</.layout>

Examples

The position of the sidebar (left or right on desktop) is set by CSS (and can be changed with attribute is_sidebar_position_end).

To place the sidebar at the right:

<.layout is_sidebar_position_end>
  <:main>
    Main content
  </:main>
  <:sidebar>
    Sidebar content
  </:sidebar>
</.layout>

To place the sidebar slot below the main slot on small screens, use attribute is_sidebar_position_flow_row_end:

<.layout is_sidebar_position_flow_row_end>
  <:main>
    Main content
  </:main>
  <:sidebar>
    Sidebar content
  </:sidebar>
</.layout>

When using a divider, use attribute is_divided to make the divider element visible.

Extra divider modifiers for vertical layout (on small screens):

  • is_divided creates a 1px border between main and sidebar
  • is_divided with is_flow_row_hidden hides the divider
  • is_divided with is_flow_row_shallow shows a filled 8px divider
<.layout is_divided>
  <:main>
    Main content
  </:main>
  <:divider></:divider>
  <:sidebar>
    Sidebar content
  </:sidebar>
</.layout>

The modifiers is_centered_xx create a wrapper around main to center its content up to a maximum width. Use with .container-xx classes to restrict the size of the content:

<.layout is_centered_md>
  <:main>
    <div class="container-md">
      Centered md
    </div>
  </:main>
  <:sidebar>
    Sidebar content
  </:sidebar>
</.layout>

Layouts can be nested.

Nested layout, example 1:

<.layout>
  <:main>
    <.layout is_sidebar_position_end is_narrow_sidebar>
      <:main>
        Main content
      </:main>
      <:sidebar>
        Metadata sidebar
      </:sidebar>
    </.layout>
  </:main>
  <:sidebar>
    Default sidebar
  </:sidebar>
</.layout>

Nested layout, example 2:

<.layout>
  <:main>
    <.layout is_sidebar_position_end is_flow_row_until_lg is_narrow_sidebar>
      <:main>
        Main content
      </:main>
      <:sidebar>
        Metadata sidebar
      </:sidebar>
    </.layout>
  </:main>
  <:sidebar>
    Default sidebar
  </:sidebar>
</.layout>

Attributes

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for layout elements.

    Any provided value will be appended to the default classname.

    Default map:

      %{
        layout: "",               # Layout wrapper
        main: "",                 # Main element
        main_center_wrapper: "",  # Wrapper for displaying content centered
        sidebar: "",              # Sidebar element
        divider: "",              # Divider element
      }

    Defaults to %{main: nil, layout: nil, main_center_wrapper: nil, sidebar: nil, divider: nil}.

  • is_divided (:boolean) - Use is_divided in conjunction with the layout_item/1 element with attribute divider to show a divider between the main content and the sidebar. Generates a 1px line between main and sidebar. Defaults to false.

  • is_narrow_sidebar (:boolean) - Smaller sidebar size. Widths: md: 240px, lg: 256px. Defaults to false.

  • is_wide_sidebar (:boolean) - Wider sidebar size. Widths: md: 296px, lg: 320px, xl: 344px. Defaults to false.

  • is_gutter_none (:boolean) - Changes the gutter size to 0px. Defaults to false.

  • is_gutter_condensed (:boolean) - Changes the gutter size to 16px. Defaults to false.

  • is_gutter_spacious (:boolean) - Changes the gutter sizes to: md: 16px, lg: 32px, xl: 40px. Defaults to false.

  • is_sidebar_position_start (:boolean) - Places the sidebar at the start (commonly at the left) (default). Defaults to false.

  • is_sidebar_position_end (:boolean) - Places the sidebar at the end (commonly at the right) on desktop. Defaults to false.

  • is_sidebar_position_flow_row_start (:boolean) - When stacked, render the sidebar first (default). Defaults to false.

  • is_sidebar_position_flow_row_end (:boolean) - When stacked, render the sidebar last. Defaults to false.

  • is_sidebar_position_flow_row_none (:boolean) - When stacked, hide the sidebar. Defaults to false.

  • is_flow_row_until_md (:boolean) - Stacks when container is md. Defaults to false.

  • is_flow_row_until_lg (:boolean) - Stacks when container is lg. Defaults to false.

  • is_centered_lg (:boolean) - Generates a wrapper around main to keep its content centered up to max width "lg". Defaults to false.

  • is_centered_md (:boolean) - Generates a wrapper around main to keep its content centered up to max width "md". Defaults to false.

  • is_centered_xl (:boolean) - Generates a wrapper around main to keep its content centered up to max width "xl". Defaults to false.

  • is_flow_row_hidden (:boolean) - On a small screen (up to 544px). Hides the horizontal divider. Defaults to false.

  • is_flow_row_shallow (:boolean) - On a small screen (up to 544px). Generates a filled 8px horizontal divider. Defaults to false.

  • Global attributes are accepted.

Slots

  • main - Generates a main element. Default gutter sizes: md: 16px, lg: 24px (change with is_gutter_none, is_gutter_condensed and is_gutter_spacious). Stacks when container is sm (change with is_flow_row_until_md and is_flow_row_until_lg). Accepts attributes:
    • order (:any) - Markup order, defines in what order the slot is rendered in HTML. Keyboard navigation follows the markup order. Decide carefully how the focus order should be be by deciding whether main or sidebar comes first in code. The markup order won't affect the visual position. Default value: 2.Must be one of 1, 2, "1", or "2".
  • divider - Generates a divider element. The divider will only be shown with option is_divided. Generates a line between the main and sidebar elements - horizontal when the elements are stacked and vertical when they are shown side by side.
  • sidebar - Generates a sidebar element. Widths: md: 256px, lg: 296px (change with is_narrow_sidebar and is_wide_sidebar). Accepts attributes:
    • order (:any) - See main slot. Default value: 1.Must be one of 1, 2, "1", or "2".

Reference

Primer Layout

Loaders

Link to this function

animated_ellipsis(assigns)

Adds animated ellipsis to indicate progress.

<.animated_ellipsis />

Examples

Inside a header:

<h2>Loading<.animated_ellipsis /></h2>

Inside a label:

<.label>Loading<.animated_ellipsis /></.label>

Inside a button:

<.button is_disabled>Loading<.animated_ellipsis /></.label>

Attributes

  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Reference

No longer referenced on https://primer.style/design/components

Link to this function

spinner(assigns)

Indicator to show that content is being loaded.

<.spinner />

Examples

Set the size (default: 32):

<.spinner size="40" />

Set the circle color (defaults to the current text color):

<.spinner color="red" />
<.spinner color="#ff0000" />
<.spinner color="rgba(250, 50, 150, 0.5)" />

Set the highlight color (defaults to the color value):

<.spinner highlight_color="black" />
<.spinner highlight_color="#000000" />

Alternatively, use octicon/1 with class "anim-rotate", using any circular icon:

<.octicon name="skip-16" class="anim-rotate" />

Attributes

  • size (:any) - Spinner size (number or number as string). Defaults to 32.
  • color (:string) - Spinner color. Defaults to "currentColor".
  • highlight_color (:string) - Spinner highlight segment color. Defaults to the color value.
  • gap_color (:string) - Deprecated: use highlight_color. Since 0.5.1.
  • class (:any) - Additional classname. Defaults to nil.
  • Global attributes are accepted.

Reference

Primer Spinner

Pagination

Link to this function

pagination(assigns)

Pagination is a horizontal set of links to navigate paginated content.

<.pagination
  page_count={@page_count}
  current_page={@current_page}
  link_path={fn page_num -> "/page/#{page_num}" end}
/>

Features

  • Configure the page number ranges for siblings and sides
  • Optionally disable page number display (minimal UI)
  • Custom labels
  • Custom classnames for all elements

If pages in the center (controlled by sibling_count) collide with pages near the sides (controlled by side_count), the center section will be pushed away from the side.

Examples

Simplified paginations, showing Next / Previous buttons:

<.pagination
  ...
  is_numbered="false"
/>

Configure the number of sibling and boundary page numbers to show:

<.pagination
  ...
  sibling_count={1}  # default: 2
  side_count={2}     # default 1
/>

Provide custom labels:

<.pagination
  ...
  labels={
    %{
      next_page: "Nächste Seite",
      previous_page: "Vorherige Seite"
    }
  }
/>

Attributes

  • page_count (:integer) (required) - Result page count.

  • current_page (:integer) (required) - Current page number.

  • link_path (:any) (required) - Function that returns a path for the given page number. The link builder uses Phoenix.Component.link/1 with attribute navigate. Extra options can be passed with link_options.

    Function signature: (page_number) -> path

  • side_count (:integer) - Number of page links at both ends. Defaults to 1.

  • sibling_count (:integer) - Number of page links at each side of the current page number element. Defaults to 2.

  • is_numbered (:any) - Boolean atom or string. Showing page numbers. Defaults to true.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for pagination elements. Any provided value will be appended to the default classname.

    Default map:

    %{
      gap: "",
      pagination_container: "",
      pagination: "",
      previous_page: "",
      next_page: "",
      current_page: "",
      page: ""
    }

    Defaults to %{pagination: nil, current_page: nil, gap: nil, pagination_container: nil, previous_page: nil, next_page: nil, page: nil}.

  • labels (:map) - Textual labels. Any provided value will override the default text. Defaults to %{gap: "…", previous_page: "Previous", next_page: "Next", aria_label_container: "Pagination navigation", aria_label_next_page: "Go to next page", aria_label_current_page: "Current page, page {page_number}", aria_label_page: "Go to page {page_number}", aria_label_previous_page: "Go to previous page"}.

  • link_options (:map) - Link options. Defaults to %{replace: false}.

  • Global attributes are accepted.

Reference

Primer Pagination

Progress

Link to this function

progress(assigns)

Generates a progress bar to visualise task completion.

The item slot creates the colored bar. Its width is a percentage value (0 - 100).

<.progress aria_label="Tasks: 8 of 10 complete">
  <:item width="50"></:item>
</.progress>

Examples

The default bar state is "success" (green). Possible states:

  • "info" - blue
  • "success" - green
  • "warning" - ocher
  • "error" - red
<.progress>
  <:item width="50" state="error"></:item>
</.progress>

Use multiple items to show a multicolored bar:

<.progress>
  <:item width="50" state="success"></:item>
  <:item width="30" state="warning"></:item>
  <:item width="10" state="error"></:item>
  <:item width="5" state="info"></:item>
</.progress>

Create a large progress bar:

<.progress is_large>
  <:item width="50"></:item>
</.progress>

Create a small progress bar:

<.progress is_small>
  <:item width="50"></:item>
</.progress>

Create an inline progress bar:

<span class="text-small color-fg-muted mr-2">4 of 16</span>
<.progress is_inline style="width: 160px;">
  <:item width="25"></:item>
</.progress>

Attributes

  • aria_label (:string) - Adds attribute aria-label to the outer element. Defaults to nil.

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for progress elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      progress: "",      # Outer container
      item: "",          # Colored bar element
      state_success: "", # Color bar modifier
      state_info: "",    # Color bar modifier
      state_warning: "", # Color bar modifier
      state_error: "",   # Color bar modifier
    }

    Defaults to %{progress: nil, item: nil, state_info: nil, state_success: nil, state_warning: nil, state_error: nil}.

  • is_large (:boolean) - Creates a large progress bar. Defaults to false.

  • is_small (:boolean) - Creates a small progress bar. Defaults to false.

  • is_inline (:boolean) - Creates an inline progress bar, to be used next to other elements.

    The "progress" element must have a width, for example:

    <.progress is_inline style="width: 160px;">
      <:item width="25"></:item>
    </.progress>

    Defaults to false.

  • Global attributes are accepted.

Slots

  • item (required) - Colored bar. Accepts attributes:

    • width (:any) - String or integer. Percentage value (0 - 100).
    • state (:string) - Color mapping:
      • "info" - blue
      • "success" - green
      • "warning" - ocher
      • "error" - red

Must be one of "info", "success", "warning", or "error".

  • rest (:any)

Reference

Primer Progress bar

Subhead

Link to this function

subhead(assigns)

Configurable and styled h2 heading.

</.subhead>Plain subhead</.subhead>

Examples

Add a top margin when separating sections on a settings page:

</.subhead is_spacious>Subhead</.subhead>

Create a danger zone heading:

</.subhead is_danger>Plain subhead</.subhead>

Add a description:

<.subhead>
  Heading
  <:description>
    Description
  </:description>
</.subhead>

Add an action (button or link):

<.subhead>
  Heading
  <:actions>
    <.button is_primary>Action</.button>
  </:actions>
</.subhead>

Attributes

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for subhead elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      subhead: "",     # Subhead container
      heading: "",     # h2 heading
      description: "", # Description element
      actions: "",     # Actions section element
    }

    Defaults to %{description: nil, subhead: nil, heading: nil, actions: nil}.

  • is_spacious (:boolean) - Add a top margin. Defaults to false.

  • is_danger (:boolean) - Makes the text bold and red. This is useful for warning users. Defaults to false.

  • Global attributes are accepted.

Slots

  • inner_block (required) - Heading content.
  • description - Description content.
  • actions - Actions content.

Reference

Primer Pagehead

Theme

Creates a wrapper that sets the light/dark color mode and theme, with support for color blindness.

See also PrimerLive.Theme.

Alternative method

Instead of using a wrapper, consider using Theme.html_attributes to set a theme on a component or element directly:

<.button
  {PrimerLive.Theme.html_attributes([color_mode: "dark", dark_theme: "dark_high_contrast"])}
>Button</.button>

<.octicon name="sun-24"
  {PrimerLive.Theme.html_attributes(%{color_mode: "dark", dark_theme: "dark_dimmed"})}
/>

Theme wrapper examples

Use default settings:

<.theme>
  Content
</.theme>

Set the color mode to dark and specify the dark theme:

<.theme color_mode="dark" dark_theme="dark_dimmed">
  Content
</.theme>

Specify light and dark themes:

<.theme color_mode="dark" light_theme="light_high_contrast" dark_theme="dark_high_contrast">
  Content
</.theme>

Use a theme_state struct for easier passing around state:

assigns = assign
  |> assign(:theme_state, %{
    color_mode: "light",
    light_theme: "light_high_contrast",
    dark_theme: "dark_high_contrast"
  })

<.theme theme_state={@theme_state}>
  Content
</.theme>

Attributes

  • theme_state (:map) - Sets all theme values at once. Defaults to nil.

  • color_mode (:string) - Color mode. Defaults to "auto".

  • light_theme (:string) - Light theme.

    Possible values:

    • "light"
    • "light_high_contrast"
    • "light_colorblind"
    • "light_tritanopia"

    Defaults to "light".

  • dark_theme (:string) - Dark theme.

    Possible values:

    • "dark"
    • "dark_dimmed"
    • "dark_high_contrast"
    • "dark_colorblind"
    • "dark_tritanopia"

    Defaults to "dark".

  • is_inline (:boolean) - Renders the wrapper as a span. Useful for setting the color on an inline element. Defaults to false.

  • Global attributes are accepted.

Slots

  • inner_block (required) - Content.

Reference

No longer referenced on https://primer.style/design/components

Link to this function

theme_menu_options(assigns)

Generates theme menu options as an action_list/1, to be used inside an action_menu/1.

See also PrimerLive.Theme.

Menu options

To create a default menu - showing all possible options, using default labels:

<.theme_menu_options
  theme_state={@theme_state}
  default_theme_state={@default_theme_state}
/>
  • theme_state contains the current theme state
  • default_theme_state contains the initial (default) state

Menu

Place the menu options inside an expanding menu:

<.action_menu>
  <:toggle class="btn btn-invisible">
    <.octicon name="sun-16" />
  </:toggle>
  <.theme_menu_options
    theme_state={@theme_state}
  />
</.action_menu>

To make the selected theme persist, follow the instructions in PrimerLive.Theme.

Attributes

  • default_theme_state (:map) - Defines the default (and initial) theme state.

    Pass a map with all theme state keys.

    Change the values to meet specific use cases, for example to set a light color mode instead of "auto":

    %{
      color_mode: "light",
      light_theme: "light",
      dark_theme: "dark_dimmed"
    }

    Defaults to %{color_mode: "auto", light_theme: "light", dark_theme: "dark"}.

  • theme_state (:map) (required) - Defines the current theme state. When using persistent data, this will be passed from the session.

    Pass a map with all theme state keys. For example:

    %{
      color_mode: "light",
      light_theme: "light_high_contrast",
      dark_theme: "dark_high_contrast"
    }
  • update_theme_event (:string) - Event name for the handle_event update callback. The callback will be called with arguments:

    • key: "color_mode", "light_theme", "dark_theme" or "reset"
    • data: any value from color_mode, light_theme or dark_theme; or "" (when key is "reset")

    If update_theme_event has value store_theme, the update theme event handler would be set up like this:

    def handle_event(
      "store_theme",
      %{"data" => data, "key" => key, "value" => _},
      socket
    ) do
      # Persist new theme state ...
    
      {:noreply, socket}
    end

    Defaults to "update_theme".

  • options (:map) - Selectable options (keys).

    To show a limited set of theme options:

    %{
      color_mode: ~w(light dark),
      light_theme: ~w(light light_high_contrast),
      dark_theme: ~w(dark dark_dimmed)
    }

    or even:

    %{
      color_mode: ~w(light dark)
    }

    Defaults to %{color_mode: ["light", "dark", "auto"], light_theme: ["light", "light_high_contrast", "light_colorblind", "light_tritanopia"], dark_theme: ["dark", "dark_dimmed", "dark_high_contrast", "dark_colorblind", "dark_tritanopia"]}.

  • labels (:map) - Custom labels for menu items. For example:

    %{
      color_mode: %{
        light: "Light theme"
      },
      reset: "Reset"
    }

    Defaults to %{reset: "Reset to default", color_mode: %{auto: "System", title: "Theme", dark: "Dark", light: "Light"}, light_theme: %{title: "Light tone", light: "Light", light_colorblind: "Light colorblind", light_high_contrast: "Light high contrast", light_tritanopia: "Light Tritanopia"}, dark_theme: %{title: "Dark tone", dark: "Dark", dark_colorblind: "Dark colorblind", dark_dimmed: "Dark dimmed", dark_high_contrast: "Dark high contrast", dark_tritanopia: "Dark Tritanopia"}}.

  • is_show_group_labels (:boolean) - Set to false to remove the labels above the menu groups. Defaults to true.

  • is_show_reset_link (:boolean) - Set to false to remove the reset link. Defaults to true.

  • is_click_disabled (:boolean) - For demo purposes. Set to true to prevent clicks on options. Defaults to false.

  • id_prefix (:string) - Prefixes generated DOM ids to prevent "duplicate id" errors in the browser. Defaults to nil.

  • Global attributes are accepted.

Timeline

Link to this function

timeline_item(assigns)

Generates a timeline item to display items on a vertical timeline.

<.timeline_item>
  <:badge>
    <.octicon name="flame-16" />
  </:badge>
  Everything is fine
</.timeline_item>

Examples

Add color to the badge by using attribute state. Possible states:

  • "default" - light gray
  • "info" - blue
  • "success" - green
  • "warning" - ocher
  • "error" - red
<.timeline_item state="error">
  <:badge>
    <.octicon name="flame-16" />
  </:badge>
  Everything will be fine
</.timeline_item>

Alternatively, use Primer CSS modifier classes on the badge slot to assign colors:

<.timeline_item>
  <:badge class="color-bg-done-emphasis color-fg-on-emphasis">
    <.octicon name="flame-16" />
  </:badge>
  Everything will be fine
</.timeline_item>

When a link attribute is supplied to the badge slot, links are created with Phoenix.Component.link/1, passing all other slot attributes to the link. Link examples:

<:badge href="#url">href link</:item>
<:badge navigate={Routes.page_path(@socket, :index)}>navigate link</:item>
<:badge patch={Routes.page_path(@socket, :index)}>patch link</:item>

Create a condensed item, reducing the vertical padding and removing the background from the badge item:

<.timeline_item is_condensed>
  <:badge>
    <.octicon name="git-commit-16" />
  </:badge>
  My commit
</.timeline_item>

Display an avatar of the author:

<.timeline_item>
  <:badge>
    <.octicon name="git-commit-16" />
  </:badge>
  <:avatar>
    <.avatar size="6" src="user.jpg" />
  </:avatar>
  Someone's commit
</.timeline_item>

Create a visual break in the timeline with attribute is_break. This adds a horizontal bar across the timeline to show that something has disrupted it.

<.timeline_item state="error">
  <:badge><.octicon name="flame-16" /></:badge>
  Everything will be fine
</.timeline_item>
<.timeline_item is_break />
<.timeline_item state="success">
  <:badge><.octicon name="smiley-16" /></:badge>
  Everything is fine
</.timeline_item>

Attributes

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for timeline elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      timeline_item: "", # Outer container
      badge: "",         # Badge element
      avatar: "",        # Avatar container
      body: "",          # Body element
      state_default: "", # Badge color modifier
      state_info: "",    # Badge color modifier
      state_success: "", # Badge color modifier
      state_warning: "", # Badge color modifier
      state_error: "",   # Badge color modifier
    }

    Defaults to %{body: nil, state_default: nil, state_info: nil, state_success: nil, state_warning: nil, state_error: nil, avatar: nil, timeline_item: nil, badge: nil}.

  • state (:string) - Create a badge color variant by setting the state. Color mapping:

    • "default" - light gray
    • "info" - blue
    • "success" - green
    • "warning" - ocher
    • "error" - red Must be one of "default", "info", "success", "warning", or "error".
  • is_condensed (:boolean) - Creates a condensed item, reducing the vertical padding and removing the background from the badge item. Defaults to false.

  • is_break (:boolean) - Creates a visual break in the timeline. This adds a horizontal bar across the timeline to show that something has disrupted it. Ignores any slots. Defaults to false.

  • Global attributes are accepted.

Slots

  • badge - Badge content. Pass an octicon/1 to display an icon. To create a link element, pass attribute href, navigate or patch. Accepts attributes:
    • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other slot attributes to the link.
    • patch (:string) - Link attribute - see href.
    • navigate (:string) - Link attribute - see href.
    • class (:any) - Additional classname.
    • style (:string) - Additional CSS styles.
    • rest (:any)
  • avatar - Avatar container.
  • inner_block - Item body.

Reference

Primer Timeline

Truncate

Link to this function

truncate(assigns)

Shortens text with ellipsis.

<.truncate>
  <:item>really-long-text</:item>
</.truncate>

Examples

Change the default generated HTML tags (default "span"). Note that the outer element is by default styled as inline-flex, regardless of the provided tag.

<.truncate tag="ol">
  <:item tag="li">really-long-text</:item>
  <:item tag="li">really-long-text</:item>
</.truncate>

Tabs are by default rendered as span elements. To create link elements, pass attribute href, navigate or patch. Link examples:

<:item href="#url">href link</:item>
<:item navigate={Routes.page_path(@socket, :index)}>navigate link</:item>
<:item patch={Routes.page_path(@socket, :index)}>patch link</:item>

Multiple item texts will truncate evenly.

<.truncate>
  <:item>really-long-text</:item>
  <:item>really-long-text</:item>
</.truncate>

Delay the truncating of specific items:

<.truncate>
  <:item>really-long-user-nametext</:item>
  <:item is_primary>really-long-project-name</:item>
</.truncate>

Expand the items on hover and focus:

<.truncate>
  <:item expandable>really-long-text</:item>
  <:item expandable>really-long-text</:item>
</.truncate>

Limit the maximum width by adding max-width style:

<.truncate>
  <:item is_expandable style="max-width: 300px;">
    really-long-text
  </:item>
</.truncate>

Attributes

  • class (:any) - Additional classname. Defaults to nil.

  • classes (:map) - Additional classnames for truncate elements.

    Any provided value will be appended to the default classname.

    Default map:

    %{
      truncate: "", # Truncate wrapper element
      item: "",     # Text wrapper element
    }

    Defaults to %{truncate: nil, item: nil}.

  • tag (:string) - HTML tag used for the truncate wrapper. Defaults to "span".

  • Global attributes are accepted.

Slots

  • item (required) - Wrapper around text to be truncated. Accepts attributes:
    • tag (:string) - HTML tag used for the text wrapper.

      Default: "span".

    • href (:any) - Link attribute. The link is created with Phoenix.Component.link/1, passing all other slot attributes to the link.

    • patch (:string) - Link attribute - see href.

    • navigate (:string) - Link attribute - see href.

    • phx-click (:string)

    • phx-target (:any)

    • phx-value-item (:any) - The payload parameter for the selected value to be sent with an event.

      Examples:

    • is_primary (:boolean) - When using multiple items. Delays the truncating of the item.

    • is_expandable (:boolean) - When using multiple items. Will expand the text on hover and focus.

    • class (:any) - Additional classname.

    • style (:string) - Additional CSS styles.

    • rest (:any)

Reference

Primer Truncate