Add paper-time-input back (#1242)

This commit is contained in:
Paulus Schoutsen 2018-05-31 17:20:57 -04:00 committed by GitHub
parent f96db5003a
commit c0919cfe11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 283 additions and 10 deletions

View File

@ -0,0 +1,263 @@
/**
Adapted from paper-time-input from
https://github.com/ryanburns23/paper-time-input
MIT Licensed. Copyright (c) 2017 Ryan Burns
`<paper-time-input>` Polymer element to accept a time with paper-input & paper-dropdown-menu
Inspired by the time input in google forms
### Styling
`<paper-time-input>` provides the following custom properties and mixins for styling:
Custom property | Description | Default
----------------|-------------|----------
`--paper-time-input-dropdown-ripple-color` | dropdown ripple color | `--primary-color`
`--paper-time-input-cotnainer` | Mixin applied to the inputs | `{}`
`--paper-time-dropdown-input-cotnainer` | Mixin applied to the dropdown input | `{}`
*/
import '@polymer/paper-input/paper-input.js';
import '@polymer/paper-listbox/paper-listbox.js';
import '@polymer/paper-item/paper-item.js';
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
class PaperTimeInput extends PolymerElement {
static get template() {
return html`
<style>
:host {
display: block;
@apply --paper-font-common-base;
}
paper-input {
width: 30px;
text-align: center;
--paper-input-container-input: {
/* Damn you firefox
* Needed to hide spin num in firefox
* http://stackoverflow.com/questions/3790935/can-i-hide-the-html5-number-input-s-spin-box
*/
-moz-appearance: textfield;
@apply --paper-time-input-cotnainer;
}
;
--paper-input-container-input-webkit-spinner: {
-webkit-appearance: none;
margin: 0;
display: none;
}
;
}
paper-dropdown-menu {
width: 55px;
padding: 0;
/* Force ripple to use the whole container */
--paper-dropdown-menu-ripple: {
color: var(--paper-time-input-dropdown-ripple-color, --primary-color);
};
--paper-input-container-input: {
@apply --paper-font-button;
text-align: center;
padding-left: 5px;
@apply --paper-time-dropdown-input-cotnainer;
};
--paper-input-container-underline: {
border-color: transparent;
}
--paper-input-container-underline-focus: {
border-color: transparent;
};
}
paper-item {
cursor: pointer;
text-align: center;
font-size: 14px;
}
paper-listbox {
padding: 0;
}
label {
@apply --paper-font-caption;
}
.time-input-wrap {
@apply --layout-horizontal;
@apply --layout-no-wrap;
}
[hidden] {
display: none !important;
}
</style>
<label hidden\$="[[hideLabel]]">[[label]]</label>
<div class="time-input-wrap">
<!-- Hour Input -->
<paper-input id="hour" type="number" value="{{hour}}" on-change="_shouldFormatHour" required="" auto-validate="[[autoValidate]]"
prevent-invalid-input="" maxlength="2" max="[[_computeHourMax(format)]]" min="0" no-label-float="" disabled="[[disabled]]">
<span suffix="" slot="suffix">:</span>
</paper-input>
<!-- Min Input -->
<paper-input id="min" type="number" value="{{min}}" on-change="_formatMin" required="" auto-validate="[[autoValidate]]" prevent-invalid-input=""
maxlength="2" max="59" min="0" no-label-float="" disabled="[[disabled]]">
</paper-input>
<!-- Dropdown Menu -->
<paper-dropdown-menu id="dropdown" required="" hidden\$="[[_equal(format, 24)]]" no-label-float="" disabled="[[disabled]]">
<paper-listbox attr-for-selected="name" selected="{{amPm}}" slot="dropdown-content">
<paper-item name="AM">AM</paper-item>
<paper-item name="PM">PM</paper-item>
</paper-listbox>
</paper-dropdown-menu>
</div>
`;
}
static get properties() {
return {
/**
* Label for the input
*/
label: {
type: String,
value: 'Time'
},
/**
* auto validate time inputs
*/
autoValidate: {
type: Boolean,
value: true
},
/**
* hides the label
*/
hideLabel: {
type: Boolean,
value: false
},
/**
* 12 or 24 hr format
*/
format: {
type: Number,
value: 12
},
/**
* disables the inputs
*/
disabled: {
type: Boolean,
value: false
},
/**
* hour
*/
hour: {
type: String,
notify: true
},
/**
* minute
*/
min: {
type: String,
notify: true
},
/**
* AM or PM
*/
amPm: {
type: String,
notify: true,
value: 'AM'
},
/**
* Formatted time string
*/
value: {
type: String,
notify: true,
readOnly: true,
computed: '_computeTime(min, hour, amPm)'
},
};
}
/**
* Validate the inputs
* @return {boolean}
*/
validate() {
var valid = true;
// Validate hour & min fields
if (!this.$.hour.validate() | !this.$.min.validate()) {
valid = false;
}
// Validate AM PM if 12 hour time
if (this.format === 12 && !this.$.dropdown.validate()) {
valid = false;
}
return valid;
}
/**
* Create time string
*/
_computeTime(min, hour, amPm) {
if (hour && min) {
// No ampm on 24 hr time
if (this.format === 24) {
amPm = '';
}
return hour + ':' + min + ' ' + amPm;
}
return undefined;
}
/**
* Format min
*/
_formatMin() {
if (this.min.toString().length === 1) {
this.min = (this.min < 10) ? ('0' + this.min) : this.min;
}
}
/**
* Hour needs a leading zero in 24hr format
*/
_shouldFormatHour() {
if (this.format === 24 && this.hour.toString().length === 1) {
this.hour = (this.hour < 10) ? ('0' + this.hour) : this.hour;
}
}
/**
* 24 hour format has a max hr of 23
*/
_computeHourMax(format) {
if (format === 12) {
return format;
}
return 23;
}
_equal(n1, n2) {
return n1 === n2;
}
}
customElements.define('paper-time-input', PaperTimeInput);

View File

@ -6,6 +6,7 @@ import '@polymer/polymer/polymer-legacy.js';
import '@vaadin/vaadin-date-picker/vaadin-date-picker.js';
import '../../../components/ha-relative-time.js';
import '../../../components/paper-time-input.js';
import attributeClassNames from '../../../common/entity/attribute_class_names.js';
@ -20,11 +21,7 @@ class DatetimeInput extends PolymerElement {
</template>
<template is="dom-if" if="[[doesHaveTime(stateObj)]]" restamp="">
<div>
<paper-input
type='time'
label='time'
value='{{selectedTime}}'
></paper-input>
<paper-time-input hour="{{selectedHour}}" min="{{selectedMinute}}" format="24"></paper-time-input>
</div>
</template>
</div>
@ -52,10 +49,15 @@ class DatetimeInput extends PolymerElement {
observer: 'dateTimeChanged',
},
selectedTime: {
type: String,
selectedHour: {
type: Number,
observer: 'dateTimeChanged',
}
},
selectedMinute: {
type: Number,
observer: 'dateTimeChanged',
},
};
}
@ -95,14 +97,22 @@ class DatetimeInput extends PolymerElement {
}
let changed = false;
let minuteFiller;
const serviceData = {
entity_id: this.stateObj.entity_id
};
if (this.stateObj.attributes.has_time) {
changed |= this.selectedTime !== `${this.stateObj.attributes.hour}:${this.stateObj.attributes.minute}`;
serviceData.time = this.selectedTime;
changed |= (parseInt(this.selectedMinute) !== this.stateObj.attributes.minute);
changed |= (parseInt(this.selectedHour) !== this.stateObj.attributes.hour);
if (this.selectedMinute < 10) {
minuteFiller = '0';
} else {
minuteFiller = '';
}
var timeStr = this.selectedHour + ':' + minuteFiller + this.selectedMinute;
serviceData.time = timeStr;
}
if (this.stateObj.attributes.has_date) {