Overview
The Select component provides a dropdown menu for selecting a single option from a list of choices. It includes label, helper text, and feedback states for form validation.
import { Select } from '@naturacosmeticos/natds-react'
Basic Usage
import React, { useState } from 'react'
import { Select } from '@naturacosmeticos/natds-react'
function App() {
const [country, setCountry] = useState('')
const countries = [
{ value: 'us', label: 'United States' },
{ value: 'ca', label: 'Canada' },
{ value: 'mx', label: 'Mexico' }
]
return (
<Select
name="country"
label="Country"
value={country}
options={countries}
onChange={(e) => setCountry(e.target.value)}
/>
)
}
With Placeholder
<Select
name="language"
label="Preferred Language"
placeholder="Select a language"
value={language}
options={[
{ value: 'en', label: 'English' },
{ value: 'es', label: 'Spanish' },
{ value: 'pt', label: 'Portuguese' }
]}
onChange={(e) => setLanguage(e.target.value)}
/>
// Medium size
<Select
name="size-medium"
label="Medium Select"
size="medium"
value={value}
options={options}
onChange={handleChange}
/>
// Medium X size (default)
<Select
name="size-mediumx"
label="Medium X Select"
size="mediumX"
value={value}
options={options}
onChange={handleChange}
/>
With Helper Text
<Select
name="payment"
label="Payment Method"
helperText="Your payment information is secure"
value={payment}
options={[
{ value: 'credit', label: 'Credit Card' },
{ value: 'debit', label: 'Debit Card' },
{ value: 'paypal', label: 'PayPal' }
]}
onChange={(e) => setPayment(e.target.value)}
/>
Feedback States
// Error state
<Select
name="category"
label="Category"
feedback="error"
helperText="Please select a valid category"
value={category}
options={options}
onChange={(e) => setCategory(e.target.value)}
/>
// Success state
<Select
name="region"
label="Region"
feedback="success"
helperText="Valid region selected"
value={region}
options={options}
onChange={(e) => setRegion(e.target.value)}
/>
Required
<Select
name="required-field"
label="Required Field"
required
helperText="This field is required"
value={value}
options={options}
onChange={handleChange}
/>
Disabled
<Select
name="disabled-field"
label="Disabled Field"
disabled
value={value}
options={options}
onChange={() => {}}
/>
Form Example
import React, { useState } from 'react'
import { Select } from '@naturacosmeticos/natds-react'
function ShippingForm() {
const [formData, setFormData] = useState({
country: '',
state: '',
shippingMethod: ''
})
const countries = [
{ value: 'us', label: 'United States' },
{ value: 'br', label: 'Brazil' },
{ value: 'mx', label: 'Mexico' }
]
const states = [
{ value: 'ca', label: 'California' },
{ value: 'ny', label: 'New York' },
{ value: 'tx', label: 'Texas' }
]
const shippingMethods = [
{ value: 'standard', label: 'Standard (5-7 days)' },
{ value: 'express', label: 'Express (2-3 days)' },
{ value: 'overnight', label: 'Overnight' }
]
const handleChange = (field: string, value: string) => {
setFormData(prev => ({ ...prev, [field]: value }))
}
return (
<form>
<Select
name="country"
label="Country"
placeholder="Select your country"
required
value={formData.country}
options={countries}
onChange={(e) => handleChange('country', e.target.value)}
/>
<Select
name="state"
label="State"
placeholder="Select your state"
required
value={formData.state}
options={states}
disabled={!formData.country}
onChange={(e) => handleChange('state', e.target.value)}
/>
<Select
name="shipping"
label="Shipping Method"
placeholder="Select shipping method"
helperText="Estimated delivery time"
value={formData.shippingMethod}
options={shippingMethods}
onChange={(e) => handleChange('shippingMethod', e.target.value)}
/>
</form>
)
}
Name attribute of the select element, also used as the id to link with label
Text displayed above the select element
Array of options to display in the dropdown. Each option has:
value: string - The option’s value
label: string - The display text
onChange
React.ChangeEventHandler<HTMLSelectElement>
required
Callback fired when the selection changes
First option shown as disabled placeholder for guidance
size
'medium' | 'mediumX'
default:"mediumX"
Height of the select element
Auxiliary text displayed below the select
Visual feedback state affecting select, label, and helper text styling
If true, displays an asterisk and marks the field as required
If true, disables the select element
Accessibility label for cases where text label is not visible
Brand theme to apply (avon, natura, theBodyShop, etc.)
Optional CSS class name for custom styling
Optional ID for testing purposes
Accessibility attributes including:
aria-label
aria-labelledby
aria-describedby
aria-disabled
aria-required
aria-invalid
role
tabIndex
Accessibility
Built-in Features
The Select component includes:
- Proper label association
- Keyboard navigation support
- Screen reader announcements
- ARIA attributes
- Focus management
Best Practices
// Good: Clear label and helper text
<Select
name="timezone"
label="Time Zone"
helperText="Select your local time zone"
accessibility={{
'aria-describedby': 'timezone-description',
'aria-required': true
}}
required
value={timezone}
options={timezones}
onChange={handleChange}
/>
// Good: Error feedback with descriptive message
<Select
name="category"
label="Category"
feedback="error"
helperText="Please select a category to continue"
value={category}
options={categories}
onChange={handleChange}
/>
Guidelines
- Always provide a clear label
- Use placeholder text to guide users
- Provide helpful error messages
- Order options logically (alphabetically, by frequency, etc.)
- Consider using Autocomplete for long lists (>10 options)
- Disable options that aren’t applicable
- Show validation feedback clearly
- Ensure sufficient color contrast
Dynamic Options
import React, { useState, useEffect } from 'react'
import { Select } from '@naturacosmeticos/natds-react'
function DynamicSelect() {
const [country, setCountry] = useState('')
const [cities, setCities] = useState<Array<{ value: string; label: string }>>([])
const [city, setCity] = useState('')
useEffect(() => {
if (country) {
// Fetch cities based on selected country
fetchCities(country).then(setCities)
} else {
setCities([])
setCity('')
}
}, [country])
const countries = [
{ value: 'us', label: 'United States' },
{ value: 'ca', label: 'Canada' },
{ value: 'mx', label: 'Mexico' }
]
return (
<div>
<Select
name="country"
label="Country"
placeholder="Select a country"
value={country}
options={countries}
onChange={(e) => setCountry(e.target.value)}
/>
<Select
name="city"
label="City"
placeholder="Select a city"
value={city}
options={cities}
disabled={!country || cities.length === 0}
onChange={(e) => setCity(e.target.value)}
/>
</div>
)
}
TypeScript
import { SelectProps, OptionProps } from '@naturacosmeticos/natds-react'
interface SelectFieldProps {
fieldName: string
fieldLabel: string
options: OptionProps[]
value: string
onChange: (value: string) => void
error?: string
required?: boolean
}
const SelectField: React.FC<SelectFieldProps> = ({
fieldName,
fieldLabel,
options,
value,
onChange,
error,
required = false
}) => {
return (
<Select
name={fieldName}
label={fieldLabel}
value={value}
options={options}
required={required}
feedback={error ? 'error' : undefined}
helperText={error}
onChange={(e) => onChange(e.target.value)}
/>
)
}
Related Components