├── .gitignore
├── LICENSE
├── README.md
├── demo
└── index.html
├── dist
├── mdtimepicker-theme.css
├── mdtimepicker.css
├── mdtimepicker.js
├── mdtimepicker.min.css
└── mdtimepicker.min.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── rollup.config.mjs
├── src
├── .babelrc.json
├── helpers.js
├── mdtimepicker.js
├── mdtimepicker.scss
├── themes
│ ├── _format.scss
│ ├── blue.scss
│ ├── dark.scss
│ ├── green.scss
│ ├── indigo.scss
│ ├── purple.scss
│ ├── red.scss
│ └── teal.scss
└── vars.js
├── vue-timepicker.js
└── vue3-timepicker.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | /logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 | *.pid.lock
11 |
12 | # Bower dependency directory (https://bower.io/)
13 | bower_components
14 |
15 | # Dependency directories
16 | node_modules/
17 |
18 | # Optional npm cache directory
19 | .npm
20 |
21 | # Optional eslint cache
22 | .eslintcache
23 |
24 | # Output of 'npm pack'
25 | *.tgz
26 |
27 | # parcel-bundler cache (https://parceljs.org/)
28 | .cache
29 |
30 | # IDE / Editor
31 | .idea
32 |
33 | # Service worker
34 | sw.*
35 |
36 | # macOS
37 | .DS_Store
38 |
39 | # Vim swap files
40 | *.swp
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Dionlee Uy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | MDTimePicker
2 | ========
3 | [](https://www.npmjs.com/package/@dmuy/timepicker)
4 |
5 |
6 |
7 | Material design inspired time picker plugin.
8 |
9 | ## Documentation
10 | * [Installation](https://github.com/dmuy/MDTimePicker/wiki/Installation)
11 | * [Options](https://github.com/dmuy/MDTimePicker/wiki/Options)
12 | * [Configurations](https://github.com/dmuy/MDTimePicker/wiki/Options#configurations)
13 | * [Callback Functions](https://github.com/dmuy/MDTimePicker/wiki/Options#callback-functions)
14 | * [Formatting](https://github.com/dmuy/MDTimePicker/wiki/Options#formatting)
15 | * [Usage](https://github.com/dmuy/MDTimePicker/wiki/Usage)
16 | * [Min and Max](https://github.com/dmuy/MDTimePicker/wiki/Usage#min-and-max)
17 | * [Built-in Methods](https://github.com/dmuy/MDTimePicker/wiki/Usage#usable-built-in-methods)
18 | * [Event Handling](https://github.com/dmuy/MDTimePicker/wiki/Usage#event)
19 | * [Themes](https://github.com/dmuy/MDTimePicker/wiki/Usage#themes)
20 | * [Usage (Vue)](https://github.com/dmuy/MDTimePicker/wiki/Usage-(Vue))
21 | * [Nuxt](https://github.com/dmuy/MDTimePicker/wiki/Usage-(Vue)#nuxt)
22 |
23 | **[DEMO](https://dmuy.github.io/MDTimePicker/)**
24 |
25 | ## Screenshots
26 | 
27 | 
28 | 
29 | 
30 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Timepicker Plugin
5 |
6 |
7 |
8 |
9 |
10 |
31 |
32 |
33 |
34 |
MDTimePicker
35 |
46 |
Time picker
47 |
48 |
49 |
50 | Logger:
51 |
52 |
53 |
54 |
55 |
85 |
86 |
--------------------------------------------------------------------------------
/dist/mdtimepicker-theme.css:
--------------------------------------------------------------------------------
1 | .mdtp__wrapper[data-theme='yellow'] .mdtp__time_holder {
2 | background-color: #F9A825;
3 | }
4 |
5 | .mdtp__wrapper[data-theme='yellow'] .mdtp__clock .mdtp__am.active,
6 | .mdtp__wrapper[data-theme='yellow'] .mdtp__clock .mdtp__pm.active,
7 | .mdtp__wrapper[data-theme='yellow'] .mdtp__clock .mdtp__clock_dot {
8 | background-color: #F9A825;
9 | }
10 |
11 | .mdtp__wrapper[data-theme='yellow'] .mdtp__clock .mdtp__digit.active span,
12 | .mdtp__wrapper[data-theme='yellow'] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
13 | background-color: #F9A825 !important;
14 | }
15 |
16 | .mdtp__wrapper[data-theme='yellow'] .mdtp__clock .mdtp__digit.active:before {
17 | background-color: #F9A825;
18 | }
19 |
20 | .mdtp__wrapper[data-theme='yellow'] .mdtp__button {
21 | color: #F9A825;
22 | }
23 |
--------------------------------------------------------------------------------
/dist/mdtimepicker.css:
--------------------------------------------------------------------------------
1 | /*!Don't remove this!
2 | * MDTimePicker plugin styles
3 | *
4 | * Author: Dionlee Uy
5 | * Email: dionleeuy@gmail.com
6 | */
7 | @import url("https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap");
8 | .mdtimepicker {
9 | position: fixed;
10 | top: 0;
11 | left: 0;
12 | right: 0;
13 | bottom: 0;
14 | font-family: Roboto, sans-serif;
15 | font-size: 14px;
16 | background-color: rgba(10, 10, 10, 0.65);
17 | transition: background-color .28s ease;
18 | z-index: 100001;
19 | }
20 |
21 | .mdtimepicker .mdtp__wrapper {
22 | position: absolute;
23 | display: flex;
24 | flex-direction: column;
25 | left: 50%;
26 | bottom: 24px;
27 | min-width: 280px;
28 | opacity: 1;
29 | outline: none;
30 | -webkit-user-select: none;
31 | -moz-user-select: none;
32 | user-select: none;
33 | border-radius: 4px;
34 | transform: translateX(-50%) scale(1);
35 | box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12);
36 | transition: transform .28s ease, opacity .28s ease;
37 | overflow: hidden;
38 | }
39 |
40 | .mdtimepicker .mdtp__wrapper.animate {
41 | transform: translateX(-50%) scale(1.05);
42 | opacity: 0;
43 | }
44 |
45 | .mdtimepicker .mdtp__time_holder {
46 | display: flex;
47 | flex-direction: row;
48 | align-items: center;
49 | justify-content: center;
50 | font-size: 46px;
51 | padding: 20px 24px;
52 | color: rgba(255, 255, 255, 0.5);
53 | text-align: center;
54 | background-color: #1565c0;
55 | }
56 |
57 | .mdtimepicker .mdtp__time_holder > span {
58 | display: inline-block;
59 | line-height: 48px;
60 | cursor: default;
61 | }
62 |
63 | .mdtimepicker .mdtp__time_holder > span:not(.mdtp__timedots):not(.mdtp__ampm) {
64 | cursor: pointer;
65 | margin: 0 4px;
66 | transition: color .2s linear;
67 | }
68 |
69 | .mdtimepicker .mdtp__time_holder .mdtp__time_h.active,
70 | .mdtimepicker .mdtp__time_holder .mdtp__time_m.active {
71 | color: #fafafa;
72 | }
73 |
74 | .mdtimepicker .mdtp__time_holder .mdtp__ampm {
75 | font-size: 18px;
76 | cursor: pointer;
77 | transition: color .2s linear;
78 | }
79 |
80 | .mdtimepicker .mdtp__time_holder .mdtp__ampm:hover {
81 | color: #fafafa;
82 | }
83 |
84 | .mdtimepicker .mdtp__clock_holder {
85 | position: relative;
86 | background-color: #fff;
87 | }
88 |
89 | .mdtimepicker .mdtp__clock_holder .mdtp__clock {
90 | position: relative;
91 | width: 250px;
92 | height: 250px;
93 | margin: 20px;
94 | border-radius: 50%;
95 | background-color: #eee;
96 | }
97 |
98 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am,
99 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm {
100 | display: block;
101 | position: absolute;
102 | bottom: -8px;
103 | width: 36px;
104 | height: 36px;
105 | line-height: 36px;
106 | text-align: center;
107 | cursor: pointer;
108 | border-radius: 50%;
109 | border: 1px solid rgba(0, 0, 0, 0.1);
110 | background: rgba(0, 0, 0, 0.05);
111 | transition: background-color .2s ease, color .2s;
112 | z-index: 3;
113 | }
114 |
115 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am:hover,
116 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm:hover {
117 | background-color: rgba(0, 0, 0, 0.1);
118 | }
119 |
120 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am.active,
121 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm.active {
122 | color: #fafafa;
123 | background-color: #1565c0;
124 | }
125 |
126 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am {
127 | left: -8px;
128 | }
129 |
130 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm {
131 | right: -8px;
132 | }
133 |
134 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__clock_dot {
135 | position: absolute;
136 | top: 50%;
137 | left: 50%;
138 | padding: 4px;
139 | border-radius: 50%;
140 | background-color: #1565c0;
141 | transform: translate(-50%, -50%);
142 | }
143 |
144 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__hour_holder,
145 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder {
146 | position: absolute;
147 | top: 0;
148 | width: 100%;
149 | height: 100%;
150 | opacity: 1;
151 | transform: scale(1);
152 | transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.35s ease;
153 | overflow: hidden;
154 | }
155 |
156 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__hour_holder.hidden,
157 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder.hidden {
158 | display: none;
159 | }
160 |
161 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__hour_holder.animate {
162 | transform: scale(1.2);
163 | opacity: 0;
164 | }
165 |
166 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder.animate {
167 | transform: scale(0.8);
168 | opacity: 0;
169 | }
170 |
171 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit {
172 | position: absolute;
173 | width: 50%;
174 | top: 50%;
175 | left: 0;
176 | margin-top: -16px;
177 | transform-origin: right center;
178 | z-index: 1;
179 | }
180 |
181 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit span {
182 | display: inline-block;
183 | width: 32px;
184 | height: 32px;
185 | line-height: 32px;
186 | margin-left: 8px;
187 | text-align: center;
188 | border-radius: 50%;
189 | cursor: pointer;
190 | transition: background-color .28s, color .14s;
191 | }
192 |
193 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.inner--digit {
194 | width: 36%;
195 | left: 14%;
196 | z-index: 2;
197 | }
198 |
199 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.active span,
200 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
201 | background-color: #1565c0 !important;
202 | color: #fff;
203 | z-index: 2;
204 | }
205 |
206 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.digit--disabled span {
207 | color: #c8c8c8;
208 | cursor: not-allowed;
209 | background-color: transparent !important;
210 | }
211 |
212 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.active:before {
213 | content: '';
214 | display: block;
215 | position: absolute;
216 | top: calc(50% - 1px);
217 | right: 0;
218 | height: 2px;
219 | width: calc(100% - 40px);
220 | background-color: #1565c0;
221 | }
222 |
223 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit {
224 | font-size: 13px;
225 | }
226 |
227 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit:not(.marker) {
228 | margin-top: -6px;
229 | height: 12px;
230 | }
231 |
232 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit:not(.marker) span {
233 | width: 12px;
234 | height: 12px;
235 | line-height: 12px;
236 | margin-left: 14px;
237 | }
238 |
239 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit:not(.marker).active:before {
240 | width: calc(100% - 26px);
241 | }
242 |
243 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit.marker {
244 | margin-top: -12px;
245 | }
246 |
247 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit.marker span {
248 | width: 24px;
249 | height: 24px;
250 | line-height: 24px;
251 | margin-left: 10px;
252 | }
253 |
254 | .mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit.marker.active:before {
255 | width: calc(100% - 34px);
256 | }
257 |
258 | .mdtimepicker .mdtp__buttons {
259 | padding: 0 10px 10px;
260 | text-align: right;
261 | }
262 |
263 | .mdtimepicker .mdtp__buttons .mdtp__button {
264 | display: inline-block;
265 | padding: 0 16px;
266 | min-width: 40px;
267 | text-align: center;
268 | text-transform: uppercase;
269 | line-height: 32px;
270 | font-weight: 500;
271 | cursor: pointer;
272 | color: #1565c0;
273 | border-radius: 4px;
274 | transition: background-color .2s linear;
275 | }
276 |
277 | .mdtimepicker .mdtp__buttons .mdtp__button:hover {
278 | background-color: rgba(0, 0, 0, 0.1);
279 | }
280 |
281 | .mdtimepicker .mdtp__buttons .mdtp__button:active {
282 | background-color: rgba(0, 0, 0, 0.2);
283 | }
284 |
285 | .mdtimepicker .mdtp__buttons .mdtp__button.clear-btn {
286 | float: left;
287 | color: #ef5350 !important;
288 | }
289 |
290 | .mdtimepicker .mdtp__buttons:after {
291 | content: '';
292 | display: block;
293 | clear: both;
294 | }
295 |
296 | .mdtimepicker.hidden {
297 | display: none;
298 | }
299 |
300 | .mdtimepicker.animate {
301 | background-color: transparent;
302 | }
303 |
304 | .mdtp__digit.rotate--15 {
305 | transform: rotate(-15deg);
306 | }
307 |
308 | .mdtp__digit.rotate--15 span {
309 | transform: rotate(15deg);
310 | }
311 |
312 | .mdtp__digit.rotate-6 {
313 | transform: rotate(6deg);
314 | }
315 |
316 | .mdtp__digit.rotate-6 span {
317 | transform: rotate(-6deg);
318 | }
319 |
320 | .mdtp__digit.rotate-12 {
321 | transform: rotate(12deg);
322 | }
323 |
324 | .mdtp__digit.rotate-12 span {
325 | transform: rotate(-12deg);
326 | }
327 |
328 | .mdtp__digit.rotate-15 {
329 | transform: rotate(15deg);
330 | }
331 |
332 | .mdtp__digit.rotate-15 span {
333 | transform: rotate(-15deg);
334 | }
335 |
336 | .mdtp__digit.rotate-18 {
337 | transform: rotate(18deg);
338 | }
339 |
340 | .mdtp__digit.rotate-18 span {
341 | transform: rotate(-18deg);
342 | }
343 |
344 | .mdtp__digit.rotate-24 {
345 | transform: rotate(24deg);
346 | }
347 |
348 | .mdtp__digit.rotate-24 span {
349 | transform: rotate(-24deg);
350 | }
351 |
352 | .mdtp__digit.rotate-30 {
353 | transform: rotate(30deg);
354 | }
355 |
356 | .mdtp__digit.rotate-30 span {
357 | transform: rotate(-30deg);
358 | }
359 |
360 | .mdtp__digit.rotate-36 {
361 | transform: rotate(36deg);
362 | }
363 |
364 | .mdtp__digit.rotate-36 span {
365 | transform: rotate(-36deg);
366 | }
367 |
368 | .mdtp__digit.rotate-42 {
369 | transform: rotate(42deg);
370 | }
371 |
372 | .mdtp__digit.rotate-42 span {
373 | transform: rotate(-42deg);
374 | }
375 |
376 | .mdtp__digit.rotate-45 {
377 | transform: rotate(45deg);
378 | }
379 |
380 | .mdtp__digit.rotate-45 span {
381 | transform: rotate(-45deg);
382 | }
383 |
384 | .mdtp__digit.rotate-48 {
385 | transform: rotate(48deg);
386 | }
387 |
388 | .mdtp__digit.rotate-48 span {
389 | transform: rotate(-48deg);
390 | }
391 |
392 | .mdtp__digit.rotate-54 {
393 | transform: rotate(54deg);
394 | }
395 |
396 | .mdtp__digit.rotate-54 span {
397 | transform: rotate(-54deg);
398 | }
399 |
400 | .mdtp__digit.rotate-60 {
401 | transform: rotate(60deg);
402 | }
403 |
404 | .mdtp__digit.rotate-60 span {
405 | transform: rotate(-60deg);
406 | }
407 |
408 | .mdtp__digit.rotate-66 {
409 | transform: rotate(66deg);
410 | }
411 |
412 | .mdtp__digit.rotate-66 span {
413 | transform: rotate(-66deg);
414 | }
415 |
416 | .mdtp__digit.rotate-72 {
417 | transform: rotate(72deg);
418 | }
419 |
420 | .mdtp__digit.rotate-72 span {
421 | transform: rotate(-72deg);
422 | }
423 |
424 | .mdtp__digit.rotate-75 {
425 | transform: rotate(75deg);
426 | }
427 |
428 | .mdtp__digit.rotate-75 span {
429 | transform: rotate(-75deg);
430 | }
431 |
432 | .mdtp__digit.rotate-78 {
433 | transform: rotate(78deg);
434 | }
435 |
436 | .mdtp__digit.rotate-78 span {
437 | transform: rotate(-78deg);
438 | }
439 |
440 | .mdtp__digit.rotate-84 {
441 | transform: rotate(84deg);
442 | }
443 |
444 | .mdtp__digit.rotate-84 span {
445 | transform: rotate(-84deg);
446 | }
447 |
448 | .mdtp__digit.rotate-90 {
449 | transform: rotate(90deg);
450 | }
451 |
452 | .mdtp__digit.rotate-90 span {
453 | transform: rotate(-90deg);
454 | }
455 |
456 | .mdtp__digit.rotate-96 {
457 | transform: rotate(96deg);
458 | }
459 |
460 | .mdtp__digit.rotate-96 span {
461 | transform: rotate(-96deg);
462 | }
463 |
464 | .mdtp__digit.rotate-102 {
465 | transform: rotate(102deg);
466 | }
467 |
468 | .mdtp__digit.rotate-102 span {
469 | transform: rotate(-102deg);
470 | }
471 |
472 | .mdtp__digit.rotate-105 {
473 | transform: rotate(105deg);
474 | }
475 |
476 | .mdtp__digit.rotate-105 span {
477 | transform: rotate(-105deg);
478 | }
479 |
480 | .mdtp__digit.rotate-108 {
481 | transform: rotate(108deg);
482 | }
483 |
484 | .mdtp__digit.rotate-108 span {
485 | transform: rotate(-108deg);
486 | }
487 |
488 | .mdtp__digit.rotate-114 {
489 | transform: rotate(114deg);
490 | }
491 |
492 | .mdtp__digit.rotate-114 span {
493 | transform: rotate(-114deg);
494 | }
495 |
496 | .mdtp__digit.rotate-120 {
497 | transform: rotate(120deg);
498 | }
499 |
500 | .mdtp__digit.rotate-120 span {
501 | transform: rotate(-120deg);
502 | }
503 |
504 | .mdtp__digit.rotate-126 {
505 | transform: rotate(126deg);
506 | }
507 |
508 | .mdtp__digit.rotate-126 span {
509 | transform: rotate(-126deg);
510 | }
511 |
512 | .mdtp__digit.rotate-132 {
513 | transform: rotate(132deg);
514 | }
515 |
516 | .mdtp__digit.rotate-132 span {
517 | transform: rotate(-132deg);
518 | }
519 |
520 | .mdtp__digit.rotate-135 {
521 | transform: rotate(135deg);
522 | }
523 |
524 | .mdtp__digit.rotate-135 span {
525 | transform: rotate(-135deg);
526 | }
527 |
528 | .mdtp__digit.rotate-138 {
529 | transform: rotate(138deg);
530 | }
531 |
532 | .mdtp__digit.rotate-138 span {
533 | transform: rotate(-138deg);
534 | }
535 |
536 | .mdtp__digit.rotate-144 {
537 | transform: rotate(144deg);
538 | }
539 |
540 | .mdtp__digit.rotate-144 span {
541 | transform: rotate(-144deg);
542 | }
543 |
544 | .mdtp__digit.rotate-150 {
545 | transform: rotate(150deg);
546 | }
547 |
548 | .mdtp__digit.rotate-150 span {
549 | transform: rotate(-150deg);
550 | }
551 |
552 | .mdtp__digit.rotate-156 {
553 | transform: rotate(156deg);
554 | }
555 |
556 | .mdtp__digit.rotate-156 span {
557 | transform: rotate(-156deg);
558 | }
559 |
560 | .mdtp__digit.rotate-162 {
561 | transform: rotate(162deg);
562 | }
563 |
564 | .mdtp__digit.rotate-162 span {
565 | transform: rotate(-162deg);
566 | }
567 |
568 | .mdtp__digit.rotate-165 {
569 | transform: rotate(165deg);
570 | }
571 |
572 | .mdtp__digit.rotate-165 span {
573 | transform: rotate(-165deg);
574 | }
575 |
576 | .mdtp__digit.rotate-168 {
577 | transform: rotate(168deg);
578 | }
579 |
580 | .mdtp__digit.rotate-168 span {
581 | transform: rotate(-168deg);
582 | }
583 |
584 | .mdtp__digit.rotate-174 {
585 | transform: rotate(174deg);
586 | }
587 |
588 | .mdtp__digit.rotate-174 span {
589 | transform: rotate(-174deg);
590 | }
591 |
592 | .mdtp__digit.rotate-180 {
593 | transform: rotate(180deg);
594 | }
595 |
596 | .mdtp__digit.rotate-180 span {
597 | transform: rotate(-180deg);
598 | }
599 |
600 | .mdtp__digit.rotate-186 {
601 | transform: rotate(186deg);
602 | }
603 |
604 | .mdtp__digit.rotate-186 span {
605 | transform: rotate(-186deg);
606 | }
607 |
608 | .mdtp__digit.rotate-192 {
609 | transform: rotate(192deg);
610 | }
611 |
612 | .mdtp__digit.rotate-192 span {
613 | transform: rotate(-192deg);
614 | }
615 |
616 | .mdtp__digit.rotate-195 {
617 | transform: rotate(195deg);
618 | }
619 |
620 | .mdtp__digit.rotate-195 span {
621 | transform: rotate(-195deg);
622 | }
623 |
624 | .mdtp__digit.rotate-198 {
625 | transform: rotate(198deg);
626 | }
627 |
628 | .mdtp__digit.rotate-198 span {
629 | transform: rotate(-198deg);
630 | }
631 |
632 | .mdtp__digit.rotate-204 {
633 | transform: rotate(204deg);
634 | }
635 |
636 | .mdtp__digit.rotate-204 span {
637 | transform: rotate(-204deg);
638 | }
639 |
640 | .mdtp__digit.rotate-210 {
641 | transform: rotate(210deg);
642 | }
643 |
644 | .mdtp__digit.rotate-210 span {
645 | transform: rotate(-210deg);
646 | }
647 |
648 | .mdtp__digit.rotate-216 {
649 | transform: rotate(216deg);
650 | }
651 |
652 | .mdtp__digit.rotate-216 span {
653 | transform: rotate(-216deg);
654 | }
655 |
656 | .mdtp__digit.rotate-222 {
657 | transform: rotate(222deg);
658 | }
659 |
660 | .mdtp__digit.rotate-222 span {
661 | transform: rotate(-222deg);
662 | }
663 |
664 | .mdtp__digit.rotate-225 {
665 | transform: rotate(225deg);
666 | }
667 |
668 | .mdtp__digit.rotate-225 span {
669 | transform: rotate(-225deg);
670 | }
671 |
672 | .mdtp__digit.rotate-228 {
673 | transform: rotate(228deg);
674 | }
675 |
676 | .mdtp__digit.rotate-228 span {
677 | transform: rotate(-228deg);
678 | }
679 |
680 | .mdtp__digit.rotate-234 {
681 | transform: rotate(234deg);
682 | }
683 |
684 | .mdtp__digit.rotate-234 span {
685 | transform: rotate(-234deg);
686 | }
687 |
688 | .mdtp__digit.rotate-240 {
689 | transform: rotate(240deg);
690 | }
691 |
692 | .mdtp__digit.rotate-240 span {
693 | transform: rotate(-240deg);
694 | }
695 |
696 | .mdtp__digit.rotate-246 {
697 | transform: rotate(246deg);
698 | }
699 |
700 | .mdtp__digit.rotate-246 span {
701 | transform: rotate(-246deg);
702 | }
703 |
704 | .mdtp__digit.rotate-252 {
705 | transform: rotate(252deg);
706 | }
707 |
708 | .mdtp__digit.rotate-252 span {
709 | transform: rotate(-252deg);
710 | }
711 |
712 | .mdtp__digit.rotate-255 {
713 | transform: rotate(255deg);
714 | }
715 |
716 | .mdtp__digit.rotate-255 span {
717 | transform: rotate(-255deg);
718 | }
719 |
720 | .mdtp__digit.rotate-258 {
721 | transform: rotate(258deg);
722 | }
723 |
724 | .mdtp__digit.rotate-258 span {
725 | transform: rotate(-258deg);
726 | }
727 |
728 | .mdtp__digit.rotate-264 {
729 | transform: rotate(264deg);
730 | }
731 |
732 | .mdtp__digit.rotate-264 span {
733 | transform: rotate(-264deg);
734 | }
735 |
736 | .mdtp__digit.rotate-270 {
737 | transform: rotate(270deg);
738 | }
739 |
740 | .mdtp__digit.rotate-270 span {
741 | transform: rotate(-270deg);
742 | }
743 |
744 | .mdtp__digit.rotate-276 {
745 | transform: rotate(276deg);
746 | }
747 |
748 | .mdtp__digit.rotate-276 span {
749 | transform: rotate(-276deg);
750 | }
751 |
752 | .mdtp__digit.rotate-282 {
753 | transform: rotate(282deg);
754 | }
755 |
756 | .mdtp__digit.rotate-282 span {
757 | transform: rotate(-282deg);
758 | }
759 |
760 | .mdtp__digit.rotate-285 {
761 | transform: rotate(285deg);
762 | }
763 |
764 | .mdtp__digit.rotate-285 span {
765 | transform: rotate(-285deg);
766 | }
767 |
768 | .mdtp__digit.rotate-288 {
769 | transform: rotate(288deg);
770 | }
771 |
772 | .mdtp__digit.rotate-288 span {
773 | transform: rotate(-288deg);
774 | }
775 |
776 | .mdtp__digit.rotate-294 {
777 | transform: rotate(294deg);
778 | }
779 |
780 | .mdtp__digit.rotate-294 span {
781 | transform: rotate(-294deg);
782 | }
783 |
784 | .mdtp__digit.rotate-300 {
785 | transform: rotate(300deg);
786 | }
787 |
788 | .mdtp__digit.rotate-300 span {
789 | transform: rotate(-300deg);
790 | }
791 |
792 | .mdtp__digit.rotate-306 {
793 | transform: rotate(306deg);
794 | }
795 |
796 | .mdtp__digit.rotate-306 span {
797 | transform: rotate(-306deg);
798 | }
799 |
800 | .mdtp__digit.rotate-312 {
801 | transform: rotate(312deg);
802 | }
803 |
804 | .mdtp__digit.rotate-312 span {
805 | transform: rotate(-312deg);
806 | }
807 |
808 | .mdtp__digit.rotate-315 {
809 | transform: rotate(315deg);
810 | }
811 |
812 | .mdtp__digit.rotate-315 span {
813 | transform: rotate(-315deg);
814 | }
815 |
816 | .mdtp__digit.rotate-318 {
817 | transform: rotate(318deg);
818 | }
819 |
820 | .mdtp__digit.rotate-318 span {
821 | transform: rotate(-318deg);
822 | }
823 |
824 | .mdtp__digit.rotate-324 {
825 | transform: rotate(324deg);
826 | }
827 |
828 | .mdtp__digit.rotate-324 span {
829 | transform: rotate(-324deg);
830 | }
831 |
832 | .mdtp__digit.rotate-330 {
833 | transform: rotate(330deg);
834 | }
835 |
836 | .mdtp__digit.rotate-330 span {
837 | transform: rotate(-330deg);
838 | }
839 |
840 | .mdtp__digit.rotate-336 {
841 | transform: rotate(336deg);
842 | }
843 |
844 | .mdtp__digit.rotate-336 span {
845 | transform: rotate(-336deg);
846 | }
847 |
848 | .mdtp__digit.rotate-342 {
849 | transform: rotate(342deg);
850 | }
851 |
852 | .mdtp__digit.rotate-342 span {
853 | transform: rotate(-342deg);
854 | }
855 |
856 | .mdtp__digit.rotate-348 {
857 | transform: rotate(348deg);
858 | }
859 |
860 | .mdtp__digit.rotate-348 span {
861 | transform: rotate(-348deg);
862 | }
863 |
864 | .mdtp__digit.rotate-354 {
865 | transform: rotate(354deg);
866 | }
867 |
868 | .mdtp__digit.rotate-354 span {
869 | transform: rotate(-354deg);
870 | }
871 |
872 | .mdtp__digit.rotate-360 {
873 | transform: rotate(360deg);
874 | }
875 |
876 | .mdtp__digit.rotate-360 span {
877 | transform: rotate(-360deg);
878 | }
879 |
880 | body[mdtimepicker-display='on'] {
881 | overflow: hidden;
882 | }
883 |
884 | @media (max-height: 360px) {
885 | .mdtimepicker .mdtp__wrapper {
886 | flex-direction: row;
887 | bottom: 8px;
888 | }
889 | .mdtimepicker .mdtp__time_holder {
890 | width: 160px;
891 | padding: 20px;
892 | }
893 | .mdtimepicker .mdtp__clock .mdtp__am, .mdtimepicker .mdtp__clock .mdtp__pm {
894 | bottom: -4px;
895 | }
896 | .mdtimepicker .mdtp__clock .mdtp__am {
897 | left: -4px;
898 | }
899 | .mdtimepicker .mdtp__clock .mdtp__pm {
900 | right: -4px;
901 | }
902 | }
903 |
904 | @media (max-height: 320px) {
905 | .mdtimepicker .mdtp__wrapper {
906 | bottom: 0;
907 | }
908 | }
909 |
910 | .mdtp__wrapper[data-theme='red'] .mdtp__time_holder {
911 | background-color: #c62828;
912 | }
913 |
914 | .mdtp__wrapper[data-theme='red'] .mdtp__clock .mdtp__am.active,
915 | .mdtp__wrapper[data-theme='red'] .mdtp__clock .mdtp__pm.active,
916 | .mdtp__wrapper[data-theme='red'] .mdtp__clock .mdtp__clock_dot {
917 | background-color: #c62828;
918 | }
919 |
920 | .mdtp__wrapper[data-theme='red'] .mdtp__clock .mdtp__digit.active span,
921 | .mdtp__wrapper[data-theme='red'] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
922 | background-color: #c62828 !important;
923 | }
924 |
925 | .mdtp__wrapper[data-theme='red'] .mdtp__clock .mdtp__digit.active:before {
926 | background-color: #c62828;
927 | }
928 |
929 | .mdtp__wrapper[data-theme='red'] .mdtp__button {
930 | color: #c62828;
931 | }
932 |
933 | .mdtp__wrapper[data-theme='green'] .mdtp__time_holder {
934 | background-color: #2e7d32;
935 | }
936 |
937 | .mdtp__wrapper[data-theme='green'] .mdtp__clock .mdtp__am.active,
938 | .mdtp__wrapper[data-theme='green'] .mdtp__clock .mdtp__pm.active,
939 | .mdtp__wrapper[data-theme='green'] .mdtp__clock .mdtp__clock_dot {
940 | background-color: #2e7d32;
941 | }
942 |
943 | .mdtp__wrapper[data-theme='green'] .mdtp__clock .mdtp__digit.active span,
944 | .mdtp__wrapper[data-theme='green'] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
945 | background-color: #2e7d32 !important;
946 | }
947 |
948 | .mdtp__wrapper[data-theme='green'] .mdtp__clock .mdtp__digit.active:before {
949 | background-color: #2e7d32;
950 | }
951 |
952 | .mdtp__wrapper[data-theme='green'] .mdtp__button {
953 | color: #2e7d32;
954 | }
955 |
956 | .mdtp__wrapper[data-theme='blue'] .mdtp__time_holder {
957 | background-color: #1565c0;
958 | }
959 |
960 | .mdtp__wrapper[data-theme='blue'] .mdtp__clock .mdtp__am.active,
961 | .mdtp__wrapper[data-theme='blue'] .mdtp__clock .mdtp__pm.active,
962 | .mdtp__wrapper[data-theme='blue'] .mdtp__clock .mdtp__clock_dot {
963 | background-color: #1565c0;
964 | }
965 |
966 | .mdtp__wrapper[data-theme='blue'] .mdtp__clock .mdtp__digit.active span,
967 | .mdtp__wrapper[data-theme='blue'] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
968 | background-color: #1565c0 !important;
969 | }
970 |
971 | .mdtp__wrapper[data-theme='blue'] .mdtp__clock .mdtp__digit.active:before {
972 | background-color: #1565c0;
973 | }
974 |
975 | .mdtp__wrapper[data-theme='blue'] .mdtp__button {
976 | color: #1565c0;
977 | }
978 |
979 | .mdtp__wrapper[data-theme='teal'] .mdtp__time_holder {
980 | background-color: #00695c;
981 | }
982 |
983 | .mdtp__wrapper[data-theme='teal'] .mdtp__clock .mdtp__am.active,
984 | .mdtp__wrapper[data-theme='teal'] .mdtp__clock .mdtp__pm.active,
985 | .mdtp__wrapper[data-theme='teal'] .mdtp__clock .mdtp__clock_dot {
986 | background-color: #00695c;
987 | }
988 |
989 | .mdtp__wrapper[data-theme='teal'] .mdtp__clock .mdtp__digit.active span,
990 | .mdtp__wrapper[data-theme='teal'] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
991 | background-color: #00695c !important;
992 | }
993 |
994 | .mdtp__wrapper[data-theme='teal'] .mdtp__clock .mdtp__digit.active:before {
995 | background-color: #00695c;
996 | }
997 |
998 | .mdtp__wrapper[data-theme='teal'] .mdtp__button {
999 | color: #00695c;
1000 | }
1001 |
1002 | .mdtp__wrapper[data-theme='purple'] .mdtp__time_holder {
1003 | background-color: #6a1b9a;
1004 | }
1005 |
1006 | .mdtp__wrapper[data-theme='purple'] .mdtp__clock .mdtp__am.active,
1007 | .mdtp__wrapper[data-theme='purple'] .mdtp__clock .mdtp__pm.active,
1008 | .mdtp__wrapper[data-theme='purple'] .mdtp__clock .mdtp__clock_dot {
1009 | background-color: #6a1b9a;
1010 | }
1011 |
1012 | .mdtp__wrapper[data-theme='purple'] .mdtp__clock .mdtp__digit.active span,
1013 | .mdtp__wrapper[data-theme='purple'] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
1014 | background-color: #6a1b9a !important;
1015 | }
1016 |
1017 | .mdtp__wrapper[data-theme='purple'] .mdtp__clock .mdtp__digit.active:before {
1018 | background-color: #6a1b9a;
1019 | }
1020 |
1021 | .mdtp__wrapper[data-theme='purple'] .mdtp__button {
1022 | color: #6a1b9a;
1023 | }
1024 |
1025 | .mdtp__wrapper[data-theme='indigo'] .mdtp__time_holder {
1026 | background-color: #283593;
1027 | }
1028 |
1029 | .mdtp__wrapper[data-theme='indigo'] .mdtp__clock .mdtp__am.active,
1030 | .mdtp__wrapper[data-theme='indigo'] .mdtp__clock .mdtp__pm.active,
1031 | .mdtp__wrapper[data-theme='indigo'] .mdtp__clock .mdtp__clock_dot {
1032 | background-color: #283593;
1033 | }
1034 |
1035 | .mdtp__wrapper[data-theme='indigo'] .mdtp__clock .mdtp__digit.active span,
1036 | .mdtp__wrapper[data-theme='indigo'] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover {
1037 | background-color: #283593 !important;
1038 | }
1039 |
1040 | .mdtp__wrapper[data-theme='indigo'] .mdtp__clock .mdtp__digit.active:before {
1041 | background-color: #283593;
1042 | }
1043 |
1044 | .mdtp__wrapper[data-theme='indigo'] .mdtp__button {
1045 | color: #283593;
1046 | }
1047 |
1048 | .mdtp__wrapper[data-theme='dark'] .mdtp__time_holder {
1049 | background-color: #121212;
1050 | }
1051 |
1052 | .mdtp__wrapper[data-theme='dark'] .mdtp__clock_holder {
1053 | background-color: #1d1d1d;
1054 | }
1055 |
1056 | .mdtp__wrapper[data-theme='dark'] .mdtp__clock_holder .mdtp__clock {
1057 | background-color: #181818;
1058 | }
1059 |
1060 | .mdtp__wrapper[data-theme='dark'] .mdtp__clock_holder .mdtp__clock .mdtp__digit:not(.digit--disabled) {
1061 | color: rgba(255, 255, 255, 0.87);
1062 | }
1063 |
1064 | .mdtp__wrapper[data-theme='dark'] .mdtp__clock_holder .mdtp__clock .mdtp__digit.digit--disabled span {
1065 | color: rgba(100, 100, 100, 0.87);
1066 | }
1067 |
1068 | .mdtp__wrapper[data-theme='dark'] .mdtp__clock_holder .mdtp__clock .mdtp__am:not(.active),
1069 | .mdtp__wrapper[data-theme='dark'] .mdtp__clock_holder .mdtp__clock .mdtp__pm:not(.active) {
1070 | color: rgba(255, 255, 255, 0.87);
1071 | background-color: rgba(200, 200, 200, 0.05);
1072 | }
1073 |
1074 | .mdtp__wrapper[data-theme='dark'] .mdtp__button {
1075 | color: #42a5f5;
1076 | }
1077 |
1078 | .mdtp__wrapper[data-theme='dark'] .mdtp__button:hover {
1079 | background-color: rgba(255, 255, 255, 0.04);
1080 | }
1081 |
1082 | .mdtp__wrapper[data-theme='dark'] .mdtp__button:active {
1083 | background-color: rgba(255, 255, 255, 0.1);
1084 | }
1085 |
--------------------------------------------------------------------------------
/dist/mdtimepicker.min.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap");.mdtimepicker{background-color:hsla(0,0%,4%,.65);bottom:0;font-family:Roboto,sans-serif;font-size:14px;left:0;position:fixed;right:0;top:0;transition:background-color .28s ease;z-index:100001}.mdtimepicker .mdtp__wrapper{border-radius:4px;bottom:24px;box-shadow:0 11px 15px -7px rgba(0,0,0,.2),0 24px 38px 3px rgba(0,0,0,.14),0 9px 46px 8px rgba(0,0,0,.12);display:flex;flex-direction:column;left:50%;min-width:280px;opacity:1;outline:none;overflow:hidden;position:absolute;transform:translateX(-50%) scale(1);transition:transform .28s ease,opacity .28s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none}.mdtimepicker .mdtp__wrapper.animate{opacity:0;transform:translateX(-50%) scale(1.05)}.mdtimepicker .mdtp__time_holder{align-items:center;background-color:#1565c0;color:hsla(0,0%,100%,.5);display:flex;flex-direction:row;font-size:46px;justify-content:center;padding:20px 24px;text-align:center}.mdtimepicker .mdtp__time_holder>span{cursor:default;display:inline-block;line-height:48px}.mdtimepicker .mdtp__time_holder>span:not(.mdtp__timedots):not(.mdtp__ampm){cursor:pointer;margin:0 4px;transition:color .2s linear}.mdtimepicker .mdtp__time_holder .mdtp__time_h.active,.mdtimepicker .mdtp__time_holder .mdtp__time_m.active{color:#fafafa}.mdtimepicker .mdtp__time_holder .mdtp__ampm{cursor:pointer;font-size:18px;transition:color .2s linear}.mdtimepicker .mdtp__time_holder .mdtp__ampm:hover{color:#fafafa}.mdtimepicker .mdtp__clock_holder{background-color:#fff;position:relative}.mdtimepicker .mdtp__clock_holder .mdtp__clock{background-color:#eee;border-radius:50%;height:250px;margin:20px;position:relative;width:250px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am,.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm{background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:50%;bottom:-8px;cursor:pointer;display:block;height:36px;line-height:36px;position:absolute;text-align:center;transition:background-color .2s ease,color .2s;width:36px;z-index:3}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am:hover,.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm:hover{background-color:rgba(0,0,0,.1)}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am.active,.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm.active{background-color:#1565c0;color:#fafafa}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__am{left:-8px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__pm{right:-8px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__clock_dot{background-color:#1565c0;border-radius:50%;left:50%;padding:4px;position:absolute;top:50%;transform:translate(-50%,-50%)}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__hour_holder,.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder{height:100%;opacity:1;overflow:hidden;position:absolute;top:0;transform:scale(1);transition:transform .35s cubic-bezier(.4,0,.2,1),opacity .35s ease;width:100%}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__hour_holder.hidden,.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder.hidden{display:none}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__hour_holder.animate{opacity:0;transform:scale(1.2)}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder.animate{opacity:0;transform:scale(.8)}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit{left:0;margin-top:-16px;position:absolute;top:50%;transform-origin:right center;width:50%;z-index:1}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit span{border-radius:50%;cursor:pointer;display:inline-block;height:32px;line-height:32px;margin-left:8px;text-align:center;transition:background-color .28s,color .14s;width:32px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.inner--digit{left:14%;width:36%;z-index:2}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.active span,.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover{background-color:#1565c0!important;color:#fff;z-index:2}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.digit--disabled span{background-color:transparent!important;color:#c8c8c8;cursor:not-allowed}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__digit.active:before{background-color:#1565c0;content:"";display:block;height:2px;position:absolute;right:0;top:calc(50% - 1px);width:calc(100% - 40px)}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit{font-size:13px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit:not(.marker){height:12px;margin-top:-6px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit:not(.marker) span{height:12px;line-height:12px;margin-left:14px;width:12px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit:not(.marker).active:before{width:calc(100% - 26px)}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit.marker{margin-top:-12px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit.marker span{height:24px;line-height:24px;margin-left:10px;width:24px}.mdtimepicker .mdtp__clock_holder .mdtp__clock .mdtp__minute_holder .mdtp__digit.marker.active:before{width:calc(100% - 34px)}.mdtimepicker .mdtp__buttons{padding:0 10px 10px;text-align:right}.mdtimepicker .mdtp__buttons .mdtp__button{border-radius:4px;color:#1565c0;cursor:pointer;display:inline-block;font-weight:500;line-height:32px;min-width:40px;padding:0 16px;text-align:center;text-transform:uppercase;transition:background-color .2s linear}.mdtimepicker .mdtp__buttons .mdtp__button:hover{background-color:rgba(0,0,0,.1)}.mdtimepicker .mdtp__buttons .mdtp__button:active{background-color:rgba(0,0,0,.2)}.mdtimepicker .mdtp__buttons .mdtp__button.clear-btn{color:#ef5350!important;float:left}.mdtimepicker .mdtp__buttons:after{clear:both;content:"";display:block}.mdtimepicker.hidden{display:none}.mdtimepicker.animate{background-color:transparent}.mdtp__digit.rotate--15{transform:rotate(-15deg)}.mdtp__digit.rotate--15 span{transform:rotate(15deg)}.mdtp__digit.rotate-6{transform:rotate(6deg)}.mdtp__digit.rotate-6 span{transform:rotate(-6deg)}.mdtp__digit.rotate-12{transform:rotate(12deg)}.mdtp__digit.rotate-12 span{transform:rotate(-12deg)}.mdtp__digit.rotate-15{transform:rotate(15deg)}.mdtp__digit.rotate-15 span{transform:rotate(-15deg)}.mdtp__digit.rotate-18{transform:rotate(18deg)}.mdtp__digit.rotate-18 span{transform:rotate(-18deg)}.mdtp__digit.rotate-24{transform:rotate(24deg)}.mdtp__digit.rotate-24 span{transform:rotate(-24deg)}.mdtp__digit.rotate-30{transform:rotate(30deg)}.mdtp__digit.rotate-30 span{transform:rotate(-30deg)}.mdtp__digit.rotate-36{transform:rotate(36deg)}.mdtp__digit.rotate-36 span{transform:rotate(-36deg)}.mdtp__digit.rotate-42{transform:rotate(42deg)}.mdtp__digit.rotate-42 span{transform:rotate(-42deg)}.mdtp__digit.rotate-45{transform:rotate(45deg)}.mdtp__digit.rotate-45 span{transform:rotate(-45deg)}.mdtp__digit.rotate-48{transform:rotate(48deg)}.mdtp__digit.rotate-48 span{transform:rotate(-48deg)}.mdtp__digit.rotate-54{transform:rotate(54deg)}.mdtp__digit.rotate-54 span{transform:rotate(-54deg)}.mdtp__digit.rotate-60{transform:rotate(60deg)}.mdtp__digit.rotate-60 span{transform:rotate(-60deg)}.mdtp__digit.rotate-66{transform:rotate(66deg)}.mdtp__digit.rotate-66 span{transform:rotate(-66deg)}.mdtp__digit.rotate-72{transform:rotate(72deg)}.mdtp__digit.rotate-72 span{transform:rotate(-72deg)}.mdtp__digit.rotate-75{transform:rotate(75deg)}.mdtp__digit.rotate-75 span{transform:rotate(-75deg)}.mdtp__digit.rotate-78{transform:rotate(78deg)}.mdtp__digit.rotate-78 span{transform:rotate(-78deg)}.mdtp__digit.rotate-84{transform:rotate(84deg)}.mdtp__digit.rotate-84 span{transform:rotate(-84deg)}.mdtp__digit.rotate-90{transform:rotate(90deg)}.mdtp__digit.rotate-90 span{transform:rotate(-90deg)}.mdtp__digit.rotate-96{transform:rotate(96deg)}.mdtp__digit.rotate-96 span{transform:rotate(-96deg)}.mdtp__digit.rotate-102{transform:rotate(102deg)}.mdtp__digit.rotate-102 span{transform:rotate(-102deg)}.mdtp__digit.rotate-105{transform:rotate(105deg)}.mdtp__digit.rotate-105 span{transform:rotate(-105deg)}.mdtp__digit.rotate-108{transform:rotate(108deg)}.mdtp__digit.rotate-108 span{transform:rotate(-108deg)}.mdtp__digit.rotate-114{transform:rotate(114deg)}.mdtp__digit.rotate-114 span{transform:rotate(-114deg)}.mdtp__digit.rotate-120{transform:rotate(120deg)}.mdtp__digit.rotate-120 span{transform:rotate(-120deg)}.mdtp__digit.rotate-126{transform:rotate(126deg)}.mdtp__digit.rotate-126 span{transform:rotate(-126deg)}.mdtp__digit.rotate-132{transform:rotate(132deg)}.mdtp__digit.rotate-132 span{transform:rotate(-132deg)}.mdtp__digit.rotate-135{transform:rotate(135deg)}.mdtp__digit.rotate-135 span{transform:rotate(-135deg)}.mdtp__digit.rotate-138{transform:rotate(138deg)}.mdtp__digit.rotate-138 span{transform:rotate(-138deg)}.mdtp__digit.rotate-144{transform:rotate(144deg)}.mdtp__digit.rotate-144 span{transform:rotate(-144deg)}.mdtp__digit.rotate-150{transform:rotate(150deg)}.mdtp__digit.rotate-150 span{transform:rotate(-150deg)}.mdtp__digit.rotate-156{transform:rotate(156deg)}.mdtp__digit.rotate-156 span{transform:rotate(-156deg)}.mdtp__digit.rotate-162{transform:rotate(162deg)}.mdtp__digit.rotate-162 span{transform:rotate(-162deg)}.mdtp__digit.rotate-165{transform:rotate(165deg)}.mdtp__digit.rotate-165 span{transform:rotate(-165deg)}.mdtp__digit.rotate-168{transform:rotate(168deg)}.mdtp__digit.rotate-168 span{transform:rotate(-168deg)}.mdtp__digit.rotate-174{transform:rotate(174deg)}.mdtp__digit.rotate-174 span{transform:rotate(-174deg)}.mdtp__digit.rotate-180{transform:rotate(180deg)}.mdtp__digit.rotate-180 span{transform:rotate(-180deg)}.mdtp__digit.rotate-186{transform:rotate(186deg)}.mdtp__digit.rotate-186 span{transform:rotate(-186deg)}.mdtp__digit.rotate-192{transform:rotate(192deg)}.mdtp__digit.rotate-192 span{transform:rotate(-192deg)}.mdtp__digit.rotate-195{transform:rotate(195deg)}.mdtp__digit.rotate-195 span{transform:rotate(-195deg)}.mdtp__digit.rotate-198{transform:rotate(198deg)}.mdtp__digit.rotate-198 span{transform:rotate(-198deg)}.mdtp__digit.rotate-204{transform:rotate(204deg)}.mdtp__digit.rotate-204 span{transform:rotate(-204deg)}.mdtp__digit.rotate-210{transform:rotate(210deg)}.mdtp__digit.rotate-210 span{transform:rotate(-210deg)}.mdtp__digit.rotate-216{transform:rotate(216deg)}.mdtp__digit.rotate-216 span{transform:rotate(-216deg)}.mdtp__digit.rotate-222{transform:rotate(222deg)}.mdtp__digit.rotate-222 span{transform:rotate(-222deg)}.mdtp__digit.rotate-225{transform:rotate(225deg)}.mdtp__digit.rotate-225 span{transform:rotate(-225deg)}.mdtp__digit.rotate-228{transform:rotate(228deg)}.mdtp__digit.rotate-228 span{transform:rotate(-228deg)}.mdtp__digit.rotate-234{transform:rotate(234deg)}.mdtp__digit.rotate-234 span{transform:rotate(-234deg)}.mdtp__digit.rotate-240{transform:rotate(240deg)}.mdtp__digit.rotate-240 span{transform:rotate(-240deg)}.mdtp__digit.rotate-246{transform:rotate(246deg)}.mdtp__digit.rotate-246 span{transform:rotate(-246deg)}.mdtp__digit.rotate-252{transform:rotate(252deg)}.mdtp__digit.rotate-252 span{transform:rotate(-252deg)}.mdtp__digit.rotate-255{transform:rotate(255deg)}.mdtp__digit.rotate-255 span{transform:rotate(-255deg)}.mdtp__digit.rotate-258{transform:rotate(258deg)}.mdtp__digit.rotate-258 span{transform:rotate(-258deg)}.mdtp__digit.rotate-264{transform:rotate(264deg)}.mdtp__digit.rotate-264 span{transform:rotate(-264deg)}.mdtp__digit.rotate-270{transform:rotate(270deg)}.mdtp__digit.rotate-270 span{transform:rotate(-270deg)}.mdtp__digit.rotate-276{transform:rotate(276deg)}.mdtp__digit.rotate-276 span{transform:rotate(-276deg)}.mdtp__digit.rotate-282{transform:rotate(282deg)}.mdtp__digit.rotate-282 span{transform:rotate(-282deg)}.mdtp__digit.rotate-285{transform:rotate(285deg)}.mdtp__digit.rotate-285 span{transform:rotate(-285deg)}.mdtp__digit.rotate-288{transform:rotate(288deg)}.mdtp__digit.rotate-288 span{transform:rotate(-288deg)}.mdtp__digit.rotate-294{transform:rotate(294deg)}.mdtp__digit.rotate-294 span{transform:rotate(-294deg)}.mdtp__digit.rotate-300{transform:rotate(300deg)}.mdtp__digit.rotate-300 span{transform:rotate(-300deg)}.mdtp__digit.rotate-306{transform:rotate(306deg)}.mdtp__digit.rotate-306 span{transform:rotate(-306deg)}.mdtp__digit.rotate-312{transform:rotate(312deg)}.mdtp__digit.rotate-312 span{transform:rotate(-312deg)}.mdtp__digit.rotate-315{transform:rotate(315deg)}.mdtp__digit.rotate-315 span{transform:rotate(-315deg)}.mdtp__digit.rotate-318{transform:rotate(318deg)}.mdtp__digit.rotate-318 span{transform:rotate(-318deg)}.mdtp__digit.rotate-324{transform:rotate(324deg)}.mdtp__digit.rotate-324 span{transform:rotate(-324deg)}.mdtp__digit.rotate-330{transform:rotate(330deg)}.mdtp__digit.rotate-330 span{transform:rotate(-330deg)}.mdtp__digit.rotate-336{transform:rotate(336deg)}.mdtp__digit.rotate-336 span{transform:rotate(-336deg)}.mdtp__digit.rotate-342{transform:rotate(342deg)}.mdtp__digit.rotate-342 span{transform:rotate(-342deg)}.mdtp__digit.rotate-348{transform:rotate(348deg)}.mdtp__digit.rotate-348 span{transform:rotate(-348deg)}.mdtp__digit.rotate-354{transform:rotate(354deg)}.mdtp__digit.rotate-354 span{transform:rotate(-354deg)}.mdtp__digit.rotate-360{transform:rotate(1turn)}.mdtp__digit.rotate-360 span{transform:rotate(-1turn)}body[mdtimepicker-display=on]{overflow:hidden}@media (max-height:360px){.mdtimepicker .mdtp__wrapper{bottom:8px;flex-direction:row}.mdtimepicker .mdtp__time_holder{padding:20px;width:160px}.mdtimepicker .mdtp__clock .mdtp__am,.mdtimepicker .mdtp__clock .mdtp__pm{bottom:-4px}.mdtimepicker .mdtp__clock .mdtp__am{left:-4px}.mdtimepicker .mdtp__clock .mdtp__pm{right:-4px}}@media (max-height:320px){.mdtimepicker .mdtp__wrapper{bottom:0}}.mdtp__wrapper[data-theme=red] .mdtp__clock .mdtp__am.active,.mdtp__wrapper[data-theme=red] .mdtp__clock .mdtp__clock_dot,.mdtp__wrapper[data-theme=red] .mdtp__clock .mdtp__pm.active,.mdtp__wrapper[data-theme=red] .mdtp__time_holder{background-color:#c62828}.mdtp__wrapper[data-theme=red] .mdtp__clock .mdtp__digit.active span,.mdtp__wrapper[data-theme=red] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover{background-color:#c62828!important}.mdtp__wrapper[data-theme=red] .mdtp__clock .mdtp__digit.active:before{background-color:#c62828}.mdtp__wrapper[data-theme=red] .mdtp__button{color:#c62828}.mdtp__wrapper[data-theme=green] .mdtp__clock .mdtp__am.active,.mdtp__wrapper[data-theme=green] .mdtp__clock .mdtp__clock_dot,.mdtp__wrapper[data-theme=green] .mdtp__clock .mdtp__pm.active,.mdtp__wrapper[data-theme=green] .mdtp__time_holder{background-color:#2e7d32}.mdtp__wrapper[data-theme=green] .mdtp__clock .mdtp__digit.active span,.mdtp__wrapper[data-theme=green] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover{background-color:#2e7d32!important}.mdtp__wrapper[data-theme=green] .mdtp__clock .mdtp__digit.active:before{background-color:#2e7d32}.mdtp__wrapper[data-theme=green] .mdtp__button{color:#2e7d32}.mdtp__wrapper[data-theme=blue] .mdtp__clock .mdtp__am.active,.mdtp__wrapper[data-theme=blue] .mdtp__clock .mdtp__clock_dot,.mdtp__wrapper[data-theme=blue] .mdtp__clock .mdtp__pm.active,.mdtp__wrapper[data-theme=blue] .mdtp__time_holder{background-color:#1565c0}.mdtp__wrapper[data-theme=blue] .mdtp__clock .mdtp__digit.active span,.mdtp__wrapper[data-theme=blue] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover{background-color:#1565c0!important}.mdtp__wrapper[data-theme=blue] .mdtp__clock .mdtp__digit.active:before{background-color:#1565c0}.mdtp__wrapper[data-theme=blue] .mdtp__button{color:#1565c0}.mdtp__wrapper[data-theme=teal] .mdtp__clock .mdtp__am.active,.mdtp__wrapper[data-theme=teal] .mdtp__clock .mdtp__clock_dot,.mdtp__wrapper[data-theme=teal] .mdtp__clock .mdtp__pm.active,.mdtp__wrapper[data-theme=teal] .mdtp__time_holder{background-color:#00695c}.mdtp__wrapper[data-theme=teal] .mdtp__clock .mdtp__digit.active span,.mdtp__wrapper[data-theme=teal] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover{background-color:#00695c!important}.mdtp__wrapper[data-theme=teal] .mdtp__clock .mdtp__digit.active:before{background-color:#00695c}.mdtp__wrapper[data-theme=teal] .mdtp__button{color:#00695c}.mdtp__wrapper[data-theme=purple] .mdtp__clock .mdtp__am.active,.mdtp__wrapper[data-theme=purple] .mdtp__clock .mdtp__clock_dot,.mdtp__wrapper[data-theme=purple] .mdtp__clock .mdtp__pm.active,.mdtp__wrapper[data-theme=purple] .mdtp__time_holder{background-color:#6a1b9a}.mdtp__wrapper[data-theme=purple] .mdtp__clock .mdtp__digit.active span,.mdtp__wrapper[data-theme=purple] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover{background-color:#6a1b9a!important}.mdtp__wrapper[data-theme=purple] .mdtp__clock .mdtp__digit.active:before{background-color:#6a1b9a}.mdtp__wrapper[data-theme=purple] .mdtp__button{color:#6a1b9a}.mdtp__wrapper[data-theme=indigo] .mdtp__clock .mdtp__am.active,.mdtp__wrapper[data-theme=indigo] .mdtp__clock .mdtp__clock_dot,.mdtp__wrapper[data-theme=indigo] .mdtp__clock .mdtp__pm.active,.mdtp__wrapper[data-theme=indigo] .mdtp__time_holder{background-color:#283593}.mdtp__wrapper[data-theme=indigo] .mdtp__clock .mdtp__digit.active span,.mdtp__wrapper[data-theme=indigo] .mdtp__clock .mdtp__digit:not(.digit--disabled) span:hover{background-color:#283593!important}.mdtp__wrapper[data-theme=indigo] .mdtp__clock .mdtp__digit.active:before{background-color:#283593}.mdtp__wrapper[data-theme=indigo] .mdtp__button{color:#283593}.mdtp__wrapper[data-theme=dark] .mdtp__time_holder{background-color:#121212}.mdtp__wrapper[data-theme=dark] .mdtp__clock_holder{background-color:#1d1d1d}.mdtp__wrapper[data-theme=dark] .mdtp__clock_holder .mdtp__clock{background-color:#181818}.mdtp__wrapper[data-theme=dark] .mdtp__clock_holder .mdtp__clock .mdtp__digit:not(.digit--disabled){color:hsla(0,0%,100%,.87)}.mdtp__wrapper[data-theme=dark] .mdtp__clock_holder .mdtp__clock .mdtp__digit.digit--disabled span{color:hsla(0,0%,39%,.87)}.mdtp__wrapper[data-theme=dark] .mdtp__clock_holder .mdtp__clock .mdtp__am:not(.active),.mdtp__wrapper[data-theme=dark] .mdtp__clock_holder .mdtp__clock .mdtp__pm:not(.active){background-color:hsla(0,0%,78%,.05);color:hsla(0,0%,100%,.87)}.mdtp__wrapper[data-theme=dark] .mdtp__button{color:#42a5f5}.mdtp__wrapper[data-theme=dark] .mdtp__button:hover{background-color:hsla(0,0%,100%,.04)}.mdtp__wrapper[data-theme=dark] .mdtp__button:active{background-color:hsla(0,0%,100%,.1)}
--------------------------------------------------------------------------------
/dist/mdtimepicker.min.js:
--------------------------------------------------------------------------------
1 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).mdtimepicker=e()}(this,function(){"use strict";function R(t){return(R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function D(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function F(t,e){for(var n=0;ni;)!_n(r,n=e[i++])||~In(o,n)||Ln(o,n);return o}function sn(t,e){return(t=zn[qn(t)])==Wn||t!=Yn&&(Bn(e)?$n(e):!!e)}function P(t,e){var n,r,i,o=t.target,c=t.global,u=t.stat,a=c?Kn:u?Kn[o]||Zn(o,{}):(Kn[o]||{}).prototype;if(a)for(n in e){if(r=e[n],i=t.dontCallGetSet?(i=Xn(a,n))&&i.value:a[n],!er(c?n:o+(u?".":"#")+n,t.forced)&&void 0!==i){if(typeof r==typeof i)continue;tr(r,i)}(t.sham||i&&i.sham)&&Jn(r,"sham",!0),Qn(a,n,r,t)}}function ln(t){if("Symbol"===ur(t))throw TypeError("Cannot convert a Symbol value to a string");return ar(t)}var fn=g,dn=y,pn=p.exports,hn=W,_={},mn=Math.ceil,vn=Math.floor,gn=Math.trunc||function(t){t=+t;return(0"+t+""+Mr+">"},Dr=function(){try{_r=new ActiveXObject("htmlfile")}catch(t){}Dr="undefined"==typeof document||document.domain&&_r?yr(_r):(t=jr("iframe"),e="java"+Mr+":",t.style.display="none",Lr.appendChild(t),t.src=String(e),(e=t.contentWindow.document).open(),e.write(Rr("document.F=Object")),e.close(),e.F);for(var t,e,n=Pr.length;n--;)delete Dr[Hr][Pr[n]];return Dr()},zt=(l[Cr]=!0,Object.create||function(t,e){var n;return null!==t?(gr[Hr]=Ar(t),n=new gr,gr[Hr]=null,n[Cr]=t):n=Dr(),void 0===e?n:Ir.f(n,e)}),x=t,Fr=a.RegExp,A=x(function(){var t=Fr(".","s");return!(t.dotAll&&t.exec("\n")&&"s"===t.flags)}),O=t,Vr=a.RegExp,_=O(function(){var t=Vr("(?b)","g");return"b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$c")}),Nr=d,l=m,Gr=ln,x=s,O=T,$r=zt,Br=S.get,s=A,T=_,Ur=O("native-string-replace",String.prototype.replace),qr=RegExp.prototype.exec,zr=qr,Yr=l("".charAt),Wr=l("".indexOf),Kr=l("".replace),Xr=l("".slice),Jr=(A=/b*/g,Nr(qr,_=/a/,"a"),Nr(qr,A,"a"),0!==_.lastIndex||0!==A.lastIndex),Qr=x.BROKEN_CARET,Zr=void 0!==/()??/.exec("")[1],O=zr=Jr||Zr||Qr||s||T?function(t){var e,n,r,i,o,c,u=this,a=Br(u),t=Gr(t),s=a.raw;if(s)return s.lastIndex=u.lastIndex,f=Nr(zr,s,t),u.lastIndex=s.lastIndex,f;var l=a.groups,s=Qr&&u.sticky,f=Nr(br,u),a=u.source,d=0,p=t;if(s&&(f=Kr(f,"y",""),-1===Wr(f,"g")&&(f+="g"),p=Xr(t,u.lastIndex),0]*>)/g,Ni=/\$([$&'`]|\d{1,2})/g,Gi=s,$i=d,l=m,O=Er,x=t,Bi=o,Ui=g,qi=U,zi=nn,Yi=on,Wi=ln,Ki=q,Xi=xr,Ji=r,Qi=function(o,c,u,a,s,t){var l=u+o.length,f=a.length,e=Ni;return void 0!==s&&(s=Mi(s),e=Vi),Di(t,e,function(t,e){var n;switch(Ri(e,0)){case"$":return"$";case"&":return o;case"`":return Fi(c,0,u);case"'":return Fi(c,l);case"<":n=s[Fi(e,1,-1)];break;default:var r,i=+e;if(0==i)return t;if(f")})||!A||uo),p),ao=I,so=(p||en(Object.prototype,"toString",T?{}.toString:function(){return"[object "+ao(this)+"]"},{unsafe:!0}),TypeError),lo=n,fo=d,po=e,ho=r,mo=d,vo=n,go=o,yo=v,bo=function(t){if(9007199254740991=e.length?la(void 0,!0):(e=aa(e,n),t.index+=e.length,la(e,!1))}),t),ma=b,va=i("species"),p=m([].slice),h=P,ga=A,ya=f,ba=v,wa=rn,Ea=cn,ka=z,xa=iu,bt=i,Ta=p,a=function(e){return 51<=ma||!ha(function(){var t=[];return(t.constructor={})[va]=function(){return{foo:1}},1!==t[e](Boolean).foo})}("slice"),Sa=bt("species"),Oa=Array,_a=Math.max,Aa=(h({target:"Array",proto:!0,forced:!a},{slice:function(t,e){var n,r,i,o=ka(this),c=Ea(o),u=wa(t,c),a=wa(void 0===e?c:e,c);if(ga(o)&&(n=o.constructor,(n=ya(n)&&(n===Oa||ga(n.prototype))||ba(n)&&null===(n=n[Sa])?void 0:n)===Oa||void 0===n))return Ta(o,u,a);for(r=new(void 0===n?Oa:n)(_a(a-u,0)),i=0;u 0.5%, ie >= 11"
14 | }
15 | }
16 | ]
17 | ]
18 | }
--------------------------------------------------------------------------------
/src/helpers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Helper functions
3 | */
4 | export const hf = {
5 | /**
6 | * Appends element(s) to parent
7 | * @param {Element|Element[]} elem Element(s) to append to parent
8 | * @param {Element} to Parent element
9 | */
10 | appendTo (elem, to, idx) {
11 | if (Array.isArray(elem)) {
12 | elem.forEach(el => {
13 | if (idx === 0) to.insertBefore(el, to.childNodes[idx] || null)
14 | else to.appendChild(el)
15 | })
16 | } else {
17 | if (idx === 0) to.insertBefore(elem, to.childNodes[idx] || null)
18 | else to.appendChild(elem)
19 | }
20 | },
21 | /**
22 | * Adds event listener to element(s)
23 | * @param {Element|Element[]} elem Element(s) to add event
24 | * @param {string} event Event name
25 | * @param {Function} handler Event handler
26 | */
27 | addEvent (elem, event, handler) {
28 | function listenEvent(el, evt, fn) {
29 | el.addEventListener(evt, fn, false)
30 | }
31 |
32 | if (Array.isArray(elem)) {
33 | elem.forEach(e => listenEvent(e, event, handler))
34 | } else listenEvent(elem, event, handler)
35 | },
36 | /**
37 | * Removes event listener to element(s)
38 | * @param {Element|Element[]} elem Element(s) to remove event
39 | * @param {string} event Event name
40 | * @param {Function} handler Event handler
41 | */
42 | removeEvent (elem, event, handler) {
43 | function delEvent(el, evt, fn) {
44 | el.removeEventListener(evt, fn, false)
45 | }
46 |
47 | if (Array.isArray(elem)) {
48 | elem.forEach(e => delEvent(e, event, handler))
49 | } else delEvent(elem, event, handler)
50 | },
51 | /**
52 | * Removes child nodes
53 | * @param {Element} elem Html element to empty
54 | */
55 | empty (elem) {
56 | while (elem.firstChild) { elem.removeChild(elem.firstChild) }
57 | },
58 | /**
59 | * Creates an HTML element; `document.createElement` helper function
60 | * @see {@link http://jsfiddle.net/andr3ww/pvuzgfg6/13/}
61 | * @param {string} tag HTML tag name (i.e. `div`, `span`, `a`)
62 | * @param {Object} attributes Attribute object
63 | * @param {string|Element} content Element content: text or HTML element(s)
64 | * @param {Boolean} isHtml Determines if `content` specified should added as an html element
65 | */
66 | createElem (tag, attributes, content, isHtml) {
67 | var el = document.createElement(tag)
68 |
69 | if (typeof content !== 'undefined')
70 | el[isHtml || false ? 'innerHTML' : 'innerText'] = content
71 |
72 | if (typeof attributes !== 'undefined')
73 | hf.setAttributes(el, attributes)
74 |
75 | return el
76 | },
77 | /**
78 | * Sets the attribute(s) of the element
79 | * @param {Element} el Html element
80 | * @param {Object} attrs Attribute object
81 | */
82 | setAttributes (el, attrs) {
83 | for(var attr in attrs) { el.setAttribute(attr, attrs[attr]) }
84 | },
85 | /**
86 | * Vanilla JavaScript version of jQuery.extend()
87 | * @see {@link https://gomakethings.com/vanilla-javascript-version-of-jquery-extend/}
88 | */
89 | extend () {
90 | // Variables
91 | var extended = {}
92 | var deep = false
93 | var i = 0
94 | var length = arguments.length
95 |
96 | // Check if a deep merge
97 | if (Object.prototype.toString.call(arguments[0]) === '[object Boolean]') {
98 | deep = arguments[0]
99 | i++
100 | }
101 |
102 | // Merge the object into the extended object
103 | var merge = function (obj) {
104 | for (var prop in obj) {
105 | if (Object.prototype.hasOwnProperty.call(obj, prop)) {
106 | // If deep merge and property is an object, merge properties
107 | if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') {
108 | extended[prop] = hf.extend(true, extended[prop], obj[prop])
109 | } else {
110 | extended[prop] = obj[prop]
111 | }
112 | }
113 | }
114 | }
115 |
116 | // Loop through each object and conduct a merge
117 | for (; i < length; i++) {
118 | var obj = arguments[i]
119 | merge(obj)
120 | }
121 |
122 | return extended
123 | },
124 | /**
125 | * Triggers the `change`, `onchange`, `datechanged` event on the specified input element
126 | * @param {HTMLInputElement} el HTML input element
127 | * @param {Object} data Event data
128 | */
129 | triggerChange (el, data) {
130 | let change = document.createEvent('Event')
131 | let onChange = document.createEvent('Event')
132 |
133 | change.initEvent('change', false, false)
134 | onChange.initEvent('onchange', false, false)
135 |
136 | el.dispatchEvent(change)
137 | el.dispatchEvent(onChange)
138 |
139 | function CustomEvent(data) {
140 | let changeEvt = document.createEvent('CustomEvent')
141 |
142 | changeEvt.initCustomEvent('datechanged', false, false, null)
143 | changeEvt.data = data
144 |
145 | return changeEvt
146 | }
147 |
148 | el.dispatchEvent(new CustomEvent(data))
149 | }
150 | }
--------------------------------------------------------------------------------
/src/mdtimepicker.js:
--------------------------------------------------------------------------------
1 | import { MDTP_DATA, DEFAULT_CLASS, HOUR_START_DEG, HOUR_DEG_INCR, MIN_START_DEG, MIN_DEG_INCR, END_DEG, EX_KEYS, DEFAULTS } from './vars'
2 | import { hf } from './helpers'
3 |
4 | /**
5 | * Time class
6 | */
7 | class Time {
8 | /**
9 | * Creates a time object
10 | * @param {number} hour Hour value (0 - 23)
11 | * @param {number} minute Minute value (0 - 59)
12 | */
13 | constructor(hour, minute) {
14 | this.hour = hour
15 | this.minute = minute
16 | }
17 | setHour(value) { this.hour = value }
18 | getHour(is12Hour) {
19 | return is12Hour ? [0, 12].indexOf(this.hour) >= 0 ? 12 : (this.hour % 12) : this.hour
20 | }
21 | invert() {
22 | if (this.getPeriod() === 'AM') this.setHour(this.getHour() + 12)
23 | else this.setHour(this.getHour() - 12)
24 | }
25 | setMinutes(value) { this.minute = value }
26 | getMinutes() { return this.minute }
27 | getPeriod() { return this.hour < 12 ? 'AM' : 'PM' }
28 | format(format, hourPadding) {
29 | let that = this, is24Hour = (format.match(/h/g) || []).length > 1
30 |
31 | return format.replace(/(hh|h|mm|ss|tt|t)/g, function (e) {
32 | switch (e.toLowerCase()) {
33 | case 'h':
34 | let hour = that.getHour(true)
35 | return (hourPadding && hour < 10 ? '0' + hour : hour)
36 | case 'hh': return (that.hour < 10 ? '0' + that.hour : that.hour)
37 | case 'mm': return (that.minute < 10 ? '0' + that.minute : that.minute)
38 | case 'ss': return '00'
39 | case 't': return is24Hour ? '' : that.getPeriod().toLowerCase()
40 | case 'tt': return is24Hour ? '' : that.getPeriod()
41 | }
42 | })
43 | }
44 | }
45 |
46 | /**
47 | * Time picker class
48 | */
49 | class MDTimePicker {
50 | /**
51 | * Default configurations
52 | */
53 | static default_configs = null;
54 | /**
55 | * Creates a time picker object
56 | * @param {HTMLInputElement} el Input element
57 | * @param {Object} config Time picker configurations
58 | */
59 | constructor(el, config) {
60 | let _ = this
61 |
62 | this.visible = false
63 | this.activeView = 'hours'
64 | this.hTimeout = null
65 | this.mTimeout = null
66 | this.input = el
67 | this.input.readOnly = true
68 | this.config = config
69 | this.time = new Time(0, 0)
70 | this.selected = new Time(0, 0)
71 | this.timepicker = {
72 | overlay: hf.createElem('div', { class: 'mdtimepicker hidden' }),
73 | wrapper: hf.createElem('div', { class: 'mdtp__wrapper', tabindex: 0 }),
74 | timeHolder: {
75 | wrapper: hf.createElem('section', { class: 'mdtp__time_holder' }),
76 | hour: hf.createElem('span', { class: 'mdtp__time_h' }, '12'),
77 | dots: hf.createElem('span', { class: 'mdtp__timedots' }, ':'),
78 | minute: hf.createElem('span', { class: 'mdtp__time_m' }, '00'),
79 | am_pm: hf.createElem('span', { class: 'mdtp__ampm' }, 'AM')
80 | },
81 | clockHolder: {
82 | wrapper: hf.createElem('section', { class: 'mdtp__clock_holder' }),
83 | am: hf.createElem('span', { class: 'mdtp__am' }, 'AM'),
84 | pm: hf.createElem('span', { class: 'mdtp__pm' }, 'PM'),
85 | clock: {
86 | wrapper: hf.createElem('div', { class: 'mdtp__clock' }),
87 | dot: hf.createElem('span', { class: 'mdtp__clock_dot' }),
88 | hours: hf.createElem('div', { class: 'mdtp__hour_holder' }),
89 | minutes: hf.createElem('div', { class: 'mdtp__minute_holder' })
90 | },
91 | buttonsHolder: {
92 | wrapper: hf.createElem('div', { class: 'mdtp__buttons' }),
93 | btnClear: hf.createElem('span', { class: 'mdtp__button clear-btn' }, 'Clear'),
94 | btnOk: hf.createElem('span', { class: 'mdtp__button ok' }, 'Ok'),
95 | btnCancel: hf.createElem('span', { class: 'mdtp__button cancel' }, 'Cancel')
96 | }
97 | }
98 | }
99 |
100 | this.setMinTime(this.input.dataset.mintime || this.config.minTime)
101 | this.setMaxTime(this.input.dataset.maxtime || this.config.maxTime)
102 |
103 | let picker = _.timepicker
104 |
105 | hf.appendTo(_._setup(), document.body)
106 |
107 | hf.addEvent(picker.overlay, 'click', () => { _.hide() })
108 |
109 | hf.addEvent(picker.wrapper, 'click', e => e.stopPropagation())
110 | hf.addEvent(picker.wrapper, 'keydown', e => {
111 | if (e.keyCode !== 27) return
112 |
113 | _.hide()
114 | })
115 |
116 | if (!config.is24hour) {
117 | hf.addEvent(picker.timeHolder.am_pm, 'click', () => {
118 | _.setPeriod(_.selected.getPeriod() == 'AM' ? 'pm' : 'am')
119 | })
120 | }
121 |
122 | hf.addEvent(picker.clockHolder.am, 'click', () => {
123 | if (_.selected.getPeriod() !== 'AM') _.setPeriod('am')
124 | })
125 |
126 | hf.addEvent(picker.clockHolder.pm, 'click', () => {
127 | if (_.selected.getPeriod() !== 'PM') _.setPeriod('pm')
128 | })
129 |
130 | hf.addEvent(picker.timeHolder.hour, 'click', () => {
131 | if (_.activeView !== 'hours') _._switchView('hours')
132 | })
133 |
134 | hf.addEvent(picker.timeHolder.minute, 'click', () => {
135 | if (_.activeView !== 'minutes') _._switchView('minutes')
136 | })
137 |
138 | hf.addEvent(picker.clockHolder.buttonsHolder.btnOk, 'click', () => {
139 | let selected = _.selected
140 |
141 | if (_.isDisabled(selected.getHour(), selected.getMinutes(), false)) return
142 |
143 | _.setValue(selected)
144 |
145 | let formatted = _.getFormattedTime()
146 |
147 | _._triggerChange({ time: formatted.time, value: formatted.value })
148 | _.hide()
149 | })
150 |
151 | hf.addEvent(picker.clockHolder.buttonsHolder.btnCancel, 'click', () => { _.hide() })
152 |
153 | if (_.config.clearBtn) {
154 | hf.addEvent(picker.clockHolder.buttonsHolder.btnClear, 'click', () => {
155 | _.input.value = ''
156 | hf.setAttributes(_.input, {
157 | 'value': '', 'data-time': null
158 | })
159 |
160 | _._triggerChange({ time: null, value: '' })
161 | _.hide()
162 | })
163 | }
164 |
165 | /* input event handlers */
166 | function _inputClick() { _.show() }
167 |
168 | function _inputKeydown(e) {
169 | if (e.keyCode === 13) {
170 | _.show()
171 | }
172 | return !(EX_KEYS.indexOf(e.which) < 0)
173 | }
174 |
175 | /**
176 | * Unbinds input `click` and `keydown` event handlers
177 | */
178 | this._unbindInput = function () {
179 | _.input.readOnly = false
180 | _.input.removeEventListener('click', _inputClick)
181 | _.input.removeEventListener('keydown', _inputKeydown)
182 | }
183 |
184 | hf.addEvent(_.input, 'keydown', _inputKeydown)
185 | hf.addEvent(_.input, 'click', _inputClick)
186 |
187 | if (_.input.value !== '') {
188 | let time = _.parseTime(_.input.value, _.config.format)
189 |
190 | _.setValue(time)
191 | } else {
192 | let time = _.getSystemTime()
193 |
194 | _.time = new Time(time.hour, time.minute)
195 | }
196 |
197 | _.resetSelected()
198 | _._switchView(_.activeView)
199 |
200 | if (_.config.events && _.config.events.ready)
201 | _.config.events.ready.call(_, _)
202 | }
203 | /**
204 | * Setup time picker html elements
205 | */
206 | _setup() {
207 | let _ = this, picker = _.timepicker, overlay = picker.overlay, wrapper = picker.wrapper,
208 | time = picker.timeHolder, clock = picker.clockHolder
209 |
210 | hf.appendTo([time.hour, time.dots, time.minute], time.wrapper)
211 | hf.appendTo(time.wrapper, wrapper)
212 |
213 | if (!_.config.is24hour) hf.appendTo(time.am_pm, time.wrapper)
214 |
215 | // Setup hours
216 | let _hours = _.config.is24hour ? 24 : 12
217 | for (let i = 0; i < _hours; i++) {
218 | let value = i + 1, deg = ((HOUR_START_DEG + (i * HOUR_DEG_INCR)) % END_DEG) - (_.config.is24hour && value < 13 ? 15 : 0),
219 | is24 = value === 24,
220 | hour = hf.createElem('div', { class: `mdtp__digit rotate-${deg}`, 'data-hour': (is24 ? 0 : value) }),
221 | hourInner = hf.createElem('span', null, (is24 ? '00' : value))
222 |
223 | hf.appendTo(hourInner, hour)
224 |
225 | if (_.config.is24hour && value < 13) hour.classList.add('inner--digit')
226 |
227 | hf.addEvent(hourInner, 'click', function() {
228 | let _hour = parseInt(this.parentNode.dataset.hour),
229 | _selectedT = _.selected.getPeriod(),
230 | _value = _.config.is24hour ? _hour :
231 | (_hour + ((_selectedT === 'PM' && _hour < 12) || (_selectedT === 'AM' && _hour === 12) ? 12 : 0)) % 24,
232 | disabled = _.isDisabled(_value, 0, true)
233 |
234 | if (disabled) return
235 |
236 | _.setHour(_value)
237 | _._switchView('minutes')
238 | })
239 |
240 | hf.appendTo(hour, clock.clock.hours)
241 | }
242 |
243 | // Setup minutes
244 | for (let i = 0; i < 60; i++) {
245 | let min = i < 10 ? '0' + i : i, deg = (MIN_START_DEG + (i * MIN_DEG_INCR)) % END_DEG,
246 | minute = hf.createElem('div', { class: `mdtp__digit rotate-${deg}`, 'data-minute': i }),
247 | minuteInner = hf.createElem('span')
248 |
249 | hf.appendTo(minuteInner, minute)
250 |
251 | if (i % 5 === 0) {
252 | minute.classList.add('marker')
253 | minuteInner.innerText = min
254 | }
255 |
256 | hf.addEvent(minuteInner, 'click', function() {
257 | let _minute = parseInt(this.parentNode.dataset.minute),
258 | _hour = _.selected.getHour(),
259 | disabled = _.isDisabled(_hour, _minute, true)
260 |
261 | if (disabled) return
262 |
263 | _.setMinute(_minute)
264 | })
265 |
266 | hf.appendTo(minute, clock.clock.minutes)
267 | }
268 |
269 | // Setup clock
270 | if (!_.config.is24hour) {
271 | hf.appendTo([clock.am, clock.pm], clock.clock.wrapper)
272 | }
273 |
274 | hf.appendTo([clock.clock.dot, clock.clock.hours, clock.clock.minutes], clock.clock.wrapper)
275 | hf.appendTo(clock.clock.wrapper, clock.wrapper)
276 |
277 | // Setup buttons
278 | if (_.config.clearBtn) {
279 | hf.appendTo(clock.buttonsHolder.btnClear, clock.buttonsHolder.wrapper)
280 | }
281 |
282 | hf.appendTo([clock.buttonsHolder.btnCancel, clock.buttonsHolder.btnOk], clock.buttonsHolder.wrapper)
283 | hf.appendTo(clock.buttonsHolder.wrapper, clock.wrapper)
284 |
285 | hf.appendTo(clock.wrapper, wrapper)
286 |
287 | // Setup theme
288 | wrapper.dataset.theme = _.input.dataset.theme || _.config.theme
289 |
290 | hf.appendTo(wrapper, overlay)
291 |
292 | return overlay
293 | }
294 | /**
295 | * Sets the hour value of the selected time
296 | * @param {number} hour Hour value
297 | */
298 | setHour(hour) {
299 | if (typeof hour === 'undefined')
300 | throw new Error('Expecting a value.')
301 |
302 | let is12Hour = !this.config.is24hour
303 |
304 | this.selected.setHour(hour)
305 |
306 | let _selectedH = this.selected.getHour(is12Hour)
307 |
308 | this.timepicker.timeHolder.hour.innerText = is12Hour ? _selectedH : this.selected.format('hh')
309 |
310 | this.timepicker.clockHolder.clock.hours.querySelectorAll('div').forEach(div => {
311 | let val = parseInt(div.dataset.hour)
312 |
313 | div.classList[val === _selectedH ? 'add' : 'remove']('active')
314 | })
315 | }
316 | /**
317 | * Sets the minute value of the selected time
318 | * @param {number} minute Minute value
319 | */
320 | setMinute(minute) {
321 | if (typeof minute === 'undefined')
322 | throw new Error('Expecting a value.')
323 |
324 | this.selected.setMinutes(minute)
325 |
326 | this.timepicker.timeHolder.minute.innerText = minute < 10 ? '0' + minute : minute
327 |
328 | this.timepicker.clockHolder.clock.minutes.querySelectorAll('div').forEach(div => {
329 | let val = parseInt(div.dataset.minute)
330 |
331 | div.classList[val === minute ? 'add' : 'remove']('active')
332 | })
333 | }
334 | /**
335 | * Sets the time period of the selected time
336 | * @param {string} period Period value (AM/PM)
337 | */
338 | setPeriod(period) {
339 | if (typeof period === 'undefined')
340 | throw new Error('Expecting a value.')
341 |
342 | if (this.selected.getPeriod() !== period.toUpperCase())
343 | this.selected.invert()
344 |
345 | let _period = this.selected.getPeriod()
346 |
347 | this._setDisabled(this.activeView)
348 | this.timepicker.timeHolder.am_pm.innerText = _period
349 | this.timepicker.clockHolder.am.classList[_period === 'AM' ? 'add' : 'remove']('active')
350 | this.timepicker.clockHolder.pm.classList[_period === 'PM' ? 'add' : 'remove']('active')
351 | }
352 | /**
353 | * Sets the value of the selected time
354 | * @param {string} value Time string values
355 | */
356 | setValue(value) {
357 | if (typeof value === 'undefined')
358 | throw new Error('Expecting a value.')
359 |
360 | let time = typeof value === 'string' ? this.parseTime(value, this.config.format) : value
361 |
362 | this.time = new Time(time.hour, time.minute)
363 |
364 | let formatted = this.getFormattedTime()
365 |
366 | this.input.value = formatted.value
367 | hf.setAttributes(this.input, {
368 | 'value': formatted.value,
369 | 'data-time': formatted.time
370 | })
371 | }
372 | /**
373 | * Sets the minimum time constraint
374 | * @param {string} time Minimum time value
375 | */
376 | setMinTime(time) { this.minTime = time }
377 | /**
378 | * Sets the maximum time constraint
379 | * @param {string} time Maximum time value
380 | */
381 | setMaxTime(time) { this.maxTime = time }
382 | /**
383 | * Sets the disabled digits of the clock
384 | * @param {string} view View name
385 | */
386 | _setDisabled(view) {
387 | if (view !== 'hours' && view !== 'minutes') return
388 |
389 | let _ = this, clock = this.timepicker.clockHolder.clock
390 |
391 | if (view === 'hours') {
392 | clock.hours.querySelectorAll('.mdtp__digit').forEach(hour => {
393 | let value = parseInt(hour.dataset.hour),
394 | period = _.selected.getPeriod(),
395 | time = new Time(value, 0)
396 |
397 | if (!_.config.is24hour && period !== time.getPeriod())
398 | time.invert()
399 |
400 | let disabled = _.isDisabled(time.getHour(), 0, true)
401 |
402 | hour.classList[disabled ? 'add' : 'remove']('digit--disabled')
403 | })
404 | }
405 |
406 | if (view === 'minutes') {
407 | clock.minutes.querySelectorAll('.mdtp__digit').forEach(minute => {
408 | let value = parseInt(minute.dataset.minute),
409 | hour = _.selected.getHour(),
410 | disabled = _.isDisabled(hour, value, true)
411 |
412 | minute.classList[disabled ? 'add' : 'remove']('digit--disabled')
413 | })
414 | }
415 | }
416 | /**
417 | * Determines if the given time is disabled
418 | * @param {number} hour Hour value
419 | * @param {number} minute Minute value
420 | * @param {boolean} renderMode `true` if called upon rendering; `false` otherwise
421 | */
422 | isDisabled(hour, minute, renderMode) {
423 | let _ = this, minT = null, min = null, maxT = null, max = null, now = new Date(),
424 | time = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute, 0, 0),
425 | hourView = _.activeView === 'hours'
426 |
427 | if (_.minTime)
428 | minT = _.minTime === 'now' ? _.getSystemTime() : _.parseTime(_.minTime)
429 | if (_.maxTime)
430 | maxT = _.maxTime === 'now' ? _.getSystemTime() : _.parseTime(_.maxTime)
431 |
432 | if (minT) {
433 | min = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
434 | minT.getHour(), hourView && renderMode ? 0 : minT.getMinutes(), 0, 0)
435 | }
436 |
437 | if (maxT) {
438 | max = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
439 | maxT.getHour(), hourView && renderMode ? 0 : maxT.getMinutes(), 0, 0)
440 | }
441 |
442 | return (min && time < min) || (max && time > max)
443 | }
444 | /**
445 | * Resets the selected time to client (system) time
446 | */
447 | resetSelected() {
448 | this.setHour(this.time.hour)
449 | this.setMinute(this.time.minute)
450 | this.setPeriod(this.time.getPeriod())
451 | }
452 | /**
453 | * Returns the selected time string
454 | */
455 | getFormattedTime() {
456 | let time = this.time.format(this.config.timeFormat, false),
457 | tValue = this.time.format(this.config.format, this.config.hourPadding)
458 |
459 | return { time: time, value: tValue }
460 | }
461 | /**
462 | * Returns the current client (system) time
463 | */
464 | getSystemTime() {
465 | return (now => {
466 | return new Time(now.getHours(), now.getMinutes())
467 | })(new Date())
468 | }
469 | /**
470 | * Parses the given time string into a Time object
471 | * @param {string} time Time value
472 | * @param {string} tf Time format
473 | */
474 | parseTime(time, tf) {
475 | let that = this, format = typeof tf === 'undefined' ? that.config.format : tf,
476 | hLength = (format.match(/h/g) || []).length,
477 | is24Hour = hLength > 1,
478 | // mLength = (format.match(/m/g) || []).length,
479 | tLength = (format.match(/t/g) || []).length,
480 | timeLength = time.length,
481 | fH = format.indexOf('h'), lH = format.lastIndexOf('h'),
482 | hour = '', min = '', t = ''
483 |
484 | // Parse hour
485 | if (that.config.hourPadding || is24Hour) {
486 | hour = time.substr(fH, 2)
487 | } else {
488 | let prev = format.substring(fH - 1, fH), next = format.substring(lH + 1, lH + 2)
489 |
490 | if (lH === format.length - 1) {
491 | hour = time.substring(time.indexOf(prev, fH - 1) + 1, timeLength)
492 | } else if (fH === 0) {
493 | hour = time.substring(0, time.indexOf(next, fH))
494 | } else {
495 | hour = time.substring(time.indexOf(prev, fH - 1) + 1, time.indexOf(next, fH + 1))
496 | }
497 | }
498 |
499 | format = format.replace(/(hh|h)/g, hour)
500 |
501 | let fM = format.indexOf('m'), lM = format.lastIndexOf('m'),
502 | fT = format.indexOf('t')
503 |
504 | // Parse minute
505 | let prevM = format.substring(fM - 1, fM), nextM = format.substring(lM + 1, lM + 2)
506 |
507 | if (lM === format.length - 1) {
508 | min = time.substring(time.indexOf(prevM, fM - 1) + 1, timeLength)
509 | } else if (fM === 0) {
510 | min = time.substring(0, 2)
511 | } else {
512 | min = time.substr(fM, 2)
513 | }
514 |
515 | // Parse t (am/pm)
516 | if (is24Hour)
517 | t = parseInt(hour) > 11 ? (tLength > 1 ? 'PM' : 'pm') : (tLength > 1 ? 'AM' : 'am')
518 | else
519 | t = time.substr(fT, 2)
520 |
521 | let isPm = t.toLowerCase() === 'pm',
522 | outTime = new Time(parseInt(hour), parseInt(min))
523 | if ((isPm && parseInt(hour) < 12) || (!isPm && parseInt(hour) === 12)) {
524 | outTime.invert()
525 | }
526 |
527 | return outTime
528 | }
529 | /**
530 | * Switches the time picker view (screen)
531 | * @param {string} view View name
532 | */
533 | _switchView(view) {
534 | let _ = this, picker = this.timepicker, anim_speed = 350
535 |
536 | if (view !== 'hours' && view !== 'minutes') return
537 |
538 | _.activeView = view
539 | _._setDisabled(view)
540 |
541 | picker.timeHolder.hour.classList[view === 'hours' ? 'add' : 'remove']('active')
542 | picker.timeHolder.minute.classList[view === 'hours' ? 'remove' : 'add']('active')
543 |
544 | picker.clockHolder.clock.hours.classList.add('animate')
545 | if (view === 'hours')
546 | picker.clockHolder.clock.hours.classList.remove('hidden')
547 |
548 | clearTimeout(_.hTimeout)
549 |
550 | _.hTimeout = setTimeout(() => {
551 | if (view !== 'hours')
552 | picker.clockHolder.clock.hours.classList.add('hidden')
553 | picker.clockHolder.clock.hours.classList.remove('animate')
554 | }, view === 'hours' ? 20 : anim_speed)
555 |
556 | picker.clockHolder.clock.minutes.classList.add('animate')
557 | if (view === 'minutes')
558 | picker.clockHolder.clock.minutes.classList.remove('hidden')
559 |
560 | clearTimeout(_.mTimeout)
561 |
562 | _.mTimeout = setTimeout(() => {
563 | if (view !== 'minutes')
564 | picker.clockHolder.clock.minutes.classList.add('hidden')
565 | picker.clockHolder.clock.minutes.classList.remove('animate')
566 | }, view === 'minutes' ? 20 : anim_speed)
567 | }
568 | /**
569 | * Shows the time picker
570 | */
571 | show() {
572 | let _ = this
573 |
574 | if (_.input.value === '') {
575 | let time = _.getSystemTime()
576 | this.time = new Time(time.hour, time.minute)
577 | }
578 |
579 | _.resetSelected()
580 |
581 | document.body.setAttribute('mdtimepicker-display', 'on')
582 |
583 | _.timepicker.wrapper.classList.add('animate')
584 | _.timepicker.overlay.classList.remove('hidden')
585 | _.timepicker.overlay.classList.add('animate')
586 | setTimeout(function () {
587 | _.timepicker.overlay.classList.remove('animate')
588 | _.timepicker.wrapper.classList.remove('animate')
589 | _.timepicker.wrapper.focus()
590 |
591 | _.visible = true
592 | _.input.blur()
593 |
594 | if (_.config.events && _.config.events.shown)
595 | _.config.events.shown.call(_)
596 | }, 10)
597 | }
598 | /**
599 | * Hides the time picker
600 | */
601 | hide() {
602 | let _ = this
603 |
604 | _.timepicker.overlay.classList.add('animate')
605 | _.timepicker.wrapper.classList.add('animate')
606 | setTimeout(function () {
607 | _._switchView('hours')
608 | _.timepicker.overlay.classList.add('hidden')
609 | _.timepicker.overlay.classList.remove('animate')
610 | _.timepicker.wrapper.classList.remove('animate')
611 |
612 | document.body.removeAttribute('mdtimepicker-display')
613 |
614 | _.visible = false
615 | _.input.focus()
616 |
617 | if (_.config.events && _.config.events.hidden)
618 | _.config.events.hidden.call(_)
619 | }, 300)
620 | }
621 | /**
622 | * Removes the time picker
623 | */
624 | destroy() {
625 | this._unbindInput()
626 | this.timepicker.overlay.remove()
627 | delete this.input[MDTP_DATA]
628 | }
629 | /**
630 | * Triggers the change event on the input element
631 | * @param {Object} data Event data
632 | */
633 | _triggerChange(data) {
634 | hf.triggerChange(this.input, data)
635 |
636 | if (this.config.events && this.config.events.timeChanged)
637 | this.config.events.timeChanged.call(this, data, this)
638 | }
639 | }
640 |
641 | /**
642 | * Time picker wrapper
643 | */
644 | function mdtimepicker() {
645 | let args = arguments,
646 | arg0 = args[0], arg0IsList = arg0 instanceof NodeList || Array.isArray(arg0), arg0IsElem = arg0 instanceof Element,
647 | inputs = typeof arg0 === 'string' ? document.querySelectorAll(arg0) :
648 | (arg0IsList ? arg0 : (arg0IsElem ? [arg0] : document.querySelectorAll(DEFAULT_CLASS))),
649 | options = typeof arg0 === 'object' && !(arg0IsList) && !(arg0IsElem) ? arg0 : args[1] && typeof args[1] === 'object' ? args[1] : {},
650 | _defaults = hf.extend({}, MDTimePicker.default_configs || DEFAULTS)
651 |
652 | if (options && options.is24hour) _defaults.format = 'hh:mm'
653 |
654 | Array.from(inputs).forEach(el => {
655 | let picker = el[MDTP_DATA]
656 |
657 | if (!picker) {
658 | el[MDTP_DATA] = (picker = new MDTimePicker(el, hf.extend(_defaults, options)))
659 | }
660 |
661 | if ((typeof arg0 === 'string' || arg0IsList || arg0IsElem) && (args[1] && typeof args[1] === 'string')) {
662 | picker[args[1]].apply(picker, Array.prototype.slice.call(args).slice(2))
663 | }
664 | })
665 | }
666 |
667 | mdtimepicker.defaults = function (configs) {
668 | MDTimePicker.default_configs = hf.extend(DEFAULTS, configs)
669 | }
670 |
671 | export default mdtimepicker
--------------------------------------------------------------------------------
/src/mdtimepicker.scss:
--------------------------------------------------------------------------------
1 | /*!Don't remove this!
2 | * MDTimePicker plugin styles
3 | *
4 | * Author: Dionlee Uy
5 | * Email: dionleeuy@gmail.com
6 | */
7 |
8 | @import url('https://fonts.googleapis.com/css?family=Roboto:400,500&display=swap');
9 |
10 | $degrees: -15, 6, 12, 15, 18, 24, 30, 36, 42, 45, 48, 54, 60, 66, 72, 75, 78, 84, 90, 96, 102, 105, 108, 114, 120, 126, 132, 135, 138, 144, 150, 156, 162, 165, 168, 174,
11 | 180, 186, 192, 195, 198, 204, 210, 216, 222, 225, 228, 234, 240, 246, 252, 255, 258, 264, 270, 276, 282, 285, 288, 294, 300, 306, 312, 315, 318, 324, 330, 336, 342,
12 | 348, 354, 360;
13 |
14 | .mdtimepicker {
15 | position: fixed;
16 | top: 0;
17 | left: 0;
18 | right: 0;
19 | bottom: 0;
20 | font-family: Roboto, sans-serif;
21 | font-size: 14px;
22 | background-color: rgba(10,10,10,.65);
23 | transition: background-color .28s ease;
24 | z-index: 100001;
25 |
26 | .mdtp__wrapper {
27 | position: absolute;
28 | display: flex;
29 | flex-direction: column;
30 | left: 50%;
31 | bottom: 24px;
32 | min-width: 280px;
33 | opacity: 1;
34 | outline: none;
35 | user-select: none;
36 | border-radius: 4px;
37 | transform: translateX(-50%) scale(1);
38 | box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12);
39 | transition: transform .28s ease, opacity .28s ease;
40 | overflow: hidden;
41 |
42 | &.animate {
43 | transform: translateX(-50%) scale(1.05);
44 | opacity: 0;
45 | }
46 | }
47 |
48 | .mdtp__time_holder {
49 | display: flex;
50 | flex-direction: row;
51 | align-items: center;
52 | justify-content: center;
53 | font-size: 46px;
54 | padding: 20px 24px;
55 | color: rgba(255,255,255,.5);
56 | text-align: center;
57 | background-color: #1565c0;
58 |
59 | & > span {
60 | display: inline-block;
61 | line-height: 48px;
62 | cursor: default;
63 |
64 | &:not(.mdtp__timedots):not(.mdtp__ampm) {
65 | cursor: pointer;
66 | margin: 0 4px;
67 | transition: color .2s linear;
68 | }
69 | }
70 |
71 | .mdtp__time_h.active,
72 | .mdtp__time_m.active { color: #fafafa; }
73 |
74 | .mdtp__ampm {
75 | font-size: 18px;
76 | cursor: pointer;
77 | transition: color .2s linear;
78 |
79 | &:hover {
80 | color: #fafafa;
81 | }
82 | }
83 | }
84 |
85 | .mdtp__clock_holder {
86 | position: relative;
87 | background-color: #fff;
88 |
89 | .mdtp__clock {
90 | position: relative;
91 | width: 250px;
92 | height: 250px;
93 | margin: 20px;
94 | border-radius: 50%;
95 | background-color: #eee;
96 |
97 | .mdtp__am,
98 | .mdtp__pm {
99 | display: block;
100 | position: absolute;
101 | bottom: -8px;
102 | width: 36px;
103 | height: 36px;
104 | line-height: 36px;
105 | text-align: center;
106 | cursor: pointer;
107 | border-radius: 50%;
108 | border: 1px solid rgba(0,0,0,.1);
109 | background: rgba(0,0,0,.05);
110 | transition: background-color .2s ease, color .2s;
111 | z-index: 3;
112 |
113 | &:hover { background-color: rgba(0,0,0,.1); }
114 |
115 | &.active {
116 | color: #fafafa;
117 | background-color: #1565c0;
118 | }
119 | }
120 |
121 | .mdtp__am { left: -8px; }
122 |
123 | .mdtp__pm { right: -8px; }
124 |
125 | .mdtp__clock_dot {
126 | position: absolute;
127 | top: 50%;
128 | left: 50%;
129 | padding: 4px;
130 | border-radius: 50%;
131 | background-color: #1565c0;
132 | transform: translate(-50%,-50%);
133 | }
134 |
135 | .mdtp__hour_holder,
136 | .mdtp__minute_holder {
137 | position: absolute;
138 | top: 0;
139 | width: 100%;
140 | height: 100%;
141 | opacity: 1;
142 | transform: scale(1);
143 | transition: transform .35s cubic-bezier(0.4, 0.0, 0.2, 1), opacity .35s ease;
144 | overflow: hidden;
145 |
146 | &.hidden { display: none; }
147 | }
148 |
149 | .mdtp__hour_holder.animate {
150 | transform: scale(1.2);
151 | opacity: 0;
152 | }
153 |
154 | .mdtp__minute_holder.animate {
155 | transform: scale(.8);
156 | opacity: 0;
157 | }
158 |
159 | .mdtp__digit {
160 | position: absolute;
161 | width: 50%;
162 | top: 50%;
163 | left: 0;
164 | margin-top: -16px;
165 | transform-origin: right center;
166 | z-index: 1;
167 |
168 | span {
169 | display: inline-block;
170 | width: 32px;
171 | height: 32px;
172 | line-height: 32px;
173 | margin-left: 8px;
174 | text-align: center;
175 | border-radius: 50%;
176 | cursor: pointer;
177 | transition: background-color .28s, color .14s;
178 | }
179 |
180 | &.inner--digit {
181 | width: 36%;
182 | left: 14%;
183 | z-index: 2;
184 | }
185 |
186 | &.active span,
187 | &:not(.digit--disabled) span:hover {
188 | background-color: #1565c0 !important;
189 | color: #fff;
190 | z-index: 2;
191 | }
192 |
193 | &.digit--disabled span {
194 | color: rgb(200,200,200);
195 | cursor: not-allowed;
196 | background-color: transparent !important;
197 | }
198 |
199 | &.active:before {
200 | content: '';
201 | display: block;
202 | position: absolute;
203 | top: calc(50% - 1px);
204 | right: 0;
205 | height: 2px;
206 | width: calc(100% - 40px);
207 | background-color: #1565c0;
208 | }
209 | }
210 |
211 | .mdtp__minute_holder {
212 | .mdtp__digit {
213 | font-size: 13px;
214 |
215 | &:not(.marker) {
216 | margin-top: -6px;
217 | height: 12px;
218 |
219 | span {
220 | width: 12px;
221 | height: 12px;
222 | line-height: 12px;
223 | margin-left: 14px;
224 | }
225 | }
226 |
227 | &:not(.marker).active:before { width: calc(100% - 26px); }
228 |
229 | &.marker {
230 | margin-top: -12px;
231 |
232 | span {
233 | width: 24px;
234 | height: 24px;
235 | line-height: 24px;
236 | margin-left: 10px;
237 | }
238 | }
239 |
240 | &.marker.active:before { width: calc(100% - 34px); }
241 | }
242 | }
243 | }
244 | }
245 |
246 | .mdtp__buttons {
247 | padding: 0 10px 10px;
248 | text-align: right;
249 |
250 | .mdtp__button {
251 | display: inline-block;
252 | padding: 0 16px;
253 | min-width: 40px;
254 | text-align: center;
255 | text-transform: uppercase;
256 | line-height: 32px;
257 | font-weight: 500;
258 | cursor: pointer;
259 | color: #1565c0;
260 | border-radius: 4px;
261 | transition: background-color .2s linear;
262 |
263 | &:hover { background-color: rgba(0,0,0,.1); }
264 |
265 | &:active { background-color: rgba(0,0,0,.2); }
266 |
267 | &.clear-btn {
268 | float: left;
269 | color: #ef5350 !important;
270 | }
271 | }
272 |
273 | &:after {
274 | content: '';
275 | display: block;
276 | clear: both;
277 | }
278 | }
279 |
280 | &.hidden { display: none; }
281 | &.animate { background-color: transparent; }
282 | }
283 |
284 | @each $degree in $degrees {
285 | .mdtp__digit.rotate-#{$degree} {
286 | transform: rotate(#{$degree}deg);
287 |
288 | span {
289 | transform: rotate(#{0 - $degree}deg);
290 | }
291 | }
292 | }
293 |
294 | body[mdtimepicker-display='on'] { overflow: hidden; }
295 |
296 | @media (max-height: 360px) {
297 | .mdtimepicker {
298 | .mdtp__wrapper {
299 | flex-direction: row;
300 | bottom: 8px;
301 | }
302 |
303 | .mdtp__time_holder {
304 | width: 160px;
305 | padding: 20px;
306 | }
307 |
308 | .mdtp__clock {
309 | .mdtp__am, .mdtp__pm { bottom: -4px; }
310 |
311 | .mdtp__am { left: -4px; }
312 | .mdtp__pm { right: -4px; }
313 | }
314 | }
315 | }
316 |
317 | @media (max-height: 320px) {
318 | .mdtimepicker .mdtp__wrapper { bottom: 0; }
319 | }
320 |
321 | // themes
322 | @import './themes/red.scss';
323 | @import './themes/green.scss';
324 | @import './themes/blue.scss';
325 | @import './themes/teal.scss';
326 | @import './themes/purple.scss';
327 | @import './themes/indigo.scss';
328 | @import './themes/dark.scss';
--------------------------------------------------------------------------------
/src/themes/_format.scss:
--------------------------------------------------------------------------------
1 | $theme: 'yellow';
2 | $color: #F9A825;
3 |
4 | .mdtp__wrapper[data-theme='#{$theme}'] {
5 | .mdtp__time_holder { background-color: $color; }
6 |
7 | .mdtp__clock {
8 | .mdtp__am.active,
9 | .mdtp__pm.active,
10 | .mdtp__clock_dot { background-color: $color; }
11 |
12 | .mdtp__digit {
13 | &.active span,
14 | &:not(.digit--disabled) span:hover {
15 | background-color: $color !important;
16 | }
17 |
18 | &.active:before { background-color: $color; }
19 | }
20 | }
21 |
22 | .mdtp__button { color: $color; }
23 | }
--------------------------------------------------------------------------------
/src/themes/blue.scss:
--------------------------------------------------------------------------------
1 | $theme: 'blue';
2 | $color: #1565c0;
3 |
4 | .mdtp__wrapper[data-theme='#{$theme}'] {
5 | .mdtp__time_holder { background-color: $color; }
6 |
7 | .mdtp__clock {
8 | .mdtp__am.active,
9 | .mdtp__pm.active,
10 | .mdtp__clock_dot { background-color: $color; }
11 |
12 | .mdtp__digit {
13 | &.active span,
14 | &:not(.digit--disabled) span:hover {
15 | background-color: $color !important;
16 | }
17 |
18 | &.active:before { background-color: $color; }
19 | }
20 | }
21 |
22 | .mdtp__button { color: $color; }
23 | }
--------------------------------------------------------------------------------
/src/themes/dark.scss:
--------------------------------------------------------------------------------
1 | $theme: 'dark';
2 | $headerBg: #121212;
3 | $contentBg: rgb(29,29,29);
4 | $clockBg: rgb(24,24,24);
5 | $color: rgba(255,255,255,.87);
6 | $periodBg: rgba(200,200,200,.05);
7 | $disabled: rgba(100,100,100,.87);
8 | $btnColor: #42a5f5;
9 | $btnHover: rgba(255,255,255,.04);
10 | $btnActive: rgba(255,255,255,.1);
11 |
12 | .mdtp__wrapper[data-theme='#{$theme}'] {
13 | .mdtp__time_holder { background-color: $headerBg; }
14 | .mdtp__clock_holder {
15 | background-color: $contentBg;
16 |
17 | .mdtp__clock {
18 | background-color: $clockBg;
19 |
20 | .mdtp__digit {
21 | &:not(.digit--disabled) { color: $color; }
22 |
23 | &.digit--disabled span { color: $disabled; }
24 | }
25 |
26 | .mdtp__am:not(.active),
27 | .mdtp__pm:not(.active) {
28 | color: $color;
29 | background-color: $periodBg;
30 | }
31 | }
32 | }
33 |
34 | .mdtp__button {
35 | color: $btnColor;
36 |
37 | &:hover { background-color: $btnHover; }
38 |
39 | &:active { background-color: $btnActive; }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/themes/green.scss:
--------------------------------------------------------------------------------
1 | $theme: 'green';
2 | $color: #2e7d32;
3 |
4 | .mdtp__wrapper[data-theme='#{$theme}'] {
5 | .mdtp__time_holder { background-color: $color; }
6 |
7 | .mdtp__clock {
8 | .mdtp__am.active,
9 | .mdtp__pm.active,
10 | .mdtp__clock_dot { background-color: $color; }
11 |
12 | .mdtp__digit {
13 | &.active span,
14 | &:not(.digit--disabled) span:hover {
15 | background-color: $color !important;
16 | }
17 |
18 | &.active:before { background-color: $color; }
19 | }
20 | }
21 |
22 | .mdtp__button { color: $color; }
23 | }
--------------------------------------------------------------------------------
/src/themes/indigo.scss:
--------------------------------------------------------------------------------
1 | $theme: 'indigo';
2 | $color: #283593;
3 |
4 | .mdtp__wrapper[data-theme='#{$theme}'] {
5 | .mdtp__time_holder { background-color: $color; }
6 |
7 | .mdtp__clock {
8 | .mdtp__am.active,
9 | .mdtp__pm.active,
10 | .mdtp__clock_dot { background-color: $color; }
11 |
12 | .mdtp__digit {
13 | &.active span,
14 | &:not(.digit--disabled) span:hover {
15 | background-color: $color !important;
16 | }
17 |
18 | &.active:before { background-color: $color; }
19 | }
20 | }
21 |
22 | .mdtp__button { color: $color; }
23 | }
--------------------------------------------------------------------------------
/src/themes/purple.scss:
--------------------------------------------------------------------------------
1 | $theme: 'purple';
2 | $color: #6a1b9a;
3 |
4 | .mdtp__wrapper[data-theme='#{$theme}'] {
5 | .mdtp__time_holder { background-color: $color; }
6 |
7 | .mdtp__clock {
8 | .mdtp__am.active,
9 | .mdtp__pm.active,
10 | .mdtp__clock_dot { background-color: $color; }
11 |
12 | .mdtp__digit {
13 | &.active span,
14 | &:not(.digit--disabled) span:hover {
15 | background-color: $color !important;
16 | }
17 |
18 | &.active:before { background-color: $color; }
19 | }
20 | }
21 |
22 | .mdtp__button { color: $color; }
23 | }
--------------------------------------------------------------------------------
/src/themes/red.scss:
--------------------------------------------------------------------------------
1 | $theme: 'red';
2 | $color: #c62828;
3 |
4 | .mdtp__wrapper[data-theme='#{$theme}'] {
5 | .mdtp__time_holder { background-color: $color; }
6 |
7 | .mdtp__clock {
8 | .mdtp__am.active,
9 | .mdtp__pm.active,
10 | .mdtp__clock_dot { background-color: $color; }
11 |
12 | .mdtp__digit {
13 | &.active span,
14 | &:not(.digit--disabled) span:hover {
15 | background-color: $color !important;
16 | }
17 |
18 | &.active:before { background-color: $color; }
19 | }
20 | }
21 |
22 | .mdtp__button { color: $color; }
23 | }
--------------------------------------------------------------------------------
/src/themes/teal.scss:
--------------------------------------------------------------------------------
1 | $theme: 'teal';
2 | $color: #00695c;
3 |
4 | .mdtp__wrapper[data-theme='#{$theme}'] {
5 | .mdtp__time_holder { background-color: $color; }
6 |
7 | .mdtp__clock {
8 | .mdtp__am.active,
9 | .mdtp__pm.active,
10 | .mdtp__clock_dot { background-color: $color; }
11 |
12 | .mdtp__digit {
13 | &.active span,
14 | &:not(.digit--disabled) span:hover {
15 | background-color: $color !important;
16 | }
17 |
18 | &.active:before { background-color: $color; }
19 | }
20 | }
21 |
22 | .mdtp__button { color: $color; }
23 | }
--------------------------------------------------------------------------------
/src/vars.js:
--------------------------------------------------------------------------------
1 | export const MDTP_DATA = '_mdtimepicker'
2 |
3 | /**
4 | * Default time picker input query selector class
5 | */
6 | export const DEFAULT_CLASS = '.mdtimepicker-input'
7 |
8 | /**
9 | * Starting degree value for hour hand
10 | */
11 | export const HOUR_START_DEG = 120
12 |
13 | /**
14 | * Hour hand degree increment
15 | */
16 | export const HOUR_DEG_INCR = 30
17 |
18 | /**
19 | * Starting degree value for minute hand
20 | */
21 | export const MIN_START_DEG = 90
22 |
23 | /**
24 | * Minute hand degree increment
25 | */
26 | export const MIN_DEG_INCR = 6
27 |
28 | /**
29 | * Degree limit
30 | */
31 | export const END_DEG = 360
32 |
33 | /**
34 | * Keydown excluded key codes
35 | */
36 | export const EX_KEYS = [9, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123]
37 |
38 | /**
39 | * Default time picker configurations
40 | */
41 | export const DEFAULTS = {
42 | // format of the time value (data-time attribute)
43 | timeFormat: 'hh:mm:ss.000',
44 | // format of the input value
45 | format: 'h:mm tt',
46 | // theme of the timepicker
47 | theme: 'blue',
48 | // determines if display value has zero padding for hour value less than 10 (i.e. 05:30 PM); 24-hour format has padding by default
49 | hourPadding: false,
50 | // determines if clear button is visible
51 | clearBtn: false,
52 | // determines if the clock will use 24-hour format in the UI; format config will be forced to `hh:mm` if not specified
53 | is24hour: false,
54 | // callback functions
55 | events: {
56 | ready: null,
57 | timeChanged: null,
58 | shown: null,
59 | hidden: null
60 | }
61 | }
--------------------------------------------------------------------------------
/vue-timepicker.js:
--------------------------------------------------------------------------------
1 | import './dist/mdtimepicker.css'
2 | import mdtimepicker from './dist/mdtimepicker.js'
3 |
4 | export default {
5 | install(Vue, options) {
6 |
7 | if (! options) options = {}
8 | else mdtimepicker.defaults(options)
9 |
10 | // component
11 | Vue.component('mdtimepicker', {
12 | render(createElement) {
13 | return createElement('input', {
14 | domProps: {
15 | type: 'text'
16 | },
17 | on: {
18 | timechanged: e => {
19 | this.$emit('timechanged', e)
20 | }
21 | }
22 | })
23 | },
24 | props: {
25 | options: { type: Object },
26 | ready: { type: Function },
27 | timeChanged: { type: Function },
28 | shown: { type: Function },
29 | hidden: { type: Function }
30 | },
31 | methods: {
32 | setValue(value) { mdtimepicker(this.$el, 'setValue', value) },
33 | setMinTime(value) { mdtimepicker(this.$el, 'setMinTime', value) },
34 | setMaxTime(value) { mdtimepicker(this.$el, 'setMaxTime', value) },
35 | show() { mdtimepicker(this.$el, 'show') },
36 | hide() { mdtimepicker(this.$el, 'hide') },
37 | destroy() { mdtimepicker(this.$el, 'destroy') }
38 | },
39 | mounted() {
40 | let evtProps = {
41 | events: { ready: this.ready, timeChanged: this.timeChanged, shown: this.shown, hidden: this.hidden }
42 | }
43 |
44 | // remove undefined callbacks
45 | Object.keys(evtProps.events).forEach(key => evtProps.events[key] === undefined && delete evtProps.events[key])
46 |
47 | // initialize
48 | mdtimepicker(this.$el, { ...this.options, ...evtProps })
49 | },
50 | destroyed() {
51 | this.destroy()
52 | }
53 | })
54 |
55 | // v-mdtimepicker directive
56 | Vue.directive('mdtimepicker', {
57 | bind(el, binding) {
58 | mdtimepicker(el, binding.value)
59 | },
60 | unbind(el) {
61 | mdtimepicker(el, 'destroy')
62 | }
63 | })
64 | }
65 | }
--------------------------------------------------------------------------------
/vue3-timepicker.js:
--------------------------------------------------------------------------------
1 | import './dist/mdtimepicker.css'
2 | import mdtimepicker from './dist/mdtimepicker.js'
3 | import { h } from 'vue'
4 |
5 | export default {
6 | install(app, options) {
7 |
8 | if (! options) options = {}
9 | else mdtimepicker.defaults(options)
10 |
11 | // component
12 | app.component('mdtimepicker', {
13 | render() {
14 | return h('input', {
15 | domProps: {
16 | type: 'text'
17 | },
18 | on: {
19 | timechanged: e => {
20 | this.$emit('timechanged', e)
21 | }
22 | }
23 | })
24 | },
25 | props: {
26 | options: { type: Object },
27 | ready: { type: Function },
28 | timeChanged: { type: Function },
29 | shown: { type: Function },
30 | hidden: { type: Function }
31 | },
32 | methods: {
33 | setValue(value) { mdtimepicker(this.$el, 'setValue', value) },
34 | setMinTime(value) { mdtimepicker(this.$el, 'setMinTime', value) },
35 | setMaxTime(value) { mdtimepicker(this.$el, 'setMaxTime', value) },
36 | show() { mdtimepicker(this.$el, 'show') },
37 | hide() { mdtimepicker(this.$el, 'hide') },
38 | destroy() { mdtimepicker(this.$el, 'destroy') }
39 | },
40 | mounted() {
41 | let evtProps = {
42 | events: { ready: this.ready, timeChanged: this.timeChanged, shown: this.shown, hidden: this.hidden }
43 | }
44 |
45 | // remove undefined callbacks
46 | Object.keys(evtProps.events).forEach(key => evtProps.events[key] === undefined && delete evtProps.events[key])
47 |
48 | // initialize
49 | mdtimepicker(this.$el, { ...this.options, ...evtProps })
50 | },
51 | destroyed() {
52 | this.destroy()
53 | }
54 | })
55 |
56 | // v-mdtimepicker directive
57 | app.directive('mdtimepicker', {
58 | bind(el, binding) {
59 | mdtimepicker(el, binding.value)
60 | },
61 | unbind(el) {
62 | mdtimepicker(el, 'destroy')
63 | }
64 | })
65 | }
66 | }
--------------------------------------------------------------------------------