@ionic/core 8.8.9-dev.11780493108.1d8e1a89 → 8.8.9-dev.11780493937.17fe092d

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 (48) hide show
  1. package/components/ion-content.js +1 -1
  2. package/components/ion-footer.js +1 -1
  3. package/components/ion-gallery.js +1 -1
  4. package/components/ion-header.js +1 -1
  5. package/components/ion-select-modal.js +1 -1
  6. package/components/ion-select.js +1 -1
  7. package/components/p-BF5oFX1I.js +4 -0
  8. package/components/p-CpFORZud.js +4 -0
  9. package/components/p-d77Zk1DK.js +4 -0
  10. package/components/p-hdGd8ben.js +4 -0
  11. package/dist/cjs/ion-app_8.cjs.entry.js +286 -28
  12. package/dist/cjs/ion-gallery.cjs.entry.js +7 -26
  13. package/dist/collection/components/content/content.css +56 -0
  14. package/dist/collection/components/footer/footer.ios.css +13 -0
  15. package/dist/collection/components/footer/footer.js +65 -18
  16. package/dist/collection/components/footer/footer.md.css +13 -0
  17. package/dist/collection/components/footer/footer.utils.js +9 -0
  18. package/dist/collection/components/gallery/gallery.js +9 -14
  19. package/dist/collection/components/header/header.ionic.css +75 -0
  20. package/dist/collection/components/header/header.ios.css +75 -0
  21. package/dist/collection/components/header/header.js +41 -11
  22. package/dist/collection/components/header/header.md.css +75 -0
  23. package/dist/collection/components/header/header.utils.js +9 -0
  24. package/dist/collection/utils/css-value-validation.js +0 -14
  25. package/dist/collection/utils/on-scroll/collapse-hide.utils.js +168 -0
  26. package/dist/docs.json +18 -10
  27. package/dist/esm/ion-app_8.entry.js +286 -28
  28. package/dist/esm/ion-gallery.entry.js +7 -26
  29. package/dist/html.html-data.json +9 -3
  30. package/dist/ionic/ionic.esm.js +1 -1
  31. package/dist/ionic/p-04b5794c.entry.js +4 -0
  32. package/dist/ionic/p-ad4d0138.entry.js +4 -0
  33. package/dist/types/components/footer/footer.d.ts +12 -2
  34. package/dist/types/components/footer/footer.utils.d.ts +1 -0
  35. package/dist/types/components/gallery/gallery.d.ts +4 -6
  36. package/dist/types/components/header/header.d.ts +10 -3
  37. package/dist/types/components/header/header.utils.d.ts +1 -0
  38. package/dist/types/components.d.ts +12 -12
  39. package/dist/types/utils/css-value-validation.d.ts +0 -9
  40. package/dist/types/utils/on-scroll/collapse-hide.utils.d.ts +26 -0
  41. package/hydrate/index.js +293 -54
  42. package/hydrate/index.mjs +293 -54
  43. package/package.json +1 -1
  44. package/components/p-7kL3tltU.js +0 -4
  45. package/components/p-BGiYL2RS.js +0 -4
  46. package/components/p-LB-QPk3e.js +0 -4
  47. package/dist/ionic/p-290778c1.entry.js +0 -4
  48. package/dist/ionic/p-70ee89c9.entry.js +0 -4
package/hydrate/index.mjs CHANGED
@@ -13335,7 +13335,7 @@ const isRTL$1 = (hostEl) => {
13335
13335
  return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
13336
13336
  };
13337
13337
 
13338
- const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{right:0px;left:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{right:0px;left:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom) + var(--internal-content-safe-area-padding-bottom, 0px));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}`;
13338
+ const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{right:0px;left:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{right:0px;left:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom) + var(--internal-content-safe-area-padding-bottom, 0px));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}:host(.content-header-hide-scroll-partner:not(.content-footer-hide-scroll-partner)) .inner-scroll{-webkit-transform:translateY(0);transform:translateY(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;height:100%;-webkit-transition:height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), height 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1)}:host(.content-header-hide-scroll-partner:not(.content-footer-hide-scroll-partner).content-header-hide-scroll-hidden) .inner-scroll{-webkit-transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));-webkit-backface-visibility:hidden;backface-visibility:hidden;height:calc(100% + var(--header-hide-slide-y, 0px));-webkit-transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1)}:host(.content-footer-hide-scroll-partner:not(.content-header-hide-scroll-partner)) .inner-scroll{-webkit-transform:translateY(0);transform:translateY(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;height:100%;-webkit-transition:height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), height 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1)}:host(.content-footer-hide-scroll-partner:not(.content-header-hide-scroll-partner).content-footer-hide-scroll-hidden) .inner-scroll{-webkit-transform:translateY(0);transform:translateY(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;height:calc(100% + var(--footer-hide-slide-y, 0px));-webkit-transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1)}:host(.content-header-hide-scroll-partner.content-footer-hide-scroll-partner:not(.content-header-hide-scroll-hidden):not(.content-footer-hide-scroll-hidden)) .inner-scroll{-webkit-transform:translateY(0);transform:translateY(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;height:100%;-webkit-transition:height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), height 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), height 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1)}:host(.content-header-hide-scroll-partner.content-footer-hide-scroll-partner.content-header-hide-scroll-hidden:not(.content-footer-hide-scroll-hidden)) .inner-scroll{-webkit-transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));-webkit-backface-visibility:hidden;backface-visibility:hidden;height:calc(100% + var(--header-hide-slide-y, 0px));-webkit-transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1)}:host(.content-header-hide-scroll-partner.content-footer-hide-scroll-partner:not(.content-header-hide-scroll-hidden).content-footer-hide-scroll-hidden) .inner-scroll{-webkit-transform:translateY(0);transform:translateY(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;height:calc(100% + var(--footer-hide-slide-y, 0px));-webkit-transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1)}:host(.content-header-hide-scroll-partner.content-footer-hide-scroll-partner.content-header-hide-scroll-hidden.content-footer-hide-scroll-hidden) .inner-scroll{-webkit-transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));-webkit-backface-visibility:hidden;backface-visibility:hidden;height:calc(100% + var(--header-hide-slide-y, 0px) + var(--footer-hide-slide-y, 0px));-webkit-transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), height 200ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1)}`;
13339
13339
 
