-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(cdk-experimental/menu): add support for inline menus #20143
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
Conversation
@@ -126,3 +126,19 @@ export class MenuStack { | |||
return this._elements[this._elements.length - 1]; | |||
} | |||
} | |||
|
|||
/** NoopMenuStack is a placeholder MenuStack used for inline menus. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify -- does 'inline' mean it's triggered by some means other than a bar? (Such as a button?) I'd make this clearer in the documentation somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inline menus aren't triggered open at all - they're always open. Think of the list of mailboxes on gmail (inbox, starred, snoozed, ...).
@@ -126,3 +126,19 @@ export class MenuStack { | |||
return this._elements[this._elements.length - 1]; | |||
} | |||
} | |||
|
|||
/** NoopMenuStack is a placeholder MenuStack used for inline menus. */ | |||
export class NoopMenuStack extends MenuStack { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypeScript lets you do implements MenuStack
so you can conform to the same API without actually inheriting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems to work only if all members are public. With private and protected it won't allow it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right, you can use TypeScript keyof
to accomplish this:
https://www.typescriptlang.org/play/#code/MYGwhgzhAECyCmA7ArgZQC5mAa2gbwChpjoAHAJwEsA3MdeaAfUsXvMTBAXQAsB7ACYAKAJT4iJScD6IIfEPAB0IPgHMhAcgAeGkQG4JxAL4FDZZACMQlYNFB8I8UQC5o1PpQH5oJk6fQAnqQMAAqW1sAAgqSUADwAKgB80AC83gDaANLQLNDY8AF8AGbQ8QC6rvFZZT4GBKCQMAByfHykCCgYWLiUALakCr1I6DBhVjbRcR1omDjJhFIqji5uHl4LkiTSsvJKKuoahboGkr5AA
closeInclusive(lastItem: MenuStackItem, focusNext?: FocusNext) {} | ||
closeExclusive(lastItem: MenuStackItem) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these are the old method names
src/cdk-experimental/menu/menu.ts
Outdated
/** Track the Menus making up the open menu stack. */ | ||
_menuStack: MenuStack; | ||
// We provide a default MenuStack implementation in case the menu is an inline menu. | ||
// For Menus part of a MenuBar nested within a MenuPanel this will be overwritten | ||
// to the correct parent MenuStack. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding implementation comments between a JsDoc and a member will break the connection
src/cdk-experimental/menu/menu.ts
Outdated
* Return true if this menu is an inline menu. That is, it exists in isolation apart from a menu | ||
* bar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that it's more that an inline menu doesn't exist in a pop-up rather than being strictly related to a menubar.
src/cdk-experimental/menu/menu.ts
Outdated
@@ -52,6 +51,8 @@ import {getItemPointerEntries} from './item-pointer-entries'; | |||
exportAs: 'cdkMenu', | |||
host: { | |||
'(keydown)': '_handleKeyEvent($event)', | |||
'(focus)': '_focusFirstItem()', | |||
'[tabindex]': '_getTabIndex()', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'[tabindex]': '_getTabIndex()', | |
'[tabindex]': '_isInline() ? 0 : null', |
It would be acceptable to inline the expression here without creating a new method
src/cdk-experimental/menu/menu.ts
Outdated
|
||
/** Set focus to the first menu item if this is an inline menu. */ | ||
_focusFirstItem() { | ||
if (this._isInline()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since focus
doesn't bubble, you could just always call this._keyManager.setFirstItemActive();
without checking if the menu is line since this menu element will only even be focusable when it's inline
4a69426
to
891dcb4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Add the ability to place a menu inline (always visible and not trigered) which is typically used as a navigation menu.
891dcb4
to
9fcb2fb
Compare
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Add the ability to place a menu inline (always visible and not trigered) which is typically used as
a navigation menu.