or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-api.mdcontext-utilities.mdhook-api.mdindex.md

context-utilities.mddocs/

0

# Context and Utilities

1

2

Context providers for server-side rendering scenarios and utility functions for media query string generation and device property management.

3

4

## Capabilities

5

6

### React Context

7

8

React Context for providing device settings to all `useMediaQuery` hooks and `MediaQuery` components in the component tree. Essential for server-side rendering and testing scenarios.

9

10

```typescript { .api }

11

/**

12

* React Context for providing device settings globally

13

* Used for server-side rendering and testing with specific device characteristics

14

*/

15

const Context: React.Context<Partial<MediaQueryAllQueryable> | undefined>;

16

```

17

18

**Usage Examples:**

19

20

```typescript

21

import React from "react";

22

import { Context as ResponsiveContext, useMediaQuery, MediaQuery } from "react-responsive";

23

24

// Server-side rendering with device context

25

const SSRExample = () => {

26

// This would typically be set based on User-Agent headers

27

const deviceSettings = {

28

width: 768,

29

height: 1024,

30

orientation: "portrait" as const,

31

};

32

33

return (

34

<ResponsiveContext.Provider value={deviceSettings}>

35

<App />

36

</ResponsiveContext.Provider>

37

);

38

};

39

40

// Testing with specific device characteristics

41

const TestingExample = () => {

42

const mobileDevice = {

43

width: 375,

44

height: 667,

45

orientation: "portrait" as const,

46

};

47

48

const desktopDevice = {

49

width: 1920,

50

height: 1080,

51

orientation: "landscape" as const,

52

};

53

54

return (

55

<div>

56

<h2>Mobile Test</h2>

57

<ResponsiveContext.Provider value={mobileDevice}>

58

<ResponsiveComponent />

59

</ResponsiveContext.Provider>

60

61

<h2>Desktop Test</h2>

62

<ResponsiveContext.Provider value={desktopDevice}>

63

<ResponsiveComponent />

64

</ResponsiveContext.Provider>

65

</div>

66

);

67

};

68

69

// Component that uses the context

70

const ResponsiveComponent = () => {

71

const isMobile = useMediaQuery({ maxWidth: 767 });

72

const isDesktop = useMediaQuery({ minWidth: 1024 });

73

74

return (

75

<div>

76

<MediaQuery maxWidth={767}>

77

<p>Mobile view (from component)</p>

78

</MediaQuery>

79

{isMobile && <p>Mobile view (from hook)</p>}

80

{isDesktop && <p>Desktop view (from hook)</p>}

81

</div>

82

);

83

};

84

```

85

86

**Real-world SSR Example with Next.js:**

87

88

```typescript

89

// pages/_app.tsx

90

import { Context as ResponsiveContext } from "react-responsive";

91

import { GetServerSideProps } from "next";

92

93

interface AppProps {

94

deviceSettings?: {

95

width: number;

96

height: number;

97

orientation: "portrait" | "landscape";

98

};

99

}

100

101

const MyApp = ({ Component, pageProps, deviceSettings }: AppProps) => {

102

return (

103

<ResponsiveContext.Provider value={deviceSettings}>

104

<Component {...pageProps} />

105

</ResponsiveContext.Provider>

106

);

107

};

108

109

// Server-side device detection

110

export const getServerSideProps: GetServerSideProps = async ({ req }) => {

111

const userAgent = req.headers["user-agent"] || "";

112

113

// Simple device detection (in practice, use a proper library)

114

const isMobile = /Mobile|Android|iPhone|iPad/i.test(userAgent);

115

116

const deviceSettings = {

117

width: isMobile ? 375 : 1920,

118

height: isMobile ? 667 : 1080,

119

orientation: isMobile ? "portrait" as const : "landscape" as const,

120

};

121

122

return {

123

props: {

124

deviceSettings,

125

},

126

};

127

};

128

```

129

130

