By default, select uses the native HTML <select> element. This is perfect for most use cases - it works great on mobile, has built-in accessibility, and requires no JavaScript.
<div class="w-full max-w-64">
<c-ui.select name="country" placeholder="Select a country">
<c-ui.select.option value="us">United States</c-ui.select.option>
<c-ui.select.option value="uk">United Kingdom</c-ui.select.option>
<c-ui.select.option value="ca">Canada</c-ui.select.option>
<c-ui.select.option value="au">Australia</c-ui.select.option>
<c-ui.select.option value="de">Germany</c-ui.select.option>
</c-ui.select>
</div>
<div class="w-full max-w-64">
{% cotton ui.select name="country" placeholder="Select a country" %}
{% cotton ui.select.option value="us" %}United States{% endcotton %}
{% cotton ui.select.option value="uk" %}United Kingdom{% endcotton %}
{% cotton ui.select.option value="ca" %}Canada{% endcotton %}
{% cotton ui.select.option value="au" %}Australia{% endcotton %}
{% cotton ui.select.option value="de" %}Germany{% endcotton %}
{% endcotton %}
</div>
Use variant="listbox" when you need custom styling, icons, descriptions, or search functionality. This provides a rich, fully customizable dropdown experience.
<div class="w-full max-w-64">
<c-ui.select name="plan" variant="listbox" placeholder="Choose a plan">
<c-ui.menu.item value="free">Free</c-ui.menu.item>
<c-ui.menu.item value="starter">Starter</c-ui.menu.item>
<c-ui.menu.item value="pro">Professional</c-ui.menu.item>
<c-ui.menu.item value="enterprise">Enterprise</c-ui.menu.item>
</c-ui.select>
</div>
<div class="w-full max-w-64">
{% cotton ui.select name="plan" variant="listbox" placeholder="Choose a plan" %}
{% cotton ui.menu.item value="free" %}Free{% endcotton %}
{% cotton ui.menu.item value="starter" %}Starter{% endcotton %}
{% cotton ui.menu.item value="pro" %}Professional{% endcotton %}
{% cotton ui.menu.item value="enterprise" %}Enterprise{% endcotton %}
{% endcotton %}
</div>
Organize options into logical groups with labels.
<div class="w-full max-w-64">
<c-ui.select name="region" variant="listbox" placeholder="Select a region">
<c-ui.menu.group label="North America">
<c-ui.menu.item value="us" group="North America">United States</c-ui.menu.item>
<c-ui.menu.item value="ca" group="North America">Canada</c-ui.menu.item>
<c-ui.menu.item value="mx" group="North America">Mexico</c-ui.menu.item>
</c-ui.menu.group>
<c-ui.menu.group label="Europe">
<c-ui.menu.item value="uk" group="Europe">United Kingdom</c-ui.menu.item>
<c-ui.menu.item value="de" group="Europe">Germany</c-ui.menu.item>
<c-ui.menu.item value="fr" group="Europe">France</c-ui.menu.item>
</c-ui.menu.group>
<c-ui.menu.group label="Asia">
<c-ui.menu.item value="jp" group="Asia">Japan</c-ui.menu.item>
<c-ui.menu.item value="cn" group="Asia">China</c-ui.menu.item>
<c-ui.menu.item value="in" group="Asia">India</c-ui.menu.item>
</c-ui.menu.group>
</c-ui.select>
</div>
<div class="w-full max-w-64">
{% cotton ui.select name="region" variant="listbox" placeholder="Select a region" %}
{% cotton ui.menu.group label="North America" %}
{% cotton ui.menu.item value="us" group="North America" %}United States{% endcotton %}
{% cotton ui.menu.item value="ca" group="North America" %}Canada{% endcotton %}
{% cotton ui.menu.item value="mx" group="North America" %}Mexico{% endcotton %}
{% endcotton %}
{% cotton ui.menu.group label="Europe" %}
{% cotton ui.menu.item value="uk" group="Europe" %}United Kingdom{% endcotton %}
{% cotton ui.menu.item value="de" group="Europe" %}Germany{% endcotton %}
{% cotton ui.menu.item value="fr" group="Europe" %}France{% endcotton %}
{% endcotton %}
{% cotton ui.menu.group label="Asia" %}
{% cotton ui.menu.item value="jp" group="Asia" %}Japan{% endcotton %}
{% cotton ui.menu.item value="cn" group="Asia" %}China{% endcotton %}
{% cotton ui.menu.item value="in" group="Asia" %}India{% endcotton %}
{% endcotton %}
{% endcotton %}
</div>
Add icons to options for better visual context.
<div class="w-full max-w-64">
<c-ui.select name="payment" variant="listbox" placeholder="Select payment method">
<c-ui.menu.item value="card" label="Credit Card">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
</c-ui.menu.item>
<c-ui.menu.item value="paypal" label="PayPal">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
</c-ui.menu.item>
<c-ui.menu.item value="bank" label="Bank Transfer">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
</c-ui.menu.item>
</c-ui.select>
</div>
<div class="w-full max-w-64">
{% cotton ui.select name="payment" variant="listbox" placeholder="Select payment method" %}
{% cotton ui.menu.item value="card" label="Credit Card" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
{% endcotton %}
{% cotton ui.menu.item value="paypal" label="PayPal" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
{% endcotton %}
{% cotton ui.menu.item value="bank" label="Bank Transfer" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
{% endcotton %}
{% endcotton %}
</div>
Add descriptions to provide additional context for each option.
<div class="w-full max-w-64">
<c-ui.select name="plan" variant="listbox" placeholder="Choose your plan">
<c-ui.menu.item value="free" label="Free" description="Perfect for personal projects" />
<c-ui.menu.item value="starter" label="Starter" description="Great for small teams • $9/month" />
<c-ui.menu.item value="pro" label="Professional" description="For growing businesses • $29/month" />
<c-ui.menu.item value="enterprise" label="Enterprise" description="Advanced features & support • $99/month" />
</c-ui.select>
</div>
<div class="w-full max-w-64">
{% cotton ui.select name="plan" variant="listbox" placeholder="Choose your plan" %}
{% cotton ui.menu.item value="free" label="Free" description="Perfect for personal projects" /%}
{% cotton ui.menu.item value="starter" label="Starter" description="Great for small teams • $9/month" /%}
{% cotton ui.menu.item value="pro" label="Professional" description="For growing businesses • $29/month" /%}
{% cotton ui.menu.item value="enterprise" label="Enterprise" description="Advanced features & support • $99/month" /%}
{% endcotton %}
</div>
Combine icons and descriptions for maximum context.
<div class="w-full max-w-64">
<c-ui.select name="integration" variant="listbox" placeholder="Select integration">
<c-ui.menu.group label="Development">
<c-ui.menu.item value="github" label="GitHub" description="Version control and collaboration" group="Development">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
</c-ui.menu.item>
<c-ui.menu.item value="gitlab" label="GitLab" description="DevOps platform" group="Development">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
</c-ui.menu.item>
</c-ui.menu.group>
<c-ui.menu.group label="Communication">
<c-ui.menu.item value="slack" label="Slack" description="Team messaging" group="Communication">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
</c-ui.menu.item>
</c-ui.menu.group>
</c-ui.select>
</div>
<div class="w-full max-w-64">
{% cotton ui.select name="integration" variant="listbox" placeholder="Select integration" %}
{% cotton ui.menu.group label="Development" %}
{% cotton ui.menu.item value="github" label="GitHub" description="Version control and collaboration" group="Development" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
{% endcotton %}
{% cotton ui.menu.item value="gitlab" label="GitLab" description="DevOps platform" group="Development" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
{% endcotton %}
{% endcotton %}
{% cotton ui.menu.group label="Communication" %}
{% cotton ui.menu.item value="slack" label="Slack" description="Team messaging" group="Communication" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
{% endcotton %}
{% endcotton %}
{% endcotton %}
</div>
Select components run from size="xs" to size="2xl", defaulting to md.
<div class="w-full max-w-64 space-y-4">
<c-ui.select name="size-sm" variant="listbox" placeholder="Small select" size="sm">
<c-ui.menu.item value="1">Option 1</c-ui.menu.item>
<c-ui.menu.item value="2">Option 2</c-ui.menu.item>
</c-ui.select>
<c-ui.select name="size-default" variant="listbox" placeholder="Default select">
<c-ui.menu.item value="1">Option 1</c-ui.menu.item>
<c-ui.menu.item value="2">Option 2</c-ui.menu.item>
</c-ui.select>
<c-ui.select name="size-lg" variant="listbox" placeholder="Large select" size="lg">
<c-ui.menu.item value="1">Option 1</c-ui.menu.item>
<c-ui.menu.item value="2">Option 2</c-ui.menu.item>
</c-ui.select>
</div>
<div class="w-full max-w-64 space-y-4">
{% cotton ui.select name="size-sm" variant="listbox" placeholder="Small select" size="sm" %}
{% cotton ui.menu.item value="1" %}Option 1{% endcotton %}
{% cotton ui.menu.item value="2" %}Option 2{% endcotton %}
{% endcotton %}
{% cotton ui.select name="size-default" variant="listbox" placeholder="Default select" %}
{% cotton ui.menu.item value="1" %}Option 1{% endcotton %}
{% cotton ui.menu.item value="2" %}Option 2{% endcotton %}
{% endcotton %}
{% cotton ui.select name="size-lg" variant="listbox" placeholder="Large select" size="lg" %}
{% cotton ui.menu.item value="1" %}Option 1{% endcotton %}
{% cotton ui.menu.item value="2" %}Option 2{% endcotton %}
{% endcotton %}
</div>
Disable the select to prevent interaction, or disable specific options.
<div class="w-full max-w-64 space-y-4">
<!-- Disabled select -->
<c-ui.select name="disabled" variant="listbox" placeholder="Disabled select" disabled>
<c-ui.menu.item value="1">Option 1</c-ui.menu.item>
<c-ui.menu.item value="2">Option 2</c-ui.menu.item>
</c-ui.select>
<!-- Disabled options -->
<c-ui.select name="disabled-options" variant="listbox" placeholder="Select an option">
<c-ui.menu.item value="available">Available</c-ui.menu.item>
<c-ui.menu.item value="sold-out" disabled>Sold Out</c-ui.menu.item>
<c-ui.menu.item value="coming-soon" disabled>Coming Soon</c-ui.menu.item>
<c-ui.menu.item value="in-stock">In Stock</c-ui.menu.item>
</c-ui.select>
</div>
<div class="w-full max-w-64 space-y-4">
<!-- Disabled select -->
{% cotton ui.select name="disabled" variant="listbox" placeholder="Disabled select" disabled %}
{% cotton ui.menu.item value="1" %}Option 1{% endcotton %}
{% cotton ui.menu.item value="2" %}Option 2{% endcotton %}
{% endcotton %}
<!-- Disabled options -->
{% cotton ui.select name="disabled-options" variant="listbox" placeholder="Select an option" %}
{% cotton ui.menu.item value="available" %}Available{% endcotton %}
{% cotton ui.menu.item value="sold-out" disabled %}Sold Out{% endcotton %}
{% cotton ui.menu.item value="coming-soon" disabled %}Coming Soon{% endcotton %}
{% cotton ui.menu.item value="in-stock" %}In Stock{% endcotton %}
{% endcotton %}
</div>
The listbox flips above the trigger when there isn't room below, keeping the options in view. Drag the handle to shorten the viewport and watch it flip. (Native selects are positioned by the browser.)
Give it any field attribute (label, description, error or badge) and the select wraps itself in a Field component, giving you the label, helper text and error styling with no extra markup.
<c-ui.select
name="country"
label="Country"
placeholder="Select a country"
description="Where are you based?"
>
<c-ui.select.option value="us">United States</c-ui.select.option>
<c-ui.select.option value="uk">United Kingdom</c-ui.select.option>
<c-ui.select.option value="ca">Canada</c-ui.select.option>
</c-ui.select>
{% cotton ui.select
name="country"
label="Country"
placeholder="Select a country"
description="Where are you based?"
%}
{% cotton ui.select.option value="us" %}United States{% endcotton %}
{% cotton ui.select.option value="uk" %}United Kingdom{% endcotton %}
{% cotton ui.select.option value="ca" %}Canada{% endcotton %}
{% endcotton %}
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
name |
Form field name for submission. | str | — | |
placeholder |
Placeholder text when no option selected. | str | — | Select an option |
disabled |
Disable the entire select. | bool | — | False |
required |
Make the field required. | bool | — | False |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
size |
Size variant from xs to 2xl. | str |
xssmmdlgxl2xl
|
md |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
placeholder |
Search input placeholder text. | str | — | Search... |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
label |
Group label text displayed above grouped options. | str | — |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
value |
Option value (required). Submitted with the form. | str | — | |
label |
Option label. Defaults to slot content if not provided. | str | — | |
description |
Secondary description text displayed below the option label. | str | — | |
group |
Group identifier for filtering. Should match the group label. | str | — | |
disabled |
Disable this specific option. | bool | — | False |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
slot (default) |
Main select content including trigger, search, groups, and options. | — | — | |
icon (Option only) |
Icon or avatar displayed before option label. Provide an SVG element. | slot | — |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
select-change |
Fired when selection changes. Detail: { value, label } | CustomEvent | — |