Install prettier + resolve linting issues

This commit is contained in:
Josh Johnson 2018-05-28 13:55:44 +01:00
parent a6bfdc0993
commit f9455b1a25
32 changed files with 752 additions and 499 deletions

View file

@ -1,34 +1,24 @@
{ {
"extends": "airbnb", "extends": ["prettier"],
"ecmaFeatures": { "plugins": ["prettier"],
"modules": true
},
"env": { "env": {
"browser": true, "browser": true,
"node": true, "node": true,
"mocha": true "mocha": true
}, },
"globals": { "globals": {
"__DEV__": true,
"describe": true, "describe": true,
"it": true, "it": true,
"before": true, "before": true,
"after": true, "after": true,
"beforeEach": true, "beforeEach": true,
"afterEach": true, "afterEach": true
"expect": true,
"browser": true,
"by": true,
"element": true,
"cy": true
}, },
"parser": "babel-eslint", "parser": "babel-eslint",
"rules": { "rules": {
"strict": 0, "prettier/prettier": ["error", {
"no-underscore-dangle": 0, "singleQuote": true,
"no-console": ["warn", { "trailingComma": "all"
"allow": ["warn", "error"] }]
}],
"space-before-function-paren": 0
} }
} }

View file

@ -43,9 +43,11 @@
"csso": "^1.8.2", "csso": "^1.8.2",
"eslint": "^3.19.0", "eslint": "^3.19.0",
"eslint-config-airbnb": "^15.1.0", "eslint-config-airbnb": "^15.1.0",
"eslint-config-prettier": "^2.9.0",
"eslint-loader": "^1.5.0", "eslint-loader": "^1.5.0",
"eslint-plugin-import": "^2.7.0", "eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^5.1.1", "eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-prettier": "^2.6.0",
"eslint-plugin-react": "^7.2.1", "eslint-plugin-react": "^7.2.1",
"express": "^4.16.3", "express": "^4.16.3",
"husky": "^0.14.3", "husky": "^0.14.3",
@ -55,6 +57,7 @@
"nodemon": "^1.9.1", "nodemon": "^1.9.1",
"nyc": "^11.0.3", "nyc": "^11.0.3",
"postcss-cli": "^2.5.1", "postcss-cli": "^2.5.1",
"prettier": "^1.13.0",
"sinon": "^2.4.0", "sinon": "^2.4.0",
"webpack": "^3.8.1", "webpack": "^3.8.1",
"webpack-dev-middleware": "^2.0.0", "webpack-dev-middleware": "^2.0.0",

View file

@ -27,17 +27,19 @@ describe('actions/choices', () => {
keyCode, keyCode,
}; };
expect(actions.addChoice( expect(
value, actions.addChoice(
label, value,
id, label,
groupId, id,
disabled, groupId,
elementId, disabled,
customProperties, elementId,
placeholder, customProperties,
keyCode, placeholder,
)).to.eql(expectedAction); keyCode,
),
).to.eql(expectedAction);
}); });
}); });
@ -88,4 +90,3 @@ describe('actions/choices', () => {
}); });
}); });
}); });

View file

@ -16,12 +16,9 @@ describe('actions/groups', () => {
disabled, disabled,
}; };
expect(actions.addGroup( expect(actions.addGroup(value, id, active, disabled)).to.eql(
value, expectedAction,
id, );
active,
disabled,
)).to.eql(expectedAction);
}); });
}); });
}); });

View file

@ -25,16 +25,18 @@ describe('actions/items', () => {
keyCode, keyCode,
}; };
expect(actions.addItem( expect(
value, actions.addItem(
label, value,
id, label,
choiceId, id,
groupId, choiceId,
customProperties, groupId,
placeholder, customProperties,
keyCode, placeholder,
)).to.eql(expectedAction); keyCode,
),
).to.eql(expectedAction);
}); });
}); });

View file

