grudus-timepicker
Version:
Material design time picker in pure Javascript without any dependencies
5 lines (4 loc) • 15.7 kB
JavaScript
/*! grudus-timepicker | (c) 2017-2017
grudus | Apache-2.0 license (see LICENSE) */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Timepicker=t()}(this,function(){"use strict";function e(e){if(e){if(e instanceof Date)return i(e);if(r.test(e.hours)&&u.test(e.minutes))return{hours:parseInt(e.hours),minutes:parseInt(e.minutes)};if(a.test(e))return t(e);throw new TypeError("INVALID FORMAT: {"+JSON.stringify(e)+"}.\n Time must be a Date or 'hh:MM' string or object with 'hours' and 'minutes' fields")}return i(new Date)}function t(e){var t=a.exec(e);return{hours:parseInt(t[1]),minutes:parseInt(t[2])}}function i(e){return{hours:e.getHours(),minutes:e.getMinutes()}}function n(e){return new Promise(function(t){setTimeout(t,e)})}function o(e){document.getElementById(f.headerId).style.background=e.headerBackground,document.getElementById(f.headerId).style.color=e.headerColor,document.getElementById(f.wrapperId).style.background=e.wrapperBackground,document.getElementById(f.clockId).style.background=e.clockBackground,document.getElementById(f.handId).style.background=e.handColor,document.getElementById(f.dotId).style.background=e.handColor,document.getElementById(f.buttonsId).style.background=e.footerBackground,document.getElementById(f.submitId).style.color=e.submitColor,document.getElementById(f.cancelId).style.color=e.cancelColor,s(m.clockItem,e.clockItemColor),s(m.inner,e.clockItemInnerColor),s(m.outer,e.handColor,"borderColor")}function s(e,t){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"color",n=Array.from(document.getElementsByClassName(e)),o=!0,s=!1,c=void 0;try{for(var l,r=n[Symbol.iterator]();!(o=(l=r.next()).done);o=!0)l.value.style[i]=t}catch(e){s=!0,c=e}finally{try{!o&&r.return&&r.return()}finally{if(s)throw c}}}function c(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};l();var i=Object.assign({},k.clockConfig,t),n=e(i.time),s=new b(i,n);o(i),s.onStart()}function l(){if(document.getElementById(k.clockId))throw Error("There is already one running grudus-timepicker instance!");var e=document.createElement("div");e.id=k.clockId,e.innerHTML=h,document.body.appendChild(e)}var r=/^([0-1]?[0-9]|2[0-3])$/,u=/^([0-5]?[0-9])$/,a=/^([0-1]?[0-9]|2[0-3]):([0-5][0-9])$/,d=function(t){var i=e(t);return(i.hours<10?"0"+i.hours:i.hours)+":"+(i.minutes<10?"0"+i.minutes:i.minutes)},h="<section class='g-time-wrapper'>\n <header class='g-head g-flex' id='g-head'>\n <section class='g-head-content'>\n <span class='g-current g-hour g-active g-pointer' id='g-hours'>21</span>\n <span class='g-current'>:</span>\n <span class='g-current g-minute g-pointer' id='g-minutes'>37</span>\n </section>\n </header>\n\n\n <section class='g-clock-wrapper g-flex' id='g-clock-wrapper'>\n <div class='g-clock' id='g-clock'> <span class='g-middle-dot' id='g-middle-dot'></span>\n <div class='g-hand-of-a-clock' id='g-hand-of-a-clock'></div>\n <div class='g-clock g-clock-inner' id='g-clock-inner'></div>\n </div>\n </section>\n\n\n <footer class='g-buttons g-flex' id='g-buttons'>\n <button id='g-time-cancel' class='g-button g-cancel g-pointer'>CANCEL</button>\n <button id='g-time-submit' class='g-button g-submit g-pointer'>OK</button>\n </footer>\n\n</section>",m={clock:"g-clock",clockItem:"g-clock-item",inner:"g-clock-inner",outer:"g-clock-outer",item:"g-clock-item",hand:"g-hand-of-a-clock",fadeOut:"g-fade-out",selected:"g-selected",active:"g-active",submit:"g-submit",cancel:"g-cancel",hour:"g-hour",minute:"g-minute"},f={headerId:"g-head",hoursId:"g-hours",minutesId:"g-minutes",clockId:"g-clock",innerId:"g-clock-inner",wrapperId:"g-clock-wrapper",dotId:"g-middle-dot",handId:"g-hand-of-a-clock",buttonsId:"g-buttons",submitId:"g-time-submit",cancelId:"g-time-cancel"},k={clockId:"grudus-clock",clockConfig:{onSubmit:function(){},onCancel:function(){},headerBackground:"#1976D2",headerColor:"#c7d6e1",headerSelected:"#ffffff",wrapperBackground:"#f0fff0",footerBackground:"#f0fff0",submitColor:"#1976D2",cancelColor:"#1976D2",clockBackground:"#CFD8DC",clockItemColor:"#212121",clockItemInnerColor:"#212121",handColor:"#1976D2"},FaceType:{HOURS:"hours",MINUTES:"minutes"}},g=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},p=function(){function e(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,i,n){return i&&e(t.prototype,i),n&&e(t,n),t}}(),y=function(){function e(t){g(this,e),this.options=t.options,this.time=t.time,this.onHourClicked=t.onHourClicked,this.onMinutesClicked=t.onMinutesClicked,this.initView()}return p(e,[{key:"initView",value:function(){var e=this;this.headerHours=document.getElementById(f.hoursId),this.headerHours.onclick=function(){e.toggleActiveToHours(),e.onHourClicked()},this.headerMinutes=document.getElementById(f.minutesId),this.headerMinutes.onclick=function(){e.toggleActiveToMinutes(),e.onMinutesClicked()},this.updateDisplayedTime(),this.toggleActiveToHours()}},{key:"toggleActiveToMinutes",value:function(){this.toggleActive(this.headerHours,this.headerMinutes)}},{key:"toggleActiveToHours",value:function(){this.toggleActive(this.headerMinutes,this.headerHours)}},{key:"toggleActive",value:function(e,t){e.style.color=this.options.headerColor,t.style.color=this.options.headerSelected}},{key:"updateDisplayedTime",value:function(){e.doUpdateDisplayedTime(this.headerHours,this.time.hours),e.doUpdateDisplayedTime(this.headerMinutes,this.time.minutes)}}],[{key:"doUpdateDisplayedTime",value:function(e,t){e.innerText=t<10?"0"+t:t}}]),e}(),v=function(){function e(t,i,n){g(this,e),this.displayed=["00","05","10","15","20","25","30","35","40","45","50","55"],this.options=t.options,this.type=k.FaceType.MINUTES,this.selected=void 0,this.items=t,this.minutes=i,this.updateMinutes=n}return p(e,[{key:"onEnter",value:function(){this.selected=this.findSelected(this.minutes),this.colorSelected(),this.updateMinutes(this.minutes,6*this.minutes)}},{key:"onLeave",value:function(){this.selected&&(this.removeSelected(),this.selected=void 0)}},{key:"selectTime",value:function(e){this.selected&&this.removeSelected();var t=Math.round(e/6)%60;this.selected=this.findSelected(t),this.colorSelected(),this.minutes=t,this.updateMinutes(this.minutes,e)}},{key:"findSelected",value:function(e){return e%5==0?this.items.clockItems[e/5]:this.items.outerClockItems[e]}},{key:"colorSelected",value:function(){this.isOuter()?this.selected.classList.add(m.selected):(this.selected.style.background=this.options.handColor,this.selected.style.color="whitesmoke")}},{key:"removeSelected",value:function(){this.isOuter()?this.selected.classList.remove(m.selected):(this.selected.style.background="transparent",this.selected.style.color=this.options.clockItemColor)}},{key:"isOuter",value:function(){return this.items.outerClockItems.indexOf(this.selected)>-1}}]),e}(),I=function(){function e(t,i,n){g(this,e),this.displayed=["12","1","2","3","4","5","6","7","8","9","10","11"],this.displayedInner=["00","13","14","15","16","17","18","19","20","21","22","23"],this.type=k.FaceType.MINUTES,this.selected=void 0,this.options=t.options,this.items=t,this.hours=i,this.updateHours=n}return p(e,[{key:"onEnter",value:function(){this.items.innerClockElem.style.display="block";var e=this.hours<13&&0!==this.hours,t=this.hours%12;this.selected=e?this.items.clockItems[t]:this.items.innerClockItems[t],this.colorSelected(),this.updateHours(this.hours,30*t,e?this.items.radius:this.items.radius-50)}},{key:"onLeave",value:function(){this.items.innerClockElem.style.display="none",this.selected&&(this.removeSelected(),this.selected=void 0)}},{key:"selectTime",value:function(e,t){this.selected&&this.removeSelected();var i=Math.round(e/30)%12;this.selected=(t===this.items.innerClockElem?this.items.innerClockItems:this.items.clockItems)[i],this.colorSelected(),this.hours=parseInt(this.selected.innerText);var n=30*Math.round(e/30);this.updateHours(this.hours,n,t===this.items.innerClockElem?this.items.radius-50:this.items.radius)}},{key:"colorSelected",value:function(){this.selected.style.background=this.options.handColor,this.selected.style.color="#ffffff"}},{key:"removeSelected",value:function(){this.selected.style.background="transparent",this.selected.style.color=this.isInner()?this.options.clockItemInnerColor:this.options.clockItemColor}},{key:"isInner",value:function(){return Array.from(this.items.innerClockItems).indexOf(this.selected)>-1}}]),e}();Promise.delay=function(e,t){return t||(t=e,e=function(){}),n(t).then(e)},Promise.prototype.delay=function(e,t){return this.then(function(){return Promise.delay(e,t)})};var C={toRadians:function(e){return e*(Math.PI/180)},toDegrees:function(e){return e*(180/Math.PI)},findMousePosition:function(e,t){var i=t.getBoundingClientRect();return{x:e.clientX-i.left,y:e.clientY-i.top}}},E=function(){function e(t,i){g(this,e),this.clockElem=t,this.innerClockElem=i,this.size={},this.middle={}}return p(e,[{key:"create",value:function(t,i,n,o){e.doCreate(t,this.clockElem,function(e){return e.classList.add(m.item)}),e.doCreate(i,this.innerClockElem,function(e,t){e.classList.add(m.item,m.inner),e.innerText=o.displayedInner[t]});for(var s=0;s<60;s++){var c=document.createElement("span");c.classList.add(m.outer),n.push(c),this.clockElem.appendChild(c)}}},{key:"calculateSize",value:function(t,i,n){this.size.width=this.clockElem.offsetWidth,this.size.height=this.clockElem.offsetHeight,this.middle.x=this.size.width/2,this.middle.y=this.size.height/2,this.itemsRadius=this.size.width/2-20;var o=this.innerClockElem.offsetWidth/2,s=this.innerClockElem.offsetHeight/2;e.doCalculateSize(this.middle.x,this.middle.y,this.itemsRadius,t),e.doCalculateSize(o,s,this.itemsRadius-40,i),e.doCalculateSize(this.middle.x,this.middle.y,this.itemsRadius,n)}}],[{key:"doCreate",value:function(e,t,i){for(var n=0;n<12;n++){var o=document.createElement("span");i(o,n),e.push(o),t.appendChild(o)}}},{key:"doCalculateSize",value:function(e,t,i,n){for(var o=360/n.length,s=0;s<n.length;s++){var c=C.toRadians(s*o),l=n[s],r=l.offsetWidth,u=l.offsetHeight;l.style.left=e+Math.sin(c)*i-r/2+"px",l.style.bottom=t+Math.cos(c)*i-u/2+"px"}}}]),e}(),T=function(){function e(t,i,n){g(this,e),this.options=t,this.time=i,this.onTimeUpdate=n,this.isMouseDown=!1,this.clockItems=[],this.innerClockItems=[],this.outerClockItems=[],this.size={},this.middle={},this.initViews(),this.initTimeFaces(i),this.createFace(),this.hoursFace.items.radius=this.itemsRadius,this.currentFace=this.hoursFace,this.changeDisplayed(this.currentFace.displayed)}return p(e,[{key:"initViews",value:function(){var e=this;this.clockElem=document.getElementById(f.clockId),this.innerClockElem=document.getElementById(f.innerId),this.handOfAClock=document.getElementById(f.handId),this.clockElem.onmousedown=function(){return e.isMouseDown=!0},this.clockElem.onmouseup=function(){e.isMouseDown=!1,e.toggleToMinutes()},this.handOfAClock.onmouseup=function(e){return e.stopPropagation()},this.handOfAClock.onmousemove=function(e){return e.stopPropagation()},this.handOfAClock.onclick=function(e){return e.stopPropagation()},this.clockElem.onmousemove=function(t){return e.selectTime(t,!1,e.clockElem)},this.clockElem.onclick=function(t){return e.selectTime(t,!0,e.clockElem)},this.innerClockElem.onmousemove=function(t){return e.selectTime(t,!1,e.innerClockElem)},this.innerClockElem.onclick=function(t){return e.selectTime(t,!0,e.innerClockElem)}}},{key:"initTimeFaces",value:function(e){var t=this;this.minutesFace=new v({options:this.options,clockItems:this.clockItems,outerClockItems:this.outerClockItems},e.minutes,function(e,i){return t.updateMinutes(e,i)}),this.hoursFace=new I({options:this.options,innerClockItems:this.innerClockItems,clockItems:this.clockItems,innerClockElem:this.innerClockElem},e.hours,function(e,i,n){return t.updateHours(e,i,n)})}},{key:"onStart",value:function(){this.currentFace.onEnter()}},{key:"createFace",value:function(){var e=new E(this.clockElem,this.innerClockElem);e.create(this.clockItems,this.innerClockItems,this.outerClockItems,this.hoursFace),e.calculateSize(this.clockItems,this.innerClockItems,this.outerClockItems),this.size=e.size,this.middle=e.middle,this.itemsRadius=e.itemsRadius}},{key:"selectTime",value:function(e,t,i){if(t||this.isMouseDown){var n=C.findMousePosition(e,this.clockElem),o=n.x-this.middle.x,s=this.middle.y-n.y,c=90-C.toDegrees(Math.atan(s/o));o<0&&(c+=180),this.currentFace.selectTime(c,i),e.stopPropagation()}}},{key:"changeDisplayed",value:function(e){for(var t=0;t<this.clockItems.length;t++)this.clockItems[t].innerText=e[t]}},{key:"onEachClockElement",value:function(e){[].forEach.call(this.clockItems,function(t){return e(t)})}},{key:"updateMinutes",value:function(e,t){this.time.minutes=e,this.calculateHandOfTheClock(t,this.itemsRadius),this.onTimeUpdate(this.time,k.FaceType.MINUTES)}},{key:"updateHours",value:function(e,t,i){this.time.hours=e,this.calculateHandOfTheClock(t,i),this.onTimeUpdate(this.time,k.FaceType.HOURS)}},{key:"calculateHandOfTheClock",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.itemsRadius;this.handOfAClock.style.transform="rotate("+(e-90)+"deg)",this.handOfAClock.style.width=t+"px"}},{key:"toggleToHours",value:function(){this.minutesFace.onLeave(),this.toggleTime(this.hoursFace)}},{key:"toggleToMinutes",value:function(){this.hoursFace.onLeave(),this.toggleTime(this.minutesFace)}},{key:"toggleTime",value:function(e){var t=this;this.currentFace!==e&&(this.onEachClockElement(function(e){return e.classList.add(m.fadeOut)}),this.handOfAClock.classList.add(m.fadeOut),Promise.delay(function(){t.onEachClockElement(function(e){return e.classList.remove(m.fadeOut)}),t.handOfAClock.classList.remove(m.fadeOut),t.changeDisplayed(e.displayed),t.currentFace=e,t.onEachClockElement(function(e){return t.removeSelected(e)}),e.onEnter()},300))}},{key:"removeSelected",value:function(e){e.classList.remove(m.selected),e.style.background="transparent",e.style.color=this.options.clockItemColor}}]),e}(),b=function(){function e(t,i){g(this,e),this.options=t,this.initView(),this.time=i,this.initElements()}return p(e,[{key:"initView",value:function(){var t=this;this.submitButton=document.getElementById(f.submitId),this.submitButton.onclick=function(){var i=t.time;i.formatted=function(){return d(i)},t.options.onSubmit(i),e.dispose()},this.cancelButton=document.getElementById(f.cancelId),this.cancelButton.onclick=function(){t.options.onCancel(),e.dispose()}}},{key:"initElements",value:function(){var e=this;this.header=new y({options:this.options,time:this.time,onHourClicked:function(){return e.toggleToHours()},onMinutesClicked:function(){return e.toggleToMinutes()}}),this.clockFace=new T(this.options,this.time,function(t,i){return e.onTimeUpdate(t,i)})}},{key:"onStart",value:function(){this.clockFace.onStart()}},{key:"toggleToHours",value:function(){this.clockFace.toggleToHours()}},{key:"toggleToMinutes",value:function(){this.clockFace.toggleToMinutes()}},{key:"onTimeUpdate",value:function(e,t){this.time=e,this.header.time=e,this.header.updateDisplayedTime(),t===k.FaceType.MINUTES&&this.header.toggleActiveToMinutes()}}],[{key:"dispose",value:function(){document.body.removeChild(document.getElementById(k.clockId))}}]),e}();return{showPicker:function(e){return c(e)},format:function(e){return d(e)}}});
//# sourceMappingURL=grudus-timepicker.es5.js.map