Select

The Select component provides a customizable dropdown for selecting options. It supports static and dynamic options, floating labels, and various styling options for flexibility.

About

Options can be written out in the markup or passed as an array through the options prop. Floating labels, animation speed and the rest of the form settings come from the Form or Fieldset around the field.

Example

You can use a Select component in two different ways. Either use the options prop to pass an array of options dynamically, or write the <option> tags manually inside the component. If options is set, the content inside the component is ignored. Here's a basic example of the Select component in action:

Svelte
<script>
  import { Select } from "theui-svelte";

  let data = [
    { text: "Option 1", value: "1" },
    { text: "Option 2", value: "2" },
    { text: "Option 3 (Disabled)", value: "3", disabled: true }
  ]
</script>

<Select label="Select an option" options={data} />

Or, you can use the <option> tag directly.

Svelte
<script>
  import { Select } from "theui-svelte";
</script>

<Select label="Choose a category">
  <option value="books">Books</option>
  <option value="electronics">Electronics</option>
  <option value="clothing" disabled>Clothing (Unavailable)</option>
</Select>

Default Value

The value prop allows you to set a default selection for the Select component. If a value is provided, the corresponding option will be pre-selected when the component loads. This ensures that users see a predefined choice without needing to manually select it. If no value is set, the first option (if available) will be selected by default.

Svelte
<Select label="Select an option" options={data} value="2" />

The value prop is bindable. Use bind:value to read the current selection, and to change it from your own code.

Selected value: 2

Svelte
<script>
  let selected = $state("2");
</script>

<Select label="Select an option" options={data} bind:value={selected} />

<p>Selected value: {selected}</p>

Placeholder

The placeholder prop adds a disabled option at the top of the list, so the select can start without a real choice. It is only rendered when you set it; there is no placeholder by default. Because the option is disabled, the user cannot go back to it after picking something.

Svelte
<Select label="Select an option" options={data} placeholder="-- Select --" />

Variant

The variant prop controls the appearance of the Select component. It has two options:

  • bordered(default): Displays the select input with a visible border, making it distinct and well-defined.
  • flat: drops the border and keeps only the bottom rule.

If the Select is inside a Fieldset or Form, it inherits their variant unless you set it here. Choosing flat also turns on the floating label, unless you set floatingLabel yourself.

Svelte
<Select label="Select an option" options={data} variant="bordered" />
<Select label="Select an option" options={data} variant="flat" />

Label & Floating Label

The label prop allows you to add a label to the Select component, improving accessibility and user experience. The label can be simple text or a more complex element using a Snippet.

If floatingLabel is enabled, the label floats above the input when a value is selected. It stays static otherwise. This only works when the label is a string prop, not a Snippet, because a snippet is rendered as you wrote it.

The floating label is on by default when the variant is "flat", and off for "bordered". Inside a Fieldset or Form, the floatingLabel of the group is used, unless this Select sets its own variant or floatingLabel.

This is helper text for the select input!
Svelte
<!-- Using label prop -->
<Select label="Select an option" options={data} />

<!-- Using label snippet -->
<Select options={data}>
  {#snippet label()}
    <div>
      <Label>Select an option</Label>
      <HelperText>This is helper text for the select input!</HelperText>
    </div>
  {/snippet}
</Select>

Label using floatingLabel.

 
Svelte
<Select ... floatingLabel />
<Select ... floatingLabel variant="flat" />

Sizing

The size prop controls the overall size of the Select component. Available options are "sm", "md", "lg", and "xl", with "md" as the default. This affects padding, font size, and spacing for a consistent UI. Inside a Fieldset or Form, the size of the group is used unless you set it here.

Svelte
<Select ... size="sm" />
<Select ... size="md" />
<Select ... size="lg" />
<Select ... size="xl" />

Rounded

The rounded prop controls the border-radius of the Select component. You can choose from "none", "sm", "md", "lg", "xl", "2xl" and "full" to determine the roundness of the corners. The default value is "md", giving the component a moderate rounded appearance. Inside a Fieldset or Form, the rounded value of the group is used unless you set it here.

Svelte
<Select ... rounded="none" />
<Select ... rounded="sm" />
<Select ... rounded="md" />
<Select ... rounded="lg" />
<Select ... rounded="xl" />
<Select ... rounded="full" />

Animation Speed

The animationSpeed prop allows you to control the speed of animations in the Select component. Available values include "none", "slower", "slow", "normal", "fast", "faster", with "normal" being the default. Adjust this value to make transitions quicker or slower based on your needs. It is used for the focus and floating label transitions, and is inherited from a Fieldset or Form when it is not set here.

Svelte
<Select ... animationSpeed="slower" />
<Select ... animationSpeed="slow" />
<Select ... animationSpeed="normal" />
<Select ... animationSpeed="fast" />
<Select ... animationSpeed="faster" />
<Select ... animationSpeed="none" />

Helper Text

The helperText prop allows you to add additional guidance or information below the Select component. It can be a simple string or a Snippet for more complex content. The helper text is linked to the select with aria-describedby, and a string renders as plain text, so use the snippet for markup.

This is helper text for the select input!
This is helper text for the select input!
Svelte
<!-- Using prop -->
<Select label="Select an option" options={data} helperText="This is helper text for the select input!" />
<!-- Using Snippet -->
<Select label="Select an option" options={data}>
  {#snippet helperText()}
    This is helper text for the select input!
  {/snippet}
</Select>

Resetting All Styles

The reset prop removes all default styles, applying only the styles you provide. This gives full control over the appearance, making it ideal for custom designs.

Svelte
<Select ... size="sm" rounded="full" reset />

In this example, even though size="sm" and rounded="full" are set, they won't take effect because the reset prop removes all default styles, including size and rounded settings. Only the styles you manually apply will be used.

Customization

The size, variant, rounded, animationSpeed, labelClasses and reset props are inherited from the nearest Fieldset or Form, so set them there to style a whole group at once.

  • wrapperClasses: Style the outer container of the Select component to adjust margins, padding, or additional styling needs.
  • labelClasses: Customize the label's style by applying custom classes, allowing better control over typography, spacing, and alignment.
  • class attribute: Directly modify the Select element itself, giving you control over borders, background, and overall appearance.
Svelte
<Select label="Select an option" options={data}
  wrapperClasses="flex-row items-center gap-16"
  labelClasses="text-xl text-blue-500"
  class="text-blue-500 focus:ring-blue-500 focus:border-blue-500"
/>

Accessibility

The Select component is fully accessible by default. It supports a linked label (floating or static) and connects to HelperText using aria-describedby for screen reader clarity. You can provide options via the options prop or write the <option> tags inside the component, and every option supports disabled for better control. Set placeholder if you want the select to start without a real choice. Just make sure a visible label or aria-label is provided.

Configuration