Shopify's comprehensive admin product component library for React applications with TypeScript support and accessibility features.
—
Modal dialogs, notifications, tooltips, and overlay components for providing user feedback, contextual information, and interactive experiences. These components handle focus management, accessibility, and proper layering.
Modal dialog component for displaying content in an overlay with backdrop, focus trapping, and accessibility features.
/**
* Modal dialog overlay with backdrop and focus management
* @param open - Modal visibility state
* @param onClose - Modal close handler
* @param title - Modal title text
* @param children - Modal content
* @returns JSX element with modal dialog
*/
function Modal(props: ModalProps): JSX.Element;
interface ModalProps extends FooterProps {
/** Whether the modal is open or not */
open: boolean;
/** The url that will be loaded as the content of the modal */
src?: string;
/** The name of the modal content iframe */
iFrameName?: string;
/** The content for the title of the modal */
title: string | React.ReactNode;
/** Hide the title in the modal */
titleHidden?: boolean;
/** The content to display inside modal */
children?: React.ReactNode;
/** Inner content of the footer */
footer?: React.ReactNode;
/** Disable animations and open modal instantly */
instant?: boolean;
/** Automatically adds sections to modal */
sectioned?: boolean;
/** The size of the modal */
size?: ModalSize;
/** Limits modal height on large screens with scrolling */
limitHeight?: boolean;
/** Replaces modal content with a spinner while a background action is being performed */
loading?: boolean;
/** Callback when the modal is closed */
onClose(): void;
/** Callback when iframe has loaded */
onIFrameLoad?(evt: React.SyntheticEvent<HTMLIFrameElement>): void;
/** Callback when modal transition animation has ended */
onTransitionEnd?(): void;
/** Callback when the bottom of the modal content is reached */
onScrolledToBottom?(): void;
/** The element or the RefObject that activates the Modal */
activator?: React.RefObject<HTMLElement> | React.ReactElement;
/** The element type to wrap the activator in */
activatorWrapper?: Element;
/** Removes Scrollable container from the modal content */
noScroll?: boolean;
}
type ModalSize = 'small' | 'large' | 'fullScreen';
interface FooterProps {
primaryAction?: PrimaryAction;
secondaryActions?: SecondaryAction[];
}
interface PrimaryAction {
/** Action content */
content: string;
/** Action callback */
onAction: () => void;
/** Loading state */
loading?: boolean;
/** Disabled state */
disabled?: boolean;
/** Destructive styling */
destructive?: boolean;
}
interface SecondaryAction {
/** Action content */
content: string;
/** Action callback */
onAction: () => void;
/** Loading state */
loading?: boolean;
/** Disabled state */
disabled?: boolean;
/** Destructive styling */
destructive?: boolean;
/** Help text */
helpText?: string;
/** Accessibility label */
accessibilityLabel?: string;
/** Icon */
icon?: IconSource;
}Usage Example:
import React, { useState } from 'react';
import { Modal, Button, TextContainer, Text } from '@shopify/polaris';
function DeleteProductModal() {
const [active, setActive] = useState(false);
const handleClose = () => setActive(false);
const handleOpen = () => setActive(true);
const primaryAction = {
content: 'Delete product',
destructive: true,
onAction: () => {
// Handle delete
handleClose();
},
};
const secondaryActions = [
{
content: 'Cancel',
onAction: handleClose,
},
];
return (
<>
<Button destructive onClick={handleOpen}>
Delete Product
</Button>
<Modal
open={active}
onClose={handleClose}
title="Delete Product"
primaryAction={primaryAction}
secondaryActions={secondaryActions}
>
<Modal.Section>
<TextContainer>
<Text variant="bodyMd">
Are you sure you want to delete this product? This action cannot be undone.
</Text>
</TextContainer>
</Modal.Section>
</Modal>
</>
);
}Important messaging banner component for displaying alerts, notifications, and status information with various tones.
/**
* Important messaging banner with tone and actions
* @param title - Banner title
* @param children - Banner content
* @param tone - Banner tone/color theme
* @param onDismiss - Dismiss handler
* @returns JSX element with banner
*/
function Banner(props: BannerProps): JSX.Element;
interface BannerProps {
/** Banner title */
title?: string;
/** Banner content */
children?: React.ReactNode;
/** Banner tone */
tone?: BannerTone;
/** Primary action */
action?: Action;
/** Secondary action */
secondaryAction?: Action;
/** Dismiss handler */
onDismiss?: () => void;
/** Hide icon */
hideIcon?: boolean;
/** Icon source override */
icon?: IconSource;
/** Stop announcements */
stopAnnouncements?: boolean;
}
/** Banner tone options */
enum BannerTone {
Info = 'info',
Success = 'success',
Warning = 'warning',
Critical = 'critical',
AttentionGrabbing = 'attention-grabbing',
}
interface BannerHandles {
/** Focus the banner */
focus(): void;
}Temporary notification component for brief messages with optional actions and automatic dismissal.
/**
* Temporary notification with automatic dismissal
* @param content - Toast message content
* @param action - Optional action button
* @param duration - Display duration in milliseconds
* @param onDismiss - Dismiss handler
* @returns JSX element with toast notification
*/
function Toast(props: ToastProps): JSX.Element;
interface ToastProps {
/** Toast message content */
content: string;
/** Error state */
error?: boolean;
/** Toast action */
action?: Action;
/** Display duration */
duration?: number;
/** Dismiss handler */
onDismiss(): void;
/** Toast ID */
id?: string;
}Floating content overlay positioned relative to a trigger element with automatic positioning and interaction handling.
/**
* Floating content overlay with positioning
* @param activator - Trigger element
* @param active - Popover visibility state
* @param onClose - Close handler
* @param children - Popover content
* @returns JSX element with popover overlay
*/
function Popover(props: PopoverProps): JSX.Element;
interface PopoverProps {
/** Popover visibility */
active: boolean;
/** Trigger element */
activator: React.ReactNode;
/** Close handler */
onClose: () => void;
/** Popover content */
children?: React.ReactNode;
/** Preferred position */
preferredPosition?: 'above' | 'below' | 'mostSpace';
/** Preferred alignment */
preferredAlignment?: 'left' | 'center' | 'right';
/** Full width */
fullWidth?: boolean;
/** Full height */
fullHeight?: boolean;
/** Prevent autofocus */
preventAutofocus?: boolean;
/** Sectioned content */
sectioned?: boolean;
/** Hide on external click */
hideOnPrint?: boolean;
/** Popover ID */
id?: string;
/** Autofocus target */
autofocusTarget?: PopoverAutofocusTarget;
/** Prevent close on child overlay click */
preventCloseOnChildOverlayClick?: boolean;
/** Capture overflow */
captureOverscroll?: boolean;
/** Fixed position */
fixed?: boolean;
/** Preferred input position */
preferInputActivator?: boolean;
/** Z-index layer */
zIndexOverride?: number;
}
/** Popover autofocus target options */
enum PopoverAutofocusTarget {
Container = 'container',
FirstNode = 'first-node',
None = 'none',
}
/** Popover close source tracking */
enum PopoverCloseSource {
Click = 'click',
EscapeKeypress = 'escape-keypress',
FocusOut = 'focus-out',
ScrollOut = 'scroll-out',
}
interface PopoverPublicAPI {
/** Close the popover */
close: (source?: PopoverCloseSource) => void;
/** Force update position */
forceUpdatePosition: () => void;
}Mobile-friendly modal sheet component that slides up from the bottom of the screen.
/**
* Mobile-friendly modal sheet sliding from bottom
* @param open - Sheet visibility state
* @param onClose - Close handler
* @param children - Sheet content
* @returns JSX element with modal sheet
*/
function Sheet(props: SheetProps): JSX.Element;
interface SheetProps {
/** Sheet visibility */
open: boolean;
/** Close handler */
onClose: () => void;
/** Sheet content */
children: React.ReactNode;
/** Accessibility label */
accessibilityLabel?: string;
/** Prevent closing on backdrop click */
closing?: boolean;
}Hover tooltip component providing contextual information and help text for interactive elements.
/**
* Hover tooltip for contextual information
* @param children - Trigger element
* @param content - Tooltip content
* @param active - Tooltip visibility override
* @returns JSX element with tooltip
*/
function Tooltip(props: TooltipProps): JSX.Element;
interface TooltipProps {
/** Trigger element */
children: React.ReactNode;
/** Tooltip content */
content: React.ReactNode;
/** Manual visibility control */
active?: boolean;
/** Dismiss callback */
onClose?: () => void;
/** Preferred position */
preferredPosition?: 'above' | 'below' | 'mostSpace';
/** Hover delay in milliseconds */
hoverDelay?: number;
/** Dismissible on outside interaction */
dismissOnMouseOut?: boolean;
/** Width constraint */
width?: 'default' | 'wide';
/** Persist on click */
persistOnClick?: boolean;
/** Z-index override */
zIndexOverride?: number;
/** Border radius */
borderRadius?: BorderRadiusScale;
/** Padding override */
padding?: SpaceScale;
/** Has underline for trigger */
hasUnderline?: boolean;
/** Accessibility label */
accessibilityLabel?: string;
}Overlay backdrop component for modals and other overlay content with interaction handling.
/**
* Overlay backdrop for modals and overlays
* @param onClick - Backdrop click handler
* @param transparent - Transparent backdrop
* @returns JSX element with backdrop overlay
*/
function Backdrop(props: BackdropProps): JSX.Element;
interface BackdropProps {
/** Backdrop click handler */
onClick?: () => void;
/** Transparent backdrop */
transparent?: boolean;
/** Background color override */
backgroundColor?: string;
/** Z-index override */
zIndex?: number;
/** Backdrop ID */
id?: string;
}Global loading indicator component for application-wide loading states.
/**
* Global loading indicator
* @param loading - Loading state
* @returns JSX element with loading indicator
*/
function Loading(props: LoadingProps): JSX.Element;
interface LoadingProps {
/** Loading state visibility */
loading?: boolean;
}Loading spinner component with size options for local loading states.
/**
* Loading spinner for local loading states
* @param size - Spinner size
* @param accessibilityLabel - Accessibility label
* @returns JSX element with spinner
*/
function Spinner(props: SpinnerProps): JSX.Element;
interface SpinnerProps {
/** Spinner size */
size?: 'small' | 'large';
/** Accessibility label */
accessibilityLabel?: string;
/** Color override */
color?: 'teal' | 'inkLightest';
/** Focus management */
hasFocusableParent?: boolean;
}Progress indicator bar for showing completion status of tasks and processes.
/**
* Progress indicator bar
* @param progress - Progress percentage (0-100)
* @param size - Progress bar size
* @returns JSX element with progress bar
*/
function ProgressBar(props: ProgressBarProps): JSX.Element;
interface ProgressBarProps {
/** Progress percentage (0-100) */
progress?: number;
/** Progress bar size */
size?: 'small' | 'medium' | 'large';
/** Color tone */
tone?: 'highlight' | 'primary' | 'success' | 'critical';
/** Animated progress */
animated?: boolean;
/** Accessibility label */
ariaLabel?: string;
}Usage Example:
import React, { useState } from 'react';
import {
Banner,
Toast,
Popover,
Button,
ActionList,
Frame
} from '@shopify/polaris';
function FeedbackExample() {
const [toastActive, setToastActive] = useState(false);
const [popoverActive, setPopoverActive] = useState(false);
const toastMarkup = toastActive ? (
<Toast
content="Product saved successfully"
onDismiss={() => setToastActive(false)}
/>
) : null;
const activator = (
<Button
onClick={() => setPopoverActive(!popoverActive)}
disclosure
>
More actions
</Button>
);
return (
<Frame>
<Banner
title="Your store is ready to accept payments"
tone="success"
action={{
content: 'Complete setup',
onAction: () => console.log('Setup clicked'),
}}
onDismiss={() => console.log('Banner dismissed')}
>
<p>Your payment provider has been configured and is ready to process transactions.</p>
</Banner>
<Popover
active={popoverActive}
activator={activator}
onClose={() => setPopoverActive(false)}
>
<ActionList
items={[
{
content: 'Duplicate',
icon: 'duplicate',
onAction: () => console.log('Duplicate'),
},
{
content: 'Archive',
icon: 'archive',
onAction: () => console.log('Archive'),
},
]}
/>
</Popover>
<Button onClick={() => setToastActive(true)}>
Show toast
</Button>
{toastMarkup}
</Frame>
);
}/** Default toast display duration in milliseconds */
const DEFAULT_TOAST_DURATION: number = 5000;
/** Default toast duration when action is present in milliseconds */
const DEFAULT_TOAST_DURATION_WITH_ACTION: number = 10000;/** Icon source type */
type IconSource = React.ComponentType<any> | 'placeholder' | string;
/** Border radius scale for tooltips and overlays */
type BorderRadiusScale = '050' | '100' | '150' | '200' | '300' | '400' | '500' | '750';
/** Space scale for padding and spacing */
type SpaceScale =
| '025' | '050' | '100' | '150' | '200' | '300' | '400' | '500' | '600'
| '800' | '1000' | '1200' | '1600' | '2000' | '2400' | '2800' | '3200';
/** Action interface for feedback components */
interface Action {
/** Action content */
content?: string;
/** Accessibility label */
accessibilityLabel?: string;
/** Action URL */
url?: string;
/** External link */
external?: boolean;
/** Action callback */
onAction?(): void;
}Low-level component for rendering content outside the normal DOM hierarchy, typically used for overlays and modals.
/**
* Renders content outside normal DOM hierarchy
* @param children - Content to render in portal
* @param idPrefix - Prefix for portal container ID
* @param onPortalCreated - Callback when portal is created
* @returns JSX element rendered in portal
*/
function Portal(props: PortalProps): JSX.Element;
interface PortalProps {
/** The content to render inside the portal */
children?: React.ReactNode;
/** The ID prefix for the portal */
idPrefix?: string;
/** Callback when the portal is created */
onPortalCreated?(): void;
}Manager component for coordinating multiple portals and their z-index stacking order.
/**
* Manages multiple portals and their stacking order
* @param children - Content that may create portals
* @returns JSX element with portal management
*/
function PortalsManager(props: PortalsManagerProps): JSX.Element;
interface PortalsManagerProps {
/** The content to wrap with portal management */
children: React.ReactNode;
}Advanced positioning component for overlays that automatically calculates optimal placement relative to an activator element.
/**
* Positions overlay content relative to an activator element
* @param active - Whether overlay is visible
* @param activator - Element that triggers the overlay
* @param children - Overlay content
* @param onClose - Close handler
* @returns JSX element with positioned overlay
*/
function PositionedOverlay(props: PositionedOverlayProps): JSX.Element;
interface PositionedOverlayProps {
/** Whether the overlay is active */
active: boolean;
/** The element that the overlay is positioned relative to */
activator: HTMLElement;
/** The preferred direction to open */
preferredPosition?: 'above' | 'below' | 'mostSpace';
/** The preferred alignment of the overlay */
preferredAlignment?: 'left' | 'center' | 'right';
/** The content of the overlay */
children?: React.ReactNode;
/** Callback when the overlay should be closed */
onClose?(): void;
/** Whether to render the overlay with a fixed position */
fixed?: boolean;
/** The minimum width of the overlay */
minWidth?: number;
/** Whether to render a full width overlay */
fullWidth?: boolean;
/** Whether to render the overlay with full height */
fullHeight?: boolean;
}Save bar that appears when forms have unsaved changes, providing save and discard actions in a prominent banner.
/**
* Save bar for forms with unsaved changes
* @param message - Message about unsaved changes
* @param saveAction - Primary save action
* @param discardAction - Discard changes action
* @returns JSX element with contextual save bar
*/
function ContextualSaveBar(props: ContextualSaveBarProps): JSX.Element;
interface ContextualSaveBarProps {
/** Provide a message about the save bar */
message?: string;
/** Save or commit contextual save bar */
saveAction?: ComplexAction;
/** Discard or cancel contextual save bar */
discardAction?: ComplexAction;
/** Remove the normal max-width on the contextual save bar */
fullWidth?: boolean;
/** Whether the save bar is visible */
visible?: boolean;
}Focus management component for controlling keyboard navigation and programmatic focus behavior.
/**
* Focus management component for keyboard navigation
* @param children - Content to manage focus within
* @param disabled - Whether focus management is disabled
* @returns JSX element with focus management
*/
function Focus(props: FocusProps): JSX.Element;
interface FocusProps {
/** The content to focus */
children?: React.ReactNode;
/** Whether the focus is disabled */
disabled?: boolean;
/** The root element to focus */
root?: HTMLElement;
}Component for declaratively adding event listeners with proper cleanup and React lifecycle integration.
/**
* Declarative event listener with automatic cleanup
* @param event - Event name to listen for
* @param handler - Event handler function
* @param capture - Use capture phase
* @returns JSX element managing event listener
*/
function EventListener(props: EventListenerProps): JSX.Element;
interface EventListenerProps {
/** The event to listen for */
event: string;
/** The handler for the event */
handler(event: Event): void;
/** Whether to capture the event */
capture?: boolean;
/** Whether the listener is passive */
passive?: boolean;
/** Whether the listener should be attached once */
once?: boolean;
}Specialized event listener for keyboard interactions with support for key combinations and modifiers.
/**
* Keyboard event listener with key combination support
* @param keyCode - Key code to listen for
* @param handler - Keypress handler function
* @param keyEvent - Type of key event
* @returns JSX element managing keypress listener
*/
function KeypressListener(props: KeypressListenerProps): JSX.Element;
interface KeypressListenerProps {
/** The key code to listen for */
keyCode: Key;
/** The handler for the keypress */
handler(event: KeyboardEvent): void;
/** The type of key event to listen for */
keyEvent?: 'keydown' | 'keyup';
}Component that prevents body scrolling when active, typically used with modals and overlays.
/**
* Prevents body scrolling when active
* @param children - Content to render while scroll is locked
* @returns JSX element with scroll lock behavior
*/
function ScrollLock(props?: { children?: React.ReactNode }): JSX.Element;Focus trap component that constrains keyboard navigation within its content, essential for modal accessibility.
/**
* Constrains keyboard focus within its content
* @param children - Content to trap focus within
* @param trapping - Whether focus trapping is active
* @returns JSX element with focus trapping
*/
function TrapFocus(props: TrapFocusProps): JSX.Element;
interface TrapFocusProps {
/** Whether to trap focus */
trapping?: boolean;
/** The content to trap focus within */
children?: React.ReactNode;
}Install with Tessl CLI
npx tessl i tessl/npm-shopify--polaris