or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions-buttons.mdcore-application.mddata-display.mdfeedback-overlays.mdform-components.mdindex.mdlayout-utilities.mdmedia-icons.mdnavigation.mdtypes-interfaces.mdutilities-hooks.md

actions-buttons.mddocs/

0

# Actions & Button Components

1

2

Button variants, action lists, and interactive components for user actions and commands. These components provide consistent interaction patterns, accessibility features, and visual feedback for all user-initiated actions.

3

4

## Capabilities

5

6

### Button

7

8

Primary button component with multiple variants, sizes, tones, and interaction states for triggering actions.

9

10

```typescript { .api }

11

/**

12

* Primary button component for triggering actions

13

* @param children - Button content/label

14

* @param onClick - Button click handler

15

* @param variant - Button visual variant

16

* @param size - Button size

17

* @returns JSX element with button

18

*/

19

function Button(props: ButtonProps): JSX.Element;

20

21

interface ButtonProps extends BaseButton {

22

/** The content to display inside the button */

23

children?: string | string[];

24

/** Changes the size of the button, giving it more or less padding */

25

size?: 'micro' | 'slim' | 'medium' | 'large';

26

/** Changes the inner text alignment of the button */

27

textAlign?: 'left' | 'right' | 'center' | 'start' | 'end';

28

/** Allows the button to grow to the width of its container */

29

fullWidth?: boolean;

30

/** Displays the button with a disclosure icon. Defaults to down when set to true */

31

disclosure?: 'down' | 'up' | 'select' | boolean;

32

/** Icon to display to the left of the button content */

33

icon?: React.ReactElement | IconSource;

34

/** Indicates whether or not the button is the primary navigation link when rendered inside of an IndexTable.Row */

35

dataPrimaryLink?: boolean;

36

/** Sets the color treatment of the Button */

37

tone?: 'critical' | 'success';

38

/** Changes the visual appearance of the Button */

39

variant?: 'plain' | 'primary' | 'secondary' | 'tertiary' | 'monochromePlain';

40

/** Button ID */

41

id?: string;

42

/** Accessibility label */

43

accessibilityLabel?: string;

44

/** ARIA describedby */

45

ariaDescribedBy?: string;

46

/** ARIA expanded state */

47

ariaExpanded?: boolean;

48

/** ARIA controls */

49

ariaControls?: string;

50

/** Button role */

51

role?: string;

52

/** Tab index */

53

tabIndex?: number;

54

/** Submit button type */

55

submit?: boolean;

56

/** Button URL for link behavior */

57

url?: string;

58

/** External link */

59

external?: boolean;

60

/** Download attribute */

61

download?: string | boolean;

62

/** Link target */

63

target?: string;

64

/** Button pressed state */

65

pressed?: boolean;

66

/** Removes underline from button text (including on interaction) @deprecated Use a variant instead */

67

removeUnderline?: boolean;

68

/** Connector top */

69

connectedTop?: boolean;

70

/** Connector bottom */

71

connectedBottom?: boolean;

72

/** Connector left */

73

connectedLeft?: boolean;

74

/** Connector right */

75

connectedRight?: boolean;

76

/** Focus event handler */

77

onFocus?: () => void;

78

/** Blur event handler */

79

onBlur?: () => void;

80

/** Key down handler */

81

onKeyDown?: (event: React.KeyboardEvent) => void;

82

/** Key press handler */

83

onKeyPress?: (event: React.KeyboardEvent) => void;

84

/** Key up handler */

85

onKeyUp?: (event: React.KeyboardEvent) => void;

86

/** Mouse enter handler */

87

onMouseEnter?: () => void;

88

/** Touch start handler */

89

onTouchStart?: () => void;

90

}

91

```

92

93

**Usage Example:**

94

95