13340
13340
  /**
13341
13341
  * @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
@@ -18585,6 +18585,171 @@ const createKeyboardController = async (keyboardChangeCallback) => {
18585
18585
  return { init, destroy, isKeyboardVisible };
18586
18586
  };
18587
18587
 
18588
+ /** Cumulative downward delta before hiding (header or footer `collapse="hide"`). */
18589
+ const COLLAPSE_HIDE_THRESHOLD_PX = 24;
18590
+ /**
18591
+ * Cumulative upward delta before showing again after hide. Small bias
18592
+ * (instead of "any upward delta") guards against inertial-scroll
18593
+ * oscillation flicking the region back open during a downward gesture.
18594
+ */
18595
+ const COLLAPSE_SHOW_THRESHOLD_PX = 5;
18596
+ const WHEEL_SCROLL_SUPPRESS_MS = 80;
18597
+ const getContentHostFromScrollEl = (scrollEl) => {
18598
+ const root = scrollEl.getRootNode();
18599
+ if (root instanceof ShadowRoot && root.host instanceof HTMLElement) {
18600
+ return root.host;
18601
+ }
18602
+ // Light-DOM fallback: the scroll element may live inside a non-shadow
18603
+ // ion-content (e.g. custom scroll host). Walk up to the nearest ion-content.
18604
+ return scrollEl.closest('ion-content');
18605
+ };
18606
+ const applySlideDistance = (regionEl, contentHost, slideCssVar, heightPx) => {
18607
+ const value = `${Math.max(0, Math.ceil(heightPx))}px`;
18608
+ regionEl.style.setProperty(slideCssVar, value);
18609
+ contentHost === null || contentHost === void 0 ? void 0 : contentHost.style.setProperty(slideCssVar, value);
18610
+ };
18611
+ const clearSlideDistance = (regionEl, contentHost, slideCssVar) => {
18612
+ regionEl.style.removeProperty(slideCssVar);
18613
+ contentHost === null || contentHost === void 0 ? void 0 : contentHost.style.removeProperty(slideCssVar);
18614
+ };
18615
+ /**
18616
+ * Scroll/wheel-driven hide/show for `collapse="hide"` on `ion-header` or `ion-footer`.
18617
+ * Hide after {@link COLLAPSE_HIDE_THRESHOLD_PX}px cumulative downward delta; show after
18618
+ * {@link COLLAPSE_SHOW_THRESHOLD_PX}px cumulative upward delta. Each direction drains
18619
+ * (not resets) the opposing accumulator so inertial-scroll jitter doesn't stall either
18620
+ * transition. Motion is defined in component SCSS and `content.scss`; this toggles
18621
+ * classes and syncs the slide distance CSS var.
18622
+ */
18623
+ const createCollapseHideInteraction = ({ regionEl, scrollEl, slideCssVar, contentPartnerClass, contentHiddenClass, regionHiddenClass, }) => {
18624
+ const contentHost = getContentHostFromScrollEl(scrollEl);
18625
+ if (contentHost !== null) {
18626
+ contentHost.classList.add(contentPartnerClass);
18627
+ }
18628
+ let resizeObserver;
18629
+ let destroyed = false;
18630
+ const syncSlideDistance = () => {
18631
+ readTask(() => {
18632
+ if (destroyed) {
18633
+ return;
18634
+ }
18635
+ const heightPx = regionEl.offsetHeight;
18636
+ writeTask(() => {
18637
+ if (destroyed) {
18638
+ return;
18639
+ }
18640
+ applySlideDistance(regionEl, contentHost, slideCssVar, heightPx);
18641
+ });
18642
+ });
18643
+ };
18644
+ if (typeof ResizeObserver !== 'undefined') {
18645
+ resizeObserver = new ResizeObserver(() => {
18646
+ syncSlideDistance();
18647
+ });
18648
+ resizeObserver.observe(regionEl);
18649
+ }
18650
+ syncSlideDistance();
18651
+ requestAnimationFrame(() => {
18652
+ if (!destroyed) {
18653
+ syncSlideDistance();
18654
+ }
18655
+ });
18656
+ let hidden = false;
18657
+ let accDown = 0;
18658
+ let accUp = 0;
18659
+ let lastScrollTop = scrollEl.scrollTop;
18660
+ let lastWheelTime = 0;
18661
+ const setHidden = (next) => {
18662
+ if (hidden === next || destroyed) {
18663
+ return;
18664
+ }
18665
+ hidden = next;
18666
+ // When transitioning to hidden, re-measure synchronously in case the
18667
+ // initial layout reported offsetHeight === 0 (e.g. mid page transition).
18668
+ // Without this the slide animates by 0px and only opacity fades.
18669
+ if (hidden) {
18670
+ const heightPx = regionEl.offsetHeight;
18671
+ if (heightPx > 0) {
18672
+ applySlideDistance(regionEl, contentHost, slideCssVar, heightPx);
18673
+ }
18674
+ }
18675
+ writeTask(() => {
18676
+ if (destroyed) {
18677
+ return;
18678
+ }
18679
+ regionEl.classList.toggle(regionHiddenClass, hidden);
18680
+ contentHost === null || contentHost === void 0 ? void 0 : contentHost.classList.toggle(contentHiddenClass, hidden);
18681
+ if (hidden) {
18682
+ // `inert` removes the subtree from the tab order and AT, AND moves
18683
+ // focus out automatically in supporting browsers. `aria-hidden` is
18684
+ // kept as a fallback for older engines without `inert` support.
18685
+ regionEl.setAttribute('inert', '');
18686
+ regionEl.setAttribute('aria-hidden', 'true');
18687
+ }
18688
+ else {
18689
+ regionEl.removeAttribute('inert');
18690
+ regionEl.removeAttribute('aria-hidden');
18691
+ }
18692
+ });
18693
+ };
18694
+ // Accumulate cumulative movement in each direction. The OPPOSITE accumulator
18695
+ // is drained (not reset) by each event, so brief inertial jitter does not
18696
+ // wipe a sustained gesture's accumulation. Crossing a threshold resets both.
18697
+ const processDelta = (delta) => {
18698
+ if (delta > 0) {
18699
+ accUp = Math.max(0, accUp - delta);
18700
+ accDown += delta;
18701
+ if (accDown >= COLLAPSE_HIDE_THRESHOLD_PX) {
18702
+ setHidden(true);
18703
+ accDown = 0;
18704
+ accUp = 0;
18705
+ }
18706
+ }
18707
+ else if (delta < 0) {
18708
+ const mag = -delta;
18709
+ accDown = Math.max(0, accDown - mag);
18710
+ accUp += mag;
18711
+ if (accUp >= COLLAPSE_SHOW_THRESHOLD_PX) {
18712
+ setHidden(false);
18713
+ accUp = 0;
18714
+ accDown = 0;
18715
+ }
18716
+ }
18717
+ };
18718
+ const onWheel = (ev) => {
18719
+ if (destroyed) {
18720
+ return;
18721
+ }
18722
+ lastWheelTime = performance.now();
18723
+ processDelta(ev.deltaY);
18724
+ };
18725
+ const onScroll = () => {
18726
+ if (destroyed) {
18727
+ return;
18728
+ }
18729
+ const st = scrollEl.scrollTop;
18730
+ if (performance.now() - lastWheelTime < WHEEL_SCROLL_SUPPRESS_MS) {
18731
+ lastScrollTop = st;
18732
+ return;
18733
+ }
18734
+ const delta = st - lastScrollTop;
18735
+ lastScrollTop = st;
18736
+ processDelta(delta);
18737
+ };
18738
+ scrollEl.addEventListener('wheel', onWheel, { passive: true });
18739
+ scrollEl.addEventListener('scroll', onScroll, { passive: true });
18740
+ return () => {
18741
+ destroyed = true;
18742
+ resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
18743
+ scrollEl.removeEventListener('wheel', onWheel);
18744
+ scrollEl.removeEventListener('scroll', onScroll);
18745
+ regionEl.classList.remove(regionHiddenClass);
18746
+ regionEl.removeAttribute('inert');
18747
+ regionEl.removeAttribute('aria-hidden');
18748
+ contentHost === null || contentHost === void 0 ? void 0 : contentHost.classList.remove(contentPartnerClass, contentHiddenClass);
18749
+ clearSlideDistance(regionEl, contentHost, slideCssVar);
18750
+ };
18751
+ };
18752
+
18588
18753
  const handleFooterFade = (scrollEl, baseEl) => {
18589
18754
  readTask(() => {
18590
18755
  const scrollTop = scrollEl.scrollTop;
@@ -18613,12 +18778,20 @@ const handleFooterFade = (scrollEl, baseEl) => {
18613
18778
  });
18614
18779
  });
