# 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 ``` ### 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
``` ### 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

{product.name}

``` #### 2. Spinner Loading ```html
``` #### 3. Progress Loading ```html
``` ### 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: '

Are you sure?

', 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 {notification}
``` ### 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 ``` ### 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
``` --- ## 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) →