```typescript

96

import React, { useState } from 'react';

97

import { Button, ButtonGroup, InlineStack } from '@shopify/polaris';

98

99

function ButtonExamples() {

100

const [loading, setLoading] = useState(false);

101

102

const handleSave = async () => {

103

setLoading(true);

104

// Simulate API call

105

await new Promise(resolve => setTimeout(resolve, 2000));

106

setLoading(false);

107

};

108

109

return (

110

<InlineStack gap="400">

111

{/* Primary actions */}

112

<Button

113

variant="primary"

114

onClick={handleSave}

115

loading={loading}

116

>

117

Save product

118

</Button>

119

120

{/* Secondary actions */}

121

<Button variant="secondary" tone="critical">

122

Delete

123

</Button>

124

125

{/* Icon buttons */}

126

<Button

127

icon="search"

128

accessibilityLabel="Search products"

129

iconOnly

130

/>

131

132

{/* Button group */}

133

<ButtonGroup>

134

<Button>Cancel</Button>

135

<Button variant="primary">Save</Button>

136

</ButtonGroup>

137

</InlineStack>

138

);

139

}

140

```

141

142

### Button Utilities

143

144

Utility functions for creating buttons from action objects and converting action arrays to button arrays.

145

146

```typescript { .api }

147

/**

148

* Create Button component from Action object

149

* @param action - Action configuration

150

* @param overrides - Button prop overrides

151

* @returns JSX element with button from action

152

*/

153

function buttonFrom(

154

action: Action,

155

overrides?: Partial<ButtonProps>

156

): JSX.Element;

157

158

/**

159

* Create Button array from Action array

160

* @param actions - Array of action configurations

161

* @param overrides - Button prop overrides for all buttons

162

* @returns Array of JSX elements with buttons from actions

163

*/

164

function buttonsFrom(

165

actions: Action[],

166

overrides?: Partial<ButtonProps>

167

): JSX.Element[];

168

```

169

170

### UnstyledButton

171

172

Unstyled button base component providing button functionality without Polaris styling.

173

174

```typescript { .api }

175

/**

176

* Unstyled button base component

177

* @param children - Button content

178

* @param onClick - Click handler

179

* @param disabled - Disabled state

180

* @returns JSX element with unstyled button

181

*/

182

function UnstyledButton(props: UnstyledButtonProps): JSX.Element;

183

184

interface UnstyledButtonProps {

185

/** Button content */

186

children?: React.ReactNode;

187

/** Click handler */

188

onClick?: () => void;

189

/** Disabled state */

190

disabled?: boolean;

191

/** Loading state */

192

loading?: boolean;

193

/** Accessibility label */

194

accessibilityLabel?: string;

195

/** ARIA describedby */

196

ariaDescribedBy?: string;

197

/** ARIA expanded */

198

ariaExpanded?: boolean;

199

/** ARIA controls */

200

ariaControls?: string;

201

/** ARIA pressed */

202

ariaPressed?: boolean;

203

/** Button ID */

204

id?: string;

205

/** Tab index */

206

tabIndex?: number;

207

/** Button role */

208

role?: string;

209

/** Button type */

210

type?: 'button' | 'submit' | 'reset';

211

/** Button URL */

212

url?: string;

213

/** External link */

214

external?: boolean;

215

/** Download attribute */

216

download?: string | boolean;

217

/** Link target */

218

target?: string;

219

/** Additional class names */

220

className?: string;

221

/** Focus handler */

222

onFocus?: () => void;

223

/** Blur handler */

224

onBlur?: () => void;

225

/** Key down handler */

226

onKeyDown?: (event: React.KeyboardEvent) => void;

227

/** Key press handler */

228

onKeyPress?: (event: React.KeyboardEvent) => void;

229

/** Key up handler */

230

onKeyUp?: (event: React.KeyboardEvent) => void;

231

/** Mouse enter handler */

232

onMouseEnter?: () => void;

233

/** Touch start handler */

234

onTouchStart?: () => void;

235

}

236

237

/**

238

* Create UnstyledButton from Action object

239

* @param action - Action configuration

240

* @param overrides - Button prop overrides

241

* @returns JSX element with unstyled button from action

242

*/

243

function unstyledButtonFrom(

244

action: Action,

245

overrides?: Partial<UnstyledButtonProps>

246

): JSX.Element;

247

```

248

249

### ButtonGroup

250

251

Group multiple buttons with consistent spacing and connected styling options.

252

253

