or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-vnodes.mdchildren-utilities.mdcore-components.mddom-operations.mdelement-creation.mdindex.mdproptypes.md
tile.json

advanced-vnodes.mddocs/

0

# Advanced VNode Functions

1

2

Lower-level VNode creation and manipulation functions for advanced use cases, providing direct access to Inferno's virtual DOM internals while maintaining React compatibility.

3

4

## Capabilities

5

6

### createVNode Function

7

8

Creates virtual DOM nodes with explicit flags and properties for maximum control.

9

10

```typescript { .api }

11

/**

12

* Creates a virtual DOM node with explicit configuration

13

* @param flags - VNode flags defining element type and behavior

14

* @param type - Element type (string for DOM, function/class for components)

15

* @param className - CSS class name for the element

16

* @param children - Child nodes

17

* @param childFlags - Flags describing children structure

18

* @param props - Element properties and attributes

19

* @param key - Unique key for reconciliation

20

* @param ref - Reference to DOM element or component instance

21

* @returns VNode representing the virtual DOM element

22

*/

23

function createVNode(

24

flags: number,

25

type: string | ComponentClass<any> | Function | null,

26

className?: string,

27

children?: InfernoNode,

28

childFlags?: number,

29

props?: any,

30

key?: string | number,

31

ref?: any

32

): VNode;

33

```

34

35

**Usage Examples:**

36

37

```typescript

38

import { createVNode, VNodeFlags } from "inferno-compat";

39

40

// Create a simple element VNode

41

const div = createVNode(

42

VNodeFlags.HtmlElement,

43

'div',

44

'container',

45

'Hello World',

46

VNodeFlags.HasNonKeyedChildren,

47

{ id: 'main' },

48

'unique-key'

49

);

50

51

// Create a component VNode

52

function MyComponent(props) {

53

return createVNode(VNodeFlags.HtmlElement, 'span', null, props.text);

54

}

55

56

const component = createVNode(

57

VNodeFlags.ComponentFunction,

58

MyComponent,

59

null,

60

null,

61

VNodeFlags.HasNonKeyedChildren,

62

{ text: 'Component text' },

63

'component-key'

64

);

65

66

// Create VNode with ref

67

let elementRef;

68

const withRef = createVNode(

69

VNodeFlags.HtmlElement,

70

'input',

71

'form-input',

72

null,

73

VNodeFlags.HasNonKeyedChildren,

74

{ type: 'text', placeholder: 'Enter text' },

75

null,

76

(ref) => { elementRef = ref; }

77

);

78

```

79

80

### createComponentVNode Function

81

82

Creates VNodes specifically for React/Inferno components.

83

84

```typescript { .api }

85

/**

86

* Creates a VNode for a component (class or function)

87

* @param flags - Component flags (ComponentClass or ComponentFunction)

88

* @param type - Component class or function

89

* @param props - Component props

90

* @param key - Unique key for reconciliation

91

* @param ref - Reference to component instance

92

* @returns VNode for the component

93

*/

94

function createComponentVNode(

95

flags: number,

96

type: ComponentClass<any> | Function,

97

props?: any,

98

key?: string | number,

99

ref?: any

100

): VNode;

101

```

102

103

**Usage Examples:**

104

105

```typescript

106

import { createComponentVNode, VNodeFlags, Component } from "inferno-compat";

107

108

class UserProfile extends Component {

109

render() {

110

return <div>User: {this.props.name}</div>;

111

}

112

}

113

114

// Create class component VNode

115

const classComponent = createComponentVNode(

116

VNodeFlags.ComponentClass,

117

UserProfile,

118

{ name: 'Alice', age: 30 },

119

'user-profile',

120

(instance) => console.log('Component mounted:', instance)

121

);

122

123

// Function component VNode

124

function WelcomeMessage({ message }) {

125

return <h1>{message}</h1>;

126

}

127

128

const functionComponent = createComponentVNode(

129

VNodeFlags.ComponentFunction,

130

WelcomeMessage,

131

{ message: 'Welcome to our app!' },

132

'welcome-message'

133

);

134

135

// Higher-order component pattern

136

function withLogging(WrappedComponent) {

137

function LoggingComponent(props) {

138

console.log('Rendering with props:', props);

139

return createComponentVNode(

140

VNodeFlags.ComponentFunction,

141

WrappedComponent,

142

props

143

);

144

}

145

return LoggingComponent;

146

}

147

148

const EnhancedComponent = withLogging(WelcomeMessage);

149

const enhanced = createComponentVNode(

150

VNodeFlags.ComponentFunction,

151

EnhancedComponent,

152

{ message: 'Enhanced message' }

153

);

154

```

