Skip to main content

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

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)}
/>

Sizes

// 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)}
/>

States

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>
  )
}

Props

name
string
required
Name attribute of the select element, also used as the id to link with label
label
string
required
Text displayed above the select element
value
string
required
Currently selected value
options
OptionProps[]
required
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
placeholder
string
First option shown as disabled placeholder for guidance
size
'medium' | 'mediumX'
default:"mediumX"
Height of the select element
helperText
string
Auxiliary text displayed below the select
feedback
'success' | 'error'
Visual feedback state affecting select, label, and helper text styling
required
boolean
default:"false"
If true, displays an asterisk and marks the field as required
disabled
boolean
default:"false"
If true, disables the select element
ariaLabel
string
Accessibility label for cases where text label is not visible
brand
BrandTypes
Brand theme to apply (avon, natura, theBodyShop, etc.)
className
string
Optional CSS class name for custom styling
testID
string
Optional ID for testing purposes
accessibility
SelectAccessibilityProps
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)}
    />
  )
}

Build docs developers (and LLMs) love