@ionic/core 8.0.1-dev.11714492860.17c00351 → 8.0.1-dev.11714496052.149681e5

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 (67) hide show
  1. package/components/index2.js +119 -1
  2. package/css/core.css +1 -1
  3. package/css/core.css.map +1 -1
  4. package/css/ionic.bundle.css +1 -1
  5. package/css/ionic.bundle.css.map +1 -1
  6. package/dist/cjs/{index-6d6ac424.js → index-be7cf657.js} +124 -6
  7. package/dist/cjs/index.cjs.js +4 -4
  8. package/dist/cjs/ion-app_8.cjs.entry.js +1 -1
  9. package/dist/cjs/ion-modal.cjs.entry.js +1 -1
  10. package/dist/cjs/ion-nav_2.cjs.entry.js +2 -1
  11. package/dist/cjs/ion-popover.cjs.entry.js +1 -1
  12. package/dist/cjs/{ios.transition-d4f0ca4e.js → ios.transition-b0e0575b.js} +3 -1
  13. package/dist/cjs/{md.transition-857328f3.js → md.transition-b22b61b7.js} +3 -1
  14. package/dist/collection/utils/focus-controller/index.js +112 -0
  15. package/dist/collection/utils/focus-controller/test/generic/focus-controller.e2e.js +52 -0
  16. package/dist/collection/utils/focus-controller/test/ionic/focus-controller.e2e.js +52 -0
  17. package/dist/collection/utils/transition/index.js +11 -1
  18. package/dist/docs.json +1 -1
  19. package/dist/esm/{index-f0d7371a.js → index-c9a90692.js} +121 -3
  20. package/dist/esm/index.js +4 -4
  21. package/dist/esm/ion-app_8.entry.js +1 -1
  22. package/dist/esm/ion-modal.entry.js +1 -1
  23. package/dist/esm/ion-nav_2.entry.js +2 -1
  24. package/dist/esm/ion-popover.entry.js +1 -1
  25. package/dist/esm/{ios.transition-71bfa932.js → ios.transition-0321a527.js} +3 -1
  26. package/dist/esm/{md.transition-86aef3c0.js → md.transition-57a06277.js} +3 -1
  27. package/dist/esm-es5/index-c9a90692.js +4 -0
  28. package/dist/esm-es5/index.js +1 -1
  29. package/dist/esm-es5/ion-app_8.entry.js +1 -1
  30. package/dist/esm-es5/ion-modal.entry.js +1 -1
  31. package/dist/esm-es5/ion-nav_2.entry.js +1 -1
  32. package/dist/esm-es5/ion-popover.entry.js +1 -1
  33. package/dist/esm-es5/ios.transition-0321a527.js +4 -0
  34. package/dist/esm-es5/md.transition-57a06277.js +4 -0
  35. package/dist/ionic/index.esm.js +1 -1
  36. package/dist/ionic/ionic.esm.js +1 -1
  37. package/dist/ionic/{p-e22c0afe.system.js → p-0cd59e4e.system.js} +1 -1
  38. package/dist/ionic/p-1fbe9447.system.js +4 -0
  39. package/dist/ionic/p-30a1fb3a.js +4 -0
  40. package/dist/ionic/{p-b1b68c3e.entry.js → p-3328cd28.entry.js} +1 -1
  41. package/dist/ionic/p-3ebbbd37.js +4 -0
  42. package/dist/ionic/{p-2a517297.system.entry.js → p-72b181e2.system.entry.js} +1 -1
  43. package/dist/ionic/{p-90f77fc2.entry.js → p-7a152fab.entry.js} +1 -1
  44. package/dist/ionic/{p-d724072e.system.entry.js → p-80270af4.system.entry.js} +1 -1
  45. package/dist/ionic/p-944dd52a.system.js +4 -0
  46. package/dist/ionic/p-aa2c2a8b.system.entry.js +4 -0
  47. package/dist/ionic/p-ae9ebfd1.entry.js +4 -0
  48. package/dist/ionic/p-b79b8d53.js +4 -0
  49. package/dist/ionic/p-c27aef92.system.js +4 -0
  50. package/dist/ionic/{p-70e5135e.system.entry.js → p-d38c209e.system.entry.js} +1 -1
  51. package/dist/ionic/{p-56932fb6.entry.js → p-d76c8ebd.entry.js} +1 -1
  52. package/dist/ionic/p-d8d6ebc0.system.js +1 -1
  53. package/dist/types/utils/config.d.ts +9 -0
  54. package/dist/types/utils/focus-controller/index.d.ts +13 -0
  55. package/hydrate/index.js +117 -1
  56. package/package.json +1 -1
  57. package/dist/esm-es5/index-f0d7371a.js +0 -4
  58. package/dist/esm-es5/ios.transition-71bfa932.js +0 -4
  59. package/dist/esm-es5/md.transition-86aef3c0.js +0 -4
  60. package/dist/ionic/p-0e713efe.js +0 -4
  61. package/dist/ionic/p-2613c305.system.js +0 -4
  62. package/dist/ionic/p-4de53118.js +0 -4
  63. package/dist/ionic/p-510cb8e6.system.js +0 -4
  64. package/dist/ionic/p-5f28cb75.js +0 -4
  65. package/dist/ionic/p-91cb391a.entry.js +0 -4
  66. package/dist/ionic/p-9fa5ff32.system.js +0 -4
  67. package/dist/ionic/p-ae6f15b0.system.entry.js +0 -4
