---
title: Input
description: Text input fields for user data entry.
icon: i-cursor
---

import { ComponentPreview } from "/snippets/component-preview.mdx";

Inputs collect text, email, passwords, and other single-line data from users.

## Basic Usage

<ComponentPreview json={{"view":{"name":"input_6","type":"Input","inputType":"text","placeholder":"Enter your email...","disabled":false,"readOnly":false,"required":false}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgSW5wdXQKCklucHV0KHBsYWNlaG9sZGVyPSJFbnRlciB5b3VyIGVtYWlsLi4uIikK">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Input

Input(placeholder="Enter your email...")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "name": "input_6",
    "type": "Input",
    "inputType": "text",
    "placeholder": "Enter your email...",
    "disabled": false,
    "readOnly": false,
    "required": false
  }
}
```
</CodeGroup>
</ComponentPreview>

## Input Types

Different input types provide appropriate keyboards and validation on mobile devices:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"name":"input_7","type":"Input","inputType":"email","placeholder":"Email","disabled":false,"readOnly":false,"required":false},{"name":"input_8","type":"Input","inputType":"password","placeholder":"Password","disabled":false,"readOnly":false,"required":false},{"name":"input_9","type":"Input","inputType":"number","placeholder":"Age","disabled":false,"readOnly":false,"required":false},{"name":"input_10","type":"Input","inputType":"tel","placeholder":"Phone","disabled":false,"readOnly":false,"required":false}]}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgKAogICAgSW5wdXQsCiAgICBDb2x1bW4sCikKCndpdGggQ29sdW1uKGdhcD00KToKICAgIElucHV0KGlucHV0X3R5cGU9ImVtYWlsIiwgcGxhY2Vob2xkZXI9IkVtYWlsIikKICAgIElucHV0KGlucHV0X3R5cGU9InBhc3N3b3JkIiwgcGxhY2Vob2xkZXI9IlBhc3N3b3JkIikKICAgIElucHV0KGlucHV0X3R5cGU9Im51bWJlciIsIHBsYWNlaG9sZGVyPSJBZ2UiKQogICAgSW5wdXQoaW5wdXRfdHlwZT0idGVsIiwgcGxhY2Vob2xkZXI9IlBob25lIikK">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Input,
    Column,
)

with Column(gap=4):
    Input(input_type="email", placeholder="Email")
    Input(input_type="password", placeholder="Password")
    Input(input_type="number", placeholder="Age")
    Input(input_type="tel", placeholder="Phone")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "name": "input_7",
        "type": "Input",
        "inputType": "email",
        "placeholder": "Email",
        "disabled": false,
        "readOnly": false,
        "required": false
      },
      {
        "name": "input_8",
        "type": "Input",
        "inputType": "password",
        "placeholder": "Password",
        "disabled": false,
        "readOnly": false,
        "required": false
      },
      {
        "name": "input_9",
        "type": "Input",
        "inputType": "number",
        "placeholder": "Age",
        "disabled": false,
        "readOnly": false,
        "required": false
      },
      {
        "name": "input_10",
        "type": "Input",
        "inputType": "tel",
        "placeholder": "Phone",
        "disabled": false,
        "readOnly": false,
        "required": false
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

## With Labels

Pair inputs with labels for accessible forms:

<ComponentPreview json={{"view":{"cssClass":"gap-2","type":"Column","children":[{"type":"Label","text":"Email address","optional":false},{"name":"input_11","type":"Input","inputType":"email","placeholder":"you@example.com","disabled":false,"readOnly":false,"required":true}]}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgKAogICAgQ29sdW1uLAogICAgSW5wdXQsCiAgICBMYWJlbCwKKQoKd2l0aCBDb2x1bW4oZ2FwPTIpOgogICAgTGFiZWwoIkVtYWlsIGFkZHJlc3MiKQogICAgSW5wdXQoaW5wdXRfdHlwZT0iZW1haWwiLCBwbGFjZWhvbGRlcj0ieW91QGV4YW1wbGUuY29tIiwgcmVxdWlyZWQ9VHJ1ZSkK">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Column,
    Input,
    Label,
)

with Column(gap=2):
    Label("Email address")
    Input(input_type="email", placeholder="you@example.com", required=True)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-2",
    "type": "Column",
    "children": [
      {"type": "Label", "text": "Email address", "optional": false},
      {
        "name": "input_11",
        "type": "Input",
        "inputType": "email",
        "placeholder": "you@example.com",
        "disabled": false,
        "readOnly": false,
        "required": true
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

## Date & Time Inputs

Native date and time pickers use the browser's built-in UI:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Row","children":[{"cssClass":"gap-2 flex-1","type":"Column","children":[{"type":"Label","text":"Date","optional":false},{"name":"date","type":"Input","inputType":"date","disabled":false,"readOnly":false,"required":false}]},{"cssClass":"gap-2 flex-1","type":"Column","children":[{"type":"Label","text":"Time","optional":false},{"name":"time","type":"Input","inputType":"time","disabled":false,"readOnly":false,"required":false}]},{"cssClass":"gap-2 flex-1","type":"Column","children":[{"type":"Label","text":"Date & Time","optional":false},{"name":"datetime","type":"Input","inputType":"datetime-local","disabled":false,"readOnly":false,"required":false}]}]}}} playground=" ">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import (
    Column,
    Input,
    Label,
    Row,
)

with Row(gap=4):
    with Column(gap=2, css_class="flex-1"):
        Label("Date")
        Input(input_type="date", name="date")
    with Column(gap=2, css_class="flex-1"):
        Label("Time")
        Input(input_type="time", name="time")
    with Column(gap=2, css_class="flex-1"):
        Label("Date & Time")
        Input(input_type="datetime-local", name="datetime")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Row",
    "children": [
      {
        "cssClass": "gap-2 flex-1",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Date", "optional": false},
          {
            "name": "date",
            "type": "Input",
            "inputType": "date",
            "disabled": false,
            "readOnly": false,
            "required": false
          }
        ]
      },
      {
        "cssClass": "gap-2 flex-1",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Time", "optional": false},
          {
            "name": "time",
            "type": "Input",
            "inputType": "time",
            "disabled": false,
            "readOnly": false,
            "required": false
          }
        ]
      },
      {
        "cssClass": "gap-2 flex-1",
        "type": "Column",
        "children": [
          {"type": "Label", "text": "Date & Time", "optional": false},
          {
            "name": "datetime",
            "type": "Input",
            "inputType": "datetime-local",
            "disabled": false,
            "readOnly": false,
            "required": false
          }
        ]
      }
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

## Disabled State

<ComponentPreview json={{"view":{"name":"input_12","type":"Input","inputType":"text","placeholder":"Disabled input","disabled":true,"readOnly":false,"required":false}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgSW5wdXQKCklucHV0KHBsYWNlaG9sZGVyPSJEaXNhYmxlZCBpbnB1dCIsIGRpc2FibGVkPVRydWUpCg">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Input

Input(placeholder="Disabled input", disabled=True)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "name": "input_12",
    "type": "Input",
    "inputType": "text",
    "placeholder": "Disabled input",
    "disabled": true,
    "readOnly": false,
    "required": false
  }
}
```
</CodeGroup>
</ComponentPreview>

