@rdlabo/ionic-theme-ios26 1.3.3 → 2.0.0

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 (42) hide show
  1. package/README.md +35 -55
  2. package/dist/css/components/ion-button.css +1 -1
  3. package/dist/css/components/ion-toolbar.css +1 -1
  4. package/dist/css/ionic-theme-ios26.css +1 -1
  5. package/dist/focus-controller /index.d.ts +6 -0
  6. package/dist/focus-controller /index.d.ts.map +1 -0
  7. package/dist/focus-controller /index.js +62 -0
  8. package/dist/popover/animations/ios.enter.js +1 -1
  9. package/dist/popover/utils.d.ts.map +1 -1
  10. package/dist/popover/utils.js +6 -0
  11. package/dist/transition/index.d.ts +19 -0
  12. package/dist/transition/index.d.ts.map +1 -0
  13. package/dist/transition/index.js +219 -0
  14. package/dist/transition/ios.transition.d.ts +5 -0
  15. package/dist/transition/ios.transition.d.ts.map +1 -0
  16. package/dist/transition/ios.transition.js +496 -0
  17. package/dist/utils.d.ts +10 -0
  18. package/dist/utils.d.ts.map +1 -1
  19. package/dist/utils.js +30 -0
  20. package/package.json +1 -1
  21. package/src/focus-controller /index.ts +123 -0
  22. package/src/popover/animations/ios.enter.ts +1 -1
  23. package/src/popover/utils.ts +6 -0
  24. package/src/styles/components/ion-button.scss +0 -4
  25. package/src/transition/index.ts +369 -0
  26. package/src/transition/ios.transition.ts +834 -0
  27. package/src/utils.ts +36 -0
  28. package/dist/gestures/animations.d.ts +0 -8
  29. package/dist/gestures/animations.d.ts.map +0 -1
  30. package/dist/gestures/animations.js +0 -97
  31. package/dist/gestures/gestures.d.ts +0 -3
  32. package/dist/gestures/gestures.d.ts.map +0 -1
  33. package/dist/gestures/gestures.js +0 -240
  34. package/dist/gestures/index.d.ts +0 -3
  35. package/dist/gestures/index.d.ts.map +0 -1
  36. package/dist/gestures/index.js +0 -160
  37. package/dist/gestures/interfaces.d.ts +0 -16
  38. package/dist/gestures/interfaces.d.ts.map +0 -1
  39. package/dist/gestures/interfaces.js +0 -1
  40. package/dist/gestures/utils.d.ts +0 -5
  41. package/dist/gestures/utils.d.ts.map +0 -1
  42. package/dist/gestures/utils.js +0 -27
