@rdlabo/ionic-theme-ios27 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dist/css/components/ion-button.css +1 -1
- package/dist/css/components/ion-fab.css +1 -1
- package/dist/css/components/ion-list.css +1 -1
- package/dist/css/components/ion-menu.css +1 -1
- package/dist/css/components/ion-searchbar.css +1 -1
- package/dist/css/components/ion-tabs.css +1 -1
- package/dist/css/components/ion-toolbar.css +1 -1
- package/dist/css/ionic-theme-ios27.css +1 -1
- package/dist/css/md-ion-list-inset.css +1 -1
- package/dist/css/utils/translucent.css +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/native/definitions.d.ts +19 -0
- package/dist/native/definitions.d.ts.map +1 -1
- package/dist/native/index.d.ts +4 -3
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +22 -9
- package/dist/native/lifecycle.d.ts +4 -0
- package/dist/native/lifecycle.d.ts.map +1 -0
- package/dist/native/lifecycle.js +34 -0
- package/dist/native/runtime.d.ts +2 -2
- package/dist/native/runtime.d.ts.map +1 -1
- package/dist/native/runtime.js +43 -4
- package/dist/tab-bar-searchable/animations/enter.d.ts +1 -1
- package/dist/tab-bar-searchable/animations/enter.d.ts.map +1 -1
- package/dist/tab-bar-searchable/animations/enter.js +1 -1
- package/dist/tab-bar-searchable/animations/leave.d.ts +1 -1
- package/dist/tab-bar-searchable/animations/leave.d.ts.map +1 -1
- package/dist/tab-bar-searchable/animations/leave.js +1 -1
- package/dist/tab-bar-searchable/index.d.ts +2 -2
- package/dist/tab-bar-searchable/index.d.ts.map +1 -1
- package/dist/tab-bar-searchable/index.js +2 -3
- package/dist/transition/ios.transition.d.ts +6 -1
- package/dist/transition/ios.transition.d.ts.map +1 -1
- package/dist/transition/ios.transition.js +10 -385
- package/docs/features.md +3 -1
- package/docs/native-ui-shell.md +113 -0
- package/ios/Sources/IonicNativeUIShellPlugin/IonicNativeUIShellPlugin.swift +28 -0
- package/node_modules/@rdlabo/ionic-theme-utils/LICENSE +21 -0
- package/node_modules/@rdlabo/ionic-theme-utils/README.md +28 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.d.ts +3 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.d.ts.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.js +13 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/dom.js.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.d.ts +6 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.d.ts.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.js +37 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/focus-controller.js.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/index.d.ts +13 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/index.d.ts.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/index.js +11 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/index.js.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.enter.d.ts +0 -1
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.d.ts.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.enter.js +8 -5
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.enter.js.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.leave.d.ts.map +1 -1
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.leave.js +11 -5
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/animations/ios.leave.js.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/callout-surface.js +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/callout-surface.js.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.js +2 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/popover-interface.js.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/utils.d.ts +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.d.ts.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/utils.js +3 -2
- package/node_modules/@rdlabo/ionic-theme-utils/dist/popover/utils.js.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.d.ts +16 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.d.ts.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.js +2 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/sheets-of-glass.js.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/interfaces.js +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/interfaces.js.map +1 -0
- package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/utils.js +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/tab-bar-searchable/utils.js.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.d.ts +15 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.d.ts.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.js +49 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/theme.js.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.d.ts +18 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.d.ts.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.js +412 -0
- package/node_modules/@rdlabo/ionic-theme-utils/dist/transition/ios.transition.js.map +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/package.json +64 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/dom.spec.ts +19 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/dom.ts +16 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/focus-controller.ts +38 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/index.ts +59 -0
- package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/animations/ios.enter.ts +7 -5
- package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/animations/ios.leave.ts +14 -5
- package/node_modules/@rdlabo/ionic-theme-utils/src/popover/utils.spec.ts +58 -0
- package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/utils.ts +4 -2
- package/node_modules/@rdlabo/ionic-theme-utils/src/sheets-of-glass.ts +17 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/styles/index.scss +1 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/styles/md-ion-list-inset.scss +20 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/styles/structured-list.scss +310 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/tab-bar-searchable/utils.spec.ts +56 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/theme.ts +51 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/transition/ios.transition.spec.ts +52 -0
- package/node_modules/@rdlabo/ionic-theme-utils/src/transition/ios.transition.ts +542 -0
- package/package.json +13 -5
- package/src/index.ts +4 -2
- package/src/native/definitions.ts +34 -0
- package/src/native/index.ts +38 -11
- package/src/native/lifecycle.ts +38 -0
- package/src/native/runtime.ts +49 -4
- package/src/styles/components/ion-button.scss +21 -10
- package/src/styles/components/ion-fab.scss +10 -4
- package/src/styles/components/ion-list.scss +12 -3
- package/src/styles/components/ion-menu.scss +17 -10
- package/src/styles/components/ion-searchbar.scss +1 -1
- package/src/styles/components/ion-tabs.scss +14 -10
- package/src/styles/components/ion-toolbar.scss +9 -10
- package/src/styles/md-ion-list-inset.scss +2 -2
- package/src/styles/utils/dark/ion-list.scss +1 -1
- package/src/styles/utils/translucent.scss +44 -0
- package/src/tab-bar-searchable/animations/enter.ts +1 -2
- package/src/tab-bar-searchable/animations/leave.ts +1 -2
- package/src/tab-bar-searchable/index.ts +12 -4
- package/src/transition/ios.transition.ts +14 -473
- package/dist/css/utils/structured-list.css +0 -1
- package/dist/popover/animations/ios.enter.d.ts.map +0 -1
- package/dist/popover/popover-interface.js +0 -1
- package/dist/popover/utils.d.ts.map +0 -1
- package/src/styles/utils/structured-list.scss +0 -223
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/animations/ios.leave.d.ts +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/callout-surface.d.ts +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/callout-surface.d.ts.map +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/popover-interface.d.ts +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/popover/popover-interface.d.ts.map +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/interfaces.d.ts +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/interfaces.d.ts.map +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/utils.d.ts +0 -0
- /package/{dist → node_modules/@rdlabo/ionic-theme-utils/dist}/tab-bar-searchable/utils.d.ts.map +0 -0
- /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/callout-surface.ts +0 -0
- /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/popover/popover-interface.ts +0 -0
- /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/tab-bar-searchable/interfaces.ts +0 -0
- /package/{src → node_modules/@rdlabo/ionic-theme-utils/src}/tab-bar-searchable/utils.ts +0 -0
|
@@ -0,0 +1,542 @@
|
|
|
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
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rdlabo/ionic-theme-ios27",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"description": "iOS27 Theme for Ionic Framework",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -27,9 +27,10 @@
|
|
|
27
27
|
"Package.swift"
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
|
-
"build": "npm run build:css && npm run build:ts",
|
|
31
|
-
"build:css": "rm -rf dist/css && sass src/styles:dist/css --style=compressed --no-source-map",
|
|
30
|
+
"build": "npm run docgen && npm run build:css && npm run build:ts",
|
|
31
|
+
"build:css": "rm -rf dist/css && sass src/styles:dist/css --style=compressed --no-source-map --pkg-importer=node",
|
|
32
32
|
"build:ts": "tsc",
|
|
33
|
+
"docgen": "docgen --project tsconfig.docgen.json --api NativeUIShellHandle --output-readme docs/native-ui-shell.md",
|
|
33
34
|
"build:demo": "npm run build && cd demo && npm install && npm run build -- --configuration=production",
|
|
34
35
|
"lint": "prettier --check \"./**/*.{scss,ts}\" && prettier --parser angular --check \"./**/*.html\"",
|
|
35
36
|
"fmt": "prettier --write \"./**/*.{scss,ts}\" && prettier --parser angular --write \"./**/*.html\"",
|
|
@@ -53,9 +54,16 @@
|
|
|
53
54
|
"url": "https://github.com/rdlabo-dev/ionic-theme-ios27/issues"
|
|
54
55
|
},
|
|
55
56
|
"homepage": "https://docs.rdlabo.dev/projects/ionic-theme-ios27",
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@rdlabo/ionic-theme-utils": "git+https://github.com/rdlabo-dev/ionic-theme-utils.git#66eb2fccca10646ebfccdfb3b6c2f3b4c9b00bf6"
|
|
59
|
+
},
|
|
60
|
+
"bundleDependencies": [
|
|
61
|
+
"@rdlabo/ionic-theme-utils"
|
|
62
|
+
],
|
|
56
63
|
"devDependencies": {
|
|
57
64
|
"@capacitor/core": "^8.5.2",
|
|
58
65
|
"@ionic/angular": "^9.0.0",
|
|
66
|
+
"@rdlabo/capacitor-docgen": "^0.4.1",
|
|
59
67
|
"husky": "^9.1.7",
|
|
60
68
|
"lint-staged": "^16.2.1",
|
|
61
69
|
"np": "^10.2.0",
|
|
@@ -65,8 +73,8 @@
|
|
|
65
73
|
"wrangler": "^4.125.0"
|
|
66
74
|
},
|
|
67
75
|
"peerDependencies": {
|
|
68
|
-
"@
|
|
69
|
-
"@
|
|
76
|
+
"@capacitor/core": ">=8.0.0 <9",
|
|
77
|
+
"@ionic/core": ">=8.8.1 <10"
|
|
70
78
|
},
|
|
71
79
|
"peerDependenciesMeta": {
|
|
72
80
|
"@capacitor/core": {
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { registeredEffect } from './sheets-of-glass/interfaces';
|
|
2
2
|
import { registerEffect } from './sheets-of-glass';
|
|
3
3
|
export * from './sheets-of-glass/interfaces';
|
|
4
|
-
export {
|
|
5
|
-
|
|
4
|
+
export {
|
|
5
|
+
iosPopoverEnterAnimation as popoverEnterAnimation,
|
|
6
|
+
iosPopoverLeaveAnimation as popoverLeaveAnimation,
|
|
7
|
+
} from '@rdlabo/ionic-theme-utils';
|
|
6
8
|
export * from './tab-bar-searchable';
|
|
7
9
|
export * from './searchbar';
|
|
8
10
|
export * from './transition/ios.transition';
|
|
@@ -10,11 +10,38 @@ export interface NativeUIShellStatus {
|
|
|
10
10
|
reason?: string;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
export interface NativeUIShellOptions {
|
|
14
|
+
/** Enables Native UI Shell globally. Defaults to `true`. */
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
/** Controls eligible for native projection. Omit to enable every control; when present, only `true` controls are enabled. */
|
|
17
|
+
controls?: NativeUIShellControls;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface NativeUIShellControls {
|
|
21
|
+
/** Projects tab bars and their native search presentation. */
|
|
22
|
+
tabs?: boolean;
|
|
23
|
+
/** Projects toolbar buttons, including back and menu buttons. */
|
|
24
|
+
toolbar?: boolean;
|
|
25
|
+
/** Projects segments. */
|
|
26
|
+
segment?: boolean;
|
|
27
|
+
/** Projects floating action buttons. */
|
|
28
|
+
fab?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
13
31
|
export interface NativeUIShellHandle {
|
|
32
|
+
/** Returns the current Web/native projection state. */
|
|
14
33
|
getStatus(): NativeUIShellStatus;
|
|
34
|
+
/** Restores projected controls to the Web until the returned lease is resumed. */
|
|
35
|
+
suspend(): Promise<NativeUIShellSuspension>;
|
|
36
|
+
/** Stops synchronization, restores Web controls and releases native resources. */
|
|
15
37
|
destroy(): Promise<void>;
|
|
16
38
|
}
|
|
17
39
|
|
|
40
|
+
export interface NativeUIShellSuspension {
|
|
41
|
+
/** Releases this suspension. Native projection resumes after all active suspensions are released. */
|
|
42
|
+
resume(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
|
|
18
45
|
export interface Frame {
|
|
19
46
|
x: number;
|
|
20
47
|
y: number;
|
|
@@ -98,10 +125,17 @@ export interface ShellActivation {
|
|
|
98
125
|
sequence: number;
|
|
99
126
|
}
|
|
100
127
|
|
|
128
|
+
export interface WebViewMetrics {
|
|
129
|
+
/** The WebView's effective top-left corner radius in points, or `0` when unavailable. */
|
|
130
|
+
radius: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
101
133
|
export interface NativeUIShellPlugin {
|
|
102
134
|
configure(): Promise<{ supported: boolean }>;
|
|
135
|
+
getWebViewMetrics(): Promise<WebViewMetrics>;
|
|
103
136
|
update(snapshot: ShellSnapshot): Promise<{ revision: number; rejectedSearches?: string[]; rejectedControls?: string[] }>;
|
|
104
137
|
clear(options: { revision: number }): Promise<void>;
|
|
105
138
|
addListener(name: 'activate', listener: (event: ShellActivation) => void): Promise<PluginListenerHandle>;
|
|
106
139
|
addListener(name: 'search', listener: (event: ShellSearchEvent) => void): Promise<PluginListenerHandle>;
|
|
140
|
+
addListener(name: 'webViewMetricsChange', listener: (event: WebViewMetrics) => void): Promise<PluginListenerHandle>;
|
|
107
141
|
}
|