Skip to main content

Input Components

MotorDesk provides styled form input components that extend native HTML elements with consistent styling and TypeScript support.

Input Component

A styled text input component with support for all standard input types.

Import

import { Input } from '@components/ui/Input';

Basic Usage

<Input 
  type="text"
  placeholder="Enter your name"
  onChange={(e) => console.log(e.target.value)}
/>

API Reference

className
string
default:""
Additional CSS classes to apply to the input.
ref
React.Ref<HTMLInputElement>
Forward ref to the underlying input element. Supports React.forwardRef pattern.

Inherited Props

The Input component accepts all standard InputHTMLAttributes<HTMLInputElement> including:
  • type (text, email, password, number, date, etc.)
  • value / defaultValue
  • onChange
  • onFocus / onBlur
  • placeholder
  • disabled
  • readOnly
  • required
  • maxLength
  • min / max (for number/date inputs)
  • pattern
  • name
  • And all other native input attributes

Examples

<Input 
  type="text"
  placeholder="Customer name"
  value={customerName}
  onChange={(e) => setCustomerName(e.target.value)}
/>

With Form Control

import { Input } from '@components/ui/Input';

function CustomerForm() {
  const [formData, setFormData] = useState({
    nombre: '',
    email: '',
    telefono: ''
  });
  
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  };
  
  return (
    <form>
      <div>
        <label>Nombre</label>
        <Input 
          name="nombre"
          value={formData.nombre}
          onChange={handleChange}
        />
      </div>
      <div>
        <label>Email</label>
        <Input 
          name="email"
          type="email"
          value={formData.email}
          onChange={handleChange}
        />
      </div>
      <div>
        <label>Teléfono</label>
        <Input 
          name="telefono"
          value={formData.telefono}
          onChange={handleChange}
        />
      </div>
    </form>
  );
}

With Ref (for form libraries)

import { useRef } from 'react';
import { Input } from '@components/ui/Input';

function FocusExample() {
  const inputRef = useRef<HTMLInputElement>(null);
  
  const focusInput = () => {
    inputRef.current?.focus();
  };
  
  return (
    <>
      <Input ref={inputRef} placeholder="Focus me" />
      <button onClick={focusInput}>Focus Input</button>
    </>
  );
}

Disabled and ReadOnly States

// Disabled input (cannot interact)
<Input 
  value="This field is disabled"
  disabled
/>

// ReadOnly input (can select text but not edit)
<Input 
  value="This field is read-only"
  readOnly
/>

Styling Details

The Input component includes:
  • Full width by default (w-full)
  • Border with slate-300 color
  • Rounded corners (rounded-lg)
  • Blue focus ring
  • Height of 38px
  • Smooth transitions
  • Disabled state: 50% opacity with gray background
  • ReadOnly state: Light gray background

Select Component

A styled dropdown select component.

Import

import { Select } from '@components/ui/Select';

Basic Usage

<Select value={selectedValue} onChange={(e) => setSelectedValue(e.target.value)}>
  <option value="option1">Option 1</option>
  <option value="option2">Option 2</option>
  <option value="option3">Option 3</option>
</Select>

API Reference

className
string
default:""
Additional CSS classes to apply to the select.
children
ReactNode
The option elements to display in the dropdown.
ref
React.Ref<HTMLSelectElement>
Forward ref to the underlying select element.

Inherited Props

Accepts all standard SelectHTMLAttributes<HTMLSelectElement> including:
  • value / defaultValue
  • onChange
  • disabled
  • required
  • name
  • multiple
  • And all other native select attributes

Examples

Document Type Selector

<div>
  <label>Tipo de Documento</label>
  <Select 
    name="tipoDocumento" 
    value={formData.tipoDocumento} 
    onChange={handleChange}
  >
    <option value="RUC">RUC (Empresa / Persona con Negocio)</option>
    <option value="DNI">DNI (Persona Natural)</option>
    <option value="CE">Carnet de Extranjería</option>
  </Select>
</div>

Payment Method Selector

<Select 
  value={paymentMethod} 
  onChange={(e) => setPaymentMethod(e.target.value)}
>
  <option value="EFECTIVO">Efectivo</option>
  <option value="TARJETA">Tarjeta de Crédito/Débito</option>
  <option value="TRANSFERENCIA">Transferencia Bancaria</option>
  <option value="YAPE">Yape</option>
</Select>

With Dynamic Options

function CustomerSelector({ customers, value, onChange }) {
  return (
    <Select value={value} onChange={onChange}>
      <option value="">Seleccione un cliente</option>
      {customers.map(customer => (
        <option key={customer.id} value={customer.id}>
          {customer.nombreRazonSocial}
        </option>
      ))}
    </Select>
  );
}

Styling Details

The Select component includes:
  • Full width by default (w-full)
  • White background
  • Border with slate-300 color
  • Rounded corners (rounded-lg)
  • Blue focus ring
  • Height of 38px
  • Bold font weight
  • Smooth transitions

Form Integration Example

Combining Input and Select in a complete form:
import { Input } from '@components/ui/Input';
import { Select } from '@components/ui/Select';
import { Button } from '@components/ui/Button';

function VehicleForm() {
  const [formData, setFormData] = useState({
    placa: '',
    marca: '',
    modelo: '',
    anio: new Date().getFullYear(),
    color: ''
  });
  
  const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  };
  
  return (
    <form>
      <div>
        <label>Placa</label>
        <Input 
          name="placa" 
          value={formData.placa} 
          onChange={handleChange}
          maxLength={7}
        />
      </div>
      
      <div>
        <label>Marca</label>
        <Select name="marca" value={formData.marca} onChange={handleChange}>
          <option value="">Seleccione marca</option>
          <option value="TOYOTA">Toyota</option>
          <option value="NISSAN">Nissan</option>
          <option value="HYUNDAI">Hyundai</option>
        </Select>
      </div>
      
      <div>
        <label>Modelo</label>
        <Input name="modelo" value={formData.modelo} onChange={handleChange} />
      </div>
      
      <div>
        <label>Año</label>
        <Input 
          name="anio" 
          type="number" 
          value={formData.anio} 
          onChange={handleChange}
          min={1900}
          max={new Date().getFullYear() + 1}
        />
      </div>
      
      <Button type="submit" variant="primary">Guardar Vehículo</Button>
    </form>
  );
}

Accessibility

  • Both components support keyboard navigation
  • Include focus states for visibility
  • Work with screen readers
  • Support all standard HTML form attributes
  • Compatible with form validation

Source Code

  • Input: /home/daytona/workspace/source/src/components/ui/Input.tsx:1
  • Select: /home/daytona/workspace/source/src/components/ui/Select.tsx:1

Build docs developers (and LLMs) love