CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-inferno-compat

Provides a compatibility with React codebases

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

advanced-vnodes.mddocs/

Advanced VNode Functions

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

Capabilities

createVNode Function

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

/**
 * Creates a virtual DOM node with explicit configuration
 * @param flags - VNode flags defining element type and behavior
 * @param type - Element type (string for DOM, function/class for components)
 * @param className - CSS class name for the element
 * @param children - Child nodes
 * @param childFlags - Flags describing children structure
 * @param props - Element properties and attributes
 * @param key - Unique key for reconciliation
 * @param ref - Reference to DOM element or component instance
 * @returns VNode representing the virtual DOM element
 */
function createVNode(
  flags: number,
  type: string | ComponentClass<any> | Function | null,
  className?: string,
  children?: InfernoNode,
  childFlags?: number,
  props?: any,
  key?: string | number,
  ref?: any
): VNode;

Usage Examples:

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

// Create a simple element VNode
const div = createVNode(
  VNodeFlags.HtmlElement,
  'div',
  'container',
  'Hello World',
  VNodeFlags.HasNonKeyedChildren,
  { id: 'main' },
  'unique-key'
);

// Create a component VNode
function MyComponent(props) {
  return createVNode(VNodeFlags.HtmlElement, 'span', null, props.text);
}

const component = createVNode(
  VNodeFlags.ComponentFunction,
  MyComponent,
  null,
  null,
  VNodeFlags.HasNonKeyedChildren,
  { text: 'Component text' },
  'component-key'
);

// Create VNode with ref
let elementRef;
const withRef = createVNode(
  VNodeFlags.HtmlElement,
  'input',
  'form-input',
  null,
  VNodeFlags.HasNonKeyedChildren,
  { type: 'text', placeholder: 'Enter text' },
  null,
  (ref) => { elementRef = ref; }
);

createComponentVNode Function

Creates VNodes specifically for React/Inferno components.

/**
 * Creates a VNode for a component (class or function)
 * @param flags - Component flags (ComponentClass or ComponentFunction)
 * @param type - Component class or function
 * @param props - Component props
 * @param key - Unique key for reconciliation
 * @param ref - Reference to component instance
 * @returns VNode for the component
 */
function createComponentVNode(
  flags: number,
  type: ComponentClass<any> | Function,
  props?: any,
  key?: string | number,
  ref?: any
): VNode;

Usage Examples:

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

class UserProfile extends Component {
  render() {
    return <div>User: {this.props.name}</div>;
  }
}

// Create class component VNode
const classComponent = createComponentVNode(
  VNodeFlags.ComponentClass,
  UserProfile,
  { name: 'Alice', age: 30 },
  'user-profile',
  (instance) => console.log('Component mounted:', instance)
);

// Function component VNode
function WelcomeMessage({ message }) {
  return <h1>{message}</h1>;
}

const functionComponent = createComponentVNode(
  VNodeFlags.ComponentFunction,
  WelcomeMessage,
  { message: 'Welcome to our app!' },
  'welcome-message'
);

// Higher-order component pattern
function withLogging(WrappedComponent) {
  function LoggingComponent(props) {
    console.log('Rendering with props:', props);
    return createComponentVNode(
      VNodeFlags.ComponentFunction,
      WrappedComponent,
      props
    );
  }
  return LoggingComponent;
}

const EnhancedComponent = withLogging(WelcomeMessage);
const enhanced = createComponentVNode(
  VNodeFlags.ComponentFunction,
  EnhancedComponent,
  { message: 'Enhanced message' }
);

createTextVNode Function

Creates text nodes for efficient text rendering.

/**
 * Creates a text VNode for rendering text content
 * @param text - Text content to render
 * @param key - Optional key for reconciliation
 * @returns VNode representing text content
 */
function createTextVNode(text: string | number, key?: string | number): VNode;

Usage Examples:

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

// Simple text node
const greeting = createTextVNode('Hello World!');

// Text with key for lists
const listItems = ['Apple', 'Banana', 'Cherry'].map((fruit, index) =>
  createVNode(
    VNodeFlags.HtmlElement,
    'li',
    null,
    createTextVNode(fruit, `fruit-${index}`),
    VNodeFlags.HasNonKeyedChildren,
    null,
    `item-${index}`
  )
);

// Dynamic text content
function DynamicText({ value, formatter }) {
  const formattedValue = formatter ? formatter(value) : value;
  return createTextVNode(formattedValue);
}

// Conditional text rendering
function StatusText({ status }) {
  const text = status === 'loading' 
    ? createTextVNode('Loading...', 'loading-text')
    : createTextVNode(`Status: ${status}`, 'status-text');
  
  return createVNode(
    VNodeFlags.HtmlElement,
    'span',
    `status ${status}`,
    text
  );
}

