mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-07 17:36:35 +00:00
Add paper-time-input back (#1242)
This commit is contained in:
parent
f96db5003a
commit
c0919cfe11
263
src/components/paper-time-input.js
Normal file
263
src/components/paper-time-input.js
Normal 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);
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user