Haunted Versions Save

React's Hooks API implemented for web components 👻

v1.6.0

5 years ago

This adds support for boolean attributes. So that a component used in HTML like:

<drop-down open>
  <ul>...</ul>
</drop-down>

When defined this now reflects as a boolean:

function Dropdown({ open }) {
  return html`
    <slot style="${open ? 'display: block;' : 'display: none;' }"></slot>
  `;
}

Dropdown.observedAttributes = ['open'];

open will be the boolean true rather than an empty string (as is the value of boolean attributes.

v1.5.0

5 years ago

This adds fully support for useEffect matching React's API. This is documented in the readme. The new parts are:

Memoization

Like useMemo, useEffect can take a second argument that are values that are memoized. The effect will only run when these values change.

function App() {
  let [name, setName] = useState('Dracula');

  useEffect(() => {
    // This only occurs when name changes.
    document.title = `Hello ${name}`;
  }, [name]);

  return html`...`;
}

Cleaning up side-effects

Since effects are used for side-effectual things and might run many times in the lifecycle of a component, useEffect supports returning a teardown function.

An example if when you might use this is if you are setting up an event listener.

function App() {
  let [name, setName] = useState('Wolf Man');

  useEffect(() => {
    function updateNameFromWorker(ev) {
      setName(ev.data);
    }

    worker.addEventListener('message', updateNameFromWorker);

    return () => {
      worker.addEventListener('message', updateNameFromWorker);
    }
  });

  return html`...`;
}

v1.4.0

5 years ago

This release includes a couple of new features:

Observed attributes

Now you can have your attributes be observed, which will automatically set their property and trigger a rerender. It works like:

import { component } from '@matthewp/haunted';
import { html } from 'lit-html';

function App({ name }) {
  return html`Hello ${name}`;
}

App.observedAttributes = ["name"];

customElements.define('my-app', component(app));

And then you can set them in HTML or anywhere else that produces DOM:

<my-app name="world"></my-app>

Lit's html is exported

Since Haunted already depends on lit-html to use its render export, it made since to go ahead and re-export the html export as well. This allows for not directly importing lit-html if you just want to use the same version Haunted uses.

import { component, html } from '@matthewp/haunted';

...

Codesandbox

We now have a starter app on Codesandbox. This makes it easier to learn and experiment.

This release made with pure 🎃

v1.3.0

5 years ago

This finally figures out our different builds. Most users should never have to care about this. We have the following builds for different use cases. These are documented in the readme.