Skip to content

Input

The Input component allows users to enter text, numbers, passwords, emails, and more. It wraps the standard HTML <input> element with comprehensive Bootstrap styling, validation states, and floating labels.

Quick Start

Input("full_name", placeholder="Enter your name", label="Full Name")

Usage Scenarios

Types & Labels

Input("email", input_type="email", label="Email Address", placeholder="name@example.com")
Input("password", input_type="password", label="Password")

Sizing

Input("large_input", placeholder="Large Input", size="lg")
Input("default_input", placeholder="Default Input")
Input("small_input", placeholder="Small Input", size="sm")

Help Text and Disabled State

Input("username", label="Username", help_text="Must be 8-20 characters long.", disabled=True, value="jdoe_archived")

Validation States

Input("username", validation_state="valid", value="Correct!")
Input("username", validation_state="invalid", value="Invalid data")

Floating Labels

FloatingLabel(Input("email", placeholder="name@example.com"), label="Email Address")

HTMX Integration

Input("search", input_type="search", placeholder="Search users...", hx_get="/search_users", hx_trigger="keyup changed delay:500ms", hx_target="#search-results")

Parameter Reference

FastStrap Param Type Bootstrap / HTML Attribute Description
name str name="..." Form field name. Required for form submission and label/input association.
input_type str type="..." HTML5 input type (text, password, email, number, date, etc.). Default text.
label str <label> Text for the associated label element.
placeholder str placeholder="..." Ghost text shown when empty.
value Any value="..." Initial value of the input.
help_text str .form-text Helper text displayed below the input.
size str .form-control-{size} Size: sm or lg.
disabled bool disabled Disables interaction.
readonly bool readonly Value is visible but not editable.
required bool required Marks field as required for browser validation.
validation_state str .is-valid / .is-invalid Validation state: valid or invalid.
validation_message str .valid-feedback / .invalid-feedback Feedback message shown for validation state.

Accessibility

  • Labels are automatically associated with inputs via for and id attributes.
  • Required fields display a red asterisk.
  • Help text is linked via aria-describedby.
  • Floating labels use proper for/id associations.

API Reference

faststrap.components.forms.input.Input(name, input_type=UNSET, placeholder=None, value=None, label=None, help_text=None, size=UNSET, disabled=UNSET, readonly=UNSET, required=UNSET, validation_state=None, validation_message=None, **kwargs)

Bootstrap Input component for text form controls.

Parameters:

Name Type Description Default
name str

Input name attribute

required
input_type InputType | None

HTML input type

UNSET
placeholder str | None

Placeholder text

None
value str | None

Initial value

None
label str | None

Label text

None
help_text str | None

Helper text below input

None
size SizeType | None

Input size (sm, lg)

UNSET
disabled bool | None

Whether input is disabled

UNSET
readonly bool | None

Whether input is readonly

UNSET
required bool | None

Whether input is required

UNSET
validation_state str | None

Validation state ('valid' or 'invalid')

None
validation_message str | None

Validation feedback message

None
**kwargs Any

Additional HTML attributes

{}
Source code in src/faststrap/components/forms/input.py
@register(category="forms")
def Input(
    name: str,
    input_type: InputType | None = UNSET,
    placeholder: str | None = None,
    value: str | None = None,
    label: str | None = None,
    help_text: str | None = None,
    size: SizeType | None = UNSET,
    disabled: bool | None = UNSET,
    readonly: bool | None = UNSET,
    required: bool | None = UNSET,
    validation_state: str | None = None,
    validation_message: str | None = None,
    **kwargs: Any,
) -> Div:
    """Bootstrap Input component for text form controls.

    Args:
        name: Input name attribute
        input_type: HTML input type
        placeholder: Placeholder text
        value: Initial value
        label: Label text
        help_text: Helper text below input
        size: Input size (sm, lg)
        disabled: Whether input is disabled
        readonly: Whether input is readonly
        required: Whether input is required
        validation_state: Validation state ('valid' or 'invalid')
        validation_message: Validation feedback message
        **kwargs: Additional HTML attributes
    """
    # Resolve API defaults
    cfg = resolve_defaults(
        "Input",
        input_type=input_type,
        size=size,
        disabled=disabled,
        readonly=readonly,
        required=required,
    )

    c_type = cfg.get("input_type", "text")
    c_size = cfg.get("size")
    c_disabled = cfg.get("disabled", False)
    c_readonly = cfg.get("readonly", False)
    c_required = cfg.get("required", False)

    # Ensure ID is present for label linkage
    input_id = kwargs.pop("id", name)

    # Build input classes
    input_classes = ["form-control"]
    if c_size:
        input_classes.append(f"form-control-{c_size}")
    if validation_state:
        input_classes.append(f"is-{validation_state}")

    user_cls = kwargs.pop("cls", "")
    input_cls = merge_classes(" ".join(input_classes), user_cls)

    # Build attributes
    attrs: dict[str, Any] = {
        "cls": input_cls,
        "name": name,
        "id": input_id,
    }
    if c_type:
        attrs["type"] = c_type

    if placeholder:
        attrs["placeholder"] = placeholder
    if value is not None:
        attrs["value"] = value
    if c_disabled:
        attrs["disabled"] = True
    if c_readonly:
        attrs["readonly"] = True
    if c_required:
        attrs["required"] = True

    # ARIA for help text
    if help_text:
        attrs["aria_describedby"] = f"{name}-help"

    # Convert remaining kwargs
    attrs.update(convert_attrs(kwargs))

    # Create input element (special-case textarea)
    if c_type == "textarea":
        textarea_value = attrs.pop("value", "")
        attrs.pop("type", None)
        input_elem = FTTextarea(textarea_value, **attrs)
    else:
        input_elem = FTInput(**attrs)

    # Wrap in div with label, help text, and validation message
    elements = []

    if label:
        label_elem = Label(
            label,
            " ",
            Small("*", cls="text-danger") if c_required else "",
            **{"for": input_id},
            cls="form-label",
        )
        elements.append(label_elem)

    elements.append(input_elem)

    if help_text:
        help_elem = Small(help_text, cls="form-text text-muted", id=f"{name}-help")
        elements.append(help_elem)

    if validation_message and validation_state:
        feedback_cls = "valid-feedback" if validation_state == "valid" else "invalid-feedback"
        feedback_elem = Div(validation_message, cls=feedback_cls)
        elements.append(feedback_elem)

    if label or help_text or validation_message:
        return Div(*elements, cls="mb-3")
    return Div(*elements)