[IGN-10035] Perspective Multi-state Button Left Border Style

So I am in Perspective, and I have multi-state button with a custom style with a light border, for some reason Ignition seems to force a "border-left" in the style

no matter what I do, I end up with the following style applied to all state button, except the first one

"border-left": "1px solid rgb(153, 153, 153)"

Can you post the formatted JSON for the button and the custom style so we can reproduce it?

More importantly, have you examined the button in question in the DOM? In a running browser session, right-click the Multi-State Button, then select Inspect, then select the Elements tab if it isn't already open by default. On the right side of the page, examine the Styles tab to see what styles are applied, why they're applied, and from where they are originating.

Also, which version are you using?

I checked in a browser, but trying to replicate it in a sample project, I have different behavior

Right now, in a sample project, in the element.style, in the button, Ignition add a "margin-right: 4px"
image

"margin-right" was not specified in my original project, but the "border-left" was.
image

So, in my sample project, I tried to set the "margin-right: 100px", but it is, as I suspected, overriden by Ignition, except for the last button in this case
image

Tried the same thing in my original project, but the margin works in this page

Here the json for the multi-state button from my test project, in an empty coordinate container view.

[
  {
    "type": "ia.input.multi-state-button",
    "version": 0,
    "props": {
      "states": [
        {
          "unselectedStyle": {
            "marginRight": "100px",
            "classes": ""
          },
          "text": "0",
          "value": 0,
          "selectedStyle": {
            "classes": ""
          }
        },
        {
          "unselectedStyle": {
            "marginRight": "100px",
            "classes": ""
          },
          "text": "1",
          "value": 1,
          "selectedStyle": {
            "classes": ""
          }
        },
        {
          "unselectedStyle": {
            "marginRight": "100px",
            "classes": ""
          },
          "text": "2",
          "value": 2,
          "selectedStyle": {
            "classes": ""
          }
        },
        {
          "unselectedStyle": {
            "marginRight": "100px",
            "classes": ""
          },
          "text": "3",
          "value": 3,
          "selectedStyle": {
            "classes": ""
          }
        },
        {
          "unselectedStyle": {
            "marginRight": "100px",
            "classes": ""
          },
          "text": "4",
          "value": 4,
          "selectedStyle": {
            "classes": ""
          }
        }
      ],
      "orientation": "row",
      "defaultSelectedStyle": {
        "marginRight": "100px"
      },
      "defaultUnselectedStyle": {
        "marginRight": "100px"
      },
      "primary": true,
      "controlValue": 0,
      "indicatorValue": 0
    },
    "meta": {
      "name": "MultiStateButton"
    },
    "position": {
      "x": 55,
      "y": 45,
      "height": 120,
      "width": 532
    },
    "custom": {
      "random": 5
    },
    "propConfig": {
      "props.states": {
        "binding": {
          "type": "expr",
          "enabled": false,
          "config": {
            "expression": "{this.custom.random}"
          },
          "transforms": [
            {
              "code": "\treturn [{\n\t  \"text\": str(i),\n\t  \"value\": i,\n\t  \"selectedStyle\": { \"classes\": \"\" },\n\t  \"unselectedStyle\": { \"classes\": \"\", \"marginRight\": \"100px\" }\n\t} for i in range(value)]",
              "type": "script"
            }
          ]
        }
      },
      "custom.random": {
        "binding": {
          "type": "expr",
          "enabled": false,
          "config": {
            "expression": "now(10000)"
          },
          "transforms": [
            {
              "code": "\tif self.custom.random == 0:\n\t\treturn 4\n\t\n\treturn 0",
              "type": "script"
            }
          ]
        }
      }
    }
  }
]

Edit: Using Ignition 8.1.35

You're complicating this enough that I'm having trouble following what it is you've provided.

Some clarifications:

  • Inside of element.style in the browser's Developer tools, flex is applied to every button because the buttons need to know how to behave in the flex-y container they reside in. margin-right are settings applied to every button except the last one, and this is how the space between each button is driven; we are telling the browser that every button should reserve 4px between it and the following button. We don't need to do that for the last button. If you didn't see it elsewhere, it's because you inspected the last button instead of any other.
  • Even if you apply marginRight within the styling of a button, Perspective will ignore it because we made a conscious decision in the early stages of Perspective to "hand-hold" a little bit with this component and provide an easy-to-find property which could be used to drive the space between buttons. We named this property buttonGap, and we inject the value of this property into the marginRight CSS property of every button except the last one. This is why the others all use 4, while your last one uses 100.

None of this will really help you with your original problem of applying a border to all buttons of a Multi-State Button because you haven't provided us with a Multi-State Button which has your border settings applied.

2 Likes

Based on your explanation, I don't understand why margin-right works on the one at the botton. Both have the same style applied, but border-left is not working at the bottom, except the first one.
image

This is a single view with both multi state button
TestPLD_2024-06-04_1541.zip (9.2 KB)

Ah, you're running into more hand-holding. When buttonGap<=0, we are hard-coding a border (top while in column orientation, left while in row orientation) with a value of solid #999 1px (rgb(153, 153, 153)). I believe this was done to prevent doubling-down on borders, but it's been so long I can't be sure. As a side-effect, when buttonGap is indeed less than or equal to 0, we don't explicitly write marginRight (or marginBottom) values, and so user-supplied values will be honored.

Best way to avoid all of this is to not use a buttonGap value of 0.

Afterthought:
Right now the consensus is that this logic was placed before 8.0.13 when we did our major "theming" update. Before that release, the buttons would likely not have had the borders they have now, and a buttonGap of 0 would likely have resulted in something that looked like one big glob of a button.

3 Likes

I don't remember setting it to 0, especially as the gap displayed as 4. Any use for buttongap that is not handled by style.gap?

It's very likely that whoever developed that component back in our Perspective infancy was not as proficient or experienced as we are now and didn't think to apply that property.

This is what the Multi-State Button looked like with a buttonGap of 0 in 8.0.11 and WITHOUT the applied border which is causing your issue:

Screenshot 2024-06-04 at 6.24.20 PM

Notice how each button actually has sort of a blue border? That's because our buttons at that time had a blue border. BUT the Multi-State Button "overrode" the blue border by specifying a border of none - effectively making the buttons look like they were hovering due to the shadowbox they also had:

Screenshot 2024-06-04 at 6.25.08 PM

If we had not put the special handling in for a buttonGap of 0, this is what you would have seen at that time:

Screenshot 2024-06-04 at 6.29.49 PM

3 Likes

I opened an internal ticket to see about removing the problematic bit of logic, but it's likely to be a very low priority due to the fact you're the first person to raise the issue since 8.0.13 and we have a LOT to work on for 8.3.

Just stating the behavior in the docs would be enough I think.

Not in this case, because the "expected behavior" is wrong and stems from a time before advanced styling like this was easily applied. Our expectations nowadays are for our code to stay out of the way, and in this scenario our code prevents styling.