[Improvement] Field: support autosize maxHeight & minHeight (#718)

This commit is contained in:
neverland 2018-03-19 11:06:46 +08:00 committed by GitHub
parent 4ae26ac8be
commit 326b2d4c51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 25 deletions

View File

@ -53,7 +53,7 @@
type="textarea" type="textarea"
:placeholder="$t('messagePlaceholder')" :placeholder="$t('messagePlaceholder')"
rows="1" rows="1"
autosize :autosize="{ maxHeight: 100, minHeight: 40 }"
/> />
</van-cell-group> </van-cell-group>
</demo-block> </demo-block>

View File

@ -99,7 +99,7 @@ Filed support all native properties of input tagsuch as `maxlength`、`placeh
| disabled | Disable field | `Boolean` | `false` | - | | disabled | Disable field | `Boolean` | `false` | - |
| error | Whether to show error info | `Boolean` | `false` | - | | error | Whether to show error info | `Boolean` | `false` | - |
| error-message | Error message | `String` | `''` | - | | error-message | Error message | `String` | `''` | - |
| autosize | Textarea auto resize | `Boolean` | `false` | - | | autosize | Textarea auto resizecan accpet an object, e.g. { maxHeight: 100, minHeight: 50 } | `Boolean | Object` | `false` | - |
| icon | Right side Icon name | `String` | - | - | | icon | Right side Icon name | `String` | - | - |
### Event ### Event

View File

@ -101,7 +101,7 @@ Filed 默认支持 Input 标签所有的原生属性,比如 `maxlength`、`pla
| disabled | 是否禁用输入框 | `Boolean` | `false` | - | | disabled | 是否禁用输入框 | `Boolean` | `false` | - |
| error | 输入框是否有错误 | `Boolean` | `false` | - | | error | 输入框是否有错误 | `Boolean` | `false` | - |
| error-message | 输入框底部错误提示文案 | `String` | `''` | - | | error-message | 输入框底部错误提示文案 | `String` | `''` | - |
| autosize | 高度自适应(仅支持textarea) | `Boolean` | `false` | - | | autosize | 自适应内容高度,只对 textarea 有效,可传入对象,如 { maxHeight: 100, minHeight: 50 },单位为 px | `Boolean | Object` | `false` | - |
| icon | 输入框尾部图标 | `String` | - | Icon 组件支持的类型 | | icon | 输入框尾部图标 | `String` | - | Icon 组件支持的类型 |
### Event ### Event

View File

@ -49,7 +49,7 @@
</template> </template>
<script> <script>
import { create } from '../utils'; import { create, isObj } from '../utils';
export default create({ export default create({
name: 'field', name: 'field',
@ -67,7 +67,7 @@ export default create({
error: Boolean, error: Boolean,
border: Boolean, border: Boolean,
required: Boolean, required: Boolean,
autosize: Boolean, autosize: [Boolean, Object],
errorMessage: String, errorMessage: String,
onIconClick: { onIconClick: {
type: Function, type: Function,
@ -77,21 +77,12 @@ export default create({
watch: { watch: {
value() { value() {
if (this.autosize && this.type === 'textarea') { this.$nextTick(this.adjustSize);
this.$nextTick(this.adjustSize);
}
} }
}, },
mounted() { mounted() {
if (this.autosize && this.type === 'textarea') { this.$nextTick(this.adjustSize);
const el = this.$refs.textarea;
const scrollHeight = el.scrollHeight;
if (scrollHeight !== 0) {
el.style.height = scrollHeight + 'px';
}
el.style.overflowY = 'hidden';
}
}, },
computed: { computed: {
@ -131,9 +122,25 @@ export default create({
}, },
adjustSize() { adjustSize() {
if (!(this.type === 'textarea' && this.autosize)) {
return;
}
const el = this.$refs.textarea; const el = this.$refs.textarea;
el.style.height = 'auto'; el.style.height = 'auto';
el.style.height = el.scrollHeight + 'px';
let height = el.scrollHeight;
if (isObj(this.autosize)) {
const { maxHeight, minHeight } = this.autosize;
if (maxHeight) {
height = Math.min(height, maxHeight);
}
if (minHeight) {
height = Math.max(height, minHeight);
}
}
el.style.height = height + 'px';
} }
} }
}); });

View File

@ -66,23 +66,26 @@ describe('Field', () => {
}); });
}); });
it('create a textarea field', () => { it('create a textarea field', (done) => {
wrapper = mount(Field, { wrapper = mount(Field, {
propsData: { propsData: {
type: 'textarea', type: 'textarea',
autosize: false autosize: true
} }
}); });
expect(wrapper.hasClass('van-field')).to.be.true; setTimeout(() => {
expect(wrapper.hasClass('van-field--has-textarea')).to.be.true; expect(wrapper.hasClass('van-field')).to.be.true;
expect(wrapper.hasClass('van-field--has-textarea')).to.be.true;
done();
}, 50);
}); });
it('create a autosize textarea field', (done) => { it('create a autosize textarea field', (done) => {
wrapper = mount(Field, { wrapper = mount(Field, {
propsData: { propsData: {
type: 'textarea', type: 'textarea',
autosize: true autosize: {}
} }
}); });
@ -98,15 +101,49 @@ describe('Field', () => {
const textAreaDiff = (parseInt(textareaElement.style.paddingBottom, 10) + const textAreaDiff = (parseInt(textareaElement.style.paddingBottom, 10) +
parseInt(textareaElement.style.paddingTop, 10)) || 0; parseInt(textareaElement.style.paddingTop, 10)) || 0;
textareaElement.value = 'test'; const longText = 'testtesttesttesttesttesttest';
textareaElement.value = longText;
textarea.trigger('input'); textarea.trigger('input');
wrapper.update(); wrapper.update();
setTimeout(() => { setTimeout(() => {
expect(wrapper.find('.van-field__control')[0].element.value).to.equal('test'); expect(wrapper.find('.van-field__control')[0].element.value).to.equal(longText);
expect(textareaElement.style.height).to.equal((textareaElement.scrollHeight - textAreaDiff) + 'px'); expect(textareaElement.style.height).to.equal((textareaElement.scrollHeight - textAreaDiff) + 'px');
done(); done();
}, 500); }, 50);
});
it('autosize object', (done) => {
wrapper = mount(Field, {
propsData: {
type: 'textarea',
autosize: {
maxHeight: 100,
minHeight: 50
}
}
});
wrapper.vm.$on('input', val => {
wrapper.vm.value = val;
});
expect(wrapper.hasClass('van-field')).to.be.true;
expect(wrapper.hasClass('van-field--autosize')).to.be.true;
const textarea = wrapper.find('.van-field__control')[0];
const textareaElement = textarea.element;
const longText = 'testtesttesttesttesttesttest';
textareaElement.value = longText;
textarea.trigger('input');
wrapper.update();
setTimeout(() => {
expect(wrapper.find('.van-field__control')[0].element.value).to.equal(longText);
expect(textareaElement.style.height).to.equal(('50px'));
done();
}, 50);
}); });
it('show icon when has value and icon props', () => { it('show icon when has value and icon props', () => {