laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
139 lines (107 loc) • 4.92 kB
Markdown
Text input component with label, sizes, optional left/right icons, custom start/end content, built-in password toggle, validation styles and accessible error messaging.
---
Extends native `<input>` props (except `size` and `label` which are redefined).
| Prop | Type | Default | Description |
| --------------- | -------------------------------------- | ----------- | -------------------------------------------------------------------- |
| `label` | `string | React.ReactNode` | `undefined` | Field label shown above the input. |
| `labelClassName`| `string` | `""` | Extra classes for the label. |
| `size` | `"sm" | "default" | "lg"` | `"default"` | Controls height and font-size. |
| `iconLeft` | `IconName` | `undefined` | Optional left icon (uses `Icon`). |
| `iconRight` | `IconName` | `undefined` | Optional right icon (ignored when `type="password"`). |
| `startContent` | `React.ReactNode` | `undefined` | Custom content before the input (coexists with `iconLeft`). |
| `endContent` | `React.ReactNode` | `undefined` | Custom content after the input (coexists with `iconRight`). |
| `errorMessage` | `string` | `undefined` | Custom error message (shown after interaction/invalid state). |
All other standard input attributes (e.g., `type`, `placeholder`, `required`, `min`, `max`, `pattern`, etc.) are supported.
---
## Behavior
- **Wrapper focus**: Clicking the wrapper focuses the input; selects text for non-password types (except file).
- **Password toggle**: When `type="password"`, a toggle button switches visibility with accessible labels (`Mostra/Nascondi password`).
- **Validation**: The wrapper reflects validity (`aria-invalid`) and shows `errorMessage` or the browser validation message once touched/invalid.
- **Accessibility**: Errors use `role="alert"` and `aria-live="polite"`; labels link via `htmlFor`/`id`.
---
```tsx
import { Input } from "laif-ds";
export function BasicInput() {
return (
<Input
label="Nome"
placeholder="Inserisci testo..."
className="w-full max-w-sm"
/>
);
}
```
```tsx
import { Input } from "laif-ds";
export function SizesAndIcons() {
return (
<div className="flex flex-col gap-3 w-full max-w-sm">
<Input size="sm" label="Email" type="email" iconLeft="Mail" placeholder="esempio@dominio.com" />
<Input size="default" label="Cerca" type="search" iconLeft="Search" placeholder="Cerca..." />
<Input size="lg" label="Prezzo" type="number" iconRight="Euro" placeholder="0.00" />
</div>
);
}
```
```tsx
import { Input } from "laif-ds";
export function CustomContent() {
return (
<div className="flex flex-col gap-3 w-full max-w-sm">
<Input
label="Importo"
type="number"
placeholder="0.00"
startContent={<span className="text-d-muted-foreground text-sm font-medium">€</span>}
/>
<Input
label="Percentuale"
type="number"
placeholder="0"
endContent={<span className="text-d-muted-foreground text-sm font-medium">%</span>}
/>
</div>
);
}
```
```tsx
import { Input } from "laif-ds";
export function PasswordField() {
return (
<Input
label="Password"
type="password"
placeholder="Inserisci la tua password"
className="w-full max-w-sm"
required
/>
);
}
```
```tsx
import { Input } from "laif-ds";
export function ValidationStates() {
return (
<div className="flex flex-col gap-3 w-full max-w-sm">
<Input label="Campo obbligatorio" placeholder="Questo campo è obbligatorio" required />
<Input label="Email" type="email" placeholder="email@esempio.com" required />
<Input label="URL" type="url" placeholder="https://esempio.com" required />
<Input label="Età (18-65)" type="number" min={18} max={65} required />
</div>
);
}
```
---
- **Icons**: Prefer `iconLeft`/`iconRight` rather than embedding icons manually.
- **Content**: `startContent`/`endContent` are ideal for units, prefixes/suffixes, or badges.
- **A11y**: Include helpful placeholders and `aria-describedby` for extra guidance when needed.