or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

colors.mddata-display.mdfeedback.mdforms.mdindex.mdinputs.mdlayout.mdnavigation.mdstyling.mdsurfaces.mdutilities.md

utilities.mddocs/

0

# Utility Components

1

2

Utility components for common functionality including click-away listeners, portals, transitions, and hooks.

3

4

## Capabilities

5

6

### ClickAwayListener

7

8

Utility component for detecting clicks outside an element.

9

10

```typescript { .api }

11

/**

12

* Utility component for detecting clicks outside element

13

* @param props - ClickAwayListener configuration

14

* @returns ClickAwayListener component

15

*/

16

function ClickAwayListener(props: ClickAwayListenerProps): JSX.Element;

17

18

interface ClickAwayListenerProps {

19

/** The wrapped element */

20

children: React.ReactElement;

21

/** If true, the React tree is ignored and only the DOM tree is considered */

22

disableReactTree?: boolean;

23

/** The mouse event to listen to */

24

mouseEvent?: 'onClick' | 'onMouseDown' | 'onMouseUp' | false;

25

/** Callback fired when a "click away" event is detected */

26

onClickAway: (event: MouseEvent | TouchEvent) => void;

27

/** The touch event to listen to */

28

touchEvent?: 'onTouchStart' | 'onTouchEnd' | false;

29

}

30

```

31

32

### Portal

33

34

Component for rendering children into a DOM node outside the normal hierarchy.

35

36

```typescript { .api }

37

/**

38

* Component for rendering children outside normal hierarchy

39

* @param props - Portal configuration

40

* @returns Portal component

41

*/

42

function Portal(props: PortalProps): JSX.Element;

43

44

interface PortalProps {

45

/** The children to render into the container */

46

children?: React.ReactNode;

47

/** An HTML element or a function that returns one */

48

container?: Element | (() => Element | null) | null;

49

/** If true, the children stay within their DOM hierarchy */

50

disablePortal?: boolean;

51

}

52

```

53

54

### Transitions

55

56

Transition components for animating component state changes.

57

58

```typescript { .api }

59

/**

60

* Fade transition component

61

* @param props - Fade configuration

62

* @returns Fade component

63

*/

64

function Fade(props: FadeProps): JSX.Element;

65

66

/**

67

* Grow transition component

68

* @param props - Grow configuration

69

* @returns Grow component

70

*/

71

function Grow(props: GrowProps): JSX.Element;

72

73

/**

74

* Slide transition component

75

* @param props - Slide configuration

76

* @returns Slide component

77

*/

78

function Slide(props: SlideProps): JSX.Element;

79

80

/**

81

* Collapse transition component

82

* @param props - Collapse configuration

83

* @returns Collapse component

84

*/

85

function Collapse(props: CollapseProps): JSX.Element;

86

87

/**

88

* Zoom transition component

89

* @param props - Zoom configuration

90

* @returns Zoom component

91

*/

92

function Zoom(props: ZoomProps): JSX.Element;

93

94

interface FadeProps extends TransitionProps {

95

/** A single child content element */

96

children?: React.ReactElement;

97

/** The transition timing function */

98

easing?: {

99

enter?: string;

100

exit?: string;

101

} | string;

102

/** If true, the component will transition in */

103

in?: boolean;

104

/** The duration for the transition */

105

timeout?: number | {

106

appear?: number;

107

enter?: number;

108

exit?: number;

109

};

110

}

111

112

interface GrowProps extends TransitionProps {

113

/** A single child content element */

114

children?: React.ReactElement;

115

/** If true, the component will transition in */

116

in?: boolean;

117

/** The duration for the transition */

118

timeout?: number | 'auto' | {

119

appear?: number;

120

enter?: number;

121

exit?: number;

122

};

123

}

124

125

interface SlideProps extends TransitionProps {

126

/** A single child content element */

127

children?: React.ReactElement;

128

/** An HTML element, or a function that returns one */

129

container?: Element | (() => Element | null) | null;

130

/** Direction the child node will enter from */

131

direction?: 'left' | 'right' | 'up' | 'down';

132

/** If true, the component will transition in */

133

in?: boolean;

134

/** The duration for the transition */

135

timeout?: number | {

136

appear?: number;

137

enter?: number;

138

exit?: number;

139

};

140

}

141

142

interface CollapseProps extends TransitionProps {

143

/** The content node to be collapsed */

144

children?: React.ReactNode;

145

/** The width (horizontal) or height (vertical) of the container when collapsed */

146

collapsedSize?: number | string;

147

/** The component used for the root node */

148

component?: React.ElementType;

149

/** If true, the component will transition in */

150

in?: boolean;

151

/** The collapse transition orientation */

152

orientation?: 'horizontal' | 'vertical';

153

/** The duration for the transition */

154

timeout?: number | 'auto' | {

155

appear?: number;

156

enter?: number;

157

exit?: number;

158

};

159

}

160

161

interface ZoomProps extends TransitionProps {

162

/** A single child content element */

163

children?: React.ReactElement;

164

/** If true, the component will transition in */

165

in?: boolean;

166

/** The duration for the transition */

167

timeout?: number | {

168

appear?: number;

169

enter?: number;

170

exit?: number;

171

};

172

}

173

```

