Can an oh-toggle-item / list item be rendered correctly below oh-context?

Hello,

I’m trying to simplify a custom MainUI widget in openHAB 5.x.

The widget itself is based on a standard list item, e.g. oh-toggle-item. I would like to use oh-context above it so I can define constants/functions once and reuse them in the list item’s expressions.

A minimal example:

version: 1
widgets:
  test_context_toggle:
    component: oh-context
    config:
      constants:
        test: "'Hello'"
    slots:
      default:
        - component: oh-toggle-item
          config:
            item: Location_Lamp_Switch
            title: Test
            subtitle: =const.test

The problem is that oh-toggle-item no longer renders as a normal list item when placed below oh-context.

By contrast, a plain oh-toggle works correctly below oh-context:

component: oh-context
slots:
  default:
    - component: oh-toggle
      config:
        item: Location_Pendant_Switch

This makes me suspect that list-item components such as oh-toggle-item, oh-label-item, etc. depend on being direct children of a list/list-card context, and that inserting oh-context between the list and the item breaks that rendering context.

The reason I would like to use oh-context is not primarily layout-related. I need to perform a fairly expensive/static lookup once, for example:

_UI[item] -> { i: baseIcon, l: label, r: renderingRule }

and then reuse the result several times in:

title:
icon:
iconColor:
...

Without oh-context, the same long expression has to be repeated for every property.

So the questions are:

  1. Is it expected that oh-toggle-item does not render correctly when it is a child of oh-context?
  2. Is there a supported way to keep oh-toggle-item as a proper list item while still giving it access to const / fn from an oh-context?
  3. Is there another supported mechanism for defining a local reusable variable/constant for the config of a root list-item component?
  4. If not, is repeating the full expression in every property currently the only option?

The intended structure would ideally be something conceptually like:

oh-context
  constants:
    ui: <lookup performed once>

  oh-toggle-item
    title: =const.ui.l
    icon: =const.ui.i
    iconColor: ...

but while still preserving normal list-item rendering inside an oh-location-card / list context.

If useful, I can also provide a minimal reproducer showing the rendering difference between oh-toggle and oh-toggle-item below oh-context.

List items can have context parents just like they can and very often do have repeater parents.

Have you tried testing the widget in a list on a page? I suspect what is happening is just that you are seeing the item rendered incorrectly in the widget editor. Here’s what’s going on.

You are 100% correct that any oh- or f7- “item” component will not render correctly unless it is the child of a list item. This is a feature of the underlying HTML, not the yaml system. Components like the context and repeater don’t add any HTML between the list and the list item, so there’s no problem with having them as parents of the list item components. However, because a list is required to properly render the list items, when your widget starts with a list item and doesn’t also have a list, it should render incorrectly.

This, in fact, used to be the case, and users would have to temporarily put a list at the top of the list item widget while developing it and then remove the list when deploying it. In newer OH versions, the widget editor window now has a little special sauce that detects when you are developing an item widget (because this is a very common use case) and automatically displays it as if it were in a list even when you haven’t added any list type component to the widget.

You are not seeing this correctly, because the root component of your widget is a context instead of an list item. The widget editor window doesn’t recognize that this is a kind of widget is should use its special trick for. Nonetheless, if you save the widget (even though it doesn’t look correct in the widget editor) and add it to a list on a page (or in another widget) it should be rendered correctly. Or, of course, go back to the old trick of putting the list in front during development and removing when you’re done:

oh-context
  constants:
    ui: <lookup performed once>
  oh-list <-- dummy list only while using the widget editor
    mediaList: true
    oh-toggle-item
      title: =const.ui.l
      icon: =const.ui.i
      iconColor: ...

Hello Justin,

of course you right and the oh-context > oh-toggle-item structure renders in real life (the oh-list wrapper helps for the editor, too).

I now have run into a different issue though:

A — current structure

component: oh-context
slots:
default:
- component: oh-toggle-item

In this structure, for example in a oh-location card, a parent Equipment group renders, but looses its caret/accordion capability … is it possible that that capability is linked to the top list item being a oh-toggle-item (or similar), but not an oh-context ?

It’s more obscure than that. oh-x-item having an accordion dropdown depends on the parent of that item having the config parameter accordionList: true. This is, of course, one of the standard properties for an f7- or oh- list, but you can also just add it to other things. So if you add it to the oh-context config, your accordion dropdown will show up in the model cards as well.

IIRC this has been fixed. I don’t remember when, but if you are on a recent enough 5.x version you might not have to do this anymore for the accordions to work in the model cards.

I think the remaining issue is slightly different from the accordionList question.

I’m on openHAB 5.2, so the fixes from #3746 (“Group popup: Enable support for accordion list items”) and #3759 (“Widget editor: Support editing accordion list item widgets”) should already be present.

My setup is:

component: oh-context

config:

  \# constants / functions

slots:

  default:

    - component: oh-toggle-item

      config:

        item: =props.item

This widget is used as the listWidget of a Point inside an Equipment. The custom widget itself renders and toggles correctly, but the Equipment one level above loses its accordion behaviour completely.

With a direct oh-toggle-item as the Point’s list widget, the Equipment accordion works normally, including when that Point is promoted with widgetOrder=0.

So where should this actually be resolved?

Is MainUI attaching the generated Equipment accordion slot/configuration to the root component of the Point’s custom listWidget, meaning it lands on oh-context and never reaches the nested oh-toggle-item?

If that is the case, is there a supported way to forward that incoming Equipment accordion slot through oh-context to the nested oh-toggle-item, while keeping oh-context as the root for reusable constants/functions?

I see. You’re right that is different, and it’s likely related to the changes in the two prs you listed. Whether or not an equipment item needs to have accordion capabilities has been separated out from general list accordion capabilities. So however that check is being made is failing because of the context between the equipment item and the toggle item. I don’t have time right now to look through the code and see if there’s an obvious workaround, but even if a workaround exists, this sounds like it might be worth filing an issue about.