@rdlabo/capacitor-native-ui 0.0.0-stage → 2.0.0-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.
Files changed (261) hide show
  1. package/LICENSE +21 -0
  2. package/Package.swift +23 -0
  3. package/README.md +66 -2
  4. package/RdlaboCapacitorNativeUi.podspec +17 -0
  5. package/android/build.gradle +69 -0
  6. package/android/proguard-rules.pro +0 -0
  7. package/android/src/main/AndroidManifest.xml +1 -0
  8. package/android/src/main/java/dev/rdlabo/capacitor/nativeui/NativeUI.kt +51 -0
  9. package/android/src/main/java/dev/rdlabo/capacitor/nativeui/NativeUIPlugin.kt +192 -0
  10. package/android/src/main/java/dev/rdlabo/capacitor/nativeui/NativeUISnapshot.kt +57 -0
  11. package/dist/_virtual/_rolldown/runtime.js +13 -0
  12. package/dist/core.d.ts +4 -0
  13. package/dist/core.js +3 -0
  14. package/dist/native/activation.d.ts +14 -0
  15. package/dist/native/activation.d.ts.map +1 -0
  16. package/dist/native/activation.js +305 -0
  17. package/dist/native/activation.js.map +1 -0
  18. package/dist/native/components/index.d.ts +19 -0
  19. package/dist/native/components/index.d.ts.map +1 -0
  20. package/dist/native/components/index.js +38 -0
  21. package/dist/native/components/index.js.map +1 -0
  22. package/dist/native/components/ion-back-button.d.ts +10 -0
  23. package/dist/native/components/ion-back-button.d.ts.map +1 -0
  24. package/dist/native/components/ion-back-button.js +21 -0
  25. package/dist/native/components/ion-back-button.js.map +1 -0
  26. package/dist/native/components/ion-button.d.ts +10 -0
  27. package/dist/native/components/ion-button.d.ts.map +1 -0
  28. package/dist/native/components/ion-button.js +25 -0
  29. package/dist/native/components/ion-button.js.map +1 -0
  30. package/dist/native/components/ion-buttons.d.ts +11 -0
  31. package/dist/native/components/ion-buttons.d.ts.map +1 -0
  32. package/dist/native/components/ion-buttons.js +30 -0
  33. package/dist/native/components/ion-buttons.js.map +1 -0
  34. package/dist/native/components/ion-fab.d.ts +10 -0
  35. package/dist/native/components/ion-fab.d.ts.map +1 -0
  36. package/dist/native/components/ion-fab.js +132 -0
  37. package/dist/native/components/ion-fab.js.map +1 -0
  38. package/dist/native/components/ion-menu-button.d.ts +13 -0
  39. package/dist/native/components/ion-menu-button.d.ts.map +1 -0
  40. package/dist/native/components/ion-menu-button.js +44 -0
  41. package/dist/native/components/ion-menu-button.js.map +1 -0
  42. package/dist/native/components/ion-segment.d.ts +11 -0
  43. package/dist/native/components/ion-segment.d.ts.map +1 -0
  44. package/dist/native/components/ion-segment.js +30 -0
  45. package/dist/native/components/ion-segment.js.map +1 -0
  46. package/dist/native/components/ion-tab-bar.d.ts +11 -0
  47. package/dist/native/components/ion-tab-bar.d.ts.map +1 -0
  48. package/dist/native/components/ion-tab-bar.js +50 -0
  49. package/dist/native/components/ion-tab-bar.js.map +1 -0
  50. package/dist/native/components/searchable-tabs.d.ts +20 -0
  51. package/dist/native/components/searchable-tabs.d.ts.map +1 -0
  52. package/dist/native/components/searchable-tabs.js +413 -0
  53. package/dist/native/components/searchable-tabs.js.map +1 -0
  54. package/dist/native/definitions.d.ts +237 -0
  55. package/dist/native/definitions.d.ts.map +1 -0
  56. package/dist/native/definitions.js +0 -0
  57. package/dist/native/extensions.d.ts +31 -0
  58. package/dist/native/extensions.d.ts.map +1 -0
  59. package/dist/native/extensions.js +122 -0
  60. package/dist/native/extensions.js.map +1 -0
  61. package/dist/native/foldable/fold-state.d.ts +5 -0
  62. package/dist/native/foldable/fold-state.d.ts.map +1 -0
  63. package/dist/native/foldable/fold-state.js +15 -0
  64. package/dist/native/foldable/fold-state.js.map +1 -0
  65. package/dist/native/foldable/types.d.ts +12 -0
  66. package/dist/native/foldable/types.d.ts.map +1 -0
  67. package/dist/native/foldable/types.js +0 -0
  68. package/dist/native/html.d.ts +9 -0
  69. package/dist/native/html.d.ts.map +1 -0
  70. package/dist/native/html.js +197 -0
  71. package/dist/native/html.js.map +1 -0
  72. package/dist/native/index.d.ts +10 -0
  73. package/dist/native/index.d.ts.map +1 -0
  74. package/dist/native/index.js +19 -0
  75. package/dist/native/index.js.map +1 -0
  76. package/dist/native/legacy-layout.d.ts +5 -0
  77. package/dist/native/legacy-layout.d.ts.map +1 -0
  78. package/dist/native/legacy-layout.js +27 -0
  79. package/dist/native/legacy-layout.js.map +1 -0
  80. package/dist/native/overlays/content.d.ts +4 -0
  81. package/dist/native/overlays/content.d.ts.map +1 -0
  82. package/dist/native/overlays/content.js +51 -0
  83. package/dist/native/overlays/content.js.map +1 -0
  84. package/dist/native/overlays/controller.d.ts +8 -0
  85. package/dist/native/overlays/controller.d.ts.map +1 -0
  86. package/dist/native/overlays/controller.js +285 -0
  87. package/dist/native/overlays/controller.js.map +1 -0
  88. package/dist/native/overlays/dialog-animation.d.ts +9 -0
  89. package/dist/native/overlays/dialog-animation.d.ts.map +1 -0
  90. package/dist/native/overlays/dialog-animation.js +53 -0
  91. package/dist/native/overlays/dialog-animation.js.map +1 -0
  92. package/dist/native/overlays/dismiss-animation.d.ts +4 -0
  93. package/dist/native/overlays/dismiss-animation.d.ts.map +1 -0
  94. package/dist/native/overlays/dismiss-animation.js +18 -0
  95. package/dist/native/overlays/dismiss-animation.js.map +1 -0
  96. package/dist/native/overlays/focus.d.ts +5 -0
  97. package/dist/native/overlays/focus.d.ts.map +1 -0
  98. package/dist/native/overlays/focus.js +59 -0
  99. package/dist/native/overlays/focus.js.map +1 -0
  100. package/dist/native/overlays/popover.d.ts +12 -0
  101. package/dist/native/overlays/popover.d.ts.map +1 -0
  102. package/dist/native/overlays/popover.js +110 -0
  103. package/dist/native/overlays/popover.js.map +1 -0
  104. package/dist/native/overlays/styles.d.ts +11 -0
  105. package/dist/native/overlays/styles.d.ts.map +1 -0
  106. package/dist/native/overlays/styles.js +167 -0
  107. package/dist/native/overlays/styles.js.map +1 -0
  108. package/dist/native/prehide.d.ts +8 -0
  109. package/dist/native/prehide.d.ts.map +1 -0
  110. package/dist/native/prehide.js +238 -0
  111. package/dist/native/prehide.js.map +1 -0
  112. package/dist/native/runtime.d.ts +7 -0
  113. package/dist/native/runtime.d.ts.map +1 -0
  114. package/dist/native/runtime.js +776 -0
  115. package/dist/native/runtime.js.map +1 -0
  116. package/dist/native/shared/bridge.d.ts +6 -0
  117. package/dist/native/shared/bridge.d.ts.map +1 -0
  118. package/dist/native/shared/bridge.js +18 -0
  119. package/dist/native/shared/bridge.js.map +1 -0
  120. package/dist/native/shared/candidate.d.ts +25 -0
  121. package/dist/native/shared/candidate.d.ts.map +1 -0
  122. package/dist/native/shared/candidate.js +106 -0
  123. package/dist/native/shared/candidate.js.map +1 -0
  124. package/dist/native/shared/clipping.d.ts +5 -0
  125. package/dist/native/shared/clipping.d.ts.map +1 -0
  126. package/dist/native/shared/clipping.js +26 -0
  127. package/dist/native/shared/clipping.js.map +1 -0
  128. package/dist/native/shared/control-options.d.ts +6 -0
  129. package/dist/native/shared/control-options.d.ts.map +1 -0
  130. package/dist/native/shared/control-options.js +17 -0
  131. package/dist/native/shared/control-options.js.map +1 -0
  132. package/dist/native/shared/crossfade.d.ts +12 -0
  133. package/dist/native/shared/crossfade.d.ts.map +1 -0
  134. package/dist/native/shared/crossfade.js +67 -0
  135. package/dist/native/shared/crossfade.js.map +1 -0
  136. package/dist/native/shared/diagnostics.d.ts +4 -0
  137. package/dist/native/shared/diagnostics.d.ts.map +1 -0
  138. package/dist/native/shared/diagnostics.js +18 -0
  139. package/dist/native/shared/diagnostics.js.map +1 -0
  140. package/dist/native/shared/dom.d.ts +46 -0
  141. package/dist/native/shared/dom.d.ts.map +1 -0
  142. package/dist/native/shared/dom.js +180 -0
  143. package/dist/native/shared/dom.js.map +1 -0
  144. package/dist/native/shared/events.d.ts +15 -0
  145. package/dist/native/shared/events.d.ts.map +1 -0
  146. package/dist/native/shared/events.js +17 -0
  147. package/dist/native/shared/events.js.map +1 -0
  148. package/dist/native/shared/icons.d.ts +8 -0
  149. package/dist/native/shared/icons.d.ts.map +1 -0
  150. package/dist/native/shared/icons.js +61 -0
  151. package/dist/native/shared/icons.js.map +1 -0
  152. package/dist/native/shared/modal.d.ts +10 -0
  153. package/dist/native/shared/modal.d.ts.map +1 -0
  154. package/dist/native/shared/modal.js +160 -0
  155. package/dist/native/shared/modal.js.map +1 -0
  156. package/dist/native/shared/projection-id.d.ts +4 -0
  157. package/dist/native/shared/projection-id.d.ts.map +1 -0
  158. package/dist/native/shared/projection-id.js +7 -0
  159. package/dist/native/shared/projection-id.js.map +1 -0
  160. package/dist/native/shared/toolbar-options.d.ts +13 -0
  161. package/dist/native/shared/toolbar-options.d.ts.map +1 -0
  162. package/dist/native/shared/toolbar-options.js +28 -0
  163. package/dist/native/shared/toolbar-options.js.map +1 -0
  164. package/dist/native/shared/vertical-bars-geometry.d.ts +10 -0
  165. package/dist/native/shared/vertical-bars-geometry.d.ts.map +1 -0
  166. package/dist/native/shared/vertical-bars-geometry.js +85 -0
  167. package/dist/native/shared/vertical-bars-geometry.js.map +1 -0
  168. package/dist/native/startup.d.ts +8 -0
  169. package/dist/native/startup.d.ts.map +1 -0
  170. package/dist/native/startup.js +70 -0
  171. package/dist/native/startup.js.map +1 -0
  172. package/dist/native/vertical-bars-web-search.d.ts +10 -0
  173. package/dist/native/vertical-bars-web-search.d.ts.map +1 -0
  174. package/dist/native/vertical-bars-web-search.js +90 -0
  175. package/dist/native/vertical-bars-web-search.js.map +1 -0
  176. package/dist/native/vertical-bars-web.d.ts +5 -0
  177. package/dist/native/vertical-bars-web.d.ts.map +1 -0
  178. package/dist/native/vertical-bars-web.js +422 -0
  179. package/dist/native/vertical-bars-web.js.map +1 -0
  180. package/dist/native-integration/index.d.ts +25 -0
  181. package/dist/native-integration/index.d.ts.map +1 -0
  182. package/dist/native-integration/index.js +33 -0
  183. package/dist/native-integration/index.js.map +1 -0
  184. package/dist/vertical-bars.d.ts +6 -0
  185. package/dist/vertical-bars.js +5 -0
  186. package/docs/appearance.md +45 -0
  187. package/docs/configuration.md +219 -0
  188. package/docs/framework-independent.md +107 -0
  189. package/docs/ionic-vertical-bars.md +173 -0
  190. package/docs/migration.md +184 -0
  191. package/docs/native-ui-extensions.md +394 -0
  192. package/docs/native-ui.md +528 -0
  193. package/docs/setup.md +224 -0
  194. package/docs/vertical-bars.md +431 -0
  195. package/ios/Sources/NativeUIPlugin/Components/NativeUIButton.swift +71 -0
  196. package/ios/Sources/NativeUIPlugin/Components/NativeUIButtons.swift +24 -0
  197. package/ios/Sources/NativeUIPlugin/Components/NativeUIComponents.swift +19 -0
  198. package/ios/Sources/NativeUIPlugin/Components/NativeUIFab.swift +80 -0
  199. package/ios/Sources/NativeUIPlugin/Components/NativeUISearchController.swift +439 -0
  200. package/ios/Sources/NativeUIPlugin/Components/NativeUISegment.swift +91 -0
  201. package/ios/Sources/NativeUIPlugin/Components/NativeUITabBar.swift +218 -0
  202. package/ios/Sources/NativeUIPlugin/Components/NativeUIVerticalBars.swift +590 -0
  203. package/ios/Sources/NativeUIPlugin/Components/NativeUIVerticalSearch.swift +118 -0
  204. package/ios/Sources/NativeUIPlugin/Extensions/NativeUI.swift +178 -0
  205. package/ios/Sources/NativeUIPlugin/Extensions/NativeUIRendering.swift +38 -0
  206. package/ios/Sources/NativeUIPlugin/NativeUIPlugin.swift +615 -0
  207. package/ios/Sources/NativeUIPlugin/Overlays/NativeUIOverlayController.swift +119 -0
  208. package/ios/Sources/NativeUIPlugin/Overlays/NativeUIOverlayHost.swift +75 -0
  209. package/ios/Sources/NativeUIPlugin/Shared/NativeUIControlRendering.swift +21 -0
  210. package/ios/Sources/NativeUIPlugin/Shared/NativeUICrossfade.swift +35 -0
  211. package/ios/Sources/NativeUIPlugin/Shared/NativeUIHost.swift +8 -0
  212. package/ios/Sources/NativeUIPlugin/Shared/NativeUISnapshot.swift +161 -0
  213. package/ios/Sources/NativeUIPlugin/Shared/NativeUIVerticalBarsGeometry.swift +52 -0
  214. package/ios/Tests/NativeUIPluginTests/NativeUIExtensionTests.swift +165 -0
  215. package/ios/Tests/NativeUIPluginTests/NativeUISnapshotTests.swift +805 -0
  216. package/package.json +89 -4
  217. package/src/core.ts +14 -0
  218. package/src/native/activation.ts +385 -0
  219. package/src/native/components/index.ts +45 -0
  220. package/src/native/components/ion-back-button.ts +22 -0
  221. package/src/native/components/ion-button.ts +25 -0
  222. package/src/native/components/ion-buttons.ts +37 -0
  223. package/src/native/components/ion-fab.ts +151 -0
  224. package/src/native/components/ion-menu-button.ts +37 -0
  225. package/src/native/components/ion-segment.ts +27 -0
  226. package/src/native/components/ion-tab-bar.ts +50 -0
  227. package/src/native/components/searchable-tabs.ts +499 -0
  228. package/src/native/definitions.ts +274 -0
  229. package/src/native/extensions.ts +176 -0
  230. package/src/native/foldable/fold-state.ts +10 -0
  231. package/src/native/foldable/types.ts +4 -0
  232. package/src/native/html.ts +199 -0
  233. package/src/native/index.ts +32 -0
  234. package/src/native/legacy-layout.ts +21 -0
  235. package/src/native/overlays/content.ts +51 -0
  236. package/src/native/overlays/controller.ts +349 -0
  237. package/src/native/overlays/dialog-animation.ts +53 -0
  238. package/src/native/overlays/dismiss-animation.ts +15 -0
  239. package/src/native/overlays/focus.ts +64 -0
  240. package/src/native/overlays/popover.ts +120 -0
  241. package/src/native/overlays/styles.ts +181 -0
  242. package/src/native/prehide.ts +285 -0
  243. package/src/native/runtime.ts +979 -0
  244. package/src/native/shared/bridge.ts +18 -0
  245. package/src/native/shared/candidate.ts +162 -0
  246. package/src/native/shared/clipping.ts +24 -0
  247. package/src/native/shared/control-options.ts +20 -0
  248. package/src/native/shared/crossfade.ts +67 -0
  249. package/src/native/shared/diagnostics.ts +13 -0
  250. package/src/native/shared/dom.ts +304 -0
  251. package/src/native/shared/events.ts +14 -0
  252. package/src/native/shared/icons.ts +57 -0
  253. package/src/native/shared/modal.ts +157 -0
  254. package/src/native/shared/projection-id.ts +2 -0
  255. package/src/native/shared/toolbar-options.ts +49 -0
  256. package/src/native/shared/vertical-bars-geometry.ts +80 -0
  257. package/src/native/startup.ts +68 -0
  258. package/src/native/vertical-bars-web-search.ts +86 -0
  259. package/src/native/vertical-bars-web.ts +500 -0
  260. package/src/native-integration/index.ts +49 -0
  261. package/src/vertical-bars.ts +12 -0
