Drafter.Widget.Header (drafter v0.3.1)

Copy Markdown View Source

Renders a single-row application header bar with a centred title and optional live clock.

With :show_clock set, a recurring 1-second timer is started during mount/1 and the current local time is rendered at the right edge. The title is centred in the remaining space. Clock format can be either :time (HH:MM:SS, default) or :datetime (YYYY-MM-DD HH:MM:SS). The clock is off unless asked for, so a header starts no timer of its own.

Component tag

Tag :header, built by Drafter.App as {:header, title, opts}:

header(title, opts)

The positional argument becomes :title, falling back to opts[:title] when nil. :app_module is supplied by the renderer.

Options

  • :title - String.t/0 displayed in the centre of the header. Default "". Supplied positionally through the header/2 element, falling back to opts[:title] when the positional value is nil
  • :show_clock - boolean/0. Default false. When true, mount/1 schedules a :clock_tick message one second out, which handle_event/2 reschedules on every tick. No timer is started when no app is registered
  • :clock_format - :time (default, HH:MM:SS) or :datetime (YYYY-MM-DD HH:MM:SS). Any other value falls back to :time
  • :app_module - module used for theme resolution, passed by the renderer as :__app_module__. Default nil

update/2 re-reads all four options and starts or cancels the clock timer as :show_clock changes. Through the component tree, however, only :title and :app_module are re-applied on a re-render, making :show_clock and :clock_format effectively mount-only there.

Widget value

Drafter.get_widget_value/1 is not implemented for this widget and returns nil.

Usage

header(title: "My App")
header(title: "Dashboard", show_clock: true, clock_format: :datetime)

Summary

Functions

The registry tag for this widget.

Turns the {:header, title, opts} element into a props map for mount/1.

Reschedules the clock on :clock_tick, returning {:ok, state} with the new timer reference, or with nil when :show_clock is off. Every other event returns {:noreply, state}.

Builds the header state from props and starts the clock timer when :show_clock is true and an app is registered.

Always 1: the header occupies a single row.

Draws the header bar into rect, returning exactly rect.height strips of which only the first carries content.

Folds fresh props into state, re-reading :title, :show_clock, :clock_format and :app_module.

Narrows the props a re-render feeds to update/2 to :title and :app_module, so a re-render never restarts or stops the clock.

Types

t()

@type t() :: %Drafter.Widget.Header{
  app_module: module() | nil,
  clock_format: :time | :datetime,
  show_clock: boolean(),
  timer_ref: reference() | nil,
  title: String.t()
}

Functions

component_tag()

@spec component_tag() :: :header

The registry tag for this widget.

iex> Drafter.Widget.Header.component_tag()
:header

from_component_opts(title, opts)

@spec from_component_opts(
  term(),
  keyword()
) :: Drafter.Widget.props()

Turns the {:header, title, opts} element into a props map for mount/1.

A nil positional title falls back to opts[:title] and then to "". :__app_module__ becomes :app_module.

iex> Drafter.Widget.Header.from_component_opts(nil, title: "Dashboard")
%{title: "Dashboard", show_clock: false, clock_format: :time, app_module: nil}

handle_event(arg1, state)

@spec handle_event(Drafter.Event.t() | :clock_tick, t()) ::
  {:ok, t()} | {:noreply, t()}

Reschedules the clock on :clock_tick, returning {:ok, state} with the new timer reference, or with nil when :show_clock is off. Every other event returns {:noreply, state}.

iex> h = Drafter.Widget.Header.mount(%{show_clock: false})
iex> Drafter.Widget.Header.handle_event(:anything_else, h) |> elem(0)
:noreply

mount(props)

@spec mount(Drafter.Widget.props()) :: t()

Builds the header state from props and starts the clock timer when :show_clock is true and an app is registered.

iex> h = Drafter.Widget.Header.mount(%{title: "My App", show_clock: false})
iex> {h.title, h.show_clock, h.clock_format, h.timer_ref}
{"My App", false, :time, nil}

preferred_height(args, opts)

@spec preferred_height(
  term(),
  keyword()
) :: pos_integer()

Always 1: the header occupies a single row.

render(state, rect)

@spec render(t(), Drafter.Widget.rect()) :: [Drafter.Draw.Strip.t()]

Draws the header bar into rect, returning exactly rect.height strips of which only the first carries content.

The clock sits at the right edge and the title is centred in the columns left over after one space of margin on each side. A title longer than that space is cut.

update(props, state)

@spec update(Drafter.Widget.props(), t()) :: t()

Folds fresh props into state, re-reading :title, :show_clock, :clock_format and :app_module.

Turning :show_clock on with no timer running starts one; turning it off cancels the running timer.

iex> h = Drafter.Widget.Header.mount(%{title: "One", show_clock: false})
iex> Drafter.Widget.Header.update(%{title: "Two"}, h).title
"Two"

update_props_from_mount(mount_props, existing_state, opts)

@spec update_props_from_mount(Drafter.Widget.props(), t(), keyword()) ::
  Drafter.Widget.props()

Narrows the props a re-render feeds to update/2 to :title and :app_module, so a re-render never restarts or stops the clock.