Renders a bordered panel with an optional title and text content lines.
Four border styles are available: :single, :double, :rounded (default),
and :heavy. When a :title is provided it is embedded into the top border
left-aligned with one padding character on either side. Content lines are
padded and truncated to fit the inner width.
Component tag
This module has no component_tag/0 and is not reached through the widget
registry. Drafter.App builds it as the element {:card, children, opts}:
card(children, opts)children is the content: the renderer wraps it in a list and calls
to_string/1 on each entry, so every entry must implement String.Chars.
Pass strings. The remaining props come from opts.
Options
:title-String.t/0shown in the top border. Defaultnil. A title whose padded length reaches the inner width is dropped and a plain border is drawn instead:content- list of strings, one per inner line. Default[]. A single non-list value is wrapped in a list at render time:border- border style atom::rounded(default),:single,:double,:heavy. An unknown value falls back to:roundedat render time:border_color-{r, g, b}tuple for border characters. Defaultnil, which falls back to the theme's border colour and then to:color:color-{r, g, b}tuple for content text. Defaultnil, which falls back to the theme and then to{200, 200, 200}:background-{r, g, b}tuple for the card background. Defaultnil, which falls back to the theme and then to{40, 44, 52}:style-map/0of style properties. Default%{}:class- theme class atom or list of them, reachingmount/1as:classes. Default[]:app_module- module supplying a per-app theme. Defaultnil
update/2 re-reads every option except :border and :app_module, which are
mount-only.
Widget value
Drafter.get_widget_value/1 is not implemented for this widget; the card is
display-only and never focusable.
Usage
card(["Line 1", "Line 2"], title: "Summary", border: :rounded)
card(["Disk full"], title: "Alert", border_color: {255, 80, 80})
Summary
Functions
Ignores every event and returns {:noreply, state}. The card is not focusable and
never consumes input.
Builds the card state from props.
Draws the card into rect.
Callback implementation for Drafter.Widget.unmount/1.
Folds fresh props into state.
Types
@type border() :: :single | :double | :rounded | :heavy
@type rgb() :: {0..255, 0..255, 0..255}
Functions
@spec handle_event(Drafter.Event.t(), t()) :: {:noreply, t()}
Ignores every event and returns {:noreply, state}. The card is not focusable and
never consumes input.
@spec mount(Drafter.Widget.props()) :: t()
Builds the card state from props.
iex> c = Drafter.Widget.Card.mount(%{title: "Summary", content: ["a", "b"]})
iex> {c.title, c.content, c.border}
{"Summary", ["a", "b"], :rounded}
iex> c = Drafter.Widget.Card.mount(%{})
iex> {c.title, c.content, c.border, c.color, c.background, c.classes}
{nil, [], :rounded, nil, nil, []}
@spec render(t() | Drafter.Widget.props(), Drafter.Widget.rect()) :: [ Drafter.Draw.Strip.t() ]
Draws the card into rect.
Accepts either a t/0 or a raw props map, which is mounted first. Returns []
when rect.width is under 2. Otherwise returns 2 + length(content) strips —
a top border, one row per content line padded and truncated to the inner width,
and a bottom border. rect.height is not consulted, so a card with more content
lines than rows overflows.
Callback implementation for Drafter.Widget.unmount/1.
@spec update(Drafter.Widget.props(), t()) :: t()
Folds fresh props into state.
Re-reads :title, :content, :style, :border_color, :background, :color
and :classes. :border and :app_module are ignored here and keep their
mounted values.
iex> c = Drafter.Widget.Card.mount(%{border: :single, content: ["a"]})
iex> updated = Drafter.Widget.Card.update(%{content: ["b"], border: :heavy}, c)
iex> {updated.content, updated.border}
{["b"], :single}