@rdlabo/ionic-theme-ios27 1.2.0-beta.pr242.sha99c4a2ec4d6a → 1.2.0-beta.pr246.sha237333ceac21
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 +8 -7
- package/dist/css/ionic-theme-ios27.css +1 -1
- package/dist/css/vertical-bars.css +1 -1
- package/dist/native/components/ion-buttons.js +1 -1
- package/dist/native/components/ion-buttons.js.map +1 -1
- package/dist/native/components/ion-menu-button.d.ts +2 -1
- package/dist/native/components/ion-menu-button.d.ts.map +1 -1
- package/dist/native/components/ion-menu-button.js +2 -2
- package/dist/native/components/ion-menu-button.js.map +1 -1
- package/dist/native/definitions.d.ts +1 -0
- package/dist/native/definitions.d.ts.map +1 -1
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +4 -3
- package/dist/native/index.js.map +1 -1
- package/dist/native/prehide.js +2 -0
- package/dist/native/prehide.js.map +1 -1
- package/dist/native/shared/candidate.d.ts +1 -0
- package/dist/native/shared/candidate.d.ts.map +1 -1
- package/dist/native/shared/candidate.js +7 -2
- package/dist/native/shared/candidate.js.map +1 -1
- package/dist/native/shared/dom.d.ts +1 -1
- package/dist/native/shared/dom.js +4 -4
- package/dist/native/shared/dom.js.map +1 -1
- package/docs/features.md +2 -2
- package/docs/iphone-duo-with-original-theme.md +20 -18
- package/docs/iphone-duo.md +11 -158
- package/docs/native-ui-shell.md +15 -13
- package/docs/special-markup.md +4 -2
- package/docs/vertical-bars.md +283 -0
- package/package.json +2 -2
- package/src/native/components/ion-buttons.ts +1 -1
- package/src/native/components/ion-menu-button.ts +3 -2
- package/src/native/definitions.ts +14 -6
- package/src/native/index.ts +5 -3
- package/src/native/prehide.ts +3 -1
- package/src/native/shared/candidate.ts +21 -2
- package/src/native/shared/dom.ts +4 -4
- package/src/styles/vertical-bars.scss +3 -2
|
@@ -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(: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)}.ios-theme-native-ui-shell-prehidden{position:absolute !important;visibility:hidden !important}html.ios-theme-native-ui-shell-prehide ion-app.ios-theme-vertical-bars ion-back-button:not([icon],[color],.ios-theme-vertical-bars-back-web-owned,.ionic-theme-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 *,.ios-theme-shell-disabled *,.ionic-theme-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-shell]: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-shell]: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-shell]: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-shell]: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-shell]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-shell]))),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-shell]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-shell]))){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%}
|
|
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(: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)}.ios-theme-native-ui-shell-prehidden{position:absolute !important;visibility:hidden !important}html.ios-theme-native-ui-shell-prehide ion-app.ios-theme-vertical-bars ion-back-button:not([icon],[color],.ios-theme-vertical-bars-back-web-owned,.ios-theme-shell-disabled,[data-shell=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 *,.ios-theme-shell-disabled *,[data-shell=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-shell]: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-shell]: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-shell]: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-shell]: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-shell]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-shell]))),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-shell]):not(:has(>:is(ion-back-button,ion-button,ion-menu-button):not([data-native-ui-shell]))){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%}
|
|
@@ -14,7 +14,7 @@ const tracksMotion = true;
|
|
|
14
14
|
const read = (element, id, options = {}) => {
|
|
15
15
|
if (!inFixedToolbar(element)) return;
|
|
16
16
|
let children = childElements(element);
|
|
17
|
-
if (children.length === 1) return read$1(element, id);
|
|
17
|
+
if (children.length === 1) return read$1(element, id, options);
|
|
18
18
|
const verticalBars = !element.closest("ion-menu, ion-popover") && modalUsesVerticalBars(element) && !!element.closest("ion-app.ios-theme-vertical-bars");
|
|
19
19
|
if (verticalBars && !isVerticalBarsToolbarGroup(element)) return;
|
|
20
20
|
if (verticalBars) children = verticalBarsToolbarActions(element);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ion-buttons.js","names":["menuButton.read","menuButton.append"],"sources":["../../../src/native/components/ion-buttons.ts"],"sourcesContent":["import type { VerticalControlAreaOptions } from '../definitions';\nimport { modalUsesVerticalBars } from '../shared/modal';\nimport { createCandidate, appendItem } from '../shared/candidate';\nimport type { Candidate, Identify } from '../shared/candidate';\nimport { childElements, verticalBarsToolbarActions, inFixedToolbar, isVerticalBarsToolbarGroup } from '../shared/dom';\nimport * as menuButton from './ion-menu-button';\n\nexport const tag = 'ion-buttons';\nexport const tracksMotion = true;\n\nexport const read = (element: HTMLElement, id: Identify, options: VerticalControlAreaOptions = {}): Candidate | undefined => {\n if (!inFixedToolbar(element)) return;\n let children = childElements(element);\n if (children.length === 1) return menuButton.read(element, id);\n const verticalBars =\n !element.closest('ion-menu, ion-popover') && modalUsesVerticalBars(element) && !!element.closest('ion-app.ios-theme-vertical-bars');\n if (verticalBars && !isVerticalBarsToolbarGroup(element)) return;\n if (verticalBars) children = verticalBarsToolbarActions(element);\n if (\n !children.length ||\n children.some(\n (child) =>\n !child.matches(`${menuButton.tag}${verticalBars ? '' : '.ios'}`) &&\n (!child.matches(`ion-button${verticalBars ? '' : '.ios.button-clear'}`) ||\n (!verticalBars && (child as HTMLIonButtonElement).fill !== 'clear')),\n )\n )\n return;\n const candidate = createCandidate(element, tag, id, options);\n if (verticalBars && children.length !== childElements(element).length) candidate.sources = children;\n for (const child of children) {\n const supported = child.matches(menuButton.tag)\n ? menuButton.append(candidate, child as HTMLIonMenuButtonElement, id)\n : appendItem(candidate, child, id);\n if (!supported) return;\n }\n return candidate;\n};\n"],"mappings":";;;;;;;;;;;AAOA,MAAa,MAAM;AACnB,MAAa,eAAe;AAE5B,MAAa,QAAQ,SAAsB,IAAc,UAAsC,CAAC,MAA6B;CAC3H,IAAI,CAAC,eAAe,OAAO,GAAG;CAC9B,IAAI,WAAW,cAAc,OAAO;CACpC,IAAI,SAAS,WAAW,GAAG,OAAOA,OAAgB,SAAS,
|
|
1
|
+
{"version":3,"file":"ion-buttons.js","names":["menuButton.read","menuButton.append"],"sources":["../../../src/native/components/ion-buttons.ts"],"sourcesContent":["import type { VerticalControlAreaOptions } from '../definitions';\nimport { modalUsesVerticalBars } from '../shared/modal';\nimport { createCandidate, appendItem } from '../shared/candidate';\nimport type { Candidate, Identify } from '../shared/candidate';\nimport { childElements, verticalBarsToolbarActions, inFixedToolbar, isVerticalBarsToolbarGroup } from '../shared/dom';\nimport * as menuButton from './ion-menu-button';\n\nexport const tag = 'ion-buttons';\nexport const tracksMotion = true;\n\nexport const read = (element: HTMLElement, id: Identify, options: VerticalControlAreaOptions = {}): Candidate | undefined => {\n if (!inFixedToolbar(element)) return;\n let children = childElements(element);\n if (children.length === 1) return menuButton.read(element, id, options);\n const verticalBars =\n !element.closest('ion-menu, ion-popover') && modalUsesVerticalBars(element) && !!element.closest('ion-app.ios-theme-vertical-bars');\n if (verticalBars && !isVerticalBarsToolbarGroup(element)) return;\n if (verticalBars) children = verticalBarsToolbarActions(element);\n if (\n !children.length ||\n children.some(\n (child) =>\n !child.matches(`${menuButton.tag}${verticalBars ? '' : '.ios'}`) &&\n (!child.matches(`ion-button${verticalBars ? '' : '.ios.button-clear'}`) ||\n (!verticalBars && (child as HTMLIonButtonElement).fill !== 'clear')),\n )\n )\n return;\n const candidate = createCandidate(element, tag, id, options);\n if (verticalBars && children.length !== childElements(element).length) candidate.sources = children;\n for (const child of children) {\n const supported = child.matches(menuButton.tag)\n ? menuButton.append(candidate, child as HTMLIonMenuButtonElement, id)\n : appendItem(candidate, child, id);\n if (!supported) return;\n }\n return candidate;\n};\n"],"mappings":";;;;;;;;;;;AAOA,MAAa,MAAM;AACnB,MAAa,eAAe;AAE5B,MAAa,QAAQ,SAAsB,IAAc,UAAsC,CAAC,MAA6B;CAC3H,IAAI,CAAC,eAAe,OAAO,GAAG;CAC9B,IAAI,WAAW,cAAc,OAAO;CACpC,IAAI,SAAS,WAAW,GAAG,OAAOA,OAAgB,SAAS,IAAI,OAAO;CACtE,MAAM,eACJ,CAAC,QAAQ,QAAQ,uBAAuB,KAAK,sBAAsB,OAAO,KAAK,CAAC,CAAC,QAAQ,QAAQ,iCAAiC;CACpI,IAAI,gBAAgB,CAAC,2BAA2B,OAAO,GAAG;CAC1D,IAAI,cAAc,WAAW,2BAA2B,OAAO;CAC/D,IACE,CAAC,SAAS,UACV,SAAS,MACN,UACC,CAAC,MAAM,QAAQ,kBAAoB,eAAe,KAAK,QAAQ,MAC9D,CAAC,MAAM,QAAQ,aAAa,eAAe,KAAK,qBAAqB,KACnE,CAAC,gBAAiB,MAA+B,SAAS,QACjE,GAEA;CACF,MAAM,YAAY,gBAAgB,SAAS,KAAK,IAAI,OAAO;CAC3D,IAAI,gBAAgB,SAAS,WAAW,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,UAAU;CAC3F,KAAK,MAAM,SAAS,UAIlB,IAAI,EAHc,MAAM,QAAQ,iBAAc,IAC1CC,OAAkB,WAAW,OAAmC,EAAE,IAClE,WAAW,WAAW,OAAO,EAAE,IACnB;CAElB,OAAO;AACT"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VerticalControlAreaOptions } from "../definitions.js";
|
|
1
2
|
import { Candidate, Identify } from "../shared/candidate.js";
|
|
2
3
|
declare namespace ion_menu_button_d_exports {
|
|
3
4
|
export { append, read, selector, shadowSelector, tag };
|
|
@@ -6,7 +7,7 @@ export declare const tag = "ion-menu-button";
|
|
|
6
7
|
export declare const selector = "";
|
|
7
8
|
export declare const shadowSelector = "ion-menu-button";
|
|
8
9
|
export declare const append: (candidate: Candidate, button: HTMLIonMenuButtonElement, id: Identify) => boolean;
|
|
9
|
-
export declare const read: (group: HTMLElement, id: Identify) => Candidate | undefined;
|
|
10
|
+
export declare const read: (group: HTMLElement, id: Identify, options?: VerticalControlAreaOptions) => Candidate | undefined;
|
|
10
11
|
//#endregion
|
|
11
12
|
export { ion_menu_button_d_exports };
|
|
12
13
|
//# sourceMappingURL=ion-menu-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ion-menu-button.d.ts","names":[],"sources":["../../../src/native/components/ion-menu-button.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ion-menu-button.d.ts","names":[],"sources":["../../../src/native/components/ion-menu-button.ts"],"mappings":";;;;;qBAKa;qBAEA;qBACA;qBAEA,SAAU,WAAW,WAAW,QAAQ,0BAA0B,IAAI;qBAMtE,OAAQ,OAAO,aAAa,IAAI,UAAU,UAAS,+BAAkC"}
|
|
@@ -17,12 +17,12 @@ const append = (candidate, button, id) => {
|
|
|
17
17
|
const content = !button.shadowRoot?.querySelector("slot")?.assignedNodes().length ? button.shadowRoot : button;
|
|
18
18
|
return !!content && !!appendItem(candidate, button, id, content);
|
|
19
19
|
};
|
|
20
|
-
const read = (group, id) => {
|
|
20
|
+
const read = (group, id, options = {}) => {
|
|
21
21
|
const children = group.matches("ion-buttons") ? childElements(group) : [];
|
|
22
22
|
if (!inFixedToolbar(group) || children.length !== 1) return;
|
|
23
23
|
const button = children[0];
|
|
24
24
|
if (!button?.matches(`ion-menu-button${group.closest("ion-app.ios-theme-vertical-bars") ? "" : ".ios"}`)) return;
|
|
25
|
-
const candidate = createCandidate(group, tag, id);
|
|
25
|
+
const candidate = createCandidate(group, tag, id, options);
|
|
26
26
|
return append(candidate, button, id) ? candidate : void 0;
|
|
27
27
|
};
|
|
28
28
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ion-menu-button.js","names":[],"sources":["../../../src/native/components/ion-menu-button.ts"],"sourcesContent":["import { createCandidate, appendItem } from '../shared/candidate';\nimport type { Candidate, Identify } from '../shared/candidate';\nimport { childElements, inFixedToolbar } from '../shared/dom';\n\nexport const tag = 'ion-menu-button';\n// The glass and projection ownership belong to ion-buttons, even for one menu button.\nexport const selector = '';\nexport const shadowSelector = tag;\n\nexport const append = (candidate: Candidate, button: HTMLIonMenuButtonElement, id: Identify): boolean => {\n if (button.type !== 'button') return false;\n const content = !button.shadowRoot?.querySelector('slot')?.assignedNodes().length ? button.shadowRoot : button;\n return !!content && !!appendItem(candidate, button, id, content);\n};\n\nexport const read = (group: HTMLElement, id: Identify): Candidate | undefined => {\n const children = group.matches('ion-buttons') ? childElements(group) : [];\n if (!inFixedToolbar(group) || children.length !== 1) return;\n const button = children[0];\n if (!button?.matches(`${tag}${group.closest('ion-app.ios-theme-vertical-bars') ? '' : '.ios'}`)) return;\n const candidate = createCandidate(group, tag, id);\n return append(candidate, button as HTMLIonMenuButtonElement, id) ? candidate : undefined;\n};\n"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"ion-menu-button.js","names":[],"sources":["../../../src/native/components/ion-menu-button.ts"],"sourcesContent":["import { createCandidate, appendItem } from '../shared/candidate';\nimport type { Candidate, Identify } from '../shared/candidate';\nimport type { VerticalControlAreaOptions } from '../definitions';\nimport { childElements, inFixedToolbar } from '../shared/dom';\n\nexport const tag = 'ion-menu-button';\n// The glass and projection ownership belong to ion-buttons, even for one menu button.\nexport const selector = '';\nexport const shadowSelector = tag;\n\nexport const append = (candidate: Candidate, button: HTMLIonMenuButtonElement, id: Identify): boolean => {\n if (button.type !== 'button') return false;\n const content = !button.shadowRoot?.querySelector('slot')?.assignedNodes().length ? button.shadowRoot : button;\n return !!content && !!appendItem(candidate, button, id, content);\n};\n\nexport const read = (group: HTMLElement, id: Identify, options: VerticalControlAreaOptions = {}): Candidate | undefined => {\n const children = group.matches('ion-buttons') ? childElements(group) : [];\n if (!inFixedToolbar(group) || children.length !== 1) return;\n const button = children[0];\n if (!button?.matches(`${tag}${group.closest('ion-app.ios-theme-vertical-bars') ? '' : '.ios'}`)) return;\n const candidate = createCandidate(group, tag, id, options);\n return append(candidate, button as HTMLIonMenuButtonElement, id) ? candidate : undefined;\n};\n"],"mappings":";;;;;;;;;;;AAKA,MAAa,MAAM;AAEnB,MAAa,WAAW;AACxB,MAAa,iBAAiB;AAE9B,MAAa,UAAU,WAAsB,QAAkC,OAA0B;CACvG,IAAI,OAAO,SAAS,UAAU,OAAO;CACrC,MAAM,UAAU,CAAC,OAAO,YAAY,cAAc,MAAM,CAAC,EAAE,cAAc,CAAC,CAAC,SAAS,OAAO,aAAa;CACxG,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,WAAW,WAAW,QAAQ,IAAI,OAAO;AACjE;AAEA,MAAa,QAAQ,OAAoB,IAAc,UAAsC,CAAC,MAA6B;CACzH,MAAM,WAAW,MAAM,QAAQ,aAAa,IAAI,cAAc,KAAK,IAAI,CAAC;CACxE,IAAI,CAAC,eAAe,KAAK,KAAK,SAAS,WAAW,GAAG;CACrD,MAAM,SAAS,SAAS;CACxB,IAAI,CAAC,QAAQ,QAAQ,kBAAS,MAAM,QAAQ,iCAAiC,IAAI,KAAK,QAAQ,GAAG;CACjG,MAAM,YAAY,gBAAgB,OAAO,KAAK,IAAI,OAAO;CACzD,OAAO,OAAO,WAAW,QAAoC,EAAE,IAAI,YAAY,KAAA;AACjF"}
|
|
@@ -8,6 +8,7 @@ export interface NativeUIShellStatus {
|
|
|
8
8
|
reason?: string;
|
|
9
9
|
}
|
|
10
10
|
export interface VerticalControlAreaOptions {
|
|
11
|
+
buttonProjection?: 'source' | 'system';
|
|
11
12
|
buttonDefaultFill?: 'solid' | null;
|
|
12
13
|
}
|
|
13
14
|
export interface NativeUIShellOptions extends VerticalControlAreaOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","names":[],"sources":["../../src/native/definitions.ts"],"mappings":";;;iBAKiB;EACf;EACA;EACA;EACA;;iBAGe;
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","names":[],"sources":["../../src/native/definitions.ts"],"mappings":";;;iBAKiB;EACf;EACA;EACA;EACA;;iBAGe;EASf;EAOA;;iBAGe,6BAA6B;EAE5C;EAEA,WAAW;EAEX;;iBAGe;EAEf;EAEA;EAEA;EAEA;;iBAGe;EAEf,aAAa;EAEb,WAAW,QAAQ;EAEnB,WAAW;;YAID;iBAEK;EACf,MAAM;EAEN;EAEA,aAAa;;iBAGE,kCAAkC;EAEjD,aAAa,WAAW,kBAAkB,sBAAsB;;iBAGjD;EAEf,UAAU;;iBAGK;EACf;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;;iBAGe,kBAAkB;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe,qBAAqB;EACpC;EACA,MAAM;EAEN;EAEA;EACA,OAAO;EACP;EACA;EACA;IAAiB;IAAgB;;EACjC,SAAS;;iBAGM;EACf;EACA,OAAO;EACP,SAAS;EACT;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe,yBAAyB;EACxC;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;EAEA;EAEA,mBAAmB;EACnB,UAAU;;iBAGK;EACf;EACA;EACA;;iBAGe;EAEf;;iBAGe;EACf,UAAU;IAAY;MAA+B;IAAU;;EAC/D,qBAAqB,QAAQ;EAC7B,OAAO,UAAU,gBAAgB;IAAU;IAAkB;IAA6B;;EAC1F,MAAM;IAAW;MAAqB;EACtC,YAAY,kBAAkB,WAAW,OAAO,2BAA2B,QAAQ;EACnF,YAAY,gBAAgB,WAAW,OAAO,4BAA4B,QAAQ;EAClF,YAAY,8BAA8B,WAAW,OAAO,0BAA0B,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/native/index.ts"],"mappings":";;;qBA+Ba,oBAAkB;qBAoElB,iCAAsC,QAAQ;qBAiD9C,kCAAmC,WAAW,kBAAkB,sBAAsB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/native/index.ts"],"mappings":";;;qBA+Ba,oBAAkB;qBAoElB,iCAAsC,QAAQ;qBAiD9C,kCAAmC,WAAW,kBAAkB,sBAAsB;qBAqBtF,4BAAmC,UAAS,+BAAkC,QAAQ;qBAgBtF,sBAAuB,UAAS,yBAA4B,QAAQ"}
|
package/dist/native/index.js
CHANGED
|
@@ -130,12 +130,12 @@ const setVerticalControlAreaPlacement = (placement, rtl) => {
|
|
|
130
130
|
};
|
|
131
131
|
/**
|
|
132
132
|
* Call once after ion-app is mounted. Ionic markup remains the source of truth.
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* This default affects native vertical projection only; explicit button fills win.
|
|
133
|
+
* Native vertical buttons default to SwiftUI appearance.
|
|
134
|
+
* See VerticalControlAreaOptions for source styling and local overrides.
|
|
136
135
|
*/
|
|
137
136
|
const enableVerticalControlArea = async (options = {}) => {
|
|
138
137
|
const handle = await enableNativeUIShell({
|
|
138
|
+
buttonProjection: options.buttonProjection,
|
|
139
139
|
buttonDefaultFill: options.buttonDefaultFill,
|
|
140
140
|
controls: {
|
|
141
141
|
tabs: true,
|
|
@@ -165,6 +165,7 @@ const enableNativeUIShell = (options = {}) => {
|
|
|
165
165
|
const controls = options.controls;
|
|
166
166
|
const configuration = JSON.stringify([
|
|
167
167
|
options.verticalBarsOnly === true,
|
|
168
|
+
options.buttonProjection ?? "system",
|
|
168
169
|
options.buttonDefaultFill ?? null,
|
|
169
170
|
...[
|
|
170
171
|
"tabs",
|
package/dist/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/native/index.ts"],"sourcesContent":["import { Capacitor, registerPlugin } from '@capacitor/core';\nimport { setConfig } from '../transition/ios.transition';\nimport type {\n NativeUIShellHandle,\n NativeUIShellOptions,\n NativeUIShellPlugin,\n VerticalBarEdge,\n VerticalBarPlacement,\n VerticalControlAreaHandle,\n VerticalControlAreaOptions,\n WebViewMetrics,\n} from './definitions';\nimport { createRuntime } from './runtime';\nimport { createVerticalBarsWebProjection } from './vertical-bars-web';\nimport { prehideVerticalBarsToolbarSources } from './prehide';\nimport { observeVerticalBarsModals } from './shared/modal';\nexport type {\n NativeUIShellComponent,\n NativeUIShellControls,\n NativeUIShellHandle,\n NativeUIShellOptions,\n NativeUIShellStatus,\n NativeUIShellSuspension,\n VerticalBarEdge,\n VerticalBarPlacement,\n VerticalControlAreaHandle,\n VerticalControlAreaOptions,\n WebViewMetrics,\n} from './definitions';\n\nconst plugin = registerPlugin<NativeUIShellPlugin>('IonicNativeUIShell');\nexport const IonicNativeUIShell = plugin;\nlet active: Promise<NativeUIShellHandle> | undefined;\nlet activeConfiguration: string | undefined;\nconst web = (reason: string): NativeUIShellHandle => ({\n getStatus: () => ({ state: 'web', projected: 0, updates: 0, reason }),\n suspend: async () => ({ resume: async () => {} }),\n destroy: async () => {},\n});\n\nconst combine = (native: NativeUIShellHandle, fallback: NativeUIShellHandle): NativeUIShellHandle => ({\n getStatus() {\n const nativeStatus = native.getStatus();\n const fallbackStatus = fallback.getStatus();\n return {\n ...nativeStatus,\n state:\n nativeStatus.state === 'stopped' && fallbackStatus.state === 'stopped' ? 'stopped' : nativeStatus.projected > 0 ? 'native' : 'web',\n projected: nativeStatus.projected + fallbackStatus.projected,\n updates: nativeStatus.updates + fallbackStatus.updates,\n };\n },\n async suspend() {\n const [nativeLease, fallbackLease] = await Promise.all([native.suspend(), fallback.suspend()]);\n return { resume: async () => void (await Promise.all([nativeLease.resume(), fallbackLease.resume()])) };\n },\n async destroy() {\n await Promise.all([native.destroy(), fallback.destroy()]);\n },\n});\n\n/** Wraps a runtime handle with the shared enable-lifecycle: reason, suspend hooks and idempotent destroy. */\nconst manage = (\n handle: NativeUIShellHandle,\n lifecycle: {\n reason?: string;\n suspend?: () => (() => void) | undefined;\n /** Runs after teardown; clears the shared slot only while this activation owns it. */\n release?: () => void;\n destroy?: () => void | Promise<void>;\n } = {},\n): NativeUIShellHandle => {\n let destroyed = false;\n return {\n getStatus: () => (lifecycle.reason ? { ...handle.getStatus(), reason: lifecycle.reason } : handle.getStatus()),\n async suspend() {\n const lease = await handle.suspend();\n const resume = lifecycle.suspend?.();\n return {\n async resume() {\n await lease.resume();\n resume?.();\n },\n };\n },\n async destroy() {\n if (destroyed) return;\n destroyed = true;\n try {\n await handle.destroy();\n } finally {\n await lifecycle.destroy?.();\n lifecycle.release?.();\n }\n },\n };\n};\n\n/** Reads the current native WebView geometry and applies it to page transitions. */\nexport const configureNativeTransition = async (): Promise<WebViewMetrics> => {\n const metrics = typeof document !== 'undefined' && Capacitor.getPlatform() === 'ios' ? await plugin.getWebViewMetrics() : { radius: 0 };\n setConfig({ radius: metrics.radius });\n return metrics;\n};\n\n/** Resolves a logical vertical-bar edge to the physical side for the given direction. */\nconst physicalVerticalBarEdge = (edge: Exclude<VerticalBarEdge, null>, rtl: boolean): 'left' | 'right' =>\n (edge === 'leading') !== rtl ? 'left' : 'right';\n\nconst elementRtl = (element: Element): boolean => element.closest('[dir]')?.getAttribute('dir') === 'rtl';\n\n// Device facts are supplied by the application; the theme only compares placement.\nconst nativePlacements = new WeakMap<HTMLElement, { edge: VerticalBarEdge; rtl?: boolean }>();\nconst horizontalFallbackAttribute = 'data-native-ui-shell-vertical-bars-suspended';\n\n// Keep the requested rail while ordinary Native UI Shell temporarily uses its\n// horizontal layout. Removing the effective class restores normal measurements,\n// toolbar ownership and safe areas throughout the existing rendering pipeline.\nconst observeNativeVerticalBarsLayout = (doc: Document): (() => void) => {\n const reconcile = () => {\n const app = doc.querySelector<HTMLElement>('ion-app');\n if (!app) return;\n const requested = app.classList.contains('ios-theme-vertical-bars') || app.hasAttribute(horizontalFallbackAttribute);\n const suspended = requested && nativePlacements.get(app)?.edge == null;\n if (app.hasAttribute(horizontalFallbackAttribute) !== suspended) app.toggleAttribute(horizontalFallbackAttribute, suspended);\n if (app.classList.contains('ios-theme-vertical-bars') !== (requested && !suspended)) {\n app.classList.toggle('ios-theme-vertical-bars', requested && !suspended);\n }\n };\n const observer = new MutationObserver(reconcile);\n observer.observe(doc.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['class'] });\n doc.defaultView?.addEventListener('nativeUIShellRefresh', reconcile);\n reconcile();\n return () => {\n observer.disconnect();\n doc.defaultView?.removeEventListener('nativeUIShellRefresh', reconcile);\n const app = doc.querySelector<HTMLElement>(`ion-app[${horizontalFallbackAttribute}]`);\n if (app) {\n app.removeAttribute(horizontalFallbackAttribute);\n app.classList.add('ios-theme-vertical-bars');\n }\n };\n};\n\n/**\n * Applies one placement to the CSS layout and both Web/native projections.\n * Pass `rtl` when the document direction is known; otherwise the nearest `dir` attribute is used.\n */\nexport const setVerticalControlAreaPlacement = (placement: VerticalBarEdge | VerticalBarPlacement, rtl?: boolean): void => {\n if (typeof document === 'undefined') return;\n const app = document.querySelector<HTMLElement>('ion-app');\n if (!app) throw new Error('Vertical Control Area requires ion-app');\n const { edge, inset = 0 } = placement && typeof placement === 'object' ? placement : { edge: placement, inset: 0 };\n if (placement && typeof placement === 'object' && placement.nativeEdge !== undefined) {\n nativePlacements.set(app, { edge: placement.nativeEdge, rtl });\n }\n app.removeAttribute(horizontalFallbackAttribute);\n app.classList.toggle('ios-theme-vertical-bars', edge !== null);\n app.classList.toggle('ios-theme-vertical-bars-left', edge !== null && physicalVerticalBarEdge(edge, rtl ?? elementRtl(app)) === 'left');\n if (edge && Number.isFinite(inset) && inset > 0) app.style.setProperty('--ios-theme-vertical-bars-native-inset', `${inset}px`);\n else app.style.removeProperty('--ios-theme-vertical-bars-native-inset');\n document.defaultView?.dispatchEvent(new Event('nativeUIShellRefresh'));\n};\n\n/**\n * Call once after ion-app is mounted. Ionic markup remains the source of truth.\n * Set buttonDefaultFill to `solid` for Ionic's default design, or `null` for this\n * theme's glass design. Omitting it is equivalent to `null`.\n * This default affects native vertical projection only; explicit button fills win.\n */\nexport const enableVerticalControlArea = async (options: VerticalControlAreaOptions = {}): Promise<VerticalControlAreaHandle> => {\n const handle = await enableNativeUIShell({\n buttonDefaultFill: options.buttonDefaultFill,\n controls: { tabs: true, toolbar: true },\n verticalBarsOnly: true,\n });\n return {\n getStatus: () => handle.getStatus(),\n suspend: () => handle.suspend(),\n destroy: () => handle.destroy(),\n setPlacement: setVerticalControlAreaPlacement,\n };\n};\n\n/** Call once at application startup. Ionic markup remains the source of truth. */\nexport const enableNativeUIShell = (options: NativeUIShellOptions = {}): Promise<NativeUIShellHandle> => {\n if (options.enabled === false) {\n const current = active;\n active = undefined;\n activeConfiguration = undefined;\n return current\n ? current.then(async (handle) => {\n await handle.destroy();\n return web('Disabled');\n })\n : Promise.resolve(web('Disabled'));\n }\n if (typeof document === 'undefined') return Promise.resolve(web('Requires a document'));\n const controls = options.controls;\n const configuration = JSON.stringify([\n options.verticalBarsOnly === true,\n options.buttonDefaultFill ?? null,\n ...(['tabs', 'toolbar', 'segment', 'fab'] as const).map((component) => !controls || controls[component] === true),\n ]);\n if (active && activeConfiguration !== configuration)\n return Promise.reject(\n new Error('Native UI Shell is already running with different controls; destroy it before changing configuration.'),\n );\n if (active) return active;\n activeConfiguration = configuration;\n const stopModals = observeVerticalBarsModals(document);\n const prehide =\n options.controls === undefined || options.controls.toolbar === true ? prehideVerticalBarsToolbarSources(document) : undefined;\n // A slow destroy of a superseded activation must not release a newer one.\n let start: Promise<NativeUIShellHandle>;\n const release = () => {\n if (active === start) {\n active = undefined;\n activeConfiguration = undefined;\n }\n };\n const fallback = (reason: string) =>\n manage(createVerticalBarsWebProjection(document, options), {\n reason,\n suspend: () => prehide?.suspend(),\n destroy: () => {\n prehide?.stop();\n stopModals();\n },\n release,\n });\n return (start = active =\n (async () => {\n if (Capacitor.getPlatform() !== 'ios') return fallback('Requires Capacitor iOS');\n let runtime: NativeUIShellHandle | undefined;\n let metricsListener: Awaited<ReturnType<typeof plugin.addListener>> | undefined;\n let stopVerticalBarsLayout: (() => void) | undefined;\n try {\n const capabilities = await plugin.configure({ verticalBarsOnly: options.verticalBarsOnly === true });\n if (!capabilities.supported) return fallback('Requires iOS 26 or later');\n if (!options.verticalBarsOnly) stopVerticalBarsLayout = observeNativeVerticalBarsLayout(document);\n // The application owns device state and selects the rail through placement classes.\n const nativeVerticalBars = () => {\n const app = document.querySelector<HTMLElement>('ion-app.ios-theme-vertical-bars');\n if (!app) return false;\n const reported = nativePlacements.get(app);\n if (!reported?.edge) return false;\n const physicalEdge = app.classList.contains('ios-theme-vertical-bars-left') ? 'left' : 'right';\n return physicalEdge === physicalVerticalBarEdge(reported.edge, reported.rtl ?? elementRtl(app));\n };\n if (!options.verticalBarsOnly) {\n metricsListener = await plugin.addListener('webViewMetricsChange', (metrics) => {\n setConfig({ radius: metrics.radius });\n });\n await configureNativeTransition().catch(() => undefined);\n }\n const native = await createRuntime(document, plugin, options, nativeVerticalBars, options.verticalBarsOnly === true);\n runtime = combine(\n native,\n createVerticalBarsWebProjection(document, options, () => !nativeVerticalBars() || native.getStatus().state === 'stopped'),\n );\n return manage(runtime, {\n suspend: () => prehide?.suspend(),\n release,\n destroy: async () => {\n await metricsListener?.remove().catch(() => {});\n stopVerticalBarsLayout?.();\n prehide?.stop();\n stopModals();\n },\n });\n } catch (error) {\n await runtime?.destroy();\n await metricsListener?.remove().catch(() => {});\n stopVerticalBarsLayout?.();\n return fallback(error instanceof Error ? error.message : String(error));\n }\n })());\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/native/index.ts"],"sourcesContent":["import { Capacitor, registerPlugin } from '@capacitor/core';\nimport { setConfig } from '../transition/ios.transition';\nimport type {\n NativeUIShellHandle,\n NativeUIShellOptions,\n NativeUIShellPlugin,\n VerticalBarEdge,\n VerticalBarPlacement,\n VerticalControlAreaHandle,\n VerticalControlAreaOptions,\n WebViewMetrics,\n} from './definitions';\nimport { createRuntime } from './runtime';\nimport { createVerticalBarsWebProjection } from './vertical-bars-web';\nimport { prehideVerticalBarsToolbarSources } from './prehide';\nimport { observeVerticalBarsModals } from './shared/modal';\nexport type {\n NativeUIShellComponent,\n NativeUIShellControls,\n NativeUIShellHandle,\n NativeUIShellOptions,\n NativeUIShellStatus,\n NativeUIShellSuspension,\n VerticalBarEdge,\n VerticalBarPlacement,\n VerticalControlAreaHandle,\n VerticalControlAreaOptions,\n WebViewMetrics,\n} from './definitions';\n\nconst plugin = registerPlugin<NativeUIShellPlugin>('IonicNativeUIShell');\nexport const IonicNativeUIShell = plugin;\nlet active: Promise<NativeUIShellHandle> | undefined;\nlet activeConfiguration: string | undefined;\nconst web = (reason: string): NativeUIShellHandle => ({\n getStatus: () => ({ state: 'web', projected: 0, updates: 0, reason }),\n suspend: async () => ({ resume: async () => {} }),\n destroy: async () => {},\n});\n\nconst combine = (native: NativeUIShellHandle, fallback: NativeUIShellHandle): NativeUIShellHandle => ({\n getStatus() {\n const nativeStatus = native.getStatus();\n const fallbackStatus = fallback.getStatus();\n return {\n ...nativeStatus,\n state:\n nativeStatus.state === 'stopped' && fallbackStatus.state === 'stopped' ? 'stopped' : nativeStatus.projected > 0 ? 'native' : 'web',\n projected: nativeStatus.projected + fallbackStatus.projected,\n updates: nativeStatus.updates + fallbackStatus.updates,\n };\n },\n async suspend() {\n const [nativeLease, fallbackLease] = await Promise.all([native.suspend(), fallback.suspend()]);\n return { resume: async () => void (await Promise.all([nativeLease.resume(), fallbackLease.resume()])) };\n },\n async destroy() {\n await Promise.all([native.destroy(), fallback.destroy()]);\n },\n});\n\n/** Wraps a runtime handle with the shared enable-lifecycle: reason, suspend hooks and idempotent destroy. */\nconst manage = (\n handle: NativeUIShellHandle,\n lifecycle: {\n reason?: string;\n suspend?: () => (() => void) | undefined;\n /** Runs after teardown; clears the shared slot only while this activation owns it. */\n release?: () => void;\n destroy?: () => void | Promise<void>;\n } = {},\n): NativeUIShellHandle => {\n let destroyed = false;\n return {\n getStatus: () => (lifecycle.reason ? { ...handle.getStatus(), reason: lifecycle.reason } : handle.getStatus()),\n async suspend() {\n const lease = await handle.suspend();\n const resume = lifecycle.suspend?.();\n return {\n async resume() {\n await lease.resume();\n resume?.();\n },\n };\n },\n async destroy() {\n if (destroyed) return;\n destroyed = true;\n try {\n await handle.destroy();\n } finally {\n await lifecycle.destroy?.();\n lifecycle.release?.();\n }\n },\n };\n};\n\n/** Reads the current native WebView geometry and applies it to page transitions. */\nexport const configureNativeTransition = async (): Promise<WebViewMetrics> => {\n const metrics = typeof document !== 'undefined' && Capacitor.getPlatform() === 'ios' ? await plugin.getWebViewMetrics() : { radius: 0 };\n setConfig({ radius: metrics.radius });\n return metrics;\n};\n\n/** Resolves a logical vertical-bar edge to the physical side for the given direction. */\nconst physicalVerticalBarEdge = (edge: Exclude<VerticalBarEdge, null>, rtl: boolean): 'left' | 'right' =>\n (edge === 'leading') !== rtl ? 'left' : 'right';\n\nconst elementRtl = (element: Element): boolean => element.closest('[dir]')?.getAttribute('dir') === 'rtl';\n\n// Device facts are supplied by the application; the theme only compares placement.\nconst nativePlacements = new WeakMap<HTMLElement, { edge: VerticalBarEdge; rtl?: boolean }>();\nconst horizontalFallbackAttribute = 'data-native-ui-shell-vertical-bars-suspended';\n\n// Keep the requested rail while ordinary Native UI Shell temporarily uses its\n// horizontal layout. Removing the effective class restores normal measurements,\n// toolbar ownership and safe areas throughout the existing rendering pipeline.\nconst observeNativeVerticalBarsLayout = (doc: Document): (() => void) => {\n const reconcile = () => {\n const app = doc.querySelector<HTMLElement>('ion-app');\n if (!app) return;\n const requested = app.classList.contains('ios-theme-vertical-bars') || app.hasAttribute(horizontalFallbackAttribute);\n const suspended = requested && nativePlacements.get(app)?.edge == null;\n if (app.hasAttribute(horizontalFallbackAttribute) !== suspended) app.toggleAttribute(horizontalFallbackAttribute, suspended);\n if (app.classList.contains('ios-theme-vertical-bars') !== (requested && !suspended)) {\n app.classList.toggle('ios-theme-vertical-bars', requested && !suspended);\n }\n };\n const observer = new MutationObserver(reconcile);\n observer.observe(doc.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['class'] });\n doc.defaultView?.addEventListener('nativeUIShellRefresh', reconcile);\n reconcile();\n return () => {\n observer.disconnect();\n doc.defaultView?.removeEventListener('nativeUIShellRefresh', reconcile);\n const app = doc.querySelector<HTMLElement>(`ion-app[${horizontalFallbackAttribute}]`);\n if (app) {\n app.removeAttribute(horizontalFallbackAttribute);\n app.classList.add('ios-theme-vertical-bars');\n }\n };\n};\n\n/**\n * Applies one placement to the CSS layout and both Web/native projections.\n * Pass `rtl` when the document direction is known; otherwise the nearest `dir` attribute is used.\n */\nexport const setVerticalControlAreaPlacement = (placement: VerticalBarEdge | VerticalBarPlacement, rtl?: boolean): void => {\n if (typeof document === 'undefined') return;\n const app = document.querySelector<HTMLElement>('ion-app');\n if (!app) throw new Error('Vertical Control Area requires ion-app');\n const { edge, inset = 0 } = placement && typeof placement === 'object' ? placement : { edge: placement, inset: 0 };\n if (placement && typeof placement === 'object' && placement.nativeEdge !== undefined) {\n nativePlacements.set(app, { edge: placement.nativeEdge, rtl });\n }\n app.removeAttribute(horizontalFallbackAttribute);\n app.classList.toggle('ios-theme-vertical-bars', edge !== null);\n app.classList.toggle('ios-theme-vertical-bars-left', edge !== null && physicalVerticalBarEdge(edge, rtl ?? elementRtl(app)) === 'left');\n if (edge && Number.isFinite(inset) && inset > 0) app.style.setProperty('--ios-theme-vertical-bars-native-inset', `${inset}px`);\n else app.style.removeProperty('--ios-theme-vertical-bars-native-inset');\n document.defaultView?.dispatchEvent(new Event('nativeUIShellRefresh'));\n};\n\n/**\n * Call once after ion-app is mounted. Ionic markup remains the source of truth.\n * Native vertical buttons default to SwiftUI appearance.\n * See VerticalControlAreaOptions for source styling and local overrides.\n */\nexport const enableVerticalControlArea = async (options: VerticalControlAreaOptions = {}): Promise<VerticalControlAreaHandle> => {\n const handle = await enableNativeUIShell({\n buttonProjection: options.buttonProjection,\n buttonDefaultFill: options.buttonDefaultFill,\n controls: { tabs: true, toolbar: true },\n verticalBarsOnly: true,\n });\n return {\n getStatus: () => handle.getStatus(),\n suspend: () => handle.suspend(),\n destroy: () => handle.destroy(),\n setPlacement: setVerticalControlAreaPlacement,\n };\n};\n\n/** Call once at application startup. Ionic markup remains the source of truth. */\nexport const enableNativeUIShell = (options: NativeUIShellOptions = {}): Promise<NativeUIShellHandle> => {\n if (options.enabled === false) {\n const current = active;\n active = undefined;\n activeConfiguration = undefined;\n return current\n ? current.then(async (handle) => {\n await handle.destroy();\n return web('Disabled');\n })\n : Promise.resolve(web('Disabled'));\n }\n if (typeof document === 'undefined') return Promise.resolve(web('Requires a document'));\n const controls = options.controls;\n const configuration = JSON.stringify([\n options.verticalBarsOnly === true,\n options.buttonProjection ?? 'system',\n // Local source overrides can use this even when the startup projection is system.\n options.buttonDefaultFill ?? null,\n ...(['tabs', 'toolbar', 'segment', 'fab'] as const).map((component) => !controls || controls[component] === true),\n ]);\n if (active && activeConfiguration !== configuration)\n return Promise.reject(\n new Error('Native UI Shell is already running with different controls; destroy it before changing configuration.'),\n );\n if (active) return active;\n activeConfiguration = configuration;\n const stopModals = observeVerticalBarsModals(document);\n const prehide =\n options.controls === undefined || options.controls.toolbar === true ? prehideVerticalBarsToolbarSources(document) : undefined;\n // A slow destroy of a superseded activation must not release a newer one.\n let start: Promise<NativeUIShellHandle>;\n const release = () => {\n if (active === start) {\n active = undefined;\n activeConfiguration = undefined;\n }\n };\n const fallback = (reason: string) =>\n manage(createVerticalBarsWebProjection(document, options), {\n reason,\n suspend: () => prehide?.suspend(),\n destroy: () => {\n prehide?.stop();\n stopModals();\n },\n release,\n });\n return (start = active =\n (async () => {\n if (Capacitor.getPlatform() !== 'ios') return fallback('Requires Capacitor iOS');\n let runtime: NativeUIShellHandle | undefined;\n let metricsListener: Awaited<ReturnType<typeof plugin.addListener>> | undefined;\n let stopVerticalBarsLayout: (() => void) | undefined;\n try {\n const capabilities = await plugin.configure({ verticalBarsOnly: options.verticalBarsOnly === true });\n if (!capabilities.supported) return fallback('Requires iOS 26 or later');\n if (!options.verticalBarsOnly) stopVerticalBarsLayout = observeNativeVerticalBarsLayout(document);\n // The application owns device state and selects the rail through placement classes.\n const nativeVerticalBars = () => {\n const app = document.querySelector<HTMLElement>('ion-app.ios-theme-vertical-bars');\n if (!app) return false;\n const reported = nativePlacements.get(app);\n if (!reported?.edge) return false;\n const physicalEdge = app.classList.contains('ios-theme-vertical-bars-left') ? 'left' : 'right';\n return physicalEdge === physicalVerticalBarEdge(reported.edge, reported.rtl ?? elementRtl(app));\n };\n if (!options.verticalBarsOnly) {\n metricsListener = await plugin.addListener('webViewMetricsChange', (metrics) => {\n setConfig({ radius: metrics.radius });\n });\n await configureNativeTransition().catch(() => undefined);\n }\n const native = await createRuntime(document, plugin, options, nativeVerticalBars, options.verticalBarsOnly === true);\n runtime = combine(\n native,\n createVerticalBarsWebProjection(document, options, () => !nativeVerticalBars() || native.getStatus().state === 'stopped'),\n );\n return manage(runtime, {\n suspend: () => prehide?.suspend(),\n release,\n destroy: async () => {\n await metricsListener?.remove().catch(() => {});\n stopVerticalBarsLayout?.();\n prehide?.stop();\n stopModals();\n },\n });\n } catch (error) {\n await runtime?.destroy();\n await metricsListener?.remove().catch(() => {});\n stopVerticalBarsLayout?.();\n return fallback(error instanceof Error ? error.message : String(error));\n }\n })());\n};\n"],"mappings":"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"}
|
package/dist/native/prehide.js
CHANGED
|
@@ -55,6 +55,7 @@ const prehideVerticalBarsToolbarSources = (doc) => {
|
|
|
55
55
|
owned.add(element);
|
|
56
56
|
};
|
|
57
57
|
(scope.matches("ion-back-button") ? [scope] : Array.from(scope.querySelectorAll(sourceSelector))).forEach((element) => {
|
|
58
|
+
if (isShellDisabled(element)) return;
|
|
58
59
|
if (!modalUsesVerticalBars(element) || element.closest(overlays) || scope.matches(".ion-page") && routedPage(element) !== scope) return;
|
|
59
60
|
if (element.matches("ion-buttons")) {
|
|
60
61
|
const children = childElements(element);
|
|
@@ -186,6 +187,7 @@ const prehideVerticalBarsToolbarSources = (doc) => {
|
|
|
186
187
|
attributeOldValue: true,
|
|
187
188
|
attributeFilter: [
|
|
188
189
|
"class",
|
|
190
|
+
"data-shell",
|
|
189
191
|
"hidden",
|
|
190
192
|
"inert",
|
|
191
193
|
"icon",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prehide.js","names":[],"sources":["../../src/native/prehide.ts"],"sourcesContent":["import { modalUsesVerticalBars } from './shared/modal';\nimport { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE } from '@ionic/core';\nimport { VERTICAL_BARS_TRANSITION_CANCELED } from '../native-integration';\nimport {\n childElements,\n clearVerticalBarsPlacement,\n createVerticalBarsPageState,\n verticalBarsActionCandidate,\n verticalBarsBackCandidate,\n verticalBarsBackWebClass,\n verticalBarsOwned,\n isVerticalBarsToolbarActionShape,\n isPermanentlyExcluded,\n isShellDisabled,\n prehiddenClass,\n prehideRootClass,\n rejectedClass,\n setVerticalBarsPlacement,\n} from './shared/dom';\n\nconst overlays = 'ion-menu, ion-popover';\nconst sourceSelector = 'ion-back-button, ion-menu-button, ion-buttons, ion-button';\n// Realm- and teardown-safe: globals such as Element/HTMLElement may be gone\n// when a queued mutation microtask or a stale listener still runs.\nconst isHtmlElement = (node: unknown): node is HTMLElement => !!node && (node as Node).nodeType === 1;\nconst asElement = (node: Node | EventTarget | null): HTMLElement | undefined => (isHtmlElement(node) ? node : undefined);\nconst backSupported = (element: HTMLElement): boolean => {\n const back = element as HTMLIonBackButtonElement;\n return back.icon === undefined && back.color === undefined && !!back.shadowRoot;\n};\nconst eligibleBack = verticalBarsBackCandidate;\nconst eligible = verticalBarsActionCandidate;\n\n/** Capture toolbar placement once per routed-page epoch, before Ionic paints its transition. */\nexport const prehideVerticalBarsToolbarSources = (doc: Document): { suspend: () => () => void; stop: () => void } => {\n doc.documentElement.classList.add(prehideRootClass);\n const scopes = new Map<HTMLElement, Set<HTMLElement>>();\n const owner = new WeakMap<HTMLElement, HTMLElement>();\n const pendingBacks = new Map<HTMLElement, { scope: HTMLElement; timer: ReturnType<typeof setTimeout> }>();\n const verticalBarsPages = createVerticalBarsPageState();\n const listeners = new AbortController();\n const root = () => doc.querySelector<HTMLElement>('ion-app.ios-theme-vertical-bars');\n let suspended = 0;\n let stopped = false;\n const routedPage = (element: HTMLElement) => element.closest<HTMLElement>('.ion-page:not(ion-app, body)');\n const release = (scope: HTMLElement) => {\n for (const [element, pending] of pendingBacks) {\n if (pending.scope !== scope) continue;\n clearTimeout(pending.timer);\n pendingBacks.delete(element);\n }\n const owned = scopes.get(scope);\n if (!owned) return;\n owned.forEach((element) => {\n if (owner.get(element) !== scope) return;\n owner.delete(element);\n element.classList.remove(prehiddenClass);\n element.classList.remove(verticalBarsBackWebClass);\n clearVerticalBarsPlacement(element);\n });\n scopes.delete(scope);\n };\n const capture = (scope: HTMLElement) => {\n if (!root()?.contains(scope) || scope.closest(overlays) || !modalUsesVerticalBars(scope) || verticalBarsPages.isDeparted(scope)) return;\n const owned = scopes.get(scope) ?? new Set<HTMLElement>();\n const place = (element: HTMLElement, rail: boolean) => {\n if (owned.has(element)) return;\n const previousScope = owner.get(element);\n if (previousScope) scopes.get(previousScope)?.delete(element);\n owner.set(element, scope);\n setVerticalBarsPlacement(element, rail);\n if (element.matches('ion-back-button')) element.classList.toggle(verticalBarsBackWebClass, !rail);\n owned.add(element);\n };\n const sources = scope.matches('ion-back-button') ? [scope] : Array.from(scope.querySelectorAll<HTMLElement>(sourceSelector));\n sources.forEach((element) => {\n if (!modalUsesVerticalBars(element) || element.closest(overlays) || (scope.matches('.ion-page') && routedPage(element) !== scope))\n return;\n if (element.matches('ion-buttons')) {\n const children = childElements(element);\n const actions = children.filter((child) => eligible(child) && isVerticalBarsToolbarActionShape(child));\n const group =\n eligible(element) &&\n actions.length === children.length &&\n (actions.length > 1 || (actions.length === 1 && actions[0].matches('ion-menu-button')));\n const freshGroup = !owned.has(element);\n place(element, group);\n children.forEach((child) => {\n if (!child.matches('ion-back-button')) place(child, freshGroup && actions.includes(child));\n });\n } else if (element.matches('ion-back-button') || !element.parentElement?.matches('ion-buttons')) {\n if (owned.has(element)) return;\n if (\n element.matches('ion-back-button') &&\n eligibleBack(element) &&\n (element as HTMLIonBackButtonElement).icon === undefined &&\n (element as HTMLIonBackButtonElement).color === undefined &&\n !element.shadowRoot &&\n !element.classList.contains('hydrated')\n ) {\n const previousPending = pendingBacks.get(element);\n if (previousPending && previousPending.scope !== scope) {\n clearTimeout(previousPending.timer);\n pendingBacks.delete(element);\n }\n if (!pendingBacks.has(element)) {\n const timer = setTimeout(() => {\n if (pendingBacks.get(element)?.scope !== scope) return;\n pendingBacks.delete(element);\n // A custom element that never hydrates must remain usable on Web.\n place(element, false);\n reconcile();\n }, 1500);\n pendingBacks.set(element, { scope, timer });\n }\n return;\n }\n const pending = pendingBacks.get(element);\n if (pending) {\n clearTimeout(pending.timer);\n pendingBacks.delete(element);\n }\n place(\n element,\n element.matches('ion-back-button')\n ? eligibleBack(element) && backSupported(element)\n : eligible(element) && isVerticalBarsToolbarActionShape(element),\n );\n }\n });\n scopes.set(scope, owned);\n };\n const reconcile = () => {\n const verticalBars = root();\n if (!verticalBars) {\n Array.from(scopes.keys()).forEach(release);\n return;\n }\n for (const scope of scopes.keys()) if (!scope.isConnected || !modalUsesVerticalBars(scope)) release(scope);\n for (const [element, pending] of pendingBacks) if (element.shadowRoot || element.classList.contains('hydrated')) capture(pending.scope);\n // Ionic inserts the destination as invisible before WillEnter. Hide its\n // sources in that same mutation microtask; capture new DOM identities on active pages too.\n verticalBars.querySelectorAll<HTMLElement>('.ion-page:not(ion-app, body, .ion-page-hidden)').forEach(capture);\n // Root toolbars can mount after startup; each new DOM identity is captured once.\n verticalBars.querySelectorAll<HTMLElement>(sourceSelector).forEach((element) => {\n if (routedPage(element) || element.closest(overlays)) return;\n const scope = element.closest<HTMLElement>('ion-toolbar') ?? (element.matches('ion-back-button') ? element : null);\n if (scope) capture(scope);\n });\n for (const owned of scopes.values()) {\n for (const element of owned) {\n const groupOwnsChildren =\n element.parentElement?.matches('ion-buttons') &&\n verticalBarsOwned(element.parentElement) &&\n childElements(element.parentElement).every((child) => verticalBarsOwned(child));\n const hide =\n !suspended &&\n verticalBarsOwned(element) &&\n !groupOwnsChildren &&\n element.isConnected &&\n !element.closest(`.${rejectedClass}`) &&\n !isPermanentlyExcluded(element) &&\n !isShellDisabled(element) &&\n (!element.matches('ion-back-button') || backSupported(element) || !element.classList.contains('hydrated')) &&\n (!element.matches('ion-buttons') || childElements(element).every((child) => verticalBarsOwned(child)));\n element.classList.toggle(prehiddenClass, hide);\n if (element.matches('ion-back-button')) element.classList.toggle(verticalBarsBackWebClass, !hide);\n }\n }\n };\n const onWillEnter = (event: Event) => {\n const page = asElement(event.target);\n if (page?.matches('.ion-page')) {\n verticalBarsPages.lifecycle(event);\n release(page); // Cached pages begin a new placement epoch.\n capture(page);\n reconcile();\n }\n };\n const onPageLifecycle: EventListener = (event) => {\n verticalBarsPages.lifecycle(event);\n if (event.type !== LIFECYCLE_DID_LEAVE) return;\n const page = asElement(event.target);\n if (page) release(page);\n };\n // A canceled transition keeps the leaving page active and abandons the entering one.\n const onTransitionCanceled: EventListener = (event) => {\n const leaving = asElement(event.target);\n if (!leaving) return;\n const entering = (event as CustomEvent<{ entering?: HTMLElement }>).detail?.entering;\n verticalBarsPages.cancel(entering, leaving);\n reconcile();\n };\n doc.addEventListener(LIFECYCLE_WILL_ENTER, onWillEnter, { capture: true, signal: listeners.signal });\n for (const name of [LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE])\n doc.addEventListener(name, onPageLifecycle, { capture: true, signal: listeners.signal });\n doc.addEventListener(VERTICAL_BARS_TRANSITION_CANCELED, onTransitionCanceled, { capture: true, signal: listeners.signal });\n doc.defaultView?.addEventListener('nativeUIShellRefresh', reconcile, { signal: listeners.signal });\n reconcile();\n const mutationRelevant = (record: MutationRecord) => {\n if (record.type === 'childList')\n return [...Array.from(record.addedNodes), ...Array.from(record.removedNodes)].some(\n (node) =>\n isHtmlElement(node) &&\n (node.matches(`${sourceSelector}, .ion-page, ion-toolbar`) || !!node.querySelector(`${sourceSelector}, .ion-page, ion-toolbar`)),\n );\n if (record.attributeName !== 'class') return true;\n const current = (record.target as Element).className;\n const previous = record.oldValue ?? '';\n const withoutOwned = (value: string) =>\n value\n .split(/\\s+/)\n .filter((name) => name && ![prehiddenClass, prehideRootClass, verticalBarsBackWebClass].includes(name))\n .join(' ');\n return typeof current !== 'string' || withoutOwned(previous) !== withoutOwned(current);\n };\n let scheduled = false;\n const observer = new (doc.defaultView?.MutationObserver ?? MutationObserver)((records) => {\n if (scheduled || stopped || !records.some(mutationRelevant)) return;\n scheduled = true;\n queueMicrotask(() => {\n scheduled = false;\n if (!stopped) reconcile();\n });\n });\n observer.observe(doc.documentElement, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeOldValue: true,\n attributeFilter: ['class', 'hidden', 'inert', 'icon', 'color'],\n });\n return {\n suspend: () => {\n if (stopped) return () => {};\n suspended++;\n doc.documentElement.classList.remove(prehideRootClass);\n reconcile();\n let resumed = false;\n return () => {\n if (resumed || stopped) return;\n resumed = true;\n if (--suspended === 0) {\n doc.documentElement.classList.add(prehideRootClass);\n reconcile();\n }\n };\n },\n stop: () => {\n if (stopped) return;\n stopped = true;\n observer.disconnect();\n listeners.abort();\n doc.documentElement.classList.remove(prehideRootClass);\n Array.from(scopes.keys()).forEach(release);\n },\n };\n};\n"],"mappings":";;;;;AAoBA,MAAM,WAAW;AACjB,MAAM,iBAAiB;AAGvB,MAAM,iBAAiB,SAAuC,CAAC,CAAC,QAAS,KAAc,aAAa;AACpG,MAAM,aAAa,SAA8D,cAAc,IAAI,IAAI,OAAO,KAAA;AAC9G,MAAM,iBAAiB,YAAkC;CACvD,MAAM,OAAO;CACb,OAAO,KAAK,SAAS,KAAA,KAAa,KAAK,UAAU,KAAA,KAAa,CAAC,CAAC,KAAK;AACvE;AACA,MAAM,eAAe;AACrB,MAAM,WAAW;;AAGjB,MAAa,qCAAqC,QAAmE;CACnH,IAAI,gBAAgB,UAAU,IAAI,gBAAgB;CAClD,MAAM,yBAAS,IAAI,IAAmC;CACtD,MAAM,wBAAQ,IAAI,QAAkC;CACpD,MAAM,+BAAe,IAAI,IAA+E;CACxG,MAAM,oBAAoB,4BAA4B;CACtD,MAAM,YAAY,IAAI,gBAAgB;CACtC,MAAM,aAAa,IAAI,cAA2B,iCAAiC;CACnF,IAAI,YAAY;CAChB,IAAI,UAAU;CACd,MAAM,cAAc,YAAyB,QAAQ,QAAqB,8BAA8B;CACxG,MAAM,WAAW,UAAuB;EACtC,KAAK,MAAM,CAAC,SAAS,YAAY,cAAc;GAC7C,IAAI,QAAQ,UAAU,OAAO;GAC7B,aAAa,QAAQ,KAAK;GAC1B,aAAa,OAAO,OAAO;EAC7B;EACA,MAAM,QAAQ,OAAO,IAAI,KAAK;EAC9B,IAAI,CAAC,OAAO;EACZ,MAAM,SAAS,YAAY;GACzB,IAAI,MAAM,IAAI,OAAO,MAAM,OAAO;GAClC,MAAM,OAAO,OAAO;GACpB,QAAQ,UAAU,OAAO,cAAc;GACvC,QAAQ,UAAU,OAAO,wBAAwB;GACjD,2BAA2B,OAAO;EACpC,CAAC;EACD,OAAO,OAAO,KAAK;CACrB;CACA,MAAM,WAAW,UAAuB;EACtC,IAAI,CAAC,KAAK,CAAC,EAAE,SAAS,KAAK,KAAK,MAAM,QAAQ,QAAQ,KAAK,CAAC,sBAAsB,KAAK,KAAK,kBAAkB,WAAW,KAAK,GAAG;EACjI,MAAM,QAAQ,OAAO,IAAI,KAAK,qBAAK,IAAI,IAAiB;EACxD,MAAM,SAAS,SAAsB,SAAkB;GACrD,IAAI,MAAM,IAAI,OAAO,GAAG;GACxB,MAAM,gBAAgB,MAAM,IAAI,OAAO;GACvC,IAAI,eAAe,OAAO,IAAI,aAAa,CAAC,EAAE,OAAO,OAAO;GAC5D,MAAM,IAAI,SAAS,KAAK;GACxB,yBAAyB,SAAS,IAAI;GACtC,IAAI,QAAQ,QAAQ,iBAAiB,GAAG,QAAQ,UAAU,OAAO,0BAA0B,CAAC,IAAI;GAChG,MAAM,IAAI,OAAO;EACnB;EAEA,CADgB,MAAM,QAAQ,iBAAiB,IAAI,CAAC,KAAK,IAAI,MAAM,KAAK,MAAM,iBAA8B,cAAc,CAAC,EAAA,CACnH,SAAS,YAAY;GAC3B,IAAI,CAAC,sBAAsB,OAAO,KAAK,QAAQ,QAAQ,QAAQ,KAAM,MAAM,QAAQ,WAAW,KAAK,WAAW,OAAO,MAAM,OACzH;GACF,IAAI,QAAQ,QAAQ,aAAa,GAAG;IAClC,MAAM,WAAW,cAAc,OAAO;IACtC,MAAM,UAAU,SAAS,QAAQ,UAAU,SAAS,KAAK,KAAK,iCAAiC,KAAK,CAAC;IACrG,MAAM,QACJ,SAAS,OAAO,KAChB,QAAQ,WAAW,SAAS,WAC3B,QAAQ,SAAS,KAAM,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAC,QAAQ,iBAAiB;IACtF,MAAM,aAAa,CAAC,MAAM,IAAI,OAAO;IACrC,MAAM,SAAS,KAAK;IACpB,SAAS,SAAS,UAAU;KAC1B,IAAI,CAAC,MAAM,QAAQ,iBAAiB,GAAG,MAAM,OAAO,cAAc,QAAQ,SAAS,KAAK,CAAC;IAC3F,CAAC;GACH,OAAO,IAAI,QAAQ,QAAQ,iBAAiB,KAAK,CAAC,QAAQ,eAAe,QAAQ,aAAa,GAAG;IAC/F,IAAI,MAAM,IAAI,OAAO,GAAG;IACxB,IACE,QAAQ,QAAQ,iBAAiB,KACjC,aAAa,OAAO,KACnB,QAAqC,SAAS,KAAA,KAC9C,QAAqC,UAAU,KAAA,KAChD,CAAC,QAAQ,cACT,CAAC,QAAQ,UAAU,SAAS,UAAU,GACtC;KACA,MAAM,kBAAkB,aAAa,IAAI,OAAO;KAChD,IAAI,mBAAmB,gBAAgB,UAAU,OAAO;MACtD,aAAa,gBAAgB,KAAK;MAClC,aAAa,OAAO,OAAO;KAC7B;KACA,IAAI,CAAC,aAAa,IAAI,OAAO,GAAG;MAC9B,MAAM,QAAQ,iBAAiB;OAC7B,IAAI,aAAa,IAAI,OAAO,CAAC,EAAE,UAAU,OAAO;OAChD,aAAa,OAAO,OAAO;OAE3B,MAAM,SAAS,KAAK;OACpB,UAAU;MACZ,GAAG,IAAI;MACP,aAAa,IAAI,SAAS;OAAE;OAAO;MAAM,CAAC;KAC5C;KACA;IACF;IACA,MAAM,UAAU,aAAa,IAAI,OAAO;IACxC,IAAI,SAAS;KACX,aAAa,QAAQ,KAAK;KAC1B,aAAa,OAAO,OAAO;IAC7B;IACA,MACE,SACA,QAAQ,QAAQ,iBAAiB,IAC7B,aAAa,OAAO,KAAK,cAAc,OAAO,IAC9C,SAAS,OAAO,KAAK,iCAAiC,OAAO,CACnE;GACF;EACF,CAAC;EACD,OAAO,IAAI,OAAO,KAAK;CACzB;CACA,MAAM,kBAAkB;EACtB,MAAM,eAAe,KAAK;EAC1B,IAAI,CAAC,cAAc;GACjB,MAAM,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,OAAO;GACzC;EACF;EACA,KAAK,MAAM,SAAS,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,eAAe,CAAC,sBAAsB,KAAK,GAAG,QAAQ,KAAK;EACzG,KAAK,MAAM,CAAC,SAAS,YAAY,cAAc,IAAI,QAAQ,cAAc,QAAQ,UAAU,SAAS,UAAU,GAAG,QAAQ,QAAQ,KAAK;EAGtI,aAAa,iBAA8B,gDAAgD,CAAC,CAAC,QAAQ,OAAO;EAE5G,aAAa,iBAA8B,cAAc,CAAC,CAAC,SAAS,YAAY;GAC9E,IAAI,WAAW,OAAO,KAAK,QAAQ,QAAQ,QAAQ,GAAG;GACtD,MAAM,QAAQ,QAAQ,QAAqB,aAAa,MAAM,QAAQ,QAAQ,iBAAiB,IAAI,UAAU;GAC7G,IAAI,OAAO,QAAQ,KAAK;EAC1B,CAAC;EACD,KAAK,MAAM,SAAS,OAAO,OAAO,GAChC,KAAK,MAAM,WAAW,OAAO;GAC3B,MAAM,oBACJ,QAAQ,eAAe,QAAQ,aAAa,KAC5C,kBAAkB,QAAQ,aAAa,KACvC,cAAc,QAAQ,aAAa,CAAC,CAAC,OAAO,UAAU,kBAAkB,KAAK,CAAC;GAChF,MAAM,OACJ,CAAC,aACD,kBAAkB,OAAO,KACzB,CAAC,qBACD,QAAQ,eACR,CAAC,QAAQ,QAAQ,qCAAmB,KACpC,CAAC,sBAAsB,OAAO,KAC9B,CAAC,gBAAgB,OAAO,MACvB,CAAC,QAAQ,QAAQ,iBAAiB,KAAK,cAAc,OAAO,KAAK,CAAC,QAAQ,UAAU,SAAS,UAAU,OACvG,CAAC,QAAQ,QAAQ,aAAa,KAAK,cAAc,OAAO,CAAC,CAAC,OAAO,UAAU,kBAAkB,KAAK,CAAC;GACtG,QAAQ,UAAU,OAAO,gBAAgB,IAAI;GAC7C,IAAI,QAAQ,QAAQ,iBAAiB,GAAG,QAAQ,UAAU,OAAO,0BAA0B,CAAC,IAAI;EAClG;CAEJ;CACA,MAAM,eAAe,UAAiB;EACpC,MAAM,OAAO,UAAU,MAAM,MAAM;EACnC,IAAI,MAAM,QAAQ,WAAW,GAAG;GAC9B,kBAAkB,UAAU,KAAK;GACjC,QAAQ,IAAI;GACZ,QAAQ,IAAI;GACZ,UAAU;EACZ;CACF;CACA,MAAM,mBAAkC,UAAU;EAChD,kBAAkB,UAAU,KAAK;EACjC,IAAI,MAAM,SAAS,qBAAqB;EACxC,MAAM,OAAO,UAAU,MAAM,MAAM;EACnC,IAAI,MAAM,QAAQ,IAAI;CACxB;CAEA,MAAM,wBAAuC,UAAU;EACrD,MAAM,UAAU,UAAU,MAAM,MAAM;EACtC,IAAI,CAAC,SAAS;EACd,MAAM,WAAY,MAAkD,QAAQ;EAC5E,kBAAkB,OAAO,UAAU,OAAO;EAC1C,UAAU;CACZ;CACA,IAAI,iBAAiB,sBAAsB,aAAa;EAAE,SAAS;EAAM,QAAQ,UAAU;CAAO,CAAC;CACnG,KAAK,MAAM,QAAQ;EAAC;EAAsB;EAAqB;CAAmB,GAChF,IAAI,iBAAiB,MAAM,iBAAiB;EAAE,SAAS;EAAM,QAAQ,UAAU;CAAO,CAAC;CACzF,IAAI,iBAAiB,mCAAmC,sBAAsB;EAAE,SAAS;EAAM,QAAQ,UAAU;CAAO,CAAC;CACzH,IAAI,aAAa,iBAAiB,wBAAwB,WAAW,EAAE,QAAQ,UAAU,OAAO,CAAC;CACjG,UAAU;CACV,MAAM,oBAAoB,WAA2B;EACnD,IAAI,OAAO,SAAS,aAClB,OAAO,CAAC,GAAG,MAAM,KAAK,OAAO,UAAU,GAAG,GAAG,MAAM,KAAK,OAAO,YAAY,CAAC,CAAC,CAAC,MAC3E,SACC,cAAc,IAAI,MACjB,KAAK,QAAQ,GAAG,eAAe,yBAAyB,KAAK,CAAC,CAAC,KAAK,cAAc,GAAG,eAAe,yBAAyB,EAClI;EACF,IAAI,OAAO,kBAAkB,SAAS,OAAO;EAC7C,MAAM,UAAW,OAAO,OAAmB;EAC3C,MAAM,WAAW,OAAO,YAAY;EACpC,MAAM,gBAAgB,UACpB,MACG,MAAM,KAAK,CAAC,CACZ,QAAQ,SAAS,QAAQ,CAAC;;;;EAA2D,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CACtG,KAAK,GAAG;EACb,OAAO,OAAO,YAAY,YAAY,aAAa,QAAQ,MAAM,aAAa,OAAO;CACvF;CACA,IAAI,YAAY;CAChB,MAAM,WAAW,MAAK,IAAI,aAAa,qBAAoB,mBAAmB,YAAY;EACxF,IAAI,aAAa,WAAW,CAAC,QAAQ,KAAK,gBAAgB,GAAG;EAC7D,YAAY;EACZ,qBAAqB;GACnB,YAAY;GACZ,IAAI,CAAC,SAAS,UAAU;EAC1B,CAAC;CACH,CAAC;CACD,SAAS,QAAQ,IAAI,iBAAiB;EACpC,SAAS;EACT,WAAW;EACX,YAAY;EACZ,mBAAmB;EACnB,iBAAiB;GAAC;GAAS;GAAU;GAAS;GAAQ;EAAO;CAC/D,CAAC;CACD,OAAO;EACL,eAAe;GACb,IAAI,SAAS,aAAa,CAAC;GAC3B;GACA,IAAI,gBAAgB,UAAU,OAAO,gBAAgB;GACrD,UAAU;GACV,IAAI,UAAU;GACd,aAAa;IACX,IAAI,WAAW,SAAS;IACxB,UAAU;IACV,IAAI,EAAE,cAAc,GAAG;KACrB,IAAI,gBAAgB,UAAU,IAAI,gBAAgB;KAClD,UAAU;IACZ;GACF;EACF;EACA,YAAY;GACV,IAAI,SAAS;GACb,UAAU;GACV,SAAS,WAAW;GACpB,UAAU,MAAM;GAChB,IAAI,gBAAgB,UAAU,OAAO,gBAAgB;GACrD,MAAM,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC,QAAQ,OAAO;EAC3C;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"prehide.js","names":[],"sources":["../../src/native/prehide.ts"],"sourcesContent":["import { modalUsesVerticalBars } from './shared/modal';\nimport { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE } from '@ionic/core';\nimport { VERTICAL_BARS_TRANSITION_CANCELED } from '../native-integration';\nimport {\n childElements,\n clearVerticalBarsPlacement,\n createVerticalBarsPageState,\n verticalBarsActionCandidate,\n verticalBarsBackCandidate,\n verticalBarsBackWebClass,\n verticalBarsOwned,\n isVerticalBarsToolbarActionShape,\n isPermanentlyExcluded,\n isShellDisabled,\n prehiddenClass,\n prehideRootClass,\n rejectedClass,\n setVerticalBarsPlacement,\n} from './shared/dom';\n\nconst overlays = 'ion-menu, ion-popover';\nconst sourceSelector = 'ion-back-button, ion-menu-button, ion-buttons, ion-button';\n// Realm- and teardown-safe: globals such as Element/HTMLElement may be gone\n// when a queued mutation microtask or a stale listener still runs.\nconst isHtmlElement = (node: unknown): node is HTMLElement => !!node && (node as Node).nodeType === 1;\nconst asElement = (node: Node | EventTarget | null): HTMLElement | undefined => (isHtmlElement(node) ? node : undefined);\nconst backSupported = (element: HTMLElement): boolean => {\n const back = element as HTMLIonBackButtonElement;\n return back.icon === undefined && back.color === undefined && !!back.shadowRoot;\n};\nconst eligibleBack = verticalBarsBackCandidate;\nconst eligible = verticalBarsActionCandidate;\n\n/** Capture toolbar placement once per routed-page epoch, before Ionic paints its transition. */\nexport const prehideVerticalBarsToolbarSources = (doc: Document): { suspend: () => () => void; stop: () => void } => {\n doc.documentElement.classList.add(prehideRootClass);\n const scopes = new Map<HTMLElement, Set<HTMLElement>>();\n const owner = new WeakMap<HTMLElement, HTMLElement>();\n const pendingBacks = new Map<HTMLElement, { scope: HTMLElement; timer: ReturnType<typeof setTimeout> }>();\n const verticalBarsPages = createVerticalBarsPageState();\n const listeners = new AbortController();\n const root = () => doc.querySelector<HTMLElement>('ion-app.ios-theme-vertical-bars');\n let suspended = 0;\n let stopped = false;\n const routedPage = (element: HTMLElement) => element.closest<HTMLElement>('.ion-page:not(ion-app, body)');\n const release = (scope: HTMLElement) => {\n for (const [element, pending] of pendingBacks) {\n if (pending.scope !== scope) continue;\n clearTimeout(pending.timer);\n pendingBacks.delete(element);\n }\n const owned = scopes.get(scope);\n if (!owned) return;\n owned.forEach((element) => {\n if (owner.get(element) !== scope) return;\n owner.delete(element);\n element.classList.remove(prehiddenClass);\n element.classList.remove(verticalBarsBackWebClass);\n clearVerticalBarsPlacement(element);\n });\n scopes.delete(scope);\n };\n const capture = (scope: HTMLElement) => {\n if (!root()?.contains(scope) || scope.closest(overlays) || !modalUsesVerticalBars(scope) || verticalBarsPages.isDeparted(scope)) return;\n const owned = scopes.get(scope) ?? new Set<HTMLElement>();\n const place = (element: HTMLElement, rail: boolean) => {\n if (owned.has(element)) return;\n const previousScope = owner.get(element);\n if (previousScope) scopes.get(previousScope)?.delete(element);\n owner.set(element, scope);\n setVerticalBarsPlacement(element, rail);\n if (element.matches('ion-back-button')) element.classList.toggle(verticalBarsBackWebClass, !rail);\n owned.add(element);\n };\n const sources = scope.matches('ion-back-button') ? [scope] : Array.from(scope.querySelectorAll<HTMLElement>(sourceSelector));\n sources.forEach((element) => {\n // Shell opt-out is temporary; decide initial placement once it is lifted.\n if (isShellDisabled(element)) return;\n if (!modalUsesVerticalBars(element) || element.closest(overlays) || (scope.matches('.ion-page') && routedPage(element) !== scope))\n return;\n if (element.matches('ion-buttons')) {\n const children = childElements(element);\n const actions = children.filter((child) => eligible(child) && isVerticalBarsToolbarActionShape(child));\n const group =\n eligible(element) &&\n actions.length === children.length &&\n (actions.length > 1 || (actions.length === 1 && actions[0].matches('ion-menu-button')));\n const freshGroup = !owned.has(element);\n place(element, group);\n children.forEach((child) => {\n if (!child.matches('ion-back-button')) place(child, freshGroup && actions.includes(child));\n });\n } else if (element.matches('ion-back-button') || !element.parentElement?.matches('ion-buttons')) {\n if (owned.has(element)) return;\n if (\n element.matches('ion-back-button') &&\n eligibleBack(element) &&\n (element as HTMLIonBackButtonElement).icon === undefined &&\n (element as HTMLIonBackButtonElement).color === undefined &&\n !element.shadowRoot &&\n !element.classList.contains('hydrated')\n ) {\n const previousPending = pendingBacks.get(element);\n if (previousPending && previousPending.scope !== scope) {\n clearTimeout(previousPending.timer);\n pendingBacks.delete(element);\n }\n if (!pendingBacks.has(element)) {\n const timer = setTimeout(() => {\n if (pendingBacks.get(element)?.scope !== scope) return;\n pendingBacks.delete(element);\n // A custom element that never hydrates must remain usable on Web.\n place(element, false);\n reconcile();\n }, 1500);\n pendingBacks.set(element, { scope, timer });\n }\n return;\n }\n const pending = pendingBacks.get(element);\n if (pending) {\n clearTimeout(pending.timer);\n pendingBacks.delete(element);\n }\n place(\n element,\n element.matches('ion-back-button')\n ? eligibleBack(element) && backSupported(element)\n : eligible(element) && isVerticalBarsToolbarActionShape(element),\n );\n }\n });\n scopes.set(scope, owned);\n };\n const reconcile = () => {\n const verticalBars = root();\n if (!verticalBars) {\n Array.from(scopes.keys()).forEach(release);\n return;\n }\n for (const scope of scopes.keys()) if (!scope.isConnected || !modalUsesVerticalBars(scope)) release(scope);\n for (const [element, pending] of pendingBacks) if (element.shadowRoot || element.classList.contains('hydrated')) capture(pending.scope);\n // Ionic inserts the destination as invisible before WillEnter. Hide its\n // sources in that same mutation microtask; capture new DOM identities on active pages too.\n verticalBars.querySelectorAll<HTMLElement>('.ion-page:not(ion-app, body, .ion-page-hidden)').forEach(capture);\n // Root toolbars can mount after startup; each new DOM identity is captured once.\n verticalBars.querySelectorAll<HTMLElement>(sourceSelector).forEach((element) => {\n if (routedPage(element) || element.closest(overlays)) return;\n const scope = element.closest<HTMLElement>('ion-toolbar') ?? (element.matches('ion-back-button') ? element : null);\n if (scope) capture(scope);\n });\n for (const owned of scopes.values()) {\n for (const element of owned) {\n const groupOwnsChildren =\n element.parentElement?.matches('ion-buttons') &&\n verticalBarsOwned(element.parentElement) &&\n childElements(element.parentElement).every((child) => verticalBarsOwned(child));\n const hide =\n !suspended &&\n verticalBarsOwned(element) &&\n !groupOwnsChildren &&\n element.isConnected &&\n !element.closest(`.${rejectedClass}`) &&\n !isPermanentlyExcluded(element) &&\n !isShellDisabled(element) &&\n (!element.matches('ion-back-button') || backSupported(element) || !element.classList.contains('hydrated')) &&\n (!element.matches('ion-buttons') || childElements(element).every((child) => verticalBarsOwned(child)));\n element.classList.toggle(prehiddenClass, hide);\n if (element.matches('ion-back-button')) element.classList.toggle(verticalBarsBackWebClass, !hide);\n }\n }\n };\n const onWillEnter = (event: Event) => {\n const page = asElement(event.target);\n if (page?.matches('.ion-page')) {\n verticalBarsPages.lifecycle(event);\n release(page); // Cached pages begin a new placement epoch.\n capture(page);\n reconcile();\n }\n };\n const onPageLifecycle: EventListener = (event) => {\n verticalBarsPages.lifecycle(event);\n if (event.type !== LIFECYCLE_DID_LEAVE) return;\n const page = asElement(event.target);\n if (page) release(page);\n };\n // A canceled transition keeps the leaving page active and abandons the entering one.\n const onTransitionCanceled: EventListener = (event) => {\n const leaving = asElement(event.target);\n if (!leaving) return;\n const entering = (event as CustomEvent<{ entering?: HTMLElement }>).detail?.entering;\n verticalBarsPages.cancel(entering, leaving);\n reconcile();\n };\n doc.addEventListener(LIFECYCLE_WILL_ENTER, onWillEnter, { capture: true, signal: listeners.signal });\n for (const name of [LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE])\n doc.addEventListener(name, onPageLifecycle, { capture: true, signal: listeners.signal });\n doc.addEventListener(VERTICAL_BARS_TRANSITION_CANCELED, onTransitionCanceled, { capture: true, signal: listeners.signal });\n doc.defaultView?.addEventListener('nativeUIShellRefresh', reconcile, { signal: listeners.signal });\n reconcile();\n const mutationRelevant = (record: MutationRecord) => {\n if (record.type === 'childList')\n return [...Array.from(record.addedNodes), ...Array.from(record.removedNodes)].some(\n (node) =>\n isHtmlElement(node) &&\n (node.matches(`${sourceSelector}, .ion-page, ion-toolbar`) || !!node.querySelector(`${sourceSelector}, .ion-page, ion-toolbar`)),\n );\n if (record.attributeName !== 'class') return true;\n const current = (record.target as Element).className;\n const previous = record.oldValue ?? '';\n const withoutOwned = (value: string) =>\n value\n .split(/\\s+/)\n .filter((name) => name && ![prehiddenClass, prehideRootClass, verticalBarsBackWebClass].includes(name))\n .join(' ');\n return typeof current !== 'string' || withoutOwned(previous) !== withoutOwned(current);\n };\n let scheduled = false;\n const observer = new (doc.defaultView?.MutationObserver ?? MutationObserver)((records) => {\n if (scheduled || stopped || !records.some(mutationRelevant)) return;\n scheduled = true;\n queueMicrotask(() => {\n scheduled = false;\n if (!stopped) reconcile();\n });\n });\n observer.observe(doc.documentElement, {\n subtree: true,\n childList: true,\n attributes: true,\n attributeOldValue: true,\n attributeFilter: ['class', 'data-shell', 'hidden', 'inert', 'icon', 'color'],\n });\n return {\n suspend: () => {\n if (stopped) return () => {};\n suspended++;\n doc.documentElement.classList.remove(prehideRootClass);\n reconcile();\n let resumed = false;\n return () => {\n if (resumed || stopped) return;\n resumed = true;\n if (--suspended === 0) {\n doc.documentElement.classList.add(prehideRootClass);\n reconcile();\n }\n };\n },\n stop: () => {\n if (stopped) return;\n stopped = true;\n observer.disconnect();\n listeners.abort();\n doc.documentElement.classList.remove(prehideRootClass);\n Array.from(scopes.keys()).forEach(release);\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { ShellControl, ShellItem, VerticalControlAreaOptions } from "../definiti
|
|
|
2
2
|
import { NativeUIShellComponent } from "../components/index.js";
|
|
3
3
|
//#region src/native/shared/candidate.d.ts
|
|
4
4
|
export interface Candidate {
|
|
5
|
+
buttonProjection?: VerticalControlAreaOptions['buttonProjection'];
|
|
5
6
|
buttonDefaultFill?: VerticalControlAreaOptions['buttonDefaultFill'];
|
|
6
7
|
element: HTMLElement;
|
|
7
8
|
sources?: HTMLElement[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate.d.ts","names":[],"sources":["../../../src/native/shared/candidate.ts"],"mappings":";;;iBAIiB;EACf,oBAAoB;EACpB,SAAS;EACT,UAAU;EACV,SAAS;EACT,SAAS,YAAY;EACrB;IAAS,MAAM;IAAW;IAAgB;;;YAGhC,YAAY,SAAS;qBAGpB,kBACX,SAAS,aACT,MAAM,wBACN,IAAI,UACJ,UAAS,+BACR;
|
|
1
|
+
{"version":3,"file":"candidate.d.ts","names":[],"sources":["../../../src/native/shared/candidate.ts"],"mappings":";;;iBAIiB;EACf,mBAAmB;EACnB,oBAAoB;EACpB,SAAS;EACT,UAAU;EACV,SAAS;EACT,SAAS,YAAY;EACrB;IAAS,MAAM;IAAW;IAAgB;;;YAGhC,YAAY,SAAS;qBAGpB,kBACX,SAAS,aACT,MAAM,wBACN,IAAI,UACJ,UAAS,+BACR;qBAqBU,aACX,WAAW,WACX,OAAO,aACP,IAAI,UACJ,UAAS,YACT,mBACC"}
|
|
@@ -6,6 +6,7 @@ const createCandidate = (element, kind, id, options = {}) => {
|
|
|
6
6
|
const style = getComputedStyle(element);
|
|
7
7
|
return {
|
|
8
8
|
element,
|
|
9
|
+
buttonProjection: options.buttonProjection,
|
|
9
10
|
buttonDefaultFill: options.buttonDefaultFill,
|
|
10
11
|
control: {
|
|
11
12
|
id: id(element),
|
|
@@ -32,9 +33,12 @@ const appendItem = (candidate, child, id, content = child, label = text(child))
|
|
|
32
33
|
const badge = child.querySelector("ion-badge");
|
|
33
34
|
const badgeStyle = badge && visible(badge) ? getComputedStyle(badge) : void 0;
|
|
34
35
|
const sourceFill = child.fill;
|
|
36
|
+
const projectionOwner = [child, child.closest("ion-buttons")].find((element) => element?.matches("[data-projection=\"source\"], [data-projection=\"system\"], .ios-theme-projection-source, .ios-theme-projection-system"));
|
|
37
|
+
const attributeProjection = projectionOwner?.getAttribute("data-projection");
|
|
38
|
+
const systemButton = (attributeProjection === "source" || attributeProjection === "system" ? attributeProjection : projectionOwner ? projectionOwner.classList.contains("ios-theme-projection-system") ? "system" : "source" : candidate.buttonProjection) !== "source" && isVerticalBarsSource(child) && child.matches("ion-button, ion-menu-button");
|
|
35
39
|
const defaultFill = child.closest("ion-buttons") ? "clear" : candidate.buttonDefaultFill;
|
|
36
40
|
const fill = !sourceFill || sourceFill === "default" ? defaultFill : sourceFill;
|
|
37
|
-
const buttonFill = isVerticalBarsSource(child) && child.matches("ion-button") && (fill === "clear" || fill === "solid" || fill === "outline") ? fill : void 0;
|
|
41
|
+
const buttonFill = !systemButton && isVerticalBarsSource(child) && child.matches("ion-button") && (fill === "clear" || fill === "solid" || fill === "outline") ? fill : void 0;
|
|
38
42
|
const outline = buttonFill === "outline" ? getComputedStyle(native ?? child) : void 0;
|
|
39
43
|
const item = {
|
|
40
44
|
id: id(child),
|
|
@@ -45,7 +49,8 @@ const appendItem = (candidate, child, id, content = child, label = text(child))
|
|
|
45
49
|
selected: !!child.selected,
|
|
46
50
|
fontSize: parseFloat(labelStyle.fontSize),
|
|
47
51
|
fontWeight: parseInt(labelStyle.fontWeight, 10) || 400,
|
|
48
|
-
color: getComputedStyle(native ?? child).color,
|
|
52
|
+
color: systemButton ? "currentColor" : getComputedStyle(native ?? child).color,
|
|
53
|
+
iconTemplate: systemButton ? true : void 0,
|
|
49
54
|
buttonFill,
|
|
50
55
|
backgroundColor: buttonFill === "solid" ? getComputedStyle(native ?? child).backgroundColor : void 0,
|
|
51
56
|
borderColor: outline?.borderTopColor,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"candidate.js","names":[],"sources":["../../../src/native/shared/candidate.ts"],"sourcesContent":["import type { ShellControl, ShellItem, NativeUIShellComponent, VerticalControlAreaOptions } from '../definitions';\nimport { frame, isDark, isVerticalBarsSource, text, visible } from './dom';\nimport { iconSource } from './icons';\n\nexport interface Candidate {\n buttonDefaultFill?: VerticalControlAreaOptions['buttonDefaultFill'];\n element: HTMLElement;\n sources?: HTMLElement[];\n control: ShellControl;\n actions: Map<string, HTMLElement>;\n icons: { item: ShellItem; source: string; field?: 'closeIcon' }[];\n}\n\nexport type Identify = (element: HTMLElement) => string;\ntype ItemElement = HTMLElement & { disabled?: boolean; selected?: boolean };\n\nexport const createCandidate = (\n element: HTMLElement,\n kind: NativeUIShellComponent,\n id: Identify,\n options: VerticalControlAreaOptions = {},\n): Candidate => {\n const rect = element.getBoundingClientRect();\n const style = getComputedStyle(element);\n return {\n element,\n buttonDefaultFill: options.buttonDefaultFill,\n control: {\n id: id(element),\n kind,\n ...frame(rect),\n items: [],\n dark: isDark(style),\n rtl: style.direction === 'rtl',\n },\n actions: new Map(),\n icons: [],\n };\n};\n\n// Shared text, artwork, geometry and action data; component rules stay with their readers.\nexport const appendItem = (\n candidate: Candidate,\n child: HTMLElement,\n id: Identify,\n content: ParentNode = child,\n label = text(child),\n): ShellItem | undefined => {\n if (\n !visible(child, isVerticalBarsSource(candidate.element)) ||\n child.querySelector('input, button, a, img, canvas, video, ion-spinner, ion-avatar')\n )\n return;\n const icons = Array.from(content.querySelectorAll<HTMLElement>('ion-icon'));\n const directSVGs = Array.from(content.querySelectorAll<SVGElement>('svg'));\n if (icons.length + directSVGs.length > 1) return undefined;\n const svg = directSVGs[0] ?? icons[0]?.shadowRoot?.querySelector<SVGElement>('svg');\n if (icons.length && !svg) return undefined; // ion-icon has not finished loading.\n const labelElement = content.querySelector('[part=\"text\"], ion-label') ?? child;\n const native = child.shadowRoot?.querySelector('[part=\"native\"]');\n const labelStyle = getComputedStyle(labelElement);\n const badge = child.querySelector<HTMLElement>('ion-badge');\n const badgeStyle = badge && visible(badge) ? getComputedStyle(badge) : undefined;\n const sourceFill = (child as HTMLIonButtonElement).fill;\n // Ionic defaults buttons inside ion-buttons to clear, even when the app defaults to solid.\n const defaultFill = child.closest('ion-buttons') ? 'clear' : candidate.buttonDefaultFill;\n const fill = !sourceFill || sourceFill === 'default' ? defaultFill : sourceFill;\n const buttonFill =\n isVerticalBarsSource(child) && child.matches('ion-button') && (fill === 'clear' || fill === 'solid' || fill === 'outline')\n ? fill\n : undefined;\n const outline = buttonFill === 'outline' ? getComputedStyle(native ?? child) : undefined;\n const item: ShellItem = {\n id: id(child),\n ...frame(child.getBoundingClientRect(), candidate.element.getBoundingClientRect()),\n label,\n accessibilityLabel:\n child.getAttribute('aria-label') ??\n native?.getAttribute('aria-label') ??\n (icons[0]?.getAttribute('aria-hidden') === 'true' ? null : icons[0]?.getAttribute('aria-label')) ??\n label,\n disabled:\n !!(child as ItemElement).disabled ||\n !!(candidate.element as ItemElement).disabled ||\n getComputedStyle(child).pointerEvents === 'none',\n selected: !!(child as ItemElement).selected,\n fontSize: parseFloat(labelStyle.fontSize),\n fontWeight: parseInt(labelStyle.fontWeight, 10) || 400,\n color: getComputedStyle(native ?? child).color,\n buttonFill,\n backgroundColor: buttonFill === 'solid' ? getComputedStyle(native ?? child).backgroundColor : undefined,\n borderColor: outline?.borderTopColor,\n borderWidth: outline ? parseFloat(outline.borderTopWidth) : undefined,\n badge: badgeStyle\n ? { value: badge!.textContent?.trim() ?? '', color: badgeStyle.backgroundColor, textColor: badgeStyle.color }\n : undefined,\n };\n if (svg) {\n const source = iconSource(svg);\n if (!source) return undefined;\n const size = (icons[0] ?? svg).getBoundingClientRect();\n item.iconWidth = size.width;\n item.iconHeight = size.height;\n if (!size.width || !size.height) return undefined;\n item.iconPosition = (icons[0] ?? svg).getAttribute('slot') === 'end' ? 'trailing' : 'leading';\n candidate.icons.push({ item, source });\n }\n if (native && child.matches('ion-button, ion-back-button')) {\n const style = getComputedStyle(native);\n const icon = icons[0] ?? svg;\n const iconStyle = icon && getComputedStyle(icon);\n const leadingMargin = parseFloat(iconStyle?.marginInlineStart ?? '') || 0;\n const trailingMargin = parseFloat(iconStyle?.marginInlineEnd ?? '') || 0;\n const trailing = item.iconPosition === 'trailing';\n const inner = native.querySelector('.button-inner');\n const gap = inner ? parseFloat(getComputedStyle(inner).columnGap) || 0 : 0;\n // UIKit centers the title/image pair using its insets. Include Ionic's\n // border and negative outer icon margin instead of applying a fixed offset.\n item.contentInsetLeading =\n (parseFloat(style.paddingInlineStart) || 0) +\n (parseFloat(style.borderInlineStartWidth) || 0) +\n (!trailing || !label ? leadingMargin : 0);\n item.contentInsetTrailing =\n (parseFloat(style.paddingInlineEnd) || 0) + (parseFloat(style.borderInlineEndWidth) || 0) + (trailing || !label ? trailingMargin : 0);\n item.imagePadding = label && icon ? gap + (trailing ? leadingMargin : trailingMargin) : 0;\n }\n if (!label && !svg) return undefined;\n candidate.control.items.push(item);\n candidate.actions.set(item.id, child);\n return item;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"candidate.js","names":[],"sources":["../../../src/native/shared/candidate.ts"],"sourcesContent":["import type { ShellControl, ShellItem, NativeUIShellComponent, VerticalControlAreaOptions } from '../definitions';\nimport { frame, isDark, isVerticalBarsSource, text, visible } from './dom';\nimport { iconSource } from './icons';\n\nexport interface Candidate {\n buttonProjection?: VerticalControlAreaOptions['buttonProjection'];\n buttonDefaultFill?: VerticalControlAreaOptions['buttonDefaultFill'];\n element: HTMLElement;\n sources?: HTMLElement[];\n control: ShellControl;\n actions: Map<string, HTMLElement>;\n icons: { item: ShellItem; source: string; field?: 'closeIcon' }[];\n}\n\nexport type Identify = (element: HTMLElement) => string;\ntype ItemElement = HTMLElement & { disabled?: boolean; selected?: boolean };\n\nexport const createCandidate = (\n element: HTMLElement,\n kind: NativeUIShellComponent,\n id: Identify,\n options: VerticalControlAreaOptions = {},\n): Candidate => {\n const rect = element.getBoundingClientRect();\n const style = getComputedStyle(element);\n return {\n element,\n buttonProjection: options.buttonProjection,\n buttonDefaultFill: options.buttonDefaultFill,\n control: {\n id: id(element),\n kind,\n ...frame(rect),\n items: [],\n dark: isDark(style),\n rtl: style.direction === 'rtl',\n },\n actions: new Map(),\n icons: [],\n };\n};\n\n// Shared text, artwork, geometry and action data; component rules stay with their readers.\nexport const appendItem = (\n candidate: Candidate,\n child: HTMLElement,\n id: Identify,\n content: ParentNode = child,\n label = text(child),\n): ShellItem | undefined => {\n if (\n !visible(child, isVerticalBarsSource(candidate.element)) ||\n child.querySelector('input, button, a, img, canvas, video, ion-spinner, ion-avatar')\n )\n return;\n const icons = Array.from(content.querySelectorAll<HTMLElement>('ion-icon'));\n const directSVGs = Array.from(content.querySelectorAll<SVGElement>('svg'));\n if (icons.length + directSVGs.length > 1) return undefined;\n const svg = directSVGs[0] ?? icons[0]?.shadowRoot?.querySelector<SVGElement>('svg');\n if (icons.length && !svg) return undefined; // ion-icon has not finished loading.\n const labelElement = content.querySelector('[part=\"text\"], ion-label') ?? child;\n const native = child.shadowRoot?.querySelector('[part=\"native\"]');\n const labelStyle = getComputedStyle(labelElement);\n const badge = child.querySelector<HTMLElement>('ion-badge');\n const badgeStyle = badge && visible(badge) ? getComputedStyle(badge) : undefined;\n const sourceFill = (child as HTMLIonButtonElement).fill;\n const projectionOwner = [child, child.closest('ion-buttons')].find((element) =>\n element?.matches('[data-projection=\"source\"], [data-projection=\"system\"], .ios-theme-projection-source, .ios-theme-projection-system'),\n );\n const attributeProjection = projectionOwner?.getAttribute('data-projection');\n const projection =\n attributeProjection === 'source' || attributeProjection === 'system'\n ? attributeProjection\n : projectionOwner\n ? projectionOwner.classList.contains('ios-theme-projection-system')\n ? 'system'\n : 'source'\n : candidate.buttonProjection;\n const systemButton = projection !== 'source' && isVerticalBarsSource(child) && child.matches('ion-button, ion-menu-button');\n // Ionic defaults buttons inside ion-buttons to clear, even when the app defaults to solid.\n const defaultFill = child.closest('ion-buttons') ? 'clear' : candidate.buttonDefaultFill;\n const fill = !sourceFill || sourceFill === 'default' ? defaultFill : sourceFill;\n const buttonFill =\n !systemButton &&\n isVerticalBarsSource(child) &&\n child.matches('ion-button') &&\n (fill === 'clear' || fill === 'solid' || fill === 'outline')\n ? fill\n : undefined;\n const outline = buttonFill === 'outline' ? getComputedStyle(native ?? child) : undefined;\n const item: ShellItem = {\n id: id(child),\n ...frame(child.getBoundingClientRect(), candidate.element.getBoundingClientRect()),\n label,\n accessibilityLabel:\n child.getAttribute('aria-label') ??\n native?.getAttribute('aria-label') ??\n (icons[0]?.getAttribute('aria-hidden') === 'true' ? null : icons[0]?.getAttribute('aria-label')) ??\n label,\n disabled:\n !!(child as ItemElement).disabled ||\n !!(candidate.element as ItemElement).disabled ||\n getComputedStyle(child).pointerEvents === 'none',\n selected: !!(child as ItemElement).selected,\n fontSize: parseFloat(labelStyle.fontSize),\n fontWeight: parseInt(labelStyle.fontWeight, 10) || 400,\n color: systemButton ? 'currentColor' : getComputedStyle(native ?? child).color,\n iconTemplate: systemButton ? true : undefined,\n buttonFill,\n backgroundColor: buttonFill === 'solid' ? getComputedStyle(native ?? child).backgroundColor : undefined,\n borderColor: outline?.borderTopColor,\n borderWidth: outline ? parseFloat(outline.borderTopWidth) : undefined,\n badge: badgeStyle\n ? { value: badge!.textContent?.trim() ?? '', color: badgeStyle.backgroundColor, textColor: badgeStyle.color }\n : undefined,\n };\n if (svg) {\n const source = iconSource(svg);\n if (!source) return undefined;\n const size = (icons[0] ?? svg).getBoundingClientRect();\n item.iconWidth = size.width;\n item.iconHeight = size.height;\n if (!size.width || !size.height) return undefined;\n item.iconPosition = (icons[0] ?? svg).getAttribute('slot') === 'end' ? 'trailing' : 'leading';\n candidate.icons.push({ item, source });\n }\n if (native && child.matches('ion-button, ion-back-button')) {\n const style = getComputedStyle(native);\n const icon = icons[0] ?? svg;\n const iconStyle = icon && getComputedStyle(icon);\n const leadingMargin = parseFloat(iconStyle?.marginInlineStart ?? '') || 0;\n const trailingMargin = parseFloat(iconStyle?.marginInlineEnd ?? '') || 0;\n const trailing = item.iconPosition === 'trailing';\n const inner = native.querySelector('.button-inner');\n const gap = inner ? parseFloat(getComputedStyle(inner).columnGap) || 0 : 0;\n // UIKit centers the title/image pair using its insets. Include Ionic's\n // border and negative outer icon margin instead of applying a fixed offset.\n item.contentInsetLeading =\n (parseFloat(style.paddingInlineStart) || 0) +\n (parseFloat(style.borderInlineStartWidth) || 0) +\n (!trailing || !label ? leadingMargin : 0);\n item.contentInsetTrailing =\n (parseFloat(style.paddingInlineEnd) || 0) + (parseFloat(style.borderInlineEndWidth) || 0) + (trailing || !label ? trailingMargin : 0);\n item.imagePadding = label && icon ? gap + (trailing ? leadingMargin : trailingMargin) : 0;\n }\n if (!label && !svg) return undefined;\n candidate.control.items.push(item);\n candidate.actions.set(item.id, child);\n return item;\n};\n"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ export declare const verticalBarsBackWebClass = "ios-theme-vertical-bars-back-we
|
|
|
10
10
|
export declare const prehideOnlyMutation: (record: MutationRecord) => boolean;
|
|
11
11
|
export declare const withoutPrehide: <T>(element: HTMLElement, read: () => T) => T;
|
|
12
12
|
export declare const isDark: (style: CSSStyleDeclaration) => boolean;
|
|
13
|
-
export declare const excluded = ".
|
|
13
|
+
export declare const excluded = ".ios-theme-disabled, .ios26-disabled, .ion-cloned-element, [hidden], [inert], .ion-page-hidden, .ion-page-invisible";
|
|
14
14
|
export declare const setVerticalBarsEnteringPage: (page: HTMLElement, entering: boolean) => void;
|
|
15
15
|
export declare const verticalBarsEnteringPage: (element: HTMLElement) => HTMLElement | undefined;
|
|
16
16
|
export declare const createVerticalBarsPageState: () => {
|
|
@@ -38,7 +38,7 @@ const isDark = (style) => {
|
|
|
38
38
|
const background = style.getPropertyValue("--ion-background-color-rgb").match(/\d+/g)?.slice(0, 3).map(Number);
|
|
39
39
|
return !!background && background.length === 3 && background[0] * .2126 + background[1] * .7152 + background[2] * .0722 < 128;
|
|
40
40
|
};
|
|
41
|
-
const permanentlyExcluded = ".
|
|
41
|
+
const permanentlyExcluded = ".ios-theme-disabled, .ios26-disabled, .ion-cloned-element, [hidden], [inert]";
|
|
42
42
|
const excluded = `${permanentlyExcluded}, .ion-page-hidden, .ion-page-invisible`;
|
|
43
43
|
const enteringPages = /* @__PURE__ */ new WeakSet();
|
|
44
44
|
const setVerticalBarsEnteringPage = (page, entering) => {
|
|
@@ -73,8 +73,8 @@ const createVerticalBarsPageState = () => {
|
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
75
|
};
|
|
76
|
-
const disabledButtonGroup = "ion-buttons:is(.
|
|
77
|
-
const shellDisabledSelector = ".ios-theme-shell-disabled";
|
|
76
|
+
const disabledButtonGroup = "ion-buttons:is(.ios-theme-disabled, .ios26-disabled)";
|
|
77
|
+
const shellDisabledSelector = ".ios-theme-shell-disabled, [data-shell=\"disabled\"]";
|
|
78
78
|
const isDisabledButtonGroupChild = (element) => element.matches("ion-button") && element.parentElement?.matches(disabledButtonGroup) === true;
|
|
79
79
|
const verticalBarsTags = /* @__PURE__ */ new Set([
|
|
80
80
|
"ion-button",
|
|
@@ -121,7 +121,7 @@ const verticalBarsActionCandidate = (element) => inFixedToolbar(element) && !ele
|
|
|
121
121
|
const verticalBarsBackCandidate = (element) => isVerticalBarsBackPosition(element) && !element.closest("ion-buttons.ios-theme-horizontal-only") && !isPermanentlyExcluded(element) && !isShellDisabled(element) && !element.closest(overlays) && modalUsesVerticalBars(element);
|
|
122
122
|
const verticalBarsToolbarActions = (element) => childElements(element).filter((child) => !child.matches("ion-back-button") && isVerticalBarsToolbarAction(child));
|
|
123
123
|
const isVerticalBarsToolbarGroup = (element) => {
|
|
124
|
-
return element.matches("ion-buttons") && verticalBarsOwned(element) && !element.matches(".
|
|
124
|
+
return element.matches("ion-buttons") && verticalBarsOwned(element) && !element.matches(".ios-theme-disabled, .ios26-disabled") && !isShellDisabled(element);
|
|
125
125
|
};
|
|
126
126
|
const activateProjectedElement = (element) => {
|
|
127
127
|
((element.matches("ion-button, ion-back-button, ion-menu-button") ? element.shadowRoot?.querySelector("[part~=\"native\"]") : void 0) ?? element).click();
|