Input

A single-line text input component with support for icons, buttons, and Alpine.js masks.

<c-ui.input placeholder="What's your name?" />
{% cotton ui.input placeholder="What's your name?" /%}

Any extra attribute you set is forwarded to the underlying <input>, so framework value-bindings (x-model, hx-*, data-*) attach straight to the control. This holds across the form components (select, textarea, checkbox, radio, switch, range); those with a hidden value control receive it there, while class stays on the visible wrapper.

Types

Use the type attribute to change the input type.

<c-ui.input type="text" placeholder="Text (default)" />
<c-ui.input type="email" placeholder="Email address" />
<c-ui.input type="password" placeholder="Password" />
<c-ui.input type="number" placeholder="Number" />
<c-ui.input type="tel" placeholder="Telephone" />
<c-ui.input type="url" placeholder="URL" />
{% cotton ui.input type="text" placeholder="Text (default)" /%}
{% cotton ui.input type="email" placeholder="Email address" /%}
{% cotton ui.input type="password" placeholder="Password" /%}
{% cotton ui.input type="number" placeholder="Number" /%}
{% cotton ui.input type="tel" placeholder="Telephone" /%}
{% cotton ui.input type="url" placeholder="URL" /%}

Sizes

Six size variants are available, from size="xs" to size="2xl". The default is md.

<c-ui.input size="xs" placeholder="Extra small" />
<c-ui.input size="sm" placeholder="Small" />
<c-ui.input size="md" placeholder="Medium (default)" />
<c-ui.input size="lg" placeholder="Large" />
<c-ui.input size="xl" placeholder="Extra large" />
<c-ui.input size="2xl" placeholder="2XL" />
{% cotton ui.input size="xs" placeholder="Extra small" /%}
{% cotton ui.input size="sm" placeholder="Small" /%}
{% cotton ui.input size="md" placeholder="Medium (default)" /%}
{% cotton ui.input size="lg" placeholder="Large" /%}
{% cotton ui.input size="xl" placeholder="Extra large" /%}
{% cotton ui.input size="2xl" placeholder="2XL" /%}

With Icons

Add icons using the left_addon and right_addon slots for visual context.

$
USD
<c-ui.input placeholder="Search..." label="Search">
    <c-slot name="left_addon">
        <svg><!-- search icon --></svg>
    </c-slot>
</c-ui.input>

<c-ui.input type="email" placeholder="you@example.com" label="Email">
    <c-slot name="left_addon">
        <svg><!-- email icon --></svg>
    </c-slot>
</c-ui.input>

<c-ui.input placeholder="Enter amount" label="Price">
    <c-slot name="left_addon">
        <span class="text-ink-600 dark:text-ink-400">$</span>
    </c-slot>
    <c-slot name="right_addon">
        <span class="text-ink-600 dark:text-ink-400">USD</span>
    </c-slot>
</c-ui.input>
{% cotton ui.input placeholder="Search..." label="Search" %}
    {% cotton:slot left_addon %}
        <svg><!-- search icon --></svg>
    {% endcotton:slot %}
{% endcotton %}

{% cotton ui.input type="email" placeholder="you@example.com" label="Email" %}
    {% cotton:slot left_addon %}
        <svg><!-- email icon --></svg>
    {% endcotton:slot %}
{% endcotton %}

{% cotton ui.input placeholder="Enter amount" label="Price" %}
    {% cotton:slot left_addon %}
        <span class="text-ink-600 dark:text-ink-400">$</span>
    {% endcotton:slot %}
    {% cotton:slot right_addon %}
        <span class="text-ink-600 dark:text-ink-400">USD</span>
    {% endcotton:slot %}
{% endcotton %}

Alpine.js Masks

Use Alpine.js x-mask directive for formatted input fields like phone numbers, dates, and credit cards.

<c-ui.input
    name="phone"
    placeholder="(123) 456-7890"
    :attrs="{'x-mask': '(999) 999-9999'}"
    label="Phone Number">
    <c-slot name="left_addon">
        <svg><!-- phone icon --></svg>
    </c-slot>
</c-ui.input>

<c-ui.input
    name="date"
    placeholder="MM/DD/YYYY"
    :attrs="{'x-mask': '99/99/9999'}"
    label="Date of Birth">
    <c-slot name="left_addon">
        <svg><!-- calendar icon --></svg>
    </c-slot>
</c-ui.input>

<c-ui.input
    name="card"
    placeholder="1234 5678 9012 3456"
    :attrs="{'x-mask': '9999 9999 9999 9999'}"
    label="Credit Card">
    <c-slot name="left_addon">
        <svg><!-- credit card icon --></svg>
    </c-slot>