// Number text nodes
const counter = createTextVNode(42);
const price = createTextVNode(19.99);

createFragment Function

Creates fragment nodes for grouping elements without DOM wrappers.

/**
 * Creates a fragment VNode for grouping multiple elements
 * @param children - Array of child VNodes
 * @param childFlags - Flags describing children structure
 * @param key - Optional key for reconciliation
 * @returns Fragment VNode containing the children
 */
function createFragment(
  children: InfernoNode[],
  childFlags?: number,
  key?: string | number
): VNode;

Usage Examples:

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

// Simple fragment
const fragment = createFragment([
  createVNode(VNodeFlags.HtmlElement, 'h1', null, createTextVNode('Title')),
  createVNode(VNodeFlags.HtmlElement, 'p', null, createTextVNode('Content'))
], VNodeFlags.HasNonKeyedChildren);

// Fragment in conditional rendering
function ConditionalContent({ showDetails, title, content }) {
  if (!showDetails) {
    return createTextVNode(title);
  }
  
  return createFragment([
    createVNode(VNodeFlags.HtmlElement, 'h2', null, createTextVNode(title)),
    createVNode(VNodeFlags.HtmlElement, 'p', null, createTextVNode(content)),
    createVNode(VNodeFlags.HtmlElement, 'button', null, createTextVNode('Close'))
  ], VNodeFlags.HasNonKeyedChildren, 'details-fragment');
}

// Fragment for list items
function TableRow({ cells }) {
  const cellVNodes = cells.map((cell, index) =>
    createVNode(
      VNodeFlags.HtmlElement,
      'td',
      null,
      createTextVNode(cell),
      VNodeFlags.HasNonKeyedChildren,
      null,
      `cell-${index}`
    )
  );
  
  return createFragment(cellVNodes, VNodeFlags.HasKeyedChildren, 'table-row');
}

// Nested fragments
const nestedFragment = createFragment([
  createTextVNode('Before nested'),
  createFragment([
    createVNode(VNodeFlags.HtmlElement, 'span', null, createTextVNode('Nested 1')),
    createVNode(VNodeFlags.HtmlElement, 'span', null, createTextVNode('Nested 2'))
  ], VNodeFlags.HasNonKeyedChildren, 'inner-fragment'),
  createTextVNode('After nested')
], VNodeFlags.HasNonKeyedChildren, 'outer-fragment');

createPortal Function

Creates portal nodes that render children into different DOM containers.

/**
 * Creates a portal VNode that renders children into a different DOM container
 * @param children - VNodes to render in the portal
 * @param container - DOM element to render the portal into
 * @returns Portal VNode that renders children elsewhere
 */
function createPortal(
  children: InfernoNode,
  container: Element
): VNode;

Usage Examples:

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

// Modal component using portal
class Modal extends Component {
  constructor(props) {
    super(props);
    this.modalRoot = document.getElementById('modal-root') || document.body;
  }
  
  render() {
    const modal = createVNode(
      VNodeFlags.HtmlElement,
      'div',
      'modal-backdrop',
      createVNode(
        VNodeFlags.HtmlElement,
        'div',
        'modal-content',
        this.props.children
      )
    );
    
    return createPortal(modal, this.modalRoot);
  }
}

// Tooltip component
function Tooltip({ children, content, targetRef }) {
  if (!targetRef.current) return null;
  
  const tooltip = createVNode(
    VNodeFlags.HtmlElement,
    'div',
    'tooltip',
    createTextVNode(content)
  );
  
  return createPortal(tooltip, targetRef.current.parentElement);
}

// Notification system
class NotificationManager extends Component {
  constructor(props) {
    super(props);
    this.state = { notifications: [] };
    this.notificationContainer = document.getElementById('notifications');
  }
  
  addNotification = (message, type = 'info') => {
    const notification = {
      id: Date.now(),
      message,
      type
    };
    
    this.setState(prevState => ({
      notifications: [...prevState.notifications, notification]
    }));
  }
  
  render() {
    const { notifications } = this.state;
    
    if (notifications.length === 0) return null;
    
    const notificationList = createVNode(
      VNodeFlags.HtmlElement,
      'div',
      'notification-list',
      notifications.map(notification =>
        createVNode(
          VNodeFlags.HtmlElement,
          'div',
          `notification ${notification.type}`,
          createTextVNode(notification.message),
          VNodeFlags.HasNonKeyedChildren,
          null,
          notification.id
        )
      )
    );
    
    return createPortal(notificationList, this.notificationContainer);
  }
}

createRef Function

Creates ref objects for accessing DOM elements and component instances.

/**
 * Creates a ref object for accessing DOM elements or component instances
 * @returns Ref object with current property
 */
function createRef<T = any>(): { current: T | null };

