Choices/src/scripts/components/list.js
Josh Johnson 0e44a916e3
Fix constructor (#693)
* breaking test

* Remove ablity to pass multiple elements + tests

* Update readme

* Update README.md

* 🔖 Version 8.0.0

* Remove type definition hack

* Update coverage command

* Add some missing list tests

* Remove .only

* Update demo page to loop over elements

* Update constructor to set initialised flag if already active

* Make templates private

* Throw type error once if element is invalid

* Fix list children bug

* Re-add generic examples to index.html

* Housekeeping

* Use typeof instead of isType where applicable

* Remove isElement

* Add test for isIE11
2019-10-29 21:19:56 +00:00

93 lines
2.3 KiB
JavaScript

import { SCROLLING_SPEED } from '../constants';
export default class List {
constructor({ element }) {
Object.assign(this, { element });
this.scrollPos = this.element.scrollTop;
this.height = this.element.offsetHeight;
}
clear() {
this.element.innerHTML = '';
}
append(node) {
this.element.appendChild(node);
}
getChild(selector) {
return this.element.querySelector(selector);
}
hasChildren() {
return this.element.hasChildNodes();
}
scrollToTop() {
this.element.scrollTop = 0;
}
scrollToChoice(choice, direction) {
if (!choice) {
return;
}
const dropdownHeight = this.element.offsetHeight;
const choiceHeight = choice.offsetHeight;
// Distance from bottom of element to top of parent
const choicePos = choice.offsetTop + choiceHeight;
// Scroll position of dropdown
const containerScrollPos = this.element.scrollTop + dropdownHeight;
// Difference between the choice and scroll position
const destination =
direction > 0
? this.element.scrollTop + choicePos - containerScrollPos
: choice.offsetTop;
requestAnimationFrame(time => {
this._animateScroll(time, destination, direction);
});
}
_scrollDown(scrollPos, strength, destination) {
const easing = (destination - scrollPos) / strength;
const distance = easing > 1 ? easing : 1;
this.element.scrollTop = scrollPos + distance;
}
_scrollUp(scrollPos, strength, destination) {
const easing = (scrollPos - destination) / strength;
const distance = easing > 1 ? easing : 1;
this.element.scrollTop = scrollPos - distance;
}
_animateScroll(time, destination, direction) {
const strength = SCROLLING_SPEED;
const choiceListScrollTop = this.element.scrollTop;
let continueAnimation = false;
if (direction > 0) {
this._scrollDown(choiceListScrollTop, strength, destination);
if (choiceListScrollTop < destination) {
continueAnimation = true;
}
} else {
this._scrollUp(choiceListScrollTop, strength, destination);
if (choiceListScrollTop > destination) {
continueAnimation = true;
}
}
if (continueAnimation) {
requestAnimationFrame(() => {
this._animateScroll(time, destination, direction);
});
}
}
}