@elurjs/ionic 2.0.7

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 (382) hide show
  1. package/CHANGELOG.md +272 -0
  2. package/MIGRATION.md +221 -0
  3. package/README.md +695 -0
  4. package/dist/lib/IonRouterOutlet.d.ts +134 -0
  5. package/dist/lib/__tests__/IonRouterOutlet.test.d.ts +1 -0
  6. package/dist/lib/__tests__/bundles.test.d.ts +1 -0
  7. package/dist/lib/__tests__/cache-policy.test.d.ts +1 -0
  8. package/dist/lib/__tests__/capacitor.test.d.ts +1 -0
  9. package/dist/lib/__tests__/components.test.d.ts +1 -0
  10. package/dist/lib/__tests__/lifecycle.test.d.ts +1 -0
  11. package/dist/lib/__tests__/mocks/ionic.d.ts +61 -0
  12. package/dist/lib/__tests__/navigation.test.d.ts +1 -0
  13. package/dist/lib/__tests__/overlays.test.d.ts +1 -0
  14. package/dist/lib/__tests__/page-state.test.d.ts +1 -0
  15. package/dist/lib/__tests__/phase0-bugs.test.d.ts +1 -0
  16. package/dist/lib/__tests__/setup.d.ts +1 -0
  17. package/dist/lib/__tests__/setup.test.d.ts +1 -0
  18. package/dist/lib/__tests__/tabs.test.d.ts +1 -0
  19. package/dist/lib/__tests__/vite-plugin.test.d.ts +1 -0
  20. package/dist/lib/bundles/all.cjs +2 -0
  21. package/dist/lib/bundles/all.cjs.map +1 -0
  22. package/dist/lib/bundles/all.d.ts +16 -0
  23. package/dist/lib/bundles/all.js +21 -0
  24. package/dist/lib/bundles/all.js.map +1 -0
  25. package/dist/lib/bundles/buttons.cjs +2 -0
  26. package/dist/lib/bundles/buttons.cjs.map +1 -0
  27. package/dist/lib/bundles/buttons.d.ts +7 -0
  28. package/dist/lib/bundles/buttons.js +17 -0
  29. package/dist/lib/bundles/buttons.js.map +1 -0
  30. package/dist/lib/bundles/feedback.cjs +2 -0
  31. package/dist/lib/bundles/feedback.cjs.map +1 -0
  32. package/dist/lib/bundles/feedback.d.ts +8 -0
  33. package/dist/lib/bundles/feedback.js +19 -0
  34. package/dist/lib/bundles/feedback.js.map +1 -0
  35. package/dist/lib/bundles/forms.cjs +2 -0
  36. package/dist/lib/bundles/forms.cjs.map +1 -0
  37. package/dist/lib/bundles/forms.d.ts +11 -0
  38. package/dist/lib/bundles/forms.js +47 -0
  39. package/dist/lib/bundles/forms.js.map +1 -0
  40. package/dist/lib/bundles/layout.cjs +2 -0
  41. package/dist/lib/bundles/layout.cjs.map +1 -0
  42. package/dist/lib/bundles/layout.d.ts +9 -0
  43. package/dist/lib/bundles/layout.js +33 -0
  44. package/dist/lib/bundles/layout.js.map +1 -0
  45. package/dist/lib/bundles/lists.cjs +2 -0
  46. package/dist/lib/bundles/lists.cjs.map +1 -0
  47. package/dist/lib/bundles/lists.d.ts +15 -0
  48. package/dist/lib/bundles/lists.js +65 -0
  49. package/dist/lib/bundles/lists.js.map +1 -0
  50. package/dist/lib/bundles/navigation.cjs +2 -0
  51. package/dist/lib/bundles/navigation.cjs.map +1 -0
  52. package/dist/lib/bundles/navigation.d.ts +9 -0
  53. package/dist/lib/bundles/navigation.js +29 -0
  54. package/dist/lib/bundles/navigation.js.map +1 -0
  55. package/dist/lib/bundles/overlays.cjs +2 -0
  56. package/dist/lib/bundles/overlays.cjs.map +1 -0
  57. package/dist/lib/bundles/overlays.d.ts +9 -0
  58. package/dist/lib/bundles/overlays.js +25 -0
  59. package/dist/lib/bundles/overlays.js.map +1 -0
  60. package/dist/lib/capacitor.cjs +2 -0
  61. package/dist/lib/capacitor.cjs.map +1 -0
  62. package/dist/lib/capacitor.d.ts +217 -0
  63. package/dist/lib/capacitor.js +223 -0
  64. package/dist/lib/capacitor.js.map +1 -0
  65. package/dist/lib/components/accordion-group.cjs +1 -0
  66. package/dist/lib/components/accordion-group.d.ts +11 -0
  67. package/dist/lib/components/accordion-group.js +2 -0
  68. package/dist/lib/components/accordion.cjs +1 -0
  69. package/dist/lib/components/accordion.d.ts +11 -0
  70. package/dist/lib/components/accordion.js +2 -0
  71. package/dist/lib/components/action-sheet.cjs +1 -0
  72. package/dist/lib/components/action-sheet.d.ts +11 -0
  73. package/dist/lib/components/action-sheet.js +2 -0
  74. package/dist/lib/components/alert.cjs +1 -0
  75. package/dist/lib/components/alert.d.ts +11 -0
  76. package/dist/lib/components/alert.js +2 -0
  77. package/dist/lib/components/avatar.cjs +1 -0
  78. package/dist/lib/components/avatar.d.ts +11 -0
  79. package/dist/lib/components/avatar.js +2 -0
  80. package/dist/lib/components/backdrop.cjs +1 -0
  81. package/dist/lib/components/backdrop.d.ts +11 -0
  82. package/dist/lib/components/backdrop.js +2 -0
  83. package/dist/lib/components/badge.cjs +1 -0
  84. package/dist/lib/components/badge.d.ts +11 -0
  85. package/dist/lib/components/badge.js +2 -0
  86. package/dist/lib/components/breadcrumb.cjs +1 -0
  87. package/dist/lib/components/breadcrumb.d.ts +11 -0
  88. package/dist/lib/components/breadcrumb.js +2 -0
  89. package/dist/lib/components/breadcrumbs.cjs +1 -0
  90. package/dist/lib/components/breadcrumbs.d.ts +11 -0
  91. package/dist/lib/components/breadcrumbs.js +2 -0
  92. package/dist/lib/components/button.cjs +1 -0
  93. package/dist/lib/components/button.d.ts +11 -0
  94. package/dist/lib/components/button.js +2 -0
  95. package/dist/lib/components/buttons.cjs +1 -0
  96. package/dist/lib/components/buttons.d.ts +11 -0
  97. package/dist/lib/components/buttons.js +2 -0
  98. package/dist/lib/components/card-content.cjs +1 -0
  99. package/dist/lib/components/card-content.d.ts +11 -0
  100. package/dist/lib/components/card-content.js +2 -0
  101. package/dist/lib/components/card-header.cjs +1 -0
  102. package/dist/lib/components/card-header.d.ts +11 -0
  103. package/dist/lib/components/card-header.js +2 -0
  104. package/dist/lib/components/card-subtitle.cjs +1 -0
  105. package/dist/lib/components/card-subtitle.d.ts +11 -0
  106. package/dist/lib/components/card-subtitle.js +2 -0
  107. package/dist/lib/components/card-title.cjs +1 -0
  108. package/dist/lib/components/card-title.d.ts +11 -0
  109. package/dist/lib/components/card-title.js +2 -0
  110. package/dist/lib/components/card.cjs +1 -0
  111. package/dist/lib/components/card.d.ts +11 -0
  112. package/dist/lib/components/card.js +2 -0
  113. package/dist/lib/components/checkbox.cjs +1 -0
  114. package/dist/lib/components/checkbox.d.ts +11 -0
  115. package/dist/lib/components/checkbox.js +2 -0
  116. package/dist/lib/components/chip.cjs +1 -0
  117. package/dist/lib/components/chip.d.ts +11 -0
  118. package/dist/lib/components/chip.js +2 -0
  119. package/dist/lib/components/col.cjs +1 -0
  120. package/dist/lib/components/col.d.ts +11 -0
  121. package/dist/lib/components/col.js +2 -0
  122. package/dist/lib/components/content.cjs +1 -0
  123. package/dist/lib/components/content.d.ts +11 -0
  124. package/dist/lib/components/content.js +2 -0
  125. package/dist/lib/components/datetime-button.cjs +1 -0
  126. package/dist/lib/components/datetime-button.d.ts +11 -0
  127. package/dist/lib/components/datetime-button.js +2 -0
  128. package/dist/lib/components/datetime.cjs +1 -0
  129. package/dist/lib/components/datetime.d.ts +11 -0
  130. package/dist/lib/components/datetime.js +2 -0
  131. package/dist/lib/components/fab-button.cjs +1 -0
  132. package/dist/lib/components/fab-button.d.ts +11 -0
  133. package/dist/lib/components/fab-button.js +2 -0
  134. package/dist/lib/components/fab-list.cjs +1 -0
  135. package/dist/lib/components/fab-list.d.ts +11 -0
  136. package/dist/lib/components/fab-list.js +2 -0
  137. package/dist/lib/components/fab.cjs +1 -0
  138. package/dist/lib/components/fab.d.ts +11 -0
  139. package/dist/lib/components/fab.js +2 -0
  140. package/dist/lib/components/footer.cjs +1 -0
  141. package/dist/lib/components/footer.d.ts +11 -0
  142. package/dist/lib/components/footer.js +2 -0
  143. package/dist/lib/components/grid.cjs +1 -0
  144. package/dist/lib/components/grid.d.ts +11 -0
  145. package/dist/lib/components/grid.js +2 -0
  146. package/dist/lib/components/header.cjs +1 -0
  147. package/dist/lib/components/header.d.ts +11 -0
  148. package/dist/lib/components/header.js +2 -0
  149. package/dist/lib/components/img.cjs +1 -0
  150. package/dist/lib/components/img.d.ts +11 -0
  151. package/dist/lib/components/img.js +2 -0
  152. package/dist/lib/components/infinite-scroll-content.cjs +1 -0
  153. package/dist/lib/components/infinite-scroll-content.d.ts +11 -0
  154. package/dist/lib/components/infinite-scroll-content.js +2 -0
  155. package/dist/lib/components/infinite-scroll.cjs +1 -0
  156. package/dist/lib/components/infinite-scroll.d.ts +11 -0
  157. package/dist/lib/components/infinite-scroll.js +2 -0
  158. package/dist/lib/components/input-otp.cjs +1 -0
  159. package/dist/lib/components/input-otp.d.ts +11 -0
  160. package/dist/lib/components/input-otp.js +2 -0
  161. package/dist/lib/components/input-password-toggle.cjs +1 -0
  162. package/dist/lib/components/input-password-toggle.d.ts +11 -0
  163. package/dist/lib/components/input-password-toggle.js +2 -0
  164. package/dist/lib/components/input.cjs +1 -0
  165. package/dist/lib/components/input.d.ts +11 -0
  166. package/dist/lib/components/input.js +2 -0
  167. package/dist/lib/components/item-divider.cjs +1 -0
  168. package/dist/lib/components/item-divider.d.ts +11 -0
  169. package/dist/lib/components/item-divider.js +2 -0
  170. package/dist/lib/components/item-group.cjs +1 -0
  171. package/dist/lib/components/item-group.d.ts +11 -0
  172. package/dist/lib/components/item-group.js +2 -0
  173. package/dist/lib/components/item-option.cjs +1 -0
  174. package/dist/lib/components/item-option.d.ts +11 -0
  175. package/dist/lib/components/item-option.js +2 -0
  176. package/dist/lib/components/item-options.cjs +1 -0
  177. package/dist/lib/components/item-options.d.ts +11 -0
  178. package/dist/lib/components/item-options.js +2 -0
  179. package/dist/lib/components/item-sliding.cjs +1 -0
  180. package/dist/lib/components/item-sliding.d.ts +11 -0
  181. package/dist/lib/components/item-sliding.js +2 -0
  182. package/dist/lib/components/item.cjs +1 -0
  183. package/dist/lib/components/item.d.ts +11 -0
  184. package/dist/lib/components/item.js +2 -0
  185. package/dist/lib/components/label.cjs +1 -0
  186. package/dist/lib/components/label.d.ts +11 -0
  187. package/dist/lib/components/label.js +2 -0
  188. package/dist/lib/components/list-header.cjs +1 -0
  189. package/dist/lib/components/list-header.d.ts +11 -0
  190. package/dist/lib/components/list-header.js +2 -0
  191. package/dist/lib/components/list.cjs +1 -0
  192. package/dist/lib/components/list.d.ts +11 -0
  193. package/dist/lib/components/list.js +2 -0
  194. package/dist/lib/components/loading.cjs +1 -0
  195. package/dist/lib/components/loading.d.ts +11 -0
  196. package/dist/lib/components/loading.js +2 -0
  197. package/dist/lib/components/manifest.cjs +2 -0
  198. package/dist/lib/components/manifest.cjs.map +1 -0
  199. package/dist/lib/components/manifest.d.ts +43 -0
  200. package/dist/lib/components/manifest.js +647 -0
  201. package/dist/lib/components/manifest.js.map +1 -0
  202. package/dist/lib/components/menu-button.cjs +1 -0
  203. package/dist/lib/components/menu-button.d.ts +11 -0
  204. package/dist/lib/components/menu-button.js +2 -0
  205. package/dist/lib/components/menu-toggle.cjs +1 -0
  206. package/dist/lib/components/menu-toggle.d.ts +11 -0
  207. package/dist/lib/components/menu-toggle.js +2 -0
  208. package/dist/lib/components/menu.cjs +1 -0
  209. package/dist/lib/components/menu.d.ts +11 -0
  210. package/dist/lib/components/menu.js +2 -0
  211. package/dist/lib/components/modal.cjs +1 -0
  212. package/dist/lib/components/modal.d.ts +11 -0
  213. package/dist/lib/components/modal.js +2 -0
  214. package/dist/lib/components/nav-link.cjs +1 -0
  215. package/dist/lib/components/nav-link.d.ts +11 -0
  216. package/dist/lib/components/nav-link.js +2 -0
  217. package/dist/lib/components/nav.cjs +1 -0
  218. package/dist/lib/components/nav.d.ts +11 -0
  219. package/dist/lib/components/nav.js +2 -0
  220. package/dist/lib/components/note.cjs +1 -0
  221. package/dist/lib/components/note.d.ts +11 -0
  222. package/dist/lib/components/note.js +2 -0
  223. package/dist/lib/components/picker-column-option.cjs +1 -0
  224. package/dist/lib/components/picker-column-option.d.ts +11 -0
  225. package/dist/lib/components/picker-column-option.js +2 -0
  226. package/dist/lib/components/picker-column.cjs +1 -0
  227. package/dist/lib/components/picker-column.d.ts +11 -0
  228. package/dist/lib/components/picker-column.js +2 -0
  229. package/dist/lib/components/picker.cjs +1 -0
  230. package/dist/lib/components/picker.d.ts +11 -0
  231. package/dist/lib/components/picker.js +2 -0
  232. package/dist/lib/components/popover.cjs +1 -0
  233. package/dist/lib/components/popover.d.ts +11 -0
  234. package/dist/lib/components/popover.js +2 -0
  235. package/dist/lib/components/progress-bar.cjs +1 -0
  236. package/dist/lib/components/progress-bar.d.ts +11 -0
  237. package/dist/lib/components/progress-bar.js +2 -0
  238. package/dist/lib/components/radio-group.cjs +1 -0
  239. package/dist/lib/components/radio-group.d.ts +11 -0
  240. package/dist/lib/components/radio-group.js +2 -0
  241. package/dist/lib/components/radio.cjs +1 -0
  242. package/dist/lib/components/radio.d.ts +11 -0
  243. package/dist/lib/components/radio.js +2 -0
  244. package/dist/lib/components/range.cjs +1 -0
  245. package/dist/lib/components/range.d.ts +11 -0
  246. package/dist/lib/components/range.js +2 -0
  247. package/dist/lib/components/refresher-content.cjs +1 -0
  248. package/dist/lib/components/refresher-content.d.ts +11 -0
  249. package/dist/lib/components/refresher-content.js +2 -0
  250. package/dist/lib/components/refresher.cjs +1 -0
  251. package/dist/lib/components/refresher.d.ts +11 -0
  252. package/dist/lib/components/refresher.js +2 -0
  253. package/dist/lib/components/reorder-group.cjs +1 -0
  254. package/dist/lib/components/reorder-group.d.ts +11 -0
  255. package/dist/lib/components/reorder-group.js +2 -0
  256. package/dist/lib/components/reorder.cjs +1 -0
  257. package/dist/lib/components/reorder.d.ts +11 -0
  258. package/dist/lib/components/reorder.js +2 -0
  259. package/dist/lib/components/ripple-effect.cjs +1 -0
  260. package/dist/lib/components/ripple-effect.d.ts +11 -0
  261. package/dist/lib/components/ripple-effect.js +2 -0
  262. package/dist/lib/components/router-link.cjs +1 -0
  263. package/dist/lib/components/router-link.d.ts +11 -0
  264. package/dist/lib/components/router-link.js +2 -0
  265. package/dist/lib/components/row.cjs +1 -0
  266. package/dist/lib/components/row.d.ts +11 -0
  267. package/dist/lib/components/row.js +2 -0
  268. package/dist/lib/components/searchbar.cjs +1 -0
  269. package/dist/lib/components/searchbar.d.ts +11 -0
  270. package/dist/lib/components/searchbar.js +2 -0
  271. package/dist/lib/components/segment-button.cjs +1 -0
  272. package/dist/lib/components/segment-button.d.ts +11 -0
  273. package/dist/lib/components/segment-button.js +2 -0
  274. package/dist/lib/components/segment-content.cjs +1 -0
  275. package/dist/lib/components/segment-content.d.ts +11 -0
  276. package/dist/lib/components/segment-content.js +2 -0
  277. package/dist/lib/components/segment-view.cjs +1 -0
  278. package/dist/lib/components/segment-view.d.ts +11 -0
  279. package/dist/lib/components/segment-view.js +2 -0
  280. package/dist/lib/components/segment.cjs +1 -0
  281. package/dist/lib/components/segment.d.ts +11 -0
  282. package/dist/lib/components/segment.js +2 -0
  283. package/dist/lib/components/select-modal.cjs +1 -0
  284. package/dist/lib/components/select-modal.d.ts +11 -0
  285. package/dist/lib/components/select-modal.js +2 -0
  286. package/dist/lib/components/select-option.cjs +1 -0
  287. package/dist/lib/components/select-option.d.ts +11 -0
  288. package/dist/lib/components/select-option.js +2 -0
  289. package/dist/lib/components/select-popover.cjs +1 -0
  290. package/dist/lib/components/select-popover.d.ts +11 -0
  291. package/dist/lib/components/select-popover.js +2 -0
  292. package/dist/lib/components/select.cjs +1 -0
  293. package/dist/lib/components/select.d.ts +11 -0
  294. package/dist/lib/components/select.js +2 -0
  295. package/dist/lib/components/skeleton-text.cjs +1 -0
  296. package/dist/lib/components/skeleton-text.d.ts +11 -0
  297. package/dist/lib/components/skeleton-text.js +2 -0
  298. package/dist/lib/components/spinner.cjs +1 -0
  299. package/dist/lib/components/spinner.d.ts +11 -0
  300. package/dist/lib/components/spinner.js +2 -0
  301. package/dist/lib/components/split-pane.cjs +1 -0
  302. package/dist/lib/components/split-pane.d.ts +11 -0
  303. package/dist/lib/components/split-pane.js +2 -0
  304. package/dist/lib/components/tab-bar.cjs +1 -0
  305. package/dist/lib/components/tab-bar.d.ts +11 -0
  306. package/dist/lib/components/tab-bar.js +2 -0
  307. package/dist/lib/components/tab-button.cjs +1 -0
  308. package/dist/lib/components/tab-button.d.ts +11 -0
  309. package/dist/lib/components/tab-button.js +2 -0
  310. package/dist/lib/components/tab.cjs +1 -0
  311. package/dist/lib/components/tab.d.ts +11 -0
  312. package/dist/lib/components/tab.js +2 -0
  313. package/dist/lib/components/tabs.cjs +1 -0
  314. package/dist/lib/components/tabs.d.ts +11 -0
  315. package/dist/lib/components/tabs.js +2 -0
  316. package/dist/lib/components/text.cjs +1 -0
  317. package/dist/lib/components/text.d.ts +11 -0
  318. package/dist/lib/components/text.js +2 -0
  319. package/dist/lib/components/textarea.cjs +1 -0
  320. package/dist/lib/components/textarea.d.ts +11 -0
  321. package/dist/lib/components/textarea.js +2 -0
  322. package/dist/lib/components/thumbnail.cjs +1 -0
  323. package/dist/lib/components/thumbnail.d.ts +11 -0
  324. package/dist/lib/components/thumbnail.js +2 -0
  325. package/dist/lib/components/title.cjs +1 -0
  326. package/dist/lib/components/title.d.ts +11 -0
  327. package/dist/lib/components/title.js +2 -0
  328. package/dist/lib/components/toast.cjs +1 -0
  329. package/dist/lib/components/toast.d.ts +11 -0
  330. package/dist/lib/components/toast.js +2 -0
  331. package/dist/lib/components/toggle.cjs +1 -0
  332. package/dist/lib/components/toggle.d.ts +11 -0
  333. package/dist/lib/components/toggle.js +2 -0
  334. package/dist/lib/components/toolbar.cjs +1 -0
  335. package/dist/lib/components/toolbar.d.ts +11 -0
  336. package/dist/lib/components/toolbar.js +2 -0
  337. package/dist/lib/components.cjs +1 -0
  338. package/dist/lib/components.d.ts +110 -0
  339. package/dist/lib/components.js +94 -0
  340. package/dist/lib/definitions-DZ-6I7Fj.js +282 -0
  341. package/dist/lib/definitions-DZ-6I7Fj.js.map +1 -0
  342. package/dist/lib/definitions-Lm2GaF-Z.cjs +2 -0
  343. package/dist/lib/definitions-Lm2GaF-Z.cjs.map +1 -0
  344. package/dist/lib/elur-ionic.cjs +1 -0
  345. package/dist/lib/elur-ionic.cjs.map +1 -0
  346. package/dist/lib/elur-ionic.js +1 -0
  347. package/dist/lib/elur-ionic.js.map +1 -0
  348. package/dist/lib/index.d.ts +47 -0
  349. package/dist/lib/lifecycle.d.ts +62 -0
  350. package/dist/lib/navigation.cjs +2 -0
  351. package/dist/lib/navigation.cjs.map +1 -0
  352. package/dist/lib/navigation.d.ts +214 -0
  353. package/dist/lib/navigation.js +193 -0
  354. package/dist/lib/navigation.js.map +1 -0
  355. package/dist/lib/overlays.cjs +2 -0
  356. package/dist/lib/overlays.cjs.map +1 -0
  357. package/dist/lib/overlays.d.ts +400 -0
  358. package/dist/lib/overlays.js +161 -0
  359. package/dist/lib/overlays.js.map +1 -0
  360. package/dist/lib/page-state.cjs +2 -0
  361. package/dist/lib/page-state.cjs.map +1 -0
  362. package/dist/lib/page-state.d.ts +160 -0
  363. package/dist/lib/page-state.js +91 -0
  364. package/dist/lib/page-state.js.map +1 -0
  365. package/dist/lib/setup.d.ts +105 -0
  366. package/dist/lib/tabs-ByPLrzax.cjs +50 -0
  367. package/dist/lib/tabs-ByPLrzax.cjs.map +1 -0
  368. package/dist/lib/tabs-DjD1_PTM.js +178 -0
  369. package/dist/lib/tabs-DjD1_PTM.js.map +1 -0
  370. package/dist/lib/tabs.cjs +1 -0
  371. package/dist/lib/tabs.d.ts +83 -0
  372. package/dist/lib/tabs.js +2 -0
  373. package/dist/lib/vite-plugin.cjs +39 -0
  374. package/dist/lib/vite-plugin.cjs.map +1 -0
  375. package/dist/lib/vite-plugin.d.ts +61 -0
  376. package/dist/lib/vite-plugin.js +26703 -0
  377. package/dist/lib/vite-plugin.js.map +1 -0
  378. package/dist/lib/web-C-maW8Tl.cjs +2 -0
  379. package/dist/lib/web-C-maW8Tl.cjs.map +1 -0
  380. package/dist/lib/web-jkqBWgLD.js +56 -0
  381. package/dist/lib/web-jkqBWgLD.js.map +1 -0
  382. package/package.json +204 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * @elurjs/ionic / navigation.ts
