Remove redundant check (#755)

* Remove redundant check

* Add integration tests covering fix

* Add missing test
This commit is contained in:
Josh Johnson 2019-11-13 15:40:47 +00:00 committed by GitHub
parent 84b952e115
commit 933ea6093f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 200 additions and 63 deletions

View File

@ -12,6 +12,30 @@ describe('Choices - select one', () => {
.click();
});
describe('focusing on container', () => {
describe('pressing enter key', () => {
it('toggles the dropdown', () => {
cy.get('[data-test-hook=basic]')
.find('.choices')
.focus()
.type('{enter}');
cy.get('[data-test-hook=basic]')
.find('.choices__list--dropdown')
.should('not.be.visible');
cy.get('[data-test-hook=basic]')
.find('.choices')
.focus()
.type('{enter}');
cy.get('[data-test-hook=basic]')
.find('.choices__list--dropdown')
.should('be.visible');
});
});
});
describe('focusing on text input', () => {
it('displays a dropdown of choices', () => {
cy.get('[data-test-hook=basic]')

View File

@ -1334,14 +1334,6 @@ var utils_wrap = function wrap(element, wrapper) {
return wrapper.appendChild(element);
};
/**
* @param {HTMLElement} el
* @param {string} attr
*/
var findAncestorByAttrName = function findAncestorByAttrName(el, attr) {
return el.closest("[" + attr + "]");
};
/**
* @param {Element} startEl
* @param {string} selector
@ -1474,14 +1466,6 @@ var dispatchEvent = function dispatchEvent(element, type, customArgs) {
});
return element.dispatchEvent(event);
};
/**
* @param {string} userAgent
* @returns {boolean}
*/
var isIE11 = function isIE11(userAgent) {
return !!(userAgent.match(/Trident/) && userAgent.match(/rv[ :]11/));
};
/**
* @param {array} array
* @param {any} value
@ -1875,6 +1859,7 @@ var DEFAULT_CLASSNAMES = {
openState: 'is-open',
disabledState: 'is-disabled',
highlightedState: 'is-highlighted',
selectedState: 'is-selected',
flippedState: 'is-flipped',
loadingState: 'is-loading',
noResults: 'has-no-results',
@ -2794,10 +2779,23 @@ function (_WrappedElement) {
* Helpers to create HTML elements used by Choices
* Can be overridden by providing `callbackOnCreateTemplates` option
* @typedef {import('../../types/index').Choices.Templates} Templates
* @typedef {import('../../types/index').Choices.ClassNames} ClassNames
* @typedef {import('../../types/index').Choices.Options} Options
* @typedef {import('../../types/index').Choices.Item} Item
* @typedef {import('../../types/index').Choices.Choice} Choice
* @typedef {import('../../types/index').Choices.Group} Group
*/
var TEMPLATES =
/** @type {Templates} */
{
/**
* @param {Partial<ClassNames>} classNames
* @param {"ltr" | "rtl" | "auto"} dir
* @param {boolean} isSelectElement
* @param {boolean} isSelectOneElement
* @param {boolean} searchEnabled
* @param {"select-one" | "select-multiple" | "text"} passedElementType
*/
containerOuter: function containerOuter(_ref, dir, isSelectElement, isSelectOneElement, searchEnabled, passedElementType) {
var _containerOuter = _ref.containerOuter;
var div = Object.assign(document.createElement('div'), {
@ -2825,12 +2823,21 @@ var TEMPLATES =
div.setAttribute('aria-expanded', 'false');
return div;
},
/**
* @param {Partial<ClassNames>} classNames
*/
containerInner: function containerInner(_ref2) {
var _containerInner = _ref2.containerInner;
return Object.assign(document.createElement('div'), {
className: _containerInner
});
},
/**
* @param {Partial<ClassNames>} classNames
* @param {boolean} isSelectOneElement
*/
itemList: function itemList(_ref3, isSelectOneElement) {
var list = _ref3.list,
listSingle = _ref3.listSingle,
@ -2839,6 +2846,11 @@ var TEMPLATES =
className: list + " " + (isSelectOneElement ? listSingle : listItems)
});
},
/**
* @param {Partial<ClassNames>} classNames
* @param {string} value
*/
placeholder: function placeholder(_ref4, value) {
var _placeholder = _ref4.placeholder;
return Object.assign(document.createElement('div'), {
@ -2846,6 +2858,12 @@ var TEMPLATES =
innerHTML: value
});
},
/**
* @param {Partial<ClassNames>} classNames
* @param {Item} item
* @param {boolean} removeItemButton
*/
item: function item(_ref5, _ref6, removeItemButton) {
var _item = _ref5.item,
button = _ref5.button,
@ -2906,6 +2924,11 @@ var TEMPLATES =
return div;
},
/**
* @param {Partial<ClassNames>} classNames
* @param {boolean} isSelectOneElement
*/
choiceList: function choiceList(_ref7, isSelectOneElement) {
var list = _ref7.list;
var div = Object.assign(document.createElement('div'), {
@ -2919,6 +2942,11 @@ var TEMPLATES =
div.setAttribute('role', 'listbox');
return div;
},
/**
* @param {Partial<ClassNames>} classNames
* @param {Group} group
*/
choiceGroup: function choiceGroup(_ref8, _ref9) {
var group = _ref8.group,
groupHeading = _ref8.groupHeading,
@ -2946,10 +2974,17 @@ var TEMPLATES =
}));
return div;
},
/**
* @param {Partial<ClassNames>} classNames
* @param {Choice} choice
* @param {Options['itemSelectText']} selectText
*/
choice: function choice(_ref10, _ref11, selectText) {
var item = _ref10.item,
itemChoice = _ref10.itemChoice,
itemSelectable = _ref10.itemSelectable,
selectedState = _ref10.selectedState,
itemDisabled = _ref10.itemDisabled,
placeholder = _ref10.placeholder;
var id = _ref11.id,
@ -2957,13 +2992,23 @@ var TEMPLATES =
label = _ref11.label,
groupId = _ref11.groupId,
elementId = _ref11.elementId,
disabled = _ref11.disabled,
isDisabled = _ref11.disabled,
isSelected = _ref11.selected,
isPlaceholder = _ref11.placeholder;
var div = Object.assign(document.createElement('div'), {
id: elementId,
innerHTML: label,
className: item + " " + itemChoice + " " + (disabled ? itemDisabled : itemSelectable) + " " + (isPlaceholder ? placeholder : '')
className: item + " " + itemChoice
});
if (isSelected) {
div.classList.add(selectedState);
}
if (isPlaceholder) {
div.classList.add(placeholder);
}
div.setAttribute('role', groupId > 0 ? 'treeitem' : 'option');
Object.assign(div.dataset, {
choice: '',
@ -2972,15 +3017,22 @@ var TEMPLATES =
selectText: selectText
});
if (disabled) {
if (isDisabled) {
div.classList.add(itemDisabled);
div.dataset.choiceDisabled = '';
div.setAttribute('aria-disabled', 'true');
} else {
div.classList.add(itemSelectable);
div.dataset.choiceSelectable = '';
}
return div;
},
/**
* @param {Partial<ClassNames>} classNames
* @param {string} placeholderValue
*/
input: function input(_ref12, placeholderValue) {
var _input = _ref12.input,
inputCloned = _ref12.inputCloned;
@ -2996,6 +3048,10 @@ var TEMPLATES =
inp.setAttribute('aria-label', placeholderValue);
return inp;
},
/**
* @param {Partial<ClassNames>} classNames
*/
dropdown: function dropdown(_ref13) {
var list = _ref13.list,
listDropdown = _ref13.listDropdown;
@ -3004,6 +3060,13 @@ var TEMPLATES =
div.setAttribute('aria-expanded', 'false');
return div;
},
/**
*
* @param {Partial<ClassNames>} classNames
* @param {string} innerHTML
* @param {"no-choices" | "no-results" | ""} type
*/
notice: function notice(_ref14, innerHTML, type) {
var item = _ref14.item,
itemChoice = _ref14.itemChoice,
@ -3027,6 +3090,10 @@ var TEMPLATES =
className: classes.join(' ')
});
},
/**
* @param {Item} option
*/
option: function option(_ref15) {
var label = _ref15.label,
value = _ref15.value,
@ -3248,6 +3315,9 @@ function choices_createClass(Constructor, protoProps, staticProps) { if (protoPr
/** @see {@link http://browserhacks.com/#hack-acea075d0ac6954f275a70023906050c} */
var IS_IE11 = '-ms-scroll-limit' in document.documentElement.style && '-ms-ime-align' in document.documentElement.style;
/**
* @typedef {import('../../types/index').Choices.Choice} Choice
* @typedef {import('../../types/index').Choices.Item} Item
@ -4469,9 +4539,9 @@ function () {
var _document = document,
documentElement = _document.documentElement; // capture events - can cancel event processing or propagation
documentElement.addEventListener('keydown', this._onKeyDown, true);
documentElement.addEventListener('touchend', this._onTouchEnd, true);
documentElement.addEventListener('mousedown', this._onMouseDown, true); // passive events - doesn't call `preventDefault` or `stopPropagation`
this.containerOuter.element.addEventListener('keydown', this._onKeyDown, true);
this.containerOuter.element.addEventListener('mousedown', this._onMouseDown, true); // passive events - doesn't call `preventDefault` or `stopPropagation`
documentElement.addEventListener('click', this._onClick, {
passive: true
@ -4479,7 +4549,7 @@ function () {
documentElement.addEventListener('touchmove', this._onTouchMove, {
passive: true
});
documentElement.addEventListener('mouseover', this._onMouseOver, {
this.dropdown.element.addEventListener('mouseover', this._onMouseOver, {
passive: true
});
@ -4514,19 +4584,19 @@ function () {
_proto._removeEventListeners = function _removeEventListeners() {
var _document2 = document,
documentElement = _document2.documentElement;
documentElement.removeEventListener('keydown', this._onKeyDown, true);
documentElement.removeEventListener('touchend', this._onTouchEnd, true);
documentElement.removeEventListener('mousedown', this._onMouseDown, true);
documentElement.removeEventListener('keyup', this._onKeyUp);
this.containerOuter.element.removeEventListener('keydown', this._onKeyDown, true);
this.containerOuter.element.removeEventListener('mousedown', this._onMouseDown, true);
documentElement.removeEventListener('click', this._onClick);
documentElement.removeEventListener('touchmove', this._onTouchMove);
documentElement.removeEventListener('mouseover', this._onMouseOver);
this.dropdown.element.removeEventListener('mouseover', this._onMouseOver);
if (this._isSelectOneElement) {
this.containerOuter.element.removeEventListener('focus', this._onFocus);
this.containerOuter.element.removeEventListener('blur', this._onBlur);
}
this.input.element.removeEventListener('keyup', this._onKeyUp);
this.input.element.removeEventListener('focus', this._onFocus);
this.input.element.removeEventListener('blur', this._onBlur);
@ -4535,7 +4605,11 @@ function () {
}
this.input.removeEventListeners();
};
}
/**
* @param {KeyboardEvent} event
*/
;
_proto._onKeyDown = function _onKeyDown(event) {
var _keyDownActions;
@ -4544,11 +4618,6 @@ function () {
keyCode = event.keyCode,
ctrlKey = event.ctrlKey,
metaKey = event.metaKey;
if (target !== this.input.element && !this.containerOuter.element.contains(target)) {
return;
}
var activeItems = this._store.activeItems;
var hasFocusedInput = this.input.isFocussed;
var hasActiveDropdown = this.dropdown.isActive;
@ -4793,43 +4862,62 @@ function () {
}
this._wasTap = true;
};
}
/**
* Handles mousedown event in capture mode for containetOuter.element
* @param {MouseEvent} event
*/
;
_proto._onMouseDown = function _onMouseDown(event) {
var target = event.target,
shiftKey = event.shiftKey; // If we have our mouse down on the scrollbar and are on IE11...
var target = event.target;
if (this.choiceList.element.contains(target) && isIE11(navigator.userAgent)) {
this._isScrollingOnIe = true;
if (!(target instanceof HTMLElement)) {
return;
} // If we have our mouse down on the scrollbar and are on IE11...
if (IS_IE11 && this.choiceList.element.contains(target)) {
// check if click was on a scrollbar area
var firstChoice =
/** @type {HTMLElement} */
this.choiceList.element.firstElementChild;
var isOnScrollbar = this._direction === 'ltr' ? event.offsetX >= firstChoice.offsetWidth : event.offsetX < firstChoice.offsetLeft;
this._isScrollingOnIe = isOnScrollbar;
}
if (!this.containerOuter.element.contains(target) || target === this.input.element) {
if (target === this.input.element) {
return;
}
var activeItems = this._store.activeItems;
var hasShiftKey = shiftKey;
var buttonTarget = findAncestorByAttrName(target, 'data-button');
var itemTarget = findAncestorByAttrName(target, 'data-item');
var choiceTarget = findAncestorByAttrName(target, 'data-choice');
var item = target.closest('[data-button],[data-item],[data-choice]');
if (buttonTarget) {
this._handleButtonAction(activeItems, buttonTarget);
} else if (itemTarget) {
this._handleItemAction(activeItems, itemTarget, hasShiftKey);
} else if (choiceTarget) {
this._handleChoiceAction(activeItems, choiceTarget);
if (item instanceof HTMLElement) {
var hasShiftKey = event.shiftKey;
var activeItems = this._store.activeItems;
var dataset = item.dataset;
if ('button' in dataset) {
this._handleButtonAction(activeItems, item);
} else if ('item' in dataset) {
this._handleItemAction(activeItems, item, hasShiftKey);
} else if ('choice' in dataset) {
this._handleChoiceAction(activeItems, item);
}
}
event.preventDefault();
};
}
/**
* Handles mouseover event over this.dropdown
* @param {MouseEvent} event
*/
;
_proto._onMouseOver = function _onMouseOver(_ref9) {
var target = _ref9.target;
var targetWithinDropdown = target === this.dropdown || this.dropdown.element.contains(target);
var shouldHighlightChoice = targetWithinDropdown && target.hasAttribute('data-choice');
if (shouldHighlightChoice) {
if (target instanceof HTMLElement && 'choice' in target.dataset) {
this._highlightChoice(target);
}
};

File diff suppressed because one or more lines are too long

View File

@ -200,6 +200,7 @@
border: 1px solid #00a5bb;
color: #ffffff;
word-break: break-all;
box-sizing: border-box;
}
.choices__list--multiple .choices__item[data-deletable] {

File diff suppressed because one or more lines are too long

View File

@ -1319,11 +1319,6 @@ class Choices {
*/
_onKeyDown(event) {
const { target, keyCode, ctrlKey, metaKey } = event;
if (target !== this.input.element) {
return;
}
const { activeItems } = this._store;
const hasFocusedInput = this.input.isFocussed;
const hasActiveDropdown = this.dropdown.isActive;

View File

@ -13,6 +13,7 @@ function expectEqualElements(element1, element2) {
expect(Object.keys(element1.dataset)).to.have.members(
Object.keys(element2.dataset),
);
expect(element1.classList).to.include(element2.classList);
// compare attributes values
for (const attribute of Object.values(element1.attributes)) {
expect(element1.getAttribute(attribute)).to.equal(
@ -336,6 +337,7 @@ describe('templates', () => {
elementId: 'test',
label: 'test',
value: 'test',
selected: false,
};
});
@ -357,8 +359,6 @@ describe('templates', () => {
`);
const actualOutput = templates.choice(classes, data, itemSelectText);
console.log(actualOutput);
expectEqualElements(actualOutput, expectedOutput);
});
});
@ -393,6 +393,35 @@ describe('templates', () => {
});
});
describe('selected state', () => {
beforeEach(() => {
data = {
...data,
selected: true,
};
});
it('returns expected html', () => {
const expectedOutput = strToEl(`
<div
class="${classes.item} ${classes.itemChoice} ${classes.selectedState} ${classes.itemSelectable}"
data-select-text="${itemSelectText}"
data-choice
data-id="${data.id}"
data-value="${data.value}"
data-choice-selectable
id="${data.elementId}"
role="option"
>
${data.label}
</div>
`);
const actualOutput = templates.choice(classes, data, itemSelectText);
expectEqualElements(actualOutput, expectedOutput);
});
});
describe('placeholder', () => {
beforeEach(() => {
data = {
@ -404,7 +433,7 @@ describe('templates', () => {
it('returns expected html', () => {
const expectedOutput = strToEl(`
<div
class="${classes.item} ${classes.itemChoice} ${classes.itemSelectable} ${classes.placeholder}"
class="${classes.item} ${classes.itemChoice} ${classes.placeholder} ${classes.itemSelectable}"
data-select-text="${itemSelectText}"
data-choice
data-id="${data.id}"