18615
18780
  };
18781
+ const createFooterHideInteraction = (footerEl, scrollEl) => createCollapseHideInteraction({
18782
+ regionEl: footerEl,
18783
+ scrollEl,
18784
+ slideCssVar: '--footer-hide-slide-y',
18785
+ contentPartnerClass: 'content-footer-hide-scroll-partner',
18786
+ contentHiddenClass: 'content-footer-hide-scroll-hidden',
18787
+ regionHiddenClass: 'footer-collapse-hide-hidden',
18788
+ });
18616
18789
 
18617
- const ionicFooterMdCss = () => `ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}.footer-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.footer-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}`;
18790
+ const ionicFooterMdCss = () => `ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}ion-footer.footer-collapse-hide{-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);opacity:1}ion-footer.footer-collapse-hide.footer-collapse-hide-hidden{-webkit-transform:translateY(var(--footer-hide-slide-y, 0px));transform:translateY(var(--footer-hide-slide-y, 0px));pointer-events:none;-webkit-transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);opacity:0}.footer-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.footer-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}`;
18618
18791
 
18619
- const footerIosCss = () => `ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}.footer-ios ion-toolbar:first-of-type{--border-width:0.55px 0 0}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.footer-background{right:0;left:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.footer-translucent-ios ion-toolbar{--opacity:0.8}}.footer-ios.ion-no-border ion-toolbar:first-of-type{--border-width:0}.footer-collapse-fade ion-toolbar{--opacity-scale:inherit}`;
18792
+ const footerIosCss = () => `ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}ion-footer.footer-collapse-hide{-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);opacity:1}ion-footer.footer-collapse-hide.footer-collapse-hide-hidden{-webkit-transform:translateY(var(--footer-hide-slide-y, 0px));transform:translateY(var(--footer-hide-slide-y, 0px));pointer-events:none;-webkit-transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);opacity:0}.footer-ios ion-toolbar:first-of-type{--border-width:0.55px 0 0}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.footer-background{right:0;left:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.footer-translucent-ios ion-toolbar{--opacity:0.8}}.footer-ios.ion-no-border ion-toolbar:first-of-type{--border-width:0}.footer-collapse-fade ion-toolbar{--opacity-scale:inherit}`;
18620
18793
 
