or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

button-typography-components.mdcore-components.mddata-display-components.mdfeedback-components.mdform-components.mdindex.mdlayout-components.mdnavigation-components.mdoverlay-components.mdtheme-system.md

navigation-components.mddocs/

0

# Navigation Components

1

2

@mantine/core provides a comprehensive set of navigation components for building user-friendly interfaces with clear navigation patterns. These components handle complex interactions while maintaining accessibility standards.

3

4

## Tabs

5

6

The Tabs component provides a tabbed interface with keyboard navigation and accessibility features.

7

8

```typescript { .api }

9

interface TabsProps {

10

/** Currently active tab key */

11

value?: string | null;

12

/** Default active tab key */

13

defaultValue?: string | null;

14

/** Called when tab changes */

15

onTabChange?: (value: string | null) => void;

16

/** Tab orientation */

17

orientation?: 'horizontal' | 'vertical';

18

/** Tab placement relative to content */

19

placement?: 'right' | 'left';

20

/** If true, tabs can be activated with keyboard */

21

activateTabWithKeyboard?: boolean;

22

/** Tab variant */

23

variant?: 'default' | 'outline' | 'pills';

24

/** Tab color theme */

25

color?: MantineColor;

26

/** Tab radius */

27

radius?: MantineRadius;

28

/** If true, tab panels are not wrapped with TabPanel */

29

keepMounted?: boolean;

30

/** Tabs children */

31

children: React.ReactNode;

32

}

33

34

interface TabsListProps {

35

/** Tabs list children (Tab components) */

36

children: React.ReactNode;

37

/** If true, tab will grow to use all available space */

38

grow?: boolean;

39

/** Tab position */

40

justify?: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around';

41

}

42

43

interface TabsPanelProps {

44

/** Panel content */

45

children: React.ReactNode;

46

/** Tab key that should activate this panel */

47

value: string;

48

}

49

50

interface TabsTabProps {

51

/** Tab label */

52

children: React.ReactNode;

53

/** Tab key */

54

value: string;

55

/** Tab icon */

56

leftSection?: React.ReactNode;

57

/** Tab right section */

58

rightSection?: React.ReactNode;

59

/** Tab color when active */

60

color?: MantineColor;

61

/** If true, tab is disabled */

62

disabled?: boolean;

63

}

64

```

65

66

**Usage Example:**

67

68

```tsx

69

import { Tabs } from '@mantine/core';

70

71

function TabsDemo() {

72

return (

73

<Tabs defaultValue="gallery">

74

<Tabs.List>

75

<Tabs.Tab value="gallery" leftSection="πŸ“·">

76

Gallery

77

</Tabs.Tab>

78

<Tabs.Tab value="messages" leftSection="πŸ’¬">

79

Messages

80

</Tabs.Tab>

81

<Tabs.Tab value="settings" leftSection="βš™οΈ">

82

Settings

83

</Tabs.Tab>

84

</Tabs.List>

85

86

<Tabs.Panel value="gallery">

87

Gallery tab content

88

</Tabs.Panel>

89

90

<Tabs.Panel value="messages">

91

Messages tab content

92

</Tabs.Panel>

93

94

<Tabs.Panel value="settings">

95

Settings tab content

96

</Tabs.Panel>

97

</Tabs>

98

);

99

}

100

```

101

102

## Stepper

103

104

Multi-step process component with validation and navigation controls.

105

106

