Select
---import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } from "@/components/starwind/select";---
<Select> <SelectTrigger class="w-[180px]"> <SelectValue placeholder="Select" /> </SelectTrigger> <SelectContent> <SelectGroup> <SelectLabel>Frameworks</SelectLabel> <SelectItem value="astro">Astro</SelectItem> <SelectItem value="next">Next.js</SelectItem> <SelectItem value="svelte">SvelteKit</SelectItem> <SelectItem value="solid">SolidStart</SelectItem> </SelectGroup> </SelectContent></Select>
Installation
pnpx starwind@latest add select
npx starwind@latest add select
yarn dlx starwind@latest add select
Usage
Basic Select
The most basic select component consists of a trigger, value display, and content with items.
---import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/starwind/select";---
<Select> <SelectTrigger class="w-[180px]"> <SelectValue placeholder="Select a fruit" /> </SelectTrigger> <SelectContent> <SelectItem value="apple">Apple</SelectItem> <SelectItem value="banana">Banana</SelectItem> <SelectItem value="orange">Orange</SelectItem> </SelectContent></Select>
Form Handling
New as of v1.2.0This component mirrors the behavior of a standard HTML select element. Internally, it renders a hidden <select>
to integrate seamlessly with forms.
Tip
Open up the dev tools console to see the form data on submission.
---import { Button } from "@/components/starwind/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,} from "@/components/starwind/card";
import { Input } from "@/components/starwind/input";import { Label } from "@/components/starwind/label";
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem, SelectGroup, SelectLabel, SelectSeparator,} from "@/components/starwind/select";---
<Card class="w-[400px]"> <CardHeader> <CardTitle>Create project</CardTitle> <CardDescription>Deploy your new project in one-click.</CardDescription> </CardHeader> <form id="create-project-form"> <CardContent class="flex flex-col gap-4"> <div class="flex w-full flex-col gap-2"> <Label for="name">Name</Label> <Input type="text" id="name" name="name" placeholder="Name of your project" /> </div> <div class="flex w-full flex-col gap-2"> <Label for="framework">Framework</Label> <Select id="framework" name="framework"> <SelectTrigger class="w-full" required> <SelectValue placeholder="Select" /> </SelectTrigger> <SelectContent> <SelectGroup> <SelectLabel>Frameworks</SelectLabel> <SelectItem value="astro">Astro</SelectItem> <SelectItem value="next">Next.js</SelectItem> <SelectItem value="svelte">SvelteKit</SelectItem> <SelectItem value="solid">SolidStart</SelectItem> </SelectGroup> </SelectContent> </Select> </div> </CardContent> <CardFooter class="flex justify-between"> <Button variant="outline">Cancel</Button> <Button type="submit">Deploy</Button> </CardFooter> </form></Card>
<script> function handleFormSubmit() { const form = document.querySelector("#create-project-form") as HTMLFormElement; if (form) { form.addEventListener("submit", (e) => { e.preventDefault(); const formData = new FormData(form); const formValues = Object.fromEntries(formData.entries());
// demo form data logging console.log("Form submission values:", formValues);
// You can add additional logic here like: // - Form validation // - API submission // - Success/error handling }); } }
handleFormSubmit();
document.addEventListener("astro:after-swap", handleFormSubmit);</script>
With Groups and Labels
Group related items together and add labels for better organization.
---import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } from "@/components/starwind/select";---
<Select> <SelectTrigger class="w-[180px]"> <SelectValue placeholder="Select a food" /> </SelectTrigger> <SelectContent> <SelectGroup> <SelectLabel>Fruits</SelectLabel> <SelectItem value="apple">Apple</SelectItem> <SelectItem value="banana">Banana</SelectItem> </SelectGroup> <SelectSeparator /> <SelectGroup> <SelectLabel>Vegetables</SelectLabel> <SelectItem value="carrot">Carrot</SelectItem> <SelectItem value="spinach">Spinach</SelectItem> </SelectGroup> </SelectContent></Select>
Positioning
You can control the position of the select dropdown using the side
and sideOffset
props on SelectContent
.
---import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/starwind/select";---
<Select> <SelectTrigger class="w-[180px]"> <SelectValue placeholder="Opens above" /> </SelectTrigger> <SelectContent side="top" sideOffset={12}> <SelectItem value="1">Option 1</SelectItem> <SelectItem value="2">Option 2</SelectItem> <SelectItem value="3">Option 3</SelectItem> </SelectContent></Select>
<Select> <SelectTrigger class="w-[180px]"> <SelectValue placeholder="Opens below" /> </SelectTrigger> <SelectContent side="bottom" sideOffset={4}> <SelectItem value="1">Option 1</SelectItem> <SelectItem value="2">Option 2</SelectItem> <SelectItem value="3">Option 3</SelectItem> </SelectContent></Select>
Disabled State
You can disable the select trigger or individual items.
---import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/starwind/select";---
<Select> <SelectTrigger disabled class="w-[180px]"> <SelectValue placeholder="Disabled trigger" /> </SelectTrigger> <SelectContent> <SelectItem value="1">Option 1</SelectItem> <SelectItem value="2">Option 2</SelectItem> </SelectContent></Select>
<Select> <SelectTrigger class="w-[180px]"> <SelectValue placeholder="With disabled items" /> </SelectTrigger> <SelectContent> <SelectItem value="1">Option 1</SelectItem> <SelectItem value="2" disabled>Option 2 (Disabled)</SelectItem> <SelectItem value="3">Option 3</SelectItem> <SelectItem value="4" disabled>Option 4 (Disabled)</SelectItem> <SelectItem value="5">Option 5</SelectItem> </SelectContent></Select>
Event Handling
The select component emits a starwind-select:change
event when a selection is made. The selected value can be accessed through event.detail.value
.
<Select> <SelectTrigger class="w-[180px]"> <SelectValue placeholder="Select option" /> </SelectTrigger> <SelectContent> <SelectItem value="1">Option 1</SelectItem> <SelectItem value="2">Option 2</SelectItem> </SelectContent></Select>
<script> document.querySelector('.starwind-select')?.addEventListener('starwind-select:change', (event) => { console.log('Selected value:', event.detail.value); });</script>
API Reference
Select
The root component that manages the select state. Accepts all standard HTML div
attributes.
SelectTrigger
The button that toggles the select dropdown. Renders a native button
element and accepts all standard HTML <button>
attributes except role
and type
which are managed internally.
Prop | Type | Default |
---|---|---|
required | boolean | false |
disabled | boolean | false |
SelectContent
The dropdown content that appears when the select is open.
Prop | Type | Default |
---|---|---|
animationDuration | number | 150 |
side | "top" | "bottom" | "bottom" |
sideOffset | number | 4 |
This component also accepts all standard HTML div
attributes.
SelectItem
An item that can be selected. Requires a value
prop.
Prop | Type | Default |
---|---|---|
value | string | - |
disabled | boolean | false |
This component also accepts all standard HTML div
attributes.
SelectValue
The component that displays the selected value or placeholder text in the trigger.
Prop | Type | Default |
---|---|---|
placeholder | string | "select" |
This component accepts all standard HTML span
attributes.
SelectGroup
A component used to group related select items together. Currently serves as a semantic wrapper for grouping items.
SelectLabel
A label component used to give a title to a group of items. This component accepts all standard HTML div
attributes.
SelectSeparator
A visual separator that can be used between select items. This component accepts all standard HTML div
attributes.
Changelog
v1.2.0
- Allow a “name” attribute to enable simple form handling by leveraging the hidden html
<select>
element that is auto-generated. - Add empty
aria-controls=""
toSelectTrigger
to make eslint happy. It is still assigned by the script.
v1.1.0
tailwind-variants
now implemented. This usestailwind-merge
under the hood to merge Tailwind classes without style conflicts, allowing you to override any existing classes using the “class” prop.