Skip to content

Commit e15f47e

Browse files
Merge pull request #5689 from Pupix:main
PiperOrigin-RevId: 660400219
2 parents 7231e51 + 6df7161 commit e15f47e

File tree

5 files changed

+55
-8
lines changed

5 files changed

+55
-8
lines changed

docs/components/menu.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,8 @@ a sharp 0px border radius.](images/menu/theming.webp)
527527
| `typeaheadDelay` | `typeahead-delay` | `number` | `200` | The max time between the keystrokes of the typeahead menu behavior before it clears the typeahead buffer. |
528528
| `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. |
529529
| `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. |
530+
| `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. |
531+
| `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. |
530532
| `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`. |
531533
| `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. |
532534
| `skipRestoreFocus` | `skip-restore-focus` | `boolean` | `false` | After closing, does not restore focus to the last focused element before the menu was opened. |

menu/demo/demo.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ const collection = new MaterialCollection<KnobTypesToKnobs<StoryKnobs>>(
105105
defaultValue: 0,
106106
ui: numberInput(),
107107
}),
108+
new Knob('noHorizontalFlip', {
109+
defaultValue: false,
110+
ui: boolInput(),
111+
}),
112+
new Knob('noVerticalFlip', {
113+
defaultValue: false,
114+
ui: boolInput(),
115+
}),
108116
new Knob('typeaheadDelay', {
109117
defaultValue: 200,
110118
ui: numberInput(),

menu/demo/stories.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export interface StoryKnobs {
3131
skipRestoreFocus: boolean;
3232
xOffset: number;
3333
yOffset: number;
34+
noVerticalFlip: boolean;
35+
noHorizontalFlip: boolean;
3436
typeaheadDelay: number;
3537
listTabIndex: number;
3638

@@ -122,6 +124,8 @@ const standard: MaterialStoryInit<StoryKnobs> = {
122124
.menuCorner="${knobs.menuCorner!}"
123125
.xOffset=${knobs.xOffset}
124126
.yOffset=${knobs.yOffset}
127+
.noVerticalFlip=${knobs.noVerticalFlip}
128+
.noHorizontalFlip=${knobs.noHorizontalFlip}
125129
.positioning=${knobs.positioning!}
126130
.defaultFocus=${knobs.defaultFocus!}
127131
.skipRestoreFocus=${knobs.skipRestoreFocus}
@@ -131,12 +135,13 @@ const standard: MaterialStoryInit<StoryKnobs> = {
131135
@close-menu=${displayCloseEvent}
132136
@closed=${setButtonAriaExpandedFalse}>
133137
${fruitNames.map(
134-
(name, index) => html` <md-menu-item
135-
id=${index}
136-
.keepOpen=${knobs.keepOpen}
137-
.disabled=${knobs.disabled}>
138-
<div slot="headline">${name}</div>
139-
</md-menu-item>`,
138+
(name, index) =>
139+
html`<md-menu-item
140+
id=${index}
141+
.keepOpen=${knobs.keepOpen}
142+
.disabled=${knobs.disabled}>
143+
<div slot="headline">${name}</div>
144+
</md-menu-item>`,
140145
)}
141146
</md-menu>
142147
</div>
@@ -191,6 +196,8 @@ const linkable: MaterialStoryInit<StoryKnobs> = {
191196
.menuCorner="${knobs.menuCorner!}"
192197
.xOffset=${knobs.xOffset}
193198
.yOffset=${knobs.yOffset}
199+
.noVerticalFlip=${knobs.noVerticalFlip}
200+
.noHorizontalFlip=${knobs.noHorizontalFlip}
194201
.positioning=${knobs.positioning!}
195202
.defaultFocus=${knobs.defaultFocus!}
196203
.skipRestoreFocus=${knobs.skipRestoreFocus}
@@ -327,6 +334,8 @@ const submenu: MaterialStoryInit<StoryKnobs> = {
327334
.menuCorner="${knobs.menuCorner!}"
328335
.xOffset=${knobs.xOffset}
329336
.yOffset=${knobs.yOffset}
337+
.noVerticalFlip=${knobs.noVerticalFlip}
338+
.noHorizontalFlip=${knobs.noHorizontalFlip}
330339
.positioning=${knobs.positioning!}
331340
.defaultFocus=${knobs.defaultFocus!}
332341
.skipRestoreFocus=${knobs.skipRestoreFocus}
@@ -379,6 +388,8 @@ const menuWithoutButton: MaterialStoryInit<StoryKnobs> = {
379388
.menuCorner="${knobs.menuCorner!}"
380389
.xOffset=${knobs.xOffset}
381390
.yOffset=${knobs.yOffset}
391+
.noVerticalFlip=${knobs.noVerticalFlip}
392+
.noHorizontalFlip=${knobs.noHorizontalFlip}
382393
.positioning=${knobs.positioning!}
383394
.defaultFocus=${knobs.defaultFocus!}
384395
.skipRestoreFocus=${knobs.skipRestoreFocus}

menu/internal/controllers/surfacePositionController.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ export interface SurfacePositionTarget extends HTMLElement {
5151
* The configurable options for the surface position controller.
5252
*/
5353
export interface SurfacePositionControllerProperties {
54+
/**
55+
* Disable the `flip` behavior on the block axis of the surface's corner
56+
*/
57+
disableBlockFlip: boolean;
58+
/**
59+
* Disable the `flip` behavior on the inline axis of the surface's corner
60+
*/
61+
disableInlineFlip: boolean;
5462
/**
5563
* The corner of the anchor to align the surface's position.
5664
*/
@@ -172,6 +180,8 @@ export class SurfacePositionController implements ReactiveController {
172180
positioning,
173181
xOffset,
174182
yOffset,
183+
disableBlockFlip,
184+
disableInlineFlip,
175185
repositionStrategy,
176186
} = this.getProperties();
177187
const anchorCorner = anchorCornerRaw.toLowerCase().trim();
@@ -293,7 +303,7 @@ export class SurfacePositionController implements ReactiveController {
293303

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

@@ -335,7 +345,7 @@ export class SurfacePositionController implements ReactiveController {
335345

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

menu/internal/menu.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,18 @@ export abstract class Menu extends LitElement {
171171
* e.g. positive -> down, negative -> up
172172
*/
173173
@property({type: Number, attribute: 'y-offset'}) yOffset = 0;
174+
/**
175+
* Disable the `flip` behavior that usually happens on the horizontal axis
176+
* when the surface would render outside the viewport.
177+
*/
178+
@property({type: Boolean, attribute: 'no-horizontal-flip'}) noHorizontalFlip =
179+
false;
180+
/**
181+
* Disable the `flip` behavior that usually happens on the vertical axis when
182+
* the surface would render outside the viewport.
183+
*/
184+
@property({type: Boolean, attribute: 'no-vertical-flip'}) noVerticalFlip =
185+
false;
174186
/**
175187
* The max time between the keystrokes of the typeahead menu behavior before
176188
* it clears the typeahead buffer.
@@ -183,6 +195,7 @@ export abstract class Menu extends LitElement {
183195
*
184196
* NOTE: This value may not be respected by the menu positioning algorithm
185197
* if the menu would render outisde the viewport.
198+
* Use `no-horizontal-flip` or `no-vertical-flip` to force the usage of the value
186199
*/
187200
@property({attribute: 'anchor-corner'})
188201
anchorCorner: Corner = Corner.END_START;
@@ -192,6 +205,7 @@ export abstract class Menu extends LitElement {
192205
*
193206
* NOTE: This value may not be respected by the menu positioning algorithm
194207
* if the menu would render outisde the viewport.
208+
* Use `no-horizontal-flip` or `no-vertical-flip` to force the usage of the value
195209
*/
196210
@property({attribute: 'menu-corner'}) menuCorner: Corner = Corner.START_START;
197211
/**
@@ -376,6 +390,8 @@ export abstract class Menu extends LitElement {
376390
isOpen: this.open,
377391
xOffset: this.xOffset,
378392
yOffset: this.yOffset,
393+
disableBlockFlip: this.noVerticalFlip,
394+
disableInlineFlip: this.noHorizontalFlip,
379395
onOpen: this.onOpened,
380396
beforeClose: this.beforeClose,
381397
onClose: this.onClosed,

0 commit comments

Comments
 (0)