CinderUI.Components.Layout (cinder_ui v0.1.0)

Copy Markdown View Source

Layout and structural primitives inspired by shadcn/ui.

Included:

View live Layout examples and component docs.

Summary

Functions

Maintains a fixed aspect ratio for content.

Card container.

Right-aligned card action region for buttons/chips.

Card content section.

Card description text.

Card footer section.

Card header section.

Card title text.

Keyboard key badge.

Groups multiple kbd/1 entries.

A bordered surface with card-like styling but no inner padding or gap, for flexible layouts where the caller controls spacing.

Resizable split layout container with optional client-side persistence.

Overflow container that mirrors shadcn scroll-area structure.

Horizontal or vertical separator.

Animated skeleton placeholder.

Functions

aspect_ratio(assigns)

Maintains a fixed aspect ratio for content.

Example

<.aspect_ratio ratio="16 / 9">
  <img src="https://picsum.photos/id/191/800/800" class="h-full w-full object-cover" />
</.aspect_ratio>

Screenshot

aspect_ratio/1 screenshot

View live examples and full component docs.

Attributes

  • ratio (:string) - Defaults to "16 / 9".
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

card(assigns)

Card container.

Examples

heex title="Project status" <.card> <.card_header> <.card_title>Project status</.card_title> <.card_description>Active deployments across environments.</.card_description> </.card_header> <.card_content> <p class="text-sm">Production healthy, staging pending one migration.</p> </.card_content> </.card>

heex title="Team invite" vrt <.card class="max-w-md"> <.card_header class="border-b"> <.card_title>Team invite</.card_title> <.card_action> <.button size={:sm} variant={:outline}>Skip</.button> </.card_action> <.card_description>Invite teammates before launch.</.card_description> </.card_header> <.card_content class="space-y-3"> <.field> <:label for="invite_email">Email</:label> <.input id="invite_email" type="email" placeholder="dev@company.com" /> </.field> </.card_content> <.card_footer class="justify-end gap-2 border-t"> <.button variant={:outline}>Cancel</.button> <.button>Send invite</.button> </.card_footer> </.card>

Minimal

<.card>
  <.card_header>
    <.card_title>Settings</.card_title>
  </.card_header>
  <.card_content>...</.card_content>
</.card>

Screenshot

card/1 screenshot

View live examples and full component docs.

Attributes

  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

card_action(assigns)

Right-aligned card action region for buttons/chips.

Example

heex title="Header action slot" align="full" <.card class="max-w-sm"> <.card_header> <.card_title>Project details</.card_title> <.card_action> <.button size={:sm} variant={:ghost}>Edit</.button> </.card_action> <.card_description>Manage metadata and ownership.</.card_description> </.card_header> </.card>

## Screenshot

card_action/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. Global attributes are accepted. ## Slots

* inner_block (required)

card_content(assigns)

Card content section.

Example

heex title="Card content body" align="full" <.card class="max-w-md"> <.card_header> <.card_title>API key</.card_title> <.card_description>Use this key for network requests.</.card_description> </.card_header> <.card_content class="space-y-3"> <p class="text-sm">Your API key was generated successfully.</p> <.input_group> <.input value="ck_live_************************" readonly /> <.input_group_addon> <.input_group_button variant={:outline}>Copy</.input_group_button> </.input_group_addon> </.input_group> </.card_content> </.card>

## Screenshot

card_content/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. Global attributes are accepted. ## Slots

* inner_block (required)

card_description(assigns)

Card description text.

Examples

heex title="Standard description" align="full" <.card class="max-w-sm"> <.card_header> <.card_title>Billing setup</.card_title> <.card_description> Connect your billing details to unlock premium features. </.card_description> </.card_header> </.card>

heex title="Muted timestamp description" align="full" <.card class="max-w-sm"> <.card_header> <.card_title>System status</.card_title> <.card_description class="text-xs">Last updated 5 minutes ago.</.card_description> </.card_header> </.card>

Screenshot

card_description/1 screenshot

View live examples and full component docs.

Attributes

  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

card_footer(assigns)

Card footer section.

Example

heex title="Card footer actions" align="full" <.card class="max-w-sm"> <.card_header> <.card_title>Notification settings</.card_title> <.card_description>Choose how you want to be notified.</.card_description> </.card_header> <.card_footer class="justify-end gap-2 border-t"> <.button variant={:outline}>Cancel</.button> <.button>Save</.button> </.card_footer> </.card>

## Screenshot

card_footer/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. Global attributes are accepted. ## Slots

* inner_block (required)

card_header(assigns)

Card header section.

Example

heex title="Card header with action" align="full" <.card class="max-w-md"> <.card_header class="border-b"> <.card_title>Billing</.card_title> <.card_action> <.button size={:sm} variant={:outline}>Manage</.button> </.card_action> <.card_description>Usage and invoices for this workspace.</.card_description> </.card_header> <.card_content> <p class="text-sm">Current cycle usage: 72%.</p> </.card_content> </.card>

## Screenshot

card_header/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. Global attributes are accepted. ## Slots

* inner_block (required)

card_title(assigns)

Card title text.

Examples

heex title="Basic title" align="full" <.card class="max-w-sm"> <.card_header> <.card_title>Payment method</.card_title> </.card_header> <.card_content> <p class="text-sm">Visa ending in 4242.</p> </.card_content> </.card>

heex title="Custom title size" align="full" <.card class="max-w-sm"> <.card_header> <.card_title class="text-xl">Pro plan</.card_title> <.card_description>Renews on the 1st of each month.</.card_description> </.card_header> </.card>

