docs/index.js.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: index.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: index.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>// @flow
/**
* Given a string containing markup renders the markup into a
* React component. This needs to be called inside the
* 'dangerouslySetInnerHTML' prop to work.
* @function generateMarkup
* @param {string} markup - String containing HTML
* @return {object} Object which is transformed to innerHTML by
* dangerouslySetInnerHTML
*/
export const generateMarkup = (markup: string): Object => {
return {
__html: markup
}
}
/**
* Given an array of objects sorts the array by the given property of
* each object in either ascending or descending order.
* @function sortByProperty
* @param {string} property - Property to sort by
* @param {number} order - Should be either 1 or -1
* @param {array} list - list of objects to sort
* @return {array} Sorted list
*/
export const sortByProperty = (
property: string,
order: number,
list: Array<Object>
): Array<Object> => list.sort((a, b) => {
const aHasProperty = typeof a[property] !== 'undefined'
const bHasProperty = typeof b[property] !== 'undefined'
const aIsSmaller = a[property] < b[property]
if (
aIsSmaller ||
(aHasProperty && !bHasProperty)
) return -order
const aIsLarger = a[property] > b[property]
if (
aIsLarger ||
(!aHasProperty && bHasProperty)
) return order
return 0
})
/**
* Pipes the output of functions as arguments into the next function
* (from left to right).
* @function pipe
* @example
* const splitString = str => str.split('')
* const getLength = arr => arr.length
* pipe(splitString, getLength)('Hello world') // => 11
*
* @param {function} f1 - first function to call
* @param {array} ...fns - Additional functions to pipe through
* @return {function} Composed function
*/
export const pipe = (f1: Function, ...fns: Array<Function>): Function =>
(...args: Array<mixed>): Function => {
return fns.reduce((res, fn) => fn(res), f1.apply(null, args))
}
/**
* Creates an array containing a range of numbers.
* @function range
* @param {number} start - First number of the range, array index 0
* @param {number} end - Endindex, not included inside the resulting array
* @return {array} array of numbers
* @example
* range(2, 6) // => [2, 3, 4, 5]
*/
export const range = (start: number, end: number): Array<number> => {
return Array.from({length: (end - start)}, (v, k) => k + start)
}
/**
* Returns the first element of an array
* @function first
* @param {array} arr - Array
* @return {element} First element of the array
*/
export const first = <T>(arr: Array<T>): T => arr[0]
/**
* Returns the last element of an array
* @function last
* @param {array} arr - Array
* @return {element} Last element of the array
*/
export const last = <T>(arr: Array<T>): T => first(arr.slice(-1))
/**
* Toggles the class on a DOM node by a given condition
* @function toggleClass
* @param {HTMLElement} node - Domnode to add/remove class to/from
* @param {string} className - Class to add/remove
* @param {boolean} condition - Expression that resolves to true/false
* @return {void}
*/
export const toggleClass = (
node: HTMLElement,
className: string,
condition: boolean
): void => {
condition
? node.classList.add(className)
: node.classList.remove(className)
}
/**
* Function partially apply arguments to a function. (Left to right)
* @function partial
* @param {function} fn - Function to apply to.
* @param {array} ...args - Arguments to apply
* @return {function} Partially applied function
*/
export const partial = (fn: Function, ...args: Array<mixed>): Function => {
return (...otherArgs) => {
return fn(...args, ...otherArgs)
}
}
/**
* Converts an object to an array of its values. This is basically the same
* as Object.values(). The latter sometimes has some unintended effects on
* flow, which is why we currently fallback to this helper.
* @function objToArray
* @param {object} obj - Object to convert
* @return {array} Array of values
*/
export const objToArray = (obj: Object): Array<*> => Object.keys(obj).map(k => obj[k])
/**
* Converts an array of objects to an object keyed by a specific property,
* where each key is the value of the property and the value is the actual object.
* @function objArrayToKeyedObj
* @param {array} arr - Array containing objects each containing a specific property
* @param {string} property - Property to key objects by
* @return {object}
*/
export const objArrayToKeyedObj = (arr: Array<Object>, property: string): Object => arr
.reduce((acc, obj) => {
if (!obj) return acc
return { ...acc, [obj[property]]: obj }
}, {})
/**
* Eliminates null/undefined values from array (flow compliant)
* @function compactArray
* @param {array} arr - Source array
* @return {array}
*/
// TODO narrow down types (this is quite a hard task =))
export const compactArray = <T>(arr: Array<?T>): Array<T> => {
let result = []
for (let i = 0; i < arr.length; i++) {
const el = arr[i]
if (el !== null && el !== undefined) {
result.push(el)
}
}
return result
}
/**
* Conditionally inserts a key-value pair into an object. To make practical
* use of this function inside an object you have to use the object spread
* operator on the result
* @function insertInObjIf
* @param {boolean} condition - condition to determine if property should be inserted
* @param {string} property - property to insert
* @param {any} value - property value
* @return {object} new object either empty or containing the inserted property only
*/
export const insertInObjIf = (
condition: boolean,
property: string,
value: any
): Object => {
return condition ? { [property]: value } : {}
}
/**
* Conditionally inserts a value into an array. To make practical use of this
* funciton inside an array you have to use the array spread operator on the
* result.
* @function insertInArrIf
* @param {boolean} condition - condition to determine if property should be inserted
* @param {any} value - value to insert
* @return {array} either empty or containing the new value
*/
export const insertInArrIf = (
condition: boolean,
value: any
): Array<any> => {
return condition ? [ value ] : []
}
/**
* Removes a property from an object and returns a new object. The original
* object is not altered.
* @function immutablyDeleteProperty
* @param {object} obj - Object to delete property from
* @param {string} property - property to delete
* @return {object} new object without the specified property
*/
export const immutablyDeleteProperty = (obj: Object, property: string): Object => {
return Object.keys(obj)
.filter(k => k !== property)
.reduce((acc, k) => {
return { ...acc, [k]: obj[k] }
}, {})
}
/**
* Reduces multiple function calls, which are fired in quick succession to
* a single function call (i.e. to reduce function calls on scroll events.
* @function debounce
* @param {function} fn - Function to debounce
* @param {number} time - Time to wait until function is called - will be reset
* on every invocation of the debounced function in the given timeframe.
* @return {function} Debounced function
*/
export const debounce = (fn: Function, time: number): Function => {
let timeout
// Has to be a 'real' function, not an arrow function, to preserve
// context of 'this'
return function (...args: Array<mixed>) {
const callback = () => fn.apply(this, args)
clearTimeout(timeout)
timeout = setTimeout(callback, time)
}
}
/**
* Makes sure that a given function is only called once in a specified
* timeframe.
* @function throttle
* @param {function} fn - Function to call after timeout
* @param {number} time - Timeout in ms
* @param {object} context - Useful for throttling object methods
* @return {function} Throttled function
*/
export const throttle = (fn: Function, time: number, context: Object = this): Function => {
let timeout
let callbackArgs
const callback = () => {
fn.apply(context, callbackArgs)
clearTimeout(timeout)
timeout = undefined
}
// Has to be a 'real' function, not an arrow function, to preserve
// context of 'this'
return function (...args: Array<mixed>) {
if (timeout) return
callbackArgs = args
timeout = setTimeout(callback, time)
}
}
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#compactArray">compactArray</a></li><li><a href="global.html#debounce">debounce</a></li><li><a href="global.html#first">first</a></li><li><a href="global.html#generateMarkup">generateMarkup</a></li><li><a href="global.html#immutablyDeleteProperty">immutablyDeleteProperty</a></li><li><a href="global.html#insertInArrIf">insertInArrIf</a></li><li><a href="global.html#insertInObjIf">insertInObjIf</a></li><li><a href="global.html#last">last</a></li><li><a href="global.html#objArrayToKeyedObj">objArrayToKeyedObj</a></li><li><a href="global.html#objToArray">objToArray</a></li><li><a href="global.html#partial">partial</a></li><li><a href="global.html#pipe">pipe</a></li><li><a href="global.html#range">range</a></li><li><a href="global.html#sortByProperty">sortByProperty</a></li><li><a href="global.html#throttle">throttle</a></li><li><a href="global.html#toggleClass">toggleClass</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon Jan 08 2018 14:59:36 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>