fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
717
docs/livecomponents/ui-integration-guide.md
Normal file
717
docs/livecomponents/ui-integration-guide.md
Normal file
@@ -0,0 +1,717 @@
|
||||
# LiveComponents UI Integration Guide
|
||||
|
||||
**Complete Guide to UI Features: Tooltips, Loading States, Dialogs, and Notifications**
|
||||
|
||||
This guide covers the integrated UI features available in LiveComponents, including tooltips, skeleton loading, dialogs, modals, notifications, and loading states.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Tooltip System](#tooltip-system)
|
||||
2. [Loading States & Skeleton Loading](#loading-states--skeleton-loading)
|
||||
3. [UI Helper System](#ui-helper-system)
|
||||
4. [Notification Component](#notification-component)
|
||||
5. [Dialog & Modal Integration](#dialog--modal-integration)
|
||||
6. [Best Practices](#best-practices)
|
||||
|
||||
---
|
||||
|
||||
## Tooltip System
|
||||
|
||||
### Overview
|
||||
|
||||
The Tooltip System provides automatic tooltip initialization and management for LiveComponent elements. Tooltips are automatically initialized when components are mounted and cleaned up when components are destroyed.
|
||||
|
||||
**Features**:
|
||||
- Automatic initialization for `data-tooltip` attributes
|
||||
- Accessibility support (ARIA attributes)
|
||||
- Smart positioning (viewport-aware)
|
||||
- Validation error tooltips
|
||||
- Automatic cleanup
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```html
|
||||
<!-- Simple tooltip -->
|
||||
<button
|
||||
data-lc-action="save"
|
||||
data-tooltip="Save your changes"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
|
||||
<!-- Tooltip with validation error -->
|
||||
<input
|
||||
type="email"
|
||||
data-lc-action="validateEmail"
|
||||
data-tooltip="Enter a valid email address"
|
||||
data-tooltip-error="Invalid email format"
|
||||
/>
|
||||
```
|
||||
|
||||
### Server-Side Validation Tooltips
|
||||
|
||||
```php
|
||||
use App\Framework\LiveComponents\Attributes\Action;
|
||||
use App\Framework\LiveComponents\ValueObjects\LiveComponentError;
|
||||
|
||||
final class UserForm extends LiveComponent
|
||||
{
|
||||
#[Action]
|
||||
public function validateEmail(string $email): void
|
||||
{
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
// Error will automatically show tooltip if element has data-tooltip-error
|
||||
throw LiveComponentError::validation(
|
||||
'Invalid email format',
|
||||
['field' => 'email'],
|
||||
$this->id->toString(),
|
||||
'validateEmail'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Tooltip Configuration
|
||||
|
||||
```javascript
|
||||
// Configure tooltip behavior globally
|
||||
import { tooltipManager } from './modules/livecomponent/TooltipManager.js';
|
||||
|
||||
// Adjust delays
|
||||
tooltipManager.tooltipDelay = 500; // Show after 500ms
|
||||
tooltipManager.hideDelay = 200; // Hide after 200ms
|
||||
```
|
||||
|
||||
### Tooltip Events
|
||||
|
||||
```javascript
|
||||
// Listen for tooltip events
|
||||
window.addEventListener('livecomponent:tooltip-shown', (e) => {
|
||||
const { element, tooltipText } = e.detail;
|
||||
console.log(`Tooltip shown: ${tooltipText}`);
|
||||
});
|
||||
|
||||
window.addEventListener('livecomponent:tooltip-hidden', (e) => {
|
||||
const { element } = e.detail;
|
||||
console.log('Tooltip hidden');
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Loading States & Skeleton Loading
|
||||
|
||||
### Overview
|
||||
|
||||
The Loading State System provides configurable loading indicators during LiveComponent actions, including skeleton loaders, spinners, and progress indicators.
|
||||
|
||||
**Features**:
|
||||
- Fragment-specific loading
|
||||
- Configurable loading types (skeleton, spinner, progress, none)
|
||||
- Smooth transitions
|
||||
- Optimistic UI integration (no loading for optimistic actions)
|
||||
- Per-component configuration
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```html
|
||||
<!-- Component with skeleton loading -->
|
||||
<div
|
||||
data-live-component="product-list"
|
||||
data-loading-type="skeleton"
|
||||
data-loading-fragments="product-list"
|
||||
>
|
||||
<div data-lc-fragment="product-list">
|
||||
<!-- Skeleton template will be shown during loading -->
|
||||
<div class="skeleton-item">
|
||||
<div class="skeleton-image"></div>
|
||||
<div class="skeleton-text"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Server-Side Loading Configuration
|
||||
|
||||
```php
|
||||
use App\Framework\LiveComponents\Attributes\Action;
|
||||
use App\Framework\LiveComponents\Attributes\Loading;
|
||||
|
||||
final class ProductList extends LiveComponent
|
||||
{
|
||||
#[Action]
|
||||
#[Loading(type: 'skeleton', fragments: ['product-list'], showDelay: 150)]
|
||||
public function loadProducts(string $category): void
|
||||
{
|
||||
$this->products = $this->productService->getByCategory($category);
|
||||
}
|
||||
|
||||
#[Action]
|
||||
#[Loading(type: 'spinner', showDelay: 0)] // Show immediately
|
||||
public function quickAction(): void
|
||||
{
|
||||
// Fast action with immediate spinner
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Loading Types
|
||||
|
||||
#### 1. Skeleton Loading
|
||||
|
||||
```html
|
||||
<!-- Skeleton template in component -->
|
||||
<div data-lc-fragment="content">
|
||||
<!-- Default content -->
|
||||
<div class="product-card">
|
||||
<img src="{product.image}" />
|
||||
<h3>{product.name}</h3>
|
||||
</div>
|
||||
|
||||
<!-- Skeleton template (shown during loading) -->
|
||||
<template data-skeleton-template>
|
||||
<div class="product-card skeleton">
|
||||
<div class="skeleton-image"></div>
|
||||
<div class="skeleton-text"></div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
```
|
||||
|
||||
#### 2. Spinner Loading
|
||||
|
||||
```html
|
||||
<!-- Automatic spinner overlay -->
|
||||
<div
|
||||
data-live-component="component-id"
|
||||
data-loading-type="spinner"
|
||||
>
|
||||
<!-- Spinner automatically appears during actions -->
|
||||
</div>
|
||||
```
|
||||
|
||||
#### 3. Progress Loading
|
||||
|
||||
```html
|
||||
<!-- Progress bar for long-running actions -->
|
||||
<div
|
||||
data-live-component="upload-component"
|
||||
data-loading-type="progress"
|
||||
>
|
||||
<div class="progress-bar" data-progress="0"></div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Custom Loading Configuration
|
||||
|
||||
```javascript
|
||||
// Configure loading behavior per component
|
||||
const component = LiveComponentManager.getInstance().getComponent('component-id');
|
||||
|
||||
component.setLoadingConfig({
|
||||
type: 'skeleton',
|
||||
fragments: ['content', 'sidebar'],
|
||||
showDelay: 150,
|
||||
hideDelay: 100
|
||||
});
|
||||
```
|
||||
|
||||
### Loading Events
|
||||
|
||||
```javascript
|
||||
// Listen for loading state changes
|
||||
window.addEventListener('livecomponent:loading-started', (e) => {
|
||||
const { componentId, type, fragments } = e.detail;
|
||||
console.log(`Loading started: ${componentId} (${type})`);
|
||||
});
|
||||
|
||||
window.addEventListener('livecomponent:loading-finished', (e) => {
|
||||
const { componentId, duration } = e.detail;
|
||||
console.log(`Loading finished: ${componentId} (${duration}ms)`);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## UI Helper System
|
||||
|
||||
### Overview
|
||||
|
||||
The UI Helper System provides a standardized way for LiveComponents to interact with common UI elements like dialogs, modals, and notifications.
|
||||
|
||||
**Features**:
|
||||
- Unified API for UI components
|
||||
- Integration with UIManager
|
||||
- Promise-based API
|
||||
- Automatic cleanup
|
||||
- Component-scoped UI elements
|
||||
|
||||
### Dialog & Modal Helpers
|
||||
|
||||
```php
|
||||
use App\Framework\LiveComponents\Attributes\Action;
|
||||
|
||||
final class UserManagement extends LiveComponent
|
||||
{
|
||||
#[Action]
|
||||
public function showDeleteConfirm(int $userId): void
|
||||
{
|
||||
// Show confirmation dialog via UI Helper
|
||||
$this->uiHelper->showDialog(
|
||||
title: 'Delete User',
|
||||
message: 'Are you sure you want to delete this user?',
|
||||
buttons: [
|
||||
['label' => 'Cancel', 'action' => 'cancel'],
|
||||
['label' => 'Delete', 'action' => 'confirm', 'variant' => 'danger']
|
||||
]
|
||||
)->then(function($action) use ($userId) {
|
||||
if ($action === 'confirm') {
|
||||
$this->deleteUser($userId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### JavaScript API
|
||||
|
||||
```javascript
|
||||
import { LiveComponentUIHelper } from './modules/livecomponent/LiveComponentUIHelper.js';
|
||||
|
||||
const uiHelper = new LiveComponentUIHelper(liveComponentManager);
|
||||
|
||||
// Show modal
|
||||
const action = await uiHelper.showModal('component-id', {
|
||||
title: 'Confirm Action',
|
||||
content: '<p>Are you sure?</p>',
|
||||
size: 'medium',
|
||||
buttons: [
|
||||
{ label: 'Cancel', action: 'cancel' },
|
||||
{ label: 'Confirm', action: 'confirm', variant: 'primary' }
|
||||
]
|
||||
});
|
||||
|
||||
if (action === 'confirm') {
|
||||
// Handle confirmation
|
||||
}
|
||||
|
||||
// Show alert
|
||||
await uiHelper.showAlert('component-id', {
|
||||
title: 'Success',
|
||||
message: 'Operation completed successfully',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
// Show confirm dialog
|
||||
const confirmed = await uiHelper.showConfirm('component-id', {
|
||||
title: 'Delete Item',
|
||||
message: 'This action cannot be undone.',
|
||||
confirmText: 'Delete',
|
||||
cancelText: 'Cancel'
|
||||
});
|
||||
```
|
||||
|
||||
### Notification Helpers
|
||||
|
||||
```javascript
|
||||
// Show notification
|
||||
uiHelper.showNotification('component-id', 'Operation successful', 'success');
|
||||
|
||||
// Show error notification with retry
|
||||
uiHelper.showErrorNotification(
|
||||
'component-id',
|
||||
'Upload failed. Please try again.',
|
||||
'error',
|
||||
true, // Can retry
|
||||
() => {
|
||||
// Retry logic
|
||||
retryUpload();
|
||||
}
|
||||
);
|
||||
|
||||
// Hide notification
|
||||
uiHelper.hideNotification('component-id');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notification Component
|
||||
|
||||
### Overview
|
||||
|
||||
The NotificationComponent is a full-featured LiveComponent for displaying toast notifications with support for different types, positions, durations, and action buttons.
|
||||
|
||||
**Features**:
|
||||
- Type-safe state management
|
||||
- Multiple notification types (info, success, warning, error)
|
||||
- Configurable positions (top-right, top-left, bottom-right, bottom-left)
|
||||
- Auto-dismiss with duration
|
||||
- Action buttons
|
||||
- Icon support
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```php
|
||||
use App\Application\LiveComponents\Notification\NotificationComponent;
|
||||
use App\Framework\LiveComponents\ValueObjects\ComponentId;
|
||||
|
||||
final class ProductController
|
||||
{
|
||||
public function create(): ViewResult
|
||||
{
|
||||
$notification = NotificationComponent::mount(
|
||||
ComponentId::generate('notification'),
|
||||
message: 'Product created successfully',
|
||||
type: 'success',
|
||||
duration: 5000
|
||||
);
|
||||
|
||||
return new ViewResult('product/index', [
|
||||
'notification' => $notification
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Template Integration
|
||||
|
||||
```html
|
||||
<!-- Include notification component in layout -->
|
||||
{notification}
|
||||
|
||||
<!-- Or use in component template -->
|
||||
<div data-live-component="{notification.id}">
|
||||
<!-- Notification will render here -->
|
||||
</div>
|
||||
```
|
||||
|
||||
### Server-Side Actions
|
||||
|
||||
```php
|
||||
final class NotificationExample extends LiveComponent
|
||||
{
|
||||
#[Action]
|
||||
public function showSuccess(): NotificationState
|
||||
{
|
||||
return NotificationState::empty()
|
||||
->withMessage('Operation successful!', 'success')
|
||||
->show();
|
||||
}
|
||||
|
||||
#[Action]
|
||||
public function showError(string $message): NotificationState
|
||||
{
|
||||
return NotificationState::empty()
|
||||
->withMessage($message, 'error')
|
||||
->show();
|
||||
}
|
||||
|
||||
#[Action]
|
||||
public function showWithAction(): NotificationState
|
||||
{
|
||||
return new NotificationState(
|
||||
message: 'File uploaded successfully',
|
||||
type: 'success',
|
||||
isVisible: true,
|
||||
actionText: 'View',
|
||||
actionUrl: '/files'
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Client-Side API
|
||||
|
||||
```javascript
|
||||
// Show notification via LiveComponent action
|
||||
liveComponentManager.executeAction('notification-id', 'showNotification', {
|
||||
message: 'Operation successful',
|
||||
type: 'success',
|
||||
duration: 5000
|
||||
});
|
||||
|
||||
// Hide notification
|
||||
liveComponentManager.executeAction('notification-id', 'hide');
|
||||
```
|
||||
|
||||
### Notification Types
|
||||
|
||||
```php
|
||||
// Info notification
|
||||
$notification = NotificationState::empty()
|
||||
->withMessage('New update available', 'info')
|
||||
->show();
|
||||
|
||||
// Success notification
|
||||
$notification = NotificationState::empty()
|
||||
->withMessage('Changes saved', 'success')
|
||||
->show();
|
||||
|
||||
// Warning notification
|
||||
$notification = NotificationState::empty()
|
||||
->withMessage('Low disk space', 'warning')
|
||||
->show();
|
||||
|
||||
// Error notification
|
||||
$notification = NotificationState::empty()
|
||||
->withMessage('Upload failed', 'error')
|
||||
->show();
|
||||
```
|
||||
|
||||
### Notification Positions
|
||||
|
||||
```php
|
||||
$notification = new NotificationState(
|
||||
message: 'Notification message',
|
||||
type: 'info',
|
||||
position: 'top-right', // or 'top-left', 'bottom-right', 'bottom-left'
|
||||
isVisible: true
|
||||
);
|
||||
```
|
||||
|
||||
### Notification with Action Button
|
||||
|
||||
```php
|
||||
$notification = new NotificationState(
|
||||
message: 'File ready for download',
|
||||
type: 'success',
|
||||
isVisible: true,
|
||||
actionText: 'Download',
|
||||
actionUrl: '/download/file.pdf'
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dialog & Modal Integration
|
||||
|
||||
### Overview
|
||||
|
||||
LiveComponents integrate seamlessly with the UIManager for dialogs and modals, providing a consistent API across the application.
|
||||
|
||||
### Basic Modal Usage
|
||||
|
||||
```php
|
||||
use App\Framework\LiveComponents\Attributes\Action;
|
||||
|
||||
final class UserSettings extends LiveComponent
|
||||
{
|
||||
#[Action]
|
||||
public function showEditModal(int $userId): void
|
||||
{
|
||||
// Modal will be shown via UI Helper
|
||||
$this->uiHelper->showModal(
|
||||
title: 'Edit User',
|
||||
content: $this->renderEditForm($userId),
|
||||
size: 'large',
|
||||
buttons: [
|
||||
['label' => 'Save', 'action' => 'save', 'variant' => 'primary'],
|
||||
['label' => 'Cancel', 'action' => 'cancel']
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Modal with LiveComponent Content
|
||||
|
||||
```php
|
||||
#[Action]
|
||||
public function showUserModal(int $userId): void
|
||||
{
|
||||
$userComponent = UserDetailsComponent::mount(
|
||||
ComponentId::generate('user-details'),
|
||||
userId: $userId
|
||||
);
|
||||
|
||||
$this->uiHelper->showModal(
|
||||
title: 'User Details',
|
||||
content: $userComponent->render(),
|
||||
size: 'medium'
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Modal Events
|
||||
|
||||
```javascript
|
||||
// Listen for modal events
|
||||
window.addEventListener('livecomponent:modal-opened', (e) => {
|
||||
const { componentId, modalInstance } = e.detail;
|
||||
console.log(`Modal opened for component: ${componentId}`);
|
||||
});
|
||||
|
||||
window.addEventListener('livecomponent:modal-closed', (e) => {
|
||||
const { componentId, action } = e.detail;
|
||||
console.log(`Modal closed with action: ${action}`);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Tooltip Usage
|
||||
|
||||
- **Do**: Use tooltips for helpful context and validation errors
|
||||
- **Don't**: Overuse tooltips - they can be distracting
|
||||
- **Accessibility**: Always ensure tooltips are keyboard-accessible
|
||||
|
||||
```html
|
||||
<!-- Good: Helpful tooltip -->
|
||||
<button data-tooltip="Save your changes (Ctrl+S)">
|
||||
Save
|
||||
</button>
|
||||
|
||||
<!-- Bad: Obvious tooltip -->
|
||||
<button data-tooltip="Click to save">
|
||||
Save
|
||||
</button>
|
||||
```
|
||||
|
||||
### 2. Loading States
|
||||
|
||||
- **Do**: Use skeleton loading for content-heavy updates
|
||||
- **Do**: Use spinners for quick actions (< 500ms)
|
||||
- **Don't**: Show loading for optimistic UI updates
|
||||
- **Do**: Configure appropriate delays to prevent flickering
|
||||
|
||||
```php
|
||||
// Good: Appropriate loading type
|
||||
#[Loading(type: 'skeleton', fragments: ['product-list'])]
|
||||
public function loadProducts(): void { }
|
||||
|
||||
// Good: Quick action with spinner
|
||||
#[Loading(type: 'spinner', showDelay: 0)]
|
||||
public function toggleFavorite(): void { }
|
||||
```
|
||||
|
||||
### 3. Notifications
|
||||
|
||||
- **Do**: Use notifications for important feedback
|
||||
- **Don't**: Overuse notifications - they can be annoying
|
||||
- **Do**: Set appropriate durations (5s for success, longer for errors)
|
||||
- **Do**: Provide action buttons for actionable notifications
|
||||
|
||||
```php
|
||||
// Good: Clear, actionable notification
|
||||
$notification = new NotificationState(
|
||||
message: 'File uploaded successfully',
|
||||
type: 'success',
|
||||
duration: 5000,
|
||||
actionText: 'View',
|
||||
actionUrl: '/files'
|
||||
);
|
||||
|
||||
// Bad: Too many notifications
|
||||
// Don't show a notification for every minor action
|
||||
```
|
||||
|
||||
### 4. Modals & Dialogs
|
||||
|
||||
- **Do**: Use modals for important confirmations
|
||||
- **Don't**: Overuse modals - they interrupt user flow
|
||||
- **Do**: Provide clear action buttons
|
||||
- **Do**: Support keyboard navigation (Escape to close)
|
||||
|
||||
```php
|
||||
// Good: Clear confirmation dialog
|
||||
$this->uiHelper->showConfirm(
|
||||
title: 'Delete Item',
|
||||
message: 'This action cannot be undone.',
|
||||
confirmText: 'Delete',
|
||||
cancelText: 'Cancel'
|
||||
);
|
||||
```
|
||||
|
||||
### 5. Error Handling
|
||||
|
||||
- **Do**: Use ErrorBoundary for automatic error handling
|
||||
- **Do**: Show user-friendly error messages
|
||||
- **Do**: Provide retry options for recoverable errors
|
||||
- **Don't**: Show technical error details to users
|
||||
|
||||
```php
|
||||
// Good: User-friendly error
|
||||
throw LiveComponentError::validation(
|
||||
'Please enter a valid email address',
|
||||
['field' => 'email'],
|
||||
$this->id->toString()
|
||||
);
|
||||
|
||||
// Bad: Technical error
|
||||
throw new \Exception('Invalid email format: ' . $email);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### Global Configuration
|
||||
|
||||
```javascript
|
||||
import { sharedConfig } from './modules/livecomponent/SharedConfig.js';
|
||||
|
||||
// Configure default values
|
||||
sharedConfig.defaultDebounce = 300;
|
||||
sharedConfig.defaultCacheTTL = 5000;
|
||||
sharedConfig.defaultLoadingShowDelay = 150;
|
||||
sharedConfig.defaultLoadingType = 'skeleton';
|
||||
sharedConfig.defaultNotificationDuration = 5000;
|
||||
sharedConfig.defaultNotificationPosition = 'top-right';
|
||||
sharedConfig.defaultModalAnimation = 'fade';
|
||||
```
|
||||
|
||||
### Per-Component Configuration
|
||||
|
||||
```html
|
||||
<!-- Component-level configuration -->
|
||||
<div
|
||||
data-live-component="component-id"
|
||||
data-loading-type="skeleton"
|
||||
data-loading-show-delay="200"
|
||||
data-notification-position="bottom-right"
|
||||
>
|
||||
<!-- Component content -->
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Tooltips Not Showing
|
||||
|
||||
1. Check that `data-tooltip` attribute is present
|
||||
2. Verify TooltipManager is initialized
|
||||
3. Check browser console for errors
|
||||
4. Ensure element is visible and not hidden
|
||||
|
||||
### Loading States Not Working
|
||||
|
||||
1. Verify `data-loading-type` attribute is set
|
||||
2. Check that fragments match between HTML and PHP
|
||||
3. Ensure LoadingStateManager is initialized
|
||||
4. Check for JavaScript errors in console
|
||||
|
||||
### Notifications Not Displaying
|
||||
|
||||
1. Verify NotificationComponent is mounted
|
||||
2. Check that component ID matches
|
||||
3. Ensure state is properly serialized
|
||||
4. Check browser console for errors
|
||||
|
||||
### Modals Not Opening
|
||||
|
||||
1. Verify UIManager is initialized
|
||||
2. Check that modal content is valid HTML
|
||||
3. Ensure no JavaScript errors are blocking execution
|
||||
4. Check z-index conflicts
|
||||
|
||||
---
|
||||
|
||||
**Next**: [API Reference](api-reference.md) →
|
||||
|
||||
Reference in New Issue
Block a user