@webview-native-ui/engine 1.0.1 → 1.0.2-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 (230) hide show
  1. package/README.md +14 -0
  2. package/WebViewNativeUIControls.podspec +17 -0
  3. package/dist/controls/activation.d.ts +15 -0
  4. package/dist/controls/activation.js +370 -0
  5. package/dist/controls/components/index.d.ts +16 -0
  6. package/dist/controls/components/index.js +38 -0
  7. package/dist/controls/components/ion-back-button.d.ts +4 -0
  8. package/dist/controls/components/ion-back-button.js +16 -0
  9. package/dist/controls/components/ion-button.d.ts +4 -0
  10. package/dist/controls/components/ion-button.js +26 -0
  11. package/dist/controls/components/ion-buttons.d.ts +5 -0
  12. package/dist/controls/components/ion-buttons.js +34 -0
  13. package/dist/controls/components/ion-fab.d.ts +4 -0
  14. package/dist/controls/components/ion-fab.js +164 -0
  15. package/dist/controls/components/ion-menu-button.d.ts +7 -0
  16. package/dist/controls/components/ion-menu-button.js +41 -0
  17. package/dist/controls/components/ion-segment.d.ts +5 -0
  18. package/dist/controls/components/ion-segment.js +24 -0
  19. package/dist/controls/components/ion-tab-bar.d.ts +5 -0
  20. package/dist/controls/components/ion-tab-bar.js +49 -0
  21. package/dist/controls/components/searchable-tabs.d.ts +20 -0
  22. package/dist/controls/components/searchable-tabs.js +525 -0
  23. package/dist/controls/definitions.d.ts +360 -0
  24. package/dist/controls/definitions.js +1 -0
  25. package/dist/controls/extensions.d.ts +44 -0
  26. package/dist/controls/extensions.js +164 -0
  27. package/dist/controls/foldable/fold-state.d.ts +4 -0
  28. package/dist/controls/foldable/fold-state.js +8 -0
  29. package/dist/controls/foldable/types.d.ts +9 -0
  30. package/dist/controls/foldable/types.js +1 -0
  31. package/dist/controls/html.d.ts +8 -0
  32. package/dist/controls/html.js +260 -0
  33. package/dist/controls/index.d.ts +7 -0
  34. package/dist/controls/index.js +4 -0
  35. package/dist/controls/ionic.d.ts +1 -0
  36. package/dist/controls/ionic.js +1 -0
  37. package/dist/controls/legacy-layout.d.ts +7 -0
  38. package/dist/controls/legacy-layout.js +23 -0
  39. package/dist/controls/overlays/content.d.ts +2 -0
  40. package/dist/controls/overlays/content.js +55 -0
  41. package/dist/controls/overlays/controller.d.ts +7 -0
  42. package/dist/controls/overlays/controller.js +369 -0
  43. package/dist/controls/overlays/covered-overlay.d.ts +4 -0
  44. package/dist/controls/overlays/covered-overlay.js +9 -0
  45. package/dist/controls/overlays/dialog-animation.d.ts +7 -0
  46. package/dist/controls/overlays/dialog-animation.js +49 -0
  47. package/dist/controls/overlays/dismiss-animation.d.ts +2 -0
  48. package/dist/controls/overlays/dismiss-animation.js +14 -0
  49. package/dist/controls/overlays/focus.d.ts +2 -0
  50. package/dist/controls/overlays/focus.js +67 -0
  51. package/dist/controls/overlays/popover.d.ts +10 -0
  52. package/dist/controls/overlays/popover.js +117 -0
  53. package/dist/controls/overlays/styles.d.ts +9 -0
  54. package/dist/controls/overlays/styles.js +194 -0
  55. package/dist/controls/prehide.d.ts +6 -0
  56. package/dist/controls/prehide.js +280 -0
  57. package/dist/controls/runtime.d.ts +5 -0
  58. package/dist/controls/runtime.js +1685 -0
  59. package/dist/controls/shared/bridge.d.ts +4 -0
  60. package/dist/controls/shared/bridge.js +15 -0
  61. package/dist/controls/shared/candidate.d.ts +23 -0
  62. package/dist/controls/shared/candidate.js +128 -0
  63. package/dist/controls/shared/clipping.d.ts +1 -0
  64. package/dist/controls/shared/clipping.js +1 -0
  65. package/dist/controls/shared/connection.d.ts +21 -0
  66. package/dist/controls/shared/connection.js +112 -0
  67. package/dist/controls/shared/control-options.d.ts +4 -0
  68. package/dist/controls/shared/control-options.js +14 -0
  69. package/dist/controls/shared/covered-snapshot.d.ts +35 -0
  70. package/dist/controls/shared/covered-snapshot.js +41 -0
  71. package/dist/controls/shared/covered-source.d.ts +22 -0
  72. package/dist/controls/shared/covered-source.js +72 -0
  73. package/dist/controls/shared/crossfade.d.ts +11 -0
  74. package/dist/controls/shared/crossfade.js +71 -0
  75. package/dist/controls/shared/diagnostics.d.ts +2 -0
  76. package/dist/controls/shared/diagnostics.js +16 -0
  77. package/dist/controls/shared/dom.d.ts +45 -0
  78. package/dist/controls/shared/dom.js +258 -0
  79. package/dist/controls/shared/events.d.ts +12 -0
  80. package/dist/controls/shared/events.js +13 -0
  81. package/dist/controls/shared/horizontal-navigation.d.ts +36 -0
  82. package/dist/controls/shared/horizontal-navigation.js +90 -0
  83. package/dist/controls/shared/icons.d.ts +5 -0
  84. package/dist/controls/shared/icons.js +66 -0
  85. package/dist/controls/shared/modal-animation.d.ts +21 -0
  86. package/dist/controls/shared/modal-animation.js +97 -0
  87. package/dist/controls/shared/modal.d.ts +26 -0
  88. package/dist/controls/shared/modal.js +261 -0
  89. package/dist/controls/shared/projection-id.d.ts +2 -0
  90. package/dist/controls/shared/projection-id.js +2 -0
  91. package/dist/controls/shared/scroll-placement.d.ts +1 -0
  92. package/dist/controls/shared/scroll-placement.js +1 -0
  93. package/dist/controls/shared/tab-bar-width.d.ts +7 -0
  94. package/dist/controls/shared/tab-bar-width.js +72 -0
  95. package/dist/controls/shared/toolbar-options.d.ts +10 -0
  96. package/dist/controls/shared/toolbar-options.js +38 -0
  97. package/dist/controls/shared/transition-identity.d.ts +3 -0
  98. package/dist/controls/shared/transition-identity.js +64 -0
  99. package/dist/controls/shared/vertical-bars-geometry.d.ts +8 -0
  100. package/dist/controls/shared/vertical-bars-geometry.js +82 -0
  101. package/dist/controls/shared/vertical-navigation.d.ts +5 -0
  102. package/dist/controls/shared/vertical-navigation.js +39 -0
  103. package/dist/controls/startup.d.ts +7 -0
  104. package/dist/controls/startup.js +72 -0
  105. package/dist/controls/transport.d.ts +10 -0
  106. package/dist/controls/transport.js +1 -0
  107. package/dist/controls/vertical-bars-web-search.d.ts +8 -0
  108. package/dist/controls/vertical-bars-web-search.js +83 -0
  109. package/dist/controls/vertical-bars-web.d.ts +2 -0
  110. package/dist/controls/vertical-bars-web.js +609 -0
  111. package/dist/index.d.ts +1 -0
  112. package/dist/index.js +1 -0
  113. package/dist/integration/index.d.ts +36 -0
  114. package/dist/integration/index.js +25 -0
  115. package/dist/native/session.js +14 -8
  116. package/dist/projection/pause.d.ts +10 -0
  117. package/dist/projection/pause.js +58 -0
  118. package/dist/projection/styles.d.ts +1 -1
  119. package/dist/projection/styles.js +0 -1
  120. package/dist/projection/surfaces.js +2 -1
  121. package/dist/projection/web.js +39 -5
  122. package/dist/types.d.ts +5 -1
  123. package/docs/README.md +1 -0
  124. package/docs/configuration/README.md +3 -1
  125. package/docs/configuration/ionic-overlays.md +36 -2
  126. package/docs/configuration/pause-resume.md +51 -0
  127. package/docs/controls.md +39 -0
  128. package/ios/Sources/WebViewNativeUIControls/Components/NativeUIButton.swift +98 -0
  129. package/ios/Sources/WebViewNativeUIControls/Components/NativeUIButtons.swift +24 -0
  130. package/ios/Sources/WebViewNativeUIControls/Components/NativeUIComponents.swift +19 -0
  131. package/ios/Sources/WebViewNativeUIControls/Components/NativeUIFab.swift +80 -0
  132. package/ios/Sources/WebViewNativeUIControls/Components/NativeUISearchController.swift +449 -0
  133. package/ios/Sources/WebViewNativeUIControls/Components/NativeUISegment.swift +91 -0
  134. package/ios/Sources/WebViewNativeUIControls/Components/NativeUITabBar.swift +213 -0
  135. package/ios/Sources/WebViewNativeUIControls/Components/NativeUIToolbarTransition.swift +186 -0
  136. package/ios/Sources/WebViewNativeUIControls/Components/NativeUIVerticalBars.swift +696 -0
  137. package/ios/Sources/WebViewNativeUIControls/Components/NativeUIVerticalSearch.swift +117 -0
  138. package/ios/Sources/WebViewNativeUIControls/Extensions/NativeUI.swift +180 -0
  139. package/ios/Sources/WebViewNativeUIControls/Extensions/NativeUIRendering.swift +38 -0
  140. package/ios/Sources/WebViewNativeUIControls/NativeUIController.swift +801 -0
  141. package/ios/Sources/WebViewNativeUIControls/Overlays/NativeUIOverlayController.swift +131 -0
  142. package/ios/Sources/WebViewNativeUIControls/Overlays/NativeUIOverlayHost.swift +85 -0
  143. package/ios/Sources/WebViewNativeUIControls/Shared/NativeUIControlRendering.swift +21 -0
  144. package/ios/Sources/WebViewNativeUIControls/Shared/NativeUICoveredSnapshots.swift +14 -0
  145. package/ios/Sources/WebViewNativeUIControls/Shared/NativeUICrossfade.swift +35 -0
  146. package/ios/Sources/WebViewNativeUIControls/Shared/NativeUIHost.swift +8 -0
  147. package/ios/Sources/WebViewNativeUIControls/Shared/NativeUIScrollTracker.swift +2 -0
  148. package/ios/Sources/WebViewNativeUIControls/Shared/NativeUISnapshot.swift +206 -0
  149. package/ios/Sources/WebViewNativeUIControls/Shared/NativeUIVerticalBarsGeometry.swift +93 -0
  150. package/ios/Sources/WebViewNativeUIEngine/CoveredSnapshots.swift +2 -2
  151. package/ios/Sources/WebViewNativeUIEngine/NativeUIProjection.swift +1 -1
  152. package/ios/Sources/WebViewNativeUIEngine/Resources/native-ui-engine.js +3 -4
  153. package/package.json +30 -5
  154. package/src/controls/activation.ts +427 -0
  155. package/src/controls/components/index.ts +45 -0
  156. package/src/controls/components/ion-back-button.ts +22 -0
  157. package/src/controls/components/ion-button.ts +28 -0
  158. package/src/controls/components/ion-buttons.ts +37 -0
  159. package/src/controls/components/ion-fab.ts +151 -0
  160. package/src/controls/components/ion-menu-button.ts +37 -0
  161. package/src/controls/components/ion-segment.ts +27 -0
  162. package/src/controls/components/ion-tab-bar.ts +55 -0
  163. package/src/controls/components/searchable-tabs.ts +534 -0
  164. package/src/controls/definitions.ts +338 -0
  165. package/src/controls/extensions.ts +198 -0
  166. package/src/controls/foldable/fold-state.ts +10 -0
  167. package/src/controls/foldable/types.ts +4 -0
  168. package/src/controls/html.ts +239 -0
  169. package/src/controls/index.ts +7 -0
  170. package/src/controls/ionic.ts +1 -0
  171. package/src/controls/legacy-layout.ts +21 -0
  172. package/src/controls/overlays/content.ts +51 -0
  173. package/src/controls/overlays/controller.ts +394 -0
  174. package/src/controls/overlays/covered-overlay.ts +11 -0
  175. package/src/controls/overlays/dialog-animation.ts +53 -0
  176. package/src/controls/overlays/dismiss-animation.ts +15 -0
  177. package/src/controls/overlays/focus.ts +64 -0
  178. package/src/controls/overlays/popover.ts +116 -0
  179. package/src/controls/overlays/styles.ts +195 -0
  180. package/src/controls/prehide.ts +285 -0
  181. package/src/controls/runtime.ts +1731 -0
  182. package/src/controls/shared/bridge.ts +18 -0
  183. package/src/controls/shared/candidate.ts +163 -0
  184. package/src/controls/shared/clipping.ts +1 -0
  185. package/src/controls/shared/connection.ts +105 -0
  186. package/src/controls/shared/control-options.ts +20 -0
  187. package/src/controls/shared/covered-snapshot.ts +52 -0
  188. package/src/controls/shared/covered-source.ts +78 -0
  189. package/src/controls/shared/crossfade.ts +70 -0
  190. package/src/controls/shared/diagnostics.ts +13 -0
  191. package/src/controls/shared/dom.ts +310 -0
  192. package/src/controls/shared/events.ts +14 -0
  193. package/src/controls/shared/horizontal-navigation.ts +106 -0
  194. package/src/controls/shared/icons.ts +64 -0
  195. package/src/controls/shared/modal-animation.ts +109 -0
  196. package/src/controls/shared/modal.ts +286 -0
  197. package/src/controls/shared/projection-id.ts +2 -0
  198. package/src/controls/shared/scroll-placement.ts +1 -0
  199. package/src/controls/shared/tab-bar-width.ts +66 -0
  200. package/src/controls/shared/toolbar-options.ts +51 -0
  201. package/src/controls/shared/transition-identity.ts +67 -0
  202. package/src/controls/shared/vertical-bars-geometry.ts +92 -0
  203. package/src/controls/shared/vertical-navigation.ts +34 -0
  204. package/src/controls/startup.ts +74 -0
  205. package/src/controls/transport.ts +11 -0
  206. package/src/controls/vertical-bars-web-search.ts +86 -0
  207. package/src/controls/vertical-bars-web.ts +674 -0
  208. package/src/dom/geometry.ts +24 -0
  209. package/src/dom/overlays.ts +196 -0
  210. package/src/dom/scroll-bindings.ts +66 -0
  211. package/src/dom/scroll-placement.ts +92 -0
  212. package/src/dom/visibility.ts +29 -0
  213. package/src/index.ts +19 -0
  214. package/src/integration/index.ts +64 -0
  215. package/src/ionic.ts +34 -0
  216. package/src/native/bootstrap.ts +132 -0
  217. package/src/native/bridge.ts +18 -0
  218. package/src/native/resource-url.ts +11 -0
  219. package/src/native/session.ts +708 -0
  220. package/src/native/updates.ts +103 -0
  221. package/src/native/values.ts +29 -0
  222. package/src/projection/events.ts +58 -0
  223. package/src/projection/pause.ts +58 -0
  224. package/src/projection/placement.ts +34 -0
  225. package/src/projection/scope.ts +13 -0
  226. package/src/projection/styles.ts +26 -0
  227. package/src/projection/surface.ts +88 -0
  228. package/src/projection/surfaces.ts +119 -0
  229. package/src/projection/web.ts +1013 -0
  230. package/src/types.ts +58 -0
