Let me check, might need some time.
Hi,
here the code for the stylesheet styled bottom navbar. Reduces code
uid: main_widget_poc
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, 4:06:06 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))
justify-content: space-between
margin: 0
padding: 0
width: 100%
background: =(themeOptions.dark=="light") ? ("white"):("black")
--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.px;
font-weight: bold;
}
.unselected_menu_item {
color: #8C8C8C;
font-weight: 300;
}
.selected_bottom_navbar_item {
color: white;
font-size: 12px;
height: auto;
--f7-button-bg-color: transparent;
}
.unselected_bottom_navbar_item {
color: "#8c8c8c";
font-size: 12px;
height: auto;
--f7-button-bg-color: transparent
}
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
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 && (vars.objVar.selectSection=="SECTION" + loop.baseMenu_idx)) ? "selected_menu_item" : "unselected_menu_item"'
style:
font-size: 24px
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: space-between
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
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
class: '=(vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
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
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
class: '=(vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
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
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
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Lights
class: '=(vars.objVar && (vars.objVar.selectThing=="Lights")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: lightbulb_fill
text: Lights
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Rollers
class: '=(vars.objVar && (vars.objVar.selectThing=="Rollers")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: archivebox
text: Shades
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Climate
class: '=(vars.objVar && (vars.objVar.selectThing=="Climate")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: snow
text: Climate
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Appliances
iconMaterial: power
class: '=(vars.objVar && (vars.objVar.selectThing=="Appliances")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
text: Appliances
Great, thanks !
@ Team. Finally I’m home.
Your poor designer needs some help to enjoy your achievements!
I’m quite sure that i have create a proper semantic model (i see @hmerk laughing out loud…) but I can’t hide the standard OH nav bar. Is there some special code to copy-paste it at page code?
@Nic0205 can you help me Buddy?
Why should I
While developing, I still find issues in my model an fix them. There is alway room for improvement….
Here is the code for the page
config:
label: openPage
sidebar: true
hideNavbar: true
showFullscreenIcon: false
hideSidebarIcon: true
style:
--f7-block-padding-horizontal: 0px
--f7-navbar-height: 0
blocks:
- component: oh-block
config:
stylesheet: |
.block:first-child{
margin-top: 15px;
}
slots:
default:
- component: oh-grid-row
config: {}
slots:
default:
- component: oh-grid-col
config: {}
slots:
default:
- component: widget:main_widget
config:
locationTitle:
scenesGroup:
securityGroup:
securityMode:
referencePIN:
masonry: null
grid: []
@Team, following this discussion
we should overthink the scenes card and make it stateless….
… I forgot to implement the stylesheet for the navbar for the home menu.
Please see updated code:
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, 4:06:06 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))
justify-content: space-between
margin: 0
padding: 0
width: 100%
background: =(themeOptions.dark=="light") ? ("white"):("black")
--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.px;
font-weight: bold;
}
.unselected_menu_item {
color: #8C8C8C;
font-weight: 300;
}
.selected_bottom_navbar_item {
color: white;
font-size: 12px;
height: auto;
--f7-button-bg-color: transparent;
}
.unselected_bottom_navbar_item {
color: "#8c8c8c";
font-size: 12px;
height: auto;
--f7-button-bg-color: transparent
}
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%
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
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
justify-content: space-between
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
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
class: '=(vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
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
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
class: '=(vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
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
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:
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Security
class: '=(vars.objVar && (vars.objVar.selectThing=="Security")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: shield_fill
iconColor: '=items[props.securityMode].state != "disarmed" ? "red" : "gray"'
text: Security
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Scenes
class: '=(vars.objVar && (vars.objVar.selectThing=="Scenes")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: rectangle_on_rectangle_angled
text: Scenes
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Weather
class: '=(vars.objVar && (vars.objVar.selectThing=="Weather")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: cloud
text: Weather
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Energy
class: '=(vars.objVar && (vars.objVar.selectThing=="Energy")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: bolt_fill
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
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Lights
class: '=(vars.objVar && (vars.objVar.selectThing=="Lights")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: lightbulb_fill
text: Lights
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Rollers
class: '=(vars.objVar && (vars.objVar.selectThing=="Rollers")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: archivebox
text: Shades
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Climate
class: '=(vars.objVar && (vars.objVar.selectThing=="Climate")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: snow
text: Climate
- component: oh-button
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Appliances
iconMaterial: power
class: '=(vars.objVar && (vars.objVar.selectThing=="Appliances")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
text: Appliances
@hmerk wow! WOW! It seems like a fully loaded security app!! Definitely many+++ for the OH platform. Now, the “fancy stuff” sticks with your widget!
@JustinG @rlkoshak @hmerk
Dear Gents.
My first approach to design a scene it was a simple card with a ON-OFF switch, showing only which types (from semantic model) participating in the scene.
Having read some of your post (5% I think) and understanding the 10% of 5%, I realized the complexity of a simple scene.
Without having the knowledge, Im trying to put in a card all required functions? /variables? etc. My goal is to design an OH Scene card that would be easy for a user to have the control of the mechanism… As you already understand, i don’t know what exactly I want. In my eyes, the scene now has became a rule.
I cant see the logical issues or problems that this design may have, so I’m asking for help to find out if this is a start to build something or its a not efficient way of thinking.
Dooh,
I like that design, but …
Think we need to talk to better understand what you want, how it should work and then start thinking, if that is possible.
It will be very difficult to sort this out via messages here.
Or, we should postpone the scene implementation for a while, as there are some heavy discussions ongoing around that topic and a first PR is created to implement something in the core…
I agree with hmerk: it’s best to wait on trying to implement scene components.
There’s plenty of other work to do on this at the moment to get a first version ready for release to users. If it first gets released without the ability to work with scenes, that’s fine, it will offer enough other benefits that people will still want to try it. You can always add more functionality, such as scenes, at a later point (once you begin development on a project like this, you’ll never run out of things to do if you’re willing to keep up the commitment).
To answer your question a little bit from a design perspective, I would caution against trying to pack too much into a card. There are definite advantages to having every piece of information about something in one place and this should always be a priority, but that place doesn’t have to be (shouldn’t be) so small that the information is too dense to be usable. If the idea is to make a UI that is convenient, you have to also think about the actual interaction.
Yes, putting all scene information on one card means that it’s only one click away for the user. But if all the components are too small to be reliably targeted with a finger on a phone screen, then that one click turns into 4 or 5 or more just to push the one button of interest (not to mention increasing the chances that one of those clicks triggers an undesired action). If instead, clicking on the small card expands to a card with only the next layer of most useful interactions and a link to a whole configuration page then sometimes there is one extra click for the user, but never a frustrating series of repetitive clicks trying to get one component to function.
@Nic0205
Could you please try and change the bottom tabs from oh-button to oh-link.
This will be needed to add the iconBadges with e.g. information on alarm counter….
Sure, I will have a look…
Understood… Let’s go with the classic on-off switch for scenes.
Εαν κέρδιζες ένα ευρώ γαι κάθε σου απάντηση, θα ήσουν πλούσιος εκτός απο σοφός που ήδη είσαι.
Σε ευχαριστώ Δάσκαλε που στηρίζεις αυτήν την ομάδα!
@Dimitris English please
Google translated to this:
If you earned a euro for every answer you gave, you would be rich in addition to being wise as you already are.
Thank you Master for supporting this team!
Kudos go to @JustinG …
Hi at all,
just following your discussion a while and wanted to start with testing this absolute amazing looking widget.
I tried to install from the marketplace but unfortunately without any success. I get an error in the log as follows:
2022-09-28 20:46:22.692 [ERROR] [munity.CommunityUIWidgetAddonHandler] - Unable to parse YAML: Unrecognized field "blocks" (class org.openhab.core.ui.components.RootUIComponent), not marked as ignorable (7 known properties: "uid", "config", "slots", "timestamp", "tags", "component", "props"])
at [Source: (StringReader); line: 12, column: 3] (through reference chain: org.openhab.core.ui.components.RootUIComponent["blocks"])
2022-09-28 20:46:22.693 [ERROR] [munity.CommunityUIWidgetAddonHandler] - Widget from marketplace is invalid: Unable to parse YAML
I’m running openHAB 3.3.0 Release Build.
Does anyone have an idea what’s might the problem?
Best regards
Stefan
There might be an issue with the timestamp line in the code.
As this will change a lot in the near future, please copy the code and add it manually into your openhab installation.
Hi,
I changed the bottom navbars to oh-link.
For some reason the stylesheet for the unselected items does not have any effect for now. I will have a further look at it tomorrow. Perhaps I simple missed a bracked or something.
@hmerk, @JustinG : if you see something at once why the unselected_bottom_navbar_item
is not interpreted correct - please let me know.
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 28, 2022, 9:54:10 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))
justify-content: space-between
margin: 0
padding: 0
width: 100%
background: =(themeOptions.dark=="light") ? ("white"):("black")
--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.px;
font-weight: bold;
}
.unselected_menu_item {
color: #8C8C8C;
font-weight: 300;
}
.selected_bottom_navbar_item {
color: white;
font-size: 12px;
height: auto;
}
.unselected_bottom_navbar_item {
color: "#8c8c8c";
font-size: 12px;
height: auto;
}
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%
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
- component: f7-row
config:
style:
align-items: center
display: flex
flex-direction: row
flex-wrap: nowrap
height: 2em
width: 100%
flex: 1 1 auto
justify-content: center
margin-left: 2%
margin-right: 2%
gap: 10px
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 1 auto
height: 2em
width: 100%
order: =(((vars.buttonIndexHome || 0) % loop.menuButtonHome_source.length) + loop.menuButtonHome_source.length + loop.menuButtonHome_idx) % loop.menuButtonHome_source.length
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
class: '=(vars.floor ==(loop.menuArray[loop.menuButtonFloor_source.sort()[loop.menuButtonFloor_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
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
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
class: '=(vars.room ==(loop.menuArrayRoom[loop.menuButtonRoom_source.sort()[loop.menuButtonRoom_idx].split("&")[1]].name)) ? "selected_menu_item" : "unselected_menu_item"'
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
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:
style:
display: flex
flex-direction: row
justify-content: space-around
slots:
default:
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Security
class: '=(vars.objVar && (vars.objVar.selectThing=="Security")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: shield_fill
text: Security
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Scenes
class: '=(vars.objVar && (vars.objVar.selectThing=="Scenes")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: rectangle_on_rectangle_angled
text: Scenes
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Weather
class: '=(vars.objVar && (vars.objVar.selectThing=="Weather")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: cloud
text: Weather
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Energy
class: '=(vars.objVar && (vars.objVar.selectThing=="Energy")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: bolt_fill
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:
style:
display: flex
flex-direction: row
justify-content: space-around
slots:
default:
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Lights
class: '=(vars.objVar && (vars.objVar.selectThing=="Lights")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: lightbulb_fill
text: Lights
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Rollers
class: '=(vars.objVar && (vars.objVar.selectThing=="Rollers")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: archivebox
text: Shades
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Climate
class: '=(vars.objVar && (vars.objVar.selectThing=="Climate")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
icon-f7: snow
text: Climate
- component: oh-link
config:
action: variable
actionVariable: objVar
actionVariableValue:
selectSection: =vars.objVar.selectSection
selectThing: Appliances
iconMaterial: power
class: '=(vars.objVar && (vars.objVar.selectThing=="Appliances")) ? "selected_bottom_navbar_item display-flex flex-direction-column padding-top half" : "unselected_bottom_navbar_item display-flex flex-direction-column padding-top half"'
text: Appliances