3
+ *
4
+ * NavigationManager — a single coordination authority for Ionic navigation.
5
+ *
6
+ * The IonRouterOutlet handles DOM rendering, transitions, and cache. The
7
+ * NavigationManager handles:
8
+ * - Per-tab navigation stacks (extracted from the outlet)
9
+ * - Navigation state tracking (isTransitioning, pending navigation)
10
+ * - Navigation hooks (beforeNav, afterNav, onTabChange)
11
+ * - Programmatic tab switching
12
+ * - Route-pattern-based cache invalidation hooks
13
+ * - Guard coordination (delegated to the core router when auto-bootstrapped)
14
+ *
15
+ * The outlet delegates navigation state to the manager, keeping a clean
16
+ * separation: navigation logic lives here, rendering lives in the outlet.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { NavigationManager } from "@elurjs/ionic";
21
+ *
22
+ * const nav = new NavigationManager({ tabs: ["/home", "/search", "/profile"] });
23
+ *
24
+ * // Navigation hooks
25
+ * nav.beforeNav((path, intent) => {
26
+ * console.log("navigating to", path);
27
+ * // return false to cancel
28
+ * });
29
+ * nav.afterNav((path) => {
30
+ * analytics.track("page_view", { path });
31
+ * });
32
+ * nav.onTabChange((tab) => {
33
+ * console.log("active tab:", tab);
34
+ * });
35
+ *
36
+ * // Programmatic tab switching
37
+ * nav.switchTab("/search");
38
+ *
39
+ * // The outlet uses the manager for stack/state:
40
+ * const outlet = new IonRouterOutlet(routes, { navigation: nav });
41
+ * ```
42
+ */
43
+ import { type Signal, type NavigationIntent, type NavigationDirection } from "@elurjs/core";
44
+ /** A function called before navigation completes. Return false to cancel. */
45
+ export type BeforeNavHook = (path: string, intent: NavigationIntent) => boolean | void | Promise<boolean | void>;
46
+ /** A function called after navigation completes. */
47
+ export type AfterNavHook = (path: string, direction: NavigationDirection) => void;
48
+ /** A function called when the active tab changes. */
49
+ export type TabChangeHook = (tab: string, previousTab: string | null) => void;
50
+ /** Options for NavigationManager construction. */
51
+ export interface NavigationManagerOptions {
52
+ /** Tab prefixes for per-tab stack management. */
53
+ tabs?: string[];
54
+ }
55
+ /**
56
+ * Manages per-tab navigation stacks. Each tab has its own back/forward
57
+ * stack. When the user switches tabs, the stack for the new tab is
58
+ * restored.
59
+ */
60
+ export declare class StackManager {
61
+ private _stacks;
62
+ private _activeTabKey;
63
+ private _tabPrefixes;
64
+ constructor(tabs: string[] | undefined);
65
+ /** Get the tab key for a given path. */
66
+ keyForPath(path: string): string;
67
+ /** Get the active tab key. */
68
+ get activeTabKey(): string;
69
+ /** Get all registered tab prefixes. */
70
+ get tabPrefixes(): readonly string[];
71
+ /** Get the current stack depth for a tab. */
72
+ stackDepth(tabKey?: string): number;
73
+ /** Get the top of the stack for a tab. */
74
+ stackTop(tabKey?: string): string | null;
75
+ /** Get all entries in a tab's stack (copy). */
76
+ stackEntries(tabKey?: string): string[];
77
+ /**
78
+ * Apply a navigation to the stacks. Returns the effective direction.
79
+ * This is the same logic that was in IonRouterOutlet._stacks.apply().
80
+ */
81
+ apply(path: string, intent: NavigationIntent): NavigationDirection;
82
+ /** Reset a specific tab's stack. */
83
+ resetTab(tabKey: string): void;
84
+ /** Clear a specific tab's stack and return the paths that were in it. */
85
+ clearTabStack(tabKey: string): string[];
86
+ /** Reset all stacks. */
87
+ resetAll(): void;
88
+ private _normalize;
89
+ }
90
+ /**
91
+ * Single coordination authority for Ionic navigation.
92
+ *
93
+ * Wraps the per-tab stack manager and adds:
94
+ * - Navigation hooks (beforeNav, afterNav, onTabChange)
95
+ * - Transition state tracking (isTransitioning, pending)
96
+ * - Programmatic tab switching
97
+ * - Route-pattern-based cache invalidation hooks
98
+ */
99
+ export declare class NavigationManager {
100
+ private _stacks;
101
+ private _beforeNavHooks;
102
+ private _afterNavHooks;
103
+ private _tabChangeHooks;
104
+ private _cacheInvalidationHandlers;
105
+ private _isTransitioning;
106
+ private _pendingNav;
107
+ private _lastTabKey;
108
+ /** Reactive signal: true when the active tab has a back stack. */
109
+ readonly canGoBack: Signal<boolean>;
110
+ constructor(options?: NavigationManagerOptions);
111
+ get stacks(): StackManager;
112
+ get activeTab(): string;
113
+ get tabPrefixes(): readonly string[];
114
+ stackDepth(tabKey?: string): number;
115
+ stackTop(tabKey?: string): string | null;
116
+ stackEntries(tabKey?: string): string[];
117
+ get isTransitioning(): boolean;
118
+ get pendingNav(): {
119
+ path: string;
120
+ intent: NavigationIntent;
121
+ } | null;
122
+ /** Called by the outlet when a transition starts. */
123
+ beginTransition(): void;
124
+ /** Called by the outlet when a transition ends. */
125
+ endTransition(): void;
126
+ /** Queue a pending navigation (called by the outlet when already transitioning). */
127
+ setPendingNav(path: string, intent: NavigationIntent): void;
128
+ /** Clear pending navigation. */
129
+ clearPendingNav(): void;
130
+ /** Consume and return the pending navigation, if any. */
131
+ consumePendingNav(): {
132
+ path: string;
133
+ intent: NavigationIntent;
134
+ } | null;
135
+ /**
136
+ * Register a hook called before navigation completes.
137
+ * Return `false` to cancel the navigation.
138
+ * Multiple hooks are called in registration order.
139
+ */
140
+ beforeNav(hook: BeforeNavHook): () => void;
141
+ /**
142
+ * Register a hook called after navigation completes.
143
+ */
144
+ afterNav(hook: AfterNavHook): () => void;
145
+ /**
146
+ * Register a hook called when the active tab changes.
147
+ */
148
+ onTabChange(hook: TabChangeHook): () => void;
149
+ /**
150
+ * Run beforeNav hooks. Returns true if all hooks allow navigation,
151
+ * false if any hook cancelled.
152
+ */
153
+ runBeforeNav(path: string, intent: NavigationIntent): Promise<boolean>;
154
+ /**
155
+ * Run afterNav hooks. Called by the outlet after a transition completes.
156
+ */
157
+ runAfterNav(path: string, direction: NavigationDirection): void;
158
+ /**
159
+ * Run tab change hooks if the tab actually changed.
160
+ */
161
+ runTabChangeIfNeeded(currentPath: string): void;
162
+ /**
163
+ * Update the reactive `canGoBack` signal based on the active tab's
164
+ * stack depth. Called by the outlet after each transition.
165
+ */
166
+ updateCanGoBack(): void;
167
+ /**
168
+ * Switch to a specific tab. Navigates to the tab's current stack top,
169
+ * or the tab prefix if the stack is empty.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * nav.switchTab("/search"); // switches to the search tab
174
+ * ```
175
+ */
176
+ switchTab(tabPrefix: string): string | null;
177
+ /**
178
+ * Register a cache invalidation handler for a route pattern.
179
+ * The outlet registers handlers for each route on construction.
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * nav.registerInvalidationHandler("/user/:id", (params) => {
184
+ * // called when invalidateRoute("/user/:id", { id: "42" }) is invoked
185
+ * });
186
+ * ```
187
+ */
188
+ registerInvalidationHandler(routePattern: string, handler: (params?: Record<string, string>) => void): () => void;
189
+ /**
190
+ * Invalidate cached pages for a specific route pattern + params.
191
+ * If the route has dynamic segments, provide params to target a
192
+ * specific instance. Omit params to invalidate all instances.
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * nav.invalidateRoute("/user/:id", { id: "42" }); // invalidate user 42
197
+ * nav.invalidateRoute("/search"); // invalidate all search instances
198
+ * ```
199
+ */
200
+ invalidateRoute(routePattern: string, params?: Record<string, string>): void;
201
+ /**
202
+ * Invalidate all cached pages matching a glob pattern.
203
+ * Supports `*` as a wildcard suffix.
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * nav.invalidatePattern("/admin/*"); // invalidate all admin pages
208
+ * nav.invalidatePattern("/*"); // invalidate everything
209
+ * ```
210
+ */
211
+ invalidatePattern(pattern: string): void;
212
+ /** Reset all navigation state (stacks, hooks, pending). */
213
+ dispose(): void;
214
+ }
@@ -0,0 +1,193 @@
1
+ import { signal as e } from "@elurjs/core";
2
+ //#region src/navigation.ts
3
+ var t = class {
4
+ _stacks = /* @__PURE__ */ new Map();
5
+ _activeTabKey;
6
+ _tabPrefixes;
7
+ constructor(e) {
8
+ if (this._stacks.set("", {
9
+ prefix: "",
10
+ entries: []
11
+ }), e?.length) {
12
+ for (let t of e) {
13
+ let e = this._normalize(t);
14
+ this._stacks.set(e, {
15
+ prefix: e,
16
+ entries: []
17
+ });
18
+ }
19
+ this._tabPrefixes = e.map((e) => this._normalize(e)).sort((e, t) => t.length - e.length);
20
+ } else this._tabPrefixes = [];
21
+ this._activeTabKey = "";
22
+ }
23
+ keyForPath(e) {
24
+ for (let t of this._tabPrefixes) if (e === t || e.startsWith(t + "/")) return t;
25
+ return "";
26
+ }
27
+ get activeTabKey() {
28
+ return this._activeTabKey;
29
+ }
30
+ get tabPrefixes() {
31
+ return this._tabPrefixes;
32
+ }
33
+ stackDepth(e) {
34
+ let t = e ?? this._activeTabKey;
35
+ return this._stacks.get(t)?.entries.length ?? 0;
36
+ }
37
+ stackTop(e) {
38
+ let t = e ?? this._activeTabKey, n = this._stacks.get(t);
39
+ return !n || n.entries.length === 0 ? null : n.entries[n.entries.length - 1];
40
+ }
41
+ stackEntries(e) {
42
+ let t = e ?? this._activeTabKey;
43
+ return [...this._stacks.get(t)?.entries ?? []];
44
+ }
45
+ apply(e, t) {
46
+ let n = this.keyForPath(e), r = this._stacks.get(n);
47
+ if (n !== this._activeTabKey) return this._activeTabKey = n, r.entries[r.entries.length - 1] !== e && r.entries.push(e), "none";
48
+ if (t.direction === "back") {
49
+ for (; r.entries.length > 0 && r.entries[r.entries.length - 1] !== e;) r.entries.pop();
50
+ return r.entries.length === 0 && r.entries.push(e), "back";
51
+ }
52
+ return t.action === "replace" || t.direction === "root" ? (r.entries.length === 0 ? r.entries.push(e) : r.entries[r.entries.length - 1] = e, t.direction === "forward" ? "forward" : "root") : t.action === "initial" ? (r.entries.length === 0 && r.entries.push(e), "none") : (r.entries[r.entries.length - 1] !== e && r.entries.push(e), t.direction);
53
+ }
54
+ resetTab(e) {
55
+ let t = this._stacks.get(e);
56
+ t && (t.entries = []);
57
+ }
58
+ clearTabStack(e) {
59
+ let t = this._stacks.get(e);
60
+ if (!t) return [];
61
+ let n = [...t.entries];
62
+ return t.entries = [], n;
63
+ }
64
+ resetAll() {
65
+ for (let e of this._stacks.values()) e.entries = [];
66
+ this._activeTabKey = "";
67
+ }
68
+ _normalize(e) {
69
+ return !e || e === "/" ? "/" : e.endsWith("/") ? e.slice(0, -1) : e;
70
+ }
71
+ }, n = class {
72
+ _stacks;
73
+ _beforeNavHooks = [];
74
+ _afterNavHooks = [];
75
+ _tabChangeHooks = [];
76
+ _cacheInvalidationHandlers = /* @__PURE__ */ new Map();
77
+ _isTransitioning = !1;
78
+ _pendingNav = null;
79
+ _lastTabKey = null;
80
+ canGoBack;
81
+ constructor(n = {}) {
82
+ this._stacks = new t(n.tabs), this.canGoBack = e(!1);
83
+ }
84
+ get stacks() {
85
+ return this._stacks;
86
+ }
87
+ get activeTab() {
88
+ return this._stacks.activeTabKey;
89
+ }
90
+ get tabPrefixes() {
91
+ return this._stacks.tabPrefixes;
92
+ }
93
+ stackDepth(e) {
94
+ return this._stacks.stackDepth(e);
95
+ }
96
+ stackTop(e) {
97
+ return this._stacks.stackTop(e);
98
+ }
99
+ stackEntries(e) {
100
+ return this._stacks.stackEntries(e);
101
+ }
102
+ get isTransitioning() {
103
+ return this._isTransitioning;
104
+ }
105
+ get pendingNav() {
106
+ return this._pendingNav;
107
+ }
108
+ beginTransition() {
109
+ this._isTransitioning = !0;
110
+ }
111
+ endTransition() {
112
+ this._isTransitioning = !1;
113
+ }
114
+ setPendingNav(e, t) {
115
+ this._pendingNav = {
116
+ path: e,
117
+ intent: t
118
+ };
119
+ }
120
+ clearPendingNav() {
121
+ this._pendingNav = null;
122
+ }
123
+ consumePendingNav() {
124
+ let e = this._pendingNav;
125
+ return this._pendingNav = null, e;
126
+ }
127
+ beforeNav(e) {
128
+ return this._beforeNavHooks.push(e), () => {
129
+ let t = this._beforeNavHooks.indexOf(e);
130
+ t >= 0 && this._beforeNavHooks.splice(t, 1);
131
+ };
132
+ }
133
+ afterNav(e) {
134
+ return this._afterNavHooks.push(e), () => {
135
+ let t = this._afterNavHooks.indexOf(e);
136
+ t >= 0 && this._afterNavHooks.splice(t, 1);
137
+ };
138
+ }
139
+ onTabChange(e) {
140
+ return this._tabChangeHooks.push(e), () => {
141
+ let t = this._tabChangeHooks.indexOf(e);
142
+ t >= 0 && this._tabChangeHooks.splice(t, 1);
143
+ };
144
+ }
145
+ async runBeforeNav(e, t) {
146
+ for (let n of this._beforeNavHooks) try {
147
+ if (await n(e, t) === !1) return !1;
148
+ } catch {}
149
+ return !0;
150
+ }
151
+ runAfterNav(e, t) {
152
+ for (let n of this._afterNavHooks) try {
153
+ n(e, t);
154
+ } catch {}
155
+ }
156
+ runTabChangeIfNeeded(e) {
157
+ let t = this._stacks.keyForPath(e);
158
+ if (t !== this._lastTabKey) {
159
+ let e = this._lastTabKey;
160
+ this._lastTabKey = t;
161
+ for (let n of this._tabChangeHooks) try {
162
+ n(t, e);
163
+ } catch {}
164
+ }
165
+ }
166
+ updateCanGoBack() {
167
+ this.canGoBack.value = this._stacks.stackDepth() > 1;
168
+ }
169
+ switchTab(e) {
170
+ let t = this._stacks.keyForPath(e);
171
+ return t === this._stacks.activeTabKey ? null : this._stacks.stackTop(t) ?? e;
172
+ }
173
+ registerInvalidationHandler(e, t) {
174
+ return this._cacheInvalidationHandlers.set(e, t), () => {
175
+ this._cacheInvalidationHandlers.delete(e);
176
+ };
177
+ }
178
+ invalidateRoute(e, t) {
179
+ let n = this._cacheInvalidationHandlers.get(e);
180
+ n && n(t);
181
+ }
182
+ invalidatePattern(e) {
183
+ let t = e.endsWith("/*"), n = t ? e.slice(0, -2) : e;
184
+ for (let r of this._cacheInvalidationHandlers.keys()) t ? (r === n || r.startsWith(n + "/") || r.startsWith(n + ":")) && this._cacheInvalidationHandlers.get(r)?.() : r === e && this._cacheInvalidationHandlers.get(r)?.();
185
+ }
186
+ dispose() {
187
+ this._stacks.resetAll(), this._beforeNavHooks = [], this._afterNavHooks = [], this._tabChangeHooks = [], this._cacheInvalidationHandlers.clear(), this._pendingNav = null, this._isTransitioning = !1, this._lastTabKey = null;
188
+ }
189
+ };
190
+ //#endregion
191
+ export { n as NavigationManager, t as StackManager };
192
+
193
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","names":[],"sources":["../../src/navigation.ts"],"sourcesContent":["/**\n * @elurjs/ionic / navigation.ts\n *\n * NavigationManager — a single coordination authority for Ionic navigation.\n *\n * The IonRouterOutlet handles DOM rendering, transitions, and cache. The\n * NavigationManager handles:\n * - Per-tab navigation stacks (extracted from the outlet)\n * - Navigation state tracking (isTransitioning, pending navigation)\n * - Navigation hooks (beforeNav, afterNav, onTabChange)\n * - Programmatic tab switching\n * - Route-pattern-based cache invalidation hooks\n * - Guard coordination (delegated to the core router when auto-bootstrapped)\n *\n * The outlet delegates navigation state to the manager, keeping a clean\n * separation: navigation logic lives here, rendering lives in the outlet.\n *\n * @example\n * ```ts\n * import { NavigationManager } from \"@elurjs/ionic\";\n *\n * const nav = new NavigationManager({ tabs: [\"/home\", \"/search\", \"/profile\"] });\n *\n * // Navigation hooks\n * nav.beforeNav((path, intent) => {\n * console.log(\"navigating to\", path);\n * // return false to cancel\n * });\n * nav.afterNav((path) => {\n * analytics.track(\"page_view\", { path });\n * });\n * nav.onTabChange((tab) => {\n * console.log(\"active tab:\", tab);\n * });\n *\n * // Programmatic tab switching\n * nav.switchTab(\"/search\");\n *\n * // The outlet uses the manager for stack/state:\n * const outlet = new IonRouterOutlet(routes, { navigation: nav });\n * ```\n */\n\nimport { signal, type Signal, type NavigationIntent, type NavigationDirection } from \"@elurjs/core\";\n\n// --- Types ---\n\n/** A function called before navigation completes. Return false to cancel. */\nexport type BeforeNavHook = (\n path: string,\n intent: NavigationIntent,\n) => boolean | void | Promise<boolean | void>;\n\n/** A function called after navigation completes. */\nexport type AfterNavHook = (\n path: string,\n direction: NavigationDirection,\n) => void;\n\n/** A function called when the active tab changes. */\nexport type TabChangeHook = (\n tab: string,\n previousTab: string | null,\n) => void;\n\n/** Options for NavigationManager construction. */\nexport interface NavigationManagerOptions {\n /** Tab prefixes for per-tab stack management. */\n tabs?: string[];\n}\n\n// --- Per-tab stack management (extracted from IonRouterOutlet) ---\n\ninterface TabStack {\n prefix: string;\n entries: string[];\n}\n\n/**\n * Manages per-tab navigation stacks. Each tab has its own back/forward\n * stack. When the user switches tabs, the stack for the new tab is\n * restored.\n */\nexport class StackManager {\n private _stacks = new Map<string, TabStack>();\n private _activeTabKey: string;\n private _tabPrefixes: string[];\n\n constructor(tabs: string[] | undefined) {\n this._stacks.set(\"\", { prefix: \"\", entries: [] });\n if (tabs?.length) {\n for (const prefix of tabs) {\n const norm = this._normalize(prefix);\n this._stacks.set(norm, { prefix: norm, entries: [] });\n }\n this._tabPrefixes = tabs.map((t) => this._normalize(t))\n .sort((a, b) => b.length - a.length);\n } else {\n this._tabPrefixes = [];\n }\n this._activeTabKey = \"\";\n }\n\n /** Get the tab key for a given path. */\n keyForPath(path: string): string {\n for (const prefix of this._tabPrefixes) {\n if (path === prefix || path.startsWith(prefix + \"/\")) {\n return prefix;\n }\n }\n return \"\";\n }\n\n /** Get the active tab key. */\n get activeTabKey(): string {\n return this._activeTabKey;\n }\n\n /** Get all registered tab prefixes. */\n get tabPrefixes(): readonly string[] {\n return this._tabPrefixes;\n }\n\n /** Get the current stack depth for a tab. */\n stackDepth(tabKey?: string): number {\n const key = tabKey ?? this._activeTabKey;\n return this._stacks.get(key)?.entries.length ?? 0;\n }\n\n /** Get the top of the stack for a tab. */\n stackTop(tabKey?: string): string | null {\n const key = tabKey ?? this._activeTabKey;\n const stack = this._stacks.get(key);\n if (!stack || stack.entries.length === 0) return null;\n return stack.entries[stack.entries.length - 1];\n }\n\n /** Get all entries in a tab's stack (copy). */\n stackEntries(tabKey?: string): string[] {\n const key = tabKey ?? this._activeTabKey;\n return [...(this._stacks.get(key)?.entries ?? [])];\n }\n\n /**\n * Apply a navigation to the stacks. Returns the effective direction.\n * This is the same logic that was in IonRouterOutlet._stacks.apply().\n */\n apply(path: string, intent: NavigationIntent): NavigationDirection {\n const targetKey = this.keyForPath(path);\n const stack = this._stacks.get(targetKey)!;\n\n if (targetKey !== this._activeTabKey) {\n this._activeTabKey = targetKey;\n const top = stack.entries[stack.entries.length - 1];\n if (top !== path) stack.entries.push(path);\n return \"none\";\n }\n\n if (intent.direction === \"back\") {\n while (stack.entries.length > 0\n && stack.entries[stack.entries.length - 1] !== path) {\n stack.entries.pop();\n }\n if (stack.entries.length === 0) stack.entries.push(path);\n return \"back\";\n }\n\n if (intent.action === \"replace\" || intent.direction === \"root\") {\n if (stack.entries.length === 0) stack.entries.push(path);\n else stack.entries[stack.entries.length - 1] = path;\n return intent.direction === \"forward\" ? \"forward\" : \"root\";\n }\n\n if (intent.action === \"initial\") {\n if (stack.entries.length === 0) stack.entries.push(path);\n return \"none\";\n }\n\n const top = stack.entries[stack.entries.length - 1];\n if (top !== path) stack.entries.push(path);\n return intent.direction;\n }\n\n /** Reset a specific tab's stack. */\n resetTab(tabKey: string): void {\n const stack = this._stacks.get(tabKey);\n if (stack) stack.entries = [];\n }\n\n /** Clear a specific tab's stack and return the paths that were in it. */\n clearTabStack(tabKey: string): string[] {\n const stack = this._stacks.get(tabKey);\n if (!stack) return [];\n const entries = [...stack.entries];\n stack.entries = [];\n return entries;\n }\n\n /** Reset all stacks. */\n resetAll(): void {\n for (const stack of this._stacks.values()) {\n stack.entries = [];\n }\n this._activeTabKey = \"\";\n }\n\n private _normalize(p: string): string {\n if (!p || p === \"/\") return \"/\";\n return p.endsWith(\"/\") ? p.slice(0, -1) : p;\n }\n}\n\n// --- NavigationManager ---\n\n/**\n * Single coordination authority for Ionic navigation.\n *\n * Wraps the per-tab stack manager and adds:\n * - Navigation hooks (beforeNav, afterNav, onTabChange)\n * - Transition state tracking (isTransitioning, pending)\n * - Programmatic tab switching\n * - Route-pattern-based cache invalidation hooks\n */\nexport class NavigationManager {\n private _stacks: StackManager;\n private _beforeNavHooks: BeforeNavHook[] = [];\n private _afterNavHooks: AfterNavHook[] = [];\n private _tabChangeHooks: TabChangeHook[] = [];\n private _cacheInvalidationHandlers = new Map<string, (params?: Record<string, string>) => void>();\n\n private _isTransitioning = false;\n private _pendingNav: { path: string; intent: NavigationIntent } | null = null;\n private _lastTabKey: string | null = null;\n\n /** Reactive signal: true when the active tab has a back stack. */\n readonly canGoBack: Signal<boolean>;\n\n constructor(options: NavigationManagerOptions = {}) {\n this._stacks = new StackManager(options.tabs);\n this.canGoBack = signal(false);\n }\n\n // --- Stack access ---\n\n get stacks(): StackManager {\n return this._stacks;\n }\n\n get activeTab(): string {\n return this._stacks.activeTabKey;\n }\n\n get tabPrefixes(): readonly string[] {\n return this._stacks.tabPrefixes;\n }\n\n stackDepth(tabKey?: string): number {\n return this._stacks.stackDepth(tabKey);\n }\n\n stackTop(tabKey?: string): string | null {\n return this._stacks.stackTop(tabKey);\n }\n\n stackEntries(tabKey?: string): string[] {\n return this._stacks.stackEntries(tabKey);\n }\n\n // --- Transition state ---\n\n get isTransitioning(): boolean {\n return this._isTransitioning;\n }\n\n get pendingNav(): { path: string; intent: NavigationIntent } | null {\n return this._pendingNav;\n }\n\n /** Called by the outlet when a transition starts. */\n beginTransition(): void {\n this._isTransitioning = true;\n }\n\n /** Called by the outlet when a transition ends. */\n endTransition(): void {\n this._isTransitioning = false;\n }\n\n /** Queue a pending navigation (called by the outlet when already transitioning). */\n setPendingNav(path: string, intent: NavigationIntent): void {\n this._pendingNav = { path, intent };\n }\n\n /** Clear pending navigation. */\n clearPendingNav(): void {\n this._pendingNav = null;\n }\n\n /** Consume and return the pending navigation, if any. */\n consumePendingNav(): { path: string; intent: NavigationIntent } | null {\n const pending = this._pendingNav;\n this._pendingNav = null;\n return pending;\n }\n\n // --- Navigation hooks ---\n\n /**\n * Register a hook called before navigation completes.\n * Return `false` to cancel the navigation.\n * Multiple hooks are called in registration order.\n */\n beforeNav(hook: BeforeNavHook): () => void {\n this._beforeNavHooks.push(hook);\n return () => {\n const i = this._beforeNavHooks.indexOf(hook);\n if (i >= 0) this._beforeNavHooks.splice(i, 1);\n };\n }\n\n /**\n * Register a hook called after navigation completes.\n */\n afterNav(hook: AfterNavHook): () => void {\n this._afterNavHooks.push(hook);\n return () => {\n const i = this._afterNavHooks.indexOf(hook);\n if (i >= 0) this._afterNavHooks.splice(i, 1);\n };\n }\n\n /**\n * Register a hook called when the active tab changes.\n */\n onTabChange(hook: TabChangeHook): () => void {\n this._tabChangeHooks.push(hook);\n return () => {\n const i = this._tabChangeHooks.indexOf(hook);\n if (i >= 0) this._tabChangeHooks.splice(i, 1);\n };\n }\n\n /**\n * Run beforeNav hooks. Returns true if all hooks allow navigation,\n * false if any hook cancelled.\n */\n async runBeforeNav(path: string, intent: NavigationIntent): Promise<boolean> {\n for (const hook of this._beforeNavHooks) {\n try {\n const result = await hook(path, intent);\n if (result === false) return false;\n } catch {\n // Hook error — don't block navigation\n }\n }\n return true;\n }\n\n /**\n * Run afterNav hooks. Called by the outlet after a transition completes.\n */\n runAfterNav(path: string, direction: NavigationDirection): void {\n for (const hook of this._afterNavHooks) {\n try {\n hook(path, direction);\n } catch { /* ignore */ }\n }\n }\n\n /**\n * Run tab change hooks if the tab actually changed.\n */\n runTabChangeIfNeeded(currentPath: string): void {\n const newTab = this._stacks.keyForPath(currentPath);\n if (newTab !== this._lastTabKey) {\n const prev = this._lastTabKey;\n this._lastTabKey = newTab;\n for (const hook of this._tabChangeHooks) {\n try {\n hook(newTab, prev);\n } catch { /* ignore */ }\n }\n }\n }\n\n /**\n * Update the reactive `canGoBack` signal based on the active tab's\n * stack depth. Called by the outlet after each transition.\n */\n updateCanGoBack(): void {\n this.canGoBack.value = this._stacks.stackDepth() > 1;\n }\n\n // --- Programmatic tab switching ---\n\n /**\n * Switch to a specific tab. Navigates to the tab's current stack top,\n * or the tab prefix if the stack is empty.\n *\n * @example\n * ```ts\n * nav.switchTab(\"/search\"); // switches to the search tab\n * ```\n */\n switchTab(tabPrefix: string): string | null {\n const normalized = this._stacks.keyForPath(tabPrefix);\n if (normalized === this._stacks.activeTabKey) return null;\n const top = this._stacks.stackTop(normalized);\n return top ?? tabPrefix;\n }\n\n // --- Cache invalidation by route pattern ---\n\n /**\n * Register a cache invalidation handler for a route pattern.\n * The outlet registers handlers for each route on construction.\n *\n * @example\n * ```ts\n * nav.registerInvalidationHandler(\"/user/:id\", (params) => {\n * // called when invalidateRoute(\"/user/:id\", { id: \"42\" }) is invoked\n * });\n * ```\n */\n registerInvalidationHandler(\n routePattern: string,\n handler: (params?: Record<string, string>) => void,\n ): () => void {\n this._cacheInvalidationHandlers.set(routePattern, handler);\n return () => {\n this._cacheInvalidationHandlers.delete(routePattern);\n };\n }\n\n /**\n * Invalidate cached pages for a specific route pattern + params.\n * If the route has dynamic segments, provide params to target a\n * specific instance. Omit params to invalidate all instances.\n *\n * @example\n * ```ts\n * nav.invalidateRoute(\"/user/:id\", { id: \"42\" }); // invalidate user 42\n * nav.invalidateRoute(\"/search\"); // invalidate all search instances\n * ```\n */\n invalidateRoute(\n routePattern: string,\n params?: Record<string, string>,\n ): void {\n const handler = this._cacheInvalidationHandlers.get(routePattern);\n if (handler) handler(params);\n }\n\n /**\n * Invalidate all cached pages matching a glob pattern.\n * Supports `*` as a wildcard suffix.\n *\n * @example\n * ```ts\n * nav.invalidatePattern(\"/admin/*\"); // invalidate all admin pages\n * nav.invalidatePattern(\"/*\"); // invalidate everything\n * ```\n */\n invalidatePattern(pattern: string): void {\n const isWildcard = pattern.endsWith(\"/*\");\n const prefix = isWildcard ? pattern.slice(0, -2) : pattern;\n\n for (const routePattern of this._cacheInvalidationHandlers.keys()) {\n if (isWildcard) {\n if (routePattern === prefix || routePattern.startsWith(prefix + \"/\") ||\n routePattern.startsWith(prefix + \":\")) {\n this._cacheInvalidationHandlers.get(routePattern)?.();\n }\n } else if (routePattern === pattern) {\n this._cacheInvalidationHandlers.get(routePattern)?.();\n }\n }\n }\n\n // --- Cleanup ---\n\n /** Reset all navigation state (stacks, hooks, pending). */\n dispose(): void {\n this._stacks.resetAll();\n this._beforeNavHooks = [];\n this._afterNavHooks = [];\n this._tabChangeHooks = [];\n this._cacheInvalidationHandlers.clear();\n this._pendingNav = null;\n this._isTransitioning = false;\n this._lastTabKey = null;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require("./vite-plugin.cjs");let e=require("@elurjs/core"),t=require("@ionic/core");var n=null,r={async attachViewToDom(t,r,i,a){if(typeof r==`function`){let i=r();return n=(0,e.mount)(i,t),t}if(typeof r==`string`){let e=document.createElement(r);return a&&a.forEach(t=>e.classList.add(t)),t.appendChild(e),e}return r instanceof HTMLElement?(a&&a.forEach(e=>r.classList.add(e)),t.appendChild(r),r):t},async removeViewFromDom(e,t){n&&=(n.unmount(),null)}};function i(t){let n=(0,e.signal)(!1),i=(0,e.signal)(null),a=null,o=!1;async function s(e){if(o)return;if(a)try{await a.el.dismiss()}catch{}let s=(a?.token??0)+1,c={...e};typeof c.component==`function`&&!c.delegate&&(c.delegate=r);let l=await t.create(c);await l.present(),a={el:l,dismissPromise:l.onDidDismiss?.()??Promise.resolve(null),token:s},n.value=!0,a.dismissPromise.then(e=>{a?.token===s&&!o&&(i.value=e,n.value=!1,a=null)}).catch(()=>{a?.token===s&&!o&&(n.value=!1,a=null)})}async function c(e,t){if(!a||o)return!1;try{return await a.el.dismiss(e,t)}catch{return!1}}function l(){if(!o){if(o=!0,a){try{a.el.dismiss()}catch{}a=null}n.value=!1}}return{presented:n,result:i,present:s,dismiss:c,dispose:l}}function a(){return i(t.toastController)}function o(){return i(t.alertController)}function s(){return i(t.loadingController)}function c(){return i(t.actionSheetController)}function l(){return i(t.popoverController)}function u(){return i(t.modalController)}async function d(e){await(await t.toastController.create(e)).present()}async function f(e,n){let r=await t.loadingController.create(e);await r.present();try{return await n()}finally{await r.dismiss()}}async function p(e){return new Promise(n=>{t.alertController.create({header:e.header,message:e.message,buttons:[{text:e.cancelText??`Cancel`,role:`cancel`,handler:()=>n(!1)},{text:e.confirmText??`OK`,role:`confirm`,handler:()=>n(!0)}]}).then(e=>e.present())})}function m(){let t=new Map;return{async attachViewToDom(n,r,i,a){let o=document.createElement(`div`);if(a)for(let e of a)o.classList.add(e);let s=(0,e.mount)(r(),o);return t.set(o,s.unmount),n.appendChild(o),o},async removeViewFromDom(e,n){let r=n,i=t.get(r);i&&(i(),t.delete(r)),r.parentElement&&r.remove()}}}function h(e){let n=e??m(),r=i(t.modalController),a=r.present;async function o(e){await a({...e,delegate:n})}return{...r,present:o}}function g(e){let n=e??m(),r=i(t.popoverController),a=r.present;async function o(e){await a({...e,delegate:n})}return{...r,present:o}}function _(){return typeof customElements<`u`&&(customElements.get(`ion-picker-legacy`)||import(`@ionic/core/components/ion-picker-legacy.js`).then(e=>e.defineCustomElement()).catch(()=>{}),customElements.get(`ion-picker-legacy-column`)||import(`@ionic/core/components/ion-picker-legacy-column.js`).then(e=>e.defineCustomElement()).catch(()=>{}),customElements.get(`ion-backdrop`)||import(`@ionic/core/components/ion-backdrop.js`).then(e=>e.defineCustomElement()).catch(()=>{})),i(t.pickerController)}exports.actionSheetController=t.actionSheetController,exports.alertController=t.alertController,exports.confirm=p,exports.createActionSheet=c,exports.createAlert=o,exports.createElurDelegate=m,exports.createLoading=s,exports.createModal=u,exports.createModalController=h,exports.createPicker=_,exports.createPopover=l,exports.createPopoverController=g,exports.createToast=a,exports.loadingController=t.loadingController,exports.modalController=t.modalController,exports.pickerController=t.pickerController,exports.popoverController=t.popoverController,exports.showToast=d,exports.toastController=t.toastController,exports.withLoading=f;
2
+ //# sourceMappingURL=overlays.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlays.cjs","names":[],"sources":["../../src/overlays.ts"],"sourcesContent":["/**\n * @elurjs/ionic / overlays.ts\n *\n * Reactive overlay controllers for Elur following the `create*` pattern\n * (`createStore`, `createRouter`, `createForm` → `createToast`, `createAlert`, etc.).\n *\n * Each controller provides:\n * - `presented: Signal<boolean>` — reactive presentation state\n * - `result: Signal<OverlayEventDetail | null>` — dismiss event detail\n * - `present(opts)` — creates + presents the overlay\n * - `dismiss(data?, role?)` — dismisses the active overlay\n * - `dispose()` — transactional cleanup, dismisses if still presented\n *\n * Stale-result protection: only the most recent `present()` call's dismiss\n * event updates the result signal. Latest-wins: presenting a new overlay\n * dismisses the previous one.\n *\n * @example Function component (preferred)\n * ```ts\n * import { signal, html } from \"@elurjs/core\";\n * import { createToast, createAlert } from \"@elurjs/ionic\";\n *\n * function SettingsPage() {\n * // Create overlay controllers — signals close over function scope\n * const toast = createToast();\n * const alert = createAlert();\n *\n * const save = async () => {\n * // Use withLoading for async tasks\n * const ok = await withLoading({ message: \"Saving...\" }, async () => {\n * await fetch(\"/api/settings\", { method: \"POST\" });\n * });\n * toast.present({ message: \"Saved!\", duration: 1500 });\n * };\n *\n * const deleteAccount = () => {\n * // confirm() returns a Promise<boolean>\n * confirm({\n * header: \"Delete account\",\n * message: \"This cannot be undone.\",\n * confirmText: \"Delete\",\n * }).then((yes) => {\n * if (yes) alert.present({ header: \"Done\", message: \"Account deleted\" });\n * });\n * };\n *\n * return html`\n * <ion-content>\n * <ion-button @click=${save}>Save</ion-button>\n * <ion-button color=\"danger\" @click=${deleteAccount}>Delete</ion-button>\n * </ion-content>\n * `;\n * }\n * ```\n *\n * @example Class component with lifecycle cleanup\n * ```ts\n * import { ElurComponent, html, signal } from \"@elurjs/core\";\n * import { createLoading, IonPage } from \"@elurjs/ionic\";\n *\n * class ProfilePage extends IonPage {\n * private loading = createLoading();\n * private data = signal<unknown>(null);\n *\n * override async onMount() {\n * // withLoading auto-dismisses on settle or error\n * const result = await withLoading(\n * { message: \"Loading profile...\" },\n * () => fetch(\"/api/profile\").then(r => r.json()),\n * );\n * this.data.value = result;\n * }\n *\n * override onUnmount() {\n * // Dispose all overlay controllers to prevent leaks\n * this.loading.dispose();\n * }\n *\n * override render() {\n * return html`\n * <ion-content>\n * <p>${() => JSON.stringify(this.data.value)}</p>\n * </ion-content>\n * `;\n * }\n * }\n * ```\n *\n * @example Reactive UI driven by overlay signals\n * ```ts\n * import { signal, html } from \"@elurjs/core\";\n * import { createModal } from \"@elurjs/ionic\";\n *\n * function ProductList() {\n * const modal = createModal();\n * const selected = signal<string | null>(null);\n *\n * const openDetail = (id: string) => {\n * selected.value = id;\n * modal.present({ component: \"product-detail\" });\n * };\n *\n * return html`\n * <ion-content>\n * <ion-list>\n * <ion-button @click=${() => openDetail(\"1\")}>Product 1</ion-button>\n * </ion-list>\n *\n * <!-- Reactively show dismiss result -->\n * ${() => modal.result.value\n * ? html`<p>Modal closed with role: ${modal.result.value.role}</p>`\n * : null}\n *\n * <!-- Reactively disable button while modal is open -->\n * <ion-button\n * disabled=${() => modal.presented.value}\n * @click=${() => openDetail(\"2\")}\n * >Product 2</ion-button>\n * </ion-content>\n * `;\n * }\n * ```\n */\n\nimport { signal, type Signal, mount, type ElurTemplate, type ElurComponent } from \"@elurjs/core\";\nimport {\n toastController,\n alertController,\n loadingController,\n actionSheetController,\n popoverController,\n modalController,\n pickerController,\n} from \"@ionic/core\";\n\n// --- Elur framework delegate for overlays ---\n// Ionic overlays (popover, modal) need a \"framework delegate\" to render\n// content when `component` is not a string tag name or HTMLElement.\n// We provide a delegate that uses Elur `mount()` to render templates.\n\ninterface FrameworkDelegate {\n attachViewToDom: (\n parentElement: HTMLElement,\n userComponent: unknown,\n userComponentProps?: Record<string, unknown>,\n cssClasses?: string[],\n ) => Promise<HTMLElement>;\n removeViewFromDom: (\n parentElement: HTMLElement,\n childElement: HTMLElement,\n ) => Promise<void>;\n}\n\nlet _delegateHandle: { unmount: () => void } | null = null;\n\nconst elurDelegate: FrameworkDelegate = {\n async attachViewToDom(parentElement, userComponent, _props, cssClasses) {\n // If userComponent is a function (ElurTemplate factory), call it and mount\n if (typeof userComponent === \"function\") {\n const template = (userComponent as () => ElurTemplate)();\n const handle = mount(template, parentElement);\n _delegateHandle = handle;\n return parentElement;\n }\n // If userComponent is a string, create the element\n if (typeof userComponent === \"string\") {\n const el = document.createElement(userComponent);\n if (cssClasses) cssClasses.forEach((c) => el.classList.add(c));\n parentElement.appendChild(el);\n return el;\n }\n // If userComponent is an HTMLElement, append it\n if (userComponent instanceof HTMLElement) {\n if (cssClasses) cssClasses.forEach((c) => userComponent.classList.add(c));\n parentElement.appendChild(userComponent);\n return userComponent;\n }\n // Fallback: just return the parent\n return parentElement;\n },\n async removeViewFromDom(_parent, _child) {\n if (_delegateHandle) {\n _delegateHandle.unmount();\n _delegateHandle = null;\n }\n },\n};\n\n// --- Types ---\n\nexport interface OverlayHandle<TDetail = unknown> {\n /** True while the overlay is presented (visible). */\n readonly presented: Signal<boolean>;\n /** The dismiss event detail (role, data) — null until dismissed. */\n readonly result: Signal<TDetail | null>;\n /** Present the overlay with the given options. */\n present(options: Record<string, unknown>): Promise<void>;\n /** Dismiss the active overlay with optional data and role. */\n dismiss(data?: unknown, role?: string): Promise<boolean>;\n /** Cleanup: dismisses any active overlay. Safe to call multiple times. */\n dispose(): void;\n}\n\ninterface ActiveOverlay {\n el: { dismiss: (data?: unknown, role?: string) => Promise<boolean> };\n dismissPromise: Promise<unknown>;\n token: number; // stale-result protection\n}\n\n// --- Internal factory ---\n\nfunction createOverlayHandle<TDetail>(\n controller: {\n create: (opts: Record<string, unknown>) => Promise<any>;\n },\n): OverlayHandle<TDetail> {\n const presented = signal(false);\n const result = signal<TDetail | null>(null);\n let active: ActiveOverlay | null = null;\n let disposed = false;\n\n async function present(options: Record<string, unknown>): Promise<void> {\n if (disposed) return;\n\n // If an overlay is already active, dismiss it first (latest-wins).\n if (active) {\n try {\n await active.el.dismiss();\n } catch { /* ignore */ }\n }\n\n const token = (active?.token ?? 0) + 1;\n\n // If `component` is a function (ElurTemplate factory), inject our\n // framework delegate so Ionic can render Elur templates inside\n // popover/modal overlays.\n const opts = { ...options };\n if (typeof opts.component === \"function\" && !opts.delegate) {\n opts.delegate = elurDelegate;\n }\n\n const el = await controller.create(opts);\n await el.present();\n active = { el, dismissPromise: el.onDidDismiss?.() ?? Promise.resolve(null), token };\n presented.value = true;\n\n // Fire-and-forget the dismiss wait — updates state when the overlay\n // is dismissed by the user or by dismiss(). This avoids blocking the\n // caller; they can use the `presented` and `result` signals to react.\n active.dismissPromise\n .then((detail) => {\n if (active?.token === token && !disposed) {\n result.value = detail as TDetail;\n presented.value = false;\n active = null;\n }\n })\n .catch(() => {\n if (active?.token === token && !disposed) {\n presented.value = false;\n active = null;\n }\n });\n }\n\n async function dismiss(data?: unknown, role?: string): Promise<boolean> {\n if (!active || disposed) return false;\n try {\n return await active.el.dismiss(data, role);\n } catch {\n return false;\n }\n }\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n if (active) {\n try {\n active.el.dismiss();\n } catch { /* ignore */ }\n active = null;\n }\n presented.value = false;\n }\n\n return { presented, result, present, dismiss, dispose };\n}\n\n// --- Public factories (create* pattern) ---\n\n/**\n * Create a reactive toast overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createToast(): OverlayHandle {\n return createOverlayHandle(toastController as any);\n}\n\n/**\n * Create a reactive alert overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createAlert(): OverlayHandle {\n return createOverlayHandle(alertController as any);\n}\n\n/**\n * Create a reactive loading overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createLoading(): OverlayHandle {\n return createOverlayHandle(loadingController as any);\n}\n\n/**\n * Create a reactive action-sheet overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createActionSheet(): OverlayHandle {\n return createOverlayHandle(actionSheetController as any);\n}\n\n/**\n * Create a reactive popover overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createPopover(): OverlayHandle {\n return createOverlayHandle(popoverController as any);\n}\n\n/**\n * Create a reactive modal overlay controller.\n * Call `dispose()` in `onUnmount()` when used in a class component.\n */\nexport function createModal(): OverlayHandle {\n return createOverlayHandle(modalController as any);\n}\n\n// --- Convenience: one-shot helpers (no controller needed) ---\n\n/**\n * Present a toast and return immediately (fire-and-forget).\n * The toast auto-dismisses after its duration.\n *\n * @example\n * ```ts\n * import { showToast } from \"@elurjs/ionic\";\n *\n * showToast({ message: \"Saved!\", duration: 1500 });\n * ```\n */\nexport async function showToast(\n options: Record<string, unknown>,\n): Promise<void> {\n const toast = await toastController.create(options);\n await toast.present();\n}\n\n/**\n * Present a loading overlay, run an async task, then dismiss.\n * Returns the task result. If the task throws, the loading is still dismissed.\n *\n * @example\n * ```ts\n * import { withLoading } from \"@elurjs/ionic\";\n *\n * const data = await withLoading(\n * { message: \"Fetching...\" },\n * () => fetch(\"/api/data\").then(r => r.json()),\n * );\n * ```\n */\nexport async function withLoading<T>(\n options: Record<string, unknown>,\n task: () => Promise<T>,\n): Promise<T> {\n const loading = await loadingController.create(options);\n await loading.present();\n try {\n return await task();\n } finally {\n await loading.dismiss();\n }\n}\n\n/**\n * Present a confirm alert and return true if \"OK\" was clicked, false otherwise.\n *\n * @example\n * ```ts\n * import { confirm } from \"@elurjs/ionic\";\n *\n * const yes = await confirm({\n * header: \"Delete\",\n * message: \"Are you sure?\",\n * confirmText: \"Delete\",\n * });\n * if (yes) deleteItem();\n * ```\n */\nexport async function confirm(\n options: { header?: string; message?: string; confirmText?: string; cancelText?: string },\n): Promise<boolean> {\n return new Promise((resolve) => {\n alertController\n .create({\n header: options.header,\n message: options.message,\n buttons: [\n { text: options.cancelText ?? \"Cancel\", role: \"cancel\", handler: () => resolve(false) },\n { text: options.confirmText ?? \"OK\", role: \"confirm\", handler: () => resolve(true) },\n ],\n } as any)\n .then((el) => el.present());\n });\n}\n\n// Re-export Ionic controllers for advanced use\nexport {\n toastController,\n alertController,\n loadingController,\n actionSheetController,\n popoverController,\n modalController,\n pickerController,\n};\n\n// =============================================================================\n// --- Elur delegate for modal/popover content mounting ---\n// =============================================================================\n\n/**\n * A Elur FrameworkDelegate that can mount ElurTemplate or ElurComponent\n * instances inside Ionic overlays (modal, popover).\n *\n * Ionic's `FrameworkDelegate` interface has two methods:\n * - `attachViewToDom(container, component, props, cssClasses)` → HTMLElement\n * - `removeViewFromDom(container, component)` → void\n *\n * For Elur, \"component\" is a function that returns a ElurTemplate or\n * ElurComponent. The delegate creates a wrapper div, mounts the Elur\n * content into it, appends it to the overlay, and tracks the unmount\n * handle for cleanup on dismiss.\n */\nexport interface ElurOverlayDelegate {\n attachViewToDom(\n container: HTMLElement,\n component: () => ElurTemplate | ElurComponent,\n propsOrData?: Record<string, unknown>,\n cssClasses?: string[],\n ): Promise<HTMLElement>;\n removeViewFromDom(container: HTMLElement, component: unknown): Promise<void>;\n}\n\n/**\n * Create a Elur delegate for use with Ionic modal/popover controllers.\n * The delegate mounts Elur templates inside overlays and cleans up on\n * removal.\n *\n * @example\n * ```ts\n * import { createElurDelegate, createModal } from \"@elurjs/ionic\";\n * import { html, signal } from \"@elurjs/core\";\n *\n * const delegate = createElurDelegate();\n * const modal = createModal();\n *\n * // The delegate is passed via `delegate` option\n * modal.present({\n * component: () => html`<ion-content><h1>Hello from modal!</h1></ion-content>`,\n * delegate,\n * });\n * ```\n */\nexport function createElurDelegate(): ElurOverlayDelegate {\n // Track unmount handles by wrapper element for cleanup\n const handles = new Map<HTMLElement, () => void>();\n\n return {\n async attachViewToDom(\n container: HTMLElement,\n component: () => ElurTemplate | ElurComponent,\n _propsOrData?: Record<string, unknown>,\n cssClasses?: string[],\n ): Promise<HTMLElement> {\n // Create a wrapper div to hold the Elur content\n const wrapper = document.createElement(\"div\");\n if (cssClasses) {\n for (const cls of cssClasses) wrapper.classList.add(cls);\n }\n // Mount the Elur content into the wrapper\n const handle = mount(component(), wrapper);\n handles.set(wrapper, handle.unmount);\n // Append to the overlay container\n container.appendChild(wrapper);\n return wrapper;\n },\n\n async removeViewFromDom(_container: HTMLElement, component: unknown): Promise<void> {\n // component is the wrapper element returned by attachViewToDom\n const wrapper = component as HTMLElement;\n const unmount = handles.get(wrapper);\n if (unmount) {\n unmount();\n handles.delete(wrapper);\n }\n if (wrapper.parentElement) {\n wrapper.remove();\n }\n },\n };\n}\n\n// =============================================================================\n// --- Enhanced modal/popover with delegate support ---\n// =============================================================================\n\n/**\n * Options for presenting a modal with Elur content.\n * The `component` function returns a ElurTemplate or ElurComponent that will\n * be mounted inside the modal via the Elur delegate.\n */\nexport interface ModalOptions {\n /** Function returning the Elur content to mount inside the modal. */\n component: () => ElurTemplate | ElurComponent;\n /** Component props/data passed to the delegate. */\n componentProps?: Record<string, unknown>;\n /** CSS classes to add to the mounted content wrapper. */\n cssClasses?: string[];\n /** Modal-specific options. */\n backdropDismiss?: boolean;\n showBackdrop?: boolean;\n animated?: boolean;\n canDismiss?: boolean | (() => Promise<boolean>);\n /** Custom delegate (if not provided, a default Elur delegate is used). */\n delegate?: ElurOverlayDelegate;\n [key: string]: unknown;\n}\n\n/**\n * Options for presenting a popover with Elur content.\n */\nexport interface PopoverOptions {\n /** Function returning the Elur content to mount inside the popover. */\n component: () => ElurTemplate | ElurComponent;\n /** Component props/data passed to the delegate. */\n componentProps?: Record<string, unknown>;\n /** CSS classes to add to the mounted content wrapper. */\n cssClasses?: string[];\n /** The element that the popover should be anchored to. */\n event?: Event | { target: HTMLElement };\n /** Popover-specific options. */\n backdropDismiss?: boolean;\n showBackdrop?: boolean;\n animated?: boolean;\n /** Custom delegate (if not provided, a default Elur delegate is used). */\n delegate?: ElurOverlayDelegate;\n [key: string]: unknown;\n}\n\n/**\n * Enhanced modal controller with Elur delegate support.\n * Unlike the basic `createModal()`, this automatically creates and uses\n * a Elur delegate so `component` can be a ElurTemplate/ElurComponent.\n *\n * @example\n * ```ts\n * import { createModalController, createElurDelegate } from \"@elurjs/ionic\";\n * import { html, signal } from \"@elurjs/core\";\n *\n * const modal = createModalController();\n *\n * modal.present({\n * component: () => html`\n * <ion-header>\n * <ion-toolbar><ion-title>Settings</ion-title></ion-toolbar>\n * </ion-header>\n * <ion-content><p>Modal content here</p></ion-content>\n * `,\n * });\n *\n * // React to dismiss\n * effect(() => {\n * if (modal.result.value) {\n * console.log(\"Modal dismissed:\", modal.result.value);\n * }\n * });\n * ```\n */\nexport function createModalController(delegate?: ElurOverlayDelegate): OverlayHandle {\n const elurDelegate = delegate ?? createElurDelegate();\n const handle = createOverlayHandle(modalController as any);\n\n // Wrap present to inject the delegate and convert component\n const originalPresent = handle.present;\n async function present(options: ModalOptions): Promise<void> {\n await originalPresent({\n ...options,\n delegate: elurDelegate,\n });\n }\n\n return { ...handle, present };\n}\n\n/**\n * Enhanced popover controller with Elur delegate support.\n * Automatically creates and uses a Elur delegate so `component` can be\n * a ElurTemplate/ElurComponent.\n *\n * @example\n * ```ts\n * import { createPopoverController } from \"@elurjs/ionic\";\n * import { html } from \"@elurjs/core\";\n *\n * const popover = createPopoverController();\n *\n * // In an event handler:\n * popover.present({\n * component: () => html`<ion-content><p>Popover content</p></ion-content>`,\n * event, // the click event for anchoring\n * });\n * ```\n */\nexport function createPopoverController(delegate?: ElurOverlayDelegate): OverlayHandle {\n const elurDelegate = delegate ?? createElurDelegate();\n const handle = createOverlayHandle(popoverController as any);\n\n const originalPresent = handle.present;\n async function present(options: PopoverOptions): Promise<void> {\n await originalPresent({\n ...options,\n delegate: elurDelegate,\n });\n }\n\n return { ...handle, present };\n}\n\n// =============================================================================\n// --- Picker wrapper ---\n// =============================================================================\n\n/**\n * Options for a picker column.\n */\nexport interface PickerColumnOption {\n text: string;\n value: string | number;\n disabled?: boolean;\n}\n\n/**\n * Options for presenting a picker overlay.\n */\nexport interface PickerOptions {\n columns: Array<{\n name: string;\n options: PickerColumnOption[];\n selectedIndex?: number;\n }>;\n buttons?: Array<{\n text: string;\n role?: string;\n handler?: (selected: Record<string, PickerColumnOption>) => void;\n }>;\n cssClass?: string;\n animated?: boolean;\n backdropDismiss?: boolean;\n [key: string]: unknown;\n}\n\n/**\n * Create a reactive picker overlay controller.\n * Pickers are column-based selection overlays (like iOS date pickers).\n *\n * @example\n * ```ts\n * import { createPicker } from \"@elurjs/ionic\";\n *\n * const picker = createPicker();\n * await picker.present({\n * columns: [{\n * name: \"size\",\n * options: [\n * { text: \"Small\", value: \"sm\" },\n * { text: \"Medium\", value: \"md\" },\n * { text: \"Large\", value: \"lg\" },\n * ],\n * }],\n * buttons: [\n * { text: \"Cancel\", role: \"cancel\" },\n * { text: \"Done\", role: \"confirm\" },\n * ],\n * });\n * ```\n */\nexport function createPicker(): OverlayHandle {\n // Ionic 8's ion-picker is a wheel-style component without columns/buttons/isOpen.\n // The legacy picker (with columns, buttons, isOpen) is accessed via pickerController,\n // which creates <ion-picker-legacy> internally. These legacy components must be\n // registered as custom elements, otherwise customElements.whenDefined() hangs\n // forever and the picker never appears.\n //\n // We register them lazily here (not in setup.ts) to preserve tree-shaking —\n // apps that don't use the picker won't bundle the legacy picker code.\n if (typeof customElements !== \"undefined\") {\n if (!customElements.get(\"ion-picker-legacy\")) {\n import(\"@ionic/core/components/ion-picker-legacy.js\")\n .then((m) => m.defineCustomElement())\n .catch(() => { });\n }\n if (!customElements.get(\"ion-picker-legacy-column\")) {\n import(\"@ionic/core/components/ion-picker-legacy-column.js\")\n .then((m) => m.defineCustomElement())\n .catch(() => { });\n }\n if (!customElements.get(\"ion-backdrop\")) {\n import(\"@ionic/core/components/ion-backdrop.js\")\n .then((m) => m.defineCustomElement())\n .catch(() => { });\n }\n }\n return createOverlayHandle(pickerController as any);\n}\n"],"mappings":"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"}