ironmansoftware / powershell-universal

Issue tracker for PowerShell Universal
https://powershelluniversal.com
35 stars 2 forks source link

UDMenu / UDButton - Add onMouseOver and onMouseLeave handler #3597

Open eizedev opened 3 weeks ago

eizedev commented 3 weeks ago

Summary of the new feature / enhancement

Hi @adamdriscoll

(same for New-UDListItem #3674)

The following request would make it technically possible to execute a redirect by clicking on the menu (onClick Handler for New-UDMenu) and to open New-UDMenuItem via mouseover.

We are currently in the process of building a new app menu in the app header / page header because we don't like the drawer or the normal navigation menu.
I would like to build a menu similar to the one on https://mui.com/.
To do this, I need the “Menu” component with the buttons used and the option to expand the menu on mouseover.

Also the onMouseLeave handler needs to be integrated. This can be done using MenuListProps={{ onMouseLeave: handleClose }}. Using onMouseLeave directly on Menu doesn't work because the Menu includes an overlay as part of the Menu leveraging Modal and the mouse never "leaves" the overlay.

I don't quite understand how exactly the integration on mui.com was built using native possibilities of their menu component, but I would like to at least basically recreate the functionality of having a menu in the header that I can open via mouseover. Of course, it would be nice if the “MenuItems” also looked like they do on mui.com.

I tried by using javascript directly to modify the component or creating the Element by myself using New-UDelement and changing the attributes but I would like it to be natively supported.

Side note: When a menu has no MenuItems, no OnClick Handler exists for the menu itself. But that would be another issue (if no children are needed, we use a button instead)...

Example

Here is a sample what we are using at the moment using the UDMenu in the HeaderContent (without any custom styling for the issue here). The ButtonGroup is only to have some content, not relevant.

https://github.com/user-attachments/assets/1de6ab0e-17b7-48ce-ac80-929427fdc43c

New-UDPage -Name 'Test' -Url 'test' -HeaderContent {
    New-UDMenu -Text 'Home' -Icon (New-UDIcon -Icon 'anchor') -Variant 'outlined' -Children {
        New-UDMenuItem -Text 'Home' -OnClick { Invoke-UDRedirect 'https://www.google.com' } -Icon (New-UDIcon -Icon 'anchor')
    }
    New-UDMenu -Text 'Service Requests' -Icon (New-UDIcon -Icon 'cubes') -Variant 'outlined' -Children {
        New-UDMenuItem -Text 'New VM' -Icon (New-UDIcon -Icon 'plus') -OnClick { Invoke-UDRedirect 'https://www.google.com' }
        New-UDMenuItem -Text 'Change VM' -Icon (New-UDIcon -Icon 'pen') -OnClick { Invoke-UDRedirect 'https://www.google.com' }
    }
    New-UDMenu -Text 'Modules' -Icon (New-UDIcon -Icon 'cubes') -Variant 'outlined' -Children {
        New-UDMenuItem -Text 'abc' -OnClick { Invoke-UDRedirect 'https://www.google.com' }
        New-UDMenuItem -Text 'def' -Icon (New-UDIcon -Icon 'helicopter') -OnClick { Invoke-UDRedirect 'https://www.google.com' }
        New-UDMenuItem -Text 'ghi' -OnClick { Invoke-UDRedirect 'https://www.google.com' }
    }
    New-UDMenu -Text 'Settings' -Icon (New-UDIcon -Icon 'edit') -Variant 'outlined' -Children {
        New-UDMenuItem -Text 'Environments' -OnClick { Invoke-UDRedirect 'https://www.google.com' }
    }
    New-UDMenu -Text 'Administration' -Icon (New-UDIcon -Icon 'id_card') -Variant 'outlined' -Children {
        New-UDMenuItem -Text 'Environments' -OnClick { Invoke-UDRedirect 'https://www.google.com' }
    }
} -Content {
    New-UDButtonGroup -Variant 'outlined' -Content {
        New-UDButtonGroupItem -Text 'Delete' -Icon (New-UDIcon -Icon 'trash') -href 'https://www.google.com'
        New-UDButtonGroupItem -Text 'Copy' -Icon (New-UDIcon -Icon 'copy') -href 'https://www.google.com'
    }
}

MUI menu from https://mui.com/

image

Thanks, René

Proposed technical implementation details (optional)

A basic example where onMouseOver and onMouseLeave is included is this one:

import React from "react";
import Button from "@material-ui/core/Button";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";

function SimpleMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  function handleClick(event) {
    if (anchorEl !== event.currentTarget) {
      setAnchorEl(event.currentTarget);
    }
  }

  function handleClose() {
    setAnchorEl(null);
  }

  return (
    <div>
      <Button
        aria-owns={anchorEl ? "simple-menu" : undefined}
        aria-haspopup="true"
        onClick={handleClick}
        onMouseOver={handleClick}
      >
        Open Menu
      </Button>
      <Menu
        id="simple-menu"
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={handleClose}
        MenuListProps={{ onMouseLeave: handleClose }}
      >
        <MenuItem onClick={handleClose}>Profile</MenuItem>
        <MenuItem onClick={handleClose}>My account</MenuItem>
        <MenuItem onClick={handleClose}>Logout</MenuItem>
      </Menu>
    </div>
  );
}

export default SimpleMenu;