@ -2,10 +2,28 @@ import Fuse from 'fuse.js';
import './lib/polyfills'; import './lib/polyfills';
import Store from './store/store'; import Store from './store/store';
import { Dropdown, Container, Input, List, WrappedInput, WrappedSelect } from './components'; import {
import { DEFAULT_CONFIG, DEFAULT_CLASSNAMES, EVENTS, KEY_CODES, SCROLLING_SPEED } from './constants'; Dropdown,
Container,
Input,
List,
WrappedInput,
WrappedSelect,
} from './components';
import {
DEFAULT_CONFIG,
DEFAULT_CLASSNAMES,
EVENTS,
KEY_CODES,
SCROLLING_SPEED,
} from './constants';
import { TEMPLATES } from './templates'; import { TEMPLATES } from './templates';
import { addChoice, filterChoices, activateChoices, clearChoices } from './actions/choices'; import {
addChoice,
filterChoices,
activateChoices,
clearChoices,
} from './actions/choices';
import { addItem, removeItem, highlightItem } from './actions/items'; import { addItem, removeItem, highlightItem } from './actions/items';
import { addGroup } from './actions/groups'; import { addGroup } from './actions/groups';
import { clearAll } from './actions/misc'; import { clearAll } from './actions/misc';
@ -48,12 +66,15 @@ class Choices {
} }
// Retrieve triggering element (i.e. element with 'data-choice' trigger) // Retrieve triggering element (i.e. element with 'data-choice' trigger)
const passedElement = isType('String', element) ? document.querySelector(element) : element; const passedElement = isType('String', element)
? document.querySelector(element)
: element;
this._isTextElement = passedElement.type === 'text'; this._isTextElement = passedElement.type === 'text';
this._isSelectOneElement = passedElement.type === 'select-one'; this._isSelectOneElement = passedElement.type === 'select-one';
this._isSelectMultipleElement = passedElement.type === 'select-multiple'; this._isSelectMultipleElement = passedElement.type === 'select-multiple';
this._isSelectElement = this._isSelectOneElement || this._isSelectMultipleElement; this._isSelectElement =
this._isSelectOneElement || this._isSelectMultipleElement;
if (this._isTextElement) { if (this._isTextElement) {
this.passedElement = new WrappedInput({ this.passedElement = new WrappedInput({
@ -72,8 +93,14 @@ class Choices {
throw new Error('Could not wrap passed element'); throw new Error('Could not wrap passed element');
} }
if (this.config.shouldSortItems === true && this._isSelectOneElement && !this.config.silent) { if (
console.warn('shouldSortElements: Type of passed element is \'select-one\', falling back to false.'); this.config.shouldSortItems === true &&
this._isSelectOneElement &&
!this.config.silent
) {
console.warn(
"shouldSortElements: Type of passed element is 'select-one', falling back to false.",
);
} }
this._store = new Store(this.render); this._store = new Store(this.render);
@ -204,13 +231,13 @@ class Choices {
render() { render() {
this._currentState = this._store.state; this._currentState = this._store.state;
const stateChanged = ( const stateChanged =
this._currentState.choices !== this._prevState.choices || this._currentState.choices !== this._prevState.choices ||
this._currentState.groups !== this._prevState.groups || this._currentState.groups !== this._prevState.groups ||
this._currentState.items !== this._prevState.items this._currentState.items !== this._prevState.items;
);
const shouldRenderChoices = this._isSelectElement; const shouldRenderChoices = this._isSelectElement;
const shouldRenderItems = this._currentState.items !== this._prevState.items; const shouldRenderItems =
this._currentState.items !== this._prevState.items;
if (!stateChanged) { if (!stateChanged) {
return; return;
@ -295,15 +322,14 @@ class Choices {
} }
removeHighlightedItems(runEvent = false) { removeHighlightedItems(runEvent = false) {
this._store.highlightedActiveItems this._store.highlightedActiveItems.forEach(item => {
.forEach((item) => { this._removeItem(item);
this._removeItem(item); // If this action was performed by the user
// If this action was performed by the user // trigger the event
// trigger the event if (runEvent) {
if (runEvent) { this._triggerChange(item.value);
this._triggerChange(item.value); }
} });
});
return this; return this;
} }
@ -358,12 +384,11 @@ class Choices {
} }
getValue(valueOnly = false) { getValue(valueOnly = false) {
const values = this._store.activeItems const values = this._store.activeItems.reduce((selectedItems, item) => {
.reduce((selectedItems, item) => { const itemValue = valueOnly ? item.value : item;
const itemValue = valueOnly ? item.value : item; selectedItems.push(itemValue);
selectedItems.push(itemValue); return selectedItems;
return selectedItems; }, []);
}, []);
return this._isSelectOneElement ? values[0] : values; return this._isSelectOneElement ? values[0] : values;
} }
@ -373,10 +398,7 @@ class Choices {
return this; return this;
} }
// Convert args to an iterable array [...args].forEach(value => this._setChoiceOrItem(value));
const values = [...args];
values.forEach(value => this._setChoiceOrItem(value));
return this; return this;
} }
@ -395,11 +417,7 @@ class Choices {
} }
setChoices(choices = [], value = '', label = '', replaceChoices = false) { setChoices(choices = [], value = '', label = '', replaceChoices = false) {
if ( if (!this._isSelectElement || !choices.length || !value) {
!this._isSelectElement ||
!choices.length ||
!value
) {
return this; return this;
} }
@ -409,14 +427,9 @@ class Choices {
} }
this.containerOuter.removeLoadingState(); this.containerOuter.removeLoadingState();
const addGroupsAndChoices = (groupOrChoice) => { const addGroupsAndChoices = groupOrChoice => {
if (groupOrChoice.choices) { if (groupOrChoice.choices) {
this._addGroup( this._addGroup(groupOrChoice, groupOrChoice.id || null, value, label);
groupOrChoice,
(groupOrChoice.id || null),
value,
label,
);
} else { } else {
this._addChoice( this._addChoice(
groupOrChoice[value], groupOrChoice[value],
@ -471,20 +484,23 @@ class Choices {
_createGroupsFragment(groups, choices, fragment) { _createGroupsFragment(groups, choices, fragment) {
const groupFragment = fragment || document.createDocumentFragment(); const groupFragment = fragment || document.createDocumentFragment();
const getGroupChoices = group => choices.filter((choice) => { const getGroupChoices = group =>
if (this._isSelectOneElement) { choices.filter(choice => {
return choice.groupId === group.id; if (this._isSelectOneElement) {
} return choice.groupId === group.id;
return choice.groupId === group.id && (this.config.renderSelectedChoices === 'always' || !choice.selected); }
}); return (
choice.groupId === group.id &&
(this.config.renderSelectedChoices === 'always' || !choice.selected)
);
});
// If sorting is enabled, filter groups // If sorting is enabled, filter groups
if (this.config.shouldSort) { if (this.config.shouldSort) {
groups.sort(this.config.sortFn); groups.sort(this.config.sortFn);
} }
groups.forEach((group) => { groups.forEach(group => {
const groupChoices = getGroupChoices(group); const groupChoices = getGroupChoices(group);
if (groupChoices.length >= 1) { if (groupChoices.length >= 1) {
const dropdownGroup = this._getTemplate('choiceGroup', group); const dropdownGroup = this._getTemplate('choiceGroup', group);
@ -499,14 +515,23 @@ class Choices {
_createChoicesFragment(choices, fragment, withinGroup = false) { _createChoicesFragment(choices, fragment, withinGroup = false) {
// Create a fragment to store our list items (so we don't have to update the DOM for each item) // Create a fragment to store our list items (so we don't have to update the DOM for each item)
const choicesFragment = fragment || document.createDocumentFragment(); const choicesFragment = fragment || document.createDocumentFragment();
const { renderSelectedChoices, searchResultLimit, renderChoiceLimit } = this.config; const {
renderSelectedChoices,
searchResultLimit,
renderChoiceLimit,
} = this.config;
const filter = this._isSearching ? sortByScore : this.config.sortFn; const filter = this._isSearching ? sortByScore : this.config.sortFn;
const appendChoice = (choice) => { const appendChoice = choice => {
const shouldRender = renderSelectedChoices === 'auto' ? const shouldRender =
(this._isSelectOneElement || !choice.selected) : renderSelectedChoices === 'auto'
true; ? this._isSelectOneElement || !choice.selected
: true;
if (shouldRender) { if (shouldRender) {
const dropdownItem = this._getTemplate('choice', choice, this.config.itemSelectText); const dropdownItem = this._getTemplate(
'choice',
choice,
this.config.itemSelectText,
);
choicesFragment.appendChild(dropdownItem); choicesFragment.appendChild(dropdownItem);
} }
}; };
@ -518,14 +543,17 @@ class Choices {
} }
// Split array into placeholders and "normal" choices // Split array into placeholders and "normal" choices
const { placeholderChoices, normalChoices } = rendererableChoices.reduce((acc, choice) => { const { placeholderChoices, normalChoices } = rendererableChoices.reduce(
if (choice.placeholder) { (acc, choice) => {
acc.placeholderChoices.push(choice); if (choice.placeholder) {
} else { acc.placeholderChoices.push(choice);
acc.normalChoices.push(choice); } else {
} acc.normalChoices.push(choice);
return acc; }
}, { placeholderChoices: [], normalChoices: [] }); return acc;
},
{ placeholderChoices: [], normalChoices: [] },
);
// If sorting is enabled or the user is searching, filter choices // If sorting is enabled or the user is searching, filter choices
if (this.config.shouldSort || this._isSearching) { if (this.config.shouldSort || this._isSearching) {
@ -571,7 +599,7 @@ class Choices {
this.passedElement.options = items; this.passedElement.options = items;
} }
const addItemToFragment = (item) => { const addItemToFragment = item => {
// Create new list element // Create new list element
const listItem = this._getTemplate('item', item, removeItemButton); const listItem = this._getTemplate('item', item, removeItemButton);
// Append it to list // Append it to list
@ -621,7 +649,9 @@ class Choices {
} }
const itemId = element.parentNode.getAttribute('data-id'); const itemId = element.parentNode.getAttribute('data-id');
const itemToRemove = activeItems.find(item => item.id === parseInt(itemId, 10)); const itemToRemove = activeItems.find(
item => item.id === parseInt(itemId, 10),
);
// Remove item associated with button // Remove item associated with button
this._removeItem(itemToRemove); this._removeItem(itemToRemove);
@ -647,7 +677,7 @@ class Choices {
// We only want to select one item with a click // We only want to select one item with a click
// so we deselect any items that aren't the target // so we deselect any items that aren't the target
// unless shift is being pressed // unless shift is being pressed
activeItems.forEach((item) => { activeItems.forEach(item => {
if (item.id === parseInt(passedId, 10) && !item.highlighted) { if (item.id === parseInt(passedId, 10) && !item.highlighted) {
this.highlightItem(item); this.highlightItem(item);
} else if (!hasShiftKey && item.highlighted) { } else if (!hasShiftKey && item.highlighted) {
@ -668,7 +698,8 @@ class Choices {
// If we are clicking on an option // If we are clicking on an option
const id = element.getAttribute('data-id'); const id = element.getAttribute('data-id');
const choice = this._store.getChoiceById(id); const choice = this._store.getChoiceById(id);
const passedKeyCode = activeItems[0] && activeItems[0].keyCode ? activeItems[0].keyCode : null; const passedKeyCode =
activeItems[0] && activeItems[0].keyCode ? activeItems[0].keyCode : null;
const hasActiveDropdown = this.dropdown.isActive; const hasActiveDropdown = this.dropdown.isActive;
// Update choice keyCode // Update choice keyCode
@ -729,12 +760,17 @@ class Choices {
} }
_handleLoadingState(isLoading = true) { _handleLoadingState(isLoading = true) {
let placeholderItem = this.itemList.getChild(`.${this.config.classNames.placeholder}`); let placeholderItem = this.itemList.getChild(
`.${this.config.classNames.placeholder}`,
);
if (isLoading) { if (isLoading) {
this.containerOuter.addLoadingState(); this.containerOuter.addLoadingState();
if (this._isSelectOneElement) { if (this._isSelectOneElement) {
if (!placeholderItem) { if (!placeholderItem) {
placeholderItem = this._getTemplate('placeholder', this.config.loadingText); placeholderItem = this._getTemplate(
'placeholder',
this.config.loadingText,
);
this.itemList.append(placeholderItem); this.itemList.append(placeholderItem);
} else { } else {
placeholderItem.innerHTML = this.config.loadingText; placeholderItem.innerHTML = this.config.loadingText;
@ -746,47 +782,51 @@ class Choices {
this.containerOuter.removeLoadingState(); this.containerOuter.removeLoadingState();
if (this._isSelectOneElement) { if (this._isSelectOneElement) {
placeholderItem.innerHTML = (this._placeholderValue || ''); placeholderItem.innerHTML = this._placeholderValue || '';
} else { } else {
this.input.placeholder = (this._placeholderValue || ''); this.input.placeholder = this._placeholderValue || '';
} }
} }
} }
_canAddItem(activeItems, value) { _canAddItem(activeItems, value) {
let canAddItem = true; let canAddItem = true;
let notice = isType('Function', this.config.addItemText) ? let notice = isType('Function', this.config.addItemText)
this.config.addItemText(value) : ? this.config.addItemText(value)
this.config.addItemText; : this.config.addItemText;
if (!this._isSelectOneElement) { if (!this._isSelectOneElement) {
const valueAlreadyExists = !existsInArray(activeItems, value); const valueAlreadyExists = !existsInArray(activeItems, value);
if (this.config.maxItemCount > 0 && this.config.maxItemCount <= activeItems.length) { if (
this.config.maxItemCount > 0 &&
this.config.maxItemCount <= activeItems.length
) {
// If there is a max entry limit and we have reached that limit // If there is a max entry limit and we have reached that limit
// don't update // don't update
canAddItem = false; canAddItem = false;
notice = isType('Function', this.config.maxItemText) ? notice = isType('Function', this.config.maxItemText)
this.config.maxItemText(this.config.maxItemCount) : ? this.config.maxItemText(this.config.maxItemCount)
this.config.maxItemText; : this.config.maxItemText;
} }
if (this.config.regexFilter && this._isTextElement && this.config.addItems && canAddItem) { if (
this.config.regexFilter &&
this._isTextElement &&
this.config.addItems &&
canAddItem
) {
// If a user has supplied a regular expression filter // If a user has supplied a regular expression filter
// determine whether we can update based on whether // determine whether we can update based on whether
// our regular expression passes // our regular expression passes
canAddItem = regexFilter(value, this.config.regexFilter); canAddItem = regexFilter(value, this.config.regexFilter);
} }
if ( if (!this.config.duplicateItems && !valueAlreadyExists && canAddItem) {
!this.config.duplicateItems &&
!valueAlreadyExists &&
canAddItem
) {
canAddItem = false; canAddItem = false;
notice = isType('Function', this.config.uniqueItemText) ? notice = isType('Function', this.config.uniqueItemText)
this.config.uniqueItemText(value) : ? this.config.uniqueItemText(value)
this.config.uniqueItemText; : this.config.uniqueItemText;
} }
} }
@ -804,19 +844,18 @@ class Choices {
const parsedResults = isType('Object', results) ? [results] : results; const parsedResults = isType('Object', results) ? [results] : results;
if (parsedResults && isType('Array', parsedResults) && parsedResults.length) { if (
parsedResults &&
isType('Array', parsedResults) &&
parsedResults.length
) {
// Remove loading states/text // Remove loading states/text
this._handleLoadingState(false); this._handleLoadingState(false);
// Add each result as a choice // Add each result as a choice
parsedResults.forEach((result) => { parsedResults.forEach(result => {
if (result.choices) { if (result.choices) {
const groupId = (result.id || null); const groupId = result.id || null;
this._addGroup( this._addGroup(result, groupId, value, label);
result,
groupId,
value,
label,
);
} else { } else {
this._addChoice( this._addChoice(
result[value], result[value],
@ -842,9 +881,9 @@ class Choices {
_searchChoices(value) { _searchChoices(value) {
const newValue = isType('String', value) ? value.trim() : value; const newValue = isType('String', value) ? value.trim() : value;
const currentValue = isType('String', this._currentValue) ? const currentValue = isType('String', this._currentValue)
this._currentValue.trim() : ? this._currentValue.trim()
this._currentValue; : this._currentValue;
if (newValue.length < 1 && newValue === `${currentValue} `) { if (newValue.length < 1 && newValue === `${currentValue} `) {
return 0; return 0;
@ -853,9 +892,9 @@ class Choices {
// If new value matches the desired length and is not the same as the current value with a space // If new value matches the desired length and is not the same as the current value with a space
const haystack = this._store.searchableChoices; const haystack = this._store.searchableChoices;
const needle = newValue; const needle = newValue;
const keys = isType('Array', this.config.searchFields) ? const keys = isType('Array', this.config.searchFields)
this.config.searchFields : ? this.config.searchFields
[this.config.searchFields]; : [this.config.searchFields];
const options = Object.assign(this.config.fuseOptions, { keys }); const options = Object.assign(this.config.fuseOptions, { keys });
const fuse = new Fuse(haystack, options); const fuse = new Fuse(haystack, options);
const results = fuse.search(needle); const results = fuse.search(needle);
@ -934,7 +973,10 @@ class Choices {
_onKeyDown(event) { _onKeyDown(event) {
const { target, keyCode, ctrlKey, metaKey } = event; const { target, keyCode, ctrlKey, metaKey } = event;
if (target !== this.input.element && !this.containerOuter.element.contains(target)) { if (
target !== this.input.element &&
!this.containerOuter.element.contains(target)
) {
return; return;
} }
@ -952,7 +994,7 @@ class Choices {
const downKey = KEY_CODES.DOWN_KEY; const downKey = KEY_CODES.DOWN_KEY;
const pageUpKey = KEY_CODES.PAGE_UP_KEY; const pageUpKey = KEY_CODES.PAGE_UP_KEY;
const pageDownKey = KEY_CODES.PAGE_DOWN_KEY; const pageDownKey = KEY_CODES.PAGE_DOWN_KEY;
const ctrlDownKey = (ctrlKey || metaKey); const ctrlDownKey = ctrlKey || metaKey;
// If a user is typing and the dropdown is not active // If a user is typing and the dropdown is not active
if (!this._isTextElement && /[a-zA-Z0-9-_ ]/.test(keyString)) { if (!this._isTextElement && /[a-zA-Z0-9-_ ]/.test(keyString)) {
@ -998,7 +1040,9 @@ class Choices {
if (hasActiveDropdown) { if (hasActiveDropdown) {
event.preventDefault(); event.preventDefault();
const highlighted = this.dropdown.getChild(`.${this.config.classNames.highlightedState}`); const highlighted = this.dropdown.getChild(
`.${this.config.classNames.highlightedState}`,
);
// If we have a highlighted choice // If we have a highlighted choice
if (highlighted) { if (highlighted) {
@ -1030,34 +1074,48 @@ class Choices {
this.config.searchEnabled = false; this.config.searchEnabled = false;
const directionInt = keyCode === downKey || keyCode === pageDownKey ? 1 : -1; const directionInt =
const skipKey = metaKey || keyCode === pageDownKey || keyCode === pageUpKey; keyCode === downKey || keyCode === pageDownKey ? 1 : -1;
const skipKey =
metaKey || keyCode === pageDownKey || keyCode === pageUpKey;
const selectableChoiceIdentifier = '[data-choice-selectable]'; const selectableChoiceIdentifier = '[data-choice-selectable]';
let nextEl; let nextEl;
if (skipKey) { if (skipKey) {
if (directionInt > 0) { if (directionInt > 0) {
nextEl = Array.from( nextEl = Array.from(
this.dropdown.element.querySelectorAll(selectableChoiceIdentifier), this.dropdown.element.querySelectorAll(
selectableChoiceIdentifier,
),
).pop(); ).pop();
} else { } else {
nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); nextEl = this.dropdown.element.querySelector(
selectableChoiceIdentifier,
);
} }
} else { } else {
const currentEl = this.dropdown.element.querySelector( const currentEl = this.dropdown.element.querySelector(
`.${this.config.classNames.highlightedState}`, `.${this.config.classNames.highlightedState}`,
); );
if (currentEl) { if (currentEl) {
nextEl = getAdjacentEl(currentEl, selectableChoiceIdentifier, directionInt); nextEl = getAdjacentEl(
currentEl,
selectableChoiceIdentifier,
directionInt,
);
} else { } else {
nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier); nextEl = this.dropdown.element.querySelector(
selectableChoiceIdentifier,
);
} }
} }
if (nextEl) { if (nextEl) {
// We prevent default to stop the cursor moving // We prevent default to stop the cursor moving
// when pressing the arrow // when pressing the arrow
if (!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)) { if (
!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)
) {
this._scrollToChoice(nextEl, directionInt); this._scrollToChoice(nextEl, directionInt);
} }
this._highlightChoice(nextEl); this._highlightChoice(nextEl);
@ -1148,20 +1206,21 @@ class Choices {
} }
_onTouchEnd(event) { _onTouchEnd(event) {
const target = (event.target || event.touches[0].target); const target = event.target || event.touches[0].target;
// If a user tapped within our container... // If a user tapped within our container...
if (this._wasTap === true && this.containerOuter.element.contains(target)) { if (this._wasTap === true && this.containerOuter.element.contains(target)) {
// ...and we aren't dealing with a single select box, show dropdown/focus input // ...and we aren't dealing with a single select box, show dropdown/focus input
if ( if (
(target === this.containerOuter.element || target === this.containerInner.element) && (target === this.containerOuter.element ||
target === this.containerInner.element) &&
!this._isSelectOneElement !this._isSelectOneElement
) { ) {
if (this._isTextElement) { if (this._isTextElement) {
// If text element, we only want to focus the input // If text element, we only want to focus the input
this.input.focus(); this.input.focus();
} else { } else {
// If a select box, we want to show the dropdown // If a select box, we want to show the dropdown
this.showDropdown(true); this.showDropdown(true);
} }
} }
@ -1179,7 +1238,10 @@ class Choices {
this._isScrollingOnIe = true; this._isScrollingOnIe = true;
} }
if (this.containerOuter.element.contains(target) && target !== this.input.element) { if (
this.containerOuter.element.contains(target) &&
target !== this.input.element
) {
const activeItems = this._store.activeItems; const activeItems = this._store.activeItems;
const hasShiftKey = shiftKey; const hasShiftKey = shiftKey;
@ -1200,10 +1262,10 @@ class Choices {
} }
_onMouseOver({ target }) { _onMouseOver({ target }) {
const targetWithinDropdown = ( const targetWithinDropdown =
target === this.dropdown || this.dropdown.element.contains(target) target === this.dropdown || this.dropdown.element.contains(target);
); const shouldHighlightChoice =
const shouldHighlightChoice = targetWithinDropdown && target.hasAttribute('data-choice'); targetWithinDropdown && target.hasAttribute('data-choice');
if (shouldHighlightChoice) { if (shouldHighlightChoice) {
this._highlightChoice(target); this._highlightChoice(target);
@ -1279,7 +1341,10 @@ class Choices {
_onBlur({ target }) { _onBlur({ target }) {
// If target is something that concerns us // If target is something that concerns us
if (this.containerOuter.element.contains(target) && !this._isScrollingOnIe) { if (
this.containerOuter.element.contains(target) &&
!this._isScrollingOnIe
) {
const activeItems = this._store.activeItems; const activeItems = this._store.activeItems;
const hasHighlightedItems = activeItems.some(item => item.highlighted); const hasHighlightedItems = activeItems.some(item => item.highlighted);
const blurActions = { const blurActions = {
@ -1296,8 +1361,11 @@ class Choices {
}, },
'select-one': () => { 'select-one': () => {
this.containerOuter.removeFocusState(); this.containerOuter.removeFocusState();
if (target === this.input.element || if (
(target === this.containerOuter.element && !this.config.searchEnabled)) { target === this.input.element ||
(target === this.containerOuter.element &&
!this.config.searchEnabled)
) {
this.hideDropdown(); this.hideDropdown();
} }
}, },
@ -1334,11 +1402,13 @@ class Choices {
// Distance from bottom of element to top of parent // Distance from bottom of element to top of parent
const choicePos = choice.offsetTop + choiceHeight; const choicePos = choice.offsetTop + choiceHeight;
// Scroll position of dropdown // Scroll position of dropdown
const containerScrollPos = this.choiceList.element.scrollTop + dropdownHeight; const containerScrollPos =
this.choiceList.element.scrollTop + dropdownHeight;
// Difference between the choice and scroll position // Difference between the choice and scroll position
const endPoint = direction > 0 ? ( const endPoint =
(this.choiceList.element.scrollTop + choicePos) - containerScrollPos direction > 0
) : choice.offsetTop; ? this.choiceList.element.scrollTop + choicePos - containerScrollPos
: choice.offsetTop;
const scrollDown = (scrollPos, strength) => { const scrollDown = (scrollPos, strength) => {
const easing = (endPoint - scrollPos) / strength; const easing = (endPoint - scrollPos) / strength;
@ -1374,19 +1444,21 @@ class Choices {
} }
if (continueAnimation) { if (continueAnimation) {
requestAnimationFrame((time) => { requestAnimationFrame(time => {
animateScroll(time, endPoint, direction); animateScroll(time, endPoint, direction);
}); });
} }
}; };
requestAnimationFrame((time) => { requestAnimationFrame(time => {
animateScroll(time, endPoint, direction); animateScroll(time, endPoint, direction);
}); });
} }
_highlightChoice(el = null) { _highlightChoice(el = null) {
const choices = Array.from(this.dropdown.element.querySelectorAll('[data-choice-selectable]')); const choices = Array.from(
this.dropdown.element.querySelectorAll('[data-choice-selectable]'),
);
if (!choices.length) { if (!choices.length) {
return; return;
@ -1394,12 +1466,14 @@ class Choices {
let passedEl = el; let passedEl = el;
const highlightedChoices = Array.from( const highlightedChoices = Array.from(
this.dropdown.element.querySelectorAll(`.${this.config.classNames.highlightedState}`), this.dropdown.element.querySelectorAll(
`.${this.config.classNames.highlightedState}`,
),
); );
const hasActiveDropdown = this.dropdown.isActive; const hasActiveDropdown = this.dropdown.isActive;
// Remove any highlighted choices // Remove any highlighted choices
highlightedChoices.forEach((choice) => { highlightedChoices.forEach(choice => {
choice.classList.remove(this.config.classNames.highlightedState); choice.classList.remove(this.config.classNames.highlightedState);
choice.setAttribute('aria-selected', 'false'); choice.setAttribute('aria-selected', 'false');
}); });
@ -1547,7 +1621,9 @@ class Choices {
const choices = this._store.choices; const choices = this._store.choices;
const choiceLabel = label || value; const choiceLabel = label || value;
const choiceId = choices ? choices.length + 1 : 1; const choiceId = choices ? choices.length + 1 : 1;
const choiceElementId = `${this._baseId}-${this._idNames.itemChoice}-${choiceId}`; const choiceElementId = `${this._baseId}-${
this._idNames.itemChoice
}-${choiceId}`;
this._store.dispatch( this._store.dispatch(
addChoice( addChoice(
@ -1581,27 +1657,21 @@ class Choices {
} }
_addGroup(group, id, valueKey = 'value', labelKey = 'label') { _addGroup(group, id, valueKey = 'value', labelKey = 'label') {
const groupChoices = isType('Object', group) ? const groupChoices = isType('Object', group)
group.choices : ? group.choices
Array.from(group.getElementsByTagName('OPTION')); : Array.from(group.getElementsByTagName('OPTION'));
const groupId = id || Math.floor(new Date().valueOf() * Math.random()); const groupId = id || Math.floor(new Date().valueOf() * Math.random());
const isDisabled = group.disabled ? group.disabled : false; const isDisabled = group.disabled ? group.disabled : false;
if (groupChoices) { if (groupChoices) {
this._store.dispatch( this._store.dispatch(addGroup(group.label, groupId, true, isDisabled));
addGroup(
group.label,
groupId,
true,
isDisabled,
),
);
const addGroupChoices = (choice) => { const addGroupChoices = choice => {
const isOptDisabled = choice.disabled || (choice.parentNode && choice.parentNode.disabled); const isOptDisabled =
choice.disabled || (choice.parentNode && choice.parentNode.disabled);
this._addChoice( this._addChoice(
choice[valueKey], choice[valueKey],
(isType('Object', choice)) ? choice[labelKey] : choice.innerHTML, isType('Object', choice) ? choice[labelKey] : choice.innerHTML,
choice.selected, choice.selected,
isOptDisabled, isOptDisabled,
groupId, groupId,
@ -1613,12 +1683,7 @@ class Choices {
groupChoices.forEach(addGroupChoices); groupChoices.forEach(addGroupChoices);
} else { } else {
this._store.dispatch( this._store.dispatch(
addGroup( addGroup(group.label, group.id, false, group.disabled),
group.label,
group.id,
false,
group.disabled,
),
); );
} }
} }
@ -1636,7 +1701,10 @@ class Choices {
const { callbackOnCreateTemplates } = this.config; const { callbackOnCreateTemplates } = this.config;
let userTemplates = {}; let userTemplates = {};
if (callbackOnCreateTemplates && isType('Function', callbackOnCreateTemplates)) { if (
callbackOnCreateTemplates &&
isType('Function', callbackOnCreateTemplates)
) {
userTemplates = callbackOnCreateTemplates.call(this, strToEl); userTemplates = callbackOnCreateTemplates.call(this, strToEl);
} }
@ -1645,7 +1713,8 @@ class Choices {
_createElements() { _createElements() {
const direction = this.passedElement.element.getAttribute('dir') || 'ltr'; const direction = this.passedElement.element.getAttribute('dir') || 'ltr';
const containerOuter = this._getTemplate('containerOuter', const containerOuter = this._getTemplate(
'containerOuter',
direction, direction,
this._isSelectElement, this._isSelectElement,
this._isSelectOneElement, this._isSelectOneElement,
@ -1654,7 +1723,10 @@ class Choices {
); );
const containerInner = this._getTemplate('containerInner'); const containerInner = this._getTemplate('containerInner');
const itemList = this._getTemplate('itemList', this._isSelectOneElement); const itemList = this._getTemplate('itemList', this._isSelectOneElement);
const choiceList = this._getTemplate('choiceList', this._isSelectOneElement); const choiceList = this._getTemplate(
'choiceList',
this._isSelectOneElement,
);
const input = this._getTemplate('input'); const input = this._getTemplate('input');
const dropdown = this._getTemplate('dropdown'); const dropdown = this._getTemplate('dropdown');
@ -1702,7 +1774,7 @@ class Choices {
this.containerOuter.wrap(this.containerInner.element); this.containerOuter.wrap(this.containerInner.element);
if (this._isSelectOneElement) { if (this._isSelectOneElement) {
this.input.placeholder = (this.config.searchPlaceholderValue || ''); this.input.placeholder = this.config.searchPlaceholderValue || '';
} else if (this._placeholderValue) { } else if (this._placeholderValue) {
this.input.placeholder = this._placeholderValue; this.input.placeholder = this._placeholderValue;
this.input.setWidth(true); this.input.setWidth(true);
@ -1723,7 +1795,10 @@ class Choices {
if (!this._isSelectOneElement) { if (!this._isSelectOneElement) {
this.containerInner.element.appendChild(this.input.element); this.containerInner.element.appendChild(this.input.element);
} else if (this.config.searchEnabled) { } else if (this.config.searchEnabled) {
this.dropdown.element.insertBefore(this.input.element, this.dropdown.element.firstChild); this.dropdown.element.insertBefore(
this.input.element,
this.dropdown.element.firstChild,
);
} }
if (this._isSelectElement) { if (this._isSelectElement) {
@ -1742,7 +1817,10 @@ class Choices {
if (passedGroups && passedGroups.length) { if (passedGroups && passedGroups.length) {
// If we have a placeholder option // If we have a placeholder option
const placeholderChoice = this.passedElement.placeholderOption; const placeholderChoice = this.passedElement.placeholderOption;
if (placeholderChoice && placeholderChoice.parentNode.tagName === 'SELECT') { if (
placeholderChoice &&
placeholderChoice.parentNode.tagName === 'SELECT'
) {
this._addChoice( this._addChoice(
placeholderChoice.value, placeholderChoice.value,
placeholderChoice.innerHTML, placeholderChoice.innerHTML,
@ -1750,12 +1828,12 @@ class Choices {
placeholderChoice.disabled, placeholderChoice.disabled,
undefined, undefined,
undefined, undefined,
/* placeholder */ true, /* placeholder */ true,
); );
} }
passedGroups.forEach((group) => { passedGroups.forEach(group => {
this._addGroup(group, (group.id || null)); this._addGroup(group, group.id || null);
}); });
} else { } else {
const passedOptions = this.passedElement.options; const passedOptions = this.passedElement.options;
@ -1763,7 +1841,7 @@ class Choices {
const allChoices = this._presetChoices; const allChoices = this._presetChoices;
// Create array of options from option elements // Create array of options from option elements
passedOptions.forEach((o) => { passedOptions.forEach(o => {
allChoices.push({ allChoices.push({
value: o.value, value: o.value,
label: o.innerHTML, label: o.innerHTML,
@ -1789,7 +1867,8 @@ class Choices {
// If there is a selected choice already or the choice is not // If there is a selected choice already or the choice is not
// the first in the array, add each choice normally // the first in the array, add each choice normally
// Otherwise pre-select the first choice in the array if it's a single select // Otherwise pre-select the first choice in the array if it's a single select
const shouldPreselect = this._isSelectOneElement && !hasSelectedChoice && index === 0; const shouldPreselect =
this._isSelectOneElement && !hasSelectedChoice && index === 0;
const isSelected = shouldPreselect ? true : choice.selected; const isSelected = shouldPreselect ? true : choice.selected;
const isDisabled = shouldPreselect ? false : choice.disabled; const isDisabled = shouldPreselect ? false : choice.disabled;
@ -1822,7 +1901,7 @@ class Choices {
} }
_addPredefinedItems() { _addPredefinedItems() {
const handlePresetItem = (item) => { const handlePresetItem = item => {
const itemType = getType(item); const itemType = getType(item);
if (itemType === 'Object') { if (itemType === 'Object') {
if (!item.value) { if (!item.value) {
@ -1859,7 +1938,8 @@ class Choices {
item.value, item.value,
item.label, item.label,
true, true,
false, -1, false,
-1,
item.customProperties, item.customProperties,
item.placeholder, item.placeholder,
); );
@ -1876,13 +1956,7 @@ class Choices {
}, },
string: () => { string: () => {
if (!this._isTextElement) { if (!this._isTextElement) {
this._addChoice( this._addChoice(item, item, true, false, -1, null);
item,
item,
true,
false, -1,
null,
);
} else { } else {
this._addItem(item); this._addItem(item);
} }
@ -1895,7 +1969,9 @@ class Choices {
_findAndSelectChoiceByValue(val) { _findAndSelectChoiceByValue(val) {
const choices = this._store.choices; const choices = this._store.choices;
// Check 'value' property exists and the choice isn't already selected // Check 'value' property exists and the choice isn't already selected
const foundChoice = choices.find(choice => this.config.itemComparer(choice.value, val)); const foundChoice = choices.find(choice =>
this.config.itemComparer(choice.value, val),
);
if (foundChoice && !foundChoice.selected) { if (foundChoice && !foundChoice.selected) {
this._addItem( this._addItem(
@ -1911,10 +1987,13 @@ class Choices {
} }
_generateInstances(elements, config) { _generateInstances(elements, config) {
return elements.reduce((instances, element) => { return elements.reduce(
instances.push(new Choices(element, config)); (instances, element) => {
return instances; instances.push(new Choices(element, config));
}, [this]); return instances;
},
[this],
);
} }
static _generateConfig(userConfig) { static _generateConfig(userConfig) {
@ -1934,9 +2013,10 @@ class Choices {
return false; return false;
} }
return this.config.placeholder ? return this.config.placeholder
(this.config.placeholderValue || this.passedElement.element.getAttribute('placeholder')) : ? this.config.placeholderValue ||
false; this.passedElement.element.getAttribute('placeholder')
: false;
} }
_renderChoices() { _renderChoices() {
@ -1955,22 +2035,32 @@ class Choices {
if (activeGroups.length >= 1 && !this._isSearching) { if (activeGroups.length >= 1 && !this._isSearching) {
// If we have a placeholder choice along with groups // If we have a placeholder choice along with groups
const activePlaceholders = activeChoices.filter( const activePlaceholders = activeChoices.filter(
activeChoice => activeChoice.placeholder === true && activeChoice.groupId === -1, activeChoice =>
); activeChoice.placeholder === true && activeChoice.groupId === -1,
);
if (activePlaceholders.length >= 1) { if (activePlaceholders.length >= 1) {
choiceListFragment = this._createChoicesFragment(activePlaceholders, choiceListFragment); choiceListFragment = this._createChoicesFragment(
activePlaceholders,
choiceListFragment,
);
} }
choiceListFragment = this._createGroupsFragment( choiceListFragment = this._createGroupsFragment(
activeGroups, activeGroups,
activeChoices, activeChoices,
choiceListFragment, choiceListFragment,
); );
} else if (activeChoices.length >= 1) { } else if (activeChoices.length >= 1) {
choiceListFragment = this._createChoicesFragment(activeChoices, choiceListFragment); choiceListFragment = this._createChoicesFragment(
activeChoices,
choiceListFragment,
);
} }
// If we have choices to show // If we have choices to show
if (choiceListFragment.childNodes && choiceListFragment.childNodes.length > 0) { if (
choiceListFragment.childNodes &&
choiceListFragment.childNodes.length > 0
) {
const activeItems = this._store.activeItems; const activeItems = this._store.activeItems;
const canAddItem = this._canAddItem(activeItems, this.input.value); const canAddItem = this._canAddItem(activeItems, this.input.value);
@ -1989,15 +2079,15 @@ class Choices {
let notice; let notice;
if (this._isSearching) { if (this._isSearching) {
notice = isType('Function', this.config.noResultsText) ? notice = isType('Function', this.config.noResultsText)
this.config.noResultsText() : ? this.config.noResultsText()
this.config.noResultsText; : this.config.noResultsText;
dropdownItem = this._getTemplate('notice', notice, 'no-results'); dropdownItem = this._getTemplate('notice', notice, 'no-results');
} else { } else {
notice = isType('Function', this.config.noChoicesText) ? notice = isType('Function', this.config.noChoicesText)
this.config.noChoicesText() : ? this.config.noChoicesText()
this.config.noChoicesText; : this.config.noChoicesText;
dropdownItem = this._getTemplate('notice', notice, 'no-choices'); dropdownItem = this._getTemplate('notice', notice, 'no-choices');
} }

View file

@ -45,7 +45,7 @@ describe('choices', () => {
instance.init(); instance.init();
}); });
it('doesn\'t set initialise flag', () => { it("doesn't set initialise flag", () => {
expect(instance.initialised).to.not.equal(false); expect(instance.initialised).to.not.equal(false);
}); });
}); });
@ -123,7 +123,7 @@ describe('choices', () => {
instance.destroy(); instance.destroy();
}); });
it('doesn\'t set initialise flag', () => { it("doesn't set initialise flag", () => {
expect(instance.initialised).to.not.equal(true); expect(instance.initialised).to.not.equal(true);
}); });
}); });
@ -161,7 +161,9 @@ describe('choices', () => {
it('reverts outer container', () => { it('reverts outer container', () => {
expect(containerOuterUnwrapSpy.called).to.equal(true); expect(containerOuterUnwrapSpy.called).to.equal(true);
expect(containerOuterUnwrapSpy.lastCall.args[0]).to.equal(instance.passedElement.element); expect(containerOuterUnwrapSpy.lastCall.args[0]).to.equal(
instance.passedElement.element,
);
}); });
it('clears store', () => { it('clears store', () => {
@ -263,7 +265,6 @@ describe('choices', () => {
inputDisableSpy = spy(instance.input, 'disable'); inputDisableSpy = spy(instance.input, 'disable');
}); });
afterEach(() => { afterEach(() => {
removeEventListenersSpy.restore(); removeEventListenersSpy.restore();
passedElementDisableSpy.restore(); passedElementDisableSpy.restore();
@ -374,24 +375,26 @@ describe('choices', () => {
expect(output).to.eql(instance); expect(output).to.eql(instance);
}); });
it('opens containerOuter', (done) => { it('opens containerOuter', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(containerOuterOpenSpy.called).to.equal(true); expect(containerOuterOpenSpy.called).to.equal(true);
done(); done();
}); });
}); });
it('shows dropdown with blurInput flag', (done) => { it('shows dropdown with blurInput flag', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(dropdownShowSpy.called).to.equal(true); expect(dropdownShowSpy.called).to.equal(true);
done(); done();
}); });
}); });
it('triggers event on passedElement', (done) => { it('triggers event on passedElement', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(passedElementTriggerEventStub.called).to.equal(true); expect(passedElementTriggerEventStub.called).to.equal(true);
expect(passedElementTriggerEventStub.lastCall.args[0]).to.eql(EVENTS.showDropdown); expect(passedElementTriggerEventStub.lastCall.args[0]).to.eql(
EVENTS.showDropdown,
);
expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({}); expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({});
done(); done();
}); });
@ -404,7 +407,7 @@ describe('choices', () => {
output = instance.showDropdown(true); output = instance.showDropdown(true);
}); });
it('focuses input', (done) => { it('focuses input', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(inputFocusSpy.called).to.equal(true); expect(inputFocusSpy.called).to.equal(true);
done(); done();
@ -425,7 +428,10 @@ describe('choices', () => {
containerOuterCloseSpy = spy(instance.containerOuter, 'close'); containerOuterCloseSpy = spy(instance.containerOuter, 'close');
dropdownHideSpy = spy(instance.dropdown, 'hide'); dropdownHideSpy = spy(instance.dropdown, 'hide');
inputBlurSpy = spy(instance.input, 'blur'); inputBlurSpy = spy(instance.input, 'blur');
inputRemoveActiveDescendantSpy = spy(instance.input, 'removeActiveDescendant'); inputRemoveActiveDescendantSpy = spy(
instance.input,
'removeActiveDescendant',
);
passedElementTriggerEventStub = stub(); passedElementTriggerEventStub = stub();
instance.passedElement.triggerEvent = passedElementTriggerEventStub; instance.passedElement.triggerEvent = passedElementTriggerEventStub;
@ -465,24 +471,26 @@ describe('choices', () => {
expect(output).to.eql(instance); expect(output).to.eql(instance);
}); });
it('closes containerOuter', (done) => { it('closes containerOuter', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(containerOuterCloseSpy.called).to.equal(true); expect(containerOuterCloseSpy.called).to.equal(true);
done(); done();
}); });
}); });
it('hides dropdown with blurInput flag', (done) => { it('hides dropdown with blurInput flag', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(dropdownHideSpy.called).to.equal(true); expect(dropdownHideSpy.called).to.equal(true);
done(); done();
}); });
}); });
it('triggers event on passedElement', (done) => { it('triggers event on passedElement', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(passedElementTriggerEventStub.called).to.equal(true); expect(passedElementTriggerEventStub.called).to.equal(true);
expect(passedElementTriggerEventStub.lastCall.args[0]).to.eql(EVENTS.hideDropdown); expect(passedElementTriggerEventStub.lastCall.args[0]).to.eql(
EVENTS.hideDropdown,
);
expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({}); expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({});
done(); done();
}); });
@ -495,14 +503,14 @@ describe('choices', () => {
output = instance.hideDropdown(true); output = instance.hideDropdown(true);
}); });
it('removes active descendants', (done) => { it('removes active descendants', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(inputRemoveActiveDescendantSpy.called).to.equal(true); expect(inputRemoveActiveDescendantSpy.called).to.equal(true);
done(); done();
}); });
}); });
it('blurs input', (done) => { it('blurs input', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(inputBlurSpy.called).to.equal(true); expect(inputBlurSpy.called).to.equal(true);
done(); done();
@ -624,7 +632,9 @@ describe('choices', () => {
it('triggers event with null groupValue', () => { it('triggers event with null groupValue', () => {
expect(passedElementTriggerEventStub.called).to.equal(true); expect(passedElementTriggerEventStub.called).to.equal(true);
expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(EVENTS.highlightItem); expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(
EVENTS.highlightItem,
);
expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({
id: item.id, id: item.id,
value: item.value, value: item.value,
@ -642,7 +652,9 @@ describe('choices', () => {
it('triggers event with groupValue', () => { it('triggers event with groupValue', () => {
expect(passedElementTriggerEventStub.called).to.equal(true); expect(passedElementTriggerEventStub.called).to.equal(true);
expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(EVENTS.highlightItem); expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(
EVENTS.highlightItem,
);
expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({
id: item.id, id: item.id,
value: item.value, value: item.value,
@ -658,7 +670,7 @@ describe('choices', () => {
output = instance.highlightItem(item, false); output = instance.highlightItem(item, false);
}); });
it('doesn\'t trigger event', () => { it("doesn't trigger event", () => {
expect(passedElementTriggerEventStub.called).to.equal(false); expect(passedElementTriggerEventStub.called).to.equal(false);
}); });
@ -735,7 +747,9 @@ describe('choices', () => {
it('triggers event with null groupValue', () => { it('triggers event with null groupValue', () => {
expect(passedElementTriggerEventStub.called).to.equal(true); expect(passedElementTriggerEventStub.called).to.equal(true);
expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(EVENTS.highlightItem); expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(
EVENTS.highlightItem,
);
expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({
id: item.id, id: item.id,
value: item.value, value: item.value,
@ -753,7 +767,9 @@ describe('choices', () => {
it('triggers event with groupValue', () => { it('triggers event with groupValue', () => {
expect(passedElementTriggerEventStub.called).to.equal(true); expect(passedElementTriggerEventStub.called).to.equal(true);
expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(EVENTS.highlightItem); expect(passedElementTriggerEventStub.lastCall.args[0]).to.equal(
EVENTS.highlightItem,
);
expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({ expect(passedElementTriggerEventStub.lastCall.args[1]).to.eql({
id: item.id, id: item.id,
value: item.value, value: item.value,
@ -769,7 +785,7 @@ describe('choices', () => {
output = instance.highlightItem(item, false); output = instance.highlightItem(item, false);
}); });
it('doesn\'t trigger event', () => { it("doesn't trigger event", () => {
expect(passedElementTriggerEventStub.called).to.equal(false); expect(passedElementTriggerEventStub.called).to.equal(false);
}); });
@ -1005,7 +1021,7 @@ describe('choices', () => {
returnsInstance(output); returnsInstance(output);
it('sets loading state', (done) => { it('sets loading state', done => {
requestAnimationFrame(() => { requestAnimationFrame(() => {
expect(handleLoadingStateStub.called).to.equal(true); expect(handleLoadingStateStub.called).to.equal(true);
done(); done();
@ -1108,15 +1124,14 @@ describe('choices', () => {
it('sets each choice with same value', () => { it('sets each choice with same value', () => {
expect(findAndSelectChoiceByValueStub.called).to.equal(true); expect(findAndSelectChoiceByValueStub.called).to.equal(true);
expect(findAndSelectChoiceByValueStub.firstCall.args[0]).to.equal(value); expect(findAndSelectChoiceByValueStub.firstCall.args[0]).to.equal(
value,
);
}); });
}); });
describe('passing an array of values', () => { describe('passing an array of values', () => {
const values = [ const values = ['Value 1', 'Value 2'];
'Value 1',
'Value 2',
];
beforeEach(() => { beforeEach(() => {
output = instance.setChoiceByValue(values); output = instance.setChoiceByValue(values);
@ -1126,8 +1141,12 @@ describe('choices', () => {
it('sets each choice with same value', () => { it('sets each choice with same value', () => {
expect(findAndSelectChoiceByValueStub.callCount).to.equal(2); expect(findAndSelectChoiceByValueStub.callCount).to.equal(2);
expect(findAndSelectChoiceByValueStub.firstCall.args[0]).to.equal(values[0]); expect(findAndSelectChoiceByValueStub.firstCall.args[0]).to.equal(
expect(findAndSelectChoiceByValueStub.secondCall.args[0]).to.equal(values[1]); values[0],
);
expect(findAndSelectChoiceByValueStub.secondCall.args[0]).to.equal(
values[1],
);
}); });
}); });
}); });
@ -1173,7 +1192,7 @@ describe('choices', () => {
}); });
it('returns all active item values', () => { it('returns all active item values', () => {
expect(output).to.eql(items.map((item => item.value))); expect(output).to.eql(items.map(item => item.value));
}); });
}); });
}); });
@ -1315,9 +1334,11 @@ describe('choices', () => {
}, },
]; ];
beforeEach(() => { beforeEach(() => {
highlightedActiveItemsStub = stub(instance._store, 'highlightedActiveItems').get(() => items); highlightedActiveItemsStub = stub(
instance._store,
'highlightedActiveItems',
).get(() => items);
removeItemStub = stub(); removeItemStub = stub();
triggerChangeStub = stub(); triggerChangeStub = stub();
@ -1557,7 +1578,9 @@ describe('choices', () => {
expect(output).to.be.instanceOf(DocumentFragment); expect(output).to.be.instanceOf(DocumentFragment);
expect(elementToWrapFragment.children[0]).to.eql(childElement); expect(elementToWrapFragment.children[0]).to.eql(childElement);
expect(elementToWrapFragment.querySelectorAll('[data-group]').length).to.equal(2); expect(
elementToWrapFragment.querySelectorAll('[data-group]').length,
).to.equal(2);
}); });
}); });
@ -1568,7 +1591,9 @@ describe('choices', () => {
elementToWrapFragment.appendChild(output); elementToWrapFragment.appendChild(output);
expect(output).to.be.instanceOf(DocumentFragment); expect(output).to.be.instanceOf(DocumentFragment);
expect(elementToWrapFragment.querySelectorAll('[data-group]').length).to.equal(2); expect(
elementToWrapFragment.querySelectorAll('[data-group]').length,
).to.equal(2);
}); });
}); });

View file

@ -16,7 +16,7 @@ export default class Container {
/** /**
* Add event listeners * Add event listeners
*/ */
addEventListeners() { addEventListeners() {
this.element.addEventListener('focus', this._onFocus); this.element.addEventListener('focus', this._onFocus);
this.element.addEventListener('blur', this._onBlur); this.element.addEventListener('blur', this._onBlur);
@ -24,7 +24,7 @@ export default class Container {
/** /**
* Remove event listeners * Remove event listeners
*/ */
/** */ /** */
removeEventListeners() { removeEventListeners() {
@ -138,10 +138,7 @@ export default class Container {
unwrap(element) { unwrap(element) {
// Move passed element outside this element // Move passed element outside this element
this.element.parentNode.insertBefore( this.element.parentNode.insertBefore(element, this.element);
element,
this.element,
);
// Remove this element // Remove this element
this.element.parentNode.removeChild(this.element); this.element.parentNode.removeChild(this.element);
} }

View file

@ -139,21 +139,32 @@ describe('components/container', () => {
}); });
describe('setActiveDescendant', () => { describe('setActiveDescendant', () => {
it('sets element\'s aria-activedescendant attribute with passed descendant ID', () => { it("sets element's aria-activedescendant attribute with passed descendant ID", () => {
const activeDescendantID = '1234'; const activeDescendantID = '1234';
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(null); expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
null,
);
instance.setActiveDescendant(activeDescendantID); instance.setActiveDescendant(activeDescendantID);
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID); expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
activeDescendantID,
);
}); });
}); });
describe('removeActiveDescendant', () => { describe('removeActiveDescendant', () => {
it('remove elememnt\'s aria-activedescendant attribute', () => { it("remove elememnt's aria-activedescendant attribute", () => {
const activeDescendantID = '1234'; const activeDescendantID = '1234';
instance.element.setAttribute('aria-activedescendant', activeDescendantID); instance.element.setAttribute(
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID); 'aria-activedescendant',
activeDescendantID,
);
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
activeDescendantID,
);
instance.removeActiveDescendant(); instance.removeActiveDescendant();
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(null); expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
null,
);
}); });
}); });
@ -163,7 +174,9 @@ describe('components/container', () => {
}); });
it('adds open state class', () => { it('adds open state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.openState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.openState),
).to.equal(true);
}); });
it('sets aria-expanded attribute to true', () => { it('sets aria-expanded attribute to true', () => {
@ -188,7 +201,9 @@ describe('components/container', () => {
}); });
it('adds adds flipped state class', () => { it('adds adds flipped state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.flippedState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.flippedState),
).to.equal(true);
}); });
it('sets isFlipped flag to true', () => { it('sets isFlipped flag to true', () => {
@ -203,7 +218,9 @@ describe('components/container', () => {
}); });
it('adds open state class', () => { it('adds open state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.openState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.openState),
).to.equal(false);
}); });
it('sets aria-expanded attribute to true', () => { it('sets aria-expanded attribute to true', () => {
@ -221,7 +238,9 @@ describe('components/container', () => {
}); });
it('removes adds flipped state class', () => { it('removes adds flipped state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.flippedState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.flippedState),
).to.equal(false);
}); });
it('sets isFlipped flag to false', () => { it('sets isFlipped flag to false', () => {
@ -264,9 +283,13 @@ describe('components/container', () => {
}); });
it('adds focus state class', () => { it('adds focus state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState),
).to.equal(false);
instance.addFocusState(); instance.addFocusState();
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState),
).to.equal(true);
}); });
}); });
@ -276,9 +299,13 @@ describe('components/container', () => {
}); });
it('removes focus state class', () => { it('removes focus state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState),
).to.equal(true);
instance.removeFocusState(); instance.removeFocusState();
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState),
).to.equal(false);
}); });
}); });
@ -288,9 +315,13 @@ describe('components/container', () => {
}); });
it('removes disabled state class', () => { it('removes disabled state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState),
).to.equal(true);
instance.enable(); instance.enable();
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState),
).to.equal(false);
}); });
it('removes aria-disabled attribute', () => { it('removes aria-disabled attribute', () => {
@ -322,9 +353,13 @@ describe('components/container', () => {
}); });
it('removes disabled state class', () => { it('removes disabled state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState),
).to.equal(false);
instance.disable(); instance.disable();
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState),
).to.equal(true);
}); });
it('removes aria-disabled attribute', () => { it('removes aria-disabled attribute', () => {
@ -366,7 +401,9 @@ describe('components/container', () => {
it('wraps passed element inside element', () => { it('wraps passed element inside element', () => {
expect(instance.element.querySelector('div#wrap-test')).to.equal(null); expect(instance.element.querySelector('div#wrap-test')).to.equal(null);
instance.wrap(document.querySelector('div#wrap-test')); instance.wrap(document.querySelector('div#wrap-test'));
expect(instance.element.querySelector('div#wrap-test')).to.equal(elementToWrap); expect(instance.element.querySelector('div#wrap-test')).to.equal(
elementToWrap,
);
}); });
}); });
@ -385,10 +422,14 @@ describe('components/container', () => {
}); });
it('moves wrapped element outside of element', () => { it('moves wrapped element outside of element', () => {
expect(instance.element.querySelector('div#unwrap-test')).to.be.instanceof(HTMLElement); expect(
instance.element.querySelector('div#unwrap-test'),
).to.be.instanceof(HTMLElement);
instance.unwrap(elementToUnwrap); instance.unwrap(elementToUnwrap);
expect(instance.element.querySelector('div#unwrap-test')).to.equal(null); expect(instance.element.querySelector('div#unwrap-test')).to.equal(null);
expect(document.querySelector('div#unwrap-test')).to.be.instanceof(HTMLElement); expect(document.querySelector('div#unwrap-test')).to.be.instanceof(
HTMLElement,
);
}); });
it('removes element from DOM', () => { it('removes element from DOM', () => {
@ -404,9 +445,13 @@ describe('components/container', () => {
}); });
it('adds loading state class', () => { it('adds loading state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState),
).to.equal(false);
instance.addLoadingState(); instance.addLoadingState();
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState),
).to.equal(true);
}); });
it('sets aria-busy attribute to true', () => { it('sets aria-busy attribute to true', () => {
@ -428,9 +473,13 @@ describe('components/container', () => {
}); });
it('removes loading state class', () => { it('removes loading state class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState),
).to.equal(true);
instance.removeLoadingState(); instance.removeLoadingState();
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.loadingState),
).to.equal(false);
}); });
it('removes aria-busy attribute', () => { it('removes aria-busy attribute', () => {

View file

@ -12,7 +12,9 @@ export default class Dropdown {
*/ */
distanceFromTopWindow() { distanceFromTopWindow() {
this.dimensions = this.element.getBoundingClientRect(); this.dimensions = this.element.getBoundingClientRect();
this.position = Math.ceil(this.dimensions.top + window.pageYOffset + this.element.offsetHeight); this.position = Math.ceil(
this.dimensions.top + window.pageYOffset + this.element.offsetHeight,
);
return this.position; return this.position;
} }

View file

@ -50,7 +50,9 @@ describe('components/dropdown', () => {
width: 0, width: 0,
}; };
getBoundingClientRectStub = sinon.stub(instance.element, 'getBoundingClientRect').returns(dimensions); getBoundingClientRectStub = sinon
.stub(instance.element, 'getBoundingClientRect')
.returns(dimensions);
window.pageYOffset = 50; window.pageYOffset = 50;
}); });
@ -107,7 +109,9 @@ describe('components/dropdown', () => {
}); });
it('adds active class', () => { it('adds active class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.activeState)).to.equal(true); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.activeState),
).to.equal(true);
}); });
it('sets expanded attribute', () => { it('sets expanded attribute', () => {
@ -135,7 +139,9 @@ describe('components/dropdown', () => {
}); });
it('adds active class', () => { it('adds active class', () => {
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.activeState)).to.equal(false); expect(
instance.element.classList.contains(DEFAULT_CLASSNAMES.activeState),
).to.equal(false);
}); });
it('sets expanded attribute', () => { it('sets expanded attribute', () => {

View file

@ -5,11 +5,4 @@ import List from './list';
import WrappedInput from './wrapped-input'; import WrappedInput from './wrapped-input';
import WrappedSelect from './wrapped-select'; import WrappedSelect from './wrapped-select';
export { export { Dropdown, Container, Input, List, WrappedInput, WrappedSelect };
Dropdown,
Container,
Input,
List,
WrappedInput,
WrappedSelect,
};

View file

@ -92,7 +92,7 @@ export default class Input {
// length than 75% of the placeholder. This stops the input jumping around. // length than 75% of the placeholder. This stops the input jumping around.
if ( if (
(this.element.value && (this.element.value &&
this.element.value.length >= (this._placeholderValue.length / 1.25)) || this.element.value.length >= this._placeholderValue.length / 1.25) ||
enforceWidth enforceWidth
) { ) {
this.element.style.width = this.calcWidth(); this.element.style.width = this.calcWidth();

View file

@ -86,7 +86,6 @@ describe('components/input', () => {
setWidthStub.restore(); setWidthStub.restore();
}); });
describe('when element is select one', () => { describe('when element is select one', () => {
it('does not set input width', () => { it('does not set input width', () => {
instance.type = 'select-one'; instance.type = 'select-one';
@ -207,7 +206,6 @@ describe('components/input', () => {
}); });
}); });
describe('blur', () => { describe('blur', () => {
let blurStub; let blurStub;
@ -220,7 +218,7 @@ describe('components/input', () => {
}); });
describe('when element is not focussed', () => { describe('when element is not focussed', () => {
it('doesn\'t blur element', () => { it("doesn't blur element", () => {
instance.isFocussed = false; instance.isFocussed = false;
instance.blur(); instance.blur();
expect(blurStub.callCount).to.equal(0); expect(blurStub.callCount).to.equal(0);
@ -247,14 +245,14 @@ describe('components/input', () => {
setWidthStub.restore(); setWidthStub.restore();
}); });
it('removes the element\'s value if it has one', () => { it("removes the element's value if it has one", () => {
instance.element.value = 'test'; instance.element.value = 'test';
expect(instance.element.value).to.equal('test'); expect(instance.element.value).to.equal('test');
instance.clear(); instance.clear();
expect(instance.element.value).to.equal(''); expect(instance.element.value).to.equal('');
}); });
it('sets the element\'s width if flag passed', () => { it("sets the element's width if flag passed", () => {
expect(setWidthStub.callCount).to.equal(0); expect(setWidthStub.callCount).to.equal(0);
instance.clear(true); instance.clear(true);
expect(setWidthStub.callCount).to.equal(1); expect(setWidthStub.callCount).to.equal(1);
@ -350,21 +348,32 @@ describe('components/input', () => {
}); });
describe('setActiveDescendant', () => { describe('setActiveDescendant', () => {
it('sets element\'s aria-activedescendant attribute with passed descendant ID', () => { it("sets element's aria-activedescendant attribute with passed descendant ID", () => {
const activeDescendantID = '1234'; const activeDescendantID = '1234';
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(null); expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
null,
);
instance.setActiveDescendant(activeDescendantID); instance.setActiveDescendant(activeDescendantID);
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID); expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
activeDescendantID,
);
}); });
}); });
describe('removeActiveDescendant', () => { describe('removeActiveDescendant', () => {
it('remove elememnt\'s aria-activedescendant attribute', () => { it("remove elememnt's aria-activedescendant attribute", () => {
const activeDescendantID = '1234'; const activeDescendantID = '1234';
instance.element.setAttribute('aria-activedescendant', activeDescendantID); instance.element.setAttribute(
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID); 'aria-activedescendant',
activeDescendantID,
);
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
activeDescendantID,
);
instance.removeActiveDescendant(); instance.removeActiveDescendant();
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(null); expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
null,
);
}); });
}); });
}); });

View file

@ -30,7 +30,7 @@ export default class List {
/** /**
* Find element that matches passed selector * Find element that matches passed selector
* @return {HTMLElement} * @return {HTMLElement}
*/ */
getChild(selector) { getChild(selector) {
return this.element.querySelector(selector); return this.element.querySelector(selector);
} }

View file

@ -24,7 +24,7 @@ describe('components/list', () => {
}); });
describe('clear', () => { describe('clear', () => {
it('clears element\'s inner HTML', () => { it("clears element's inner HTML", () => {
const innerHTML = 'test'; const innerHTML = 'test';
instance.element.innerHTML = innerHTML; instance.element.innerHTML = innerHTML;
expect(instance.element.innerHTML).to.equal(innerHTML); expect(instance.element.innerHTML).to.equal(innerHTML);
@ -59,11 +59,12 @@ describe('components/list', () => {
elementToAppend.classList.add(childClass); elementToAppend.classList.add(childClass);
expect(instance.element.querySelector(`.${childClass}`)).to.equal(null); expect(instance.element.querySelector(`.${childClass}`)).to.equal(null);
instance.append(elementToAppend); instance.append(elementToAppend);
expect(instance.element.querySelector(`.${childClass}`)).to.equal(elementToAppend); expect(instance.element.querySelector(`.${childClass}`)).to.equal(
elementToAppend,
);
}); });
}); });
describe('getChild', () => { describe('getChild', () => {
let childElement; let childElement;
const childClass = 'test-element'; const childClass = 'test-element';

View file

@ -10,7 +10,7 @@ describe('components/wrappedElement', () => {
element = document.createElement('select'); element = document.createElement('select');
instance = new WrappedElement({ instance = new WrappedElement({
element, element,
classNames: DEFAULT_CLASSNAMES, classNames: DEFAULT_CLASSNAMES
}); });
}); });
@ -50,11 +50,17 @@ describe('components/wrappedElement', () => {
it('hides element', () => { it('hides element', () => {
instance.conceal(); instance.conceal();
expect(instance.element.tabIndex).to.equal(-1); expect(instance.element.tabIndex).to.equal(-1);
expect(instance.element.classList.contains(instance.classNames.input)).to.equal(true); expect(
expect(instance.element.classList.contains(instance.classNames.hiddenState)).to.equal(true); instance.element.classList.contains(instance.classNames.input)
).to.equal(true);
expect(
instance.element.classList.contains(instance.classNames.hiddenState)
).to.equal(true);
expect(instance.element.getAttribute('aria-hidden')).to.equal('true'); expect(instance.element.getAttribute('aria-hidden')).to.equal('true');
expect(instance.element.getAttribute('data-choice')).to.equal('active'); expect(instance.element.getAttribute('data-choice')).to.equal('active');
expect(instance.element.getAttribute('data-choice-orig-style')).to.equal(originalStyling); expect(instance.element.getAttribute('data-choice-orig-style')).to.equal(
originalStyling
);
}); });
}); });
@ -69,12 +75,18 @@ describe('components/wrappedElement', () => {
it('shows element', () => { it('shows element', () => {
instance.reveal(); instance.reveal();
expect(instance.element.tabIndex).to.equal(0); expect(instance.element.tabIndex).to.equal(0);
expect(instance.element.classList.contains(instance.classNames.input)).to.equal(false); expect(
expect(instance.element.classList.contains(instance.classNames.hiddenState)).to.equal(false); instance.element.classList.contains(instance.classNames.input)
).to.equal(false);
expect(
instance.element.classList.contains(instance.classNames.hiddenState)
).to.equal(false);
expect(instance.element.getAttribute('style')).to.equal(originalStyling); expect(instance.element.getAttribute('style')).to.equal(originalStyling);
expect(instance.element.getAttribute('aria-hidden')).to.equal(null); expect(instance.element.getAttribute('aria-hidden')).to.equal(null);
expect(instance.element.getAttribute('data-choice')).to.equal(null); expect(instance.element.getAttribute('data-choice')).to.equal(null);
expect(instance.element.getAttribute('data-choice-orig-style')).to.equal(null); expect(instance.element.getAttribute('data-choice-orig-style')).to.equal(
null
);
}); });
}); });
@ -127,9 +139,9 @@ describe('components/wrappedElement', () => {
}); });
describe('triggerEvent', () => { describe('triggerEvent', () => {
it('fires event on element using passed eventType and data', (done) => { it('fires event on element using passed eventType and data', done => {
const data = { const data = {
test: true, test: true
}; };
instance.element.addEventListener('testEvent', ({ detail }) => { instance.element.addEventListener('testEvent', ({ detail }) => {

View file

@ -34,7 +34,7 @@ describe('components/wrappedInput', () => {
}); });
describe('inherited methods', () => { describe('inherited methods', () => {
['conceal', 'reveal', 'enable', 'disable'].forEach((method) => { ['conceal', 'reveal', 'enable', 'disable'].forEach(method => {
describe(method, () => { describe(method, () => {
beforeEach(() => { beforeEach(() => {
stub(WrappedElement.prototype, method); stub(WrappedElement.prototype, method);
@ -72,7 +72,9 @@ describe('components/wrappedInput', () => {
it('sets delimited value of element based on passed data', () => { it('sets delimited value of element based on passed data', () => {
expect(instance.element.value).to.equal(''); expect(instance.element.value).to.equal('');
instance.value = data; instance.value = data;
expect(instance.value).to.equal(`Value 1${delimiter}Value 2${delimiter}Value 3`); expect(instance.value).to.equal(
`Value 1${delimiter}Value 2${delimiter}Value 3`,
);
}); });
}); });
}); });

View file

@ -20,7 +20,7 @@ export default class WrappedSelect extends WrappedElement {
set options(options) { set options(options) {
const fragment = document.createDocumentFragment(); const fragment = document.createDocumentFragment();
const addOptionToFragment = (data) => { const addOptionToFragment = data => {
// Create a standard select option // Create a standard select option
const template = templates.option(data); const template = templates.option(data);
// Append it to fragment // Append it to fragment

View file

@ -47,7 +47,7 @@ describe('components/wrappedSelect', () => {
}); });
describe('inherited methods', () => { describe('inherited methods', () => {
['conceal', 'reveal', 'enable', 'disable'].forEach((method) => { ['conceal', 'reveal', 'enable', 'disable'].forEach(method => {
beforeEach(() => { beforeEach(() => {
stub(WrappedElement.prototype, method); stub(WrappedElement.prototype, method);
}); });
@ -76,7 +76,7 @@ describe('components/wrappedSelect', () => {
it('returns all option elements', () => { it('returns all option elements', () => {
const { options } = instance; const { options } = instance;
expect(options).to.be.an('array'); expect(options).to.be.an('array');
options.forEach((option) => { options.forEach(option => {
expect(option).to.be.instanceOf(HTMLOptionElement); expect(option).to.be.instanceOf(HTMLOptionElement);
}); });
}); });
@ -91,7 +91,7 @@ describe('components/wrappedSelect', () => {
const { optionGroups } = instance; const { optionGroups } = instance;
expect(optionGroups.length).to.equal(3); expect(optionGroups.length).to.equal(3);
optionGroups.forEach((option) => { optionGroups.forEach(option => {
expect(option).to.be.instanceOf(HTMLOptGroupElement); expect(option).to.be.instanceOf(HTMLOptGroupElement);
}); });
}); });
@ -141,9 +141,13 @@ describe('components/wrappedSelect', () => {
describe('appendDocFragment', () => { describe('appendDocFragment', () => {
it('empties contents of element', () => { it('empties contents of element', () => {
expect(instance.element.getElementsByTagName('option').length).to.equal(4); expect(instance.element.getElementsByTagName('option').length).to.equal(
4,
);
instance.appendDocFragment(document.createDocumentFragment()); instance.appendDocFragment(document.createDocumentFragment());
expect(instance.element.getElementsByTagName('option').length).to.equal(0); expect(instance.element.getElementsByTagName('option').length).to.equal(
0,
);
}); });
it('appends passed fragment to element', () => { it('appends passed fragment to element', () => {
@ -153,7 +157,9 @@ describe('components/wrappedSelect', () => {
fragment.appendChild(elementToAppend); fragment.appendChild(elementToAppend);
expect(instance.element.querySelector('#fragment-target')).to.equal(null); expect(instance.element.querySelector('#fragment-target')).to.equal(null);
instance.appendDocFragment(fragment); instance.appendDocFragment(fragment);
expect(instance.element.querySelector('#fragment-target')).to.eql(elementToAppend); expect(instance.element.querySelector('#fragment-target')).to.eql(
elementToAppend,
);
}); });
}); });
}); });

View file

@ -65,7 +65,7 @@ export const DEFAULT_CONFIG = {
uniqueItemText: 'Only unique values can be added.', uniqueItemText: 'Only unique values can be added.',
addItemText: value => `Press Enter to add <b>"${stripHTML(value)}"</b>`, addItemText: value => `Press Enter to add <b>"${stripHTML(value)}"</b>`,
maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`, maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`,
itemComparer: (choice, item) => (choice === item), itemComparer: (choice, item) => choice === item,
fuseOptions: { fuseOptions: {
includeScore: true, includeScore: true,
}, },

View file

@ -140,7 +140,7 @@ describe('constants', () => {
}); });
it('exports each value as a number', () => { it('exports each value as a number', () => {
Object.keys(KEY_CODES).forEach((key) => { Object.keys(KEY_CODES).forEach(key => {
expect(KEY_CODES[key]).to.be.a('number'); expect(KEY_CODES[key]).to.be.a('number');
}); });
}); });

View file

@ -43,11 +43,7 @@ describe('utils', () => {
]; ];
it('returns an array of item values', () => { it('returns an array of item values', () => {
const expectedResponse = [ const expectedResponse = [items[0].value, items[1].value, items[2].value];
items[0].value,
items[1].value,
items[2].value,
];
const actualResponse = reduceToValues(items); const actualResponse = reduceToValues(items);
expect(actualResponse).to.eql(expectedResponse); expect(actualResponse).to.eql(expectedResponse);

View file

@ -8,26 +8,29 @@ export default function choices(state = defaultState, action) {
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 [
id: action.id, ...state,
elementId: action.elementId, {
groupId: action.groupId, id: action.id,
value: action.value, elementId: action.elementId,
label: (action.label || action.value), groupId: action.groupId,
disabled: (action.disabled || false), value: action.value,
selected: false, label: action.label || action.value,
active: true, disabled: action.disabled || false,
score: 9999, selected: false,
customProperties: action.customProperties, active: true,
placeholder: (action.placeholder || false), score: 9999,
keyCode: null, customProperties: action.customProperties,
}]; placeholder: action.placeholder || false,
keyCode: null,
},
];
} }
case 'ADD_ITEM': { case 'ADD_ITEM': {
// If all choices need to be activated // If all choices need to be activated
if (action.activateOptions) { if (action.activateOptions) {
return state.map((obj) => { return state.map(obj => {
const choice = obj; const choice = obj;
choice.active = action.active; choice.active = action.active;
return choice; return choice;
@ -37,7 +40,7 @@ export default function choices(state = defaultState, action) {
// When an item is added and it has an associated choice, // When an item is added and it has an associated choice,
// we want to disable it so it can't be chosen again // we want to disable it so it can't be chosen again
if (action.choiceId > -1) { if (action.choiceId > -1) {
return state.map((obj) => { return state.map(obj => {
const choice = obj; const choice = obj;
if (choice.id === parseInt(action.choiceId, 10)) { if (choice.id === parseInt(action.choiceId, 10)) {
choice.selected = true; choice.selected = true;
@ -53,7 +56,7 @@ export default function choices(state = defaultState, action) {
// When an item is removed and it has an associated choice, // When an item is removed and it has an associated choice,
// we want to re-enable it so it can be chosen again // we want to re-enable it so it can be chosen again
if (action.choiceId > -1) { if (action.choiceId > -1) {
return state.map((obj) => { return state.map(obj => {
const choice = obj; const choice = obj;
if (choice.id === parseInt(action.choiceId, 10)) { if (choice.id === parseInt(action.choiceId, 10)) {
choice.selected = false; choice.selected = false;
@ -66,7 +69,7 @@ export default function choices(state = defaultState, action) {
} }
case 'FILTER_CHOICES': { case 'FILTER_CHOICES': {
return state.map((obj) => { return state.map(obj => {
const choice = obj; const choice = obj;
// Set active state based on whether choice is // Set active state based on whether choice is
// within filtered results // within filtered results
@ -83,7 +86,7 @@ export default function choices(state = defaultState, action) {
} }
case 'ACTIVATE_CHOICES': { case 'ACTIVATE_CHOICES': {
return state.map((obj) => { return state.map(obj => {
const choice = obj; const choice = obj;
choice.active = action.active; choice.active = action.active;
return choice; return choice;

View file

@ -174,15 +174,16 @@ describe('reducers/choices', () => {
score, score,
}; };
const actualResponse = choices(state, { const actualResponse = choices(state, {
type: 'FILTER_CHOICES', type: 'FILTER_CHOICES',
results: [{ results: [
item: { {
id, item: {
id,
},
score,
}, },
score, ],
}],
}).find(choice => choice.id === id); }).find(choice => choice.id === id);
expect(actualResponse).to.eql(expectedResponse); expect(actualResponse).to.eql(expectedResponse);

View file

@ -3,12 +3,15 @@ export const defaultState = [];
export default function groups(state = defaultState, action) { export default function groups(state = defaultState, action) {
switch (action.type) { switch (action.type) {
case 'ADD_GROUP': { case 'ADD_GROUP': {
return [...state, { return [
id: action.id, ...state,
value: action.value, {
active: action.active, id: action.id,
disabled: action.disabled, value: action.value,
}]; active: action.active,
disabled: action.disabled,
},
];
} }
case 'CLEAR_CHOICES': { case 'CLEAR_CHOICES': {

View file

@ -4,20 +4,23 @@ export default function items(state = defaultState, 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 = [
id: action.id, ...state,
choiceId: action.choiceId, {
groupId: action.groupId, id: action.id,
value: action.value, choiceId: action.choiceId,
label: action.label, groupId: action.groupId,
active: true, value: action.value,
highlighted: false, label: action.label,
customProperties: action.customProperties, active: true,
placeholder: (action.placeholder || false), highlighted: false,
keyCode: null, customProperties: action.customProperties,
}]; placeholder: action.placeholder || false,
keyCode: null,
},
];
return newState.map((obj) => { return newState.map(obj => {
const item = obj; const item = obj;
item.highlighted = false; item.highlighted = false;
return item; return item;
@ -26,7 +29,7 @@ export default function items(state = defaultState, action) {
case 'REMOVE_ITEM': { case 'REMOVE_ITEM': {
// Set item to inactive // Set item to inactive
return state.map((obj) => { return state.map(obj => {
const item = obj; const item = obj;
if (item.id === action.id) { if (item.id === action.id) {
item.active = false; item.active = false;
@ -36,7 +39,7 @@ export default function items(state = defaultState, action) {
} }
case 'HIGHLIGHT_ITEM': { case 'HIGHLIGHT_ITEM': {
return state.map((obj) => { return state.map(obj => {
const item = obj; const item = obj;
if (item.id === action.id) { if (item.id === action.id) {
item.highlighted = action.highlighted; item.highlighted = action.highlighted;

View file

@ -56,7 +56,7 @@ describe('reducers/items', () => {
}); });
it('unhighlights all highlighted items', () => { it('unhighlights all highlighted items', () => {
actualResponse.forEach((item) => { actualResponse.forEach(item => {
expect(item.highlighted).to.equal(false); expect(item.highlighted).to.equal(false);
}); });
}); });

View file

@ -5,9 +5,7 @@ export default class Store {
constructor() { constructor() {
this._store = createStore( this._store = createStore(
rootReducer, rootReducer,
window.devToolsExtension ? window.devToolsExtension ? window.devToolsExtension() : undefined,
window.devToolsExtension() :
undefined,
); );
} }
@ -54,9 +52,9 @@ export default class Store {
} }
/** /**
* Get highlighted items from store * Get highlighted items from store
* @return {Array} Item objects * @return {Array} Item objects
*/ */
get highlightedActiveItems() { get highlightedActiveItems() {
return this.items.filter(item => item.active && item.highlighted); return this.items.filter(item => item.active && item.highlighted);
} }
@ -122,10 +120,10 @@ export default class Store {
const groups = this.groups; const groups = this.groups;
const choices = this.choices; const choices = this.choices;
return groups.filter((group) => { return groups.filter(group => {
const isActive = group.active === true && group.disabled === false; const isActive = group.active === true && group.disabled === false;
const hasActiveOptions = choices.some(choice => const hasActiveOptions = choices.some(
choice.active === true && choice.disabled === false, choice => choice.active === true && choice.disabled === false,
); );
return isActive && hasActiveOptions; return isActive && hasActiveOptions;
}, []); }, []);
@ -138,7 +136,9 @@ export default class Store {
getChoiceById(id) { getChoiceById(id) {
if (id) { if (id) {
const choices = this.activeChoices; const choices = this.activeChoices;
const foundChoice = choices.find(choice => choice.id === parseInt(id, 10)); const foundChoice = choices.find(
choice => choice.id === parseInt(id, 10),
);
return foundChoice; return foundChoice;
} }
return false; return false;

View file

@ -21,7 +21,6 @@ describe('reducers/store', () => {
getStateStub.restore(); getStateStub.restore();
}); });
describe('constructor', () => { describe('constructor', () => {
it('creates redux store', () => { it('creates redux store', () => {
expect(instance._store).to.contain.keys([ expect(instance._store).to.contain.keys([
@ -32,7 +31,6 @@ describe('reducers/store', () => {
}); });
}); });
describe('subscribe', () => { describe('subscribe', () => {
it('wraps redux subscribe method', () => { it('wraps redux subscribe method', () => {
const onChange = () => {}; const onChange = () => {};
@ -163,14 +161,16 @@ describe('reducers/store', () => {
describe('activeItems getter', () => { describe('activeItems getter', () => {
it('returns items that are active', () => { it('returns items that are active', () => {
const expectedResponse = state.items.filter((item => item.active)); const expectedResponse = state.items.filter(item => item.active);
expect(instance.activeItems).to.eql(expectedResponse); expect(instance.activeItems).to.eql(expectedResponse);
}); });
}); });
describe('highlightedActiveItems getter', () => { describe('highlightedActiveItems getter', () => {
it('returns items that are active and highlighted', () => { it('returns items that are active and highlighted', () => {
const expectedResponse = state.items.filter((item => item.highlighted && item.active)); const expectedResponse = state.items.filter(
item => item.highlighted && item.active,
);
expect(instance.highlightedActiveItems).to.eql(expectedResponse); expect(instance.highlightedActiveItems).to.eql(expectedResponse);
}); });
}); });
@ -184,21 +184,25 @@ describe('reducers/store', () => {
describe('activeChoices getter', () => { describe('activeChoices getter', () => {
it('returns choices that are active', () => { it('returns choices that are active', () => {
const expectedResponse = state.choices.filter((choice => choice.active)); const expectedResponse = state.choices.filter(choice => choice.active);
expect(instance.activeChoices).to.eql(expectedResponse); expect(instance.activeChoices).to.eql(expectedResponse);
}); });
}); });
describe('selectableChoices getter', () => { describe('selectableChoices getter', () => {
it('returns choices that are not disabled', () => { it('returns choices that are not disabled', () => {
const expectedResponse = state.choices.filter((choice => !choice.disabled)); const expectedResponse = state.choices.filter(
choice => !choice.disabled,
);
expect(instance.selectableChoices).to.eql(expectedResponse); expect(instance.selectableChoices).to.eql(expectedResponse);
}); });
}); });
describe('searchableChoices getter', () => { describe('searchableChoices getter', () => {
it('returns choices that are not placeholders and are selectable', () => { it('returns choices that are not placeholders and are selectable', () => {
const expectedResponse = state.choices.filter((choice => !choice.disabled && !choice.placeholder)); const expectedResponse = state.choices.filter(
choice => !choice.disabled && !choice.placeholder,
);
expect(instance.searchableChoices).to.eql(expectedResponse); expect(instance.searchableChoices).to.eql(expectedResponse);
}); });
}); });
@ -207,7 +211,9 @@ describe('reducers/store', () => {
describe('passing id', () => { describe('passing id', () => {
it('returns active choice by passed id', () => { it('returns active choice by passed id', () => {
const id = '1'; const id = '1';
const expectedResponse = state.choices.find((choice => choice.id === parseInt(id, 10))); const expectedResponse = state.choices.find(
choice => choice.id === parseInt(id, 10),
);
const actualResponse = instance.getChoiceById(id); const actualResponse = instance.getChoiceById(id);
expect(actualResponse).to.eql(expectedResponse); expect(actualResponse).to.eql(expectedResponse);
}); });
@ -223,7 +229,9 @@ describe('reducers/store', () => {
describe('placeholderChoice getter', () => { describe('placeholderChoice getter', () => {
it('returns placeholder choice', () => { it('returns placeholder choice', () => {
const expectedResponse = state.choices.reverse().find(choice => choice.placeholder); const expectedResponse = state.choices
.reverse()
.find(choice => choice.placeholder);
expect(instance.getPlaceholderChoice).to.eql(expectedResponse); expect(instance.getPlaceholderChoice).to.eql(expectedResponse);
}); });
}); });
@ -245,7 +253,9 @@ describe('reducers/store', () => {
describe('getGroupById', () => { describe('getGroupById', () => {
it('returns group by id', () => { it('returns group by id', () => {
const id = '1'; const id = '1';
const expectedResponse = state.groups.find((group => group.id === parseInt(id, 10))); const expectedResponse = state.groups.find(
group => group.id === parseInt(id, 10),
);
const actualResponse = instance.getGroupById(id); const actualResponse = instance.getGroupById(id);
expect(actualResponse).to.eql(expectedResponse); expect(actualResponse).to.eql(expectedResponse);
}); });

View file

@ -39,13 +39,10 @@ export const TEMPLATES = {
`); `);
}, },
itemList(globalClasses, isSelectOneElement) { itemList(globalClasses, isSelectOneElement) {
const localClasses = classNames( const localClasses = classNames(globalClasses.list, {
globalClasses.list, [globalClasses.listSingle]: isSelectOneElement,
{ [globalClasses.listItems]: !isSelectOneElement,
[globalClasses.listSingle]: (isSelectOneElement), });
[globalClasses.listItems]: (!isSelectOneElement),
},
);
return strToEl(` return strToEl(`
<div class="${localClasses}"></div> <div class="${localClasses}"></div>
@ -62,22 +59,18 @@ export const TEMPLATES = {
const ariaSelected = data.active ? 'aria-selected="true"' : ''; const ariaSelected = data.active ? 'aria-selected="true"' : '';
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : ''; const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
let localClasses = classNames( let localClasses = classNames(globalClasses.item, {
globalClasses.item, { [globalClasses.highlightedState]: data.highlighted,
[globalClasses.highlightedState]: data.highlighted, [globalClasses.itemSelectable]: !data.highlighted,
[globalClasses.itemSelectable]: !data.highlighted, [globalClasses.placeholder]: data.placeholder,
[globalClasses.placeholder]: data.placeholder, });
},
);
if (removeItemButton) { if (removeItemButton) {
localClasses = classNames( localClasses = classNames(globalClasses.item, {
globalClasses.item, { [globalClasses.highlightedState]: data.highlighted,
[globalClasses.highlightedState]: data.highlighted, [globalClasses.itemSelectable]: !data.disabled,
[globalClasses.itemSelectable]: !data.disabled, [globalClasses.placeholder]: data.placeholder,
[globalClasses.placeholder]: data.placeholder, });
},
);
return strToEl(` return strToEl(`
<div <div
@ -116,9 +109,9 @@ export const TEMPLATES = {
`); `);
}, },
choiceList(globalClasses, isSelectOneElement) { choiceList(globalClasses, isSelectOneElement) {
const ariaMultiSelectable = !isSelectOneElement ? const ariaMultiSelectable = !isSelectOneElement
'aria-multiselectable="true"' : ? 'aria-multiselectable="true"'
''; : '';
return strToEl(` return strToEl(`
<div <div
@ -132,11 +125,9 @@ export const TEMPLATES = {
}, },
choiceGroup(globalClasses, data) { choiceGroup(globalClasses, data) {
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : ''; const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
const localClasses = classNames( const localClasses = classNames(globalClasses.group, {
globalClasses.group, { [globalClasses.itemDisabled]: data.disabled,
[globalClasses.itemDisabled]: data.disabled, });
},
);
return strToEl(` return strToEl(`
<div <div
@ -155,7 +146,8 @@ export const TEMPLATES = {
const role = data.groupId > 0 ? 'role="treeitem"' : 'role="option"'; const role = data.groupId > 0 ? 'role="treeitem"' : 'role="option"';
const localClasses = classNames( const localClasses = classNames(
globalClasses.item, globalClasses.item,
globalClasses.itemChoice, { globalClasses.itemChoice,
{
[globalClasses.itemDisabled]: data.disabled, [globalClasses.itemDisabled]: data.disabled,
[globalClasses.itemSelectable]: !data.disabled, [globalClasses.itemSelectable]: !data.disabled,
[globalClasses.placeholder]: data.placeholder, [globalClasses.placeholder]: data.placeholder,
@ -169,9 +161,10 @@ export const TEMPLATES = {
data-choice data-choice
data-id="${data.id}" data-id="${data.id}"
data-value="${data.value}" data-value="${data.value}"
${data.disabled ? ${
'data-choice-disabled aria-disabled="true"' : data.disabled
'data-choice-selectable' ? 'data-choice-disabled aria-disabled="true"'
: 'data-choice-selectable'
} }
id="${data.elementId}" id="${data.elementId}"
${role} ${role}
@ -217,8 +210,8 @@ export const TEMPLATES = {
globalClasses.item, globalClasses.item,
globalClasses.itemChoice, globalClasses.itemChoice,
{ {
[globalClasses.noResults]: (type === 'no-results'), [globalClasses.noResults]: type === 'no-results',
[globalClasses.noChoices]: (type === 'no-choices'), [globalClasses.noChoices]: type === 'no-choices',
}, },
); );
@ -230,7 +223,9 @@ export const TEMPLATES = {
}, },
option(data) { option(data) {
return strToEl(` return strToEl(`
<option value="${data.value}" ${data.selected ? 'selected' : ''} ${data.disabled ? 'disabled' : ''}>${data.label}</option> <option value="${data.value}" ${data.selected ? 'selected' : ''} ${
data.disabled ? 'disabled' : ''
}>${data.label}</option>
`); `);
}, },
}; };

View file

@ -2,7 +2,8 @@ import { expect } from 'chai';
import templates from './templates'; import templates from './templates';
import { getType, strToEl } from './lib/utils'; import { getType, strToEl } from './lib/utils';
const stripElement = element => element.outerHTML.replace(/(^|>)\s+|\s+(?=<|$)/g, '$1'); const stripElement = element =>
element.outerHTML.replace(/(^|>)\s+|\s+(?=<|$)/g, '$1');
describe('templates', () => { describe('templates', () => {
describe('containerOuter', () => { describe('containerOuter', () => {
@ -41,7 +42,9 @@ describe('templates', () => {
); );
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
@ -73,7 +76,9 @@ describe('templates', () => {
); );
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
@ -106,7 +111,9 @@ describe('templates', () => {
); );
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
}); });
@ -138,7 +145,9 @@ describe('templates', () => {
); );
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
}); });
@ -148,7 +157,9 @@ describe('templates', () => {
const classes = { const classes = {
containerInner: 'test', containerInner: 'test',
}; };
const expectedOutput = strToEl(`<div class="${classes.containerInner}"></div>`); const expectedOutput = strToEl(
`<div class="${classes.containerInner}"></div>`,
);
const actualOutput = templates.containerInner(classes); const actualOutput = templates.containerInner(classes);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
@ -165,21 +176,29 @@ describe('templates', () => {
describe('select one element', () => { describe('select one element', () => {
it('returns expected html', () => { it('returns expected html', () => {
const expectedOutput = strToEl(`<div class="${classes.list} ${classes.listSingle}"></div>`); const expectedOutput = strToEl(
`<div class="${classes.list} ${classes.listSingle}"></div>`,
);
const actualOutput = templates.itemList(classes, true); const actualOutput = templates.itemList(classes, true);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
describe('non select one element', () => { describe('non select one element', () => {
it('returns expected html', () => { it('returns expected html', () => {
const expectedOutput = strToEl(`<div class="${classes.list} ${classes.listItems}"></div>`); const expectedOutput = strToEl(
`<div class="${classes.list} ${classes.listItems}"></div>`,
);
const actualOutput = templates.itemList(classes, false); const actualOutput = templates.itemList(classes, false);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
}); });
@ -191,8 +210,7 @@ describe('templates', () => {
}; };
const value = 'test'; const value = 'test';
const expectedOutput = strToEl(` const expectedOutput = strToEl(`
<div class="${classes.placeholder}">${value}</div>`, <div class="${classes.placeholder}">${value}</div>`);
);
const actualOutput = templates.placeholder(classes, value); const actualOutput = templates.placeholder(classes, value);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
@ -222,7 +240,9 @@ describe('templates', () => {
const actualOutput = templates.choiceList(classes, true); const actualOutput = templates.choiceList(classes, true);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
@ -240,7 +260,9 @@ describe('templates', () => {
const actualOutput = templates.choiceList(classes, false); const actualOutput = templates.choiceList(classes, false);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
}); });
@ -278,7 +300,9 @@ describe('templates', () => {
const actualOutput = templates.choiceGroup(classes, data); const actualOutput = templates.choiceGroup(classes, data);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
@ -306,7 +330,9 @@ describe('templates', () => {
const actualOutput = templates.choiceGroup(classes, data); const actualOutput = templates.choiceGroup(classes, data);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
}); });
@ -339,7 +365,9 @@ describe('templates', () => {
it('returns expected html', () => { it('returns expected html', () => {
const expectedOutput = strToEl(` const expectedOutput = strToEl(`
<div <div
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}" class="${classes.item} ${classes.itemChoice} ${
classes.itemSelectable
}"
data-select-text="${itemSelectText}" data-select-text="${itemSelectText}"
data-choice data-choice
data-id="${data.id}" data-id="${data.id}"
@ -354,7 +382,9 @@ describe('templates', () => {
const actualOutput = templates.choice(classes, data, itemSelectText); const actualOutput = templates.choice(classes, data, itemSelectText);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
@ -369,7 +399,9 @@ describe('templates', () => {
it('returns expected html', () => { it('returns expected html', () => {
const expectedOutput = strToEl(` const expectedOutput = strToEl(`
<div <div
class="${classes.item} ${classes.itemChoice} ${classes.itemDisabled}" class="${classes.item} ${classes.itemChoice} ${
classes.itemDisabled
}"
data-select-text="${itemSelectText}" data-select-text="${itemSelectText}"
data-choice data-choice
data-id="${data.id}" data-id="${data.id}"
@ -385,7 +417,9 @@ describe('templates', () => {
const actualOutput = templates.choice(classes, data, itemSelectText); const actualOutput = templates.choice(classes, data, itemSelectText);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
@ -400,7 +434,9 @@ describe('templates', () => {
it('returns expected html', () => { it('returns expected html', () => {
const expectedOutput = strToEl(` const expectedOutput = strToEl(`
<div <div
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable} ${classes.placeholder}" class="${classes.item} ${classes.itemChoice} ${
classes.itemSelectable
} ${classes.placeholder}"
data-select-text="${itemSelectText}" data-select-text="${itemSelectText}"
data-choice data-choice
data-id="${data.id}" data-id="${data.id}"
@ -415,7 +451,9 @@ describe('templates', () => {
const actualOutput = templates.choice(classes, data, itemSelectText); const actualOutput = templates.choice(classes, data, itemSelectText);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
@ -423,14 +461,16 @@ describe('templates', () => {
beforeEach(() => { beforeEach(() => {
data = { data = {
...data, ...data,
groupId: 1 groupId: 1,
}; };
}); });
it('returns expected html', () => { it('returns expected html', () => {
const expectedOutput = strToEl(` const expectedOutput = strToEl(`
<div <div
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}" class="${classes.item} ${classes.itemChoice} ${
classes.itemSelectable
}"
data-select-text="${itemSelectText}" data-select-text="${itemSelectText}"
data-choice data-choice
data-id="${data.id}" data-id="${data.id}"
@ -445,7 +485,9 @@ describe('templates', () => {
const actualOutput = templates.choice(classes, data, itemSelectText); const actualOutput = templates.choice(classes, data, itemSelectText);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
}); });
@ -479,11 +521,14 @@ describe('templates', () => {
const classes = { const classes = {
list: 'test 1', list: 'test 1',
listDropdown: 'test 2', listDropdown: 'test 2',
} };
;
it('returns expected html', () => { it('returns expected html', () => {
const value = 'test'; const value = 'test';
const expectedOutput = strToEl(`<div class="${classes.list} ${classes.listDropdown}" aria-expanded="false"></div>`); const expectedOutput = strToEl(
`<div class="${classes.list} ${
classes.listDropdown
}" aria-expanded="false"></div>`,
);
const actualOutput = templates.dropdown(classes, value); const actualOutput = templates.dropdown(classes, value);
expect(getType(actualOutput)).to.equal('HTMLDivElement'); expect(getType(actualOutput)).to.equal('HTMLDivElement');
@ -517,26 +562,34 @@ describe('templates', () => {
describe('no results', () => { describe('no results', () => {
it('adds no results classname', () => { it('adds no results classname', () => {
const expectedOutput = strToEl(` const expectedOutput = strToEl(`
<div class="${classes.item} ${classes.itemChoice} ${classes.noResults}"> <div class="${classes.item} ${classes.itemChoice} ${
classes.noResults
}">
${label} ${label}
</div> </div>
`); `);
const actualOutput = templates.notice(classes, label, 'no-results'); const actualOutput = templates.notice(classes, label, 'no-results');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
describe('no choices', () => { describe('no choices', () => {
it('adds no choices classname', () => { it('adds no choices classname', () => {
const expectedOutput = strToEl(` const expectedOutput = strToEl(`
<div class="${classes.item} ${classes.itemChoice} ${classes.noChoices}"> <div class="${classes.item} ${classes.itemChoice} ${
classes.noChoices
}">
${label} ${label}
</div> </div>
`); `);
const actualOutput = templates.notice(classes, label, 'no-choices'); const actualOutput = templates.notice(classes, label, 'no-choices');
expect(stripElement(actualOutput)).to.equal(stripElement(expectedOutput)); expect(stripElement(actualOutput)).to.equal(
stripElement(expectedOutput),
);
}); });
}); });
}); });
@ -555,7 +608,11 @@ describe('templates', () => {
}); });
it('returns expected html', () => { it('returns expected html', () => {
const expectedOutput = strToEl(`<option value="${data.value}" ${data.selected ? 'selected' : ''} ${data.disabled ? 'disabled' : ''}>${data.label}</option>`); const expectedOutput = strToEl(
`<option value="${data.value}" ${data.selected ? 'selected' : ''} ${
data.disabled ? 'disabled' : ''
}>${data.label}</option>`,
);
const actualOutput = templates.option(data); const actualOutput = templates.option(data);
expect(getType(actualOutput)).to.equal('HTMLOptionElement'); expect(getType(actualOutput)).to.equal('HTMLOptionElement');