Coder Social home page Coder Social logo

mobx-static-dom's Introduction

Caution! this is isn't something ready for production; you may try it though in a side project

Getting starts

npm i --save mobx-static-dom

Simple Demo

Sandbox demo

import { h, p, on, render } from "mobx-static-dom";
import { observable } from "mobx";

const state = observable({
  count: 0
});

export const counterApp = h.h1(
  p.style("cursor: pointer"),
  () => `Count ${state.count}`,
  on.click(() => state.count++)
);

// assuming your html file contains an element with id="app"
render(counterApp, document.getElementById("app"));
  • Use h to create HTML elements
  • Use p to set DOM properties
  • Use on to attach event handlers
  • Use mobx to create observable values (values that will be changed by your app)
  • When createing HTML elements, wrap dynamic values in a function (() => state.count)
  • Call render to append the created element

Do not append the create elements directly to the parent DOM, it won't work

Dynamic lists of elements

Sandbox demo

import { h, p, on, map, render } from "mobx-static-dom";
import { observable, computed } from "mobx";

const state = observable({
  input: "",
  todos: []
});

function addTodo() {
  state.todos.push({ title: state.input, done: false });
  state.input = "";
}

export const todoApp = h.div(
  h.input(
    p.value(() => state.input),
    on.input(event => (state.input = event.target.value)),
    on.keydown(event => {
      if (event.which === 13) addTodo();
    })
  ),
  map(() => state.todos, todoView)
);

function todoView(todo) {
  return h.label(
    p.style(
      () => `
        display: block;
        text-decoration: ${todo.done ? "line-through" : "none"}`
    ),
    p.for("cb-done"),
    h.input(
      p.type("checkbox"),
      p.id("cb-done"),
      p.checked(() => todo.done),
      on.click(event => (todo.done = event.target.checked))
    ),
    () => todo.title
  );
}

render(todoApp, document.getElementById("app"));

Notes

  • Use map to render dynamic arrays
  • Event handlers are automatically wrapped with mobx actions

Local state

Sandbox demo

function panel(...children) {
  const state = observable({
    isContentVisible: true
  });

  function toggleContent() {
    state.isContentVisible = !state.isContentVisible;
  }

  return h.section(
    h.button(
      () => (state.isContentVisible ? "Hide content" : "Show content"),
      on.click(toggleContent)
    ),
    h.div(
      p.style(() => (state.isContentVisible ? visibleStyle : collapsedStyle)),
      ...children
    )
  );
}
  • Simply declare local state inside your function
  • Children elements are passed as ordinary function arguments

Simple router (dynamic element)

Sandbox demo

import { h, p, on, dynamic } from "mobx-static-dom";
import { observable } from "mobx";
import { createBrowserHistory } from "history";

export const history = createBrowserHistory();

export function router(config) {
  const state = observable({
    currentView: config(history.location.pathname)
  });

  history.listen((location, action) => {
    console.log(action, location.pathname, location.state);
    state.currentView = config(history.location.pathname);
  });

  // switch the current view
  return dynamic(() => state.currentView);
}

export function link(path, label) {
  return h.a(
    label,
    p.href("#"),
    on.click(event => {
      event.preventDefault();
      if (path === history.location.pathname) return;
      history.push(path);
    })
  );
}
  • Use dynamic to create dynamically changing HTML elements
  • Note the dynamic dierctive mounts a new instance of the wrapped element, so the internal state is gone when you switch back to the same element.

mobx-static-dom's People

Contributors

yelouafi avatar

Stargazers

Jason Butler avatar hardfist avatar Valentyn avatar Sjoerd de Jong avatar typoerr avatar Andrejs Agejevs avatar Young avatar __ avatar nhducit avatar tejesh avatar Evgeny Kochetkov avatar Ionut Achim avatar Alex Lévy avatar Baruch Velez avatar Lucas Alexander Floriani avatar Victor avatar Heaven avatar Matthew Francis Brunetti avatar Toan Tran avatar BK avatar 伊撒尔 avatar Matija Grcic avatar Kilin Mikhail avatar Michel Weststrate avatar Rodrigo Muniz avatar Sibelius Seraphini avatar Marko Roganovic avatar

Watchers

James Cloos avatar Young avatar Michel Weststrate avatar  avatar Ionut Achim avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.