UNPKG

@vanillawc/wc-datepicker

Version:

A web component that wraps a text input element and adds date-picker functionality to it.

1 lines 9.64 kB
export class Datepicker extends HTMLElement{constructor(){super(),this.dayNames=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],this.monthNames=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],this.sundayFirst=!1,this.persistOnSelect=!1,this.longPressThreshold=500,this.longPressInterval=150,this.initDate=null,this.ignoreOnFocus=!1,this.showCloseIcon=!1,this.i=!1,this.t=[],this.s=[],this.l='<style>#calContainer{border:1px solid black;position:absolute;background-color:white;z-index:1000;}#calHeader{display:flex;align-items:center;justify-content:space-around;margin-top:5px;}#calGrid{display:grid;grid-template-columns:auto auto auto auto auto auto auto;padding:10px;}.calDayName, .calDayStyle, .calAdjacentMonthDay, #calTitle{padding:5px;font-size:20px;text-align:center;}.calDayStyle:hover, .calCtrl:hover{color:white;background-color:black;cursor:default;}.calHiddenRow{display:none;}.calAdjacentMonthDay{color:lightgray;}.calSelectedDay{color:red;font-weight:bold;}#calTitle{width:110px;}.calCtrl{font-size:20px;padding:0px 8px;user-select:none;}</style><div id="calContainer" tabindex="0"><div id="calHeader"><div id="calCtrlPrevYear" class="calCtrl">&#9668;&#9668;</div><div id="calCtrlPrevMonth" class="calCtrl">&#9668;</div><div id="calTitle"></div><div id="calCtrlNextMonth" class="calCtrl">&#9658;</div><div id="calCtrlNextYear" class="calCtrl">&#9658;&#9658;</div><div id="calCtrlHideCal" class="calCtrl">&#10005;</div></div><div id="calGrid"><div class="calDayName"></div><div class="calDayName"></div><div class="calDayName"></div><div class="calDayName"></div><div class="calDayName"></div><div class="calDayName"></div><div class="calDayName"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div><div class="calDay"></div></div></div>'}static get observedAttributes(){return["init-date","ignore-on-focus","sunday-first","persist-on-select","show-close-icon"]}disconnectedCallback(){}attributeChangedCallback(i,t,s){"init-date"===i?this.initDate=s:"ignore-on-focus"===i?this.ignoreOnFocus=!0:"sunday-first"===i?this.sundayFirst=!0:"persist-on-select"===i?this.persistOnSelect=!0:"show-close-icon"===i&&(this.showCloseIcon=!0)}connectedCallback(){setTimeout(()=>{this.init()},0)}init(){if(this.h=this.querySelector("input"),null===this.h)return;var i=document.createElement("div");i.style.display="inline-block",this.v&&this.v.remove(),this.v=this.appendChild(i);const t=document.createElement("template");var s;t.innerHTML=this.l,this.v.appendChild(this.h),this.v.appendChild(t.content),this.o=this.querySelector("#calTitle"),this.u=this.querySelector("#calContainer"),this.D=new Date,null!==this.initDate?(s=this.m(this.initDate)).valid?(this.D=new Date(s.p,s.C,s.g),this.i=!0,this.h.value=this._(this.D)):"current"===this.initDate&&(this.i=!0,this.h.value=this._(this.D)):(s=this.m(this.h.value)).valid?(this.D=new Date(s.p,s.C,s.g),this.i=!0):this.i=!1,this.initDate=null,this.N=this.D.getMonth(),this.k=this.D.getFullYear(),this.u.style.display="none",this.H(),this.M(),this.S(),this.ignoreOnFocus||(this.h.onfocus=this.A,this.h.onfocus=this.h.onfocus.bind(this)),this.h.oninput=this.T,this.h.oninput=this.h.oninput.bind(this),this.h.onblur=this.P,this.h.onblur=this.h.onblur.bind(this),this.u.onblur=this.P,this.u.onblur=this.u.onblur.bind(this),this.showCloseIcon||(this.querySelector("#calCtrlHideCal").style.display="none")}setFocusOnCal(){this.u&&(this.u.style.display="block",this.u.focus())}I(i){this.i=!0,this.Y(i.target.innerHTML,this.N,this.k),this.h.value=this._(this.D),this.h.dispatchEvent(new CustomEvent("dateselect")),this.S(),this.persistOnSelect||this.j()}j(){document.activeElement.blur()}O(i){"Enter"===i.key&&this.I(i)}P(){setTimeout(()=>{var i;i=this,"calContainer"===document.activeElement.id||document.activeElement.classList.contains("calCtrl")||document.activeElement.classList.contains("calDay")||document.activeElement.isSameNode(i.h)||(i.u.style.display="none",i.F(),i.i||i.h.dispatchEvent(new Event("invalid")))},0)}M(){for(var i=this.u.querySelectorAll(".calCtrl").entries(),t=i.next();!1===t.done;)t.value[1].tabIndex=0,t.value[1].onblur=this.P,t.value[1].onblur=t.value[1].onblur.bind(this),t.value[1].onclick=this.L,t.value[1].onclick=t.value[1].onclick.bind(this),t.value[1].onkeydown=this.L,t.value[1].onkeydown=t.value[1].onkeydown.bind(this),t.value[1].onmousedown=this.J,t.value[1].onmousedown=t.value[1].onmousedown.bind(this),t.value[1].onmouseup=this.F,t.value[1].onmouseup=t.value[1].onmouseup.bind(this),t.value[1].onmouseleave=this.F,t.value[1].onmouseleave=t.value[1].onmouseleave.bind(this),t.value[1].ontouchstart=this.J,t.value[1].ontouchstart=t.value[1].ontouchstart.bind(this),t.value[1].ontouchend=this.F,t.value[1].ontouchend=t.value[1].ontouchend.bind(this),t.value[1].ontouchcancel=this.F,t.value[1].ontouchcancel=t.value[1].ontouchcancel.bind(this),t=i.next()}R(i){this.t.push(setInterval(()=>{this.L(i)},this.longPressInterval)),this.querySelector("#"+i.target.id).onclick=()=>{this.V(i,this)}}V(i,t){t.querySelector("#"+i.target.id).onclick=t.L,t.querySelector("#"+i.target.id).onclick=t.querySelector("#"+i.target.id).onclick.bind(t)}J(i){this.s.push(setTimeout(()=>{this.R(i)},this.longPressThreshold))}F(){this.s.forEach(clearTimeout),this.s=[],this.t.forEach(clearInterval),this.t=[]}m(i){var t,s,a,l={},n=i.match(/^\s*(\d{1,2})\.(\d{1,2})\.(\d\d\d\d)\s*$/);return null===n?l.valid=!1:(t=Number(n[1]),s=Number(n[2]),a=Number(n[3]),this.G(t,s,a)?(l.valid=!0,l.g=t,l.C=s-1,l.p=a):l.valid=!1),l}T(){var i=this.m(this.h.value);i.valid?(this.i=!0,this.Y(i.g,i.C,i.p),this.N=i.C,this.k=i.p,this.h.dispatchEvent(new CustomEvent("dateselect")),this.S()):this.i=!1}G(i,t,s){if(t<1||t>12)return!1;var a=this.K(t,s);return!(i<1||i>a)}L(i){if("Enter"===i.key||"keydown"!==i.type)switch(i.target.id){case"calCtrlPrevYear":this.U();break;case"calCtrlNextYear":this.W();break;case"calCtrlPrevMonth":this.$();break;case"calCtrlNextMonth":this.q();break;case"calCtrlHideCal":this.j()}}A(){this.T(),this.u.style.display="block"}W(){this.k++,this.S()}U(){this.k--,this.S()}q(){11===this.N?(this.N=0,this.k++):this.N++,this.S()}$(){0===this.N?(this.N=11,this.k--):this.N--,this.S()}S(){var i=new Date(this.k,this.N);i.setDate(1),this.o.innerHTML=this.monthNames[this.N]+" "+this.k;var t=[],s=[];this.B(i,t,s);for(var a=this.u.querySelectorAll(".calDay").entries(),l=a.next();!1===l.done;)l.value[1].classList.remove("calAdjacentMonthDay"),l.value[1].classList.remove("calSelectedDay"),l.value[1].classList.remove("calHiddenRow"),l.value[1].classList.remove("calDayStyle"),l.value[1].onclick=null,l.value[1].onblur=null,l.value[1].onkeydown=null,s[l.value[0]]?l.value[1].classList.add("calAdjacentMonthDay"):l.value[1].classList.add("calDayStyle"),l.value[1].innerHTML=t[l.value[0]],this.N!==this.D.getMonth()||this.k!==this.D.getFullYear()||t[l.value[0]]!==this.D.getDate()||s[l.value[0]]||l.value[1].classList.add("calSelectedDay"),s[l.value[0]]?l.value[1].removeAttribute("tabindex"):(l.value[1].onclick=this.I,l.value[1].onclick=l.value[1].onclick.bind(this),l.value[1].onkeydown=this.O,l.value[1].onkeydown=l.value[1].onkeydown.bind(this),l.value[1].tabIndex=0,l.value[1].onblur=this.P,l.value[1].onblur=l.value[1].onblur.bind(this)),l=a.next();if(s.slice(35,42).every(i=>!0===i))for(l=(a=this.u.querySelectorAll(".calDay").entries()).next();!1===l.done;)l.value[0]>34&&l.value[1].classList.add("calHiddenRow"),l=a.next()}getDateString(){return this.i?this._(this.D):null}getDateObject(){return this.i?this.D:null}Y(i,t,s){i=Number(i),t=Number(t),s=Number(s),i===this.D.getDate()&&t===this.D.getMonth()&&s===this.D.getFullYear()||(this.D.setFullYear(s),this.D.setMonth(t,i))}_(i){var t=i.getFullYear(),s=i.getMonth()+1;return i.getDate()+"."+s+"."+t}H(){var i=[];i=this.dayNames.slice(),this.sundayFirst&&(i.pop(),i.unshift(this.dayNames[6]));for(var t=this.u.querySelectorAll(".calDayName").entries(),s=t.next();!1===s.done;)s.value[1].innerHTML=i[s.value[0]],s=t.next()}B(i,t,s){var a,l=i.getDay(),n=i.getMonth()+1,e=i.getFullYear(),c=this.K(n,e);i.setDate(i.getDate()-1);var h=i.getMonth()+1,d=i.getFullYear(),r=this.K(h,d);if(this.sundayFirst)for(a=0;a<l;a++)t.unshift(r),r--,s.push(!0);else if(0===l)for(a=0;a<6;a++)t.unshift(r),r--,s.push(!0);else for(a=0;a<l-1;a++)t.unshift(r),r--,s.push(!0);for(a=0;a<c;a++)t.push(a+1),s.push(!1);var v=42-t.length;for(a=0;a<v;a++)t.push(a+1),s.push(!0)}X(i){return i%4==0&&i%100!=0||i%400==0}K(i,t){return 1===i||3===i||5===i||7===i||8===i||10===i||12===i?31:4===i||6===i||9===i||11===i?30:2===i&&this.X(t)?29:2!==i||this.X(t)?void 0:28}}customElements.define("wc-datepicker",Datepicker);