# Button

> Atom — orn-ui

> ⚠️ Requires <UIProvider>: This component (like every orn-ui component) must render inside a <UIProvider> ancestor, or it throws at runtime. See https://orn-ui-docs.vercel.app/getting-started.md

> Runs on Expo SDK 54, 55, 56 and 57, and on bare React Native >=0.81 with react >=19.1. No native modules — works in Expo Go, no prebuild.

## Installation

Install just this component (copies the source into your project, no npm dependency)
```bash
npx orn-ui add button
```

Or install the whole package and import it
```tsx
pnpm add orn-ui
import { Button } from 'orn-ui/button';
```

Depends on: core (theme + icons)

## Variants

### Primary

```tsx
<Button title="Primary" onPress={() => {}} />
```

### Secondary

```tsx
<Button title="Secondary" variant="secondary" onPress={() => {}} />
```

### Outline

```tsx
<Button title="Outline" variant="outline" onPress={() => {}} />
```

### Ghost

```tsx
<Button title="Ghost" variant="ghost" onPress={() => {}} />
```

### Link

```tsx
<Button title="Link" variant="link" onPress={() => {}} />
```

### Destructive

```tsx
<Button title="Destructive" variant="destructive" onPress={() => {}} />
```

### Sizes

```tsx
<View style={{ gap: 8 }}>
  <Button title="Small" size="sm" onPress={() => {}} />
  <Button title="Medium (default)" size="md" onPress={() => {}} />
  <Button title="Large" size="lg" onPress={() => {}} />
</View>
```

### Disabled

```tsx
<Button title="Disabled" disabled onPress={() => {}} />
```

### Loading

```tsx
<Button
  title="Tap to load"
  loading={loading}
  onPress={() => {
    setLoading(true);
    setTimeout(() => setLoading(false), 1500);
  }}
/>
```

### Left icon

```tsx
<Button title="Confirm" leftIconName="check" onPress={() => {}} />
```

### Right icon

```tsx
<Button title="Next" rightIconName="chevron-right" onPress={() => {}} />
```

## Full demo source

```tsx
const variants: VariantDef[] = [
  { label: 'Primary', content: <Button title="Primary" onPress={() => {}} /> },
  { label: 'Secondary', content: <Button title="Secondary" variant="secondary" onPress={() => {}} /> },
  { label: 'Outline', content: <Button title="Outline" variant="outline" onPress={() => {}} /> },
  { label: 'Ghost', content: <Button title="Ghost" variant="ghost" onPress={() => {}} /> },
  { label: 'Link', content: <Button title="Link" variant="link" onPress={() => {}} /> },
  { label: 'Destructive', content: <Button title="Destructive" variant="destructive" onPress={() => {}} /> },
  {
    label: 'Sizes',
    content: (
      <View style={{ gap: 8 }}>
        <Button title="Small" size="sm" onPress={() => {}} />
        <Button title="Medium (default)" size="md" onPress={() => {}} />
        <Button title="Large" size="lg" onPress={() => {}} />
      </View>
    ),
  },
  { label: 'Disabled', content: <Button title="Disabled" disabled onPress={() => {}} /> },
  {
    label: 'Loading',
    content: (
      <Button
        title="Tap to load"
        loading={loading}
        onPress={() => {
          setLoading(true);
          setTimeout(() => setLoading(false), 1500);
        }}
      />
    ),
  },
  { label: 'Left icon', content: <Button title="Confirm" leftIconName="check" onPress={() => {}} /> },
  { label: 'Right icon', content: <Button title="Next" rightIconName="chevron-right" onPress={() => {}} /> },
];
return <VariantList variants={variants} />;
```

## Props

| Name | Type | Default | Description |
|---|---|---|---|
| `title` | `string` | — | — |
| `onPress` | `(e: GestureResponderEvent) => void` | — | — |
| `variant?` | `'primary' \| 'secondary' \| 'outline' \| 'ghost' \| 'link' \| 'destructive'` | primary | — |
| `size?` | `'sm' \| 'md' \| 'lg'` | md | — |
| `loading?` | `boolean` | false | — |
| `disabled?` | `boolean` | false | — |
| `style?` | `StyleProp<ViewStyle>` | — | — |
| `textStyle?` | `StyleProp<TextStyle>` | — | — |
| `leftIcon?` | `ReactNode` | — | — |
| `rightIcon?` | `ReactNode` | — | — |
| `leftIconName?` | `IconName` | — | — |
| `rightIconName?` | `IconName` | — | — |
| `iconColor?` | `string` | — | — |
| `accessibilityLabel?` | `string` | — | — |
