js-widgets
TypeScript icon, indicating that this package has built-in type declarations

0.0.113 • Public • Published

js-widgets

A R&D project to evaluate an API for developing components using an alternative to hook functions (called "extensions"), while still remain the possibility to implement in usual react-style.
The main advantages of the new API (= using "extensions" instead of "hooks") are:

  • No rules of hooks
  • No special linter necessary

Be aware that this project is just for research purposes and is not meant to be used in production.

Installation

git clone https://github.com/js-works/js-widgets.git
cd js-widgets
npm install

Running demos

npm run storybook

Examples

Remark: We are using the following naming convention to reduce the amount of noise in the source code (for non-trivial components, where you access the props and the state object very often, that makes quite a difference):

  • p is the variable for the props object
  • s is the variable for a state object

Simple counter

import { render } from 'js-widgets';
import { preset, state } from 'js-widgets/ext';

function Counter(p: {
  name?: string; //
  initialCount?: number;
}) {
  preset(p, () => ({
    initialCount: 0,
    name: 'Counter'
  }));

  const [s, set] = state({ count: p.initialCount });
  const increment = () => set.count((it) => it + 1);

  return () => (
    <button onClick={increment}>
      {p.name}: {s.count}
    </button>
  );
}

render(<Counter />, '#app');

Additional example - showing some lifecycle extensions

import { render } from 'js-widgets';
import { afterMount, effect, preset, state } from 'js-widgets/ext';

function Counter(p: {
  name?: string; //
  initialCount?: number;
}) {
  preset(p, () => ({
    name: 'Counter',
    initialCount: 0
  }));

  const [s, set] = state({ count: p.initialCount });
  const increment = () => set.count((it) => it + 1);

  afterMount(() => {
    console.log(`Counter "${p.name}" has been mounted`);
    return () => console.log(`Counter "${p.name}" will unmount`);
  });

  effect(
    () => console.log(`Value of "${p.name}": ${s.count}`),
    () => [s.count]
  );

  return () => (
    <div>
      <button onClick={increment}>
        {p.name}: {s.count}
      </button>
    </div>
  );
}

render(<Counter />, '#app');

API

Core functions

  • createContext
  • createElement
  • createPortal
  • getType
  • getProps
  • intercept
  • isElement
  • lazy
  • render
  • Boundary
  • Fragment
  • Suspense

Extensions

tbd

Hooks

tbd

Utility functions

tbd

Project state

This R&D project is in a very early development state

/js-widgets/

    Package Sidebar

    Install

    npm i js-widgets

    Weekly Downloads

    25

    Version

    0.0.113

    License

    LGPL-3.0

    Unpacked Size

    424 kB

    Total Files

    72

    Last publish

    Collaborators

    • mcjazzyfunky
    • js-works