CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-preact-compat

A React compatibility layer for Preact

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

legacy-apis.mddocs/

Legacy React APIs

Support for legacy React patterns including createClass, DOM factories, and deprecated lifecycle methods for backward compatibility.

Capabilities

Create Class

Legacy React component creation using the createClass pattern.

/**
 * Create component class using legacy React pattern
 * @param {object} spec - Component specification object
 * @returns {ComponentClass} Component constructor
 */
function createClass(spec);

/**
 * Component specification for createClass
 */
interface ComponentSpec {
  // Required render method
  render(): VNode;
  
  // Optional lifecycle methods
  getInitialState?(): object;
  getDefaultProps?(): object;
  componentWillMount?(): void;
  componentDidMount?(): void;
  componentWillReceiveProps?(nextProps: object): void;
  shouldComponentUpdate?(nextProps: object, nextState: object): boolean;
  componentWillUpdate?(nextProps: object, nextState: object): void;
  componentDidUpdate?(prevProps: object, prevState: object): void;
  componentWillUnmount?(): void;
  
  // Mixins support
  mixins?: Array<object>;
  
  // Auto-binding
  [methodName: string]: any;
}

Usage Examples:

import { createClass } from 'preact-compat';
// or
import createClass from 'preact-compat/lib/create-react-class';

const MyComponent = createClass({
  getInitialState() {
    return { count: 0 };
  },
  
  getDefaultProps() {
    return { title: 'Default Title' };
  },
  
  handleClick() {
    this.setState({ count: this.state.count + 1 });
  },
  
  render() {
    return (
      <div>
        <h1>{this.props.title}</h1>
        <p>Count: {this.state.count}</p>
        <button onClick={this.handleClick}>Increment</button>
      </div>
    );
  }
});

DOM Factories

Factory functions for creating HTML elements without JSX.

/**
 * DOM element factories for all HTML elements
 */
const DOM = {
  // Common elements
  a: ElementFactory<AnchorHTMLAttributes>;
  div: ElementFactory<HTMLAttributes>;
  span: ElementFactory<HTMLAttributes>;
  p: ElementFactory<HTMLAttributes>;
  h1: ElementFactory<HTMLAttributes>;
  h2: ElementFactory<HTMLAttributes>;
  h3: ElementFactory<HTMLAttributes>;
  h4: ElementFactory<HTMLAttributes>;
  h5: ElementFactory<HTMLAttributes>;
  h6: ElementFactory<HTMLAttributes>;
  
  // Form elements
  form: ElementFactory<FormHTMLAttributes>;
  input: ElementFactory<InputHTMLAttributes>;
  button: ElementFactory<ButtonHTMLAttributes>;
  select: ElementFactory<SelectHTMLAttributes>;
  option: ElementFactory<OptionHTMLAttributes>;
  textarea: ElementFactory<TextareaHTMLAttributes>;
  label: ElementFactory<LabelHTMLAttributes>;
  
  // Media elements
  img: ElementFactory<ImgHTMLAttributes>;
  video: ElementFactory<VideoHTMLAttributes>;
  audio: ElementFactory<AudioHTMLAttributes>;
  
  // Table elements
  table: ElementFactory<TableHTMLAttributes>;
  thead: ElementFactory<HTMLAttributes>;
  tbody: ElementFactory<HTMLAttributes>;
  tr: ElementFactory<HTMLAttributes>;
  td: ElementFactory<TdHTMLAttributes>;
  th: ElementFactory<ThHTMLAttributes>;
  
  // ... and all other HTML elements
};

/**
 * Element factory function type
 */
interface ElementFactory<P = {}> {
  (props?: P, ...children: ComponentChildren[]): VNode;
}

Usage Examples:

import { DOM } from 'preact-compat';
// or
import { DOM } from 'preact-compat/lib/react-dom-factories';

// Create elements without JSX
const element = DOM.div(
  { className: 'container', id: 'main' },
  DOM.h1(null, 'Hello World'),
  DOM.p(null, 'This is a paragraph'),
  DOM.button(
    { onClick: handleClick },
    'Click me'
  )
);

