or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-hooks.mdcomponent-extensions.mdcontent-rendering.mdcore-integration.mdeditor-hooks.mdindex.mdtable-extensions.mdui-components.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

React-specific utility functions for element manipulation, type checking, and React component handling.

3

4

## Capabilities

5

6

### Element Utilities

7

8

Functions for working with React elements and their properties.

9

10

```typescript { .api }

11

/**

12

* Add key prop to React element for use in arrays

13

* @param element - React element to add key to

14

* @param key - Key value to add

15

* @returns Element with key prop added

16

*/

17

function addKeyToElement(element: ReactElement, key: string): ReactElement;

18

19

/**

20

* Extract props from JSX element

21

* @param element - React element to extract props from

22

* @returns Props object or empty object if not valid element

23

*/

24

function getElementProps(element: ReactElement): Record<string, any>;

25

```

26

27

**Usage Example:**

28

29

```typescript

30

import React from 'react';

31

import { addKeyToElement, getElementProps } from '@remirror/react';

32

33

function DynamicList({ items }) {

34

const elementList = items.map((item, index) => {

35

const element = <div>{item.content}</div>;

36

return addKeyToElement(element, `item-${index}`);

37

});

38

39

const firstElementProps = getElementProps(elementList[0]);

40

console.log('First element props:', firstElementProps);

41

42

return <div>{elementList}</div>;

43

}

44

```

45

46

### Type Checking Utilities

47

48

Functions for validating React elements and components.

49

50

```typescript { .api }

51

/**

52

* Check if value is a React DOM element (not a custom component)

53

* @param element - Value to check

54

* @returns True if element is a React DOM element

55

*/

56

function isReactDOMElement(element: unknown): element is ReactElement<any, string>;

57

58

/**

59

* Check if value is a React Fragment

60

* @param element - Value to check

61

* @returns True if element is a React Fragment

62

*/

63

function isReactFragment(element: unknown): element is ReactElement<any, typeof React.Fragment>;

64

65

/**

66

* Drop-in replacement for React.isValidElement with enhanced type checking

67

* @param element - Value to check

68

* @returns True if element is a valid React element

69

*/

70

function isValidElement(element: unknown): element is ReactElement;

71

```

72

73

**Usage Example:**

74

75

```typescript

76

import React from 'react';

77

import {

78

isReactDOMElement,

79

isReactFragment,

80

isValidElement

81

} from '@remirror/react';

82

83

function ElementAnalyzer({ children }) {

84

const analyzeChild = (child) => {

85

if (!isValidElement(child)) {

86

return 'Not a React element';

87

}

88

89

if (isReactFragment(child)) {

90

return 'React Fragment';

91

}

92

93

if (isReactDOMElement(child)) {

94

return `DOM Element: ${child.type}`;

95

}

96

97

return `Custom Component: ${child.type.name || 'Anonymous'}`;

98

};

99

100

return (

101

<div>

102

{React.Children.map(children, (child, index) => (

103

<div key={index}>

104

Child {index}: {analyzeChild(child)}

105

</div>

106

))}

107

</div>

108

);

109

}

110

```

111

112

### Prop Validation Utilities

113

114

Functions for validating component props and function props.

115

116

```typescript { .api }

117

/**

118

* Validate that a prop is a function, throws error if not

119

* @param prop - Property value to validate

120

* @param propName - Name of the property for error messages

121

* @throws Error if prop is not a function

122

*/

123

function propIsFunction(prop: unknown, propName: string): asserts prop is Function;

124

```

125

126

**Usage Example:**

127

128

```typescript

129

import React from 'react';

130

import { propIsFunction } from '@remirror/react';

131

132

interface CallbackComponentProps {

133

onAction: Function;

134

onError?: Function;

135

data: any;

136

}

137

138

function CallbackComponent({ onAction, onError, data }: CallbackComponentProps) {

139

// Validate required function props

140

propIsFunction(onAction, 'onAction');

141

142

// Validate optional function props

143

if (onError) {

144

propIsFunction(onError, 'onError');

145

}

146

147

const handleClick = () => {

148

try {

149

onAction(data);

150

} catch (error) {

151

onError?.(error);

152

}

153

};

154

155

return <button onClick={handleClick}>Execute Action</button>;

156

}

157

```

158

159

### Advanced Element Manipulation

160

161

More sophisticated utilities for working with React elements.

162

163

