View Source Doggo (Doggo v0.3.1)
Collection of Phoenix Components.
Summary
Components
The action bar offers users quick access to primary actions within the application.
The alert component serves as a notification mechanism to provide feedback to the user.
The app bar is typically located at the top of the interface and provides access to key features and navigation options.
Renders profile picture, typically to represent a user.
Renders a badge, typically used for drawing attention to elements like notification counts.
Renders a navigation that sticks to the bottom of the screen.
Renders a box for a section on the page.
Renders a breadcrumb navigation.
Renders a button.
Renders a link (<a>
) that has the role and style of a button.
Use the callout to highlight supplementary information related to the main content.
Renders a card in an article
tag, typically used repetitively in a grid or
flex box layout.
Renders a Date
, DateTime
, or NaiveDateTime
in a <time>
tag.
Renders a DateTime
or NaiveDateTime
in a <time>
tag.
Renders a drawer with a brand
, top
, and bottom
slot.
Renders a navigation menu as a drawer section.
Renders nested navigation items within the :item
slot of the drawer_nav/1
component.
Renders a section in a drawer that contains one or more items, which are not navigation links.
Renders a floating action button.
The fallback component renders a given value unless it is empty, in which case it renders a fallback value instead.
Shows the flash messages as alerts.
Renders a frame with an aspect ratio for images or videos.
Renders a customizable icon using a slot for SVG content.
Renders an icon using an SVG sprite.
Renders an image with an optional caption.
Renders a modal.
Renders a navigation bar.
Renders a list of navigation items.
Renders a header that is specific to the content of the current page.
Renders a list of properties, i.e. key/value pairs.
Renders a skeleton loader, a placeholder for content that is in the process of loading.
Applies a vertical margin between the child elements.
Renders a navigation for form steps.
Renders a switch as a button.
Renders navigation tabs.
Renders a simple table.
Renders a tag, typically used for displaying labels, categories, or keywords.
Renders a Time
, DateTime
, or NaiveDateTime
in a <time>
tag.
Renders content with a tooltip.
Form
Renders the description of an input.
Renders the errors for an input.
Use the field group component to visually group multiple inputs in a form.
Renders a form field including input, label, errors, and description.
Renders the label for an input.
Components
The action bar offers users quick access to primary actions within the application.
It is typically positioned to float above other content.
Example
<.action_bar>
<:item label="Edit" on_click={JS.push("edit")}>
<.icon size={:small}><Lucideicons.pencil aria-hidden /></.icon>
</:item>
<:item label="Move" on_click={JS.push("move")}>
<.icon size={:small}><Lucideicons.move aria-hidden /></.icon>
</:item>
<:item label="Archive" on_click={JS.push("archive")}>
<.icon size={:small}><Lucideicons.archive aria-hidden /></.icon>
</:item>
</.action_bar>
Attributes
class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
item
(required) - Accepts attributes:label
(:string
) (required)on_click
(Phoenix.LiveView.JS
) (required)
The alert component serves as a notification mechanism to provide feedback to the user.
For supplementary information that doesn't require the user's immediate
attention, use callout/1
instead.
Attributes
id
(:string
) - Defaults tonil
.level
(:atom
) - Semantic level of the alert. Defaults to:info
.title
(:string
) - An optional title. Defaults tonil
.on_close
(Phoenix.LiveView.JS
) - JS command to run when the close button is clicked. If not set, no close button is rendered.Defaults to
nil
.close_label
(:any
) - This value will be used as aria label. Consider overriding it in case your app is served in different languages.Defaults to
"close"
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.Global attributes are accepted. Any additional HTML attributes.
Slots
inner_block
(required) - The main content of the alert.icon
- Optional slot to render an icon.
The app bar is typically located at the top of the interface and provides access to key features and navigation options.
Usage
<.app_bar title="Page title">
<:navigation label="Open menu" on_click={JS.push("toggle-menu")}>
<.icon><Lucideicons.menu aria-hidden /></.icon>
</:navigation>
<:action label="Search" on_click={JS.push("search")}>
<.icon><Lucideicons.search aria-hidden /></.icon>
</:action>
<:action label="Like" on_click={JS.push("like")}>
<.icon><Lucideicons.heart aria-hidden /></.icon>
</:action>
</.app_bar>
Attributes
title
(:string
) - The page title. Will be set ash1
. Defaults tonil
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
navigation
- Slot for a single button left of the title, typically used for a menu button that toggles a drawer, or for a back link.Accepts attributes:label
(:string
) (required)on_click
(:any
) (required) - Event name orPhoenix.LiveView.JS
command.
action
- Slot for action buttons right of the title. Accepts attributes:label
(:string
) (required)on_click
(:any
) (required) - Event name orPhoenix.LiveView.JS
command.
Renders profile picture, typically to represent a user.
Example
Minimal example with only the src
attribute:
<.avatar src="avatar.png" />
Render avatar as a circle:
<.avatar src="avatar.png" circle />
Use a placeholder image in case the avatar is not set:
<.avatar src={@user.avatar_url} placeholder={{:src, "fallback.png"}} />
Render an text as the placeholder value:
<.avatar src={@user.avatar_url} placeholder="A" />
Attributes
src
(:string
) - The URL of the avatar image. Ifnil
, the component will use the value provided in the placeholder attribute.Defaults to
nil
.placeholder
(:any
) - Fallback value to render in case thesrc
attribute isnil
.- For a placeholder image, pass a tuple
{:src, url}
. - For other types of placeholder content, such as text initials or inline SVG, pass the content directly. The component will render this content as-is.
If the placeholder value is set to
nil
, no avatar will be rendered if thesrc
isnil
.Defaults to
nil
.- For a placeholder image, pass a tuple
alt
(:string
) - Use alt text to identify the individual in an avatar if their name or identifier isn't otherwise provided in adjacent text. In contexts where the user's name or identifying information is already displayed alongside the avatar, usealt=""
(the default) to avoid redundancy and treat the avatar as a decorative element for screen readers.Defaults to
""
.size
(:atom
) - Defaults to:normal
.circle
(:boolean
) - Defaults tofalse
.loading
(:string
) - Defaults to"lazy"
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.Global attributes are accepted. Any additional HTML attributes.
Renders a badge, typically used for drawing attention to elements like notification counts.
Examples
<.badge>8</.badge>
Attributes
size
(:atom
) - Defaults to:normal
.variant
(:atom
) - Defaults tonil
.
Slots
inner_block
(required)
Renders a box for a section on the page.
Example
Minimal example with only a box body:
<.box>
<p>This is a box.</p>
</.box>
With title, banner, action, and footer:
<.box>
<:title>Profile</:title>
<:banner>
<img src="banner-image.png" alt="" />
</:banner>
<:action>
<.button_link patch={~p"/profiles/#{@profile}/edit}>Edit</.button_link>
</:action>
<p>This is a profile.</p>
<:footer>
<p>Last edited: <%= @profile.updated_at %></p>
</:footer>
</.box>
Attributes
class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
title
- The title for the box.inner_block
(required) - Slot for the content of the box body.action
- A slot for action buttons related to the box.banner
- A slot that can be used to render a banner image in the header.footer
- An optional slot for the footer.
Renders a breadcrumb navigation.
Example
<.breadcrumb>
<:item patch="/categories">Categories</:item>
<:item patch="/categories/1">Reviews</:item>
<:item patch="/categories/1/articles/1">The Movie</:item>
</.breadcrumb>
Attributes
aria_label
(:string
) - Defaults to"breadcrumb"
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
item
(required) - Accepts attributes:navigate
(:string
)patch
(:string
)href
(:string
)
Renders a button.
Examples
<.button>Confirm</.button>
<.button type="submit" variant={:secondary} size={:medium} shape={:pill}>
Submit
</.button>
To indicate a loading state, for example when submitting a form, use the
aria-busy
attribute:
<.button aria-label="Saving..." aria-busy={true}>
click me
</.button>
Attributes
type
(:string
) - Defaults to"button"
.variant
(:atom
) - Defaults to:primary
.fill
(:atom
) - Defaults to:solid
.size
(:atom
) - Defaults to:normal
.shape
(:atom
) - Defaults tonil
.disabled
(:boolean
) - Defaults tonil
.- Global attributes are accepted. Supports all globals plus:
["autofocus", "form", "name", "value"]
.
Slots
inner_block
(required)
Renders a link (<a>
) that has the role and style of a button.
Examples
<.button_link patch={~p"/confirm"}>Confirm</.button>
<.button_link
navigate={~p"/registration"}
variant={:primary}
shape={:pill}>
Submit
</.button>
Attributes
variant
(:atom
) - Defaults to:primary
.fill
(:atom
) - Defaults to:solid
.size
(:atom
) - Defaults to:normal
.shape
(:atom
) - Defaults tonil
.disabled
(:boolean
) - Since<a>
tags cannot have adisabled
attribute, this attribute toggles the"is-disabled"
class.Defaults to
false
.Global attributes are accepted. Supports all globals plus:
["download", "hreflang", "referrerpolicy", "rel", "target", "type", "navigate", "patch", "href", "replace", "method", "csrf_token"]
.
Slots
inner_block
(required)
Use the callout to highlight supplementary information related to the main content.
For information that needs immediate attention of the user, use alert/1
instead.
Example
Standard callout:
<.callout title="Dog Care Tip">
<p>Regular exercise is essential for keeping your dog healthy and happy.</p>
</.callout>
Callout with an icon:
<.callout title="Fun Dog Fact">
<:icon><Heroicons.information_circle /></:icon>
<p>
Did you know? Dogs have a sense of time and can get upset when their
routine is changed.
</p>
</.callout>
Attributes
id
(:string
) - Defaults tonil
.variant
(:atom
) - Defaults to:info
.title
(:string
) - An optional title. Defaults tonil
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
inner_block
(required) - The main content of the alert.icon
- Optional slot to render an icon.
Renders a card in an article
tag, typically used repetitively in a grid or
flex box layout.
Usage
<Doggo.card>
<:image>
<img src="image.png" alt="Picture of a dog dressed in a poncho." />
</:image>
<:header><h2>Dog Fashion Show</h2></:header>
<:main>
The next dog fashion show is coming up quickly. Here's what you need
to look out for.
</:main>
<:footer>
<span>2023-11-15 12:24</span>
<span>Events</span>
</:footer>
</Doggo.card>
Attributes
class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
image
- An optional image slot. The slot content will be rendered within a figure element.header
- The header of the card. You typically want to wrap the header in ah2
orh3
tag, or another header level, depending on the hierarchy on the page.main
- The main content of the card.footer
- A footer of the card, typically containing controls, tags, or meta information.
Renders a Date
, DateTime
, or NaiveDateTime
in a <time>
tag.
Examples
By default, the given value is formatted for display with to_string/1
. This:
<.date value={~D[2023-02-05]} />
Will be rendered as:
<time datetime="2023-02-05">
2023-02-05
</time>
You can also pass a custom formatter function. For example, if you are using ex_cldr_dates_times in your application, you could do this:
<.date
value={~D[2023-02-05]}
formatter={&MyApp.Cldr.Date.to_string!/1}
/>
Which, depending on your locale, may be rendered as:
<time datetime="2023-02-05">
Feb 2, 2023
</time>
Attributes
value
(:any
) (required) - Either aDate
,DateTime
, orNaiveDateTime
.formatter
(:any
) - A function that takes aDate
as an argument and returns the value formatted for display. Defaults toto_string/1
.title_formatter
(:any
) - When provided, this function is used to format the date value for thetitle
attribute. If the attribute is not set, notitle
attribute will be added.Defaults to
nil
.timezone
(:string
) - If set and the given value is aDateTime
, the value will be shifted to that time zone. This affects both the display value and thedatetime
tag. Note that you need to configure a time zone database for this to work.Defaults to
nil
.
Renders a DateTime
or NaiveDateTime
in a <time>
tag.
Examples
By default, the given value is formatted for display with to_string/1
. This:
<.datetime value={~U[2023-02-05 12:22:06.003Z]} />
Will be rendered as:
<time datetime="2023-02-05T12:22:06.003Z">
2023-02-05 12:22:06.003Z
</time>
You can also pass a custom formatter function. For example, if you are using ex_cldr_dates_times in your application, you could do this:
<.datetime
value={~U[2023-02-05 14:22:06.003Z]}
formatter={&MyApp.Cldr.DateTime.to_string!/1}
/>
Which, depending on your locale, may be rendered as:
<time datetime="2023-02-05T14:22:06.003Z">
Feb 2, 2023, 14:22:06 PM
</time>
Attributes
value
(:any
) (required) - Either aDateTime
orNaiveDateTime
.formatter
(:any
) - A function that takes aDateTime
or aNaiveDateTime
as an argument and returns the value formatted for display. Defaults toto_string/1
.title_formatter
(:any
) - When provided, this function is used to format the date time value for thetitle
attribute. If the attribute is not set, notitle
attribute will be added.Defaults to
nil
.precision
(:atom
) - Precision to truncate the given value with. The truncation is applied on both the display value and the value of thedatetime
attribute.Defaults to
nil
.timezone
(:string
) - If set and the given value is aDateTime
, the value will be shifted to that time zone. This affects both the display value and thedatetime
tag. Note that you need to configure a time zone database for this to work.Defaults to
nil
.
Renders a drawer with a brand
, top
, and bottom
slot.
Within the slots, you can use the drawer_nav/1
and drawer_section/1
components.
Example
<.drawer>
<:brand>
<.link navigate={~p"/"}>App</.link>
</:brand>
<:top>
<.drawer_nav aria-label="Main">
<:item>
<.link navigate={~p"/dashboard"}>Dashboard</.link>
</:item>
<:item>
<.drawer_nested_nav>
<:title>Content</:title>
<:item current_page>
<.link navigate={~p"/posts"}>Posts</.link>
</:item>
<:item>
<.link navigate={~p"/comments"}>Comments</.link>
</:item>
</.drawer_nested_nav>
</:item>
</.drawer_nav>
<.drawer_section>
<:title>Search</:title>
<:item><input type="search" placeholder="Search" /></:item>
</.drawer_section>
</:top>
<:bottom>
<.drawer_nav aria-label="User menu">
<:item>
<.link navigate={~p"/settings"}>Settings</.link>
</:item>
<:item>
<.link navigate={~p"/logout"}>Logout</.link>
</:item>
</.drawer_nav>
</:bottom>
</.drawer>
Attributes
class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
brand
- Optional slot for the brand name or logo.top
- Slot for content that is rendered after the brand, at the start of the side bar.bottom
- Slot for content that is rendered at the end of the drawer, pinned to the bottom, if there is enough room.
Renders a section in a drawer that contains one or more items, which are not navigation links.
To render a drawer navigation, use drawer_nav/1
instead.
Example
<.drawer_section>
<:title>Search</:title>
<:item><input type="search" placeholder="Search" /></:item>
</.drawer_section>
Attributes
class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
title
- An optional slot for the title of the section.item
(required) - Items. Accepts attributes:class
(:any
) - Additional CSS classes. Can be a string or a list of strings.
Renders a floating action button.
Example
<.fab label="Add item" phx-click={JS.patch(to: "/items/new")}>
<.icon><Heroicons.plus /></.icon>
</.fab>
Attributes
label
(:string
) (required)variant
(:atom
) - Defaults to:primary
.size
(:atom
) - Defaults to:normal
.shape
(:atom
) - Defaults to:circle
.disabled
(:boolean
) - Defaults tonil
.- Global attributes are accepted.
Slots
inner_block
(required)
The fallback component renders a given value unless it is empty, in which case it renders a fallback value instead.
The values nil
, ""
, []
and %{}
are treated as empty values.
This component optionally applies a formatter function to non-empty values.
The primary purpose of this component is to enhance accessibility. In situations where a value in a table column or property list is set to be invisible or not displayed, it's crucial to provide an alternative text for screen readers.
Examples
Render the value of @some_value
if it's available, or display the
default placeholder otherwise:
<.fallback value={@some_value} />
Apply a formatter function to @some_value
if it is not nil
:
<.fallback value={@some_value} formatter={&format_date/1} />
Set a custom placeholder and text for screen readers:
<.fallback
value={@some_value}
placeholder="n/a"
accessibility_text="not available"
/>
Attributes
value
(:any
) (required) - The value to display. If the value isnil
,""
,[]
or%{}
, the placeholder is rendered instead.formatter
(:any
) - A 1-arity function that takes the value and returns the value for display. The formatter function is only applied ifvalue
is not an empty value.Defaults to
nil
.placeholder
(:any
) - The placeholder to render if thevalue
is empty. Defaults to"-"
.accessibility_text
(:string
) - The text for thearia-label
attribute in case thevalue
is empty. Defaults to"not set"
.
Shows the flash messages as alerts.
Hidden attribute
This component uses the hidden
attribute to hide alerts related to
disconnections. If you explicitly set the CSS display
property for the
alert/1
component, it may override the default browser behavior for the
hidden
attribute, in which case you will see these alerts flashing on each
page load. To prevent this, add the following lines to your CSS styles:
[hidden] {
display: none !important;
}
Examples
<.flash_group flash={@flash} />
Attributes
flash
(:map
) (required) - The map of flash messages.info_title
(:string
) - Defaults to"Success"
.error_title
(:string
) - Defaults to"Error"
.id
(:string
) - An optional ID for the container. Defaults tonil
.class
(:any
) - An optional class name. Defaults to"stack"
.- Global attributes are accepted. Any additional HTML attributes.
Renders a frame with an aspect ratio for images or videos.
This component is used within the image/1
component.
Example
Rendering an image with the aspect ratio 4:3.
<.frame ratio={{4, 3}}>
<img src="image.png" alt="An example image illustrating the usage." />
</.frame>
Rendering an image as a circle.
<.frame circle>
<img src="image.png" alt="An example image illustrating the usage." />
</.frame>
Attributes
ratio
(:any
) - Defaults tonil
.circle
(:boolean
) - Defaults tofalse
.
Slots
inner_block
Renders a customizable icon using a slot for SVG content.
This component does not bind you to a specific set of icons. Instead, it provides a slot for inserting SVG content from any icon library you choose
The label
attribute is used to describe the icon and is by default applied
as an aria-label
for accessibility. If label_placement
is set to
:left
or :right
, the text becomes visible alongside the icon.
Examples
Render an icon with text as aria-label
using the heroicons
library:
<.icon label="report bug"><Heroicons.bug_ant /></.icon>
To display the text visibly:
<.icon label="report bug" label_placement={:right}>
<Heroicons.bug_ant />
</.icon>
aria-hidden
Not all icon libraries set the
aria-hidden
attribute by default. Always make sure that it is set on the<svg>
element that the library renders.
Attributes
label
(:string
) - Text that describes the icon. Iflabel_placement
is set to:hidden
, this text is set asaria-label
attribute.Defaults to
nil
.label_placement
(:atom
) - Position of the label relative to the icon. If set to:hidden
, thelabel
text is used asaria-label
attribute.Defaults to
:hidden
.size
(:atom
) - Defaults to:normal
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.Global attributes are accepted. Any additional HTML attributes.
Slots
inner_block
- Slot for the SVG element.
Renders an icon using an SVG sprite.
Examples
Render an icon with text as aria-label
:
<.icon name="arrow-left" label="Go back" />
To display the text visibly:
<.icon name="arrow-left" label="Go back" label_placement={:right} />
Attributes
name
(:string
) (required) - Icon name as used in the sprite.sprite_url
(:string
) - The URL of the SVG sprite. Defaults to"/assets/icons/sprite.svg"
.label
(:string
) - Text that describes the icon. Iflabel_placement
is set to:hidden
, this text is set asaria-label
attribute.Defaults to
nil
.label_placement
(:atom
) - Position of the label relative to the icon. If set to:hidden
, thelabel
text is used asaria-label
attribute.Defaults to
:hidden
.size
(:atom
) - Defaults to:medium
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.Global attributes are accepted. Any additional HTML attributes.
Renders an image with an optional caption.
Example
<.image
src="https://github.com/woylie/doggo/blob/main/assets/dog_poncho.jpg?raw=true"
alt="A dog wearing a colorful poncho walks down a fashion show runway."
ratio={{16, 9}}
>
<:caption>
Spotlight on canine couture: A dog fashion show where four-legged models
dazzle the runway with the latest in pet apparel.
</:caption>
</.image>
Attributes
src
(:string
) (required) - The URL of the image to render.srcset
(:any
) - A set of image URLs in different sizes. Can be passed as a string or a map.For example, this map:
%{ "1x" => "images/image-1x.jpg", "2x" => "images/image-2x.jpg" }
Will result in this
srcset
:"images/image-1x.jpg 1x, images/image-2x.jpg 2x"
See https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset.
Defaults to
nil
.sizes
(:string
) - Specifies media conditions for the image widths, if thesrcset
attribute uses intrinsic widths.See https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes.
Defaults to
nil
.alt
(:string
) (required) - A text description of the image for screen reader users and those with slow internet. Effective alt text should concisely capture the image's essence and function, considering its context within the content. Aim for clarity and inclusivity without repeating information already conveyed by surrounding text, and avoid starting with "Image of" as screen readers automatically announce image presence.width
(:integer
) - Defaults tonil
.height
(:integer
) - Defaults tonil
.loading
(:string
) - Defaults to"lazy"
.ratio
(:any
) - Defaults tonil
.Global attributes are accepted. Any additional HTML attributes.
Slots
caption
Renders a modal.
Usage
There are two primary ways to manage the display of the modal: via URL state
or by setting and removing the open
attribute.
With URL
To toggle the modal visibility based on the URL:
- Use the
:if
attribute to conditionally render the modal when a specific live action matches. - Set the
on_cancel
attribute to patch back to the original URL when the user chooses to close the modal. - Set the
open
attribute to declare the modal's initial visibility state.
Example
<.modal
:if={@live_action == :show}
id="pet-modal"
on_cancel={JS.patch(~p"/pets")}
open
>
<:title>Show pet</:title>
<p>My pet is called Johnny.</p>
<:footer>
<.link phx-click={JS.exec("data-cancel", to: "#pet-modal")}>
Close
</.link>
</:footer>
</.modal>
To open the modal, patch or navigate to the URL associated with the live action.
<.link patch={~p"/pets/#{@id}"}>show</.link>
Without URL
To toggle the modal visibility dynamically with the open
attribute:
- Omit the
open
attribute in the template. - Use the
show_modal
andhide_modal
functions to change the visibility.
Example
<.modal id="pet-modal">
<:title>Show pet</:title>
<p>My pet is called Johnny.</p>
<:footer>
<.link phx-click={JS.exec("data-cancel", to: "#pet-modal")}>
Close
</.link>
</:footer>
</.modal>
To open modal, use the show_modal
function.
<.link phx-click={show_modal("pet-modal")}>show</.link>
CSS
To hide the modal when the open
attribute is not set, use the following CSS
styles:
dialog.modal:not([open]),
dialog.modal[open="false"] {
display: none;
}
Semantics
While the showModal()
JavaScript function is typically recommended for
managing modal dialog semantics, this component utilizes the open
attribute
to control visibility. This approach is chosen to eliminate the need for
library consumers to add additional JavaScript code. To ensure proper
modal semantics, the aria-modal
attribute is added to the dialog element.
Attributes
id
(:string
) (required)open
(:boolean
) - Initializes the modal as open. Defaults tofalse
.on_cancel
(Phoenix.LiveView.JS
) - Defaults to%Phoenix.LiveView.JS{ops: []}
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
title
(required)inner_block
(required) - The modal body.close
- The content for the 'close' link. Defaults to the word 'close'.footer
Renders a header that is specific to the content of the current page.
Unlike a site-wide header, which offers consistent navigation and elements like logos throughout the website or application, this component is meant to describe the unique content of each page. For instance, on an article page, it would display the article's title.
It is typically used as a direct child of the <main>
element.
Example
<main>
<.page_header title="Puppy Profiles" subtitle="Share Your Pup's Story">
<:action>
<.button_link patch={~p"/puppies/new"}>Add New Profile</.button_link>
</:action>
</.page_header>
<section>
<!-- Content -->
</section>
</main>
Attributes
title
(:string
) (required) - The title for the current page.subtitle
(:string
) - An optional sub title. Defaults tonil
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
action
- A slot for action buttons related to the current page.
Renders a list of properties, i.e. key/value pairs.
Example
<.property_list>
<:prop label={gettext("Name")}>George</:prop>
<:prop label={gettext("Age")}>42</:prop>
</.property_list>
Attributes
class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
prop
- A property to be rendered. Accepts attributes:label
(:string
) (required)
Renders a skeleton loader, a placeholder for content that is in the process of loading.
It mimics the layout of the actual content, providing a better user experience during loading phases.
Usage
Render one of several primitive types:
<.skeleton type={:text_line} />
Combine primitives for complex layouts:
<div class="card-skeleton" aria-busy="true">
<.skeleton type={:image} />
<.skeleton type={:text_line} />
<.skeleton type={:text_line} />
<.skeleton type={:text_line} />
<.skeleton type={:rectangle} />
</div>
To modify the primitives for your use cases, you can use custom classes or CSS properties:
<.skeleton type={:text_line} class="header" />
<.skeleton type={:image} style="--aspect-ratio: 75%;" />
Aria-busy attribute
When using skeleton loaders, apply aria-busy="true"
to the container element
that contains the skeleton layout. For standalone use, add the attribute
directly to the individual skeleton loader.
Async result component
The easiest way to load data asynchronously and render a skeleton loader is
to use LiveView's
async operations
and Phoenix.Component.async_result/1
.
Assuming you defined a card skeleton component as described above:
<.async_result :let={puppy} assign={@puppy}>
<:loading><.card_skeleton /></:loading>
<:failed :let={_reason}>There was an error loading the puppy.</:failed>
<!-- Card for loaded content -->
</.async_result>
Attributes
type
(:atom
) (required) - Must be one of:text_line
,:text_block
,:image
,:circle
,:rectangle
, or:square
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Applies a vertical margin between the child elements.
Example
<.stack>
<div>some block</div>
<div>some other block</div>
</.stack>
To apply a vertical margin on nested elements as well, set recursive
to
true
.
<.stack recursive={true}>
<div>
<div>some nested block</div>
<div>another nested block</div>
</div>
<div>some other block</div>
</.stack>
Attributes
recursive
(:boolean
) - Iftrue
, the stack margins will be applied to nested elements as well. Defaults tofalse
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
inner_block
(required)
Renders a navigation for form steps.
Examples
With patch navigation:
<.steps current_step={0}>
<:step on_click={JS.patch(to: ~p"/form/step/personal-information")}>
Profile
</:step>
<:step on_click={JS.patch(to: ~p"/form/step/delivery")}>
Delivery
</:step>
<:step on_click={JS.patch(to: ~p"/form/step/confirmation")}>
Confirmation
</:step>
</.steps>
With push events:
<.steps current_step={0}>
<:step on_click={JS.push("go-to-step", value: %{step: "profile"})}>
Profile
</:step>
<:step on_click={JS.push("go-to-step", value: %{step: "delivery"})}>
Delivery
</:step>
<:step on_click={JS.push("go-to-step", value: %{step: "confirmation"})}>
Confirmation
</:step>
</.steps>
Attributes
label
(:string
) - Defaults to"Form steps"
.current_step
(:integer
) (required) - The current form step, zero-based index.completed_label
(:string
) - Visually hidden text that is rendered for screen readers for completed steps.Defaults to
"Completed: "
.linear
(:boolean
) - Iftrue
, clickable links are only rendered for completed steps.If
false
, also upcoming steps are clickable.If you don't want any clickable links to be rendered, omit the
on_click
attribute on the:step
slots.Defaults to
false
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.Global attributes are accepted. Any additional HTML attributes.
Slots
step
(required) - Accepts attributes:on_click
(:any
) - Event name orPhoenix.LiveView.JS
command to execute when clicking on the step.
Renders a switch as a button.
If you want to render a switch as part of a form, use the input/1
component
with the type "switch"
instead.
Note that this component only renders a button with a label, a state, and
<span>
with the class switch-control
. You will need to style the switch
control span with CSS in order to give it the appearance of a switch.
Examples
<.switch
label="Subscribe"
checked={true}
phx-click="toggle-subscription"
/>
Attributes
label
(:string
) (required)on_text
(:string
) - Defaults to"On"
.off_text
(:string
) - Defaults to"Off"
.checked
(:boolean
) - Defaults tofalse
.- Global attributes are accepted.
Renders a simple table.
Examples
<.table id="pets" rows={@pets}>
<:col :let={p} label="name"><%= p.name %></:col>
<:col :let={p} label="age"><%= p.age %></:col>
</.table>
Attributes
id
(:string
) (required)rows
(:list
) (required) - The list of items to be displayed in rows.caption
(:string
) - Content for the<caption>
element. Defaults tonil
.row_id
(:any
) - Overrides the default function that retrieves the row ID from a stream item. Defaults tonil
.row_click
(Phoenix.LiveView.JS
) - Sets thephx-click
function attribute for each rowtd
. Expects to be a function that receives a row item as an argument. This does not add thephx-click
attribute to theaction
slot.Example:
row_click={&JS.navigate(~p"/users/#{&1}")}
Defaults to
nil
.row_item
(:any
) - This function is called on the row item before it is passed to the :col and :action slots.Defaults to
&Function.identity/1
.
Slots
col
(required) - For each column to render, add one<:col>
element.<:col :let={pet} label="Name" field={:name} col_style="width: 20%;"> <%= pet.name %> </:col>
Any additional assigns will be added as attributes to the
<td>
elements.Accepts attributes:
label
(:any
) - The content for the header column.col_attrs
(:string
) - If set, a<colgroup>
element is rendered and the attributes are added to the<col>
element of the respective column.
action
- The slot for showing user actions in the last table column. These columns do not receive therow_click
attribute.<:action :let={user}> <.link navigate={~p"/users/#{user}"}>Show</.link> </:action>
Accepts attributes:
label
(:string
) - The content for the header column.col_attrs
(:string
) - If set, a<colgroup>
element is rendered and the attributes are added to the<col>
element of the respective column.
foot
- You can optionally add afoot
. The inner block will be rendered inside atfoot
element.<Flop.Phoenix.table> <:foot> <tr><td>Total: <span class="total"><%= @total %></span></td></tr> </:foot> </Flop.Phoenix.table>
Renders a tag, typically used for displaying labels, categories, or keywords.
Examples
Plain tag:
<.tag>Well-Trained</.tag>
With icon:
<.tag>
Puppy
<.icon><Heroicons.edit /></icon>
</.tag>
With delete button:
<.tag>
High Energy
<button
phx-click="remove-tag"
phx-value-tag="high-energy"
aria-label="Remove tag"
>
<.icon><Heroicons.x /></icon>
</button>
</.tag>
Attributes
size
(:atom
) - Defaults to:normal
.variant
(:atom
) - Defaults tonil
.shape
(:atom
) - Defaults tonil
.
Slots
inner_block
(required)
Renders a Time
, DateTime
, or NaiveDateTime
in a <time>
tag.
Examples
By default, the given value is formatted for display with to_string/1
. This:
<.time value={~T[12:22:06.003Z]} />
Will be rendered as:
<time datetime="12:22:06.003">
12:22:06.003
</time>
You can also pass a custom formatter function. For example, if you are using ex_cldr_dates_times in your application, you could do this:
<.time
value={~T[12:22:06.003]}
formatter={&MyApp.Cldr.Time.to_string!/1}
/>
Which, depending on your locale, may be rendered as:
<time datetime="14:22:06.003">
14:22:06 PM
</time>
Attributes
value
(:any
) (required) - Either aTime
,DateTime
, orNaiveDateTime
.formatter
(:any
) - A function that takes aTime
,DateTime
, orNaiveDateTime
as an argument and returns the value formatted for display. Defaults toto_string/1
.title_formatter
(:any
) - When provided, this function is used to format the time value for thetitle
attribute. If the attribute is not set, notitle
attribute will be added.Defaults to
nil
.precision
(:atom
) - Precision to truncate the given value with. The truncation is applied on both the display value and the value of thedatetime
attribute.Defaults to
nil
.timezone
(:string
) - If set and the given value is aDateTime
, the value will be shifted to that time zone. This affects both the display value and thedatetime
tag. Note that you need to configure a time zone database for this to work.Defaults to
nil
.
Renders content with a tooltip.
There are different ways to render a tooltip. This component renders a <div>
with the tooltip
role, which is hidden unless the element is hovered on or
focused. For example CSS for this kind of tooltip, refer to
ARIA: tooltip role.
A simpler alternative for styled text-only tooltips is to use a data attribute
and the attr
CSS function.
Doggo does not provide a component for that kind of tooltip, since it is
controlled by attributes only. You can check
Pico CSS for an example implementation.
Example
With an inline text:
<p>
Did you know that the
<.tooltip id="labrador-info">
Labrador Retriever
<:tooltip>
<p><strong>Labrador Retriever</strong></p>
<p>
Labradors are known for their friendly nature and excellent
swimming abilities.
</p>
</:tooltip>
</.tooltip>
is one of the most popular dog breeds in the world?
</p>
If the inner block contains a link, add the :contains_link
attribute:
<p>
Did you know that the
<.tooltip id="labrador-info" contains_link>
<.link navigate={~p"/labradors"}>Labrador Retriever</.link>
<:tooltip>
<p><strong>Labrador Retriever</strong></p>
<p>
Labradors are known for their friendly nature and excellent
swimming abilities.
</p>
</:tooltip>
</.tooltip>
is one of the most popular dog breeds in the world?
</p>
Attributes
id
(:string
) (required)contains_link
(:boolean
) - Iffalse
, the component setstabindex="0"
on the element wrapping the inner block, so that the tooltip can be made visible by focusing the element.If the inner block already contains an element that is focusable, such as a link or a button, set this attribute to
true
.Defaults to
false
.
Slots
inner_block
(required)tooltip
(required)
Form
Renders the description of an input.
Attributes
for
(:string
) (required) - The ID of the input.description
(:any
)
Renders the errors for an input.
Attributes
for
(:string
) (required) - The ID of the input.errors
(:list
) (required) - A list of errors as strings.
Use the field group component to visually group multiple inputs in a form.
This component is intended for styling purposes and does not provide semantic
grouping. For semantic grouping of related form elements, use the <fieldset>
and <legend>
HTML elements instead.
Examples
Visual grouping of inputs:
<.field_group>
<.input field={@form[:given_name]} label="Given name" />
<.input field={@form[:family_name]} label="Family name"/>
</.field_group>
Semantic grouping (for reference):
<fieldset>
<legend>Personal Information</legend>
<.input field={@form[:given_name]} label="Given name" />
<.input field={@form[:family_name]} label="Family name"/>
</fieldset>
Attributes
class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
inner_block
(required)
Renders a form field including input, label, errors, and description.
A Phoenix.HTML.FormField
may be passed as argument,
which is used to retrieve the input name, id, and values.
Otherwise all attributes may be passed explicitly.
Types
In addition to all HTML input types, the following type values are also supported:
"select"
- For<select>
elements.
Gettext
To translate field errors using Gettext, configure your Gettext module in
config/config.exs
.
config :doggo, gettext: MyApp.Gettext
Alternatively, pass the Gettext module as an attribute:
<.input field={@form[:name]} gettext={MyApp.Gettext} />
Label positioning
The component does not provide an attribute to modify label positioning directly. Instead, label positioning should be handled with CSS. If your application requires different label positions, such as horizontal and vertical layouts, it is recommended to add a modifier class to the form.
For example, the default style could position labels above inputs. To place
labels to the left of the inputs in a horizontal form layout, you can add an
is-horizontal
class to the form:
<.form class="is-horizontal">
<!-- inputs -->
</.form>
Then, in your CSS, apply the necessary styles to the .field
class within
forms having the is-horizontal
class:
form.is-horizontal .field {
// styles to position label left of the input
}
The component has a hide_label
attribute to visually hide labels while still
making them accessible to screen readers. If all labels within a form need to
be visually hidden, it may be more convenient to define a
.has-visually-hidden-labels
modifier class for the <form>
.
<.form class="has-visually-hidden-labels">
<!-- inputs -->
</.form>
Ensure to take checkbox and radio labels into consideration when writing the CSS styles.
Examples
<.input field={@form[:name]} />
<.input field={@form[:email]} type="email" />
Radio group and checkbox group
The radio-group
and checkbox-group
types allow you to easily render groups
of radio buttons or checkboxes with a single component invocation. The
options
attribute is required for these types and has the same format as
the options for the select
type, except that options may not be nested.
<.input
field={@form[:email]}
type="checkbox-group"
label="Cuisine"
options={[
{"Mexican", "mexican"},
{"Japanese", "japanese"},
{"Libanese", "libanese"}
]}
/>
Note that the checkbox-group
type renders an additional hidden input with
an empty value before the checkboxes. This ensures that a value exists in case
all checkboxes are unchecked. Consequently, the resulting list value includes
an extra empty string. While Ecto.Changeset.cast/3
filters out empty strings
in array fields by default, you may need to handle the additional empty string
manual in other contexts.
Attributes
id
(:any
) - Defaults tonil
.name
(:any
)label
(:string
) - Defaults tonil
.hide_label
(:boolean
) - Adds an "is-visually-hidden" class to the<label>
. This option does not apply to checkbox and radio inputs.Defaults to
false
.value
(:any
)type
(:string
) - Defaults to"text"
.field
(Phoenix.HTML.FormField
) - A form field struct, for example: @form[:name].errors
(:list
)validations
(:list
) - A list of HTML input validation attributes (required
,minlength
,maxlength
,min
,max
,pattern
). The attributes are derived automatically from the form.checked_value
(:string
) - The value that is sent when the checkbox is checked. Defaults to"true"
.checked
(:boolean
) - The checked attribute for checkboxes.prompt
(:string
) - An optional prompt for select elements. Defaults tonil
.options
(:list
) - A list of options.This attribute is supported for the following types:
"select"
"radio-group"
"checkbox-group"
- other text types, date and time types, and the
"range"
type
If this attribute is set for types other than select, radio, and checkbox, a datalist is rendered for the input.
See
Phoenix.HTML.Form.options_for_select/2
for the format. Note that only the select supports nested options.Defaults to
nil
.multiple
(:boolean
) - Sets themultiple
attribute on a select element to allow selecting multiple options.Defaults to
false
.gettext
(:atom
) - The Gettext module to use for translating error messages. This option can also be set globally, see above.Global attributes are accepted. Supports all globals plus:
["accept", "autocomplete", "capture", "cols", "disabled", "form", "list", "max", "maxlength", "min", "minlength", "multiple", "passwordrules", "pattern", "placeholder", "readonly", "required", "rows", "size", "step"]
.
Slots
description
- A field description to render underneath the input.addon_left
- Can be used to render an icon left in the input. Only supported for single-line inputs.addon_right
- Can be used to render an icon left in the input. Only supported for single-line inputs.
Renders the label for an input.
Attributes
for
(:string
) - The ID of the input. Defaults tonil
.required
(:boolean
) - If set totrue
, a 'required' mark is rendered. Defaults tofalse
.visually_hidden
(:boolean
) - Adds an "is-visually-hidden" class to the<label>
. Defaults tofalse
.class
(:any
) - Additional CSS classes. Can be a string or a list of strings. Defaults to[]
.- Global attributes are accepted. Any additional HTML attributes.
Slots
inner_block
(required)