@rdlabo/ionic-theme-ios27 1.0.4 → 1.1.0-beta.pr224.shac63de393e27b

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 (96) hide show
  1. package/dist/css/components/ion-toggle.css +1 -1
  2. package/dist/css/ionic-theme-ios27.css +1 -1
  3. package/dist/native/components/searchable-tabs.d.ts.map +1 -1
  4. package/dist/native/components/searchable-tabs.js +2 -0
  5. package/dist/native/runtime.d.ts.map +1 -1
  6. package/dist/native/runtime.js +73 -7
  7. package/dist/native/shared/crossfade.d.ts +2 -2
  8. package/dist/native/shared/crossfade.d.ts.map +1 -1
  9. package/dist/native/shared/crossfade.js +3 -3
  10. package/dist/segment/index.d.ts.map +1 -1
  11. package/dist/segment/index.js +7 -0
  12. package/docs/animation.md +2 -2
  13. package/docs/native-ui-shell.md +2 -0
  14. package/package.json +2 -5
  15. package/src/native/components/searchable-tabs.ts +3 -0
  16. package/src/native/runtime.ts +81 -6
  17. package/src/native/shared/crossfade.ts +4 -3
  18. package/src/segment/index.ts +11 -0
  19. package/src/styles/components/ion-toggle.scss +8 -2
  20. package/src/tab-bar-searchable/index.ts +1 -1
  21. package/node_modules/@rdlabo/ionic-theme-utils/LICENSE +0 -21
  22. package/node_modules/@rdlabo/ionic-theme-utils/README.md +0 -28
  23. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.d.ts +0 -3
  24. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.d.ts.map +0 -1
  25. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.js +0 -13
  26. package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.js.map +0 -1
  27. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.d.ts +0 -6
  28. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.d.ts.map +0 -1
  29. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.js +0 -37
  30. package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.js.map +0 -1
  31. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.d.ts +0 -13
  32. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.d.ts.map +0 -1
  33. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.js +0 -11
  34. package/node_modules/@rdlabo/ionic-theme-utils/dist/index.js.map +0 -1
  35. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.d.ts +0 -3
  36. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.d.ts.map +0 -1
  37. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.js +0 -196
  38. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.js.map +0 -1
  39. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.leave.d.ts +0 -3
  40. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.leave.d.ts.map +0 -1
  41. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.leave.js +0 -80
  42. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.leave.js.map +0 -1
  43. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/callout-surface.d.ts +0 -2
  44. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/callout-surface.d.ts.map +0 -1
  45. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/callout-surface.js +0 -45
  46. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/callout-surface.js.map +0 -1
  47. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.d.ts +0 -38
  48. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.d.ts.map +0 -1
  49. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.js +0 -2
  50. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.js.map +0 -1
  51. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.d.ts +0 -38
  52. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.d.ts.map +0 -1
  53. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.js +0 -378
  54. package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.js.map +0 -1
  55. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.d.ts +0 -16
  56. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.d.ts.map +0 -1
  57. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.js +0 -2
  58. package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.js.map +0 -1
  59. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/interfaces.d.ts +0 -41
  60. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/interfaces.d.ts.map +0 -1
  61. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/interfaces.js +0 -6
  62. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/interfaces.js.map +0 -1
  63. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/utils.d.ts +0 -12
  64. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/utils.d.ts.map +0 -1
  65. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/utils.js +0 -61
  66. package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/utils.js.map +0 -1
  67. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.d.ts +0 -15
  68. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.d.ts.map +0 -1
  69. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.js +0 -49
  70. package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.js.map +0 -1
  71. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.d.ts +0 -18
  72. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.d.ts.map +0 -1
  73. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.js +0 -412
  74. package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.js.map +0 -1
  75. package/node_modules/@rdlabo/ionic-theme-utils/package.json +0 -68
  76. package/node_modules/@rdlabo/ionic-theme-utils/scripts/copy-structured-list.mjs +0 -17
  77. package/node_modules/@rdlabo/ionic-theme-utils/src/dom.spec.ts +0 -19
  78. package/node_modules/@rdlabo/ionic-theme-utils/src/dom.ts +0 -16
  79. package/node_modules/@rdlabo/ionic-theme-utils/src/focus-controller.ts +0 -38
  80. package/node_modules/@rdlabo/ionic-theme-utils/src/index.ts +0 -59
  81. package/node_modules/@rdlabo/ionic-theme-utils/src/popover/animations/ios.enter.ts +0 -259
  82. package/node_modules/@rdlabo/ionic-theme-utils/src/popover/animations/ios.leave.ts +0 -99
  83. package/node_modules/@rdlabo/ionic-theme-utils/src/popover/callout-surface.ts +0 -54
  84. package/node_modules/@rdlabo/ionic-theme-utils/src/popover/popover-interface.ts +0 -44
  85. package/node_modules/@rdlabo/ionic-theme-utils/src/popover/utils.spec.ts +0 -58
  86. package/node_modules/@rdlabo/ionic-theme-utils/src/popover/utils.ts +0 -698
  87. package/node_modules/@rdlabo/ionic-theme-utils/src/sheets-of-glass.ts +0 -17
  88. package/node_modules/@rdlabo/ionic-theme-utils/src/styles/index.scss +0 -1
  89. package/node_modules/@rdlabo/ionic-theme-utils/src/styles/md-ion-list-inset.scss +0 -20
  90. package/node_modules/@rdlabo/ionic-theme-utils/src/styles/structured-list.scss +0 -310
  91. package/node_modules/@rdlabo/ionic-theme-utils/src/tab-bar-searchable/interfaces.ts +0 -28
  92. package/node_modules/@rdlabo/ionic-theme-utils/src/tab-bar-searchable/utils.spec.ts +0 -56
  93. package/node_modules/@rdlabo/ionic-theme-utils/src/tab-bar-searchable/utils.ts +0 -75
  94. package/node_modules/@rdlabo/ionic-theme-utils/src/theme.ts +0 -51
  95. package/node_modules/@rdlabo/ionic-theme-utils/src/transition/ios.transition.spec.ts +0 -52
  96. package/node_modules/@rdlabo/ionic-theme-utils/src/transition/ios.transition.ts +0 -542
