ItsJonQ / g2

✨ An experimental reimagining of WordPress components
http://g2-components.com/
MIT License
105 stars 12 forks source link

Dropdown: Closing by clicking a child item #147

Closed ItsJonQ closed 3 years ago

ItsJonQ commented 4 years ago

The current Dropdown component from @wordpress/components provides a handful of useful callbacks through it's children render function:

import { Fragment } from '@wordpress/element';
import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
import { more, arrowUp, arrowDown, trash } from '@wordpress/icons';

const MyDropdownMenu = () => (
    <DropdownMenu icon={ more } label="Select a direction">
        { ( { onClose } ) => (
            <Fragment>
                <MenuGroup>
                    <MenuItem icon={ arrowUp } onClick={ onClose }>
                        Move Up
                    </MenuItem>
                    <MenuItem icon={ arrowDown } onClick={ onClose }>
                        Move Down
                    </MenuItem>
                </MenuGroup>
                <MenuGroup>
                    <MenuItem icon={ trash } onClick={ onClose }>
                        Remove
                    </MenuItem>
                </MenuGroup>
            </Fragment>
        ) }
    </DropdownMenu>
);

At the moment, it's tricky to have this kind of setup with the current G2 Dropdown.

If we go with the reakit setup, it would look something like this:

import {
  useMenuState,
  Menu,
  MenuItem,
  MenuButton,
  MenuSeparator,
} from "reakit/Menu";

function Example() {
  const menu = useMenuState();
  return (
    <>
      <MenuButton {...menu}>Preferences</MenuButton>
      <Menu {...menu} aria-label="Preferences">
        <MenuItem {...menu}>Settings</MenuItem>
        <MenuItem {...menu} disabled>
          Extensions
        </MenuItem>
        <MenuSeparator {...menu} />
        <MenuItem {...menu}>Keyboard shortcuts</MenuItem>
      </Menu>
    </>
  );
}

The state is created and passed down into the components.

For the G2 Dropdown component, we can do something like Reakit, but pass in the menu state via a state prop:

  const menu = useMenuState();
  return (<Dropdown state={menu}>...</Dropdown>)

@saramarcondes and I used this technique to improve the G2 Modal.