```typescript { .api }

107

interface StepperProps {

108

/** Active step index */

109

active: number;

110

/** Called when step changes */

111

onStepClick?: (stepIndex: number) => void;

112

/** Step icon size */

113

iconSize?: number;

114

/** Stepper orientation */

115

orientation?: 'vertical' | 'horizontal';

116

/** Icon position relative to step body */

117

iconPosition?: 'right' | 'left';

118

/** Step size */

119

size?: MantineSize;

120

/** Step radius */

121

radius?: MantineRadius;

122

/** Step color theme */

123

color?: MantineColor;

124

/** If true, steps before active can be clicked */

125

allowNextStepsSelect?: boolean;

126

/** Stepper children (Step components) */

127

children: React.ReactNode;

128

}

129

130

interface StepperStepProps {

131

/** Step label */

132

label?: React.ReactNode;

133

/** Step description */

134

description?: React.ReactNode;

135

/** Step icon, displayed instead of step number */

136

icon?: React.ReactNode;

137

/** Step content */

138

children?: React.ReactNode;

139

/** Step state */

140

state?: 'stepInactive' | 'stepProgress' | 'stepCompleted';

141

/** Step color when active */

142

color?: MantineColor;

143

/** If true, step can be clicked */

144

allowStepClick?: boolean;

145

/** If true, step is completed */

146

completedIcon?: React.ReactNode;

147

/** If true, step is loading */

148

loading?: boolean;

149

}

150

151

interface StepperCompletedProps {

152

/** Completed state content */

153

children: React.ReactNode;

154

}

155

```

156

157

**Usage Example:**

158

159

```tsx

160

import { Stepper, Button, Group } from '@mantine/core';

161

import { useState } from 'react';

162

163

function StepperDemo() {

164

const [active, setActive] = useState(0);

165

166

const nextStep = () => setActive(current =>

167

current < 3 ? current + 1 : current

168

);

169

const prevStep = () => setActive(current =>

170

current > 0 ? current - 1 : current

171

);

172

173

return (

174

<>

175

<Stepper active={active} onStepClick={setActive}>

176

<Stepper.Step label="First step" description="Create an account">

177

Step 1 content: Create an account

178

</Stepper.Step>

179

180

<Stepper.Step label="Second step" description="Verify email">

181

Step 2 content: Verify email

182

</Stepper.Step>

183

184

<Stepper.Step label="Final step" description="Get full access">

185

Step 3 content: Get full access

186

</Stepper.Step>

187

188

<Stepper.Completed>

189

Completed! Form values are:

190

</Stepper.Completed>

191

</Stepper>

192

193

<Group justify="center" mt="xl">

194

<Button variant="default" onClick={prevStep}>Back</Button>

195

<Button onClick={nextStep}>Next step</Button>

196

</Group>

197

</>

198

);

199

}

200

```

201

202

## Breadcrumbs

203

204

Navigation breadcrumb component for showing the current page location.

205

206

```typescript { .api }

207

interface BreadcrumbsProps {

208

/** Breadcrumb items */

209

children: React.ReactNode;

210

/** Separator between items */

211

separator?: React.ReactNode;

212

/** Number of items to display, other items will be hidden */

213

max?: number;

214

/** Separator for hidden items */

215

separatorMargin?: MantineSpacing;

216

}

217

```

218

219

**Usage Example:**

220

221

```tsx

222

import { Breadcrumbs, Anchor } from '@mantine/core';

223

224

const items = [

225

{ title: 'Mantine', href: '#' },

226

{ title: 'Core', href: '#' },

227

{ title: 'Breadcrumbs', href: '#' },

228

].map((item, index) => (

229

<Anchor href={item.href} key={index}>

230

{item.title}

231

</Anchor>

232

));

233

234

function BreadcrumbsDemo() {

235

return <Breadcrumbs>{items}</Breadcrumbs>;

236

}

237

```

238

239

## Pagination

240

241

Pagination controls with customizable appearance and behavior.

242

243