## Read-Only

A read-only input displays its value and allows users to select and copy the text, but prevents editing. Unlike `disabled`, the input retains its normal visual appearance -- it doesn't grey out or signal that interaction is blocked.

<ComponentPreview json={{"view":{"name":"input_13","value":"api_key_91x8z3...","type":"Input","inputType":"text","disabled":false,"readOnly":true,"required":false},"state":{"input_13":"api_key_91x8z3..."}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgSW5wdXQKCklucHV0KHZhbHVlPSJhcGlfa2V5XzkxeDh6My4uLiIsIHJlYWRfb25seT1UcnVlKQo">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Input

Input(value="api_key_91x8z3...", read_only=True)
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "name": "input_13",
    "value": "api_key_91x8z3...",
    "type": "Input",
    "inputType": "text",
    "disabled": false,
    "readOnly": true,
    "required": false
  },
  "state": {"input_13": "api_key_91x8z3..."}
}
```
</CodeGroup>
</ComponentPreview>

## Reading the Value

Use `.rx` to get a reactive reference to the input's current text. As the user types, any component that references `.rx` updates automatically:

<ComponentPreview json={{"view":{"cssClass":"gap-4","type":"Column","children":[{"name":"input_14","type":"Input","inputType":"text","placeholder":"What is your name, traveler?","disabled":false,"readOnly":false,"required":false},{"content":"Hello, {{ input_14 | default:stranger }}!","type":"Text"}]}}} playground="ZnJvbSBwcmVmYWJfdWkuY29tcG9uZW50cyBpbXBvcnQgQ29sdW1uLCBJbnB1dCwgVGV4dAoKd2l0aCBDb2x1bW4oZ2FwPTQpOgogICAgaW5wID0gSW5wdXQocGxhY2Vob2xkZXI9IldoYXQgaXMgeW91ciBuYW1lLCB0cmF2ZWxlcj8iKQogICAgVGV4dChmIkhlbGxvLCB7aW5wLnJ4LmRlZmF1bHQoJ3N0cmFuZ2VyJyl9ISIpCg">
<CodeGroup>
```python Python icon="python"
from prefab_ui.components import Column, Input, Text

