pangpp
pangpp

Reputation: 165

React-select, open sub-menu when hover over an option

I'm trying to build a submenu inside a main menu with React-select, it should be something like this:

Text

When hovering over an option from the main menu, it triggers the submenu to open at the side.

Is there a way to do this using react-select? I couldn't find any example or documentation on this, is there a function like ```optionOnMouseover`` for this? Thank you in advance!

const options = [
  { value: 'chocolate', label: 'Chocolate' },
  { value: 'strawberry', label: 'Strawberry' },
  { value: 'vanilla', label: 'Vanilla' },
];
...

<Select
    value={...}
    onChange={...}
    options={options}
 />```

Upvotes: 4

Views: 3658

Answers (1)

Garry14
Garry14

Reputation: 41

This is on click, but if you need on hover, just modify it

import React, { useState } from "react";

import ReactDOM from "react-dom";
import Select, { components } from "react-select"

const CustomOption = (props) => {
  const [submenu, setSubmenu] = useState(false)
  const [height, setHeight] = useState(0)
  const handleOption = (e) => {
    if(submenu) {
      setSubmenu(false)  
    } else {
      setHeight(e.clientY)
      setSubmenu(true)  
    }
    
  }
  const handleSubOption = (e) => {
    console.log('clicked')
  }
  const { data } = props;
  return data.custom ? (
    <>
      <div onClick={handleOption} className="customs">
        {data.label} <span className="caret"/>
          {
            submenu && (
              <div className="dropdown-submenu">
                <div className="drops" onClick={handleSubOption}>
                  Test dropdown 1
                </div>
                <div className="drops" onClick={handleSubOption}>
                  Test dropdown 2
                </div>
                <div className="drops" onClick={handleSubOption}>
                  Test dropdown 3
                </div>
              </div>
            )
          }
      </div>
      <style jsx>{`
        .customs {
          height: 36px;
          padding: 8px;
          position: relative;
        }
        
        .drops {
          height: 36px;
          padding: 8px;
        }

        .customs:hover, .drops:hover {
          background-color: #17cf76;
        }

        .dropdown-submenu {
          position: fixed;
          top: ${height - 10}px;
          left: 410px;
          min-height: 36px;
          overflow: auto;
          border: 1px solid hsl(0,0%,80%);
          border-radius: 4px;
          color: #212529;
        }
      `}</style>
    </>
  ) : (
    <components.Option {...props} />
  );
};

const options = [
  { custom: true, label: "I'm a custom link", value: "cust" }
];

function App() {
  return (
    <>
      <Select classNamePrefix="category-select" className="w-30" components={{ Option: CustomOption }} options={options} />
      <style jsx global>{`
        * {
          font-family: sans-serif;
          text-align: center;
        }
        .w-30 {
          width: 30% !important;
        }
      `}</style>
    </>
  )
}

export default App

Upvotes: 1

Related Questions