---
title: "Hotwire Native Bridge Menu (Action Sheet) Component"
author: "Yaroslav Shmarov"
date: "2024-11-09"
canonical_url: "https://blog.superails.com/hotwire-native-bridge-menu-component"
markdown_url: "https://blog.superails.com/hotwire-native-bridge-menu-component.md"
description: "Hotwire Native ships with a default Menu and OverflowMenu component. Menu let's you invoke a native dropdown with links and buttons that you define in HTML."
tags: ["hotwire-native"]
license: "GNU AGPL v3. Credit Yaroslav Shmarov and link the canonical URL."
---

# Hotwire Native Bridge Menu (Action Sheet) Component

Hotwire Native ships with a default `Menu` and `OverflowMenu` component.

![ios action sheet](https://blog.superails.com/assets/images/ios-action-sheet.png)

`Menu` let's you invoke a native dropdown with links and buttons that you define in HTML.

In SwiftUI it is called [Action sheets](https://developer.apple.com/design/human-interface-guidelines/action-sheets)

![hotwire-native-menu-example](https://blog.superails.com/assets/images/hotwire-native-menu-example.gif)

`OverflowMenu` invokes the same menu, but as a native button on the top-right corner of your screen.

![hotwire-native-overflow-menu-example](https://blog.superails.com/assets/images/hotwire-native-overflow-menu-example.gif)

To use this component, be sure to first install `hotwire-native-bridge` in your app:

```shell
./bin/importmap pin @hotwired/stimulus @hotwired/hotwire-native-bridge
```

Import the StimulusJS controllers into your app:

- [menu_controller.js](https://github.com/hotwired/hotwire-native-demo/blob/main/public/javascript/controllers/bridge/menu_controller.js)
- [overflow_menu_controller.js](https://github.com/hotwired/hotwire-native-demo/blob/main/public/javascript/controllers/bridge/overflow_menu_controller.js)

Ensure your ios app has these Bridge components:

- [MenuComponent.swift](https://github.com/hotwired/hotwire-native-ios/blob/main/Demo/Bridge/MenuComponent.swift)
- [OverflowMenuComponent.swift](https://github.com/hotwired/hotwire-native-ios/blob/main/Demo/Bridge/OverflowMenuComponent.swift)

The default HMTL example of using these menus:

- [HTML example - Menu](https://github.com/hotwired/hotwire-native-demo/blob/main/views/bridge-menu.ejs)
- [HTML example - OverflowMenu](https://github.com/hotwired/hotwire-native-demo/blob/main/views/bridge-overflow.ejs)

Stripped dowwn HTML example for `Menu`:

```html
<div data-controller="bridge--menu">
  <button 
    data-action="click->bridge--menu#show click->menu#show">
    Open Menu
  </button>
  <div>
    <p data-bridge--menu-target="title">Select an option</p>
    <%= link_to "Edit", edit_organization_path(@organization), data: {"bridge--menu-target": "item"} %>
    <%= button_to "Destroy", @organization, method: :delete, data: { "bridge--menu-target": "item", turbo_confirm: "Are you sure?" } %>
    <button data-bridge--menu-target="item">
      Option Three
    </button>
  </div>
</div>
```

For `OverflowMenu`, just initialize the `bridge--overflow-menu` controller on the action button:

```diff
<div data-controller="bridge--menu">
  <button 
+    data-controller="bridge--overflow-menu"
    data-action="click->bridge--menu#show click->menu#show">
    Open Menu
  </button>
  <div>
    <p data-bridge--menu-target="title">Select an option</p>
    <%= link_to "Edit", edit_organization_path(@organization), data: {"bridge--menu-target": "item"} %>
    <%= button_to "Destroy", @organization, method: :delete, data: { "bridge--menu-target": "item", turbo_confirm: "Are you sure?" } %>
    <button data-bridge--menu-target="item">
      Option Three
    </button>
  </div>
</div>
```

As a next step, you might want to completely hide the menu element `style="display: hidden"`, and only display the native elements generated by it.

That's it!