@@ -0,0 +1,112 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { config } from "../../global/config";
5
+ import { printIonWarning } from "../logging/index";
6
+ /**
7
+ * Moves focus to a specified element. Note that we do not remove the tabindex
8
+ * because that can result in an unintentional blur. Non-focusables can't be
9
+ * focused, so the body will get focused again.
10
+ */
11
+ const moveFocus = (el) => {
12
+ el.tabIndex = -1;
13
+ el.focus();
14
+ };
15
+ /**
16
+ * Elements that are hidden using `display: none` should not be focused even if
17
+ * they are present in the DOM.
18
+ */
19
+ const isVisible = (el) => {
20
+ return el.offsetParent !== null;
21
+ };
22
+ /**
23
+ * The focus controller allows us to manage focus within a view so assistive
24
+ * technologies can inform users of changes to the navigation state. Traditional
25
+ * native apps have a way of informing assistive technology about a navigation
26
+ * state change. Mobile browsers have this too, but only when doing a full page
27
+ * load. In a single page app we do not do that, so we need to build this
28
+ * integration ourselves.
29
+ */
30
+ export const createFocusController = () => {
31
+ const saveViewFocus = (referenceEl) => {
32
+ const focusManagerEnabled = config.get('focusManagerPriority', false);
33
+ /**
34
+ * When going back to a previously visited page focus should typically be moved
35
+ * back to the element that was last focused when the user was on this view.
36
+ */
37
+ if (focusManagerEnabled) {
38
+ const activeEl = document.activeElement;
39
+ if (activeEl !== null && (referenceEl === null || referenceEl === void 0 ? void 0 : referenceEl.contains(activeEl))) {
40
+ activeEl.setAttribute(LAST_FOCUS, 'true');
41
+ }
42
+ }
43
+ };
44
+ const setViewFocus = (referenceEl) => {
45
+ const focusManagerPriorities = config.get('focusManagerPriority', false);
46
+ /**
47
+ * If the focused element is a descendant of the referenceEl then it's possible
48
+ * that the app developer manually moved focus, so we do not want to override that.
49
+ * This can happen with inputs the are focused when a view transitions in.
50
+ */
51
+ if (Array.isArray(focusManagerPriorities) && !referenceEl.contains(document.activeElement)) {
52
+ /**
53
+ * When going back to a previously visited view focus should always be moved back
54
+ * to the element that the user was last focused on when they were on this view.
55
+ */
56
+ const lastFocus = referenceEl.querySelector(`[${LAST_FOCUS}]`);
57
+ if (lastFocus && isVisible(lastFocus)) {
58
+ moveFocus(lastFocus);
59
+ return;
60
+ }
61
+ for (const priority of focusManagerPriorities) {
62
+ /**
63
+ * For each recognized case (excluding the default case) make sure to return
64
+ * so that the fallback focus behavior does not run.
65
+ *
66
+ * We intentionally query for specific roles/semantic elements so that the
67
+ * transition manager can work with both Ionic and non-Ionic UI components.
68
+ *
69
+ * If new selectors are added, be sure to remove the outline ring by adding
70
+ * new selectors to rule in core.scss.
71
+ */
72
+ switch (priority) {
73
+ case 'content':
74
+ const content = referenceEl.querySelector('main, [role="main"]');
75
+ if (content && isVisible(content)) {
76
+ moveFocus(content);
77
+ return;
78
+ }
79
+ break;
80
+ case 'heading':
81
+ const headingOne = referenceEl.querySelector('h1, [role="heading"][aria-level="1"]');
82
+ if (headingOne && isVisible(headingOne)) {
83
+ moveFocus(headingOne);
84
+ return;
85
+ }
86
+ break;
87
+ case 'banner':
88
+ const header = referenceEl.querySelector('header, [role="banner"]');
89
+ if (header && isVisible(header)) {
90
+ moveFocus(header);
91
+ return;
92
+ }
93
+ break;
94
+ default:
95
+ printIonWarning(`Unrecognized focus manager priority value ${priority}`);
96
+ break;
97
+ }
98
+ }
99
+ /**
100
+ * If there is nothing to focus then focus the page so focus at least moves to
101
+ * the correct view. The browser will then determine where within the page to
102
+ * move focus to.
103
+ */
104
+ moveFocus(referenceEl);
105
+ }
106
+ };
107
+ return {
108
+ saveViewFocus,
109
+ setViewFocus,
110
+ };
111
+ };
112
+ const LAST_FOCUS = 'ion-last-focus';
@@ -0,0 +1,52 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { expect } from "@playwright/test";
5
+ import { configs, test } from "../../../test/playwright/index";
6
+ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
7
+ test.describe(title('focus controller: generic components'), () => {
8
+ test.beforeEach(async ({ page }) => {
9
+ await page.goto('/src/utils/focus-controller/test/generic', config);
10
+ });
11
+ test('should focus heading', async ({ page }) => {
12
+ const goToPageOneButton = page.locator('page-root button.page-one');
13
+ const nav = page.locator('ion-nav');
14
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
15
+ // Focus heading on Page One
16
+ await goToPageOneButton.click();
17
+ await ionNavDidChange.next();
18
+ const pageOneTitle = page.locator('page-one h1');
19
+ await expect(pageOneTitle).toBeFocused();
20
+ });
21
+ test('should focus banner', async ({ page }) => {
22
+ const goToPageThreeButton = page.locator('page-root button.page-three');
23
+ const nav = page.locator('ion-nav');
24
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
25
+ const pageThreeHeader = page.locator('page-three header');
26
+ await goToPageThreeButton.click();
27
+ await ionNavDidChange.next();
28
+ await expect(pageThreeHeader).toBeFocused();
29
+ });
30
+ test('should focus content', async ({ page }) => {
31
+ const goToPageTwoButton = page.locator('page-root button.page-two');
32
+ const nav = page.locator('ion-nav');
33
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
34
+ const pageTwoContent = page.locator('page-two main');
35
+ await goToPageTwoButton.click();
36
+ await ionNavDidChange.next();
37
+ await expect(pageTwoContent).toBeFocused();
38
+ });
39
+ test('should return focus when going back', async ({ page, browserName }) => {
40
+ test.skip(browserName === 'webkit', 'Desktop Safari does not consider buttons to be focusable');
41
+ const goToPageOneButton = page.locator('page-root button.page-one');
42
+ const nav = page.locator('ion-nav');
43
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
44
+ const pageOneBackButton = page.locator('page-one ion-back-button');
45
+ await goToPageOneButton.click();
46
+ await ionNavDidChange.next();
47
+ await pageOneBackButton.click();
48
+ await ionNavDidChange.next();
49
+ await expect(goToPageOneButton).toBeFocused();
50
+ });
51
+ });
52
+ });
@@ -0,0 +1,52 @@
1
+ /*!
2
+ * (C) Ionic http://ionicframework.com - MIT License
3
+ */
4
+ import { expect } from "@playwright/test";
5
+ import { configs, test } from "../../../test/playwright/index";
6
+ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
7
+ test.describe(title('focus controller: ionic components'), () => {
8
+ test.beforeEach(async ({ page }) => {
9
+ await page.goto('/src/utils/focus-controller/test/ionic', config);
10
+ });
11
+ test('should focus heading', async ({ page }) => {
12
+ const goToPageOneButton = page.locator('page-root ion-button.page-one');
13
+ const nav = page.locator('ion-nav');
14
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
15
+ // Focus heading on Page One
16
+ await goToPageOneButton.click();
17
+ await ionNavDidChange.next();
18
+ const pageOneTitle = page.locator('page-one ion-title');
19
+ await expect(pageOneTitle).toBeFocused();
20
+ });
21
+ test('should focus banner', async ({ page }) => {
22
+ const goToPageThreeButton = page.locator('page-root ion-button.page-three');
23
+ const nav = page.locator('ion-nav');
24
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
25
+ const pageThreeHeader = page.locator('page-three ion-header');
26
+ await goToPageThreeButton.click();
27
+ await ionNavDidChange.next();
28
+ await expect(pageThreeHeader).toBeFocused();
29
+ });
30
+ test('should focus content', async ({ page }) => {
31
+ const goToPageTwoButton = page.locator('page-root ion-button.page-two');
32
+ const nav = page.locator('ion-nav');
33
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
34
+ const pageTwoContent = page.locator('page-two ion-content');
35
+ await goToPageTwoButton.click();
36
+ await ionNavDidChange.next();
37
+ await expect(pageTwoContent).toBeFocused();
38
+ });
39
+ test('should return focus when going back', async ({ page, browserName }) => {
40
+ test.skip(browserName === 'webkit', 'Desktop Safari does not consider buttons to be focusable');
41
+ const goToPageOneButton = page.locator('page-root ion-button.page-one');
42
+ const nav = page.locator('ion-nav');
43
+ const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange');
44
+ const pageOneBackButton = page.locator('page-one ion-back-button');
45
+ await goToPageOneButton.click();
46
+ await ionNavDidChange.next();
47
+ await pageOneBackButton.click();
48
+ await ionNavDidChange.next();
49
+ await expect(goToPageOneButton).toBeFocused();
50
+ });
51
+ });
52
+ });
@@ -1,11 +1,14 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
+ import { config } from "../../global/config";
4
5
  import { Build, writeTask } from "@stencil/core";
