2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-06-22 10:30:34 +03:00

feat: add deselectFromDropdown boolean prop (#1033)

This commit is contained in:
andreas
2021-10-17 19:47:06 +03:00
committed by GitHub
parent caf8a34e09
commit 68da1c172e
5 changed files with 99 additions and 1 deletions
+11
View File
@@ -163,6 +163,17 @@ createOption: {
}, },
``` ```
## deselectFromDropdown <Badge text="v3.12.0+" />
Determines whether the user can deselect an option by clicking
it from within the dropdown menu.
```js
deselectFromDropdown: {
type: Boolean,
default: false
},
```
## dir ## dir
+26 -1
View File
@@ -103,6 +103,8 @@
role="option" role="option"
class="vs__dropdown-option" class="vs__dropdown-option"
:class="{ :class="{
'vs__dropdown-option--deselect':
isOptionDeselectable(option) && index === typeAheadPointer,
'vs__dropdown-option--selected': isOptionSelected(option), 'vs__dropdown-option--selected': isOptionSelected(option),
'vs__dropdown-option--highlight': index === typeAheadPointer, 'vs__dropdown-option--highlight': index === typeAheadPointer,
'vs__dropdown-option--disabled': !selectable(option), 'vs__dropdown-option--disabled': !selectable(option),
@@ -206,6 +208,16 @@ export default {
default: true, default: true,
}, },
/**
* Can the user deselect an option by clicking it from
* within the dropdown.
* @type {Boolean}
*/
deselectFromDropdown: {
type: Boolean,
default: false,
},
/** /**
* Enable/disable filtering the options. * Enable/disable filtering the options.
* @type {Boolean} * @type {Boolean}
@@ -960,7 +972,8 @@ export default {
}, },
/** /**
* Select a given option. * Select or deselect a given option.
* Allow deselect if clearable or if not the only selected option.
* @param {Object|String} option * @param {Object|String} option
* @return {void} * @return {void}
*/ */
@@ -975,6 +988,11 @@ export default {
} }
this.updateValue(option) this.updateValue(option)
this.$emit('option:selected', option) this.$emit('option:selected', option)
} else if (
this.deselectFromDropdown &&
(this.clearable || (this.multiple && this.selectedValue.length > 1))
) {
this.deselect(option)
} }
this.onAfterSelect(option) this.onAfterSelect(option)
}, },
@@ -1090,6 +1108,13 @@ export default {
) )
}, },
/**
* Can the current option be removed via the dropdown?
*/
isOptionDeselectable(option) {
return this.isOptionSelected(option) && this.deselectFromDropdown
},
/** /**
* Determine if two option objects are matching. * Determine if two option objects are matching.
* *
+4
View File
@@ -13,6 +13,10 @@ $vs-component-placeholder-color: inherit !default;
$vs-state-active-bg: #5897fb !default; $vs-state-active-bg: #5897fb !default;
$vs-state-active-color: #fff !default; $vs-state-active-color: #fff !default;
// Deselect State
$vs-state-deselect-bg: #fb5858 !default;
$vs-state-deselect-color: #fff !default;
// Disabled State // Disabled State
$vs-state-disabled-bg: rgb(248, 248, 248) !default; $vs-state-disabled-bg: rgb(248, 248, 248) !default;
$vs-state-disabled-color: map_get($vs-colors, 'light') !default; $vs-state-disabled-color: map_get($vs-colors, 'light') !default;
+5
View File
@@ -14,6 +14,11 @@
color: $vs-state-active-color; color: $vs-state-active-color;
} }
.vs__dropdown-option--deselect {
background: $vs-state-deselect-bg;
color: $vs-state-deselect-color;
}
.vs__dropdown-option--disabled { .vs__dropdown-option--disabled {
background: inherit; background: inherit;
color: $vs-state-disabled-color; color: $vs-state-disabled-color;
+53
View File
@@ -51,6 +51,7 @@ describe('Removing values', () => {
it('will not emit input event if value has not changed with backspace', () => { it('will not emit input event if value has not changed with backspace', () => {
const Select = mountDefault() const Select = mountDefault()
Select.vm.$data._value = 'one' Select.vm.$data._value = 'one'
Select.findComponent({ ref: 'search' }).trigger('keydown.backspace') Select.findComponent({ ref: 'search' }).trigger('keydown.backspace')
expect(Select.emitted().input.length).toBe(1) expect(Select.emitted().input.length).toBe(1)
@@ -59,6 +60,58 @@ describe('Removing values', () => {
expect(Select.emitted().input.length).toBe(1) expect(Select.emitted().input.length).toBe(1)
}) })
it('should deselect a selected option when clicked and deselectFromDropdown is true', async () => {
const Select = selectWithProps({
value: 'one',
options: ['one', 'two', 'three'],
deselectFromDropdown: true,
})
const deselect = spyOn(Select.vm, 'deselect')
Select.vm.open = true
await Select.vm.$nextTick()
Select.find('.vs__dropdown-option--selected').trigger('click')
await Select.vm.$nextTick()
expect(deselect).toHaveBeenCalledWith('one')
})
it('should not deselect a selected option when clicked if clearable is false', async () => {
const Select = selectWithProps({
value: 'one',
options: ['one', 'two', 'three'],
clearable: false,
deselectFromDropdown: true,
})
const deselect = spyOn(Select.vm, 'deselect')
Select.vm.open = true
await Select.vm.$nextTick()
Select.find('.vs__dropdown-option--selected').trigger('click')
await Select.vm.$nextTick()
expect(deselect).not.toHaveBeenCalledWith('one')
})
it('should not deselect a selected option when clicked if deselectFromDropdown is false', async () => {
const Select = selectWithProps({
value: 'one',
options: ['one', 'two', 'three'],
deselectFromDropdown: false,
})
const deselect = spyOn(Select.vm, 'deselect')
Select.vm.open = true
await Select.vm.$nextTick()
Select.find('.vs__dropdown-option--selected').trigger('click')
await Select.vm.$nextTick()
expect(deselect).not.toHaveBeenCalledWith('one')
})
describe('Clear button', () => { describe('Clear button', () => {
it('should be displayed on single select when value is selected', () => { it('should be displayed on single select when value is selected', () => {
const Select = selectWithProps({ const Select = selectWithProps({