```typescript { .api }

254

/**

255

* Group buttons with consistent spacing and styling

256

* @param children - Button components

257

* @param segmented - Connected button styling

258

* @param fullWidth - Full width button group

259

* @returns JSX element with button group

260

*/

261

function ButtonGroup(props: ButtonGroupProps): JSX.Element;

262

263

interface ButtonGroupProps {

264

/** Button components */

265

children?: React.ReactNode;

266

/** Connected button styling */

267

segmented?: boolean;

268

/** Full width buttons */

269

fullWidth?: boolean;

270

/** Connector top */

271

connectedTop?: boolean;

272

/** Connector bottom */

273

connectedBottom?: boolean;

274

/** Button group variant */

275

variant?: 'segmented';

276

}

277

```

278

279

### ActionList

280

281

List of clickable actions with icons, descriptions, and keyboard navigation support.

282

283

```typescript { .api }

284

/**

285

* List of clickable actions with icons and descriptions

286

* @param items - Action items to display

287

* @param sections - Grouped action sections

288

* @param onActionAnyItem - Global action handler

289

* @returns JSX element with action list

290

*/

291

function ActionList(props: ActionListProps): JSX.Element;

292

293

interface ActionListProps {

294

/** Individual action items */

295

items?: ActionListItemDescriptor[];

296

/** Grouped action sections */

297

sections?: ActionListSection[];

298

/** Action role for accessibility */

299

actionRole?: string;

300

/** Global action handler */

301

onActionAnyItem?: ActionListItemDescriptor['onAction'];

302

}

303

304

interface ActionListItemDescriptor {

305

/** Action content/label */

306

content?: React.ReactNode;

307

/** Action callback */

308

onAction?(): void;

309

/** Action URL */

310

url?: string;

311

/** External link */

312

external?: boolean;

313

/** Action icon */

314

icon?: IconSource;

315

/** Action image */

316

image?: string;

317

/** Prefix content */

318

prefix?: React.ReactNode;

319

/** Suffix content */

320

suffix?: React.ReactNode;

321

/** Help text */

322

helpText?: React.ReactNode;

323

/** Accessibility label */

324

accessibilityLabel?: string;

325

/** Disabled state */

326

disabled?: boolean;

327

/** Destructive action */

328

destructive?: boolean;

329

/** Ellipsis truncation */

330

ellipsis?: boolean;

331

/** Active state */

332

active?: boolean;

333

/** Badge content */

334

badge?: BadgeProps;

335

/** Role override */

336

role?: string;

337

/** Truncate text */

338

truncate?: boolean;

339

/** Indentation variant */

340

variant?: 'default' | 'indented' | 'menu';

341

}

342

343

interface ActionListSection {

344

/** Section title */

345

title?: string;

346

/** Section items */

347

items: ActionListItemDescriptor[];

348

/** Fill available space */

349

fill?: boolean;

350

}

351

352

/**

353

* Individual action list item component

354

* @param content - Item content

355

* @param onAction - Action handler

356

* @param icon - Item icon

357

* @returns JSX element with action item

358

*/

359

function ActionListItem(props: ActionListItemProps): JSX.Element;

360

361

interface ActionListItemProps extends ActionListItemDescriptor {

362

/** Item index for keyboard navigation */

363

index?: number;

364

}

365

```

366

367

### ActionMenu

368

369

Menu component for displaying grouped actions with overflow handling and responsive behavior.

370

371

```typescript { .api }

372

/**

373

* Menu for displaying grouped actions with overflow handling

374

* @param groups - Action groups to display

375

* @param actions - Individual actions

376

* @param rollup - Overflow rollup configuration

377

* @returns JSX element with action menu

378

*/

379

function ActionMenu(props: ActionMenuProps): JSX.Element;

380

381

interface ActionMenuProps {

382

/** Action groups */

383

groups?: MenuGroupDescriptor[];

384

/** Individual actions */

385

actions?: MenuActionDescriptor[];

386

/** Overflow rollup behavior */

387

rollup?: boolean;

388

/** Rollup actions configuration */

389

rollupActionsLabel?: string;

390

/** Callback when menu opens */

391

onOpen?(): void;

392

/** Callback when menu closes */

393

onClose?(): void;

394

}

395

396

interface MenuGroupDescriptor {

397

/** Group title */

398

title?: string;

399

/** Group actions */

400

actions: MenuActionDescriptor[];

401

/** Group icon */

402

icon?: IconSource;

403

/** Details content */

404

details?: React.ReactNode;

405

/** Disabled state */

406

disabled?: boolean;

407

}

408

409

interface MenuActionDescriptor extends ActionListItemDescriptor {

410

/** Help text tooltip */

411

helpText?: string;

412

/** Action index for positioning */

413

index?: number;

414

}

415

```

