Cairnloop.Web.Components (cairnloop v0.5.1)

Copy Markdown View Source

Cairnloop's shared operator-UI component library.

Stateless Phoenix.Component function components that render the design system's .cl-* classes. The styling itself ships in priv/static/cairnloop.css (self-contained, token-driven, themeable) — these components only emit markup, so the CSS file is the single source of visual truth.

Import into a LiveView with import Cairnloop.Web.Components and compose:

<.cl_button variant="primary" phx-click="save">Save policy</.cl_button>
<.cl_chip variant="warning" label="Needs review" />
<.cl_card></.cl_card>

Design rules enforced here (so screens can't re-introduce drift):

  • Never state-by-color-alone (brand §7.5) — cl_chip/cl_banner always pair a status color with a distinct-silhouette icon and a text label.
  • Self-contained iconscl_icon is an inline SVG set, so the library never requires the host to install heroicons or an icon font.
  • Tokens only — components carry semantic .cl-* classes; spacing/color/motion come from --cl-* custom properties, never inline hex.

Summary

Functions

Persistent, region-level status banner (use for actionable status, not transient confirmations).

Breadcrumb trail (renders after the user goes a level deep).

Primary/secondary/danger/ghost button. Buttons and inputs share token heights.

Surface card. Optional :header slot renders a bordered title row; route_active adds the copper rail marker.

Status chip — color + icon + text together (never color alone). label or an inner block supplies the text; the icon is chosen from the variant unless overridden.

Calm, reassuring empty state. :icon slot optional; title + inner block carry the copy.

Self-contained inline-SVG icon. Distinct silhouettes so status reads without color (colorblind-safe, grayscale-safe). 16px default; size overrides.

Persistent navigation shell. Pass current (a destination key) so the active link gets a 3-cue "you are here" state (weight + copper underline + fill, never color alone). destinations is a list of %{key, label, href, icon, count} maps.

Cockpit Home job card — a verb-led job, ONE actionable "needs-you" count, and a CTA. calm? renders the count in the success hue (used for the all-caught-up zero state).

Functions

cl_banner(assigns)

Persistent, region-level status banner (use for actionable status, not transient confirmations).

Attributes

  • variant (:string) - Defaults to "neutral". Must be one of "success", "info", "warning", "danger", "ai", or "neutral".
  • icon (:string) - Defaults to nil.
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block (required)

cl_breadcrumb(assigns)

Breadcrumb trail (renders after the user goes a level deep).

Attributes

  • items (:list) (required) - list of %{label, href} (last item is current, no href).

cl_button(assigns)

Primary/secondary/danger/ghost button. Buttons and inputs share token heights.

Attributes

  • variant (:string) - Defaults to "default". Must be one of "default", "primary", "danger", or "ghost".
  • size (:string) - Defaults to "md". Must be one of "sm", "md", or "lg".
  • type (:string) - Defaults to "button".
  • class (:string) - Defaults to nil.
  • Global attributes are accepted. Supports all globals plus: ["disabled", "form", "name", "value", "phx-click", "phx-value-id", "phx-disable-with", "data-confirm"].

Slots

  • inner_block (required)

cl_card(assigns)

Surface card. Optional :header slot renders a bordered title row; route_active adds the copper rail marker.

Attributes

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

Slots

  • header
  • inner_block (required)

cl_chip(assigns)

Status chip — color + icon + text together (never color alone). label or an inner block supplies the text; the icon is chosen from the variant unless overridden.

Attributes

  • variant (:string) - Defaults to "neutral". Must be one of "success", "info", "warning", "danger", "ai", or "neutral".
  • label (:string) - Defaults to nil.
  • icon (:string) - Defaults to nil.
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • inner_block

cl_empty(assigns)

Calm, reassuring empty state. :icon slot optional; title + inner block carry the copy.

Attributes

  • title (:string) (required)
  • icon (:string) - Defaults to "compass".
  • class (:string) - Defaults to nil.

Slots

  • inner_block

cl_icon(assigns)

Self-contained inline-SVG icon. Distinct silhouettes so status reads without color (colorblind-safe, grayscale-safe). 16px default; size overrides.

Attributes

  • name (:string) (required)
  • size (:string) - Defaults to "16".
  • class (:string) - Defaults to nil.
  • Global attributes are accepted.

cl_shell(assigns)

Persistent navigation shell. Pass current (a destination key) so the active link gets a 3-cue "you are here" state (weight + copper underline + fill, never color alone). destinations is a list of %{key, label, href, icon, count} maps.

Attributes

  • current (:atom) - Defaults to nil.
  • destinations (:list) (required)
  • brand (:string) - Defaults to "Cairnloop".

Slots

  • inner_block (required)

cl_stat(assigns)

Cockpit Home job card — a verb-led job, ONE actionable "needs-you" count, and a CTA. calm? renders the count in the success hue (used for the all-caught-up zero state).

Attributes

  • job (:string) (required)
  • count (:any) (required)
  • meta (:string) - Defaults to nil.
  • href (:string) - Defaults to nil.
  • cta (:string) - Defaults to nil.
  • icon (:string) - Defaults to nil.
  • calm? (:boolean) - Defaults to false.
  • Global attributes are accepted.

Slots

  • inner_block