174

175

**Usage Examples:**

176

177

```typescript

178

import {

179

ClickAwayListener,

180

Portal,

181

Fade,

182

Grow,

183

Slide,

184

Collapse,

185

Zoom,

186

Box,

187

Button,

188

Paper

189

} from "@mui/material";

190

191

// ClickAwayListener example

192

function DropdownMenu() {

193

const [open, setOpen] = useState(false);

194

195

const handleClickAway = () => {

196

setOpen(false);

197

};

198

199

return (

200

<ClickAwayListener onClickAway={handleClickAway}>

201

<Box>

202

<Button onClick={() => setOpen(!open)}>

203

Toggle Menu

204

</Button>

205

{open && (

206

<Paper sx={{ position: 'absolute', mt: 1, p: 1 }}>

207

Menu content

208

</Paper>

209

)}

210

</Box>

211

</ClickAwayListener>

212

);

213

}

214

215

// Portal example

216

<Portal container={document.body}>

217

<Box sx={{ position: 'fixed', top: 0, left: 0, zIndex: 9999 }}>

218

This content is rendered in document.body

219

</Box>

220

</Portal>

221

222

// Transition examples

223

<Fade in={fadeIn} timeout={500}>

224

<Box>Fade transition content</Box>

225

</Fade>

226

227

<Grow in={growIn} timeout={300}>

228

<Paper elevation={4} sx={{ p: 2 }}>

229

Grow transition content

230

</Paper>

231

</Grow>

232

233

<Slide direction="up" in={slideIn} mountOnEnter unmountOnExit>

234

<Alert severity="success">

235

Slide transition alert

236

</Alert>

237

</Slide>

238

239

<Collapse in={collapseIn}>

240

<Box sx={{ p: 2, bgcolor: 'background.paper' }}>

241

Collapsible content that can be hidden or shown

242

</Box>

243

</Collapse>

244

```

245

246

### Hooks

247

248

Utility hooks for common functionality.

249

250

```typescript { .api }

251

/**

252

* Hook for responsive design with media queries

253

* @param query - Media query string or function

254

* @param options - Additional options

255

* @returns Boolean indicating if query matches

256

*/

257

function useMediaQuery<Theme = DefaultTheme>(

258

query: string | ((theme: Theme) => string),

259

options?: UseMediaQueryOptions

260

): boolean;

261

262

/**

263

* Hook for triggering actions based on scroll position

264

* @param options - Scroll trigger options

265

* @returns Boolean indicating if trigger is active

266

*/

267

function useScrollTrigger(options?: UseScrollTriggerOptions): boolean;

268

269

interface UseMediaQueryOptions {

270

/** The default value for the match result */

271

defaultMatches?: boolean;

272

/** Whether to match during hydration */

273

matchMedia?: (query: string) => { matches: boolean; media: string; onchange: any; addListener: any; removeListener: any; };

274

/** If true, the hook will not re-render on media query changes */

275

noSsr?: boolean;

276

/** If true, SSR compatibility mode is enabled */

277

ssrMatchMedia?: (query: string) => { matches: boolean };

278

}

279

280

interface UseScrollTriggerOptions {

281

/** The node to listen to for scroll events */

282

target?: Node | Window;

283

/** If true, hide trigger will be true when scrolling down */

284

disableHysteresis?: boolean;

285

/** The scroll threshold */

286

threshold?: number;

287

}

288

```

289

290

**Usage Examples:**

291

292

