@ionic/core 8.0.0-dev.11712072527.1dd97c66 → 8.0.0-dev.11712850753.10c4a960
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/button.js +2 -2
- package/components/ion-datetime.js +8 -6
- package/components/ion-modal.js +9 -7
- package/components/overlays.js +3 -2
- package/components/popover.js +8 -6
- package/css/core.css +1 -624
- package/css/core.css.map +1 -1
- package/css/display.css +1 -131
- package/css/display.css.map +1 -1
- package/css/flex-utils.css +1 -81
- package/css/flex-utils.css.map +1 -1
- package/css/float-elements.css +1 -293
- package/css/float-elements.css.map +1 -1
- package/css/global.bundle.css +1 -457
- package/css/global.bundle.css.map +1 -1
- package/css/ionic-swiper.css +1 -127
- package/css/ionic-swiper.css.map +1 -1
- package/css/ionic.bundle.css +1 -1
- package/css/ionic.bundle.css.map +1 -1
- package/css/normalize.css +1 -150
- package/css/normalize.css.map +1 -1
- package/css/padding.css +1 -202
- package/css/padding.css.map +1 -1
- package/css/palettes/dark.always.css +1 -160
- package/css/palettes/dark.always.css.map +1 -1
- package/css/palettes/dark.class.css +1 -160
- package/css/palettes/dark.class.css.map +1 -1
- package/css/palettes/dark.css +0 -2
- package/css/palettes/dark.system.css +1 -162
- package/css/palettes/dark.system.css.map +1 -1
- package/css/palettes/high-contrast-dark.always.css +1 -180
- package/css/palettes/high-contrast-dark.always.css.map +1 -1
- package/css/palettes/high-contrast-dark.class.css +1 -180
- package/css/palettes/high-contrast-dark.class.css.map +1 -1
- package/css/palettes/high-contrast-dark.css +0 -2
- package/css/palettes/high-contrast-dark.system.css +1 -182
- package/css/palettes/high-contrast-dark.system.css.map +1 -1
- package/css/palettes/high-contrast.always.css +1 -101
- package/css/palettes/high-contrast.always.css.map +1 -1
- package/css/palettes/high-contrast.class.css +1 -101
- package/css/palettes/high-contrast.class.css.map +1 -1
- package/css/palettes/high-contrast.css +0 -2
- package/css/palettes/high-contrast.system.css +1 -103
- package/css/palettes/high-contrast.system.css.map +1 -1
- package/css/structure.css +1 -152
- package/css/structure.css.map +1 -1
- package/css/text-alignment.css +1 -243
- package/css/text-alignment.css.map +1 -1
- package/css/text-transformation.css +1 -158
- package/css/text-transformation.css.map +1 -1
- package/css/typography.css +1 -157
- package/css/typography.css.map +1 -1
- package/css/utils.bundle.css +1 -1100
- package/css/utils.bundle.css.map +1 -1
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/ion-action-sheet.cjs.entry.js +1 -1
- package/dist/cjs/ion-alert.cjs.entry.js +1 -1
- package/dist/cjs/ion-button_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-datetime_3.cjs.entry.js +9 -7
- package/dist/cjs/ion-loading.cjs.entry.js +1 -1
- package/dist/cjs/ion-menu_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-modal.cjs.entry.js +8 -7
- package/dist/cjs/ion-popover.cjs.entry.js +7 -6
- package/dist/cjs/ion-select_3.cjs.entry.js +1 -1
- package/dist/cjs/ion-toast.cjs.entry.js +1 -1
- package/dist/cjs/ionic.cjs.js +2 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{overlays-6487955a.js → overlays-66fcac49.js} +3 -1
- package/dist/collection/collection-manifest.json +2 -2
- package/dist/collection/components/button/button.ios.css +47 -8
- package/dist/collection/components/button/button.md.css +49 -8
- package/dist/collection/components/datetime/datetime.js +8 -6
- package/dist/collection/components/datetime/test/overlay-roles/datetime.e2e.js +34 -0
- package/dist/collection/components/input/input.js +1 -1
- package/dist/collection/components/modal/gestures/sheet.js +3 -2
- package/dist/collection/components/modal/modal.js +24 -5
- package/dist/collection/components/modal/test/basic/modal.spec.js +19 -0
- package/dist/collection/components/popover/popover.ios.css +0 -1
- package/dist/collection/components/popover/popover.js +23 -4
- package/dist/collection/components/popover/popover.md.css +0 -1
- package/dist/collection/components/popover/test/basic/popover.e2e.js +76 -0
- package/dist/collection/components/popover/test/basic/popover.spec.js +19 -0
- package/dist/collection/components/searchbar/searchbar.js +1 -1
- package/dist/collection/components/toolbar/test/basic/toolbar.e2e.js +133 -5
- package/dist/collection/utils/overlays.js +2 -1
- package/dist/docs.json +75 -31
- package/dist/esm/index.js +1 -1
- package/dist/esm/ion-action-sheet.entry.js +1 -1
- package/dist/esm/ion-alert.entry.js +1 -1
- package/dist/esm/ion-button_2.entry.js +2 -2
- package/dist/esm/ion-datetime_3.entry.js +9 -7
- package/dist/esm/ion-loading.entry.js +1 -1
- package/dist/esm/ion-menu_3.entry.js +1 -1
- package/dist/esm/ion-modal.entry.js +8 -7
- package/dist/esm/ion-popover.entry.js +7 -6
- package/dist/esm/ion-select_3.entry.js +1 -1
- package/dist/esm/ion-toast.entry.js +1 -1
- package/dist/esm/ionic.js +2 -2
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{overlays-9472c98b.js → overlays-634df4be.js} +3 -2
- package/dist/esm-es5/index.js +1 -1
- package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
- package/dist/esm-es5/ion-alert.entry.js +1 -1
- package/dist/esm-es5/ion-button_2.entry.js +1 -1
- package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
- package/dist/esm-es5/ion-loading.entry.js +1 -1
- package/dist/esm-es5/ion-menu_3.entry.js +1 -1
- package/dist/esm-es5/ion-modal.entry.js +1 -1
- package/dist/esm-es5/ion-popover.entry.js +1 -1
- package/dist/esm-es5/ion-select_3.entry.js +1 -1
- package/dist/esm-es5/ion-toast.entry.js +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/{overlays-9472c98b.js → overlays-634df4be.js} +1 -1
- package/dist/html.html-data.json +26 -18
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/ionic.js +1 -1
- package/dist/ionic/p-012cc611.system.entry.js +4 -0
- package/dist/ionic/p-18057853.entry.js +4 -0
- package/dist/ionic/p-2b106d43.system.entry.js +4 -0
- package/dist/ionic/{p-ea6f36fb.system.entry.js → p-32950317.system.entry.js} +1 -1
- package/dist/ionic/{p-4665ab20.entry.js → p-33444157.entry.js} +1 -1
- package/dist/ionic/{p-10ad2148.system.entry.js → p-33723893.system.entry.js} +1 -1
- package/dist/ionic/{p-d68569fe.system.entry.js → p-414d73bc.system.entry.js} +1 -1
- package/dist/ionic/{p-83b6da7c.system.entry.js → p-5cf61334.system.entry.js} +1 -1
- package/dist/ionic/p-73281e75.system.entry.js +4 -0
- package/dist/ionic/{p-fab4ecad.system.entry.js → p-745eb00b.system.entry.js} +1 -1
- package/dist/ionic/p-88250ff0.entry.js +4 -0
- package/dist/ionic/p-9399625f.entry.js +4 -0
- package/dist/ionic/p-ab5db814.js +4 -0
- package/dist/ionic/{p-51ff648c.entry.js → p-ae21e7ab.entry.js} +1 -1
- package/dist/ionic/{p-81c91374.entry.js → p-bcbce3d9.entry.js} +1 -1
- package/dist/ionic/{p-16dc1af8.entry.js → p-bd516c16.entry.js} +1 -1
- package/dist/ionic/p-c478747f.system.js +4 -0
- package/dist/ionic/p-cfdb1223.entry.js +4 -0
- package/dist/ionic/p-d335115d.system.js +4 -0
- package/dist/ionic/{p-4e802677.entry.js → p-db1d7caa.entry.js} +1 -1
- package/dist/ionic/{p-a8f02173.system.js → p-f24e9676.system.js} +1 -1
- package/dist/ionic/p-f31ef319.system.entry.js +4 -0
- package/dist/ionic/{p-c99ccdc9.entry.js → p-f4f3b780.entry.js} +1 -1
- package/dist/ionic/{p-510578f3.system.entry.js → p-fe246e19.system.entry.js} +1 -1
- package/dist/types/components/modal/modal-interface.d.ts +1 -0
- package/dist/types/components/modal/modal.d.ts +18 -0
- package/dist/types/components/popover/popover-interface.d.ts +1 -0
- package/dist/types/components/popover/popover.d.ts +18 -0
- package/dist/types/components.d.ts +16 -0
- package/dist/types/utils/overlays.d.ts +1 -0
- package/hydrate/index.js +43 -21
- package/package.json +2 -2
- package/dist/ionic/p-23b89985.entry.js +0 -4
- package/dist/ionic/p-25575222.system.js +0 -4
- package/dist/ionic/p-55d7edd7.entry.js +0 -4
- package/dist/ionic/p-8e2368ae.system.entry.js +0 -4
- package/dist/ionic/p-aeb5a22b.system.entry.js +0 -4
- package/dist/ionic/p-b75155ca.entry.js +0 -4
- package/dist/ionic/p-bb835b4d.system.entry.js +0 -4
- package/dist/ionic/p-c06e1332.system.entry.js +0 -4
- package/dist/ionic/p-c389d18c.entry.js +0 -4
- package/dist/ionic/p-ea4be6ac.system.js +0 -4
- package/dist/ionic/p-f4cb521c.js +0 -4
|
@@ -85,10 +85,10 @@ export class Datetime {
|
|
|
85
85
|
const { activeParts } = this;
|
|
86
86
|
return Array.isArray(activeParts) ? activeParts[0] : activeParts;
|
|
87
87
|
};
|
|
88
|
-
this.closeParentOverlay = () => {
|
|
88
|
+
this.closeParentOverlay = (role) => {
|
|
89
89
|
const popoverOrModal = this.el.closest('ion-modal, ion-popover');
|
|
90
90
|
if (popoverOrModal) {
|
|
91
|
-
popoverOrModal.dismiss();
|
|
91
|
+
popoverOrModal.dismiss(undefined, role);
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
94
|
this.setWorkingParts = (parts) => {
|
|
@@ -758,7 +758,7 @@ export class Datetime {
|
|
|
758
758
|
}
|
|
759
759
|
}
|
|
760
760
|
if (closeOverlay) {
|
|
761
|
-
this.closeParentOverlay();
|
|
761
|
+
this.closeParentOverlay(CONFIRM_ROLE);
|
|
762
762
|
}
|
|
763
763
|
}
|
|
764
764
|
/**
|
|
@@ -778,7 +778,7 @@ export class Datetime {
|
|
|
778
778
|
async cancel(closeOverlay = false) {
|
|
779
779
|
this.ionCancel.emit();
|
|
780
780
|
if (closeOverlay) {
|
|
781
|
-
this.closeParentOverlay();
|
|
781
|
+
this.closeParentOverlay(CANCEL_ROLE);
|
|
782
782
|
}
|
|
783
783
|
}
|
|
784
784
|
get isCalendarPicker() {
|
|
@@ -1556,7 +1556,7 @@ export class Datetime {
|
|
|
1556
1556
|
const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
|
|
1557
1557
|
const hasWheelVariant = hasDatePresentation && preferWheel;
|
|
1558
1558
|
renderHiddenInput(true, el, name, formatValue(value), disabled);
|
|
1559
|
-
return (h(Host, { key: '
|
|
1559
|
+
return (h(Host, { key: '952afba4aff8f172dcdc7986afb56271f0e239aa', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses(color, {
|
|
1560
1560
|
[mode]: true,
|
|
1561
1561
|
['datetime-readonly']: readonly,
|
|
1562
1562
|
['datetime-disabled']: disabled,
|
|
@@ -1566,7 +1566,7 @@ export class Datetime {
|
|
|
1566
1566
|
[`datetime-size-${size}`]: true,
|
|
1567
1567
|
[`datetime-prefer-wheel`]: hasWheelVariant,
|
|
1568
1568
|
[`datetime-grid`]: isGridStyle,
|
|
1569
|
-
})) }, h("div", { key: '
|
|
1569
|
+
})) }, h("div", { key: '2de62751e7498f09cef364a401e65a098be4705a', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
|
|
1570
1570
|
}
|
|
1571
1571
|
static get is() { return "ion-datetime"; }
|
|
1572
1572
|
static get encapsulation() { return "shadow"; }
|
|
@@ -2396,5 +2396,7 @@ export class Datetime {
|
|
|
2396
2396
|
}
|
|
2397
2397
|
}
|
|
2398
2398
|
let datetimeIds = 0;
|
|
2399
|
+
const CANCEL_ROLE = 'datetime-cancel';
|
|
2400
|
+
const CONFIRM_ROLE = 'datetime-confirm';
|
|
2399
2401
|
const WHEEL_ITEM_PART = 'wheel-item';
|
|
2400
2402
|
const WHEEL_ITEM_ACTIVE_PART = `active`;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
import { expect } from "@playwright/test";
|
|
5
|
+
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
6
|
+
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ config, title }) => {
|
|
7
|
+
test.describe(title('datetime: overlay roles'), () => {
|
|
8
|
+
test.beforeEach(async ({ page }) => {
|
|
9
|
+
await page.setContent(`
|
|
10
|
+
<ion-modal>
|
|
11
|
+
<ion-datetime></ion-datetime>
|
|
12
|
+
</ion-modal>
|
|
13
|
+
`, config);
|
|
14
|
+
});
|
|
15
|
+
test('should pass role to overlay when calling confirm method', async ({ page }) => {
|
|
16
|
+
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
|
17
|
+
const modal = page.locator('ion-modal');
|
|
18
|
+
const datetime = page.locator('ion-datetime');
|
|
19
|
+
await modal.evaluate((el) => el.present());
|
|
20
|
+
await datetime.evaluate((el) => el.confirm(true));
|
|
21
|
+
await ionModalDidDismiss.next();
|
|
22
|
+
expect(ionModalDidDismiss).toHaveReceivedEventDetail({ data: undefined, role: 'datetime-confirm' });
|
|
23
|
+
});
|
|
24
|
+
test('should pass role to overlay when calling cancel method', async ({ page }) => {
|
|
25
|
+
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
|
26
|
+
const modal = page.locator('ion-modal');
|
|
27
|
+
const datetime = page.locator('ion-datetime');
|
|
28
|
+
await modal.evaluate((el) => el.present());
|
|
29
|
+
await datetime.evaluate((el) => el.cancel(true));
|
|
30
|
+
await ionModalDidDismiss.next();
|
|
31
|
+
expect(ionModalDidDismiss).toHaveReceivedEventDetail({ data: undefined, role: 'datetime-cancel' });
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -480,7 +480,7 @@ export class Input {
|
|
|
480
480
|
"mutable": false,
|
|
481
481
|
"complexType": {
|
|
482
482
|
"original": "AutocompleteTypes",
|
|
483
|
-
"resolved": "\"name\" | \"on\" | \"off\" | \"honorific-prefix\" | \"given-name\" | \"additional-name\" | \"family-name\" | \"honorific-suffix\" | \"nickname\" | \"
|
|
483
|
+
"resolved": "\"name\" | \"email\" | \"tel\" | \"url\" | \"on\" | \"off\" | \"honorific-prefix\" | \"given-name\" | \"additional-name\" | \"family-name\" | \"honorific-suffix\" | \"nickname\" | \"username\" | \"new-password\" | \"current-password\" | \"one-time-code\" | \"organization-title\" | \"organization\" | \"street-address\" | \"address-line1\" | \"address-line2\" | \"address-line3\" | \"address-level4\" | \"address-level3\" | \"address-level2\" | \"address-level1\" | \"country\" | \"country-name\" | \"postal-code\" | \"cc-name\" | \"cc-given-name\" | \"cc-additional-name\" | \"cc-family-name\" | \"cc-number\" | \"cc-exp\" | \"cc-exp-month\" | \"cc-exp-year\" | \"cc-csc\" | \"cc-type\" | \"transaction-currency\" | \"transaction-amount\" | \"language\" | \"bday\" | \"bday-day\" | \"bday-month\" | \"bday-year\" | \"sex\" | \"tel-country-code\" | \"tel-national\" | \"tel-area-code\" | \"tel-local\" | \"tel-extension\" | \"impp\" | \"photo\"",
|
|
484
484
|
"references": {
|
|
485
485
|
"AutocompleteTypes": {
|
|
486
486
|
"location": "import",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { createGesture } from "../../../utils/gesture/index";
|
|
5
5
|
import { clamp, raf } from "../../../utils/helpers";
|
|
6
|
+
import { FOCUS_TRAP_DISABLE_CLASS } from "../../../utils/overlays";
|
|
6
7
|
import { getBackdropValueForSheet } from "../utils";
|
|
7
8
|
import { calculateSpringStep, handleCanDismiss } from "./utils";
|
|
8
9
|
export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
|
|
@@ -41,7 +42,7 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
|
|
|
41
42
|
* as inputs should not be focusable outside
|
|
42
43
|
* the sheet.
|
|
43
44
|
*/
|
|
44
|
-
baseEl.classList.remove(
|
|
45
|
+
baseEl.classList.remove(FOCUS_TRAP_DISABLE_CLASS);
|
|
45
46
|
};
|
|
46
47
|
const disableBackdrop = () => {
|
|
47
48
|
baseEl.style.setProperty('pointer-events', 'none');
|
|
@@ -53,7 +54,7 @@ export const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpo
|
|
|
53
54
|
* Adding this class disables focus trapping
|
|
54
55
|
* for the sheet temporarily.
|
|
55
56
|
*/
|
|
56
|
-
baseEl.classList.add(
|
|
57
|
+
baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
|
|
57
58
|
};
|
|
58
59
|
/**
|
|
59
60
|
* After the entering animation completes,
|
|
@@ -8,7 +8,7 @@ import { raf, inheritAttributes, hasLazyBuild } from "../../utils/helpers";
|
|
|
8
8
|
import { createLockController } from "../../utils/lock-controller";
|
|
9
9
|
import { printIonWarning } from "../../utils/logging/index";
|
|
10
10
|
import { Style as StatusBarStyle, StatusBar } from "../../utils/native/status-bar";
|
|
11
|
-
import { GESTURE, BACKDROP, dismiss, eventMethod, prepareOverlay, present, createTriggerController, setOverlayId, } from "../../utils/overlays";
|
|
11
|
+
import { GESTURE, BACKDROP, dismiss, eventMethod, prepareOverlay, present, createTriggerController, setOverlayId, FOCUS_TRAP_DISABLE_CLASS, } from "../../utils/overlays";
|
|
12
12
|
import { getClassMap } from "../../utils/theme";
|
|
13
13
|
import { deepReady, waitForMount } from "../../utils/transition/index";
|
|
14
14
|
import { config } from "../../global/config";
|
|
@@ -101,6 +101,7 @@ export class Modal {
|
|
|
101
101
|
this.isOpen = false;
|
|
102
102
|
this.trigger = undefined;
|
|
103
103
|
this.keepContentsMounted = false;
|
|
104
|
+
this.focusTrap = true;
|
|
104
105
|
this.canDismiss = true;
|
|
105
106
|
}
|
|
106
107
|
onIsOpenChange(newValue, oldValue) {
|
|
@@ -557,14 +558,14 @@ export class Modal {
|
|
|
557
558
|
return true;
|
|
558
559
|
}
|
|
559
560
|
render() {
|
|
560
|
-
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes } = this;
|
|
561
|
+
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap } = this;
|
|
561
562
|
const showHandle = handle !== false && isSheetModal;
|
|
562
563
|
const mode = getIonMode(this);
|
|
563
564
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
564
565
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
565
|
-
return (h(Host, Object.assign({ key: '
|
|
566
|
+
return (h(Host, Object.assign({ key: '1fbeb502325f00153e335c235a038507e35a210e', "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
|
|
566
567
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
567
|
-
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }), h("ion-backdrop", { key: '
|
|
568
|
+
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }), h("ion-backdrop", { key: '388aa2b92fa5795d1ef9021c4df9817ac426bcea', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { class: "modal-shadow" }), h("div", Object.assign({ key: '752f4e329a330cc0802476404ef292f73fac257f',
|
|
568
569
|
/*
|
|
569
570
|
role and aria-modal must be used on the
|
|
570
571
|
same element. They must also be set inside the
|
|
@@ -573,7 +574,7 @@ export class Modal {
|
|
|
573
574
|
*/
|
|
574
575
|
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { class: "modal-handle",
|
|
575
576
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
576
|
-
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle" })), h("slot", { key: '
|
|
577
|
+
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle" })), h("slot", { key: '87d1d4a725c463cefed2e96a6a9fee36ba6e8311' }))));
|
|
577
578
|
}
|
|
578
579
|
static get is() { return "ion-modal"; }
|
|
579
580
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1019,6 +1020,24 @@ export class Modal {
|
|
|
1019
1020
|
"reflect": false,
|
|
1020
1021
|
"defaultValue": "false"
|
|
1021
1022
|
},
|
|
1023
|
+
"focusTrap": {
|
|
1024
|
+
"type": "boolean",
|
|
1025
|
+
"mutable": false,
|
|
1026
|
+
"complexType": {
|
|
1027
|
+
"original": "boolean",
|
|
1028
|
+
"resolved": "boolean",
|
|
1029
|
+
"references": {}
|
|
1030
|
+
},
|
|
1031
|
+
"required": false,
|
|
1032
|
+
"optional": false,
|
|
1033
|
+
"docs": {
|
|
1034
|
+
"tags": [],
|
|
1035
|
+
"text": "If `true`, focus will not be allowed to move outside of this overlay.\nIf 'false', focus will be allowed to move outside of the overlay.\n\nIn most scenarios this property should remain set to `true`. Setting\nthis property to `false` can cause severe accessibility issues as users\nrelying on assistive technologies may be able to move focus into\na confusing state. We recommend only setting this to `false` when\nabsolutely necessary.\n\nDevelopers may want to consider disabling focus trapping if this\noverlay presents a non-Ionic overlay from a 3rd party library.\nDevelopers would disable focus trapping on the Ionic overlay\nwhen presenting the 3rd party overlay and then re-enable\nfocus trapping when dismissing the 3rd party overlay and moving\nfocus back to the Ionic overlay."
|
|
1036
|
+
},
|
|
1037
|
+
"attribute": "focus-trap",
|
|
1038
|
+
"reflect": false,
|
|
1039
|
+
"defaultValue": "true"
|
|
1040
|
+
},
|
|
1022
1041
|
"canDismiss": {
|
|
1023
1042
|
"type": "boolean",
|
|
1024
1043
|
"mutable": false,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { h } from "@stencil/core";
|
|
5
5
|
import { newSpecPage } from "@stencil/core/testing";
|
|
6
6
|
import { Modal } from "../../modal";
|
|
7
|
+
import { FOCUS_TRAP_DISABLE_CLASS } from "../../../../utils/overlays";
|
|
7
8
|
describe('modal: htmlAttributes inheritance', () => {
|
|
8
9
|
it('should correctly inherit attributes on host', async () => {
|
|
9
10
|
const page = await newSpecPage({
|
|
@@ -14,3 +15,21 @@ describe('modal: htmlAttributes inheritance', () => {
|
|
|
14
15
|
await expect(modal.getAttribute('data-testid')).toBe('basic-modal');
|
|
15
16
|
});
|
|
16
17
|
});
|
|
18
|
+
describe('modal: focus trap', () => {
|
|
19
|
+
it('should set the focus trap class when disabled', async () => {
|
|
20
|
+
const page = await newSpecPage({
|
|
21
|
+
components: [Modal],
|
|
22
|
+
template: () => h("ion-modal", { focusTrap: false, overlayIndex: 1 }),
|
|
23
|
+
});
|
|
24
|
+
const modal = page.body.querySelector('ion-modal');
|
|
25
|
+
expect(modal.classList.contains(FOCUS_TRAP_DISABLE_CLASS)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it('should not set the focus trap class by default', async () => {
|
|
28
|
+
const page = await newSpecPage({
|
|
29
|
+
components: [Modal],
|
|
30
|
+
template: () => h("ion-modal", { overlayIndex: 1 }),
|
|
31
|
+
});
|
|
32
|
+
const modal = page.body.querySelector('ion-modal');
|
|
33
|
+
expect(modal.classList.contains(FOCUS_TRAP_DISABLE_CLASS)).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -7,7 +7,7 @@ import { CoreDelegate, attachComponent, detachComponent } from "../../utils/fram
|
|
|
7
7
|
import { addEventListener, raf, hasLazyBuild } from "../../utils/helpers";
|
|
8
8
|
import { createLockController } from "../../utils/lock-controller";
|
|
9
9
|
import { printIonWarning } from "../../utils/logging/index";
|
|
10
|
-
import { BACKDROP, dismiss, eventMethod, prepareOverlay, present, setOverlayId } from "../../utils/overlays";
|
|
10
|
+
import { BACKDROP, dismiss, eventMethod, prepareOverlay, present, setOverlayId, FOCUS_TRAP_DISABLE_CLASS, } from "../../utils/overlays";
|
|
11
11
|
import { isPlatform } from "../../utils/platform";
|
|
12
12
|
import { getClassMap } from "../../utils/theme";
|
|
13
13
|
import { deepReady, waitForMount } from "../../utils/transition/index";
|
|
@@ -107,6 +107,7 @@ export class Popover {
|
|
|
107
107
|
this.arrow = true;
|
|
108
108
|
this.isOpen = false;
|
|
109
109
|
this.keyboardEvents = false;
|
|
110
|
+
this.focusTrap = true;
|
|
110
111
|
this.keepContentsMounted = false;
|
|
111
112
|
}
|
|
112
113
|
onTriggerChange() {
|
|
@@ -333,12 +334,12 @@ export class Popover {
|
|
|
333
334
|
}
|
|
334
335
|
render() {
|
|
335
336
|
const mode = getIonMode(this);
|
|
336
|
-
const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes } = this;
|
|
337
|
+
const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes, focusTrap } = this;
|
|
337
338
|
const desktop = isPlatform('desktop');
|
|
338
339
|
const enableArrow = arrow && !parentPopover;
|
|
339
|
-
return (h(Host, Object.assign({ key: '
|
|
340
|
+
return (h(Host, Object.assign({ key: '4c8d34559a6e383cb778566f2c6e88690def0ba0', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
|
|
340
341
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
341
|
-
}, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: '
|
|
342
|
+
}, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: '710e22246d151441d80f2bbd618145d7dc651f09', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && h("div", { class: "popover-arrow", part: "arrow" }), h("div", { key: 'aefcaa864ba3b941597bae15dedc51c33e1b7bb9', class: "popover-content", part: "content" }, h("slot", { key: 'b2384f79e042a5946b65511bd339bd0cf7772d18' })))));
|
|
342
343
|
}
|
|
343
344
|
static get is() { return "ion-popover"; }
|
|
344
345
|
static get encapsulation() { return "shadow"; }
|
|
@@ -860,6 +861,24 @@ export class Popover {
|
|
|
860
861
|
"reflect": false,
|
|
861
862
|
"defaultValue": "false"
|
|
862
863
|
},
|
|
864
|
+
"focusTrap": {
|
|
865
|
+
"type": "boolean",
|
|
866
|
+
"mutable": false,
|
|
867
|
+
"complexType": {
|
|
868
|
+
"original": "boolean",
|
|
869
|
+
"resolved": "boolean",
|
|
870
|
+
"references": {}
|
|
871
|
+
},
|
|
872
|
+
"required": false,
|
|
873
|
+
"optional": false,
|
|
874
|
+
"docs": {
|
|
875
|
+
"tags": [],
|
|
876
|
+
"text": "If `true`, focus will not be allowed to move outside of this overlay.\nIf 'false', focus will be allowed to move outside of the overlay.\n\nIn most scenarios this property should remain set to `true`. Setting\nthis property to `false` can cause severe accessibility issues as users\nrelying on assistive technologies may be able to move focus into\na confusing state. We recommend only setting this to `false` when\nabsolutely necessary.\n\nDevelopers may want to consider disabling focus trapping if this\noverlay presents a non-Ionic overlay from a 3rd party library.\nDevelopers would disable focus trapping on the Ionic overlay\nwhen presenting the 3rd party overlay and then re-enable\nfocus trapping when dismissing the 3rd party overlay and moving\nfocus back to the Ionic overlay."
|
|
877
|
+
},
|
|
878
|
+
"attribute": "focus-trap",
|
|
879
|
+
"reflect": false,
|
|
880
|
+
"defaultValue": "true"
|
|
881
|
+
},
|
|
863
882
|
"keepContentsMounted": {
|
|
864
883
|
"type": "boolean",
|
|
865
884
|
"mutable": false,
|
|
@@ -46,6 +46,82 @@ configs({ directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
|
46
46
|
* Translucent popovers are only available on iOS
|
|
47
47
|
*/
|
|
48
48
|
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
49
|
+
test.describe(title('popover: scrolling'), async () => {
|
|
50
|
+
test.beforeEach(({ skip }) => {
|
|
51
|
+
test.info().annotations.push({
|
|
52
|
+
type: 'issue',
|
|
53
|
+
description: 'https://github.com/ionic-team/ionic-framework/issues/29211',
|
|
54
|
+
});
|
|
55
|
+
// We are testing if Ionic sets overflow is set correctly on elements,
|
|
56
|
+
// so we do not need to test across browsers
|
|
57
|
+
skip.browser('webkit', 'Behavior does not vary across browsers');
|
|
58
|
+
skip.browser('firefox', 'Behavior does not vary across browsers');
|
|
59
|
+
});
|
|
60
|
+
test('should scroll to bottom without IonContent', async ({ page }) => {
|
|
61
|
+
await page.setContent(`
|
|
62
|
+
<style>
|
|
63
|
+
ion-popover {
|
|
64
|
+
--height: 150px;
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
67
|
+
<ion-popover>
|
|
68
|
+
<p>Text</p>
|
|
69
|
+
<p>Text</p>
|
|
70
|
+
<p>Text</p>
|
|
71
|
+
<p>Text</p>
|
|
72
|
+
<p>Text</p>
|
|
73
|
+
<p>Text</p>
|
|
74
|
+
<p>Text</p>
|
|
75
|
+
<p>Text</p>
|
|
76
|
+
<p>Text</p>
|
|
77
|
+
<p>Text</p>
|
|
78
|
+
</ion-popover>
|
|
79
|
+
`, config);
|
|
80
|
+
const popover = page.locator('ion-popover');
|
|
81
|
+
const viewport = popover.locator('.popover-viewport');
|
|
82
|
+
const p = popover.locator('p');
|
|
83
|
+
const lastP = await p.last();
|
|
84
|
+
await popover.evaluate((el) => el.present());
|
|
85
|
+
await expect(lastP).not.toBeInViewport();
|
|
86
|
+
// hover over viewport and scroll to bottom
|
|
87
|
+
await viewport.hover();
|
|
88
|
+
await page.mouse.wheel(0, 500);
|
|
89
|
+
await expect(lastP).toBeInViewport();
|
|
90
|
+
});
|
|
91
|
+
test('should scroll to bottom with IonContent', async ({ page }) => {
|
|
92
|
+
await page.setContent(`
|
|
93
|
+
<style>
|
|
94
|
+
ion-popover {
|
|
95
|
+
--height: 150px;
|
|
96
|
+
}
|
|
97
|
+
</style>
|
|
98
|
+
<ion-popover>
|
|
99
|
+
<ion-content>
|
|
100
|
+
<p>Text</p>
|
|
101
|
+
<p>Text</p>
|
|
102
|
+
<p>Text</p>
|
|
103
|
+
<p>Text</p>
|
|
104
|
+
<p>Text</p>
|
|
105
|
+
<p>Text</p>
|
|
106
|
+
<p>Text</p>
|
|
107
|
+
<p>Text</p>
|
|
108
|
+
<p>Text</p>
|
|
109
|
+
<p>Text</p>
|
|
110
|
+
</ion-content>
|
|
111
|
+
</ion-popover>
|
|
112
|
+
`, config);
|
|
113
|
+
const popover = page.locator('ion-popover');
|
|
114
|
+
const content = popover.locator('ion-content');
|
|
115
|
+
const p = popover.locator('p');
|
|
116
|
+
const lastP = await p.last();
|
|
117
|
+
await popover.evaluate((el) => el.present());
|
|
118
|
+
await expect(lastP).not.toBeInViewport();
|
|
119
|
+
// hover over viewport and scroll to bottom
|
|
120
|
+
await content.hover();
|
|
121
|
+
await page.mouse.wheel(0, 500);
|
|
122
|
+
await expect(lastP).toBeInViewport();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
49
125
|
test.describe(title('popover: translucent variants'), async () => {
|
|
50
126
|
let popoverFixture;
|
|
51
127
|
test.beforeEach(async ({ page }) => {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { h } from "@stencil/core";
|
|
5
5
|
import { newSpecPage } from "@stencil/core/testing";
|
|
6
6
|
import { Popover } from "../../popover";
|
|
7
|
+
import { FOCUS_TRAP_DISABLE_CLASS } from "../../../../utils/overlays";
|
|
7
8
|
describe('popover: htmlAttributes inheritance', () => {
|
|
8
9
|
it('should correctly inherit attributes on host', async () => {
|
|
9
10
|
const page = await newSpecPage({
|
|
@@ -14,3 +15,21 @@ describe('popover: htmlAttributes inheritance', () => {
|
|
|
14
15
|
await expect(popover.getAttribute('data-testid')).toBe('basic-popover');
|
|
15
16
|
});
|
|
16
17
|
});
|
|
18
|
+
describe('popover: focus trap', () => {
|
|
19
|
+
it('should set the focus trap class when disabled', async () => {
|
|
20
|
+
const page = await newSpecPage({
|
|
21
|
+
components: [Popover],
|
|
22
|
+
template: () => h("ion-popover", { focusTrap: false, overlayIndex: 1 }),
|
|
23
|
+
});
|
|
24
|
+
const popover = page.body.querySelector('ion-popover');
|
|
25
|
+
expect(popover.classList.contains(FOCUS_TRAP_DISABLE_CLASS)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it('should not set the focus trap class by default', async () => {
|
|
28
|
+
const page = await newSpecPage({
|
|
29
|
+
components: [Popover],
|
|
30
|
+
template: () => h("ion-popover", { overlayIndex: 1 }),
|
|
31
|
+
});
|
|
32
|
+
const popover = page.body.querySelector('ion-popover');
|
|
33
|
+
expect(popover.classList.contains(FOCUS_TRAP_DISABLE_CLASS)).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -478,7 +478,7 @@ export class Searchbar {
|
|
|
478
478
|
"mutable": false,
|
|
479
479
|
"complexType": {
|
|
480
480
|
"original": "AutocompleteTypes",
|
|
481
|
-
"resolved": "\"name\" | \"on\" | \"off\" | \"honorific-prefix\" | \"given-name\" | \"additional-name\" | \"family-name\" | \"honorific-suffix\" | \"nickname\" | \"
|
|
481
|
+
"resolved": "\"name\" | \"email\" | \"tel\" | \"url\" | \"on\" | \"off\" | \"honorific-prefix\" | \"given-name\" | \"additional-name\" | \"family-name\" | \"honorific-suffix\" | \"nickname\" | \"username\" | \"new-password\" | \"current-password\" | \"one-time-code\" | \"organization-title\" | \"organization\" | \"street-address\" | \"address-line1\" | \"address-line2\" | \"address-line3\" | \"address-level4\" | \"address-level3\" | \"address-level2\" | \"address-level1\" | \"country\" | \"country-name\" | \"postal-code\" | \"cc-name\" | \"cc-given-name\" | \"cc-additional-name\" | \"cc-family-name\" | \"cc-number\" | \"cc-exp\" | \"cc-exp-month\" | \"cc-exp-year\" | \"cc-csc\" | \"cc-type\" | \"transaction-currency\" | \"transaction-amount\" | \"language\" | \"bday\" | \"bday-day\" | \"bday-month\" | \"bday-year\" | \"sex\" | \"tel-country-code\" | \"tel-national\" | \"tel-area-code\" | \"tel-local\" | \"tel-extension\" | \"impp\" | \"photo\"",
|
|
482
482
|
"references": {
|
|
483
483
|
"AutocompleteTypes": {
|
|
484
484
|
"location": "import",
|
|
@@ -3,13 +3,141 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { expect } from "@playwright/test";
|
|
5
5
|
import { configs, test } from "../../../../utils/test/playwright/index";
|
|
6
|
-
configs().forEach(({ title, screenshot, config }) => {
|
|
6
|
+
configs({ palettes: ['light', 'dark'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
|
7
|
+
test.describe(title('toolbar: basic (LTR only)'), () => {
|
|
8
|
+
test('should not have visual regressions with text only', async ({ page }) => {
|
|
9
|
+
await page.setContent(`
|
|
10
|
+
<ion-header>
|
|
11
|
+
<ion-toolbar>
|
|
12
|
+
<ion-title>Toolbar</ion-title>
|
|
13
|
+
</ion-toolbar>
|
|
14
|
+
</ion-header>
|
|
15
|
+
`, config);
|
|
16
|
+
const header = page.locator('ion-header');
|
|
17
|
+
await expect(header).toHaveScreenshot(screenshot(`toolbar-basic-text-only`));
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
configs({ palettes: ['light', 'dark'] }).forEach(({ title, screenshot, config }) => {
|
|
7
22
|
test.describe(title('toolbar: basic'), () => {
|
|
8
|
-
test('should
|
|
9
|
-
await page.
|
|
10
|
-
|
|
23
|
+
test('should truncate long title with ellipsis', async ({ page }) => {
|
|
24
|
+
await page.setContent(`
|
|
25
|
+
<ion-header>
|
|
26
|
+
<ion-toolbar>
|
|
27
|
+
<ion-title>This is the title that never ends. It just goes on and on my friend.</ion-title>
|
|
28
|
+
</ion-toolbar>
|
|
29
|
+
</ion-header>
|
|
30
|
+
`, config);
|
|
31
|
+
const header = page.locator('ion-header');
|
|
32
|
+
await expect(header).toHaveScreenshot(screenshot(`toolbar-basic-long-text`));
|
|
33
|
+
});
|
|
34
|
+
test('should not have visual regressions with icon-only buttons', async ({ page }) => {
|
|
35
|
+
await page.setContent(`
|
|
36
|
+
<ion-header>
|
|
37
|
+
<ion-toolbar>
|
|
38
|
+
<ion-buttons slot="secondary">
|
|
39
|
+
<ion-button>
|
|
40
|
+
<ion-icon slot="icon-only" name="person-circle"></ion-icon>
|
|
41
|
+
</ion-button>
|
|
42
|
+
<ion-button>
|
|
43
|
+
<ion-icon slot="icon-only" name="search"></ion-icon>
|
|
44
|
+
</ion-button>
|
|
45
|
+
</ion-buttons>
|
|
46
|
+
<ion-buttons slot="primary">
|
|
47
|
+
<ion-button color="secondary">
|
|
48
|
+
<ion-icon slot="icon-only" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
|
|
49
|
+
</ion-button>
|
|
50
|
+
</ion-buttons>
|
|
51
|
+
<ion-title>Toolbar</ion-title>
|
|
52
|
+
</ion-toolbar>
|
|
53
|
+
<ion-toolbar>
|
|
54
|
+
<ion-buttons slot="secondary">
|
|
55
|
+
<ion-button class="ion-activated">
|
|
56
|
+
<ion-icon slot="icon-only" name="person-circle"></ion-icon>
|
|
57
|
+
</ion-button>
|
|
58
|
+
<ion-button class="ion-activated">
|
|
59
|
+
<ion-icon slot="icon-only" name="search"></ion-icon>
|
|
60
|
+
</ion-button>
|
|
61
|
+
</ion-buttons>
|
|
62
|
+
<ion-buttons slot="primary">
|
|
63
|
+
<ion-button color="secondary" class="ion-activated">
|
|
64
|
+
<ion-icon slot="icon-only" ios="ellipsis-horizontal" md="ellipsis-vertical"></ion-icon>
|
|
65
|
+
</ion-button>
|
|
66
|
+
</ion-buttons>
|
|
67
|
+
<ion-title>Activated Buttons</ion-title>
|
|
68
|
+
</ion-toolbar>
|
|
69
|
+
</ion-header>
|
|
70
|
+
`, config);
|
|
71
|
+
const header = page.locator('ion-header');
|
|
72
|
+
await expect(header).toHaveScreenshot(screenshot(`toolbar-basic-icon-buttons`));
|
|
73
|
+
});
|
|
74
|
+
test('should not have visual regressions with buttons with icons and text', async ({ page }) => {
|
|
75
|
+
await page.setContent(`
|
|
76
|
+
<ion-header>
|
|
77
|
+
<ion-toolbar>
|
|
78
|
+
<ion-buttons slot="secondary">
|
|
79
|
+
<ion-button fill="solid">
|
|
80
|
+
<ion-icon slot="start" name="person-circle"></ion-icon>
|
|
81
|
+
Solid
|
|
82
|
+
</ion-button>
|
|
83
|
+
</ion-buttons>
|
|
84
|
+
<ion-title>Solid</ion-title>
|
|
85
|
+
<ion-buttons slot="primary">
|
|
86
|
+
<ion-button fill="solid" color="secondary">
|
|
87
|
+
Help
|
|
88
|
+
<ion-icon slot="end" name="help-circle"></ion-icon>
|
|
89
|
+
</ion-button>
|
|
90
|
+
</ion-buttons>
|
|
91
|
+
</ion-toolbar>
|
|
92
|
+
<ion-toolbar>
|
|
93
|
+
<ion-buttons slot="secondary">
|
|
94
|
+
<ion-button fill="solid" class="ion-activated">
|
|
95
|
+
<ion-icon slot="start" name="person-circle"></ion-icon>
|
|
96
|
+
Solid
|
|
97
|
+
</ion-button>
|
|
98
|
+
</ion-buttons>
|
|
99
|
+
<ion-title>Solid Activated</ion-title>
|
|
100
|
+
<ion-buttons slot="primary">
|
|
101
|
+
<ion-button fill="solid" color="secondary" class="ion-activated">
|
|
102
|
+
Help
|
|
103
|
+
<ion-icon slot="end" name="help-circle"></ion-icon>
|
|
104
|
+
</ion-button>
|
|
105
|
+
</ion-buttons>
|
|
106
|
+
</ion-toolbar>
|
|
107
|
+
<ion-toolbar>
|
|
108
|
+
<ion-buttons slot="secondary">
|
|
109
|
+
<ion-button fill="outline">
|
|
110
|
+
<ion-icon slot="start" name="star"></ion-icon>
|
|
111
|
+
Star
|
|
112
|
+
</ion-button>
|
|
113
|
+
</ion-buttons>
|
|
114
|
+
<ion-title>Outline</ion-title>
|
|
115
|
+
<ion-buttons slot="primary">
|
|
116
|
+
<ion-button color="secondary" fill="outline">
|
|
117
|
+
Info
|
|
118
|
+
<ion-icon slot="end" name="information-circle"></ion-icon>
|
|
119
|
+
</ion-button>
|
|
120
|
+
</ion-buttons>
|
|
121
|
+
</ion-toolbar>
|
|
122
|
+
<ion-toolbar>
|
|
123
|
+
<ion-buttons slot="secondary">
|
|
124
|
+
<ion-button fill="outline" class="ion-activated">
|
|
125
|
+
<ion-icon slot="start" name="star"></ion-icon>
|
|
126
|
+
Star
|
|
127
|
+
</ion-button>
|
|
128
|
+
</ion-buttons>
|
|
129
|
+
<ion-title>Outline Activated</ion-title>
|
|
130
|
+
<ion-buttons slot="primary">
|
|
131
|
+
<ion-button color="secondary" fill="outline" class="ion-activated">
|
|
132
|
+
Info
|
|
133
|
+
<ion-icon slot="end" name="information-circle"></ion-icon>
|
|
134
|
+
</ion-button>
|
|
135
|
+
</ion-buttons>
|
|
136
|
+
</ion-toolbar>
|
|
137
|
+
</ion-header>
|
|
138
|
+
`, config);
|
|
11
139
|
const header = page.locator('ion-header');
|
|
12
|
-
await expect(header).toHaveScreenshot(screenshot(`toolbar-basic`));
|
|
140
|
+
await expect(header).toHaveScreenshot(screenshot(`toolbar-basic-text-icon-buttons`));
|
|
13
141
|
});
|
|
14
142
|
});
|
|
15
143
|
});
|
|
@@ -152,7 +152,7 @@ const trapKeyboardFocus = (ev, doc) => {
|
|
|
152
152
|
* behind the sheet should be focusable until
|
|
153
153
|
* the backdrop is enabled.
|
|
154
154
|
*/
|
|
155
|
-
if (lastOverlay.classList.contains(
|
|
155
|
+
if (lastOverlay.classList.contains(FOCUS_TRAP_DISABLE_CLASS)) {
|
|
156
156
|
return;
|
|
157
157
|
}
|
|
158
158
|
const trapScopedFocus = () => {
|
|
@@ -827,3 +827,4 @@ const revealOverlaysToScreenReaders = () => {
|
|
|
827
827
|
}
|
|
828
828
|
}
|
|
829
829
|
};
|
|
830
|
+
export const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
|