<c-ui.field>
<c-ui.label>Email</c-ui.label>
<c-ui.input type="email" name="email" placeholder="you@example.com" />
<c-ui.error name="email" />
</c-ui.field>
{% cotton ui.field %}
{% cotton ui.label %}Email{% endcotton %}
{% cotton ui.input type="email" name="email" placeholder="you@example.com" /%}
{% cotton ui.error name="email" /%}
{% endcotton %}
To reduce repetitive markup, form controls like input and textarea can accept label, description, error, and badge props directly. When any of these props are provided, the control will automatically be wrapped in a field structure.
<c-ui.input
label="Email Address"
type="email"
name="email"
placeholder="Enter your email"
/>
<c-ui.input
label="Password"
badge="Required"
description_trailing="Must be at least 8 characters"
type="password"
name="password"
placeholder="•••••••••"
/>
<c-ui.textarea
label="Bio"
description="Tell us about yourself"
name="bio"
placeholder="Write something..."
/>
{% cotton ui.input
label="Email Address"
type="email"
name="email"
placeholder="Enter your email"
/%}
{% cotton ui.input
label="Password"
badge="Required"
description_trailing="Must be at least 8 characters"
type="password"
name="password"
placeholder="•••••••••"
/%}
{% cotton ui.textarea
label="Bio"
description="Tell us about yourself"
name="bio"
placeholder="Write something..."
/%}
Add a badge to the label to indicate required or optional fields.
<c-ui.field>
<c-ui.label badge="Required">Full Name</c-ui.label>
<c-ui.input type="text" name="name" placeholder="John Doe" />
</c-ui.field>
<c-ui.field>
<c-ui.label badge="Optional">Phone Number</c-ui.label>
<c-ui.input type="tel" name="phone" placeholder="+1 (555) 000-0000" />
</c-ui.field>
{% cotton ui.field %}
{% cotton ui.label badge="Required" %}Full Name{% endcotton %}
{% cotton ui.input type="text" name="name" placeholder="John Doe" /%}
{% endcotton %}
{% cotton ui.field %}
{% cotton ui.label badge="Optional" %}Phone Number{% endcotton %}
{% cotton ui.input type="tel" name="phone" placeholder="+1 (555) 000-0000" /%}
{% endcotton %}
Add helper text to provide context about the field. Descriptions can appear before or after the input.
{# Description before input #}
<c-ui.field>
<c-ui.label>Username</c-ui.label>
<c-ui.description>This will be your public display name.</c-ui.description>
<c-ui.input type="text" name="username" placeholder="johndoe" />
</c-ui.field>
{# Description after input (trailing) #}
<c-ui.field>
<c-ui.label>Email</c-ui.label>
<c-ui.input type="email" name="email" placeholder="you@example.com" />
<c-ui.description>We'll send confirmation to this address.</c-ui.description>
</c-ui.field>
{# Description before input #}
{% cotton ui.field %}
{% cotton ui.label %}Username{% endcotton %}
{% cotton ui.description %}This will be your public display name.{% endcotton %}
{% cotton ui.input type="text" name="username" placeholder="johndoe" /%}
{% endcotton %}
{# Description after input (trailing) #}
{% cotton ui.field %}
{% cotton ui.label %}Email{% endcotton %}
{% cotton ui.input type="email" name="email" placeholder="you@example.com" /%}
{% cotton ui.description %}We'll send confirmation to this address.{% endcotton %}
{% endcotton %}
Display validation feedback with the error component. Supports Django form integration or explicit messages.
{# With explicit message #}
<c-ui.field>
<c-ui.label>Password</c-ui.label>
<c-ui.input type="password" name="password" placeholder="•••••••••" />
<c-ui.error message="Password must be at least 8 characters." />
</c-ui.field>
{# With Django form integration #}
<c-ui.field>
<c-ui.label>Email</c-ui.label>
<c-ui.input type="email" name="email" />
<c-ui.error name="email" :form="form" />
</c-ui.field>
{# With explicit message #}
{% cotton ui.field %}
{% cotton ui.label %}Password{% endcotton %}
{% cotton ui.input type="password" name="password" placeholder="•••••••••" /%}
{% cotton ui.error message="Password must be at least 8 characters." /%}
{% endcotton %}
{# With Django form integration #}
{% cotton ui.field %}
{% cotton ui.label %}Email{% endcotton %}
{% cotton ui.input type="email" name="email" /%}
{% cotton ui.error name="email" :form="form" /%}
{% endcotton %}
Combining all elements together with Django form integration.
<c-ui.field>
<c-ui.label badge="Required">Password</c-ui.label>
<c-ui.description>
Must include at least 8 characters with uppercase, lowercase, and numbers.
</c-ui.description>
<c-ui.input type="password" name="password" placeholder="•••••••••" />
<c-ui.error name="password" />
</c-ui.field>
{% cotton ui.field %}
{% cotton ui.label badge="Required" %}Password{% endcotton %}
{% cotton ui.description %}
Must include at least 8 characters with uppercase, lowercase, and numbers.
{% endcotton %}
{% cotton ui.input type="password" name="password" placeholder="•••••••••" /%}
{% cotton ui.error name="password" /%}
{% endcotton %}
The default block layout stacks the label above the control. Two named
shortcuts cover the common alternatives: inline sits the label beside the
control, and toggle pushes the control to the far right (ideal for switches
and checkboxes). The Switch uses the toggle
layout for its own inline prop.
These shortcuts only exist because they encode flex wiring that is awkward to repeat by hand. They are deliberately few: for anything outside them, pass utility classes on the field rather than waiting for a new variant to be invented.
{# block: label above control (default) #}
<c-ui.field>
<c-ui.label>Email</c-ui.label>
<c-ui.input type="email" name="email" placeholder="you@example.com" />
</c-ui.field>
{# inline: label beside control #}
<c-ui.field variant="inline">
<c-ui.label class="w-24 pt-2">Email</c-ui.label>
<div class="flex-1">
<c-ui.input type="email" name="email" placeholder="you@example.com" />
</div>
</c-ui.field>
{# toggle: control pushed to the far right #}
<c-ui.field variant="toggle" label="Email alerts" description="Get notified about activity.">
<c-ui.switch name="alerts" />
</c-ui.field>
{# escape hatch: override classes for anything else #}
<c-ui.field class="flex flex-row-reverse items-center gap-3">
...
</c-ui.field>
{# block: label above control (default) #}
{% cotton ui.field %}
{% cotton ui.label %}Email{% endcotton %}
{% cotton ui.input type="email" name="email" placeholder="you@example.com" /%}
{% endcotton %}
{# inline: label beside control #}
{% cotton ui.field variant="inline" %}
{% cotton ui.label class="w-24 pt-2" %}Email{% endcotton %}
<div class="flex-1">
{% cotton ui.input type="email" name="email" placeholder="you@example.com" /%}
</div>
{% endcotton %}
{# toggle: control pushed to the far right #}
{% cotton ui.field variant="toggle" label="Email alerts" description="Get notified about activity." %}
{% cotton ui.switch name="alerts" /%}
{% endcotton %}
{# escape hatch: override classes for anything else #}
{% cotton ui.field class="flex flex-row-reverse items-center gap-3" %}
...
{% endcotton %}
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
variant |
Layout variant. 'block' stacks the label above the control, 'inline' sits the label beside it, 'toggle' pushes the control to the far right. For anything else, pass utility classes via class. | str |
blockinlinetoggle
|
block |
class |
Utility classes merged onto the field wrapper. The escape hatch for layouts the variants don't cover. | str | — |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
badge |
Badge text like 'Required' or 'Optional'. | str | — | |
for |
ID of the associated input element. | str | — |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
slot (default) |
Helper text content - no props available. | — | — |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
name |
Field name to lookup in form.errors. Use '__all__' for non-field errors. | str | — | |
:form |
Django form instance. When provided with name, automatically displays validation errors from form.errors. | Form | — | None |
message |
Explicit error message to display. Bypasses form integration. | str | — |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
color |
Badge color variant. | str |
zincredorangeamberyellowlimegreenemeraldtealcyanskyblueindigovioletpurplefuchsiapinkrose
|
zinc |
size |
Badge size. | str |
smlg
|
|
variant |
Badge style variant. | str |
pillsolid
|
|
:inset |
Apply negative margins. | bool |
TrueFalse
|
False |