Merge branch 'tostringtheory-master'

This commit is contained in:
Josh Johnson 2018-01-04 11:32:18 +00:00
commit 2e59385cc2
8 changed files with 350 additions and 214 deletions

View file

@ -1,4 +1,4 @@
/*! choices.js v3.0.2 | (c) 2017 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
/*! choices.js v3.0.2 | (c) 2018 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
@ -78,11 +78,11 @@ return /******/ (function(modules) { // webpackBootstrap
var _index2 = _interopRequireDefault(_index);
var _index3 = __webpack_require__(30);
var _index3 = __webpack_require__(31);
var _utils = __webpack_require__(31);
var _utils = __webpack_require__(32);
__webpack_require__(32);
__webpack_require__(33);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@ -576,6 +576,8 @@ return /******/ (function(modules) { // webpackBootstrap
}, {
key: 'render',
value: function render() {
if (this.store.isLoading()) return;
this.currentState = this.store.getState();
// Only render if our state has actually changed
@ -1102,10 +1104,14 @@ return /******/ (function(modules) { // webpackBootstrap
if (!(0, _utils.isType)('Array', choices) || !value) {
return this;
}
// Clear choices if needed
if (replaceChoices) {
this._clearChoices();
}
this._setLoading(true);
// Add choices if passed
if (choices && choices.length) {
this.containerOuter.classList.remove(this.config.classNames.loadingState);
@ -1117,6 +1123,8 @@ return /******/ (function(modules) { // webpackBootstrap
}
});
}
this._setLoading(false);
}
}
return this;
@ -1483,7 +1491,7 @@ return /******/ (function(modules) { // webpackBootstrap
/**
* Apply or remove a loading state to the component.
* @param {Boolean} isLoading default value set to 'true'.
* @param {Boolean} setLoading default value set to 'true'.
* @return
* @private
*/
@ -1491,10 +1499,10 @@ return /******/ (function(modules) { // webpackBootstrap
}, {
key: '_handleLoadingState',
value: function _handleLoadingState() {
var isLoading = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var setLoading = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var placeholderItem = this.itemList.querySelector('.' + this.config.classNames.placeholder);
if (isLoading) {
if (setLoading) {
this.containerOuter.classList.add(this.config.classNames.loadingState);
this.containerOuter.setAttribute('aria-busy', 'true');
if (this.isSelectOneElement) {
@ -1541,6 +1549,9 @@ return /******/ (function(modules) { // webpackBootstrap
// Remove loading states/text
_this15._handleLoadingState(false);
// Add each result as a choice
_this15._setLoading(true);
parsedResults.forEach(function (result) {
if (result.choices) {
var groupId = result.id || null;
@ -1550,6 +1561,8 @@ return /******/ (function(modules) { // webpackBootstrap
}
});
_this15._setLoading(false);
if (_this15.isSelectOneElement) {
_this15._selectPlaceholderChoice();
}
@ -2689,6 +2702,11 @@ return /******/ (function(modules) { // webpackBootstrap
this.config.templates = (0, _utils.extend)(templates, userTemplates);
}
}, {
key: '_setLoading',
value: function _setLoading(isLoading) {
this.store.dispatch((0, _index3.setIsLoading)(isLoading));
}
/**
* Create DOM structure around passed select element
@ -2770,6 +2788,8 @@ return /******/ (function(modules) { // webpackBootstrap
this.highlightPosition = 0;
this.isSearching = false;
this._setLoading(true);
if (passedGroups && passedGroups.length) {
passedGroups.forEach(function (group) {
_this23._addGroup(group, group.id || null);
@ -2814,6 +2834,8 @@ return /******/ (function(modules) { // webpackBootstrap
}
});
}
this._setLoading(false);
} else if (this.isTextElement) {
// Add any preset values seperated by delimiter
this.presetItems.forEach(function (item) {
@ -3788,6 +3810,18 @@ return /******/ (function(modules) { // webpackBootstrap
this.store.subscribe(onChange);
}
/**
* Get loading state from store
* @return {Boolean} Loading State
*/
}, {
key: 'isLoading',
value: function isLoading() {
var state = this.store.getState();
return state.general.loading;
}
/**
* Get items from store
* @return {Array} Item objects
@ -4065,7 +4099,6 @@ return /******/ (function(modules) { // webpackBootstrap
*/
var ActionTypes = exports.ActionTypes = {
INIT: '@@redux/INIT'
};
/**
* Creates a Redux store that holds the state tree.
@ -4084,7 +4117,7 @@ return /******/ (function(modules) { // webpackBootstrap
* If you use `combineReducers` to produce the root reducer function, this must be
* an object with the same shape as `combineReducers` keys.
*
* @param {Function} enhancer The store enhancer. You may optionally specify it
* @param {Function} [enhancer] The store enhancer. You may optionally specify it
* to enhance the store with third-party capabilities such as middleware,
* time travel, persistence, etc. The only store enhancer that ships with Redux
* is `applyMiddleware()`.
@ -4092,7 +4125,7 @@ return /******/ (function(modules) { // webpackBootstrap
* @returns {Store} A Redux store that lets you read the state, dispatch actions
* and subscribe to changes.
*/
function createStore(reducer, preloadedState, enhancer) {
};function createStore(reducer, preloadedState, enhancer) {
var _ref2;
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
@ -4226,7 +4259,8 @@ return /******/ (function(modules) { // webpackBootstrap
var listeners = currentListeners = nextListeners;
for (var i = 0; i < listeners.length; i++) {
listeners[i]();
var listener = listeners[i];
listener();
}
return action;
@ -4255,7 +4289,7 @@ return /******/ (function(modules) { // webpackBootstrap
* Interoperability point for observable/reactive libraries.
* @returns {observable} A minimal observable of state changes.
* For more information, see the observable proposal:
* https://github.com/zenparsing/es-observable
* https://github.com/tc39/proposal-observable
*/
function observable() {
var _ref;
@ -4702,7 +4736,7 @@ return /******/ (function(modules) { // webpackBootstrap
var actionType = action && action.type;
var actionName = actionType && '"' + actionType.toString() + '"' || 'an action';
return 'Given action ' + actionName + ', reducer "' + key + '" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.';
return 'Given action ' + actionName + ', reducer "' + key + '" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state. ' + 'If you want this reducer to hold no value, you can return null instead of undefined.';
}
function getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {
@ -4730,18 +4764,18 @@ return /******/ (function(modules) { // webpackBootstrap
}
}
function assertReducerSanity(reducers) {
function assertReducerShape(reducers) {
Object.keys(reducers).forEach(function (key) {
var reducer = reducers[key];
var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT });
if (typeof initialState === 'undefined') {
throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');
throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined. If you don\'t want to set a value for this reducer, ' + 'you can use null instead of undefined.');
}
var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');
if (typeof reducer(undefined, { type: type }) === 'undefined') {
throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');
throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined, but can be null.');
}
});
}
@ -4780,23 +4814,24 @@ return /******/ (function(modules) { // webpackBootstrap
}
var finalReducerKeys = Object.keys(finalReducers);
var unexpectedKeyCache = void 0;
if (false) {
var unexpectedKeyCache = {};
unexpectedKeyCache = {};
}
var sanityError;
var shapeAssertionError = void 0;
try {
assertReducerSanity(finalReducers);
assertReducerShape(finalReducers);
} catch (e) {
sanityError = e;
shapeAssertionError = e;
}
return function combination() {
var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var action = arguments[1];
if (sanityError) {
throw sanityError;
if (shapeAssertionError) {
throw shapeAssertionError;
}
if (false) {
@ -4808,16 +4843,16 @@ return /******/ (function(modules) { // webpackBootstrap
var hasChanged = false;
var nextState = {};
for (var i = 0; i < finalReducerKeys.length; i++) {
var key = finalReducerKeys[i];
var reducer = finalReducers[key];
var previousStateForKey = state[key];
for (var _i = 0; _i < finalReducerKeys.length; _i++) {
var _key = finalReducerKeys[_i];
var reducer = finalReducers[_key];
var previousStateForKey = state[_key];
var nextStateForKey = reducer(previousStateForKey, action);
if (typeof nextStateForKey === 'undefined') {
var errorMessage = getUndefinedStateErrorMessage(key, action);
var errorMessage = getUndefinedStateErrorMessage(_key, action);
throw new Error(errorMessage);
}
nextState[key] = nextStateForKey;
nextState[_key] = nextStateForKey;
hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
}
return hasChanged ? nextState : state;
@ -5007,13 +5042,11 @@ return /******/ (function(modules) { // webpackBootstrap
return funcs[0];
}
var last = funcs[funcs.length - 1];
var rest = funcs.slice(0, -1);
return funcs.reduce(function (a, b) {
return function () {
return rest.reduceRight(function (composed, f) {
return f(composed);
}, last.apply(undefined, arguments));
return a(b.apply(undefined, arguments));
};
});
}
/***/ }),
@ -5040,12 +5073,17 @@ return /******/ (function(modules) { // webpackBootstrap
var _choices2 = _interopRequireDefault(_choices);
var _general = __webpack_require__(30);
var _general2 = _interopRequireDefault(_general);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var appReducer = (0, _redux.combineReducers)({
items: _items2.default,
groups: _groups2.default,
choices: _choices2.default
choices: _choices2.default,
general: _general2.default
});
var rootReducer = function rootReducer(passedState, action) {
@ -5305,6 +5343,36 @@ return /******/ (function(modules) { // webpackBootstrap
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var general = function general() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { loading: false };
var action = arguments[1];
switch (action.type) {
case 'LOADING':
{
return {
loading: action.isLoading
};
}
default:
{
return state;
}
}
};
exports.default = general;
/***/ }),
/* 31 */
/***/ (function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
@ -5391,8 +5459,15 @@ return /******/ (function(modules) { // webpackBootstrap
};
};
var setIsLoading = exports.setIsLoading = function setIsLoading(isLoading) {
return {
type: 'LOADING',
isLoading: isLoading
};
};
/***/ }),
/* 31 */
/* 32 */
/***/ (function(module, exports) {
'use strict';
@ -5984,7 +6059,7 @@ return /******/ (function(modules) { // webpackBootstrap
};
/***/ }),
/* 32 */
/* 33 */
/***/ (function(module, exports) {
'use strict';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -78,3 +78,11 @@ export const clearAll = () => {
type: 'CLEAR_ALL',
};
};
export const setIsLoading = (isLoading) => {
return {
type: 'LOADING',
isLoading,
};
};

View file

@ -2,6 +2,7 @@ import Fuse from 'fuse.js';
import classNames from 'classnames';
import Store from './store/index.js';
import {
setIsLoading,
addItem,
removeItem,
highlightItem,
@ -480,6 +481,9 @@ class Choices {
* @private
*/
render() {
if(this.store.isLoading())
return;
this.currentState = this.store.getState();
// Only render if our state has actually changed
@ -982,10 +986,14 @@ class Choices {
if (!isType('Array', choices) || !value) {
return this;
}
// Clear choices if needed
if (replaceChoices) {
this._clearChoices();
}
this._setLoading(true);
// Add choices if passed
if (choices && choices.length) {
this.containerOuter.classList.remove(this.config.classNames.loadingState);
@ -1010,6 +1018,9 @@ class Choices {
}
});
}
this._setLoading(false);
}
}
return this;
@ -1360,13 +1371,13 @@ class Choices {
/**
* Apply or remove a loading state to the component.
* @param {Boolean} isLoading default value set to 'true'.
* @param {Boolean} setLoading default value set to 'true'.
* @return
* @private
*/
_handleLoadingState(isLoading = true) {
_handleLoadingState(setLoading = true) {
let placeholderItem = this.itemList.querySelector(`.${this.config.classNames.placeholder}`);
if (isLoading) {
if (setLoading) {
this.containerOuter.classList.add(this.config.classNames.loadingState);
this.containerOuter.setAttribute('aria-busy', 'true');
if (this.isSelectOneElement) {
@ -1408,6 +1419,9 @@ class Choices {
// Remove loading states/text
this._handleLoadingState(false);
// Add each result as a choice
this._setLoading(true);
parsedResults.forEach((result) => {
if (result.choices) {
const groupId = (result.id || null);
@ -1430,6 +1444,8 @@ class Choices {
}
});
this._setLoading(false);
if (this.isSelectOneElement) {
this._selectPlaceholderChoice();
}
@ -2689,6 +2705,12 @@ class Choices {
this.config.templates = extend(templates, userTemplates);
}
_setLoading(isLoading) {
this.store.dispatch(
setIsLoading(isLoading)
);
}
/**
* Create DOM structure around passed select element
* @return
@ -2767,6 +2789,8 @@ class Choices {
this.highlightPosition = 0;
this.isSearching = false;
this._setLoading(true);
if (passedGroups && passedGroups.length) {
passedGroups.forEach((group) => {
this._addGroup(group, (group.id || null));
@ -2825,6 +2849,9 @@ class Choices {
}
});
}
this._setLoading(false);
} else if (this.isTextElement) {
// Add any preset values seperated by delimiter
this.presetItems.forEach((item) => {

View file

@ -0,0 +1,15 @@
const general = (state = { loading: false }, action) => {
switch (action.type) {
case 'LOADING': {
return {
loading: action.isLoading
};
}
default: {
return state;
}
}
};
export default general;

View file

@ -2,11 +2,13 @@ import { combineReducers } from 'redux';
import items from './items';
import groups from './groups';
import choices from './choices';
import general from './general';
const appReducer = combineReducers({
items,
groups,
choices,
general
});
const rootReducer = (passedState, action) => {

View file

@ -35,6 +35,15 @@ export default class Store {
this.store.subscribe(onChange);
}
/**
* Get loading state from store
* @return {Boolean} Loading State
*/
isLoading() {
const state = this.store.getState();
return state.general.loading;
}
/**
* Get items from store
* @return {Array} Item objects