mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-02 05:52:46 +02:00
Install prettier + resolve linting issues
This commit is contained in:
parent
a6bfdc0993
commit
f9455b1a25
24
.eslintrc
24
.eslintrc
|
@ -1,34 +1,24 @@
|
|||
{
|
||||
"extends": "airbnb",
|
||||
"ecmaFeatures": {
|
||||
"modules": true
|
||||
},
|
||||
"extends": ["prettier"],
|
||||
"plugins": ["prettier"],
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"globals": {
|
||||
"__DEV__": true,
|
||||
"describe": true,
|
||||
"it": true,
|
||||
"before": true,
|
||||
"after": true,
|
||||
"beforeEach": true,
|
||||
"afterEach": true,
|
||||
"expect": true,
|
||||
"browser": true,
|
||||
"by": true,
|
||||
"element": true,
|
||||
"cy": true
|
||||
"afterEach": true
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"rules": {
|
||||
"strict": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-console": ["warn", {
|
||||
"allow": ["warn", "error"]
|
||||
}],
|
||||
"space-before-function-paren": 0
|
||||
"prettier/prettier": ["error", {
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,9 +43,11 @@
|
|||
"csso": "^1.8.2",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-airbnb": "^15.1.0",
|
||||
"eslint-config-prettier": "^2.9.0",
|
||||
"eslint-loader": "^1.5.0",
|
||||
"eslint-plugin-import": "^2.7.0",
|
||||
"eslint-plugin-jsx-a11y": "^5.1.1",
|
||||
"eslint-plugin-prettier": "^2.6.0",
|
||||
"eslint-plugin-react": "^7.2.1",
|
||||
"express": "^4.16.3",
|
||||
"husky": "^0.14.3",
|
||||
|
@ -55,6 +57,7 @@
|
|||
"nodemon": "^1.9.1",
|
||||
"nyc": "^11.0.3",
|
||||
"postcss-cli": "^2.5.1",
|
||||
"prettier": "^1.13.0",
|
||||
"sinon": "^2.4.0",
|
||||
"webpack": "^3.8.1",
|
||||
"webpack-dev-middleware": "^2.0.0",
|
||||
|
|
|
@ -27,17 +27,19 @@ describe('actions/choices', () => {
|
|||
keyCode,
|
||||
};
|
||||
|
||||
expect(actions.addChoice(
|
||||
value,
|
||||
label,
|
||||
id,
|
||||
groupId,
|
||||
disabled,
|
||||
elementId,
|
||||
customProperties,
|
||||
placeholder,
|
||||
keyCode,
|
||||
)).to.eql(expectedAction);
|
||||
expect(
|
||||
actions.addChoice(
|
||||
value,
|
||||
label,
|
||||
id,
|
||||
groupId,
|
||||
disabled,
|
||||
elementId,
|
||||
customProperties,
|
||||
placeholder,
|
||||
keyCode,
|
||||
),
|
||||
).to.eql(expectedAction);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -88,4 +90,3 @@ describe('actions/choices', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -16,12 +16,9 @@ describe('actions/groups', () => {
|
|||
disabled,
|
||||
};
|
||||
|
||||
expect(actions.addGroup(
|
||||
value,
|
||||
id,
|
||||
active,
|
||||
disabled,
|
||||
)).to.eql(expectedAction);
|
||||
expect(actions.addGroup(value, id, active, disabled)).to.eql(
|
||||
expectedAction,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,16 +25,18 @@ describe('actions/items', () => {
|
|||
keyCode,
|
||||
};
|
||||
|
||||
expect(actions.addItem(
|
||||
value,
|
||||
label,
|
||||
id,
|
||||
choiceId,
|
||||
groupId,
|
||||
customProperties,
|
||||
placeholder,
|
||||
keyCode,
|
||||
)).to.eql(expectedAction);
|
||||
expect(
|
||||
actions.addItem(
|
||||
value,
|
||||
label,
|
||||
id,
|
||||
choiceId,
|
||||
groupId,
|
||||
customProperties,
|
||||
placeholder,
|
||||
keyCode,
|
||||
),
|
||||
).to.eql(expectedAction);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,10 +2,28 @@ import Fuse from 'fuse.js';
|
|||
|
||||
import './lib/polyfills';
|
||||
import Store from './store/store';
|
||||
import { Dropdown, Container, Input, List, WrappedInput, WrappedSelect } from './components';
|
||||
import { DEFAULT_CONFIG, DEFAULT_CLASSNAMES, EVENTS, KEY_CODES, SCROLLING_SPEED } from './constants';
|
||||
import {
|
||||
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 { addChoice, filterChoices, activateChoices, clearChoices } from './actions/choices';
|
||||
import {
|
||||
addChoice,
|
||||
filterChoices,
|
||||
activateChoices,
|
||||
clearChoices,
|
||||
} from './actions/choices';
|
||||
import { addItem, removeItem, highlightItem } from './actions/items';
|
||||
import { addGroup } from './actions/groups';
|
||||
import { clearAll } from './actions/misc';
|
||||
|
@ -48,12 +66,15 @@ class Choices {
|
|||
}
|
||||
|
||||
// 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._isSelectOneElement = passedElement.type === 'select-one';
|
||||
this._isSelectMultipleElement = passedElement.type === 'select-multiple';
|
||||
this._isSelectElement = this._isSelectOneElement || this._isSelectMultipleElement;
|
||||
this._isSelectElement =
|
||||
this._isSelectOneElement || this._isSelectMultipleElement;
|
||||
|
||||
if (this._isTextElement) {
|
||||
this.passedElement = new WrappedInput({
|
||||
|
@ -72,8 +93,14 @@ class Choices {
|
|||
throw new Error('Could not wrap passed element');
|
||||
}
|
||||
|
||||
if (this.config.shouldSortItems === true && this._isSelectOneElement && !this.config.silent) {
|
||||
console.warn('shouldSortElements: Type of passed element is \'select-one\', falling back to false.');
|
||||
if (
|
||||
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);
|
||||
|
@ -204,13 +231,13 @@ class Choices {
|
|||
render() {
|
||||
this._currentState = this._store.state;
|
||||
|
||||
const stateChanged = (
|
||||
const stateChanged =
|
||||
this._currentState.choices !== this._prevState.choices ||
|
||||
this._currentState.groups !== this._prevState.groups ||
|
||||
this._currentState.items !== this._prevState.items
|
||||
);
|
||||
this._currentState.items !== this._prevState.items;
|
||||
const shouldRenderChoices = this._isSelectElement;
|
||||
const shouldRenderItems = this._currentState.items !== this._prevState.items;
|
||||
const shouldRenderItems =
|
||||
this._currentState.items !== this._prevState.items;
|
||||
|
||||
if (!stateChanged) {
|
||||
return;
|
||||
|
@ -295,15 +322,14 @@ class Choices {
|
|||
}
|
||||
|
||||
removeHighlightedItems(runEvent = false) {
|
||||
this._store.highlightedActiveItems
|
||||
.forEach((item) => {
|
||||
this._removeItem(item);
|
||||
// If this action was performed by the user
|
||||
// trigger the event
|
||||
if (runEvent) {
|
||||
this._triggerChange(item.value);
|
||||
}
|
||||
});
|
||||
this._store.highlightedActiveItems.forEach(item => {
|
||||
this._removeItem(item);
|
||||
// If this action was performed by the user
|
||||
// trigger the event
|
||||
if (runEvent) {
|
||||
this._triggerChange(item.value);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -358,12 +384,11 @@ class Choices {
|
|||
}
|
||||
|
||||
getValue(valueOnly = false) {
|
||||
const values = this._store.activeItems
|
||||
.reduce((selectedItems, item) => {
|
||||
const itemValue = valueOnly ? item.value : item;
|
||||
selectedItems.push(itemValue);
|
||||
return selectedItems;
|
||||
}, []);
|
||||
const values = this._store.activeItems.reduce((selectedItems, item) => {
|
||||
const itemValue = valueOnly ? item.value : item;
|
||||
selectedItems.push(itemValue);
|
||||
return selectedItems;
|
||||
}, []);
|
||||
|
||||
return this._isSelectOneElement ? values[0] : values;
|
||||
}
|
||||
|
@ -373,10 +398,7 @@ class Choices {
|
|||
return this;
|
||||
}
|
||||
|
||||
// Convert args to an iterable array
|
||||
const values = [...args];
|
||||
values.forEach(value => this._setChoiceOrItem(value));
|
||||
|
||||
[...args].forEach(value => this._setChoiceOrItem(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -395,11 +417,7 @@ class Choices {
|
|||
}
|
||||
|
||||
setChoices(choices = [], value = '', label = '', replaceChoices = false) {
|
||||
if (
|
||||
!this._isSelectElement ||
|
||||
!choices.length ||
|
||||
!value
|
||||
) {
|
||||
if (!this._isSelectElement || !choices.length || !value) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -409,14 +427,9 @@ class Choices {
|
|||
}
|
||||
|
||||
this.containerOuter.removeLoadingState();
|
||||
const addGroupsAndChoices = (groupOrChoice) => {
|
||||
const addGroupsAndChoices = groupOrChoice => {
|
||||
if (groupOrChoice.choices) {
|
||||
this._addGroup(
|
||||
groupOrChoice,
|
||||
(groupOrChoice.id || null),
|
||||
value,
|
||||
label,
|
||||
);
|
||||
this._addGroup(groupOrChoice, groupOrChoice.id || null, value, label);
|
||||
} else {
|
||||
this._addChoice(
|
||||
groupOrChoice[value],
|
||||
|
@ -471,20 +484,23 @@ class Choices {
|
|||
|
||||
_createGroupsFragment(groups, choices, fragment) {
|
||||
const groupFragment = fragment || document.createDocumentFragment();
|
||||
const getGroupChoices = group => choices.filter((choice) => {
|
||||
if (this._isSelectOneElement) {
|
||||
return choice.groupId === group.id;
|
||||
}
|
||||
return choice.groupId === group.id && (this.config.renderSelectedChoices === 'always' || !choice.selected);
|
||||
});
|
||||
|
||||
const getGroupChoices = group =>
|
||||
choices.filter(choice => {
|
||||
if (this._isSelectOneElement) {
|
||||
return choice.groupId === group.id;
|
||||
}
|
||||
return (
|
||||
choice.groupId === group.id &&
|
||||
(this.config.renderSelectedChoices === 'always' || !choice.selected)
|
||||
);
|
||||
});
|
||||
|
||||
// If sorting is enabled, filter groups
|
||||
if (this.config.shouldSort) {
|
||||
groups.sort(this.config.sortFn);
|
||||
}
|
||||
|
||||
groups.forEach((group) => {
|
||||
groups.forEach(group => {
|
||||
const groupChoices = getGroupChoices(group);
|
||||
if (groupChoices.length >= 1) {
|
||||
const dropdownGroup = this._getTemplate('choiceGroup', group);
|
||||
|
@ -499,14 +515,23 @@ class Choices {
|
|||
_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)
|
||||
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 appendChoice = (choice) => {
|
||||
const shouldRender = renderSelectedChoices === 'auto' ?
|
||||
(this._isSelectOneElement || !choice.selected) :
|
||||
true;
|
||||
const appendChoice = choice => {
|
||||
const shouldRender =
|
||||
renderSelectedChoices === 'auto'
|
||||
? this._isSelectOneElement || !choice.selected
|
||||
: true;
|
||||
if (shouldRender) {
|
||||
const dropdownItem = this._getTemplate('choice', choice, this.config.itemSelectText);
|
||||
const dropdownItem = this._getTemplate(
|
||||
'choice',
|
||||
choice,
|
||||
this.config.itemSelectText,
|
||||
);
|
||||
choicesFragment.appendChild(dropdownItem);
|
||||
}
|
||||
};
|
||||
|
@ -518,14 +543,17 @@ class Choices {
|
|||
}
|
||||
|
||||
// Split array into placeholders and "normal" choices
|
||||
const { placeholderChoices, normalChoices } = rendererableChoices.reduce((acc, choice) => {
|
||||
if (choice.placeholder) {
|
||||
acc.placeholderChoices.push(choice);
|
||||
} else {
|
||||
acc.normalChoices.push(choice);
|
||||
}
|
||||
return acc;
|
||||
}, { placeholderChoices: [], normalChoices: [] });
|
||||
const { placeholderChoices, normalChoices } = rendererableChoices.reduce(
|
||||
(acc, choice) => {
|
||||
if (choice.placeholder) {
|
||||
acc.placeholderChoices.push(choice);
|
||||
} else {
|
||||
acc.normalChoices.push(choice);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{ placeholderChoices: [], normalChoices: [] },
|
||||
);
|
||||
|
||||
// If sorting is enabled or the user is searching, filter choices
|
||||
if (this.config.shouldSort || this._isSearching) {
|
||||
|
@ -571,7 +599,7 @@ class Choices {
|
|||
this.passedElement.options = items;
|
||||
}
|
||||
|
||||
const addItemToFragment = (item) => {
|
||||
const addItemToFragment = item => {
|
||||
// Create new list element
|
||||
const listItem = this._getTemplate('item', item, removeItemButton);
|
||||
// Append it to list
|
||||
|
@ -621,7 +649,9 @@ class Choices {
|
|||
}
|
||||
|
||||
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
|
||||
this._removeItem(itemToRemove);
|
||||
|
@ -647,7 +677,7 @@ class Choices {
|
|||
// We only want to select one item with a click
|
||||
// so we deselect any items that aren't the target
|
||||
// unless shift is being pressed
|
||||
activeItems.forEach((item) => {
|
||||
activeItems.forEach(item => {
|
||||
if (item.id === parseInt(passedId, 10) && !item.highlighted) {
|
||||
this.highlightItem(item);
|
||||
} else if (!hasShiftKey && item.highlighted) {
|
||||
|
@ -668,7 +698,8 @@ class Choices {
|
|||
// If we are clicking on an option
|
||||
const id = element.getAttribute('data-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;
|
||||
|
||||
// Update choice keyCode
|
||||
|
@ -729,12 +760,17 @@ class Choices {
|
|||
}
|
||||
|
||||
_handleLoadingState(isLoading = true) {
|
||||
let placeholderItem = this.itemList.getChild(`.${this.config.classNames.placeholder}`);
|
||||
let placeholderItem = this.itemList.getChild(
|
||||
`.${this.config.classNames.placeholder}`,
|
||||
);
|
||||
if (isLoading) {
|
||||
this.containerOuter.addLoadingState();
|
||||
if (this._isSelectOneElement) {
|
||||
if (!placeholderItem) {
|
||||
placeholderItem = this._getTemplate('placeholder', this.config.loadingText);
|
||||
placeholderItem = this._getTemplate(
|
||||
'placeholder',
|
||||
this.config.loadingText,
|
||||
);
|
||||
this.itemList.append(placeholderItem);
|
||||
} else {
|
||||
placeholderItem.innerHTML = this.config.loadingText;
|
||||
|
@ -746,47 +782,51 @@ class Choices {
|
|||
this.containerOuter.removeLoadingState();
|
||||
|
||||
if (this._isSelectOneElement) {
|
||||
placeholderItem.innerHTML = (this._placeholderValue || '');
|
||||
placeholderItem.innerHTML = this._placeholderValue || '';
|
||||
} else {
|
||||
this.input.placeholder = (this._placeholderValue || '');
|
||||
this.input.placeholder = this._placeholderValue || '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_canAddItem(activeItems, value) {
|
||||
let canAddItem = true;
|
||||
let notice = isType('Function', this.config.addItemText) ?
|
||||
this.config.addItemText(value) :
|
||||
this.config.addItemText;
|
||||
let notice = isType('Function', this.config.addItemText)
|
||||
? this.config.addItemText(value)
|
||||
: this.config.addItemText;
|
||||
|
||||
if (!this._isSelectOneElement) {
|
||||
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
|
||||
// don't update
|
||||
canAddItem = false;
|
||||
notice = isType('Function', this.config.maxItemText) ?
|
||||
this.config.maxItemText(this.config.maxItemCount) :
|
||||
this.config.maxItemText;
|
||||
notice = isType('Function', this.config.maxItemText)
|
||||
? this.config.maxItemText(this.config.maxItemCount)
|
||||
: 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
|
||||
// determine whether we can update based on whether
|
||||
// our regular expression passes
|
||||
canAddItem = regexFilter(value, this.config.regexFilter);
|
||||
}
|
||||
|
||||
if (
|
||||
!this.config.duplicateItems &&
|
||||
!valueAlreadyExists &&
|
||||
canAddItem
|
||||
) {
|
||||
if (!this.config.duplicateItems && !valueAlreadyExists && canAddItem) {
|
||||
canAddItem = false;
|
||||
notice = isType('Function', this.config.uniqueItemText) ?
|
||||
this.config.uniqueItemText(value) :
|
||||
this.config.uniqueItemText;
|
||||
notice = isType('Function', this.config.uniqueItemText)
|
||||
? this.config.uniqueItemText(value)
|
||||
: this.config.uniqueItemText;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -804,19 +844,18 @@ class Choices {
|
|||
|
||||
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
|
||||
this._handleLoadingState(false);
|
||||
// Add each result as a choice
|
||||
parsedResults.forEach((result) => {
|
||||
parsedResults.forEach(result => {
|
||||
if (result.choices) {
|
||||
const groupId = (result.id || null);
|
||||
this._addGroup(
|
||||
result,
|
||||
groupId,
|
||||
value,
|
||||
label,
|
||||
);
|
||||
const groupId = result.id || null;
|
||||
this._addGroup(result, groupId, value, label);
|
||||
} else {
|
||||
this._addChoice(
|
||||
result[value],
|
||||
|
@ -842,9 +881,9 @@ class Choices {
|
|||
|
||||
_searchChoices(value) {
|
||||
const newValue = isType('String', value) ? value.trim() : value;
|
||||
const currentValue = isType('String', this._currentValue) ?
|
||||
this._currentValue.trim() :
|
||||
this._currentValue;
|
||||
const currentValue = isType('String', this._currentValue)
|
||||
? this._currentValue.trim()
|
||||
: this._currentValue;
|
||||
|
||||
if (newValue.length < 1 && newValue === `${currentValue} `) {
|
||||
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
|
||||
const haystack = this._store.searchableChoices;
|
||||
const needle = newValue;
|
||||
const keys = isType('Array', this.config.searchFields) ?
|
||||
this.config.searchFields :
|
||||
[this.config.searchFields];
|
||||
const keys = isType('Array', this.config.searchFields)
|
||||
? this.config.searchFields
|
||||
: [this.config.searchFields];
|
||||
const options = Object.assign(this.config.fuseOptions, { keys });
|
||||
const fuse = new Fuse(haystack, options);
|
||||
const results = fuse.search(needle);
|
||||
|
@ -934,7 +973,10 @@ class Choices {
|
|||
_onKeyDown(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;
|
||||
}
|
||||
|
||||
|
@ -952,7 +994,7 @@ class Choices {
|
|||
const downKey = KEY_CODES.DOWN_KEY;
|
||||
const pageUpKey = KEY_CODES.PAGE_UP_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 (!this._isTextElement && /[a-zA-Z0-9-_ ]/.test(keyString)) {
|
||||
|
@ -998,7 +1040,9 @@ class Choices {
|
|||
|
||||
if (hasActiveDropdown) {
|
||||
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 (highlighted) {
|
||||
|
@ -1030,34 +1074,48 @@ class Choices {
|
|||
|
||||
this.config.searchEnabled = false;
|
||||
|
||||
const directionInt = keyCode === downKey || keyCode === pageDownKey ? 1 : -1;
|
||||
const skipKey = metaKey || keyCode === pageDownKey || keyCode === pageUpKey;
|
||||
const directionInt =
|
||||
keyCode === downKey || keyCode === pageDownKey ? 1 : -1;
|
||||
const skipKey =
|
||||
metaKey || keyCode === pageDownKey || keyCode === pageUpKey;
|
||||
const selectableChoiceIdentifier = '[data-choice-selectable]';
|
||||
|
||||
let nextEl;
|
||||
if (skipKey) {
|
||||
if (directionInt > 0) {
|
||||
nextEl = Array.from(
|
||||
this.dropdown.element.querySelectorAll(selectableChoiceIdentifier),
|
||||
this.dropdown.element.querySelectorAll(
|
||||
selectableChoiceIdentifier,
|
||||
),
|
||||
).pop();
|
||||
} else {
|
||||
nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier);
|
||||
nextEl = this.dropdown.element.querySelector(
|
||||
selectableChoiceIdentifier,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const currentEl = this.dropdown.element.querySelector(
|
||||
`.${this.config.classNames.highlightedState}`,
|
||||
);
|
||||
if (currentEl) {
|
||||
nextEl = getAdjacentEl(currentEl, selectableChoiceIdentifier, directionInt);
|
||||
nextEl = getAdjacentEl(
|
||||
currentEl,
|
||||
selectableChoiceIdentifier,
|
||||
directionInt,
|
||||
);
|
||||
} else {
|
||||
nextEl = this.dropdown.element.querySelector(selectableChoiceIdentifier);
|
||||
nextEl = this.dropdown.element.querySelector(
|
||||
selectableChoiceIdentifier,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (nextEl) {
|
||||
// We prevent default to stop the cursor moving
|
||||
// when pressing the arrow
|
||||
if (!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)) {
|
||||
if (
|
||||
!isScrolledIntoView(nextEl, this.choiceList.element, directionInt)
|
||||
) {
|
||||
this._scrollToChoice(nextEl, directionInt);
|
||||
}
|
||||
this._highlightChoice(nextEl);
|
||||
|
@ -1148,20 +1206,21 @@ class Choices {
|
|||
}
|
||||
|
||||
_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 (this._wasTap === true && this.containerOuter.element.contains(target)) {
|
||||
// ...and we aren't dealing with a single select box, show dropdown/focus input
|
||||
if (
|
||||
(target === this.containerOuter.element || target === this.containerInner.element) &&
|
||||
(target === this.containerOuter.element ||
|
||||
target === this.containerInner.element) &&
|
||||
!this._isSelectOneElement
|
||||
) {
|
||||
if (this._isTextElement) {
|
||||
// If text element, we only want to focus the input
|
||||
this.input.focus();
|
||||
} else {
|
||||
// If a select box, we want to show the dropdown
|
||||
// If a select box, we want to show the dropdown
|
||||
this.showDropdown(true);
|
||||
}
|
||||
}
|
||||
|
@ -1179,7 +1238,10 @@ class Choices {
|
|||
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 hasShiftKey = shiftKey;
|
||||
|
||||
|
@ -1200,10 +1262,10 @@ class Choices {
|
|||
}
|
||||
|
||||
_onMouseOver({ target }) {
|
||||
const targetWithinDropdown = (
|
||||
target === this.dropdown || this.dropdown.element.contains(target)
|
||||
);
|
||||
const shouldHighlightChoice = targetWithinDropdown && target.hasAttribute('data-choice');
|
||||
const targetWithinDropdown =
|
||||
target === this.dropdown || this.dropdown.element.contains(target);
|
||||
const shouldHighlightChoice =
|
||||
targetWithinDropdown && target.hasAttribute('data-choice');
|
||||
|
||||
if (shouldHighlightChoice) {
|
||||
this._highlightChoice(target);
|
||||
|
@ -1279,7 +1341,10 @@ class Choices {
|
|||
|
||||
_onBlur({ target }) {
|
||||
// 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 hasHighlightedItems = activeItems.some(item => item.highlighted);
|
||||
const blurActions = {
|
||||
|
@ -1296,8 +1361,11 @@ class Choices {
|
|||
},
|
||||
'select-one': () => {
|
||||
this.containerOuter.removeFocusState();
|
||||
if (target === this.input.element ||
|
||||
(target === this.containerOuter.element && !this.config.searchEnabled)) {
|
||||
if (
|
||||
target === this.input.element ||
|
||||
(target === this.containerOuter.element &&
|
||||
!this.config.searchEnabled)
|
||||
) {
|
||||
this.hideDropdown();
|
||||
}
|
||||
},
|
||||
|
@ -1334,11 +1402,13 @@ class Choices {
|
|||
// Distance from bottom of element to top of parent
|
||||
const choicePos = choice.offsetTop + choiceHeight;
|
||||
// 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
|
||||
const endPoint = direction > 0 ? (
|
||||
(this.choiceList.element.scrollTop + choicePos) - containerScrollPos
|
||||
) : choice.offsetTop;
|
||||
const endPoint =
|
||||
direction > 0
|
||||
? this.choiceList.element.scrollTop + choicePos - containerScrollPos
|
||||
: choice.offsetTop;
|
||||
|
||||
const scrollDown = (scrollPos, strength) => {
|
||||
const easing = (endPoint - scrollPos) / strength;
|
||||
|
@ -1374,19 +1444,21 @@ class Choices {
|
|||
}
|
||||
|
||||
if (continueAnimation) {
|
||||
requestAnimationFrame((time) => {
|
||||
requestAnimationFrame(time => {
|
||||
animateScroll(time, endPoint, direction);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
requestAnimationFrame((time) => {
|
||||
requestAnimationFrame(time => {
|
||||
animateScroll(time, endPoint, direction);
|
||||
});
|
||||
}
|
||||
|
||||
_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) {
|
||||
return;
|
||||
|
@ -1394,12 +1466,14 @@ class Choices {
|
|||
|
||||
let passedEl = el;
|
||||
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;
|
||||
|
||||
// Remove any highlighted choices
|
||||
highlightedChoices.forEach((choice) => {
|
||||
highlightedChoices.forEach(choice => {
|
||||
choice.classList.remove(this.config.classNames.highlightedState);
|
||||
choice.setAttribute('aria-selected', 'false');
|
||||
});
|
||||
|
@ -1547,7 +1621,9 @@ class Choices {
|
|||
const choices = this._store.choices;
|
||||
const choiceLabel = label || value;
|
||||
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(
|
||||
addChoice(
|
||||
|
@ -1581,27 +1657,21 @@ class Choices {
|
|||
}
|
||||
|
||||
_addGroup(group, id, valueKey = 'value', labelKey = 'label') {
|
||||
const groupChoices = isType('Object', group) ?
|
||||
group.choices :
|
||||
Array.from(group.getElementsByTagName('OPTION'));
|
||||
const groupChoices = isType('Object', group)
|
||||
? group.choices
|
||||
: Array.from(group.getElementsByTagName('OPTION'));
|
||||
const groupId = id || Math.floor(new Date().valueOf() * Math.random());
|
||||
const isDisabled = group.disabled ? group.disabled : false;
|
||||
|
||||
if (groupChoices) {
|
||||
this._store.dispatch(
|
||||
addGroup(
|
||||
group.label,
|
||||
groupId,
|
||||
true,
|
||||
isDisabled,
|
||||
),
|
||||
);
|
||||
this._store.dispatch(addGroup(group.label, groupId, true, isDisabled));
|
||||
|
||||
const addGroupChoices = (choice) => {
|
||||
const isOptDisabled = choice.disabled || (choice.parentNode && choice.parentNode.disabled);
|
||||
const addGroupChoices = choice => {
|
||||
const isOptDisabled =
|
||||
choice.disabled || (choice.parentNode && choice.parentNode.disabled);
|
||||
this._addChoice(
|
||||
choice[valueKey],
|
||||
(isType('Object', choice)) ? choice[labelKey] : choice.innerHTML,
|
||||
isType('Object', choice) ? choice[labelKey] : choice.innerHTML,
|
||||
choice.selected,
|
||||
isOptDisabled,
|
||||
groupId,
|
||||
|
@ -1613,12 +1683,7 @@ class Choices {
|
|||
groupChoices.forEach(addGroupChoices);
|
||||
} else {
|
||||
this._store.dispatch(
|
||||
addGroup(
|
||||
group.label,
|
||||
group.id,
|
||||
false,
|
||||
group.disabled,
|
||||
),
|
||||
addGroup(group.label, group.id, false, group.disabled),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1636,7 +1701,10 @@ class Choices {
|
|||
const { callbackOnCreateTemplates } = this.config;
|
||||
let userTemplates = {};
|
||||
|
||||
if (callbackOnCreateTemplates && isType('Function', callbackOnCreateTemplates)) {
|
||||
if (
|
||||
callbackOnCreateTemplates &&
|
||||
isType('Function', callbackOnCreateTemplates)
|
||||
) {
|
||||
userTemplates = callbackOnCreateTemplates.call(this, strToEl);
|
||||
}
|
||||
|
||||
|
@ -1645,7 +1713,8 @@ class Choices {
|
|||
|
||||
_createElements() {
|
||||
const direction = this.passedElement.element.getAttribute('dir') || 'ltr';
|
||||
const containerOuter = this._getTemplate('containerOuter',
|
||||
const containerOuter = this._getTemplate(
|
||||
'containerOuter',
|
||||
direction,
|
||||
this._isSelectElement,
|
||||
this._isSelectOneElement,
|
||||
|
@ -1654,7 +1723,10 @@ class Choices {
|
|||
);
|
||||
const containerInner = this._getTemplate('containerInner');
|
||||
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 dropdown = this._getTemplate('dropdown');
|
||||
|
||||
|
@ -1702,7 +1774,7 @@ class Choices {
|
|||
this.containerOuter.wrap(this.containerInner.element);
|
||||
|
||||
if (this._isSelectOneElement) {
|
||||
this.input.placeholder = (this.config.searchPlaceholderValue || '');
|
||||
this.input.placeholder = this.config.searchPlaceholderValue || '';
|
||||
} else if (this._placeholderValue) {
|
||||
this.input.placeholder = this._placeholderValue;
|
||||
this.input.setWidth(true);
|
||||
|
@ -1723,7 +1795,10 @@ class Choices {
|
|||
if (!this._isSelectOneElement) {
|
||||
this.containerInner.element.appendChild(this.input.element);
|
||||
} 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) {
|
||||
|
@ -1742,7 +1817,10 @@ class Choices {
|
|||
if (passedGroups && passedGroups.length) {
|
||||
// If we have a placeholder option
|
||||
const placeholderChoice = this.passedElement.placeholderOption;
|
||||
if (placeholderChoice && placeholderChoice.parentNode.tagName === 'SELECT') {
|
||||
if (
|
||||
placeholderChoice &&
|
||||
placeholderChoice.parentNode.tagName === 'SELECT'
|
||||
) {
|
||||
this._addChoice(
|
||||
placeholderChoice.value,
|
||||
placeholderChoice.innerHTML,
|
||||
|
@ -1750,12 +1828,12 @@ class Choices {
|
|||
placeholderChoice.disabled,
|
||||
undefined,
|
||||
undefined,
|
||||
/* placeholder */ true,
|
||||
/* placeholder */ true,
|
||||
);
|
||||
}
|
||||
|
||||
passedGroups.forEach((group) => {
|
||||
this._addGroup(group, (group.id || null));
|
||||
passedGroups.forEach(group => {
|
||||
this._addGroup(group, group.id || null);
|
||||
});
|
||||
} else {
|
||||
const passedOptions = this.passedElement.options;
|
||||
|
@ -1763,7 +1841,7 @@ class Choices {
|
|||
const allChoices = this._presetChoices;
|
||||
|
||||
// Create array of options from option elements
|
||||
passedOptions.forEach((o) => {
|
||||
passedOptions.forEach(o => {
|
||||
allChoices.push({
|
||||
value: o.value,
|
||||
label: o.innerHTML,
|
||||
|
@ -1789,7 +1867,8 @@ class Choices {
|
|||
// If there is a selected choice already or the choice is not
|
||||
// the first in the array, add each choice normally
|
||||
// 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 isDisabled = shouldPreselect ? false : choice.disabled;
|
||||
|
||||
|
@ -1822,7 +1901,7 @@ class Choices {
|
|||
}
|
||||
|
||||
_addPredefinedItems() {
|
||||
const handlePresetItem = (item) => {
|
||||
const handlePresetItem = item => {
|
||||
const itemType = getType(item);
|
||||
if (itemType === 'Object') {
|
||||
if (!item.value) {
|
||||
|
@ -1859,7 +1938,8 @@ class Choices {
|
|||
item.value,
|
||||
item.label,
|
||||
true,
|
||||
false, -1,
|
||||
false,
|
||||
-1,
|
||||
item.customProperties,
|
||||
item.placeholder,
|
||||
);
|
||||
|
@ -1876,13 +1956,7 @@ class Choices {
|
|||
},
|
||||
string: () => {
|
||||
if (!this._isTextElement) {
|
||||
this._addChoice(
|
||||
item,
|
||||
item,
|
||||
true,
|
||||
false, -1,
|
||||
null,
|
||||
);
|
||||
this._addChoice(item, item, true, false, -1, null);
|
||||
} else {
|
||||
this._addItem(item);
|
||||
}
|
||||
|
@ -1895,7 +1969,9 @@ class Choices {
|
|||
_findAndSelectChoiceByValue(val) {
|
||||
const choices = this._store.choices;
|
||||
// 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) {
|
||||
this._addItem(
|
||||
|
@ -1911,10 +1987,13 @@ class Choices {
|
|||
}
|
||||
|
||||
_generateInstances(elements, config) {
|
||||
return elements.reduce((instances, element) => {
|
||||
instances.push(new Choices(element, config));
|
||||
return instances;
|
||||
}, [this]);
|
||||
return elements.reduce(
|
||||
(instances, element) => {
|
||||
instances.push(new Choices(element, config));
|
||||
return instances;
|
||||
},
|
||||
[this],
|
||||
);
|
||||
}
|
||||
|
||||
static _generateConfig(userConfig) {
|
||||
|
@ -1934,9 +2013,10 @@ class Choices {
|
|||
return false;
|
||||
}
|
||||
|
||||
return this.config.placeholder ?
|
||||
(this.config.placeholderValue || this.passedElement.element.getAttribute('placeholder')) :
|
||||
false;
|
||||
return this.config.placeholder
|
||||
? this.config.placeholderValue ||
|
||||
this.passedElement.element.getAttribute('placeholder')
|
||||
: false;
|
||||
}
|
||||
|
||||
_renderChoices() {
|
||||
|
@ -1955,22 +2035,32 @@ class Choices {
|
|||
if (activeGroups.length >= 1 && !this._isSearching) {
|
||||
// If we have a placeholder choice along with groups
|
||||
const activePlaceholders = activeChoices.filter(
|
||||
activeChoice => activeChoice.placeholder === true && activeChoice.groupId === -1,
|
||||
);
|
||||
activeChoice =>
|
||||
activeChoice.placeholder === true && activeChoice.groupId === -1,
|
||||
);
|
||||
if (activePlaceholders.length >= 1) {
|
||||
choiceListFragment = this._createChoicesFragment(activePlaceholders, choiceListFragment);
|
||||
choiceListFragment = this._createChoicesFragment(
|
||||
activePlaceholders,
|
||||
choiceListFragment,
|
||||
);
|
||||
}
|
||||
choiceListFragment = this._createGroupsFragment(
|
||||
activeGroups,
|
||||
activeChoices,
|
||||
choiceListFragment,
|
||||
);
|
||||
activeGroups,
|
||||
activeChoices,
|
||||
choiceListFragment,
|
||||
);
|
||||
} else if (activeChoices.length >= 1) {
|
||||
choiceListFragment = this._createChoicesFragment(activeChoices, choiceListFragment);
|
||||
choiceListFragment = this._createChoicesFragment(
|
||||
activeChoices,
|
||||
choiceListFragment,
|
||||
);
|
||||
}
|
||||
|
||||
// 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 canAddItem = this._canAddItem(activeItems, this.input.value);
|
||||
|
||||
|
@ -1989,15 +2079,15 @@ class Choices {
|
|||
let notice;
|
||||
|
||||
if (this._isSearching) {
|
||||
notice = isType('Function', this.config.noResultsText) ?
|
||||
this.config.noResultsText() :
|
||||
this.config.noResultsText;
|
||||
notice = isType('Function', this.config.noResultsText)
|
||||
? this.config.noResultsText()
|
||||
: this.config.noResultsText;
|
||||
|
||||
dropdownItem = this._getTemplate('notice', notice, 'no-results');
|
||||
} else {
|
||||
notice = isType('Function', this.config.noChoicesText) ?
|
||||
this.config.noChoicesText() :
|
||||
this.config.noChoicesText;
|
||||
notice = isType('Function', this.config.noChoicesText)
|
||||
? this.config.noChoicesText()
|
||||
: this.config.noChoicesText;
|
||||
|
||||
dropdownItem = this._getTemplate('notice', notice, 'no-choices');
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ describe('choices', () => {
|
|||
instance.init();
|
||||
});
|
||||
|
||||
it('doesn\'t set initialise flag', () => {
|
||||
it("doesn't set initialise flag", () => {
|
||||
expect(instance.initialised).to.not.equal(false);
|
||||
});
|
||||
});
|
||||
|
@ -123,7 +123,7 @@ describe('choices', () => {
|
|||
instance.destroy();
|
||||
});
|
||||
|
||||
it('doesn\'t set initialise flag', () => {
|
||||
it("doesn't set initialise flag", () => {
|
||||
expect(instance.initialised).to.not.equal(true);
|
||||
});
|
||||
});
|
||||
|
@ -161,7 +161,9 @@ describe('choices', () => {
|
|||
|
||||
it('reverts outer container', () => {
|
||||
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', () => {
|
||||
|
@ -263,7 +265,6 @@ describe('choices', () => {
|
|||
inputDisableSpy = spy(instance.input, 'disable');
|
||||
});
|
||||
|
||||
|
||||
afterEach(() => {
|
||||
removeEventListenersSpy.restore();
|
||||
passedElementDisableSpy.restore();
|
||||
|
@ -374,24 +375,26 @@ describe('choices', () => {
|
|||
expect(output).to.eql(instance);
|
||||
});
|
||||
|
||||
it('opens containerOuter', (done) => {
|
||||
it('opens containerOuter', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(containerOuterOpenSpy.called).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows dropdown with blurInput flag', (done) => {
|
||||
it('shows dropdown with blurInput flag', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(dropdownShowSpy.called).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('triggers event on passedElement', (done) => {
|
||||
it('triggers event on passedElement', done => {
|
||||
requestAnimationFrame(() => {
|
||||
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({});
|
||||
done();
|
||||
});
|
||||
|
@ -404,7 +407,7 @@ describe('choices', () => {
|
|||
output = instance.showDropdown(true);
|
||||
});
|
||||
|
||||
it('focuses input', (done) => {
|
||||
it('focuses input', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(inputFocusSpy.called).to.equal(true);
|
||||
done();
|
||||
|
@ -425,7 +428,10 @@ describe('choices', () => {
|
|||
containerOuterCloseSpy = spy(instance.containerOuter, 'close');
|
||||
dropdownHideSpy = spy(instance.dropdown, 'hide');
|
||||
inputBlurSpy = spy(instance.input, 'blur');
|
||||
inputRemoveActiveDescendantSpy = spy(instance.input, 'removeActiveDescendant');
|
||||
inputRemoveActiveDescendantSpy = spy(
|
||||
instance.input,
|
||||
'removeActiveDescendant',
|
||||
);
|
||||
passedElementTriggerEventStub = stub();
|
||||
|
||||
instance.passedElement.triggerEvent = passedElementTriggerEventStub;
|
||||
|
@ -465,24 +471,26 @@ describe('choices', () => {
|
|||
expect(output).to.eql(instance);
|
||||
});
|
||||
|
||||
it('closes containerOuter', (done) => {
|
||||
it('closes containerOuter', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(containerOuterCloseSpy.called).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('hides dropdown with blurInput flag', (done) => {
|
||||
it('hides dropdown with blurInput flag', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(dropdownHideSpy.called).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('triggers event on passedElement', (done) => {
|
||||
it('triggers event on passedElement', done => {
|
||||
requestAnimationFrame(() => {
|
||||
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({});
|
||||
done();
|
||||
});
|
||||
|
@ -495,14 +503,14 @@ describe('choices', () => {
|
|||
output = instance.hideDropdown(true);
|
||||
});
|
||||
|
||||
it('removes active descendants', (done) => {
|
||||
it('removes active descendants', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(inputRemoveActiveDescendantSpy.called).to.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('blurs input', (done) => {
|
||||
it('blurs input', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(inputBlurSpy.called).to.equal(true);
|
||||
done();
|
||||
|
@ -624,7 +632,9 @@ describe('choices', () => {
|
|||
|
||||
it('triggers event with null groupValue', () => {
|
||||
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({
|
||||
id: item.id,
|
||||
value: item.value,
|
||||
|
@ -642,7 +652,9 @@ describe('choices', () => {
|
|||
|
||||
it('triggers event with groupValue', () => {
|
||||
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({
|
||||
id: item.id,
|
||||
value: item.value,
|
||||
|
@ -658,7 +670,7 @@ describe('choices', () => {
|
|||
output = instance.highlightItem(item, false);
|
||||
});
|
||||
|
||||
it('doesn\'t trigger event', () => {
|
||||
it("doesn't trigger event", () => {
|
||||
expect(passedElementTriggerEventStub.called).to.equal(false);
|
||||
});
|
||||
|
||||
|
@ -735,7 +747,9 @@ describe('choices', () => {
|
|||
|
||||
it('triggers event with null groupValue', () => {
|
||||
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({
|
||||
id: item.id,
|
||||
value: item.value,
|
||||
|
@ -753,7 +767,9 @@ describe('choices', () => {
|
|||
|
||||
it('triggers event with groupValue', () => {
|
||||
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({
|
||||
id: item.id,
|
||||
value: item.value,
|
||||
|
@ -769,7 +785,7 @@ describe('choices', () => {
|
|||
output = instance.highlightItem(item, false);
|
||||
});
|
||||
|
||||
it('doesn\'t trigger event', () => {
|
||||
it("doesn't trigger event", () => {
|
||||
expect(passedElementTriggerEventStub.called).to.equal(false);
|
||||
});
|
||||
|
||||
|
@ -1005,7 +1021,7 @@ describe('choices', () => {
|
|||
|
||||
returnsInstance(output);
|
||||
|
||||
it('sets loading state', (done) => {
|
||||
it('sets loading state', done => {
|
||||
requestAnimationFrame(() => {
|
||||
expect(handleLoadingStateStub.called).to.equal(true);
|
||||
done();
|
||||
|
@ -1108,15 +1124,14 @@ describe('choices', () => {
|
|||
|
||||
it('sets each choice with same value', () => {
|
||||
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', () => {
|
||||
const values = [
|
||||
'Value 1',
|
||||
'Value 2',
|
||||
];
|
||||
const values = ['Value 1', 'Value 2'];
|
||||
|
||||
beforeEach(() => {
|
||||
output = instance.setChoiceByValue(values);
|
||||
|
@ -1126,8 +1141,12 @@ describe('choices', () => {
|
|||
|
||||
it('sets each choice with same value', () => {
|
||||
expect(findAndSelectChoiceByValueStub.callCount).to.equal(2);
|
||||
expect(findAndSelectChoiceByValueStub.firstCall.args[0]).to.equal(values[0]);
|
||||
expect(findAndSelectChoiceByValueStub.secondCall.args[0]).to.equal(values[1]);
|
||||
expect(findAndSelectChoiceByValueStub.firstCall.args[0]).to.equal(
|
||||
values[0],
|
||||
);
|
||||
expect(findAndSelectChoiceByValueStub.secondCall.args[0]).to.equal(
|
||||
values[1],
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1173,7 +1192,7 @@ describe('choices', () => {
|
|||
});
|
||||
|
||||
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(() => {
|
||||
highlightedActiveItemsStub = stub(instance._store, 'highlightedActiveItems').get(() => items);
|
||||
highlightedActiveItemsStub = stub(
|
||||
instance._store,
|
||||
'highlightedActiveItems',
|
||||
).get(() => items);
|
||||
removeItemStub = stub();
|
||||
triggerChangeStub = stub();
|
||||
|
||||
|
@ -1557,7 +1578,9 @@ describe('choices', () => {
|
|||
|
||||
expect(output).to.be.instanceOf(DocumentFragment);
|
||||
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);
|
||||
|
||||
expect(output).to.be.instanceOf(DocumentFragment);
|
||||
expect(elementToWrapFragment.querySelectorAll('[data-group]').length).to.equal(2);
|
||||
expect(
|
||||
elementToWrapFragment.querySelectorAll('[data-group]').length,
|
||||
).to.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export default class Container {
|
|||
|
||||
/**
|
||||
* Add event listeners
|
||||
*/
|
||||
*/
|
||||
addEventListeners() {
|
||||
this.element.addEventListener('focus', this._onFocus);
|
||||
this.element.addEventListener('blur', this._onBlur);
|
||||
|
@ -24,7 +24,7 @@ export default class Container {
|
|||
|
||||
/**
|
||||
* Remove event listeners
|
||||
*/
|
||||
*/
|
||||
|
||||
/** */
|
||||
removeEventListeners() {
|
||||
|
@ -138,10 +138,7 @@ export default class Container {
|
|||
|
||||
unwrap(element) {
|
||||
// Move passed element outside this element
|
||||
this.element.parentNode.insertBefore(
|
||||
element,
|
||||
this.element,
|
||||
);
|
||||
this.element.parentNode.insertBefore(element, this.element);
|
||||
// Remove this element
|
||||
this.element.parentNode.removeChild(this.element);
|
||||
}
|
||||
|
|
|
@ -139,21 +139,32 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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';
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(null);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
||||
null,
|
||||
);
|
||||
instance.setActiveDescendant(activeDescendantID);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
||||
activeDescendantID,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeActiveDescendant', () => {
|
||||
it('remove elememnt\'s aria-activedescendant attribute', () => {
|
||||
it("remove elememnt's aria-activedescendant attribute", () => {
|
||||
const activeDescendantID = '1234';
|
||||
instance.element.setAttribute('aria-activedescendant', activeDescendantID);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID);
|
||||
instance.element.setAttribute(
|
||||
'aria-activedescendant',
|
||||
activeDescendantID,
|
||||
);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
||||
activeDescendantID,
|
||||
);
|
||||
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', () => {
|
||||
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', () => {
|
||||
|
@ -188,7 +201,9 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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', () => {
|
||||
|
@ -203,7 +218,9 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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', () => {
|
||||
|
@ -221,7 +238,9 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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', () => {
|
||||
|
@ -264,9 +283,13 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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();
|
||||
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', () => {
|
||||
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState)).to.equal(true);
|
||||
expect(
|
||||
instance.element.classList.contains(DEFAULT_CLASSNAMES.focusState),
|
||||
).to.equal(true);
|
||||
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', () => {
|
||||
expect(instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState)).to.equal(true);
|
||||
expect(
|
||||
instance.element.classList.contains(DEFAULT_CLASSNAMES.disabledState),
|
||||
).to.equal(true);
|
||||
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', () => {
|
||||
|
@ -322,9 +353,13 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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();
|
||||
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', () => {
|
||||
|
@ -366,7 +401,9 @@ describe('components/container', () => {
|
|||
it('wraps passed element inside element', () => {
|
||||
expect(instance.element.querySelector('div#wrap-test')).to.equal(null);
|
||||
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', () => {
|
||||
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);
|
||||
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', () => {
|
||||
|
@ -404,9 +445,13 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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();
|
||||
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', () => {
|
||||
|
@ -428,9 +473,13 @@ describe('components/container', () => {
|
|||
});
|
||||
|
||||
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();
|
||||
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', () => {
|
||||
|
|
|
@ -12,7 +12,9 @@ export default class Dropdown {
|
|||
*/
|
||||
distanceFromTopWindow() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,9 @@ describe('components/dropdown', () => {
|
|||
width: 0,
|
||||
};
|
||||
|
||||
getBoundingClientRectStub = sinon.stub(instance.element, 'getBoundingClientRect').returns(dimensions);
|
||||
getBoundingClientRectStub = sinon
|
||||
.stub(instance.element, 'getBoundingClientRect')
|
||||
.returns(dimensions);
|
||||
|
||||
window.pageYOffset = 50;
|
||||
});
|
||||
|
@ -107,7 +109,9 @@ describe('components/dropdown', () => {
|
|||
});
|
||||
|
||||
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', () => {
|
||||
|
@ -135,7 +139,9 @@ describe('components/dropdown', () => {
|
|||
});
|
||||
|
||||
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', () => {
|
||||
|
|
|
@ -5,11 +5,4 @@ import List from './list';
|
|||
import WrappedInput from './wrapped-input';
|
||||
import WrappedSelect from './wrapped-select';
|
||||
|
||||
export {
|
||||
Dropdown,
|
||||
Container,
|
||||
Input,
|
||||
List,
|
||||
WrappedInput,
|
||||
WrappedSelect,
|
||||
};
|
||||
export { Dropdown, Container, Input, List, WrappedInput, WrappedSelect };
|
||||
|
|
|
@ -92,7 +92,7 @@ export default class Input {
|
|||
// length than 75% of the placeholder. This stops the input jumping around.
|
||||
if (
|
||||
(this.element.value &&
|
||||
this.element.value.length >= (this._placeholderValue.length / 1.25)) ||
|
||||
this.element.value.length >= this._placeholderValue.length / 1.25) ||
|
||||
enforceWidth
|
||||
) {
|
||||
this.element.style.width = this.calcWidth();
|
||||
|
|
|
@ -86,7 +86,6 @@ describe('components/input', () => {
|
|||
setWidthStub.restore();
|
||||
});
|
||||
|
||||
|
||||
describe('when element is select one', () => {
|
||||
it('does not set input width', () => {
|
||||
instance.type = 'select-one';
|
||||
|
@ -207,7 +206,6 @@ describe('components/input', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('blur', () => {
|
||||
let blurStub;
|
||||
|
||||
|
@ -220,7 +218,7 @@ describe('components/input', () => {
|
|||
});
|
||||
|
||||
describe('when element is not focussed', () => {
|
||||
it('doesn\'t blur element', () => {
|
||||
it("doesn't blur element", () => {
|
||||
instance.isFocussed = false;
|
||||
instance.blur();
|
||||
expect(blurStub.callCount).to.equal(0);
|
||||
|
@ -247,14 +245,14 @@ describe('components/input', () => {
|
|||
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';
|
||||
expect(instance.element.value).to.equal('test');
|
||||
instance.clear();
|
||||
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);
|
||||
instance.clear(true);
|
||||
expect(setWidthStub.callCount).to.equal(1);
|
||||
|
@ -350,21 +348,32 @@ describe('components/input', () => {
|
|||
});
|
||||
|
||||
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';
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(null);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
||||
null,
|
||||
);
|
||||
instance.setActiveDescendant(activeDescendantID);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
||||
activeDescendantID,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeActiveDescendant', () => {
|
||||
it('remove elememnt\'s aria-activedescendant attribute', () => {
|
||||
it("remove elememnt's aria-activedescendant attribute", () => {
|
||||
const activeDescendantID = '1234';
|
||||
instance.element.setAttribute('aria-activedescendant', activeDescendantID);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(activeDescendantID);
|
||||
instance.element.setAttribute(
|
||||
'aria-activedescendant',
|
||||
activeDescendantID,
|
||||
);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
||||
activeDescendantID,
|
||||
);
|
||||
instance.removeActiveDescendant();
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(null);
|
||||
expect(instance.element.getAttribute('aria-activedescendant')).to.equal(
|
||||
null,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class List {
|
|||
/**
|
||||
* Find element that matches passed selector
|
||||
* @return {HTMLElement}
|
||||
*/
|
||||
*/
|
||||
getChild(selector) {
|
||||
return this.element.querySelector(selector);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('components/list', () => {
|
|||
});
|
||||
|
||||
describe('clear', () => {
|
||||
it('clears element\'s inner HTML', () => {
|
||||
it("clears element's inner HTML", () => {
|
||||
const innerHTML = 'test';
|
||||
instance.element.innerHTML = innerHTML;
|
||||
expect(instance.element.innerHTML).to.equal(innerHTML);
|
||||
|
@ -59,11 +59,12 @@ describe('components/list', () => {
|
|||
elementToAppend.classList.add(childClass);
|
||||
expect(instance.element.querySelector(`.${childClass}`)).to.equal(null);
|
||||
instance.append(elementToAppend);
|
||||
expect(instance.element.querySelector(`.${childClass}`)).to.equal(elementToAppend);
|
||||
expect(instance.element.querySelector(`.${childClass}`)).to.equal(
|
||||
elementToAppend,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('getChild', () => {
|
||||
let childElement;
|
||||
const childClass = 'test-element';
|
||||
|
|
|
@ -10,7 +10,7 @@ describe('components/wrappedElement', () => {
|
|||
element = document.createElement('select');
|
||||
instance = new WrappedElement({
|
||||
element,
|
||||
classNames: DEFAULT_CLASSNAMES,
|
||||
classNames: DEFAULT_CLASSNAMES
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -50,11 +50,17 @@ describe('components/wrappedElement', () => {
|
|||
it('hides element', () => {
|
||||
instance.conceal();
|
||||
expect(instance.element.tabIndex).to.equal(-1);
|
||||
expect(instance.element.classList.contains(instance.classNames.input)).to.equal(true);
|
||||
expect(instance.element.classList.contains(instance.classNames.hiddenState)).to.equal(true);
|
||||
expect(
|
||||
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('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', () => {
|
||||
instance.reveal();
|
||||
expect(instance.element.tabIndex).to.equal(0);
|
||||
expect(instance.element.classList.contains(instance.classNames.input)).to.equal(false);
|
||||
expect(instance.element.classList.contains(instance.classNames.hiddenState)).to.equal(false);
|
||||
expect(
|
||||
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('aria-hidden')).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', () => {
|
||||
it('fires event on element using passed eventType and data', (done) => {
|
||||
it('fires event on element using passed eventType and data', done => {
|
||||
const data = {
|
||||
test: true,
|
||||
test: true
|
||||
};
|
||||
|
||||
instance.element.addEventListener('testEvent', ({ detail }) => {
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('components/wrappedInput', () => {
|
|||
});
|
||||
|
||||
describe('inherited methods', () => {
|
||||
['conceal', 'reveal', 'enable', 'disable'].forEach((method) => {
|
||||
['conceal', 'reveal', 'enable', 'disable'].forEach(method => {
|
||||
describe(method, () => {
|
||||
beforeEach(() => {
|
||||
stub(WrappedElement.prototype, method);
|
||||
|
@ -72,7 +72,9 @@ describe('components/wrappedInput', () => {
|
|||
it('sets delimited value of element based on passed data', () => {
|
||||
expect(instance.element.value).to.equal('');
|
||||
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`,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ export default class WrappedSelect extends WrappedElement {
|
|||
|
||||
set options(options) {
|
||||
const fragment = document.createDocumentFragment();
|
||||
const addOptionToFragment = (data) => {
|
||||
const addOptionToFragment = data => {
|
||||
// Create a standard select option
|
||||
const template = templates.option(data);
|
||||
// Append it to fragment
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('components/wrappedSelect', () => {
|
|||
});
|
||||
|
||||
describe('inherited methods', () => {
|
||||
['conceal', 'reveal', 'enable', 'disable'].forEach((method) => {
|
||||
['conceal', 'reveal', 'enable', 'disable'].forEach(method => {
|
||||
beforeEach(() => {
|
||||
stub(WrappedElement.prototype, method);
|
||||
});
|
||||
|
@ -76,7 +76,7 @@ describe('components/wrappedSelect', () => {
|
|||
it('returns all option elements', () => {
|
||||
const { options } = instance;
|
||||
expect(options).to.be.an('array');
|
||||
options.forEach((option) => {
|
||||
options.forEach(option => {
|
||||
expect(option).to.be.instanceOf(HTMLOptionElement);
|
||||
});
|
||||
});
|
||||
|
@ -91,7 +91,7 @@ describe('components/wrappedSelect', () => {
|
|||
|
||||
const { optionGroups } = instance;
|
||||
expect(optionGroups.length).to.equal(3);
|
||||
optionGroups.forEach((option) => {
|
||||
optionGroups.forEach(option => {
|
||||
expect(option).to.be.instanceOf(HTMLOptGroupElement);
|
||||
});
|
||||
});
|
||||
|
@ -141,9 +141,13 @@ describe('components/wrappedSelect', () => {
|
|||
|
||||
describe('appendDocFragment', () => {
|
||||
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());
|
||||
expect(instance.element.getElementsByTagName('option').length).to.equal(0);
|
||||
expect(instance.element.getElementsByTagName('option').length).to.equal(
|
||||
0,
|
||||
);
|
||||
});
|
||||
|
||||
it('appends passed fragment to element', () => {
|
||||
|
@ -153,7 +157,9 @@ describe('components/wrappedSelect', () => {
|
|||
fragment.appendChild(elementToAppend);
|
||||
expect(instance.element.querySelector('#fragment-target')).to.equal(null);
|
||||
instance.appendDocFragment(fragment);
|
||||
expect(instance.element.querySelector('#fragment-target')).to.eql(elementToAppend);
|
||||
expect(instance.element.querySelector('#fragment-target')).to.eql(
|
||||
elementToAppend,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -65,7 +65,7 @@ export const DEFAULT_CONFIG = {
|
|||
uniqueItemText: 'Only unique values can be added.',
|
||||
addItemText: value => `Press Enter to add <b>"${stripHTML(value)}"</b>`,
|
||||
maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`,
|
||||
itemComparer: (choice, item) => (choice === item),
|
||||
itemComparer: (choice, item) => choice === item,
|
||||
fuseOptions: {
|
||||
includeScore: true,
|
||||
},
|
||||
|
|
|
@ -140,7 +140,7 @@ describe('constants', () => {
|
|||
});
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -43,11 +43,7 @@ describe('utils', () => {
|
|||
];
|
||||
|
||||
it('returns an array of item values', () => {
|
||||
const expectedResponse = [
|
||||
items[0].value,
|
||||
items[1].value,
|
||||
items[2].value,
|
||||
];
|
||||
const expectedResponse = [items[0].value, items[1].value, items[2].value];
|
||||
|
||||
const actualResponse = reduceToValues(items);
|
||||
expect(actualResponse).to.eql(expectedResponse);
|
||||
|
|
|
@ -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)
|
||||
An active choice appears within the choice dropdown
|
||||
*/
|
||||
return [...state, {
|
||||
id: action.id,
|
||||
elementId: action.elementId,
|
||||
groupId: action.groupId,
|
||||
value: action.value,
|
||||
label: (action.label || action.value),
|
||||
disabled: (action.disabled || false),
|
||||
selected: false,
|
||||
active: true,
|
||||
score: 9999,
|
||||
customProperties: action.customProperties,
|
||||
placeholder: (action.placeholder || false),
|
||||
keyCode: null,
|
||||
}];
|
||||
return [
|
||||
...state,
|
||||
{
|
||||
id: action.id,
|
||||
elementId: action.elementId,
|
||||
groupId: action.groupId,
|
||||
value: action.value,
|
||||
label: action.label || action.value,
|
||||
disabled: action.disabled || false,
|
||||
selected: false,
|
||||
active: true,
|
||||
score: 9999,
|
||||
customProperties: action.customProperties,
|
||||
placeholder: action.placeholder || false,
|
||||
keyCode: null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
case 'ADD_ITEM': {
|
||||
// If all choices need to be activated
|
||||
if (action.activateOptions) {
|
||||
return state.map((obj) => {
|
||||
return state.map(obj => {
|
||||
const choice = obj;
|
||||
choice.active = action.active;
|
||||
return choice;
|
||||
|
@ -37,7 +40,7 @@ export default function choices(state = defaultState, action) {
|
|||
// When an item is added and it has an associated choice,
|
||||
// we want to disable it so it can't be chosen again
|
||||
if (action.choiceId > -1) {
|
||||
return state.map((obj) => {
|
||||
return state.map(obj => {
|
||||
const choice = obj;
|
||||
if (choice.id === parseInt(action.choiceId, 10)) {
|
||||
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,
|
||||
// we want to re-enable it so it can be chosen again
|
||||
if (action.choiceId > -1) {
|
||||
return state.map((obj) => {
|
||||
return state.map(obj => {
|
||||
const choice = obj;
|
||||
if (choice.id === parseInt(action.choiceId, 10)) {
|
||||
choice.selected = false;
|
||||
|
@ -66,7 +69,7 @@ export default function choices(state = defaultState, action) {
|
|||
}
|
||||
|
||||
case 'FILTER_CHOICES': {
|
||||
return state.map((obj) => {
|
||||
return state.map(obj => {
|
||||
const choice = obj;
|
||||
// Set active state based on whether choice is
|
||||
// within filtered results
|
||||
|
@ -83,7 +86,7 @@ export default function choices(state = defaultState, action) {
|
|||
}
|
||||
|
||||
case 'ACTIVATE_CHOICES': {
|
||||
return state.map((obj) => {
|
||||
return state.map(obj => {
|
||||
const choice = obj;
|
||||
choice.active = action.active;
|
||||
return choice;
|
||||
|
|
|
@ -174,15 +174,16 @@ describe('reducers/choices', () => {
|
|||
score,
|
||||
};
|
||||
|
||||
|
||||
const actualResponse = choices(state, {
|
||||
type: 'FILTER_CHOICES',
|
||||
results: [{
|
||||
item: {
|
||||
id,
|
||||
results: [
|
||||
{
|
||||
item: {
|
||||
id,
|
||||
},
|
||||
score,
|
||||
},
|
||||
score,
|
||||
}],
|
||||
],
|
||||
}).find(choice => choice.id === id);
|
||||
|
||||
expect(actualResponse).to.eql(expectedResponse);
|
||||
|
|
|
@ -3,12 +3,15 @@ export const defaultState = [];
|
|||
export default function groups(state = defaultState, action) {
|
||||
switch (action.type) {
|
||||
case 'ADD_GROUP': {
|
||||
return [...state, {
|
||||
id: action.id,
|
||||
value: action.value,
|
||||
active: action.active,
|
||||
disabled: action.disabled,
|
||||
}];
|
||||
return [
|
||||
...state,
|
||||
{
|
||||
id: action.id,
|
||||
value: action.value,
|
||||
active: action.active,
|
||||
disabled: action.disabled,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
case 'CLEAR_CHOICES': {
|
||||
|
|
|
@ -4,20 +4,23 @@ export default function items(state = defaultState, action) {
|
|||
switch (action.type) {
|
||||
case 'ADD_ITEM': {
|
||||
// Add object to items array
|
||||
const newState = [...state, {
|
||||
id: action.id,
|
||||
choiceId: action.choiceId,
|
||||
groupId: action.groupId,
|
||||
value: action.value,
|
||||
label: action.label,
|
||||
active: true,
|
||||
highlighted: false,
|
||||
customProperties: action.customProperties,
|
||||
placeholder: (action.placeholder || false),
|
||||
keyCode: null,
|
||||
}];
|
||||
const newState = [
|
||||
...state,
|
||||
{
|
||||
id: action.id,
|
||||
choiceId: action.choiceId,
|
||||
groupId: action.groupId,
|
||||
value: action.value,
|
||||
label: action.label,
|
||||
active: true,
|
||||
highlighted: false,
|
||||
customProperties: action.customProperties,
|
||||
placeholder: action.placeholder || false,
|
||||
keyCode: null,
|
||||
},
|
||||
];
|
||||
|
||||
return newState.map((obj) => {
|
||||
return newState.map(obj => {
|
||||
const item = obj;
|
||||
item.highlighted = false;
|
||||
return item;
|
||||
|
@ -26,7 +29,7 @@ export default function items(state = defaultState, action) {
|
|||
|
||||
case 'REMOVE_ITEM': {
|
||||
// Set item to inactive
|
||||
return state.map((obj) => {
|
||||
return state.map(obj => {
|
||||
const item = obj;
|
||||
if (item.id === action.id) {
|
||||
item.active = false;
|
||||
|
@ -36,7 +39,7 @@ export default function items(state = defaultState, action) {
|
|||
}
|
||||
|
||||
case 'HIGHLIGHT_ITEM': {
|
||||
return state.map((obj) => {
|
||||
return state.map(obj => {
|
||||
const item = obj;
|
||||
if (item.id === action.id) {
|
||||
item.highlighted = action.highlighted;
|
||||
|
|
|
@ -56,7 +56,7 @@ describe('reducers/items', () => {
|
|||
});
|
||||
|
||||
it('unhighlights all highlighted items', () => {
|
||||
actualResponse.forEach((item) => {
|
||||
actualResponse.forEach(item => {
|
||||
expect(item.highlighted).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,9 +5,7 @@ export default class Store {
|
|||
constructor() {
|
||||
this._store = createStore(
|
||||
rootReducer,
|
||||
window.devToolsExtension ?
|
||||
window.devToolsExtension() :
|
||||
undefined,
|
||||
window.devToolsExtension ? window.devToolsExtension() : undefined,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -54,9 +52,9 @@ export default class Store {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get highlighted items from store
|
||||
* @return {Array} Item objects
|
||||
*/
|
||||
* Get highlighted items from store
|
||||
* @return {Array} Item objects
|
||||
*/
|
||||
get highlightedActiveItems() {
|
||||
return this.items.filter(item => item.active && item.highlighted);
|
||||
}
|
||||
|
@ -122,10 +120,10 @@ export default class Store {
|
|||
const groups = this.groups;
|
||||
const choices = this.choices;
|
||||
|
||||
return groups.filter((group) => {
|
||||
return groups.filter(group => {
|
||||
const isActive = group.active === true && group.disabled === false;
|
||||
const hasActiveOptions = choices.some(choice =>
|
||||
choice.active === true && choice.disabled === false,
|
||||
const hasActiveOptions = choices.some(
|
||||
choice => choice.active === true && choice.disabled === false,
|
||||
);
|
||||
return isActive && hasActiveOptions;
|
||||
}, []);
|
||||
|
@ -138,7 +136,9 @@ export default class Store {
|
|||
getChoiceById(id) {
|
||||
if (id) {
|
||||
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 false;
|
||||
|
|
|
@ -21,7 +21,6 @@ describe('reducers/store', () => {
|
|||
getStateStub.restore();
|
||||
});
|
||||
|
||||
|
||||
describe('constructor', () => {
|
||||
it('creates redux store', () => {
|
||||
expect(instance._store).to.contain.keys([
|
||||
|
@ -32,7 +31,6 @@ describe('reducers/store', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('subscribe', () => {
|
||||
it('wraps redux subscribe method', () => {
|
||||
const onChange = () => {};
|
||||
|
@ -163,14 +161,16 @@ describe('reducers/store', () => {
|
|||
|
||||
describe('activeItems getter', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
describe('highlightedActiveItems getter', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
@ -184,21 +184,25 @@ describe('reducers/store', () => {
|
|||
|
||||
describe('activeChoices getter', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectableChoices getter', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchableChoices getter', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
@ -207,7 +211,9 @@ describe('reducers/store', () => {
|
|||
describe('passing id', () => {
|
||||
it('returns active choice by passed id', () => {
|
||||
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);
|
||||
expect(actualResponse).to.eql(expectedResponse);
|
||||
});
|
||||
|
@ -223,7 +229,9 @@ describe('reducers/store', () => {
|
|||
|
||||
describe('placeholderChoice getter', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
@ -245,7 +253,9 @@ describe('reducers/store', () => {
|
|||
describe('getGroupById', () => {
|
||||
it('returns group by id', () => {
|
||||
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);
|
||||
expect(actualResponse).to.eql(expectedResponse);
|
||||
});
|
||||
|
|
|
@ -39,13 +39,10 @@ export const TEMPLATES = {
|
|||
`);
|
||||
},
|
||||
itemList(globalClasses, isSelectOneElement) {
|
||||
const localClasses = classNames(
|
||||
globalClasses.list,
|
||||
{
|
||||
[globalClasses.listSingle]: (isSelectOneElement),
|
||||
[globalClasses.listItems]: (!isSelectOneElement),
|
||||
},
|
||||
);
|
||||
const localClasses = classNames(globalClasses.list, {
|
||||
[globalClasses.listSingle]: isSelectOneElement,
|
||||
[globalClasses.listItems]: !isSelectOneElement,
|
||||
});
|
||||
|
||||
return strToEl(`
|
||||
<div class="${localClasses}"></div>
|
||||
|
@ -62,22 +59,18 @@ export const TEMPLATES = {
|
|||
const ariaSelected = data.active ? 'aria-selected="true"' : '';
|
||||
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
|
||||
|
||||
let localClasses = classNames(
|
||||
globalClasses.item, {
|
||||
[globalClasses.highlightedState]: data.highlighted,
|
||||
[globalClasses.itemSelectable]: !data.highlighted,
|
||||
[globalClasses.placeholder]: data.placeholder,
|
||||
},
|
||||
);
|
||||
let localClasses = classNames(globalClasses.item, {
|
||||
[globalClasses.highlightedState]: data.highlighted,
|
||||
[globalClasses.itemSelectable]: !data.highlighted,
|
||||
[globalClasses.placeholder]: data.placeholder,
|
||||
});
|
||||
|
||||
if (removeItemButton) {
|
||||
localClasses = classNames(
|
||||
globalClasses.item, {
|
||||
[globalClasses.highlightedState]: data.highlighted,
|
||||
[globalClasses.itemSelectable]: !data.disabled,
|
||||
[globalClasses.placeholder]: data.placeholder,
|
||||
},
|
||||
);
|
||||
localClasses = classNames(globalClasses.item, {
|
||||
[globalClasses.highlightedState]: data.highlighted,
|
||||
[globalClasses.itemSelectable]: !data.disabled,
|
||||
[globalClasses.placeholder]: data.placeholder,
|
||||
});
|
||||
|
||||
return strToEl(`
|
||||
<div
|
||||
|
@ -116,9 +109,9 @@ export const TEMPLATES = {
|
|||
`);
|
||||
},
|
||||
choiceList(globalClasses, isSelectOneElement) {
|
||||
const ariaMultiSelectable = !isSelectOneElement ?
|
||||
'aria-multiselectable="true"' :
|
||||
'';
|
||||
const ariaMultiSelectable = !isSelectOneElement
|
||||
? 'aria-multiselectable="true"'
|
||||
: '';
|
||||
|
||||
return strToEl(`
|
||||
<div
|
||||
|
@ -132,11 +125,9 @@ export const TEMPLATES = {
|
|||
},
|
||||
choiceGroup(globalClasses, data) {
|
||||
const ariaDisabled = data.disabled ? 'aria-disabled="true"' : '';
|
||||
const localClasses = classNames(
|
||||
globalClasses.group, {
|
||||
[globalClasses.itemDisabled]: data.disabled,
|
||||
},
|
||||
);
|
||||
const localClasses = classNames(globalClasses.group, {
|
||||
[globalClasses.itemDisabled]: data.disabled,
|
||||
});
|
||||
|
||||
return strToEl(`
|
||||
<div
|
||||
|
@ -155,7 +146,8 @@ export const TEMPLATES = {
|
|||
const role = data.groupId > 0 ? 'role="treeitem"' : 'role="option"';
|
||||
const localClasses = classNames(
|
||||
globalClasses.item,
|
||||
globalClasses.itemChoice, {
|
||||
globalClasses.itemChoice,
|
||||
{
|
||||
[globalClasses.itemDisabled]: data.disabled,
|
||||
[globalClasses.itemSelectable]: !data.disabled,
|
||||
[globalClasses.placeholder]: data.placeholder,
|
||||
|
@ -169,9 +161,10 @@ export const TEMPLATES = {
|
|||
data-choice
|
||||
data-id="${data.id}"
|
||||
data-value="${data.value}"
|
||||
${data.disabled ?
|
||||
'data-choice-disabled aria-disabled="true"' :
|
||||
'data-choice-selectable'
|
||||
${
|
||||
data.disabled
|
||||
? 'data-choice-disabled aria-disabled="true"'
|
||||
: 'data-choice-selectable'
|
||||
}
|
||||
id="${data.elementId}"
|
||||
${role}
|
||||
|
@ -217,8 +210,8 @@ export const TEMPLATES = {
|
|||
globalClasses.item,
|
||||
globalClasses.itemChoice,
|
||||
{
|
||||
[globalClasses.noResults]: (type === 'no-results'),
|
||||
[globalClasses.noChoices]: (type === 'no-choices'),
|
||||
[globalClasses.noResults]: type === 'no-results',
|
||||
[globalClasses.noChoices]: type === 'no-choices',
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -230,7 +223,9 @@ export const TEMPLATES = {
|
|||
},
|
||||
option(data) {
|
||||
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>
|
||||
`);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,7 +2,8 @@ import { expect } from 'chai';
|
|||
import templates from './templates';
|
||||
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('containerOuter', () => {
|
||||
|
@ -41,7 +42,9 @@ describe('templates', () => {
|
|||
);
|
||||
|
||||
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(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(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(stripElement(actualOutput)).to.equal(stripElement(expectedOutput));
|
||||
expect(stripElement(actualOutput)).to.equal(
|
||||
stripElement(expectedOutput),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -148,7 +157,9 @@ describe('templates', () => {
|
|||
const classes = {
|
||||
containerInner: 'test',
|
||||
};
|
||||
const expectedOutput = strToEl(`<div class="${classes.containerInner}"></div>`);
|
||||
const expectedOutput = strToEl(
|
||||
`<div class="${classes.containerInner}"></div>`,
|
||||
);
|
||||
const actualOutput = templates.containerInner(classes);
|
||||
|
||||
expect(getType(actualOutput)).to.equal('HTMLDivElement');
|
||||
|
@ -165,21 +176,29 @@ describe('templates', () => {
|
|||
|
||||
describe('select one element', () => {
|
||||
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);
|
||||
|
||||
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', () => {
|
||||
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);
|
||||
|
||||
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 expectedOutput = strToEl(`
|
||||
<div class="${classes.placeholder}">${value}</div>`,
|
||||
);
|
||||
<div class="${classes.placeholder}">${value}</div>`);
|
||||
const actualOutput = templates.placeholder(classes, value);
|
||||
|
||||
expect(getType(actualOutput)).to.equal('HTMLDivElement');
|
||||
|
@ -222,7 +240,9 @@ describe('templates', () => {
|
|||
const actualOutput = templates.choiceList(classes, true);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}"
|
||||
class="${classes.item} ${classes.itemChoice} ${
|
||||
classes.itemSelectable
|
||||
}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -354,7 +382,9 @@ describe('templates', () => {
|
|||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
|
||||
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', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.itemDisabled}"
|
||||
class="${classes.item} ${classes.itemChoice} ${
|
||||
classes.itemDisabled
|
||||
}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -385,7 +417,9 @@ describe('templates', () => {
|
|||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
|
||||
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', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable} ${classes.placeholder}"
|
||||
class="${classes.item} ${classes.itemChoice} ${
|
||||
classes.itemSelectable
|
||||
} ${classes.placeholder}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -415,7 +451,9 @@ describe('templates', () => {
|
|||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
|
||||
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(() => {
|
||||
data = {
|
||||
...data,
|
||||
groupId: 1
|
||||
groupId: 1,
|
||||
};
|
||||
});
|
||||
|
||||
it('returns expected html', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div
|
||||
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable}"
|
||||
class="${classes.item} ${classes.itemChoice} ${
|
||||
classes.itemSelectable
|
||||
}"
|
||||
data-select-text="${itemSelectText}"
|
||||
data-choice
|
||||
data-id="${data.id}"
|
||||
|
@ -445,7 +485,9 @@ describe('templates', () => {
|
|||
const actualOutput = templates.choice(classes, data, itemSelectText);
|
||||
|
||||
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 = {
|
||||
list: 'test 1',
|
||||
listDropdown: 'test 2',
|
||||
}
|
||||
;
|
||||
};
|
||||
it('returns expected html', () => {
|
||||
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);
|
||||
|
||||
expect(getType(actualOutput)).to.equal('HTMLDivElement');
|
||||
|
@ -517,26 +562,34 @@ describe('templates', () => {
|
|||
describe('no results', () => {
|
||||
it('adds no results classname', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div class="${classes.item} ${classes.itemChoice} ${classes.noResults}">
|
||||
<div class="${classes.item} ${classes.itemChoice} ${
|
||||
classes.noResults
|
||||
}">
|
||||
${label}
|
||||
</div>
|
||||
`);
|
||||
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', () => {
|
||||
it('adds no choices classname', () => {
|
||||
const expectedOutput = strToEl(`
|
||||
<div class="${classes.item} ${classes.itemChoice} ${classes.noChoices}">
|
||||
<div class="${classes.item} ${classes.itemChoice} ${
|
||||
classes.noChoices
|
||||
}">
|
||||
${label}
|
||||
</div>
|
||||
`);
|
||||
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', () => {
|
||||
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);
|
||||
|
||||
expect(getType(actualOutput)).to.equal('HTMLOptionElement');
|
||||
|
|
Loading…
Reference in a new issue