```typescript { .api }

244

interface PaginationProps {

245

/** Active page number */

246

value?: number;

247

/** Default active page */

248

defaultValue?: number;

249

/** Called when page changes */

250

onChange?: (value: number) => void;

251

/** Total number of pages */

252

total: number;

253

/** Number of siblings on each side of active page */

254

siblings?: number;

255

/** Number of boundaries on each side */

256

boundaries?: number;

257

/** Pagination size */

258

size?: MantineSize;

259

/** Pagination radius */

260

radius?: MantineRadius;

261

/** Pagination color theme */

262

color?: MantineColor;

263

/** If true, pagination will not wrap to next line */

264

withEdges?: boolean;

265

/** If true, controls are disabled */

266

disabled?: boolean;

267

/** Get aria-label for page button */

268

getItemAriaLabel?: (page: number) => string;

269

/** Get control aria-label */

270

getControlAriaLabel?: (control: string) => string;

271

}

272

273

interface PaginationRootProps {

274

/** Root element children */

275

children: React.ReactNode;

276

/** Pagination size */

277

size?: MantineSize;

278

/** Total number of pages */

279

total: number;

280

/** Active page number */

281

value?: number;

282

/** Default active page */

283

defaultValue?: number;

284

/** Called when page changes */

285

onChange?: (value: number) => void;

286

/** If true, controls are disabled */

287

disabled?: boolean;

288

/** Number of siblings */

289

siblings?: number;

290

/** Number of boundaries */

291

boundaries?: number;

292

/** Get aria-label for page */

293

getItemAriaLabel?: (page: number) => string;

294

}

295

296

interface PaginationControlProps {

297

/** Control content */

298

children?: React.ReactNode;

299

/** Control action */

300

onClick?: () => void;

301

/** If true, control is disabled */

302

disabled?: boolean;

303

/** If true, control is active */

304

active?: boolean;

305

/** Control aria-label */

306

'aria-label'?: string;

307

}

308

```

309

310

**Usage Example:**

311

312

```tsx

313

import { Pagination } from '@mantine/core';

314

import { useState } from 'react';

315

316

function PaginationDemo() {

317

const [activePage, setPage] = useState(1);

318

319

return (

320

<Pagination

321

value={activePage}

322

onChange={setPage}

323

total={10}

324

siblings={1}

325

boundaries={3}

326

/>

327

);

328

}

329

330

// Compound components usage

331

function CustomPagination() {

332

return (

333

<Pagination.Root total={10}>

334

<Pagination.First />

335

<Pagination.Previous />

336

<Pagination.Items />

337

<Pagination.Next />

338

<Pagination.Last />

339

</Pagination.Root>

340

);

341

}

342

```

343

344

## NavLink

345

346

Navigation link component with active state and nested structure support.

347

348

```typescript { .api }

349

interface NavLinkProps {

350

/** Link label */

351

label: React.ReactNode;

352

/** Link description */

353

description?: React.ReactNode;

354

/** Link left section (usually icon) */

355

leftSection?: React.ReactNode;

356

/** Link right section */

357

rightSection?: React.ReactNode;

358

/** If true, link will have active styles */

359

active?: boolean;

360

/** Link variant */

361

variant?: 'light' | 'filled' | 'subtle';

362

/** Link color theme */

363

color?: MantineColor;

364

/** If true, link is disabled */

365

disabled?: boolean;

366

/** Link children for nested structure */

367

children?: React.ReactNode;

368

/** Called when link is clicked */

369

onClick?: () => void;

370

/** If true, children will not be rendered */

371

childrenOffset?: MantineSpacing;

372

/** If true, link cannot be activated with click */

373

disableRightSectionRotation?: boolean;

374

/** Collapse icon */

375

collapseIcon?: React.ReactNode;

376

}

377

```

378

379

**Usage Example:**

380

381

```tsx

382

import { NavLink } from '@mantine/core';

383

384

function NavLinkDemo() {

385

return (

386

<NavLink

387

label="With icon"

388

leftSection="🏠"

389

rightSection="β†’"

390

active

391

/>

392

);

393

}

394

395

// Nested NavLinks

396

function NestedNavLinks() {

397

return (

398

<NavLink label="Dashboard" leftSection="πŸ“Š">

399

<NavLink label="Analytics" />

400

<NavLink label="Reports" active />

401

<NavLink label="Settings" />

402

</NavLink>

403

);

404

}

405

```

406

407

## TableOfContents

408

409

Table of contents component for navigation within documents.

