@ionic/core 7.4.3-dev.11696273737.1ba31223 → 7.4.3-dev.11696355648.1f181be0
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.
- package/components/index4.js +11 -0
- package/components/ion-menu.js +12 -0
- package/components/ion-segment.js +35 -23
- package/dist/cjs/{index-d90b29dd.js → index-5121bb90.js} +11 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/ion-menu_3.cjs.entry.js +15 -4
- package/dist/cjs/ion-segment_2.cjs.entry.js +35 -24
- package/dist/collection/components/menu/menu.js +12 -0
- package/dist/collection/components/segment/segment.js +35 -23
- package/dist/collection/components/segment/test/scrollable/segment.e2e.js +55 -1
- package/dist/collection/utils/menu-controller/index.js +11 -0
- package/dist/docs.json +1 -1
- package/dist/esm/{index-39b3eab6.js → index-61bddc90.js} +11 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/ion-menu_3.entry.js +13 -2
- package/dist/esm/ion-segment_2.entry.js +35 -24
- package/dist/esm-es5/{index-39b3eab6.js → index-61bddc90.js} +1 -1
- package/dist/esm-es5/index.js +1 -1
- package/dist/esm-es5/ion-menu_3.entry.js +1 -1
- package/dist/esm-es5/ion-segment_2.entry.js +1 -1
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-155dfdda.entry.js +4 -0
- package/dist/ionic/p-40e16caa.system.entry.js +4 -0
- package/dist/ionic/p-6edbc09b.system.js +1 -1
- package/dist/ionic/{p-233cafdf.system.js → p-b098f738.system.js} +1 -1
- package/dist/ionic/p-b95fd3c6.entry.js +4 -0
- package/dist/ionic/{p-43252033.system.js → p-d4cea1ba.system.js} +1 -1
- package/dist/ionic/p-f1a71e75.system.entry.js +4 -0
- package/dist/ionic/p-f978ccd1.js +4 -0
- package/dist/types/components/menu/menu-interface.d.ts +1 -0
- package/dist/types/components/segment/segment.d.ts +1 -0
- package/dist/types/utils/menu-controller/index.d.ts +1 -0
- package/hydrate/index.js +56 -23
- package/package.json +1 -1
- package/dist/collection/components/menu/test/multiple/menu.e2e.js +0 -36
- package/dist/ionic/p-13a7b105.entry.js +0 -4
- package/dist/ionic/p-55b99166.entry.js +0 -4
- package/dist/ionic/p-7e994a60.js +0 -4
- package/dist/ionic/p-b5637aeb.system.entry.js +0 -4
- package/dist/ionic/p-f7d61a1c.system.entry.js +0 -4
package/components/index4.js
CHANGED
|
@@ -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/components/ion-menu.js
CHANGED
|
@@ -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
|
-
|
|
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();
|
package/dist/cjs/index.cjs.js
CHANGED
|
@@ -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-
|
|
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-
|
|
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$
|
|
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$
|
|
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
|
-
|
|
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
|
-
|
|
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,57 @@ 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.only('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 = (box.x >= 0 &&
|
|
91
|
+
box.y >= 0 &&
|
|
92
|
+
box.x + box.width <= viewport.width &&
|
|
93
|
+
box.y + box.height <= viewport.height);
|
|
94
|
+
}
|
|
95
|
+
expect(isInViewport).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -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
|
@@ -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-
|
|
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-
|
|
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() {
|