resoai / TileBoard

A simple yet highly configurable Dashboard for HomeAssistant
MIT License
1.63k stars 278 forks source link

feat(SLIDER): add vertical slider option and improve design #672

Closed timota closed 3 years ago

timota commented 3 years ago

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 and sliderWidth. If they are defined inside slider - they will be used in first place and take precedence via automated calculation. Also, Tile supports icon. If icon doesn't defined it will be taken to consideration in case of automatic calculation.

Example:

{
    position: [0, 0],
    height: 3,
    id: 'light.entity',
    type: TYPES.SLIDER_VERTICAL,
    unit: '%',
    title: 'Slider',
    icon: 'mdi-lightbulb',
    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',
       // sliderHeight: '270',
       request: {
          type: "call_service",
          domain: "light",
          service: "turn_on",
          field: "brightness"
       },
    },
}
Screenshot 2021-03-22 at 01 36 06
rchl commented 3 years ago

Will also need to be added to TILES.md (example) and README.md (at least the new type)

alphasixtyfive commented 3 years ago

I'm sorry to interrupt you guys, but here are my two thoughts:

1) This should probably be called VERTICAL_SLIDER rather than SLIDER_VERTICAL 2) I would think that default theme should not have rounded corners of the slider to better match the overall boxy style yet Homekit theme would be great with it.

timota commented 3 years ago

@alphasixtyfive

  1. to be honest i like VERTICAL_SLIDER more than SLIDER_VERTICAL. I named it slider_vertical as this points to the same tile family - slider. If all parties are ok to rename - im ok with this.

default theme should not have rounded corners

for me it looks so cubic. at least, probably radius:2px ?

timota commented 3 years ago

Sorry for a long delay in work, was busy with family/work issues.

So, This commit contains Vertical and Horizontal sliders. Vertical behaves same way as it was before (you can manage width/height on your own or leave it for auto-calculation)

New options:

  vertical: true,
  alignRow: false, - ignored when vertical is tru

alignRow, - ignored when vertical is true. it doesn't make sense

For Horizontal i have added new option to make Tile look column or 'row' aligned:

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.

image

alphasixtyfive commented 3 years ago

Thanks for great work but I really think that the default theme should stay without rounded corners to keep the style consistent.

timota commented 3 years ago

Thanks for great work but I really think that the default theme should stay without rounded corners to keep the style consistent.

default theme has only radius 2px just to smooth edges. On screenshot homekit theme.

Below screenshot of default theme. Please check it

Screenshot 2021-04-08 at 22 12 53
rchl commented 3 years ago

It will take me a while to review this properly so please be patient. :)

Just was quickly checking for now and noticed that it doesn't work that well with smaller tiles (tileSize 80):

Screenshot 2021-04-09 at 22 55 48

rchl commented 3 years ago

Actually bigger tile size doesn't really help. It appears it's more about the colors of the input. I think you need to override more of its styles since it's probably picking OS styles (macOS/chrome here).

Screenshot 2021-04-09 at 22 59 59

rchl commented 3 years ago

Is the alignRow option really needed? It looks rather cramped in the row configuration. And there is a lot of unused space in the tile. What would be the use case for that?

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...

rchl commented 3 years ago

Quick update. Looks saner when the slider is not at max value but still not good enough. Not enough contrast to be able to tell where the slider control is.

Screenshot 2021-04-09 at 23 09 15

timota commented 3 years ago

It will take me a while to review this properly so please be patient. :)

Just was quickly checking for now and noticed that it doesn't work that well with smaller tiles (tileSize 80):

Screenshot 2021-04-09 at 22 55 48

i will take a look what i can do

timota commented 3 years ago

Actually bigger tile size doesn't really help. It appears it's more about the colors of the input. I think you need to override more of its styles since it's probably picking OS styles (macOS/chrome here).

Screenshot 2021-04-09 at 22 59 59

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.

timota commented 3 years ago

Quick update. Looks saner when the slider is not at max value but still not good enough. Not enough contrast to be able to tell where the slider control is.

Screenshot 2021-04-09 at 23 09 15

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.

rchl commented 3 years ago

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.

I'm on macOS also, not Windows. I'm on Big Sur though, which can make a difference.

timota commented 3 years ago

Is the alignRow option really needed? It looks rather cramped in the row configuration. And there is a lot of unused space in the tile. What would be the use case for that?

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...

I can be wrong but as for me slider horizontal/AlignRow as it should looks like.

timota commented 3 years ago

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.

I'm on macOS also, not Windows. I'm on Big Sur though, which can make a difference.

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

rchl commented 3 years ago

I haven't checked all themes but it seems to look decent with border: 1px solid #808080;

Screenshot 2021-04-09 at 23 55 35

timota commented 3 years ago

So... in the latest commit i have rearrange styles a bit to fit into lowest possible(without modification) tileSize: 90px. If tileSize < 90 - some inputs from user are required:

Below you can find screenshots:

tileSize: 90px

Screenshot 2021-04-14 at 13 02 56

tileSize: 80px default view. Some tiles are marked FIXME

Screenshot 2021-04-14 at 13 05 14

tileSize: 80px user modified (removed: icon, state)

Screenshot 2021-04-14 at 13 08 23

Hopefully all these make sense.

timota commented 3 years ago

@rchl sorry for bothering, but did you have a chance to review this PR ?

rchl commented 3 years ago

Didn't have much time. Will try in the evening.

rchl commented 3 years ago

I'll be fixing those as I comment as I don't want to prolong this but just mentioning here so you are up to date.

In the default theme, the value text color should be white (to match existing tiles and make the contrast better):

Screenshot 2021-04-19 at 21 09 06

rchl commented 3 years ago

OK, I did some updates that I wanted. Feel free to try it out and check if I did break something, before merging.

timota commented 3 years ago

Thanks for all your help and effort. all looks good. If you are happy - can you merge it please.

rchl commented 3 years ago

Thanks for your work on this!