155

156

### createTextVNode Function

157

158

Creates text nodes for efficient text rendering.

159

160

```typescript { .api }

161

/**

162

* Creates a text VNode for rendering text content

163

* @param text - Text content to render

164

* @param key - Optional key for reconciliation

165

* @returns VNode representing text content

166

*/

167

function createTextVNode(text: string | number, key?: string | number): VNode;

168

```

169

170

**Usage Examples:**

171

172

```typescript

173

import { createTextVNode, createVNode, VNodeFlags } from "inferno-compat";

174

175

// Simple text node

176

const greeting = createTextVNode('Hello World!');

177

178

// Text with key for lists

179

const listItems = ['Apple', 'Banana', 'Cherry'].map((fruit, index) =>

180

createVNode(

181

VNodeFlags.HtmlElement,

182

'li',

183

null,

184

createTextVNode(fruit, `fruit-${index}`),

185

VNodeFlags.HasNonKeyedChildren,

186

null,

187

`item-${index}`

188

)

189

);

190

191

// Dynamic text content

192

function DynamicText({ value, formatter }) {

193

const formattedValue = formatter ? formatter(value) : value;

194

return createTextVNode(formattedValue);

195

}

196

197

// Conditional text rendering

198

function StatusText({ status }) {

199

const text = status === 'loading'

200

? createTextVNode('Loading...', 'loading-text')

201

: createTextVNode(`Status: ${status}`, 'status-text');

202

203

return createVNode(

204

VNodeFlags.HtmlElement,

205

'span',

206

`status ${status}`,

207

text

208

);

209

}

210

211

// Number text nodes

212

const counter = createTextVNode(42);

213

const price = createTextVNode(19.99);

214

```

215

216

### createFragment Function

217

218

Creates fragment nodes for grouping elements without DOM wrappers.

219

220

```typescript { .api }

221

/**

222

* Creates a fragment VNode for grouping multiple elements

223

* @param children - Array of child VNodes

224

* @param childFlags - Flags describing children structure

225

* @param key - Optional key for reconciliation

226

* @returns Fragment VNode containing the children

227

*/

228

function createFragment(

229

children: InfernoNode[],

230

childFlags?: number,

231

key?: string | number

232

): VNode;

233

```

234

235

**Usage Examples:**

236

237

```typescript

238

import { createFragment, createVNode, createTextVNode, VNodeFlags } from "inferno-compat";

239

240

// Simple fragment

241

const fragment = createFragment([

242

createVNode(VNodeFlags.HtmlElement, 'h1', null, createTextVNode('Title')),

243

createVNode(VNodeFlags.HtmlElement, 'p', null, createTextVNode('Content'))

244

], VNodeFlags.HasNonKeyedChildren);

245

246

// Fragment in conditional rendering

247

function ConditionalContent({ showDetails, title, content }) {

248

if (!showDetails) {

249

return createTextVNode(title);

250

}

251

252

return createFragment([

253

createVNode(VNodeFlags.HtmlElement, 'h2', null, createTextVNode(title)),

254

createVNode(VNodeFlags.HtmlElement, 'p', null, createTextVNode(content)),

255

createVNode(VNodeFlags.HtmlElement, 'button', null, createTextVNode('Close'))

256

], VNodeFlags.HasNonKeyedChildren, 'details-fragment');

257

}

258

259

// Fragment for list items

260

function TableRow({ cells }) {

261

const cellVNodes = cells.map((cell, index) =>

262

createVNode(

263

VNodeFlags.HtmlElement,

264

'td',

265

null,

266

createTextVNode(cell),

267

VNodeFlags.HasNonKeyedChildren,

268

null,

269

`cell-${index}`

270

)

271

);

272

273

return createFragment(cellVNodes, VNodeFlags.HasKeyedChildren, 'table-row');

274

}

275

276

// Nested fragments

277

const nestedFragment = createFragment([

278

createTextVNode('Before nested'),

279

createFragment([

280

createVNode(VNodeFlags.HtmlElement, 'span', null, createTextVNode('Nested 1')),

281

createVNode(VNodeFlags.HtmlElement, 'span', null, createTextVNode('Nested 2'))

282

], VNodeFlags.HasNonKeyedChildren, 'inner-fragment'),

283

createTextVNode('After nested')

284

], VNodeFlags.HasNonKeyedChildren, 'outer-fragment');

285

```

