diff --git a/src/scripts/src/choices.js b/src/scripts/src/choices.js index 5d76da8..be87fdf 100644 --- a/src/scripts/src/choices.js +++ b/src/scripts/src/choices.js @@ -5,6 +5,7 @@ import Dropdown from './components/dropdown'; import Container from './components/container'; import Input from './components/input'; import List from './components/list'; +import { DEFAULT_CONFIG, DEFAULT_CLASSNAMES } from './constants'; import { addItem, removeItem, @@ -53,75 +54,11 @@ class Choices { } const defaultConfig = { - silent: false, + ...DEFAULT_CONFIG, items: [], choices: [], - renderChoiceLimit: -1, - maxItemCount: -1, - addItems: true, - removeItems: true, - removeItemButton: false, - editItems: false, - duplicateItems: true, - delimiter: ',', - paste: true, - searchEnabled: true, - searchChoices: true, - searchFloor: 1, - searchResultLimit: 4, - searchFields: ['label', 'value'], - position: 'auto', - resetScrollPosition: true, - regexFilter: null, - shouldSort: true, - shouldSortItems: false, + classNames: DEFAULT_CLASSNAMES, sortFilter: sortByAlpha, - placeholder: true, - placeholderValue: null, - searchPlaceholderValue: null, - prependValue: null, - appendValue: null, - renderSelectedChoices: 'auto', - loadingText: 'Loading...', - noResultsText: 'No results found', - noChoicesText: 'No choices to choose from', - itemSelectText: 'Press to select', - addItemText: value => `Press Enter to add "${value}"`, - maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`, - uniqueItemText: 'Only unique values can be added.', - classNames: { - containerOuter: 'choices', - containerInner: 'choices__inner', - input: 'choices__input', - inputCloned: 'choices__input--cloned', - list: 'choices__list', - listItems: 'choices__list--multiple', - listSingle: 'choices__list--single', - listDropdown: 'choices__list--dropdown', - item: 'choices__item', - itemSelectable: 'choices__item--selectable', - itemDisabled: 'choices__item--disabled', - itemChoice: 'choices__item--choice', - placeholder: 'choices__placeholder', - group: 'choices__group', - groupHeading: 'choices__heading', - button: 'choices__button', - activeState: 'is-active', - focusState: 'is-focused', - openState: 'is-open', - disabledState: 'is-disabled', - highlightedState: 'is-highlighted', - hiddenState: 'is-hidden', - flippedState: 'is-flipped', - loadingState: 'is-loading', - noResults: 'has-no-results', - noChoices: 'has-no-choices', - }, - fuseOptions: { - includeScore: true, - }, - callbackOnInit: null, - callbackOnCreateTemplates: null, }; this.idNames = { @@ -2570,11 +2507,11 @@ class Choices { const input = this._getTemplate('input'); const dropdown = this._getTemplate('dropdown'); - this.containerOuter = new Container(this, containerOuter); - this.containerInner = new Container(this, containerInner); - this.input = new Input(this, input); - this.choiceList = new List(this, choiceList); - this.itemList = new List(this, itemList); + this.containerOuter = new Container(this, containerOuter, this.config.classNames); + this.containerInner = new Container(this, containerInner, this.config.classNames); + this.input = new Input(this, input, this.config.classNames); + this.choiceList = new List(this, choiceList, this.config.classNames); + this.itemList = new List(this, itemList, this.config.classNames); this.dropdown = new Dropdown(this, dropdown, this.config.classNames); // Hide passed input diff --git a/src/scripts/src/components/container.js b/src/scripts/src/components/container.js index 8015a06..e124ca9 100644 --- a/src/scripts/src/components/container.js +++ b/src/scripts/src/components/container.js @@ -1,9 +1,9 @@ export default class Container { - constructor(instance, element) { + constructor(instance, element, classNames) { this.instance = instance; this.element = element; + this.classNames = classNames; this.config = instance.config; - this.classNames = instance.config.classNames; this.isOpen = false; this.isFlipped = false; this.isFocussed = false; diff --git a/src/scripts/src/components/container.test.js b/src/scripts/src/components/container.test.js index e69de29..df94aff 100644 --- a/src/scripts/src/components/container.test.js +++ b/src/scripts/src/components/container.test.js @@ -0,0 +1,32 @@ +import { expect } from 'chai'; +import Container from './container'; +import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from '../constants'; + +describe('Container', () => { + let instance; + let choicesInstance; + let choicesElement; + + + beforeEach(() => { + choicesInstance = { + config: { + ...DEFAULT_CONFIG, + }, + }; + choicesElement = document.createElement('select'); + instance = new Container(choicesInstance, choicesElement, DEFAULT_CLASSNAMES); + }); + + it('assigns choices instance to class', () => { + expect(instance.instance).to.eql(choicesInstance); + }); + + it('assigns choices element to class', () => { + expect(instance.element).to.eql(choicesElement); + }); + + it('assigns classnames to class', () => { + expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES); + }); +}); diff --git a/src/scripts/src/components/dropdown.test.js b/src/scripts/src/components/dropdown.test.js index e69de29..b147b13 100644 --- a/src/scripts/src/components/dropdown.test.js +++ b/src/scripts/src/components/dropdown.test.js @@ -0,0 +1,32 @@ +import { expect } from 'chai'; +import Dropdown from './dropdown'; +import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from '../constants'; + +describe('Dropdown', () => { + let instance; + let choicesInstance; + let choicesElement; + + + beforeEach(() => { + choicesInstance = { + config: { + ...DEFAULT_CONFIG, + }, + }; + choicesElement = document.createElement('select'); + instance = new Dropdown(choicesInstance, choicesElement, DEFAULT_CLASSNAMES); + }); + + it('assigns choices instance to class', () => { + expect(instance.instance).to.eql(choicesInstance); + }); + + it('assigns choices element to class', () => { + expect(instance.element).to.eql(choicesElement); + }); + + it('assigns classnames to class', () => { + expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES); + }); +}); diff --git a/src/scripts/src/components/input.js b/src/scripts/src/components/input.js index fcab558..9768ba9 100644 --- a/src/scripts/src/components/input.js +++ b/src/scripts/src/components/input.js @@ -1,9 +1,10 @@ import { getWidthOfInput } from '../lib/utils'; export default class Input { - constructor(instance, element) { + constructor(instance, element, classNames) { this.instance = instance; this.element = element; + this.classNames = classNames; this.isFocussed = this.element === document.activeElement; this.isDisabled = false; diff --git a/src/scripts/src/components/input.test.js b/src/scripts/src/components/input.test.js index e69de29..aedddf2 100644 --- a/src/scripts/src/components/input.test.js +++ b/src/scripts/src/components/input.test.js @@ -0,0 +1,32 @@ +import { expect } from 'chai'; +import Input from './input'; +import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from '../constants'; + +describe('Input', () => { + let instance; + let choicesInstance; + let choicesElement; + + + beforeEach(() => { + choicesInstance = { + config: { + ...DEFAULT_CONFIG, + }, + }; + choicesElement = document.createElement('select'); + instance = new Input(choicesInstance, choicesElement, DEFAULT_CLASSNAMES); + }); + + it('assigns choices instance to class', () => { + expect(instance.instance).to.eql(choicesInstance); + }); + + it('assigns choices element to class', () => { + expect(instance.element).to.eql(choicesElement); + }); + + it('assigns classnames to class', () => { + expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES); + }); +}); diff --git a/src/scripts/src/components/list.js b/src/scripts/src/components/list.js index 184347a..2263ac3 100644 --- a/src/scripts/src/components/list.js +++ b/src/scripts/src/components/list.js @@ -1,8 +1,8 @@ export default class List { - constructor(instance, element) { + constructor(instance, element, classNames) { this.instance = instance; this.element = element; - this.classNames = this.instance.config.classNames; + this.classNames = classNames; this.scrollPos = this.element.scrollTop; this.height = this.element.offsetHeight; this.hasChildren = !!this.element.children; diff --git a/src/scripts/src/components/list.test.js b/src/scripts/src/components/list.test.js index e69de29..4adae70 100644 --- a/src/scripts/src/components/list.test.js +++ b/src/scripts/src/components/list.test.js @@ -0,0 +1,32 @@ +import { expect } from 'chai'; +import List from './list'; +import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from '../constants'; + +describe('List', () => { + let instance; + let choicesInstance; + let choicesElement; + + + beforeEach(() => { + choicesInstance = { + config: { + ...DEFAULT_CONFIG, + }, + }; + choicesElement = document.createElement('select'); + instance = new List(choicesInstance, choicesElement, DEFAULT_CLASSNAMES); + }); + + it('assigns choices instance to class', () => { + expect(instance.instance).to.eql(choicesInstance); + }); + + it('assigns choices element to class', () => { + expect(instance.element).to.eql(choicesElement); + }); + + it('assigns classnames to class', () => { + expect(instance.classNames).to.eql(DEFAULT_CLASSNAMES); + }); +}); diff --git a/src/scripts/src/constants.js b/src/scripts/src/constants.js new file mode 100644 index 0000000..e1f899f --- /dev/null +++ b/src/scripts/src/constants.js @@ -0,0 +1,70 @@ + +export const DEFAULT_CLASSNAMES = { + containerOuter: 'choices', + containerInner: 'choices__inner', + input: 'choices__input', + inputCloned: 'choices__input--cloned', + list: 'choices__list', + listItems: 'choices__list--multiple', + listSingle: 'choices__list--single', + listDropdown: 'choices__list--dropdown', + item: 'choices__item', + itemSelectable: 'choices__item--selectable', + itemDisabled: 'choices__item--disabled', + itemChoice: 'choices__item--choice', + placeholder: 'choices__placeholder', + group: 'choices__group', + groupHeading: 'choices__heading', + button: 'choices__button', + activeState: 'is-active', + focusState: 'is-focused', + openState: 'is-open', + disabledState: 'is-disabled', + highlightedState: 'is-highlighted', + hiddenState: 'is-hidden', + flippedState: 'is-flipped', + loadingState: 'is-loading', + noResults: 'has-no-results', + noChoices: 'has-no-choices', +}; + +export const DEFAULT_CONFIG = { + silent: false, + renderChoiceLimit: -1, + maxItemCount: -1, + addItems: true, + removeItems: true, + removeItemButton: false, + editItems: false, + duplicateItems: true, + delimiter: ',', + paste: true, + searchEnabled: true, + searchChoices: true, + searchFloor: 1, + searchResultLimit: 4, + searchFields: ['label', 'value'], + position: 'auto', + resetScrollPosition: true, + regexFilter: null, + shouldSort: true, + shouldSortItems: false, + placeholder: true, + placeholderValue: null, + searchPlaceholderValue: null, + prependValue: null, + appendValue: null, + renderSelectedChoices: 'auto', + loadingText: 'Loading...', + noResultsText: 'No results found', + noChoicesText: 'No choices to choose from', + itemSelectText: 'Press to select', + addItemText: value => `Press Enter to add "${value}"`, + maxItemText: maxItemCount => `Only ${maxItemCount} values can be added.`, + uniqueItemText: 'Only unique values can be added.', + fuseOptions: { + includeScore: true, + }, + callbackOnInit: null, + callbackOnCreateTemplates: null, +};