@ionic/core 7.4.3-dev.11696273737.1ba31223 → 7.4.3-dev.11696355997.1d94070b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/components/index4.js +11 -0
  2. package/components/ion-menu.js +12 -0
  3. package/components/ion-segment.js +35 -23
  4. package/dist/cjs/{index-d90b29dd.js → index-5121bb90.js} +11 -0
  5. package/dist/cjs/index.cjs.js +1 -1
  6. package/dist/cjs/ion-menu_3.cjs.entry.js +15 -4
  7. package/dist/cjs/ion-segment_2.cjs.entry.js +35 -24
  8. package/dist/collection/components/menu/menu.js +12 -0
  9. package/dist/collection/components/segment/segment.js +35 -23
  10. package/dist/collection/components/segment/test/scrollable/segment.e2e.js +53 -1
  11. package/dist/collection/utils/menu-controller/index.js +11 -0
  12. package/dist/docs.json +1 -1
  13. package/dist/esm/{index-39b3eab6.js → index-61bddc90.js} +11 -0
  14. package/dist/esm/index.js +1 -1
  15. package/dist/esm/ion-menu_3.entry.js +13 -2
  16. package/dist/esm/ion-segment_2.entry.js +35 -24
  17. package/dist/esm-es5/{index-39b3eab6.js → index-61bddc90.js} +1 -1
  18. package/dist/esm-es5/index.js +1 -1
  19. package/dist/esm-es5/ion-menu_3.entry.js +1 -1
  20. package/dist/esm-es5/ion-segment_2.entry.js +1 -1
  21. package/dist/ionic/index.esm.js +1 -1
  22. package/dist/ionic/ionic.esm.js +1 -1
  23. package/dist/ionic/p-155dfdda.entry.js +4 -0
  24. package/dist/ionic/p-40e16caa.system.entry.js +4 -0
  25. package/dist/ionic/p-6edbc09b.system.js +1 -1
  26. package/dist/ionic/{p-233cafdf.system.js → p-b098f738.system.js} +1 -1
  27. package/dist/ionic/p-b95fd3c6.entry.js +4 -0
  28. package/dist/ionic/{p-43252033.system.js → p-d4cea1ba.system.js} +1 -1
  29. package/dist/ionic/p-f1a71e75.system.entry.js +4 -0
  30. package/dist/ionic/p-f978ccd1.js +4 -0
  31. package/dist/types/components/menu/menu-interface.d.ts +1 -0
  32. package/dist/types/components/segment/segment.d.ts +1 -0
  33. package/dist/types/utils/menu-controller/index.d.ts +1 -0
  34. package/hydrate/index.js +56 -23
  35. package/package.json +1 -1
  36. package/dist/collection/components/menu/test/multiple/menu.e2e.js +0 -36
  37. package/dist/ionic/p-13a7b105.entry.js +0 -4
  38. package/dist/ionic/p-55b99166.entry.js +0 -4
  39. package/dist/ionic/p-7e994a60.js +0 -4
  40. package/dist/ionic/p-b5637aeb.system.entry.js +0 -4
  41. package/dist/ionic/p-f7d61a1c.system.entry.js +0 -4
@@ -203,6 +203,9 @@ const createMenuController = () => {
203
203
  };
204
204
  const _register = (menu) => {
205
205
  if (menus.indexOf(menu) < 0) {
206
+ if (!menu.disabled) {
207
+ _setActiveMenu(menu);
208
+ }
206
209
  menus.push(menu);
207
210
  }
208
211
  };
@@ -212,6 +215,13 @@ const createMenuController = () => {
212
215
  menus.splice(index, 1);
213
216
  }
214
217
  };
