# TextInput

A text input component that allows users to input custom text entries with a keyboard. Built with React Aria's `useTextField` hook for full accessibility and the Cube `tasty` style system for theming.

## When to Use

- Collect single-line text input from users (names, emails, URLs)
- Create multiline text areas for longer content
- Build forms with validation and field decoration
- Implement search inputs with icons and prefixes
- Handle password inputs with proper masking

## Component

---

### Properties

- **`value`** `string` — The text value in controlled mode
- **`defaultValue`** `string` — The default text value in uncontrolled mode
- **`placeholder`** `string` — Placeholder text when input is empty
- **`icon`** — Icon element rendered before the input
- **`prefix`** — Input decoration before the main input
- **`suffix`** — Input decoration after the main input
- **`suffixPosition`** `'before' | 'after'` (default: `before`) — Position of suffix relative to validation/loading state icons
- **`type`** `'text' | 'password' | 'email' | 'url' | 'tel' | 'search'` (default: `text`) — Input type
- **`multiLine`** `boolean` (default: `false`) — Whether the input is multiline (textarea)
- **`rows`** `number` — Number of visible rows for multiline input
- **`resize`** `string` — CSS resize value for multiline input (e.g. `'vertical'`, `'none'`)
- **`size`** `'small' | 'medium' | 'large'` (default: `medium`) — Input size
- **`autocomplete`** `string` — Browser autocomplete attribute value
- **`maxLength`** `number` — Maximum number of characters allowed
- **`minLength`** `number` — Minimum number of characters required
- **`inputProps`** `Props` — Direct HTML props passed to the inner input element
- **`inputRef`** `RefObject<HTMLInputElement | HTMLTextAreaElement>` — Ref to the inner input element
- **`wrapperRef`** `RefObject<HTMLDivElement>` — Ref to the input wrapper container
- **`loadingIndicator`** `ReactNode` — Custom loading indicator element
- **`onChange`** `function` — Callback fired when the input value changes
- **`onBlur`** `function` — Callback fired when the input loses focus
- **`onFocus`** `function` — Callback fired when the input receives focus

### Base Properties

Supports [Base properties](../../BaseProperties.md)

### Field Properties

Supports all [Field properties](../../FieldProperties.md)

### Styling Properties

#### styles

Customizes the root element of the component.

**Sub-elements:**
- `InputWrapper` – container around the input field
- `Prefix` – wrapper around prefix content
- `Suffix` – wrapper around suffix content
- `State` – container for validation and loading icons
- `InputIcon` – wrapper around the main icon
- `ValidationIcon` – wrapper around validation state icons

#### inputStyles

Customizes the input element itself.

#### wrapperProps

Additional HTML props passed to the input wrapper container.

### Style Properties

These properties allow direct style application without using the `styles` prop:

- **Base:** `display`, `font`, `preset`, `hide`, `whiteSpace`, `opacity`, `transition`
- **Position:** `gridArea`, `order`, `gridColumn`, `gridRow`, `placeSelf`, `alignSelf`, `justifySelf`, `zIndex`, `margin`, `inset`, `position`
- **Dimension:** `width`, `height`, `flexBasis`, `flexGrow`, `flexShrink`, `flex`
- **Block:** `border`, `radius`, `shadow`, `outline`, `padding`, `paddingInline`, `paddingBlock`, `overflow`, `scrollbar`, `textAlign`
- **Color:** `color`, `fill`, `fade`, `image`

### Modifiers

The `mods` prop accepts the following modifiers you can override:

- **`focused`** `boolean` — Forces focus ring appearance.
- **`disabled`** `boolean` — Forces disabled appearance.
- **`invalid`** `boolean` — Forces invalid state styling.
- **`valid`** `boolean` — Forces valid state styling.
- **`loading`** `boolean` — Displays loading spinner.
- **`prefix`** `boolean` — Indicates presence of prefix content.
- **`suffix`** `boolean` — Indicates presence of suffix content.

## Variants

### Types

- `text` – Standard text input (default)
- `password` – Masked password input
- `email` – Email input with validation
- `url` – URL input with validation
- `tel` – Telephone number input
- `search` – Search input styling

### Sizes

- `small` – Compact height for dense interfaces
- `medium` – Standard height for most use cases
- `large` – Emphasized height for important inputs

## Examples

### Basic Usage

```jsx
<TextInput
  label="Name"
  placeholder="Enter your name"
  onChange={(value) => console.log(value)}
/>
```

### With Icon

```jsx
import { IconMail } from '@tabler/icons-react';

<TextInput
  label="Email"
  type="email"
  icon={<IconMail />}
  placeholder="Enter your email"
/>
```

### Multiline Text Area

```jsx
<TextInput
  label="Description"
  multiLine
  rows={4}
  placeholder="Enter description..."
/>
```

### With Validation

```jsx
<TextInput
  label="Username"
  isRequired
  validationState="invalid"
  message="Username must be at least 3 characters"
/>
```

## Accessibility

### Keyboard Navigation

- `Tab` – Moves focus to the input field
- `Shift + Tab` – Moves focus away from the input
- Standard text editing shortcuts (Ctrl+A, Ctrl+C, etc.)

### Screen Reader Support

- Announces role "textbox" or "searchbox" for search inputs
- Announces label, description, and validation messages
- State changes like "invalid" or "required" are announced
- Loading state is announced to screen readers

### ARIA Properties

- `aria-label`, `aria-labelledby` – Accessible name for the input
- `aria-describedby` – Links to description and error messages
- `aria-invalid` – Managed automatically based on `validationState`
- `aria-required` – Set when `isRequired` is true
- Additional ARIA attributes supported by React Aria's `useTextField`

## Best Practices

1. **Do**: Provide clear labels and helpful placeholder text
   ```jsx
   <TextInput label="Email Address" placeholder="you@example.com" />
   ```

2. **Don't**: Use placeholder text as the only label
   ```jsx
   {/* Avoid this */}
   <TextInput placeholder="Enter your email" />
   ```

3. **Accessibility**: Always provide proper labels for screen readers
4. **Validation**: Use `validationState` and `message` for user feedback
5. **Performance**: Use `defaultValue` for uncontrolled inputs when possible

## Integration with Forms

This component supports all [Field properties](../../FieldProperties.md) when used within a Form.

## Suggested Improvements

- Provide `maxLength` indicator with visible character count
- Support for input masks and formatting
- Built-in debouncing for onChange events

## Related Components

- [TextArea](./TextArea.md) – Dedicated multiline text input
- [SearchInput](./SearchInput.md) – Specialized search input with clear button
- [PasswordInput](./PasswordInput.md) – Enhanced password input with show/hide toggle
- [NumberInput](./NumberInput.md) – Numeric input with increment/decrement controls
