npm package: @jopijs/jopimod_menu
Description: This module is responsible for menu management within the JopiJS application. It provides a centralized infrastructure for creating, manipulating, and rendering dynamic menus, facilitating navigation throughout the application.
Latest version: 1.0.2

# @jopijs/jopimod_menu

This module is responsible for menu management within the JopiJS application. It provides a centralized infrastructure for creating, manipulating, and rendering dynamic menus, facilitating navigation throughout the application.

## Role of the Module

The `mod_jopijs@menu` module acts as a central manager for all navigation elements. Its key responsibilities include:

- **Menu Infrastructure**: Provides the classes and interfaces (`MenuManager`, `MenuTreeBuilder`, `MenuTree`) needed to build complex menu hierarchies.
- **Active State Management**: Automatically detects and maintains the active menu item based on the browser's current URL.
- **Overrides System**: Offers a flexible mechanism to override menu item properties (such as title, icon, or priority) from other modules, allowing customization without modifying the original source code.
- **Event Reactivity**: Connects to system events (such as `app.router.locationUpdated` or `app.user.infosUpdated`) to recalculate and update menus in real-time.
- **Normalization**: Ensures URL consistency (handling trailing slashes) and automatic icon association via the JopiJS resource system.

## Usage

Developers primarily interact with this module to:
1. Define new menus.
2. Add items to existing menus (such as the main menu or sidebar).
3. Modify the appearance or behavior of navigation links.

## API Reference

### Hooks

*   `useMenu(name: string)`: Retrieves the list of items for a specific menu (e.g., `LEFT`). The return value is reactive and updates automatically when the menu is modified or when the active item changes.

    **Return Structure (Array of `ReactMenuItem`):**
    ```typescript
    interface ReactMenuItem {
        key: string;             // Unique identifier for the item
        title?: string;          // Display text
        url?: string;            // Navigation URL
        isActive?: boolean;      // True if this item corresponds to the current route
        items?: ReactMenuItem[]; // Nested sub-items (for dropdowns or trees)
        icon?: React.FC<any>;    // Icon component
        breadcrumb?: string[] | React.FC<any>; // Breadcrumb data
        [key: string]: any;      // Additional properties allowed
    }
    ```

*   `useMatchingItem()`: Returns the currently active menu item based on the browser's current URL. Useful for displaying breadcrumbs or highlighting the active link.
*   `useMenuManager()`: Returns the singleton instance of `MenuManager`, allowing access to low-level methods if needed.

### Libraries

*   `MenuNames`: A collection of constants for standard menu names used in the application (e.g., `TOP_MENU`, `LEFT_MENU`, `RIGHT_MENU`).
*   `Item`: The TypeScript interface defining the structure of a menu item (title, url, icon, children, etc.).

## Examples

### 1. Displaying a Menu

Here is a simple example of how to render a navigation menu using the `useMenu` hook.

```tsx
import React from "react";
import useMenu from "@/hooks/jopijs.menu.useMenu";
import MenuNames from "@/lib/jopijs.menu.MenuNames";
// Assuming you use a Link component for routing
import { Link } from "jopijs/router"; 

export const TopNavigation = () => {
    // Fetch items for the Top Menu
    const items = useMenu(MenuNames.TOP_MENU);

    return (
        <nav className="navbar">
            <ul>
                {items.map((item) => (
                    <li key={item.key} className={item.isActive ? "active" : ""}>
                        <Link to={item.url || "#"}>
                            {item.icon && <item.icon />}
                            <span>{item.title}</span>
                        </Link>
                    </li>
                ))}
            </ul>
        </nav>
    );
};
```

### 2. Registering Translated Items

To ensure menu items are correctly translated, you should resolve the translation strings *inside* the menu builder callback. The `MenuManager` will re-execute this builder whenever it is invalidated (e.g., on language change or user login), ensuring the title is always up-to-date.

```typescript
import { JopiUiApplication } from "jopijs/ui";
import getMenuManager from "@/lib/jopijs.menu.getManager";
import MenuNames from "@/lib/jopijs.menu.MenuNames";
// Import your translation provider
import trProvider from "@alias/translations"; 

export default function(uiApp: JopiUiApplication) {
    const manager = getMenuManager(uiApp);

    // Register a builder for the Top Menu
    manager.addMenuBuilder(MenuNames.TOP_MENU, (menu) => {
        // Fetch current translations
        // This code runs every time the menu is rebuilt
        const tr = trProvider.getCurrentTranslations();

        menu.selectItem(["contact"])
            .set([], {
                title: tr.menu.contact, // e.g., "Contact Us" or "Nous contacter"
                url: "/contact",
                priority: 50
            });
    });
}
```

## Documentation

For comprehensive documentation, integration guides, and code examples, please visit the official project website:

[https://jopijs.com](https://jopijs.com)