Functions and macros for building the element tree returned by
Tuix.App.render/1.
Box props
:width/:height- integer cells,{:percent, n}, or a"50%"string:flex_direction-:column(default) or:row:flex_grow- share of leftover space along the parent's main axis:gap- cells between children:padding- cells inside the border on all sides:border-:none(default),:single,:rounded,:double, ortrue(alias for:single):border_color- color of the border (seeTuix.Color):title- text drawn into the top border:bg- background fill color
Focus props (boxes)
:id- stable identity for the element (any term, unique per tree):focusable- includes the box in the Tab / Shift+Tab focus order; requires:id:autofocus- focuses this box on the first frame when nothing is focused:focus_border_color- border color while focused (overrides:border_color):focus_bg- background fill while focused (overrides:bg):focus_within_border_color/:focus_within_bg- styles applied while a descendant is focused; fall back to thefocus_*props
Focus styles also apply while a descendant has focus (e.g. a bordered box
wrapping a focused input): the runtime sets focused: true on the focused
element's props and focus_within: true on its ancestors before painting;
see Tuix.Focus.
Input props
:id- required; also makes the input focusable by default:value- the current value (owned by the app; default""):placeholder- text shown while empty and unfocused:placeholder_color- color of the placeholder (default:bright_black):mask- replaces each grapheme on display, e.g."•"for passwords:width/:fg/:bg/:attrsand the focus props above
Select props
:id- required; also makes the select focusable by default:options- list of{label, value}tuples, or bare strings (which are their own value):value- the currently selected value (owned by the app):marker- prefix drawn on the selected row (default"❯ "); other rows are padded to match:selected_fg- foreground of the selected row (default: inherits:fg):selected_attrs- attrs of the selected row (default[:bold]):fg/:bg/:attrsand the focus props above
Text props
:fg/:bg- colors (seeTuix.Color):attrs- list of:bold,:dim,:italic,:underline,:blink,:reverse,:strikethrough
Examples
box border: :rounded, padding: 1, gap: 1 do
text("Welcome", fg: :yellow)
text("Press q to quit")
end
Summary
Functions
Builds a box element.
Builds a single-line text input element.
Builds a vertical list-picker element.
Builds a text element.
Functions
Builds a box element.
Accepts props and children either as a do block or as a list:
box(border: :single) # empty box
box [border: :single] do
text("hi")
end
box([border: :single], [text("hi")])
@spec input(keyword()) :: Tuix.Element.t()
Builds a single-line text input element.
Inputs join the Tab focus order automatically (focusable: true) and
require an :id. The value is controlled by the app: handle
%Tuix.Event.Input{} and assign the new value back into state, LiveView
form style — otherwise the input appears frozen.
input(id: :email, value: assigns.email, placeholder: "you@example.com")
def handle_event(%Tuix.Event.Input{id: :email, value: value}, app),
do: {:noreply, assign(app, email: value)}While focused, printable keys and :space, :backspace, :delete,
:left / :right / :home / :end edit the value; everything else
(:enter, :escape, ctrl combos, Tab traversal) falls through to the
app with target set. See Tuix.Components.Input for the editing core
and the module docs above for the accepted props.
@spec select(keyword()) :: Tuix.Element.t()
Builds a vertical list-picker element.
Selects join the Tab focus order automatically (focusable: true) and
require an :id. They are controlled: the selection follows the
highlight, so :up / :down / :home / :end emit
%Tuix.Event.Select{} with the new value immediately, and the app
assigns it back into state:
select(id: :plan, options: [{"Basic", :basic}, {"Pro", :pro}], value: assigns.plan)
def handle_event(%Tuix.Event.Select{id: :plan, value: value}, app),
do: {:noreply, assign(app, plan: value)}Navigation is clamped (no wrap-around). :enter, :space, and
everything else fall through to the app with target set — so
commit-on-Enter flows keep a draft value in assigns and match
%Tuix.Event.Key{key: :enter, target: :plan}. When the select is
shorter than its option list, it scrolls to keep the selection visible.
See the module docs above for the accepted props.
@spec text( String.t(), keyword() ) :: Tuix.Element.t()
Builds a text element.
text("Hello")
text("Hello", fg: "#00FF00", attrs: [:bold])Multi-line content (embedded newlines) renders one line per row.