Radio

Radio buttons allow users to select a single option from a set.

<c-ui.radio.group name="payment" label="Payment method" value="cc">
    <c-ui.radio value="cc" label="Credit card" />
    <c-ui.radio value="paypal" label="PayPal" />
    <c-ui.radio value="bank" label="Bank transfer" />
</c-ui.radio.group>
{% cotton ui.radio.group name="payment" label="Payment method" value="cc" %}
    {% cotton ui.radio value="cc" label="Credit card" /%}
    {% cotton ui.radio value="paypal" label="PayPal" /%}
    {% cotton ui.radio value="bank" label="Bank transfer" /%}
{% endcotton %}

With Descriptions

Add contextual information to each option with the description attribute.

<c-ui.radio.group name="backup" label="Backup frequency" value="daily">
    <c-ui.radio
        value="realtime"
        label="Real-time"
        description="Continuous backup as changes occur" />
    <c-ui.radio
        value="daily"
        label="Daily"
        description="Automated backup every 24 hours" />
    <c-ui.radio
        value="weekly"
        label="Weekly"
        description="Weekly backup on Sunday at midnight" />
</c-ui.radio.group>
{% cotton ui.radio.group name="backup" label="Backup frequency" value="daily" %}
    {% cotton ui.radio
        value="realtime"
        label="Real-time"
        description="Continuous backup as changes occur"
    /%}
    {% cotton ui.radio value="daily" label="Daily" description="Automated backup every 24 hours" /%}
    {% cotton ui.radio
        value="weekly"
        label="Weekly"
        description="Weekly backup on Sunday at midnight"
    /%}
{% endcotton %}

Horizontal

Add horizontal to lay the options out in a wrapping row instead of stacking them.

<c-ui.radio.group name="tshirt" label="Size" horizontal value="m">
    <c-ui.radio value="xs" label="XS" />
    <c-ui.radio value="s" label="S" />
    <c-ui.radio value="m" label="M" />
    <c-ui.radio value="l" label="L" />
    <c-ui.radio value="xl" label="XL" />
</c-ui.radio.group>
{% cotton ui.radio.group name="tshirt" label="Size" horizontal value="m" %}
    {% cotton ui.radio value="xs" label="XS" /%}
    {% cotton ui.radio value="s" label="S" /%}
    {% cotton ui.radio value="m" label="M" /%}
    {% cotton ui.radio value="l" label="L" /%}
    {% cotton ui.radio value="xl" label="XL" /%}
{% endcotton %}

Segmented

Display options as a horizontal button group with the variant="segmented" attribute.

<c-ui.radio.group name="visibility" label="Post visibility" variant="segmented" value="public">
    <c-ui.radio value="public" label="Public" />
    <c-ui.radio value="unlisted" label="Unlisted" />
    <c-ui.radio value="private" label="Private" />
</c-ui.radio.group>
{% cotton ui.radio.group name="visibility" label="Post visibility" variant="segmented" value="public" %}
    {% cotton ui.radio value="public" label="Public" /%}
    {% cotton ui.radio value="unlisted" label="Unlisted" /%}
    {% cotton ui.radio value="private" label="Private" /%}
{% endcotton %}

Segmented with Icons

Put an icon and label together in a segmented option's slot to combine them (bring your own icon set).

<c-ui.radio.group name="weather" label="Weather today" variant="segmented" value="sunny">
    <c-ui.radio value="sunny">
        <span class="inline-flex items-center gap-2">
            <svg class="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                <circle cx="12" cy="12" r="4" />
                <path d="M12 2v2M12 20v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M2 12h2M20 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4" />
            </svg>
            Sunny
        </span>
    </c-ui.radio>
    <c-ui.radio value="cloudy">
        <span class="inline-flex items-center gap-2">
            <svg class="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                <path d="M7 18a4 4 0 0 1 0-8 5 5 0 0 1 9.6-1A3.5 3.5 0 0 1 17 18H7z" />
            </svg>
            Cloudy
        </span>
    </c-ui.radio>
    <c-ui.radio value="rainy">
        <span class="inline-flex items-center gap-2">
            <svg class="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                <path d="M7 15a4 4 0 0 1 0-8 5 5 0 0 1 9.6-1A3.5 3.5 0 0 1 17 15" />
                <path d="M8 19l-1 2M13 19l-1 2M18 19l-1 2" />
            </svg>
            Rainy
        </span>
    </c-ui.radio>
