OH3 Widget Developer Tool - f7-row produces incorrect preview and not able to set oh-button width

Hi All

I have been working on a customer widget which includes animated scrolling text with the contents retrieved vi an oh-repeater to get item labels as well as states. These are concatenated and displayed as scrolling text.

After getting the widget fully working using Developer Tools - Widgets, I implemented this on my Overview page and was surprised to find that the Preview from the developer tool did not match the actual display. (examples from a cut down version to debug).

From Widget Developer:
Developer

From Overview Page (Called via Cell)

Called from Cell

My Code is as follows:

uid: Test_Scrolling_Animation_Repeater-FixIssues-2
tags: []
props:
  parameters:
    - context: item
      description: Partition State Group Item
      label: Partition State Group Item
      name: partitionStateGroup
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Dec 29, 2022, 8:43:03 PM
component: f7-page
config: {}
slots:
  default:
    - component: f7-badge
      config:
        style:
          background: rgba(39,26,226,255)
          border-radius: 5px
          display: flex
          height: 90px
          left: 30px
          overflow: hidden
          position: absolute
          top: 5%
          width: 300px
      slots:
        default:
          - component: oh-repeater
            config:
              for: PartitionState
              sourceType: itemsInGroup
              groupItem: =props.partitionStateGroup
              fragment: true
            slots:
              default:
                - component: f7-row
                  config:
                    stylesheet: >
                      .scroll_text {
                        display: block; /* Important to give the content a width */
                        width: 430px;
                        overflow: hidden;
                        position: relative;
                        transform: translateX(200%); /* Animation start out of the screen */
                        /* Add the animation */
                        animation: move 12s linear infinite /* infinite make reapeat the animation indefinitely */;
                      } /* Create the animation */ @keyframes move {
                        to { transform: translateX(-320%); }
                      }                    
                  slots:
                    default:
                      - component: oh-button
                        config:
                          class: scroll_text
                          large: true
                          raised: true
                          style:
                            background: white
                            color: rgba(6,192,232,255)
                            font-size: 30px
                            font-weight: 700
                            left: 300px
                            top: 40px
                            width: 430px
                          text: =loop.PartitionState.label.slice(0, 11) + loop.PartitionState.label.slice(21, 27) +" - " + loop.PartitionState.state

I eventually tracked the issue down to the f7-row component, which I had added in an attempt to fix some alignment issues.
I initially tried to remove the f7-row completely. However I ended up with a weird situation where the setting for the oh-button width were being ignored. Setting positions etc all worked correctly.

So I then replaced f7-row with f7-block (with no other changes) which results in:

Developer Tool:
Developer-block

Called from Cell:
Called from Cell-block

These are equivalent and require only adjustment of the oh-button setting for top: 40px to be adjusted to top: 20px to fix the alignment.

Can anyone explain why the f7-row component would result in this difference between Developer Tool and Actual?

