@rdlabo/ionic-theme-ios27 2.0.0 → 2.0.1-beta.pr320.sha1504df298a37
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.
- package/README.md +1 -1
- package/dist/css/ionic-theme-ios27.css +1 -1
- package/dist/css/vertical-bars.css +1 -1
- package/dist/transition/ios.transition.d.ts.map +1 -1
- package/dist/transition/ios.transition.js +41 -1
- package/dist/transition/ios.transition.js.map +1 -1
- package/dist/transition/native-ui.d.ts +1 -1
- package/dist/transition/native-ui.d.ts.map +1 -1
- package/dist/transition/native-ui.js +43 -9
- package/dist/transition/native-ui.js.map +1 -1
- package/docs/features.md +2 -2
- package/package.json +2 -2
- package/src/styles/vertical-bars.scss +6 -4
- package/src/transition/ios.transition.ts +46 -3
- package/src/transition/native-ui.ts +56 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
@property --ios-theme-split-pane-width{syntax:"<length>";inherits:false;initial-value:320px}ion-app.ios-theme-fold-half-opened ion-split-pane.split-pane-fold-layout,ion-split-pane.ios-theme-split-pane-half-open{--ios-theme-split-pane-width: 50vw}ion-app.ios-theme-vertical-bars{--ios-theme-vertical-bars-safe-area-left-resolved: var(--ios-theme-vertical-bars-safe-area-left, 0px);--ios-theme-vertical-bars-safe-area-right-resolved: var( --ios-theme-vertical-bars-safe-area-right, var(--ios-theme-vertical-bars-native-inset, max(80px, env(safe-area-inset-right, 0px))) )}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left{--ios-theme-vertical-bars-safe-area-left-resolved: var( --ios-theme-vertical-bars-safe-area-left, var(--ios-theme-vertical-bars-native-inset, max(80px, env(safe-area-inset-left, 0px))) );--ios-theme-vertical-bars-safe-area-right-resolved: var(--ios-theme-vertical-bars-safe-area-right, 0px)}ion-app.ios-theme-vertical-bars ion-modal:not(.ios-theme-vertical-bars-modal){--ios-theme-vertical-bars-safe-area-left-resolved: 0px;--ios-theme-vertical-bars-safe-area-right-resolved: 0px}ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal{--ios-theme-vertical-bars-modal-toolbar-top: max( 24px, calc(var(--ios-theme-vertical-bars-toolbar-top, 220px) - var(--ios-theme-vertical-bars-modal-offset-top, 0px)) )}:is(ion-app.ios-theme-vertical-bars,ion-modal.ios-theme-vertical-bars-modal).ios-theme-vertical-bars-toolbar-ready>:is(ion-menu-button,ion-button).ios-theme-vertical-bars-toolbar-projection{--ios26-glass-background-rgb: var(--ion-background-color-rgb, 255, 255, 255);--ios26-glass-border-color-rgb: var(--ion-background-color-rgb, 255, 255, 255);--ios26-glass-box-shadow-color-rgb: var(--ion-text-color-rgb, 0, 0, 0)}ion-app.ios-theme-vertical-bars .ios-transition-shade{clip-path:inset(0 var(--ios-theme-vertical-bars-safe-area-right-resolved) 0 var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-header.ios:not(.header-collapse-condense,.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)){--ion-safe-area-top: max(24px, env(safe-area-inset-top, 0px))}ion-app.ios-theme-vertical-bars ion-content:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)){--ion-safe-area-left: 0px;--ion-safe-area-right: 0px}ion-app.ios-theme-vertical-bars ion-content:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *))::part(scroll){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-content:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):dir(rtl)::part(scroll){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)){--ion-safe-area-left: 0px;--ion-safe-area-right: 0px}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not([data-native-ui-toolbar-text]):has(>.native-ui-prehidden,>ion-buttons>.native-ui-prehidden):not(:has(>:not(ion-buttons,.native-ui-prehidden))):not(:has(>ion-buttons:not(.native-ui-prehidden)>:not(.native-ui-prehidden))){display:none}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-header.header-collapse-condense *,ion-footer.footer-collapse-fade *))>ion-title.ios.title-default:not(.ios-theme-disabled,.ios26-disabled){inset-inline-start:var(--ios-theme-vertical-bars-safe-area-left-resolved);width:calc(100% - var(--ios-theme-vertical-bars-safe-area-left-resolved) - var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-header.header-collapse-condense *,ion-footer.footer-collapse-fade *))>ion-title.ios.title-default:not(.ios-theme-disabled,.ios26-disabled):dir(rtl){inset-inline-start:var(--ios-theme-vertical-bars-safe-area-right-resolved)}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-header.header-collapse-condense *,ion-footer.footer-collapse-fade *))::part(container){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-header.header-collapse-condense *,ion-footer.footer-collapse-fade *)):dir(rtl)::part(container){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)){--ion-safe-area-left: 0px;--ion-safe-area-right: 0px;--ios-theme-vertical-bars-fab-edge-gap: 16px;--ios-theme-vertical-bars-fab-start-offset: var(--ios-theme-menu-width, var(--ios26-menu-width, 0px))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)).fab-horizontal-start{inset-inline-start:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-fab-start-offset) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)).fab-horizontal-end{inset-inline-end:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)):dir(rtl).fab-horizontal-start{inset-inline-start:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-fab-start-offset) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)):dir(rtl).fab-horizontal-end{inset-inline-end:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)):has(.fab-button-small){--ios-theme-vertical-bars-fab-edge-gap: 10px}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:dir(rtl):not(.ios-theme-disabled,.ios26-disabled){--ion-safe-area-right: 0px}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled)::part(container),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:dir(rtl):not(.ios-theme-disabled,.ios26-disabled)::part(container){margin-right:var(--ios-theme-vertical-bars-safe-area-right-resolved)}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:dir(rtl):not(.ios-theme-disabled,.ios26-disabled){--ion-safe-area-left: 0px}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled)::part(container),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:dir(rtl):not(.ios-theme-disabled,.ios26-disabled)::part(container){margin-left:var(--ios-theme-vertical-bars-safe-area-left-resolved)}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled){--ios-theme-side-tab-bar-width: 48px;--ios-theme-side-tab-content-width: 44px;--ios-theme-side-tab-bar-gap: 24px;contain:layout style;position:absolute;z-index:2;display:flex;flex-direction:column;width:44px;min-width:44px;max-width:44px;height:fit-content;min-height:0;padding:2px;border-radius:24px;left:auto;right:calc(24px + (48px - var(--ios-theme-side-tab-bar-width))/2);margin:0;top:auto;bottom:var(--ios-theme-side-tab-bar-gap)}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled).ios27-enable-gesture{touch-action:pan-x pinch-zoom}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element){display:block;flex:none;width:44px;min-width:44px;height:58px;min-height:58px;border-radius:22px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element)::part(native){justify-content:center;min-height:58px;padding:0}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element) ion-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element) ion-icon{margin:0;font-size:28px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button.ion-activated{transform:scale(1.16)}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element)~ion-tab-button:not(.ion-cloned-element){margin-block-start:-8px;margin-inline-start:0}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active))){--ios-theme-side-tab-bar-width: 72px;--ios-theme-side-tab-content-width: 64px;--ios-theme-side-tab-bar-gap: 20px;width:64px;min-width:64px;max-width:64px;padding:4px;border-radius:36px;transform:none;-webkit-transform:none}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element){width:64px;min-width:64px;height:64px;min-height:64px;border-radius:32px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element)::part(native){flex-direction:column;min-height:64px;padding-block:11px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element) ion-label{position:static;width:auto;height:auto;max-width:64px;padding:0;margin:1px 0 0;overflow:hidden;clip:auto;font-size:10px;line-height:12px;text-overflow:ellipsis;white-space:nowrap}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element) ion-icon{margin:0;font-size:28px}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled){right:auto;left:calc(24px + (48px - var(--ios-theme-side-tab-bar-width))/2)}.native-ui-prehidden{position:absolute !important;visibility:hidden !important}html.native-ui-prehide ion-app.ios-theme-vertical-bars ion-back-button:not([icon],[color],.ios-theme-vertical-bars-back-web-owned,.native-ui-disabled,[data-native-ui=disabled],.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-back-button-projection):not(:where(ion-menu *,ion-modal *,ion-popover *,ion-header[collapse] *,ion-footer[collapse] *,ion-buttons.ios-theme-horizontal-only *,.native-ui-disabled *,[data-native-ui=disabled] *,.ios-theme-disabled *,.ios26-disabled *)){position:absolute !important;visibility:hidden !important}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-back-button:is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-back-button-projection),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-back-button:is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-back-button-projection){display:none}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md)>:is(ion-button,ion-menu-button):is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-toolbar-action),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md)>:is(ion-button,ion-menu-button):is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-toolbar-action){display:none}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md):has(>:is(ion-back-button,ion-button,ion-menu-button)[data-native-ui-projected]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-projected]))),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md):has(>:is(ion-back-button,ion-button,ion-menu-button)[data-native-ui-projected]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-projected]))){display:none}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-back-button.ios-theme-vertical-bars-back-button-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-back-button.ios-theme-vertical-bars-back-button-projection{position:fixed;z-index:1001;top:var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px));right:max(4px,(var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px)/2);display:block;width:46px;height:46px;margin:0}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{position:fixed;z-index:1001;top:calc(var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px)) + var(--ios-theme-vertical-bars-toolbar-offset, 0px));right:max(4px,(var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px)/2);width:46px;min-width:46px;height:46px;min-height:46px;margin:0}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection :is(ion-icon,svg),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection :is(ion-icon,svg){width:22px;height:22px;margin:0;font-size:22px}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{backdrop-filter:blur(2px) saturate(360%);transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);box-shadow:inset 0 1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.25),inset 0 -1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.3),0 -0.5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 .5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 0 0 .5px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.22),0 .5px 1px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08);border:.5px solid rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)));background-image:linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%);background-origin:padding-box;background-clip:border-box;border-inline-color:rgba(0,0,0,0)}@supports(background-clip: border-area){ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{border-color:rgba(0,0,0,0);background-image:linear-gradient(180deg, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), transparent 50%, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)))),linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%),linear-gradient(transparent, transparent);background-origin:border-box,padding-box,border-box;background-clip:border-area,padding-box,border-box}}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{border-radius:50%}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-solid):not(.button-outline),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-solid):not(.button-outline){--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72)}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{--border-radius: 50%;--box-shadow:inset 0 1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.25),inset 0 -1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.3),0 -0.5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 .5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 0 0 .5px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.22),0 .5px 1px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08)}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native){backdrop-filter:blur(2px) saturate(360%);transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;box-shadow:var(--box-shadow);border:.5px solid rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)));background-image:linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%);background-origin:padding-box;background-clip:border-box;border-inline-color:rgba(0,0,0,0)}@supports(background-clip: border-area){ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native){border-color:rgba(0,0,0,0);background-image:linear-gradient(180deg, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), transparent 50%, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)))),linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%),linear-gradient(transparent, transparent);background-origin:border-box,padding-box,border-box;background-clip:border-area,padding-box,border-box}}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{display:flex;flex-direction:column;height:auto;min-height:0}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action{display:block;width:44px;min-width:44px;height:46px;min-height:46px;margin:0 1px}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action::part(native),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action::part(native){margin-inline:auto}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left>ion-back-button.ios-theme-vertical-bars-back-button-projection,ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal>ion-back-button.ios-theme-vertical-bars-back-button-projection,ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{right:auto;left:max(4px,(var(--ios-theme-vertical-bars-safe-area-left-resolved) - 46px)/2)}ion-tab-button.ios.ion-cloned-element.ios27-vertical-tab-effect{border-radius:32px}ion-tab-button.ios.ion-cloned-element.ios27-vertical-tab-effect::part(native){min-height:0;height:100%}:is(ion-app.ios-theme-vertical-bars,ion-modal.ios-theme-vertical-bars-modal)>ion-fab.ios-theme-vertical-bars-search-projection{position:fixed;left:auto;right:25px;top:auto;bottom:24px;z-index:3;width:46px;height:46px;margin:0}:is(ion-app.ios-theme-vertical-bars,ion-modal.ios-theme-vertical-bars-modal)>ion-fab.ios-theme-vertical-bars-search-projection>ion-fab-button{width:46px;height:46px;margin:0}ion-app.ios-theme-vertical-bars ion-fab>ion-fab-button[data-native-ui-projected]{visibility:hidden !important}.ios-theme-vertical-bars-search-projection[hidden]{display:none !important}ion-app.ios-theme-vertical-bars-left>ion-fab.ios-theme-vertical-bars-search-projection,ion-app.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal>ion-fab.ios-theme-vertical-bars-search-projection{left:25px;right:auto}
|
|
1
|
+
@property --ios-theme-split-pane-width{syntax:"<length>";inherits:false;initial-value:320px}ion-app.ios-theme-fold-half-opened ion-split-pane.split-pane-fold-layout,ion-split-pane.ios-theme-split-pane-half-open{--ios-theme-split-pane-width: 50vw}ion-app.ios-theme-vertical-bars{--ios-theme-vertical-bars-safe-area-left-resolved: var(--ios-theme-vertical-bars-safe-area-left, 0px);--ios-theme-vertical-bars-safe-area-right-resolved: var( --ios-theme-vertical-bars-safe-area-right, var(--ios-theme-vertical-bars-native-inset, max(80px, env(safe-area-inset-right, 0px))) )}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left{--ios-theme-vertical-bars-safe-area-left-resolved: var( --ios-theme-vertical-bars-safe-area-left, var(--ios-theme-vertical-bars-native-inset, max(80px, env(safe-area-inset-left, 0px))) );--ios-theme-vertical-bars-safe-area-right-resolved: var(--ios-theme-vertical-bars-safe-area-right, 0px)}ion-app.ios-theme-vertical-bars ion-modal:not(.ios-theme-vertical-bars-modal){--ios-theme-vertical-bars-safe-area-left-resolved: 0px;--ios-theme-vertical-bars-safe-area-right-resolved: 0px}ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal{--ios-theme-vertical-bars-modal-toolbar-top: max( 24px, calc(var(--ios-theme-vertical-bars-toolbar-top, 220px) - var(--ios-theme-vertical-bars-modal-offset-top, 0px)) )}:is(ion-app.ios-theme-vertical-bars,ion-modal.ios-theme-vertical-bars-modal).ios-theme-vertical-bars-toolbar-ready>:is(ion-menu-button,ion-button).ios-theme-vertical-bars-toolbar-projection{--ios26-glass-background-rgb: var(--ion-background-color-rgb, 255, 255, 255);--ios26-glass-border-color-rgb: var(--ion-background-color-rgb, 255, 255, 255);--ios26-glass-box-shadow-color-rgb: var(--ion-text-color-rgb, 0, 0, 0)}ion-app.ios-theme-vertical-bars .ios-transition-shade{clip-path:inset(0 var(--ios-theme-vertical-bars-safe-area-right-resolved) 0 var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-header.ios:not(.header-collapse-condense,.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)){--ion-safe-area-top: max(24px, env(safe-area-inset-top, 0px))}ion-app.ios-theme-vertical-bars ion-content:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)){--ion-safe-area-left: 0px;--ion-safe-area-right: 0px}ion-app.ios-theme-vertical-bars ion-content:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *))::part(scroll){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-content:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):dir(rtl)::part(scroll){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)){--ion-safe-area-left: 0px;--ion-safe-area-right: 0px}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not([data-native-ui-toolbar-text]):has(>.native-ui-prehidden,>ion-buttons>.native-ui-prehidden):not(:has(>:not(ion-buttons,.native-ui-prehidden))):not(:has(>ion-buttons:not(.native-ui-prehidden)>:not(.native-ui-prehidden))){display:none}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-content *))>ion-title.ios.title-default:not(.ios-theme-disabled,.ios26-disabled){inset-inline-start:var(--ios-theme-vertical-bars-safe-area-left-resolved);width:calc(100% - var(--ios-theme-vertical-bars-safe-area-left-resolved) - var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-content *))>ion-title.ios.title-default:not(.ios-theme-disabled,.ios26-disabled):dir(rtl){inset-inline-start:var(--ios-theme-vertical-bars-safe-area-right-resolved)}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-content *))::part(container){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)):not(:where(ion-content *)):dir(rtl)::part(container){padding-inline-start:calc(var(--padding-start, 0px) + var(--ios-theme-vertical-bars-safe-area-right-resolved));padding-inline-end:calc(var(--padding-end, 0px) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)){--ion-safe-area-left: 0px;--ion-safe-area-right: 0px;--ios-theme-vertical-bars-fab-edge-gap: 16px;--ios-theme-vertical-bars-fab-start-offset: var(--ios-theme-menu-width, var(--ios26-menu-width, 0px))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)).fab-horizontal-start{inset-inline-start:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-fab-start-offset) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)).fab-horizontal-end{inset-inline-end:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)):dir(rtl).fab-horizontal-start{inset-inline-start:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-fab-start-offset) + var(--ios-theme-vertical-bars-safe-area-right-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)):dir(rtl).fab-horizontal-end{inset-inline-end:calc(var(--ios-theme-vertical-bars-fab-edge-gap) + var(--ios-theme-vertical-bars-safe-area-left-resolved))}ion-app.ios-theme-vertical-bars ion-fab:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal *,ion-popover *)):has(.fab-button-small){--ios-theme-vertical-bars-fab-edge-gap: 10px}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:dir(rtl):not(.ios-theme-disabled,.ios26-disabled){--ion-safe-area-right: 0px}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled)::part(container),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:dir(rtl):not(.ios-theme-disabled,.ios26-disabled)::part(container){margin-right:var(--ios-theme-vertical-bars-safe-area-right-resolved)}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:dir(rtl):not(.ios-theme-disabled,.ios26-disabled){--ion-safe-area-left: 0px}ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-start:not(:dir(rtl)):not(.ios-theme-disabled,.ios26-disabled)::part(container),ion-app.ios-theme-vertical-bars ion-menu:is(.ios,.md).menu-side-end:dir(rtl):not(.ios-theme-disabled,.ios26-disabled)::part(container){margin-left:var(--ios-theme-vertical-bars-safe-area-left-resolved)}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled){--ios-theme-side-tab-bar-width: 48px;--ios-theme-side-tab-content-width: 44px;--ios-theme-side-tab-bar-gap: 24px;contain:layout style;position:absolute;z-index:2;display:flex;flex-direction:column;width:44px;min-width:44px;max-width:44px;height:fit-content;min-height:0;padding:2px;border-radius:24px;left:auto;right:calc(24px + (48px - var(--ios-theme-side-tab-bar-width))/2);margin:0;top:auto;bottom:var(--ios-theme-side-tab-bar-gap)}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled).ios27-enable-gesture{touch-action:pan-x pinch-zoom}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element){display:block;flex:none;width:44px;min-width:44px;height:58px;min-height:58px;border-radius:22px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element)::part(native){justify-content:center;min-height:58px;padding:0}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element) ion-label{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element) ion-icon{margin:0;font-size:28px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button.ion-activated{transform:scale(1.16)}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled)>ion-tab-button:not(.ion-cloned-element)~ion-tab-button:not(.ion-cloned-element){margin-block-start:-8px;margin-inline-start:0}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active))){--ios-theme-side-tab-bar-width: 72px;--ios-theme-side-tab-content-width: 64px;--ios-theme-side-tab-bar-gap: 20px;width:64px;min-width:64px;max-width:64px;padding:4px;border-radius:36px;transform:none;-webkit-transform:none}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element){width:64px;min-width:64px;height:64px;min-height:64px;border-radius:32px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element)::part(native){flex-direction:column;min-height:64px;padding-block:11px}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element) ion-label{position:static;width:auto;height:auto;max-width:64px;padding:0;margin:1px 0 0;overflow:hidden;clip:auto;font-size:10px;line-height:12px;text-overflow:ellipsis;white-space:nowrap}ion-app.ios-theme-vertical-bars ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):is(.ios27-animated,:has(>ion-tab-button:is(.ion-activated,:active)))>ion-tab-button:not(.ion-cloned-element) ion-icon{margin:0;font-size:28px}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-tabs:not(:where(ion-menu *,ion-modal *,ion-popover *))>ion-tab-bar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled){right:auto;left:calc(24px + (48px - var(--ios-theme-side-tab-bar-width))/2)}.native-ui-prehidden{position:absolute !important;visibility:hidden !important}html.native-ui-prehide ion-app.ios-theme-vertical-bars ion-back-button:not([icon],[color],.ios-theme-vertical-bars-back-web-owned,.native-ui-disabled,[data-native-ui=disabled],.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-back-button-projection):not(:where(ion-menu *,ion-modal *,ion-popover *,ion-header[collapse=condense] *,ion-header.header-collapse-condense *,ion-content ion-header *,ion-content ion-footer *,ion-buttons.ios-theme-horizontal-only *,.native-ui-disabled *,[data-native-ui=disabled] *,.ios-theme-disabled *,.ios26-disabled *)){position:absolute !important;visibility:hidden !important}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-back-button:is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-back-button-projection),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-back-button:is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-back-button-projection){display:none}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md)>:is(ion-button,ion-menu-button):is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-toolbar-action),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md)>:is(ion-button,ion-menu-button):is(.ios,.md)[data-native-ui-projected]:not(.ios-theme-disabled,.ios26-disabled,.ios-theme-vertical-bars-toolbar-action){display:none}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md):has(>:is(ion-back-button,ion-button,ion-menu-button)[data-native-ui-projected]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-projected]))),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready ion-toolbar:is(.ios,.md):not(.ios-theme-disabled,.ios26-disabled):not(:where(ion-menu *,ion-modal:not(.ios-theme-vertical-bars-modal) *,ion-popover *)) ion-buttons:is(.ios,.md):has(>:is(ion-back-button,ion-button,ion-menu-button)[data-native-ui-projected]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-projected]))){display:none}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-back-button.ios-theme-vertical-bars-back-button-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-back-button.ios-theme-vertical-bars-back-button-projection{position:fixed;z-index:1001;top:var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px));right:max(4px,(var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px)/2);display:block;width:46px;height:46px;margin:0}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{position:fixed;z-index:1001;top:calc(var(--ios-theme-vertical-bars-modal-toolbar-top, var(--ios-theme-vertical-bars-toolbar-top, 220px)) + var(--ios-theme-vertical-bars-toolbar-offset, 0px));right:max(4px,(var(--ios-theme-vertical-bars-safe-area-right-resolved) - 46px)/2);width:46px;min-width:46px;height:46px;min-height:46px;margin:0}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection :is(ion-icon,svg),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection :is(ion-icon,svg){width:22px;height:22px;margin:0;font-size:22px}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{backdrop-filter:blur(2px) saturate(360%);transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;background-color:rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);box-shadow:inset 0 1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.25),inset 0 -1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.3),0 -0.5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 .5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 0 0 .5px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.22),0 .5px 1px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08);border:.5px solid rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)));background-image:linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%);background-origin:padding-box;background-clip:border-box;border-inline-color:rgba(0,0,0,0)}@supports(background-clip: border-area){ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{border-color:rgba(0,0,0,0);background-image:linear-gradient(180deg, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), transparent 50%, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)))),linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%),linear-gradient(transparent, transparent);background-origin:border-box,padding-box,border-box;background-clip:border-area,padding-box,border-box}}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-menu-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{border-radius:50%}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-solid):not(.button-outline),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-solid):not(.button-outline){--background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72)}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{--border-radius: 50%;--box-shadow:inset 0 1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.25),inset 0 -1px 2px rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.3),0 -0.5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 .5px 0 rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.65),0 0 0 .5px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.22),0 .5px 1px rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08)}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native){backdrop-filter:blur(2px) saturate(360%);transform:translateZ(0);-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;box-shadow:var(--box-shadow);border:.5px solid rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)));background-image:linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%);background-origin:padding-box;background-clip:border-box;border-inline-color:rgba(0,0,0,0)}@supports(background-clip: border-area){ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-button:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection:not(.button-outline)::part(native){border-color:rgba(0,0,0,0);background-image:linear-gradient(180deg, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb))), transparent 50%, rgb(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)))),linear-gradient(180deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 4%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.01) 8%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 16%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.027) 22%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.026) 28%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.018) 36%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 44%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.024) 58%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.008) 80%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.006) 88%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0) 94%),linear-gradient(transparent, transparent);background-origin:border-box,padding-box,border-box;background-clip:border-area,padding-box,border-box}}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{display:flex;flex-direction:column;height:auto;min-height:0}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action,ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action{display:block;width:44px;min-width:44px;height:46px;min-height:46px;margin:0 1px}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action::part(native),ion-app.ios-theme-vertical-bars ion-modal.ios-theme-vertical-bars-modal.ios-theme-vertical-bars-toolbar-ready>ion-buttons:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection>:is(ion-button,ion-menu-button):is(.ios,.md).ios-theme-vertical-bars-toolbar-action::part(native){margin-inline:auto}ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left>ion-back-button.ios-theme-vertical-bars-back-button-projection,ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection,ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal>ion-back-button.ios-theme-vertical-bars-back-button-projection,ion-app.ios-theme-vertical-bars.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal>:is(.ios,.md).ios-theme-vertical-bars-toolbar-projection{right:auto;left:max(4px,(var(--ios-theme-vertical-bars-safe-area-left-resolved) - 46px)/2)}ion-tab-button.ios.ion-cloned-element.ios27-vertical-tab-effect{border-radius:32px}ion-tab-button.ios.ion-cloned-element.ios27-vertical-tab-effect::part(native){min-height:0;height:100%}:is(ion-app.ios-theme-vertical-bars,ion-modal.ios-theme-vertical-bars-modal)>ion-fab.ios-theme-vertical-bars-search-projection{position:fixed;left:auto;right:25px;top:auto;bottom:24px;z-index:3;width:46px;height:46px;margin:0}:is(ion-app.ios-theme-vertical-bars,ion-modal.ios-theme-vertical-bars-modal)>ion-fab.ios-theme-vertical-bars-search-projection>ion-fab-button{width:46px;height:46px;margin:0}ion-app.ios-theme-vertical-bars ion-fab>ion-fab-button[data-native-ui-projected]{visibility:hidden !important}.ios-theme-vertical-bars-search-projection[hidden]{display:none !important}ion-app.ios-theme-vertical-bars-left>ion-fab.ios-theme-vertical-bars-search-projection,ion-app.ios-theme-vertical-bars-left ion-modal.ios-theme-vertical-bars-modal>ion-fab.ios-theme-vertical-bars-search-projection{left:25px;right:auto}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios.transition.d.ts","names":[],"sources":["../../src/transition/ios.transition.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"ios.transition.d.ts","names":[],"sources":["../../src/transition/ios.transition.ts"],"mappings":";;;;iBAUiB;EACf;;qBAYW,YAAa,QAAQ,QAAQ;qBAK7B,yBAAyB,OAAO,aAAa,MAAM,sBAAsB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getIonPageElement } from "./index.js";
|
|
2
2
|
import { withNativeUITransition } from "./native-ui.js";
|
|
3
|
+
import { createAnimation } from "@ionic/core/components/index.js";
|
|
3
4
|
import { nativeWebViewMetrics } from "@rdlabo/capacitor-native-ui/integration";
|
|
4
5
|
import { createIosTransitionAnimation, shadow } from "@rdlabo/ionic-theme-utils";
|
|
5
6
|
//#region src/transition/ios.transition.ts
|
|
@@ -14,7 +15,46 @@ const transitionConfig = {
|
|
|
14
15
|
const setConfig = (config) => {
|
|
15
16
|
if (config.radius !== void 0) nativeWebViewMetrics.radius = config.radius;
|
|
16
17
|
};
|
|
17
|
-
const
|
|
18
|
+
const buildTransition = createIosTransitionAnimation(transitionConfig);
|
|
19
|
+
const iosTransitionAnimation = withNativeUITransition((navEl, opts) => {
|
|
20
|
+
const animation = buildTransition(navEl, opts);
|
|
21
|
+
const backing = "var(--ion-background-color, #fff)";
|
|
22
|
+
let ownsBacking = false;
|
|
23
|
+
animation.beforeAddWrite(() => {
|
|
24
|
+
if (navEl.style.backgroundColor) return;
|
|
25
|
+
const style = navEl.ownerDocument.defaultView?.getComputedStyle(navEl);
|
|
26
|
+
if (!style || !["transparent", "rgba(0, 0, 0, 0)"].includes(style.backgroundColor)) return;
|
|
27
|
+
if (style.backgroundImage && style.backgroundImage !== "none") return;
|
|
28
|
+
navEl.style.backgroundColor = backing;
|
|
29
|
+
ownsBacking = true;
|
|
30
|
+
});
|
|
31
|
+
const restoreBacking = () => {
|
|
32
|
+
if (ownsBacking && navEl.style.backgroundColor === backing && !navEl.style.getPropertyPriority("background-color")) navEl.style.removeProperty("background-color");
|
|
33
|
+
ownsBacking = false;
|
|
34
|
+
};
|
|
35
|
+
animation.afterAddWrite(restoreBacking);
|
|
36
|
+
const destroy = animation.destroy.bind(animation);
|
|
37
|
+
animation.destroy = (...args) => {
|
|
38
|
+
restoreBacking();
|
|
39
|
+
return destroy(...args);
|
|
40
|
+
};
|
|
41
|
+
const buttons = opts.leavingEl?.querySelectorAll(":scope > ion-header.header-translucent ion-buttons, :scope > ion-header.header-translucent ion-toolbar > ion-button");
|
|
42
|
+
if (buttons?.length) animation.addAnimation(createAnimation().addElement(buttons).keyframes([
|
|
43
|
+
{
|
|
44
|
+
offset: 0,
|
|
45
|
+
opacity: 1
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
offset: .5,
|
|
49
|
+
opacity: 0
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
offset: 1,
|
|
53
|
+
opacity: 0
|
|
54
|
+
}
|
|
55
|
+
]));
|
|
56
|
+
return animation;
|
|
57
|
+
});
|
|
18
58
|
//#endregion
|
|
19
59
|
export { iosTransitionAnimation, setConfig, shadow };
|
|
20
60
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios.transition.js","names":[],"sources":["../../src/transition/ios.transition.ts"],"sourcesContent":["import { createIosTransitionAnimation, shadow } from '@rdlabo/ionic-theme-utils';\nimport type { Animation } from '@ionic/core/components';\nimport type { TransitionOptions } from './index';\nimport { getIonPageElement } from './index';\nimport { nativeWebViewMetrics } from '@rdlabo/capacitor-native-ui/integration';\nimport { withNativeUITransition } from './native-ui';\n\nexport { shadow };\n\nexport interface IosTransitionConfig {\n radius: number;\n}\n\nconst transitionConfig = {\n offLeftPercent: 30,\n getIonPageElement,\n shouldAnimateFixedBackButton: (navEl: HTMLElement) => !navEl.closest('ion-app.ios-theme-vertical-bars'),\n get radius() {\n return nativeWebViewMetrics.radius;\n },\n};\n\nexport const setConfig = (config: Partial<IosTransitionConfig>): void => {\n if (config.radius !== undefined) nativeWebViewMetrics.radius = config.radius;\n};\n\nexport const iosTransitionAnimation: (navEl: HTMLElement, opts: TransitionOptions) => Animation = withNativeUITransition(\n
|
|
1
|
+
{"version":3,"file":"ios.transition.js","names":[],"sources":["../../src/transition/ios.transition.ts"],"sourcesContent":["import { createIosTransitionAnimation, shadow } from '@rdlabo/ionic-theme-utils';\nimport { createAnimation } from '@ionic/core/components/index.js';\nimport type { Animation } from '@ionic/core/components';\nimport type { TransitionOptions } from './index';\nimport { getIonPageElement } from './index';\nimport { nativeWebViewMetrics } from '@rdlabo/capacitor-native-ui/integration';\nimport { withNativeUITransition } from './native-ui';\n\nexport { shadow };\n\nexport interface IosTransitionConfig {\n radius: number;\n}\n\nconst transitionConfig = {\n offLeftPercent: 30,\n getIonPageElement,\n shouldAnimateFixedBackButton: (navEl: HTMLElement) => !navEl.closest('ion-app.ios-theme-vertical-bars'),\n get radius() {\n return nativeWebViewMetrics.radius;\n },\n};\n\nexport const setConfig = (config: Partial<IosTransitionConfig>): void => {\n if (config.radius !== undefined) nativeWebViewMetrics.radius = config.radius;\n};\n\nconst buildTransition = createIosTransitionAnimation<TransitionOptions>(transitionConfig);\nexport const iosTransitionAnimation: (navEl: HTMLElement, opts: TransitionOptions) => Animation = withNativeUITransition((navEl, opts) => {\n const animation = buildTransition(navEl, opts);\n const backing = 'var(--ion-background-color, #fff)';\n let ownsBacking = false;\n // Translucent pages expose the outlet as they move. Keep that backing surface\n // in the page theme instead of exposing WKWebView's transparent native backing.\n animation.beforeAddWrite(() => {\n if (navEl.style.backgroundColor) return;\n const style = navEl.ownerDocument.defaultView?.getComputedStyle(navEl);\n if (!style || !['transparent', 'rgba(0, 0, 0, 0)'].includes(style.backgroundColor)) return;\n if (style.backgroundImage && style.backgroundImage !== 'none') return;\n navEl.style.backgroundColor = backing;\n ownsBacking = true;\n });\n const restoreBacking = () => {\n if (ownsBacking && navEl.style.backgroundColor === backing && !navEl.style.getPropertyPriority('background-color'))\n navEl.style.removeProperty('background-color');\n ownsBacking = false;\n };\n animation.afterAddWrite(restoreBacking);\n // Ionic destroy does not run after-write hooks when playback is interrupted.\n const destroy = animation.destroy.bind(animation);\n animation.destroy = (...args) => {\n restoreBacking();\n return destroy(...args);\n };\n // Translucent pages move as a whole, but outgoing toolbar actions still need\n // the same exit fade as opaque headers when they return from native to Web.\n const buttons = opts.leavingEl?.querySelectorAll(\n ':scope > ion-header.header-translucent ion-buttons, :scope > ion-header.header-translucent ion-toolbar > ion-button',\n );\n if (buttons?.length)\n animation.addAnimation(\n createAnimation()\n .addElement(buttons)\n .keyframes([\n { offset: 0, opacity: 1 },\n // Finish the exit before the incoming title occupies this toolbar.\n { offset: 0.5, opacity: 0 },\n { offset: 1, opacity: 0 },\n ]),\n );\n return animation;\n});\n"],"mappings":";;;;;;AAcA,MAAM,mBAAmB;CACvB,gBAAgB;CAChB;CACA,+BAA+B,UAAuB,CAAC,MAAM,QAAQ,iCAAiC;CACtG,IAAI,SAAS;EACX,OAAO,qBAAqB;CAC9B;AACF;AAEA,MAAa,aAAa,WAA+C;CACvE,IAAI,OAAO,WAAW,KAAA,GAAW,qBAAqB,SAAS,OAAO;AACxE;AAEA,MAAM,kBAAkB,6BAAgD,gBAAgB;AACxF,MAAa,yBAAqF,wBAAwB,OAAO,SAAS;CACxI,MAAM,YAAY,gBAAgB,OAAO,IAAI;CAC7C,MAAM,UAAU;CAChB,IAAI,cAAc;CAGlB,UAAU,qBAAqB;EAC7B,IAAI,MAAM,MAAM,iBAAiB;EACjC,MAAM,QAAQ,MAAM,cAAc,aAAa,iBAAiB,KAAK;EACrE,IAAI,CAAC,SAAS,CAAC,CAAC,eAAe,kBAAkB,CAAC,CAAC,SAAS,MAAM,eAAe,GAAG;EACpF,IAAI,MAAM,mBAAmB,MAAM,oBAAoB,QAAQ;EAC/D,MAAM,MAAM,kBAAkB;EAC9B,cAAc;CAChB,CAAC;CACD,MAAM,uBAAuB;EAC3B,IAAI,eAAe,MAAM,MAAM,oBAAoB,WAAW,CAAC,MAAM,MAAM,oBAAoB,kBAAkB,GAC/G,MAAM,MAAM,eAAe,kBAAkB;EAC/C,cAAc;CAChB;CACA,UAAU,cAAc,cAAc;CAEtC,MAAM,UAAU,UAAU,QAAQ,KAAK,SAAS;CAChD,UAAU,WAAW,GAAG,SAAS;EAC/B,eAAe;EACf,OAAO,QAAQ,GAAG,IAAI;CACxB;CAGA,MAAM,UAAU,KAAK,WAAW,iBAC9B,qHACF;CACA,IAAI,SAAS,QACX,UAAU,aACR,gBAAgB,CAAC,CACd,WAAW,OAAO,CAAC,CACnB,UAAU;EACT;GAAE,QAAQ;GAAG,SAAS;EAAE;EAExB;GAAE,QAAQ;GAAK,SAAS;EAAE;EAC1B;GAAE,QAAQ;GAAG,SAAS;EAAE;CAC1B,CAAC,CACL;CACF,OAAO;AACT,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Animation, AnimationBuilder } from "@ionic/core/components";
|
|
2
2
|
//#region src/transition/native-ui.d.ts
|
|
3
3
|
export declare const withNativeUITransition: (builder: AnimationBuilder) => AnimationBuilder;
|
|
4
|
-
export declare const connectNativeUITransition: (animation: Animation, entering: HTMLElement, leaving?: HTMLElement) => void;
|
|
4
|
+
export declare const connectNativeUITransition: (animation: Animation, entering: HTMLElement, leaving?: HTMLElement, direction?: "forward" | "back" | "root") => void;
|
|
5
5
|
//#endregion
|
|
6
6
|
//# sourceMappingURL=native-ui.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-ui.d.ts","names":[],"sources":["../../src/transition/native-ui.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"native-ui.d.ts","names":[],"sources":["../../src/transition/native-ui.ts"],"mappings":";;qBAUa,yBACV,SAAS,qBAAmB;qBAWlB,4BACX,WAAW,WACX,UAAU,aACV,UAAU,aACV"}
|
|
@@ -7,13 +7,13 @@ import { VERTICAL_BARS_TRANSITION_CANCELED, hasNativeUIIntegration, suspendNativ
|
|
|
7
7
|
*/
|
|
8
8
|
const withNativeUITransition = (builder) => (baseEl, opts) => {
|
|
9
9
|
const animation = builder(baseEl, opts);
|
|
10
|
-
if (opts?.enteringEl) connectNativeUITransition(animation, opts.enteringEl, opts.leavingEl);
|
|
10
|
+
if (opts?.enteringEl) connectNativeUITransition(animation, opts.enteringEl, opts.leavingEl, opts.direction);
|
|
11
11
|
return animation;
|
|
12
12
|
};
|
|
13
13
|
const connectedTransitions = /* @__PURE__ */ new WeakSet();
|
|
14
14
|
const cancellationTransitions = /* @__PURE__ */ new WeakSet();
|
|
15
15
|
/** Ionic write hooks cannot await the bridge. Gate playback, including interactive playback. */
|
|
16
|
-
const connectNativeUITransition = (animation, entering, leaving) => {
|
|
16
|
+
const connectNativeUITransition = (animation, entering, leaving, direction) => {
|
|
17
17
|
if (leaving && !cancellationTransitions.has(animation)) {
|
|
18
18
|
cancellationTransitions.add(animation);
|
|
19
19
|
animation.onFinish((step) => {
|
|
@@ -32,16 +32,35 @@ const connectNativeUITransition = (animation, entering, leaving) => {
|
|
|
32
32
|
const progressEnd = animation.progressEnd.bind(animation);
|
|
33
33
|
const destroy = animation.destroy.bind(animation);
|
|
34
34
|
let release;
|
|
35
|
+
let frame = 0;
|
|
36
|
+
const win = entering.ownerDocument.defaultView;
|
|
37
|
+
const webAnimations = (value) => [...value.getWebAnimations(), ...value.childAnimations.flatMap(webAnimations)];
|
|
38
|
+
const track = () => {
|
|
39
|
+
if (!release?.progress || !win) return;
|
|
40
|
+
const sample = () => {
|
|
41
|
+
const progress = webAnimations(animation).map((value) => value.effect?.getComputedTiming().progress).find((value) => value != null);
|
|
42
|
+
if (progress != null) release?.progress?.(progress);
|
|
43
|
+
frame = win.requestAnimationFrame(sample);
|
|
44
|
+
};
|
|
45
|
+
frame = win.requestAnimationFrame(sample);
|
|
46
|
+
};
|
|
35
47
|
let preparation;
|
|
36
48
|
let disposed = false;
|
|
37
49
|
let interactiveReady = false;
|
|
38
50
|
let step;
|
|
39
51
|
let end;
|
|
40
|
-
const prepare = () => preparation ?? (preparation = suspendNativeUI(scopes
|
|
52
|
+
const prepare = (interactive = false) => preparation ?? (preparation = suspendNativeUI(scopes, {
|
|
53
|
+
navigation: true,
|
|
54
|
+
...direction ? { direction } : {},
|
|
55
|
+
...interactive ? { interactive: true } : {}
|
|
56
|
+
}).then((resume) => {
|
|
41
57
|
if (disposed) resume(true);
|
|
42
58
|
else release = resume;
|
|
43
59
|
}));
|
|
44
60
|
const finish = (canceled = false) => {
|
|
61
|
+
if (frame) win?.cancelAnimationFrame(frame);
|
|
62
|
+
frame = 0;
|
|
63
|
+
release?.progress?.(canceled ? 0 : 1);
|
|
45
64
|
release?.(canceled);
|
|
46
65
|
release = void 0;
|
|
47
66
|
preparation = void 0;
|
|
@@ -51,7 +70,9 @@ const connectNativeUITransition = (animation, entering, leaving) => {
|
|
|
51
70
|
await prepare();
|
|
52
71
|
if (disposed) return;
|
|
53
72
|
try {
|
|
54
|
-
|
|
73
|
+
const playing = play(options);
|
|
74
|
+
track();
|
|
75
|
+
await playing;
|
|
55
76
|
} finally {
|
|
56
77
|
finish();
|
|
57
78
|
}
|
|
@@ -60,23 +81,36 @@ const connectNativeUITransition = (animation, entering, leaving) => {
|
|
|
60
81
|
interactiveReady = false;
|
|
61
82
|
step = void 0;
|
|
62
83
|
end = void 0;
|
|
63
|
-
prepare().then(() => {
|
|
84
|
+
prepare(true).then(() => {
|
|
64
85
|
if (disposed) return;
|
|
65
86
|
progressStart(...args);
|
|
87
|
+
track();
|
|
66
88
|
interactiveReady = true;
|
|
67
|
-
if (step !== void 0)
|
|
68
|
-
|
|
89
|
+
if (step !== void 0) {
|
|
90
|
+
progressStep(step);
|
|
91
|
+
release?.progress?.(step);
|
|
92
|
+
}
|
|
93
|
+
if (end) {
|
|
94
|
+
release?.finishGesture?.(end[0] === 1);
|
|
95
|
+
progressEnd(...end);
|
|
96
|
+
}
|
|
69
97
|
});
|
|
70
98
|
return animation;
|
|
71
99
|
};
|
|
72
100
|
animation.progressStep = (value) => {
|
|
73
101
|
step = value;
|
|
74
|
-
if (interactiveReady)
|
|
102
|
+
if (interactiveReady) {
|
|
103
|
+
progressStep(value);
|
|
104
|
+
release?.progress?.(value);
|
|
105
|
+
}
|
|
75
106
|
return animation;
|
|
76
107
|
};
|
|
77
108
|
animation.progressEnd = (...args) => {
|
|
78
109
|
end = args;
|
|
79
|
-
if (interactiveReady)
|
|
110
|
+
if (interactiveReady) {
|
|
111
|
+
release?.finishGesture?.(args[0] === 1);
|
|
112
|
+
progressEnd(...args);
|
|
113
|
+
}
|
|
80
114
|
return animation;
|
|
81
115
|
};
|
|
82
116
|
animation.destroy = (...args) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-ui.js","names":[],"sources":["../../src/transition/native-ui.ts"],"sourcesContent":["import type { Animation } from '@ionic/core/components';\nimport { hasNativeUIIntegration, suspendNativeUI, VERTICAL_BARS_TRANSITION_CANCELED } from '@rdlabo/capacitor-native-ui/integration';\nimport type { AnimationBuilder } from '@ionic/core/components';\n\n/**\n * Keeps an existing Ionic navigation animation and coordinates native control handoff.\n * Register the returned builder as navAnimation. Do not use it for overlay animations.\n * The builder must return a fresh Animation for each navigation; Ionic destroys it afterward.\n */\nexport const withNativeUITransition =\n (builder: AnimationBuilder): AnimationBuilder =>\n (baseEl, opts) => {\n const animation = builder(baseEl, opts);\n if (opts?.enteringEl) connectNativeUITransition(animation, opts.enteringEl, opts.leavingEl);\n return animation;\n };\n\nconst connectedTransitions = new WeakSet<Animation>();\nconst cancellationTransitions = new WeakSet<Animation>();\n\n/** Ionic write hooks cannot await the bridge. Gate playback, including interactive playback. */\nexport const connectNativeUITransition = (animation: Animation
|
|
1
|
+
{"version":3,"file":"native-ui.js","names":[],"sources":["../../src/transition/native-ui.ts"],"sourcesContent":["import type { NativeUITransitionRelease } from '@rdlabo/capacitor-native-ui/integration';\nimport type { Animation } from '@ionic/core/components';\nimport { hasNativeUIIntegration, suspendNativeUI, VERTICAL_BARS_TRANSITION_CANCELED } from '@rdlabo/capacitor-native-ui/integration';\nimport type { AnimationBuilder } from '@ionic/core/components';\n\n/**\n * Keeps an existing Ionic navigation animation and coordinates native control handoff.\n * Register the returned builder as navAnimation. Do not use it for overlay animations.\n * The builder must return a fresh Animation for each navigation; Ionic destroys it afterward.\n */\nexport const withNativeUITransition =\n (builder: AnimationBuilder): AnimationBuilder =>\n (baseEl, opts) => {\n const animation = builder(baseEl, opts);\n if (opts?.enteringEl) connectNativeUITransition(animation, opts.enteringEl, opts.leavingEl, opts.direction);\n return animation;\n };\n\nconst connectedTransitions = new WeakSet<Animation>();\nconst cancellationTransitions = new WeakSet<Animation>();\n\n/** Ionic write hooks cannot await the bridge. Gate playback, including interactive playback. */\nexport const connectNativeUITransition = (\n animation: Animation,\n entering: HTMLElement,\n leaving?: HTMLElement,\n direction?: 'forward' | 'back' | 'root',\n) => {\n if (leaving && !cancellationTransitions.has(animation)) {\n cancellationTransitions.add(animation);\n animation.onFinish((step) => {\n if (step === 0) leaving.dispatchEvent(new CustomEvent(VERTICAL_BARS_TRANSITION_CANCELED, { bubbles: true, detail: { entering } }));\n });\n }\n if (connectedTransitions.has(animation) || !hasNativeUIIntegration(entering.ownerDocument)) return;\n connectedTransitions.add(animation);\n const scopes = leaving ? [entering, leaving] : [entering];\n const play = animation.play.bind(animation);\n const progressStart = animation.progressStart.bind(animation);\n const progressStep = animation.progressStep.bind(animation);\n const progressEnd = animation.progressEnd.bind(animation);\n const destroy = animation.destroy.bind(animation);\n let release: NativeUITransitionRelease | undefined;\n let frame = 0;\n const win = entering.ownerDocument.defaultView;\n const webAnimations = (value: Animation): globalThis.Animation[] => [\n ...value.getWebAnimations(),\n ...value.childAnimations.flatMap(webAnimations),\n ];\n const track = () => {\n if (!release?.progress || !win) return;\n const sample = () => {\n const progress = webAnimations(animation)\n .map((value) => value.effect?.getComputedTiming().progress)\n .find((value) => value != null);\n if (progress != null) release?.progress?.(progress);\n frame = win.requestAnimationFrame(sample);\n };\n frame = win.requestAnimationFrame(sample);\n };\n let preparation: Promise<void> | undefined;\n let disposed = false;\n let interactiveReady = false;\n let step: number | undefined;\n let end: Parameters<Animation['progressEnd']> | undefined;\n const prepare = (interactive = false) =>\n (preparation ??= suspendNativeUI(scopes, {\n navigation: true,\n ...(direction ? { direction } : {}),\n ...(interactive ? { interactive: true } : {}),\n }).then((resume) => {\n if (disposed) resume(true);\n else release = resume;\n }));\n const finish = (canceled = false) => {\n if (frame) win?.cancelAnimationFrame(frame);\n frame = 0;\n release?.progress?.(canceled ? 0 : 1);\n release?.(canceled);\n release = undefined;\n preparation = undefined;\n };\n animation.onFinish((step) => finish(step === 0));\n animation.play = async (options) => {\n await prepare();\n if (disposed) return;\n try {\n const playing = play(options);\n track();\n await playing;\n } finally {\n finish();\n }\n };\n animation.progressStart = (...args) => {\n interactiveReady = false;\n step = undefined;\n end = undefined;\n void prepare(true).then(() => {\n if (disposed) return;\n progressStart(...args);\n track();\n interactiveReady = true;\n if (step !== undefined) {\n progressStep(step);\n release?.progress?.(step);\n }\n if (end) {\n release?.finishGesture?.(end[0] === 1);\n progressEnd(...end);\n }\n });\n return animation;\n };\n animation.progressStep = (value) => {\n step = value;\n if (interactiveReady) {\n progressStep(value);\n release?.progress?.(value);\n }\n return animation;\n };\n animation.progressEnd = (...args) => {\n end = args;\n if (interactiveReady) {\n release?.finishGesture?.(args[0] === 1);\n progressEnd(...args);\n }\n return animation;\n };\n animation.destroy = (...args) => {\n disposed = true;\n finish(true);\n return destroy(...args);\n };\n};\n"],"mappings":";;;;;;;AAUA,MAAa,0BACV,aACA,QAAQ,SAAS;CAChB,MAAM,YAAY,QAAQ,QAAQ,IAAI;CACtC,IAAI,MAAM,YAAY,0BAA0B,WAAW,KAAK,YAAY,KAAK,WAAW,KAAK,SAAS;CAC1G,OAAO;AACT;AAEF,MAAM,uCAAuB,IAAI,QAAmB;AACpD,MAAM,0CAA0B,IAAI,QAAmB;;AAGvD,MAAa,6BACX,WACA,UACA,SACA,cACG;CACH,IAAI,WAAW,CAAC,wBAAwB,IAAI,SAAS,GAAG;EACtD,wBAAwB,IAAI,SAAS;EACrC,UAAU,UAAU,SAAS;GAC3B,IAAI,SAAS,GAAG,QAAQ,cAAc,IAAI,YAAY,mCAAmC;IAAE,SAAS;IAAM,QAAQ,EAAE,SAAS;GAAE,CAAC,CAAC;EACnI,CAAC;CACH;CACA,IAAI,qBAAqB,IAAI,SAAS,KAAK,CAAC,uBAAuB,SAAS,aAAa,GAAG;CAC5F,qBAAqB,IAAI,SAAS;CAClC,MAAM,SAAS,UAAU,CAAC,UAAU,OAAO,IAAI,CAAC,QAAQ;CACxD,MAAM,OAAO,UAAU,KAAK,KAAK,SAAS;CAC1C,MAAM,gBAAgB,UAAU,cAAc,KAAK,SAAS;CAC5D,MAAM,eAAe,UAAU,aAAa,KAAK,SAAS;CAC1D,MAAM,cAAc,UAAU,YAAY,KAAK,SAAS;CACxD,MAAM,UAAU,UAAU,QAAQ,KAAK,SAAS;CAChD,IAAI;CACJ,IAAI,QAAQ;CACZ,MAAM,MAAM,SAAS,cAAc;CACnC,MAAM,iBAAiB,UAA6C,CAClE,GAAG,MAAM,iBAAiB,GAC1B,GAAG,MAAM,gBAAgB,QAAQ,aAAa,CAChD;CACA,MAAM,cAAc;EAClB,IAAI,CAAC,SAAS,YAAY,CAAC,KAAK;EAChC,MAAM,eAAe;GACnB,MAAM,WAAW,cAAc,SAAS,CAAC,CACtC,KAAK,UAAU,MAAM,QAAQ,kBAAkB,CAAC,CAAC,QAAQ,CAAC,CAC1D,MAAM,UAAU,SAAS,IAAI;GAChC,IAAI,YAAY,MAAM,SAAS,WAAW,QAAQ;GAClD,QAAQ,IAAI,sBAAsB,MAAM;EAC1C;EACA,QAAQ,IAAI,sBAAsB,MAAM;CAC1C;CACA,IAAI;CACJ,IAAI,WAAW;CACf,IAAI,mBAAmB;CACvB,IAAI;CACJ,IAAI;CACJ,MAAM,WAAW,cAAc,UAC5B,gBAAA,cAAgB,gBAAgB,QAAQ;EACvC,YAAY;EACZ,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;EACjC,GAAI,cAAc,EAAE,aAAa,KAAK,IAAI,CAAC;CAC7C,CAAC,CAAC,CAAC,MAAM,WAAW;EAClB,IAAI,UAAU,OAAO,IAAI;OACpB,UAAU;CACjB,CAAC;CACH,MAAM,UAAU,WAAW,UAAU;EACnC,IAAI,OAAO,KAAK,qBAAqB,KAAK;EAC1C,QAAQ;EACR,SAAS,WAAW,WAAW,IAAI,CAAC;EACpC,UAAU,QAAQ;EAClB,UAAU,KAAA;EACV,cAAc,KAAA;CAChB;CACA,UAAU,UAAU,SAAS,OAAO,SAAS,CAAC,CAAC;CAC/C,UAAU,OAAO,OAAO,YAAY;EAClC,MAAM,QAAQ;EACd,IAAI,UAAU;EACd,IAAI;GACF,MAAM,UAAU,KAAK,OAAO;GAC5B,MAAM;GACN,MAAM;EACR,UAAU;GACR,OAAO;EACT;CACF;CACA,UAAU,iBAAiB,GAAG,SAAS;EACrC,mBAAmB;EACnB,OAAO,KAAA;EACP,MAAM,KAAA;EACN,QAAa,IAAI,CAAC,CAAC,WAAW;GAC5B,IAAI,UAAU;GACd,cAAc,GAAG,IAAI;GACrB,MAAM;GACN,mBAAmB;GACnB,IAAI,SAAS,KAAA,GAAW;IACtB,aAAa,IAAI;IACjB,SAAS,WAAW,IAAI;GAC1B;GACA,IAAI,KAAK;IACP,SAAS,gBAAgB,IAAI,OAAO,CAAC;IACrC,YAAY,GAAG,GAAG;GACpB;EACF,CAAC;EACD,OAAO;CACT;CACA,UAAU,gBAAgB,UAAU;EAClC,OAAO;EACP,IAAI,kBAAkB;GACpB,aAAa,KAAK;GAClB,SAAS,WAAW,KAAK;EAC3B;EACA,OAAO;CACT;CACA,UAAU,eAAe,GAAG,SAAS;EACnC,MAAM;EACN,IAAI,kBAAkB;GACpB,SAAS,gBAAgB,KAAK,OAAO,CAAC;GACtC,YAAY,GAAG,IAAI;EACrB;EACA,OAAO;CACT;CACA,UAAU,WAAW,GAAG,SAAS;EAC/B,WAAW;EACX,OAAO,IAAI;EACX,OAAO,QAAQ,GAAG,IAAI;CACxB;AACF"}
|
package/docs/features.md
CHANGED
|
@@ -31,9 +31,9 @@ ion-textarea label.textarea-wrapper {
|
|
|
31
31
|
}
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
## Native UI
|
|
34
|
+
## Native UI
|
|
35
35
|
|
|
36
|
-
Once your theme is working, [add Native UI](add-native-ui.md) to render supported fixed controls with UIKit and SwiftUI on iOS. Keep theme styles for Web content and fallback controls. Native UI is
|
|
36
|
+
Once your theme is working, [add Native UI](add-native-ui.md) to render supported fixed controls with UIKit and SwiftUI on iOS. Keep theme styles for Web content and fallback controls. Native UI is officially supported starting with 2.0.0 and remains opt-in; adding styles alone does not enable it.
|
|
37
37
|
|
|
38
38
|
## Selective component imports
|
|
39
39
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rdlabo/ionic-theme-ios27",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.1-beta.pr320.sha1504df298a37",
|
|
5
5
|
"description": "iOS27 Theme for Ionic Framework",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"homepage": "https://docs.rdlabo.dev/projects/ionic-theme-ios27",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@rdlabo/capacitor-native-ui": "2.0.
|
|
49
|
+
"@rdlabo/capacitor-native-ui": "2.0.1-beta.pr320.sha1504df298a37",
|
|
50
50
|
"@rdlabo/ionic-theme-utils": "0.1.5",
|
|
51
51
|
"@stencil/core": "^4.43.5",
|
|
52
52
|
"ionicons": "^8.1.0"
|
|
@@ -101,8 +101,8 @@ ion-app.ios-theme-vertical-bars
|
|
|
101
101
|
display: none;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
//
|
|
105
|
-
&:not(:where(ion-
|
|
104
|
+
// Scrolling toolbars already sit inside the padded ion-content scroll area.
|
|
105
|
+
&:not(:where(ion-content *)) {
|
|
106
106
|
// Ionic's centered iOS title is absolute and does not follow container padding.
|
|
107
107
|
// Center it within the same foreground width as the page content.
|
|
108
108
|
> ion-title.ios.title-default:not(.ios-theme-disabled, .ios26-disabled) {
|
|
@@ -313,8 +313,10 @@ html.native-ui-prehide
|
|
|
313
313
|
ion-menu *,
|
|
314
314
|
ion-modal *,
|
|
315
315
|
ion-popover *,
|
|
316
|
-
ion-header[collapse] *,
|
|
317
|
-
ion-
|
|
316
|
+
ion-header[collapse='condense'] *,
|
|
317
|
+
ion-header.header-collapse-condense *,
|
|
318
|
+
ion-content ion-header *,
|
|
319
|
+
ion-content ion-footer *,
|
|
318
320
|
ion-buttons.ios-theme-horizontal-only *,
|
|
319
321
|
.native-ui-disabled *,
|
|
320
322
|
[data-native-ui='disabled'] *,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createIosTransitionAnimation, shadow } from '@rdlabo/ionic-theme-utils';
|
|
2
|
+
import { createAnimation } from '@ionic/core/components/index.js';
|
|
2
3
|
import type { Animation } from '@ionic/core/components';
|
|
3
4
|
import type { TransitionOptions } from './index';
|
|
4
5
|
import { getIonPageElement } from './index';
|
|
@@ -24,6 +25,48 @@ export const setConfig = (config: Partial<IosTransitionConfig>): void => {
|
|
|
24
25
|
if (config.radius !== undefined) nativeWebViewMetrics.radius = config.radius;
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
28
|
+
const buildTransition = createIosTransitionAnimation<TransitionOptions>(transitionConfig);
|
|
29
|
+
export const iosTransitionAnimation: (navEl: HTMLElement, opts: TransitionOptions) => Animation = withNativeUITransition((navEl, opts) => {
|
|
30
|
+
const animation = buildTransition(navEl, opts);
|
|
31
|
+
const backing = 'var(--ion-background-color, #fff)';
|
|
32
|
+
let ownsBacking = false;
|
|
33
|
+
// Translucent pages expose the outlet as they move. Keep that backing surface
|
|
34
|
+
// in the page theme instead of exposing WKWebView's transparent native backing.
|
|
35
|
+
animation.beforeAddWrite(() => {
|
|
36
|
+
if (navEl.style.backgroundColor) return;
|
|
37
|
+
const style = navEl.ownerDocument.defaultView?.getComputedStyle(navEl);
|
|
38
|
+
if (!style || !['transparent', 'rgba(0, 0, 0, 0)'].includes(style.backgroundColor)) return;
|
|
39
|
+
if (style.backgroundImage && style.backgroundImage !== 'none') return;
|
|
40
|
+
navEl.style.backgroundColor = backing;
|
|
41
|
+
ownsBacking = true;
|
|
42
|
+
});
|
|
43
|
+
const restoreBacking = () => {
|
|
44
|
+
if (ownsBacking && navEl.style.backgroundColor === backing && !navEl.style.getPropertyPriority('background-color'))
|
|
45
|
+
navEl.style.removeProperty('background-color');
|
|
46
|
+
ownsBacking = false;
|
|
47
|
+
};
|
|
48
|
+
animation.afterAddWrite(restoreBacking);
|
|
49
|
+
// Ionic destroy does not run after-write hooks when playback is interrupted.
|
|
50
|
+
const destroy = animation.destroy.bind(animation);
|
|
51
|
+
animation.destroy = (...args) => {
|
|
52
|
+
restoreBacking();
|
|
53
|
+
return destroy(...args);
|
|
54
|
+
};
|
|
55
|
+
// Translucent pages move as a whole, but outgoing toolbar actions still need
|
|
56
|
+
// the same exit fade as opaque headers when they return from native to Web.
|
|
57
|
+
const buttons = opts.leavingEl?.querySelectorAll(
|
|
58
|
+
':scope > ion-header.header-translucent ion-buttons, :scope > ion-header.header-translucent ion-toolbar > ion-button',
|
|
59
|
+
);
|
|
60
|
+
if (buttons?.length)
|
|
61
|
+
animation.addAnimation(
|
|
62
|
+
createAnimation()
|
|
63
|
+
.addElement(buttons)
|
|
64
|
+
.keyframes([
|
|
65
|
+
{ offset: 0, opacity: 1 },
|
|
66
|
+
// Finish the exit before the incoming title occupies this toolbar.
|
|
67
|
+
{ offset: 0.5, opacity: 0 },
|
|
68
|
+
{ offset: 1, opacity: 0 },
|
|
69
|
+
]),
|
|
70
|
+
);
|
|
71
|
+
return animation;
|
|
72
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { NativeUITransitionRelease } from '@rdlabo/capacitor-native-ui/integration';
|
|
1
2
|
import type { Animation } from '@ionic/core/components';
|
|
2
3
|
import { hasNativeUIIntegration, suspendNativeUI, VERTICAL_BARS_TRANSITION_CANCELED } from '@rdlabo/capacitor-native-ui/integration';
|
|
3
4
|
import type { AnimationBuilder } from '@ionic/core/components';
|
|
@@ -11,7 +12,7 @@ export const withNativeUITransition =
|
|
|
11
12
|
(builder: AnimationBuilder): AnimationBuilder =>
|
|
12
13
|
(baseEl, opts) => {
|
|
13
14
|
const animation = builder(baseEl, opts);
|
|
14
|
-
if (opts?.enteringEl) connectNativeUITransition(animation, opts.enteringEl, opts.leavingEl);
|
|
15
|
+
if (opts?.enteringEl) connectNativeUITransition(animation, opts.enteringEl, opts.leavingEl, opts.direction);
|
|
15
16
|
return animation;
|
|
16
17
|
};
|
|
17
18
|
|
|
@@ -19,7 +20,12 @@ const connectedTransitions = new WeakSet<Animation>();
|
|
|
19
20
|
const cancellationTransitions = new WeakSet<Animation>();
|
|
20
21
|
|
|
21
22
|
/** Ionic write hooks cannot await the bridge. Gate playback, including interactive playback. */
|
|
22
|
-
export const connectNativeUITransition = (
|
|
23
|
+
export const connectNativeUITransition = (
|
|
24
|
+
animation: Animation,
|
|
25
|
+
entering: HTMLElement,
|
|
26
|
+
leaving?: HTMLElement,
|
|
27
|
+
direction?: 'forward' | 'back' | 'root',
|
|
28
|
+
) => {
|
|
23
29
|
if (leaving && !cancellationTransitions.has(animation)) {
|
|
24
30
|
cancellationTransitions.add(animation);
|
|
25
31
|
animation.onFinish((step) => {
|
|
@@ -34,18 +40,42 @@ export const connectNativeUITransition = (animation: Animation, entering: HTMLEl
|
|
|
34
40
|
const progressStep = animation.progressStep.bind(animation);
|
|
35
41
|
const progressEnd = animation.progressEnd.bind(animation);
|
|
36
42
|
const destroy = animation.destroy.bind(animation);
|
|
37
|
-
let release:
|
|
43
|
+
let release: NativeUITransitionRelease | undefined;
|
|
44
|
+
let frame = 0;
|
|
45
|
+
const win = entering.ownerDocument.defaultView;
|
|
46
|
+
const webAnimations = (value: Animation): globalThis.Animation[] => [
|
|
47
|
+
...value.getWebAnimations(),
|
|
48
|
+
...value.childAnimations.flatMap(webAnimations),
|
|
49
|
+
];
|
|
50
|
+
const track = () => {
|
|
51
|
+
if (!release?.progress || !win) return;
|
|
52
|
+
const sample = () => {
|
|
53
|
+
const progress = webAnimations(animation)
|
|
54
|
+
.map((value) => value.effect?.getComputedTiming().progress)
|
|
55
|
+
.find((value) => value != null);
|
|
56
|
+
if (progress != null) release?.progress?.(progress);
|
|
57
|
+
frame = win.requestAnimationFrame(sample);
|
|
58
|
+
};
|
|
59
|
+
frame = win.requestAnimationFrame(sample);
|
|
60
|
+
};
|
|
38
61
|
let preparation: Promise<void> | undefined;
|
|
39
62
|
let disposed = false;
|
|
40
63
|
let interactiveReady = false;
|
|
41
64
|
let step: number | undefined;
|
|
42
65
|
let end: Parameters<Animation['progressEnd']> | undefined;
|
|
43
|
-
const prepare = () =>
|
|
44
|
-
(preparation ??= suspendNativeUI(scopes
|
|
66
|
+
const prepare = (interactive = false) =>
|
|
67
|
+
(preparation ??= suspendNativeUI(scopes, {
|
|
68
|
+
navigation: true,
|
|
69
|
+
...(direction ? { direction } : {}),
|
|
70
|
+
...(interactive ? { interactive: true } : {}),
|
|
71
|
+
}).then((resume) => {
|
|
45
72
|
if (disposed) resume(true);
|
|
46
73
|
else release = resume;
|
|
47
74
|
}));
|
|
48
75
|
const finish = (canceled = false) => {
|
|
76
|
+
if (frame) win?.cancelAnimationFrame(frame);
|
|
77
|
+
frame = 0;
|
|
78
|
+
release?.progress?.(canceled ? 0 : 1);
|
|
49
79
|
release?.(canceled);
|
|
50
80
|
release = undefined;
|
|
51
81
|
preparation = undefined;
|
|
@@ -55,7 +85,9 @@ export const connectNativeUITransition = (animation: Animation, entering: HTMLEl
|
|
|
55
85
|
await prepare();
|
|
56
86
|
if (disposed) return;
|
|
57
87
|
try {
|
|
58
|
-
|
|
88
|
+
const playing = play(options);
|
|
89
|
+
track();
|
|
90
|
+
await playing;
|
|
59
91
|
} finally {
|
|
60
92
|
finish();
|
|
61
93
|
}
|
|
@@ -64,23 +96,36 @@ export const connectNativeUITransition = (animation: Animation, entering: HTMLEl
|
|
|
64
96
|
interactiveReady = false;
|
|
65
97
|
step = undefined;
|
|
66
98
|
end = undefined;
|
|
67
|
-
void prepare().then(() => {
|
|
99
|
+
void prepare(true).then(() => {
|
|
68
100
|
if (disposed) return;
|
|
69
101
|
progressStart(...args);
|
|
102
|
+
track();
|
|
70
103
|
interactiveReady = true;
|
|
71
|
-
if (step !== undefined)
|
|
72
|
-
|
|
104
|
+
if (step !== undefined) {
|
|
105
|
+
progressStep(step);
|
|
106
|
+
release?.progress?.(step);
|
|
107
|
+
}
|
|
108
|
+
if (end) {
|
|
109
|
+
release?.finishGesture?.(end[0] === 1);
|
|
110
|
+
progressEnd(...end);
|
|
111
|
+
}
|
|
73
112
|
});
|
|
74
113
|
return animation;
|
|
75
114
|
};
|
|
76
115
|
animation.progressStep = (value) => {
|
|
77
116
|
step = value;
|
|
78
|
-
if (interactiveReady)
|
|
117
|
+
if (interactiveReady) {
|
|
118
|
+
progressStep(value);
|
|
119
|
+
release?.progress?.(value);
|
|
120
|
+
}
|
|
79
121
|
return animation;
|
|
80
122
|
};
|
|
81
123
|
animation.progressEnd = (...args) => {
|
|
82
124
|
end = args;
|
|
83
|
-
if (interactiveReady)
|
|
125
|
+
if (interactiveReady) {
|
|
126
|
+
release?.finishGesture?.(args[0] === 1);
|
|
127
|
+
progressEnd(...args);
|
|
128
|
+
}
|
|
84
129
|
return animation;
|
|
85
130
|
};
|
|
86
131
|
animation.destroy = (...args) => {
|