416

417

### PageActions

418

419

Page-level action buttons positioned consistently in page headers with primary and secondary action support.

420

421

```typescript { .api }

422

/**

423

* Page-level action buttons for page headers

424

* @param primaryAction - Primary page action

425

* @param secondaryActions - Secondary page actions

426

* @returns JSX element with page actions

427

*/

428

function PageActions(props: PageActionsProps): JSX.Element;

429

430

interface PageActionsProps {

431

/** Primary page action */

432

primaryAction?: ComplexAction;

433

/** Secondary page actions */

434

secondaryActions?: ComplexAction[];

435

}

436

437

interface ComplexAction extends Action {

438

/** Accessibility label */

439

accessibilityLabel?: string;

440

/** Disabled state */

441

disabled?: boolean;

442

/** Destructive styling */

443

destructive?: boolean;

444

/** External link */

445

external?: boolean;

446

/** Help text */

447

helpText?: React.ReactNode;

448

/** Action icon */

449

icon?: IconSource;

450

/** Action ID */

451

id?: string;

452

/** Loading state */

453

loading?: boolean;

454

/** Outline variant */

455

outline?: boolean;

456

/** Plain variant */

457

plain?: boolean;

458

/** Primary styling */

459

primary?: boolean;

460

/** Remove underline */

461

removeUnderline?: boolean;

462

/** Size variant */

463

size?: 'slim' | 'medium' | 'large';

464

/** Submit button */

465

submit?: boolean;

466

/** Target for links */

467

target?: Target;

468

/** Tooltip content */

469

tooltip?: string;

470

}

471

```

472

473

**Usage Example:**

474

475

```typescript

476

import React from 'react';

477

import { ActionList, ActionMenu, Popover, Button } from '@shopify/polaris';

478

479

function ActionsExample() {

480

const [active, setActive] = React.useState(false);

481

482

const actionItems = [

483

{

484

content: 'Edit product',

485

icon: 'edit',

486

onAction: () => console.log('Edit clicked'),

487

},

488

{

489

content: 'Duplicate product',

490

icon: 'duplicate',

491

onAction: () => console.log('Duplicate clicked'),

492

},

493

{

494

content: 'Archive product',

495

icon: 'archive',

496

destructive: true,

497

onAction: () => console.log('Archive clicked'),

498

},

499

];

500

501

const menuGroups = [

502

{

503

title: 'Promote',

504

actions: [

505

{

506

content: 'Share on social media',

507

icon: 'share',

508

onAction: () => console.log('Share clicked'),

509

},

510

],

511

},

512

{

513

title: 'Organize',

514

actions: [

515

{

516

content: 'Add to collection',

517

icon: 'collection',

518

onAction: () => console.log('Add to collection'),

519

},

520

{

521

content: 'Add tags',

522

icon: 'tag',

523

onAction: () => console.log('Add tags'),

524

},

525

],

526

},

527

];

528

529

const activator = (

530

<Button

531

disclosure

532

onClick={() => setActive(!active)}

533

>

534

More actions

535

</Button>

536

);

537

538

return (

539

<>

540

{/* Simple action list */}

541

<ActionList items={actionItems} />

542

543

{/* Action menu with groups */}

544

<Popover

545

active={active}

546

activator={activator}

547

onClose={() => setActive(false)}

548

>

549

<ActionMenu groups={menuGroups} />

550

</Popover>

551

</>

552

);

553

}

554

```

555

556

## Action Types and Interfaces

557

558

