LavaUI docs GitHub

struct TextField

Swift

struct TextField

Single-line editable text.

Step 1 of the plan's Phase 7 ladder: Latin, no IME, no multi-line. The editing logic itself is TextEditingState in LavaText (pure, tested headlessly); this type is only the view/node plumbing around it.

The buffer lives on the node, not in @State, because a PrimitiveView has no body and so never goes through CompositeNode's state transplant. The node persists across rebuilds, which is the same guarantee.

Focus chrome comes from Theme.focusRingStyle by default (a full rounded outline). Pass focusRing: / focusRingWidth: / focusRingColor: to override per field — e.g. .underline for the historical top+bottom bars.

Sources/LavaUI/TextField.swift:16

Constructors

init(text: Binding<String>, placeholder: String = "", font: UIFont? = nil, multiline: Bool = false, maxLines: Int = 8, wraps: Bool = false, autoFocus: Bool = false, selectionOnFocus: FocusSelection = .none, focusRing: FocusRingStyle? = nil, focusRingWidth: Float? = nil, focusRingColor: Color? = nil, secure: Bool = false, onSubmit: (() -> Void)? = nil)

Creates a text field.

  • text: The text being edited.
  • placeholder: Dim text shown while the field is empty.
  • font: The field's font; nil uses the environment's.
  • multiline: Whether Enter inserts a newline rather than submitting.
  • maxLines: Most lines a multiline field grows to before it scrolls.
  • wraps: Whether a multiline field breaks long lines at its width.
  • autoFocus: Whether the field takes focus when it mounts.
  • selectionOnFocus: What focus without a click selects.
  • focusRing: The focus chrome; nil uses the theme's.
  • focusRingWidth: Width of the focus ring; nil uses the theme's.
  • focusRingColor: Colour of the focus ring; nil uses the theme's.
  • secure: Shows a dot per character instead of the text, and refuses copy, cut and undo. Single-line only.
  • onSubmit: Called when Enter is pressed in a single-line field.

Sources/LavaUI/TextField.swift:86

Properties

var autoFocus: Bool

Take the caret as soon as this field appears.

For the window whose entire purpose is one field — a launcher, a search overlay, a rename prompt. Without it the user has to click the box before typing, which is asking them to aim at something before saying what they want.

Only on mount, and only when no other text is being typed in: a field that re-took focus on every reconcile would steal the caret back from wherever the user had since put it.

Sources/LavaUI/TextField.swift:44

var dumpDetail: String { get }

Not documented.

Sources/LavaUI/TextField.swift:119

var focusRing: FocusRingStyle?

Overrides Theme.focusRingStyle when set.

Sources/LavaUI/TextField.swift:62

var focusRingColor: Color?

Colour of the focus ring, overriding the theme's.

Sources/LavaUI/TextField.swift:66

var focusRingWidth: Float?

Width of the focus ring, overriding the theme's.

Sources/LavaUI/TextField.swift:64

var font: UIFont?

The field's font, or nil for the environment's.

Sources/LavaUI/TextField.swift:22

var isMultiline: Bool

When true, Enter inserts a newline instead of submitting, and the box grows to fit its lines. Hard line breaks only for now — soft wrap is a separate step, because a wrapped visual line is no longer a logical one and every index mapping has to account for that.

Sources/LavaUI/TextField.swift:29

var isSecure: Bool

Shows a dot per character instead of the text — a password.

Sources/LavaUI/TextField.swift:68

var maxLines: Int

Height cap in rows when multi-line; the box grows up to this.

Sources/LavaUI/TextField.swift:31

var onSubmit: (() -> Void)?

Called when Enter is pressed in a single-line field.

Sources/LavaUI/TextField.swift:24

var placeholder: String

Dim text shown while the field is empty.

Sources/LavaUI/TextField.swift:20

var resolvedFont: UIFont? { get }

The font the field draws with: font, or the environment's when that is nil.

Sources/LavaUI/TextField.swift:117

var selectionOnFocus: FocusSelection

What is selected when focus arrives without a click — autoFocus, or a .focused flag set from code — so typing replaces a suggested value rather than appending to it: all of a new folder's offered name, a file's name up to its extension when renaming, all of an address after Ctrl+L. A click places the caret where it lands instead.

Sources/LavaUI/TextField.swift:50

@Binding var text: String { get nonmutating set }

The text being edited.

Sources/LavaUI/TextField.swift:18

var wraps: Bool

Wrap long lines to the field width instead of letting them overflow.

Sources/LavaUI/TextField.swift:33

Methods

func mountPrimitive() -> any AnyViewNode

Not documented.

Sources/LavaUI/TextField.swift:123

func reconcilePrimitive(_ node: any AnyViewNode) -> any AnyViewNode

Not documented.

Sources/LavaUI/TextField.swift:159

Types