@@ -0,0 +1,496 @@
1
+ import { createAnimation } from '@ionic/core';
2
+ import { getIonPageElement } from './index';
3
+ const DURATION = 540;
4
+ const getClonedElement = (tagName) => {
5
+ return document.querySelector(`${tagName}.ion-cloned-element`);
6
+ };
7
+ export const shadow = (el) => {
8
+ return el.shadowRoot || el;
9
+ };
10
+ const getLargeTitle = (refEl) => {
11
+ const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
12
+ const query = 'ion-content ion-header:not(.header-collapse-condense-inactive) ion-title.title-large';
13
+ if (tabs != null) {
14
+ const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
15
+ return activeTab != null ? activeTab.querySelector(query) : null;
16
+ }
17
+ return refEl.querySelector(query);
18
+ };
19
+ const getBackButton = (refEl, backDirection) => {
20
+ const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
21
+ let buttonsList = [];
22
+ if (tabs != null) {
23
+ const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
24
+ if (activeTab != null) {
25
+ buttonsList = activeTab.querySelectorAll('ion-buttons');
26
+ }
27
+ }
28
+ else {
29
+ buttonsList = refEl.querySelectorAll('ion-buttons');
30
+ }
31
+ for (const buttons of buttonsList) {
32
+ const parentHeader = buttons.closest('ion-header');
33
+ const activeHeader = parentHeader && !parentHeader.classList.contains('header-collapse-condense-inactive');
34
+ const backButton = buttons.querySelector('ion-back-button');
35
+ const buttonsCollapse = buttons.classList.contains('buttons-collapse');
36
+ const startSlot = buttons.slot === 'start' || buttons.slot === '';
37
+ if (backButton !== null && startSlot && ((buttonsCollapse && activeHeader && backDirection) || !buttonsCollapse)) {
38
+ return backButton;
39
+ }
40
+ }
41
+ return null;
42
+ };
43
+ const createLargeTitleTransition = (rootAnimation, rtl, backDirection, enteringEl, leavingEl) => {
44
+ const enteringBackButton = getBackButton(enteringEl, backDirection);
45
+ const leavingLargeTitle = getLargeTitle(leavingEl);
46
+ const enteringLargeTitle = getLargeTitle(enteringEl);
47
+ const leavingBackButton = getBackButton(leavingEl, backDirection);
48
+ const shouldAnimationForward = enteringBackButton !== null && leavingLargeTitle !== null && !backDirection;
49
+ const shouldAnimationBackward = enteringLargeTitle !== null && leavingBackButton !== null && backDirection;
50
+ if (shouldAnimationForward) {
51
+ const leavingLargeTitleBox = leavingLargeTitle.getBoundingClientRect();
52
+ const enteringBackButtonBox = enteringBackButton.getBoundingClientRect();
53
+ const enteringBackButtonTextEl = shadow(enteringBackButton).querySelector('.button-text');
54
+ const enteringBackButtonTextBox = enteringBackButtonTextEl?.getBoundingClientRect();
55
+ const leavingLargeTitleTextEl = shadow(leavingLargeTitle).querySelector('.toolbar-title');
56
+ const leavingLargeTitleTextBox = leavingLargeTitleTextEl.getBoundingClientRect();
57
+ animateLargeTitle(rootAnimation, rtl, backDirection, leavingLargeTitle, leavingLargeTitleBox, leavingLargeTitleTextBox, enteringBackButtonBox, enteringBackButtonTextEl, enteringBackButtonTextBox);
58
+ }
59
+ else if (shouldAnimationBackward) {
60
+ const enteringLargeTitleBox = enteringLargeTitle.getBoundingClientRect();
61
+ const leavingBackButtonBox = leavingBackButton.getBoundingClientRect();
62
+ const leavingBackButtonTextEl = shadow(leavingBackButton).querySelector('.button-text');
63
+ const leavingBackButtonTextBox = leavingBackButtonTextEl?.getBoundingClientRect();
64
+ const enteringLargeTitleTextEl = shadow(enteringLargeTitle).querySelector('.toolbar-title');
65
+ const enteringLargeTitleTextBox = enteringLargeTitleTextEl.getBoundingClientRect();
66
+ animateLargeTitle(rootAnimation, rtl, backDirection, enteringLargeTitle, enteringLargeTitleBox, enteringLargeTitleTextBox, leavingBackButtonBox, leavingBackButtonTextEl, leavingBackButtonTextBox);
67
+ }
68
+ return {
69
+ forward: shouldAnimationForward,
70
+ backward: shouldAnimationBackward,
71
+ };
72
+ };
73
+ const animateBackButton = (rootAnimation, rtl, backDirection, backButtonEl, backButtonBox, backButtonTextEl, backButtonTextBox, largeTitleEl, largeTitleTextBox) => {
74
+ const BACK_BUTTON_START_OFFSET = rtl ? `calc(100% - ${backButtonBox.right + 4}px)` : `${backButtonBox.left - 4}px`;
75
+ const TEXT_ORIGIN_X = rtl ? 'right' : 'left';
76
+ const ICON_ORIGIN_X = rtl ? 'left' : 'right';
77
+ const CONTAINER_ORIGIN_X = rtl ? 'right' : 'left';
78
+ let WIDTH_SCALE = 1;
79
+ let HEIGHT_SCALE = 1;
80
+ let TEXT_START_SCALE = `scale(${HEIGHT_SCALE})`;
81
+ const TEXT_END_SCALE = 'scale(1)';
82
+ if (backButtonTextEl && backButtonTextBox) {
83
+ const doTitleAndButtonTextsMatch = backButtonTextEl.textContent?.trim() === largeTitleEl.textContent?.trim();
84
+ WIDTH_SCALE = largeTitleTextBox.width / backButtonTextBox.width;
85
+ HEIGHT_SCALE = (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET) / backButtonTextBox.height;
86
+ TEXT_START_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
87
+ }
88
+ const backButtonIconEl = shadow(backButtonEl).querySelector('ion-icon');
89
+ const backButtonIconBox = backButtonIconEl.getBoundingClientRect();
90
+ const CONTAINER_START_TRANSLATE_X = rtl
91
+ ? `${backButtonIconBox.width / 2 - (backButtonIconBox.right - backButtonBox.right)}px`
92
+ : `${backButtonBox.left - backButtonIconBox.width / 2}px`;
93
+ const CONTAINER_END_TRANSLATE_X = rtl ? `-${window.innerWidth - backButtonBox.right}px` : `${backButtonBox.left}px`;
94
+ const CONTAINER_START_TRANSLATE_Y = `${largeTitleTextBox.top}px`;
95
+ const CONTAINER_END_TRANSLATE_Y = `${backButtonBox.top}px`;
96
+ const FORWARD_CONTAINER_KEYFRAMES = [
97
+ { offset: 0, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
98
+ { offset: 1, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
99
+ ];
100
+ const BACKWARD_CONTAINER_KEYFRAMES = [
101
+ { offset: 0, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
102
+ { offset: 1, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
103
+ ];
104
+ const CONTAINER_KEYFRAMES = backDirection ? BACKWARD_CONTAINER_KEYFRAMES : FORWARD_CONTAINER_KEYFRAMES;
105
+ const FORWARD_TEXT_KEYFRAMES = [
106
+ { offset: 0, opacity: 0, transform: TEXT_START_SCALE },
107
+ { offset: 1, opacity: 1, transform: TEXT_END_SCALE },
108
+ ];
109
+ const BACKWARD_TEXT_KEYFRAMES = [
110
+ { offset: 0, opacity: 1, transform: TEXT_END_SCALE },
111
+ { offset: 1, opacity: 0, transform: TEXT_START_SCALE },
112
+ ];
113
+ const TEXT_KEYFRAMES = backDirection ? BACKWARD_TEXT_KEYFRAMES : FORWARD_TEXT_KEYFRAMES;
114
+ const FORWARD_ICON_KEYFRAMES = [
115
+ { offset: 0, opacity: 0, transform: 'scale(0.6)' },
116
+ { offset: 0.6, opacity: 0, transform: 'scale(0.6)' },
117
+ { offset: 1, opacity: 1, transform: 'scale(1)' },
118
+ ];
119
+ const BACKWARD_ICON_KEYFRAMES = [
120
+ { offset: 0, opacity: 1, transform: 'scale(1)' },
121
+ { offset: 0.2, opacity: 0, transform: 'scale(0.6)' },
122
+ { offset: 1, opacity: 0, transform: 'scale(0.6)' },
123
+ ];
124
+ const ICON_KEYFRAMES = backDirection ? BACKWARD_ICON_KEYFRAMES : FORWARD_ICON_KEYFRAMES;
125
+ const enteringBackButtonTextAnimation = createAnimation();
126
+ const enteringBackButtonIconAnimation = createAnimation();
127
+ const enteringBackButtonAnimation = createAnimation();
128
+ const clonedBackButtonEl = getClonedElement('ion-back-button');
129
+ const clonedBackButtonTextEl = shadow(clonedBackButtonEl).querySelector('.button-text');
130
+ const clonedBackButtonIconEl = shadow(clonedBackButtonEl).querySelector('ion-icon');
131
+ clonedBackButtonEl.text = backButtonEl.text;
132
+ clonedBackButtonEl.mode = backButtonEl.mode;
133
+ clonedBackButtonEl.icon = backButtonEl.icon;
134
+ clonedBackButtonEl.color = backButtonEl.color;
135
+ clonedBackButtonEl.disabled = backButtonEl.disabled;
136
+ clonedBackButtonEl.style.setProperty('display', 'block');
137
+ clonedBackButtonEl.style.setProperty('position', 'fixed');
138
+ enteringBackButtonIconAnimation.addElement(clonedBackButtonIconEl);
139
+ enteringBackButtonTextAnimation.addElement(clonedBackButtonTextEl);
140
+ enteringBackButtonAnimation.addElement(clonedBackButtonEl);
141
+ enteringBackButtonAnimation
142
+ .beforeStyles({
143
+ position: 'absolute',
144
+ top: '0px',
145
+ [CONTAINER_ORIGIN_X]: '0px',
146
+ })
147
+ .beforeAddWrite(() => {
148
+ backButtonEl.style.setProperty('display', 'none');
149
+ clonedBackButtonEl.style.setProperty(TEXT_ORIGIN_X, BACK_BUTTON_START_OFFSET);
150
+ })
151
+ .afterAddWrite(() => {
152
+ backButtonEl.style.setProperty('display', '');
153
+ clonedBackButtonEl.style.setProperty('display', 'none');
154
+ clonedBackButtonEl.style.removeProperty(TEXT_ORIGIN_X);
155
+ })
156
+ .keyframes(CONTAINER_KEYFRAMES);
157
+ enteringBackButtonTextAnimation
158
+ .beforeStyles({
159
+ 'transform-origin': `${TEXT_ORIGIN_X} top`,
160
+ })
161
+ .keyframes(TEXT_KEYFRAMES);
162
+ enteringBackButtonIconAnimation
163
+ .beforeStyles({
164
+ 'transform-origin': `${ICON_ORIGIN_X} center`,
165
+ })
166
+ .keyframes(ICON_KEYFRAMES);
167
+ rootAnimation.addAnimation([enteringBackButtonTextAnimation, enteringBackButtonIconAnimation, enteringBackButtonAnimation]);
168
+ };
169
+ const animateLargeTitle = (rootAnimation, rtl, backDirection, largeTitleEl, largeTitleBox, largeTitleTextBox, backButtonBox, backButtonTextEl, backButtonTextBox) => {
170
+ const ORIGIN_X = rtl ? 'right' : 'left';
171
+ const TITLE_START_OFFSET = rtl ? `calc(100% - ${largeTitleBox.right}px)` : `${largeTitleBox.left}px`;
172
+ const START_TRANSLATE_X = '0px';
173
+ const START_TRANSLATE_Y = `${largeTitleBox.top}px`;
174
+ const LARGE_TITLE_TRANSLATION_OFFSET = 8;
175
+ let END_TRANSLATE_X = rtl
176
+ ? `-${window.innerWidth - backButtonBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
177
+ : `${backButtonBox.x + LARGE_TITLE_TRANSLATION_OFFSET}px`;
178
+ let HEIGHT_SCALE = 0.5;
179
+ const START_SCALE = 'scale(1)';
180
+ let END_SCALE = `scale(${HEIGHT_SCALE})`;
181
+ if (backButtonTextEl && backButtonTextBox) {
182
+ END_TRANSLATE_X = rtl
183
+ ? `-${window.innerWidth - backButtonTextBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
184
+ : `${backButtonTextBox.x - LARGE_TITLE_TRANSLATION_OFFSET}px`;
185
+ const doTitleAndButtonTextsMatch = backButtonTextEl.textContent?.trim() === largeTitleEl.textContent?.trim();
186
+ const WIDTH_SCALE = backButtonTextBox.width / largeTitleTextBox.width;
187
+ HEIGHT_SCALE = backButtonTextBox.height / (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET);
188
+ END_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
189
+ }
190
+ const backButtonMidPoint = backButtonBox.top + backButtonBox.height / 2;
191
+ const titleMidPoint = (largeTitleBox.height * HEIGHT_SCALE) / 2;
192
+ const END_TRANSLATE_Y = `${backButtonMidPoint - titleMidPoint}px`;
193
+ const BACKWARDS_KEYFRAMES = [
194
+ { offset: 0, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
195
+ { offset: 0.1, opacity: 0 },
196
+ { offset: 1, opacity: 1, transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}` },
197
+ ];
198
+ const FORWARDS_KEYFRAMES = [
199
+ {
200
+ offset: 0,
201
+ opacity: 0.99,
202
+ transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}`,
203
+ },
204
+ { offset: 0.6, opacity: 0 },
205
+ { offset: 1, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
206
+ ];
207
+ const KEYFRAMES = backDirection ? BACKWARDS_KEYFRAMES : FORWARDS_KEYFRAMES;
208
+ const clonedTitleEl = getClonedElement('ion-title');
209
+ const clonedLargeTitleAnimation = createAnimation();
210
+ clonedTitleEl.innerText = largeTitleEl.innerText;
211
+ clonedTitleEl.size = largeTitleEl.size;
212
+ clonedTitleEl.color = largeTitleEl.color;
213
+ clonedLargeTitleAnimation.addElement(clonedTitleEl);
214
+ clonedLargeTitleAnimation
215
+ .beforeStyles({
216
+ 'transform-origin': `${ORIGIN_X} top`,
217
+ height: `${largeTitleBox.height}px`,
218
+ display: '',
219
+ position: 'relative',
220
+ [ORIGIN_X]: TITLE_START_OFFSET,
221
+ })
222
+ .beforeAddWrite(() => {
223
+ largeTitleEl.style.setProperty('opacity', '0');
224
+ })
225
+ .afterAddWrite(() => {
226
+ largeTitleEl.style.setProperty('opacity', '');
227
+ clonedTitleEl.style.setProperty('display', 'none');
228
+ })
229
+ .keyframes(KEYFRAMES);
230
+ rootAnimation.addAnimation(clonedLargeTitleAnimation);
231
+ };
232
+ export const iosTransitionAnimation = (navEl, opts) => {
233
+ try {
234
+ const EASING = 'cubic-bezier(0.32,0.72,0,1)';
235
+ const OPACITY = 'opacity';
236
+ const TRANSFORM = 'transform';
237
+ const CENTER = '0%';
238
+ const OFF_OPACITY = 0.8;
239
+ const isRTL = navEl.ownerDocument.dir === 'rtl';
240
+ const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
241
+ const OFF_LEFT = isRTL ? '33%' : '-33%';
242
+ const enteringEl = opts.enteringEl;
243
+ const leavingEl = opts.leavingEl;
244
+ const backDirection = opts.direction === 'back';
245
+ const contentEl = enteringEl.querySelector(':scope > ion-content');
246
+ const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
247
+ const enteringToolBarEls = enteringEl.querySelectorAll(':scope > ion-header > ion-toolbar');
248
+ const rootAnimation = createAnimation();
249
+ const enteringContentAnimation = createAnimation();
250
+ rootAnimation
251
+ .addElement(enteringEl)
252
+ .duration((opts.duration ?? 0) || DURATION)
253
+ .easing(opts.easing || EASING)
254
+ .fill('both')
255
+ .beforeRemoveClass('ion-page-invisible');
256
+ if (leavingEl && navEl !== null && navEl !== undefined) {
257
+ const navDecorAnimation = createAnimation();
258
+ navDecorAnimation.addElement(navEl);
259
+ rootAnimation.addAnimation(navDecorAnimation);
260
+ }
261
+ if (!contentEl && enteringToolBarEls.length === 0 && headerEls.length === 0) {
262
+ enteringContentAnimation.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs'));
263
+ }
264
+ else {
265
+ enteringContentAnimation.addElement(contentEl);
266
+ enteringContentAnimation.addElement(headerEls);
267
+ }
268
+ rootAnimation.addAnimation(enteringContentAnimation);
269
+ if (backDirection) {
270
+ enteringContentAnimation
271
+ .beforeClearStyles([OPACITY])
272
+ .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
273
+ .fromTo(OPACITY, OFF_OPACITY, 1);
274
+ }
275
+ else {
276
+ enteringContentAnimation.beforeClearStyles([OPACITY]).fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
277
+ }
278
+ if (contentEl) {
279
+ const enteringTransitionEffectEl = shadow(contentEl).querySelector('.transition-effect');
280
+ if (enteringTransitionEffectEl) {
281
+ const enteringTransitionCoverEl = enteringTransitionEffectEl.querySelector('.transition-cover');
282
+ const enteringTransitionShadowEl = enteringTransitionEffectEl.querySelector('.transition-shadow');
283
+ const enteringTransitionEffect = createAnimation();
284
+ const enteringTransitionCover = createAnimation();
285
+ const enteringTransitionShadow = createAnimation();
286
+ enteringTransitionEffect
287
+ .addElement(enteringTransitionEffectEl)
288
+ .beforeStyles({ opacity: '1', display: 'block' })
289
+ .afterStyles({ opacity: '', display: '' });
290
+ enteringTransitionCover
291
+ .addElement(enteringTransitionCoverEl)
292
+ .beforeClearStyles([OPACITY])
293
+ .fromTo(OPACITY, 0, 0.1);
294
+ enteringTransitionShadow
295
+ .addElement(enteringTransitionShadowEl)
296
+ .beforeClearStyles([OPACITY])
297
+ .fromTo(OPACITY, 0.03, 0.7);
298
+ enteringTransitionEffect.addAnimation([enteringTransitionCover, enteringTransitionShadow]);
299
+ enteringContentAnimation.addAnimation([enteringTransitionEffect]);
300
+ }
301
+ }
302
+ const enteringContentHasLargeTitle = enteringEl.querySelector('ion-header.header-collapse-condense');
303
+ const { forward, backward } = createLargeTitleTransition(rootAnimation, isRTL, backDirection, enteringEl, leavingEl);
304
+ enteringToolBarEls.forEach((enteringToolBarEl) => {
305
+ const enteringToolBar = createAnimation();
306
+ enteringToolBar.addElement(enteringToolBarEl);
307
+ rootAnimation.addAnimation(enteringToolBar);
308
+ const enteringTitle = createAnimation();
309
+ enteringTitle.addElement(enteringToolBarEl.querySelector('ion-title'));
310
+ const enteringToolBarButtons = createAnimation();
311
+ const buttons = Array.from(enteringToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
312
+ const parentHeader = enteringToolBarEl.closest('ion-header');
313
+ const inactiveHeader = parentHeader?.classList.contains('header-collapse-condense-inactive');
314
+ let buttonsToAnimate;
315
+ if (backDirection) {
316
+ buttonsToAnimate = buttons.filter((button) => {
317
+ const isCollapseButton = button.classList.contains('buttons-collapse');
318
+ return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
319
+ });
320
+ }
321
+ else {
322
+ buttonsToAnimate = buttons.filter((button) => !button.classList.contains('buttons-collapse'));
323
+ }
324
+ enteringToolBarButtons.addElement(buttonsToAnimate);
325
+ const enteringToolBarItems = createAnimation();
326
+ enteringToolBarItems.addElement(enteringToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])'));
327
+ const enteringToolBarBg = createAnimation();
328
+ enteringToolBarBg.addElement(shadow(enteringToolBarEl).querySelector('.toolbar-background'));
329
+ const enteringBackButton = createAnimation();
330
+ const backButtonEl = enteringToolBarEl.querySelector('ion-back-button');
331
+ if (backButtonEl) {
332
+ enteringBackButton.addElement(backButtonEl);
333
+ }
334
+ enteringToolBar.addAnimation([enteringTitle, enteringToolBarButtons, enteringToolBarItems, enteringToolBarBg, enteringBackButton]);
335
+ enteringToolBarButtons.fromTo(OPACITY, 0.01, 1);
336
+ enteringToolBarItems.fromTo(OPACITY, 0.01, 1);
337
+ if (backDirection) {
338
+ if (!inactiveHeader) {
339
+ enteringTitle.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`).fromTo(OPACITY, 0.01, 1);
340
+ }
341
+ enteringToolBarItems.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`);
342
+ enteringBackButton.fromTo(OPACITY, 0.01, 1);
343
+ }
344
+ else {
345
+ if (!enteringContentHasLargeTitle) {
346
+ enteringTitle.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`).fromTo(OPACITY, 0.01, 1);
347
+ }
348
+ enteringToolBarItems.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
349
+ enteringToolBarBg.beforeClearStyles([OPACITY, 'transform']);
350
+ const translucentHeader = parentHeader?.translucent;
351
+ if (!translucentHeader) {
352
+ enteringToolBarBg.fromTo(OPACITY, 0.01, 'var(--opacity)');
353
+ }
354
+ else {
355
+ enteringToolBarBg.fromTo('transform', isRTL ? 'translateX(-100%)' : 'translateX(100%)', 'translateX(0px)');
356
+ }
357
+ if (!forward) {
358
+ enteringBackButton.fromTo(OPACITY, 0.01, 1);
359
+ }
360
+ if (backButtonEl && !forward) {
361
+ const enteringBackBtnText = createAnimation();
362
+ enteringBackBtnText
363
+ .addElement(shadow(backButtonEl).querySelector('.button-text'))
364
+ .fromTo(`transform`, isRTL ? 'translateX(-100px)' : 'translateX(100px)', 'translateX(0px)');
365
+ enteringToolBar.addAnimation(enteringBackBtnText);
366
+ }
367
+ }
368
+ });
369
+ if (leavingEl) {
370
+ const leavingContent = createAnimation();
371
+ const leavingContentEl = leavingEl.querySelector(':scope > ion-content');
372
+ const leavingToolBarEls = leavingEl.querySelectorAll(':scope > ion-header > ion-toolbar');
373
+ const leavingHeaderEls = leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
374
+ if (!leavingContentEl && leavingToolBarEls.length === 0 && leavingHeaderEls.length === 0) {
375
+ leavingContent.addElement(leavingEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs'));
376
+ }
377
+ else {
378
+ leavingContent.addElement(leavingContentEl);
379
+ leavingContent.addElement(leavingHeaderEls);
380
+ }
381
+ rootAnimation.addAnimation(leavingContent);
382
+ if (backDirection) {
383
+ leavingContent
384
+ .beforeClearStyles([OPACITY])
385
+ .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
386
+ const leavingPage = getIonPageElement(leavingEl);
387
+ rootAnimation.afterAddWrite(() => {
388
+ if (rootAnimation.getDirection() === 'normal') {
389
+ leavingPage.style.setProperty('display', 'none');
390
+ }
391
+ });
392
+ }
393
+ else {
394
+ leavingContent.fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`).fromTo(OPACITY, 1, OFF_OPACITY);
395
+ }
396
+ if (leavingContentEl) {
397
+ const leavingTransitionEffectEl = shadow(leavingContentEl).querySelector('.transition-effect');
398
+ if (leavingTransitionEffectEl) {
399
+ const leavingTransitionCoverEl = leavingTransitionEffectEl.querySelector('.transition-cover');
400
+ const leavingTransitionShadowEl = leavingTransitionEffectEl.querySelector('.transition-shadow');
401
+ const leavingTransitionEffect = createAnimation();
402
+ const leavingTransitionCover = createAnimation();
403
+ const leavingTransitionShadow = createAnimation();
404
+ leavingTransitionEffect
405
+ .addElement(leavingTransitionEffectEl)
406
+ .beforeStyles({ opacity: '1', display: 'block' })
407
+ .afterStyles({ opacity: '', display: '' });
408
+ leavingTransitionCover
409
+ .addElement(leavingTransitionCoverEl)
410
+ .beforeClearStyles([OPACITY])
411
+ .fromTo(OPACITY, 0.1, 0);
412
+ leavingTransitionShadow
413
+ .addElement(leavingTransitionShadowEl)
414
+ .beforeClearStyles([OPACITY])
415
+ .fromTo(OPACITY, 0.7, 0.03);
416
+ leavingTransitionEffect.addAnimation([leavingTransitionCover, leavingTransitionShadow]);
417
+ leavingContent.addAnimation([leavingTransitionEffect]);
418
+ }
419
+ }
420
+ leavingToolBarEls.forEach((leavingToolBarEl) => {
421
+ const leavingToolBar = createAnimation();
422
+ leavingToolBar.addElement(leavingToolBarEl);
423
+ const leavingTitle = createAnimation();
424
+ leavingTitle.addElement(leavingToolBarEl.querySelector('ion-title'));
425
+ const leavingToolBarButtons = createAnimation();
426
+ const buttons = leavingToolBarEl.querySelectorAll('ion-buttons,[menuToggle]');
427
+ const parentHeader = leavingToolBarEl.closest('ion-header');
428
+ const inactiveHeader = parentHeader?.classList.contains('header-collapse-condense-inactive');
429
+ const buttonsToAnimate = Array.from(buttons).filter((button) => {
430
+ const isCollapseButton = button.classList.contains('buttons-collapse');
431
+ return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
432
+ });
433
+ leavingToolBarButtons.addElement(buttonsToAnimate);
434
+ const leavingToolBarItems = createAnimation();
435
+ const leavingToolBarItemEls = leavingToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])');
436
+ if (leavingToolBarItemEls.length > 0) {
437
+ leavingToolBarItems.addElement(leavingToolBarItemEls);
438
+ }
439
+ const leavingToolBarBg = createAnimation();
440
+ leavingToolBarBg.addElement(shadow(leavingToolBarEl).querySelector('.toolbar-background'));
441
+ const leavingBackButton = createAnimation();
442
+ const backButtonEl = leavingToolBarEl.querySelector('ion-back-button');
443
+ if (backButtonEl) {
444
+ leavingBackButton.addElement(backButtonEl);
445
+ }
446
+ leavingToolBar.addAnimation([leavingTitle, leavingToolBarButtons, leavingToolBarItems, leavingBackButton, leavingToolBarBg]);
447
+ rootAnimation.addAnimation(leavingToolBar);
448
+ leavingBackButton.fromTo(OPACITY, 0.99, 0);
449
+ leavingToolBarButtons.fromTo(OPACITY, 0.99, 0);
450
+ leavingToolBarItems.fromTo(OPACITY, 0.99, 0);
451
+ if (backDirection) {
452
+ if (!inactiveHeader) {
453
+ leavingTitle
454
+ .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)')
455
+ .fromTo(OPACITY, 0.99, 0);
456
+ }
457
+ leavingToolBarItems.fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
458
+ leavingToolBarBg.beforeClearStyles([OPACITY, 'transform']);
459
+ const translucentHeader = parentHeader?.translucent;
460
+ if (!translucentHeader) {
461
+ leavingToolBarBg.fromTo(OPACITY, 'var(--opacity)', 0);
462
+ }
463
+ else {
464
+ leavingToolBarBg.fromTo('transform', 'translateX(0px)', isRTL ? 'translateX(-100%)' : 'translateX(100%)');
465
+ }
466
+ if (backButtonEl && !backward) {
467
+ const leavingBackBtnText = createAnimation();
468
+ leavingBackBtnText
469
+ .addElement(shadow(backButtonEl).querySelector('.button-text'))
470
+ .fromTo('transform', `translateX(${CENTER})`, `translateX(${(isRTL ? -124 : 124) + 'px'})`);
471
+ leavingToolBar.addAnimation(leavingBackBtnText);
472
+ }
473
+ }
474
+ else {
475
+ if (!inactiveHeader) {
476
+ leavingTitle
477
+ .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
478
+ .fromTo(OPACITY, 0.99, 0)
479
+ .afterClearStyles([TRANSFORM, OPACITY]);
480
+ }
481
+ leavingToolBarItems
482
+ .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
483
+ .afterClearStyles([TRANSFORM, OPACITY]);
484
+ leavingBackButton.afterClearStyles([OPACITY]);
485
+ leavingTitle.afterClearStyles([OPACITY]);
486
+ leavingToolBarButtons.afterClearStyles([OPACITY]);
487
+ }
488
+ });
489
+ }
490
+ return rootAnimation;
491
+ }
492
+ catch (err) {
493
+ throw err;
494
+ }
495
+ };
496
+ const LARGE_TITLE_SIZE_OFFSET = 10;
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,17 @@
1
1
  import { AnimationPosition } from './sheets-of-glass/interfaces';
2
+ import { IonicConfig } from '@ionic/core';
2
3
  export declare const getElementRoot: (el: HTMLElement, fallback?: HTMLElement) => HTMLElement | ShadowRoot;
3
4
  export declare const raf: (h: FrameRequestCallback) => any;
4
5
  export declare const cloneElement: (tagName: string) => HTMLElement;
5
6
  export declare const getStep: (targetX: number, animationPosition: AnimationPosition) => number;
6
7
  export declare const changeSelectedElement: (targetElement: HTMLElement, selectedElement: HTMLElement, effectTagName: string, selectedClassName: string) => void;
8
+ export declare class Config {
9
+ private m;
10
+ reset(configObj: IonicConfig): void;
11
+ get(key: keyof IonicConfig, fallback?: any): any;
12
+ getBoolean(key: keyof IonicConfig, fallback?: boolean): boolean;
13
+ getNumber(key: keyof IonicConfig, fallback?: number): number;
14
+ set(key: keyof IonicConfig, value: any): void;
15
+ }
16
+ export declare const config: Config;
7
17
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAKjE,eAAO,MAAM,cAAc,GAAI,IAAI,WAAW,EAAE,WAAU,WAAgB,6BAEzE,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,GAAG,oBAAoB,QAQ1C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,WAY9C,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,EAAE,mBAAmB,iBAAiB,WAQ5E,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,eAAe,WAAW,EAC1B,iBAAiB,WAAW,EAC5B,eAAe,MAAM,EACrB,mBAAmB,MAAM,KACxB,IAMF,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK1C,eAAO,MAAM,cAAc,GAAI,IAAI,WAAW,EAAE,WAAU,WAAgB,6BAEzE,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,GAAG,oBAAoB,QAQ1C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,WAY9C,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,EAAE,mBAAmB,iBAAiB,WAQ5E,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,eAAe,WAAW,EAC1B,iBAAiB,WAAW,EAC5B,eAAe,MAAM,EACrB,mBAAmB,MAAM,KACxB,IAMF,CAAC;AAEF,qBAAa,MAAM;IACjB,OAAO,CAAC,CAAC,CAAqC;IAE9C,KAAK,CAAC,SAAS,EAAE,WAAW;IAI5B,GAAG,CAAC,GAAG,EAAE,MAAM,WAAW,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,GAAG;IAKhD,UAAU,CAAC,GAAG,EAAE,MAAM,WAAW,EAAE,QAAQ,UAAQ,GAAG,OAAO;IAW7D,SAAS,CAAC,GAAG,EAAE,MAAM,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;IAK5D,GAAG,CAAC,GAAG,EAAE,MAAM,WAAW,EAAE,KAAK,EAAE,GAAG;CAGvC;AAED,eAAO,MAAM,MAAM,QAA6B,CAAC"}
package/dist/utils.js CHANGED
@@ -37,3 +37,33 @@ export const changeSelectedElement = (targetElement, selectedElement, effectTagN
37
37
  });
38
38
  selectedElement.classList.add('ion-activated');
39
39
  };
40
+ export class Config {
41
+ constructor() {
42
+ this.m = new Map();
43
+ }
44
+ reset(configObj) {
45
+ this.m = new Map(Object.entries(configObj));
46
+ }
47
+ get(key, fallback) {
48
+ const value = this.m.get(key);
49
+ return value !== undefined ? value : fallback;
50
+ }
51
+ getBoolean(key, fallback = false) {
52
+ const val = this.m.get(key);
53
+ if (val === undefined) {
54
+ return fallback;
55
+ }
56
+ if (typeof val === 'string') {
57
+ return val === 'true';
58
+ }
59
+ return !!val;
60
+ }
61
+ getNumber(key, fallback) {
62
+ const val = parseFloat(this.m.get(key));
63
+ return isNaN(val) ? (fallback !== undefined ? fallback : NaN) : val;
64
+ }
65
+ set(key, value) {
66
+ this.m.set(key, value);
67
+ }
68
+ }
69
+ export const config = new Config();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rdlabo/ionic-theme-ios26",
3
- "version": "1.3.3",
3
+ "version": "2.0.0",
4
4
  "description": "iOS26 Theme for Ionic Framework",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",