Skip to content

Commit 970d1da

Browse files
committed
Fixing unexpected linebreak on single selects
What --- - Hiding the search input field if the component is in the single value option. - Making the search input field full width if no options are selected in either single or multi select mode. - Shrinking it to width auto if there are selected entries in multi mode. Why --- The component broke into two lines when selecting a a value in single mode, because an empty, non-interactable input field was pushed down to the next row if the selected entry had a long label.
1 parent 173f0bf commit 970d1da

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

src/components/Select.vue

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
padding: 0;
7474
background: none;
7575
border: 1px solid rgba(60, 60, 60, .26);
76+
min-height: 36px;
7677
border-radius: 4px;
7778
white-space: normal;
7879
}
@@ -213,6 +214,16 @@
213214
.v-select.unsearchable input[type="search"]:hover {
214215
cursor: pointer;
215216
}
217+
.v-select input[type="search"].hidden {
218+
display: none;
219+
}
220+
.v-select input[type="search"].shrunk {
221+
width: auto;
222+
}
223+
.v-select input[type="search"].empty {
224+
width: 100%;
225+
}
226+
216227
/* List Items */
217228
.v-select li {
218229
line-height: 1.42857143; /* Normalize line height */
@@ -336,12 +347,12 @@
336347
@focus="onSearchFocus"
337348
type="search"
338349
class="form-control"
350+
:class="inputClasses"
339351
autocomplete="off"
340352
:disabled="disabled"
341353
:placeholder="searchPlaceholder"
342354
:tabindex="tabindex"
343355
:readonly="!searchable"
344-
:style="{ width: isValueEmpty ? '100%' : 'auto' }"
345356
:id="inputId"
346357
aria-label="Search for option"
347358
>
@@ -972,6 +983,18 @@
972983
}
973984
},
974985
986+
/**
987+
* Classes to be output on input.form-control
988+
* @return {Object}
989+
*/
990+
inputClasses() {
991+
return {
992+
hidden: !this.multiple && !this.isValueEmpty,
993+
shrunk: this.multiple && !this.isValueEmpty,
994+
empty: this.isValueEmpty,
995+
}
996+
},
997+
975998
/**
976999
* If search text should clear on blur
9771000
* @return {Boolean} True when single and clearSearchOnSelect

test/unit/specs/Select.spec.js

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,36 @@ describe('Select.vue', () => {
249249
expect(vm.$children[0].isOptionSelected('foo')).toEqual(true)
250250
}),
251251

252+
it('applies the "empty" class to the search input when no value is selected', () => {
253+
const vm = new Vue({
254+
template: '<div><v-select :options="options" multiple v-model="value"></v-select></div>',
255+
components: {vSelect},
256+
data: {
257+
value: null,
258+
options: [{label: 'one'}]
259+
}
260+
}).$mount()
261+
262+
expect(vm.$children[0].inputClasses.empty).toEqual(true)
263+
expect(vm.$children[0].inputClasses.shrunk).toEqual(false)
264+
expect(vm.$children[0].inputClasses.hidden).toEqual(false)
265+
}),
266+
267+
it('applies the "shrunk" class to the search input when one or more value is selected', () => {
268+
const vm = new Vue({
269+
template: '<div><v-select :options="options" multiple v-model="value"></v-select></div>',
270+
components: {vSelect},
271+
data: {
272+
value: [{label: 'one'}],
273+
options: [{label: 'one'}]
274+
}
275+
}).$mount()
276+
277+
expect(vm.$children[0].inputClasses.shrunk).toEqual(true)
278+
expect(vm.$children[0].inputClasses.empty).toEqual(false)
279+
expect(vm.$children[0].inputClasses.hidden).toEqual(false)
280+
}),
281+
252282
describe('change Event', () => {
253283
it('will trigger the input event when the selection changes', (done) => {
254284
const vm = new Vue({
@@ -1318,7 +1348,34 @@ describe('Select.vue', () => {
13181348
expect(vm.$refs.select.search).toEqual('')
13191349
done()
13201350
})
1321-
})
1351+
})
1352+
1353+
it('should apply the "empty" class to the search input when it does not have a selected value', () => {
1354+
const vm = new Vue({
1355+
template: '<div><v-select ref="select" :options="options" :value="value"></v-select></div>',
1356+
data: {
1357+
value: '',
1358+
options: ['one', 'two', 'three']
1359+
}
1360+
}).$mount()
1361+
expect(vm.$children[0].inputClasses.empty).toEqual(true)
1362+
expect(vm.$children[0].inputClasses.shrunk).toEqual(false)
1363+
expect(vm.$children[0].inputClasses.hidden).toEqual(false)
1364+
})
1365+
1366+
it('should apply the "hidden" class to the search input when a value is present', () => {
1367+
const vm = new Vue({
1368+
template: '<div><v-select ref="select" :options="options" :value="value"></v-select></div>',
1369+
data: {
1370+
value: 'one',
1371+
options: ['one', 'two', 'three']
1372+
}
1373+
}).$mount()
1374+
1375+
expect(vm.$children[0].inputClasses.hidden).toEqual(true)
1376+
expect(vm.$children[0].inputClasses.empty).toEqual(false)
1377+
expect(vm.$children[0].inputClasses.shrunk).toEqual(false)
1378+
})
13221379

13231380
it ('should not reset the search input on focus lost when clearSearchOnSelect is false', (done) => {
13241381
const vm = new Vue({

0 commit comments

Comments
 (0)