@@ -0,0 +1,132 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { childElements, excluded, isDark, text } from "../shared/dom.js";
3
+ import { iconSource } from "../shared/icons.js";
4
+ //#region src/native/components/ion-fab.ts
5
+ var ion_fab_exports = /* @__PURE__ */ __exportAll({
6
+ read: () => read,
7
+ shadowSelector: () => shadowSelector,
8
+ tag: () => tag
9
+ });
10
+ const tag = "ion-fab";
11
+ const shadowSelector = "ion-fab-button, ion-fab-list";
12
+ const hasHostMotion = (style) => style.animationName !== "none" || style.transitionDuration.split(",").some((value) => parseFloat(value) > 0);
13
+ const read = (fab, id) => {
14
+ if (fab.slot !== "fixed" || !fab.parentElement?.matches("ion-content") || fab.contains(fab.ownerDocument.activeElement)) return;
15
+ const children = childElements(fab);
16
+ const main = children.filter((child) => child.matches("ion-fab-button"));
17
+ const lists = children.filter((child) => child.matches("ion-fab-list"));
18
+ if (main.length !== 1 || main.length + lists.length !== children.length) return;
19
+ if (lists.some((list) => list.closest(excluded) || childElements(list).some((child) => !child.matches("ion-fab-button")))) return;
20
+ const buttons = [main[0], ...lists.flatMap((list) => childElements(list))];
21
+ const style = getComputedStyle(fab);
22
+ if (hasHostMotion(style)) return;
23
+ const transform = new DOMMatrixReadOnly(style.transform);
24
+ if (!transform.is2D || transform.a !== 1 || transform.d !== 1 || transform.b || transform.c) return;
25
+ const candidate = {
26
+ element: fab,
27
+ control: {
28
+ id: id(fab),
29
+ kind: "floating-action-button",
30
+ x: 0,
31
+ y: 0,
32
+ width: innerWidth,
33
+ height: innerHeight,
34
+ dark: isDark(style),
35
+ rtl: style.direction === "rtl",
36
+ items: []
37
+ },
38
+ actions: /* @__PURE__ */ new Map(),
39
+ icons: []
40
+ };
41
+ for (const button of buttons) {
42
+ if (!button.classList.contains("ios") || button.closest(excluded) || button.color || button.type !== "button" || button.href) return;
43
+ if (button.querySelector("input, button, a, img, canvas, video, ion-spinner, ion-avatar, ion-badge")) return;
44
+ const native = button.shadowRoot?.querySelector("[part=native]");
45
+ if (!native) return;
46
+ const s = getComputedStyle(button), n = getComputedStyle(native);
47
+ const alpha = n.backgroundColor.startsWith("rgba(") ? Number(n.backgroundColor.slice(5, -1).split(",")[3]) : 1;
48
+ if (s.backgroundColor !== "rgba(0, 0, 0, 0)" || s.backgroundImage !== "none" || n.backgroundImage.includes("url(") || !n.backdropFilter.includes("blur") || !(alpha > 0 && alpha < 1)) return;
49
+ const width = parseFloat(s.width), height = parseFloat(s.height);
50
+ if (!(width > 0 && height > 0) || Math.abs(width - height) > .5 || !n.borderRadius.includes("50%")) return;
51
+ const list = button.parentElement?.matches("ion-fab-list") ? button.parentElement : void 0;
52
+ const listStyle = list && getComputedStyle(list);
53
+ const laidOut = s.display !== "none" && (!listStyle || listStyle.display !== "none");
54
+ const visible = laidOut && (!list || list.activated && button.show && listStyle.visibility === "visible" && Number(listStyle.opacity) > 0) && s.visibility === "visible" && Number(s.opacity) > 0;
55
+ const matrix = new DOMMatrixReadOnly(s.transform);
56
+ if (!matrix.is2D || matrix.b || matrix.c || matrix.e || matrix.f || matrix.a !== matrix.d || matrix.a < 0) return;
57
+ if (matrix.a !== 1 && (matrix.a !== 0 || !list || button.classList.contains("fab-button-show"))) return;
58
+ if (laidOut && !matrix.isIdentity) {
59
+ const origin = s.transformOrigin.split(" ").map(parseFloat);
60
+ if (Math.abs(origin[0] - width / 2) > .5 || Math.abs(origin[1] - height / 2) > .5) return;
61
+ }
62
+ if (hasHostMotion(s)) return;
63
+ if (listStyle) {
64
+ if (hasHostMotion(listStyle)) return;
65
+ const transform = new DOMMatrixReadOnly(listStyle.transform);
66
+ if (!transform.is2D || transform.a !== 1 || transform.d !== 1 || transform.b || transform.c) return;
67
+ }
68
+ const rect = button.getBoundingClientRect();
69
+ const x = laidOut ? rect.x + rect.width / 2 - width / 2 : 0;
70
+ const y = laidOut ? rect.y + rect.height / 2 - height / 2 : 0;
71
+ if (visible && (x < -1 || y < -1 || x + width > innerWidth + 1 || y + height > innerHeight + 1)) return;
72
+ const label = text(button);
73
+ const item = {
74
+ id: id(button),
75
+ x,
76
+ y,
77
+ width,
78
+ height,
79
+ label,
80
+ accessibilityLabel: button.getAttribute("aria-label") ?? native.getAttribute("aria-label") ?? label,
81
+ disabled: button.disabled || s.pointerEvents === "none",
82
+ selected: button.activated,
83
+ visible,
84
+ fontSize: parseFloat(s.fontSize),
85
+ fontWeight: parseInt(s.fontWeight, 10) || 400,
86
+ color: n.color
87
+ };
88
+ const normal = Array.from(button.querySelectorAll("ion-icon, svg"));
89
+ if (normal.length > 1) return;
90
+ const close = button.shadowRoot?.querySelector("ion-icon[part=close-icon]");
91
+ for (const [index, icon] of [normal[0], close].entries()) {
92
+ if (!icon) {
93
+ if (index === 1 || !label) return;
94
+ else continue;
95
+ }
96
+ const svg = icon.matches("svg") ? icon : icon.shadowRoot?.querySelector("svg");
97
+ if (!svg) return;
98
+ const iconStyle = getComputedStyle(icon);
99
+ const inner = icon.shadowRoot?.querySelector(".icon-inner");
100
+ if (index === 0 && inner && !new DOMMatrixReadOnly(iconStyle.transform).isIdentity) return;
101
+ const transform = new DOMMatrixReadOnly(inner ? getComputedStyle(inner).transform : iconStyle.transform);
102
+ const mirrored = transform.is2D && transform.a === -1 && transform.d === 1 && !transform.b && !transform.c && !transform.e && !transform.f;
103
+ if (index === 0 && !transform.isIdentity && !mirrored) return;
104
+ const source = iconSource(svg, index === 0 && mirrored);
105
+ const iconWidth = parseFloat(iconStyle.width), iconHeight = parseFloat(iconStyle.height);
106
+ const size = index === 1 ? parseFloat(iconStyle.fontSize) : iconWidth;
107
+ const h = index === 1 ? size : iconHeight;
108
+ if (!source || !(size > 0 && h > 0)) return;
109
+ if (index === 0) {
110
+ item.iconWidth = size;
111
+ item.iconHeight = h;
112
+ } else {
113
+ item.closeIconWidth = size;
114
+ item.closeIconHeight = h;
115
+ item.iconTransition = parseFloat(iconStyle.transitionDuration) * (iconStyle.transitionDuration.split(",")[0].trim().endsWith("ms") ? .001 : 1);
116
+ }
117
+ candidate.icons.push({
118
+ item,
119
+ source,
120
+ ...index === 1 ? { field: "closeIcon" } : {}
121
+ });
122
+ }
123
+ if (!visible && !list) return;
124
+ candidate.control.items.push(item);
125
+ if (visible) candidate.actions.set(item.id, button);
126
+ }
127
+ return candidate;
128
+ };
129
+ //#endregion
130
+ export { ion_fab_exports, read, shadowSelector, tag };
131
+
132
+ //# sourceMappingURL=ion-fab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ion-fab.js","names":[],"sources":["../../../src/native/components/ion-fab.ts"],"sourcesContent":["import type { Candidate } from '../shared/candidate';\nimport { childElements, excluded, isDark, text } from '../shared/dom';\nimport { iconSource } from '../shared/icons';\nimport type { NativeUIItem } from '../definitions';\n\nexport const tag = 'ion-fab';\nexport const shadowSelector = 'ion-fab-button, ion-fab-list';\n\nconst hasHostMotion = (style: CSSStyleDeclaration): boolean =>\n style.animationName !== 'none' || style.transitionDuration.split(',').some((value) => parseFloat(value) > 0);\n\n// FAB owns the batch; only its buttons draw glass. Closed lists keep their IDs\n// and resolved artwork, without inventing layout for display:none descendants.\nexport const read = (fab: HTMLElement, id: (element: HTMLElement) => string): Candidate | undefined => {\n if (fab.slot !== 'fixed' || !fab.parentElement?.matches('ion-content') || fab.contains(fab.ownerDocument.activeElement)) return;\n const children = childElements(fab);\n const main = children.filter((child) => child.matches('ion-fab-button'));\n const lists = children.filter((child) => child.matches('ion-fab-list'));\n if (main.length !== 1 || main.length + lists.length !== children.length) return;\n if (lists.some((list) => list.closest(excluded) || childElements(list).some((child) => !child.matches('ion-fab-button')))) return;\n const buttons = [main[0], ...lists.flatMap((list) => childElements(list))] as HTMLIonFabButtonElement[];\n const style = getComputedStyle(fab);\n if (hasHostMotion(style)) return;\n const transform = new DOMMatrixReadOnly(style.transform);\n if (!transform.is2D || transform.a !== 1 || transform.d !== 1 || transform.b || transform.c) return;\n const candidate: Candidate = {\n element: fab,\n control: {\n id: id(fab),\n kind: 'floating-action-button',\n x: 0,\n y: 0,\n width: innerWidth,\n height: innerHeight,\n dark: isDark(style),\n rtl: style.direction === 'rtl',\n items: [],\n },\n actions: new Map(),\n icons: [],\n };\n for (const button of buttons) {\n if (!button.classList.contains('ios') || button.closest(excluded) || button.color || button.type !== 'button' || button.href) return;\n if (button.querySelector('input, button, a, img, canvas, video, ion-spinner, ion-avatar, ion-badge')) return;\n const native = button.shadowRoot?.querySelector<HTMLElement>('[part=native]');\n if (!native) return;\n const s = getComputedStyle(button),\n n = getComputedStyle(native);\n // An opaque custom host/background or custom shape cannot be discarded.\n const alpha = n.backgroundColor.startsWith('rgba(') ? Number(n.backgroundColor.slice(5, -1).split(',')[3]) : 1;\n if (\n s.backgroundColor !== 'rgba(0, 0, 0, 0)' ||\n s.backgroundImage !== 'none' ||\n n.backgroundImage.includes('url(') ||\n !n.backdropFilter.includes('blur') ||\n !(alpha > 0 && alpha < 1)\n )\n return;\n const width = parseFloat(s.width),\n height = parseFloat(s.height);\n if (!(width > 0 && height > 0) || Math.abs(width - height) > 0.5 || !n.borderRadius.includes('50%')) return;\n const list = button.parentElement?.matches('ion-fab-list') ? (button.parentElement as HTMLIonFabListElement) : undefined;\n const listStyle = list && getComputedStyle(list);\n const laidOut = s.display !== 'none' && (!listStyle || listStyle.display !== 'none');\n const visible =\n laidOut &&\n (!list || (list.activated && button.show && listStyle!.visibility === 'visible' && Number(listStyle!.opacity) > 0)) &&\n s.visibility === 'visible' &&\n Number(s.opacity) > 0;\n // Standard scale is centered: even scale(0) retains its actual layout center.\n // Static list translation is already included in the DOM rect (including RTL).\n const matrix = new DOMMatrixReadOnly(s.transform);\n if (!matrix.is2D || matrix.b || matrix.c || matrix.e || matrix.f || matrix.a !== matrix.d || matrix.a < 0) return;\n // Only Ionic's hidden list child may use scale(0). Custom static scaling\n // changes the actual glass/hit area and must retain its Web rendering.\n // Stencil updates show before rendering its host class. Judge the rendered\n // scale against that class so this normal one-frame gap keeps its cover.\n if (matrix.a !== 1 && (matrix.a !== 0 || !list || button.classList.contains('fab-button-show'))) return;\n if (laidOut && !matrix.isIdentity) {\n const origin = s.transformOrigin.split(' ').map(parseFloat);\n if (Math.abs(origin[0] - width / 2) > 0.5 || Math.abs(origin[1] - height / 2) > 0.5) return;\n }\n // Ionic's list appearance is staggered show changes, without a host CSS\n // transition. Custom host animations keep their complete Web rendering.\n if (hasHostMotion(s)) return;\n if (listStyle) {\n if (hasHostMotion(listStyle)) return;\n const transform = new DOMMatrixReadOnly(listStyle.transform);\n if (!transform.is2D || transform.a !== 1 || transform.d !== 1 || transform.b || transform.c) return;\n }\n const rect = button.getBoundingClientRect();\n const x = laidOut ? rect.x + rect.width / 2 - width / 2 : 0;\n const y = laidOut ? rect.y + rect.height / 2 - height / 2 : 0;\n if (visible && (x < -1 || y < -1 || x + width > innerWidth + 1 || y + height > innerHeight + 1)) return;\n const label = text(button);\n const item: NativeUIItem = {\n id: id(button),\n x,\n y,\n width,\n height,\n label,\n accessibilityLabel: button.getAttribute('aria-label') ?? native.getAttribute('aria-label') ?? label,\n disabled: button.disabled || s.pointerEvents === 'none',\n selected: button.activated,\n visible,\n fontSize: parseFloat(s.fontSize),\n fontWeight: parseInt(s.fontWeight, 10) || 400,\n color: n.color,\n };\n const normal = Array.from(button.querySelectorAll('ion-icon, svg'));\n if (normal.length > 1) return;\n const close = button.shadowRoot?.querySelector<HTMLElement>('ion-icon[part=close-icon]');\n for (const [index, icon] of [normal[0], close].entries()) {\n if (!icon) {\n if (index === 1 || !label) return;\n else continue;\n }\n const svg = icon.matches('svg') ? (icon as SVGElement) : icon.shadowRoot?.querySelector<SVGElement>('svg');\n if (!svg) return;\n const iconStyle = getComputedStyle(icon);\n const inner = icon.shadowRoot?.querySelector('.icon-inner');\n if (index === 0 && inner && !new DOMMatrixReadOnly(iconStyle.transform).isIdentity) return;\n const transform = new DOMMatrixReadOnly(inner ? getComputedStyle(inner).transform : iconStyle.transform);\n const mirrored =\n transform.is2D && transform.a === -1 && transform.d === 1 && !transform.b && !transform.c && !transform.e && !transform.f;\n if (index === 0 && !transform.isIdentity && !mirrored) return;\n const source = iconSource(svg, index === 0 && mirrored);\n const iconWidth = parseFloat(iconStyle.width),\n iconHeight = parseFloat(iconStyle.height);\n // The internal close-icon fills the button vertically; its glyph uses font-size.\n const size = index === 1 ? parseFloat(iconStyle.fontSize) : iconWidth;\n const h = index === 1 ? size : iconHeight;\n if (!source || !(size > 0 && h > 0)) return;\n if (index === 0) {\n item.iconWidth = size;\n item.iconHeight = h;\n } else {\n item.closeIconWidth = size;\n item.closeIconHeight = h;\n item.iconTransition =\n parseFloat(iconStyle.transitionDuration) * (iconStyle.transitionDuration.split(',')[0].trim().endsWith('ms') ? 0.001 : 1);\n }\n candidate.icons.push({ item, source, ...(index === 1 ? { field: 'closeIcon' as const } : {}) });\n }\n if (!visible && !list) return;\n candidate.control.items.push(item);\n if (visible) candidate.actions.set(item.id, button);\n }\n return candidate;\n};\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Candidate, Identify } from "../shared/candidate.js";
2
+ import { VerticalControlAreaOptions } from "../definitions.js";
3
+ declare namespace ion_menu_button_d_exports {
4
+ export { append, read, selector, shadowSelector, tag };
5
+ }
6
+ export declare const tag = "ion-menu-button";
7
+ export declare const selector = "ion-menu-button";
8
+ export declare const shadowSelector = "ion-menu-button";
9
+ export declare const append: (candidate: Candidate, button: HTMLIonMenuButtonElement, id: Identify) => boolean;
10
+ export declare const read: (group: HTMLElement, id: Identify, options?: VerticalControlAreaOptions) => Candidate | undefined;
11
+ //#endregion
12
+ export { ion_menu_button_d_exports };
13
+ //# sourceMappingURL=ion-menu-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ion-menu-button.d.ts","names":[],"sources":["../../../src/native/components/ion-menu-button.ts"],"mappings":";;;;;qBAMa;qBAEA;qBACA;qBAEA,SAAU,WAAW,WAAW,QAAQ,0BAA0B,IAAI;qBAMtE,OAAQ,OAAO,aAAa,IAAI,UAAU,UAAS,+BAAkC"}
@@ -0,0 +1,44 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { childElements, inFixedToolbar, isVerticalBarsToolbarAction, isVerticalBarsToolbarGroup } from "../shared/dom.js";
3
+ import { horizontalSelected, horizontalToolbarGroup, inVerticalToolbarLayout } from "../shared/toolbar-options.js";
4
+ import { appendItem, createCandidate } from "../shared/candidate.js";
5
+ //#region src/native/components/ion-menu-button.ts
6
+ var ion_menu_button_exports = /* @__PURE__ */ __exportAll({
7
+ append: () => append,
8
+ read: () => read,
9
+ selector: () => selector,
10
+ shadowSelector: () => shadowSelector,
11
+ tag: () => tag
12
+ });
13
+ const tag = "ion-menu-button";
14
+ const selector = tag;
15
+ const shadowSelector = tag;
16
+ const append = (candidate, button, id) => {
17
+ if (button.type !== "button") return false;
18
+ const content = !button.shadowRoot?.querySelector("slot")?.assignedNodes().length ? button.shadowRoot : button;
19
+ return !!content && !!appendItem(candidate, button, id, content);
20
+ };
21
+ const read = (group, id, options = {}) => {
22
+ if (group.matches("ion-menu-button")) {
23
+ if (!inFixedToolbar(group)) return;
24
+ if (inVerticalToolbarLayout(group)) {
25
+ if (!isVerticalBarsToolbarAction(group)) return;
26
+ if (group.parentElement && isVerticalBarsToolbarGroup(group.parentElement)) return;
27
+ } else {
28
+ if (!horizontalSelected(group, options) || !group.parentElement?.matches("ion-buttons")) return;
29
+ if (horizontalToolbarGroup(group.parentElement, options)) return;
30
+ }
31
+ const candidate = createCandidate(group, tag, id, options);
32
+ return append(candidate, group, id) ? candidate : void 0;
33
+ }
34
+ const children = group.matches("ion-buttons") ? childElements(group) : [];
35
+ if (!inFixedToolbar(group) || children.length !== 1) return;
36
+ const button = children[0];
37
+ if (!button?.matches(`ion-menu-button${group.closest("ion-app.ios-theme-vertical-bars") ? "" : ".ios"}`)) return;
38
+ const candidate = createCandidate(group, tag, id, options);
39
+ return append(candidate, button, id) ? candidate : void 0;
40
+ };
41
+ //#endregion
42
+ export { append, ion_menu_button_exports, read, selector, shadowSelector, tag };
43
+
44
+ //# sourceMappingURL=ion-menu-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ion-menu-button.js","names":[],"sources":["../../../src/native/components/ion-menu-button.ts"],"sourcesContent":["import { horizontalSelected, horizontalToolbarGroup, inVerticalToolbarLayout } from '../shared/toolbar-options';\nimport { createCandidate, appendItem } from '../shared/candidate';\nimport type { Candidate, Identify } from '../shared/candidate';\nimport type { VerticalControlAreaOptions } from '../definitions';\nimport { childElements, inFixedToolbar, isVerticalBarsToolbarAction, isVerticalBarsToolbarGroup } from '../shared/dom';\n\nexport const tag = 'ion-menu-button';\n// Horizontal menu buttons belong to ion-buttons; vertical actions can opt out of grouping.\nexport const selector = tag;\nexport const shadowSelector = tag;\n\nexport const append = (candidate: Candidate, button: HTMLIonMenuButtonElement, id: Identify): boolean => {\n if (button.type !== 'button') return false;\n const content = !button.shadowRoot?.querySelector('slot')?.assignedNodes().length ? button.shadowRoot : button;\n return !!content && !!appendItem(candidate, button, id, content);\n};\n\nexport const read = (group: HTMLElement, id: Identify, options: VerticalControlAreaOptions = {}): Candidate | undefined => {\n if (group.matches(tag)) {\n if (!inFixedToolbar(group)) return;\n if (inVerticalToolbarLayout(group)) {\n if (!isVerticalBarsToolbarAction(group)) return;\n if (group.parentElement && isVerticalBarsToolbarGroup(group.parentElement)) return;\n } else {\n if (!horizontalSelected(group, options) || !group.parentElement?.matches('ion-buttons')) return;\n if (horizontalToolbarGroup(group.parentElement, options)) return;\n }\n const candidate = createCandidate(group, tag, id, options);\n return append(candidate, group as HTMLIonMenuButtonElement, id) ? candidate : undefined;\n }\n const children = group.matches('ion-buttons') ? childElements(group) : [];\n if (!inFixedToolbar(group) || children.length !== 1) return;\n const button = children[0];\n if (!button?.matches(`${tag}${group.closest('ion-app.ios-theme-vertical-bars') ? '' : '.ios'}`)) return;\n const candidate = createCandidate(group, tag, id, options);\n return append(candidate, button as HTMLIonMenuButtonElement, id) ? candidate : undefined;\n};\n"],"mappings":";;;;;;;;;;;;AAMA,MAAa,MAAM;AAEnB,MAAa,WAAW;AACxB,MAAa,iBAAiB;AAE9B,MAAa,UAAU,WAAsB,QAAkC,OAA0B;CACvG,IAAI,OAAO,SAAS,UAAU,OAAO;CACrC,MAAM,UAAU,CAAC,OAAO,YAAY,cAAc,MAAM,CAAC,EAAE,cAAc,CAAC,CAAC,SAAS,OAAO,aAAa;CACxG,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,WAAW,WAAW,QAAQ,IAAI,OAAO;AACjE;AAEA,MAAa,QAAQ,OAAoB,IAAc,UAAsC,CAAC,MAA6B;CACzH,IAAI,MAAM,QAAA,iBAAW,GAAG;EACtB,IAAI,CAAC,eAAe,KAAK,GAAG;EAC5B,IAAI,wBAAwB,KAAK,GAAG;GAClC,IAAI,CAAC,4BAA4B,KAAK,GAAG;GACzC,IAAI,MAAM,iBAAiB,2BAA2B,MAAM,aAAa,GAAG;EAC9E,OAAO;GACL,IAAI,CAAC,mBAAmB,OAAO,OAAO,KAAK,CAAC,MAAM,eAAe,QAAQ,aAAa,GAAG;GACzF,IAAI,uBAAuB,MAAM,eAAe,OAAO,GAAG;EAC5D;EACA,MAAM,YAAY,gBAAgB,OAAO,KAAK,IAAI,OAAO;EACzD,OAAO,OAAO,WAAW,OAAmC,EAAE,IAAI,YAAY,KAAA;CAChF;CACA,MAAM,WAAW,MAAM,QAAQ,aAAa,IAAI,cAAc,KAAK,IAAI,CAAC;CACxE,IAAI,CAAC,eAAe,KAAK,KAAK,SAAS,WAAW,GAAG;CACrD,MAAM,SAAS,SAAS;CACxB,IAAI,CAAC,QAAQ,QAAQ,kBAAS,MAAM,QAAQ,iCAAiC,IAAI,KAAK,QAAQ,GAAG;CACjG,MAAM,YAAY,gBAAgB,OAAO,KAAK,IAAI,OAAO;CACzD,OAAO,OAAO,WAAW,QAAoC,EAAE,IAAI,YAAY,KAAA;AACjF"}
@@ -0,0 +1,11 @@
1
+ import { Candidate, Identify } from "../shared/candidate.js";
2
+ declare namespace ion_segment_d_exports {
3
+ export { read, shadowSelector, tag, tracksMotion };
4
+ }
5
+ export declare const tag = "ion-segment";
6
+ export declare const shadowSelector = "ion-segment-button";
7
+ export declare const tracksMotion = true;
8
+ export declare const read: (element: HTMLElement, id: Identify) => Candidate | undefined;
9
+ //#endregion
10
+ export { ion_segment_d_exports };
11
+ //# sourceMappingURL=ion-segment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ion-segment.d.ts","names":[],"sources":["../../../src/native/components/ion-segment.ts"],"mappings":";;;;qBAIa;qBACA;qBACA;qBAEA,OAAQ,SAAS,aAAa,IAAI,aAAW"}
@@ -0,0 +1,30 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { inFixedToolbar } from "../shared/dom.js";
3
+ import { appendItem, createCandidate } from "../shared/candidate.js";
4
+ //#region src/native/components/ion-segment.ts
5
+ var ion_segment_exports = /* @__PURE__ */ __exportAll({
6
+ read: () => read,
7
+ shadowSelector: () => shadowSelector,
8
+ tag: () => tag,
9
+ tracksMotion: () => true
10
+ });
11
+ const tag = "ion-segment";
12
+ const shadowSelector = "ion-segment-button";
13
+ const tracksMotion = true;
14
+ const read = (element, id) => {
15
+ const segment = element;
16
+ if (!inFixedToolbar(element) || segment.scrollable || element.classList.contains("segment-expand") || element.querySelector("ion-segment-button[content-id]")) return;
17
+ const children = Array.from(element.querySelectorAll(":scope > ion-segment-button"));
18
+ if (!children.length) return;
19
+ const candidate = createCandidate(element, tag, id);
20
+ for (const child of children) {
21
+ const item = appendItem(candidate, child, id);
22
+ if (!item || item.label && item.iconWidth) return;
23
+ item.selected = segment.value === child.value;
24
+ }
25
+ return candidate;
26
+ };
27
+ //#endregion
28
+ export { ion_segment_exports, read, shadowSelector, tag, tracksMotion };
29
+
30
+ //# sourceMappingURL=ion-segment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ion-segment.js","names":[],"sources":["../../../src/native/components/ion-segment.ts"],"sourcesContent":["import { createCandidate, appendItem } from '../shared/candidate';\nimport type { Candidate, Identify } from '../shared/candidate';\nimport { inFixedToolbar } from '../shared/dom';\n\nexport const tag = 'ion-segment';\nexport const shadowSelector = 'ion-segment-button';\nexport const tracksMotion = true;\n\nexport const read = (element: HTMLElement, id: Identify): Candidate | undefined => {\n const segment = element as HTMLIonSegmentElement;\n if (\n !inFixedToolbar(element) ||\n segment.scrollable ||\n element.classList.contains('segment-expand') ||\n element.querySelector('ion-segment-button[content-id]')\n )\n return;\n const children = Array.from(element.querySelectorAll<HTMLIonSegmentButtonElement>(':scope > ion-segment-button'));\n if (!children.length) return;\n const candidate = createCandidate(element, tag, id);\n for (const child of children) {\n const item = appendItem(candidate, child, id);\n if (!item || (item.label && item.iconWidth)) return;\n item.selected = segment.value === child.value;\n }\n return candidate;\n};\n"],"mappings":";;;;;;;;;;AAIA,MAAa,MAAM;AACnB,MAAa,iBAAiB;AAC9B,MAAa,eAAe;AAE5B,MAAa,QAAQ,SAAsB,OAAwC;CACjF,MAAM,UAAU;CAChB,IACE,CAAC,eAAe,OAAO,KACvB,QAAQ,cACR,QAAQ,UAAU,SAAS,gBAAgB,KAC3C,QAAQ,cAAc,gCAAgC,GAEtD;CACF,MAAM,WAAW,MAAM,KAAK,QAAQ,iBAA8C,6BAA6B,CAAC;CAChH,IAAI,CAAC,SAAS,QAAQ;CACtB,MAAM,YAAY,gBAAgB,SAAS,KAAK,EAAE;CAClD,KAAK,MAAM,SAAS,UAAU;EAC5B,MAAM,OAAO,WAAW,WAAW,OAAO,EAAE;EAC5C,IAAI,CAAC,QAAS,KAAK,SAAS,KAAK,WAAY;EAC7C,KAAK,WAAW,QAAQ,UAAU,MAAM;CAC1C;CACA,OAAO;AACT"}
@@ -0,0 +1,11 @@
1
+ import { Candidate, Identify } from "../shared/candidate.js";
2
+ declare namespace ion_tab_bar_d_exports {
3
+ export { read, shadowSelector, tag, tracksMotion };
4
+ }
5
+ export declare const tag = "ion-tab-bar";
6
+ export declare const shadowSelector = "ion-tab-button";
7
+ export declare const tracksMotion = true;
8
+ export declare const read: (element: HTMLElement, id: Identify) => Candidate | undefined;
9
+ //#endregion
10
+ export { ion_tab_bar_d_exports };
11
+ //# sourceMappingURL=ion-tab-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ion-tab-bar.d.ts","names":[],"sources":["../../../src/native/components/ion-tab-bar.ts"],"mappings":";;;;qBAGa;qBACA;qBACA;qBAEA,OAAQ,SAAS,aAAa,IAAI,aAAW"}
@@ -0,0 +1,50 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { appendItem, createCandidate } from "../shared/candidate.js";
3
+ //#region src/native/components/ion-tab-bar.ts
4
+ var ion_tab_bar_exports = /* @__PURE__ */ __exportAll({
5
+ read: () => read,
6
+ shadowSelector: () => shadowSelector,
7
+ tag: () => tag,
8
+ tracksMotion: () => true
9
+ });
10
+ const tag = "ion-tab-bar";
11
+ const shadowSelector = "ion-tab-button";
12
+ const tracksMotion = true;
13
+ const read = (element, id) => {
14
+ if (element.closest("ion-content")) return;
15
+ const children = Array.from(element.querySelectorAll(":scope > ion-tab-button:not(.ion-cloned-element)"));
16
+ if (!children.length) return;
17
+ const width = children[0].getBoundingClientRect().width;
18
+ if (children.some((child) => (child.layout ?? "icon-top") !== "icon-top" || Math.abs(child.getBoundingClientRect().width - width) > 1)) return void 0;
19
+ const candidate = createCandidate(element, tag, id);
20
+ const style = getComputedStyle(element);
21
+ const rtl = style.direction === "rtl";
22
+ const position = [
23
+ "start",
24
+ "center",
25
+ "end"
26
+ ].find((value) => element.classList.contains(`tab-bar-position-${value}`));
27
+ candidate.control.tabBarAnchor = {
28
+ x: position === "center" ? .5 : position ? position === "start" !== rtl ? 0 : 1 : style.left !== "auto" ? 0 : 1,
29
+ y: element.slot === "bottom" ? 1 : 0
30
+ };
31
+ for (const child of children) {
32
+ const item = appendItem(candidate, child, id);
33
+ if (!item) return;
34
+ const svg = child.querySelector("svg") ?? child.querySelector("ion-icon")?.shadowRoot?.querySelector("svg");
35
+ if (svg) {
36
+ item.iconPosition = "top";
37
+ const color = getComputedStyle(svg).color;
38
+ const shapes = Array.from(svg.querySelectorAll("path, rect, circle, ellipse, line, polygon, polyline"));
39
+ item.iconTemplate = shapes.length > 0 && shapes.every((shape) => {
40
+ const paint = getComputedStyle(shape);
41
+ return [paint.fill, paint.stroke].every((value) => value === "none" || value === color);
42
+ });
43
+ }
44
+ }
45
+ return candidate;
46
+ };
47
+ //#endregion
48
+ export { ion_tab_bar_exports, read, shadowSelector, tag, tracksMotion };
49
+
50
+ //# sourceMappingURL=ion-tab-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ion-tab-bar.js","names":[],"sources":["../../../src/native/components/ion-tab-bar.ts"],"sourcesContent":["import { createCandidate, appendItem } from '../shared/candidate';\nimport type { Candidate, Identify } from '../shared/candidate';\n\nexport const tag = 'ion-tab-bar';\nexport const shadowSelector = 'ion-tab-button';\nexport const tracksMotion = true;\n\nexport const read = (element: HTMLElement, id: Identify): Candidate | undefined => {\n if (element.closest('ion-content')) return;\n const children = Array.from(element.querySelectorAll<HTMLElement>(':scope > ion-tab-button:not(.ion-cloned-element)'));\n if (!children.length) return;\n // Only equal items with Ionic's default layout map to UIKit's adaptive tabs.\n const width = children[0].getBoundingClientRect().width;\n if (\n children.some(\n (child) =>\n ((child as HTMLIonTabButtonElement).layout ?? 'icon-top') !== 'icon-top' ||\n Math.abs(child.getBoundingClientRect().width - width) > 1,\n )\n )\n return undefined;\n\n const candidate = createCandidate(element, tag, id);\n const style = getComputedStyle(element);\n const rtl = style.direction === 'rtl';\n const position = ['start', 'center', 'end'].find((value) => element.classList.contains(`tab-bar-position-${value}`));\n candidate.control.tabBarAnchor = {\n x: position === 'center' ? 0.5 : position ? ((position === 'start') !== rtl ? 0 : 1) : style.left !== 'auto' ? 0 : 1,\n y: element.slot === 'bottom' ? 1 : 0,\n };\n\n for (const child of children) {\n const item = appendItem(candidate, child, id);\n if (!item) return;\n const svg = child.querySelector<SVGElement>('svg') ?? child.querySelector('ion-icon')?.shadowRoot?.querySelector<SVGElement>('svg');\n if (svg) {\n item.iconPosition = 'top';\n const color = getComputedStyle(svg).color;\n const shapes = Array.from(svg.querySelectorAll('path, rect, circle, ellipse, line, polygon, polyline'));\n // Only text-colored SVGs follow UIKit selection tint; preserve explicit artwork colors.\n item.iconTemplate =\n shapes.length > 0 &&\n shapes.every((shape) => {\n const paint = getComputedStyle(shape);\n return [paint.fill, paint.stroke].every((value) => value === 'none' || value === color);\n });\n }\n }\n return candidate;\n};\n"],"mappings":";;;;;;;;;AAGA,MAAa,MAAM;AACnB,MAAa,iBAAiB;AAC9B,MAAa,eAAe;AAE5B,MAAa,QAAQ,SAAsB,OAAwC;CACjF,IAAI,QAAQ,QAAQ,aAAa,GAAG;CACpC,MAAM,WAAW,MAAM,KAAK,QAAQ,iBAA8B,kDAAkD,CAAC;CACrH,IAAI,CAAC,SAAS,QAAQ;CAEtB,MAAM,QAAQ,SAAS,EAAE,CAAC,sBAAsB,CAAC,CAAC;CAClD,IACE,SAAS,MACN,WACG,MAAkC,UAAU,gBAAgB,cAC9D,KAAK,IAAI,MAAM,sBAAsB,CAAC,CAAC,QAAQ,KAAK,IAAI,CAC5D,GAEA,OAAO,KAAA;CAET,MAAM,YAAY,gBAAgB,SAAS,KAAK,EAAE;CAClD,MAAM,QAAQ,iBAAiB,OAAO;CACtC,MAAM,MAAM,MAAM,cAAc;CAChC,MAAM,WAAW;EAAC;EAAS;EAAU;CAAK,CAAC,CAAC,MAAM,UAAU,QAAQ,UAAU,SAAS,oBAAoB,OAAO,CAAC;CACnH,UAAU,QAAQ,eAAe;EAC/B,GAAG,aAAa,WAAW,KAAM,WAAa,aAAa,YAAa,MAAM,IAAI,IAAK,MAAM,SAAS,SAAS,IAAI;EACnH,GAAG,QAAQ,SAAS,WAAW,IAAI;CACrC;CAEA,KAAK,MAAM,SAAS,UAAU;EAC5B,MAAM,OAAO,WAAW,WAAW,OAAO,EAAE;EAC5C,IAAI,CAAC,MAAM;EACX,MAAM,MAAM,MAAM,cAA0B,KAAK,KAAK,MAAM,cAAc,UAAU,CAAC,EAAE,YAAY,cAA0B,KAAK;EAClI,IAAI,KAAK;GACP,KAAK,eAAe;GACpB,MAAM,QAAQ,iBAAiB,GAAG,CAAC,CAAC;GACpC,MAAM,SAAS,MAAM,KAAK,IAAI,iBAAiB,sDAAsD,CAAC;GAEtG,KAAK,eACH,OAAO,SAAS,KAChB,OAAO,OAAO,UAAU;IACtB,MAAM,QAAQ,iBAAiB,KAAK;IACpC,OAAO,CAAC,MAAM,MAAM,MAAM,MAAM,CAAC,CAAC,OAAO,UAAU,UAAU,UAAU,UAAU,KAAK;GACxF,CAAC;EACL;CACF;CACA,OAAO;AACT"}
@@ -0,0 +1,20 @@
1
+ import { Candidate } from "../shared/candidate.js";
2
+ import { NativeUISearchEvent } from "../definitions.js";
3
+ import { NativeSearchBinding } from "../../native-integration/index.js";
4
+ //#region src/native/components/searchable-tabs.d.ts
5
+ export declare const createSearchSupport: (doc: Document, id: (element: Element) => string, schedule: () => void) => {
6
+ keyboard(visible: boolean): void;
7
+ keepSearchTabsVisible(): void;
8
+ decorate(candidates: Candidate[], blocked: (element: HTMLElement) => boolean): Candidate[];
9
+ projected: (binding: NativeSearchBinding) => boolean;
10
+ hasActive(): boolean;
11
+ begin(binding: NativeSearchBinding, revision: number): void;
12
+ setStatus(binding: NativeSearchBinding, active: boolean, focused?: boolean): void;
13
+ release(element: HTMLElement): void;
14
+ reject(ids: string[]): void;
15
+ event(event: NativeUISearchEvent): void;
16
+ retire(binding: NativeSearchBinding): void;
17
+ destroy(): void;
18
+ };
19
+ //#endregion
20
+ //# sourceMappingURL=searchable-tabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchable-tabs.d.ts","names":[],"sources":["../../../src/native/components/searchable-tabs.ts"],"mappings":";;;;qBAwBa,sBAAuB,KAAK,UAAU,KAAK,SAAS,oBAAoB;EA8I/D,SAAA;;EAwBG,SAAA,YAAA,aAAW,UAAY,SAAS,0BAA0B;EAvJrD,YAAA,SAAA;;EAuXX,MAAA,SAAA,qBAAmB;EAKf,UAAA,SAAA,qBAAmB,iBAAiB;EAUtC,QAAA,SAAA;EAGL,OAAA;EASC,MAAA,OAAA;EAqCG,OAAA,SAAA"}