import { tagName } from '@ember-decorators/component';
import { computed } from '@ember/object';
import Component from '@ember/component';
import ComponentChild from 'ember-bootstrap/mixins/component-child';
import { next } from '@ember/runloop';
import overrideableCP from 'ember-bootstrap/utils/cp/overrideable';
import { addObserver } from '@ember/object/observers';
import deprecateSubclassing from 'ember-bootstrap/utils/deprecate-subclassing';
import { ref } from 'ember-ref-bucket';
/**
A visible user-defined slide.
See [Components.Carousel](Components.Carousel.html) for examples.
@class CarouselSlide
@namespace Components
@extends Ember.Component
@public
*/
@tagName('')
@deprecateSubclassing
export default class CarouselSlide extends Component.extend(ComponentChild) {
/**
* @property _element
* @type null | HTMLElement
* @private
*/
@ref('mainNode') _element = null;
/**
* Defines slide visibility.
*
* @property active
* @type boolean
* @private
*/
@overrideableCP('isCurrentSlide', 'presentationState', function () {
return this.isCurrentSlide && this.presentationState === null;
})
active;
/**
* @private
* @property isCurrentSlide
* @type boolean
*/
@(computed('currentSlide').readOnly())
get isCurrentSlide() {
return this.currentSlide === this;
}
/**
* @private
* @property isFollowingSlide
* @type boolean
*/
@(computed('followingSlide').readOnly())
get isFollowingSlide() {
return this.followingSlide === this;
}
/**
* Slide is moving to the left.
*
* @property left
* @type boolean
* @private
*/
left = false;
/**
* Next to appear in a left sliding.
*
* @property next
* @type boolean
* @private
*/
next = false;
/**
* Next to appear in a right sliding.
*
* @property prev
* @type boolean
* @private
*/
prev = false;
/**
* Slide is moving to the right.
*
* @property right
* @type boolean
* @private
*/
right = false;
/**
* Coordinates the execution of a presentation.
*
* @method presentationStateObserver
* @private
*/
presentationStateObserver() {
let presentationState = this.presentationState;
if (this.isCurrentSlide) {
switch (presentationState) {
case 'didTransition':
this.currentSlideDidTransition();
break;
case 'willTransit':
this.currentSlideWillTransit();
break;
}
}
if (this.isFollowingSlide) {
switch (presentationState) {
case 'didTransition':
this.followingSlideDidTransition();
break;
case 'willTransit':
this.followingSlideWillTransit();
break;
}
}
}
init() {
super.init(...arguments);
addObserver(this, 'presentationState', null, this.presentationStateObserver, true);
}
/**
* @method currentSlideDidTransition
* @private
*/
currentSlideDidTransition() {
this.set(this.directionalClassName, false);
this.set('active', false);
}
/**
* @method currentSlideWillTransit
* @private
*/
currentSlideWillTransit() {
this.set('active', true);
next(this, function () {
this.set(this.directionalClassName, true);
});
}
/**
* @method followingSlideDidTransition
* @private
*/
followingSlideDidTransition() {
this.set('active', true);
this.set(this.directionalClassName, false);
this.set(this.orderClassName, false);
}
/**
* @method followingSlideWillTransit
* @private
*/
followingSlideWillTransit() {
this.set(this.orderClassName, true);
next(this, function () {
this.reflow();
this.set(this.directionalClassName, true);
});
}
/**
* Makes things more stable, especially when fast changing.
*/
reflow() {
this._element.offsetHeight;
}
}