Building a draggable menu with react-float-menu
Tags: javascript, webdev, typescript, react
Published: 2022-09-05 13:15:43

![demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nvre3ftyckqtlhlkuwo.gif)

Menus are a crucial user interface (UI) control that have long
been a staple of desktop and web applications.

Menus have typically been static, and they bring a lot of efficiency to accessing contextual information. But should the menus always be static? why cant Menu's have some fun.

> What if the menu was draggable and the user had complete control over its placement on the screen?

But why do we need a draggable menu? I started this project
because I wanted to build a menu that is easy to move around and
lets users focus on what's important.

For instance, you might want to maximize the screen area when working on a painting or drawing application. We can put all the painting tools in this menu and easily pull them out when we need them.

In this article, we'll take a closer look at one such smart draggable menu library for React with a user-friendly API that can do exactly that.

We'll learn about [react-float-menu] (https://github.com/prabhuignoto/react-float-menu), understand its API, and see it in action.

As its name suggests, you can easily drag the menu and place it 
wherever you like on the screen. The library is capable of more than just dragging, as we'll see in a second.

---

Before we start using the library, let's go through and learn about some of its most important features.

## ⭐ Starting position & Pinning

The menu's starting point can be easily set to one of four predefined positions (`top left`, `top right`, `bottom left`, `bottom right`). You can also pin the menu. Pinning turns off the ability to drag, which could be useful in apps where you want to keep the menu in the same position.

## ⭐ Custom shape and icon for the Menu head

A menu head is the main part of react-float-menu that can be moved, and you can choose whether you want it to be square or round. The menu head shows a default icon, which can also be changed.

## ⭐ Auto flip

There are times when it's convenient to have the menu automatically flip for you, especially if it's on a screen edge where there isn't much room to show the menu downwards. This is especially the case when the menu is placed at the bottom of the screen.

## ⭐ Auto positioning

When the menu head is placed on the horizontal edges, the menu may also become hidden. The library offers the choice to automatically move and bring it to our focus.

## ⭐ Sub menu

Sub-menus work right out of the box. No extra property is needed. All we have to do to create a submenu is add a nested collection to an existing menu item.

## ⭐ Theme

The library allows for very precise themeing, and you are completely free to change the colors of the different elements of the menu.

---

## Getting started

Let's get started by installing the library.

`npm install react-float-menu or yarn add react-float-menu`

> The article assumes that you already have everything set up and ready to go for development. If you don't know how to start, use [create-react-app](https://reactjs.org/docs/create-a-new-react-app.html) or [vite](https://vitejs.dev/) to get the react project off the ground.

### Building the menu

`react-float-menu` is a data driven library. This means you need to pass a collection of menu items to build the menu. Let's see how to do that.

```
<Menu
  items={[
    { name: "File" },
    { name: "Edit" },
    { name: "Add" }
  ]}
></Menu>
```

Now that we've set up the basics, let's check out some of the other features. First, let's look at how to change the shape of the menu head and the main icon.

```
<Menu
  items={[
    { name: "File" },
    { name: "Edit" },
    { name: "Add" }
  ]}
  shape="square"
>
  <span>💟</span>
</Menu>
```

We changed the shape of the menu head and changed the default icon with this new code. Now it's time to add some of the cool things we talked about before.


#### Pinning & Start Position

```
<Menu
  items={[
    { name: "File" },
    { name: "Edit" },
    { name: "Add" },
  ]}
  startPosition="top left"
  pin
>
  <span>💟</span>
</Menu>
```

By setting the `pin` prop, we have made the menu non draggable and, by using the `startPosition` prop, we have placed it on the top left corner of the screen.

#### Auto flip & Positioning

```
<Menu
  items={[
    { name: "File" },
    { name: "Edit"  },
    { name: "Add" }
  ]}
  startPosition="top left"
  pin
  autoFlipMenu
  bringMenuToFocus
>
  <span>💟</span>
</Menu>
```

The `autoFlipMenu` automagically flips the menu vertically and brings it to the visible area of the browser. Similarly, `bringMenuToFocus` moves the menu horizontally and brings it to the visible area of the browser.

#### Themeing

With the theme prop, you can completely change the look and feel of the menu.

```
<Menu
  items={[
    { name: "File" },
    { name: "Edit"  },
    { name: "Add" }
  ]}
  shape="square"
  startPosition="top left"
  pin
  autoFlipMenu
  bringMenuToFocus
  theme={{
    menuBackgroundColor: "#FFFFFF",
    menuItemHoverColor: "#318CE7",
    menuItemHoverTextColor: "#fff",
    primary: "#318CE7",
    secondary: "#FFFFFF",
  }}
>
  <PlusIcon />
</Menu>;
```

Before we wrap up, let's take a look at one more cool feature. What if we also want the `menu items` to have icons? It is as simple as adding an `icon` property to the `items` collection.

```
<Menu
  items={[
    { name: "File", icon: <span>📁</span> },
    {
      name: "Edit", icon: <span>📝</span>,
      children: [{name: "Cut", icon: <span>✂️</span>}]
    },
    { name: "Add", icon: <span>➕</span> },
  ]}
  shape="square"
  startPosition="top left"
  pin
  autoFlipMenu
  bringMenuToFocus
  theme={{
    menuBackgroundColor: "#FFFFFF",
    menuItemHoverColor: "#318CE7",
    menuItemHoverTextColor: "#fff",
    primary: "#318CE7",
    secondary: "#FFFFFF",
  }}
>
</Menu>;
```

Notice how we have added a submenu to the `Edit` menu item. To add a submenu, all we need to do is pass an array of menu items to the `children` property.

```
items={[
    { name: "File", icon: <span>📁</span> },
    {
      name: "Edit", icon: <span>📝</span>,
      items: [{name: "Cut", icon: <span>✂️</span>}]
    },
    { name: "Add", icon: <span>➕</span> },
  ]}
```

After completing all the steps, the menu should look as follows.

![demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1nvocems7wnse7ujosfh.png)

You can check out the menu for yourself in this [codesandbox](https://codesandbox.io/s/cocky-satoshi-hkm28g?file=/src/App.tsx).

The library's first release came out a few weeks back, and more important updates are on the way. Soon, things like improved accessibility and rendering custom content will be made available.

[Github Project Page](https://github.com/prabhuignoto/react-float-menu)

If you liked this project, you might also like some of [my other open source work](https://github.com/prabhuignoto).