Skip to main content

Your first custom menu item

Now that we have our map up and running, let's add some interactivity.

We can do this with a Menu Item! But what is a menu item?

Menu items exist inside the Context Menu, which can be opened by right clicking on a widget.

Clicking on a menu item performs a predetermined action.

Context Menu

To start our quest for interactivity, let's make a "Hello world" menu item from scratch.

Hello world menu item#

  • In the src folder, create a new file: pluginMenuItemFilterOnCountries.tsx
  • Copy in the following code:
import { MenuItemPlugin, MenuItemProps } from "@activeviam/activeui-sdk";import React, { FC } from "react";import Menu from "antd/lib/menu";
import { MapWidgetState } from "./map.types";
const FilterOnCountriesMenuItem: FC<MenuItemProps<MapWidgetState>> = (  props,) => {  return <Menu.Item {...props}>Filter dashboard on countries</Menu.Item>;};
export const pluginMenuItemFilterOnCountries: MenuItemPlugin<MapWidgetState> = {  key: "filter-on-countries",  Component: FilterOnCountriesMenuItem,};

…don't forget to internationalize it!

  import { MenuItemPlugin, MenuItemProps } from "@activeviam/activeui-sdk";  import React, { FC } from "react";  import Menu from "antd/lib/menu";+ import { useIntl } from "react-intl";  import { MapWidgetState } from "./map.types";
  const FilterOnCountriesMenuItem: FC<MenuItemProps<MapWidgetState>> = (props) => {+   const { formatMessage } = useIntl();
    return (      <Menu.Item {...props}>-       Filter dashboard on countries+       {formatMessage({+         id: "aui.plugins.menu-item.filter-on-countries.caption",+       })}      </Menu.Item>    );  };
  export const pluginMenuItemFilterOnCountries: MenuItemPlugin<MapWidgetState> = {    key: "filter-on-countries",    Component: FilterOnCountriesMenuItem,+   translations: {+     "en-US": {+       caption: "Filter dashboard on countries",+     },+   },  };

As always, we have to wire this new plugin into plugins.tsx.

Since we are making a menu item, we will put it in the menuItemPlugins array:

+ import { pluginMenuItemFilterOnCountries } from "./pluginMenuItemFilterOnCountries";
  const menuItemPlugins: MenuItemPlugin<any, any>[] = [+   pluginMenuItemFilterOnCountries,    pluginMenuItemDuplicateWidget,
    ...
  ];

However, our new menu item won't show up when we right-click our map yet.

  • Add its key to the map's list of context menu items.

plugins.tsx:

...
+  pluginWidgetMap.contextMenuItems = [ "filter-on-countries" ];
...

It worked!

The menu item now appears when we right-click the map!

But nothing happens when we then click it.

Let's fix this!

pluginMenuItemFilterOnCountries.tsx:

const FilterOnCountriesMenuItem: FC<MenuItemProps<MapWidgetState>> = (props) => {
  const { formatMessage } = useIntl();
+ const handleClicked = () => {+   alert("hello world!");+ };
  return (-   <Menu.Item {...props}>+   <Menu.Item {...props} onClick={handleClicked}>
      ...
    </Menu.Item>  );};

Great! But it doesn't close itself after the click.

This can be fixed by calling props.onClick. This will tell Ant Design that the menu item was clicked:

+ import { MenuItemProps as AntMenuItemProps } from "antd/lib/menu/MenuItem";
...
- const handleClicked = () => {+ const handleClicked: AntMenuItemProps["onClick"] = (param) => {    alert("hello world!");+   props.onClick?.(param);  };

And that's all there is to it!

On the next page, we will give our new menu item some functionality! 🕺