diff --git a/.github/workflows/browsers.yml b/.github/workflows/browsers.yml index dc58f31..0dceed2 100644 --- a/.github/workflows/browsers.yml +++ b/.github/workflows/browsers.yml @@ -17,16 +17,16 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-latest, macOS-latest] + os: [windows-latest, macos-latest] browser: [ie, firefox, safari] exclude: # On Windows, run tests with only IE and Edge - os: windows-latest browser: safari # On macOS, run tests with only on safari - - os: macOS-latest + - os: macos-latest browser: ie - - os: macOS-latest + - os: macos-latest browser: chrome # Safari workaround is not working in Catalina - browser: safari @@ -77,7 +77,7 @@ jobs: - run: | brew cask install firefox brew install geckodriver - if: matrix.browser == 'firefox' && matrix.os == 'macOS-latest' + if: matrix.browser == 'firefox' && matrix.os == 'macos-latest' - run: echo "::add-path::$env:GeckoWebDriver" if: matrix.browser == 'firefox' && matrix.os == 'windows-latest' diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..28193ca --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v12.13.1 diff --git a/README.md b/README.md index 694130c..191849f 100644 --- a/README.md +++ b/README.md @@ -707,7 +707,7 @@ example.passedElement.element.addEventListener( ### addItem -**Arguments:** `id, value, label, groupValue, keyCode` +**Payload:** `id, value, label, customProperties, groupValue, keyCode` **Input types affected:** `text`, `select-one`, `select-multiple` @@ -715,7 +715,7 @@ example.passedElement.element.addEventListener( ### removeItem -**Arguments:** `id, value, label, groupValue` +**Payload:** `id, value, label, customProperties, groupValue` **Input types affected:** `text`, `select-one`, `select-multiple` @@ -723,7 +723,7 @@ example.passedElement.element.addEventListener( ### highlightItem -**Arguments:** `id, value, label, groupValue` +**Payload:** `id, value, label, groupValue` **Input types affected:** `text`, `select-multiple` @@ -731,7 +731,7 @@ example.passedElement.element.addEventListener( ### unhighlightItem -**Arguments:** `id, value, label, groupValue` +**Payload:** `id, value, label, groupValue` **Input types affected:** `text`, `select-multiple` @@ -739,7 +739,7 @@ example.passedElement.element.addEventListener( ### choice -**Arguments:** `choice` +**Payload:** `choice` **Input types affected:** `select-one`, `select-multiple` @@ -748,7 +748,7 @@ example.passedElement.element.addEventListener( ### change -**Arguments:** `value` +**Payload:** `value` **Input types affected:** `text`, `select-one`, `select-multiple` @@ -756,7 +756,7 @@ example.passedElement.element.addEventListener( ### search -**Arguments:** `value`, `resultCount` +**Payload:** `value`, `resultCount` **Input types affected:** `select-one`, `select-multiple` @@ -764,7 +764,7 @@ example.passedElement.element.addEventListener( ### showDropdown -**Arguments:** - +**Payload:** - **Input types affected:** `select-one`, `select-multiple` @@ -772,7 +772,7 @@ example.passedElement.element.addEventListener( ### hideDropdown -**Arguments:** - +**Payload:** - **Input types affected:** `select-one`, `select-multiple` @@ -780,7 +780,7 @@ example.passedElement.element.addEventListener( ### highlightChoice -**Arguments:** `el` +**Payload:** `el` **Input types affected:** `select-one`, `select-multiple` diff --git a/src/scripts/actions/items.js b/src/scripts/actions/items.js index b22d9dc..e280759 100644 --- a/src/scripts/actions/items.js +++ b/src/scripts/actions/items.js @@ -31,9 +31,9 @@ export const addItem = ({ }); /** - * @param {string} id - * @param {string} choiceId - * @returns {Action & { id: string, choiceId: string }} + * @param {number} id + * @param {number} choiceId + * @returns {Action & { id: number, choiceId: number }} */ export const removeItem = (id, choiceId) => ({ type: ACTION_TYPES.REMOVE_ITEM, @@ -42,9 +42,9 @@ export const removeItem = (id, choiceId) => ({ }); /** - * @param {string} id + * @param {number} id * @param {boolean} highlighted - * @returns {Action & { id: string, highlighted: boolean }} + * @returns {Action & { id: number, highlighted: boolean }} */ export const highlightItem = (id, highlighted) => ({ type: ACTION_TYPES.HIGHLIGHT_ITEM, diff --git a/src/scripts/choices.js b/src/scripts/choices.js index 99404c8..f9a71ef 100644 --- a/src/scripts/choices.js +++ b/src/scripts/choices.js @@ -456,7 +456,7 @@ class Choices { } /** - * @param {string[] | import('../../types/index').Choices.Item[]} items + * @param {string[] | Item[]} items */ setValue(items) { if (!this.initialised) { @@ -1625,6 +1625,7 @@ class Choices { this._handleChoiceAction(activeItems, item); } } + event.preventDefault(); } @@ -1859,39 +1860,26 @@ class Choices { value: passedValue, label: passedLabel, customProperties: passedCustomProperties, - groupValue: group && group.value ? group.value : undefined, + groupValue: group && group.value ? group.value : null, keyCode: passedKeyCode, }); - - return this; } + /** + * @param {Item} item + */ _removeItem(item) { - if (!item || !isType('Object', item)) { - return this; - } - - const { id, value, label, choiceId, groupId } = item; + const { id, value, label, customProperties, choiceId, groupId } = item; const group = groupId >= 0 ? this._store.getGroupById(groupId) : null; this._store.dispatch(removeItem(id, choiceId)); - - if (group && group.value) { - this.passedElement.triggerEvent(EVENTS.removeItem, { - id, - value, - label, - groupValue: group.value, - }); - } else { - this.passedElement.triggerEvent(EVENTS.removeItem, { - id, - value, - label, - }); - } - - return this; + this.passedElement.triggerEvent(EVENTS.removeItem, { + id, + value, + label, + customProperties, + groupValue: group && group.value ? group.value : null, + }); } _addChoice({ diff --git a/src/scripts/choices.test.js b/src/scripts/choices.test.js index 3c0b69b..f5c0bd1 100644 --- a/src/scripts/choices.test.js +++ b/src/scripts/choices.test.js @@ -5,6 +5,7 @@ import sinonChai from 'sinon-chai'; import Choices from './choices'; import { EVENTS, ACTION_TYPES, DEFAULT_CONFIG, KEY_CODES } from './constants'; import { WrappedSelect, WrappedInput } from './components/index'; +import { removeItem } from './actions/items'; chai.use(sinonChai); @@ -2155,5 +2156,93 @@ describe('choices', () => { }); }); }); + + describe('_removeItem', () => { + beforeEach(() => { + instance._store.dispatch = stub(); + }); + + afterEach(() => { + instance._store.dispatch.reset(); + }); + + describe('when given an item to remove', () => { + const item = { + id: 1111, + value: 'test value', + label: 'test label', + choiceId: 2222, + groupId: 3333, + customProperties: {}, + }; + + it('dispatches a REMOVE_ITEM action to the store', () => { + instance._removeItem(item); + + expect(instance._store.dispatch).to.have.been.calledWith( + removeItem(item.id, item.choiceId), + ); + }); + + it('triggers a REMOVE_ITEM event on the passed element', done => { + passedElement.addEventListener( + 'removeItem', + event => { + expect(event.detail).to.eql({ + id: item.id, + value: item.value, + label: item.label, + customProperties: item.customProperties, + groupValue: null, + }); + done(); + }, + false, + ); + + instance._removeItem(item); + }); + + describe('when the item belongs to a group', () => { + const group = { + id: 1, + value: 'testing', + }; + const itemWithGroup = { + ...item, + groupId: group.id, + }; + + beforeEach(() => { + instance._store.getGroupById = stub(); + instance._store.getGroupById.returns(group); + }); + + afterEach(() => { + instance._store.getGroupById.reset(); + }); + + it("includes the group's value in the triggered event", done => { + passedElement.addEventListener( + 'removeItem', + event => { + expect(event.detail).to.eql({ + id: itemWithGroup.id, + value: itemWithGroup.value, + label: itemWithGroup.label, + customProperties: itemWithGroup.customProperties, + groupValue: group.value, + }); + + done(); + }, + false, + ); + + instance._removeItem(itemWithGroup); + }); + }); + }); + }); }); });