feature : display input number next to slider (#808)

* feature : display input number next to slider

* Improvements for Box mode of input number

Add unit when available and align the value to the right

* fix for small width cards

hide state if slider width<100px

* add a space between if and (

* Fix value display after a window resize

State value is now hiding or showing correctly after a window resize, using iron-resize component

* fixes eslint validator

* Fix a typo in state-card

* Improvement : Apply all properties altogether

As suggered by @andrey-git, I made use of setProperties

* Watch for mode update of input_number

If a mode is updated and the box switches from "box" to "slider", it now also update the visibility of the state value depending on the slider width

* Update width showing state value

* Use ResizeObserver when available

* Fix conditionnal mistake

Related @andrey-git review here https://github.com/home-assistant/home-assistant-polymer/pull/808#pullrequestreview-90048982
This commit is contained in:
Victor Cerutti 2018-01-21 06:47:15 +01:00 committed by Paulus Schoutsen
parent 31d2b6ffe1
commit 447dd6640f
3 changed files with 90 additions and 26 deletions

View File

@ -16,7 +16,8 @@
"__DEMO__": false,
"__BUILD__": false,
"Polymer": true,
"webkitSpeechRecognition": false
"webkitSpeechRecognition": false,
"ResizeObserver": false
},
"env": {
"browser": true,

View File

@ -66,6 +66,17 @@
width: 100%;
}
.container-humidity .single-row {
display: flex;
height: 50px;
}
.target-humidity {
width: 90px;
font-size: 200%;
margin: auto;
}
ha-climate-control.range-control-left,
ha-climate-control.range-control-right {
float: left;
@ -144,17 +155,18 @@
</div>
<div class='container-humidity'>
<div class='single-row'>
<div>Target Humidity</div>
<paper-slider
class='humidity'
min='[[stateObj.attributes.min_humidity]]'
max='[[stateObj.attributes.max_humidity]]'
secondary-progress='[[stateObj.attributes.max_humidity]]'
step='1' pin
value='[[stateObj.attributes.humidity]]'
on-change='targetHumiditySliderChanged'>
</paper-slider>
<div>Target Humidity</div>
<div class="single-row">
<div class="target-humidity">[[stateObj.attributes.humidity]] %</div>
<paper-slider
class='humidity'
min='[[stateObj.attributes.min_humidity]]'
max='[[stateObj.attributes.max_humidity]]'
secondary-progress='[[stateObj.attributes.max_humidity]]'
step='1' pin
value='[[stateObj.attributes.humidity]]'
on-change='targetHumiditySliderChanged'>
</paper-slider>
</div>
</div>

View File

@ -6,6 +6,8 @@
<link rel="import" href="../../bower_components/paper-slider/paper-slider.html">
<link rel="import" href="../../bower_components/iron-resizable-behavior/iron-resizable-behavior.html">
<link rel="import" href="../components/entity/state-info.html">
<link rel="import" href="../util/hass-util.html">
@ -15,17 +17,31 @@
<style is="custom-style" include="iron-flex iron-flex-alignment"></style>
<style>
paper-slider {
margin-left: 16px;
margin-left: auto;
}
.state {
@apply(--paper-font-body1);
color: var(--primary-text-color);
text-align: right;
line-height: 40px;
}
.sliderstate {
min-width: 45px;
}
paper-slider[hidden] {
display: none !important;
}
paper-input {
text-align: right;
margin-left: auto;
}
</style>
<div class='horizontal justified layout'>
<state-info state-obj="[[stateObj]]" in-dialog='[[inDialog]]'></state-info>
<paper-slider min='[[min]]' max='[[max]]' value='{{value}}' step='[[step]]' hidden='[[hiddenslider]]' pin
on-change='selectedValueChanged' on-tap='stopPropagation'>
on-change='selectedValueChanged' on-tap='stopPropagation' id='slider'>
</paper-slider>
<paper-input
no-label-float
@ -41,14 +57,32 @@
hidden='[[hiddenbox]]'
>
</paper-input>
<div class="state" hidden='[[hiddenbox]]'>[[stateObj.attributes.unit_of_measurement]]</div>
<div id="sliderstate" class="state sliderstate" hidden='[[hiddenslider]]'>[[value]] [[stateObj.attributes.unit_of_measurement]]</div>
</div>
</template>
</dom-module>
<script>
class StateCardInputNumber extends Polymer.Element {
class StateCardInputNumber extends Polymer.mixinBehaviors([
Polymer.IronResizableBehavior
], Polymer.Element) {
static get is() { return 'state-card-input_number'; }
ready() {
super.ready();
if (typeof ResizeObserver === 'function') {
const ro = new ResizeObserver((entries) => {
entries.forEach((entry) => {
this.hiddenState(entry.contentRect.width);
});
});
ro.observe(this.$.slider);
} else {
this.addEventListener('iron-resize', this.hiddenState);
}
}
static get properties() {
return {
hass: Object,
@ -86,21 +120,38 @@ class StateCardInputNumber extends Polymer.Element {
value: {
type: Number,
},
mode: {
type: String,
}
};
}
hiddenState(sliderwidth) {
if (this.mode !== 'slider') return;
if (isNaN(sliderwidth)) {
sliderwidth = this.$.slider.offsetWidth;
}
if (sliderwidth < 100) {
this.$.sliderstate.hidden = true;
} else if (sliderwidth >= 145) {
this.$.sliderstate.hidden = false;
}
}
stateObjectChanged(newVal) {
this.min = Number(newVal.attributes.min);
this.max = Number(newVal.attributes.max);
this.step = Number(newVal.attributes.step);
this.value = Number(newVal.state);
this.maxlength = this.max.legnth;
if (newVal.attributes.mode === 'slider') {
this.hiddenbox = true;
this.hiddenslider = false;
} else {
this.hiddenbox = false;
this.hiddenslider = true;
const prevMode = this.mode;
this.setProperties({
min: Number(newVal.attributes.min),
max: Number(newVal.attributes.max),
step: Number(newVal.attributes.step),
value: Number(newVal.state),
mode: String(newVal.attributes.mode),
maxlength: String(newVal.attributes.max).length,
hiddenbox: (newVal.attributes.mode !== 'box'),
hiddenslider: (newVal.attributes.mode !== 'slider'),
});
if (this.mode === 'slider' && prevMode !== 'slider') {
this.hiddenState();
}
}