```typescript { .api }

559

/** Base action interface */

560

interface Action {

561

/** Action content/label */

562

content?: string;

563

/** Accessibility label */

564

accessibilityLabel?: string;

565

/** Action URL */

566

url?: string;

567

/** External link */

568

external?: boolean;

569

/** Action callback */

570

onAction?(): void;

571

/** Mouse enter handler */

572

onMouseEnter?(): void;

573

/** Touch start handler */

574

onTouchStart?(): void;

575

}

576

577

/** Link action with required URL */

578

interface LinkAction extends Action {

579

/** Required URL for link actions */

580

url: string;

581

}

582

583

/** Callback action with required handler */

584

interface CallbackAction extends Action {

585

/** Required callback for action */

586

onAction(): void;

587

}

588

589

/** Disableable action interface */

590

interface DisableableAction extends Action {

591

/** Disabled state */

592

disabled?: boolean;

593

}

594

595

/** Destructable action interface */

596

interface DestructableAction extends Action {

597

/** Destructive styling */

598

destructive?: boolean;

599

}

600

601

/** Iconable action interface */

602

interface IconableAction extends Action {

603

/** Action icon */

604

icon?: IconSource;

605

}

606

607

/** Loadable action interface */

608

interface LoadableAction extends Action {

609

/** Loading state */

610

loading?: boolean;

611

}

612

613

/** Outlineable action interface */

614

interface OutlineableAction extends Action {

615

/** Outline variant */

616

outline?: boolean;

617

}

618

619

/** Plain action interface */

620

interface PlainAction extends Action {

621

/** Plain styling variant */

622

plain?: boolean;

623

}

624

625

/** Tooltip action interface */

626

interface TooltipAction extends Action {

627

/** Help text tooltip */

628

helpText?: React.ReactNode;

629

}

630

631

/** Badge action interface */

632

interface BadgeAction extends Action {

633

/** Badge configuration */

634

badge?: string | BadgeProps;

635

}

636

637

/** Icon source type */

638

type IconSource = React.ComponentType<any> | 'placeholder' | string;

639

640

/** Link target type */

641

type Target = '_blank' | '_self' | '_parent' | '_top';

642

643

/** Badge props interface */

644

interface BadgeProps {

645

/** Badge content */

646

children?: React.ReactNode;

647

/** Badge tone */

648

tone?: 'default' | 'success' | 'info' | 'attention' | 'warning' | 'critical';

649

/** Badge progress */

650

progress?: 'incomplete' | 'partiallyComplete' | 'complete';

651

/** Badge size */

652

size?: 'small' | 'medium';

653

}

654

```

655

656

### OptionList

657

658

Selectable list of options with keyboard navigation, ideal for dropdowns, filters, and selection interfaces.

659

660

```typescript { .api }

661

/**

662

* Selectable list with keyboard navigation

663

* @param options - Array of selectable options

664

* @param selected - Currently selected options

665

* @param onChange - Selection change handler

666

* @returns JSX element with option list

667

*/

668

function OptionList(props: OptionListProps): JSX.Element;

669

670

interface OptionListProps {

671

/** The title of the option list */

672

title?: string;

673

/** Collection of options to be rendered */

674

options?: SectionDescriptor[] | OptionDescriptor[];

675

/** The selected options */

676

selected: string[];

677

/** Allow more than one option to be selected */

678

allowMultiple?: boolean;

679

/** The role for the option list */

680

role?: string;

681

/** The option list's section role */

682

sectionRole?: string;

683

/** Callback when the selection of options is changed */

684

onChange(selected: string[]): void;

685

}

686

```

687

688

### SelectAllActions

689

690

Bulk selection controls for data tables and lists with select all, deselect all, and selective actions.

691

692

```typescript { .api }

693

/**

694

* Bulk selection controls for data lists

695

* @param label - Label for the select all control

696

* @param selected - Whether all items are selected

697

* @param onToggleAll - Toggle all selection handler

698

* @returns JSX element with select all controls

699

*/

700

function SelectAllActions(props: SelectAllActionsProps): JSX.Element;

701

702

interface SelectAllActionsProps {

703

/** Label for the bulk actions */

704

label?: string;

705

/** Callback when the selection of all items is changed */

706

onToggleAll?(): void;

707

/** Whether to select all items */

708

selectMode?: boolean;

709

/** Callback when the select mode is toggled */

710

onSelectModeToggle?(): void;

711

}

712

```