```typescript { .api }

164

/**

165

* Clone element with additional props, preserving existing props

166

* @param element - Element to clone

167

* @param additionalProps - Props to add or override

168

* @returns Cloned element with merged props

169

*/

170

function cloneElementWithProps(

171

element: ReactElement,

172

additionalProps: Record<string, any>

173

): ReactElement;

174

175

/**

176

* Recursively map over React children, including nested structures

177

* @param children - React children to map over

178

* @param mapFn - Function to apply to each child

179

* @returns Mapped children

180

*/

181

function deepMapChildren(

182

children: React.ReactNode,

183

mapFn: (child: ReactElement, index: number, depth: number) => ReactElement

184

): React.ReactNode;

185

186

/**

187

* Filter React children based on a predicate function

188

* @param children - React children to filter

189

* @param predicate - Function to test each child

190

* @returns Filtered children

191

*/

192

function filterChildren(

193

children: React.ReactNode,

194

predicate: (child: ReactElement, index: number) => boolean

195

): React.ReactNode;

196

197

/**

198

* Find first child element matching a predicate

199

* @param children - React children to search

200

* @param predicate - Function to test each child

201

* @returns First matching child or undefined

202

*/

203

function findChild(

204

children: React.ReactNode,

205

predicate: (child: ReactElement, index: number) => boolean

206

): ReactElement | undefined;

207

```

208

209

**Usage Example:**

210

211

```typescript

212

import React from 'react';

213

import {

214

cloneElementWithProps,

215

deepMapChildren,

216

filterChildren,

217

findChild

218

} from '@remirror/react';

219

220

function EnhancedContainer({ children, theme }) {

221

// Add theme prop to all child elements

222

const themedChildren = deepMapChildren(children, (child, index, depth) => {

223

return cloneElementWithProps(child, {

224

theme,

225

depth,

226

'data-index': index,

227

});

228

});

229

230

// Filter out hidden children

231

const visibleChildren = filterChildren(themedChildren, (child) => {

232

return child.props.hidden !== true;

233

});

234

235

// Find first button child

236

const firstButton = findChild(visibleChildren, (child) => {

237

return child.type === 'button' || child.type?.name === 'Button';

238

});

239

240

return (

241

<div className="enhanced-container">

242

{firstButton && (

243

<div className="primary-action">

244

{cloneElementWithProps(firstButton, { primary: true })}

245

</div>

246

)}

247

<div className="other-children">

248

{visibleChildren}

249

</div>

250

</div>

251

);

252

}

253

```

254

255

### Component Analysis Utilities

256

257

Functions for analyzing React component structures and hierarchies.

258

259

```typescript { .api }

260

/**

261

* Get the display name of a React component

262

* @param component - Component to get name from

263

* @returns Component display name or 'Anonymous'

264

*/

265

function getComponentName(component: ComponentType): string;

266

267

/**

268

* Check if component is a class component

269

* @param component - Component to check

270

* @returns True if component is a class component

271

*/

272

function isClassComponent(component: ComponentType): boolean;

273

274

/**

275

* Check if component is a function component

276

* @param component - Component to check

277

* @returns True if component is a function component

278

*/

279

function isFunctionComponent(component: ComponentType): boolean;

280

281

/**

282

* Check if component is a memo component

283

* @param component - Component to check

284

* @returns True if component is wrapped with React.memo

285

*/

286

function isMemoComponent(component: ComponentType): boolean;

287

288

/**

289

* Check if component is a forwardRef component

290

* @param component - Component to check

291

* @returns True if component is wrapped with React.forwardRef

292

*/

293

function isForwardRefComponent(component: ComponentType): boolean;

294

```

295

296

**Usage Example:**

297

298

```typescript

299

import React from 'react';

300

import {

301

getComponentName,

302

isClassComponent,

303

isFunctionComponent,

304

isMemoComponent,

305

isForwardRefComponent

306

} from '@remirror/react';

307

308

function ComponentInspector({ component }) {

309

const analysis = {

310

name: getComponentName(component),

311

isClass: isClassComponent(component),

312

isFunction: isFunctionComponent(component),

313

isMemo: isMemoComponent(component),

314

isForwardRef: isForwardRefComponent(component),

315

};

316

317

return (

318

<div className="component-analysis">

319

<h3>Component Analysis</h3>

320

<ul>

321

<li>Name: {analysis.name}</li>

322

<li>Type: {analysis.isClass ? 'Class' : 'Function'}</li>

323

<li>Memoized: {analysis.isMemo ? 'Yes' : 'No'}</li>

324

<li>Forward Ref: {analysis.isForwardRef ? 'Yes' : 'No'}</li>

325

</ul>

326

</div>

327

);

328

}

329

```

330

331

### Event Utilities

332

333

Helper functions for working with React events and event handlers.

334

335

