Skip to content

Commit

Permalink
docs(menu): add initial docs for menu (#906)
Browse files Browse the repository at this point in the history
  • Loading branch information
kara authored and hansl committed Jul 25, 2016
1 parent 5251c27 commit 5cfe4c3
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 5 deletions.
167 changes: 167 additions & 0 deletions src/components/menu/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# md-menu

`md-menu` is a list of options that displays when triggered. You can read more about menus in the
[Material Design spec](https://material.google.com/components/menus.html).

## Usage

### Setup

`md-menu` relies on the existence of an app-wide `OverlayContainer`. This is the container in which
it will display. You'll need to import this from `@angular2-material/core` and add it to your
providers list on bootstrap.

*main.ts*
```ts
import { OverlayContainer } from '@angular2-material/core';

bootstrap(AppComponent, [
OverlayContainer
]);
```

You'll also want to import the menu directives and add them to your component's directives array:

*my-comp.component.ts*
```ts
import {MD_MENU_DIRECTIVES} fom '@angular2-material/menu';

@Component({
...
directives: [MD_MENU_DIRECTIVES]
})
class MyComp {}
```
### Simple menu
In your template, create an `md-menu` element. You can use either `<button>` or `<anchor>` tags for
your menu items, as long as each is tagged with an `md-menu-item` attribute. Note that you can
disable items by adding the `disabled` boolean attribute or binding to it.
*my-comp.html*
```html
<!-- this menu starts as hidden by default -->
<md-menu>
<button md-menu-item> Refresh </button>
<button md-menu-item> Settings </button>
<button md-menu-item> Help </button>
<button md-menu-item disabled> Sign Out </button>
</md-menu>
```
Menus are hidden by default, so you'll want to connect up a menu trigger that can open your menu.
You can do so by adding a button tag with an `md-menu-trigger-for` attribute and passing in the menu
instance. You can create a local reference to your menu instance by adding `#menu="mdMenu"` to
your menu element.
*my-comp.html*
```html
<!-- menu opens when trigger button is clicked -->
<button md-icon-button [md-menu-trigger-for]="menu">
<md-icon>more_vert</md-icon>
</button>

<md-menu #menu="mdMenu">
<button md-menu-item> Refresh </button>
<button md-menu-item> Settings </button>
<button md-menu-item> Help </button>
<button md-menu-item disabled> Sign Out </button>
</md-menu>
```
Output:
<img src="https://material.angularjs.org/material2_assets/menu/default_closed.png">
<img src="https://material.angularjs.org/material2_assets/menu/default_open.png">
### Toggling the menu programmatically
You can also use the menu's API to open or close the menu programmatically from your class. Please
note that in this case, an `md-menu-trigger-for` attribute is still necessary to connect
the menu to its trigger element in the DOM.
*my-comp.component.ts*
```ts
class MyComp {
@ViewChild(MdMenuTrigger) trigger: MdMenuTrigger;

someMethod() {
this.trigger.openMenu();
}
}
```
*my-comp.html*
```html
<button md-icon-button [md-menu-trigger-for]="menu">
<md-icon>more_vert</md-icon>
</button>

<md-menu #menu="mdMenu">
<button md-menu-item> Refresh </button>
<button md-menu-item> Settings </button>
<button md-menu-item> Help </button>
<button md-menu-item disabled> Sign Out </button>
</md-menu>
```
### Customizing menu position
By default, the menu will display after and below its trigger. You can change this display position
using the `x-position` (`before | after`) and `y-position` (`above | below`) attributes.
*my-comp.html*
```html
<md-menu x-position="before" #menu="mdMenu">
<button md-menu-item> Refresh </button>
<button md-menu-item> Settings </button>
<button md-menu-item> Help </button>
<button md-menu-item disabled> Sign Out </button>
</md-menu>
```
Output:
<img src="https://material.angularjs.org/material2_assets/menu/before_closed.png">
<img src="https://material.angularjs.org/material2_assets/menu/before_open.png">
### Accessibility
The menu adds `role="menu"` to the main menu element and `role="menuitem"` to each menu item. It
also adds `aria-hasPopup="true"` to the trigger element.
### Menu attributes
| Signature | Values | Description |
| --- | --- | --- |
| `x-position` | `before | after` | The horizontal position of the menu in relation to the trigger. Defaults to `after`. |
| `y-position` | `above | below` | The vertical position of the menu in relation to the trigger. Defaults to `below`. |
### Trigger Programmatic API
**Properties**
| Name | Type | Description |
| --- | --- | --- |
| `menuOpen` | `Boolean` | Property that is true when the menu is open. It is not settable (use methods below). |
| `onMenuOpen` | `Observable<void>` | Observable that emits when the menu opens. |
| `onMenuClose` | `Observable<void>` | Observable that emits when the menu closes. |
**Methods**
| Method | Returns | Description |
| --- | --- | --- |
| `openMenu()` | `Promise<void>` | Opens the menu. Returns a promise that will resolve when the menu has opened. |
| `closeMenu()` | `Promise<void>` | Closes the menu. Returns a promise that will resolve when the menu has closed. |
| `toggleMenu()` | `Promise<void>` | Toggles the menu. Returns a promise that will resolve when the menu has completed opening or closing. |
| `destroyMenu()` | `Promise<void>` | Destroys the menu overlay completely.
### TODO
- Keyboard events: up arrow, down arrow, enter
- `prevent-close` option, to turn off automatic menu close when clicking outside the menu
- Custom offset support
15 changes: 10 additions & 5 deletions src/components/menu/menu-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
export class MdMenuTrigger implements AfterViewInit, OnDestroy {
private _portal: TemplatePortal;
private _overlayRef: OverlayRef;
menuOpen: boolean = false;
private _menuOpen: boolean = false;

@Input('md-menu-trigger-for') menu: MdMenu;
@Output() onMenuOpen = new EventEmitter();
Expand All @@ -56,9 +56,11 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {

ngOnDestroy() { this.destroyMenu(); }

get menuOpen(): boolean { return this._menuOpen; }

@HostListener('click')
toggleMenu(): Promise<void> {
return this.menuOpen ? this.closeMenu() : this.openMenu();
return this._menuOpen ? this.closeMenu() : this.openMenu();
}

openMenu(): Promise<void> {
Expand All @@ -75,14 +77,17 @@ export class MdMenuTrigger implements AfterViewInit, OnDestroy {
}

destroyMenu(): void {
if (this._overlayRef) { this._overlayRef.dispose(); }
if (this._overlayRef) {
this._overlayRef.dispose();
this._overlayRef = null;
}
}

// set state rather than toggle to support triggers sharing a menu
private _setIsMenuOpen(isOpen: boolean): void {
this.menuOpen = isOpen;
this._menuOpen = isOpen;
this.menu._setClickCatcher(isOpen);
this.menuOpen ? this.onMenuOpen.emit(null) : this.onMenuClose.emit(null);
this._menuOpen ? this.onMenuOpen.emit(null) : this.onMenuClose.emit(null);
}

/**
Expand Down

0 comments on commit 5cfe4c3

Please sign in to comment.