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

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

Visual Examples & Use Cases

1. Types & Labels

FastStrap supports all HTML5 input types. Adding a label argument automatically creates a properly accessible <label> associated with the input.

Code & Output

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

2. Sizing

Match inputs to buttons or other components using size.

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

3. Utility Text and Disabled State

Add flexible helper text below the input using help_text. Use disabled or readonly to restrict interaction.

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

Practical Functionality

Live Preview
This username is available.
Please provide a valid entry.
# Valid state (Green border)
Input("username", validation_state="valid", value="Correct!")

# Invalid state (Red border)
Input("username", validation_state="invalid", value="Invalid data")

2. Floating Labels

Bootstrap's modern "Floating Label" pattern moves the label inside the input, floating up when the user types.

<div class="component-preview">
  <div class="preview-header">Live Preview</div>
  <div class="preview-render">
    <div class="form-floating w-100">
      <input type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
      <label for="floatingInput">Email Address</label>
    </div>
  </div>
  <div class="preview-code" markdown>
```python
FloatingLabel(
    Input("email", placeholder="name@example.com"),
    label="Email Address"
)

3. HTMX Integration

Trigger server requests on user input (e.g., live search).

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

Advanced Customization

1. CSS Variables

Customize standard form colors and spacing.

CSS Variable Description
--bs-body-bg Background color of input.
--bs-body-color Text color.
--bs-border-color Default border color.
--bs-focus-ring-color Glow color when focused.

2. Input Groups

Combine inputs with text or buttons using InputGroup.

Live Preview
@ .com
InputGroup(
    InputGroupText("@"),
    Input("username", placeholder="Username"),
    InputGroupText(".com")
)

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 analyzing browser validation.

faststrap.components.forms.input.Input(name, input_type=None, placeholder=None, value=None, label=None, help_text=None, size=None, disabled=None, readonly=None, required=None, 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

None
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)

None
disabled bool | None

Whether input is disabled

None
readonly bool | None

Whether input is readonly

None
required bool | None

Whether input is required

None
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 = None,
    placeholder: str | None = None,
    value: str | None = None,
    label: str | None = None,
    help_text: str | None = None,
    size: SizeType | None = None,
    disabled: bool | None = None,
    readonly: bool | None = None,
    required: bool | None = None,
    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,
        "type": c_type,
        "name": name,
        "id": input_id,
    }

    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)