wijjit.elements.input.text.TextInput
- class wijjit.elements.input.text.TextInput(id=None, classes=None, tab_index=None, placeholder='', value='', width=20, max_length=None, style=InputStyle.BRACKETS, completer=None, autocomplete=None, action=None, bind=True, password=False, mask_char='*')[source]
Text input field element.
- Parameters:
id (
str, optional) – Element identifierplaceholder (
str, optional) – Placeholder text when emptyvalue (
str, optional) – Initial valuewidth (
int, optional) – Display width for content (default: 20), excludes bordersmax_length (
int, optional) – Maximum input lengthstyle (
InputStyle, optional) – Visual style for input rendering (default: BRACKETS)completer (
Completer, optional) – Autocomplete completer for suggestionspassword (
bool, optional) – If True, render each character asmask_charinstead of the literal text (default: False). The real text is still stored invalueand returned by state bindings and callbacks; only the display is masked.mask_char (
str, optional) – Character used to mask each character whenpasswordis True (default:"*").tab_index (int | None)
action (str | None)
- Variables:
Examples
Create a basic text input:
>>> inp = TextInput(placeholder="Enter name...")
Create input with different styles:
>>> inp = TextInput(placeholder="Email", style=InputStyle.BOX, width=30) >>> inp = TextInput(value="Default", style=InputStyle.UNDERLINE)
- __init__(id=None, classes=None, tab_index=None, placeholder='', value='', width=20, max_length=None, style=InputStyle.BRACKETS, completer=None, autocomplete=None, action=None, bind=True, password=False, mask_char='*')[source]
Methods
__init__([id, classes, tab_index, ...])add_class(class_name)Add a CSS class to this element.
apply_props(props)Apply props from a VNode, skipping ephemeral props.
Get ephemeral state for reconciliation.
get_hardware_cursor_position()Absolute screen cell where the hardware terminal cursor should park.
get_height_for_width(width)Return the height this element needs when laid out at
width.Get the intrinsic size of the text input.
handle_key(key)Handle keyboard input.
handle_mouse(event)Handle mouse input.
has_class(class_name)Check if element has a CSS class.
on_blur()Called when element loses focus.
on_focus()Called when element gains focus.
on_hover_enter()Called when mouse enters element.
on_hover_exit()Called when mouse exits element.
on_mount()Called when element is first added to the element tree.
on_unmount()Called when element is removed from the element tree.
on_update(changed_props)Called when element props are updated during reconciliation.
remove_class(class_name)Remove a CSS class from this element.
Paint memo for the skip-unchanged fast path.
render_to(ctx)Render text input using cell-based rendering (NEW API).
restore_ephemeral_state(state)Restore ephemeral state, clamping the cursor into range.
set_bounds(bounds)Stretch the field to the assigned width (e.g.
width="fill").toggle_class(class_name)Toggle a CSS class on this element.
Attributes
autocomplete_is_openCheck if the autocomplete popup is currently open.
Whether Tab should reach this input instead of moving focus.
completerparent_frameGet the parent Frame if this element is inside a scrollable frame.
supports_dynamic_sizingWhether this element supports dynamic sizing.
valuecursor_posbounds- property captures_tab: bool
Whether Tab should reach this input instead of moving focus.
- Returns:
True only while an autocomplete popup is open and configured to accept the highlighted suggestion on Tab.
- Return type:
Notes
Claimed conditionally rather than always: a text input in a form must keep Tab-to-next-field. The moment the popup closes, Tab goes back to moving focus - which is also what makes the completer’s
select_on_tabreachable at all, since the app’s focus handler would otherwise cancel Tab before any element saw it.
- handle_key(key)[source]
Handle keyboard input.
- Parameters:
key (
Key) – Key press to handle- Returns:
True if key was handled
- Return type:
- async handle_mouse(event)[source]
Handle mouse input.
On click events, positions the cursor at the clicked character position. Focus management is handled separately by the MouseEventRouter before this method is called (see mouse_router.py:_handle_focus_on_click).
- Parameters:
event (
MouseEvent) – Mouse event to handle- Returns:
True if event was handled (click/double-click consumed)
- Return type:
Notes
The MouseEventRouter sets focus on focusable elements before calling handle_mouse(). This method handles cursor positioning within the text. Returning True indicates the event was consumed, preventing propagation to parent containers.
- render_signature()[source]
Paint memo for the skip-unchanged fast path.
Captures value, placeholder, cursor position, masking, width, visual style, and style-affecting state. The scroll offset and caret rendering are derived deterministically from these, so they need not be listed separately. See
Element.render_signature().- Return type:
- render_to(ctx)[source]
Render text input using cell-based rendering (NEW API).
- Parameters:
ctx (
PaintContext) – Paint context with buffer, style resolver, and bounds- Return type:
None
Notes
This is the reference implementation for text input cell-based rendering. It demonstrates how to: 1. Handle text that exceeds display width (scrolling) 2. Render cursor position with proper styling 3. Show placeholder text when empty 4. Apply different border styles 5. Resolve styles based on focus state
The input renders as a single line with decorative borders and cursor indication when focused.
- get_intrinsic_size()[source]
Get the intrinsic size of the text input.
Returns the total width including border characters based on style.
- Returns:
(width, height) tuple where width includes borders
- Return type:
tuple[int,int]
- set_bounds(bounds)[source]
Stretch the field to the assigned width (e.g.
width="fill").The field is painted from
self.width(content columns, excluding the bracket/box border glyphs), which under a"fill"spec holds the tag’s numeric default rather than the width the layout engine assigned. Fixed-width inputs already budget the border into the layout node, so bounds match the props and this sync is a no-op.- Parameters:
bounds (
Bounds) – New bounds for the element.- Return type:
None
- get_ephemeral_state()[source]
Get ephemeral state for reconciliation.
- Returns:
Cursor position that should survive re-renders
- Return type:
- restore_ephemeral_state(state)[source]
Restore ephemeral state, clamping the cursor into range.
- Parameters:
state (
dict) – State fromget_ephemeral_state().- Return type:
None
Notes
Called by the reconciler after prop changes are applied, so
self.valuealready holds the new value. A programmatic value change (e.g. a shrinking state binding) can leave the preserved cursor position past the end of the text; clamping here prevents out-of-range insert/delete.