286

287

### createPortal Function

288

289

Creates portal nodes that render children into different DOM containers.

290

291

```typescript { .api }

292

/**

293

* Creates a portal VNode that renders children into a different DOM container

294

* @param children - VNodes to render in the portal

295

* @param container - DOM element to render the portal into

296

* @returns Portal VNode that renders children elsewhere

297

*/

298

function createPortal(

299

children: InfernoNode,

300

container: Element

301

): VNode;

302

```

303

304

**Usage Examples:**

305

306

```typescript

307

import { createPortal, createVNode, createTextVNode, VNodeFlags, Component } from "inferno-compat";

308

309

// Modal component using portal

310

class Modal extends Component {

311

constructor(props) {

312

super(props);

313

this.modalRoot = document.getElementById('modal-root') || document.body;

314

}

315

316

render() {

317

const modal = createVNode(

318

VNodeFlags.HtmlElement,

319

'div',

320

'modal-backdrop',

321

createVNode(

322

VNodeFlags.HtmlElement,

323

'div',

324

'modal-content',

325

this.props.children

326

)

327

);

328

329

return createPortal(modal, this.modalRoot);

330

}

331

}

332

333

// Tooltip component

334

function Tooltip({ children, content, targetRef }) {

335

if (!targetRef.current) return null;

336

337

const tooltip = createVNode(

338

VNodeFlags.HtmlElement,

339

'div',

340

'tooltip',

341

createTextVNode(content)

342

);

343

344

return createPortal(tooltip, targetRef.current.parentElement);

345

}

346

347

// Notification system

348

class NotificationManager extends Component {

349

constructor(props) {

350

super(props);

351

this.state = { notifications: [] };

352

this.notificationContainer = document.getElementById('notifications');

353

}

354

355

addNotification = (message, type = 'info') => {

356

const notification = {

357

id: Date.now(),

358

message,

359

type

360

};

361

362

this.setState(prevState => ({

363

notifications: [...prevState.notifications, notification]

364

}));

365

}

366

367

render() {

368

const { notifications } = this.state;

369

370

if (notifications.length === 0) return null;

371

372

const notificationList = createVNode(

373

VNodeFlags.HtmlElement,

374

'div',

375

'notification-list',

376

notifications.map(notification =>

377

createVNode(

378

VNodeFlags.HtmlElement,

379

'div',

380

`notification ${notification.type}`,

381

createTextVNode(notification.message),

382

VNodeFlags.HasNonKeyedChildren,

383

null,

384

notification.id

385

)

386

)

387

);

388

389

return createPortal(notificationList, this.notificationContainer);

390

}

391

}

392

```

393

394

### createRef Function

395

396

Creates ref objects for accessing DOM elements and component instances.

397

398

```typescript { .api }

399

/**

400

* Creates a ref object for accessing DOM elements or component instances

401

* @returns Ref object with current property

402

*/

403

function createRef<T = any>(): { current: T | null };

404

```

405

406

**Usage Examples:**

407

408

```typescript

409

import { createRef, createVNode, VNodeFlags, Component } from "inferno-compat";

410

411

class InputComponent extends Component {

412

constructor(props) {

413

super(props);

414

this.inputRef = createRef();

415

}

416

417

componentDidMount() {

418

// Focus the input after mounting

419

if (this.inputRef.current) {

420

this.inputRef.current.focus();

421

}

422

}

423

424

getValue = () => {

425

return this.inputRef.current ? this.inputRef.current.value : '';

426

}

427

428

render() {

429

return createVNode(

430

VNodeFlags.HtmlElement,

431

'input',

432

'form-input',

433

null,

434

VNodeFlags.HasNonKeyedChildren,

435

{

436

type: 'text',

437

placeholder: this.props.placeholder,

438

ref: this.inputRef

439

}

440

);

441

}

442

}

443

444

// Functional component with ref

445

function VideoPlayer({ src }) {

446

const videoRef = createRef();

447

448

const play = () => {

449

if (videoRef.current) {

450

videoRef.current.play();

451

}

452

};

453

454

const pause = () => {

455

if (videoRef.current) {

456

videoRef.current.pause();

457

}

458

};

459

460

return createFragment([

461

createVNode(

462

VNodeFlags.HtmlElement,

463

'video',

464

'video-player',

465

null,

466

VNodeFlags.HasNonKeyedChildren,

467

{ src, ref: videoRef }

468

),

469

createVNode(

470

VNodeFlags.HtmlElement,

471

'div',

472

'controls',

473

[

474

createVNode(

475

VNodeFlags.HtmlElement,

476

'button',

477

null,

478

createTextVNode('Play'),

479

VNodeFlags.HasNonKeyedChildren,

480

{ onClick: play }

481

),

482

createVNode(

483

VNodeFlags.HtmlElement,

484

'button',

485

null,

486

createTextVNode('Pause'),

487

VNodeFlags.HasNonKeyedChildren,

488

{ onClick: pause }

489

)

490

]

491

)

492

]);

493

}

494

```

