# Dropdown API

### JavaScript API

#### Global Helper: `window.Dropdowns`

* `window.Dropdowns.getAll()`: Returns an array of all initialized Dropdown instances.
* `window.Dropdowns.findById(idOrDomId)`: Finds a specific instance by its numeric ID or DOM ID (e.g., `dropdown-1`).

#### Instance Methods

If you have a reference to a dropdown instance, you can call these methods:

* `instance.open({ cascade: true })`: Opens the dropdown.
* `instance.close({ cascade: true })`: Closes the dropdown.
* `instance.toggle({ cascade: true })`: Toggles the open state.

### Custom Events

Events are dispatched from the main `[data-menu-element="dropdown"]` element and bubble up.

| Event                       | Description                                                                            |
| --------------------------- | -------------------------------------------------------------------------------------- |
| `menuDropdown:open`         | Fired when the dropdown opens.                                                         |
| `menuDropdown:close`        | Fired when the dropdown closes.                                                        |
| `menuDropdown:modeChange`   | Fired when the component switches between `dropdown`, `accordion`, or `stacked` modes. |
| `menuDropdown:open:[mode]`  | Specific open event (e.g., `menuDropdown:open:dropdown`).                              |
| `menuDropdown:close:[mode]` | Specific close event (e.g., `menuDropdown:close:stacked`).                             |

**Event Detail (`event.detail`):**

* `instanceId`: The unique numeric ID of the dropdown.
* `mode`: The current mode (`dropdown`, `accordion`, or `stacked`).
* `level`: The nesting level (0 for top-level).

***

### Examples

#### Programmatic Control

```javascript
// Find a dropdown by its DOM ID (e.g., "dropdown-1")
const dropdown = window.Dropdowns.findById("dropdown-1");

// Open a dropdown
dropdown.open();

// Close a dropdown (cascade: true closes children too)
dropdown.close({ cascade: true });

// Toggle open/closed state
dropdown.toggle();

// Close all open dropdowns on the page
window.Dropdowns.getAll()
  .filter(d => d.isOpen)
  .forEach(d => d.close({ cascade: true }));

// Find a dropdown by numeric ID
const firstDropdown = window.Dropdowns.findById(1);
```

#### Listening for Events

```javascript
// Listen for any dropdown opening
document.addEventListener("menuDropdown:open", (e) => {
  console.log(`Dropdown ${e.detail.instanceId} opened`);
  console.log(`Current mode: ${e.detail.mode}`);
  console.log(`Nesting level: ${e.detail.level}`);
});

// Listen for any dropdown closing
document.addEventListener("menuDropdown:close", (e) => {
  console.log(`Dropdown ${e.detail.instanceId} closed`);
});

// Listen for mode-specific events
document.addEventListener("menuDropdown:open:stacked", (e) => {
  console.log("A dropdown opened in stacked (mobile) mode");
});

document.addEventListener("menuDropdown:close:accordion", (e) => {
  console.log("A dropdown closed in accordion mode");
});
```

#### Detecting Mode Changes

```javascript
// Listen for responsive mode switches
document.addEventListener("menuDropdown:modeChange", (e) => {
  const { instanceId, mode, oldMode, newMode } = e.detail;
  
  console.log(`Dropdown ${instanceId} switched from ${oldMode} to ${newMode}`);
  
  // Perform actions based on new mode
  if (newMode === "stacked") {
    // Mobile stacked mode activated
    document.body.classList.add("mobile-nav-active");
  } else if (newMode === "dropdown") {
    // Desktop dropdown mode activated
    document.body.classList.remove("mobile-nav-active");
  }
});
```

#### Working with Nested Dropdowns

```javascript
// Get all dropdown instances
const allDropdowns = window.Dropdowns.getAll();

// Find top-level dropdowns only (level 0)
const topLevelDropdowns = allDropdowns.filter(d => d.level === 0);

// Find nested dropdowns (level > 0)
const nestedDropdowns = allDropdowns.filter(d => d.level > 0);

// Check if a dropdown has open children
const dropdown = window.Dropdowns.findById(1);
if (dropdown.hasOpenDescendant()) {
  console.log("This dropdown has open nested menus");
}

// Access parent/child relationships
const childDropdown = window.Dropdowns.findById(2);
if (childDropdown.parentInstance) {
  console.log("Parent dropdown ID:", childDropdown.parentInstance.id);
}
```