218
+ const _setActiveMenu = (menu) => {
219
+ // if this menu should be enabled
220
+ // then find all the other menus on this same side
221
+ // and automatically disable other same side menus
222
+ const side = menu.side;
223
+ menus.filter((m) => m.side === side && m !== menu).forEach((m) => (m.disabled = true));
224
+ };
215
225
  const _setOpen = async (menu, shouldOpen, animated) => {
216
226
  if (isAnimatingSync()) {
217
227
  return false;
@@ -283,6 +293,7 @@ const createMenuController = () => {
283
293
  _register,
284
294
  _unregister,
285
295
  _setOpen,
296
+ _setActiveMenu,
286
297
  };
287
298
  };
288
299
  const menuController = /*@__PURE__*/ createMenuController();
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { proxyCustomElement, HTMLElement, createEvent, Build, h, Host } from '@stencil/core/internal/client';
5
5
  import { g as getTimeGivenProgression } from './cubic-bezier.js';
6
+ import { d as doc } from './index5.js';
6
7
  import { G as GESTURE_CONTROLLER } from './gesture-controller.js';
7
8
  import { o as isEndSide, i as inheritAriaAttributes, p as assert, m as clamp } from './helpers.js';
8
9
  import { m as menuController } from './index4.js';
@@ -548,6 +549,17 @@ const Menu = /*@__PURE__*/ proxyCustomElement(class Menu extends HTMLElement {
548
549
  // close if this menu is open, and should not be enabled
549
550
  this.forceClosing();
550
551
  }
552
+ if (doc === null || doc === void 0 ? void 0 : doc.contains(this.el)) {
553
+ /**
554
+ * Only set the active menu if the menu element is
555
+ * present in the DOM. Otherwise if it was destructively
556
+ * re-hydrated (through Angular Universal), then ignore
557
+ * setting the removed node as the active menu.
558
+ */
559
+ if (!this.disabled) {
560
+ menuController._setActiveMenu(this);
561
+ }
562
+ }
551
563
  assert(!this.isAnimating, 'can not be animating');
552
564
  }
553
565
  forceClosing() {
@@ -2,6 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { proxyCustomElement, HTMLElement, createEvent, writeTask, h, Host } from '@stencil/core/internal/client';
5
+ import { r as raf } from './helpers.js';
5
6
  import { i as isRTL } from './dir.js';
6
7
  import { c as createColorClasses, h as hostContext } from './theme.js';
7
8
  import { b as getIonMode } from './ionic-global.js';
@@ -86,29 +87,7 @@ const Segment = /*@__PURE__*/ proxyCustomElement(class Segment extends HTMLEleme
86
87
  * Used by `ion-segment-button` to determine if the button should be checked.
87
88
  */
88
89
  this.ionSelect.emit({ value });
89
- if (this.scrollable) {
90
- const buttons = this.getButtons();
91
- const activeButton = buttons.find((button) => button.value === value);
92
- if (activeButton !== undefined) {
93
- /**
94
- * Scrollable segment buttons should be
95
- * centered within the view including
96
- * buttons that are partially offscreen.
97
- */
98
- activeButton.scrollIntoView({
99
- behavior: 'smooth',
100
- inline: 'center',
101
- /**
102
- * Segment should scroll on the
103
- * horizontal axis. `block: 'nearest'`
104
- * ensures that the vertical axis
105
- * does not scroll if the segment
106
- * as a whole is already in view.
107
- */
108
- block: 'nearest',
109
- });
110
- }
111
- }
90
+ this.scrollActiveButtonIntoView();
112
91
  }
113
92
  disabledChanged() {
114
93
  this.gestureChanged();
@@ -130,6 +109,13 @@ const Segment = /*@__PURE__*/ proxyCustomElement(class Segment extends HTMLEleme
130
109
  }
131
110
  async componentDidLoad() {
132
111
  this.setCheckedClasses();
112
+ /**
113
+ * We need to wait for the buttons to all be rendered
114
+ * before we can scroll.
115
+ */
116
+ raf(() => {
117
+ this.scrollActiveButtonIntoView();
118
+ });
133
119
  this.gesture = (await import('./index3.js')).createGesture({
134
120
  el: this.el,
135
121
  gestureName: 'segment',
@@ -258,6 +244,32 @@ const Segment = /*@__PURE__*/ proxyCustomElement(class Segment extends HTMLEleme
258
244
  buttons[next].classList.add('segment-button-after-checked');
259
245
  }
260
246
  }
247
+ scrollActiveButtonIntoView() {
248
+ const { scrollable, value } = this;
249
+ if (scrollable) {
250
+ const buttons = this.getButtons();
251
+ const activeButton = buttons.find((button) => button.value === value);
252
+ if (activeButton !== undefined) {
253
+ /**
254
+ * Scrollable segment buttons should be
255
+ * centered within the view including
256
+ * buttons that are partially offscreen.
257
+ */
258
+ activeButton.scrollIntoView({
259
+ behavior: 'smooth',
260
+ inline: 'center',
261
+ /**
262
+ * Segment should scroll on the
263
+ * horizontal axis. `block: 'nearest'`
264
+ * ensures that the vertical axis
265
+ * does not scroll if the segment
266
+ * as a whole is already in view.
267
+ */
268
+ block: 'nearest',
269
+ });
270
+ }
271
+ }
272
+ }
261
273
  setNextIndex(detail, isEnd = false) {
262
274
  const rtl = isRTL(this.el);
263
275
  const activated = this.activated;
@@ -205,6 +205,9 @@ const createMenuController = () => {
205
205
  };
206
206
  const _register = (menu) => {
207
207
  if (menus.indexOf(menu) < 0) {
208
+ if (!menu.disabled) {
209
+ _setActiveMenu(menu);
210
+ }
208
211
  menus.push(menu);
209
212
  }
210
213
  };
@@ -214,6 +217,13 @@ const createMenuController = () => {
214
217
  menus.splice(index, 1);
215
218
  }
216
219
  };
220
+ const _setActiveMenu = (menu) => {
221
+ // if this menu should be enabled
222
+ // then find all the other menus on this same side
223
+ // and automatically disable other same side menus
224
+ const side = menu.side;
225
+ menus.filter((m) => m.side === side && m !== menu).forEach((m) => (m.disabled = true));
226
+ };
217
227
  const _setOpen = async (menu, shouldOpen, animated) => {
218
228
  if (isAnimatingSync()) {
219
229
  return false;
@@ -285,6 +295,7 @@ const createMenuController = () => {
285
295
  _register,
286
296
  _unregister,
287
297
  _setOpen,
298
+ _setActiveMenu,
288
299
  };
289
300
  };
290
301
  const menuController = /*@__PURE__*/ createMenuController();
@@ -14,7 +14,7 @@ const index$1 = require('./index-0ee995e4.js');
14
14
  const ionicGlobal = require('./ionic-global-14a0604b.js');
15
15
  const helpers = require('./helpers-ea4ccbcb.js');
16
16
  const config = require('./config-d5882735.js');
17
- const index$2 = require('./index-d90b29dd.js');
17
+ const index$2 = require('./index-5121bb90.js');
18
18
  const overlays = require('./overlays-d3a13e61.js');
19
19
  require('./index-306a7476.js');
20
20
  require('./index-6f887430.js');
@@ -7,16 +7,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
7
7
 
8
8
  const index = require('./index-6f887430.js');
9
9
  const cubicBezier = require('./cubic-bezier-6b9222ad.js');
10
+ const index$2 = require('./index-306a7476.js');
10
11
  const gestureController = require('./gesture-controller-b46721be.js');
11
12
  const helpers = require('./helpers-ea4ccbcb.js');
12
- const index$1 = require('./index-d90b29dd.js');
13
+ const index$1 = require('./index-5121bb90.js');
13
14
  const overlays = require('./overlays-d3a13e61.js');
14
15
  const ionicGlobal = require('./ionic-global-14a0604b.js');
15
16
  const theme = require('./theme-fbc56b3b.js');
16
- const index$2 = require('./index-d8d1fc0b.js');
17
+ const index$3 = require('./index-d8d1fc0b.js');
17
18
  require('./hardware-back-button-b67c8e75.js');
18
19
  require('./animation-2bb33618.js');
19
- require('./index-306a7476.js');
20
20
  require('./framework-delegate-c0873a6f.js');
21
21
  require('./index-cc7dfb7c.js');
22
22
 
@@ -553,6 +553,17 @@ const Menu = class {
553
553
  // close if this menu is open, and should not be enabled
554
554
  this.forceClosing();
555
555
  }
556
+ if (index$2.doc === null || index$2.doc === void 0 ? void 0 : index$2.doc.contains(this.el)) {
557
+ /**
558
+ * Only set the active menu if the menu element is
559
+ * present in the DOM. Otherwise if it was destructively
560
+ * re-hydrated (through Angular Universal), then ignore
561
+ * setting the removed node as the active menu.
562
+ */
563
+ if (!this.disabled) {
564
+ index$1.menuController._setActiveMenu(this);
565
+ }
566
+ }
556
567
  helpers.assert(!this.isAnimating, 'can not be animating');
557
568
  }
558
569
  forceClosing() {
@@ -636,7 +647,7 @@ const MenuButton = class {
636
647
  render() {
637
648
  const { color, disabled, inheritedAttributes } = this;
638
649
  const mode = ionicGlobal.getIonMode(this);
639
- const menuIcon = ionicGlobal.config.get('menuIcon', mode === 'ios' ? index$2.menuOutline : index$2.menuSharp);
650
+ const menuIcon = ionicGlobal.config.get('menuIcon', mode === 'ios' ? index$3.menuOutline : index$3.menuSharp);
640
651
  const hidden = this.autoHide && !this.visible;
641
652
  const attrs = {
642
653
  type: this.type,
@@ -6,10 +6,10 @@
6
6
  Object.defineProperty(exports, '__esModule', { value: true });
7
7
 
8
8
  const index = require('./index-6f887430.js');
9
+ const helpers = require('./helpers-ea4ccbcb.js');
9
10
  const dir = require('./dir-f1e0ca26.js');
10
11
  const theme = require('./theme-fbc56b3b.js');
11
12
  const ionicGlobal = require('./ionic-global-14a0604b.js');
12
- const helpers = require('./helpers-ea4ccbcb.js');
13
13
 
14
14
  const segmentIosCss = ":host{--ripple-color:currentColor;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:grid;grid-auto-columns:1fr;position:relative;-ms-flex-align:stretch;align-items:stretch;-ms-flex-pack:center;justify-content:center;width:100%;background:var(--background);font-family:var(--ion-font-family, inherit);text-align:center;contain:paint;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host(.segment-scrollable){-ms-flex-pack:start;justify-content:start;width:auto;overflow-x:auto;grid-auto-columns:minmax(-webkit-min-content, 1fr);grid-auto-columns:minmax(min-content, 1fr)}:host(.segment-scrollable::-webkit-scrollbar){display:none}:host{--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.065);border-radius:8px;overflow:hidden;z-index:0}:host(.ion-color){background:rgba(var(--ion-color-base-rgb), 0.065)}:host(.in-toolbar){-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;width:auto}:host(.in-toolbar:not(.ion-color)){background:var(--ion-toolbar-segment-background, var(--background))}:host(.in-toolbar-color:not(.ion-color)){background:rgba(var(--ion-color-contrast-rgb), 0.11)}";
15
15
 
@@ -89,29 +89,7 @@ const Segment = class {
89
89
  * Used by `ion-segment-button` to determine if the button should be checked.
90
90
  */
91
91
  this.ionSelect.emit({ value });
92
- if (this.scrollable) {
93
- const buttons = this.getButtons();
94
- const activeButton = buttons.find((button) => button.value === value);
95
- if (activeButton !== undefined) {
96
- /**
97
- * Scrollable segment buttons should be
98
- * centered within the view including
99
- * buttons that are partially offscreen.
100
- */
101
- activeButton.scrollIntoView({
102
- behavior: 'smooth',
103
- inline: 'center',
104
- /**
105
- * Segment should scroll on the
106
- * horizontal axis. `block: 'nearest'`
107
- * ensures that the vertical axis
108
- * does not scroll if the segment
109
- * as a whole is already in view.
110
- */
111
- block: 'nearest',
112
- });
113
- }
114
- }
92
+ this.scrollActiveButtonIntoView();
115
93
  }
116
94
  disabledChanged() {
117
95
  this.gestureChanged();
@@ -133,6 +111,13 @@ const Segment = class {
133
111
  }
134
112
  async componentDidLoad() {
135
113
  this.setCheckedClasses();
114
+ /**
115
+ * We need to wait for the buttons to all be rendered
116
+ * before we can scroll.
117
+ */
118
+ helpers.raf(() => {
119
+ this.scrollActiveButtonIntoView();
120
+ });
136
121
  this.gesture = (await Promise.resolve().then(function () { return require('./index-0ee995e4.js'); })).createGesture({
137
122
  el: this.el,
138
123
  gestureName: 'segment',
@@ -261,6 +246,32 @@ const Segment = class {
261
246
  buttons[next].classList.add('segment-button-after-checked');
262
247
  }
263
248
  }
249
+ scrollActiveButtonIntoView() {
250
+ const { scrollable, value } = this;
251
+ if (scrollable) {
252
+ const buttons = this.getButtons();
253
+ const activeButton = buttons.find((button) => button.value === value);
254
+ if (activeButton !== undefined) {
255
+ /**
256
+ * Scrollable segment buttons should be
257
+ * centered within the view including
258
+ * buttons that are partially offscreen.
259
+ */
260
+ activeButton.scrollIntoView({
261
+ behavior: 'smooth',
262
+ inline: 'center',
263
+ /**
264
+ * Segment should scroll on the
265
+ * horizontal axis. `block: 'nearest'`
266
+ * ensures that the vertical axis
267
+ * does not scroll if the segment
268
+ * as a whole is already in view.
269
+ */
270
+ block: 'nearest',
271
+ });
272
+ }
273
+ }
274
+ }
264
275
  setNextIndex(detail, isEnd = false) {
265
276
  const rtl = dir.isRTL(this.el);
266
277
  const activated = this.activated;
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { Build, Host, h } from "@stencil/core";
5
5
  import { getTimeGivenProgression } from "../../utils/animation/cubic-bezier";
6
+ import { doc } from "../../utils/browser/index";
6
7
  import { GESTURE_CONTROLLER } from "../../utils/gesture/index";
7
8
  import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from "../../utils/helpers";
8
9
  import { menuController } from "../../utils/menu-controller/index";
@@ -539,6 +540,17 @@ export class Menu {
539
540
  // close if this menu is open, and should not be enabled
540
541
  this.forceClosing();
541
542
  }
543
+ if (doc === null || doc === void 0 ? void 0 : doc.contains(this.el)) {
544
+ /**
545
+ * Only set the active menu if the menu element is
546
+ * present in the DOM. Otherwise if it was destructively
547
+ * re-hydrated (through Angular Universal), then ignore
548
+ * setting the removed node as the active menu.
549
+ */
550
+ if (!this.disabled) {
551
+ menuController._setActiveMenu(this);
552
+ }
553
+ }
542
554
  assert(!this.isAnimating, 'can not be animating');
543
555
  }
544
556
  forceClosing() {
@@ -2,6 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { Host, h, writeTask } from "@stencil/core";
5
+ import { raf } from "../../utils/helpers";
5
6
  import { isRTL } from "../../utils/rtl/index";
6
7
  import { createColorClasses, hostContext } from "../../utils/theme";
7
8
  import { getIonMode } from "../../global/ionic-global";
@@ -78,29 +79,7 @@ export class Segment {
78
79
  * Used by `ion-segment-button` to determine if the button should be checked.
79
80
  */
80
81
  this.ionSelect.emit({ value });
81
- if (this.scrollable) {
82
- const buttons = this.getButtons();
83
- const activeButton = buttons.find((button) => button.value === value);
84
- if (activeButton !== undefined) {
85
- /**
86
- * Scrollable segment buttons should be
87
- * centered within the view including
88
- * buttons that are partially offscreen.
89
- */
90
- activeButton.scrollIntoView({
91
- behavior: 'smooth',
92
- inline: 'center',
93
- /**
94
- * Segment should scroll on the
95
- * horizontal axis. `block: 'nearest'`
96
- * ensures that the vertical axis
97
- * does not scroll if the segment
98
- * as a whole is already in view.
99
- */
100
- block: 'nearest',
101
- });
102
- }
103
- }
82
+ this.scrollActiveButtonIntoView();
104
83
  }
105
84
  disabledChanged() {
106
85
  this.gestureChanged();
@@ -122,6 +101,13 @@ export class Segment {
122
101
  }
123
102
  async componentDidLoad() {
124
103
  this.setCheckedClasses();
104
+ /**
105
+ * We need to wait for the buttons to all be rendered
106
+ * before we can scroll.
107
+ */
108
+ raf(() => {
109
+ this.scrollActiveButtonIntoView();
110
+ });
125
111
  this.gesture = (await import('../../utils/gesture')).createGesture({
126
112
  el: this.el,
127
113
  gestureName: 'segment',
@@ -250,6 +236,32 @@ export class Segment {
250
236
  buttons[next].classList.add('segment-button-after-checked');
251
237
  }
252
238
  }
239
+ scrollActiveButtonIntoView() {
240
+ const { scrollable, value } = this;
241
+ if (scrollable) {
242
+ const buttons = this.getButtons();
243
+ const activeButton = buttons.find((button) => button.value === value);
244
+ if (activeButton !== undefined) {
245
+ /**
246
+ * Scrollable segment buttons should be
247
+ * centered within the view including
248
+ * buttons that are partially offscreen.
249
+ */
250
+ activeButton.scrollIntoView({
251
+ behavior: 'smooth',
252
+ inline: 'center',
253
+ /**
254
+ * Segment should scroll on the
255
+ * horizontal axis. `block: 'nearest'`
256
+ * ensures that the vertical axis
257
+ * does not scroll if the segment
258
+ * as a whole is already in view.
259
+ */
260
+ block: 'nearest',
261
+ });
262
+ }
263
+ }
264
+ }
253
265
  setNextIndex(detail, isEnd = false) {
254
266
  const rtl = isRTL(this.el);
255
267
  const activated = this.activated;
@@ -4,7 +4,7 @@
4
4
  import { expect } from "@playwright/test";
5
5
  import { configs, test } from "../../../../utils/test/playwright/index";
6
6
  configs().forEach(({ title, screenshot, config }) => {
7
- test.describe(title('segment: scrollable'), () => {
7
+ test.describe(title('segment: scrollable (rendering)'), () => {
8
8
  test('should not have visual regressions', async ({ page }) => {
9
9
  await page.setContent(`
10
10
  <ion-segment scrollable="true" value="2">
@@ -42,3 +42,55 @@ configs().forEach(({ title, screenshot, config }) => {
42
42
  });
43
43
  });
44
44
  });
45
+ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
46
+ test.describe(title('segment: scrollable (functionality)'), () => {
47
+ test('should scroll active button into view when value is already set', async ({ page }) => {
48
+ await page.setContent(`
49
+ <ion-segment scrollable="true" value="8">
50
+ <ion-segment-button value="1">
51
+ <ion-label>First</ion-label>
52
+ </ion-segment-button>
53
+ <ion-segment-button value="2">
54
+ <ion-label>Second</ion-label>
55
+ </ion-segment-button>
56
+ <ion-segment-button value="3">
57
+ <ion-label>Third</ion-label>
58
+ </ion-segment-button>
59
+ <ion-segment-button value="4">
60
+ <ion-label>Fourth</ion-label>
61
+ </ion-segment-button>
62
+ <ion-segment-button value="5">
63
+ <ion-label>Fifth</ion-label>
64
+ </ion-segment-button>
65
+ <ion-segment-button value="6">
66
+ <ion-label>Sixth</ion-label>
67
+ </ion-segment-button>
68
+ <ion-segment-button value="7">
69
+ <ion-label>Seventh</ion-label>
70
+ </ion-segment-button>
71
+ <ion-segment-button id="activeButton" value="8">
72
+ <ion-label>Eighth</ion-label>
73
+ </ion-segment-button>
74
+ <ion-segment-button value="9">
75
+ <ion-label>Ninth</ion-label>
76
+ </ion-segment-button>
77
+ </ion-segment>
78
+ `, config);
79
+ const activeButton = page.locator('#activeButton');
80
+ // wait for segment to scroll, which is done in a raf
81
+ await page.waitForTimeout(500);
82
+ /**
83
+ * We can't use toBeVisible() here because it returns true
84
+ * even if the element is outside the viewport.
85
+ */
86
+ const box = await activeButton.boundingBox();
87
+ const viewport = page.viewportSize();
88
+ let isInViewport = false;
89
+ if (box && viewport) {
90
+ isInViewport =
91
+ box.x >= 0 && box.y >= 0 && box.x + box.width <= viewport.width && box.y + box.height <= viewport.height;
92
+ }
93
+ expect(isInViewport).toBe(true);
94
+ });
95
+ });
96
+ });
@@ -115,6 +115,9 @@ const createMenuController = () => {
115
115
  };
116
116
  const _register = (menu) => {
117
117
  if (menus.indexOf(menu) < 0) {
118
+ if (!menu.disabled) {
119
+ _setActiveMenu(menu);
120
+ }
118
121
  menus.push(menu);
119
122
  }
120
123
  };
@@ -124,6 +127,13 @@ const createMenuController = () => {
124
127
  menus.splice(index, 1);
125
128
  }
126
129
  };
130
+ const _setActiveMenu = (menu) => {
131
+ // if this menu should be enabled
132
+ // then find all the other menus on this same side
133
+ // and automatically disable other same side menus
134
+ const side = menu.side;
135
+ menus.filter((m) => m.side === side && m !== menu).forEach((m) => (m.disabled = true));
136
+ };
127
137
  const _setOpen = async (menu, shouldOpen, animated) => {
128
138
  if (isAnimatingSync()) {
129
139
  return false;
@@ -195,6 +205,7 @@ const createMenuController = () => {
195
205
  _register,
196
206
  _unregister,
197
207
  _setOpen,
208
+ _setActiveMenu,
198
209
  };
199
210
  };
200
211
  export const menuController = /*@__PURE__*/ createMenuController();
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2023-10-02T19:12:01",
2
+ "timestamp": "2023-10-03T18:02:07",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.3.0",
@@ -203,6 +203,9 @@ const createMenuController = () => {
203
203
  };
204
204
  const _register = (menu) => {
205
205
  if (menus.indexOf(menu) < 0) {
206
+ if (!menu.disabled) {
207
+ _setActiveMenu(menu);
208
+ }
206
209
  menus.push(menu);
207
210
  }
208
211
  };
@@ -212,6 +215,13 @@ const createMenuController = () => {
212
215
  menus.splice(index, 1);
213
216
  }
214
217
  };
218
+ const _setActiveMenu = (menu) => {
219
+ // if this menu should be enabled
220
+ // then find all the other menus on this same side
221
+ // and automatically disable other same side menus
222
+ const side = menu.side;
223
+ menus.filter((m) => m.side === side && m !== menu).forEach((m) => (m.disabled = true));
224
+ };
215
225
  const _setOpen = async (menu, shouldOpen, animated) => {
216
226
  if (isAnimatingSync()) {
217
227
  return false;
@@ -283,6 +293,7 @@ const createMenuController = () => {
283
293
  _register,
284
294
  _unregister,
285
295
  _setOpen,
296
+ _setActiveMenu,
286
297
  };
287
298
  };
288
299
  const menuController = /*@__PURE__*/ createMenuController();
package/dist/esm/index.js CHANGED
@@ -10,7 +10,7 @@ export { createGesture } from './index-ff313b19.js';
10
10
  export { g as getPlatforms, i as initialize, a as isPlatform } from './ionic-global-b3fc28dd.js';
11
11
  export { c as componentOnReady } from './helpers-3379ba19.js';
12
12
  export { I as IonicSafeString, g as getMode, s as setupConfig } from './config-96c9ace3.js';
13
- export { m as menuController } from './index-39b3eab6.js';
13
+ export { m as menuController } from './index-61bddc90.js';
14
14
  export { b as actionSheetController, a as alertController, l as loadingController, m as modalController, p as pickerController, c as popoverController, t as toastController } from './overlays-8fc6656c.js';
15
15
  import './index-7a14ecec.js';
16
16
  import './index-2d388930.js';
@@ -3,16 +3,16 @@
3
3
  */
4
4
  import { r as registerInstance, d as createEvent, h, H as Host, f as getElement } from './index-2d388930.js';
5
5
  import { g as getTimeGivenProgression } from './cubic-bezier-66542bc5.js';
6
+ import { d as doc } from './index-7a14ecec.js';
6
7
  import { G as GESTURE_CONTROLLER } from './gesture-controller-0fa396c4.js';
7
8
  import { p as isEndSide, i as inheritAriaAttributes, o as assert, l as clamp } from './helpers-3379ba19.js';
8
- import { m as menuController } from './index-39b3eab6.js';
9
+ import { m as menuController } from './index-61bddc90.js';
9
10
  import { q as getPresentedOverlay } from './overlays-8fc6656c.js';
10
11
  import { c as config, b as getIonMode } from './ionic-global-b3fc28dd.js';
11
12
  import { c as createColorClasses, h as hostContext } from './theme-17531cdf.js';
12
13
  import { u as menuOutline, v as menuSharp } from './index-ecfc2c9f.js';
13
14
  import './hardware-back-button-39299f84.js';
14
15
  import './animation-a1d9e088.js';
15
- import './index-7a14ecec.js';
16
16
  import './framework-delegate-aa433dea.js';
17
17
  import './index-595d62c9.js';
18
18
 
@@ -549,6 +549,17 @@ const Menu = class {
549
549
  // close if this menu is open, and should not be enabled
550
550
  this.forceClosing();
551
551
  }
552
+ if (doc === null || doc === void 0 ? void 0 : doc.contains(this.el)) {
553
+ /**
554
+ * Only set the active menu if the menu element is
555
+ * present in the DOM. Otherwise if it was destructively
556
+ * re-hydrated (through Angular Universal), then ignore
557
+ * setting the removed node as the active menu.
558
+ */
559
+ if (!this.disabled) {
560
+ menuController._setActiveMenu(this);
561
+ }
562
+ }
552
563
  assert(!this.isAnimating, 'can not be animating');
553
564
  }
554
565
  forceClosing() {