UNPKG

3.02 kBJavaScriptView Raw
1import Class from '../mixin/class';
2import {$, empty, html} from 'uikit-util';
3
4export default {
5
6 mixins: [Class],
7
8 props: {
9 date: String,
10 clsWrapper: String
11 },
12
13 data: {
14 date: '',
15 clsWrapper: '.uk-countdown-%unit%'
16 },
17
18 computed: {
19
20 date({date}) {
21 return Date.parse(date);
22 },
23
24 days({clsWrapper}, $el) {
25 return $(clsWrapper.replace('%unit%', 'days'), $el);
26 },
27
28 hours({clsWrapper}, $el) {
29 return $(clsWrapper.replace('%unit%', 'hours'), $el);
30 },
31
32 minutes({clsWrapper}, $el) {
33 return $(clsWrapper.replace('%unit%', 'minutes'), $el);
34 },
35
36 seconds({clsWrapper}, $el) {
37 return $(clsWrapper.replace('%unit%', 'seconds'), $el);
38 },
39
40 units() {
41 return ['days', 'hours', 'minutes', 'seconds'].filter(unit => this[unit]);
42 }
43
44 },
45
46 connected() {
47 this.start();
48 },
49
50 disconnected() {
51 this.stop();
52 this.units.forEach(unit => empty(this[unit]));
53 },
54
55 events: [
56
57 {
58
59 name: 'visibilitychange',
60
61 el: document,
62
63 handler() {
64 if (document.hidden) {
65 this.stop();
66 } else {
67 this.start();
68 }
69 }
70
71 }
72
73 ],
74
75 update: {
76
77 write() {
78
79 const timespan = getTimeSpan(this.date);
80
81 if (timespan.total <= 0) {
82
83 this.stop();
84
85 timespan.days
86 = timespan.hours
87 = timespan.minutes
88 = timespan.seconds
89 = 0;
90 }
91
92 this.units.forEach(unit => {
93
94 let digits = String(Math.floor(timespan[unit]));
95
96 digits = digits.length < 2 ? `0${digits}` : digits;
97
98 const el = this[unit];
99 if (el.textContent !== digits) {
100 digits = digits.split('');
101
102 if (digits.length !== el.children.length) {
103 html(el, digits.map(() => '<span></span>').join(''));
104 }
105
106 digits.forEach((digit, i) => el.children[i].textContent = digit);
107 }
108
109 });
110
111 }
112
113 },
114
115 methods: {
116
117 start() {
118
119 this.stop();
120
121 if (this.date && this.units.length) {
122 this.$emit();
123 this.timer = setInterval(() => this.$emit(), 1000);
124 }
125
126 },
127
128 stop() {
129
130 if (this.timer) {
131 clearInterval(this.timer);
132 this.timer = null;
133 }
134
135 }
136
137 }
138
139};
140
141function getTimeSpan(date) {
142
143 const total = date - Date.now();
144
145 return {
146 total,
147 seconds: total / 1000 % 60,
148 minutes: total / 1000 / 60 % 60,
149 hours: total / 1000 / 60 / 60 % 24,
150 days: total / 1000 / 60 / 60 / 24
151 };
152}