Inline s-stack alignment issue

Once again a proof that Polaris web components are absolute :poop: , why is it not possible to have an inline alignment between a text and an input (text-field, select…) ??

Here i have this code:

<s-stack direction="inline">
    <s-text>
       View By
    </s-text>
    <s-select
        label=""
        value={viewByOption}
        onChange={(e) => setViewByOption(e.currentTarget.value)}
    >
        <s-option value="conversation">
            Conversation 
        </s-option>
        <s-option value="customer">
            Customer
        </s-option>
    </s-select>
</s-stack>

Result of this code:

Expected result:

image

The expected result shown above uses the exact same approach with Polaris React components.

The inline alignment works perfectly between 2 texts or badges for example, but as soon as I put a control as a children of the stack it decides to not be horizontally aligned anymore.

What’s the reasoning behind this? Let me know if I did something wrong.

It states in the documentation for <s-stack>:

* Placing non-form items in rows or columns when sections don't work for your layout.
* Controlling the spacing between elements.
* For form layouts where you need multiple input fields on the same row, use `s-grid` instead.

I assume this is because these components get a flex-grow: 1 or width: 100%.

Options:

  • Wrap your input field in an <s-box>, and give it a specific inlineSize
  • Use the <s-grid> component instead of <s-stack>
  • Wrap the above in an <s-query-container> and you can stack things differently for mobile/desktop

Here are some examples:

https://codepen.io/bkspace/pen/vEKeRpy

The web components do have different ergonomics from the pre-existing library, and I think that’s expected.

1 Like

Our form fields grow to take up any available space so they don’t work well in flex contexts. Grid is your friend here

<s-grid gridTemplateColumns="auto 1fr" gap="base" alignItems="center">
  <s-text aria-hidden>
      View By
  </s-text>
  <s-select
      label="View By"
      labelAccessibilityVisibility="exclusive"
      value={viewByOption}
      onChange={(e) => setViewByOption(e.currentTarget.value)}
  >
      <s-option value="conversation">
          Conversation 
      </s-option>
      <s-option value="customer">
          Customer
      </s-option>
  </s-select>
</s-grid>

Note: Make sure you use a label on your form elements. You can visually hide them with labelAccessibilityVisibility. When you do this it’s best to also hide the visual label with aria-hidden

3 Likes