18621
- const footerMdCss = () => `ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}.footer-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.footer-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}`;
18794
+ const footerMdCss = () => `ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}ion-footer.footer-collapse-hide{-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);opacity:1}ion-footer.footer-collapse-hide.footer-collapse-hide-hidden{-webkit-transform:translateY(var(--footer-hide-slide-y, 0px));transform:translateY(var(--footer-hide-slide-y, 0px));pointer-events:none;-webkit-transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);opacity:0}.footer-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.footer-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}`;
18622
18795
 
18623
18796
  /**
18624
18797
  * @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
@@ -18627,6 +18800,8 @@ const footerMdCss = () => `ion-footer{display:block;position:relative;-ms-flex-o
18627
18800
  class Footer {
18628
18801
  constructor(hostRef) {
18629
18802
  registerInstance(this, hostRef);
18803
+ this.didLoad = false;
18804
+ this.setupToken = 0;
18630
18805
  this.keyboardCtrl = null;
18631
18806
  this.keyboardCtrlPromise = null;
18632
18807
  this.keyboardVisible = false;
@@ -18641,25 +18816,45 @@ class Footer {
18641
18816
  this.translucent = false;
18642
18817
  this.checkCollapsibleFooter = () => {
18643
18818
  const theme = getIonTheme(this);
18644
- if (theme !== 'ios') {
18645
- return;
18646
- }
18647
18819
  const { collapse } = this;
18648
18820
  const hasFade = collapse === 'fade';
18821
+ const hasHide = collapse === 'hide';
18822
+ const runIosFade = theme === 'ios' && hasFade;
18823
+ if (!runIosFade && !hasHide) {
18824
+ this.destroyCollapsibleFooter();
18825
+ return;
18826
+ }
18827
+ // Skip teardown/rebuild when the collapse mode and theme have not changed
18828
+ // since the last setup — avoids thrashing listeners and resetting scroll
18829
+ // accumulators on unrelated re-renders (e.g. keyboardVisible state flips).
18830
+ const activeMode = hasHide ? 'hide' : 'fade';
18831
+ if (this.appliedCollapse === activeMode && this.appliedTheme === theme) {
18832
+ return;
18833
+ }
18649
18834
  this.destroyCollapsibleFooter();
18650
- if (hasFade) {
18651
- const appRootSelector = config.get('appRootSelector', 'ion-app');
18652
- const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
18653
- const contentEl = pageEl ? findIonContent(pageEl) : null;
18654
- if (!contentEl) {
18655
- printIonContentErrorMsg(this.el);
18656
- return;
18657
- }
18835
+ const appRootSelector = config.get('appRootSelector', 'ion-app');
18836
+ const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
18837
+ const contentEl = pageEl ? findIonContent(pageEl) : null;
18838
+ if (!contentEl) {
18839
+ printIonContentErrorMsg(this.el);
18840
+ return;
18841
+ }
18842
+ this.appliedCollapse = activeMode;
18843
+ this.appliedTheme = theme;
18844
+ if (runIosFade) {
18658
18845
  this.setupFadeFooter(contentEl);
18659
18846
  }
18847
+ else if (hasHide) {
18848
+ void this.setupHideFooter(contentEl);
18849
+ }
18660
18850
  };
18661
18851
  this.setupFadeFooter = async (contentEl) => {
18662
- const scrollEl = (this.scrollEl = await getScrollElement(contentEl));
18852
+ const token = ++this.setupToken;
18853
+ const scrollEl = await getScrollElement(contentEl);
18854
+ if (token !== this.setupToken) {
18855
+ return;
18856
+ }
18857
+ this.scrollEl = scrollEl;
18663
18858
  /**
18664
18859
  * Handle fading of toolbars on scroll
18665
18860
  */
@@ -18671,12 +18866,18 @@ class Footer {
18671
18866
  };
18672
18867
  }
18673
18868
  componentDidLoad() {
18869
+ this.didLoad = true;
18674
18870
  this.checkCollapsibleFooter();
18675
18871
  }
18676
18872
  componentDidUpdate() {
18677
18873
  this.checkCollapsibleFooter();
18678
18874
  }
