0.0.0 • Published 3 years ago

@strangeskies/dope v0.0.0

Weekly downloads
-
License
LGPL-3.0-or-later
Repository
github
Last release
3 years ago

dope

An extremely lightweight HTML templating library which uses the platform to the fullest possible extent.

Write templates declaratively in plain HTML using javascript template literals.

html`<span>Hello there.</span>`

Declare slots using placeholders, which are filled by javascript expressions.

let greet = (name) => html`<span>Hello there, ${name}.</span>`;

Templates compose trivially, simple pass a template into a slot.

let welcome = (name, destination) =>
  html`
    ${greet(name)}
    <span>Welcome to ${destination}!</span>
  `;

Templates may transparently define custom elements, with near-zero boilerplate and no manual class registration.

let welcomeAnywhere = (name) =>
  let setDestination = (destination) => {
    instance().destination = destination;
    instance().updateDestination.forEach(call);
  };
  let getDestination = () => {
    (instance().updateDestination ||= new Set()).add(runner().repeat); 
    return instance().destination;
  };
  component`
    <welcome-somewhere ${{ destination: defaultDestination() }}>
      ${() => welcome(name, getDestination())}
      <button @click=${() => setDestination(randomDestination())}>
    </welcome-somewhere>
  `;
let welcomeAnywhere = (name) =>
  component`
    <welcome-somewhere ${{ destination: defaultDestination() }}>
      ${() => welcome(name, ctx.destination)}
      <button @click=${() => ctx.destination = randomDestination()}>
    </welcome-somewhere>
  `;
let welcomeAnywhere = (name) => {
  let welcomeCtx = ctx`welcome`({ destination: defaultDestination() });
  return component`
    <welcome-somewhere ${welcomeCtx}>
      ${() => welcome(name, welcomeCtx.destination)}
      <button @click=${() => welcomeCtx.destination = nextDestination()}>
    </welcome-somewhere>
  `;
};
let welcomeAnywhere = (name) => {
  let welcomeCtx = ctx`welcome`({ destination: defaultDestination() });
  return component()`
    <welcome-somewhere>
      ${() => welcome(name, welcomeCtx.destination)}
      <button
          ${{
            click: () => welcomeCtx.destination = nextDestination()
          }}>
    </welcome-somewhere>
  `;
};
function friendHook(friend) {
  let friendState = state`friend`({ online: null });

  let friendEffect = () => {
    let handleStatusChange = status =>
      friendState.online = status.isOnline;

    ChatAPI.subscribeToFriendStatus(friend.id, handleStatusChange);
    action().onUndo = () => {
      ChatAPI.unsubscribeFromFriendStatus(friend.id, handleStatusChange);
    };
  };

  return component`
    <friend-status ${[ friendState, friendEffect ]}>
      <h1>${friend.name}</h1>
      ${() => statusText(friendState.online)}
    </friend-status>
  `;
}
function FriendStatus(friend) {
  let friendKey = sym`friend-state`;
  return component`
    <friend-status ${friendHook(friend)}>
      <h1>${friend.name}</h1>
      ${() => statusText(elem.friendOnline)}
    </friend-status>
  `;
}
function App() {
  const myResult = useAsync(myFunction, false);

  return () => html`
    <div>
      <div>
        ${
          myResult.value ||
          myResult.error ||
          "Start your journey by clicking a button"
        }
      </div>
      <button @click=${myResult.execute} disabled=${myResult.pending}>
        ${myResult.pending ? "Loading..." : "Click me"}
      </button>
    </div>
  `;
}
const friendKey = Symbol('friendState');
function friendHook(friend) {
  return [
    { [friendKey]: { online: null } },
    () => {
      let handleStatusChange = status =>
        state().friendOnline = status.isOnline;
      ChatAPI.subscribeToFriendStatus(
        friend.id,
        handleStatusChange);
      return () => {
        ChatAPI.unsubscribeFromFriendStatus(
          friend.id,
          handleStatusChange);
      };
    }
  ];
}
function friendState() {
  return element()[friendKey];
}

function FriendStatus(friend) {
  return component`
    <friend-status ${friendHook(friend)}>
      <h1>${friend.name}</h1>
      ${() => statusText(friendState().online)}
    </friend-status>
  `;
}

Minimal, targeted DOM updates. No virtual DOM, and no diff heuristics. Uses the platform, no custom HTML parsing.