with Column(gap=4):
    inp = Input(placeholder="What is your name, traveler?")
    Text(f"Hello, {inp.rx.default('stranger')}!")
```
```json Protocol icon="brackets-curly"
{
  "view": {
    "cssClass": "gap-4",
    "type": "Column",
    "children": [
      {
        "name": "input_14",
        "type": "Input",
        "inputType": "text",
        "placeholder": "What is your name, traveler?",
        "disabled": false,
        "readOnly": false,
        "required": false
      },
      {"content": "Hello, {{ input_14 | default:stranger }}!", "type": "Text"}
    ]
  }
}
```
</CodeGroup>
</ComponentPreview>

Type a name and the greeting updates with each keystroke.

## API Reference

<Card icon="code" title="Input Parameters">

<ParamField body="input_type" type="str" default="text">
  Input type: `"text"`, `"email"`, `"password"`, `"number"`, `"tel"`, `"url"`, `"search"`, `"date"`, `"time"`, `"datetime-local"`, `"file"`.
</ParamField>

<ParamField body="placeholder" type="str | None" default="None">
  Placeholder text shown when the input is empty.
</ParamField>

<ParamField body="value" type="str | None" default="None">
  Initial value.
</ParamField>

<ParamField body="name" type="str | None" default="None">
  State key for the input's current value. Auto-generated if not provided. Set this to bind the input to a known key, or use `.rx` to reference the auto-generated key without knowing it.
</ParamField>

<ParamField body="disabled" type="bool" default="False">
  Whether the input is non-interactive.
</ParamField>

<ParamField body="read_only" type="bool" default="False">
  Whether the input is read-only. The value is visible and selectable but cannot be edited.
</ParamField>

<ParamField body="required" type="bool" default="False">
  Whether the input is required for form submission.
</ParamField>

<ParamField body="css_class" type="str | None" default="None">
  Additional Tailwind CSS classes appended to the component's built-in styles.
</ParamField>
</Card>

## Protocol Reference

```json Input
{
  "type": "Input",
  "name?": "string",
  "inputType?": "text | email | password | number | tel | url | search | date | time | datetime-local | file",
  "placeholder?": "string",
  "value?": "string",
  "disabled?": false,
  "readOnly?": false,
  "required?": false,
  "minLength?": "number",
  "maxLength?": "number",
  "min?": "number",
  "max?": "number",
  "step?": "number",
  "pattern?": "string",
  "onChange?": "Action | Action[]",
  "cssClass?": "string"
}
```

For the complete protocol schema, see [Input](/protocol/input).
