Skip to content

Commit e4d4b27

Browse files
authored
V3/update list items slot (sagalbot#799)
* add tests for slots, add normalized function for passing options to slots * update active class * update active class
1 parent 3979f98 commit e4d4b27

File tree

3 files changed

+65
-9
lines changed

3 files changed

+65
-9
lines changed

src/components/Select.vue

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
<div class="vs__selected-options" ref="selectedOptions">
1010
<slot v-for="option in selectedValue"
1111
name="selected-option-container"
12-
:option="(typeof option === 'object')?option:{[label]: option}"
12+
:option="normalizeOptionForSlot(option)"
1313
:deselect="deselect"
1414
:multiple="multiple"
1515
:disabled="disabled">
1616
<span class="vs__selected" v-bind:key="option.index">
17-
<slot name="selected-option" v-bind="(typeof option === 'object')?option:{[label]: option}">
17+
<slot name="selected-option" v-bind="normalizeOptionForSlot(option)">
1818
{{ getOptionLabel(option) }}
1919
</slot>
2020
<button v-if="multiple" :disabled="disabled" @click="deselect(option)" type="button" class="vs__deselect" aria-label="Deselect option">
@@ -55,11 +55,11 @@
5555
v-for="(option, index) in filteredOptions"
5656
:key="index"
5757
class="vs__dropdown-option"
58-
:class="{ active: isOptionSelected(option), 'vs__dropdown-option--highlight': index === typeAheadPointer }"
58+
:class="{ 'vs__dropdown-option--selected': isOptionSelected(option), 'vs__dropdown-option--highlight': index === typeAheadPointer }"
5959
@mouseover="typeAheadPointer = index"
6060
@mousedown.prevent.stop="select(option)"
6161
>
62-
<slot name="option" v-bind="(typeof option === 'object')?option:{[label]: option}">
62+
<slot name="option" v-bind="normalizeOptionForSlot(option)">
6363
{{ getOptionLabel(option) }}
6464
</slot>
6565
</li>
@@ -700,6 +700,16 @@
700700
})
701701
},
702702
703+
/**
704+
* Ensures that options are always
705+
* passed as objects to scoped slots.
706+
* @param option
707+
* @return {*}
708+
*/
709+
normalizeOptionForSlot (option) {
710+
return (typeof option === 'object') ? option : {[this.label]: option};
711+
},
712+
703713
/**
704714
* If push-tags is true, push the
705715
* given option to `this.pushedTags`.

tests/helpers.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,20 @@ export const selectWithProps = (propsData = {}) => {
2828

2929
/**
3030
* Returns a Wrapper with a v-select component.
31+
* @param props
3132
* @param options
3233
* @return {Wrapper<Vue>}
3334
*/
34-
export const mountDefault = (options = {}) =>
35-
shallowMount(VueSelect, {
36-
propsData: { options: ["one", "two", "three"],
37-
...options
38-
}
35+
export const mountDefault = (props = {}, options = {}) => {
36+
return shallowMount(VueSelect, {
37+
propsData: {
38+
options: ['one', 'two', 'three'],
39+
...props,
40+
},
41+
...options,
3942
});
43+
};
44+
4045

4146
/**
4247
* Returns a v-select component directly.

tests/unit/Slots.spec.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { mountDefault } from '../helpers';
2+
3+
describe('Scoped Slots', () => {
4+
it('receives an option object to the selected-option-container slot', () => {
5+
const Select = mountDefault(
6+
{value: 'one'},
7+
{
8+
scopedSlots: {
9+
'selected-option-container': `<span slot="selected-option-container" slot-scope="{option}">{{ option.label }}</span>`,
10+
},
11+
});
12+
13+
expect(Select.find({ ref: 'selectedOptions' }).text()).toEqual('one')
14+
});
15+
16+
it('receives an option object to the selected-option slot', () => {
17+
const Select = mountDefault(
18+
{value: 'one'},
19+
{
20+
scopedSlots: {
21+
'selected-option': `<span slot="selected-option" slot-scope="option">{{ option.label }}</span>`,
22+
},
23+
});
24+
25+
expect(Select.find('.vs__selected').text()).toEqual('one')
26+
});
27+
28+
it('receives an option object to the option slot in the dropdown menu', () => {
29+
const Select = mountDefault(
30+
{value: 'one'},
31+
{
32+
scopedSlots: {
33+
'option': `<span slot="option" slot-scope="option">{{ option.label }}</span>`,
34+
},
35+
});
36+
37+
Select.vm.open = true;
38+
39+
expect(Select.find({ref: 'dropdownMenu'}).text()).toEqual('onetwothree')
40+
});
41+
});

0 commit comments

Comments
 (0)