18679
18875
  async connectedCallback() {
18876
+ // On re-attach (didLoad already true but disconnectedCallback ran since),
18877
+ // componentDidLoad will not fire again — re-run setup here.
18878
+ if (this.didLoad) {
18879
+ this.checkCollapsibleFooter();
18880
+ }
18680
18881
  const promise = createKeyboardController(async (keyboardOpen, waitForResize) => {
18681
18882
  /**
18682
18883
  * If the keyboard is hiding, then we need to wait
@@ -18704,6 +18905,7 @@ class Footer {
18704
18905
  }
18705
18906
  }
18706
18907
  disconnectedCallback() {
18908
+ this.destroyCollapsibleFooter();
18707
18909
  if (this.keyboardCtrlPromise) {
18708
18910
  this.keyboardCtrlPromise.then((ctrl) => ctrl.destroy());
18709
18911
  this.keyboardCtrlPromise = null;
@@ -18713,18 +18915,36 @@ class Footer {
18713
18915
  this.keyboardCtrl = null;
18714
18916
  }
18715
18917
  }
18918
+ async setupHideFooter(contentEl) {
18919
+ const token = ++this.setupToken;
18920
+ const scrollEl = await getScrollElement(contentEl);
18921
+ // A newer checkCollapsibleFooter ran while we were awaiting — abandon.
18922
+ if (token !== this.setupToken) {
18923
+ return;
18924
+ }
18925
+ this.scrollEl = scrollEl;
18926
+ this.footerHideCleanup = createFooterHideInteraction(this.el, scrollEl);
18927
+ }
18716
18928
  destroyCollapsibleFooter() {
18929
+ // Invalidate any in-flight setupHideFooter/setupFadeFooter awaits.
18930
+ this.setupToken++;
18931
+ if (this.footerHideCleanup) {
18932
+ this.footerHideCleanup();
18933
+ this.footerHideCleanup = undefined;
18934
+ }
18717
18935
  if (this.scrollEl && this.contentScrollCallback) {
18718
18936
  this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
18719
18937
  this.contentScrollCallback = undefined;
18720
18938
  }
18939
+ this.appliedCollapse = undefined;
18940
+ this.appliedTheme = undefined;
18721
18941
  }
18722
18942
  render() {
18723
18943
  const { translucent, collapse } = this;
18724
18944
  const theme = getIonTheme(this);
18725
18945
  const tabs = this.el.closest('ion-tabs');
18726
18946
  const tabBar = tabs === null || tabs === void 0 ? void 0 : tabs.querySelector(':scope > ion-tab-bar');
18727
- return (hAsync(Host, { key: '4a2989a177b47ee26ffa23e2c9f5418773584796', role: "contentinfo", class: {
18947
+ return (hAsync(Host, { key: '5df79a31f36febfad49c5858727e93c7ba5734f8', role: "contentinfo", class: {
18728
18948
  [theme]: true,
18729
18949
  // Used internally for styling
18730
18950
  [`footer-${theme}`]: true,
@@ -18732,7 +18952,7 @@ class Footer {
18732
18952
  [`footer-translucent-${theme}`]: translucent,
18733
18953
  ['footer-toolbar-padding']: !this.keyboardVisible && (!tabBar || tabBar.slot !== 'bottom'),
18734
18954
  [`footer-collapse-${collapse}`]: collapse !== undefined,
18735
- } }, theme === 'ios' && translucent && hAsync("div", { key: 'c644963db3e06254014e398ea02189d6127ccf61', class: "footer-background" }), hAsync("slot", { key: '839e33c6c30f5c1c703239a19458ff10da9a5e76' })));
18955
+ } }, theme === 'ios' && translucent && hAsync("div", { key: '9175ae4f6576d82dff2a00a36e91f4b633d8c9ad', class: "footer-background" }), hAsync("slot", { key: 'd6d618cdae4726822d8e82edb782c5c86fc7b77b' })));
18736
18956
  }
18737
18957
  get el() { return getElement(this); }
18738
18958
  static get style() { return {
@@ -18762,9 +18982,6 @@ class Footer {
18762
18982
  const LENGTH_PERCENTAGE_PATTERN = /^[-+]?(?:\d+\.?\d*|\.\d+)(?:%|[a-z]+)$/i;
18763
18983
  // Matches simple `calc` / `min` / `max` / `clamp(...)` functions.
18764
18984
  const MATH_FUNCTION_PATTERN = /^(calc|min|max|clamp)\s*\(.+\)$/i;
18765
- // Matches a `var(--name)` reference with an optional fallback, e.g.
18766
- // `var(--my-gap)` or `var(--my-gap, 16px)`.
18767
- const VAR_FUNCTION_PATTERN = /^var\(\s*--[^\s,)]+\s*(?:,[\s\S]*)?\)$/i;
18768
18985
  /**
18769
18986
  * Returns whether `value` matches the [length-percentage](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/length-percentage)
18770
18987
  * syntax. Accepts `<length>` (`<number>` + unit identifier) or `<percentage>` (`<number>%`).
@@ -18779,17 +18996,6 @@ function isValidLengthPercentage(value) {
18779
18996
  }
18780
18997
  return MATH_FUNCTION_PATTERN.test(v) || LENGTH_PERCENTAGE_PATTERN.test(v);
18781
18998
  }
18782
- /**
18783
- * Returns whether `value` is a single [`var()`](https://developer.mozilla.org/en-US/docs/Web/CSS/var)
18784
- * reference, e.g. `var(--my-token)` or `var(--my-token, 16px)`. The referenced
18785
- * custom property is resolved by the browser, so the resolved value is not
18786
- * validated here.
18787
- *
18788
- * @param value String value to validate.
18789
- */
18790
- function isCssVariable(value) {
18791
- return VAR_FUNCTION_PATTERN.test(value.trim());
18792
- }
18793
18999
 
18794
19000
  const DEFAULT_COLUMNS = {
18795
19001
  xs: 2,
@@ -18843,8 +19049,7 @@ class Gallery {
18843
19049
  /**
18844
19050
  * The space between gallery items. Accepts valid CSS [length-percentage](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/length-percentage)
18845
19051
  * values like `16px`, `1rem`, `20%`, math functions like `calc(10px + 20%)`,
18846
- * CSS variables like `var(--app-gallery-gap)`, or numbers (treated as pixel
18847
- * values). Can also be set as a breakpoint map
19052
+ * or numbers (treated as pixel values). Can also be set as a breakpoint map
18848
19053
  * (e.g. `{ xs: '8px', sm: '1rem', md: '24px' }`). Does not accept
18849
19054
  * space-separated values or CSS keyword values like `inherit`, `auto`, etc.
18850
19055
  */
@@ -18965,10 +19170,9 @@ class Gallery {
18965
19170
  return numericColumns;
18966
19171
  }
18967
19172
  /**
18968
- * Normalize a single gap value (`gap` as a number, a string such as a CSS
18969
- * length-percentage or `var()` reference, or one entry from a `gap`
18970
- * breakpoint map) to a CSS length string. Returns `undefined` when the
18971
- * input cannot be interpreted as a valid CSS length or `var()` reference.
19173
+ * Normalize a single gap value (`gap` as a number, string, or one entry from
19174
+ * a `gap` breakpoint map) to a CSS length string. Returns `undefined` when
19175
+ * the input cannot be interpreted as a valid CSS length.
18972
19176
  */
18973
19177
  sanitizeGap(gap) {
18974
19178
  if (gap === undefined) {
@@ -18985,9 +19189,6 @@ class Gallery {
18985
19189
  if (typeof normalizedGap !== 'string') {
18986
19190
  return undefined;
18987
19191
  }
18988
- if (isCssVariable(normalizedGap)) {
18989
- return normalizedGap;
18990
- }
18991
19192
  const isValidCssLength = isValidLengthPercentage(normalizedGap);
18992
19193
  return isValidCssLength ? normalizedGap : undefined;
18993
19194
  }
@@ -19068,7 +19269,7 @@ class Gallery {
19068
19269
  if (this.hasWarnedInvalidGap) {
19069
19270
  return;
19070
19271
  }
19071
- printIonWarning(`[ion-gallery] - Invalid "gap" value (${JSON.stringify(gap)}). Expected a non-negative number, CSS length string, CSS variable (e.g. var(--app-gap)), or breakpoint map object (e.g. { xs: 8, md: "1rem" }).`, this.el);
19272
+ printIonWarning(`[ion-gallery] - Invalid "gap" value (${JSON.stringify(gap)}). Expected a non-negative number, CSS length string, or breakpoint map object (e.g. { xs: 8, md: "1rem" }).`, this.el);
19072
19273
  this.hasWarnedInvalidGap = true;
19073
19274
  }
19074
19275
  /**
@@ -19254,11 +19455,11 @@ class Gallery {
19254
19455
  const { layout } = this;
19255
19456
  const order = this.getOrder();
19256
19457
  const theme = getIonTheme(this);
19257
- return (hAsync(Host, { key: '4f578bea373b422f5dd41395ca04ade699a2f398', class: {
19458
+ return (hAsync(Host, { key: '1bf2973d22835c0dbddf3214b602f8c08b95e421', class: {
19258
19459
  [theme]: true,
19259
19460
  [`gallery-layout-${layout}`]: true,
19260
19461
  [`gallery-order-${order}`]: layout === 'masonry' && order !== undefined,
19261
- } }, hAsync("slot", { key: '0daa3ba1ea894c8c10ab077a6b83476ad5cf514d', onSlotchange: this.onSlotChange })));
19462
+ } }, hAsync("slot", { key: '0dea31f609f6afdb1d73ecb2d873909ffe49203f', onSlotchange: this.onSlotChange })));
19262
19463
  }
19263
19464
  get el() { return getElement(this); }
19264
19465
  static get watchers() { return {
@@ -19501,6 +19702,14 @@ const scaleLargeTitles = (toolbars = [], scale = 1, transition = false) => {
19501
19702
  titleDiv.style.transform = `scale3d(${scale}, ${scale}, 1)`;
19502
19703
  });
19503
19704
  };
19705
+ const createHeaderHideInteraction = (headerEl, scrollEl) => createCollapseHideInteraction({
19706
+ regionEl: headerEl,
19707
+ scrollEl,
19708
+ slideCssVar: '--header-hide-slide-y',
19709
+ contentPartnerClass: 'content-header-hide-scroll-partner',
19710
+ contentHiddenClass: 'content-header-hide-scroll-hidden',
19711
+ regionHiddenClass: 'header-collapse-hide-hidden',
19712
+ });
19504
19713
  const handleHeaderFade = (scrollEl, baseEl, condenseHeader) => {
19505
19714
  readTask(() => {
19506
19715
  const scrollTop = scrollEl.scrollTop;
@@ -19557,11 +19766,11 @@ const getRoleType = (isInsideMenu, isCondensed, theme) => {
19557
19766
  return ROLE_BANNER;
19558
19767
  };
19559
19768
 
19560
- const headerIonicCss = () => `ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}ion-header{z-index:10}ion-header.header-divider{border-bottom:var(--token-border-size-025, var(--token-scale-025, 1px)) var(--token-border-style-solid, solid) var(--token-border-default, var(--token-primitives-neutral-400, #d5d5d5))}ion-toolbar+ion-toolbar{--padding-start:var(--token-space-400, var(--token-scale-400, 16px));--padding-end:var(--token-space-400, var(--token-scale-400, 16px))}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.header-background{right:0;left:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(var(--token-scale-100, 4px));backdrop-filter:saturate(180%) blur(var(--token-scale-100, 4px))}.header-translucent-ionic ion-toolbar{--opacity:0.7}}`;
19769
+ const headerIonicCss = () => `ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}ion-header.header-collapse-hide{-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);opacity:1;z-index:10}ion-header.header-collapse-hide.header-collapse-hide-hidden{-webkit-transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));pointer-events:none;-webkit-transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);opacity:0}ion-header{z-index:10}ion-header.header-divider{border-bottom:var(--token-border-size-025, var(--token-scale-025, 1px)) var(--token-border-style-solid, solid) var(--token-border-default, var(--token-primitives-neutral-400, #d5d5d5))}ion-toolbar+ion-toolbar{--padding-start:var(--token-space-400, var(--token-scale-400, 16px));--padding-end:var(--token-space-400, var(--token-scale-400, 16px))}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.header-background{right:0;left:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(var(--token-scale-100, 4px));backdrop-filter:saturate(180%) blur(var(--token-scale-100, 4px))}.header-translucent-ionic ion-toolbar{--opacity:0.7}}`;
19561
19770
 
19562
- const headerIosCss = () => `ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}ion-header{z-index:10}.header-ios ion-toolbar:last-of-type{--border-width:0 0 0.55px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.header-background{right:0;left:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.header-translucent-ios ion-toolbar{--opacity:0.8}.header-collapse-condense-inactive .header-background{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}}.header-ios.ion-no-border ion-toolbar:last-of-type{--border-width:0}.header-collapse-fade ion-toolbar{--opacity-scale:inherit}.header-collapse-fade.header-transitioning ion-toolbar{--background:transparent;--border-style:none}.header-collapse-condense{z-index:9}.header-collapse-condense ion-toolbar{position:-webkit-sticky;position:sticky;top:0}.header-collapse-condense ion-toolbar:first-of-type{padding-top:0px;z-index:1}.header-collapse-condense ion-toolbar{z-index:0}.header-collapse-condense ion-toolbar:last-of-type{--border-width:0px}.header-collapse-condense ion-toolbar ion-searchbar{padding-top:0px;padding-bottom:13px}.header-collapse-main{--opacity-scale:1}.header-collapse-main ion-toolbar{--opacity-scale:inherit}.header-collapse-main ion-toolbar.in-toolbar ion-title,.header-collapse-main ion-toolbar.in-toolbar ion-buttons{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.header-collapse-condense ion-toolbar,.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar{--background:var(--ion-background-color, #fff)}.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar{--border-style:none;--opacity-scale:1}.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-buttons.buttons-collapse{opacity:0;pointer-events:none}.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse{visibility:hidden}ion-header.header-ios:not(.header-collapse-main):has(~ion-content ion-header.header-ios[collapse=condense],~ion-content ion-header.header-ios.header-collapse-condense){opacity:0}`;
19771
+ const headerIosCss = () => `ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}ion-header.header-collapse-hide{-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);opacity:1;z-index:10}ion-header.header-collapse-hide.header-collapse-hide-hidden{-webkit-transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));pointer-events:none;-webkit-transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);opacity:0}ion-header{z-index:10}.header-ios ion-toolbar:last-of-type{--border-width:0 0 0.55px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.header-background{right:0;left:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.header-translucent-ios ion-toolbar{--opacity:0.8}.header-collapse-condense-inactive .header-background{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}}.header-ios.ion-no-border ion-toolbar:last-of-type{--border-width:0}.header-collapse-fade ion-toolbar{--opacity-scale:inherit}.header-collapse-fade.header-transitioning ion-toolbar{--background:transparent;--border-style:none}.header-collapse-condense{z-index:9}.header-collapse-condense ion-toolbar{position:-webkit-sticky;position:sticky;top:0}.header-collapse-condense ion-toolbar:first-of-type{padding-top:0px;z-index:1}.header-collapse-condense ion-toolbar{z-index:0}.header-collapse-condense ion-toolbar:last-of-type{--border-width:0px}.header-collapse-condense ion-toolbar ion-searchbar{padding-top:0px;padding-bottom:13px}.header-collapse-main{--opacity-scale:1}.header-collapse-main ion-toolbar{--opacity-scale:inherit}.header-collapse-main ion-toolbar.in-toolbar ion-title,.header-collapse-main ion-toolbar.in-toolbar ion-buttons{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.header-collapse-condense ion-toolbar,.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar{--background:var(--ion-background-color, #fff)}.header-collapse-condense-inactive.header-transitioning:not(.header-collapse-condense) ion-toolbar{--border-style:none;--opacity-scale:1}.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-buttons.buttons-collapse{opacity:0;pointer-events:none}.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse{visibility:hidden}ion-header.header-ios:not(.header-collapse-main):has(~ion-content ion-header.header-ios[collapse=condense],~ion-content ion-header.header-ios.header-collapse-condense){opacity:0}`;
19563
19772
 
19564
- const headerMdCss = () => `ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}ion-header{z-index:10}.header-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.header-md.header-collapse-condense{display:none}.header-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}`;
19773
+ const headerMdCss = () => `ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}ion-header.header-collapse-hide{-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1);transition:transform 300ms cubic-bezier(0, 0, 0.2, 1), opacity 300ms cubic-bezier(0, 0, 0.2, 1), -webkit-transform 300ms cubic-bezier(0, 0, 0.2, 1);opacity:1;z-index:10}ion-header.header-collapse-hide.header-collapse-hide-hidden{-webkit-transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));transform:translateY(calc(-1 * var(--header-hide-slide-y, 0px)));pointer-events:none;-webkit-transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1);transition:transform 200ms cubic-bezier(0.4, 0, 1, 1), opacity 300ms cubic-bezier(0.4, 0, 1, 1), -webkit-transform 200ms cubic-bezier(0.4, 0, 1, 1);opacity:0}ion-header{z-index:10}.header-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.header-md.header-collapse-condense{display:none}.header-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}`;
19565
19774
 
19566
19775
  /**
19567
19776
  * @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of the component.
@@ -19571,6 +19780,7 @@ class Header {
19571
19780
  constructor(hostRef) {
19572
19781
  registerInstance(this, hostRef);
19573
19782
  this.inheritedAttributes = {};
19783
+ this.didLoad = false;
19574
19784
  /**
19575
19785
  * If `true`, the header will have a line at the bottom.
19576
19786
  * TODO(ROU-10855): add support for this prop on ios/md themes
@@ -19601,25 +19811,37 @@ class Header {
19601
19811
  this.inheritedAttributes = inheritAriaAttributes(this.el);
19602
19812
  }
19603
19813
  componentDidLoad() {
19814
+ this.didLoad = true;
19604
19815
  this.checkCollapsibleHeader();
19605
19816
  }
19606
19817
  componentDidUpdate() {
19607
19818
  this.checkCollapsibleHeader();
19608
19819
  }
19820
+ connectedCallback() {
19821
+ // On re-attach (didLoad already true but disconnectedCallback ran since),
19822
+ // componentDidLoad will not fire again — re-run setup here.
19823
+ if (this.didLoad) {
19824
+ this.checkCollapsibleHeader();
19825
+ }
19826
+ }
19609
19827
  disconnectedCallback() {
19610
19828
  this.destroyCollapsibleHeader();
19611
19829
  }
19612
19830
  async checkCollapsibleHeader() {
19613
19831
  const theme = getIonTheme(this);
19614
- if (theme !== 'ios') {
19615
- return;
19616
- }
19617
19832
  const { collapse } = this;
19618
19833
  const hasCondense = collapse === 'condense';
19619
19834
  const hasFade = collapse === 'fade';
19835
+ const hasHide = collapse === 'hide';
19836
+ const runIosCollapse = theme === 'ios' && (hasCondense || hasFade);
19837
+ const runHide = hasHide;
19838
+ if (!runIosCollapse && !runHide) {
19839
+ this.destroyCollapsibleHeader();
19840
+ return;
19841
+ }
19620
19842
  this.destroyCollapsibleHeader();
19621
19843
  const appRootSelector = config.get('appRootSelector', 'ion-app');
19622
- if (hasCondense) {
19844
+ if (runIosCollapse && hasCondense) {
19623
19845
  const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
19624
19846
  const contentEl = pageEl ? findIonContent(pageEl) : null;
19625
19847
  // Cloned elements are always needed in iOS transition
@@ -19630,7 +19852,7 @@ class Header {
19630
19852
  });
19631
19853
  await this.setupCondenseHeader(contentEl, pageEl);
19632
19854
  }
19633
- else if (hasFade) {
19855
+ else if (runIosCollapse && hasFade) {
19634
19856
  const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
19635
19857
  const contentEl = pageEl ? findIonContent(pageEl) : null;
19636
19858
  if (!contentEl) {
@@ -19640,12 +19862,29 @@ class Header {
19640
19862
  const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"]');
19641
19863
  await this.setupFadeHeader(contentEl, condenseHeader);
19642
19864
  }
19865
+ if (runHide) {
19866
+ const pageEl = this.el.closest(`${appRootSelector},ion-page,.ion-page,page-inner`);
19867
+ const contentEl = pageEl ? findIonContent(pageEl) : null;
19868
+ if (!contentEl) {
19869
+ printIonContentErrorMsg(this.el);
19870
+ return;
19871
+ }
19872
+ await this.setupHideHeader(contentEl);
19873
+ }
19874
+ }
19875
+ async setupHideHeader(contentEl) {
19876
+ const scrollEl = (this.scrollEl = await getScrollElement(contentEl));
19877
+ this.headerHideCleanup = createHeaderHideInteraction(this.el, scrollEl);
19643
19878
  }
19644
19879
  destroyCollapsibleHeader() {
19645
19880
  if (this.intersectionObserver) {
19646
19881
  this.intersectionObserver.disconnect();
19647
19882
  this.intersectionObserver = undefined;
19648
19883
  }
19884
+ if (this.headerHideCleanup) {
19885
+ this.headerHideCleanup();
19886
+ this.headerHideCleanup = undefined;
19887
+ }
19649
19888
  if (this.scrollEl && this.contentScrollCallback) {
19650
19889
  this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
19651
19890
  this.contentScrollCallback = undefined;
@@ -19712,7 +19951,7 @@ class Header {
19712
19951
  const isCondensed = collapse === 'condense';
19713
19952
  // banner role must be at top level, so remove role if inside a menu
19714
19953
  const roleType = getRoleType(hostContext('ion-menu', this.el), isCondensed, theme);
19715
- return (hAsync(Host, Object.assign({ key: 'b43e5f542bdcec5e94c299556183cf6d9d673438', role: roleType, class: {
19954
+ return (hAsync(Host, Object.assign({ key: '5cae1ff0bbc5f2035325c128a9394caf7f1459a0', role: roleType, class: {
19716
19955
  [theme]: true,
19717
19956
  // Used internally for styling
19718
19957
  [`header-${theme}`]: true,
@@ -19720,7 +19959,7 @@ class Header {
19720
19959
  [`header-collapse-${collapse}`]: true,
19721
19960
  [`header-translucent-${theme}`]: this.translucent,
19722
19961
  ['header-divider']: divider,
19723
- } }, inheritedAttributes), theme !== 'md' && translucent && hAsync("div", { key: 'fd9938f02edd38e1afc83025373ec0aec5633711', class: "header-background" }), hAsync("slot", { key: '900aaa7da5d6f08e6f94b128fa065348d595159e' })));
19962
+ } }, inheritedAttributes), theme !== 'md' && translucent && hAsync("div", { key: '705f120951a3dd429286b66cd0b511fa267b3702', class: "header-background" }), hAsync("slot", { key: '1c7a9d474083cf92abfe88c02d363f8d420716ca' })));
19724
19963
  }
19725
19964
  get el() { return getElement(this); }
19726
19965
  static get style() { return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic/core",
3
- "version": "8.8.9-dev.11780493108.1d8e1a89",
3
+ "version": "8.8.9-dev.11780493937.17fe092d",
4
4
  "description": "Base components for Ionic",
5
5
  "engines": {
6
6
  "node": ">= 16"