</c-ui.radio.group>
{% cotton ui.radio.group name="weather" label="Weather today" variant="segmented" value="sunny" %}
    {% cotton ui.radio value="sunny" %}
        <span class="inline-flex items-center gap-2">
            <svg class="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                <circle cx="12" cy="12" r="4" />
                <path d="M12 2v2M12 20v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M2 12h2M20 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4" />
            </svg>
            Sunny
        </span>
    {% endcotton %}
    {% cotton ui.radio value="cloudy" %}
        <span class="inline-flex items-center gap-2">
            <svg class="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                <path d="M7 18a4 4 0 0 1 0-8 5 5 0 0 1 9.6-1A3.5 3.5 0 0 1 17 18H7z" />
            </svg>
            Cloudy
        </span>
    {% endcotton %}
    {% cotton ui.radio value="rainy" %}
        <span class="inline-flex items-center gap-2">
            <svg class="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
                <path d="M7 15a4 4 0 0 1 0-8 5 5 0 0 1 9.6-1A3.5 3.5 0 0 1 17 15" />
                <path d="M8 19l-1 2M13 19l-1 2M18 19l-1 2" />
            </svg>
            Rainy
        </span>
    {% endcotton %}
{% endcotton %}

Pill segments

Add pill to a segmented group for a rounded, padded toggle where the active option fills with the accent color.

<c-ui.radio.group name="view" label="View" variant="pill" value="grid">
    <c-ui.radio value="list" label="List" />
    <c-ui.radio value="grid" label="Grid" />
    <c-ui.radio value="board" label="Board" />
</c-ui.radio.group>
{% cotton ui.radio.group name="view" label="View" variant="pill" value="grid" %}
    {% cotton ui.radio value="list" label="List" /%}
    {% cotton ui.radio value="grid" label="Grid" /%}
    {% cotton ui.radio value="board" label="Board" /%}
{% endcotton %}

Radio Cards

Display options as interactive cards with variant="cards". Perfect for visually distinct choices.

<c-ui.radio.group name="deployment" label="Deployment region" variant="cards" value="us-east">
    <c-ui.radio
        value="us-east"
        label="US East"
        description="Virginia (us-east-1)" />
    <c-ui.radio
        value="eu-west"
        label="EU West"
        description="Ireland (eu-west-1)" />
</c-ui.radio.group>
{% cotton ui.radio.group name="deployment" label="Deployment region" variant="cards" value="us-east" %}
    {% cotton ui.radio value="us-east" label="US East" description="Virginia (us-east-1)" /%}
    {% cotton ui.radio
        value="eu-west"
        label="EU West"
        description="Ireland (eu-west-1)"
    /%}
{% endcotton %}

Vertical Cards

Stack cards vertically by adding a class to the group.

<c-ui.radio.group name="database" label="Database engine" variant="cards" class="flex-col" value="postgresql">
    <c-ui.radio
        value="postgresql"
        label="PostgreSQL"
        description="Advanced open-source relational database" />
    <c-ui.radio
        value="mysql"
        label="MySQL"
        description="Popular open-source relational database" />
    <c-ui.radio
        value="mongodb"
        label="MongoDB"
        description="Flexible NoSQL document database" />
</c-ui.radio.group>
{% cotton ui.radio.group name="database" label="Database engine" variant="cards" class="flex-col" value="postgresql" %}
    {% cotton ui.radio value="postgresql" label="PostgreSQL" description="Advanced open-source relational database" /%}
    {% cotton ui.radio
        value="mysql"
        label="MySQL"
        description="Popular open-source relational database"
    /%}
    {% cotton ui.radio
        value="mongodb"
        label="MongoDB"
        description="Flexible NoSQL document database"
    /%}
{% endcotton %}

Cards Without Indicators

Hide the radio indicator for a cleaner card design with :show_indicator="False".

<c-ui.radio.group name="theme" label="Interface theme" variant="cards" value="light">
    <c-ui.radio
        value="light"
        label="Light"
        description="Bright background, dark text"
        :show_indicator="False" />
    <c-ui.radio
        value="dark"
        label="Dark"
        description="Dark background, light text"
        :show_indicator="False" />
    <c-ui.radio
        value="auto"
        label="Auto"
        description="Match system preferences"
        :show_indicator="False" />
</c-ui.radio.group>
{% cotton ui.radio.group name="theme" label="Interface theme" variant="cards" value="light" %}
    {% cotton ui.radio value="light" label="Light" description="Bright background, dark text" :show_indicator="False" /%}
    {% cotton ui.radio
        value="dark"
        label="Dark"
        description="Dark background, light text"
        :show_indicator="False"
    /%}
    {% cotton ui.radio
        value="auto"
        label="Auto"
        description="Match system preferences"
        :show_indicator="False"
    /%}
{% endcotton %}

