@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,74 @@
1
+ import { createNativeUIActivation } from './activation.js';
2
+ import type { NativeUITransport } from './transport.js';
3
+ import type { NativeUIRuntimeOptions, NativeUIHandle, NativeUIOptions, NativeUIRuntimeHandle } from './definitions.js';
4
+
5
+ export const createNativeUI = (transport: NativeUITransport) => {
6
+ const { enableNativeUI: activate, configureNativeTransition } = createNativeUIActivation(transport);
7
+ type OverlayFactory = Parameters<typeof activate>[1];
8
+ const handles = new WeakMap<NativeUIRuntimeHandle, NativeUIHandle>();
9
+
10
+ /** Start one shell. Partial options override defaults; markup owns individual placement. */
11
+ const startNativeUI = async (input: NativeUIOptions = {}, overlayFactory?: OverlayFactory): Promise<NativeUIHandle> => {
12
+ const root = input.root ?? (typeof document === 'undefined' ? undefined : document.body);
13
+ const bars = { enabled: true, ...input.verticalBars };
14
+ const host = bars.placement?.webHost;
15
+ if (root && (!root.isConnected || root.ownerDocument !== document))
16
+ throw new Error('Native UI requires a connected root in the current document');
17
+ if (host && (!host.isConnected || host.ownerDocument !== document || root?.contains(host) || host.contains(root!)))
18
+ throw new Error('The Web rail host must be connected in the current document and outside the source root');
19
+ const options: NativeUIRuntimeOptions = {
20
+ ...input,
21
+ root,
22
+ source: 'auto',
23
+ verticalBars: bars,
24
+ rail: host ? { host, edge: bars.placement?.edge === 'leading' ? 'left' : 'right' } : undefined,
25
+ };
26
+ const runtime = await activate(options, overlayFactory);
27
+ const existing = handles.get(runtime);
28
+ if (existing) return existing;
29
+ let stopped = false;
30
+ let queue = Promise.resolve();
31
+ const change = (enabled: boolean) => {
32
+ const operation = queue.then(async () => {
33
+ if (stopped) throw new Error('Native UI has been destroyed');
34
+ if (bars.enabled === enabled) return;
35
+ // Retire both surfaces before changing ownership. Resume also waits for native reconciliation.
36
+ const lease = await runtime.suspend();
37
+ try {
38
+ if (stopped) throw new Error('Native UI has been destroyed');
39
+ bars.enabled = enabled;
40
+ root?.ownerDocument.defaultView?.dispatchEvent(new Event('nativeUIRefresh'));
41
+ } finally {
42
+ await lease.resume();
43
+ }
44
+ });
45
+ queue = operation.catch(() => {});
46
+ return operation;
47
+ };
48
+ let destruction: Promise<void> | undefined;
49
+ const destroy = runtime.destroy.bind(runtime);
50
+ const handle: NativeUIHandle = {
51
+ markForCheck: runtime.markForCheck.bind(runtime),
52
+ getStatus: runtime.getStatus.bind(runtime),
53
+ suspend: runtime.suspend.bind(runtime),
54
+ enableVerticalControlArea: () => change(true),
55
+ disableVerticalControlArea: () => change(false),
56
+ destroy() {
57
+ if (!destruction) {
58
+ stopped = true;
59
+ // Reserve native teardown immediately, preserving the shared startup queue.
60
+ destruction = destroy();
61
+ }
62
+ return destruction;
63
+ },
64
+ };
65
+ const managed = Object.assign(runtime, handle);
66
+ handles.set(runtime, managed);
67
+ return managed;
68
+ };
69
+
70
+ /** Enable the shared standard shell without loading the optional Ionic overlay adapter. */
71
+ const enableNativeUI = (options: NativeUIOptions = {}): Promise<NativeUIHandle> => startNativeUI(options);
72
+
73
+ return { startNativeUI, enableNativeUI, configureNativeTransition };
74
+ };
@@ -0,0 +1,11 @@
1
+ import type { NativeUIPlugin } from './definitions.js';
2
+
3
+ /** Host bridge supplied by Capacitor, Cordova, or another embedding runtime. */
4
+ export interface NativeUITransport {
5
+ readonly plugin: NativeUIPlugin;
6
+ getPlatform(): string;
7
+ isAvailable(): boolean;
8
+ }
9
+ export interface NativeUIListenerHandle {
10
+ remove(): Promise<void>;
11
+ }
@@ -0,0 +1,86 @@
1
+ import { getNativeSearchBindings, type NativeSearchBinding } from '../integration/index.js';
2
+ import { activateProjectedElement, marker, unprojected } from './shared/dom.js';
3
+
4
+ export const searchProjectionClass = 'ios-theme-vertical-bars-search-projection';
5
+
6
+ /** Web counterpart of the system search button above the vertical tabs, or at the rail bottom without visible tabs. */
7
+ export const createVerticalBarsWebSearch = (doc: Document, eligible: (element: HTMLElement) => boolean, refresh: () => void) => {
8
+ let binding: NativeSearchBinding | undefined;
9
+ let projection: HTMLIonFabButtonElement | undefined;
10
+ let container: HTMLIonFabElement | undefined;
11
+ const iconObserver = new MutationObserver(refresh);
12
+ let previousAriaHidden: string | null = null;
13
+ const restore = (retire?: (surface: HTMLElement) => void) => {
14
+ iconObserver.disconnect();
15
+ if (container) {
16
+ if (retire) retire(container);
17
+ else container.remove();
18
+ }
19
+ container = undefined;
20
+ projection = undefined;
21
+ if (binding) {
22
+ binding.trigger.removeAttribute(marker);
23
+ if (previousAriaHidden === null) binding.trigger.removeAttribute('aria-hidden');
24
+ else binding.trigger.setAttribute('aria-hidden', previousAriaHidden);
25
+ }
26
+ binding = undefined;
27
+ };
28
+ return {
29
+ restore,
30
+ get surface() {
31
+ return container;
32
+ },
33
+ get source() {
34
+ return binding?.trigger;
35
+ },
36
+ update(root: HTMLElement) {
37
+ const next = unprojected(binding ? [binding.trigger] : [], () =>
38
+ getNativeSearchBindings(doc).find(({ trigger, footer }) => eligible(trigger) && eligible(footer)),
39
+ );
40
+ if (next !== binding || container?.parentElement !== root) restore();
41
+ if (!next) return;
42
+ if (!projection) {
43
+ binding = next;
44
+ previousAriaHidden = next.trigger.getAttribute('aria-hidden');
45
+ projection = next.trigger.cloneNode(true) as HTMLIonFabButtonElement;
46
+ for (const name of ['id', 'slot', marker, 'aria-hidden', 'style']) projection.removeAttribute(name);
47
+ container = doc.createElement('ion-fab');
48
+ container.setAttribute('mode', (next.trigger as HTMLIonFabButtonElement).mode ?? 'ios');
49
+ container.classList.add(searchProjectionClass, 'ion-cloned-element');
50
+ projection.addEventListener(
51
+ 'click',
52
+ (event) => {
53
+ event.preventDefault();
54
+ event.stopImmediatePropagation();
55
+ activateProjectedElement(next.trigger);
56
+ },
57
+ { capture: true },
58
+ );
59
+ container.append(projection);
60
+ root.append(container);
61
+ next.trigger.setAttribute(marker, '');
62
+ next.trigger.setAttribute('aria-hidden', 'true');
63
+ }
64
+ projection.setAttribute(
65
+ 'aria-label',
66
+ next.trigger.getAttribute('aria-label') ?? next.footer.querySelector('ion-searchbar')?.getAttribute('aria-label') ?? 'Search',
67
+ );
68
+ const sourceIcon = next.trigger.querySelector('ion-icon');
69
+ const icon = projection.querySelector('ion-icon');
70
+ if (sourceIcon?.shadowRoot) iconObserver.observe(sourceIcon.shadowRoot, { subtree: true, childList: true, attributes: true });
71
+ if (sourceIcon && icon) {
72
+ icon.icon = sourceIcon.icon;
73
+ icon.name = sourceIcon.name;
74
+ icon.src = sourceIcon.src;
75
+ }
76
+ container!.hidden = next.trigger.style.pointerEvents === 'none';
77
+ projection.disabled = (next.trigger as HTMLIonFabButtonElement).disabled;
78
+ const bounds = next.tabBar.getBoundingClientRect();
79
+ const tabs = bounds.width > 0 && bounds.height > 0 && getComputedStyle(next.tabBar).visibility === 'visible' ? bounds : undefined;
80
+ container!.style.left = tabs ? `${tabs.left + (tabs.width - 46) / 2}px` : '';
81
+ container!.style.top = tabs ? `${tabs.top - 56}px` : '';
82
+ container!.style.right = tabs ? 'auto' : '';
83
+ container!.style.bottom = tabs ? 'auto' : '';
84
+ },
85
+ };
86
+ };