From 9b09f6aa9ff1159e09c170759b3e420c603ddce7 Mon Sep 17 00:00:00 2001 From: Black Wayne <451578533@qq.com> Date: Thu, 12 Oct 2017 17:50:06 +0800 Subject: [PATCH] Form: add size attribute (#7428) --- build/bin/build-entry.js | 5 +++ examples/docs/en-US/cascader.md | 2 +- examples/docs/en-US/dialog.md | 2 +- examples/docs/en-US/form.md | 47 +++++++++++++++++++++ examples/docs/zh-CN/cascader.md | 2 +- examples/docs/zh-CN/dialog.md | 2 +- examples/docs/zh-CN/form.md | 48 ++++++++++++++++++++++ packages/button/src/button.vue | 13 +++++- packages/cascader/src/main.vue | 10 ++++- packages/checkbox/src/checkbox-button.vue | 8 +++- packages/checkbox/src/checkbox-group.vue | 11 +++++ packages/checkbox/src/checkbox.vue | 11 ++++- packages/color-picker/src/main.vue | 12 +++++- packages/date-picker/src/picker.vue | 14 ++++++- packages/dropdown/src/dropdown.vue | 12 ++++-- packages/form/src/form-item.vue | 9 +++- packages/form/src/form.vue | 3 +- packages/input-number/src/input-number.vue | 11 ++++- packages/input/src/input.vue | 8 +++- packages/radio/src/radio-button.vue | 8 +++- packages/radio/src/radio-group.vue | 12 ++++++ packages/radio/src/radio.vue | 10 ++++- packages/select/src/select.vue | 11 ++++- packages/tag/src/tag.vue | 7 +++- packages/theme-chalk/src/cascader.scss | 17 ++------ packages/theme-chalk/src/dropdown.scss | 4 ++ packages/theme-chalk/src/input-number.scss | 8 ++-- src/index.js | 5 +++ 28 files changed, 270 insertions(+), 42 deletions(-) diff --git a/build/bin/build-entry.js b/build/bin/build-entry.js index 9f024608d..505c12d04 100644 --- a/build/bin/build-entry.js +++ b/build/bin/build-entry.js @@ -31,6 +31,9 @@ const install = function(Vue, opts = {}) { Vue.use(Loading.directive); + const ELEMENT = {}; + ELEMENT.size = opts.size || ''; + Vue.prototype.$loading = Loading.service; Vue.prototype.$msgbox = MessageBox; Vue.prototype.$alert = MessageBox.alert; @@ -38,6 +41,8 @@ const install = function(Vue, opts = {}) { Vue.prototype.$prompt = MessageBox.prompt; Vue.prototype.$notify = Notification; Vue.prototype.$message = Message; + + Vue.prototype.$ELEMENT = ELEMENT; }; /* istanbul ignore if */ diff --git a/examples/docs/en-US/cascader.md b/examples/docs/en-US/cascader.md index d7fb37875..4afb131a3 100644 --- a/examples/docs/en-US/cascader.md +++ b/examples/docs/en-US/cascader.md @@ -1678,7 +1678,7 @@ Search and select options with a keyword. | filterable | whether the options can be searched | boolean | — | — | | debounce | debounce delay when typing filter keyword, in milliseconds | number | — | 300 | | change-on-select | whether selecting an option of any level is permitted | boolean | — | false | -| size | size of Input | string | large / small / mini | — | +| size | size of Input | string | medium / small / mini | — | ### props | Attribute | Description | Type | Accepted Values | Default | diff --git a/examples/docs/en-US/dialog.md b/examples/docs/en-US/dialog.md index d84d45738..3e5a0c296 100644 --- a/examples/docs/en-US/dialog.md +++ b/examples/docs/en-US/dialog.md @@ -287,7 +287,7 @@ If the variable bound to `visible` is managed in Vuex store, the `.sync` can not | title | title of Dialog. Can also be passed with a named slot (see the following table) | string | — | — | | width | width of Dialog | string | — | 50% | | fullscreen | whether the Dialog takes up full screen | boolean | — | false | -| top | value for `margin-top` of Dialog CSS, works when `size` is not `full` | string | — | 15vh | +| top | value for `margin-top` of Dialog CSS | string | — | 15vh | | modal | whether a mask is displayed | boolean | — | true | | modal-append-to-body | whether to append modal to body element. If false, the modal will be appended to Dialog's parent element | boolean | — | true | | append-to-body | whether to append Dialog itself to body. A nested Dialog should have this attribute set to `true` | boolean | — | false | diff --git a/examples/docs/en-US/form.md b/examples/docs/en-US/form.md index 08bf451d7..781ebe858 100644 --- a/examples/docs/en-US/form.md +++ b/examples/docs/en-US/form.md @@ -739,6 +739,51 @@ This example shows how to customize your own validation rules to finish a two-fa When an `el-form-item` is nested in another `el-form-item`, its label width will be `0`. You can set `label-width` on that `el-form-item` if needed. ::: +### Size control + +All components in a Form inherit their `size` attribute from that Form. Similarly, FormItem also has a `size` attribute. + +::: demo Still you can fine tune each component's `size` if you don't want that component to inherit its size from From or FormIten. +```html + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + Create + Cancel + + +``` +::: + ### Form Attributes | Attribute | Description | Type | Accepted Values | Default | @@ -752,6 +797,7 @@ When an `el-form-item` is nested in another `el-form-item`, its label width will | show-message | whether to show the error message | boolean | — | true | | inline-message | whether to display the error message inline with the form item | boolean | — | false | | status-icon | whether to display an icon indicating the validation result | boolean | — | false | +| size | control the size of components in this form | string | medium / small / mini | - | ### Form Methods @@ -773,6 +819,7 @@ When an `el-form-item` is nested in another `el-form-item`, its label width will | error | field error message, set its value and the field will validate error and show this message immediately | string | — | — | | show-message | whether to show the error message | boolean | — | true | | inline-message | inline style validate message | boolean | — | false | +| size | control the size of components in this form-item | string | medium / small / mini | - | ### Form-Item Slot | Name | Description | diff --git a/examples/docs/zh-CN/cascader.md b/examples/docs/zh-CN/cascader.md index 9be7bf2f8..bd5d6f7b1 100644 --- a/examples/docs/zh-CN/cascader.md +++ b/examples/docs/zh-CN/cascader.md @@ -1678,7 +1678,7 @@ | filterable | 是否可搜索选项 | boolean | — | — | | debounce | 搜索关键词输入的去抖延迟,毫秒 | number | — | 300 | | change-on-select | 是否允许选择任意一级的选项 | boolean | — | false | -| size | 尺寸 | string | large / small / mini | — | +| size | 尺寸 | string | medium / small / mini | — | ### props | 参数 | 说明 | 类型 | 可选值 | 默认值 | diff --git a/examples/docs/zh-CN/dialog.md b/examples/docs/zh-CN/dialog.md index ebd569ab4..613b9181a 100644 --- a/examples/docs/zh-CN/dialog.md +++ b/examples/docs/zh-CN/dialog.md @@ -282,7 +282,7 @@ Dialog 组件的内容可以是任意的,甚至可以是表格或表单,下 | title | Dialog 的标题,也可通过具名 slot (见下表)传入 | string | — | — | | width | Dialog 的宽度 | string | — | 50% | | fullscreen | 是否为全屏 Dialog | boolean | — | false | -| top | Dialog CSS 中的 margin-top 值(仅在 size 不为 full 时有效) | string | — | 15vh | +| top | Dialog CSS 中的 margin-top 值 | string | — | 15vh | | modal | 是否需要遮罩层 | boolean | — | true | | modal-append-to-body | 遮罩层是否插入至 body 元素上,若为 false,则遮罩层会插入至 Dialog 的父元素上 | boolean | — | true | | append-to-body | Dialog 自身是否插入至 body 元素上。嵌套的 Dialog 必须指定该属性并赋值为 true | boolean | — | false | diff --git a/examples/docs/zh-CN/form.md b/examples/docs/zh-CN/form.md index ea9da4d5d..115c0a425 100644 --- a/examples/docs/zh-CN/form.md +++ b/examples/docs/zh-CN/form.md @@ -728,6 +728,52 @@ 嵌套在 `el-form-item` 中的 `el-form-item` 标签宽度默认为零,不会继承 `el-form` 的 `label-width`。如果需要可以为其单独设置 `label-width` 属性。 ::: +### 表单内组件尺寸控制 + +通过设置 Form 上的 `size` 属性可以使该表单内所有可调节大小的组件继承该尺寸。Form-Item 也具有该属性。 + +::: demo 如果希望某个表单项或某个表单组件的尺寸不同于 Form 上的`size`属性,直接为这个表单项或表单组件设置自己的`size`即可。 +```html + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + 立即创建 + 取消 + + +``` +::: + ### Form Attributes | 参数 | 说明 | 类型 | 可选值 | 默认值 | @@ -741,6 +787,7 @@ | show-message | 是否显示校验错误信息 | boolean | — | true | | inline-message | 是否以行内形式展示校验信息 | boolean | — | false | | status-icon | 是否在输入框中显示校验结果反馈图标 | boolean | — | false | +| size | 用于控制该表单内组件的尺寸 | string | medium / small / mini | - | ### Form Methods @@ -762,6 +809,7 @@ | error | 表单域验证错误信息, 设置该值会使表单验证状态变为`error`,并显示该错误信息 | string | — | — | | show-message | 是否显示校验错误信息 | boolean | — | true | | inline-message | 以行内形式展示校验信息 | boolean | — | false | +| size | 用于控制该表单域下组件的尺寸 | string | medium / small / mini | - | ### Form-Item Slot | name | 说明 | diff --git a/packages/button/src/button.vue b/packages/button/src/button.vue index 6872f3401..ea3127d32 100644 --- a/packages/button/src/button.vue +++ b/packages/button/src/button.vue @@ -7,7 +7,7 @@ :type="nativeType" :class="[ type ? 'el-button--' + type : '', - size ? 'el-button--' + size : '', + buttonSize ? 'el-button--' + buttonSize : '', { 'is-disabled': disabled, 'is-loading': loading, @@ -25,6 +25,8 @@ export default { name: 'ElButton', + inject: ['elFormItem'], + props: { type: { type: String, @@ -46,6 +48,15 @@ round: Boolean }, + computed: { + _elFormItemSize() { + return (this.elFormItem || {}).elFormItemSize; + }, + buttonSize() { + return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; + } + }, + methods: { handleClick(evt) { this.$emit('click', evt); diff --git a/packages/cascader/src/main.vue b/packages/cascader/src/main.vue index b26f16b66..257619e3c 100644 --- a/packages/cascader/src/main.vue +++ b/packages/cascader/src/main.vue @@ -6,7 +6,7 @@ 'is-opened': menuVisible, 'is-disabled': disabled }, - size ? 'el-cascader--' + size : '' + cascaderSize ? 'el-cascader--' + cascaderSize : '' ]" @click="handleClick" @mouseenter="inputHover = true" @@ -87,6 +87,8 @@ export default { mixins: [popperMixin, emitter, Locale], + inject: ['elFormItem'], + components: { ElInput }, @@ -179,6 +181,12 @@ export default { } }); return labels; + }, + _elFormItemSize() { + return (this.elFormItem || {}).elFormItemSize; + }, + cascaderSize() { + return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; } }, diff --git a/packages/checkbox/src/checkbox-button.vue b/packages/checkbox/src/checkbox-button.vue index 8843d724e..abbbe2070 100644 --- a/packages/checkbox/src/checkbox-button.vue +++ b/packages/checkbox/src/checkbox-button.vue @@ -51,6 +51,8 @@ mixins: [Emitter], + inject: ['elFormItem'], + data() { return { selfModel: false, @@ -133,8 +135,12 @@ }; }, + _elFormItemSize() { + return (this.elFormItem || {}).elFormItemSize; + }, + size() { - return this._checkboxGroup.size; + return this._checkboxGroup.checkboxGroupSize || this._elFormItemSize || (this.$ELEMENT || {}).size; }, isDisabled() { diff --git a/packages/checkbox/src/checkbox-group.vue b/packages/checkbox/src/checkbox-group.vue index 9b5ec46ce..9db3450c4 100644 --- a/packages/checkbox/src/checkbox-group.vue +++ b/packages/checkbox/src/checkbox-group.vue @@ -8,6 +8,8 @@ mixins: [Emitter], + inject: ['elFormItem'], + props: { value: {}, disabled: Boolean, @@ -18,6 +20,15 @@ textColor: String }, + computed: { + _elFormItemSize() { + return (this.elFormItem || {}).elFormItemSize; + }, + checkboxGroupSize() { + return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; + } + }, + watch: { value(value) { this.dispatch('ElFormItem', 'el.form.change', [value]); diff --git a/packages/checkbox/src/checkbox.vue b/packages/checkbox/src/checkbox.vue index 68dfab973..ca185001b 100644 --- a/packages/checkbox/src/checkbox.vue +++ b/packages/checkbox/src/checkbox.vue @@ -60,6 +60,8 @@ mixins: [Emitter], + inject: ['elFormItem'], + componentName: 'ElCheckbox', data() { @@ -131,10 +133,15 @@ : this.disabled; }, + _elFormItemSize() { + return (this.elFormItem || {}).elFormItemSize; + }, + checkboxSize() { + const temCheckboxSize = this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; return this.isGroup - ? this._checkboxGroup.size || this.size - : this.size; + ? this._checkboxGroup.checkboxGroupSize || temCheckboxSize + : temCheckboxSize; } }, diff --git a/packages/color-picker/src/main.vue b/packages/color-picker/src/main.vue index c7b9771f3..3cc8cbf39 100644 --- a/packages/color-picker/src/main.vue +++ b/packages/color-picker/src/main.vue @@ -3,7 +3,7 @@ :class="[ 'el-color-picker', disabled ? 'is-disabled' : '', - size ? `el-color-picker--${ size }` : '' + colorSize ? `el-color-picker--${ colorSize }` : '' ]" v-clickoutside="hide">
@@ -46,6 +46,8 @@ popperClass: String }, + inject: ['elFormItem'], + directives: { Clickoutside }, computed: { @@ -58,6 +60,14 @@ ? `rgba(${ r }, ${ g }, ${ b }, ${ this.color.get('alpha') / 100 })` : `rgb(${ r }, ${ g }, ${ b })`; } + }, + + _elFormItemSize() { + return (this.elFormItem || {}).elFormItemSize; + }, + + colorSize() { + return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; } }, diff --git a/packages/date-picker/src/picker.vue b/packages/date-picker/src/picker.vue index a81eff053..a25727ba4 100644 --- a/packages/date-picker/src/picker.vue +++ b/packages/date-picker/src/picker.vue @@ -4,7 +4,7 @@ :class="'el-date-editor--' + type" :readonly="!editable || readonly" :disabled="disabled" - :size="size" + :size="pickerSize" :name="name" v-if="!ranged" v-clickoutside="handleClose" @@ -31,7 +31,7 @@ class="el-date-editor el-range-editor el-input__inner" :class="[ 'el-date-editor--' + type, - 'el-range-editor--' + size, + 'el-range-editor--' + pickerSize, pickerVisible ? 'is-active' : '' ]" @click="handleRangeClick" @@ -266,6 +266,8 @@ const valueEquals = function(a, b) { export default { mixins: [Emitter, NewPopper, Focus('reference')], + inject: ['elFormItem'], + props: { size: String, format: String, @@ -421,6 +423,14 @@ export default { } else { return this.value; } + }, + + _elFormItemSize() { + return (this.elFormItem || {}).elFormItemSize; + }, + + pickerSize() { + return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; } }, diff --git a/packages/dropdown/src/dropdown.vue b/packages/dropdown/src/dropdown.vue index 9801cadd2..88d0ce865 100644 --- a/packages/dropdown/src/dropdown.vue +++ b/packages/dropdown/src/dropdown.vue @@ -56,6 +56,12 @@ }; }, + computed: { + dropdownSize() { + return this.size || (this.$ELEMENT || {}).size; + } + }, + mounted() { this.$on('menu-item-click', this.handleMenuItemClick); this.initEvent(); @@ -114,7 +120,7 @@ }, render(h) { - let { hide, splitButton, type, size } = this; + let { hide, splitButton, type, dropdownSize } = this; var handleMainButtonClick = (event) => { this.$emit('click', event); @@ -124,10 +130,10 @@ let triggerElm = !splitButton ? this.$slots.default : ( - + {this.$slots.default} - + ); diff --git a/packages/form/src/form-item.vue b/packages/form/src/form-item.vue index 932796b00..d49008baf 100644 --- a/packages/form/src/form-item.vue +++ b/packages/form/src/form-item.vue @@ -86,7 +86,8 @@ showMessage: { type: Boolean, default: true - } + }, + size: String }, watch: { error(value) { @@ -158,6 +159,12 @@ }); } return isRequired; + }, + _formSize() { + return this.elForm.size; + }, + elFormItemSize() { + return this.size || this._formSize; } }, data() { diff --git a/packages/form/src/form.vue b/packages/form/src/form.vue index ed242b9f4..654d5b374 100644 --- a/packages/form/src/form.vue +++ b/packages/form/src/form.vue @@ -33,7 +33,8 @@ showMessage: { type: Boolean, default: true - } + }, + size: String }, watch: { rules() { diff --git a/packages/input-number/src/input-number.vue b/packages/input-number/src/input-number.vue index a9fc360fa..e8a982e57 100644 --- a/packages/input-number/src/input-number.vue +++ b/packages/input-number/src/input-number.vue @@ -1,7 +1,7 @@