[OH3] f7-list-item rendering all slots in item-inner / Help understand how slots are processed from yaml to html

I’m trying to recreate the oh-toggle-item using f7-list-item in order to customize the inner content, but I’m running into this issue where all the slots are rendered inside the <div class="item-inner"> instead of the places described in the f7-list-item docs

Compare:

    - component: oh-toggle-item
      config:
        icon: f7:lightbulb
        title: Test Switch
        item: TestSwitch1

renders to

<li class="" icon="f7:lightbulb" item="TestSwitch1">
   <div class="item-content">
      <div class="item-media">
         <i class="icon f7-icons" style="font-size: 32px; width: 32px; height: 32px;">lightbulb</i>
      </div>
      <div class="item-inner">
         <div class="item-title">Test Switch</div>
         <div class="item-after">
            <div>
               <label class="toggle" icon="f7:lightbulb" title="Test Switch" item="TestSwitch1">
                   <input type="checkbox" value="">
                   <span class="toggle-icon"></span>
               </label>
            </div>
         </div>
         <!---->
         <!---->
      </div>
   </div>
</li>

whereas

    - component: f7-list-item
      slots:
        media:
          - component: f7-icon
            config:
              f7: lightbulb
              style:
                # to match oh-icon
                font-size: 32px
                width: 32px
                height: 32px
        default:
          - component: Label
            config:
              text: Test Switch
              class:
                - item-title
        after:
          - component: oh-toggle
            config:
              item: TestSwitch1

renders to

<li class="">
   <div class="item-content">
      <div class="item-inner">
         <i class="icon f7-icons" style="width: 32px; height: 32px; font-size: 32px;">lightbulb</i>
         <label class="toggle" item="TestSwitch1">
             <input type="checkbox" value="">
             <span class="toggle-icon"></span>
         </label>
         <div class="item-title">Test Switch</div>
      </div>
   </div>
</li>

Not only is the icon rendered inside item-inner but the after slot is actually put before the default slot. Using inner-start instead of default does put the title between the icon and toggle, but that only adds to my confusion. Using inner also puts it in the right place, even though that should be the same as default per the f7 docs :thinking:

Am I mistunderstanding how the slots are supposed to work?

I also tried searching the openhab-webui source for the place where the json/yaml is turned into vue components to maybe better understand how it works, but could not find it. Can someone point me to the right place?

I can probably just recreate the whole layout inside the item-inner using custom styles, but I’d really like to understand how this works.

So after some more experimenting, I solved my original issue of wanting to recreate the oh-toggle-item in yaml using a terrible hack.

Posting it here in hopes of invoking Cunningham’s Law

uid: w_list_items_test
props: {}
timestamp: Oct 31, 2021, 9:50:16 AM
component: f7-list
config: {}
slots:
  default:
    - component: oh-repeater
      config:
        for: v
        in:
          - icon: lightbulb
            item: sDeskLamp
            label: Desk Lamp
          - icon: lightbulb
            item: sLavaLamp
            label: Lava Lamp
        fragment: true
      slots:
        default:
          - component: f7-col
            config:
              tag: li
            slots:
              default:
                - component: f7-col
                  config:
                    class:
                      - item-content
                  slots:
                    default:
                      - component: f7-col
                        config:
                          class:
                            - item-media
                        slots:
                          default:
                            - component: f7-icon
                              config:
                                f7: =loop.v.icon
                                style:
                                  font-size: 32px
                                  width: 32px
                                  height: 32px
                      - component: f7-col
                        config:
                          class:
                            - item-inner
                        slots:
                          default:
                            - component: Label
                              config:
                                text: =loop.v.label
                                class:
                                  - item-title
                            - component: f7-col
                              config:
                                class:
                                  - item-after
                              slots:
                                default:
                                  - component: oh-toggle
                                    config:
                                      item: =loop.v.item

Essentially, I recreate the item structure with the icon and toggle in the correct places. Two problems with that:

  1. I need a <li> with content I can fully control
  2. I need a <div> with no styling and content I can fully control (Label apparently only takes text, no children )

I “solved” both of these issues by using f7-col, because it has the handy config value tag and the col class does not seem to do anything on its own so it does not break the layout in any way.

I feel like I’m really missing something here and there’s a much better solution, I just haven’t found it.