Shopify's comprehensive admin product component library for React applications with TypeScript support and accessibility features.
—
Advanced components for displaying, sorting, and managing large datasets with selection, bulk operations, and comprehensive data presentation features. These components are optimized for enterprise-level data management and provide consistent patterns for resource handling.
Sortable data table component for displaying structured data with column headers, row data, and sorting functionality.
/**
* Sortable data table for structured data display
* @param columnContentTypes - Content types for each column
* @param headings - Column header content
* @param rows - Table row data
* @param sortable - Sortable columns configuration
* @returns JSX element with data table
*/
function DataTable(props: DataTableProps): JSX.Element;
interface DataTableProps {
/** Content types for column alignment and formatting */
columnContentTypes: ColumnContentType[];
/** Column header content */
headings: React.ReactNode[];
/** Table row data */
rows: TableRow[];
/** Sortable columns (boolean for each column) */
sortable?: boolean[];
/** Default sort direction */
defaultSortDirection?: SortDirection;
/** Initial sort column index */
initialSortColumnIndex?: number;
/** Sort change handler */
onSort?: (headingIndex: number, direction: SortDirection) => void;
/** Footer content */
footerContent?: TableData;
/** Truncate cell content */
truncate?: boolean;
/** Vertical alignment of cell content */
verticalAlign?: 'top' | 'bottom' | 'middle' | 'baseline';
/** Show totals row */
totals?: TableData[];
/** Show totals in footer */
totalsInFooter?: boolean;
/** Loading state */
loading?: boolean;
/** Empty state content */
emptyState?: React.ReactNode;
/** Increase density */
increasedTableDensity?: boolean;
/** Has zebra striping */
hasZebraStriping?: boolean;
}
/** Column content type for alignment and formatting */
type ColumnContentType = 'text' | 'numeric' | 'date';
/** Table row data array */
type TableRow = TableData[];
/** Individual table cell data */
type TableData = string | number | React.ReactNode;
/** Sort direction enum */
enum SortDirection {
ascending = 'ascending',
descending = 'descending',
}Usage Example:
import React, { useState } from 'react';
import { DataTable, Card, SortDirection } from '@shopify/polaris';
function SalesTable() {
const [sortedRows, setSortedRows] = useState([
['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
['Navy Merino Wool Blazer', '$445.00', 124518, 32, '$14,240.00'],
]);
const columnContentTypes: ColumnContentType[] = [
'text',
'numeric',
'numeric',
'numeric',
'numeric',
];
const headings = [
'Product',
'Price',
'SKU Number',
'Net quantity',
'Net sales',
];
const handleSort = (index: number, direction: SortDirection) => {
const newRows = [...sortedRows].sort((rowA, rowB) => {
const a = rowA[index];
const b = rowB[index];
if (typeof a === 'string' && typeof b === 'string') {
return direction === SortDirection.descending
? b.localeCompare(a)
: a.localeCompare(b);
}
return direction === SortDirection.descending
? (b as number) - (a as number)
: (a as number) - (b as number);
});
setSortedRows(newRows);
};
return (
<Card>
<DataTable
columnContentTypes={columnContentTypes}
headings={headings}
rows={sortedRows}
sortable={[true, true, false, true, true]}
defaultSortDirection={SortDirection.descending}
initialSortColumnIndex={4}
onSort={handleSort}
/>
</Card>
);
}Enhanced data table component specifically designed for resource lists with selection, bulk actions, and advanced data management features.
/**
* Enhanced data table for resource management
* @param resourceName - Resource naming configuration
* @param selectedItemsCount - Count of selected items
* @param onSelectionChange - Selection change handler
* @param bulkActions - Available bulk actions
* @returns JSX element with index table
*/
function IndexTable(props: IndexTableProps): JSX.Element;
interface IndexTableProps extends DataTableProps {
/** Resource naming for accessibility and bulk actions */
resourceName: ResourceName;
/** Number of selected items or 'All' */
selectedItemsCount: number | 'All';
/** Selection change handler */
onSelectionChange: (
selectionType: SelectionType,
isSelecting: boolean,
selection?: string | string[]
) => void;
/** Available bulk actions */
bulkActions?: BulkAction[];
/** Promoted bulk actions */
promotedBulkActions?: BulkAction[];
/** Loading state */
loading?: boolean;
/** Last column sticky */
lastColumnSticky?: boolean;
/** Selection type */
selectionType?: IndexTableSelectionType;
/** Condensed layout */
condensed?: boolean;
/** Flush left content */
flushLeft?: boolean;
}
/**
* Individual index table row
* @param children - Row cell content
* @param id - Row identifier for selection
* @param selected - Row selection state
* @param position - Row position in table
* @returns JSX element with table row
*/
function IndexTableRow(props: IndexTableRowProps): JSX.Element;
interface IndexTableRowProps {
/** Row cell content */
children: React.ReactNode;
/** Unique row identifier */
id: string;
/** Row selection state */
selected?: boolean;
/** Row position for accessibility */
position: number;
/** Disabled selection */
disabled?: boolean;
/** Row click handler */
onClick?: () => void;
/** Row tone/status */
tone?: 'default' | 'subdued' | 'success' | 'warning' | 'critical';
}
/**
* Index table cell component
* @param children - Cell content
* @param className - Additional CSS classes
* @returns JSX element with table cell
*/
function IndexTableCell(props: IndexTableCellProps): JSX.Element;
interface IndexTableCellProps {
/** Cell content */
children?: React.ReactNode;
/** Additional CSS class names */
className?: string;
/** Flush content left */
flush?: boolean;
}
interface ResourceName {
/** Singular resource name */
singular: string;
/** Plural resource name */
plural: string;
}
interface BulkAction extends Action {
/** Action type */
type?: 'default' | 'destructive';
/** Action icon */
icon?: IconSource;
}
enum IndexTableSelectionType {
All = 'all',
Page = 'page',
Multiple = 'multiple',
Single = 'single',
}
enum SelectionType {
All = 'all',
Page = 'page',
Range = 'range',
Single = 'single',
}List component for displaying resources with filtering, sorting, selection, and item-level actions.
/**
* List of resources with selection and filtering
* @param resourceName - Resource naming configuration
* @param items - Resource items to display
* @param renderItem - Item rendering function
* @returns JSX element with resource list
*/
function ResourceList<T>(props: ResourceListProps<T>): JSX.Element;
interface ResourceListProps<T> {
/** Resource naming */
resourceName: ResourceName;
/** Resource items array */
items: T[];
/** Item rendering function */
renderItem: (item: T, id: string, index: number) => React.ReactNode;
/** Selected item IDs */
selectedItems?: string[];
/** Selection change handler */
onSelectionChange?: (selectedIds: string[]) => void;
/** Bulk actions for selected items */
bulkActions?: BulkAction[];
/** Promoted bulk actions */
promotedBulkActions?: BulkAction[];
/** Loading state */
loading?: boolean;
/** Show header */
showHeader?: boolean;
/** Total item count */
totalItemsCount?: number;
/** Sort options */
sortOptions?: SortOption[];
/** Current sort value */
sortValue?: string;
/** Sort change handler */
onSortChange?: (selected: string) => void;
/** Filter control */
filterControl?: React.ReactNode;
/** Alternate tool */
alternateTool?: React.ReactNode;
/** Empty state */
emptyState?: React.ReactNode;
/** Item ID resolver */
idForItem?: (item: T, index: number) => string;
/** Resolve item ID callback */
resolveItemId?: (item: T) => string;
}
interface SortOption {
/** Option label */
label: string;
/** Option value */
value: string;
/** Sort direction */
directionLabel: string;
}Individual resource item component for display within ResourceList with actions and media.
/**
* Individual resource item with actions and media
* @param id - Resource item ID
* @param children - Item content
* @param url - Item navigation URL
* @param media - Item media content
* @returns JSX element with resource item
*/
function ResourceItem(props: ResourceItemProps): JSX.Element;
interface ResourceItemProps {
/** Unique resource identifier */
id: string;
/** Item content */
children?: React.ReactNode;
/** Navigation URL */
url?: string;
/** Media content (avatar, thumbnail, etc.) */
media?: React.ReactNode;
/** Shortcut actions */
shortcutActions?: DisableableAction[];
/** Persistent actions */
persistActions?: boolean;
/** Item accessibility label */
accessibilityLabel?: string;
/** Item name */
name?: string;
/** onClick handler */
onClick?: (id?: string) => void;
/** Vertical alignment */
verticalAlignment?: 'leading' | 'trailing' | 'center' | 'fill' | 'baseline';
}Simple list component for displaying content items with consistent styling and spacing.
/**
* Simple content list component
* @param children - List items
* @param type - List type styling
* @returns JSX element with list
*/
function List(props: ListProps): JSX.Element;
interface ListProps {
/** List items */
children?: React.ReactNode;
/** List type */
type?: 'bullet' | 'number';
/** Gap between items */
gap?: 'extraTight' | 'tight' | 'loose';
}
/**
* Individual list item
* @param children - Item content
* @returns JSX element with list item
*/
function ListItem(props: ListItemProps): JSX.Element;
interface ListItemProps {
/** Item content */
children?: React.ReactNode;
}Key-value description lists for displaying structured information with consistent formatting.
/**
* Key-value description list
* @param items - Description items
* @param spacing - Spacing between items
* @returns JSX element with description list
*/
function DescriptionList(props: DescriptionListProps): JSX.Element;
interface DescriptionListProps {
/** Description items */
items: DescriptionListItem[];
/** Spacing between items */
spacing?: 'tight' | 'loose';
}
interface DescriptionListItem {
/** Item term/key */
term: React.ReactNode;
/** Item description/value */
description: React.ReactNode;
}/** Constant for selecting all items in IndexTable */
const INDEX_TABLE_SELECT_ALL_ITEMS = 'SELECT_ALL_ITEMS';
/**
* Hook for managing resource selection state
* @param resources - Array of resources
* @param options - Configuration options
* @returns Resource state management object
*/
function useIndexResourceState<T>(
resources: T[],
options?: IndexResourceStateOptions<T>
): IndexResourceState<T>;
interface IndexResourceStateOptions<T> {
/** Resource ID resolver */
resourceIDResolver?: (resource: T) => string;
/** Initial selected resources */
resourceFilter?: (resource: T) => boolean;
}
interface IndexResourceState<T> {
/** Currently selected resource IDs */
selectedResources: string[];
/** All resources selected */
allResourcesSelected: boolean;
/** Handle resource selection change */
handleSelectionChange: (
selectionType: SelectionType,
isSelecting: boolean,
selection?: string | string[]
) => void;
/** Clear all selection */
clearSelection: () => void;
/** Remove selected resources */
removeSelectedResources: (removeResources: string[]) => void;
}interface DisableableAction extends Action {
/** Disabled state */
disabled?: boolean;
}
type IconSource = React.ComponentType<any> | 'placeholder' | string;
interface PaginationDescriptor {
/** Has previous page */
hasPrevious?: boolean;
/** Previous page handler */
onPrevious?: () => void;
/** Has next page */
hasNext?: boolean;
/** Next page handler */
onNext?: () => void;
/** Pagination label */
label: string;
}Specialized empty state component for search results that provides clear messaging and helpful actions when no search results are found.
/**
* Empty state component for search results
* @param title - Main message for empty search
* @param description - Additional context about the empty search
* @param withIllustration - Whether to show search illustration
* @returns JSX element with empty search result display
*/
function EmptySearchResult(props: EmptySearchResultProps): JSX.Element;
interface EmptySearchResultProps {
/** Give the empty state a title */
title: string;
/** Give the empty state a description */
description?: string;
/** Whether or not to show the border */
withIllustration?: boolean;
}General purpose empty state component for when content is unavailable, with customizable illustration, title, and action buttons.
/**
* Empty state component for missing content
* @param heading - Main heading for empty state
* @param children - Content and actions for empty state
* @param image - Custom image or illustration
* @returns JSX element with empty state display
*/
function EmptyState(props: EmptyStateProps): JSX.Element;
interface EmptyStateProps {
/** The empty state heading */
heading?: string;
/** The path to the image to display */
image?: string;
/** Elements to display inside empty state */
children?: React.ReactNode;
/** Action for empty state */
action?: ComplexAction;
/** Secondary action for empty state */
secondaryAction?: ComplexAction;
/** Footer help text for empty state */
footerContent?: React.ReactNode;
/** Whether or not to limit the image to the size of its container. */
imageContained?: boolean;
/** Whether or not to show the border */
withIllustration?: boolean;
}Component for displaying a list of exceptions, warnings, or errors with consistent formatting and appropriate visual hierarchy.
/**
* List component for displaying exceptions and errors
* @param items - Array of exception items to display
* @returns JSX element with formatted exception list
*/
function ExceptionList(props: ExceptionListProps): JSX.Element;
interface ExceptionListProps {
/** Collection of exceptions to render */
items: {
/** Icon to display with the item */
icon?: IconSource;
/** Item title */
title?: string;
/** Item description */
description: string;
/** Truncate content */
truncate?: boolean;
}[];
}Container component that groups related information and actions with consistent padding, borders, and visual hierarchy.
/**
* Container component for grouping related content
* @param children - Content to display in the card
* @param title - Card title
* @param sectioned - Whether to add default padding to content
* @returns JSX element with card container
*/
function Card(props: CardProps): JSX.Element;
interface CardProps {
/** Title content for the card */
title?: React.ReactNode;
/** Card header actions */
actions?: ActionListItemDescriptor[];
/** Auto wrap content in padding */
sectioned?: boolean;
/** Card content */
children?: React.ReactNode;
/** A less prominent card */
subdued?: boolean;
/** Size of the card */
size?: 'medium' | 'small';
/** Background color of the card */
background?: string;
/** Padding around the card */
padding?: SpaceScale;
/** Border radius of the card */
borderRadius?: BorderRadiusScale;
}Specialized card component for highlighting important information, announcements, or calls-to-action with visual emphasis.
/**
* Card component for important announcements and calls to action
* @param title - Card title
* @param children - Card content
* @param primaryAction - Main action button
* @returns JSX element with callout card
*/
function CalloutCard(props: CalloutCardProps): JSX.Element;
interface CalloutCardProps {
/** The content to display inside the callout card. */
children: React.ReactNode;
/** The callout card's title. */
title: React.ReactNode;
/** URL to the card illustration. */
illustration?: string;
/** Primary action for the card */
primaryAction?: ComplexAction;
/** Secondary action for the card */
secondaryAction?: ComplexAction;
/** Callback when the dismiss button is clicked */
onDismiss?(): void;
}Layout component that visually connects related form fields and controls, typically used for input groups and compound controls.
/**
* Layout component for visually connecting related form elements
* @param children - Form elements to connect
* @param left - Content to display on the left
* @param right - Content to display on the right
* @returns JSX element with connected form layout
*/
function Connected(props: ConnectedProps): JSX.Element;
interface ConnectedProps {
/** Components to connect together */
children: React.ReactNode;
/** Content to display to the left of the connected children */
left?: React.ReactNode;
/** Content to display to the right of the connected children */
right?: React.ReactNode;
}Expandable content container that shows/hides content with smooth animations, commonly used for progressive disclosure.
/**
* Expandable content container with smooth animations
* @param open - Whether content is expanded
* @param children - Content to show/hide
* @param onToggle - Expand/collapse handler
* @returns JSX element with collapsible content
*/
function Collapsible(props: CollapsibleProps): JSX.Element;
interface CollapsibleProps {
/** Assign a unique ID to the collapsible's content */
id: string;
/** Toggle whether the collapsible is expanded or not */
open: boolean;
/** The content to display inside the collapsible */
children: React.ReactNode;
/** Callback when the collapsible is toggled */
onToggle?(): void;
/** Transition timing function for the collapsible */
transition?: {
duration?: string;
timingFunction?: string;
};
}Legacy card component for backward compatibility with older card implementations and styling.
/**
* Legacy card component for backward compatibility
* @param title - Card title
* @param sectioned - Whether to add section styling
* @param children - Card content
* @returns JSX element with legacy card styling
*/
function LegacyCard(props: LegacyCardProps): JSX.Element;
interface LegacyCardProps {
/** The title content for the card */
title?: React.ReactNode;
/** Card header actions */
actions?: ComplexAction[];
/** Auto wrap content in section */
sectioned?: boolean;
/** Card content */
children?: React.ReactNode;
/** A less prominent card */
subdued?: boolean;
/** Footer content for the card */
footerActionAlignment?: 'right' | 'left';
/** Primary footer action */
primaryFooterAction?: ComplexAction;
/** Secondary footer actions */
secondaryFooterActions?: ComplexAction[];
}
interface LegacyCardSectionProps {
/** Section title */
title?: React.ReactNode;
/** Section content */
children?: React.ReactNode;
/** Whether the section is subdued */
subdued?: boolean;
/** Whether the section is flush with card edges */
flush?: boolean;
/** Whether the section fills available height */
fullHeight?: boolean;
}
interface LegacyCardHeaderProps {
/** Header actions */
actions?: ComplexAction[];
/** Header title */
title?: React.ReactNode;
}
interface LegacyCardSubsectionProps {
/** Subsection content */
children?: React.ReactNode;
}Legacy filtering component for backward compatibility with older filter implementations.
/**
* Legacy filters component for backward compatibility
* @param filters - Available filter options
* @param appliedFilters - Currently applied filters
* @param onFiltersChange - Filter change handler
* @returns JSX element with legacy filtering interface
*/
function LegacyFilters(props: LegacyFiltersProps): JSX.Element;
interface LegacyFiltersProps {
/** Available filters */
filters?: FilterInterface[];
/** Applied filters */
appliedFilters?: AppliedFilterInterface[];
/** Query value */
queryValue?: string;
/** Query placeholder */
queryPlaceholder?: string;
/** Whether query field is focused */
focused?: boolean;
/** Additional search field filters */
searchFieldFilters?: React.ReactNode;
/** Disable query field */
disabled?: boolean;
/** Hide query field */
hideQueryField?: boolean;
/** Callback when query changes */
onQueryChange?(queryValue: string): void;
/** Callback when query is cleared */
onQueryClear?(): void;
/** Callback when query is focused */
onQueryFocus?(): void;
/** Callback when query is blurred */
onQueryBlur?(): void;
/** Callback when filters change */
onFiltersChange?(appliedFilters: AppliedFilterInterface[]): void;
/** Callback when all filters are cleared */
onClearAll?(): void;
}Alpha/experimental picker component for selecting from a list of options with advanced features.
/**
* Alpha picker component for advanced option selection
* @param items - Available picker items
* @param selected - Currently selected items
* @param onSelect - Selection change handler
* @returns JSX element with picker interface
*/
function Picker(props: PickerProps): JSX.Element;
interface PickerProps {
/** Items to choose from */
items: PickerItem[];
/** Currently selected items */
selected: string[];
/** Allow multiple selection */
allowMultiple?: boolean;
/** Callback when selection changes */
onSelect(selected: string[]): void;
/** Whether picker is disabled */
disabled?: boolean;
/** Loading state */
loading?: boolean;
/** Error message */
error?: string;
/** Help text */
helpText?: string;
}
interface PickerItem {
/** Unique identifier */
value: string;
/** Display label */
label: string;
/** Whether item is disabled */
disabled?: boolean;
/** Item description */
description?: string;
}Experimental bulk actions component for managing operations on multiple selected items.
/**
* Experimental bulk actions for multiple item operations
* @param actions - Available bulk actions
* @param selected - Number of selected items
* @param onAction - Action handler
* @returns JSX element with bulk action interface
*/
function BulkActions(props: BulkActionsProps): JSX.Element;
interface BulkActionsProps {
/** Label for the bulk actions */
label?: string;
/** Actions available for bulk operations */
actions?: ActionListItemDescriptor[];
/** Promotional bulk actions */
promotedActions?: ActionListItemDescriptor[];
/** Callback when all items are selected */
onToggleAll?(): void;
/** Whether all items are selected */
selectMode?: boolean;
/** Whether to show the select mode toggle */
onSelectModeToggle?(): void;
/** Accessibility label for selected items */
accessibilityLabel?: string;
}Install with Tessl CLI
npx tessl i tessl/npm-shopify--polaris