Menu
Ecosistema completo para organización y gestión de contenido con interfaces espaciales
UX Menu
The UX Menu component is a versatile navigation and interaction tool that provides a consistent way to display menu options to users. It supports various layouts, nested items, badges, icons, and theme options while maintaining a seamless user experience.
Features
- Multiple Layout Options: Support for horizontal, vertical, dropdown, side drawers, and more
- Nested Submenus: Create multi-level navigation hierarchies with expandable sections
- Badge Support: Show notification counts or labels on menu items
- Icon Integration: Material icons or custom icon system support
- Theme Options: Multiple visual themes that can be customized
- Persistence: Saves user's menu configuration using IndexedDB
- Accessibility: Fully keyboard navigable and screen-reader compatible
- Responsive Design: Adapts to various screen sizes and devices
- Animation: Smooth transitions for item selection and submenu expansion
- Programmatic Control: API for controlling the menu from parent components
Basic Usage
<app-ux-menu
[id]="'main-navigation'"
[items]="menuItems"
[config]="menuConfig"
(itemSelected)="onMenuItemSelected($event)">
</app-ux-menu>
import { Component } from '@angular/core';
import { UxMenuComponent, UxMenuItem, UxMenuConfig } from '@ux-widgets';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [UxMenuComponent],
// ...
})
export class MyComponent {
// Menu configuration
menuConfig: UxMenuConfig = {
id: 'main-navigation',
position: 'left',
theme: 'light',
showIcons: true,
showBadges: true,
allowMultipleExpanded: false,
animationDuration: 300,
closeOnNavigation: true,
hasOverlay: true,
overlayOpacity: 0.5,
backdropBlur: true,
zIndex: 1000,
persistConfig: true,
autoLoadSavedConfig: true
};
// Menu items
menuItems: UxMenuItem[] = [
{
id: 'dashboard',
title: 'Dashboard',
icon: 'dashboard',
route: '/dashboard'
},
{
id: 'projects',
title: 'Projects',
icon: 'folder',
badge: '8',
badgeColor: '#4caf50',
children: [
{
id: 'my-projects',
title: 'My Projects',
icon: 'folder_special',
route: '/projects/my-projects'
},
{
id: 'shared',
title: 'Shared with Me',
icon: 'folder_shared',
route: '/projects/shared',
badge: 'New',
badgeColor: '#2196f3'
}
]
}
];
// Menu item selection handler
onMenuItemSelected(item: UxMenuItem) {
console.log('Selected menu item:', item);
// Handle navigation or action
}
}
IndexedDB Integration
The UX Menu uses IndexedDB to save and restore user's menu configuration, ensuring a consistent experience across sessions. This is particularly important for menus with expandable sections, where users expect their navigation state to be preserved.
How IndexedDB Storage Works
The menu uses a dedicated storage service (UxMenuStorageService) that handles all database operations:
Database Initialization:
- The service creates a database called
ux-menu-dbwith a store namedmenu-configurations - Each configuration is identified by a unique menu ID
- The service creates a database called
Data Structure:
- Menu configurations are stored with the following structure:
{ id: string; // Menu ID [configProperties]; // All properties from UxMenuConfig _menuItems: UxMenuItem[]; // Optional: Menu items if stored together lastSaved: string; // Timestamp }
- Menu configurations are stored with the following structure:
Saving Process:
- When a user interacts with the menu (expands sections, changes theme, etc.), changes are recorded
- If
persistConfigis enabled, these changes are saved to IndexedDB - The service handles queuing multiple save operations to prevent conflicts
- Robust error handling prevents data corruption
Loading Process:
- When a menu with the same ID is initialized and
autoLoadSavedConfigis true, the saved configuration is automatically loaded - This happens transparently to restore the user's previous state
- When a menu with the same ID is initialized and
Ensuring Proper Functionality
When implementing the UX Menu with IndexedDB storage, follow these steps to ensure everything works correctly:
1. Provide Unique IDs
Always provide a unique ID for each menu instance to avoid configuration conflicts:
menuConfig: UxMenuConfig = {
id: 'app-main-navigation', // Unique ID
// Other configuration...
};
2. Handle Database Initialization
Menu operations should wait for the database to be initialized:
import { UxMenuService, UxMenuStorageService } from '@ux-widgets';
constructor(
private menuService: UxMenuService,
private menuStorage: UxMenuStorageService
) {}
ngOnInit() {
// Wait for database to be ready
this.menuStorage.isDatabaseReady().pipe(
filter(ready => ready),
take(1)
).subscribe(() => {
// Safe to perform menu operations
this.initializeMenu();
});
}
3. Implement Proper Error Handling
IndexedDB operations can fail for various reasons. Implement proper error handling:
saveMenuState() {
this.menuService.getMenuState(this.menuId).pipe(
switchMap(state => {
return this.menuStorage.saveMenuConfig(state);
}),
catchError(error => {
console.error('Failed to save menu state', error);
// Implement fallback if needed
return of(false);
})
).subscribe(success => {
if (success) {
console.log('Menu state saved successfully');
} else {
console.warn('Menu state could not be saved');
}
});
}
4. Test Edge Cases
Test your menu implementation in various scenarios:
- Browser Compatibility: Test in different browsers (Chrome, Firefox, Safari, Edge)
- Private Browsing: Test in private/incognito mode where IndexedDB might be restricted
- Storage Limits: Test with large menu configurations
- Offline Usage: Test behavior when the user goes offline during saving
5. Implement Fallbacks
Always provide fallback mechanisms for cases where IndexedDB is unavailable:
// Check if IndexedDB is available
if (!window.indexedDB) {
console.warn('IndexedDB not supported in this browser. Menu state will not persist.');
// Disable persistence to prevent errors
this.menuConfig = {
...this.menuConfig,
persistConfig: false,
autoLoadSavedConfig: false
};
// Optionally, try to use localStorage as fallback
this.setupLocalStorageFallback();
}
By following these guidelines, you can ensure that the UX Menu with IndexedDB storage provides a reliable and consistent user experience across different environments and usage scenarios.