Skip to content

Commit

Permalink
feat!(menu): Implemented new Menu API
Browse files Browse the repository at this point in the history
This is a complete rehaul of the menu components to hopefully be a lot
easier to use. Here's a quick diff representing the changes:

```diff
 import { render } from "react-dom";
-import { DropdownMenu } from "@react-md/menu";
+import { DropdownMenu, MenuItem } from "@react-md/menu";

 const App = () => (
-  <DropdownMenu
-    id="example-dropdown-menu"
-    items={[
-      { onClick: () => console.log("Clicked Item 1"), children: "Item 1" },
-      { onClick: () => console.log("Clicked Item 2"), children: "Item 2" },
-      { onClick: () => console.log("Clicked Item 3"), children: "Item 3" },
-    ]}
-  >
-    Dropdown
+  <DropdownMenu id="example-dropdown-menu" buttonChildren="Dropdown">
+    <MenuItem onClick={() => console.log("Clicked Item 1")}>Item 1</MenuItem>
+    <MenuItem onClick={() => console.log("Clicked Item 2")}>Item 2</MenuItem>
+    <MenuItem onClick={() => console.log("Clicked Item 3")}>Item 3</MenuItem>
   </DropdownMenu>
 );
```

New Functionality

- App-wide `Menu` behavior can be configured using the
  `MenuConfigurationProvider` or `menuConfiguration` prop on the
  `Layout` component
- The focus behavior in menus can be disabled with the new
  `disableFocusOnMount` and `disableFocusOnUnmount` props
- Menus have built-in support for rendering as a `Sheet` on mobile
  devices by setting `renderAsSheet="mobile"` on the `DropdownMenu`,
  `Menu`, `MenuConfigurationProvider`, or
  `Layout.menuConfiguration.renderAsSheet`
  - `rendeAsSheet` can also be set to `true` if you want to render all
    menus as sheets for some reason.
  - the sheets can be configured to have an optional `header` and
    `footer` as well
- `Menu` visibility can be controlled by child components of the
  `DropdownMenu` or `Menu` components using the new `useMenuVisibility`
  hook that provides the `visible` state and a `setVisible` function
- Built-in support for hoverable menus using the new `MenuBar` component

New Components

- `MenuItemFileInput` - a wrapper for the `<input type="file">` that
  works within `Menu` components (`@react-md/form`)
- `MenuItemTextField` - a wrapper for the `TextField` component that
  works within `Menu` components (`@react-md/form`)
- `MenuItemGroup` - a small wrapper for the `List` component that
  requires an `aria-label` and sets its `role` to `"group"`. This is
  just a convenience component for rendering `MenuItemRadio` components
  with other `MenuItem`s while maintaining accessibility
  (`@react-md/menu`)
- `MenuConfigurationProvider` - a new context provider to override menu
  behavior like rendering sheets.
- `MenuBar` - a new component that allows the child `DropdownMenu`
  components to gain visibility on hover after clicking one of the menus
  once. The menus can gain visibility on hover immediately if you
  provide a `hoverTimeout={0}` to the `MenuBar`.
  - The `MenuBar` also integrates some keyboard movement behavior
    following the [menubar spec](https://www.w3.org/TR/wai-aria-practices/#menu)

BREAKING CHANGE: The `DropdownMenu` component no longer accepts a list
of `items` and instead the `children` should be the `MenuItem`
components.

BREAKING CHANGE: The `useContextMenu` now returns an object instead of an
ordered list.

BREAKING CHANGE: The `DropdownMenuItem` component is no longer required
for nested dropdown menus and is an "internal" component instead that
shouldn't really be used.

BREAKING CHANGE: The `DropdownMenu` component no longer supports the
`menuRenderer` and `itemRenderer` props. Instead, there is built-in
support for conditionally rendering as a `Sheet` component using the
`renderAsSheet` prop.

BREAKING CHANGE: The `MenuItemSeparator` now renders as an `<li>`
instead of an `<hr>` or `<div>`.

BREAKING CHANGE: The `DropdownMenu` component now requires a parent
`AppSizeListener` because of the conditional `Sheet` rendering
functionality. This might require updating your tests to either use the
`Configuration` component from `@react-md/layout` (recommended) or
adding the `AppSizeListener` to tests that include `DropdownMenu`s.

BREAKING CHANGE: Menu buttons will no longer open by pressing the
`ArrowUp` or `ArrowDown` keys.

BREAKING CHANGE: Using any of the `MenuItem` components requires the
`<MenuKeyboardFocusProvider>` to be mounted as a parent component which
might affect tests. This will not break anything if you are using the
`DropdownMenu` or `Menu` components.
  • Loading branch information
mlaursen committed Jan 30, 2022
1 parent 77f0d01 commit c27bf55
Show file tree
Hide file tree
Showing 138 changed files with 4,390 additions and 4,511 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ import switchExamples from "./SwitchExamples.md";
import AsyncSwitchExample from "./AsyncSwitchExample";
import asyncSwitchExample from "./AsyncSwitchExample.md";

import MenusWithFormControls from "./MenusWithFormControls";
import menusWithFormControls from "./MenusWithFormControls.md";

const demos: DemoConfig[] = [
{
name: "Checkbox and Radio Examples",
Expand All @@ -48,11 +45,6 @@ const demos: DemoConfig[] = [
description: asyncSwitchExample,
children: <AsyncSwitchExample />,
},
{
name: "Menus with Form Controls",
description: menusWithFormControls,
children: <MenusWithFormControls />,
},
];

export default function SelectionControls(): ReactElement | null {
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This demo will showcase some of the props available for the `DropdownMenu`
component.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.column {
align-content: flex-start;
}

.container {
display: flex;
justify-content: center;
margin-top: 3rem;
}
Loading

0 comments on commit c27bf55

Please sign in to comment.