And then why the width setting for the oh-button would only work if the button is inside another container? (Bearing in mind that I cannot use position: absolute as this breaks the animation.

Thanks for the feedback.

There have been a few cases over the years where discrepancies between the widget viewer and the page renders have been noted. It’s not ever easy to ascertain whether the issue is how the rendering is being done or just the way the widget is composed. In this case, I would lean towards the latter.

You have a lot extra styling applied “under the hood” because of the f7 component that you’ve used. Most f7 components are just an html element with a class applied that adds a lot of default css styling (some, like the f7-page, are actually several nested elements). For example, an f7-row is just a <div> element with the row class and an f7-badge is a <span> element with the badge class. When you’re trying to maintain as much control over the display of these elements as you need for this kind of widget, those extra classes can add a lot of css that makes your life more difficult.

There are a couple of solutions that you should investigate before we conclude that the problem is the widget engine.

The first option is to go through the widget and generalize the components more. For example, why is your base component an f7-page? If you don’t have an explicit reason for this then it’s probably better to use an f7-block because the page adds two elements, one div with a page class and a second div with a page-content class. These classes are likely candidates for extra css injection from the overall page once this widget is added to an OH page and that could very well explain the difference you are seeing. Why is the blue background element an f7-badge? This is a very specific component in the f7 library and not really intended for general widget construction. This would be much better as an f7-block or f7-row (the primary different being that because a badge is a <span> and the others are <div> elements you will likely need to add a few additional flex parameters such as flex-wrap to keep everything on one line).

The second option, if you are on the new 3.4 release or recent milestones, is to get rid of the extra f7 class baggage altogether. In newer OH versions, the widget system can accept html elements directly. So if you want complete control without any additional f7 classes added just use:

- component: div

instead of

- component: f7-row

See the docs here for a fuller explanation.

If you replace all the f7 components with generic html elements and you still see a difference between the widget editor and the page view, then we know there’s an issue to address in the widget rendering because the problem cannot be some extra css class stashed somewhere.

1 Like

Thanks Justin for the detailed explanation. I will have to try and digest and process all of the details.

I am not a developer by any means - so make use of the components that look right for what I am trying to achieve (was not aware of the details of the background stuff). But will certainly look at the details and see if I can reduce the complexity and still reproduce the issue.

Do you think this could all also result in the width issue I reported? Some of the complexity is due to the width not working too.

I don’t know. I’d say you’re well on your way.

Absolutely. I haven’t looked into all the different styles in the f7-badge, but they could certainly be interfering with the size of child elements.

As usual you are correct!

Changing the f7-badge to an f7-block fixes the issue with the f7-row difference.

This does introduce some other alignment issues, but I guess that is to be expected. Will work through and see how to address those as well.

The oh-button width is still an issue though. Will keep at it and report back

Much appreciated.

So here is a cut down and simplified as per your advise:

uid: Test_Scrolling_Animation_Repeater-Fix_and_Cleanup
tags: []
props:
  parameters:
    - context: item
      description: Partition State Group Item
      label: Partition State Group Item
      name: partitionStateGroup
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Dec 30, 2022, 7:50:16 PM
component: f7-block
config: {}
slots:
  default:
    - component: f7-block
      config:
        stylesheet: >
          .scroll_text {
            display: block; /* Important to give the content a width */
            width: 500px;
            overflow: hidden;
            position: relative;
            transform: translateX(200%); /* Animation start out of the screen */
            /* Add the animation */
            animation: move 7s linear infinite /* infinite make reapeat the animation indefinitely */;
          } /* Create the animation */ @keyframes move {
            to { transform: translateX(-490%); }
          }        
        style:
          background: rgba(39,26,226,255)
          border-radius: 5px
          display: flex
          height: 90px
          left: 30px
          overflow: hidden
          position: absolute
          top: 5%
          width: 300px
      slots:
        default:
          - component: oh-repeater
            config:
              for: PartitionState
              fragment: true
              groupItem: =props.partitionStateGroup
              sourceType: itemsInGroup
            slots:
              default:
                - component: oh-button
                  config:
                    class: scroll_text
                    large: true
                    raised: true
                    style:
                      background: white
                      color: rgba(6,192,232,255)
                      font-size: 30px
                      font-weight: 700
                      left: 300px
                      top: 40px
                      width: 1430px
                    text: =loop.PartitionState.label.slice(0, 11) + loop.PartitionState.label.slice(21, 27) +" - " + loop.PartitionState.state

On the oh-button

                    font-size: 30px
                    font-weight: 700
                    left: 300px
                    top: 40px

all seem to work, however

                    width: 330px

Only works for very small widths. So does not get wide enough to fit the required text. However when contained in another component the width can be adjusted as required.

Do you have any basic instructions for debugging with the browser console? I see this referred to a lot but I have not managed to get anything useful.

You are putting these button elements inside a container with flexbox styling. Flexbox is specifically for not only aligning but sizing elements in automatic ways. So, without any further directives about what the flexbox should do about the size of the child elements, it’s trying to shrink them down to a minimum acceptable size to get them all to fit inside the container. There’s a flex-box specific solution to this which is the flex style for the child element:

So you would add to your button style something like

flex: 0 0 1430px

and your button will always be that width and will not be allowed to shrink or grow.

There are other, more brute-force ways, such as setting the element’s min-width style. Then even if flexbox needs to shrink the element there will be a width beyond which it is not allowed to shrink any further.

The most useful thing to do with the browser when building widgets such as this is to “inspect” the widget (in chrome that’s just right click on some part of the widget and select the inspect option). This is the Elements portion of the browser development tools that allows you to see all the css impacting any element you select. There are two different helpful windows. The first is the style tab which shows the full css hierarchy so you can see what styles come from where and which are being overridden by other style definitions. The second tab is the computed tab which gives you a list of all the specific styles that are applied and what the final values are.

This is often helpful in diagnosing where the problem lies. Finding the solution, of course, is another story…