Skip to content

Commit

Permalink
Merge pull request #5689 from Pupix:main
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 660400219
  • Loading branch information
copybara-github committed Aug 7, 2024
2 parents 7231e51 + 6df7161 commit e15f47e
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docs/components/menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ a sharp 0px border radius.](images/menu/theming.webp)
| `typeaheadDelay` | `typeahead-delay` | `number` | `200` | The max time between the keystrokes of the typeahead menu behavior before it clears the typeahead buffer. |
| `anchorCorner` | `anchor-corner` | `string` | `Corner.END_START` | The corner of the anchor which to align the menu in the standard logical property style of <block>-<inline> e.g. `'end-start'`.<br>NOTE: This value may not be respected by the menu positioning algorithm if the menu would render outisde the viewport. |
| `menuCorner` | `menu-corner` | `string` | `Corner.START_START` | The corner of the menu which to align the anchor in the standard logical property style of <block>-<inline> e.g. `'start-start'`.<br>NOTE: This value may not be respected by the menu positioning algorithm if the menu would render outisde the viewport. |
| `noHorizontalFlip` | `no-horizontal-flip` | `boolean` | `false` | Disable the `flip` behavior that usually happens on the horizontal axis when the surface would render outside the viewport. |
| `noVerticalFlip` | `no-vertical-flip` | `boolean` | `false` | Disable the `flip` behavior that usually happens on the vertical axis when the surface would render outside the viewport. |
| `stayOpenOnOutsideClick` | `stay-open-on-outside-click` | `boolean` | `false` | Keeps the user clicks outside the menu.<br>NOTE: clicking outside may still cause focusout to close the menu so see `stayOpenOnFocusout`. |
| `stayOpenOnFocusout` | `stay-open-on-focusout` | `boolean` | `false` | Keeps the menu open when focus leaves the menu's composed subtree.<br>NOTE: Focusout behavior will stop propagation of the focusout event. Set this property to true to opt-out of menu's focusout handling altogether. |
| `skipRestoreFocus` | `skip-restore-focus` | `boolean` | `false` | After closing, does not restore focus to the last focused element before the menu was opened. |
Expand Down
8 changes: 8 additions & 0 deletions menu/demo/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ const collection = new MaterialCollection<KnobTypesToKnobs<StoryKnobs>>(
defaultValue: 0,
ui: numberInput(),
}),
new Knob('noHorizontalFlip', {
defaultValue: false,
ui: boolInput(),
}),
new Knob('noVerticalFlip', {
defaultValue: false,
ui: boolInput(),
}),
new Knob('typeaheadDelay', {
defaultValue: 200,
ui: numberInput(),
Expand Down
23 changes: 17 additions & 6 deletions menu/demo/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export interface StoryKnobs {
skipRestoreFocus: boolean;
xOffset: number;
yOffset: number;
noVerticalFlip: boolean;
noHorizontalFlip: boolean;
typeaheadDelay: number;
listTabIndex: number;

Expand Down Expand Up @@ -122,6 +124,8 @@ const standard: MaterialStoryInit<StoryKnobs> = {
.menuCorner="${knobs.menuCorner!}"
.xOffset=${knobs.xOffset}
.yOffset=${knobs.yOffset}
.noVerticalFlip=${knobs.noVerticalFlip}
.noHorizontalFlip=${knobs.noHorizontalFlip}
.positioning=${knobs.positioning!}
.defaultFocus=${knobs.defaultFocus!}
.skipRestoreFocus=${knobs.skipRestoreFocus}
Expand All @@ -131,12 +135,13 @@ const standard: MaterialStoryInit<StoryKnobs> = {
@close-menu=${displayCloseEvent}
@closed=${setButtonAriaExpandedFalse}>
${fruitNames.map(
(name, index) => html` <md-menu-item
id=${index}
.keepOpen=${knobs.keepOpen}
.disabled=${knobs.disabled}>
<div slot="headline">${name}</div>
</md-menu-item>`,
(name, index) =>
html`<md-menu-item
id=${index}
.keepOpen=${knobs.keepOpen}
.disabled=${knobs.disabled}>
<div slot="headline">${name}</div>
</md-menu-item>`,
)}
</md-menu>
</div>
Expand Down Expand Up @@ -191,6 +196,8 @@ const linkable: MaterialStoryInit<StoryKnobs> = {
.menuCorner="${knobs.menuCorner!}"
.xOffset=${knobs.xOffset}
.yOffset=${knobs.yOffset}
.noVerticalFlip=${knobs.noVerticalFlip}
.noHorizontalFlip=${knobs.noHorizontalFlip}
.positioning=${knobs.positioning!}
.defaultFocus=${knobs.defaultFocus!}
.skipRestoreFocus=${knobs.skipRestoreFocus}
Expand Down Expand Up @@ -327,6 +334,8 @@ const submenu: MaterialStoryInit<StoryKnobs> = {
.menuCorner="${knobs.menuCorner!}"
.xOffset=${knobs.xOffset}
.yOffset=${knobs.yOffset}
.noVerticalFlip=${knobs.noVerticalFlip}
.noHorizontalFlip=${knobs.noHorizontalFlip}
.positioning=${knobs.positioning!}
.defaultFocus=${knobs.defaultFocus!}
.skipRestoreFocus=${knobs.skipRestoreFocus}
Expand Down Expand Up @@ -379,6 +388,8 @@ const menuWithoutButton: MaterialStoryInit<StoryKnobs> = {
.menuCorner="${knobs.menuCorner!}"
.xOffset=${knobs.xOffset}
.yOffset=${knobs.yOffset}
.noVerticalFlip=${knobs.noVerticalFlip}
.noHorizontalFlip=${knobs.noHorizontalFlip}
.positioning=${knobs.positioning!}
.defaultFocus=${knobs.defaultFocus!}
.skipRestoreFocus=${knobs.skipRestoreFocus}
Expand Down
14 changes: 12 additions & 2 deletions menu/internal/controllers/surfacePositionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ export interface SurfacePositionTarget extends HTMLElement {
* The configurable options for the surface position controller.
*/
export interface SurfacePositionControllerProperties {
/**
* Disable the `flip` behavior on the block axis of the surface's corner
*/
disableBlockFlip: boolean;
/**
* Disable the `flip` behavior on the inline axis of the surface's corner
*/
disableInlineFlip: boolean;
/**
* The corner of the anchor to align the surface's position.
*/
Expand Down Expand Up @@ -172,6 +180,8 @@ export class SurfacePositionController implements ReactiveController {
positioning,
xOffset,
yOffset,
disableBlockFlip,
disableInlineFlip,
repositionStrategy,
} = this.getProperties();
const anchorCorner = anchorCornerRaw.toLowerCase().trim();
Expand Down Expand Up @@ -293,7 +303,7 @@ export class SurfacePositionController implements ReactiveController {

// If the surface should be out of bounds in the block direction, flip the
// surface and anchor corner block values and recalculate
if (blockOutOfBoundsCorrection) {
if (blockOutOfBoundsCorrection && !disableBlockFlip) {
const flippedSurfaceBlock = surfaceBlock === 'start' ? 'end' : 'start';
const flippedAnchorBlock = anchorBlock === 'start' ? 'end' : 'start';

Expand Down Expand Up @@ -335,7 +345,7 @@ export class SurfacePositionController implements ReactiveController {

// If the surface should be out of bounds in the inline direction, flip the
// surface and anchor corner inline values and recalculate
if (inlineOutOfBoundsCorrection) {
if (inlineOutOfBoundsCorrection && !disableInlineFlip) {
const flippedSurfaceInline = surfaceInline === 'start' ? 'end' : 'start';
const flippedAnchorInline = anchorInline === 'start' ? 'end' : 'start';

Expand Down
16 changes: 16 additions & 0 deletions menu/internal/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,18 @@ export abstract class Menu extends LitElement {
* e.g. positive -> down, negative -> up
*/
@property({type: Number, attribute: 'y-offset'}) yOffset = 0;
/**
* Disable the `flip` behavior that usually happens on the horizontal axis
* when the surface would render outside the viewport.
*/
@property({type: Boolean, attribute: 'no-horizontal-flip'}) noHorizontalFlip =
false;
/**
* Disable the `flip` behavior that usually happens on the vertical axis when
* the surface would render outside the viewport.
*/
@property({type: Boolean, attribute: 'no-vertical-flip'}) noVerticalFlip =
false;
/**
* The max time between the keystrokes of the typeahead menu behavior before
* it clears the typeahead buffer.
Expand All @@ -183,6 +195,7 @@ export abstract class Menu extends LitElement {
*
* NOTE: This value may not be respected by the menu positioning algorithm
* if the menu would render outisde the viewport.
* Use `no-horizontal-flip` or `no-vertical-flip` to force the usage of the value
*/
@property({attribute: 'anchor-corner'})
anchorCorner: Corner = Corner.END_START;
Expand All @@ -192,6 +205,7 @@ export abstract class Menu extends LitElement {
*
* NOTE: This value may not be respected by the menu positioning algorithm
* if the menu would render outisde the viewport.
* Use `no-horizontal-flip` or `no-vertical-flip` to force the usage of the value
*/
@property({attribute: 'menu-corner'}) menuCorner: Corner = Corner.START_START;
/**
Expand Down Expand Up @@ -376,6 +390,8 @@ export abstract class Menu extends LitElement {
isOpen: this.open,
xOffset: this.xOffset,
yOffset: this.yOffset,
disableBlockFlip: this.noVerticalFlip,
disableInlineFlip: this.noHorizontalFlip,
onOpen: this.onOpened,
beforeClose: this.beforeClose,
onClose: this.onClosed,
Expand Down

0 comments on commit e15f47e

Please sign in to comment.