713

714

### SettingToggle

715

716

Toggle control for enabling/disabling settings with descriptive labels and contextual actions.

717

718

```typescript { .api }

719

/**

720

* Toggle control for settings with descriptive labels

721

* @param action - Toggle action configuration

722

* @param enabled - Whether setting is enabled

723

* @param children - Description content

724

* @returns JSX element with setting toggle

725

*/

726

function SettingToggle(props: SettingToggleProps): JSX.Element;

727

728

interface SettingToggleProps {

729

/** The action to toggle the setting */

730

action?: ComplexAction;

731

/** Whether the setting is enabled */

732

enabled?: boolean;

733

/** The content to display with the setting */

734

children?: React.ReactNode;

735

}

736

```

737

738

### Listbox

739

740

Accessible listbox component with support for single and multiple selection, keyboard navigation, and custom option rendering.

741

742

```typescript { .api }

743

/**

744

* Accessible listbox with selection and keyboard navigation

745

* @param options - Array of listbox options

746

* @param selected - Currently selected values

747

* @param onSelect - Selection change handler

748

* @returns JSX element with listbox interface

749

*/

750

function Listbox(props: ListboxProps): JSX.Element;

751

752

interface ListboxProps {

753

/** Enable auto selection behavior */

754

enableKeyboardControl?: boolean;

755

/** Collection of options to render */

756

children?: React.ReactNode;

757

/** Auto selection mode */

758

autoSelection?: AutoSelection;

759

/** Callback when an option is selected */

760

onSelect?(value: string): void;

761

/** Callback when the active option changes */

762

onActiveOptionChange?(value?: string): void;

763

}

764

765

enum AutoSelection {

766

None = 'NONE',

767

First = 'FIRST',

768

Selected = 'SELECTED',

769

}

770

```

771

772

### Tabs

773

774

Tab navigation component for organizing content into switchable panels with keyboard accessibility.

775

776

```typescript { .api }

777

/**

778

* Tab navigation for organizing content into panels

779

* @param tabs - Array of tab definitions

780

* @param selected - Index of selected tab

781

* @param onSelect - Tab selection handler

782

* @returns JSX element with tab navigation

783

*/

784

function Tabs(props: TabsProps): JSX.Element;

785

786

interface TabsProps {

787

/** Collection of tabs to display */

788

tabs: TabProps[];

789

/** The index of the selected tab */

790

selected: number;

791

/** Whether the tabs are fitted to the container */

792

fitted?: boolean;

793

/** The callback to handle tab selection */

794

onSelect?(selectedTabIndex: number): void;

795

/** Visually hide the tab navigation */

796

disclosureText?: string;

797

}

798

799

interface TabProps {

800

/** A unique identifier for the tab */

801

id: string;

802

/** Content to display in the tab */

803

content: React.ReactNode;

804

/** Accessible label for the tab */

805

accessibilityLabel?: string;

806

/** URL for the tab */

807

url?: string;

808

/** Badge content */

809

badge?: React.ReactNode;

810

/** Panel content */

811

panelID?: string;

812

}

813

```

814

815

### LegacyTabs

816

817

Legacy tab component for backward compatibility with older tab implementations.

818

819

```typescript { .api }

820

/**

821

* Legacy tab component for backward compatibility

822

* @param tabs - Array of legacy tab definitions

823

* @param selected - Index of selected tab

824

* @param onSelect - Tab selection handler

825

* @returns JSX element with legacy tab navigation

826

*/

827

function LegacyTabs(props: LegacyTabsProps): JSX.Element;

828

829

interface LegacyTabsProps {

830

/** Collection of tabs to display */

831

tabs: LegacyTab[];

832

/** The index of the selected tab */

833

selected: number;

834

/** Whether the tabs are fitted to the container */

835

fitted?: boolean;

836

/** The callback to handle tab selection */

837

onSelect?(selectedTabIndex: number): void;

838

}

839

840

interface LegacyTab {

841

/** A unique identifier for the tab */

842

id: string;

843

/** The title of the tab */

844

title: string;

845

/** URL for the tab */

846

url?: string;

847

/** Badge content */

848

badge?: React.ReactNode;

849

}

850

```