</c-ui.input>

<c-ui.input
    name="ssn"
    placeholder="123-45-6789"
    :attrs="{'x-mask': '999-99-9999'}"
    label="Social Security Number">
    <c-slot name="left_addon">
        <svg><!-- lock icon --></svg>
    </c-slot>
</c-ui.input>
{% cotton ui.input name="phone" placeholder="(123) 456-7890" :attrs="{'x-mask': '(999) 999-9999'}" label="Phone Number" %}
    {% cotton:slot left_addon %}
        <svg><!-- phone icon --></svg>
    {% endcotton:slot %}
{% endcotton %}

{% cotton ui.input name="date" placeholder="MM/DD/YYYY" :attrs="{'x-mask': '99/99/9999'}" label="Date of Birth" %}
    {% cotton:slot left_addon %}
        <svg><!-- calendar icon --></svg>
    {% endcotton:slot %}
{% endcotton %}

{% cotton ui.input name="card" placeholder="1234 5678 9012 3456" :attrs="{'x-mask': '9999 9999 9999 9999'}" label="Credit Card" %}
    {% cotton:slot left_addon %}
        <svg><!-- credit card icon --></svg>
    {% endcotton:slot %}
{% endcotton %}

{% cotton ui.input name="ssn" placeholder="123-45-6789" :attrs="{'x-mask': '999-99-9999'}" label="Social Security Number" %}
    {% cotton:slot left_addon %}
        <svg><!-- lock icon --></svg>
    {% endcotton:slot %}
{% endcotton %}

States

Input states for different use cases including disabled, readonly, and with field labels.

This input is disabled
This input is readonly
Choose a unique username
<c-ui.input
    placeholder="You can't edit this"
    disabled
    label="Disabled"
    description="This input is disabled"
/>

<c-ui.input
    value="Read-only value"
    readonly
    label="Readonly"
    description="This input is readonly"
/>

<c-ui.input
    name="username"
    placeholder="Enter username"
    label="Username"
    description="Choose a unique username"
    badge="Required"
/>

<c-ui.input
    name="email"
    type="email"
    placeholder="your@email.com"
    label="Email"
    error="This email is already taken"
/>
{% cotton ui.input
    placeholder="You can't edit this"
    disabled
    label="Disabled"
    description="This input is disabled"
/%}

{% cotton ui.input
    value="Read-only value"
    readonly
    label="Readonly"
    description="This input is readonly"
/%}

{% cotton ui.input
    name="username"
    placeholder="Enter username"
    label="Username"
    description="Choose a unique username"
    badge="Required"
/%}

{% cotton ui.input
    name="email"
    type="email"
    placeholder="your@email.com"
    label="Email"
    error="This email is already taken"
/%}

As a field

Give it any field attribute (label, description, error or badge) and the input wraps itself in a Field component, giving you the label, helper text and error styling with no extra markup.

We'll only use this for receipts.
<c-ui.input
    label="Email"
    type="email"
    placeholder="you@example.com"
    description="We'll only use this for receipts."
/>
{% cotton ui.input
    label="Email"
    type="email"
    placeholder="you@example.com"
    description="We'll only use this for receipts."
/%}

Reference

Props

Name Description Type Options Default
type The HTML input type str
textpasswordemailnumbertelurlsearchdatetimedatetime-local
text
name Form field name for submission str —
value Initial value of the input str —
placeholder Placeholder text displayed when the input is empty str —
size Size variant from xs to 2xl. str
xssmmdlgxl2xl
md
:disabled Disables the input and prevents interaction bool
TrueFalse
False
:readonly Makes the input readonly (user can't edit but can copy) bool
TrueFalse
False
label Label text displayed above the input (automatically wraps in field) str —
description Helper text displayed below the label str —
description_trailing Additional helper text displayed after the input str —
error Error message to display (field name for Django form error lookup, or explicit message) str —
badge Badge text to display next to the label (e.g., 'Required' or 'Optional') str —
form Django form object for automatic error handling Form —

Slots

Name Description Type Options Default
left_addon Content to display on the left side of the input (icons, text, buttons). Static icons are non-clickable by default (pointer-events-none). Add class='pointer-events-auto' for clickable elements. slot —
right_addon Content to display on the right side of the input (icons, text, buttons). Static icons are non-clickable by default (pointer-events-none). Add class='pointer-events-auto' for clickable elements. slot —
Theme
Accent
Ink