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;
niluses 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;
niluses the theme's. - focusRingWidth: Width of the focus ring;
niluses the theme's. - focusRingColor: Colour of the focus ring;
niluses 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