Drafter.Widget.Label (drafter v0.3.2)

Copy Markdown View Source

Renders a single line or multi-line string of styled text.

Supports semantic variants that apply theme colors automatically, and accepts an explicit style map for full control over foreground and background colors.

Component tag

Tag :label, built by Drafter.App as {:label, text, opts}:

label(text, opts)

The positional argument becomes :text. All other props come from opts.

Options

  • :text - String.t/0 to render. Default "". Supplied positionally through the label/2 element. A "\n" splits it into one strip per line
  • :style - map/0 of style properties, e.g. %{fg: {255, 100, 0}, bold: true}. Default %{}
  • :align - text alignment: :left (default), :center, :right
  • :variant - semantic colour: :default (default), :primary, :success, :warning, :error, :muted. Anything other than :default is also added as a theme class while rendering
  • :class - theme class atom or list of them, reaching mount/1 as :classes. Default []
  • :app_module - module supplying a per-app theme, passed by the renderer as :__app_module__. Default nil

update/2 accepts :text, :style, :align, :variant, :classes and :app_module, and silently drops any other key. All of them are live-updatable through the component tree.

Widget value

Drafter.get_widget_value/1 returns the label's :text as a String.t/0, because the value extractor reads the :text field.

Usage

label("Hello world", style: %{fg: {100, 200, 255}, bold: true})
label("Warning!", variant: :warning)
label("Centered", align: :center)

Summary

Functions

The registry tag for this widget.

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

Builds the label state from props.

Builds a label struct directly from text and opts.

Always 1, whatever the text contains — a multi-line label still reserves a single row.

Draws the text into rect, one strip per newline-separated line.

Callback implementation for Drafter.Widget.unmount/1.

Folds fresh props into state.

Returns mount_props unchanged, so a re-render passes every option through to update/2.

Types

align()

@type align() :: :left | :center | :right

t()

@type t() :: %Drafter.Widget.Label{
  align: align(),
  app_module: module() | nil,
  classes: [atom()],
  style: map(),
  text: String.t(),
  variant: variant()
}

variant()

@type variant() :: :default | :primary | :success | :warning | :error | :muted

Functions

component_tag()

@spec component_tag() :: :label

The registry tag for this widget.

iex> Drafter.Widget.Label.component_tag()
:label

focused(state)

from_component_opts(text, opts)

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

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

text is the positional argument. :class is normalised into :classes and :__app_module__ becomes :app_module.

iex> Drafter.Widget.Label.from_component_opts("Hi", align: :right)
%{text: "Hi", style: %{}, align: :right, variant: :default, classes: [], app_module: nil}

handle_event(event, state)

Callback implementation for Drafter.Widget.handle_event/2.

mount(props)

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

Builds the label state from props.

iex> l = Drafter.Widget.Label.mount(%{text: "Hi", variant: :warning})
iex> {l.text, l.variant, l.align}
{"Hi", :warning, :left}

iex> l = Drafter.Widget.Label.mount(%{})
iex> {l.text, l.style, l.align, l.variant, l.classes, l.app_module}
{"", %{}, :left, :default, [], nil}

new(text, opts \\ [])

@spec new(
  String.t(),
  keyword()
) :: t()

Builds a label struct directly from text and opts.

Reads :style (default %{}), :align (default :left) and :variant (default :default). :classes and :app_module are not read here and stay at their struct defaults; use mount/1 to set them.

iex> l = Drafter.Widget.Label.new("Hello", align: :center)
iex> {l.text, l.align, l.variant, l.classes}
{"Hello", :center, :default, []}

preferred_height(args, opts)

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

Always 1, whatever the text contains — a multi-line label still reserves a single row.

render(state, rect)

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

Draws the text into rect, one strip per newline-separated line.

Empty text yields a single blank strip. Each line is padded to rect.width according to :align, or cropped to it when it is longer. rect.height is not consulted, so a label with more lines than rows overflows.

unmount(state)

Callback implementation for Drafter.Widget.unmount/1.

update(props, state)

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

Folds fresh props into state.

Only :text, :style, :align, :variant, :classes and :app_module are applied; any other key in props is dropped without error.

iex> l = Drafter.Widget.Label.mount(%{text: "Hi"})
iex> updated = Drafter.Widget.Label.update(%{text: "Bye", nonsense: 1}, l)
iex> {updated.text, updated.align}
{"Bye", :left}

update_props_from_mount(mount_props, existing_state, opts)

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

Returns mount_props unchanged, so a re-render passes every option through to update/2.