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?" /%}

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-zinc-600 dark:text-zinc-400">$</span>
    </c-slot>
    <c-slot name="right_addon">
        <span class="text-zinc-600 dark:text-zinc-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-zinc-600 dark:text-zinc-400">$</span>
    {% endcotton:slot %}
    {% cotton:slot right_addon %}
        <span class="text-zinc-600 dark:text-zinc-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