diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index f947369366..646f19c62b 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -3059,6 +3059,7 @@ declare global { } namespace JSXElements { export interface IonTabAttributes extends HTMLAttributes { + active?: boolean; badge?: string; badgeStyle?: string; btnId?: string; diff --git a/packages/core/src/components/animation-controller/animation-interface.tsx b/packages/core/src/components/animation-controller/animation-interface.tsx index 5e586a5d1f..6f385546a3 100644 --- a/packages/core/src/components/animation-controller/animation-interface.tsx +++ b/packages/core/src/components/animation-controller/animation-interface.tsx @@ -22,6 +22,7 @@ export interface Animation { beforeClearStyles(propertyNames: string[]): Animation; beforeAddRead(domReadFn: Function): Animation; beforeAddWrite(domWriteFn: Function): Animation; + duringAddClass(className: string): Animation; afterAddClass(className: string): Animation; afterRemoveClass(className: string): Animation; afterStyles(styles: { [property: string]: any; }): Animation; diff --git a/packages/core/src/components/animation-controller/animator.tsx b/packages/core/src/components/animation-controller/animator.tsx index b880882486..2fac725a44 100644 --- a/packages/core/src/components/animation-controller/animator.tsx +++ b/packages/core/src/components/animation-controller/animator.tsx @@ -231,6 +231,15 @@ export class Animator { return this; } + /** + * Sets a CSS class during the duration of the animation. + */ + duringAddClass(className: string): Animator { + this.beforeAddClass(className); + this.afterRemoveClass(className); + return this; + } + /** * Set CSS inline styles to this animation's elements * before the animation begins. diff --git a/packages/core/src/components/content/content.ios.vars.scss b/packages/core/src/components/content/content.ios.vars.scss index b9296de3ad..648eca1242 100644 --- a/packages/core/src/components/content/content.ios.vars.scss +++ b/packages/core/src/components/content/content.ios.vars.scss @@ -8,6 +8,3 @@ $content-ios-font-family: $font-family-ios-base !default; /// @prop - Background color of the outer content $content-ios-outer-background: $background-ios-color-step-50 !default; - -/// @prop - Background color of the content when making transition -$content-ios-transition-background: #000 !default; diff --git a/packages/core/src/components/nav/nav-utils.ts b/packages/core/src/components/nav/nav-utils.ts index 5d9d60cc1f..851257efda 100644 --- a/packages/core/src/components/nav/nav-utils.ts +++ b/packages/core/src/components/nav/nav-utils.ts @@ -68,7 +68,7 @@ export function canNavGoBack(nav: Nav, view?: ViewController) { if (!nav) { return false; } - return nav.getPrevious(view); + return !!nav.getPrevious(view); } export function transitionFactory(animation: Animation): Transition { @@ -127,20 +127,28 @@ export function destroyTransition(transitionId: number) { } export function getHydratedTransition(name: string, config: Config, transitionId: number, emptyTransition: Transition, enteringView: ViewController, leavingView: ViewController, opts: AnimationOptions, defaultTransitionFactory: TransitionBuilder): Promise { - + // Let makes sure everything is hydrated and ready to animate + const componentReadyPromise: Promise[] = []; + if (enteringView && (enteringView.element as any).componentOnReady) { + componentReadyPromise.push((enteringView.element as any).componentOnReady()); + } + if (leavingView && (leavingView.element as any).componentOnReady) { + componentReadyPromise.push((leavingView.element as any).componentOnReady()); + } const transitionFactory = config.get(name) as TransitionBuilder || defaultTransitionFactory; - - return transitionFactory(emptyTransition, enteringView, leavingView, opts).then((hydratedTransition) => { - hydratedTransition.transitionId = transitionId; - if (!activeTransitions.has(transitionId)) { - // sweet, this is the root transition - activeTransitions.set(transitionId, hydratedTransition); - } else { - // we've got a parent transition going - // just append this transition to the existing one - activeTransitions.get(transitionId).add(hydratedTransition); - } - return hydratedTransition; + return Promise.all(componentReadyPromise) + .then(() => transitionFactory(emptyTransition, enteringView, leavingView, opts)) + .then((hydratedTransition) => { + hydratedTransition.transitionId = transitionId; + if (!activeTransitions.has(transitionId)) { + // sweet, this is the root transition + activeTransitions.set(transitionId, hydratedTransition); + } else { + // we've got a parent transition going + // just append this transition to the existing one + activeTransitions.get(transitionId).add(hydratedTransition); + } + return hydratedTransition; }); } diff --git a/packages/core/src/components/nav/nav.scss b/packages/core/src/components/nav/nav.scss index 385ea48ca3..e1a35ce1b7 100644 --- a/packages/core/src/components/nav/nav.scss +++ b/packages/core/src/components/nav/nav.scss @@ -1,7 +1,6 @@ -// Util -// -------------------------------------------------- @import "../../themes/util"; +$navigation-ios-transition-background: #000 !default; ion-nav { @include position(0); @@ -13,10 +12,7 @@ ion-nav { width: 100%; height: 100%; - background-color: #000; - contain: layout size style; - } .ion-page { @@ -31,3 +27,24 @@ ion-nav { contain: layout size style; } + +.nav-decor { + display: none; +} + +.show-decor > .nav-decor { + @include position(0, null, null, 0); + + // when ios pages transition, the leaving page grays out + // this is the black square behind all pages so they gray out + position: absolute; + z-index: 0; + display: block; + + width: 100%; + height: 100%; + + background: $navigation-ios-transition-background; + + pointer-events: none; +} diff --git a/packages/core/src/components/nav/nav.tsx b/packages/core/src/components/nav/nav.tsx index f4fe878fc0..db43c83c79 100644 --- a/packages/core/src/components/nav/nav.tsx +++ b/packages/core/src/components/nav/nav.tsx @@ -335,6 +335,9 @@ export class Nav implements PublicNav, NavOutlet { attachTo='body' >); } + if (this.mode === 'ios') { + dom.push(