diff --git a/src/components/Select.vue b/src/components/Select.vue index 88d3d61..fd7ee24 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -23,6 +23,10 @@ .v-select.rtl .dropdown-menu { text-align: right; } + .v-select.rtl .dropdown-toggle .clear { + left: 30px; + right: auto; + } /* Open Indicator */ .v-select .open-indicator { position: absolute; @@ -80,6 +84,22 @@ clear: both; height: 0; } + + /* Clear Button */ + .v-select .dropdown-toggle .clear { + position: absolute; + bottom: 7px; + right: 30px; + font-size: 23px; + font-weight: 700; + line-height: 1; + color: rgba(60, 60, 60, .5); + padding: 0; + border: 0; + background-color: transparent; + cursor: pointer; + } + /* Dropdown Toggle States */ .v-select.searchable .dropdown-toggle { cursor: text; @@ -248,6 +268,7 @@ /* Disabled state */ .v-select.disabled .dropdown-toggle, + .v-select.disabled .dropdown-toggle .clear, .v-select.disabled .dropdown-toggle input, .v-select.disabled .selected-tag .close, .v-select.disabled .open-indicator { @@ -322,6 +343,17 @@ aria-label="Search for option" > + + @@ -715,6 +747,14 @@ } }, + /** + * Clears the currently selected value(s) + * @return {void} + */ + clearSelection() { + this.mutableValue = this.multiple ? [] : null + }, + /** * Called from this.select after each selection. * @param {Object|String} option @@ -964,6 +1004,14 @@ } return [] + }, + + /** + * Determines if the clear button should be displayed. + * @return {Boolean} + */ + showClearButton() { + return !this.multiple && !this.open && this.mutableValue != null } }, diff --git a/test/unit/specs/Select.spec.js b/test/unit/specs/Select.spec.js index 33d954c..5601389 100644 --- a/test/unit/specs/Select.spec.js +++ b/test/unit/specs/Select.spec.js @@ -1299,4 +1299,61 @@ describe('Select.vue', () => { }) }) }) + + describe( 'Clear button', () => { + + it( 'should be displayed on single select when value is selected', () => { + const VueSelect = Vue.extend( vSelect ) + const vm = new VueSelect({ + propsData: { + options: ['foo','bar'], + value: 'foo' + } + }).$mount() + + expect(vm.showClearButton).toEqual(true) + }) + + it( 'should not be displayed on multiple select', () => { + const VueSelect = Vue.extend( vSelect ) + const vm = new VueSelect({ + propsData: { + options: ['foo','bar'], + value: 'foo', + multiple: true + } + }).$mount() + + expect(vm.showClearButton).toEqual(false) + }) + + it( 'should remove selected value when clicked', () => { + const VueSelect = Vue.extend( vSelect ) + const vm = new VueSelect({ + propsData: { + options: ['foo','bar'], + value: 'foo' + } + }).$mount() + + expect(vm.mutableValue).toEqual('foo') + vm.$el.querySelector( 'button.clear' ).click() + expect(vm.mutableValue).toEqual(null) + }) + + it( 'should be disabled when component is disabled', () => { + const VueSelect = Vue.extend( vSelect ) + const vm = new VueSelect({ + propsData: { + options: ['foo','bar'], + value: 'foo', + disabled: true + } + }).$mount() + + const buttonEl = vm.$el.querySelector( 'button.clear' ) + expect(buttonEl.disabled).toEqual(true); + }) + + }); })