Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
react-fluckity / fluckity / add-remove-cell.js
Size: Mime:
// const Flickity = require('./flickity')
const utils = require('./utils')

module.exports = addRemoveCell

// append cells to a document fragment
function getCellsFragment(cells) {
  let fragment = document.createDocumentFragment()
  cells.forEach(function(cell) {
    fragment.appendChild(cell.element)
  })
  return fragment
}

// -------------------------- add/remove cell prototype -------------------------- //

function addRemoveCell(Flickity) {

  let proto = Flickity.prototype
  /**
   * Insert, prepend, or append cells
   * @param {Element, Array, NodeList} elems
   * @param {Integer} index
   */
  proto.insert = function(elems, index) {
    let cells = this._makeCells(elems)
    if (!cells || !cells.length) {
      return
    }
    let len = this.cells.length
    // default to append
    index = index === undefined ? len : index
    // add cells with document fragment
    let fragment = getCellsFragment(cells)
    // append to slider
    let isAppend = index == len
    if (isAppend) {
      this.slider.appendChild(fragment)
    } else {
      let insertCellElement = this.cells[index].element
      this.slider.insertBefore(fragment, insertCellElement)
    }
    // add to this.cells
    if (index === 0) {
      // prepend, add to start
      this.cells = cells.concat(this.cells)
    } else if (isAppend) {
      // append, add to end
      this.cells = this.cells.concat(cells)
    } else {
      // insert in this.cells
      let endCells = this.cells.splice(index, len - index)
      this.cells = this.cells.concat(cells).concat(endCells)
    }

    this._sizeCells(cells)

    let selectedIndexDelta = index > this.selectedIndex ? 0 : cells.length
    this._cellAddedRemoved(index, selectedIndexDelta)
  }

  proto.append = function(elems) {
    this.insert(elems, this.cells.length)
  }

  proto.prepend = function(elems) {
    this.insert(elems, 0)
  }

  /**
   * Remove cells
   * @param {Element, Array, NodeList} elems
   */
  proto.remove = function(elems) {
    let cells = this.getCells(elems)
    let selectedIndexDelta = 0
    let len = cells.length
    let i, cell
    // calculate selectedIndexDelta, easier if done in seperate loop
    for (i = 0; i < len; i++) {
      cell = cells[i]
      let wasBefore = this.cells.indexOf(cell) < this.selectedIndex
      selectedIndexDelta -= wasBefore ? 1 : 0
    }

    for (i = 0; i < len; i++) {
      cell = cells[i]
      cell.remove()
      // remove item from collection
      utils.removeFrom(this.cells, cell)
    }

    if (cells.length) {
      // update stuff
      this._cellAddedRemoved(0, selectedIndexDelta)
    }
  }

  // updates when cells are added or removed
  proto._cellAddedRemoved = function(changedCellIndex, selectedIndexDelta) {
    // TODO this math isn't perfect with grouped slides
    selectedIndexDelta = selectedIndexDelta || 0
    this.selectedIndex += selectedIndexDelta
    this.selectedIndex = Math.max(0, Math.min(this.slides.length - 1, this.selectedIndex))

    this.cellChange(changedCellIndex, true)
    // backwards compatibility
    this.emitEvent('cellAddedRemoved', [changedCellIndex, selectedIndexDelta])
  }

  /**
   * logic to be run after a cell's size changes
   * @param {Element} elem - cell's element
   */
  proto.cellSizeChange = function(elem) {
    let cell = this.getCell(elem)
    if (!cell) {
      return
    }
    cell.getSize()

    let index = this.cells.indexOf(cell)
    this.cellChange(index)
  }

  /**
   * logic any time a cell is changed: added, removed, or size changed
   * @param {Integer} changedCellIndex - index of the changed cell, optional
   */
  proto.cellChange = function(changedCellIndex, isPositioningSlider) {
    let prevSlideableWidth = this.slideableWidth
    this._positionCells(changedCellIndex)
    this._getWrapShiftCells()
    this.setGallerySize()
    this.emitEvent('cellChange', [changedCellIndex])
    // position slider
    if (this.options.freeScroll) {
      // shift x by change in slideableWidth
      // TODO fix position shifts when prepending w/ freeScroll
      let deltaX = prevSlideableWidth - this.slideableWidth
      this.x += deltaX * this.cellAlign
      this.positionSlider()
    } else {
      // do not position slider after lazy load
      if (isPositioningSlider) {
        this.positionSliderAtSelected()
      }
      this.select(this.selectedIndex)
    }
  }

}

addRemoveCell.flickTheBean = addRemoveCell