未验证 提交 0e58863f 编写于 作者: D doly mood 提交者: GitHub

Enhance textarea (#239)

* feat(textarea): support indicator config

* chore(example): textarea support indicator config

* test(textarea): support indicator config test

* docs(textarea): add indicator config doc

* fix(textarea): check indicator condition
上级 1cd754ef
......@@ -24,6 +24,31 @@ Multi-line input box components. You can use the `v-model` directive to create t
}
```
- Config indicator
```html
<cube-textarea v-model="value" indicator="indicator"></cube-textarea>
```
```js
export default {
data() {
return {
indicator: {
negative: true,
remain: true
}
}
}
}
```
If `indicator` is `false` then the indicator element will not be visible.
If `indicator` is `true`, the config equals `{remain: true, negative: true}`.
If `indicator` is an object, you can use `remain` and `negative` to control whether show the remaining count(if `remain` is `false` means show the textarea value length) and whether allow remaining number is negative.
- Multiple configurations
Support the native attributes of the textarea element.
......@@ -63,6 +88,20 @@ Multi-line input box components. You can use the `v-model` directive to create t
| maxlength | maxlength of input | Number | - | 60 |
| placeholder | placeholder of input | String | - | empty |
| autofocus | autofocus status | Boolean | true/false | false |
| indicator<sup>1.10.0</sup> | indicator config | Boolean/Object | true/false/{} | true |
- indicator sub configuration
If `indicator` is `false` then the indicator element will not be visible.
If `indicator` is `true`, the config equals `{remain: true, negative: true}`.
If `indicator` is an object:
| Attribute | Description | Type | Accepted Values | Default |
| - | - | - | - | - |
| remain | whether show the remaining count, if this value is `false` means show the textarea value length | Boolean | true/false | true |
| negative | avaliable when `remain` is true, this value control whether allow remaining number is negative | Boolean | true/false | true |
### Event
......
......@@ -11,7 +11,7 @@
使用`v-model`对输入内容双向绑定。
```html
<cube-textarea v-model="value" ></cube-textarea>
<cube-textarea v-model="value"></cube-textarea>
```
```javascript
......@@ -24,6 +24,26 @@
}
```
- 配置计数标识
```html
<cube-textarea v-model="value" indicator="indicator"></cube-textarea>
```
```js
export default {
data() {
return {
indicator: {
negative: true,
remain: true
}
}
}
}
```
如果 `indicator` 的值为 `false`,则不显示计数标识,如果为 `true`,则等同于 `{remain: true, negative: true}`,而如果是对象,则可通过 `remain``negative` 分别控制是否显示剩余字数(如果为 `false` 则显示输入字数)和是否允许负值。
- 多项配置
支持原生组件的配置。
......@@ -63,6 +83,16 @@
| maxlength | 最大输入长度 | Number | - | 60 |
| placeholder | 占位文本 | String | - | 空 |
| autofocus | 自动对焦 | Boolean | true/false | false |
| indicator<sup>1.10.0</sup> | 计数标识配置 | Boolean/Object | true/false/{} | true |
- indicator 子配置项
如果 `indicator` 的值为 `false`,则不显示计数标识,如果为 `true` 则等同于配置 `{remain: true, negative: true}`。如果是对象,则:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| remain | 是否控制显示剩余字数,如果为 `false` 则代表显示输入字数 | Boolean | true/false | true |
| negative | 当 `remain` 为 true 时有效,是否允许出现负值 | Boolean | true/false | true |
### 事件
......
......@@ -2,8 +2,12 @@
<cube-page type="textarea-view" title="Textarea" class="option-demo">
<div slot="content">
<div class="textarea-wrapper">
<cube-textarea :disabled="disabled" v-model="text" :maxlength="+maxlength || 60"
:width="width || '300px'"></cube-textarea>
<cube-textarea
v-model="text"
:disabled="disabled"
:maxlength="+maxlength || 60"
:indicator="showIndicator ? indicator : showIndicator"
:width="width || '300px'"></cube-textarea>
</div>
<div class="options">
<div class="title">Options</div>
......@@ -16,6 +20,14 @@
<input-option class="item sub" name="width" :value="width"
@update:value="updateWidth"></input-option>
</div>
<div class="group">
<switch-option class="item" name="indicator" :value="showIndicator"
@update:value="updateIndicator"></switch-option>
<switch-option v-if="showIndicator" class="item" name="negative" :value="indicator.negative"
@update:value="updateIndicatorNegative"></switch-option>
<switch-option v-if="showIndicator" class="item" name="remain" :value="indicator.remain"
@update:value="updateIndicatorRemain"></switch-option>
</div>
</div>
</div>
</div>
......@@ -34,7 +46,12 @@
text: '',
disabled: false,
maxlength: 60,
width: '274px'
width: '274px',
showIndicator: true,
indicator: {
negative: true,
remain: true
}
}
},
methods: {
......@@ -46,6 +63,15 @@
},
updateWidth(val) {
this.width = val
},
updateIndicator(val) {
this.showIndicator = val
},
updateIndicatorNegative(val) {
this.indicator.negative = val
},
updateIndicatorRemain(val) {
this.indicator.remain = val
}
},
components: {
......
......@@ -10,7 +10,7 @@
@focus="handleFocus"
@blur="handleBlur">
</textarea>
<span v-show="expanded" class="cube-textarea-indicator">{{remain}}</span>
<span v-if="indicator" v-show="expanded" class="cube-textarea-indicator">{{indicatorConf.remain ? remain : count}}</span>
</div>
</template>
......@@ -18,6 +18,11 @@
const COMPONENT_NAME = 'cube-textarea'
const EVENT_INPUT = 'input'
const DEFAULT_INDICATOR = {
negative: true,
remain: true
}
export default {
name: COMPONENT_NAME,
data() {
......@@ -52,11 +57,29 @@
maxlength: {
type: Number,
default: 60
},
indicator: {
type: [Boolean, Object],
default: true
}
},
computed: {
indicatorConf() {
let indicator = this.indicator
if (typeof indicator === 'boolean') {
indicator = {}
}
return Object.assign({}, DEFAULT_INDICATOR, indicator)
},
count() {
return this.textareaValue.length
},
remain() {
return this.maxlength - this.value.length
let diff = this.maxlength - this.count
if (!this.indicatorConf.negative && diff < 0) {
diff = 0
}
return diff
}
},
watch: {
......
......@@ -23,6 +23,16 @@ describe('Textarea.vue', () => {
expect(el.querySelector('textarea'))
.to.be.ok
})
it('should render correct contents - no indicator', () => {
vm = createTextarea('', false)
const el = vm.$el
expect(el.className)
.to.equal('cube-textarea-wrapper')
expect(el.querySelector('textarea'))
.to.be.ok
expect(el.querySelector('.cube-textarea-indicator'))
.not.to.be.ok
})
it('should not expand when blur', () => {
vm = createTextarea()
expect(vm.$el.offsetHeight)
......@@ -49,15 +59,34 @@ describe('Textarea.vue', () => {
setTimeout(() => {
expect(vm.$el.querySelector('.cube-textarea-indicator').innerText)
.to.equal('56')
done()
vm.$parent.value = new Array(61).join('1')
setTimeout(() => {
expect(vm.$el.querySelector('.cube-textarea-indicator').innerText)
.to.equal('0')
// update maxlength
vm.$parent.maxlength = 30
vm.$parent.$set(vm.$parent, 'indicator', {
negative: false,
remain: true
})
setTimeout(() => {
expect(vm.$el.querySelector('.cube-textarea-indicator').innerText)
.to.equal('0')
done()
})
})
})
})
it('should change value', (done) => {
vm = createTextarea(1)
vm = createTextarea(1, {
remain: false
})
vm.$parent.value = '1234'
setTimeout(() => {
expect(vm.$el.querySelector('textarea').value)
.to.equal('1234')
expect(vm.$el.querySelector('.cube-textarea-indicator').innerText)
.to.equal('4')
done()
}, 100)
})
......@@ -81,12 +110,14 @@ describe('Textarea.vue', () => {
})
})
function createTextarea (value) {
function createTextarea (value, indicator = true) {
const vm = createVue({
template: `
<cube-textarea
:disabled="disabled"
:readonly="readonly"
:indicator="indicator"
:maxlength="maxlength"
v-model="value"
>
</cube-textarea>
......@@ -94,7 +125,9 @@ function createTextarea (value) {
data: {
disabled: false,
readonly: false,
value: value && 'test'
maxlength: 60,
value: value && 'test',
indicator: indicator
}
})
return vm
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册