UNPKG

@dman777/lit-time-picker

Version:

a time picker web component made with lit element

220 lines (187 loc) 5.44 kB
import { LitElement, html, css } from 'lit-element'; import moment from 'moment'; import { timePickerStyles } from './time-picker.css.js' import '@material/mwc-icon-button'; import '@material/mwc-textfield'; import '@material/mwc-button'; const hour = (hour, changeTimeFromArrow, onChange) => { return html` <div data-unit="hour"> <mwc-icon-button @click="${changeTimeFromArrow}" data-op="add" data-unit="hour"> <img src="src/up-arrow-icon.svg"></img> </mwc-icon-button> <mwc-textfield @change="${onChange}" size="2" pattern="[0-9]+" data-unit="hour" data-format="hh" value="${hour}"></mwc-textfield> <mwc-icon-button @click="${changeTimeFromArrow}" data-op="subtract" data-unit="hour"> <img src="src/down-arrow-icon.svg"></img> </mwc-icon-button> </div> `; } const minutes = (minutes, changeTimeFromArrow, onChange) => { return html` <div data-unit="hour"> <mwc-icon-button @click="${changeTimeFromArrow}" data-op="add" data-unit="minutes"> <img src="src/up-arrow-icon.svg"></img> </mwc-icon-button> <mwc-textfield @change="${onChange}" size="2" pattern="[0-9]+" data-unit="minute" data-format="mm" value="${minutes}"></mwc-textfield> <mwc-icon-button @click="${changeTimeFromArrow}" data-op="subtract" data-unit="minutes"> <img src="src/down-arrow-icon.svg"></img> </mwc-icon-button> </div> `; } const seconds = (seconds, changeTimeFromArrow, onChange) => { return html` <div data-unit="seconds"> <mwc-icon-button @click="${changeTimeFromArrow}" data-op="add" data-unit="seconds"> <img src="src/up-arrow-icon.svg"></img> </mwc-icon-button> <mwc-textfield @change="${onChange}" size="2" pattern="[0-9]+" data-unit="second" data-format="ss" value="${seconds}"></mwc-textfield> <mwc-icon-button @click="${changeTimeFromArrow}" data-op="subtract" data-unit="seconds"> <img src="src/down-arrow-icon.svg"></img> </mwc-icon-button> </div> `; } const meridian = (meridian, toggleMeridianFromArrow) => { return html` <div> <mwc-icon-button @click="${toggleMeridianFromArrow}"> <img src="src/up-arrow-icon.svg"></img> </mwc-icon-button> <mwc-button @click="${toggleMeridianFromArrow}" label="${meridian}" ></mwc-button> <mwc-icon-button @click="${toggleMeridianFromArrow}"> <img src="src/down-arrow-icon.svg"></img> </mwc-icon-button> </div> `; } class TimePicker extends LitElement { static get styles() { return [ timePickerStyles, ]; } static get properties() { return { hour: { type: Number }, minutes: { type: Number }, seconds: { type: Number }, meridian: { type: String }, momentObj: { type: Object }, timeDateStamp: { type: String, attribute: 'time-date-stamp', }, } } constructor() { super(); this.timeDateStamp = moment().toDate().toISOString(); } render() { return html` <div class="body"> ${hour(this.hour, this.changeTimeFromArrow, this.onChange)} <div class="colon">:</div> ${minutes(this.minutes, this.changeTimeFromArrow, this.onChange)} <div class="colon">:</div> ${seconds(this.seconds, this.changeTimeFromArrow, this.onChange)} ${meridian(this.meridian, this.toggleMeridianFromArrow)} </div> `; } dissectEventObj(e) { const unit = e.target.dataset.unit; const op = e.target.dataset.op; const value = e.target.value; const format = e.target.format; return { unit, op, value, format }; } changeTimeFromArrow(e) { const { unit, op } = this.dissectEventObj(e); this.setTimeDateStampRaw((momentObj) => { momentObj[op](1, unit); }); } toggleMeridianFromArrow() { this.setTimeDateStampRaw((momentObj) => { momentObj.add('12', 'hours'); }); } fireTimeChangeEvent() { const event = new CustomEvent('time-changed', { detail: { timeStampISO: this.timeDateStamp, momentObj: moment(this.timeDateStamp), } }); this.dispatchEvent(event); } set timeDateStamp(value) { this._timeDateStamp = value; const momentObj = moment(value).local(); this.hour = momentObj.format('hh'); this.minutes = momentObj.format('mm'); this.seconds = momentObj.format('ss'); this.meridian = momentObj.format('A'); this.fireTimeChangeEvent(); } setTimeDateStampRaw(callback) { const momentObj = moment(this.timeDateStamp); callback(momentObj) this.timeDateStamp = momentObj.toDate().toISOString(); } get timeDateStamp() { return this._timeDateStamp; } onChange(e) { const el = e.composedPath()[0]; const { unit, value } = this.dissectEventObj(e); const isValid = moment(value, `${unit} A`).isValid(); if (!isValid) { el.setCustomValidity(); el.focus(); } else { el.setCustomValidity(''); this.setTimeDateStampRaw((momentObj) => {momentObj[unit](value);}); } } } customElements.define('lit-time-picker', TimePicker);