As said before, just a poc to see if it is achievable. New cards and widgets need some finetuning regarding positioning.
I have fixed the menu button text, unselected will be normal text and selected will be bold, as per your design. Also fixed that this will be used right at the start.
Need to apply it to the other menu entrys and will deploy to my github repo during the day.
@Nic0205 Could you please try to reduce the space between the Top Menu entries, like in @Dimitris reference design.
I will try this afternoon. The sd-card of my test raspi has crashed to night. As soon as the new one is up again I will have a look
No Backup?
I am using VM‘s for development, makes my life easy….
Maybe you forgot that top bar and bottom bar are completely separated from widgets for items
Btw, items on widgets are almost identical to your drafts
If you want i can post the yaml code so you can check and eventually tell me what to change or view in different way
Hi,
I tried it for the Top-Menu (Home, Floor, Room).
The main problem is in my opinion that we use the f7-segmented component, which creates oh-buttons with always the same size - equal if the text in it is 10px or 100px - It will ever be 100px + a few pixel left and right.
@JustinG: Is there any CSS that could prevent the segmented component from doing that? Or Do you advice an other component for that?
For all: here is an attempt to deal with the top to-menu. But that does not solve the real base problem…
uid: main_widget
tags: []
props:
parameters:
- description: Set default color for Text
label: Text color
name: textColor
required: false
type: TEXT
- default: RGB(96, 96, 96)
description: Set default color for Text
label: Bottom-Navbar-Color
name: bnavColor
required: false
type: TEXT
- default: Somewhere
description: Name for your weather location
label: Weather Location
name: locationTitle
required: false
type: TEXT
- context: item
description: Name of scenes group item
label: Scenes Group
name: scenesGroup
required: false
type: TEXT
- context: item
description: Name of security group item
label: Security Group
name: securityGroup
required: false
type: TEXT
- context: item
description: Security Mode Item
label: Security Mode
name: securityMode
required: false
type: TEXT
- context: item
description: Security PIN Item
label: Security PIN
name: referencePIN
required: false
type: TEXT
parameterGroups: []
timestamp: Sep 25, 2022, 3:29:27 PM
component: f7-block
config:
style:
display: flex
flex-direction: column
height: calc(100vh - var(--f7-toolbar-height) - var(--f7-safe-area-bottom) - var(--f7-safe-area-top))
--menu-text-color: '= (!props.textColor) ? (themeOptions.dark=="light")? black : white : props.textColor'
--f7-button-text-color: "#8c8c8c"
--opmw-menu-text-color: =(themeOptions.dark=="light")?("#8C8C8C"):("#848484")
stylesheet: >
.selected_menu_item {
color: var(--menu-text-color);
text-decoration-color: #F8BB00 !important;
text-decoration: underline;
text-underline-offset: 2.5px;
}
.unselected_menu_item {
color: #8C8C8C;
}
slots:
default:
- component: f7-block
config:
style:
flex: 0 0 auto
overflow: scroll
slots:
default:
- component: f7-segmented
config:
style:
flex: 1 1 auto
justify-content: center
margin-left: 2%
margin-right: 2%
slots:
default:
- component: oh-repeater
config:
for: baseMenu
fragment: true
in:
- name: Home
- name: Floors
- name: Rooms
map: loop.baseMenu.name
sourceType: array
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: ="SECTION" + loop.baseMenu_idx
large: true
class: '=vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx ? "selected_menu_item" : "unselected_menu_item"'
style:
font-size: 24px
font-weight: 200
width: 25%
text: =loop.baseMenu
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
justify-content: center
width: 100%
visible: false
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexHome
actionVariableValue: =(vars.buttonIndexHome || 0) - 1
iconF7: chevron_left
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
for: menuArray
fragment: true
sourceType: itemsWithTags
itemTags: Floor
fetchMetadata: widgetOrder
map: loop.menuArray_source
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
for: menuButtonHome
fragment: true
in: =loop.menuArray
filter: loop.menuArray_idx == 0
map: ((loop.menuButtonHome.metadata && loop.menuButtonHome.metadata.widgetOrder && loop.menuButtonHome.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonHome_idx
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].name
style:
flex: 0 0 auto
height: 2em
order: =(((vars.buttonIndexHome || 0) % loop.menuButtonHome_source.length) + loop.menuButtonHome_source.length + loop.menuButtonHome_idx) % loop.menuButtonHome_source.length
#margin-left: 5%
#margin-right: 5%
text: =loop.menuArray[loop.menuButtonHome_source.sort()[loop.menuButtonHome_idx].split('&')[1]].label
- component: oh-button
config:
action: variable
actionVariable: buttonIndexHome
actionVariableValue: =(vars.buttonIndexHome || 0) + 1
iconF7: chevron_right
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
justify-content: center
width: 100%
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION1") ? true : false : false'
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexFloor
actionVariableValue: =(vars.buttonIndexFloor || 0) - 1
iconF7: chevron_left
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
for: menuArray
fragment: true
sourceType: itemsWithTags
itemTags: Floor
fetchMetadata: widgetOrder
map: loop.menuArray_source
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
for: menuButtonFloor
fragment: true
in: =loop.menuArray
filter: loop.menuArray_idx == 0
map: ((loop.menuButtonFloor.metadata && loop.menuButtonFloor.metadata.widgetOrder && loop.menuButtonFloor.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonFloor_idx
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: floor
actionVariableValue: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].name
style:
flex: 0 0 auto
height: 2em
order: =(((vars.buttonIndexFloor || 0) % loop.menuButtonFloor_source.length) + loop.menuButtonFloor_source.length + loop.menuButtonFloor_idx) % loop.menuButtonFloor_source.length
color: '=vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name) ? props.textColor : "gray"'
text-decoration: underline
text-decoration-color: '=vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name) ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split('&')[1]].label
- component: oh-button
config:
action: variable
actionVariable: buttonIndexFloor
actionVariableValue: =(vars.buttonIndexFloor || 0) + 1
iconF7: chevron_right
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
justify-content: center
width: 100%
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION2") ? true : false : false'
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: buttonIndexRoom
actionVariableValue: =(vars.buttonIndexRoom || 0) - 1
iconF7: chevron_left
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: oh-repeater
config:
for: menuArrayRoom
fragment: true
sourceType: itemsWithTags
itemTags: =vars.floor
fetchMetadata: widgetOrder
map: loop.menuArrayRoom_source
slots:
default:
- component: f7-row
config:
style:
display: flex
height: 2em
justify-content: center
overflow: hidden
slots:
default:
- component: oh-repeater
config:
for: menuButtonRoom
fragment: true
in: =loop.menuArrayRoom
filter: loop.menuArrayRoom_idx == 0
map: ((loop.menuButtonRoom.metadata && loop.menuButtonRoom.metadata.widgetOrder && loop.menuButtonRoom.metadata.widgetOrder.value) || 0).toString().padStart(3,'0') + '&' + loop.menuButtonRoom_idx
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: room
actionVariableValue: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].name
style:
flex: 0 0 auto
height: 2em
order: =(((vars.buttonIndexRoom || 0) % loop.menuButtonRoom_source.length) + loop.menuButtonRoom_source.length + loop.menuButtonRoom_idx) % loop.menuButtonRoom_source.length
color: '=vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name) ? props.textColor : "gray"'
text-decoration: underline
text-decoration-color: '=vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name) ? "#F8BB00" : "transparent"'
text-underline-offset: 4px
text: =loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split('&')[1]].label
- component: oh-button
config:
action: variable
actionVariable: buttonIndexRoom
actionVariableValue: =(vars.buttonIndexRoom || 0) + 1
iconF7: chevron_right
style:
color: "#F8BB00"
flex: 0 0 auto
height: 2em
- component: widget:main_widget_Home_Card
config:
locationTitle: =props.locationTitle
scenesGroup: =props.scenesGroup
securityGroup: =props.securityGroup
securityMode: =props.securityMode
referencePIN: =props.referencePIN
- component: widget:main_widget_Floor_Card
- component: widget:main_widget_Room_Card
- component: f7-block
config:
style:
flex: 0 0 auto
overflow: scroll
margin-bottom: -4em
background: =props.bnavColor
border-radius: 0px 0px 10px 10px
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? true : false : false'
slots:
default:
- component: f7-segmented
config:
class:
- segmented-strong
style:
--f7-segmented-strong-between-buttons: 0px
--f7-segmented-strong-bg-color: transparent
--f7-segmented-strong-button-font-weight: 300
--f7-segmented-strong-button-hover-bg-color: rgba(255, 255, 255, 0.15)
--f7-segmented-strong-padding: 0px
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Security
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Security" ? true : false'
icon-f7: shield_fill
iconColor: '=items[props.securityMode].state != "disarmed" ? "red" : "gray"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Security" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Security" ? "black" : "white"'
font-size: 12px
height: auto
text: Security
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Scenes
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Scenes" ? true : false'
icon-f7: rectangle_on_rectangle_angled
iconColor: '=vars.objVar.selectThing=="Scenes" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Scenes" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Scenes" ? "black" : "white"'
font-size: 12px
height: auto
text: Scenes
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Weather
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Weather" ? true : false'
icon-f7: cloud
iconColor: '=vars.objVar.selectThing=="Weather" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Weather" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Weather" ? "black" : "white"'
font-size: 12px
height: auto
text: Weather
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Energy
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Energy" ? true : false'
icon-f7: bolt_fill
iconColor: '=vars.objVar.selectThing=="Energy" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Energy" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Energy" ? "black" : "white"'
font-size: 12px
height: auto
text: Energy
- component: f7-block
config:
style:
flex: 0 0 auto
overflow: scroll
margin-bottom: -4em
background: =props.bnavColor
border-radius: 0px 0px 10px 10px
visible: '=vars.objVar ? (vars.objVar.selectSection=="SECTION0") ? false : true : false'
slots:
default:
- component: f7-segmented
config:
class:
- segmented-strong
style:
--f7-segmented-strong-between-buttons: 0px
--f7-segmented-strong-bg-color: transparent
--f7-segmented-strong-button-font-weight: 300
--f7-segmented-strong-button-hover-bg-color: rgba(255, 255, 255, 0.15)
--f7-segmented-strong-padding: 0px
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Lights
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Lights" ? true : false'
icon-f7: lightbulb_fill
iconColor: '=vars.objVar.selectThing=="Lights" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Lights" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Lights" ? "black" : "white"'
font-size: 12px
height: auto
text: Lights
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Rollers
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Rollers" ? true : false'
icon-f7: archivebox
iconColor: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Rollers" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
font-size: 12px
height: auto
text: Shades
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Climate
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Climate" ? true : false'
icon-f7: snow
iconColor: '=vars.objVar.selectThing=="Climate" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Climate" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Climate" ? "black" : "white"'
font-size: 12px
height: auto
text: Climate
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Appliances
class:
- padding-top-half
- display-flex
- flex-direction-column
fill: '=vars.objVar.selectThing=="Appliances" ? true : false'
iconMaterial: power
iconColor: '=vars.objVar.selectThing=="Appliances" ? "black" : "white"'
iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Appliances" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Appliances" ? "black" : "white"'
font-size: 12px
height: auto
text: Appliances
Thanks @Nic0205, it does solve the issue for now. I have implemented it in my poc and updated github.
There is now tha latest version with fixed bold menu items, white background and since now, reduced space between top menu items.
I have also changed the background for the security card to white (those changes depend on the overall theme dark/light)
Please feel free to test and report back.
It’s not the segmented element that is making the buttons the same width; it’s that the buttons are all defined as having a width of 25% of the segmented element’s overall width. Probably what you’re looking for is to get rid of the width
style and instead add
flex: 1 1 auto
The auto
part of that means "start this element with the width that best fits it’s contents.
Unfortunately, removing width and adding flex: 1 1 auto gives the same result like w had before adding the width part.
I’ve lost track. What problem was that?
this was the old version:
this is the new version with the width tag inserted:
The space between the Menu entries is now “narrower”. But only with the “Width”-trick.
All buttons does still have the same size. In the end we want to have the alignments following Dimitris pattern:
Good job man!
For bottom menu,i think to invert colors: selected buttons=white
Unselected=black
Yes and no - unselected = light gray and selected = white.
@hmerk: I Suggest that I have a look at it while going further with the stylesheet…
@Dimitris: Is the background-color also a light gray or just white? Did not find it in your color scheme:
and: do you have a final one?
Yes please, I can then concentrate on the logic for the floors
OK,
Then the problem that causes the wide spacing is, indirectly, the f7-segmented
component. When a button is inside a segmented component it inherits a width of 100% from the segmented parent. This means that the buttons will try to take up as much space as they can (if the segmented didn’t have no-wrap
set for the flex display, each button would take up the entire width and they would be stacked top-to-bottom instead of side-to-side). Setting the width of the button does fix this, but you don’t want to set it to a fixed value if you want the buttons to each size to their content. Instead you want:
width: auto
which will let the browser set the width. However, once you do that, it doesn’t look like it fixes the problem immediately:
That’s because the segmented is still the full width of the display, and the flexbox spacing is causing the buttons to grow to fill the space. So you also have to set the button not to grow:
flex: 0 1 auto
That’s better. But if we take a detailed look, it still doesn’t quite match Dimitris design exactly: because the buttons actually touch each other instead of there being space which we can see if we temporarily change the background:
With flexbox spacing it’s very easy to make sure that there is space between the elements, we just tell the flex container (in this case the segmented component) to add a gap. Dimitri’s template calls for the same padding width as the gap. The default button padding is 10px so we can start with a gap of 10px:
gap: 10px
If that’s too much space then you can adjust the left- and right- padding and the gap values accordingly.
Put it all together and you get:
- component: f7-segmented
config:
style:
flex: 1 1 auto
justify-content: center
margin-left: 2%
margin-right: 2%
gap: 10px
slots:
default:
- component: oh-repeater
config:
for: baseMenu
fragment: true
in:
- name: Home
- name: Floors
- name: Rooms
map: loop.baseMenu.name
sourceType: array
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: ="SECTION" + loop.baseMenu_idx
large: true
class: '=vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx ? "selected_menu_item" : "unselected_menu_item"'
style:
font-size: 24px
font-weight: 200
flex: 0 1 auto
width: auto
text: =loop.baseMenu
Which results in:
Excellent explained @JustinG, like always
@Nic0205, @Dimitris, i think we are running into some issues with the color scheme.
The version @Nic0205 refered to includes e.g. different background and icon clours based on the scene state.
I tried it, but it is not working.
The card background is read on loading, but cannot be changed dynamically, or I did not find a way how to.
@JustinG Do you have a clever idea ?
Hey @JustinG I am working on putting as much in the stylesheet as it is possible / makes sense.
One extended question to that.
In the bottom navbar we call different styling options, that are not put in the style tag but one level above:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Rollers
class:
- padding-top-half
- display-flex
- flex-direction-column
---> fill: '=vars.objVar.selectThing=="Rollers" ? true : false'
---> icon-f7: archivebox
---> iconColor: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
---> iconSize: 20
style:
--f7-button-bg-color: transparent
--f7-button-border-radius: 15px
--f7-button-hover-bg-color: '=vars.objVar.selectThing=="Rollers" ? "F8BB00" : "transparent"'
--f7-button-padding-horizontal: 0px
--f7-button-padding-vertical: 0px
--f7-button-text-color: '=vars.objVar.selectThing=="Rollers" ? "black" : "white"'
font-size: 12px
height: auto
text: Shades
How could I put the things like fill, icon-f7, iconColor etc. in the stylesheet too?