/
progress-bar.vue
117 lines (116 loc) · 4.15 KB
/
progress-bar.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<template>
<div role="progressbar"
:class="progressBarClasses"
:style="progressBarStyles"
:aria-valuenow="value.toFixed(this.computedPrecision)"
:aria-valuemin="0"
:aria-valuemax="computedMax"
>
<slot>
<span v-if="label" v-html="label"></span>
<template v-else-if="computedShowProgress">{{ progress.toFixed(this.computedPrecision) }}%</template>
<template v-else-if="computedShowValue">{{ value.toFixed(this.computedPrecision) }}</template>
</slot>
</div>
</template>
<script>
export default {
computed: {
progressBarClasses() {
return [
'progress-bar',
this.computedVariant ? `bg-${this.computedVariant}` : '',
(this.computedStriped || this.computedAnimated) ? 'progress-bar-striped' : '',
this.computedAnimated ? 'progress-bar-animated' : ''
];
},
progressBarStyles() {
return {
width: (this.value / this.computedMax) + '%',
height: this.computedHeight,
lineHeight: this.computedHeight
};
},
progress() {
const p = Math.pow(10, this.computedPrecision);
return Math.round((100 * p * this.value) / this.computedMax) / p;
},
computedMax() {
// Prefer our max over parent setting
return typeof this.max === 'number' ? this.max : (this.$parent.max || 100);
},
computedHeight() {
// Prefer parent height over our height
return this.$parent.height || this.height || '1rem';
},
computedVariant() {
// Prefer our variant over parent setting
return this.variant || this.$parent.variant;
},
computedPrecision() {
// Prefer our precision over parent setting
return typeof this.precision === 'number' ? this.precision : (this.$parent.precision || 0);
},
computedStriped() {
// Prefer our striped over parent setting
return typeof this.striped === 'boolean' ? this.striped : (this.$parent.striped || false);
},
computedAnimated() {
// Prefer our animated over parent setting
return typeof this.animated === 'boolean' ? this.animated : (this.$parent.animated || false);
},
computedShowProgress() {
// Prefer our showProgress over parent setting
return typeof this.showProgress === 'boolean' ? this.showProgress : (this.$parent.showProgress || false);
},
computedShowValue() {
// Prefer our showValue over parent setting
return typeof this.showValue === 'boolean' ? this.showValue : (this.$parent.showValue || false);
}
},
props: {
value: {
type: Number,
default: 0
},
label: {
type: String,
value: null
},
// $parent prop values take precedence over the following props
// Which is why they are defaulted to null
max: {
type: Number,
default: null
},
precision: {
type: Number,
default: null
},
variant: {
type: String,
default: null
},
striped: {
type: Boolean,
default: null
},
animated: {
type: Boolean,
default: null
},
showProgress: {
type: Boolean,
default: null
},
showValue: {
type: Boolean,
default: null
},
height: {
type: String,
default: null
}
}
};
</script>