mirror of
https://github.com/Choices-js/Choices.git
synced 2024-04-24 18:30:31 +02:00
Move to 2 space indentation + editorconfig
This commit is contained in:
parent
9bb9e0b4c2
commit
d40841d8dd
9
.editorconfig
Normal file
9
.editorconfig
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
|
@ -10,7 +10,7 @@
|
||||||
"rules": {
|
"rules": {
|
||||||
"quotes": [2, "single"],
|
"quotes": [2, "single"],
|
||||||
"strict": [2, "never"],
|
"strict": [2, "never"],
|
||||||
"indent": ["error", 4, {"SwitchCase": 1}],
|
"indent": ["error", 2, {"SwitchCase": 1}],
|
||||||
"eol-last": "off",
|
"eol-last": "off",
|
||||||
"arrow-body-style": "off",
|
"arrow-body-style": "off",
|
||||||
"no-underscore-dangle": "off",
|
"no-underscore-dangle": "off",
|
||||||
|
|
|
@ -1,67 +1,67 @@
|
||||||
export const addItem = (value, label, id, choiceId, activateOptions) => {
|
export const addItem = (value, label, id, choiceId, activateOptions) => {
|
||||||
return {
|
return {
|
||||||
type: 'ADD_ITEM',
|
type: 'ADD_ITEM',
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
id,
|
id,
|
||||||
choiceId,
|
choiceId,
|
||||||
activateOptions,
|
activateOptions,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeItem = (id, choiceId) => {
|
export const removeItem = (id, choiceId) => {
|
||||||
return {
|
return {
|
||||||
type: 'REMOVE_ITEM',
|
type: 'REMOVE_ITEM',
|
||||||
id,
|
id,
|
||||||
choiceId,
|
choiceId,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const highlightItem = (id, highlighted) => {
|
export const highlightItem = (id, highlighted) => {
|
||||||
return {
|
return {
|
||||||
type: 'HIGHLIGHT_ITEM',
|
type: 'HIGHLIGHT_ITEM',
|
||||||
id,
|
id,
|
||||||
highlighted,
|
highlighted,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addChoice = (value, label, id, groupId, disabled) => {
|
export const addChoice = (value, label, id, groupId, disabled) => {
|
||||||
return {
|
return {
|
||||||
type: 'ADD_CHOICE',
|
type: 'ADD_CHOICE',
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
id,
|
id,
|
||||||
groupId,
|
groupId,
|
||||||
disabled,
|
disabled,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const filterChoices = (results) => {
|
export const filterChoices = (results) => {
|
||||||
return {
|
return {
|
||||||
type: 'FILTER_CHOICES',
|
type: 'FILTER_CHOICES',
|
||||||
results,
|
results,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const activateChoices = (active = true) => {
|
export const activateChoices = (active = true) => {
|
||||||
return {
|
return {
|
||||||
type: 'ACTIVATE_CHOICES',
|
type: 'ACTIVATE_CHOICES',
|
||||||
active,
|
active,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addGroup = (value, id, active, disabled) => {
|
export const addGroup = (value, id, active, disabled) => {
|
||||||
return {
|
return {
|
||||||
type: 'ADD_GROUP',
|
type: 'ADD_GROUP',
|
||||||
value,
|
value,
|
||||||
id,
|
id,
|
||||||
active,
|
active,
|
||||||
disabled,
|
disabled,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const clearAll = () => {
|
export const clearAll = () => {
|
||||||
return {
|
return {
|
||||||
type: 'CLEAR_ALL',
|
type: 'CLEAR_ALL',
|
||||||
};
|
};
|
||||||
};
|
};
|
File diff suppressed because it is too large
Load diff
|
@ -1,113 +1,112 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
// Production steps of ECMA-262, Edition 6, 22.1.2.1
|
// Production steps of ECMA-262, Edition 6, 22.1.2.1
|
||||||
// Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
|
// Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
|
||||||
if (!Array.from) {
|
if (!Array.from) {
|
||||||
Array.from = (function() {
|
Array.from = (function() {
|
||||||
var toStr = Object.prototype.toString;
|
var toStr = Object.prototype.toString;
|
||||||
|
|
||||||
var isCallable = function(fn) {
|
var isCallable = function(fn) {
|
||||||
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
|
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
|
||||||
};
|
};
|
||||||
|
|
||||||
var toInteger = function(value) {
|
var toInteger = function(value) {
|
||||||
var number = Number(value);
|
var number = Number(value);
|
||||||
if (isNaN(number)) {
|
if (isNaN(number)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (number === 0 || !isFinite(number)) {
|
if (number === 0 || !isFinite(number)) {
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
|
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
|
||||||
};
|
};
|
||||||
|
|
||||||
var maxSafeInteger = Math.pow(2, 53) - 1;
|
var maxSafeInteger = Math.pow(2, 53) - 1;
|
||||||
|
|
||||||
var toLength = function(value) {
|
var toLength = function(value) {
|
||||||
var len = toInteger(value);
|
var len = toInteger(value);
|
||||||
return Math.min(Math.max(len, 0), maxSafeInteger);
|
return Math.min(Math.max(len, 0), maxSafeInteger);
|
||||||
};
|
};
|
||||||
|
|
||||||
// The length property of the from method is 1.
|
// The length property of the from method is 1.
|
||||||
return function from(arrayLike /*, mapFn, thisArg */ ) {
|
return function from(arrayLike /*, mapFn, thisArg */ ) {
|
||||||
// 1. Let C be the this value.
|
// 1. Let C be the this value.
|
||||||
var C = this;
|
var C = this;
|
||||||
|
|
||||||
// 2. Let items be ToObject(arrayLike).
|
// 2. Let items be ToObject(arrayLike).
|
||||||
var items = Object(arrayLike);
|
var items = Object(arrayLike);
|
||||||
|
|
||||||
// 3. ReturnIfAbrupt(items).
|
// 3. ReturnIfAbrupt(items).
|
||||||
if (arrayLike == null) {
|
if (arrayLike == null) {
|
||||||
throw new TypeError("Array.from requires an array-like object - not null or undefined");
|
throw new TypeError("Array.from requires an array-like object - not null or undefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. If mapfn is undefined, then let mapping be false.
|
// 4. If mapfn is undefined, then let mapping be false.
|
||||||
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
|
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
|
||||||
var T;
|
var T;
|
||||||
if (typeof mapFn !== 'undefined') {
|
if (typeof mapFn !== 'undefined') {
|
||||||
// 5. else
|
// 5. else
|
||||||
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
|
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
|
||||||
if (!isCallable(mapFn)) {
|
if (!isCallable(mapFn)) {
|
||||||
throw new TypeError('Array.from: when provided, the second argument must be a function');
|
throw new TypeError('Array.from: when provided, the second argument must be a function');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
|
||||||
if (arguments.length > 2) {
|
if (arguments.length > 2) {
|
||||||
T = arguments[2];
|
T = arguments[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. Let lenValue be Get(items, "length").
|
// 10. Let lenValue be Get(items, "length").
|
||||||
// 11. Let len be ToLength(lenValue).
|
// 11. Let len be ToLength(lenValue).
|
||||||
var len = toLength(items.length);
|
var len = toLength(items.length);
|
||||||
|
|
||||||
// 13. If IsConstructor(C) is true, then
|
// 13. If IsConstructor(C) is true, then
|
||||||
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
|
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
|
||||||
// 14. a. Else, Let A be ArrayCreate(len).
|
// 14. a. Else, Let A be ArrayCreate(len).
|
||||||
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
|
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
|
||||||
|
|
||||||
// 16. Let k be 0.
|
// 16. Let k be 0.
|
||||||
var k = 0;
|
var k = 0;
|
||||||
// 17. Repeat, while k < len… (also steps a - h)
|
// 17. Repeat, while k < len… (also steps a - h)
|
||||||
var kValue;
|
var kValue;
|
||||||
while (k < len) {
|
while (k < len) {
|
||||||
kValue = items[k];
|
kValue = items[k];
|
||||||
if (mapFn) {
|
if (mapFn) {
|
||||||
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
|
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
|
||||||
} else {
|
} else {
|
||||||
A[k] = kValue;
|
A[k] = kValue;
|
||||||
}
|
}
|
||||||
k += 1;
|
k += 1;
|
||||||
}
|
}
|
||||||
// 18. Let putStatus be Put(A, "length", len, true).
|
// 18. Let putStatus be Put(A, "length", len, true).
|
||||||
A.length = len;
|
A.length = len;
|
||||||
// 20. Return A.
|
// 20. Return A.
|
||||||
return A;
|
return A;
|
||||||
};
|
};
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find
|
// Reference: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find
|
||||||
if (!Array.prototype.find) {
|
if (!Array.prototype.find) {
|
||||||
Array.prototype.find = function(predicate) {
|
Array.prototype.find = function(predicate) {
|
||||||
'use strict';
|
'use strict';
|
||||||
if (this == null) {
|
if (this == null) {
|
||||||
throw new TypeError('Array.prototype.find called on null or undefined');
|
throw new TypeError('Array.prototype.find called on null or undefined');
|
||||||
}
|
}
|
||||||
if (typeof predicate !== 'function') {
|
if (typeof predicate !== 'function') {
|
||||||
throw new TypeError('predicate must be a function');
|
throw new TypeError('predicate must be a function');
|
||||||
}
|
}
|
||||||
var list = Object(this);
|
var list = Object(this);
|
||||||
var length = list.length >>> 0;
|
var length = list.length >>> 0;
|
||||||
var thisArg = arguments[1];
|
var thisArg = arguments[1];
|
||||||
var value;
|
var value;
|
||||||
|
|
||||||
for (var i = 0; i < length; i++) {
|
for (var i = 0; i < length; i++) {
|
||||||
value = list[i];
|
value = list[i];
|
||||||
if (predicate.call(thisArg, value, i, list)) {
|
if (predicate.call(thisArg, value, i, list)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,14 +1,13 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capitalises the first letter of each word in a string
|
* Capitalises the first letter of each word in a string
|
||||||
* @param {String} str String to capitalise
|
* @param {String} str String to capitalise
|
||||||
* @return {String} Capitalised string
|
* @return {String} Capitalised string
|
||||||
*/
|
*/
|
||||||
export const capitalise = function(str) {
|
export const capitalise = function(str) {
|
||||||
return str.replace(/\w\S*/g, function(txt){
|
return str.replace(/\w\S*/g, function(txt) {
|
||||||
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,8 +17,8 @@ export const capitalise = function(str) {
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
export const isType = function(type, obj) {
|
export const isType = function(type, obj) {
|
||||||
var clas = Object.prototype.toString.call(obj).slice(8, -1);
|
var clas = Object.prototype.toString.call(obj).slice(8, -1);
|
||||||
return obj !== undefined && obj !== null && clas === type;
|
return obj !== undefined && obj !== null && clas === type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,10 +27,10 @@ export const isType = function(type, obj) {
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
export const isNode = (o) => {
|
export const isNode = (o) => {
|
||||||
return (
|
return (
|
||||||
typeof Node === "object" ? o instanceof Node :
|
typeof Node === "object" ? o instanceof Node :
|
||||||
o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
|
o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,10 +39,10 @@ export const isNode = (o) => {
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
export const isElement = (o) => {
|
export const isElement = (o) => {
|
||||||
return (
|
return (
|
||||||
typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
|
typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
|
||||||
o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName==="string"
|
o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string"
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,63 +51,63 @@ export const isElement = (o) => {
|
||||||
* @return {Object} Merged object of arguments
|
* @return {Object} Merged object of arguments
|
||||||
*/
|
*/
|
||||||
export const extend = function() {
|
export const extend = function() {
|
||||||
let extended = {};
|
let extended = {};
|
||||||
let deep = false;
|
let deep = false;
|
||||||
let length = arguments.length;
|
let length = arguments.length;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge one object into another
|
* Merge one object into another
|
||||||
* @param {Object} obj Object to merge into extended object
|
* @param {Object} obj Object to merge into extended object
|
||||||
*/
|
*/
|
||||||
let merge = function (obj) {
|
let merge = function(obj) {
|
||||||
for (let prop in obj) {
|
for (let prop in obj) {
|
||||||
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
||||||
// If deep merge and property is an object, merge properties
|
// If deep merge and property is an object, merge properties
|
||||||
if (deep && isType('Object', obj[prop])) {
|
if (deep && isType('Object', obj[prop])) {
|
||||||
extended[prop] = extend( true, extended[prop], obj[prop]);
|
extended[prop] = extend(true, extended[prop], obj[prop]);
|
||||||
} else {
|
|
||||||
extended[prop] = obj[prop];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Loop through each passed argument
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
// store argument at position i
|
|
||||||
let obj = arguments[i];
|
|
||||||
|
|
||||||
// If we are in fact dealing with an object, merge it. Otherwise throw error
|
|
||||||
if (isType('Object', obj)) {
|
|
||||||
merge(obj);
|
|
||||||
} else {
|
} else {
|
||||||
console.error('Custom options must be an object');
|
extended[prop] = obj[prop];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return extended;
|
// Loop through each passed argument
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
// store argument at position i
|
||||||
|
let obj = arguments[i];
|
||||||
|
|
||||||
|
// If we are in fact dealing with an object, merge it. Otherwise throw error
|
||||||
|
if (isType('Object', obj)) {
|
||||||
|
merge(obj);
|
||||||
|
} else {
|
||||||
|
console.error('Custom options must be an object');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extended;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CSS transition end event listener
|
* CSS transition end event listener
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
export const whichTransitionEvent = function(){
|
export const whichTransitionEvent = function() {
|
||||||
var t,
|
var t,
|
||||||
el = document.createElement("fakeelement");
|
el = document.createElement("fakeelement");
|
||||||
|
|
||||||
var transitions = {
|
var transitions = {
|
||||||
"transition" : "transitionend",
|
"transition": "transitionend",
|
||||||
"OTransition" : "oTransitionEnd",
|
"OTransition": "oTransitionEnd",
|
||||||
"MozTransition" : "transitionend",
|
"MozTransition": "transitionend",
|
||||||
"WebkitTransition": "webkitTransitionEnd"
|
"WebkitTransition": "webkitTransitionEnd"
|
||||||
}
|
}
|
||||||
|
|
||||||
for (t in transitions){
|
for (t in transitions) {
|
||||||
if (el.style[t] !== undefined){
|
if (el.style[t] !== undefined) {
|
||||||
return transitions[t];
|
return transitions[t];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,21 +115,21 @@ export const whichTransitionEvent = function(){
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
export const whichAnimationEvent = function() {
|
export const whichAnimationEvent = function() {
|
||||||
var t,
|
var t,
|
||||||
el = document.createElement('fakeelement');
|
el = document.createElement('fakeelement');
|
||||||
|
|
||||||
var animations = {
|
var animations = {
|
||||||
'animation': 'animationend',
|
'animation': 'animationend',
|
||||||
'OAnimation': 'oAnimationEnd',
|
'OAnimation': 'oAnimationEnd',
|
||||||
'MozAnimation': 'animationend',
|
'MozAnimation': 'animationend',
|
||||||
'WebkitAnimation': 'webkitAnimationEnd'
|
'WebkitAnimation': 'webkitAnimationEnd'
|
||||||
};
|
};
|
||||||
|
|
||||||
for (t in animations) {
|
for (t in animations) {
|
||||||
if (el.style[t] !== undefined) {
|
if (el.style[t] !== undefined) {
|
||||||
return animations[t];
|
return animations[t];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,103 +141,103 @@ export const whichAnimationEvent = function() {
|
||||||
* @return {Array} Array of parent elements
|
* @return {Array} Array of parent elements
|
||||||
*/
|
*/
|
||||||
export const getParentsUntil = function(elem, parent, selector) {
|
export const getParentsUntil = function(elem, parent, selector) {
|
||||||
var parents = [];
|
var parents = [];
|
||||||
// Get matches
|
// Get matches
|
||||||
for (; elem && elem !== document; elem = elem.parentNode) {
|
for (; elem && elem !== document; elem = elem.parentNode) {
|
||||||
|
|
||||||
// Check if parent has been reached
|
// Check if parent has been reached
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
|
||||||
var parentType = parent.charAt(0);
|
var parentType = parent.charAt(0);
|
||||||
|
|
||||||
// If parent is a class
|
|
||||||
if (parentType === '.') {
|
|
||||||
if (elem.classList.contains(parent.substr(1))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If parent is an ID
|
|
||||||
if (parentType === '#') {
|
|
||||||
if (elem.id === parent.substr(1)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If parent is a data attribute
|
|
||||||
if (parentType === '[') {
|
|
||||||
if (elem.hasAttribute(parent.substr(1, parent.length - 1))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If parent is a tag
|
|
||||||
if (elem.tagName.toLowerCase() === parent) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// If parent is a class
|
||||||
|
if (parentType === '.') {
|
||||||
|
if (elem.classList.contains(parent.substr(1))) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (selector) {
|
}
|
||||||
var selectorType = selector.charAt(0);
|
|
||||||
|
|
||||||
// If selector is a class
|
// If parent is an ID
|
||||||
if (selectorType === '.') {
|
if (parentType === '#') {
|
||||||
if (elem.classList.contains(selector.substr(1))) {
|
if (elem.id === parent.substr(1)) {
|
||||||
parents.push(elem);
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If selector is an ID
|
|
||||||
if (selectorType === '#') {
|
|
||||||
if (elem.id === selector.substr(1)) {
|
|
||||||
parents.push(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If selector is a data attribute
|
|
||||||
if (selectorType === '[') {
|
|
||||||
if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {
|
|
||||||
parents.push(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If selector is a tag
|
|
||||||
if (elem.tagName.toLowerCase() === selector) {
|
|
||||||
parents.push(elem);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
parents.push(elem);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If parent is a data attribute
|
||||||
|
if (parentType === '[') {
|
||||||
|
if (elem.hasAttribute(parent.substr(1, parent.length - 1))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If parent is a tag
|
||||||
|
if (elem.tagName.toLowerCase() === parent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (selector) {
|
||||||
|
var selectorType = selector.charAt(0);
|
||||||
|
|
||||||
|
// If selector is a class
|
||||||
|
if (selectorType === '.') {
|
||||||
|
if (elem.classList.contains(selector.substr(1))) {
|
||||||
|
parents.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If selector is an ID
|
||||||
|
if (selectorType === '#') {
|
||||||
|
if (elem.id === selector.substr(1)) {
|
||||||
|
parents.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If selector is a data attribute
|
||||||
|
if (selectorType === '[') {
|
||||||
|
if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {
|
||||||
|
parents.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If selector is a tag
|
||||||
|
if (elem.tagName.toLowerCase() === selector) {
|
||||||
|
parents.push(elem);
|
||||||
|
}
|
||||||
|
|
||||||
// Return parents if any exist
|
|
||||||
if (parents.length === 0) {
|
|
||||||
return null;
|
|
||||||
} else {
|
} else {
|
||||||
return parents;
|
parents.push(elem);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return parents if any exist
|
||||||
|
if (parents.length === 0) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const wrap = function (element, wrapper) {
|
export const wrap = function(element, wrapper) {
|
||||||
wrapper = wrapper || document.createElement('div');
|
wrapper = wrapper || document.createElement('div');
|
||||||
if (element.nextSibling) {
|
if (element.nextSibling) {
|
||||||
element.parentNode.insertBefore(wrapper, element.nextSibling);
|
element.parentNode.insertBefore(wrapper, element.nextSibling);
|
||||||
} else {
|
} else {
|
||||||
element.parentNode.appendChild(wrapper);
|
element.parentNode.appendChild(wrapper);
|
||||||
}
|
}
|
||||||
return wrapper.appendChild(element);
|
return wrapper.appendChild(element);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSiblings = function (elem) {
|
export const getSiblings = function(elem) {
|
||||||
var siblings = [];
|
var siblings = [];
|
||||||
var sibling = elem.parentNode.firstChild;
|
var sibling = elem.parentNode.firstChild;
|
||||||
for ( ; sibling; sibling = sibling.nextSibling ) {
|
for (; sibling; sibling = sibling.nextSibling) {
|
||||||
if ( sibling.nodeType === 1 && sibling !== elem ) {
|
if (sibling.nodeType === 1 && sibling !== elem) {
|
||||||
siblings.push( sibling );
|
siblings.push(sibling);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return siblings;
|
}
|
||||||
|
return siblings;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -248,8 +247,8 @@ export const getSiblings = function (elem) {
|
||||||
* @return {NodeElement} Found parent element
|
* @return {NodeElement} Found parent element
|
||||||
*/
|
*/
|
||||||
export const findAncestor = function(el, cls) {
|
export const findAncestor = function(el, cls) {
|
||||||
while ((el = el.parentElement) && !el.classList.contains(cls));
|
while ((el = el.parentElement) && !el.classList.contains(cls));
|
||||||
return el;
|
return el;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -260,19 +259,19 @@ export const findAncestor = function(el, cls) {
|
||||||
* @return {Function} A function will be called after it stops being called for a given delay
|
* @return {Function} A function will be called after it stops being called for a given delay
|
||||||
*/
|
*/
|
||||||
export const debounce = function(func, wait, immediate) {
|
export const debounce = function(func, wait, immediate) {
|
||||||
var timeout;
|
var timeout;
|
||||||
return function() {
|
return function() {
|
||||||
var context = this,
|
var context = this,
|
||||||
args = arguments;
|
args = arguments;
|
||||||
var later = function() {
|
var later = function() {
|
||||||
timeout = null;
|
timeout = null;
|
||||||
if (!immediate) func.apply(context, args);
|
if (!immediate) func.apply(context, args);
|
||||||
};
|
|
||||||
var callNow = immediate && !timeout;
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(later, wait);
|
|
||||||
if (callNow) func.apply(context, args);
|
|
||||||
};
|
};
|
||||||
|
var callNow = immediate && !timeout;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
if (callNow) func.apply(context, args);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,14 +281,14 @@ export const debounce = function(func, wait, immediate) {
|
||||||
* @return {Number} Elements Distance from top of page
|
* @return {Number} Elements Distance from top of page
|
||||||
*/
|
*/
|
||||||
export const getElemDistance = function(el) {
|
export const getElemDistance = function(el) {
|
||||||
var location = 0;
|
var location = 0;
|
||||||
if (el.offsetParent) {
|
if (el.offsetParent) {
|
||||||
do {
|
do {
|
||||||
location += el.offsetTop;
|
location += el.offsetTop;
|
||||||
el = el.offsetParent;
|
el = el.offsetParent;
|
||||||
} while (el);
|
} while (el);
|
||||||
}
|
}
|
||||||
return location >= 0 ? location : 0;
|
return location >= 0 ? location : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -299,11 +298,11 @@ export const getElemDistance = function(el) {
|
||||||
* @return {Number} Height of element
|
* @return {Number} Height of element
|
||||||
*/
|
*/
|
||||||
export const getElementOffset = function(el, offset) {
|
export const getElementOffset = function(el, offset) {
|
||||||
var elOffset = offset;
|
var elOffset = offset;
|
||||||
if(elOffset > 1) elOffset = 1;
|
if (elOffset > 1) elOffset = 1;
|
||||||
if(elOffset > 0) elOffset = 0;
|
if (elOffset > 0) elOffset = 0;
|
||||||
|
|
||||||
return Math.max(el.offsetHeight*elOffset);
|
return Math.max(el.offsetHeight * elOffset);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -314,15 +313,15 @@ export const getElementOffset = function(el, offset) {
|
||||||
* @return {[HTMLElement} Found element
|
* @return {[HTMLElement} Found element
|
||||||
*/
|
*/
|
||||||
export const getAdjacentEl = (startEl, className, direction = 1) => {
|
export const getAdjacentEl = (startEl, className, direction = 1) => {
|
||||||
if(!startEl || !className) return;
|
if (!startEl || !className) return;
|
||||||
|
|
||||||
const parent = startEl.parentNode.parentNode;
|
const parent = startEl.parentNode.parentNode;
|
||||||
const children = Array.from(parent.querySelectorAll(className));
|
const children = Array.from(parent.querySelectorAll(className));
|
||||||
|
|
||||||
const startPos = children.indexOf(startEl);
|
const startPos = children.indexOf(startEl);
|
||||||
const operatorDirection = direction > 0 ? 1 : -1;
|
const operatorDirection = direction > 0 ? 1 : -1;
|
||||||
|
|
||||||
return children[startPos + operatorDirection];
|
return children[startPos + operatorDirection];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,13 +330,13 @@ export const getAdjacentEl = (startEl, className, direction = 1) => {
|
||||||
* @return {String} Position of scroll
|
* @return {String} Position of scroll
|
||||||
*/
|
*/
|
||||||
export const getScrollPosition = function(position) {
|
export const getScrollPosition = function(position) {
|
||||||
if(position === 'bottom') {
|
if (position === 'bottom') {
|
||||||
// Scroll position from the bottom of the viewport
|
// Scroll position from the bottom of the viewport
|
||||||
return Math.max((window.scrollY || window.pageYOffset) + (window.innerHeight || document.documentElement.clientHeight));
|
return Math.max((window.scrollY || window.pageYOffset) + (window.innerHeight || document.documentElement.clientHeight));
|
||||||
} else {
|
} else {
|
||||||
// Scroll position from the top of the viewport
|
// Scroll position from the top of the viewport
|
||||||
return (window.scrollY || window.pageYOffset);
|
return (window.scrollY || window.pageYOffset);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -347,8 +346,8 @@ export const getScrollPosition = function(position) {
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
export const isInView = function(el, position, offset) {
|
export const isInView = function(el, position, offset) {
|
||||||
// If the user has scrolled further than the distance from the element to the top of its parent
|
// If the user has scrolled further than the distance from the element to the top of its parent
|
||||||
return this.getScrollPosition(position) > (this.getElemDistance(el) + this.getElementOffset(el, offset)) ? true : false;
|
return this.getScrollPosition(position) > (this.getElemDistance(el) + this.getElementOffset(el, offset)) ? true : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -359,19 +358,19 @@ export const isInView = function(el, position, offset) {
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
export const isScrolledIntoView = (el, parent, direction = 1) => {
|
export const isScrolledIntoView = (el, parent, direction = 1) => {
|
||||||
if(!el) return;
|
if (!el) return;
|
||||||
|
|
||||||
let isVisible;
|
let isVisible;
|
||||||
|
|
||||||
if(direction > 0) {
|
if (direction > 0) {
|
||||||
// In view from bottom
|
// In view from bottom
|
||||||
isVisible = (parent.scrollTop + parent.offsetHeight) >= (el.offsetTop + el.offsetHeight) ;
|
isVisible = (parent.scrollTop + parent.offsetHeight) >= (el.offsetTop + el.offsetHeight);
|
||||||
} else {
|
} else {
|
||||||
// In view from top
|
// In view from top
|
||||||
isVisible = el.offsetTop >= parent.scrollTop;
|
isVisible = el.offsetTop >= parent.scrollTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isVisible;
|
return isVisible;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -380,9 +379,9 @@ export const isScrolledIntoView = (el, parent, direction = 1) => {
|
||||||
* @return {String} Sanitised string
|
* @return {String} Sanitised string
|
||||||
*/
|
*/
|
||||||
export const stripHTML = function(html) {
|
export const stripHTML = function(html) {
|
||||||
let el = document.createElement("DIV");
|
let el = document.createElement("DIV");
|
||||||
el.innerHTML = html;
|
el.innerHTML = html;
|
||||||
return el.textContent || el.innerText || "";
|
return el.textContent || el.innerText || "";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -392,15 +391,15 @@ export const stripHTML = function(html) {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
export const addAnimation = (el, animation) => {
|
export const addAnimation = (el, animation) => {
|
||||||
let animationEvent = whichAnimationEvent();
|
let animationEvent = whichAnimationEvent();
|
||||||
|
|
||||||
let removeAnimation = () => {
|
let removeAnimation = () => {
|
||||||
el.classList.remove(animation);
|
el.classList.remove(animation);
|
||||||
el.removeEventListener(animationEvent, removeAnimation, false);
|
el.removeEventListener(animationEvent, removeAnimation, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
el.classList.add(animation);
|
el.classList.add(animation);
|
||||||
el.addEventListener(animationEvent, removeAnimation, false);
|
el.addEventListener(animationEvent, removeAnimation, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -411,7 +410,7 @@ export const addAnimation = (el, animation) => {
|
||||||
* @return {Number} Random number
|
* @return {Number} Random number
|
||||||
*/
|
*/
|
||||||
export const getRandomNumber = function(min, max) {
|
export const getRandomNumber = function(min, max) {
|
||||||
return Math.floor(Math.random() * (max - min) + min);
|
return Math.floor(Math.random() * (max - min) + min);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,18 +419,18 @@ export const getRandomNumber = function(min, max) {
|
||||||
* @return {HTMLElement} Converted node element
|
* @return {HTMLElement} Converted node element
|
||||||
*/
|
*/
|
||||||
export const strToEl = (function() {
|
export const strToEl = (function() {
|
||||||
var tmpEl = document.createElement('div');
|
var tmpEl = document.createElement('div');
|
||||||
return function(str) {
|
return function(str) {
|
||||||
var r;
|
var r;
|
||||||
tmpEl.innerHTML = str;
|
tmpEl.innerHTML = str;
|
||||||
r = tmpEl.children[0];
|
r = tmpEl.children[0];
|
||||||
|
|
||||||
while (tmpEl.firstChild) {
|
while (tmpEl.firstChild) {
|
||||||
tmpEl.removeChild(tmpEl.firstChild);
|
tmpEl.removeChild(tmpEl.firstChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
}());
|
}());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -439,39 +438,39 @@ export const strToEl = (function() {
|
||||||
* @return {Number} Width of input
|
* @return {Number} Width of input
|
||||||
*/
|
*/
|
||||||
export const getWidthOfInput = (input) => {
|
export const getWidthOfInput = (input) => {
|
||||||
const value = input.value || input.placeholder;
|
const value = input.value || input.placeholder;
|
||||||
let width = input.offsetWidth;
|
let width = input.offsetWidth;
|
||||||
|
|
||||||
if(value) {
|
if (value) {
|
||||||
const testEl = strToEl(`<span>${ value }</span>`);
|
const testEl = strToEl(`<span>${ value }</span>`);
|
||||||
testEl.style.position = 'absolute';
|
testEl.style.position = 'absolute';
|
||||||
testEl.style.padding = '0';
|
testEl.style.padding = '0';
|
||||||
testEl.style.top = '-9999px';
|
testEl.style.top = '-9999px';
|
||||||
testEl.style.left = '-9999px';
|
testEl.style.left = '-9999px';
|
||||||
testEl.style.width = 'auto';
|
testEl.style.width = 'auto';
|
||||||
testEl.style.whiteSpace = 'pre';
|
testEl.style.whiteSpace = 'pre';
|
||||||
|
|
||||||
document.body.appendChild(testEl);
|
document.body.appendChild(testEl);
|
||||||
|
|
||||||
if(value && testEl.offsetWidth !== input.offsetWidth) {
|
if (value && testEl.offsetWidth !== input.offsetWidth) {
|
||||||
width = testEl.offsetWidth + 4;
|
width = testEl.offsetWidth + 4;
|
||||||
}
|
|
||||||
|
|
||||||
document.body.removeChild(testEl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${width}px`;
|
document.body.removeChild(testEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${width}px`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sortByAlpha = (a, b) => {
|
export const sortByAlpha = (a, b) => {
|
||||||
const labelA = (a.label || a.value).toLowerCase();
|
const labelA = (a.label || a.value).toLowerCase();
|
||||||
const labelB = (b.label || b.value).toLowerCase();
|
const labelB = (b.label || b.value).toLowerCase();
|
||||||
|
|
||||||
if (labelA < labelB) return -1;
|
if (labelA < labelB) return -1;
|
||||||
if (labelA > labelB) return 1;
|
if (labelA > labelB) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sortByScore = (a, b) => {
|
export const sortByScore = (a, b) => {
|
||||||
return a.score - b.score;
|
return a.score - b.score;
|
||||||
};
|
};
|
|
@ -1,93 +1,93 @@
|
||||||
const choices = (state = [], action) => {
|
const choices = (state = [], action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_CHOICE': {
|
case 'ADD_CHOICE': {
|
||||||
/*
|
/*
|
||||||
A disabled choice appears in the choice dropdown but cannot be selected
|
A disabled choice appears in the choice dropdown but cannot be selected
|
||||||
A selected choice has been added to the passed input's value (added as an item)
|
A selected choice has been added to the passed input's value (added as an item)
|
||||||
An active choice appears within the choice dropdown
|
An active choice appears within the choice dropdown
|
||||||
*/
|
*/
|
||||||
return [...state, {
|
return [...state, {
|
||||||
id: action.id,
|
id: action.id,
|
||||||
groupId: action.groupId,
|
groupId: action.groupId,
|
||||||
value: action.value,
|
value: action.value,
|
||||||
label: action.label,
|
label: action.label,
|
||||||
disabled: action.disabled,
|
disabled: action.disabled,
|
||||||
selected: false,
|
selected: false,
|
||||||
active: true,
|
active: true,
|
||||||
score: 9999,
|
score: 9999,
|
||||||
}];
|
}];
|
||||||
}
|
|
||||||
|
|
||||||
case 'ADD_ITEM': {
|
|
||||||
let newState = state;
|
|
||||||
|
|
||||||
// If all choices need to be activated
|
|
||||||
if (action.activateOptions) {
|
|
||||||
newState = state.map((choice) => {
|
|
||||||
choice.active = action.active;
|
|
||||||
return choice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// When an item is added and it has an associated choice,
|
|
||||||
// we want to disable it so it can't be chosen again
|
|
||||||
if (action.choiceId > -1) {
|
|
||||||
newState = state.map((choice) => {
|
|
||||||
if (choice.id === parseInt(action.choiceId, 10)) {
|
|
||||||
choice.selected = true;
|
|
||||||
}
|
|
||||||
return choice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return newState;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'REMOVE_ITEM': {
|
|
||||||
// When an item is removed and it has an associated choice,
|
|
||||||
// we want to re-enable it so it can be chosen again
|
|
||||||
if (action.choiceId > -1) {
|
|
||||||
return state.map((choice) => {
|
|
||||||
if (choice.id === parseInt(action.choiceId, 10)) {
|
|
||||||
choice.selected = false;
|
|
||||||
}
|
|
||||||
return choice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'FILTER_CHOICES': {
|
|
||||||
const filteredResults = action.results;
|
|
||||||
const filteredState = state.map((choice) => {
|
|
||||||
// Set active state based on whether choice is
|
|
||||||
// within filtered results
|
|
||||||
|
|
||||||
choice.active = filteredResults.some((result) => {
|
|
||||||
if (result.item.id === choice.id) {
|
|
||||||
choice.score = result.score;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
return choice;
|
|
||||||
});
|
|
||||||
|
|
||||||
return filteredState;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'ACTIVATE_CHOICES': {
|
|
||||||
return state.map((choice) => {
|
|
||||||
choice.active = action.active;
|
|
||||||
return choice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'ADD_ITEM': {
|
||||||
|
let newState = state;
|
||||||
|
|
||||||
|
// If all choices need to be activated
|
||||||
|
if (action.activateOptions) {
|
||||||
|
newState = state.map((choice) => {
|
||||||
|
choice.active = action.active;
|
||||||
|
return choice;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// When an item is added and it has an associated choice,
|
||||||
|
// we want to disable it so it can't be chosen again
|
||||||
|
if (action.choiceId > -1) {
|
||||||
|
newState = state.map((choice) => {
|
||||||
|
if (choice.id === parseInt(action.choiceId, 10)) {
|
||||||
|
choice.selected = true;
|
||||||
|
}
|
||||||
|
return choice;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'REMOVE_ITEM': {
|
||||||
|
// When an item is removed and it has an associated choice,
|
||||||
|
// we want to re-enable it so it can be chosen again
|
||||||
|
if (action.choiceId > -1) {
|
||||||
|
return state.map((choice) => {
|
||||||
|
if (choice.id === parseInt(action.choiceId, 10)) {
|
||||||
|
choice.selected = false;
|
||||||
|
}
|
||||||
|
return choice;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'FILTER_CHOICES': {
|
||||||
|
const filteredResults = action.results;
|
||||||
|
const filteredState = state.map((choice) => {
|
||||||
|
// Set active state based on whether choice is
|
||||||
|
// within filtered results
|
||||||
|
|
||||||
|
choice.active = filteredResults.some((result) => {
|
||||||
|
if (result.item.id === choice.id) {
|
||||||
|
choice.score = result.score;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return choice;
|
||||||
|
});
|
||||||
|
|
||||||
|
return filteredState;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'ACTIVATE_CHOICES': {
|
||||||
|
return state.map((choice) => {
|
||||||
|
choice.active = action.active;
|
||||||
|
return choice;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default choices;
|
export default choices;
|
|
@ -1,18 +1,18 @@
|
||||||
const groups = (state = [], action) => {
|
const groups = (state = [], action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_GROUP': {
|
case 'ADD_GROUP': {
|
||||||
return [...state, {
|
return [...state, {
|
||||||
id: action.id,
|
id: action.id,
|
||||||
value: action.value,
|
value: action.value,
|
||||||
active: action.active,
|
active: action.active,
|
||||||
disabled: action.disabled,
|
disabled: action.disabled,
|
||||||
}];
|
}];
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default groups;
|
export default groups;
|
|
@ -4,22 +4,22 @@ import groups from './groups';
|
||||||
import choices from './choices';
|
import choices from './choices';
|
||||||
|
|
||||||
const appReducer = combineReducers({
|
const appReducer = combineReducers({
|
||||||
items,
|
items,
|
||||||
groups,
|
groups,
|
||||||
choices,
|
choices,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rootReducer = (passedState, action) => {
|
const rootReducer = (passedState, action) => {
|
||||||
let state = passedState;
|
let state = passedState;
|
||||||
// If we are clearing all items, groups and options we reassign
|
// If we are clearing all items, groups and options we reassign
|
||||||
// state and then pass that state to our proper reducer. This isn't
|
// state and then pass that state to our proper reducer. This isn't
|
||||||
// mutating our actual state
|
// mutating our actual state
|
||||||
// See: http://stackoverflow.com/a/35641992
|
// See: http://stackoverflow.com/a/35641992
|
||||||
if (action.type === 'CLEAR_ALL') {
|
if (action.type === 'CLEAR_ALL') {
|
||||||
state = undefined;
|
state = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return appReducer(state, action);
|
return appReducer(state, action);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
|
@ -1,47 +1,47 @@
|
||||||
const items = (state = [], action) => {
|
const items = (state = [], action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_ITEM': {
|
case 'ADD_ITEM': {
|
||||||
// Add object to items array
|
// Add object to items array
|
||||||
const newState = [...state, {
|
const newState = [...state, {
|
||||||
id: action.id,
|
id: action.id,
|
||||||
choiceId: action.choiceId,
|
choiceId: action.choiceId,
|
||||||
value: action.value,
|
value: action.value,
|
||||||
label: action.label,
|
label: action.label,
|
||||||
active: true,
|
active: true,
|
||||||
highlighted: false,
|
highlighted: false,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return newState.map((item) => {
|
return newState.map((item) => {
|
||||||
if (item.highlighted) {
|
if (item.highlighted) {
|
||||||
item.highlighted = false;
|
item.highlighted = false;
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'REMOVE_ITEM': {
|
|
||||||
// Set item to inactive
|
|
||||||
return state.map((item) => {
|
|
||||||
if (item.id === action.id) {
|
|
||||||
item.active = false;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'HIGHLIGHT_ITEM': {
|
|
||||||
return state.map((item) => {
|
|
||||||
if (item.id === action.id) {
|
|
||||||
item.highlighted = action.highlighted;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'REMOVE_ITEM': {
|
||||||
|
// Set item to inactive
|
||||||
|
return state.map((item) => {
|
||||||
|
if (item.id === action.id) {
|
||||||
|
item.active = false;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'HIGHLIGHT_ITEM': {
|
||||||
|
return state.map((item) => {
|
||||||
|
if (item.id === action.id) {
|
||||||
|
item.highlighted = action.highlighted;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default items;
|
export default items;
|
|
@ -2,149 +2,149 @@ import { createStore } from 'redux';
|
||||||
import rootReducer from './../reducers/index.js';
|
import rootReducer from './../reducers/index.js';
|
||||||
|
|
||||||
export default class Store {
|
export default class Store {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.store = createStore(
|
this.store = createStore(
|
||||||
rootReducer,
|
rootReducer
|
||||||
window.devToolsExtension ? window.devToolsExtension() : undefined
|
, window.devToolsExtension ? window.devToolsExtension() : undefined
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get store object (wrapping Redux method)
|
||||||
|
* @return {Object} State
|
||||||
|
*/
|
||||||
|
getState() {
|
||||||
|
return this.store.getState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch event to store (wrapped Redux method)
|
||||||
|
* @param {Function} action Action function to trigger
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
dispatch(action) {
|
||||||
|
this.store.dispatch(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscribe store to function call (wrapped Redux method)
|
||||||
|
* @param {Function} onChange Function to trigger when state changes
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
subscribe(onChange) {
|
||||||
|
this.store.subscribe(onChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get items from store
|
||||||
|
* @return {Array} Item objects
|
||||||
|
*/
|
||||||
|
getItems() {
|
||||||
|
const state = this.store.getState();
|
||||||
|
return state.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get active items from store
|
||||||
|
* @return {Array} Item objects
|
||||||
|
*/
|
||||||
|
getItemsFilteredByActive() {
|
||||||
|
const items = this.getItems();
|
||||||
|
const values = items.filter((item) => {
|
||||||
|
return item.active === true;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get items from store reduced to just their values
|
||||||
|
* @return {Array} Item objects
|
||||||
|
*/
|
||||||
|
getItemsReducedToValues(items = this.getItems()) {
|
||||||
|
const values = items.reduce((prev, current) => {
|
||||||
|
prev.push(current.value);
|
||||||
|
return prev;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get choices from store
|
||||||
|
* @return {Array} Option objects
|
||||||
|
*/
|
||||||
|
getChoices() {
|
||||||
|
const state = this.store.getState();
|
||||||
|
return state.choices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get active choices from store
|
||||||
|
* @return {Array} Option objects
|
||||||
|
*/
|
||||||
|
getChoicesFilteredByActive() {
|
||||||
|
const choices = this.getChoices();
|
||||||
|
const values = choices.filter((choice) => {
|
||||||
|
return choice.active === true;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get selectable choices from store
|
||||||
|
* @return {Array} Option objects
|
||||||
|
*/
|
||||||
|
getChoicesFilteredBySelectable() {
|
||||||
|
const choices = this.getChoices();
|
||||||
|
const values = choices.filter((choice) => {
|
||||||
|
return choice.disabled !== true;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get single choice by it's ID
|
||||||
|
* @return {Object} Found choice
|
||||||
|
*/
|
||||||
|
getChoiceById(id) {
|
||||||
|
if (id) {
|
||||||
|
const choices = this.getChoicesFilteredByActive();
|
||||||
|
const foundChoice = choices.find((choice) => choice.id === parseInt(id, 10));
|
||||||
|
return foundChoice;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get store object (wrapping Redux method)
|
* Get groups from store
|
||||||
* @return {Object} State
|
* @return {Array} Group objects
|
||||||
*/
|
*/
|
||||||
getState() {
|
getGroups() {
|
||||||
return this.store.getState();
|
const state = this.store.getState();
|
||||||
}
|
return state.groups;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch event to store (wrapped Redux method)
|
* Get active groups from store
|
||||||
* @param {Function} action Action function to trigger
|
* @return {Array} Group objects
|
||||||
* @return
|
*/
|
||||||
*/
|
getGroupsFilteredByActive() {
|
||||||
dispatch(action) {
|
const groups = this.getGroups();
|
||||||
this.store.dispatch(action);
|
const choices = this.getChoices();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
const values = groups.filter((group) => {
|
||||||
* Subscribe store to function call (wrapped Redux method)
|
const isActive = group.active === true && group.disabled === false;
|
||||||
* @param {Function} onChange Function to trigger when state changes
|
const hasActiveOptions = choices.some((choice) => {
|
||||||
* @return
|
return choice.active === true && choice.disabled === false;
|
||||||
*/
|
});
|
||||||
subscribe(onChange) {
|
return isActive && hasActiveOptions;
|
||||||
this.store.subscribe(onChange);
|
}, []);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
return values;
|
||||||
* Get items from store
|
}
|
||||||
* @return {Array} Item objects
|
|
||||||
*/
|
|
||||||
getItems() {
|
|
||||||
const state = this.store.getState();
|
|
||||||
return state.items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get active items from store
|
|
||||||
* @return {Array} Item objects
|
|
||||||
*/
|
|
||||||
getItemsFilteredByActive() {
|
|
||||||
const items = this.getItems();
|
|
||||||
const values = items.filter((item) => {
|
|
||||||
return item.active === true;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get items from store reduced to just their values
|
|
||||||
* @return {Array} Item objects
|
|
||||||
*/
|
|
||||||
getItemsReducedToValues(items = this.getItems()) {
|
|
||||||
const values = items.reduce((prev, current) => {
|
|
||||||
prev.push(current.value);
|
|
||||||
return prev;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get choices from store
|
|
||||||
* @return {Array} Option objects
|
|
||||||
*/
|
|
||||||
getChoices() {
|
|
||||||
const state = this.store.getState();
|
|
||||||
return state.choices;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get active choices from store
|
|
||||||
* @return {Array} Option objects
|
|
||||||
*/
|
|
||||||
getChoicesFilteredByActive() {
|
|
||||||
const choices = this.getChoices();
|
|
||||||
const values = choices.filter((choice) => {
|
|
||||||
return choice.active === true;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get selectable choices from store
|
|
||||||
* @return {Array} Option objects
|
|
||||||
*/
|
|
||||||
getChoicesFilteredBySelectable() {
|
|
||||||
const choices = this.getChoices();
|
|
||||||
const values = choices.filter((choice) => {
|
|
||||||
return choice.disabled !== true;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get single choice by it's ID
|
|
||||||
* @return {Object} Found choice
|
|
||||||
*/
|
|
||||||
getChoiceById(id) {
|
|
||||||
if (id) {
|
|
||||||
const choices = this.getChoicesFilteredByActive();
|
|
||||||
const foundChoice = choices.find((choice) => choice.id === parseInt(id, 10));
|
|
||||||
return foundChoice;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get groups from store
|
|
||||||
* @return {Array} Group objects
|
|
||||||
*/
|
|
||||||
getGroups() {
|
|
||||||
const state = this.store.getState();
|
|
||||||
return state.groups;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get active groups from store
|
|
||||||
* @return {Array} Group objects
|
|
||||||
*/
|
|
||||||
getGroupsFilteredByActive() {
|
|
||||||
const groups = this.getGroups();
|
|
||||||
const choices = this.getChoices();
|
|
||||||
|
|
||||||
const values = groups.filter((group) => {
|
|
||||||
const isActive = group.active === true && group.disabled === false;
|
|
||||||
const hasActiveOptions = choices.some((choice) => {
|
|
||||||
return choice.active === true && choice.disabled === false;
|
|
||||||
});
|
|
||||||
return isActive && hasActiveOptions;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Store;
|
module.exports = Store;
|
Loading…
Reference in a new issue