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.
The name attribute for the select element, useful for form submission.
Label text displayed above the select.
When true, the select is disabled.
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.
When true, the placeholder option is disabled and cannot be selected.
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
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}
/>
<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