5
6
  import { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE, } from "../../components/nav/constants";
7
+ import { createFocusController } from "../focus-controller";
6
8
  import { raf } from "../helpers";
7
9
  const iosTransitionAnimation = () => import('./ios.transition');
8
10
  const mdTransitionAnimation = () => import('./md.transition');
11
+ const focusController = createFocusController();
9
12
  // TODO(FW-2832): types
10
13
  export const transition = (opts) => {
11
14
  return new Promise((resolve, reject) => {
@@ -27,6 +30,7 @@ export const transition = (opts) => {
27
30
  const beforeTransition = (opts) => {
28
31
  const enteringEl = opts.enteringEl;
29
32
  const leavingEl = opts.leavingEl;
33
+ focusController.saveViewFocus(leavingEl);
30
34
  setZIndex(enteringEl, leavingEl, opts.direction);
31
35
  if (opts.showGoBack) {
32
36
  enteringEl.classList.add('can-go-back');
@@ -61,6 +65,7 @@ const afterTransition = (opts) => {
61
65
  leavingEl.classList.remove('ion-page-invisible');
62
66
  leavingEl.style.removeProperty('pointer-events');
63
67
  }
68
+ focusController.setViewFocus(enteringEl);
64
69
  };
65
70
  const getAnimationBuilder = async (opts) => {
66
71
  if (!opts.leavingEl || !opts.animated || opts.duration === 0) {
@@ -93,7 +98,12 @@ const animation = async (animationBuilder, opts) => {
93
98
  const noAnimation = async (opts) => {
94
99
  const enteringEl = opts.enteringEl;
95
100
  const leavingEl = opts.leavingEl;
96
- await waitForReady(opts, false);
101
+ const focusManagerEnabled = config.get('focusManagerPriority', false);
102
+ /**
103
+ * If the focus manager is enabled then we need to wait for Ionic components to be
104
+ * rendered otherwise the component to focus may not be focused because it is hidden.
105
+ */
106
+ await waitForReady(opts, focusManagerEnabled);
97
107
  fireWillEvents(enteringEl, leavingEl);
98
108
  fireDidEvents(enteringEl, leavingEl);
99
109
  return {
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2024-04-30T16:03:00",
2
+ "timestamp": "2024-04-30T16:56:15",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.16.0",
@@ -1,7 +1,9 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
+ import { c as config } from './ionic-global-e6c98cd0.js';
4
5
  import { w as writeTask, B as Build } from './index-bcd8859b.js';
6
+ import { p as printIonWarning } from './index-9b0d46f4.js';
5
7
  import { r as raf } from './helpers-da915de8.js';
6
8
 
7
9
  const LIFECYCLE_WILL_ENTER = 'ionViewWillEnter';
@@ -10,8 +12,117 @@ const LIFECYCLE_WILL_LEAVE = 'ionViewWillLeave';
10
12
  const LIFECYCLE_DID_LEAVE = 'ionViewDidLeave';
11
13
  const LIFECYCLE_WILL_UNLOAD = 'ionViewWillUnload';
12
14
 
13
- const iosTransitionAnimation = () => import('./ios.transition-71bfa932.js');
14
- const mdTransitionAnimation = () => import('./md.transition-86aef3c0.js');
15
+ /**
16
+ * Moves focus to a specified element. Note that we do not remove the tabindex
17
+ * because that can result in an unintentional blur. Non-focusables can't be
18
+ * focused, so the body will get focused again.
19
+ */
20
+ const moveFocus = (el) => {
21
+ el.tabIndex = -1;
22
+ el.focus();
23
+ };
24
+ /**
25
+ * Elements that are hidden using `display: none` should not be focused even if
26
+ * they are present in the DOM.
27
+ */
28
+ const isVisible = (el) => {
29
+ return el.offsetParent !== null;
30
+ };
31
+ /**
32
+ * The focus controller allows us to manage focus within a view so assistive
33
+ * technologies can inform users of changes to the navigation state. Traditional
34
+ * native apps have a way of informing assistive technology about a navigation
35
+ * state change. Mobile browsers have this too, but only when doing a full page
36
+ * load. In a single page app we do not do that, so we need to build this
37
+ * integration ourselves.
38
+ */
39
+ const createFocusController = () => {
40
+ const saveViewFocus = (referenceEl) => {
41
+ const focusManagerEnabled = config.get('focusManagerPriority', false);
42
+ /**
43
+ * When going back to a previously visited page focus should typically be moved
44
+ * back to the element that was last focused when the user was on this view.
45
+ */
46
+ if (focusManagerEnabled) {
47
+ const activeEl = document.activeElement;
48
+ if (activeEl !== null && (referenceEl === null || referenceEl === void 0 ? void 0 : referenceEl.contains(activeEl))) {
49
+ activeEl.setAttribute(LAST_FOCUS, 'true');
50
+ }
51
+ }
52
+ };
53
+ const setViewFocus = (referenceEl) => {
54
+ const focusManagerPriorities = config.get('focusManagerPriority', false);
55
+ /**
56
+ * If the focused element is a descendant of the referenceEl then it's possible
57
+ * that the app developer manually moved focus, so we do not want to override that.
58
+ * This can happen with inputs the are focused when a view transitions in.
59
+ */
60
+ if (Array.isArray(focusManagerPriorities) && !referenceEl.contains(document.activeElement)) {
61
+ /**
62
+ * When going back to a previously visited view focus should always be moved back
63
+ * to the element that the user was last focused on when they were on this view.
64
+ */
65
+ const lastFocus = referenceEl.querySelector(`[${LAST_FOCUS}]`);
66
+ if (lastFocus && isVisible(lastFocus)) {
67
+ moveFocus(lastFocus);
68
+ return;
69
+ }
70
+ for (const priority of focusManagerPriorities) {
71
+ /**
72
+ * For each recognized case (excluding the default case) make sure to return
73
+ * so that the fallback focus behavior does not run.
74
+ *
75
+ * We intentionally query for specific roles/semantic elements so that the
76
+ * transition manager can work with both Ionic and non-Ionic UI components.
77
+ *
78
+ * If new selectors are added, be sure to remove the outline ring by adding
79
+ * new selectors to rule in core.scss.
80
+ */
81
+ switch (priority) {
82
+ case 'content':
83
+ const content = referenceEl.querySelector('main, [role="main"]');
84
+ if (content && isVisible(content)) {
85
+ moveFocus(content);
86
+ return;
87
+ }
88
+ break;
89
+ case 'heading':
90
+ const headingOne = referenceEl.querySelector('h1, [role="heading"][aria-level="1"]');
91
+ if (headingOne && isVisible(headingOne)) {
92
+ moveFocus(headingOne);
93
+ return;
94
+ }
95
+ break;
96
+ case 'banner':
97
+ const header = referenceEl.querySelector('header, [role="banner"]');
98
+ if (header && isVisible(header)) {
99
+ moveFocus(header);
100
+ return;
101
+ }
102
+ break;
103
+ default:
104
+ printIonWarning(`Unrecognized focus manager priority value ${priority}`);
105
+ break;
106
+ }
107
+ }
108
+ /**
109
+ * If there is nothing to focus then focus the page so focus at least moves to
110
+ * the correct view. The browser will then determine where within the page to
111
+ * move focus to.
112
+ */
113
+ moveFocus(referenceEl);
114
+ }
115
+ };
116
+ return {
117
+ saveViewFocus,
118
+ setViewFocus,
119
+ };
120
+ };
121
+ const LAST_FOCUS = 'ion-last-focus';
122
+
123
+ const iosTransitionAnimation = () => import('./ios.transition-0321a527.js');
124
+ const mdTransitionAnimation = () => import('./md.transition-57a06277.js');
125
+ const focusController = createFocusController();
15
126
  // TODO(FW-2832): types
16
127
  const transition = (opts) => {
17
128
  return new Promise((resolve, reject) => {
@@ -33,6 +144,7 @@ const transition = (opts) => {
33
144
  const beforeTransition = (opts) => {
34
145
  const enteringEl = opts.enteringEl;
35
146
  const leavingEl = opts.leavingEl;
147
+ focusController.saveViewFocus(leavingEl);
36
148
  setZIndex(enteringEl, leavingEl, opts.direction);
37
149
  if (opts.showGoBack) {
38
150
  enteringEl.classList.add('can-go-back');
@@ -67,6 +179,7 @@ const afterTransition = (opts) => {
67
179
  leavingEl.classList.remove('ion-page-invisible');
68
180
  leavingEl.style.removeProperty('pointer-events');
69
181
  }
182
+ focusController.setViewFocus(enteringEl);
70
183
  };
71
184
  const getAnimationBuilder = async (opts) => {
72
185
  if (!opts.leavingEl || !opts.animated || opts.duration === 0) {
@@ -99,7 +212,12 @@ const animation = async (animationBuilder, opts) => {
99
212
  const noAnimation = async (opts) => {
100
213
  const enteringEl = opts.enteringEl;
101
214
  const leavingEl = opts.leavingEl;
102
- await waitForReady(opts, false);
215
+ const focusManagerEnabled = config.get('focusManagerPriority', false);
216
+ /**
217
+ * If the focus manager is enabled then we need to wait for Ionic components to be
218
+ * rendered otherwise the component to focus may not be focused because it is hidden.
219
+ */
220
+ await waitForReady(opts, focusManagerEnabled);
103
221
  fireWillEvents(enteringEl, leavingEl);
104
222
  fireDidEvents(enteringEl, leavingEl);
105
223
  return {
package/dist/esm/index.js CHANGED
@@ -2,9 +2,9 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  export { c as createAnimation } from './animation-eab5a4ca.js';
5
- export { a as LIFECYCLE_DID_ENTER, c as LIFECYCLE_DID_LEAVE, L as LIFECYCLE_WILL_ENTER, b as LIFECYCLE_WILL_LEAVE, d as LIFECYCLE_WILL_UNLOAD, g as getIonPageElement } from './index-f0d7371a.js';
6
- export { iosTransitionAnimation } from './ios.transition-71bfa932.js';
7
- export { mdTransitionAnimation } from './md.transition-86aef3c0.js';
5
+ export { a as LIFECYCLE_DID_ENTER, c as LIFECYCLE_DID_LEAVE, L as LIFECYCLE_WILL_ENTER, b as LIFECYCLE_WILL_LEAVE, d as LIFECYCLE_WILL_UNLOAD, g as getIonPageElement } from './index-c9a90692.js';
6
+ export { iosTransitionAnimation } from './ios.transition-0321a527.js';
7
+ export { mdTransitionAnimation } from './md.transition-57a06277.js';
8
8
  export { g as getTimeGivenProgression } from './cubic-bezier-fe2083dc.js';
9
9
  export { createGesture } from './index-39782642.js';
10
10
  export { g as getPlatforms, i as initialize, a as isPlatform } from './ionic-global-e6c98cd0.js';
@@ -15,9 +15,9 @@ export { m as menuController } from './index-56d90da9.js';
15
15
  export { b as actionSheetController, a as alertController, l as loadingController, m as modalController, p as pickerController, c as popoverController, t as toastController } from './overlays-1eac28e2.js';
16
16
  import './index-a5d50daf.js';
17
17
  import './index-bcd8859b.js';
18
+ import './index-9b0d46f4.js';
18
19
  import './gesture-controller-314a54f6.js';
19
20
  import './hardware-back-button-ba8f64c2.js';
20
- import './index-9b0d46f4.js';
21
21
  import './framework-delegate-63d1a679.js';
22
22
 
23
23
  const IonicSlides = (opts) => {
@@ -13,7 +13,7 @@ import { c as createKeyboardController } from './keyboard-controller-ec5c2bfa.js
13
13
  import { g as getTimeGivenProgression } from './cubic-bezier-fe2083dc.js';
14
14
  import { a as attachComponent, d as detachComponent } from './framework-delegate-63d1a679.js';
15
15
  import { c as createLockController } from './lock-controller-316928be.js';
16
- import { t as transition } from './index-f0d7371a.js';
16
+ import { t as transition } from './index-c9a90692.js';
17
17
  import './index-a5d50daf.js';
18
18
  import './keyboard-73175e24.js';
19
19
  import './capacitor-59395cbd.js';
@@ -10,7 +10,7 @@ import { p as printIonWarning } from './index-9b0d46f4.js';
10
10
  import { g as getCapacitor } from './capacitor-59395cbd.js';
11
11
  import { G as GESTURE, O as OVERLAY_GESTURE_PRIORITY, F as FOCUS_TRAP_DISABLE_CLASS, e as createTriggerController, B as BACKDROP, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod } from './overlays-1eac28e2.js';
12
12
  import { g as getClassMap } from './theme-01f3f29c.js';
13
- import { e as deepReady, w as waitForMount } from './index-f0d7371a.js';
13
+ import { e as deepReady, w as waitForMount } from './index-c9a90692.js';
14
14
  import { b as getIonMode, c as config } from './ionic-global-e6c98cd0.js';
15
15
  import { KEYBOARD_DID_OPEN } from './keyboard-52278bd7.js';
16
16
  import { c as createAnimation } from './animation-eab5a4ca.js';
@@ -4,9 +4,10 @@
4
4
  import { r as registerInstance, d as createEvent, h, i as getElement, f as Host } from './index-bcd8859b.js';
5
5
  import { g as getTimeGivenProgression } from './cubic-bezier-fe2083dc.js';
6
6
  import { m as assert, s as shallowEqualStringMap } from './helpers-da915de8.js';
7
- import { l as lifecycle, t as transition, s as setPageHidden, d as LIFECYCLE_WILL_UNLOAD, b as LIFECYCLE_WILL_LEAVE, c as LIFECYCLE_DID_LEAVE } from './index-f0d7371a.js';
7
+ import { l as lifecycle, t as transition, s as setPageHidden, d as LIFECYCLE_WILL_UNLOAD, b as LIFECYCLE_WILL_LEAVE, c as LIFECYCLE_DID_LEAVE } from './index-c9a90692.js';
8
8
  import { b as getIonMode, c as config } from './ionic-global-e6c98cd0.js';
9
9
  import { a as attachComponent } from './framework-delegate-63d1a679.js';
10
+ import './index-9b0d46f4.js';
10
11
 
11
12
  const VIEW_STATE_NEW = 1;
12
13
  const VIEW_STATE_ATTACHED = 2;
@@ -9,7 +9,7 @@ import { c as createLockController } from './lock-controller-316928be.js';
9
9
  import { p as printIonWarning } from './index-9b0d46f4.js';
10
10
  import { b as getIonMode, a as isPlatform } from './ionic-global-e6c98cd0.js';
11
11
  import { g as getClassMap } from './theme-01f3f29c.js';
12
- import { e as deepReady, w as waitForMount } from './index-f0d7371a.js';
12
+ import { e as deepReady, w as waitForMount } from './index-c9a90692.js';
13
13
  import { c as createAnimation } from './animation-eab5a4ca.js';
14
14
  import './index-a5d50daf.js';
15
15
  import './hardware-back-button-ba8f64c2.js';
@@ -2,9 +2,11 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { c as createAnimation } from './animation-eab5a4ca.js';
5
- import { g as getIonPageElement } from './index-f0d7371a.js';
5
+ import { g as getIonPageElement } from './index-c9a90692.js';
6
6
  import './index-a5d50daf.js';
7
+ import './ionic-global-e6c98cd0.js';
7
8
  import './index-bcd8859b.js';
9
+ import './index-9b0d46f4.js';
8
10
  import './helpers-da915de8.js';
9
11
 
10
12
  const DURATION = 540;
@@ -2,9 +2,11 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { c as createAnimation } from './animation-eab5a4ca.js';
5
- import { g as getIonPageElement } from './index-f0d7371a.js';
5
+ import { g as getIonPageElement } from './index-c9a90692.js';
6
6
  import './index-a5d50daf.js';
7
+ import './ionic-global-e6c98cd0.js';
7
8
  import './index-bcd8859b.js';
9
+ import './index-9b0d46f4.js';
8
10
  import './helpers-da915de8.js';
9
11
 
10
12
  const mdTransitionAnimation = (_, opts) => {
@@ -0,0 +1,4 @@
1
+ import{__awaiter,__generator}from"tslib";
2
+ /*!
3
+ * (C) Ionic http://ionicframework.com - MIT License
4
+ */import{c as config}from"./ionic-global-e6c98cd0.js";import{w as writeTask,B as Build}from"./index-bcd8859b.js";import{p as printIonWarning}from"./index-9b0d46f4.js";import{r as raf}from"./helpers-da915de8.js";var LIFECYCLE_WILL_ENTER="ionViewWillEnter";var LIFECYCLE_DID_ENTER="ionViewDidEnter";var LIFECYCLE_WILL_LEAVE="ionViewWillLeave";var LIFECYCLE_DID_LEAVE="ionViewDidLeave";var LIFECYCLE_WILL_UNLOAD="ionViewWillUnload";var moveFocus=function(n){n.tabIndex=-1;n.focus()};var isVisible=function(n){return n.offsetParent!==null};var createFocusController=function(){var n=function(n){var e=config.get("focusManagerPriority",false);if(e){var r=document.activeElement;if(r!==null&&(n===null||n===void 0?void 0:n.contains(r))){r.setAttribute(LAST_FOCUS,"true")}}};var e=function(n){var e=config.get("focusManagerPriority",false);if(Array.isArray(e)&&!n.contains(document.activeElement)){var r=n.querySelector("[".concat(LAST_FOCUS,"]"));if(r&&isVisible(r)){moveFocus(r);return}for(var i=0,t=e;i<t.length;i++){var a=t[i];switch(a){case"content":var o=n.querySelector('main, [role="main"]');if(o&&isVisible(o)){moveFocus(o);return}break;case"heading":var s=n.querySelector('h1, [role="heading"][aria-level="1"]');if(s&&isVisible(s)){moveFocus(s);return}break;case"banner":var u=n.querySelector('header, [role="banner"]');if(u&&isVisible(u)){moveFocus(u);return}break;default:printIonWarning("Unrecognized focus manager priority value ".concat(a));break}}moveFocus(n)}};return{saveViewFocus:n,setViewFocus:e}};var LAST_FOCUS="ion-last-focus";var iosTransitionAnimation=function(){return import("./ios.transition-0321a527.js")};var mdTransitionAnimation=function(){return import("./md.transition-57a06277.js")};var focusController=createFocusController();var transition=function(n){return new Promise((function(e,r){writeTask((function(){beforeTransition(n);runTransition(n).then((function(r){if(r.animation){r.animation.destroy()}afterTransition(n);e(r)}),(function(e){afterTransition(n);r(e)}))}))}))};var beforeTransition=function(n){var e=n.enteringEl;var r=n.leavingEl;focusController.saveViewFocus(r);setZIndex(e,r,n.direction);if(n.showGoBack){e.classList.add("can-go-back")}else{e.classList.remove("can-go-back")}setPageHidden(e,false);e.style.setProperty("pointer-events","none");if(r){setPageHidden(r,false);r.style.setProperty("pointer-events","none")}};var runTransition=function(n){return __awaiter(void 0,void 0,void 0,(function(){var e,r;return __generator(this,(function(i){switch(i.label){case 0:return[4,getAnimationBuilder(n)];case 1:e=i.sent();r=e&&Build.isBrowser?animation(e,n):noAnimation(n);return[2,r]}}))}))};var afterTransition=function(n){var e=n.enteringEl;var r=n.leavingEl;e.classList.remove("ion-page-invisible");e.style.removeProperty("pointer-events");if(r!==undefined){r.classList.remove("ion-page-invisible");r.style.removeProperty("pointer-events")}focusController.setViewFocus(e)};var getAnimationBuilder=function(n){return __awaiter(void 0,void 0,void 0,(function(){var e,r;return __generator(this,(function(i){switch(i.label){case 0:if(!n.leavingEl||!n.animated||n.duration===0){return[2,undefined]}if(n.animationBuilder){return[2,n.animationBuilder]}if(!(n.mode==="ios"))return[3,2];return[4,iosTransitionAnimation()];case 1:r=i.sent().iosTransitionAnimation;return[3,4];case 2:return[4,mdTransitionAnimation()];case 3:r=i.sent().mdTransitionAnimation;i.label=4;case 4:e=r;return[2,e]}}))}))};var animation=function(n,e){return __awaiter(void 0,void 0,void 0,(function(){var r,i;return __generator(this,(function(t){switch(t.label){case 0:return[4,waitForReady(e,true)];case 1:t.sent();r=n(e.baseEl,e);fireWillEvents(e.enteringEl,e.leavingEl);return[4,playTransition(r,e)];case 2:i=t.sent();if(e.progressCallback){e.progressCallback(undefined)}if(i){fireDidEvents(e.enteringEl,e.leavingEl)}return[2,{hasCompleted:i,animation:r}]}}))}))};var noAnimation=function(n){return __awaiter(void 0,void 0,void 0,(function(){var e,r,i;return __generator(this,(function(t){switch(t.label){case 0:e=n.enteringEl;r=n.leavingEl;i=config.get("focusManagerPriority",false);return[4,waitForReady(n,i)];case 1:t.sent();fireWillEvents(e,r);fireDidEvents(e,r);return[2,{hasCompleted:true}]}}))}))};var waitForReady=function(n,e){return __awaiter(void 0,void 0,void 0,(function(){var r;return __generator(this,(function(i){switch(i.label){case 0:r=n.deepWait!==undefined?n.deepWait:e;if(!r)return[3,2];return[4,Promise.all([deepReady(n.enteringEl),deepReady(n.leavingEl)])];case 1:i.sent();i.label=2;case 2:return[4,notifyViewReady(n.viewIsReady,n.enteringEl)];case 3:i.sent();return[2]}}))}))};var notifyViewReady=function(n,e){return __awaiter(void 0,void 0,void 0,(function(){return __generator(this,(function(r){switch(r.label){case 0:if(!n)return[3,2];return[4,n(e)];case 1:r.sent();r.label=2;case 2:return[2]}}))}))};var playTransition=function(n,e){var r=e.progressCallback;var i=new Promise((function(e){n.onFinish((function(n){return e(n===1)}))}));if(r){n.progressStart(true);r(n)}else{n.play()}return i};var fireWillEvents=function(n,e){lifecycle(e,LIFECYCLE_WILL_LEAVE);lifecycle(n,LIFECYCLE_WILL_ENTER)};var fireDidEvents=function(n,e){lifecycle(n,LIFECYCLE_DID_ENTER);lifecycle(e,LIFECYCLE_DID_LEAVE)};var lifecycle=function(n,e){if(n){var r=new CustomEvent(e,{bubbles:false,cancelable:false});n.dispatchEvent(r)}};var waitForMount=function(){return new Promise((function(n){return raf((function(){return raf((function(){return n()}))}))}))};var deepReady=function(n){return __awaiter(void 0,void 0,void 0,(function(){var e,r,i;return __generator(this,(function(t){switch(t.label){case 0:e=n;if(!e)return[3,6];if(!(e.componentOnReady!=null))return[3,2];return[4,e.componentOnReady()];case 1:r=t.sent();if(r!=null){return[2]}return[3,4];case 2:if(!(e.__registerHost!=null))return[3,4];i=new Promise((function(n){return raf(n)}));return[4,i];case 3:t.sent();return[2];case 4:return[4,Promise.all(Array.from(e.children).map(deepReady))];case 5:t.sent();t.label=6;case 6:return[2]}}))}))};var setPageHidden=function(n,e){if(e){n.setAttribute("aria-hidden","true");n.classList.add("ion-page-hidden")}else{n.hidden=false;n.removeAttribute("aria-hidden");n.classList.remove("ion-page-hidden")}};var setZIndex=function(n,e,r){if(n!==undefined){n.style.zIndex=r==="back"?"99":"101"}if(e!==undefined){e.style.zIndex="100"}};var getIonPageElement=function(n){if(n.classList.contains("ion-page")){return n}var e=n.querySelector(":scope > .ion-page, :scope > ion-nav, :scope > ion-tabs");if(e){return e}return n};export{LIFECYCLE_WILL_ENTER as L,LIFECYCLE_DID_ENTER as a,LIFECYCLE_WILL_LEAVE as b,LIFECYCLE_DID_LEAVE as c,LIFECYCLE_WILL_UNLOAD as d,deepReady as e,getIonPageElement as g,lifecycle as l,setPageHidden as s,transition as t,waitForMount as w};
@@ -1,4 +1,4 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- export{c as createAnimation}from"./animation-eab5a4ca.js";export{a as LIFECYCLE_DID_ENTER,c as LIFECYCLE_DID_LEAVE,L as LIFECYCLE_WILL_ENTER,b as LIFECYCLE_WILL_LEAVE,d as LIFECYCLE_WILL_UNLOAD,g as getIonPageElement}from"./index-f0d7371a.js";export{iosTransitionAnimation}from"./ios.transition-71bfa932.js";export{mdTransitionAnimation}from"./md.transition-86aef3c0.js";export{g as getTimeGivenProgression}from"./cubic-bezier-fe2083dc.js";export{createGesture}from"./index-39782642.js";export{g as getPlatforms,i as initialize,a as isPlatform}from"./ionic-global-e6c98cd0.js";export{c as componentOnReady}from"./helpers-da915de8.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./config-49c88215.js";export{o as openURL}from"./theme-01f3f29c.js";export{m as menuController}from"./index-56d90da9.js";export{b as actionSheetController,a as alertController,l as loadingController,m as modalController,p as pickerController,c as popoverController,t as toastController}from"./overlays-1eac28e2.js";import"./index-a5d50daf.js";import"./index-bcd8859b.js";import"./gesture-controller-314a54f6.js";import"./hardware-back-button-ba8f64c2.js";import"./index-9b0d46f4.js";import"./framework-delegate-63d1a679.js";var IonicSlides=function(e){var o=e.swiper,t=e.extendParams;var s={effect:undefined,direction:"horizontal",initialSlide:0,loop:false,parallax:false,slidesPerView:1,spaceBetween:0,speed:300,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:false,slidesOffsetBefore:0,slidesOffsetAfter:0,touchEventsTarget:"container",freeMode:false,freeModeMomentum:true,freeModeMomentumRatio:1,freeModeMomentumBounce:true,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:false,freeModeMinimumVelocity:.02,autoHeight:false,setWrapperSize:false,zoom:{maxRatio:3,minRatio:1,toggle:false},touchRatio:1,touchAngle:45,simulateTouch:true,touchStartPreventDefault:false,shortSwipes:true,longSwipes:true,longSwipesRatio:.5,longSwipesMs:300,followFinger:true,threshold:0,touchMoveStopPropagation:true,touchReleaseOnEdges:false,iOSEdgeSwipeDetection:false,iOSEdgeSwipeThreshold:20,resistance:true,resistanceRatio:.85,watchSlidesProgress:false,watchSlidesVisibility:false,preventClicks:true,preventClicksPropagation:true,slideToClickedSlide:false,loopAdditionalSlides:0,noSwiping:true,runCallbacksOnInit:true,coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:true},flipEffect:{slideShadows:true,limitRotation:true},cubeEffect:{slideShadows:true,shadow:true,shadowOffset:20,shadowScale:.94},fadeEffect:{crossFade:false},a11y:{prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide"}};if(o.pagination){s.pagination={type:"bullets",clickable:false,hideOnClick:false}}if(o.scrollbar){s.scrollbar={hide:true}}t(s)};export{IonicSlides};
4
+ export{c as createAnimation}from"./animation-eab5a4ca.js";export{a as LIFECYCLE_DID_ENTER,c as LIFECYCLE_DID_LEAVE,L as LIFECYCLE_WILL_ENTER,b as LIFECYCLE_WILL_LEAVE,d as LIFECYCLE_WILL_UNLOAD,g as getIonPageElement}from"./index-c9a90692.js";export{iosTransitionAnimation}from"./ios.transition-0321a527.js";export{mdTransitionAnimation}from"./md.transition-57a06277.js";export{g as getTimeGivenProgression}from"./cubic-bezier-fe2083dc.js";export{createGesture}from"./index-39782642.js";export{g as getPlatforms,i as initialize,a as isPlatform}from"./ionic-global-e6c98cd0.js";export{c as componentOnReady}from"./helpers-da915de8.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./config-49c88215.js";export{o as openURL}from"./theme-01f3f29c.js";export{m as menuController}from"./index-56d90da9.js";export{b as actionSheetController,a as alertController,l as loadingController,m as modalController,p as pickerController,c as popoverController,t as toastController}from"./overlays-1eac28e2.js";import"./index-a5d50daf.js";import"./index-bcd8859b.js";import"./index-9b0d46f4.js";import"./gesture-controller-314a54f6.js";import"./hardware-back-button-ba8f64c2.js";import"./framework-delegate-63d1a679.js";var IonicSlides=function(e){var o=e.swiper,t=e.extendParams;var s={effect:undefined,direction:"horizontal",initialSlide:0,loop:false,parallax:false,slidesPerView:1,spaceBetween:0,speed:300,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:false,slidesOffsetBefore:0,slidesOffsetAfter:0,touchEventsTarget:"container",freeMode:false,freeModeMomentum:true,freeModeMomentumRatio:1,freeModeMomentumBounce:true,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:false,freeModeMinimumVelocity:.02,autoHeight:false,setWrapperSize:false,zoom:{maxRatio:3,minRatio:1,toggle:false},touchRatio:1,touchAngle:45,simulateTouch:true,touchStartPreventDefault:false,shortSwipes:true,longSwipes:true,longSwipesRatio:.5,longSwipesMs:300,followFinger:true,threshold:0,touchMoveStopPropagation:true,touchReleaseOnEdges:false,iOSEdgeSwipeDetection:false,iOSEdgeSwipeThreshold:20,resistance:true,resistanceRatio:.85,watchSlidesProgress:false,watchSlidesVisibility:false,preventClicks:true,preventClicksPropagation:true,slideToClickedSlide:false,loopAdditionalSlides:0,noSwiping:true,runCallbacksOnInit:true,coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:true},flipEffect:{slideShadows:true,limitRotation:true},cubeEffect:{slideShadows:true,shadow:true,shadowOffset:20,shadowScale:.94},fadeEffect:{crossFade:false},a11y:{prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide"}};if(o.pagination){s.pagination={type:"bullets",clickable:false,hideOnClick:false}}if(o.scrollbar){s.scrollbar={hide:true}}t(s)};export{IonicSlides};