Custom Content Card

Use slots to create fully custom card content with any HTML structure.

<c-ui.radio.group name="hosting" variant="cards" class="flex-col" value="shared">
    <c-ui.radio value="shared">
        <div class="flex items-start gap-4 flex-1">
            {# Radio indicator #}
            <div class="flex items-center h-5">...</div>

            {# Custom content #}
            <div class="flex-1">
                <div class="flex items-center justify-between">
                    <h3>Shared Hosting</h3>
                    <span class="text-accent">$5/mo</span>
                </div>
                <p>Cost-effective for small websites</p>
                <ul class="mt-3 space-y-1">
                    <li>10 GB storage</li>
                    <li>Shared resources</li>
                </ul>
            </div>
        </div>
    </c-ui.radio>
    <c-ui.radio value="vps">
        <div class="flex items-start gap-4 flex-1">
            {# Radio indicator #}
            <div class="flex items-center h-5">...</div>

            {# Custom content #}
            <div class="flex-1">
                <div class="flex items-center justify-between">
                    <h3>VPS Hosting</h3>
                    <span class="text-accent">$25/mo</span>
                </div>
                <p>Dedicated resources and full control</p>
                <ul class="mt-3 space-y-1">
                    <li>100 GB SSD storage</li>
                    <li>4 vCPU cores</li>
                    <li>Root access</li>
                </ul>
            </div>
        </div>
    </c-ui.radio>
</c-ui.radio.group>
{% cotton ui.radio.group name="hosting" variant="cards" class="flex-col" value="shared" %}
    {% cotton ui.radio value="shared" %}
        <div class="flex items-start gap-4 flex-1">
            {# Radio indicator #}
            <div class="flex items-center h-5">...</div>

            {# Custom content #}
            <div class="flex-1">
                <div class="flex items-center justify-between">
                    <h3>Shared Hosting</h3>
                    <span class="text-accent">$5/mo</span>
                </div>
                <p>Cost-effective for small websites</p>
                <ul class="mt-3 space-y-1">
                    <li>10 GB storage</li>
                    <li>Shared resources</li>
                </ul>
            </div>
        </div>
    {% endcotton %}
    {% cotton ui.radio value="vps" %}
        <div class="flex items-start gap-4 flex-1">
            {# Radio indicator #}
            <div class="flex items-center h-5">...</div>

            {# Custom content #}
            <div class="flex-1">
                <div class="flex items-center justify-between">
                    <h3>VPS Hosting</h3>
                    <span class="text-accent">$25/mo</span>
                </div>
                <p>Dedicated resources and full control</p>
                <ul class="mt-3 space-y-1">
                    <li>100 GB SSD storage</li>
                    <li>4 vCPU cores</li>
                    <li>Root access</li>
                </ul>
            </div>
        </div>
    {% endcotton %}
{% endcotton %}

As a field

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

How would you like to pay?
<c-ui.radio.group
    name="payment"
    label="Payment method"
    description="How would you like to pay?"
    value="cc"
>
    <c-ui.radio value="cc" label="Credit card" />
    <c-ui.radio value="paypal" label="PayPal" />
</c-ui.radio.group>
{% cotton ui.radio.group
    name="payment"
    label="Payment method"
    description="How would you like to pay?"
    value="cc"
%}
    {% cotton ui.radio
    value="cc"
    label="Credit card"
/%}
    {% cotton ui.radio value="paypal" label="PayPal" /%}
{% endcotton %}

API Reference

Radio Group Props

Name Description Type Options Default
name Form input name for the radio group str
label Group label displayed above options str
description Help text displayed below label str
value Value of the initially selected option (e.g. value=&quot;cc&quot; selects the option with value=&quot;cc&quot;) str
variant Visual style of the radio group str
defaultsegmentedpillcards
default
:pill With variant='segmented', renders rounded pill segments with a solid accent active state. bool
TrueFalse
False
:horizontal With the default variant, lays options out in a wrapping row instead of a vertical stack. bool
TrueFalse
False
class Additional CSS classes for the options container str

Radio Props

Name Description Type Options Default
value Value submitted when this option is selected str
label Label text for the option str
description Additional descriptive text below the label str
icon Icon name (for segmented variant) str
name Form input name (inherited from group if not specified) str
:disabled Whether this option is disabled bool
TrueFalse
False
:show_indicator Whether to show the radio indicator bool
TrueFalse
True
:accent Whether to use accent colors (True) or monochrome zinc colors (False) bool
TrueFalse
True

Slots

Name Description Type Options Default
slot (default) Custom content for the radio option. When used, you have full control over the markup.