Add inlinesize property to s-button & programatically show s-modal

Hello, I’m in the process of migrating one of our extensions to the new Polaris web components and I’m currently having difficulty getting buttons to fill up the available space in the layout.

Previously I’d use a stack with the flexChildren property to achieve this but this is no longer available. I noticed that elsewhere an inlineSize property has been added to the button component, can we get this on the component available in POS extensions too?

Or am I missing something, is it currently possible to make a button take up the available space already?

I have another question, how do I programatically show a confirmation modal?

Previously I could display a Dialog / modal using the isVisible property, this is not present on the s-modal component, which means it can only be triggered by a button click by the looks of it?

It’s pretty important that we be able to display a UI blocking modal programmatically.

Hey @simon_b - thanks for flagging this as always!

From what I can tell on my end, you’re right that inlineSize isn’t currently exposed on POS s-button, even though similar button sizing support exists on other Polaris web component surfaces. So at the moment there isn’t a supported one-for-one replacement for the old Stack + flexChildren pattern that makes POS buttons fill the available inline space.

I’m going to pass this up on our end as a POS web components parity / migration gap. I definitely get why this matters when moving existing extensions over to the new components.

For the modal question: s-modal in POS also doesn’t currently have an isVisible prop like the older Dialog/modal pattern. For user-triggered flows, the intended pattern is to render the modal and open it with commandFor / command, for example:

<s-button commandFor="confirm-modal" command="--show">
  Confirm
</s-button>

<s-modal id="confirm-modal" heading="Confirm action">
  <s-text>Are you sure?</s-text>
  <s-button slot="primary-action" commandFor="confirm-modal" command="--hide">
    Continue
  </s-button>
  <s-button slot="secondary-actions" commandFor="confirm-modal" command="--hide">
    Cancel
  </s-button>
</s-modal>

For full-screen POS extension modals, shopify.action.presentModal() is still available, but it needs to be called from a user interaction like a button click or tile tap. It can’t currently be invoked during initialization or from a background/programmatic flow, so a truly programmatic UI-blocking confirmation modal isn’t supported in the same way as before.

I’ll raise both things internally though, Let me know if there’s anything else I can pass on as well or if I can clarify anything here.

No worries thanks @Alan_G much appreciated.

I have a workaround for both of these I think, but they aren’t ideal. For the buttons I can use percentage based inline sizing, and for the modal I can use another page/screen within my extension instead of a modal, modal / dialog would be much more appropriate though.

An example of a situation I used to use the modal for is displaying a warning message for billing purposes if we detect that they have not activated the location they are making a request from. Or presenting a confirmation prompt when the user attempts to add items to a cart that already has items in it, in this situation they would decide to either merge the items or clear the cart first, I’m not sure I can do this now. My extension is targeting pos.home.modal.render.

Hey @simon_b - thanks for the extra context.

For the button sizing piece, I’ve raised this as a POS Polaris web components migration/parity gap since inlineSize would be the cleaner replacement for the old full-width button behaviour.

For the modal piece, happy to raise that too. Just to clarify, you essentially want there to be the ability to have a pop up or something like that to display confirmation prompts/warnings in a modal?

For now, I agree that the separate screen/page approach is still the most reliable workaround, but I’ll pass these examples along on our end. I can’t promise a timeline, but I’ll keep this thread updated if I get more concrete info.

Hi @Alan_G yes it would be great to be able to programmatically display a modal without a user action. I think a nice solution would be a new contextual API on the shopify global object that allowed you to show or hide an s-modal in the DOM based on its id property.

shopify.modal.show("clear-cart");

<s-modal
  id="clear-cart"
  heading="Clear cart?"
>
  There are already items in your cart, would you like to clear the cart?
  <s-button
    slot="primary-action"
    onClick={() => {
      // Clear cart
    }}
  >
    Clear cart
  </s-button>
  <s-button
    slot="secondary-action"
    onClick={() => {
      // Merge cart
    }}
  >
    Leave items in cart
  </s-button>
</s-modal>

It looks like this exists elsewhere in the Polaris ecosystem - Modal API, although I’m not sure if it works without a user action, as I’m yet to migrate any of my admin components to the new Polaris, I hope it does.

Thanks @simon_b - going to reach out to some folks on my end to confirm the current roadmap and see if there’s anything I can share/at the very least pass this on as a feature request, I’ll loop back once I have more info :slight_smile:

No worries, thanks @Alan_G much appreciated.

I actually ended up using the s-empty-state component within an s-page for my modal replacement which actually turned out pretty good in the end.

One nice thing about this approach is that it allowed me to include a “Cancel” button as the secondary action for the “Clear cart” page, previously I couldn’t do this with the modal so the user was kinda locked in after I showed it.

Hey @simon_b - nice, thanks for circling back on that.

That s-empty-state inside an s-page workaround makes sense for the flow you described, especially since it gives you a cleaner Cancel / secondary action path than the modal approach did.

I’m still going to keep the feedback raised on our end, since that workaround solves the immediate UX reasonably well but it’s still not quite the same as having POS support either full-width s-button sizing or a programmatic s-modal show/hide API for confirmation/warning flows.

For now, the separate page/screen approach is for sure the better reliable pattern, and I’ll loop back here if I get anything more concrete to share.

Let me know if anything else comes up while you’re migrating this extension over!

Yeah I think the modal changes are still a good idea, as in my opinion they are fairly limited in their usefulness currently.

In general I like the new approach I think, my main gripe with it is the amount of work required to move my existing extensions over, been at it for two weeks almost :sweat_smile: that’s why I was putting it off, but I took the opportunity to do a bit of a redesign and I’m happy with the results.

One thing I’m not a huge fan of is how you manage the navigation. An app with a decent number of pages requires one huge if / else block to handle it :grimacing: it would be nice if the framework managed more of that for us, perhaps defining routes somewhere in a file instead or something like that.

Another nice to have would be allowing us to add a border radius to the s-image component, the old React image component had this by default, with no option to remove it, but I prefer the softer edges for my use case.

That’s all I can think of for now.

Thanks @simon_b , yeah I definitely get where you’re coming from. I’ve added some extra context to the feature request on my side here, but let me know if I can help out further or add anything else, Thanks again for the flag!