410

411

```typescript { .api }

412

interface TableOfContentsProps {

413

/** Table of contents links */

414

links: TableOfContentsLink[];

415

/** Active link */

416

active?: string;

417

/** Called when link is clicked */

418

onLinkClick?: (link: TableOfContentsLink) => void;

419

}

420

421

interface TableOfContentsLink {

422

/** Link label */

423

label: string;

424

/** Link id */

425

link: string;

426

/** Nested links */

427

links?: TableOfContentsLink[];

428

/** Link order for sorting */

429

order?: number;

430

}

431

```

432

433

**Usage Example:**

434

435

```tsx

436

import { TableOfContents } from '@mantine/core';

437

438

const links = [

439

{

440

label: 'Usage',

441

link: '#usage',

442

order: 1,

443

},

444

{

445

label: 'API Reference',

446

link: '#api',

447

order: 1,

448

links: [

449

{ label: 'Props', link: '#props', order: 2 },

450

{ label: 'Methods', link: '#methods', order: 2 },

451

],

452

},

453

{

454

label: 'Examples',

455

link: '#examples',

456

order: 1,

457

},

458

];

459

460

function TableOfContentsDemo() {

461

return (

462

<TableOfContents

463

links={links}

464

active="#usage"

465

onLinkClick={(link) => console.log(link)}

466

/>

467

);

468

}

469

```

470

471

## Theme Integration

472

473

All navigation components integrate seamlessly with the Mantine theme system:

474

475

```tsx

476

import { MantineProvider, Tabs, Stepper, Pagination } from '@mantine/core';

477

478

const theme = {

479

components: {

480

Tabs: {

481

defaultProps: {

482

color: 'blue',

483

variant: 'pills',

484

},

485

},

486

Stepper: {

487

defaultProps: {

488

size: 'sm',

489

color: 'teal',

490

},

491

},

492

Pagination: {

493

defaultProps: {

494

size: 'md',

495

radius: 'md',

496

},

497

},

498

},

499

};

500

501

function App() {

502

return (

503

<MantineProvider theme={theme}>

504

{/* Navigation components will use theme defaults */}

505

</MantineProvider>

506

);

507

}

508

```

509

510

## Accessibility Features

511

512

Navigation components include comprehensive accessibility support:

513

514

- **Keyboard Navigation**: Full keyboard support with arrow keys, Enter, Space

515

- **ARIA Labels**: Proper labeling for screen readers

516

- **Focus Management**: Logical focus flow and visible focus indicators

517

- **Role Attributes**: Correct semantic roles (tab, tablist, tabpanel, etc.)

518

- **State Announcement**: Active and disabled states are properly announced

519

520

## Common Patterns

521

522

**Responsive Navigation:**

523

```tsx

524

import { useMediaQuery } from '@mantine/hooks';

525

import { Tabs, Burger, Drawer } from '@mantine/core';

526

527

function ResponsiveNavigation() {

528

const isMobile = useMediaQuery('(max-width: 768px)');

529

530

return isMobile ? (

531

<MobileBurgerMenu />

532

) : (

533

<Tabs>

534

<Tabs.List>

535

<Tabs.Tab value="home">Home</Tabs.Tab>

536

<Tabs.Tab value="about">About</Tabs.Tab>

537

<Tabs.Tab value="contact">Contact</Tabs.Tab>

538

</Tabs.List>

539

</Tabs>

540

);

541

}

542

```

543

544

**Multi-level Navigation:**

545

```tsx

546

function MultiLevelNavigation() {

547

return (

548

<NavLink label="Products" leftSection="πŸ“¦">

549

<NavLink label="Software">

550

<NavLink label="Desktop Apps" />

551

<NavLink label="Mobile Apps" />

552

</NavLink>

553

<NavLink label="Hardware">

554

<NavLink label="Computers" />

555

<NavLink label="Accessories" />

556

</NavLink>

557

</NavLink>

558

);

559

}

560

```