# HTMX Components

This directory contains HTMX-related template components for loading states, error handling, and success feedback.

## Loading State Guidelines

### When to Use Each Type

| Scenario | Component | Example |
|----------|-----------|---------|
| Initial page load, full content replacement | Skeleton screens | Parks list loading |
| Button actions, form submissions | Loading indicator (inline) | Submit button spinner |
| Partial content updates | Loading indicator (block) | Search results loading |
| Container replacement | Loading indicator (overlay) | Modal content loading |

### Components

#### loading_indicator.html

Standardized loading indicator for HTMX requests with three modes:

**Inline Mode** - For buttons and links:
```django
<button hx-post="/api/action" hx-indicator="#btn-loading">
    Save
    {% include 'htmx/components/loading_indicator.html' with id='btn-loading' mode='inline' %}
</button>
```

**Block Mode** (default) - For content areas:
```django
<div hx-get="/api/list" hx-indicator="#list-loading">
    <!-- Content -->
</div>
{% include 'htmx/components/loading_indicator.html' with id='list-loading' %}
```

**Overlay Mode** - For containers:
```django
<div class="relative" hx-get="/api/data" hx-indicator="#overlay-loading">
    <!-- Content to cover -->
    {% include 'htmx/components/loading_indicator.html' with id='overlay-loading' mode='overlay' %}
</div>
```

#### Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `id` | str | - | ID for hx-indicator targeting |
| `message` | str | "Loading..." | Loading text to display |
| `mode` | str | "block" | 'inline', 'block', or 'overlay' |
| `size` | str | "md" | 'sm', 'md', or 'lg' |
| `spinner` | str | "border" | 'spin' (fa-spinner) or 'border' (CSS) |

## Skeleton Screens

Located in `components/skeletons/`, these provide content-aware loading placeholders:

### Available Skeletons

| Component | Use Case |
|-----------|----------|
| `list_skeleton.html` | List views, search results |
| `card_grid_skeleton.html` | Card-based grid layouts |
| `detail_skeleton.html` | Detail/show pages |
| `form_skeleton.html` | Form loading states |
| `table_skeleton.html` | Data tables |

### Usage with HTMX

```django
{# Initial content shows skeleton, replaced by HTMX #}
<div id="parks-list"
     hx-get="/parks/"
     hx-trigger="load"
     hx-swap="innerHTML">
    {% include 'components/skeletons/card_grid_skeleton.html' with cards=6 %}
</div>
```

### With hx-indicator

```django
<div id="results">
    <!-- Results here -->
</div>

{# Skeleton shown during loading #}
<div id="results-skeleton" class="htmx-indicator">
    {% include 'components/skeletons/list_skeleton.html' %}
</div>
```

## Error Handling

### error_message.html

Displays error messages with consistent styling:

```django
{% include 'htmx/components/error_message.html' with
    message="Unable to load data"
    show_retry=True
    retry_url="/api/data"
%}
```

### Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `message` | str | - | Error message text |
| `code` | str | - | HTTP status code |
| `show_retry` | bool | False | Show retry button |
| `retry_url` | str | - | URL for retry action |
| `show_report` | bool | False | Show "Report Issue" link |

## Success Feedback

### success_toast.html

Triggers a toast notification via HTMX response:

```django
{% include 'htmx/components/success_toast.html' with
    message="Park saved successfully"
    type="success"
%}
```

### Using HX-Trigger Header

From views, trigger toasts via response headers:

```python
from django.http import HttpResponse

def save_park(request):
    # ... save logic ...
    response = HttpResponse()
    response['HX-Trigger'] = json.dumps({
        'showToast': {
            'type': 'success',
            'message': 'Park saved successfully'
        }
    })
    return response
```

## HTMX Configuration

The base template configures HTMX with:

- 30-second timeout
- Global view transitions enabled
- Template fragments enabled
- Comprehensive error handling

### Swap Strategies

| Strategy | Use Case |
|----------|----------|
| `innerHTML` | Replace content inside container (lists, search results) |
| `outerHTML` | Replace entire element (status badges, individual items) |
| `beforeend` | Append items (infinite scroll) |
| `afterbegin` | Prepend items (new items at top) |

### Target Naming Conventions

- `#object-type-id` - For specific objects (e.g., `#park-123`)
- `#section-name` - For page sections (e.g., `#results`, `#filters`)
- `#modal-container` - For modals
- `this` - For self-replacement

### Custom Events

- `{model}-status-changed` - Status updates (e.g., `park-status-changed`)
- `auth-changed` - Authentication state changes
- `{model}-created` - New item created
- `{model}-updated` - Item updated
- `{model}-deleted` - Item deleted

## Best Practices

1. **Always specify hx-indicator** for user feedback
2. **Use skeleton screens** for initial page loads and full content replacement
3. **Use inline indicators** for button actions
4. **Use overlay indicators** for modal content loading
5. **Add aria attributes** for accessibility (role="status", aria-busy)
6. **Clean up loading states** after request completion (automatic with HTMX)