@@ -1,542 +0,0 @@
1
- import type { Animation } from '@ionic/core';
2
- import { createAnimation } from '@ionic/core';
3
-
4
- /** Options consumed by the shared iOS page transition animation. */
5
- export interface IosTransitionAnimationOptions {
6
- enteringEl: HTMLElement;
7
- leavingEl?: HTMLElement;
8
- direction?: string;
9
- duration?: number;
10
- easing?: string;
11
- progressCallback?: (ani: Animation | undefined) => void;
12
- }
13
-
14
- /** Theme-specific knobs for {@link createIosTransitionAnimation}. */
15
- export interface IosTransitionAnimationConfig {
16
- /**
17
- * Previous-page retreat as a positive percent of the viewport width.
18
- * ios26 uses 30; ios27 uses 33.
19
- */
20
- offLeftPercent: number;
21
- /** Radius applied to the foreground page while transitioning. */
22
- radius?: number;
23
- /** Resolves the ion-page (or fallback) element for a leaving view. */
24
- getIonPageElement: (element: HTMLElement) => Element;
25
- /**
26
- * Optional hook invoked after the root animation is fully composed
27
- * (e.g. ios27 `connectNativeUIShellTransition`).
28
- */
29
- connectNativeUIShellTransition?: (animation: Animation, entering: HTMLElement, leaving?: HTMLElement) => void;
30
- }
31
-
32
- const DURATION = 540;
33
-
34
- const getClonedElement = <T extends HTMLIonBackButtonElement | HTMLIonTitleElement>(tagName: string) => {
35
- return document.querySelector<T>(`${tagName}.ion-cloned-element`);
36
- };
37
-
38
- export const shadow = <T extends Element>(el: T): ShadowRoot | T => {
39
- return el.shadowRoot || el;
40
- };
41
-
42
- const animateFixedBackButton = (
43
- root: Animation,
44
- navEl: HTMLElement,
45
- page: HTMLElement,
46
- entering: boolean,
47
- interactive: boolean,
48
- otherPage?: HTMLElement,
49
- ) => {
50
- const button = page.querySelector<HTMLIonBackButtonElement>(
51
- ':scope > ion-header.header-translucent:not(.ios-theme-disabled, .ios26-disabled) ion-back-button:not(.ios-theme-disabled, .ios26-disabled)',
52
- );
53
- if (!button || button.offsetWidth === 0) {
54
- return;
55
- }
56
-
57
- const otherButton = otherPage?.querySelector<HTMLIonBackButtonElement>(
58
- ':scope > ion-header.header-translucent:not(.ios-theme-disabled, .ios26-disabled) ion-back-button:not(.ios-theme-disabled, .ios26-disabled)',
59
- );
60
- const persistent = !!otherButton && otherButton.offsetWidth > 0;
61
- const buttons = [button, ...(persistent ? [otherButton!] : [])].map((element) => ({
62
- element,
63
- visibility: element.style.visibility,
64
- }));
65
- const rect = button.getBoundingClientRect();
66
- const width = button.offsetWidth;
67
- const height = button.offsetHeight;
68
- const clone = getClonedElement<HTMLIonBackButtonElement>('ion-back-button');
69
- if (!clone) {
70
- return;
71
- }
72
- const cloneParent = clone.parentNode!;
73
- const cloneNextSibling = clone.nextSibling;
74
- const cloneStyle = clone.getAttribute('style');
75
- clone.icon = button.icon;
76
- clone.text = button.text;
77
- clone.mode = button.mode;
78
- clone.color = button.color;
79
- clone.disabled = button.disabled;
80
- const icon = shadow(clone).querySelector('ion-icon');
81
- const animation = createAnimation().addElement(clone);
82
- const fadeStart = !entering && interactive ? 0.8 : 0.4;
83
- const fadeEnd = entering ? 0.96 : interactive ? 1 : 0.95;
84
- if (persistent) {
85
- animation.fromTo('transform', 'scale(1)', 'scale(1)').fromTo('opacity', 1, 1);
86
- } else if (entering) {
87
- animation.keyframes([
88
- { offset: 0, transform: 'scale(1.2)', opacity: 0 },
89
- { offset: fadeStart, transform: 'scale(1.2)', opacity: 0 },
90
- { offset: 0.65, transform: 'scale(1.12)', opacity: 0.15 },
91
- { offset: 0.9, transform: 'scale(1.02)', opacity: 0.75 },
92
- { offset: fadeEnd, transform: 'scale(1)', opacity: 1 },
93
- { offset: 1, transform: 'scale(1)', opacity: 1 },
94
- ]);
95
- } else {
96
- animation.keyframes([
97
- { offset: 0, transform: 'scale(1)', opacity: 1 },
98
- { offset: fadeStart, transform: 'scale(1)', opacity: 1 },
99
- { offset: fadeEnd, transform: 'scale(1.2)', opacity: 0 },
100
- { offset: 1, transform: 'scale(1.2)', opacity: 0 },
101
- ]);
102
- }
103
- if (icon && !persistent) {
104
- const from = entering ? 'blur(4px)' : 'blur(0px)';
105
- const to = entering ? 'blur(0px)' : 'blur(4px)';
106
- animation.addAnimation(
107
- createAnimation()
108
- .addElement(icon)
109
- .keyframes([
110
- { offset: 0, filter: from },
111
- { offset: fadeStart, filter: from },
112
- { offset: fadeEnd, filter: to },
113
- { offset: 1, filter: to },
114
- ]),
115
- );
116
- }
117
- root.beforeAddWrite(() => {
118
- Object.assign(clone.style, {
119
- position: 'fixed',
120
- left: `${rect.left + (rect.width - width) / 2}px`,
121
- top: `${rect.top + (rect.height - height) / 2}px`,
122
- width: `${width}px`,
123
- height: `${height}px`,
124
- margin: '0',
125
- pointerEvents: 'none',
126
- visibility: 'visible',
127
- display: getComputedStyle(button).display,
128
- zIndex: '1000',
129
- });
130
- navEl.appendChild(clone);
131
- buttons.forEach(({ element }) => (element.style.visibility = 'hidden'));
132
- });
133
- root.afterAddWrite(() => {
134
- buttons.forEach(({ element, visibility }) => (element.style.visibility = visibility));
135
- cloneParent.insertBefore(clone, cloneNextSibling);
136
- if (cloneStyle === null) {
137
- clone.removeAttribute('style');
138
- } else {
139
- clone.setAttribute('style', cloneStyle);
140
- }
141
- });
142
- root.addAnimation(animation);
143
- };
144
-
145
- /**
146
- * Builds an `iosTransitionAnimation` function parameterized by theme config
147
- * (OFF_LEFT percent and an optional native-shell hook).
148
- */
149
- export const createIosTransitionAnimation = <TOpts extends IosTransitionAnimationOptions>(
150
- config: IosTransitionAnimationConfig,
151
- ): ((navEl: HTMLElement, opts: TOpts) => Animation) => {
152
- const { offLeftPercent, getIonPageElement, connectNativeUIShellTransition } = config;
153
-
154
- return (navEl: HTMLElement, opts: TOpts): Animation => {
155
- try {
156
- const EASING = 'cubic-bezier(0.32,0.72,0,1)';
157
- const OPACITY = 'opacity';
158
- const TRANSFORM = 'transform';
159
- const CENTER = '0%';
160
- const OFF_OPACITY = 0.8;
161
-
162
- const isRTL = navEl.ownerDocument.dir === 'rtl';
163
- const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
164
- const OFF_LEFT = isRTL ? `${offLeftPercent}%` : `-${offLeftPercent}%`;
165
-
166
- const enteringEl = opts.enteringEl;
167
- const leavingEl = opts.leavingEl;
168
-
169
- const backDirection = opts.direction === 'back';
170
- const contentEl = enteringEl.querySelector(':scope > ion-content');
171
- const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
172
- const enteringToolBarEls = enteringEl.querySelectorAll(':scope > ion-header > ion-toolbar');
173
-
174
- const rootAnimation = createAnimation();
175
- const enteringContentAnimation = createAnimation();
176
-
177
- rootAnimation
178
- .addElement(enteringEl)
179
- .duration((opts.duration ?? 0) || DURATION)
180
- .easing(opts.easing || EASING)
181
- .fill('both')
182
- .beforeRemoveClass('ion-page-invisible');
183
-
184
- const topPage = backDirection ? leavingEl : enteringEl;
185
- const translucentTop = topPage?.querySelector(':scope > ion-header.header-translucent:not(.ios-theme-disabled, .ios26-disabled)');
186
- if (topPage && translucentTop) {
187
- // UIKit dims the opaque page underneath, including its header, with 10% black.
188
- const shade = navEl.ownerDocument.createElement('div');
189
- shade.className = 'ios-transition-shade';
190
- shade.setAttribute('aria-hidden', 'true');
191
- const clipPath = topPage.style.clipPath;
192
- const corner = config.radius ?? 0;
193
- Object.assign(shade.style, {
194
- position: 'absolute',
195
- inset: '0',
196
- zIndex: topPage.style.zIndex,
197
- pointerEvents: 'none',
198
- background: 'rgba(0, 0, 0, 0.1)',
199
- });
200
- rootAnimation.beforeAddWrite(() => {
201
- topPage.before(shade);
202
- if (corner > 0) {
203
- topPage.style.clipPath = `inset(0 round ${corner}px)`;
204
- }
205
- });
206
- rootAnimation.afterAddWrite(() => {
207
- shade.remove();
208
- topPage.style.clipPath = clipPath;
209
- });
210
- rootAnimation.addAnimation(
211
- createAnimation()
212
- .addElement(shade)
213
- .fromTo(OPACITY, backDirection ? 1 : 0, backDirection ? 0 : 1),
214
- );
215
- }
216
-
217
- if (leavingEl && navEl !== null && navEl !== undefined) {
218
- const navDecorAnimation = createAnimation();
219
- navDecorAnimation.addElement(navEl);
220
- rootAnimation.addAnimation(navDecorAnimation);
221
- }
222
-
223
- if (enteringEl.querySelector(':scope > ion-header.header-translucent:not(.ios-theme-disabled, .ios26-disabled)')) {
224
- enteringContentAnimation.addElement(enteringEl);
225
- } else if (!contentEl && enteringToolBarEls.length === 0 && headerEls.length === 0) {
226
- enteringContentAnimation.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')!); // REVIEW
227
- } else {
228
- enteringContentAnimation.addElement(contentEl!); // REVIEW
229
- enteringContentAnimation.addElement(headerEls);
230
- }
231
-
232
- rootAnimation.addAnimation(enteringContentAnimation);
233
-
234
- if (backDirection) {
235
- enteringContentAnimation
236
- .beforeClearStyles([OPACITY])
237
- .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
238
- .fromTo(OPACITY, translucentTop ? 1 : OFF_OPACITY, 1);
239
- } else {
240
- // entering content, forward direction
241
- enteringContentAnimation.beforeClearStyles([OPACITY]).fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
242
- }
243
-
244
- if (contentEl && !enteringEl.querySelector(':scope > ion-header.header-translucent:not(.ios-theme-disabled, .ios26-disabled)')) {
245
- const enteringTransitionEffectEl = shadow(contentEl).querySelector('.transition-effect');
246
- if (enteringTransitionEffectEl) {
247
- const enteringTransitionCoverEl = enteringTransitionEffectEl.querySelector('.transition-cover');
248
- const enteringTransitionShadowEl = enteringTransitionEffectEl.querySelector('.transition-shadow');
249
-
250
- const enteringTransitionEffect = createAnimation();
251
- const enteringTransitionCover = createAnimation();
252
- const enteringTransitionShadow = createAnimation();
253
-
254
- enteringTransitionEffect
255
- .addElement(enteringTransitionEffectEl)
256
- .beforeStyles({ opacity: '1', display: 'block' })
257
- .afterStyles({ opacity: '', display: '' });
258
-
259
- enteringTransitionCover
260
- .addElement(enteringTransitionCoverEl!) // REVIEW
261
- .beforeClearStyles([OPACITY])
262
- .fromTo(OPACITY, 0, 0.1);
263
-
264
- enteringTransitionShadow
265
- .addElement(enteringTransitionShadowEl!) // REVIEW
266
- .beforeClearStyles([OPACITY])
267
- .fromTo(OPACITY, 0.03, 0.7);
268
-
269
- enteringTransitionEffect.addAnimation([enteringTransitionCover, enteringTransitionShadow]);
270
- enteringContentAnimation.addAnimation([enteringTransitionEffect]);
271
- }
272
- }
273
-
274
- if (topPage) {
275
- animateFixedBackButton(
276
- rootAnimation,
277
- navEl,
278
- topPage,
279
- !backDirection,
280
- opts.progressCallback !== undefined,
281
- backDirection ? enteringEl : leavingEl,
282
- );
283
- }
284
-
285
- const enteringContentHasLargeTitle = enteringEl.querySelector('ion-header.header-collapse-condense');
286
-
287
- enteringToolBarEls.forEach((enteringToolBarEl) => {
288
- if (enteringToolBarEl.closest('ion-header')?.matches('.header-translucent:not(.ios-theme-disabled, .ios26-disabled)')) {
289
- return;
290
- }
291
- const enteringToolBar = createAnimation();
292
- enteringToolBar.addElement(enteringToolBarEl);
293
- rootAnimation.addAnimation(enteringToolBar);
294
-
295
- const enteringTitle = createAnimation();
296
- enteringTitle.addElement(enteringToolBarEl.querySelector('ion-title')!); // REVIEW
297
-
298
- const enteringToolBarButtons = createAnimation();
299
- const buttons = Array.from(enteringToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
300
-
301
- const parentHeader = enteringToolBarEl.closest('ion-header');
302
- const inactiveHeader = parentHeader?.classList.contains('header-collapse-condense-inactive');
303
-
304
- let buttonsToAnimate;
305
- if (backDirection) {
306
- buttonsToAnimate = buttons.filter((button) => {
307
- const isCollapseButton = button.classList.contains('buttons-collapse');
308
- return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
309
- });
310
- } else {
311
- buttonsToAnimate = buttons.filter((button) => !button.classList.contains('buttons-collapse'));
312
- }
313
-
314
- enteringToolBarButtons.addElement(buttonsToAnimate);
315
-
316
- const enteringToolBarItems = createAnimation();
317
- enteringToolBarItems.addElement(enteringToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])'));
318
-
319
- const enteringToolBarBg = createAnimation();
320
- enteringToolBarBg.addElement(shadow(enteringToolBarEl).querySelector('.toolbar-background')!); // REVIEW
321
-
322
- const enteringBackButton = createAnimation();
323
- const backButtonEl = enteringToolBarEl.querySelector('ion-back-button');
324
-
325
- if (backButtonEl) {
326
- enteringBackButton.addElement(backButtonEl);
327
- }
328
-
329
- enteringToolBar.addAnimation([enteringTitle, enteringToolBarButtons, enteringToolBarItems, enteringToolBarBg, enteringBackButton]);
330
- enteringToolBarButtons.fromTo(OPACITY, 0.01, 1);
331
- enteringToolBarItems.fromTo(OPACITY, 0.01, 1);
332
-
333
- if (backDirection) {
334
- if (!inactiveHeader) {
335
- enteringTitle.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`).fromTo(OPACITY, 0.01, 1);
336
- }
337
-
338
- enteringToolBarItems.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`);
339
-
340
- // back direction, entering page has a back button
341
- enteringBackButton.fromTo(OPACITY, 0.01, 1);
342
- } else {
343
- // entering toolbar, forward direction
344
- if (!enteringContentHasLargeTitle) {
345
- enteringTitle.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`).fromTo(OPACITY, 0.01, 1);
346
- }
347
-
348
- enteringToolBarItems.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
349
- enteringToolBarBg.beforeClearStyles([OPACITY, 'transform']);
350
-
351
- const translucentHeader = parentHeader?.translucent;
352
- if (!translucentHeader) {
353
- enteringToolBarBg.fromTo(OPACITY, 0.01, 'var(--opacity)');
354
- } else {
355
- enteringToolBarBg.fromTo('transform', isRTL ? 'translateX(-100%)' : 'translateX(100%)', 'translateX(0px)');
356
- }
357
-
358
- // forward direction, entering page has a back button
359
- enteringBackButton.fromTo(OPACITY, 0.01, 1);
360
-
361
- if (backButtonEl) {
362
- const enteringBackBtnText = createAnimation();
363
- enteringBackBtnText
364
- .addElement(shadow(backButtonEl).querySelector('.button-text')!) // REVIEW
365
- .fromTo(`transform`, isRTL ? 'translateX(-100px)' : 'translateX(100px)', 'translateX(0px)');
366
-
367
- enteringToolBar.addAnimation(enteringBackBtnText);
368
- }
369
- }
370
- });
371
-
372
- // setup leaving view
373
- if (leavingEl) {
374
- const leavingContent = createAnimation();
375
- const leavingContentEl = leavingEl.querySelector(':scope > ion-content');
376
- const leavingToolBarEls = leavingEl.querySelectorAll(':scope > ion-header > ion-toolbar');
377
- const leavingHeaderEls = leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
378
-
379
- if (leavingEl.querySelector(':scope > ion-header.header-translucent:not(.ios-theme-disabled, .ios26-disabled)')) {
380
- leavingContent.addElement(leavingEl);
381
- } else if (!leavingContentEl && leavingToolBarEls.length === 0 && leavingHeaderEls.length === 0) {
382
- leavingContent.addElement(leavingEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')!); // REVIEW
383
- } else {
384
- leavingContent.addElement(leavingContentEl!); // REVIEW
385
- leavingContent.addElement(leavingHeaderEls);
386
- }
387
-
388
- rootAnimation.addAnimation(leavingContent);
389
-
390
- if (backDirection) {
391
- // leaving content, back direction
392
- leavingContent
393
- .beforeClearStyles([OPACITY])
394
- .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
395
-
396
- const leavingPage = getIonPageElement(leavingEl) as HTMLElement;
397
- rootAnimation.afterAddWrite(() => {
398
- if (rootAnimation.getDirection() === 'normal') {
399
- leavingPage.style.setProperty('display', 'none');
400
- }
401
- });
402
- } else {
403
- // leaving content, forward direction
404
- leavingContent
405
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
406
- .fromTo(OPACITY, 1, translucentTop ? 1 : OFF_OPACITY);
407
- }
408
-
409
- if (
410
- leavingContentEl &&
411
- !leavingEl.querySelector(':scope > ion-header.header-translucent:not(.ios-theme-disabled, .ios26-disabled)')
412
- ) {
413
- const leavingTransitionEffectEl = shadow(leavingContentEl).querySelector('.transition-effect');
414
-
415
- if (leavingTransitionEffectEl) {
416
- const leavingTransitionCoverEl = leavingTransitionEffectEl.querySelector('.transition-cover');
417
- const leavingTransitionShadowEl = leavingTransitionEffectEl.querySelector('.transition-shadow');
418
-
419
- const leavingTransitionEffect = createAnimation();
420
- const leavingTransitionCover = createAnimation();
421
- const leavingTransitionShadow = createAnimation();
422
-
423
- leavingTransitionEffect
424
- .addElement(leavingTransitionEffectEl)
425
- .beforeStyles({ opacity: '1', display: 'block' })
426
- .afterStyles({ opacity: '', display: '' });
427
-
428
- leavingTransitionCover
429
- .addElement(leavingTransitionCoverEl!) // REVIEW
430
- .beforeClearStyles([OPACITY])
431
- .fromTo(OPACITY, 0.1, 0);
432
-
433
- leavingTransitionShadow
434
- .addElement(leavingTransitionShadowEl!) // REVIEW
435
- .beforeClearStyles([OPACITY])
436
- .fromTo(OPACITY, 0.7, 0.03);
437
-
438
- leavingTransitionEffect.addAnimation([leavingTransitionCover, leavingTransitionShadow]);
439
- leavingContent.addAnimation([leavingTransitionEffect]);
440
- }
441
- }
442
-
443
- leavingToolBarEls.forEach((leavingToolBarEl) => {
444
- if (leavingToolBarEl.closest('ion-header')?.matches('.header-translucent:not(.ios-theme-disabled, .ios26-disabled)')) {
445
- return;
446
- }
447
- const leavingToolBar = createAnimation();
448
- leavingToolBar.addElement(leavingToolBarEl);
449
-
450
- const leavingTitle = createAnimation();
451
- leavingTitle.addElement(leavingToolBarEl.querySelector('ion-title')!); // REVIEW
452
-
453
- const leavingToolBarButtons = createAnimation();
454
- const buttons = leavingToolBarEl.querySelectorAll('ion-buttons,[menuToggle]');
455
-
456
- const parentHeader = leavingToolBarEl.closest('ion-header');
457
- const inactiveHeader = parentHeader?.classList.contains('header-collapse-condense-inactive');
458
-
459
- const buttonsToAnimate = Array.from(buttons).filter((button) => {
460
- const isCollapseButton = button.classList.contains('buttons-collapse');
461
- return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
462
- });
463
-
464
- leavingToolBarButtons.addElement(buttonsToAnimate);
465
-
466
- const leavingToolBarItems = createAnimation();
467
- const leavingToolBarItemEls = leavingToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])');
468
- if (leavingToolBarItemEls.length > 0) {
469
- leavingToolBarItems.addElement(leavingToolBarItemEls);
470
- }
471
-
472
- const leavingToolBarBg = createAnimation();
473
- leavingToolBarBg.addElement(shadow(leavingToolBarEl).querySelector('.toolbar-background')!); // REVIEW
474
-
475
- const leavingBackButton = createAnimation();
476
- const backButtonEl = leavingToolBarEl.querySelector('ion-back-button');
477
- if (backButtonEl) {
478
- leavingBackButton.addElement(backButtonEl);
479
- }
480
-
481
- leavingToolBar.addAnimation([leavingTitle, leavingToolBarButtons, leavingToolBarItems, leavingBackButton, leavingToolBarBg]);
482
- rootAnimation.addAnimation(leavingToolBar);
483
-
484
- // fade out leaving toolbar items
485
- leavingBackButton.fromTo(OPACITY, 0.99, 0);
486
-
487
- leavingToolBarButtons.fromTo(OPACITY, 0.99, 0);
488
- leavingToolBarItems.fromTo(OPACITY, 0.99, 0);
489
-
490
- if (backDirection) {
491
- if (!inactiveHeader) {
492
- // leaving toolbar, back direction
493
- leavingTitle
494
- .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)')
495
- .fromTo(OPACITY, 0.99, 0);
496
- }
497
-
498
- leavingToolBarItems.fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
499
- leavingToolBarBg.beforeClearStyles([OPACITY, 'transform']);
500
- // leaving toolbar, back direction, and there's no entering toolbar
501
- // should just slide out, no fading out
502
- const translucentHeader = parentHeader?.translucent;
503
- if (!translucentHeader) {
504
- leavingToolBarBg.fromTo(OPACITY, 'var(--opacity)', 0);
505
- } else {
506
- leavingToolBarBg.fromTo('transform', 'translateX(0px)', isRTL ? 'translateX(-100%)' : 'translateX(100%)');
507
- }
508
-
509
- if (backButtonEl) {
510
- const leavingBackBtnText = createAnimation();
511
- leavingBackBtnText
512
- .addElement(shadow(backButtonEl).querySelector('.button-text')!) // REVIEW
513
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${(isRTL ? -124 : 124) + 'px'})`);
514
- leavingToolBar.addAnimation(leavingBackBtnText);
515
- }
516
- } else {
517
- // leaving toolbar, forward direction
518
- if (!inactiveHeader) {
519
- leavingTitle
520
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
521
- .fromTo(OPACITY, 0.99, 0)
522
- .afterClearStyles([TRANSFORM, OPACITY]);
523
- }
524
-
525
- leavingToolBarItems
526
- .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
527
- .afterClearStyles([TRANSFORM, OPACITY]);
528
-
529
- leavingBackButton.afterClearStyles([OPACITY]);
530
- leavingTitle.afterClearStyles([OPACITY]);
531
- leavingToolBarButtons.afterClearStyles([OPACITY]);
532
- }
533
- });
534
- }
535
-
536
- connectNativeUIShellTransition?.(rootAnimation, enteringEl, leavingEl);
537
- return rootAnimation;
538
- } catch (err) {
539
- throw err;
540
- }
541
- };
542
- };