-
Notifications
You must be signed in to change notification settings - Fork 279
feat(SLIDER): add vertical slider option and improve design #672
Conversation
Will also need to be added to TILES.md (example) and README.md (at least the new type) |
styles/themes.less
Outdated
@sliderValueColor: #555; | ||
@sliderTrackBg: #555; | ||
@sliderColor: #aaa; | ||
@sliderThumbColor: #777; | ||
|
||
.slidervertical-inner { | ||
&-value { | ||
color: @sliderValueColor; | ||
font-weight: 400; | ||
} | ||
} | ||
|
||
.range-holder input[type="range"] { | ||
|
||
&::-webkit-slider-runnable-track { | ||
background-color: @sliderTrackBg; | ||
} | ||
|
||
&::-moz-range-track { | ||
background-color: @sliderTrackBg; | ||
} | ||
|
||
&::-webkit-slider-thumb{ | ||
background: @sliderColor; | ||
border-bottom:20px solid @sliderColor; | ||
border-left:10px solid @sliderColor; | ||
border-right:10px solid @sliderColor; | ||
border-top:20px solid @sliderColor; | ||
box-shadow: -350px 0 0 350px @sliderColor, inset 0 0 0 80px @sliderThumbColor; | ||
} | ||
|
||
&::-moz-range-thumb{ | ||
background: @sliderColor; | ||
border-bottom:20px solid @sliderColor; | ||
border-left: 12px solid @sliderColor; | ||
border-right: 12px solid @sliderColor; | ||
border-top:20px solid @sliderColor; | ||
box-shadow: -350px 0 0 350px @sliderColor, inset 0 0 0 80px @sliderThumbColor; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would hope there is some more generic way to do that that works in all themes because this is not very scalable.
I would expect to use some theme-specific color variables without repeating all those selectors in each theme.
Also, have you tested that it looks decent in every theme?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would hope there is some more generic way to do that that works in all themes because this is not very scalable.
I would expect to use some theme-specific color variables without repeating all those selectors in each theme.
This can be changed to use parameterised mixin
s.
#lib-range-holder-input() {
.range-holder-input() {
generic_attr: attr;
&::-webkit-slider-runnable-track {
color: @Value1;
}
&::-moz-range-track {
color: @Value2;
}
}
}
@Value1: green;
@Value2: red;
.range-holder input[type="range"] {
#lib-range-holder-input.range-holder-input();
}
.-theme-homekit {
@Value1: black;
@Value2: white;
.range-holder input[type="range"] {
extend_attr: extend;
#lib-range-holder-input.range-holder-input();
&::-moz-range-track {
extend_this: this;
}
}
}
Result:
.range-holder input[type="range"] {
generic_attr: attr;
}
.range-holder input[type="range"]::-webkit-slider-runnable-track {
color: green;
}
.range-holder input[type="range"]::-moz-range-track {
color: red;
}
.-theme-homekit .range-holder input[type="range"] {
extend_attr: extend;
generic_attr: attr;
}
.-theme-homekit .range-holder input[type="range"]::-webkit-slider-runnable-track {
color: black;
}
.-theme-homekit .range-holder input[type="range"]::-moz-range-track {
color: white;
}
.-theme-homekit .range-holder input[type="range"]::-moz-range-track {
extend_this: this;
}
In this case you can get rid of all those selectors and manage all with variables, but potentially raw css will grow in size as all basic attrs can be populated inside themes selectors. Have to be careful with this.
Another way use parameterised mixins as functions;
#lib-range-holder-input() {
.range-input(@Val1, @Val2) {
color: @Val1;
background: @Val2;
}
}
@Val1: green;
@Val2: red;
.range-holder input[type="range"] {
&::-webkit-slider-runnable-track {
#lib-range-holder-input.range-input(@Val1, @Val2);
}
}
.-theme-homekit {
@Value1: black;
@Value2: white;
.range-holder input[type="range"] {
&::-webkit-slider-runnable-track {
#lib-range-holder-input.range-input(@Value1, @Value2);
}
}
}
result:
.range-holder input[type="range"]::-webkit-slider-runnable-track {
color: green;
background: red;
}
.-theme-homekit .range-holder input[type="range"]::-webkit-slider-runnable-track {
color: black;
background: white;
}
In this case we have to define selectors inside themes as well, but code looks more clear/readable as for me.
So please choose which you prefer.
I'm sorry to interrupt you guys, but here are my two thoughts:
|
for me it looks so cubic. at least, probably |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've actually come to the realization that I'd like this functionality to be merged into SLIDER
. It could just have a flag to switch to vertical mode. Otherwise, everything becomes inconsistent as SLIDER has a generic name but can only be horizontal, and also the styles for both of those are completely different. I think the styles for SLIDER
don't really work that well for Tileboard as the slider is very small so it would make sense to consolidate that.
I can help with doing that work.
Sorry for a long delay in work, was busy with family/work issues. So, This commit contains Vertical and Horizontal sliders. New options:
For Horizontal i have added new option to make Tile look
To make it testing easier, below you can find Tiles examples. {
position: [0, 0],
width: 2, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (vertical 1)',
vertical: true,
alignRow: false,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 50,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [2, 0],
width: 2, height: 1,
type: TYPES.SLIDER,
title: 'SLIDER (vertical 2)',
vertical: true,
alignRow: true,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 30,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [2, 1],
width: 1, height: 1,
type: TYPES.SLIDER,
title: 'SLIDER (vertical 2)',
vertical: true,
alignRow: true,
unit: '%',
icon: '',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 30,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [4, 0],
width: 1, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (vertical 3)',
vertical: true,
// alignRow: true,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [5, 0],
width: 0.5, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (vertical 4)',
vertical: true,
alignRow: true,
state: '',
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [0, 2],
width: 2, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/col)',
vertical: false,
alignRow: false,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [2, 2],
width: 2, height: 1,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/col)',
vertical: false,
alignRow: false,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [2, 3],
width: 1, height: 1,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/col)',
vertical: false,
alignRow: false,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [4, 2],
width: 1, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/col)',
vertical: false,
alignRow: false,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [5, 2],
width: 0.5, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/col)',
vertical: false,
alignRow: false,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [6, 0],
width: 2, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/row)',
vertical: false,
alignRow: true,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [8, 0],
width: 2, height: 1,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/row)',
vertical: false,
alignRow: true,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [8, 1],
width: 1, height: 1,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/row)',
vertical: false,
alignRow: true,
unit: '%',
icon: '',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [6, 2],
width: 1, height: 2,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/row)',
vertical: false,
alignRow: true,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [7, 2],
width: 3, height: 1,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/row)',
vertical: false,
alignRow: true,
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
},
{
position: [7, 3],
width: 3, height: 0.5,
type: TYPES.SLIDER,
title: 'SLIDER (horiz/row)',
vertical: false,
alignRow: true,
state: '',
unit: '%',
icon: 'mdi-lightbulb',
id: 'light.f1_r2_light_tv_wall',
value: '@attributes.brightness',
slider: {
max: 255,
min: 0,
step: 5,
field: 'brightness',
// sliderHeight: 120,
// sliderWidth: 80,
request: {
type: "call_service",
domain: "light",
service: "turn_on",
field: "brightness"
},
}
}, If you will have questions - please let me know. |
Thanks for great work but I really think that the default theme should stay without rounded corners to keep the style consistent. |
Is the EDIT: But maybe the "cramped" issue is just a matter of adding some more padding. I guess it could be useful for creating tiles that take little space vertically... |
Thats really strange. i'm using mac/catalina/chrome and dont have access to WinOS at all. If you can help me to identify colours for that it will be great. |
same as previous comment - for me colours look nice. I can make them a bit darker to look better. I will try android tablet to and hope i can find golden middle. |
I'm on macOS also, not Windows. I'm on Big Sur though, which can make a difference. |
I can be wrong but as for me slider |
can you be so kind and pickup colours that work well on Big Sur ? i can compare them with colours on Catalina and Android. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you be so kind and pickup colours that work well on Big Sur ? i can compare them with colours on Catalina and Android.
Thanks
Actually, I see now what's happening. Your entity is in "off" state so its background is a bit transparent, making the slider stand out. Turn that entity on and you will see the same as me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are done
@rchl sorry for bothering, but did you have a chance to review this PR ? |
Didn't have much time. Will try in the evening. |
TILE_EXAMPLES.md
Outdated
![SLIDER](images/tile-screenshots/SLIDER_VERTICAL.png) | ||
```js | ||
{ | ||
position: [6, 1], | ||
id: 'input_number.casatunes_volume_6', | ||
type: TYPES.SLIDER, | ||
unit: '%', | ||
state: false, | ||
//bottom: true, // puts slider on bottom | ||
slider: { | ||
//max: 100, | ||
//min: 0, | ||
//step: 2, | ||
request: { | ||
type: "call_service", | ||
domain: "input_number", | ||
service: "set_value", | ||
field: "value" | ||
} | ||
} | ||
position: [0, 0], | ||
height: 2, // Best works with height > 1. In case height=1, better use custom sliderHeight to achieve your needs | ||
id: 'light.entity', | ||
type: TYPES.SLIDER_VERTICAL, | ||
unit: '%', | ||
title: 'Slider', | ||
icon: 'mdi-lightbulb', // Can be defined or omited. Slider height will be calculated automatically | ||
// legacy: true, // old-style slider that only works in horizontal mode (defaults to `false`) | ||
// bottom: true, // puts slider on the bottom (defaults to `true`) | ||
// vertical: true, // show vertical slider (defaults to `false` - horizontal) | ||
state: false, | ||
filter: function (value) { | ||
var num = parseFloat(value) / 2.55; | ||
return num && !isNaN(num) ? num.toFixed() : 0; | ||
}, | ||
value: '@attributes.brightness', | ||
slider: { | ||
max: 255, | ||
min: 0, | ||
step: 5, | ||
field: 'brightness', | ||
// sliderWidth: '60', // Custom slider width | ||
// sliderHeight: '270', // Custom slider height | ||
request: { | ||
type: "call_service", | ||
domain: "light", | ||
service: "turn_on", | ||
field: "brightness" | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lot needs to be made up to date here. Also update screenshot to use the default theme, for consistency.
scripts/directives/tile.html
Outdated
<span ng-bind="getSliderValue(item, entity, _c)"></span> | ||
<span ng-if="(_unit = entityUnit(item, entity))" ng-bind="_unit"></span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Existing classes need to be reused (with some overrides) instead of creating a completely new one as that is a recipe for creating inconsistencies with existing themes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually didn't change much here as things are a bit messy currently.
OK, I did some updates that I wanted. Feel free to try it out and check if I did break something, before merging. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Except one comment regarding custom slider height - all looks good
scripts/controllers/main.js
Outdated
if (sliderWidth <= 0 || sliderHeight <= 22) { | ||
styles.display = 'none'; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not agree with this, as this can affect user entered values (sliderHeight
). What if user has his own styles applied, and his tile can accommodate height lower than 22
. I know that it too small to be useable but...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking was that if the input is not visible then it should not have a layout since then it would be focusable. That said, focusing stuff with the keyboard is probably not something very relevant in TileBoard so it's more a theoretical issue. But OK, will revert that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks
Thanks for all your help and effort. all looks good. If you are happy - can you merge it please. |
Thanks for your work on this! |
Add Vertical Slider tile.
Tile doesn't require any input from user, width and height will be calculated automatically based on Tile size.
Best to use with tile
height
> 1.Also, some other options are available for user:
sliderHeight
andsliderWidth
. If they are defined insideslider
- they will be used in first place and take precedence via automated calculation.Also, Tile supports
icon
. Ificon
doesn't defined it will be taken to consideration in case of automatic calculation.Example: