Hi,
experimenting with my first custom widget set I struggle on a behaviour, I can’t understand right know. Through a combination of widgets I pass a JSON object as configuration for a template I would like to reuse on a few other widgets. Among other things this config contains a description to show different icons on states of a given items.
At first this seems to work like a charm, but every time I toggle the state of one of the three items in this configuration, the list seems to be reduce by one entry and thereby the icons are reduced too.
First “ON” command:
Second “ON” command:
Third “ON” command:
Maybe someone could see something I miss at the moment? Below is my used code and configuration.
uid: card_template
tags: []
props:
parameters:
- label: Header
name: cardLabel
required: false
type: TEXT
groupName: cardConfig
- description: Top-left corner icon
label: Icon
name: cardIcon
required: true
type: TEXT
groupName: cardConfig
- context: page
label: Page to show as a popup
name: cardPopupPage
required: false
type: TEXT
groupName: cardConfig
- context: item
description: Humidity item
label: Humidity item
name: actionItem
required: false
type: TEXT
- label: States
name: stateData
required: false
type: TEXT
groupName: statusConfig
- context: widget
label: Test
name: contentWidget
required: false
type: TEXT
groupName: cwidget
- label: Content widget data
name: contentData
required: false
type: TEXT
groupName: cwidget
- label: Accent color
name: acolor
required: true
type: TEXT
parameterGroups:
- name: cardConfig
description: Card configuration
- name: cardAction
context: action
label: Action
description: Choose your recomended action
- name: statusConfig
description: Status section configuration
- name: cwidget
description: Content Widget
timestamp: Aug 18, 2024, 8:58:48 AM
component: oh-link
config:
style:
--hf-accent-color: =(props.acolor || "var(--f7-theme-color)")
margin: 10px
border-radius: 20px
background-color: white
border: 6px solid var(--hf-accent-color)
box-shadow: rgba(50, 50, 93, 0.25) 0px 10px 16px -4px, rgba(0, 0, 0, 0.3) 0px 7px 11px -7px, inset rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, inset rgba(0, 0, 0, 0.3) 0px 3px 7px -3px
margin-top: 10px
display: grid
grid-template: >
"icon header status" "values values status"
grid-template-columns: 70px calc(100% - 144px) 34px
grid-template-rows: 70px calc(100% - 70px)
column-gap: 20px
white-space: nowrap
opacity: 1 !important
action: popup
actionModal: =props.cardPopupPage
slots:
default:
- component: div
config:
style:
width: 70px
height: 70px
background-color: var(--hf-accent-color)
border: 4px
border-bottom-right-radius: 20px
border-top-left-radius: 13px
grid-area: icon
slots:
default:
- component: div
config:
style:
position: absolute
background-color: transparent
width: 20px
height: 20px
margin-top: 0px
margin-left: 70px
border-top-left-radius: 16px
box-shadow: -5px -5px 0px 0px var(--hf-accent-color)
- component: div
config:
style:
position: absolute
background-color: transparent
width: 20px
height: 20px
margin-top: 70px
margin-left: 0px
border-top-left-radius: 16px
box-shadow: -5px -5px 0px 0px var(--hf-accent-color)
- component: oh-button
config:
style:
width: 52px
height: 52px
margin: 6px
background-color: white
border-radius: 16px
color: var(--hf-accent-color)
display: grid
align-items: center
justify-content: center
opacity: 1 !important
disabled: =(undefined === props.card_actionItem)
actionPropsParameterGroup: cardAction
slots:
default:
- component: oh-icon
config:
icon: =props.cardIcon || ''
style:
height: 34px
width: 34px
- component: div
config:
style:
grid-area: status
background-color: var(--hf-accent-color)
position: relative
color: white
height: 100%
slots:
default:
- component: div
config:
style:
margin-top: 16px
margin-bottom: 16px
margin-left: 6px
display: flex
flex-direction: column
justify-content: space-evenly
gap: 16px
slots:
default:
- component: oh-repeater
config:
for: listitem
fragment: true
sourceType: array
in: =JSON.parse(props.stateData)
slots:
default:
- component: oh-icon
config:
icon: =loop.listitem.states.find((e) => e.state === items[loop.listitem.item].state).icon
style:
height: 28px
width: 100%
visible: =((0 < loop.listitem.states.length) && (items[loop.listitem.item].state) && (undefined !== loop.listitem.states.find((e) => e.state === items[loop.listitem.item].state)))
- component: div
config:
style:
height: 28px
width: 100%
visible: =((0 == loop.listitem.states.length) || (!items[loop.listitem.item].state) || (undefined === loop.listitem.states.find((e) => e.state === items[loop.listitem.item].state)))
- component: div
config:
style:
position: absolute
background-color: transparent
width: 20px
height: 20px
top: 0px
left: -20px
border-top-right-radius: 16px
box-shadow: 5px -5px 0px 0px var(--hf-accent-color)
- component: div
config:
style:
position: absolute
background-color: transparent
width: 20px
height: 20px
bottom: 0px
left: -20px
border-bottom-right-radius: 15px
box-shadow: 5px 5px 0px 0px var(--hf-accent-color)
- component: Label
config:
style:
grid-area: header
width: 100%
color: var(--hf-accent-color)
font-weight: bold
font-size: 24px
text-align: left
vertical-align: middle
line-height: 70px
text: =props.cardLabel || ""
- component: =props.contentWidget
config:
style:
grid-area: values
margin-bottom: 20px
contentData: =props.contentData
uid: card_room
tags: []
props:
parameters:
- description: A text prop
label: Prop 1
name: cardLabel
required: false
type: TEXT
- description: A text prop
label: Prop 1
name: cardIcon
required: true
type: TEXT
- context: page
label: Page to show as a popup
name: cardPopupPage
required: false
type: TEXT
- context: item
description: Toggle item
label: Item to toggle on icon click
name: actionItem
required: false
type: TEXT
- context: item
description: Temprature item
label: Temperature item
name: tempItem
required: false
type: TEXT
- context: item
description: Brightness item
label: Brightness item
name: brightItem
required: false
type: TEXT
- context: item
description: Humidity item
label: Humidity item
name: humItem
required: false
type: TEXT
- context: item
description: Light status item
label: Light status item
name: lightItem
required: false
type: TEXT
- context: item
description: Security status item
label: Security status item
name: securityItem
required: false
type: TEXT
- context: item
description: Occupancy status item
label: Occupancy status item
name: occupancyItem
required: false
type: TEXT
parameterGroups: []
timestamp: Aug 18, 2024, 9:07:29 AM
component: widget:card_template
config:
cardLabel: =props.cardLabel
cardIcon: =props.cardIcon
cardPopupPage: =props.cardPopupPage
card_action: toggle
card_actionCommand: ON
card_actionCommandAlt: OFF
card_actionItem: =props.actionItem
contentWidget: widget:hf_value_row
contentData: ='[{"label":"Temperatur","item":"'+props.tempItem+'"},{"label":"Helligkeit","item":"'+props.brightItem+'"},{"label":"Luftfeuchtigkeit","item":"'+props.humItem+'"}]'
stateData: ='[{"item":"'+props.lightItem+'","states":[{"state":"ON", "icon":"iconify:mdi:lightbulb-on"}]},{"item":"'+props.securityItem+'", "states":[{"state":"ON", "icon":"iconify:mdi:shield-unlocked"}]},{"item":"'+props.occupancyItem+'", "states":[{"state":"ON", "icon":"iconify:mdi:person-circle"}]}]'
uid: hf_value_row
tags: []
props:
parameters:
- label: Values
name: contentData
required: false
type: TEXT
parameterGroups: []
timestamp: Aug 15, 2024, 1:58:48 PM
component: div
config:
style:
grid-area: values
display: flex
flex-direction: row
margin: 10px 0px 16px 16px
gap: 10px
justify-content: space-evenly
flex-wrap: wrap
slots:
default:
- component: oh-repeater
config:
for: listitem
sourceType: array
fragment: true
in: =JSON.parse(props.contentData)
slots:
default:
- component: div
config:
style:
color: props.textColor || var(--hf-accent-color)
display: flex
flex-direction: column
height: 46px
slots:
default:
- component: Label
config:
text: =loop.listitem.label
style:
font-weight: bold
text-align: center
font-size: 14px
- component: Label
config:
style:
padding-top: 4px
text-align: center
font-size: 14px
text: "=('-' === @loop.listitem.item ? '' : @loop.listitem.item)"
Configuration used for testing:
- component: widget:card_room
config:
cardIcon: iconify:mdi:face-male
cardLabel: Zimmer Markus
lightItem: DeckenlampeMarkus
securityItem: DeckenlampeMarkus
occupancyItem: DeckenlampeMarkus
cardPopupPage: page:pageMarkus
card_action: toggle
card_actionItem: DeckenlampeMarkus
card_actionCommand: ON
card_actionCommandAlt: OFF
actionItem: DeckenlampeMarkus