Screenshot

card_title/1 screenshot

View live examples and full component docs.

Attributes

  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

kbd(assigns)

Keyboard key badge.

Examples

heex title="Single shortcut key" <.kbd>⌘K</.kbd>

heex title="Shortcut combination" <.kbd_group> <.kbd>⌘</.kbd> <.kbd>K</.kbd> </.kbd_group>

Screenshot

kbd/1 screenshot

View live examples and full component docs.

Attributes

  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

kbd_group(assigns)

Groups multiple kbd/1 entries.

Example

heex title="Key group" <.kbd_group> <.kbd>⌘</.kbd> <.kbd>⇧</.kbd> <.kbd>P</.kbd> </.kbd_group>

## Screenshot

kbd_group/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. Global attributes are accepted. ## Slots

* inner_block (required)

panel(assigns)

A bordered surface with card-like styling but no inner padding or gap, for flexible layouts where the caller controls spacing.

Example

heex title="Panel with custom content" <.panel class="max-w-md"> <div class="p-4 border-b"> <h3 class="text-sm font-medium">Notifications</h3> </div> <ul class="divide-y"> <li class="px-4 py-3 text-sm">New deployment completed</li> <li class="px-4 py-3 text-sm">Invite accepted by teammate</li> </ul> </.panel>

## Screenshot

panel/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. Global attributes are accepted. ## Slots

* inner_block (required)

resizable(assigns)

Resizable split layout container with optional client-side persistence.

Current Scope

resizable/1 currently supports adjacent panel resizing, keyboard handle controls, optional visible handles, and localStorage persistence. It does not yet include collapsed panels, imperative panel APIs, or the richer nested-group ergonomics of a full panel system.

Uses the optional CuiResizable LiveView hook to support drag handles. Provide storage_key to persist panel percentages in localStorage.

Example

heex title="Default" align="full" <.resizable id="resizable-1"> <:panel size={35}> <div class="rounded-md bg-muted p-2 text-xs">Panel A</div> </:panel> <:panel size={65}> <div class="rounded-md bg-muted/60 p-2 text-xs">Panel B</div> </:panel> </.resizable>

heex title="Vertical" align="full" vrt <.resizable id="resizable-2" direction={:vertical} class="h-[240px]"> <:panel size={45}> <div class="h-full rounded-md bg-muted p-2 text-xs">Top panel</div> </:panel> <:panel size={55}> <div class="h-full rounded-md bg-muted/60 p-2 text-xs">Bottom panel</div> </:panel> </.resizable>

heex title="Handle + persisted sizes" align="full" vrt <.resizable id="resizable-3" with_handle storage_key="docs-layout-main"> <:panel size={30} min_size={20}> <div class="rounded-md bg-muted p-2 text-xs">Explorer</div> </:panel> <:panel size={70} min_size={30}> <div class="rounded-md bg-muted/60 p-2 text-xs">Editor</div> </:panel> </.resizable>

## Screenshot

resizable/1 screenshot

View live examples and full component docs.

## Attributes

direction (:atom) - Defaults to :horizontal. Must be one of :horizontal, or :vertical. with_handle (:boolean) - Defaults to false. storage_key (:string) - Defaults to nil. id (:string) - Defaults to nil. class (:string) - Defaults to nil. Global attributes are accepted. ## Slots

* panel (required) - Accepts attributes:

size (:integer) min_size (:integer) * class (:string)

scroll_area(assigns)

Overflow container that mirrors shadcn scroll-area structure.

Example

heex title="Scrollable container" align="full" <.scroll_area class="h-24 rounded-md border"> <div class="space-y-2 text-sm p-4"> <div>Scrollable content</div> <div>Scrollable content</div> <div>Scrollable content</div> <div>Scrollable content</div> <div>Scrollable content</div> </div> </.scroll_area>

## Screenshot

scroll_area/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. viewport_class (:string) - Defaults to nil. * Global attributes are accepted. ## Slots

* inner_block (required)

separator(assigns)

Horizontal or vertical separator.

Example

heex title="Horizontal separator" align="full" <div class="space-y-3"> <p class="text-sm">Overview</p> <.separator /> <p class="text-sm">Details</p> </div>

## Screenshot

separator/1 screenshot

View live examples and full component docs.

## Attributes

orientation (:atom) - Defaults to :horizontal. Must be one of :horizontal, or :vertical. decorative (:boolean) - Defaults to true. class (:string) - Defaults to nil. Global attributes are accepted.

skeleton(assigns)

Animated skeleton placeholder.

Examples

heex title="Single line placeholder" <.skeleton class="h-4 w-[220px]" />

heex title="Avatar + text row" align="full" <div class="flex items-center gap-3"> <.skeleton class="size-10 rounded-full" /> <div class="space-y-2"> <.skeleton class="h-4 w-[180px]" /> <.skeleton class="h-4 w-[120px]" /> </div> </div>

heex title="Card loading state" align="full" vrt <.card class="max-w-sm"> <.card_header> <.skeleton class="h-5 w-[140px]" /> <.skeleton class="h-4 w-[220px]" /> </.card_header> <.card_content class="space-y-2"> <.skeleton class="h-4 w-full" /> <.skeleton class="h-4 w-[90%]" /> <.skeleton class="h-4 w-[75%]" /> </.card_content> </.card>

## Screenshot

skeleton/1 screenshot

View live examples and full component docs.

## Attributes

class (:string) - Defaults to nil. Global attributes are accepted.