diff --git a/src/PowerSelect/__tests__/PowerSelect-test.js b/src/PowerSelect/__tests__/PowerSelect-test.js index 0f9b0e0..453abbc 100644 --- a/src/PowerSelect/__tests__/PowerSelect-test.js +++ b/src/PowerSelect/__tests__/PowerSelect-test.js @@ -74,6 +74,97 @@ describe('', () => { expect(wrapper.find('.PowerSelect__TriggerLabel').text()).toBeFalsy(); }); + it('should clear the selected option, when the backspace key is pressed on focussed powerselect', () => { + const handleOnFocus = sinon.spy(); + const wrapper = powerselect.renderWithProps({ + selected: countries[2], + onFocus: handleOnFocus, + }); + + // Make sure powerselect is focussed + expect(handleOnFocus.calledOnce).toBeFalsy(); + wrapper.find('.PowerSelect').simulate('focus'); + expect(handleOnFocus.calledOnce).toBeTruthy(); + + // Make sure option is selected + expect(wrapper.find('.PowerSelect__TriggerLabel').text()).toBe('Canada'); + + // Make sure backspace clears the selected option + powerselect.triggerKeydown(KEY_CODES.BACKSPACE); + let args = powerselect.handleChange.getCall(0).args[0]; + expect(powerselect.handleChange.calledOnce).toBeTruthy(); + expect(args.option).toBe(undefined); + expect(args.select).toBeTruthy(); + expect(args.select.searchTerm).toBe(null); + + wrapper.setProps({ + selected: args.option, + }); + expect(wrapper.find('.PowerSelect__TriggerLabel').text()).toBeFalsy(); + }); + + it('should not clear the selected option on backspace press if powerselect is disabled', () => { + const handleOnFocus = sinon.spy(); + const wrapper = powerselect.renderWithProps({ + selected: countries[2], + onFocus: handleOnFocus, + disabled: true, + }); + + // Make sure powerselect is focussed + expect(handleOnFocus.calledOnce).toBeFalsy(); + wrapper.find('.PowerSelect').simulate('focus'); + expect(handleOnFocus.calledOnce).toBeTruthy(); + + // Make sure option is selected and powerselect is disabled + expect(wrapper.find('.PowerSelect__TriggerLabel').text()).toBe('Canada'); + expect(wrapper.find('.PowerSelect').hasClass('PowerSelect--disabled')).toBeTruthy(); + + //Make sure backspace does not trigger handlechange and selected option is not cleared + powerselect.triggerKeydown(KEY_CODES.BACKSPACE); + expect(powerselect.handleChange.notCalled).toBeTruthy(); + expect(wrapper.find('.PowerSelect__TriggerLabel').text()).toBe('Canada'); + }); + + it('should delegate `className` to the container, tether & menu', () => { + const wrapper = powerselect.renderWithProps({ + className: 'TestPowerSelect', + }); + expect(wrapper.find('.PowerSelect').hasClass('TestPowerSelect')).toBeTruthy(); + + powerselect.triggerContainerClick(); + expect( + powerselect.portal.find('.PowerSelect__Menu').hasClass('TestPowerSelect__Menu') + ).toBeTruthy(); + expect(document.querySelectorAll('.PowerSelect__Tether.TestPowerSelect__Tether').length).toBe( + 1 + ); + }); + + it('should not clear the selected option on backspace press if powerselect does not have a clear option', () => { + const handleOnFocus = sinon.spy(); + const wrapper = powerselect.renderWithProps({ + showClear: false, + selected: countries[2], + onFocus: handleOnFocus, + disabled: true, + }); + + // Make sure powerselect is focussed + expect(handleOnFocus.calledOnce).toBeFalsy(); + wrapper.find('.PowerSelect').simulate('focus'); + expect(handleOnFocus.calledOnce).toBeTruthy(); + + // Make sure option is selected and powerselect has no clear field + expect(wrapper.find('.PowerSelect__TriggerLabel').text()).toBe('Canada'); + expect(wrapper.find('.PowerSelect').hasClass('PowerSelect__Clear')).toBeFalsy(); + + //Make sure backspace does not trigger handlechange and selected option is not cleared + powerselect.triggerKeydown(KEY_CODES.BACKSPACE); + expect(powerselect.handleChange.notCalled).toBeTruthy(); + expect(wrapper.find('.PowerSelect__TriggerLabel').text()).toBe('Canada'); + }); + it('should delegate `className` to the container, tether & menu', () => { const wrapper = powerselect.renderWithProps({ className: 'TestPowerSelect', diff --git a/src/Select.js b/src/Select.js index 9f03769..0b35e80 100644 --- a/src/Select.js +++ b/src/Select.js @@ -18,6 +18,7 @@ const KEY_CODES = { DOWN_ARROW: 40, ENTER: 13, TAB: 9, + BACKSPACE: 8, }; const actions = { @@ -25,6 +26,7 @@ const actions = { [KEY_CODES.DOWN_ARROW]: 'handleDownArrow', [KEY_CODES.ENTER]: 'handleEnterPress', [KEY_CODES.TAB]: 'handleTabPress', + [KEY_CODES.BACKSPACE]: 'handleBackspacePress', }; const noop = () => {}; @@ -321,6 +323,27 @@ export default class Select extends Component { } }; + /* + * Backspace clears field if the power select: + * 1. is focused + * 2. is closed + * 3. has no search term + * 4. is not disabled + * 5. has clear button + */ + handleBackspacePress() { + if ( + this.state.focused && + !this.state.isOpen && + !this.state.searchTerm && + !this.props.disabled && + this.props.showClear + ) { + this.selectOption(undefined); + this.focusField(); + } + } + getPublicApi() { let { isOpen, searchTerm } = this.state; return { diff --git a/src/__tests__/test-utils/constants.js b/src/__tests__/test-utils/constants.js index b0a637c..ea902a5 100644 --- a/src/__tests__/test-utils/constants.js +++ b/src/__tests__/test-utils/constants.js @@ -4,6 +4,7 @@ export const KEY_CODES = { ESCAPE: 27, ENTER: 13, TAB: 9, + BACKSPACE: 8, }; export const frameworks = ['React', 'Ember', 'Angular', 'Vue', 'Inferno'];