```typescript { .api }

336

/**

337

* Create a debounced event handler

338

* @param handler - Original event handler

339

* @param delay - Debounce delay in milliseconds

340

* @returns Debounced event handler

341

*/

342

function debounceEventHandler<T extends (...args: any[]) => void>(

343

handler: T,

344

delay: number

345

): T;

346

347

/**

348

* Create a throttled event handler

349

* @param handler - Original event handler

350

* @param interval - Throttle interval in milliseconds

351

* @returns Throttled event handler

352

*/

353

function throttleEventHandler<T extends (...args: any[]) => void>(

354

handler: T,

355

interval: number

356

): T;

357

358

/**

359

* Combine multiple event handlers into one

360

* @param handlers - Array of event handlers

361

* @returns Combined event handler

362

*/

363

function combineEventHandlers<T extends (...args: any[]) => void>(

364

...handlers: (T | undefined)[]

365

): T;

366

367

/**

368

* Stop event propagation and prevent default

369

* @param event - React event or native event

370

*/

371

function stopEvent(event: React.SyntheticEvent | Event): void;

372

```

373

374

**Usage Example:**

375

376

```typescript

377

import React, { useState } from 'react';

378

import {

379

debounceEventHandler,

380

throttleEventHandler,

381

combineEventHandlers,

382

stopEvent

383

} from '@remirror/react';

384

385

function SmartInput({ onChange, onFocus, onBlur, onKeyDown }) {

386

const [value, setValue] = useState('');

387

388

// Debounce onChange to avoid excessive API calls

389

const debouncedOnChange = debounceEventHandler(onChange, 300);

390

391

// Throttle scroll event handler

392

const throttledScroll = throttleEventHandler((e) => {

393

console.log('Scroll position:', e.target.scrollTop);

394

}, 100);

395

396

// Combine multiple key handlers

397

const combinedKeyHandler = combineEventHandlers(

398

onKeyDown,

399

(e) => {

400

if (e.key === 'Escape') {

401

stopEvent(e);

402

setValue('');

403

}

404

}

405

);

406

407

const handleChange = (e) => {

408

setValue(e.target.value);

409

debouncedOnChange(e.target.value);

410

};

411

412

return (

413

<input

414

value={value}

415

onChange={handleChange}

416

onFocus={onFocus}

417

onBlur={onBlur}

418

onKeyDown={combinedKeyHandler}

419

onScroll={throttledScroll}

420

/>

421

);

422

}

423

```

424

425

## Type Definitions

426

427

```typescript { .api }

428

/**

429

* Generic component type that accepts any props

430

*/

431

type ComponentType<P = {}> = React.ComponentType<P>;

432

433

/**

434

* Props with children

435

*/

436

interface PropsWithChildren<P = {}> extends P {

437

children?: React.ReactNode;

438

}

439

440

/**

441

* Props with optional className

442

*/

443

interface PropsWithClassName<P = {}> extends P {

444

className?: string;

445

}

446

447

/**

448

* Element properties for HTML elements

449

*/

450

type HTMLElementProps<T = HTMLElement> = React.HTMLAttributes<T>;

451

452

/**

453

* Event handler type for React events

454

*/

455

type EventHandler<E = React.SyntheticEvent> = (event: E) => void;

456

457

/**

458

* Ref type for React elements

459

*/

460

type ElementRef<T = HTMLElement> = React.RefObject<T> | React.MutableRefObject<T>;

461

```

462

463

## Performance Utilities

464

465

```typescript { .api }

466

/**

467

* Memoize a component with custom comparison

468

* @param component - Component to memoize

469

* @param areEqual - Custom equality function

470

* @returns Memoized component

471

*/

472

function memoizeComponent<P>(

473

component: ComponentType<P>,

474

areEqual?: (prevProps: P, nextProps: P) => boolean

475

): React.MemoExoticComponent<ComponentType<P>>;

476

477

/**

478

* Create a stable callback that doesn't change on re-renders

479

* @param callback - Callback function

480

* @param deps - Dependency array

481

* @returns Stable callback

482

*/

483

function useStableCallback<T extends (...args: any[]) => any>(

484

callback: T,

485

deps: React.DependencyList

486

): T;

487

488

/**

489

* Lazy load a component with optional loading fallback

490

* @param importFn - Dynamic import function

491

* @param fallback - Loading component

492

* @returns Lazy component

493

*/

494

function lazyComponent<P>(

495

importFn: () => Promise<{ default: ComponentType<P> }>,

496

fallback?: ComponentType

497

): React.LazyExoticComponent<ComponentType<P>>;

498

```