npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lit/react

v1.0.6

Published

A React component wrapper for web components.

Downloads

561,700

Readme

@lit/react

React integration for Web Components and Reactive Controllers.

Overview

createComponent

While React can render Web Components, it cannot easily pass React props to custom element properties or event listeners.

This package provides a utility wrapper createComponent which makes a React component wrapper for a custom element class. The wrapper correctly passes React props to properties accepted by the custom element and listens for events dispatched by the custom element.

How it works

For properties, the wrapper interrogates the web component class to discover its available properties. Then any React props passed with property names are set on the custom element as properties and not attributes.

For events, createComponent accepts a mapping of React event prop names to events fired by the custom element. For example passing {onfoo: 'foo'} means a function passed via a prop named onfoo will be called when the custom element fires the foo event with the event as an argument.

Usage

Import React, a custom element class, and createComponent.

import * as React from 'react';
import {createComponent} from '@lit/react';
import {MyElement} from './my-element.js';

export const MyElementComponent = createComponent({
  tagName: 'my-element',
  elementClass: MyElement,
  react: React,
  events: {
    onactivate: 'activate',
    onchange: 'change',
  },
});

After defining the React component, you can use it just as you would any other React component.

<MyElementComponent
  active={isActive}
  onactivate={(e) => (isActive = e.active)}
/>

Typescript

Event callback types can be refined by type casting with EventName. The type cast helps createComponent correlate typed callbacks to property names in the event property map.

Non-casted event names will fallback to an event type of Event.

import type {EventName} from '@lit/react';

import * as React from 'react';
import {createComponent} from '@lit/react';
import {MyElement} from './my-element.js';

export const MyElementComponent = createComponent({
  tagName: 'my-element',
  elementClass: MyElement,
  react: React,
  events: {
    onClick: 'pointerdown' as EventName<PointerEvent>,
    onChange: 'input',
  },
});

Event callbacks will match their type cast. In the example below, a PointerEvent is expected in the onClick callback.

<MyElementComponent
  onClick={(e: PointerEvent) => {
    console.log('DOM PointerEvent called!');
  }}
  onChange={(e: Event) => {
    console.log(e);
  }}
/>

NOTE: This type casting is not associated to any component property. Be careful to use the corresponding type dispatched or bubbled from the webcomponent. Incorrect types might result in additional properties, missing properties, or properties of the wrong type.

useController

Reactive Controllers allow developers to hook a component's lifecycle to bundle together state and behavior related to a feature. They are similar to React hooks in the user cases and capabilities, but are plain JavaScript objects instead of functions with hidden state.

useController is a React hook that create and stores a Reactive Controller and drives its lifecycle using React hooks like useState and useLayoutEffect.

How it works

useController uses useState to create and store an instance of a controller and a ReactControllerHost. It then calls the controller's lifecycle from the hook body and useLayoutEffect callbacks, emulating the ReactiveElement lifecycle as closely as possible. ReactControllerHost implements addController so that controller composition works and nested controller lifecycles are called correctly. ReactControllerHost also implements requestUpdate by calling a useState setter, so that a controller with new renderable state can cause its host component to re-render.

Controller timings are implemented as follows:

| Controller API | React hook equivalent | | ---------------- | ----------------------------------- | | constructor | useState initial value | | hostConnected | useState initial value | | hostDisconnected | useLayoutEffect cleanup, empty deps | | hostUpdate | hook body | | hostUpdated | useLayoutEffect | | requestUpdate | useState setter | | updateComplete | useLayoutEffect |

Usage

import * as React from 'react';
import {useController} from '@lit/react/use-controller.js';
import {MouseController} from '@example/mouse-controller';

// Write a React hook function:
const useMouse = () => {
  // Use useController to create and store a controller instance:
  const controller = useController(React, (host) => new MouseController(host));
  // return the controller: return controller;
  // or return a custom object for a more React-idiomatic API:
  return controller.position;
};

// Now use the new hook in a React component:
const Component = (props) => {
  const mousePosition = useMouse();
  return (
    <pre>
      x: {mousePosition.x}
      y: {mousePosition.y}
    </pre>
  );
};

Installation

From inside your project folder, run:

$ npm install @lit/react

Contributing

Please see CONTRIBUTING.md.