Search code examples
reactjspluginsiconsjbrowse

Adding Icons to dropdown menus with JBrowse2 plugins


I'm developing a React.js, JBrowse2 application and my goal is to build tools on top of the existing 'jbrowse-react-linear-genome-view' app from their GitHub. One major feature of JBrowse2 is developing what they call 'plugins'. Below is a simple example of a 'locally defined plugin', meaning I define this plugin directly where I'm generating my JBrowse session. This plugin shows up when you highlight a region and allows me to add other dropdown options to the HighlightRegion feature. My question, is it possible to add menu icons to this dropdown menu so it looks like the default JBrowse2 options? ChatGPT says just add an 'icon' key:value to the rubberBandMenuItems, but any version of trying that just gives me errors (Error Below). Any ideas on how to get icons in dropdown menus with JBrowse2 Plugins?

// I call this small class a 'locally defined' plugin
class HighlightRegionPlugin extends Plugin {
    name = "HighlightRegionPlugin"

    install(pluginManager) {
    pluginManager.addToExtensionPoint(
        "Core-extendPluggableElement",
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        pluggableElement => {
            if (pluggableElement.name === "LinearGenomeView") {
                const { stateModel } = pluggableElement
                const newStateModel = stateModel.extend(self => {
                    const superRubberBandMenuItems = self.rubberBandMenuItems
                    return {
                        views: {
                            rubberBandMenuItems() {
                                return [
                                    ...superRubberBandMenuItems(),
                                    {
                                      label: "Console log selected region",
                                      onClick: () => {
                                        const { leftOffset, rightOffset } = self
                                        const selectedRegions = self.getSelectedRegions(
                                          leftOffset,
                                          rightOffset
                                        )
                                        // console log the list of potentially multiple
                                        // regions that were selected
                                        console.log("selected: ",selectedRegions);
                                      }
                                    }
                                ]
                            }
                        }
                    }
                })

                pluggableElement.stateModel = newStateModel
            }
            return pluggableElement
        }
    )
}

configure() { }

}

Errors:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <ForwardRef(InfoIcon) />. Did you accidentally export a JSX literal instead of a component?

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Solution

  • You have to use the '@mui/icons-material' library for the icons to work. I was attempting to use 'react-icons' which doesn't work. Just add this line to your rubberBandMenuItems:

     import SearchIcon from '@mui/icons-material/Search';
    
     return [
        ...superRubberBandMenuItems(),
        {
            label: "New Feature",
            icon: SearchIcon,
            onClick: () => {
                console.log("got here");
            }
        } ...