@@ -0,0 +1,26 @@
1
+ import type { Frame } from '../definitions.js';
2
+ import { type ModalAnimation } from './modal-animation.js';
3
+ /** Modal hosts cover the viewport even when their visible dialog is centered. */
4
+ export declare const modalRailClass = "ios-theme-vertical-bars-modal";
5
+ export declare const modalPresentation: (modal: Element) => {
6
+ animation: ModalAnimation;
7
+ frame: Frame;
8
+ } | null | undefined;
9
+ export declare const modalPreparing: (modal: Element) => boolean;
10
+ export declare const modalDismissing: (modal: Element) => boolean;
11
+ export declare const modalStack: (doc: Document) => readonly HTMLIonModalElement[];
12
+ export declare const movingModal: (doc: Document) => HTMLIonModalElement | undefined;
13
+ export declare const modalMotionEvent = "nativeUIModalMotion";
14
+ export declare const topModal: (doc: Document) => HTMLIonModalElement | undefined;
15
+ export declare const modalUsesVerticalBars: (element: Element) => boolean;
16
+ /** Only the foreground modal may contribute controls; never the covered page. */
17
+ export declare const inVerticalBarsSurface: (element: Element) => boolean;
18
+ /** Release Ionic's dormant sheet gesture effect before the leave animation owns opacity.
19
+ * WillDismiss is emitted only after canDismiss succeeds. A gesture dismissal already
20
+ * owns its animation and must not be interrupted. Match only Ionic's standard
21
+ * opacity-only keyframes; leave running and nonmatching effects alone.
22
+ */
23
+ export declare const releaseSheetBackdropGesture: (modal: HTMLElement, role?: string) => void;
24
+ export declare const observeVerticalBarsModals: (doc: Document, animate?: () => boolean) => (() => void);
25
+ /** Visible modal bounds, clipped at the viewport for Ionic's translated sheets. */
26
+ export declare const modalVerticalBarFrame: (modal: Element) => Frame | undefined;
@@ -0,0 +1,261 @@
1
+ import { enableSupportIonicOverlays, ionicModalStack } from '../../ionic.js';
2
+ import { prepareSheetLayout, readModalAnimation } from './modal-animation.js';
3
+ /** Modal hosts cover the viewport even when their visible dialog is centered. */
4
+ export const modalRailClass = 'ios-theme-vertical-bars-modal';
5
+ const presentations = new WeakMap();
6
+ export const modalPresentation = (modal) => presentations.get(modal);
7
+ export const modalPreparing = (modal) => presentations.has(modal) && presentations.get(modal) === null;
8
+ const dismissing = new WeakSet();
9
+ export const modalDismissing = (modal) => dismissing.has(modal);
10
+ const states = new WeakMap();
11
+ export const modalStack = (doc) => states.get(doc)?.stack ?? [];
12
+ export const movingModal = (doc) => states.get(doc)?.moving;
13
+ export const modalMotionEvent = 'nativeUIModalMotion';
14
+ export const topModal = (doc) => states.get(doc)?.top;
15
+ export const modalUsesVerticalBars = (element) => {
16
+ const modal = element.closest('ion-modal');
17
+ return !modal || modal.classList.contains(modalRailClass);
18
+ };
19
+ /** Only the foreground modal may contribute controls; never the covered page. */
20
+ export const inVerticalBarsSurface = (element) => {
21
+ const modal = topModal(element.ownerDocument);
22
+ return modal ? element.closest('ion-modal') === modal && modalUsesVerticalBars(element) : !element.closest('ion-modal');
23
+ };
24
+ /** Release Ionic's dormant sheet gesture effect before the leave animation owns opacity.
25
+ * WillDismiss is emitted only after canDismiss succeeds. A gesture dismissal already
26
+ * owns its animation and must not be interrupted. Match only Ionic's standard
27
+ * opacity-only keyframes; leave running and nonmatching effects alone.
28
+ */
29
+ export const releaseSheetBackdropGesture = (modal, role) => {
30
+ if (role === 'gesture' || !modal.matches('.modal-sheet.ios-theme-vertical-bars-modal'))
31
+ return;
32
+ const backdrop = modal.shadowRoot?.querySelector('ion-backdrop');
33
+ const breakpoint = modal.backdropBreakpoint ?? 0;
34
+ const expected = breakpoint === 0
35
+ ? [
36
+ { offset: 0, opacity: 'var(--backdrop-opacity)' },
37
+ { offset: 1, opacity: '0.01' },
38
+ ]
39
+ : [
40
+ { offset: 0, opacity: 'var(--backdrop-opacity)' },
41
+ { offset: 1 - breakpoint, opacity: '0' },
42
+ { offset: 1, opacity: '0' },
43
+ ];
44
+ for (const animation of backdrop?.getAnimations() ?? []) {
45
+ const effect = animation.effect;
46
+ if (animation.playState !== 'paused' || !(effect instanceof KeyframeEffect))
47
+ continue;
48
+ const frames = effect.getKeyframes();
49
+ if (effect.target !== backdrop ||
50
+ frames.length !== expected.length ||
51
+ !frames.every((frame, index) => frame.offset === expected[index].offset &&
52
+ frame['opacity'] === expected[index].opacity &&
53
+ frame.easing === 'linear' &&
54
+ (frame.composite === 'auto' || frame.composite === 'replace') &&
55
+ Object.keys(frame).every((key) => ['offset', 'computedOffset', 'easing', 'composite', 'opacity'].includes(key))))
56
+ continue;
57
+ animation.cancel();
58
+ }
59
+ };
60
+ export const observeVerticalBarsModals = (doc, animate = () => false) => {
61
+ const win = doc.defaultView;
62
+ const state = { stack: [] };
63
+ states.set(doc, state);
64
+ const overlays = enableSupportIonicOverlays(undefined, doc);
65
+ const observed = new Set();
66
+ const listeners = new AbortController();
67
+ let stopped = false;
68
+ let frame = 0;
69
+ let pointerActive = false;
70
+ let touchActive = false;
71
+ let bounds = '';
72
+ const toolbarTop = '--ios-theme-vertical-bars-modal-offset-top';
73
+ const refresh = () => {
74
+ win.cancelAnimationFrame(frame);
75
+ frame = 0;
76
+ if (stopped)
77
+ return;
78
+ const app = doc.querySelector('ion-app.ios-theme-vertical-bars');
79
+ const modals = Array.from(doc.querySelectorAll('ion-modal'));
80
+ const active = ionicModalStack(doc);
81
+ state.stack = active;
82
+ const top = state.stack[state.stack.length - 1];
83
+ let changed = state.top !== top;
84
+ state.top = top;
85
+ if (top && modalPreparing(top)) {
86
+ const content = top.shadowRoot?.querySelector('[part~="content"]');
87
+ if (content?.getAnimations().some((animation) => animation.playState === 'running')) {
88
+ const presentation = readModalAnimation(content);
89
+ if (presentation) {
90
+ prepareSheetLayout(top);
91
+ presentations.set(top, presentation);
92
+ }
93
+ else
94
+ presentations.delete(top); // Unsupported custom animations retain the existing projection path.
95
+ changed = true;
96
+ }
97
+ }
98
+ const nextBounds = top && !modalPreparing(top) ? JSON.stringify(modalVerticalBarFrame(top)) : '';
99
+ const moved = bounds !== '' && nextBounds !== '' && bounds !== nextBounds;
100
+ changed ||= bounds !== nextBounds;
101
+ bounds = nextBounds;
102
+ const wrapper = top?.shadowRoot?.querySelector('[part~="content"]');
103
+ const animating = wrapper?.getAnimations().some((animation) => animation.playState === 'running') ?? false;
104
+ const moving = top &&
105
+ app &&
106
+ !modalPreparing(top) &&
107
+ !modalDismissing(top) &&
108
+ (state.moving === top ? pointerActive || touchActive || animating || moved : moved && (pointerActive || touchActive || animating))
109
+ ? top
110
+ : undefined;
111
+ const appStyle = app && win.getComputedStyle(app);
112
+ const leftRail = app?.classList.contains('ios-theme-vertical-bars-left') ?? false;
113
+ const resolvedInset = parseFloat(appStyle?.getPropertyValue(`--ios-theme-vertical-bars-safe-area-${leftRail ? 'left' : 'right'}-resolved`) ?? '');
114
+ const inset = Number.isFinite(resolvedInset)
115
+ ? resolvedInset
116
+ : parseFloat(appStyle?.getPropertyValue('--ios-theme-vertical-bars-native-inset') ?? '') || 0;
117
+ const wanted = new Set();
118
+ for (const modal of modals) {
119
+ const content = modal.shadowRoot?.querySelector('[part~="content"]');
120
+ if (content)
121
+ wanted.add(content);
122
+ // offsetWidth is unaffected by Ionic's presentation transforms.
123
+ const fullWidth = !!content && Math.abs(content.offsetWidth - win.innerWidth) <= 1 && Math.abs(content.offsetLeft) <= 1;
124
+ const overlapsRail = !!content &&
125
+ inset > 0 &&
126
+ (leftRail ? content.offsetLeft < inset : content.offsetLeft + content.offsetWidth > win.innerWidth - inset);
127
+ const enabled = !!app?.contains(modal) && active.includes(modal) && (fullWidth || overlapsRail);
128
+ if (enabled) {
129
+ const top = modalPreparing(modal) ? 0 : (modalVerticalBarFrame(modal)?.y ?? 0);
130
+ const offset = `${top}px`;
131
+ if (modal.style.getPropertyValue(toolbarTop) !== offset) {
132
+ modal.style.setProperty(toolbarTop, offset);
133
+ changed = true;
134
+ }
135
+ }
136
+ else
137
+ modal.style.removeProperty(toolbarTop);
138
+ if (modal.classList.contains(modalRailClass) !== enabled) {
139
+ modal.classList.toggle(modalRailClass, enabled);
140
+ changed = true;
141
+ }
142
+ }
143
+ if (state.moving !== moving) {
144
+ const previous = state.moving;
145
+ state.moving = moving;
146
+ win.dispatchEvent(new CustomEvent(modalMotionEvent, { detail: { modal: moving ?? previous, moving: !!moving } }));
147
+ changed = true;
148
+ }
149
+ if (wanted.size !== observed.size || [...wanted].some((element) => !observed.has(element))) {
150
+ resize?.disconnect();
151
+ observer.disconnect();
152
+ observer.observe(doc.documentElement, observation);
153
+ observed.clear();
154
+ for (const element of wanted) {
155
+ resize?.observe(element);
156
+ observer.observe(element, { attributes: true, attributeFilter: ['style', 'class'] });
157
+ observed.add(element);
158
+ }
159
+ }
160
+ if (changed)
161
+ win.dispatchEvent(new CustomEvent('nativeUIRefresh', { detail: { modalMotion: !!state.moving } }));
162
+ if (top &&
163
+ (modalPreparing(top) ||
164
+ (!modalPresentation(top) &&
165
+ (pointerActive ||
166
+ touchActive ||
167
+ !!state.moving ||
168
+ Array.from(wanted).some((element) => element.getAnimations().some((animation) => animation.playState === 'running'))))))
169
+ schedule();
170
+ };
171
+ const schedule = () => {
172
+ if (!stopped && !frame)
173
+ frame = win.requestAnimationFrame(refresh);
174
+ };
175
+ const resize = win.ResizeObserver ? new win.ResizeObserver(schedule) : undefined;
176
+ const observer = new MutationObserver(schedule);
177
+ const observation = { subtree: true, childList: true, attributes: true, attributeFilter: ['class', 'style'] };
178
+ observer.observe(doc.documentElement, observation);
179
+ const stopOverlays = overlays.subscribe(({ element, phase, event }) => {
180
+ if (!element?.matches('ion-modal')) {
181
+ if (phase === 'change')
182
+ refresh();
183
+ return;
184
+ }
185
+ const modal = element;
186
+ if (phase === 'willPresent' && animate() && modal.closest('ion-app.ios-theme-vertical-bars'))
187
+ presentations.set(modal, null);
188
+ else if (phase === 'didPresent' || phase === 'willDismiss' || phase === 'didDismiss') {
189
+ if (presentations.delete(modal))
190
+ bounds = '';
191
+ }
192
+ if (phase === 'willDismiss') {
193
+ dismissing.add(modal);
194
+ if (animate())
195
+ releaseSheetBackdropGesture(modal, event?.detail?.role);
196
+ }
197
+ else if (phase === 'willPresent' || phase === 'didDismiss')
198
+ dismissing.delete(modal);
199
+ refresh();
200
+ });
201
+ doc.addEventListener('pointerdown', (event) => {
202
+ if (event.target.closest('ion-modal')) {
203
+ pointerActive = true;
204
+ schedule();
205
+ }
206
+ }, { capture: true, signal: listeners.signal });
207
+ // WebKit cancels pointer events when Ionic takes over a touch gesture.
208
+ // Touch ownership lasts through dragging, including a stationary hold.
209
+ doc.addEventListener('touchstart', (event) => {
210
+ if (event.target.closest('ion-modal')) {
211
+ touchActive = true;
212
+ schedule();
213
+ }
214
+ }, { capture: true, passive: true, signal: listeners.signal });
215
+ for (const name of ['touchend', 'touchcancel'])
216
+ doc.addEventListener(name, (event) => {
217
+ touchActive = event.touches.length > 0;
218
+ schedule();
219
+ }, { capture: true, passive: true, signal: listeners.signal });
220
+ for (const name of ['pointerup', 'pointercancel'])
221
+ doc.addEventListener(name, () => {
222
+ pointerActive = false;
223
+ schedule();
224
+ }, { capture: true, signal: listeners.signal });
225
+ win.addEventListener('resize', () => {
226
+ if (state.top)
227
+ presentations.delete(state.top);
228
+ schedule();
229
+ }, { signal: listeners.signal });
230
+ win.addEventListener('nativeUIRefresh', schedule, { signal: listeners.signal });
231
+ refresh();
232
+ return () => {
233
+ stopped = true;
234
+ stopOverlays();
235
+ win.cancelAnimationFrame(frame);
236
+ observer.disconnect();
237
+ resize?.disconnect();
238
+ listeners.abort();
239
+ if (states.get(doc) !== state)
240
+ return;
241
+ states.delete(doc);
242
+ doc.querySelectorAll('ion-modal').forEach((modal) => presentations.delete(modal));
243
+ doc.querySelectorAll(`.${modalRailClass}`).forEach((modal) => {
244
+ modal.classList.remove(modalRailClass);
245
+ modal.style.removeProperty(toolbarTop);
246
+ });
247
+ };
248
+ };
249
+ /** Visible modal bounds, clipped at the viewport for Ionic's translated sheets. */
250
+ export const modalVerticalBarFrame = (modal) => {
251
+ const presentation = modalPresentation(modal);
252
+ if (presentation)
253
+ return presentation.frame;
254
+ const rect = modal.shadowRoot?.querySelector('[part~="content"]')?.getBoundingClientRect();
255
+ const win = modal.ownerDocument.defaultView;
256
+ if (!rect)
257
+ return;
258
+ const y = Math.max(0, rect.top);
259
+ const height = Math.min(win.innerHeight, rect.bottom) - y;
260
+ return height > 0 ? { x: 0, y, width: win.innerWidth, height } : undefined;
261
+ };
@@ -0,0 +1,2 @@
1
+ /** Internal identity used to anchor overlays to their native control. */
2
+ export declare const projectionIds: WeakMap<Element, string>;
@@ -0,0 +1,2 @@
1
+ /** Internal identity used to anchor overlays to their native control. */
2
+ export const projectionIds = new WeakMap();
@@ -0,0 +1 @@
1
+ export { readScrollPlacement } from '../../index.js';
@@ -0,0 +1 @@
1
+ export { readScrollPlacement } from '../../index.js';
@@ -0,0 +1,7 @@
1
+ /** Keep the Web fallback at the acknowledged native width, without feeding that
2
+ * width back as the next layout request (which can progressively shrink a bar). */
3
+ export declare const createTabBarWidths: (doc: Document) => {
4
+ measure<T>(read: () => T): T;
5
+ apply(bar: HTMLElement, width: number): void;
6
+ clear(): void;
7
+ };
@@ -0,0 +1,72 @@
1
+ /** Keep the Web fallback at the acknowledged native width, without feeding that
2
+ * width back as the next layout request (which can progressively shrink a bar). */
3
+ export const createTabBarWidths = (doc) => {
4
+ const entries = new Map();
5
+ let next = 0;
6
+ const key = (bar) => {
7
+ const computed = doc.defaultView.getComputedStyle(bar);
8
+ return JSON.stringify([
9
+ doc.defaultView.innerWidth,
10
+ doc.defaultView.innerHeight,
11
+ bar.closest('ion-app')?.className,
12
+ computed.width,
13
+ computed.boxSizing,
14
+ computed.paddingLeft,
15
+ computed.paddingRight,
16
+ computed.borderLeftWidth,
17
+ computed.borderRightWidth,
18
+ Array.from(bar.children)
19
+ .filter((child) => !child.classList.contains('ion-cloned-element'))
20
+ .map((child) => child.textContent),
21
+ ]);
22
+ };
23
+ const remove = (bar) => {
24
+ entries.get(bar)?.style.remove();
25
+ entries.delete(bar);
26
+ bar.removeAttribute('data-native-tab-width');
27
+ };
28
+ return {
29
+ measure(read) {
30
+ // Compare layout with the source CSS. Gesture classes and transforms must
31
+ // not discard the measured resting width during a Web handoff.
32
+ for (const { style } of entries.values())
33
+ if (style.sheet)
34
+ style.sheet.disabled = true;
35
+ for (const [bar, entry] of entries)
36
+ if (!bar.isConnected || entry.key !== key(bar))
37
+ remove(bar);
38
+ try {
39
+ return read();
40
+ }
41
+ finally {
42
+ for (const { style } of entries.values())
43
+ if (style.sheet)
44
+ style.sheet.disabled = false;
45
+ }
46
+ },
47
+ apply(bar, width) {
48
+ if (!Number.isFinite(width) || width <= 0)
49
+ return;
50
+ const previous = entries.get(bar);
51
+ const computed = doc.defaultView.getComputedStyle(bar);
52
+ const inset = computed.boxSizing === 'border-box'
53
+ ? 0
54
+ : ['paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'].reduce((total, property) => total + (parseFloat(computed[property]) || 0), 0);
55
+ const cssWidth = Math.max(0, width - inset);
56
+ if (previous && Math.abs(previous.width - width) < 0.1 && Math.abs(previous.cssWidth - cssWidth) < 0.1)
57
+ return;
58
+ remove(bar);
59
+ const sourceKey = key(bar);
60
+ const token = `tab-${++next}`;
61
+ const style = doc.createElement('style');
62
+ bar.setAttribute('data-native-tab-width', token);
63
+ style.textContent = `[data-native-tab-width="${token}"]{width:${cssWidth}px!important;min-width:${cssWidth}px!important;max-width:${cssWidth}px!important}`;
64
+ doc.head.append(style);
65
+ entries.set(bar, { style, key: sourceKey, width, cssWidth });
66
+ },
67
+ clear() {
68
+ for (const bar of entries.keys())
69
+ remove(bar);
70
+ },
71
+ };
72
+ };
@@ -0,0 +1,10 @@
1
+ import type { VerticalControlAreaOptions } from '../definitions.js';
2
+ export declare const toolbarOptions: (options: VerticalControlAreaOptions, vertical: boolean) => {
3
+ buttonGroup: boolean;
4
+ button: boolean;
5
+ backButton: boolean;
6
+ };
7
+ export declare const localToolbarOption: (element: HTMLElement, vertical: boolean) => boolean | undefined;
8
+ export declare const horizontalSelected: (element: HTMLElement, options: VerticalControlAreaOptions) => boolean;
9
+ export declare const horizontalToolbarGroup: (element: HTMLElement, options: VerticalControlAreaOptions) => boolean;
10
+ export declare const inVerticalToolbarLayout: (element: HTMLElement) => boolean;
@@ -0,0 +1,38 @@
1
+ import { modalUsesVerticalBars } from './modal.js';
2
+ import { controlDefault } from './control-options.js';
3
+ import { childElements, inFixedToolbar, isExcluded, isNativeUIDisabled } from './dom.js';
4
+ export const toolbarOptions = (options, vertical) => ({
5
+ buttonGroup: controlDefault(options, 'buttonGroup', vertical),
6
+ button: controlDefault(options, 'button', vertical),
7
+ backButton: controlDefault(options, 'backButton', vertical),
8
+ });
9
+ export const localToolbarOption = (element, vertical) => {
10
+ const value = element.getAttribute(vertical ? 'data-vertical-bars' : 'data-horizontal-bars');
11
+ return value === 'true' ? true : value === 'false' ? false : undefined;
12
+ };
13
+ export const horizontalSelected = (element, options) => {
14
+ const group = element.parentElement;
15
+ if (group?.matches('ion-buttons') && isNativeUIDisabled(group))
16
+ return false;
17
+ return localToolbarOption(element, false) ?? toolbarOptions(options, false)[element.matches('ion-back-button') ? 'backButton' : 'button'];
18
+ };
19
+ // Group only if all original children qualify; otherwise selected actions remain individual.
20
+ // Back navigation never joins an ordinary action group.
21
+ export const horizontalToolbarGroup = (element, options) => {
22
+ if (!element.matches('ion-buttons.ios') ||
23
+ !(localToolbarOption(element, false) ?? toolbarOptions(options, false).buttonGroup) ||
24
+ !inFixedToolbar(element) ||
25
+ isExcluded(element) ||
26
+ isNativeUIDisabled(element))
27
+ return false;
28
+ const children = childElements(element);
29
+ return (children.length > 0 &&
30
+ children.every((child) => horizontalSelected(child, options) &&
31
+ !isExcluded(child) &&
32
+ !isNativeUIDisabled(child) &&
33
+ (child.matches('ion-menu-button.ios') ||
34
+ (children.length > 1 &&
35
+ child.matches('ion-button.ios.button-clear') &&
36
+ (child.fill ?? 'clear') === 'clear'))));
37
+ };
38
+ export const inVerticalToolbarLayout = (element) => !element.closest('ion-menu, ion-popover') && modalUsesVerticalBars(element) && !!element.closest('ion-app.ios-theme-vertical-bars');
@@ -0,0 +1,3 @@
1
+ import type { Candidate } from './candidate.js';
2
+ /** Presentation correspondence only. Action IDs always remain source-specific. */
3
+ export declare const assignToolbarTransitionIds: (candidates: Candidate[]) => void;
@@ -0,0 +1,64 @@
1
+ /** Presentation correspondence only. Action IDs always remain source-specific. */
2
+ export const assignToolbarTransitionIds = (candidates) => {
3
+ const entries = candidates.flatMap((candidate) => {
4
+ const { element, control } = candidate;
5
+ if (!['button', 'button-group', 'menu-button', 'back-button'].includes(control.kind))
6
+ return [];
7
+ const toolbar = element.closest('ion-toolbar, [role="toolbar"]');
8
+ if (!toolbar && control.placement !== 'vertical-bars')
9
+ return [];
10
+ const page = element.closest('.ion-page, ion-modal') ?? element.ownerDocument.body;
11
+ const slotOwner = element.closest('ion-buttons') ?? element;
12
+ const slot = control.toolbarSlot ?? slotOwner.getAttribute('slot') ?? (control.kind === 'back-button' ? 'start' : 'end');
13
+ return [{ candidate, toolbar, page, slot }];
14
+ });
15
+ const counters = new Map();
16
+ for (const { toolbar, page, slot } of entries) {
17
+ const counts = counters.get(toolbar ?? page) ?? new Map();
18
+ counters.set(toolbar ?? page, counts);
19
+ if (slot === 'end')
20
+ counts.set(slot, (counts.get(slot) ?? 0) + 1);
21
+ }
22
+ const identities = [];
23
+ for (const { candidate, toolbar, page, slot } of entries) {
24
+ const { element, control } = candidate;
25
+ const section = toolbar?.closest('ion-header, ion-footer');
26
+ const sectionName = section?.tagName.toLowerCase() ?? 'toolbar';
27
+ const toolbars = Array.from(page.querySelectorAll('ion-toolbar, [role="toolbar"]')).filter((node) => (node.closest('ion-header, ion-footer')?.tagName.toLowerCase() ?? 'toolbar') === sectionName);
28
+ const scope = [sectionName, toolbar ? toolbars.indexOf(toolbar) : 0];
29
+ const counts = counters.get(toolbar ?? page);
30
+ // DOM order follows the inline direction. Count from the logical outer edge:
31
+ // start uses DOM order, end reverses it, including when RTL mirrors the layout.
32
+ const position = slot === 'end' ? counts.get(slot) - 1 : (counts.get(slot) ?? 0);
33
+ counts.set(slot, slot === 'end' ? position : position + 1);
34
+ const explicitSurface = element.getAttribute('data-transition-id')?.trim() ||
35
+ (!element.matches('ion-buttons') && control.items.length === 1
36
+ ? candidate.actions.get(control.items[0].id)?.getAttribute('data-transition-id')?.trim()
37
+ : undefined);
38
+ const surfaceId = JSON.stringify(explicitSurface ? ['surface-explicit', ...scope, explicitSurface] : ['group', ...scope, slot, position]);
39
+ identities.push({
40
+ target: control,
41
+ id: surfaceId,
42
+ fallback: control.id,
43
+ });
44
+ for (const [index, item] of control.items.entries()) {
45
+ const source = candidate.actions.get(item.id);
46
+ const explicit = source?.getAttribute('data-transition-id')?.trim();
47
+ // Child positions belong to their surface. Resizing a group cannot renumber the next one.
48
+ identities.push({
49
+ target: item,
50
+ id: explicit
51
+ ? JSON.stringify(['explicit', ...scope, explicit])
52
+ : JSON.stringify(['auto', surfaceId, slot === 'end' ? control.items.length - 1 - index : index]),
53
+ fallback: item.id,
54
+ });
55
+ }
56
+ }
57
+ const counts = new Map();
58
+ for (const { id } of identities)
59
+ counts.set(id, (counts.get(id) ?? 0) + 1);
60
+ // Ambiguous keys must not merge actions or produce duplicate SwiftUI identities.
61
+ for (const { target, id, fallback } of identities) {
62
+ target.transitionId = counts.get(id) === 1 ? id : JSON.stringify(['unmatched', fallback]);
63
+ }
64
+ };
@@ -0,0 +1,8 @@
1
+ import type { Frame, NativeUIVerticalBarFrame } from '../definitions.js';
2
+ export declare const validVerticalBarFrame: (frame: Frame) => boolean;
3
+ export declare const forgetVerticalBarFrame: (element: Element) => boolean;
4
+ export declare const rememberVerticalBarFrame: (element: Element, frame: Frame) => void;
5
+ export declare const verticalBarFrame: (element: Element) => Frame | undefined;
6
+ /** Convert the native viewport rectangle into the clone's positioning container. */
7
+ export declare const alignVerticalBarClone: (clone: HTMLElement, source: Element, parent: HTMLElement) => void;
8
+ export declare const alignVerticalTabBar: (tabBar: HTMLElement, frame: NativeUIVerticalBarFrame, items: Map<HTMLElement, NativeUIVerticalBarFrame>) => (() => void);
@@ -0,0 +1,82 @@
1
+ const measurements = new WeakMap();
2
+ const viewport = (element) => {
3
+ const win = element.ownerDocument.defaultView;
4
+ const classes = element.closest('ion-app')?.classList;
5
+ return `${win.innerWidth}:${win.innerHeight}:${classes?.contains('ios-theme-vertical-bars')}:${classes?.contains('ios-theme-vertical-bars-left')}`;
6
+ };
7
+ export const validVerticalBarFrame = (frame) => [frame.x, frame.y, frame.width, frame.height].every(Number.isFinite) && frame.width > 0 && frame.height > 0;
8
+ export const forgetVerticalBarFrame = (element) => measurements.delete(element);
9
+ export const rememberVerticalBarFrame = (element, frame) => {
10
+ if (validVerticalBarFrame(frame))
11
+ measurements.set(element, { frame, viewport: viewport(element) });
12
+ };
13
+ export const verticalBarFrame = (element) => {
14
+ const saved = measurements.get(element);
15
+ return saved?.viewport === viewport(element) ? saved.frame : undefined;
16
+ };
17
+ /** Convert the native viewport rectangle into the clone's positioning container. */
18
+ export const alignVerticalBarClone = (clone, source, parent) => {
19
+ const frame = verticalBarFrame(source);
20
+ if (!frame)
21
+ return;
22
+ const origin = parent.getBoundingClientRect();
23
+ const parentStyle = parent.ownerDocument.defaultView.getComputedStyle(parent);
24
+ // clientLeft/clientTop round subpixel glass borders to whole CSS pixels.
25
+ const borderLeft = parseFloat(parentStyle.borderLeftWidth) || 0;
26
+ const borderTop = parseFloat(parentStyle.borderTopWidth) || 0;
27
+ // Absolute children use the padding edge, not the outer edge of a glass group.
28
+ Object.assign(clone.style, {
29
+ position: 'absolute',
30
+ left: `${frame.x - origin.left - borderLeft}px`,
31
+ top: `${frame.y - origin.top - borderTop}px`,
32
+ right: 'auto',
33
+ bottom: 'auto',
34
+ width: `${frame.width}px`,
35
+ height: `${frame.height}px`,
36
+ minWidth: `${frame.width}px`,
37
+ maxWidth: `${frame.width}px`,
38
+ minHeight: `${frame.height}px`,
39
+ maxHeight: `${frame.height}px`,
40
+ margin: '0',
41
+ boxSizing: 'border-box',
42
+ });
43
+ };
44
+ export const alignVerticalTabBar = (tabBar, frame, items) => {
45
+ const doc = tabBar.ownerDocument;
46
+ const style = doc.createElement('style');
47
+ const token = `rail-${Math.random().toString(36).slice(2)}`;
48
+ const selector = `[data-native-rail-geometry="${token}"]`;
49
+ const origin = tabBar.offsetParent?.getBoundingClientRect() ?? { left: 0, top: 0 };
50
+ tabBar.setAttribute('data-native-rail-geometry', token);
51
+ // Preserve the measured shape. Only older binaries need the capsule fallback.
52
+ const radius = (rect) => Number.isFinite(rect.cornerRadius) && rect.cornerRadius >= 0 ? rect.cornerRadius : Math.min(rect.width, rect.height) / 2;
53
+ const box = (rect, x, y) => `position:absolute!important;left:${rect.x - x}px!important;top:${rect.y - y}px!important;right:auto!important;bottom:auto!important;width:${rect.width}px!important;min-width:${rect.width}px!important;max-width:${rect.width}px!important;height:${rect.height}px!important;min-height:${rect.height}px!important;max-height:${rect.height}px!important;margin:0!important;padding:0!important;box-sizing:border-box!important;border-radius:${radius(rect)}px!important;`;
54
+ style.textContent =
55
+ `${selector}{${box(frame, origin.left, origin.top)}}` +
56
+ [...items]
57
+ .map(([element, rect]) => {
58
+ const index = Array.from(tabBar.children).indexOf(element) + 1;
59
+ return `${selector}>:nth-child(${index}){${box(rect, frame.x, frame.y)}}${selector}>:nth-child(${index})::part(native){min-height:0!important}`;
60
+ })
61
+ .join('');
62
+ doc.head.append(style);
63
+ const win = doc.defaultView;
64
+ const measuredViewport = viewport(tabBar);
65
+ const stop = () => {
66
+ observer.disconnect();
67
+ win.removeEventListener('resize', stop);
68
+ style.remove();
69
+ if (tabBar.getAttribute('data-native-rail-geometry') === token)
70
+ tabBar.removeAttribute('data-native-rail-geometry');
71
+ };
72
+ const observer = new MutationObserver((records) => {
73
+ if (viewport(tabBar) !== measuredViewport || records.some((record) => record.type === 'childList'))
74
+ stop();
75
+ });
76
+ observer.observe(tabBar, { childList: true });
77
+ const app = tabBar.closest('ion-app');
78
+ if (app)
79
+ observer.observe(app, { attributes: true, attributeFilter: ['class'] });
80
+ win.addEventListener('resize', stop);
81
+ return stop;
82
+ };
@@ -0,0 +1,5 @@
1
+ /** Mirror each Web page's ancestry without depending on tab selection timing. */
2
+ export declare const createVerticalNavigation: () => {
3
+ begin(entering: HTMLElement, leaving?: HTMLElement, direction?: "forward" | "back" | "root"): (canceled: boolean) => boolean;
4
+ read(page: HTMLElement): HTMLElement[];
5
+ };
@@ -0,0 +1,39 @@
1
+ /** Mirror each Web page's ancestry without depending on tab selection timing. */
2
+ export const createVerticalNavigation = () => {
3
+ const paths = new WeakMap();
4
+ let transition;
5
+ return {
6
+ begin(entering, leaving, direction) {
7
+ const before = leaving ? (paths.get(leaving) ?? [leaving]) : [];
8
+ const index = before.indexOf(entering);
9
+ const after = direction === 'root'
10
+ ? [entering]
11
+ : index >= 0
12
+ ? before.slice(0, index + 1)
13
+ : direction === 'back'
14
+ ? [entering]
15
+ : [...before, entering];
16
+ const current = { entering, leaving, before, after };
17
+ transition = current;
18
+ return (canceled) => {
19
+ if (transition !== current)
20
+ return false;
21
+ if (canceled) {
22
+ if (leaving)
23
+ paths.set(leaving, before);
24
+ }
25
+ else
26
+ paths.set(entering, after);
27
+ transition = undefined;
28
+ return true;
29
+ };
30
+ },
31
+ read(page) {
32
+ if (transition?.entering === page)
33
+ return transition.after;
34
+ if (transition?.leaving === page)
35
+ return transition.before;
36
+ return paths.get(page) ?? [page];
37
+ },
38
+ };
39
+ };
@@ -0,0 +1,7 @@
1
+ import type { NativeUITransport } from './transport.js';
2
+ import type { NativeUIRuntimeOptions, NativeUIHandle, NativeUIOptions } from './definitions.js';
3
+ export declare const createNativeUI: (transport: NativeUITransport) => {
4
+ startNativeUI: (input?: NativeUIOptions, overlayFactory?: ((doc: Document, plugin: import("./definitions.js").NativeUIPlugin, options: NativeUIRuntimeOptions, retain: (deferActivation?: (id: string) => boolean) => () => void, nativeRail: () => boolean, connection?: import("./shared/connection.js").NativeUIConnection) => Promise<import("./activation.js").OverlayController>) | undefined) => Promise<NativeUIHandle>;
5
+ enableNativeUI: (options?: NativeUIOptions) => Promise<NativeUIHandle>;
6
+ configureNativeTransition: () => Promise<import("./definitions.js").WebViewMetrics>;
7
+ };