Skip to main content

Overview

InputSelect is a styled native HTML select element that supports icons, labels, error states, and various sizing options. It maintains a consistent look with custom dropdown styling.

Props

id
any
default:"Random string"
Unique identifier for the select element. If not provided, a random ID is generated.
name
string
default:"''"
The name attribute for the select element, useful for form submission.
label
string
default:"''"
Label text displayed above the select.
disabled
boolean
default:"false"
When true, the select is disabled.
value
string
default:"''"
The selected value. This prop is bindable using bind:value.
icon
IconSource | string | undefined
default:"undefined"
Optional icon displayed on the left side of the select. Can be an IconSource or a string path to resolve.
iconTheme
IconTheme
default:"'default'"
Theme variant for the icon (‘default’ | ‘solid’ | ‘mini’).
options
SelectOption[]
default:"[]"
Array of options to display. Each option has:
  • label: Display text
  • value: Option value
placeholder
string
default:"'Select one...'"
Placeholder text shown when no option is selected.
disablePlaceholder
boolean
default:"true"
When true, the placeholder option is disabled and cannot be selected.
errorText
string
default:"''"
Error message displayed below the select.
size
'xs' | 'sm' | 'md'
default:"'md'"
Size variant of the select:
  • xs: Height 26px
  • sm: Height 28px
  • md: Height 32px
onchange
(value: string) => void
Callback fired when the selected value changes.

Usage

Basic Select

<script>
  import { InputSelect } from 'popui'
  
  let country = $state('')
  
  const countries = [
    { label: 'United States', value: 'US' },
    { label: 'Canada', value: 'CA' },
    { label: 'United Kingdom', value: 'GB' },
    { label: 'Australia', value: 'AU' }
  ]
</script>

<InputSelect 
  bind:value={country}
  label="Country"
  options={countries}
  placeholder="Select a country"
/>

With Icon

<script>
  import { InputSelect } from 'popui'
  import { Globe } from '@invopop/ui-icons'
  
  let language = $state('')
  
  const languages = [
    { label: 'English', value: 'en' },
    { label: 'Spanish', value: 'es' },
    { label: 'French', value: 'fr' }
  ]
</script>

<InputSelect 
  bind:value={language}
  label="Language"
  icon={Globe}
  iconTheme="solid"
  options={languages}
/>

Different Sizes

<InputSelect size="xs" options={options} placeholder="Extra small" />
<InputSelect size="sm" options={options} placeholder="Small" />
<InputSelect size="md" options={options} placeholder="Medium" />

With Error Validation

<script>
  import { InputSelect } from 'popui'
  
  let category = $state('')
  let error = $state('')
  
  const categories = [
    { label: 'Electronics', value: 'electronics' },
    { label: 'Clothing', value: 'clothing' },
    { label: 'Books', value: 'books' }
  ]
  
  function validateCategory(value: string) {
    if (!value) {
      error = 'Please select a category'
    } else {
      error = ''
    }
  }
</script>

<InputSelect 
  bind:value={category}
  label="Category"
  options={categories}
  errorText={error}
  onchange={validateCategory}
/>

In a Form

<script>
  import { InputSelect } from 'popui'
  
  let priority = $state('medium')
  
  const priorities = [
    { label: 'Low', value: 'low' },
    { label: 'Medium', value: 'medium' },
    { label: 'High', value: 'high' },
    { label: 'Critical', value: 'critical' }
  ]
  
  function handleSubmit() {
    console.log('Selected priority:', priority)
  }
</script>

<form onsubmit={handleSubmit}>
  <InputSelect 
    bind:value={priority}
    name="priority"
    label="Priority Level"
    options={priorities}
    disablePlaceholder={false}
  />
  <button type="submit">Submit</button>
</form>

Features

  • Native HTML Select: Uses the native <select> element for best accessibility and mobile experience
  • Custom Styling: Custom dropdown arrow and consistent design system styling
  • Icon Support: Optional icon on the left side of the select
  • Error States: Built-in error styling and message display
  • Flexible Sizing: Three size variants to fit different contexts
  • Type Safety: Proper TypeScript types for SelectOption

Build docs developers (and LLMs) love