**Testing with React Testing Library:**

131

132

```typescript

133

import { render, screen } from "@testing-library/react";

134

import { Context as ResponsiveContext } from "react-responsive";

135

import MyResponsiveComponent from "./MyResponsiveComponent";

136

137

describe("MyResponsiveComponent", () => {

138

test("renders mobile layout", () => {

139

const mobileDevice = { width: 375, height: 667 };

140

141

render(

142

<ResponsiveContext.Provider value={mobileDevice}>

143

<MyResponsiveComponent />

144

</ResponsiveContext.Provider>

145

);

146

147

expect(screen.getByText("Mobile Layout")).toBeInTheDocument();

148

expect(screen.queryByText("Desktop Layout")).not.toBeInTheDocument();

149

});

150

151

test("renders desktop layout", () => {

152

const desktopDevice = { width: 1920, height: 1080 };

153

154

render(

155

<ResponsiveContext.Provider value={desktopDevice}>

156

<MyResponsiveComponent />

157

</ResponsiveContext.Provider>

158

);

159

160

expect(screen.getByText("Desktop Layout")).toBeInTheDocument();

161

expect(screen.queryByText("Mobile Layout")).not.toBeInTheDocument();

162

});

163

});

164

```

165

166

### toQuery Utility

167

168

Utility function that converts JavaScript object representation of media queries to CSS media query strings.

169

170

```typescript { .api }

171

/**

172

* Converts media query object to CSS media query string

173

* @param obj - Object with media query properties

174

* @returns CSS media query string

175

*/

176

function toQuery(obj: Partial<MediaQueryAllQueryable>): string;

177

```

178

179

**Usage Examples:**

180

181

```typescript

182

import { toQuery } from "react-responsive";

183

184

// Basic conversion

185

const queryString = toQuery({ minWidth: 768, maxWidth: 1024 });

186

console.log(queryString); // "(min-width: 768px) and (max-width: 1024px)"

187

188

// Complex query with multiple properties

189

const complexQuery = toQuery({

190

minWidth: 768,

191

orientation: "landscape",

192

color: true,

193

type: "screen"

194

});

195

console.log(complexQuery);

196

// "screen and (min-width: 768px) and (orientation: landscape) and color"

197

198

// Boolean properties

199

const printQuery = toQuery({

200

type: "print",

201

color: false, // Negated

202

monochrome: true

203

});

204

console.log(printQuery); // "print and not color and monochrome"

205

206

// Number conversion to px

207

const dimensionQuery = toQuery({

208

width: 1024,

209

height: 768,

210

minResolution: "2dppx"

211

});

212

console.log(dimensionQuery);

213

// "(width: 1024px) and (height: 768px) and (min-resolution: 2dppx)"

214

```

215

216

**Integration with Custom Logic:**

217

218

```typescript

219

import { toQuery, useMediaQuery } from "react-responsive";

220

221

const CustomMediaQueryHook = (breakpoints: Record<string, Partial<MediaQueryAllQueryable>>) => {

222

const results: Record<string, boolean> = {};

223

224

Object.entries(breakpoints).forEach(([name, query]) => {

225

const queryString = toQuery(query);

226

console.log(`${name} query:`, queryString);

227

228

// Use the generated query string with useMediaQuery

229

results[name] = useMediaQuery({ query: queryString });

230

});

231

232

return results;

233

};

234

235

// Usage

236

const ResponsiveComponent = () => {

237

const queries = CustomMediaQueryHook({

238

mobile: { maxWidth: 767 },

239

tablet: { minWidth: 768, maxWidth: 1023 },

240

desktop: { minWidth: 1024 },

241

portrait: { orientation: "portrait" },

242

retina: { minResolution: "2dppx" }

243

});

244

245

return (

246

<div>

247

{queries.mobile && <p>Mobile device</p>}

248

{queries.tablet && <p>Tablet device</p>}

249

{queries.desktop && <p>Desktop device</p>}

250

{queries.portrait && <p>Portrait orientation</p>}

251

{queries.retina && <p>High DPI display</p>}

252

</div>

253

);

254

};

255

```