Usage Examples:

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

class InputComponent extends Component {
  constructor(props) {
    super(props);
    this.inputRef = createRef();
  }
  
  componentDidMount() {
    // Focus the input after mounting
    if (this.inputRef.current) {
      this.inputRef.current.focus();
    }
  }
  
  getValue = () => {
    return this.inputRef.current ? this.inputRef.current.value : '';
  }
  
  render() {
    return createVNode(
      VNodeFlags.HtmlElement,
      'input',
      'form-input',
      null,
      VNodeFlags.HasNonKeyedChildren,
      {
        type: 'text',
        placeholder: this.props.placeholder,
        ref: this.inputRef
      }
    );
  }
}

// Functional component with ref
function VideoPlayer({ src }) {
  const videoRef = createRef();
  
  const play = () => {
    if (videoRef.current) {
      videoRef.current.play();
    }
  };
  
  const pause = () => {
    if (videoRef.current) {
      videoRef.current.pause();
    }
  };
  
  return createFragment([
    createVNode(
      VNodeFlags.HtmlElement,
      'video',
      'video-player',
      null,
      VNodeFlags.HasNonKeyedChildren,
      { src, ref: videoRef }
    ),
    createVNode(
      VNodeFlags.HtmlElement,
      'div',
      'controls',
      [
        createVNode(
          VNodeFlags.HtmlElement,
          'button',
          null,
          createTextVNode('Play'),
          VNodeFlags.HasNonKeyedChildren,
          { onClick: play }
        ),
        createVNode(
          VNodeFlags.HtmlElement,
          'button',
          null,
          createTextVNode('Pause'),
          VNodeFlags.HasNonKeyedChildren,
          { onClick: pause }
        )
      ]
    )
  ]);
}

forwardRef Function

Creates components that forward refs to child elements.

/**
 * Creates a component that forwards refs to child elements
 * @param render - Render function that receives props and ref
 * @returns Component that forwards refs
 */
function forwardRef<T, P = {}>(
  render: (props: P, ref: { current: T | null }) => InfernoNode
): ComponentType<P & { ref?: { current: T | null } }>;

Usage Examples:

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

// Forward ref to DOM element
const FancyButton = forwardRef((props, ref) => {
  return createVNode(
    VNodeFlags.HtmlElement,
    'button',
    `fancy-button ${props.variant || 'primary'}`,
    createTextVNode(props.children),
    VNodeFlags.HasNonKeyedChildren,
    {
      ...props,
      ref: ref
    }
  );
});

// Usage with ref
function App() {
  const buttonRef = createRef();
  
  const handleClick = () => {
    if (buttonRef.current) {
      buttonRef.current.classList.add('clicked');
    }
  };
  
  return createVNode(
    VNodeFlags.ComponentFunction,
    FancyButton,
    null,
    null,
    VNodeFlags.HasNonKeyedChildren,
    {
      variant: 'secondary',
      onClick: handleClick,
      ref: buttonRef,
      children: 'Click Me'
    }
  );
}

// Forward ref to child component
const EnhancedInput = forwardRef((props, ref) => {
  return createVNode(
    VNodeFlags.HtmlElement,
    'div',
    'input-wrapper',
    [
      props.label && createVNode(
        VNodeFlags.HtmlElement,
        'label',
        'input-label',
        createTextVNode(props.label)
      ),
      createVNode(
        VNodeFlags.HtmlElement,
        'input',
        'enhanced-input',
        null,
        VNodeFlags.HasNonKeyedChildren,
        {
          ...props,
          ref: ref
        }
      )
    ]
  );
});

VNode Flags

Understanding VNode flags is crucial for advanced VNode manipulation:

enum VNodeFlags {
  // Element types
  HtmlElement = 1,
  SvgElement = 2,
  InputElement = 4,
  TextareaElement = 8,
  SelectElement = 16,
  
  // Component types  
  ComponentFunction = 32,
  ComponentClass = 64,
  ComponentUnknown = 128,
  
  // Children types
  HasKeyedChildren = 256,
  HasNonKeyedChildren = 512,
  
  // Special flags
  Fragment = 1024,
  Portal = 2048,
  ReCreate = 4096,
  ContentEditable = 8192,
  UpdateEffect = 16384,
  Ref = 32768
}

Advanced Patterns

These functions enable advanced patterns like:

  • Custom renderers: Building alternative rendering targets
  • Performance optimization: Fine-grained control over reconciliation
  • Framework integration: Bridging with other UI libraries
  • Testing utilities: Creating controlled virtual DOM structures
  • Development tools: Building debugging and inspection tools

docs

advanced-vnodes.md

children-utilities.md

core-components.md

dom-operations.md

element-creation.md

index.md

proptypes.md

tile.json