import * as Hammer from 'hammerjs' /** * Mixin for extends Riot-Component * * @author Björn Hase * @license http://opensource.org/licenses/MIT The MIT License * @link https://gitea.node001.net/tiny-components/slider * */ export default { /** * * */ state: { position: 0, max: 0, slides: undefined, classes: { item: 'tiny-slider__item' } }, /** * * */ onMounted() { if (this.props.slides) { this.state.slides = this.props.slides } // start and add resize listener window.addEventListener('resize', this.update.bind(this)) setTimeout(() => { this.update() }, 100) // Create a manager to manager the element const manager = new Hammer(this.root) manager.on('swipe', (event) => { if (event.direction === 4) { this.handlePrevious(event) } else if (event.direction === 2) { this.handleNext(event) } }) }, /** * remove resize listener before unmount * */ onBeforeUnmount() { window.removeEventListener('resize', this.update.bind(this)) }, /** * before update view, calculate values * * @param {object} props * @param {object} state * */ onBeforeUpdate(props, state) { // getting current max const max = this.state.max // setting max to show visible this.state.max = 0 this.state.width = this.$('.' + this.state.classes.item).offsetWidth // check how many elements can visible in element this.$$('.' + this.state.classes.item).forEach((element, index) => { if (element.offsetLeft < this.root.offsetWidth) { this.state.max++; } }) // change position to fit new max value const value = Math.abs(this.state.max - max) // @TODO check this, at 0 it makes me mad if (this.state.position >= value && this.state.position > 1) { this.state.position -= value } }, /** * set current position * * */ handleSelect(event, position) { event.preventDefault() if (this.state.position !== position) { this.update({ position: position }) } }, /** * set next postion * * */ handlePrevious(event) { event.preventDefault() if (this.state.position > 0) { this.update({ position: --this.state.position }) } }, /** * set next postion * * * @param {object} event * */ handleNext(event) { event.preventDefault() if (this.state.position < (this.props.slides.length - 1)) { this.update({ position: ++this.state.position }) } }, /** * getting classes for next-button, * show button only * * * @return {string} * */ getPreviousClasses() { const classes = [ 'tiny-slider__button', 'tiny-slider__button--previous' ] if (this.state.position > 0) { classes.push('visibility-visible') } else { classes.push('visibility-hidden') } return classes.join(' ') }, /** * getting classes for next-button, * show button unless length is smaller then max * * @return {string} * */ getNextClasses() { const classes = [ 'tiny-slider__button', 'tiny-slider__button--next' ] if (this.state.position <= (this.props.slides.length - this.state.max)) { classes.push('visibility-visible') } else { classes.push('visibility-hidden') } return classes.join(' ') }, /** * getting classes for select, * adding current-class if postion and state.postion are equal * * @param {integer} position * @return {string} * */ getSelectClasses(position) { const classes = [ 'tiny-slider__select-item' ] if (this.state.position === position) { classes.push('tiny-slider__select-item--current') } return classes.join(' ') }, /** * set translate with position and witdh * * * @return {string} * */ getContentStyles() { // getting value for position const value = (-(this.state.position * this.state.width)); return this.styles({ transform: 'translate(' + value + 'px, 0px)' }) } }