or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-apis.mddevice.mddom-events.mdindex.mdnavigation.mdnetwork.mdobservers.mdspecialized.mdstate-management.mdstorage.mdtiming.mdutilities.md

navigation.mddocs/

0

# Navigation & Scroll

1

2

Navigation helpers and scroll management including pagination logic, smooth scrolling, scroll spy functionality, and headroom patterns.

3

4

## Capabilities

5

6

### usePagination

7

8

Pagination logic with range calculation and navigation controls.

9

10

```typescript { .api }

11

/**

12

* Pagination logic with range calculation

13

* @param options - Pagination configuration

14

* @returns Object with pagination state and controls

15

*/

16

function usePagination(options: UsePaginationOptions): UsePaginationReturnValue;

17

18

const DOTS = 'dots';

19

20

interface UsePaginationOptions {

21

initialPage?: number;

22

page?: number;

23

total: number;

24

siblings?: number;

25

boundaries?: number;

26

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

27

}

28

29

interface UsePaginationReturnValue {

30

range: (number | 'dots')[];

31

active: number;

32

setPage: (page: number) => void;

33

next: () => void;

34

previous: () => void;

35

first: () => void;

36

last: () => void;

37

}

38

```

39

40

**Usage Examples:**

41

42

```typescript

43

import { usePagination } from "@mantine/hooks";

44

45

function DataTable({ totalItems }: { totalItems: number }) {

46

const [currentPage, setCurrentPage] = useState(1);

47

const itemsPerPage = 10;

48

const totalPages = Math.ceil(totalItems / itemsPerPage);

49

50

const pagination = usePagination({

51

total: totalPages,

52

page: currentPage,

53

onChange: setCurrentPage,

54

siblings: 1,

55

boundaries: 1,

56

});

57

58

return (

59

<div>

60

<div>{/* Table content */}</div>

61

62

<div>

63

<button onClick={pagination.first} disabled={pagination.active === 1}>

64

First

65

</button>

66

<button onClick={pagination.previous} disabled={pagination.active === 1}>

67

Previous

68

</button>

69

70

{pagination.range.map((page, index) => (

71

<button

72

key={index}

73

onClick={() => typeof page === 'number' && pagination.setPage(page)}

74

disabled={page === 'dots'}

75

className={page === pagination.active ? 'active' : ''}

76

>

77

{page === 'dots' ? '...' : page}

78

</button>

79

))}

80

81

<button onClick={pagination.next} disabled={pagination.active === totalPages}>

82

Next

83

</button>

84

<button onClick={pagination.last} disabled={pagination.active === totalPages}>

85

Last

86

</button>

87

</div>

88

</div>

89

);

90

}

91

```

92

93

### useScrollIntoView

94

95

Smooth scroll into view with animation and cancellation support.

96

97

```typescript { .api }

98

/**

99

* Smooth scroll into view with animation

100

* @param options - Scroll configuration

101

* @returns Object with refs and scroll controls

102

*/

103

function useScrollIntoView<T extends HTMLElement = any>(

104

options?: UseScrollIntoViewOptions

105

): UseScrollIntoViewReturnValue<T>;

106

107

interface UseScrollIntoViewOptions {

108

duration?: number;

109

axis?: 'x' | 'y';

110

easing?: (t: number) => number;

111

offset?: number;

112

cancelable?: boolean;

113

isList?: boolean;

114

onScrollFinish?: () => void;

115

}

116

117

interface UseScrollIntoViewReturnValue<T extends HTMLElement = any> {

118

scrollableRef: React.RefCallback<T | null>;

119

targetRef: React.RefCallback<HTMLElement | null>;

120

scrollIntoView: (alignment?: ScrollLogicalPosition) => void;

121

cancel: () => void;

122

}

123

```

124

125

**Usage Examples:**

126

127

```typescript

128

import { useScrollIntoView } from "@mantine/hooks";

129

130

function ScrollableList({ items, activeId }: Props) {

131

const { scrollableRef, targetRef, scrollIntoView } = useScrollIntoView<HTMLDivElement>({

132

duration: 500,

133

offset: 60,

134

onScrollFinish: () => console.log('Scrolled to target'),

135

});

136

137

useEffect(() => {

138

if (activeId) {

139

scrollIntoView({ block: 'center' });

140

}

141

}, [activeId, scrollIntoView]);

142

143

return (

144

<div ref={scrollableRef} style={{ height: '400px', overflow: 'auto' }}>

145

{items.map(item => (

146

<div

147

key={item.id}

148

ref={item.id === activeId ? targetRef : undefined}

149

className={item.id === activeId ? 'active' : ''}

150

>

151

{item.title}

152

</div>

153

))}

154

</div>

155

);

156

}

157

```

158

159

### useScrollSpy

160

161

Track active section during scroll for table of contents navigation.

162

163

```typescript { .api }

164

/**

165

* Track active section during scroll

166

* @param selectors - Array of CSS selectors to track

167

* @param options - Scroll spy configuration

168

* @returns Tuple with root ref, active index, and heading data

169

*/

170

function useScrollSpy<T extends HTMLElement = any>(

171

selectors: string[],

172

options?: UseScrollSpyOptions<T>

173

): UseScrollSpyReturnType;

174

175

interface UseScrollSpyOptions<T extends HTMLElement = any> {

176

root?: T;

177

rootMargin?: string;

178

threshold?: number | number[];

179

}

180

181

interface UseScrollSpyHeadingData {

182

id: string;

183

level: number;

184

element: HTMLElement;

185

}

186

187

type UseScrollSpyReturnType = [

188

React.RefCallback<HTMLElement | null>, // rootRef

189

number, // activeIndex

190

UseScrollSpyHeadingData[] // headings

191

];

192

```

193

194

### useHeadroom

195

196

Hide/show header based on scroll direction for better UX.

197

198

```typescript { .api }

199

/**

200

* Hide/show header based on scroll direction

201

* @param options - Headroom configuration

202

* @returns Boolean indicating if header should be pinned

203

*/

204

function useHeadroom(options?: UseHeadroomOptions): boolean;

205

206

interface UseHeadroomOptions {

207

fixedAt?: number;

208

onPin?: () => void;

209

onRelease?: () => void;

210

}

211

```

212

213

**Usage Examples:**

214

215

```typescript

216

import { useHeadroom } from "@mantine/hooks";

217

218

function Header() {

219

const pinned = useHeadroom({ fixedAt: 120 });

220

221

return (

222

<header

223

style={{

224

position: 'fixed',

225

top: 0,

226

left: 0,

227

right: 0,

228

transform: pinned ? 'translateY(0)' : 'translateY(-100%)',

229

transition: 'transform 0.3s ease',

230

zIndex: 1000,

231

}}

232

>

233

<nav>Navigation content</nav>

234

</header>

235

);

236

}

237

```