Passing CSS into custom widgets

I am struggling to understand something here. I have a custom group toggle widget that shows an intermediate state if not all member items are ON or OFF. See here. The widget is built in an `f7- card because I presume I need to have the three buttons it is made up of in some form of container. It works fine if on its own in a page in another card.

However I am trying to use it inside another custom widget, my accordion list, which works fine with regular oh-toggle components but will not work with my custom toggle. It seems to be that the custom toggle is ignoring CSS either contained in the widget or that I am trying to apply to the widget from the parent widget.

The parent widget is here

uid: Expanding_List_Props
tags: []
props:
  parameters:
    - description: Display name of the top group
      label: Top group name
      name: groupname
      required: false
      type: TEXT
    - context: item
      description: Top group
      label: Whole house
      name: groupItem
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Jan 28, 2024, 7:20:04 PM
component: f7-block
config:
  title: Accordion Repeater
slots:
  default:
    - component: oh-list
      config:
        accordionList: true
        virtualList: true
      slots:
        default:
          - component: f7-list-item
            config:
              accordionItem: true
              style:
                margin-left: 40px
                width: calc(100% - 40px)
              title: =[props.groupname]
            slots:
              default:
                - component: f7-accordion-content
                  slots:
                    default:
                      - component: oh-list
                        config:
                          virtualList: true
                        slots:
                          default:
                            - component: oh-repeater
                              config:
                                accordionList: true
                                fetchMetadata: widgetOrder
                                for: floor
                                fragment: false
                                groupItem: =[props.groupItem]
                                sourceType: itemsInGroup
                              slots:
                                default:
                                  - component: f7-list-item
                                    config:
                                      accordionItem: true
                                      style:
                                        margin-left: 50px
                                        width: calc(100% - 50px)
                                      title: =loop.floor.label
                                    slots:
                                      default:
                                        - component: f7-accordion-content
                                          slots:
                                            default:
                                              - component: oh-list
                                                slots:
                                                  default:
                                                    - component: oh-repeater
                                                      config:
                                                        fetchMetadata: widgetOrder
                                                        for: room
                                                        groupItem: =loop.floor.name
                                                        sourceType: itemsInGroup
                                                      slots:
                                                        default:
                                                          - component: f7-list-item
                                                            config:
                                                              style:
                                                                margin-left: 50px
                                                                margin-right: 0px
                                                                width: calc(100% - 50px)
                                                              title: =loop.room.label
                                                            slots:
                                                              root-start:
                                                                - component: oh-toggle
                                                                  config:
                                                                    item: =loop.room.name
                                                                    style:
                                                                      left: -35px
                                                                      position: absolute
                                                                      top: 6px
                                      root-start:
                                        - component: oh-toggle
                                          config:
                                            item: =loop.floor.name
                                            style:
                                              left: -35px
                                              position: absolute
                                              top: 6px
              root-start:
                - component: oh-toggle
                  config:
                    item: UI_All
                    style:
                      left: -35px
                      position: absolute
                      top: 6px

The toggles go in the root-start slots and work fine if they are regular oh-toggle components. If I replace oh-toggle with widget:GroupToggle then the positioning is all off and nothing I do to the style: properties makes any difference. If I am using a regular oh- component or an f7 component I can override the style properties easily.

I’d be very grateful if someone could point out where I am going wrong.

Right now there is nothing in your 3-way toggle that accepts the style property. When you are configuring a custom widget all of the config options get passed to the widget as the widget props (which is why in when you configure your 3-way toggle your item config becomes props.item which you then use in the 3-way toggle expressions).

The style configuration, in this case, is no different. It will be passed to the custom widget as props.style and you have no expression in your custom widget that includes a props.style.

You can look at this widget for an example:

In your case, you have an easy solution because the root container in your 3-way toggle doesn’t have any style parameter already in use and that’s where you would want these styles to be applied anyway:

component: f7-row
config:
  style: =props.style

You don’t even have to add the style property to the parameter list at the top if you don’t want to. That only determines how the properties are displayed in the configuration wizard that pops up when you use UI configuration for the widget. But, you cannot create the style object in that manner anyway so this only works when configuration is in an editor like your current use case.

Awesome! Again Justin, many thanks. I am learning fast but this would be so much harder without your valuable input. I hadn’t spotted from the docs that you can just style a regular component but not one made up of a custom widget.

I scratched my head for a second or two because I have lots of style properties in the custom widget relating to the f7 block that contains its components, some of which are calculated CSS variables, but I need to pass two from the parent widget. I can do that by using

config:
  style:
    position: absolute
    left: =props.style.left
    top: =props.style.top
    ...
    --widgetHeight: calc(var(--widgetWidth) / var(--widthHeightRatio))
    ...
    etc

The combination of my accordion list toggle widget incorporating my 3-way toggles now looks like this, which is exactly what I was going for. Many many thanks.

Screenshot 2024-02-17 at 14-15-13 openHAB

1 Like