256

257

### Media Query Object Properties

258

259

The utility functions and context work with the complete set of media query properties:

260

261

```typescript { .api }

262

interface MediaQueryAllQueryable extends MediaQueryFeatures, MediaQueryTypes {

263

// Dimension properties (support min/max variants)

264

width?: number | string;

265

height?: number | string;

266

deviceWidth?: number | string;

267

deviceHeight?: number | string;

268

269

// Aspect ratio properties (support min/max variants)

270

aspectRatio?: string;

271

deviceAspectRatio?: string;

272

273

// Display properties

274

color?: boolean;

275

colorIndex?: boolean;

276

monochrome?: boolean;

277

278

// Resolution properties (support min/max variants)

279

resolution?: number | string;

280

281

// Orientation and scan properties

282

orientation?: "portrait" | "landscape";

283

scan?: "progressive" | "interlace";

284

285

// Media type properties

286

type?: "all" | "grid" | "aural" | "braille" | "handheld" | "print" |

287

"projection" | "screen" | "tty" | "tv" | "embossed";

288

289

// All boolean media types

290

all?: boolean;

291

grid?: boolean;

292

aural?: boolean;

293

braille?: boolean;

294

handheld?: boolean;

295

print?: boolean;

296

projection?: boolean;

297

screen?: boolean;

298

tty?: boolean;

299

tv?: boolean;

300

embossed?: boolean;

301

302

// Min/max variants for all dimension properties

303

minWidth?: number | string;

304

maxWidth?: number | string;

305

minHeight?: number | string;

306

maxHeight?: number | string;

307

minDeviceWidth?: number | string;

308

maxDeviceWidth?: number | string;

309

minDeviceHeight?: number | string;

310

maxDeviceHeight?: number | string;

311

minAspectRatio?: string;

312

maxAspectRatio?: string;

313

minDeviceAspectRatio?: string;

314

maxDeviceAspectRatio?: string;

315

minColor?: number;

316

maxColor?: number;

317

minColorIndex?: number;

318

maxColorIndex?: number;

319

minMonochrome?: number;

320

maxMonochrome?: number;

321

minResolution?: number | string;

322

maxResolution?: number | string;

323

}

324

```

325

326

### Advanced Context Patterns

327

328

**Dynamic Context Updates:**

329

330

```typescript

331

import React, { createContext, useContext, useState, useEffect } from "react";

332

import { Context as ResponsiveContext } from "react-responsive";

333

334

// Custom context that updates based on actual window size

335

const DynamicResponsiveProvider = ({ children }: { children: React.ReactNode }) => {

336

const [deviceSettings, setDeviceSettings] = useState({

337

width: typeof window !== "undefined" ? window.innerWidth : 1024,

338

height: typeof window !== "undefined" ? window.innerHeight : 768,

339

});

340

341

useEffect(() => {

342

const handleResize = () => {

343

setDeviceSettings({

344

width: window.innerWidth,

345

height: window.innerHeight,

346

});

347

};

348

349

window.addEventListener("resize", handleResize);

350

return () => window.removeEventListener("resize", handleResize);

351

}, []);

352

353

return (

354

<ResponsiveContext.Provider value={deviceSettings}>

355

{children}

356

</ResponsiveContext.Provider>

357

);

358

};

359

```

360

361

## Type Definitions

362

363

```typescript { .api }

364

import { Context } from "react";

365

366

const Context: Context<Partial<MediaQueryAllQueryable> | undefined>;

367

368

function toQuery(obj: Partial<MediaQueryAllQueryable>): string;

369

370

interface MediaQueryAllQueryable {

371

// Complete interface with all media query properties

372

// (See full definition in index.md)

373

}

374

```