```typescript

293

import { useMediaQuery, useScrollTrigger, useTheme } from "@mui/material";

294

import { AppBar, Toolbar, Typography, Slide } from "@mui/material";

295

296

// Media query hook

297

function ResponsiveComponent() {

298

const theme = useTheme();

299

const isMobile = useMediaQuery(theme.breakpoints.down('md'));

300

const isTablet = useMediaQuery(theme.breakpoints.between('md', 'lg'));

301

const isDesktop = useMediaQuery(theme.breakpoints.up('lg'));

302

303

return (

304

<Box>

305

{isMobile && <Typography>Mobile View</Typography>}

306

{isTablet && <Typography>Tablet View</Typography>}

307

{isDesktop && <Typography>Desktop View</Typography>}

308

</Box>

309

);

310

}

311

312

// Scroll trigger hook

313

function HideOnScroll({ children }: { children: React.ReactElement }) {

314

const trigger = useScrollTrigger({

315

target: window,

316

disableHysteresis: true,

317

threshold: 100,

318

});

319

320

return (

321

<Slide appear={false} direction="down" in={!trigger}>

322

{children}

323

</Slide>

324

);

325

}

326

327

// Usage with AppBar

328

<HideOnScroll>

329

<AppBar>

330

<Toolbar>

331

<Typography variant="h6">Hide on Scroll AppBar</Typography>

332

</Toolbar>

333

</AppBar>

334

</HideOnScroll>

335

```

336

337

### NoSsr

338

339

Utility component for preventing server-side rendering.

340

341

```typescript { .api }

342

/**

343

* Utility component for preventing server-side rendering

344

* @param props - NoSsr configuration

345

* @returns NoSsr component

346

*/

347

function NoSsr(props: NoSsrProps): JSX.Element;

348

349

interface NoSsrProps {

350

/** The content */

351

children?: React.ReactNode;

352

/** If true, the component will defer the rendering of the children into a different screen frame */

353

defer?: boolean;

354

/** The fallback content to display during SSR */

355

fallback?: React.ReactNode;

356

}

357

```

358

359

### TextareaAutosize

360

361

Auto-resizing textarea component.

362

363

```typescript { .api }

364

/**

365

* Auto-resizing textarea component

366

* @param props - TextareaAutosize configuration

367

* @returns TextareaAutosize component

368

*/

369

function TextareaAutosize(props: TextareaAutosizeProps): JSX.Element;

370

371

interface TextareaAutosizeProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {

372

/** Maximum number of rows to display */

373

maxRows?: number;

374

/** Minimum number of rows to display */

375

minRows?: number;

376

/** Callback fired when the textarea is resized */

377

onResize?: (event: Event) => void;

378

}

379

```

380

381

**Usage Examples:**

382

383

```typescript

384

import { NoSsr, TextareaAutosize, Box } from "@mui/material";

385

386

// NoSsr example - useful for components that behave differently on client vs server

387

<NoSsr fallback={<Box>Loading...</Box>}>

388

<SomeClientOnlyComponent />

389

</NoSsr>

390

391

// TextareaAutosize example

392

<TextareaAutosize

393

minRows={3}

394

maxRows={10}

395

placeholder="Enter your message here..."

396

style={{

397

width: '100%',

398

fontSize: '16px',

399

fontFamily: 'inherit',

400

padding: '8px',

401

border: '1px solid #ccc',

402

borderRadius: '4px',

403

resize: 'none',

404

}}

405

/>

406

```

407

408

## Common Utility Patterns

409

410

### Conditional Rendering with Media Queries

411

412

```typescript

413

import { useMediaQuery, useTheme, Hidden } from "@mui/material";

414

415

function ConditionalContent() {

416

const theme = useTheme();

417

const isMobile = useMediaQuery(theme.breakpoints.down('md'));

418

419

return (

420

<Box>

421

{/* Using hook */}

422

{isMobile ? (

423

<MobileNavigation />

424

) : (

425

<DesktopNavigation />

426

)}

427

428

{/* Using Hidden component (deprecated but still available) */}

429

<Hidden mdDown>

430

<DesktopSidebar />

431

</Hidden>

432

<Hidden mdUp>

433

<MobileDrawer />

434

</Hidden>

435

</Box>

436

);

437

}

438

```

439

440

### Scroll-based Interactions

441

442

```typescript

443

import { useScrollTrigger, Fab, Zoom } from "@mui/material";

444

import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";

445

446

function ScrollToTop() {

447

const trigger = useScrollTrigger({

448

disableHysteresis: true,

449

threshold: 100,

450

});

451

452

const handleClick = () => {

453

window.scrollTo({

454

top: 0,

455

behavior: 'smooth',

456

});

457

};

458

459

return (

460

<Zoom in={trigger}>

461

<Fab

462

onClick={handleClick}

463

color="primary"

464

size="small"

465

aria-label="scroll back to top"

466

sx={{

467

position: 'fixed',

468

bottom: 16,

469

right: 16,

470

}}

471

>

472

<KeyboardArrowUpIcon />

473

</Fab>

474

</Zoom>

475

);

476

}

477

```