Using Polaris web components
Polaris web components are Shopify's UI toolkit for building interfaces that match the Shopify Point of Sale design system. This toolkit provides a set of custom HTML elements (web components) that you can use to create consistent, accessible, and performant user interfaces for the POS UI Extensions.
Anchor to stylingStyling
Polaris web components come with built-in styling that follows Shopify's design system. The components will automatically apply the correct styling based on the properties you set and the context in which they are used. For example, headings automatically display at progressively less prominent sizes based on how many levels deep they are nested inside of sections. All components inherit a merchant's brand settings and the CSS cannot be altered or overridden.
Example
JSX
Examples
Example
JSX
<s-box padding="base" background="subdued" border="base" borderRadius="base" class="my-custom-class" > Content </s-box>;
Anchor to custom-layoutCustom layout
When you need to build custom layouts you can use s-stack
and s-box
.
s-stack
do not include spacing between children by default. To apply white space between children use thegap
property- When
s-stack
isdirection="inline"
it will automatically wrap children to a new line when space is limited.
Anchor to scaleScale
Our components use a middle-out scale for multiple properties like padding
, size
and gap
.
Our scale moves from the middle out:
small-300
is smaller thansmall-100
large-300
is bigger thanlarge-100
small-100
andlarge-100
have aliases ofsmall
andlarge
base
is the default value
Example
Examples
Example
Default
export type Scale = | 'small-300' | 'small-200' | 'small-100' | 'small' // alias of small-100 | 'base' | 'large' // alias of large-100 | 'large-100' | 'large-200' | 'large-300';
Anchor to variant-tone-and-colorVariant tone and color
The tone
is used to apply a group of color design tokens to the component such as critical
, success
or info
.
The color
adjusts the intensity of the tone
making it more subdued
or strong
.
The variant
is used to change how the component is rendered to match the design language this is different for each component.
Example
Examples
Example
Default
<s-button tone="critical" variant="primary"> Primary Critical Button </s-button> <s-badge tone="success" color="strong"> Success Strong Badge </s-badge>
Anchor to using-with-preactUsing with Preact
For UI Extensions, Shopify provides Preact as the framework of choice. Using Polaris web components with Preact is very similar to using them with React.
Example
JSX
Examples
Example
JSX
export function ProductExtension() { return ( <s-box padding="base"> <s-stack gap="base"> <s-text>Enable special pricing</s-text> <s-number-field label="Discount percentage" suffix="%" min="0" max="100" /> </s-stack> </s-box> ); }
Anchor to properties-vs-attributesProperties vs attributes
Polaris web components follow the same property and attribute patterns as standard HTML elements. Understanding this distinction is important for using the components effectively.
Anchor to properties-vs-attributes-key-conceptsKey concepts
- Attributes are HTML attributes that appear in the HTML markup.
- Properties are JavaScript object properties accessed directly on the DOM element.
- Most attributes in Polaris web components are reflected as properties, with a few exceptions like
value
andchecked
which follow HTML's standard behavior.
Anchor to properties-vs-attributes-how-jsx-properties-are-appliedHow JSX properties are applied
When using Polaris web components in JSX, the framework determines how to apply your props based on whether the element has a matching property name.
If the element has a property with the exact same name as your prop, the value is set as a property. Otherwise, it's applied as an attribute. Here's how this works in pseudocode:
For Polaris web components, you can generally just use the property names as documented, and everything will work as expected.
Examples
Anchor to handling-eventsHandling events
Handling events in UI extensions are the same as you would handle them in a web app. You can use the method to listen for events on the components or use the
on[event]
property to listen for events from the components.
When using Preact, event handlers can be registered by passing props beginning with on
, and the event handler name is case-insensitive. For example, the JSX registers
fn
as a "click" event listener on the button.
Handling events
JSX
Examples
Handling events
JSX
export default function HandlingEvents() { const handleClick = () => { console.log('s-button clicked'); }; return <s-button onClick={handleClick}>Click me</s-button>; } // or export default function HandlingEvents() { const handleClick = () => { console.log('s-button clicked'); }; const button = document.createElement('s-button'); button.addEventListener('click', handleClick); document.body.appendChild(button); }
Anchor to slotsSlots
Slots allow you to insert custom content into specific areas of Polaris web components. Use the slot
attribute to specify where your content should appear within a component.
Key points:
- Named slots (e.g.,
slot="title"
) place content in designated areas - Multiple elements can share the same slot name
- Elements without a slot attribute go into the default (unnamed) slot
Examples
Banner
Examples
Examples
Banner
<s-banner heading="Order created" status="success"> The order has been created successfully. <s-button slot="primary-action">View order</s-button> </s-banner>;
Anchor to commandsCommands
Commands provide a declarative way for components to control other components without JavaScript. Using the and
command
properties, you can create interactive behaviors directly in your markup.
Key points:
specifies the ID of the target component to control
command
defines the action to perform on the target (e.g.,--toggle
,--show
,--hide
)- Commands work with components that support being controlled (like modals, popovers, and other interactive elements)
- The default command is
--auto
, which performs the most appropriate action for the target component - No JavaScript event handlers are required—the browser handles the interaction automatically
Examples
Commands
Examples
Examples
Commands
<s-box> {/* Modal that will be controlled by the buttons */} <s-modal id="example-modal" heading="Product Details"> <s-text> This modal is controlled using the commands API. No JavaScript event handlers are needed—the browser handles all interactions automatically. </s-text> <s-stack slot="primaryAction"> {/* Button inside modal that can hide it */} <s-button commandFor="example-modal" command="--hide"> Close </s-button> </s-stack> </s-modal> {/* Button controls using different command actions */} <s-stack gap="small"> <s-heading>Modal Controls</s-heading> {/* Toggle button - most common use case */} <s-button commandFor="example-modal" command="--toggle" variant="primary"> Toggle Modal </s-button> {/* Explicit show button */} <s-button commandFor="example-modal" command="--show" tone="success"> Show Modal </s-button> {/* Explicit hide button */} <s-button commandFor="example-modal" command="--hide" tone="critical"> Hide Modal </s-button> {/* Auto command (default) - performs the most appropriate action */} <s-button commandFor="example-modal" command="--auto"> Auto Command (Toggle) </s-button> </s-stack> </s-box>