Styleguide

HoverDropdown

The HoverDropdown component is a glorified <select>. One advantage over a regular <select> is that it allows for the rendering of a "secondary" UX element within the dropdown, wherein the user can add additional detail about a "primary" option that they selected. For example, one option might be "Custom", and the user can specify what exactly they want "Custom" to mean in the "secondary" UX element.

Even if you don't use the "secondary UX element" functionality, there are still some advantages over a <select>: more flexible CSS styling and the UX of not having to click to open the dropdown.

Basic

import React from 'react';
import HoverDropdown from 'react_components/hover_dropdown';

export default function HoverDropdownSimpleExample() {
  const options = [
    { key: 1, displayName: 'One', value: 'Uno' },
    { key: 2, displayName: 'Two', value: 'Dos' },
    { key: 3, displayName: 'Three', value: 'Tres' },
  ];

  return (
    <HoverDropdown
      options={options}
      onSelectValue={value => alert(`That's "${value}" en español`)} // eslint-disable-line no-alert
      titleClass='xs-epsilon'
    />
  );
}

Specifying a Pre-selected Option

By default, the first option will be marked as selected. If you would like some other option to be initially selected, you can provide a preselectedKey prop.

import React from 'react';
import HoverDropdown from 'react_components/hover_dropdown';

export default function HoverDropdownPreselectedExample() {
  const options = [
    { key: 1, displayName: 'One', value: 'Uno' },
    { key: 2, displayName: 'Two', value: 'Dos' },
    { key: 3, displayName: 'Three', value: 'Tres' },
  ];

  return (
    <HoverDropdown
      options={options}
      onSelectValue={value => alert(`That's "${value}" en español`)} // eslint-disable-line no-alert
      titleClass='xs-epsilon'
      preselectedKey={options[2].key}
    />
  );
}

With Secondary UX Element

Instead of having the initial click on a dropdown option immediately trigger the selection of a certain value, you can instead show the user a secondary screen, allowing the user to make a selection using a secondary UX element. In this example, the secondary UX element is just a set of buttons, but it could be something more complex, such as a date range picker.

To implement a secondary screen for one or more of the dropdown options, provide a secondaryContent value instead of a value for those options. secondaryContent should be a function. The function will be passed two arguments (which are themselves functions) that you can call selectValue and cancelSecondaryScreen. Your secondaryContent should return some JSX, in which you use the selectValue and (optionally) the cancelSecondaryScreen callbacks as event handlers. Calling the selectValue callback will trigger the onSelectValue function that you originally passed as a prop to the HoverDropdown component. Calling cancelSecondaryScreen will clear the secondary screen and close the dropdown.

import React from 'react';
import HoverDropdown from 'react_components/hover_dropdown';

export default function HoverDropdownComplexExample() {
  const numberButtons = (selectValue, cancelSecondaryScreen) => (
    <div className='xs-text-center xs-m1'>
      <button
        className='button button--full button--primary xs-mbh0'
        onClick={() => selectValue(1)}
      >One</button>
      <button
        className='button button--full button--primary xs-mbh0'
        onClick={() => selectValue(2)}
      >Two</button>
      <button
        className='button button--full button--primary xs-mbh0'
        onClick={() => selectValue(3)}
      >Three</button>
      <button
        className='button button--full button--tertiary'
        onClick={cancelSecondaryScreen}
      >Cancel</button>
    </div>
  );

  const options = [
    { key: 'random', displayName: 'Surprise me', value: Math.floor(100 * Math.random()) },
    { key: 'user-selected', displayName: 'I want to choose', secondaryContent: numberButtons },
  ];

  return (
    <HoverDropdown
      options={options}
      // eslint-disable-next-line no-alert
      onSelectValue={value => alert(`You chose the number ${value}`)}
      titleClass='xs-epsilon'
    />
  );
}