# Button

## Overview

Versatile button with multiple variants and sizes, optional leading/trailing icons, loading state, and support for rendering as a child element.

---

## Props

### Button (Root)

| Prop        | Type                                               | Default       | Description                                             |
| ----------- | -------------------------------------------------- | ------------- | ------------------------------------------------------- | ----------------- | --------------------- | ------------------- | ------- | ------------------- | -------------- | ------- | ----------- | --------------------------- |
| `variant`   | `"default"                                         | "destructive" | "outline"                                               | "outline-primary" | "outline-destructive" | "secondary"         | "ghost" | "ghost-destructive" | "ghost-accent" | "link"` | `"default"` | Visual style of the button. |
| `size`      | `"default"                                         | "sm"          | "lg"                                                    | "icon"`           | `"default"`           | Size of the button. |
| `asChild`   | `boolean`                                          | `false`       | Render as child (e.g., anchor) while preserving styles. |
| `iconLeft`  | `IconName`                                         | `undefined`   | Optional left icon name.                                |
| `iconRight` | `IconName`                                         | `undefined`   | Optional right icon name.                               |
| `isLoading` | `boolean`                                          | `false`       | Shows a loading spinner; overrides `iconLeft`.          |
| `className` | `string`                                           | `""`          | Additional classes for layout/width.                    |
| `disabled`  | `boolean`                                          | `false`       | Disables the button.                                    |
| `onClick`   | `(e: React.MouseEvent<HTMLButtonElement>) => void` | `undefined`   | Click handler.                                          |
| `children`  | `React.ReactNode`                                  | **required**  | Button label or content.                                |

---

## Behavior

- **Loading**: When `isLoading` is `true`, a spinner is shown and `iconLeft` is hidden.
- **Icons**: Icon sizes adapt to the button size (`sm`, `default`, `lg`, `icon`).
- **As Child**: Use `asChild` to render the button as a link or custom element while keeping button styles.
- **Accessibility**: Keyboard-focus ring and proper semantics are included.

---

## Examples

### Default

```tsx
import { Button } from "laif-ds";

export function DefaultButton() {
  return <Button>Button</Button>;
}
```

### Showcase (Variants × Sizes)

```tsx
import { Button, type ButtonProps } from "laif-ds";

const variants: ButtonProps["variant"][] = [
  "default",
  "destructive",
  "outline",
  "outline-primary",
  "outline-destructive",
  "secondary",
  "ghost",
  "ghost-accent",
  "ghost-destructive",
  "link",
];

const sizes: ButtonProps["size"][] = ["lg", "default", "sm", "icon"];

export function ButtonsGrid() {
  return (
    <div className="flex flex-col gap-4">
      {variants.map((variant) => (
        <div key={variant} className="flex flex-wrap items-center gap-2">
          {sizes.map((size) =>
            size === "icon" ? (
              <Button
                key={`${variant}-${size}`}
                variant={variant}
                size={size}
                iconLeft="BadgeInfo"
              />
            ) : (
              <Button key={`${variant}-${size}`} variant={variant} size={size}>
                {variant} - {size}
              </Button>
            ),
          )}
        </div>
      ))}
    </div>
  );
}
```

### Full Width

```tsx
import { Button } from "laif-ds";

export function FullWidthButton() {
  return <Button className="w-full">Full Width Button</Button>;
}
```

### With Icon

```tsx
import { Button } from "laif-ds";

export function WithIcon() {
  return <Button iconLeft="Check">Button with Icon</Button>;
}
```

### Loading

```tsx
import { Button } from "laif-ds";

export function LoadingButton() {
  return <Button isLoading>Loading Button</Button>;
}
```

---

## Notes

- **Disabled**: Applies reduced opacity and prevents interactions.
- **Icon-only**: Use `size="icon"` for square icon buttons.
- **Theming**: Use variants to match semantic meaning (primary, destructive, etc.).
