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

@remote-ui/dom

v1.3.19

Published

This library provides utilities to render the host side of a [`@remote-ui/core` `ReactRoot`](../core#remoteroot) into the DOM by mapping remote components to [custom elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elemen

Downloads

66

Readme

@remote-ui/dom

This library provides utilities to render the host side of a @remote-ui/core ReactRoot into the DOM by mapping remote components to custom elements.

Installation

Using yarn:

yarn add @remote-ui/dom

or, using npm:

npm install @remote-ui/dom --save

Usage

This library provides a custom remote “receiver”, DomReceiver. This object is a replacement for the generic @remote-ui/core RemoteReceiver. It implements an optimized approach for mapping updates on a RemoteRoot to the DOM, where any RemoteText objects become Text nodes in the DOM, and any RemoteComponent objects become custom element instances.

Before you can render anything to the DOM, you must provide one argument to the DomReceiver: customElement. This option is used to determine what custom element to create for a given remote component. It can be an object or Map, where the keys are names of remote components, and values are the name of the custom element; or a function that accepts the name of the component as its argument, and returns the name of the custom element.

import {DomReceiver} from '@remote-ui/dom';

const receiver = new DomReceiver({
  customElement: {
    Card: 'ui-card',
    Button: 'ui-button',
  },
});

Once you have an instance of the receiver, you can use its receive method to connect it to a new RemoteRoot object:

import {createRemoteRoot} from '@remote-ui/core';
import {DomReceiver} from '@remote-ui/dom';

const {receive} = new DomReceiver({
  customElement: {
    Card: 'ui-card',
    Button: 'ui-button',
  },
});

// Somewhere else, usually in a “remote context” like a web worker.

const remoteRoot = createRemoteRoot(receive);

You also need to tell the receiver what node to “bind” to. When a receiver is bound to a node, all of the current top-level children of the RemoteRoot will be appended to that node, and any subsequent root updates will also be applied to that node. You can bind a node, which can be an HTML element, document fragment, shadow root, or any other object satisfying the Node interface, by passing it to the constructor as the bind option, or by subsequently calling the bind() method on DomReceiver.

import {DomReceiver} from '@remote-ui/dom';

const root = document.querySelector('#root');

const receiver = new DomReceiver({
  bind: root,
  customElement: {
    Card: 'ui-card',
    Button: 'ui-button',
  },
});

// or...

receiver.bind(root);

If you want to remove the bound node’s connection to the RemoteRoot, you can call unbind() on the DomReceiver. This will empty the node and disconnect it from future updates to the RemoteRoot.

import {DomReceiver} from '@remote-ui/dom';

const root = document.querySelector('#root');

const receiver = new DomReceiver({
  bind: root,
  customElement: {
    Card: 'ui-card',
    Button: 'ui-button',
  },
});

// later...

receiver.unbind();

By default, all props on a remote component are directly applied as properties to the matching custom element. This is the simplest behavior that is guaranteed to work for all the types that can be passed as props from a remote component (strings, numbers, booleans, objects, arrays, and functions). However, you can customize way a property is applied to its custom element by passing the applyProperty option. This option is passed the custom element being created, the name of the property being applied, the value for that property, and the type of the remote component. You can use these details to change the behavior on a per-prop basis; for instance, using attributes instead of properties in some cases, or attaching event listeners. If this function returns false, the default logic for applying a property will be used instead.

import {DomReceiver} from '@remote-ui/dom';

const root = document.querySelector('#root');

const receiver = new DomReceiver({
  bind: root,
  customElement: {
    Card: 'ui-card',
    Button: 'ui-button',
  },
  // For the `disabled` property on Button, we will use an HTML attribute.
  applyProperty({type, element, property, value}) {
    if (type !== 'Button' || property !== 'disabled') return false;
    element.setAttribute('disabled', 'disabled');
  },
});

One particularly common way to customize custom elements is to turn some function properties into native DOM event listeners. You can pass the withEventListeners function from this package to applyProperty to automatically convert any prop starting with on into an event listener, and otherwise using the default property setting logic noted above.

import {DomReceiver, withEventListeners} from '@remote-ui/dom';

const root = document.querySelector('#root');

const receiver = new DomReceiver({
  bind: root,
  customElement: {
    Card: 'ui-card',
    Button: 'ui-button',
  },
  applyProperty: withEventListeners,
});

// Now, if we have a remote component that creates a `Button` component with an
// `onPress` prop, that will become a `ui-button` custom element, with an
// `addEventListener('press', props.onPress)` applied to it.

As a custom element

This library also provides a small custom element meant to make this library feel more ergonomic in larger, custom element-based apps. This custom element is registered for the name remote-ui-root. In environments that support custom elements, you can use this element in your HTML like so:

<remote-ui-root></remote-ui-root>

You’ll then need to ensure you load the definition for this component, find its node in the DOM, and update its receiver prop. Whenever the receiver prop updates to a new DomReceiver, this custom element will bind its own shadow root as the top-level element for the RemoteRoot. You can accomplish this using just a few lines of JavaScript:

import {DomReceiver} from '@remote-ui/dom/browser';

const receiver = new DomReceiver({
  customElement: {
    Card: 'ui-card',
    Button: 'ui-button',
  },
});

document.querySelector('remote-ui-root').receiver = receiver;

// Somewhere else, you construct the `RemoteRoot` and start rendering to it,
// and those updates will be reflected in the shadow root of this custom
// element.