# InputSelector

## Overview

Compact numeric selector with increment/decrement buttons, value bounds, and subtle animations. Useful for choosing small integer quantities (e.g., seats, guests).

---

## Props

| Prop               | Type                      | Default     | Description                      |
| ------------------ | ------------------------- | ----------- | -------------------------------- |
| `value`            | `number`                  | `1`         | Current numeric value.           |
| `onChange`         | `(value: number) => void` | `undefined` | Called with the new value.       |
| `min`              | `number`                  | `1`         | Minimum allowed value.           |
| `max`              | `number`                  | `4`         | Maximum allowed value.           |
| `className`        | `string`                  | `""`        | Wrapper classes.                 |
| `buttonClassName`  | `string`                  | `""`        | Classes for +/- buttons.         |
| `counterClassName` | `string`                  | `""`        | Classes for the numeric counter. |

---

## Behavior

- **Controlled**: `value` is controlled; emits `onChange(newValue)` on clicks within bounds.
- **Bounds**: At min or max, the component vibrates (subtle shake animation) instead of changing value.
- **A11y**: Buttons are real `<button>` elements with clear `+`/`-` labels.

---

## Examples

### Basic

```tsx
import { useState } from "react";
import { InputSelector } from "laif-ds";

export function BasicSelector() {
  const [value, setValue] = useState(2);

  return <InputSelector value={value} onChange={setValue} min={1} max={4} />;
}
```

### Controlled

```tsx
import { useState } from "react";
import { InputSelector } from "laif-ds";

export function ControlledSelector() {
  const [value, setValue] = useState(2);

  return (
    <div className="flex flex-col items-center gap-2">
      <InputSelector value={value} onChange={setValue} min={1} max={6} />
      <div className="text-d-secondary-foreground text-sm">
        Current value: {value}
      </div>
    </div>
  );
}
```

### Custom Styling

```tsx
import { useState } from "react";
import { InputSelector } from "laif-ds";

export function CustomStyledSelector() {
  const [value, setValue] = useState(2);

  return (
    <InputSelector
      value={value}
      onChange={setValue}
      min={1}
      max={4}
      className="bg-d-secondary/10 rounded-xl p-6"
      buttonClassName="bg-d-primary text-d-primary-foreground hover:bg-d-primary/90 border-0"
      counterClassName="text-d-primary font-bold"
    />
  );
}
```

---

## Notes

- **Bounds UX**: The slight vibration on bound hit provides feedback without changing the value.
- **Styling**: Prefer design tokens (`bg-d-*`, `text-d-*`) over raw colors.