// Equivalent JSX:
// <div className="container" id="main">
//   <h1>Hello World</h1>
//   <p>This is a paragraph</p>
//   <button onClick={handleClick}>Click me</button>
// </div>

Legacy Component with Mixins

import { createClass } from 'preact-compat';

// Example mixin
const TimerMixin = {
  componentWillMount() {
    this.timers = [];
  },
  
  componentWillUnmount() {
    this.timers.forEach(clearInterval);
  },
  
  setInterval(fn, delay) {
    const id = setInterval(fn, delay);
    this.timers.push(id);
    return id;
  }
};

const MyComponent = createClass({
  mixins: [TimerMixin],
  
  getInitialState() {
    return { seconds: 0 };
  },
  
  componentDidMount() {
    this.setInterval(() => {
      this.setState({ seconds: this.state.seconds + 1 });
    }, 1000);
  },
  
  render() {
    return <div>Seconds: {this.state.seconds}</div>;
  }
});

Prop Types Integration

Legacy PropTypes support (re-exported from prop-types).

/**
 * PropTypes for runtime type checking (re-exported from prop-types package)
 */
const PropTypes = {
  array: Validator<any[]>;
  bool: Validator<boolean>;
  func: Validator<Function>;
  number: Validator<number>;
  object: Validator<object>;
  string: Validator<string>;
  symbol: Validator<symbol>;
  
  node: Validator<ComponentChildren>;
  element: Validator<VNode>;
  instanceOf(expectedClass: any): Validator<any>;
  oneOf(expectedValues: any[]): Validator<any>;
  oneOfType(expectedTypes: Validator<any>[]): Validator<any>;
  arrayOf(expectedType: Validator<any>): Validator<any[]>;
  objectOf(expectedType: Validator<any>): Validator<object>;
  shape(expectedShape: ValidationMap<any>): Validator<object>;
  exact(expectedShape: ValidationMap<any>): Validator<object>;
  
  // Modifiers
  isRequired: symbol;
};

interface ValidationMap<T> {
  [K in keyof T]?: Validator<T[K]>;
}

interface Validator<T> {
  (props: object, propName: string, componentName: string): Error | null;
  isRequired: Validator<T>;
}

Usage Examples:

import { PropTypes } from 'preact-compat';

const MyComponent = createClass({
  propTypes: {
    name: PropTypes.string.isRequired,
    age: PropTypes.number,
    items: PropTypes.arrayOf(PropTypes.string),
    user: PropTypes.shape({
      id: PropTypes.number.isRequired,
      email: PropTypes.string
    }),
    onClick: PropTypes.func
  },
  
  getDefaultProps() {
    return {
      age: 0,
      items: []
    };
  },
  
  render() {
    return (
      <div onClick={this.props.onClick}>
        <h1>{this.props.name}</h1>
        <p>Age: {this.props.age}</p>
      </div>
    );
  }
});

Import Patterns

// Main imports
import { createClass, DOM, PropTypes } from 'preact-compat';

// Specific library imports
import createClass from 'preact-compat/lib/create-react-class';
import { DOM } from 'preact-compat/lib/react-dom-factories';

// CommonJS
const { createClass, DOM, PropTypes } = require('preact-compat');

Types

interface CreateClassSpec {
  render(): VNode;
  getInitialState?(): object;
  getDefaultProps?(): object;
  mixins?: Array<object>;
  [key: string]: any;
}

type CreateClassComponent = ComponentClass<any>;

interface DOMFactory<P = {}> {
  (props?: P, ...children: ComponentChildren[]): VNode;
}

interface DOMFactories {
  [elementName: string]: DOMFactory;
}

Install with Tessl CLI

npx tessl i tessl/npm-preact-compat

docs

children-utilities.md

context-api.md

core-api.md

immutability-helpers.md

index.md

legacy-apis.md

performance-tools.md

refs-system.md

server-rendering.md

transition-groups.md

tile.json