laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
98 lines (71 loc) • 2.97 kB
Markdown
# 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 p-6 rounded-xl"
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.