LineaUI.Components.Tabs (linea_ui v0.1.1)

Copy Markdown View Source

LineOne's tabs: underlined (line), on a gray track (boxed), rounded (pill) and plain text (text), laid out horizontally or vertically, with or without icons.

<.tabs id="profile-tabs" selected="home">
  <:tab name="home">Home</:tab>
  <:tab name="profile">Profile</:tab>
  <:panel name="home">…</:panel>
  <:panel name="profile">…</:panel>
</.tabs>

<.tabs id="boxed" variant="boxed">
  <:tab name="home"><svg class="size-4.5">…</svg><span>Home</span></:tab>
  <:panel name="home">…</:panel>
</.tabs>

The selected tab comes from selected and switching happens in the browser (click, ←/→ or ↑/↓, Home and End) without a round trip. A choice made in the browser survives patches; when the server changes selected, the server wins.

on_change tells the server what was chosen:

<.tabs id="server-tabs" selected={@tab} on_change="select_tab">…</.tabs>
<.tabs id="period" variant="boxed" size="sm"><:tab name="month">Last month</:tab></.tabs>
<.tabs id="range" variant="text"><:tab name="week">Last 7 days</:tab><:tab name="all">All time</:tab></.tabs>

def handle_event("select_tab", %{"id" => "server-tabs", "value" => tab}, socket),
  do: {:noreply, assign(socket, tab: tab)}

Every selection also dispatches a bubbling linea:change DOM event with detail: %{id: id, value: name, tab: name}.

Summary

Functions

Renders a tab list and its panels. Each :tab is matched to the :panel with the same name.

Functions

tabs(assigns)

Renders a tab list and its panels. Each :tab is matched to the :panel with the same name.

<.tabs id="settings" selected={@tab} variant="boxed" on_change="tab_changed">
  <:tab name="general">General</:tab>
  <:tab name="billing" disabled>Billing</:tab>
  <:panel name="general">…</:panel>
  <:panel name="billing">…</:panel>
</.tabs>

Events: with on_change="tab_changed" the hook pushes "tab_changed" with %{"id" => "settings", "value" => "general", "tab" => "general"} (to target or the closest LiveComponent) after the browser switched; with on_change={%JS{}} the commands run on the tabs element. Either way a bubbling linea:change DOM event carries detail: %{id, value, tab}; tab repeats value.

Attributes

  • id (:string) (required) - Needed by the hook and for the tab/panel ids.

  • selected (:string) - The name of the selected tab; the first one when not given. Defaults to nil.

  • variant (:string) - line underlines the selected tab, boxed lifts it off a gray track, pill fills a rounded tab, text is plain text that only changes color (no border or background; spacing comes from list_class, space-x-4 by default). Defaults to "line". Must be one of "line", "boxed", "pill", or "text".

  • size (:string) - For boxed: md is px-3 py-1.5, sm is LineOne's compact px-3 py-1 text-xs-plus, xs is px-2.5 py-0.5 text-xs. Defaults to "md". Must be one of "xs", "sm", or "md".

  • color (:string) - The fill of the selected pill tab and the text color of the selected text tab. Defaults to "primary". Must be one of "primary", or "neutral".

  • orientation (:string) - Defaults to "horizontal". Must be one of "horizontal", or "vertical".

  • bordered (:boolean) - For line: draws the gray rule the tabs sit on. Defaults to false.

  • overlap (:boolean) - For a bordered line: the selected tab's line covers the gray rule instead of sitting on it. Defaults to false.

  • grow (:boolean) - The tabs share the whole width of the list. Defaults to false.

  • transition (:string) - The way a panel comes in: sliding from the right (left) or from below (up). Defaults to "left". Must be one of "left", "up", or "none".

  • on_change (:any) - Run when a tab is chosen in the browser. An event name is pushed with %{"id" => id, "value" => name, "tab" => name}; a %JS{} is executed on the tabs element.

    Defaults to nil.

  • target (:any) - The phx-target of on_change. Defaults to nil.

  • list_class (:any) - Extra classes for the tab list. Defaults to nil.

  • panels_class (:any) - Extra classes for the wrapper of the panels. Defaults to nil.

  • class (:any) - Defaults to nil.

  • Global attributes are accepted.

Slots

  • tab (required) - A tab button; its content is the label, icons included. Accepts attributes:
    • name (:string) (required) - Matches the :panel it shows and is the on_change value.
    • disabled (:boolean) - Skipped by clicks and the arrow keys.
    • class (:any)
  • panel - The content shown while the tab with the same name is selected. Accepts attributes:
    • name (:string) (required) - The name of its tab.
    • class (:any)