1.0.5 • Published 6 years ago

web-component-simple-program v1.0.5

Weekly downloads
1
License
MIT
Repository
-
Last release
6 years ago

Web Component Simple Program

A minimalist JS view library for Web Components inspired by Elm

Install with npm or yarn.

npm i web-component-simple-program

Example:

import {
  Html,
  HtmlAttributes,
  HtmlEvents,
  render
} from "web-component-simple-program";

const { div, text, button } = Html;
const { class_ } = HtmlAttributes;
const { onclick } = HtmlEvents;

const dom = div()([
  span([class_("text-red")])([text("hello world")]),
  button([onclick(e => console.log(e))])([text("Click Me")])
]);

render(document, dom);

Use the updateNode helper to override the nodes attributes and children

import {
  Html,
  HtmlAttributes,
  HtmlEvents,
  updateNode,
  render
} from "web-component-simple-program";

const { div, text, button } = Html;
const { class_, id } = HtmlAttributes;
const { onclick } = HtmlEvents;

const buttonHandler = _ => {
  updateNode(document.getElementById("title"))([class_("text-green")])([
    text("goodbye world")
  ]);
};

const dom = div()([
  span([id("title"), class_("text-red")])([text("hello world")]),
  button([onclick(buttonHandler)])([text("Click Me")])
]);

render(document, dom);

If managing state, I recommend using Program (Inspired by The Elm Architecture)

import {
  Html,
  HtmlAttributes,
  Program,
  updateNode,
  main
} from "web-component-simple-program";

const { div, text, button } = Html;
const { class_, id } = HtmlAttributes;
const { main, toModel, toMsg, toUpdate, Events } = Program;

const UpdateTitle = "@@app/UPDATE_TITLE";

const init = ({ title }) => toModel({ title });

const update = msg => model => {
  switch (msg.payload) {
    case UpdateTitle:
      return toModel({ ...model, title: msg.payload.title });
    default:
      return toModel(model);
  }
};

// Instead of using a Virtual DOM,
// viewUpdate (which is passed into toUpdate as the second argument)
// is called after the update function
// which allows manual changes to be made to the DOM for now
const viewUpdate = root => [
  model =>
    updateNode(root.getElementById("title"))([class_("text-green")])([
      text(model.title)
    ]),
  model =>
    updateNode(root.getElementById("button"))()([
      text("Click Me" + model.title)
    ])
];

const view = root => model => {
  // Program Events intercept the HTMLEvents to handle async msg passing
  // these events now take in a function that returns a Msg
  // dispatch is also an added event if needed
  // Ex. dispatch(toMsg(UpdateTitle, {title: "blah"}))
  const { onclick } = Events(root);
  return div()([
    span([id("title"), class_("text-red")])([text(model.title)]),
    button([
      id("button"),
      onclick(e => toMsg(UpdateTitle, { title: "goodbye world" }))
    ])([text("Click Me")])
  ]);
};

class MyCustomElement extends HTMLElement {
  connectedCallback() {
    const props = {
      title: this.getAttribute("title") || ""
    };

    main(createRoot(this), {
      init: init(props),
      update: toUpdate(update, viewUpdate),
      view
    });
  }
}

customElements.define("my-custom-element", MyCustomElement);
1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago