LanternUI.Components.Waterfall (LanternUI v0.8.2)

Copy Markdown View Source

Waterfall: horizontal spans laid out on ONE shared time axis, with a ruler. No Fluxon equivalent. Pure presentational server render; no JS hook.

<.waterfall id="run-phases" ticks={@ticks} label="Phase">
  <.waterfall_lane label="plan" status={:done} left={0.0} width={31.4} bar_label="4m 12s">
    <:icon><.icon name="hero-check-circle" /></:icon>
  </.waterfall_lane>
  <.waterfall_lane label="implement" status={:danger} left={31.4} width={52.1} bar_label="7m 02s" />
  <.waterfall_lane label="test" status={:pending} queued bar_label="queued" />
</.waterfall>

Why this is not timeline/1

timeline/1 is a VERTICAL sequence sized by its content: a marker rail, a connector, one row per event. A waterfall is horizontal and sized by DURATION — the whole claim it makes is that two lanes are comparable because their bars are measured against the same axis. Those are different layouts, not two modes of one component, and a component that tried to be both would have to choose which of the two its status, spacing and rail meant.

The axis is the component's contract

The caller supplies left and width as PERCENTAGES of a shared axis it computed, and ticks as percentages on that same axis. The component does no time math and formats no timestamps — it cannot, because only the caller knows whether the axis is wall-clock, CPU time, or bytes. What the component guarantees is that the ruler, the gridlines and every lane's bar are laid out in ONE track of identical width, so those percentages mean the same thing on every row. That is why the ticks live on the root and are drawn ONCE, as a grid layer behind every lane, rather than passed to each lane: two lanes cannot disagree about an axis neither of them owns.

A lane with no position on the axis (never started) is queued — rendered as a dashed placeholder at the right edge rather than given a fabricated left. Inventing a position for work that has not happened is the one thing a waterfall must not do.

--lui-waterfall-label-w tunes the label column.

Summary

Functions

waterfall(assigns)

Attributes

  • id (:string) - DOM id for the root element. Defaults to nil.
  • ticks (:list) - Shared axis ruler marks: a list of %{label: string, pct: number}, where pct is a percentage of the same axis lanes position against. Also drawn as gridlines behind the lanes. Defaults to [].
  • label (:string) - Heading for the label column, rendered above the lane labels. Defaults to nil.
  • class (:any) - Extra classes merged onto the root element. Defaults to nil.
  • Global attributes are accepted. Arbitrary HTML/phx-* attributes passed through.

Slots

waterfall_lane(assigns)

Attributes

  • label (:string) - Lane name, shown in the fixed label column. Defaults to nil.
  • at (:string) - Optional preformatted secondary line under the label; not formatted by the component. Defaults to nil.
  • status (:atom) - Bar status, rendered as data-status for CSS coloring. Defaults to :neutral. Must be one of :done, :active, :pending, :danger, :warning, or :neutral.
  • state_label (:string) - State word (e.g. "Failed"). Set whenever status is meaningful so state is never color-only; rendered for assistive tech. Defaults to nil.
  • left (:float) - Bar start as a percentage of the shared axis. Defaults to 0.0.
  • width (:float) - Bar length as a percentage of the shared axis. Defaults to 0.0.
  • bar_label (:string) - Text inside (or beside) the bar, typically a preformatted duration. Defaults to nil.
  • queued (:boolean) - Lane has no position on the axis yet. Renders a dashed placeholder at the right edge instead of a positioned bar; left/width are ignored. Defaults to false.
  • selected (:boolean) - Marks this lane as the current selection. Defaults to false.
  • navigate (:string) - When set, the whole lane is a navigation link. Defaults to nil.
  • patch (:string) - When set, the whole lane is a patch link. Defaults to nil.
  • class (:any) - Extra classes merged onto the lane root. Defaults to nil.
  • Global attributes are accepted. Arbitrary HTML/phx-* attributes passed through.

Slots

  • inner_block - Optional trailing content in the label column (badges, counts).
  • icon - Optional glyph rendered before the label. A SLOT, not an icon name: the host app owns its icon set, and a shared component that dictated one would crash any caller whose vocabulary differs.