495

496

### forwardRef Function

497

498

Creates components that forward refs to child elements.

499

500

```typescript { .api }

501

/**

502

* Creates a component that forwards refs to child elements

503

* @param render - Render function that receives props and ref

504

* @returns Component that forwards refs

505

*/

506

function forwardRef<T, P = {}>(

507

render: (props: P, ref: { current: T | null }) => InfernoNode

508

): ComponentType<P & { ref?: { current: T | null } }>;

509

```

510

511

**Usage Examples:**

512

513

```typescript

514

import { forwardRef, createVNode, VNodeFlags, createRef } from "inferno-compat";

515

516

// Forward ref to DOM element

517

const FancyButton = forwardRef((props, ref) => {

518

return createVNode(

519

VNodeFlags.HtmlElement,

520

'button',

521

`fancy-button ${props.variant || 'primary'}`,

522

createTextVNode(props.children),

523

VNodeFlags.HasNonKeyedChildren,

524

{

525

...props,

526

ref: ref

527

}

528

);

529

});

530

531

// Usage with ref

532

function App() {

533

const buttonRef = createRef();

534

535

const handleClick = () => {

536

if (buttonRef.current) {

537

buttonRef.current.classList.add('clicked');

538

}

539

};

540

541

return createVNode(

542

VNodeFlags.ComponentFunction,

543

FancyButton,

544

null,

545

null,

546

VNodeFlags.HasNonKeyedChildren,

547

{

548

variant: 'secondary',

549

onClick: handleClick,

550

ref: buttonRef,

551

children: 'Click Me'

552

}

553

);

554

}

555

556

// Forward ref to child component

557

const EnhancedInput = forwardRef((props, ref) => {

558

return createVNode(

559

VNodeFlags.HtmlElement,

560

'div',

561

'input-wrapper',

562

[

563

props.label && createVNode(

564

VNodeFlags.HtmlElement,

565

'label',

566

'input-label',

567

createTextVNode(props.label)

568

),

569

createVNode(

570

VNodeFlags.HtmlElement,

571

'input',

572

'enhanced-input',

573

null,

574

VNodeFlags.HasNonKeyedChildren,

575

{

576

...props,

577

ref: ref

578

}

579

)

580

]

581

);

582

});

583

```

584

585

### VNode Flags

586

587

Understanding VNode flags is crucial for advanced VNode manipulation:

588

589

```typescript { .api }

590

enum VNodeFlags {

591

// Element types

592

HtmlElement = 1,

593

SvgElement = 2,

594

InputElement = 4,

595

TextareaElement = 8,

596

SelectElement = 16,

597

598

// Component types

599

ComponentFunction = 32,

600

ComponentClass = 64,

601

ComponentUnknown = 128,

602

603

// Children types

604

HasKeyedChildren = 256,

605

HasNonKeyedChildren = 512,

606

607

// Special flags

608

Fragment = 1024,

609

Portal = 2048,

610

ReCreate = 4096,

611

ContentEditable = 8192,

612

UpdateEffect = 16384,

613

Ref = 32768

614

}

615

```

616

617

### Advanced Patterns

618

619

These functions enable advanced patterns like:

620

621

- **Custom renderers**: Building alternative rendering targets

622

- **Performance optimization**: Fine-grained control over reconciliation

623

- **Framework integration**: Bridging with other UI libraries

624

- **Testing utilities**: Creating controlled virtual DOM structures

625

- **Development tools**: Building debugging and inspection tools