Skip to content

Commit f1bb1c6

Browse files
committed
feat(MdField): create character counter
1 parent 1adc7dd commit f1bb1c6

File tree

5 files changed

+68
-3
lines changed

5 files changed

+68
-3
lines changed

docs/app/pages/Components/Input/Input.vue

+7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<example src="./examples/TextFields.vue" />
22
<example src="./examples/ErrorsMessages.vue" />
3+
<example src="./examples/Counters.vue" />
34

45
<template>
56
<page-container centered :title="$t('pages.input.title')">
@@ -18,6 +19,12 @@
1819

1920
<code-example title="Validation" :component="examples['errors-messages']" />
2021
</div>
22+
23+
<div class="page-container-section">
24+
<h2>Character count</h2>
25+
26+
<code-example title="Counter" :component="examples['counters']" />
27+
</div>
2128
</page-container>
2229
</template>
2330

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<template>
2+
<div>
3+
<md-field>
4+
<label>Required Field</label>
5+
<md-input required maxlength="30" />
6+
</md-field>
7+
8+
<md-field>
9+
<label>Autogrow</label>
10+
<md-textarea md-autogrow required maxlength="200" />
11+
</md-field>
12+
13+
<md-field>
14+
<label>Textarea</label>
15+
<md-textarea required maxlength="80" />
16+
</md-field>
17+
</div>
18+
</template>
19+
20+
<script>
21+
export default {
22+
name: 'Counters'
23+
}
24+
</script>

src/components/MdField/MdField.vue

+28-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<template>
22
<div class="md-field" :class="[$mdActiveTheme, fieldClasses]">
33
<slot />
4+
5+
<span class="md-count" v-if="hasCounter">{{ valueLength }} / {{ state.maxlength }}</span>
46
</div>
57
</template>
68

@@ -13,7 +15,11 @@
1315
state: {}
1416
},
1517
props: {
16-
mdInline: Boolean
18+
mdInline: Boolean,
19+
mdCounter: {
20+
type: Boolean,
21+
default: true
22+
}
1723
},
1824
data: () => ({
1925
state: {
@@ -23,10 +29,24 @@
2329
required: false,
2430
placeholder: false,
2531
textarea: false,
26-
autogrow: false
32+
autogrow: false,
33+
maxlength: null
2734
}
2835
}),
2936
computed: {
37+
hasCounter () {
38+
return this.mdCounter && this.state.maxlength
39+
},
40+
hasValue () {
41+
return this.state.value && this.state.value.length > 0
42+
},
43+
valueLength () {
44+
if (this.state.value) {
45+
return this.state.value.length
46+
}
47+
48+
return 0
49+
},
3050
fieldClasses () {
3151
return {
3252
'md-inline': this.mdInline,
@@ -68,7 +88,7 @@
6888
&:after {
6989
height: 1px;
7090
position: absolute;
71-
top: 47px;
91+
bottom: 0;
7292
right: 0;
7393
left: 0;
7494
z-index: 1;
@@ -233,6 +253,11 @@
233253
padding: 0 16px;
234254
}
235255
256+
.md-count {
257+
right: 6px;
258+
bottom: 2px;
259+
}
260+
236261
&:hover,
237262
&.md-focused {
238263
&:before {

src/components/MdField/MdFieldMixin.js

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export default {
3232
},
3333
required () {
3434
this.setRequired()
35+
},
36+
maxlength () {
37+
this.setMaxlength()
3538
}
3639
},
3740
methods: {
@@ -47,6 +50,9 @@ export default {
4750
setRequired () {
4851
this.state.required = Boolean(this.required)
4952
},
53+
setMaxlength () {
54+
this.state.maxlength = parseInt(this.maxlength, 10)
55+
},
5056
onFocus () {
5157
this.state.focused = true
5258
},
@@ -62,5 +68,6 @@ export default {
6268
this.setPlaceholder()
6369
this.setDisabled()
6470
this.setRequired()
71+
this.setMaxlength()
6572
}
6673
}

src/components/MdField/theme.scss

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88

99
.md-helper-text,
10+
.md-count,
1011
label {
1112
color: rgba(#000, .54);
1213
}
@@ -49,6 +50,7 @@
4950
}
5051

5152
.md-helper-text,
53+
.md-count,
5254
label {
5355
color: rgba(#fff, .7);
5456
}

0 commit comments

Comments
 (0)