diff --git a/.eslintrc b/.eslintrc index 855e546..c3cd957 100644 --- a/.eslintrc +++ b/.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" + }] } } diff --git a/package.json b/package.json index c6a091f..9c8e667 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/scripts/actions/choices.test.js b/src/scripts/actions/choices.test.js index 61457d6..755f2ec 100644 --- a/src/scripts/actions/choices.test.js +++ b/src/scripts/actions/choices.test.js @@ -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', () => { }); }); }); - diff --git a/src/scripts/actions/groups.test.js b/src/scripts/actions/groups.test.js index 815561f..56f860e 100644 --- a/src/scripts/actions/groups.test.js +++ b/src/scripts/actions/groups.test.js @@ -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, + ); }); }); }); diff --git a/src/scripts/actions/items.test.js b/src/scripts/actions/items.test.js index 887a76a..99dc350 100644 --- a/src/scripts/actions/items.test.js +++ b/src/scripts/actions/items.test.js @@ -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); }); }); diff --git a/src/scripts/choices.js b/src/scripts/choices.js index 61f68a3..b1c2bd7 100644 --- a/src/scripts/choices.js +++ b/src/scripts/choices.js @@ -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'); } diff --git a/src/scripts/choices.test.js b/src/scripts/choices.test.js index 2c09500..50ef0a8 100644 --- a/src/scripts/choices.test.js +++ b/src/scripts/choices.test.js @@ -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); }); }); diff --git a/src/scripts/components/container.js b/src/scripts/components/container.js index 549ec1c..e03bda9 100644 --- a/src/scripts/components/container.js +++ b/src/scripts/components/container.js @@ -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); } diff --git a/src/scripts/components/container.test.js b/src/scripts/components/container.test.js index cec84ae..f4be133 100644 --- a/src/scripts/components/container.test.js +++ b/src/scripts/components/container.test.js @@ -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', () => { diff --git a/src/scripts/components/dropdown.js b/src/scripts/components/dropdown.js index 0936ed0..b914a6b 100644 --- a/src/scripts/components/dropdown.js +++ b/src/scripts/components/dropdown.js @@ -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; } diff --git a/src/scripts/components/dropdown.test.js b/src/scripts/components/dropdown.test.js index 770f0de..900b5a8 100644 --- a/src/scripts/components/dropdown.test.js +++ b/src/scripts/components/dropdown.test.js @@ -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', () => { diff --git a/src/scripts/components/index.js b/src/scripts/components/index.js index 202c536..67d4e85 100644 --- a/src/scripts/components/index.js +++ b/src/scripts/components/index.js @@ -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 }; diff --git a/src/scripts/components/input.js b/src/scripts/components/input.js index 1a04d65..91ed36c 100644 --- a/src/scripts/components/input.js +++ b/src/scripts/components/input.js @@ -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(); diff --git a/src/scripts/components/input.test.js b/src/scripts/components/input.test.js index 315df99..dc24c28 100644 --- a/src/scripts/components/input.test.js +++ b/src/scripts/components/input.test.js @@ -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, + ); }); }); }); diff --git a/src/scripts/components/list.js b/src/scripts/components/list.js index eecb53c..2d66560 100644 --- a/src/scripts/components/list.js +++ b/src/scripts/components/list.js @@ -30,7 +30,7 @@ export default class List { /** * Find element that matches passed selector * @return {HTMLElement} - */ + */ getChild(selector) { return this.element.querySelector(selector); } diff --git a/src/scripts/components/list.test.js b/src/scripts/components/list.test.js index 574fd47..858f897 100644 --- a/src/scripts/components/list.test.js +++ b/src/scripts/components/list.test.js @@ -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'; diff --git a/src/scripts/components/wrapped-element.test.js b/src/scripts/components/wrapped-element.test.js index a4102fa..2b1c154 100644 --- a/src/scripts/components/wrapped-element.test.js +++ b/src/scripts/components/wrapped-element.test.js @@ -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 }) => { diff --git a/src/scripts/components/wrapped-input.test.js b/src/scripts/components/wrapped-input.test.js index d012927..48adf84 100644 --- a/src/scripts/components/wrapped-input.test.js +++ b/src/scripts/components/wrapped-input.test.js @@ -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`, + ); }); }); }); diff --git a/src/scripts/components/wrapped-select.js b/src/scripts/components/wrapped-select.js index 8c3bf69..f158681 100644 --- a/src/scripts/components/wrapped-select.js +++ b/src/scripts/components/wrapped-select.js @@ -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 diff --git a/src/scripts/components/wrapped-select.test.js b/src/scripts/components/wrapped-select.test.js index b85c64f..18fdc06 100644 --- a/src/scripts/components/wrapped-select.test.js +++ b/src/scripts/components/wrapped-select.test.js @@ -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, + ); }); }); }); diff --git a/src/scripts/constants.js b/src/scripts/constants.js index cb9535b..ba09816 100644 --- a/src/scripts/constants.js +++ b/src/scripts/constants.js @@ -65,7 +65,7 @@ export const DEFAULT_CONFIG = { uniqueItemText: 'Only unique values can be added.', addItemText: value => `Press Enter to add "${stripHTML(value)}"`, maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`, - itemComparer: (choice, item) => (choice === item), + itemComparer: (choice, item) => choice === item, fuseOptions: { includeScore: true, }, diff --git a/src/scripts/constants.test.js b/src/scripts/constants.test.js index 965202d..ca5bf6b 100644 --- a/src/scripts/constants.test.js +++ b/src/scripts/constants.test.js @@ -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'); }); }); diff --git a/src/scripts/lib/utils.test.js b/src/scripts/lib/utils.test.js index ad7a68a..a0036e2 100644 --- a/src/scripts/lib/utils.test.js +++ b/src/scripts/lib/utils.test.js @@ -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); diff --git a/src/scripts/reducers/choices.js b/src/scripts/reducers/choices.js index 72c4102..266b063 100644 --- a/src/scripts/reducers/choices.js +++ b/src/scripts/reducers/choices.js @@ -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; diff --git a/src/scripts/reducers/choices.test.js b/src/scripts/reducers/choices.test.js index 76ec175..9563f6c 100644 --- a/src/scripts/reducers/choices.test.js +++ b/src/scripts/reducers/choices.test.js @@ -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); diff --git a/src/scripts/reducers/groups.js b/src/scripts/reducers/groups.js index 5e77feb..d704e92 100644 --- a/src/scripts/reducers/groups.js +++ b/src/scripts/reducers/groups.js @@ -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': { diff --git a/src/scripts/reducers/items.js b/src/scripts/reducers/items.js index 96fdd9e..a119404 100644 --- a/src/scripts/reducers/items.js +++ b/src/scripts/reducers/items.js @@ -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; diff --git a/src/scripts/reducers/items.test.js b/src/scripts/reducers/items.test.js index eff3055..4041a3b 100644 --- a/src/scripts/reducers/items.test.js +++ b/src/scripts/reducers/items.test.js @@ -56,7 +56,7 @@ describe('reducers/items', () => { }); it('unhighlights all highlighted items', () => { - actualResponse.forEach((item) => { + actualResponse.forEach(item => { expect(item.highlighted).to.equal(false); }); }); diff --git a/src/scripts/store/store.js b/src/scripts/store/store.js index 2ddf594..32d3b35 100644 --- a/src/scripts/store/store.js +++ b/src/scripts/store/store.js @@ -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; diff --git a/src/scripts/store/store.test.js b/src/scripts/store/store.test.js index f9141a4..d8bb1d6 100644 --- a/src/scripts/store/store.test.js +++ b/src/scripts/store/store.test.js @@ -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); }); diff --git a/src/scripts/templates.js b/src/scripts/templates.js index 6ebb390..48e91a9 100644 --- a/src/scripts/templates.js +++ b/src/scripts/templates.js @@ -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(`
@@ -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(`
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(` - + `); }, }; diff --git a/src/scripts/templates.test.js b/src/scripts/templates.test.js index 21ab07e..40f840d 100644 --- a/src/scripts/templates.test.js +++ b/src/scripts/templates.test.js @@ -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(`
`); + const expectedOutput = strToEl( + `
`, + ); 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(`
`); + const expectedOutput = strToEl( + `
`, + ); 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(`
`); + const expectedOutput = strToEl( + `
`, + ); 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(` -
${value}
`, - ); +
${value}
`); 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(`
{ 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(`
{ 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(`
{ 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(`
{ 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(``); + const expectedOutput = strToEl( + ``, + ); 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(` -
+
${label}
`); 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(` -
+
${label}
`); 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(``); + const expectedOutput = strToEl( + ``, + ); const actualOutput = templates.option(data); expect(getType(actualOutput)).to.equal('HTMLOptionElement');