Skip to content

docs(cdk-experimental/menu): add initial documentation for cdk menu directives #20412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 28, 2020

Conversation

andy9775
Copy link
Contributor

No description provided.

@andy9775 andy9775 requested a review from jelbourn as a code owner August 25, 2020 15:21
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Aug 25, 2020
@andy9775 andy9775 requested a review from teflonwaffles August 25, 2020 15:21
@andy9775
Copy link
Contributor Author

Once approved, a follow up pr to have the actual examples

@jelbourn jelbourn added the target: minor This PR is targeted for the next minor release label Aug 25, 2020
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you break lines at 100 characters?

@@ -0,0 +1,167 @@
The `@angular/cdk-experimental/menu` module provides you with a way to easily create complex menu interfaces with support for:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The `@angular/cdk-experimental/menu` module provides you with a way to easily create complex menu interfaces with support for:
The `@angular/cdk-experimental/menu` module provides directive to help create custom menu interactions based on the [WAI ARIA specification](https://www.w3.org/TR/wai-aria-1.1/).

Comment on lines 3 to 9
- Standalone Menus
- Menubars
- Context Menus
- Inline Menus
- MenuItems
- RadioButtonItems
- CheckboxItems
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would break this into a section called "Supported ARIA roles" and use the role names from the spec, combining with some of the text you have below.

Comment on lines 11 to 9
`@angular/cdk-experimental/menu` can also intelligently predict if a user is attempting to navigate to an open submenu and prevent premature closeouts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move this to its own section named something like "Smart menu aim" that outlines what it does (potentially with a diagram) and a very brief explanation of how it works.

Comment on lines 26 to 28
Keep in mind that there are two important requirements which must be kept in mind when building menus:

First, a triggering component, or a component inside of a `CdkMenu` or `CdkMenuBar`, must have the `cdkMenuItem` directive like so,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Keep in mind that there are two important requirements which must be kept in mind when building menus:
First, a triggering component, or a component inside of a `CdkMenu` or `CdkMenuBar`, must have the `cdkMenuItem` directive like so,
Most menu interactions consist of two parts: a trigger and a menu panel.
#### Triggers
(talk about buttons and menu-bars here)
#### Menu panels
(talk about cdkMenuPanel here)


<!-- TODO inline menu example (gmail buttons?) -->

### Menuitem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Menuitem
### Menu items

(similar for other headers)


<!-- TODO standalone menu example with checkboxes and grouped radios -->

### Accessability
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Accessability
### Accessibility

Comment on lines 166 to 167
[1]: https://www.w3.org/TR/wai-aria-practices-1.1/#menu 'Aria Menubar Pattern'
[2]: https://www.w3.org/TR/wai-aria-practices-1.1/#keyboard-interaction-12 'Aria Menubar Keyboard Interaction'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to get away from using numbered links now and instead using links with names, e.g.

Suggested change
[1]: https://www.w3.org/TR/wai-aria-practices-1.1/#menu 'Aria Menubar Pattern'
[2]: https://www.w3.org/TR/wai-aria-practices-1.1/#keyboard-interaction-12 'Aria Menubar Keyboard Interaction'
[menubar]: https://www.w3.org/TR/wai-aria-practices-1.1/#menu 'Aria Menubar Pattern'
[keyboard]: https://www.w3.org/TR/wai-aria-practices-1.1/#keyboard-interaction-12 'Aria Menubar Keyboard Interaction'

@andy9775
Copy link
Contributor Author

@jelbourn feedback should be addressed

now add the various directives in order to build out your menu. A basic standalone menu consists of
the following directives:

- `cdkMenuItem` - added to the button itself

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which button? (There's talk of multiple buttons here.)


<!-- TODO basic context menu example -->

Context menu triggers may be nested within parent contexts and when a user right clicks, the deepest

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be clearer. 'Nested components can have context menu triggers at each level. When a user right clicks, the menu associated with the deepest component the user is hovering over is opened up.'


### Inline Menus

Inline menus are groups of menu items which typically do not trigger their own menus and the menu

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also be clearer -- emphasize that the menu doesn't 'pop up', but all menu items are displayed from the start.

### Inline Menus

Inline menus are groups of menu items which typically do not trigger their own menus and the menu
items implement some type of on-click behavior. The benefit of using an inline menu over a group of

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'implement some type of on-click behavior' should be clear enough that you can omit it. (You say from the start that these are groups of menu items, which usually have on-click behavior.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During our feedback session some thought that a trigger can open a submenu when placed inline. I want to emphasize that it shouldn't be the case.

```html
<ng-template cdkMenuPanel #panel="cdkMenuPanel">
<div cdkMenu [cdkMenuPanel]="panel">
<button cdkMenuItem [cdkMenuItemTriggered]="closeApp()">Close</button>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be (cdkMenuItemTriggered), instead of [...]? (If not, this is noteworthy, and should be explained -- with a TODO to switch to the regular style.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! It should use parentheses

```

Note however that when the menu is closed and reopened any state is lost. You must subscribe to the
groups `change` output, or to `cdkMenuItemToggled` on each radio item and track changes your self.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you specify which item should be checked to start?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a checked input - I'll add that to the doc.

![menu aim diagram][diagram]

As demonstrated in the diagram above we first track the users mouse movements within a menu. Next,
when a user mouses into a sibling menu item (e.g. Share button) the sibling item asks the Menu Aim

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"user's mouse movements"

user is moving towards the submenu and we shouldn't close out. Finally, as the user mouses into
other sibling triggers, as long as the slope of the current mouse movement is steeper than the
previous, it assumes that the user is moving towards the submenu. Users however may sometimes stop
short in a sibling item after moving towards the submenu therefore the service is intelligent enough

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit of a run-on sentence.

@andy9775
Copy link
Contributor Author

@teflonwaffles feedback should be addressed

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly suggestions for passive voice and brevity here without substantively affecting content or organization

interaction. Further, all directives apply their associated aria roles to the component they are
added to.

### Supported Aria Roles
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Supported Aria Roles
### Supported ARIA Roles

nit: aria is an acronym

Comment on lines 11 to 12
The directives provided by `@angular/cdk-experimental/menu` automatically provide the related roles
for each component they are placed on.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The directives provided by `@angular/cdk-experimental/menu` automatically provide the related roles
for each component they are placed on.
The directives in `@angular/cdk-experimental/menu` set the appropriate roles
on their host element.

tweaks for brevity

Comment on lines 25 to 27
Start by importing the `CdkMenuModule` into the `NgModule` where you want to create menus. You can
now add the various directives in order to build out your menu. A basic standalone menu consists of
the following directives:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Start by importing the `CdkMenuModule` into the `NgModule` where you want to create menus. You can
now add the various directives in order to build out your menu. A basic standalone menu consists of
the following directives:
Import the `CdkMenuModule` into the `NgModule` in which you want to create menus. You can
then apply menu directives to build your custom menu. A typical menu consists of the following directives:

- `cdkMenuItem` - added to each button
- `cdkMenuTriggerFor` - links a trigger button to a menu you intend to open
- `cdkMenuPanel` - wraps the menu and provides a link between the `cdkMenuTriggerFor` and the
`cdkMenu`
- `cdkMenu` - the actual menu you want to open
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would list in the order: trigger, panel, menu, item


#### Triggers

A triggering component must have the `cdkMenuItem` and `cdkMenuTriggerFor` directives like so,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cdkMenuItem isn't supposed to be required for just a regular button

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A trigger does need cdkMenuItem, also if you don't add cdkMenuItem to a regular button keyboard navigation won't work as expected - I'll make that clear.


### Smart Menu Aim

`@angular/cdk-experimental/menu` can also intelligently predict if a user is attempting to navigate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`@angular/cdk-experimental/menu` can also intelligently predict if a user is attempting to navigate
`@angular/cdk-experimental/menu` intelligently predicts when a user intends to navigate

nit: some passive voice, brevity


`@angular/cdk-experimental/menu` can also intelligently predict if a user is attempting to navigate
to an open submenu and prevent premature closeouts. This functionality prevents users from having to
hunt through the open menus in a maze-like fashion in order to get to their destination.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hunt through the open menus in a maze-like fashion in order to get to their destination.
hunt through the open menus in a maze-like fashion to reach their destination.

Comment on lines 174 to 176
By default `cdkMenu` acts as a group for `cdkMenuItemRadio` elements. That is, components marked
with `cdkMenuItemRadio` added as children of a `cdkMenu` will be logically grouped and only a single
component can have the checked state.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
By default `cdkMenu` acts as a group for `cdkMenuItemRadio` elements. That is, components marked
with `cdkMenuItemRadio` added as children of a `cdkMenu` will be logically grouped and only a single
component can have the checked state.
By default `cdkMenu` acts as a group for `cdkMenuItemRadio` elements. Elements
with `cdkMenuItemRadio` added as children of a `cdkMenu` will be logically grouped and only a single
item can have the checked state.

Comment on lines 168 to 146
A `cdkMenuItemRadio` behaves as you would expect a radio button to behave. A use case may be
toggling through more than one state since radio buttons can be grouped together. A component with
the `cdkMenuItemRadio` directive does not need the additional `cdkMenuItem` directive.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A `cdkMenuItemRadio` behaves as you would expect a radio button to behave. A use case may be
toggling through more than one state since radio buttons can be grouped together. A component with
the `cdkMenuItemRadio` directive does not need the additional `cdkMenuItem` directive.
A `cdkMenuItemRadio` is a special type of menuitem that behaves as a radio button. You
can use this type of menuitem for menus with exclusively selectable items.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think leaving A component with the cdkMenuItemRadiodirective does not need the additionalcdkMenuItem directive. is worth it. Thoughts?

Here and for checkbox

Comment on lines 161 to 164
A component with the `cdkMenuItemCheckbox` directive behaves just as you would expect a typical
checkbox to behave. A use case may be toggling an independent setting since it contains a checked
state. A component with the `cdkMenuItemCheckbox` directive does not need the additional
`cdkMenuItem` directive.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A component with the `cdkMenuItemCheckbox` directive behaves just as you would expect a typical
checkbox to behave. A use case may be toggling an independent setting since it contains a checked
state. A component with the `cdkMenuItemCheckbox` directive does not need the additional
`cdkMenuItem` directive.
A `cdkMenuItemCheckbox` is a special type of menuitem that behaves as a checkbox. You
can use this type of menuitem to toggle items on and off.

@andy9775
Copy link
Contributor Author

@jelbourn feedback should be addressed. I also took another run through and changed some passive to active voice so please take a look through again.

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I think this is my last set of comments


The `CdkMenuBar` directive follows the [ARIA menubar][menubar] spec and behaves similar to a desktop
app menubar. It consists of at least one `CdkMenuItem` which triggers a submenu. A menubar can be
layed out horizontally or vertically (defaulting to horizontal). If the style is changed, you must
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
layed out horizontally or vertically (defaulting to horizontal). If the style is changed, you must
layed out horizontally or vertically (defaulting to horizontal). If the layout changes, you must

Comment on lines 74 to 77
The primary difference between a menubar and a standalone menu is the menubar groups together the
triggering components. Therefore, menus in a menubar can be opened/closed when hovering between
their triggers and keyboard navigation listens to left and right arrow buttons which toggles between
the menu items in the menubar.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this bit is strictly necessary, since I think the difference between a menubar and a standalone menu (just a button) is readily apparent.

Comment on lines 83 to 86
A context menu opens when a user right-clicks within some container element. A context is an area of
your application which contains some content where you want to open up a menu. When a user
right-clicks within the context the associated menu opens up next to their cursor - as you would
expect with a typical right click menu.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A context menu opens when a user right-clicks within some container element. A context is an area of
your application which contains some content where you want to open up a menu. When a user
right-clicks within the context the associated menu opens up next to their cursor - as you would
expect with a typical right click menu.
A context menu opens when a user right-clicks within some container element. You can
mark a container element with the `cdkContextMenuTriggerFor`, which behaves like
`cdkMenuTriggerFor` except that it responds to the browser's native `contextmenu` event.
Custom context menus appear next to the cursor, similarly to native context menus.

Comment on lines 90 to 91
Nested container elements can have context menu triggers at each level. When a user right-clicks,
the menu associated with the closest container element opens.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Nested container elements can have context menu triggers at each level. When a user right-clicks,
the menu associated with the closest container element opens.
You can nest context menu container elements. Upon right-click,
the menu associated with the closest container element will open.

#### Menu Item Checkboxes

A `cdkMenuItemCheckbox` is a special type of menuitem that behaves as a checkbox. You can use this
type of menuitem to toggle items on and off. A component with the `cdkMenuItemCheckbox` directive
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type of menuitem to toggle items on and off. A component with the `cdkMenuItemCheckbox` directive
type of menuitem to toggle items on and off. An element with the `cdkMenuItemCheckbox` directive

#### Menu Item Radios

A `cdkMenuItemRadio` is a special type of menuitem that behaves as a radio button. You can use this
type of menuitem for menus with exclusively selectable items. A component with the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type of menuitem for menus with exclusively selectable items. A component with the
type of menuitem for menus with exclusively selectable items. An element with the

Comment on lines 4 to 7
By using `@angular/cdk-experimental/menu` you get all of the expected behaviors following the ARIA
best practices including consideration for left-to-right and right-to-left layouts, and accessible
interaction. Further, all directives apply their associated ARIA roles to the component they are
added to.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
By using `@angular/cdk-experimental/menu` you get all of the expected behaviors following the ARIA
best practices including consideration for left-to-right and right-to-left layouts, and accessible
interaction. Further, all directives apply their associated ARIA roles to the component they are
added to.
By using `@angular/cdk-experimental/menu` you get all of the expected behaviors for an accessible experience, including bidi layout support, keyboard interaction, and focus management. All directives apply their associated ARIA roles to their host element.


### Accessibility

The set of directives defined in `@angular/cdk-experimental/menu` follow accessability best
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The set of directives defined in `@angular/cdk-experimental/menu` follow accessability best
The set of directives defined in `@angular/cdk-experimental/menu` follow accessibility best

practices as defined in the [ARIA spec][menubar]. Specifically, the menus are aware of left-to-right
and right-to-left layouts and opened appropriately. You should however add any necessary CSS styles.
Menu items should always have meaningful labels, whether through text content, `aria-label`, or
`aria-labelledby` Finally, keyboard interaction is supported as defined in the [ARIA menubar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`aria-labelledby` Finally, keyboard interaction is supported as defined in the [ARIA menubar
`aria-labelledby`. Finally, keyboard interaction is supported as defined in the [ARIA menubar

@andy9775
Copy link
Contributor Author

@jelbourn Feedback should be addressed

Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jelbourn jelbourn added action: merge The PR is ready for merge by the caretaker merge safe labels Aug 28, 2020
@jelbourn jelbourn merged commit 4f1238f into angular:master Aug 28, 2020
annieyw pushed a commit to annieyw/components that referenced this pull request Aug 31, 2020
mmalerba pushed a commit to mmalerba/components that referenced this pull request Sep 5, 2020
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants