Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing unexpected linebreak on single selects #512

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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.
eriknygren committed Apr 18, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 970d1da3c2fbcefeadb2ee8910cd383c98f56032
25 changes: 24 additions & 1 deletion src/components/Select.vue
Original file line number Diff line number Diff line change
@@ -73,6 +73,7 @@
padding: 0;
background: none;
border: 1px solid rgba(60, 60, 60, .26);
min-height: 36px;
border-radius: 4px;
white-space: normal;
}
@@ -213,6 +214,16 @@
.v-select.unsearchable input[type="search"]:hover {
cursor: pointer;
}
.v-select input[type="search"].hidden {
display: none;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my testing, display: none can mess up the vertical alignment of the clear button and the dropdown arrow. Perhaps we consider the following instead, as they preserve the height of the input element, and the vertical alignment of the other elements?

width: 0px;
padding: 0;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good shout @stevenharman , will update

}
.v-select input[type="search"].shrunk {
width: auto;
}
.v-select input[type="search"].empty {
width: 100%;
}
/* List Items */
.v-select li {
line-height: 1.42857143; /* Normalize line height */
@@ -336,12 +347,12 @@
@focus="onSearchFocus"
type="search"
class="form-control"
:class="inputClasses"
autocomplete="off"
:disabled="disabled"
:placeholder="searchPlaceholder"
:tabindex="tabindex"
:readonly="!searchable"
:style="{ width: isValueEmpty ? '100%' : 'auto' }"
:id="inputId"
aria-label="Search for option"
>
@@ -972,6 +983,18 @@
}
},
/**
* Classes to be output on input.form-control
* @return {Object}
*/
inputClasses() {
return {
hidden: !this.multiple && !this.isValueEmpty,
shrunk: this.multiple && !this.isValueEmpty,
empty: this.isValueEmpty,
}
},
/**
* If search text should clear on blur
* @return {Boolean} True when single and clearSearchOnSelect
59 changes: 58 additions & 1 deletion test/unit/specs/Select.spec.js
Original file line number Diff line number Diff line change
@@ -249,6 +249,36 @@ describe('Select.vue', () => {
expect(vm.$children[0].isOptionSelected('foo')).toEqual(true)
}),

it('applies the "empty" class to the search input when no value is selected', () => {
const vm = new Vue({
template: '<div><v-select :options="options" multiple v-model="value"></v-select></div>',
components: {vSelect},
data: {
value: null,
options: [{label: 'one'}]
}
}).$mount()

expect(vm.$children[0].inputClasses.empty).toEqual(true)
expect(vm.$children[0].inputClasses.shrunk).toEqual(false)
expect(vm.$children[0].inputClasses.hidden).toEqual(false)
}),

it('applies the "shrunk" class to the search input when one or more value is selected', () => {
const vm = new Vue({
template: '<div><v-select :options="options" multiple v-model="value"></v-select></div>',
components: {vSelect},
data: {
value: [{label: 'one'}],
options: [{label: 'one'}]
}
}).$mount()

expect(vm.$children[0].inputClasses.shrunk).toEqual(true)
expect(vm.$children[0].inputClasses.empty).toEqual(false)
expect(vm.$children[0].inputClasses.hidden).toEqual(false)
}),

describe('change Event', () => {
it('will trigger the input event when the selection changes', (done) => {
const vm = new Vue({
@@ -1318,7 +1348,34 @@ describe('Select.vue', () => {
expect(vm.$refs.select.search).toEqual('')
done()
})
})
})

it('should apply the "empty" class to the search input when it does not have a selected value', () => {
const vm = new Vue({
template: '<div><v-select ref="select" :options="options" :value="value"></v-select></div>',
data: {
value: '',
options: ['one', 'two', 'three']
}
}).$mount()
expect(vm.$children[0].inputClasses.empty).toEqual(true)
expect(vm.$children[0].inputClasses.shrunk).toEqual(false)
expect(vm.$children[0].inputClasses.hidden).toEqual(false)
})

it('should apply the "hidden" class to the search input when a value is present', () => {
const vm = new Vue({
template: '<div><v-select ref="select" :options="options" :value="value"></v-select></div>',
data: {
value: 'one',
options: ['one', 'two', 'three']
}
}).$mount()

expect(vm.$children[0].inputClasses.hidden).toEqual(true)
expect(vm.$children[0].inputClasses.empty).toEqual(false)
expect(vm.$children[0].inputClasses.shrunk).toEqual(false)
})

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