Giter Site home page Giter Site logo

redom / redom Goto Github PK

View Code? Open in Web Editor NEW
3.4K 50.0 125.0 7.98 MB

Tiny (2 KB) turboboosted JavaScript library for creating user interfaces.

Home Page: https://redom.js.org

License: MIT License

JavaScript 100.00%
javascript dom html5 web-development redom tiny

redom's Introduction

RE:DOM logo
Develop web applications with 100% JavaScript and web standards. ๐Ÿš€


Version Build Status JavaScript Semi-Standard Style License Backers on Open Collective Sponsors on Open Collective Join the chat
Follow @pakastin Follow @redomjs

RE:DOM is a tiny (2 KB) UI library by Juha Lindstedt and contributors, which adds some useful helpers to create DOM elements and keeping them in sync with the data.

Because RE:DOM is so close to the metal and doesn't use virtual dom, it's actually faster and uses less memory than almost all virtual dom based libraries, including React (benchmark).

It's also easy to create reusable components with RE:DOM.

Another great benefit is, that you can use just pure JavaScript, so no complicated templating languages to learn and hassle with.

Supporting RE:DOM

RE:DOM is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome backers.

If you'd like to join them, please consider:

Installation

# Using npm
npm install redom

# Using Yarn
yarn add redom

Documentation

To check out live examples and docs, visit RE:DOM.

Questions

For questions and support please use community chat.

Tools

Performance

Issues

Please make sure to read the Issue Reporting Checklist before opening an issue. Issues not conforming to the guidelines may be closed immediately.

Changelog

Detailed changes for each release are documented in the release notes.

Contribution

Please make sure to read the Contributing Guide before making a pull request.
Thank you to all the people who already contributed to RE:DOM!

License

MIT

Copyright (c) 2016-present, Juha Lindstedt and contributors

redom's People

Contributors

131 avatar absolux avatar andrejcremoznik avatar anttikissa avatar bfrengley avatar dependabot-preview[bot] avatar dependabot[bot] avatar evandrolg avatar fishead avatar gitter-badger avatar h-h-h-h avatar hville avatar joona avatar jscissr avatar katywings avatar maciejhirsz avatar mauroreisvieira avatar monkeywithacupcake avatar mrwanashraf avatar pakastin avatar paneraallday avatar petetnt avatar pocorall avatar raulil avatar ryanv avatar spapas avatar talmobi avatar terkelg avatar tomerigal avatar trautonen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redom's Issues

Composing components

This is is more of a question that an issue report.

How to compose components using RE:DOM?

What would be the RE:DOM equivalent of this?

<SomeComponent>
  <SomeOtherComponent/>
  <YetAnotherComponent/>
</SomeComponent>

Unable to install redom with npm

Calling npm install redom fails stating its a dependency of itself

C:\dev\redom>npm install redom
npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\apps\nodejs\node.exe" "C:\apps\nodejs\node_modules\npm\bin\npm-cli.js" "install" "redom"
npm ERR! node v6.10.3
npm ERR! npm v3.10.10
npm ERR! code ENOSELF

npm ERR! Refusing to install redom as a dependency of itself
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR! https://github.com/npm/npm/issues

npm ERR! Please include the following file with any support request:
npm ERR! C:\dev\redom\npm-debug.log

setChildren a component with a list as component el (update: of course...) not working ^^

Hey hey Juha :)

Danger: at the end is a Second Update, read that first please! ๐Ÿ‘ฏโ€โ™€๏ธ

Issue

I am working on the todo example and found out the following interesting behaviour:

Reduced example code: Link

jan 12 2017 7-20 pm - edited

Every time I setChildren a List element which is the el of a component, the el will be toggle mounted.


My current workaround is to wrap the setChildren of the app-div in an if(!inputElement.isMounted && !listElement.isMounted) { ... }, but this workaround might not work in more complex scenarios...

After the workaround it looks like this:

jan 12 2017 7-23 pm - edited 1


Do you have an idea why that toggle happens on mutlible setChildren?


Update 1

Update: I tried a little bit around in the setChildren function and found a strange bugfix at the Line:

    if (child.el) {
      // I noticed here, that child.el is not referenced to the dom element every second "setChildren", but just to the List, therefore to get the el it was needed to use child.el.el if defined :/
      if (child.el.el) {
        var childEl = child.el.el
      } else {
        var childEl = child.el
      }
    }
    else {
      var childEl = child
    }

Maybe you have an idea why the child.el is incorrectly referenced every second setChildren :)

Update 2

๐Ÿ˜ฉ I found out what I did wrong xD

class MyList {
  constructor() {
    // This is not good
    this.el = list('ul', Li);
    this.el.update([ 1, 2, 3 ].map(i => 'Item ' + i));

    // Better would have been this:
    this.list = list('ul', Li);
    this.el = this.list.el
    this.el.update([ 1, 2, 3 ].map(i => 'Item ' + i));
  }
}

What I now dont understand is why the problem only happens every second setChildren ๐Ÿณ

But today I am too tired to figure it out...

ListPool, Place and Router require View with constructor

Is there any reason why ListPool, Place and Router require view to have a constructor? E.g. for Router:

this.view = View && new View(this.initData, data);

I would much prefer something like:

function isConstructor(obj) {
  return !!obj.prototype && !!obj.prototype.constructor.name;
}

this.view = isConstructor(View) ? new View(this.initData, data) : View;

That would give me freedom to pass HTML Node or an object with el or a class into Router, ListPool and Place.

Are there any implications that I am not aware of?

PS: I like the idea of simplicity so if I can, I try to avoid classes as these are complex.

PPS: These 3 places are the only places where RE:DOM requires existence of a constructor so I must ask why? ;)

PPS: We could go even further -> check if it has a constructor, if not check if it is a function, if not just leave it as is, else call constructor or function

List update child api idea :)

Sorry for my annoying looking-by :P, just working on the Todomvc and stumbled upon something:

https://github.com/pakastin/redom/wiki/2.-API#listparentquery-childview-key-initdata

In your list helper, isn't it not quite common that one needs the index of the current li item in the update function of the item? Would you consider something like this? (Adding a second parameter to the list update children behaviour) I think this would not be API breaking :).

class Li {
  constructor () {
    this.el = el('li');
  }

  update (data, idx) {
    // idx is the index of this item in the [ 1, 2, 3 ] array
    this.el.textContent = data;
  }
}

const ul = list('ul', Li);

mount(document.body, ul)

ul.update([ 1, 2, 3 ].map(i => 'Item ' + i);

[BUG] setChildren with a element with children

Hi,

think i found another bug ; ). (Sorry for playing around with strange corner cases :D).

The following code

const {
  mount,
  el,
  setChildren,
} = redom;

const myElem = el('div');
const mySelect = el('select', [
  el('option', { value: '1' }, 'one'),
  el('option', { value: '2' }, 'two'),
  el('option', { value: '3' }, 'three'),
]);
setChildren(myElem, mySelect);

mount(document.getElementById('app'), myElem);

results in this html:

<div>
  <select>
    <option value="2">two</option>
  </select>
  <option value="1">one</option>
  <option value="3">three</option>
</div>

JSFiddle to play with: Example

Am i doing something wrong ?

Cheers

Marc

Provide attributes when creating a list

I would love to be able to (optionally, as can be done in el) provide attributes when creating a list, e.g., like so:

const ul = list('ul', {class: 'ul-styling'}, Li);

Is there a way to do this?

v4

v4 checklist:

  • .js โ€“> .mjs
  • Create better middleware system
  • Separate list, listpool, place and router
  • Simplify test system
  • Probably new websites, too
  • #104

Remove items from list

I have a list of elements where each element contains a link. When the user clicks the link the element will be removed. Each element is created from dynamic data.

I tried to create a view using something like this:

this.el = place(... this.close = el("a") ...);
var self = this;
this.close.onclick = function() {
    self.el.update(false);
}

The problem is when I mount the list of views. The elements are hidden and when I tried to use this.el.update(true) inside the view's update function I got an error.

What is the correct way to do this?
So far I have created an object to store each element. The onclick event finds its element in the object and umounts it.

One-field curry

Gonna keep the Feedback issue for more broader design discussion.

What do you think about having these being equivalent:

on({ click: callback })
on('click', callback)

prop({ src: url })
prop('src', url)

attr({ 'data-foo': 'bar' }) // this has to create a hashmap
attr('data-foo', 'bar')

โ“

Implementation is pretty simple - you can check for arguments.length and return different functions from the curry.

[Question] How to show/hide elements without display: none

  1. What a simple/right way to show or hide single elements on page without changing their style?
    For example, simple form with input fields, which depends on some user actions.
    I'm not sure that inserting all of this inputs with display: none to page is a good idea.
    I know about place, but create components for each single elements (like an input element) is not a best solution.
    And now we're returning to this issue.
<form>
  <input id="1">
  <input id="2">
  <input id="3">
  <input id="4">
</form

How to show/hide inputs with id 2-4? display: none/block?
this.input.style.display = "none/block" - use it every time when i want to display/hide it?

  1. How to insert multiple elements to page with place without div (or any other) container.
class MultipleElements {
  constructor() {
    this.el = el("div",
      el("input"),
      el("input"),
      el("input"),
    )
  }
}

this.el = el("form", 
  this.elements = place(MultipleElements),
  this.button = el("button", "Submit")
)

mount(document.body, this.el)

this.elements.update(true)

Here div container not needed, but i don't know how to add this inputs without it.

Thanks for answer.

list does not work properly with functional components defined with fat-arrow notation

Well what the title says:

  import { el, mount, list } from 'https://redom.js.org/redom.es.min.js';

  const h1 = el('h1', 'Hello modules!');
  class Li {
    constructor () {
      this.el = el('li');
    }
    update (i) {
      this.el.textContent = `Item ${i}`;
    }
  }
  function Li2() {
  	const liEL = el('li');
    return {
    	el: liEL,
      update: i => liEL.textContent = `Item ${i}`
    }
  }
  const Li3 = () => {
  	const liEL = el('li');
    return {
    	el: liEL,
      update: i => liEL.textContent = `Item ${i}`
    }
  }
  
  const ul = list('ul', Li);

  ul.update([1, 2, 3]);
  mount(document.body, ul);

In the above code I've defined three Li-like components (Li, Li2 and Li3). Both Li and Li2 work as expected. However when I use const ul = list('ul', Li3) I see the following error:

TypeError: View is not a constructor

I understand that probably this is because of the difference between function-declared and fat-arrow functions (since they bind their this differently) but it needs to be written in the documentation so that people won't be dissapointed by their code not working with fat-arrow functions.

ES modules

At first, Thank You for a great job! <3

How do you look at the idea of adding native ES modules support to the source code? Browsers that support modules will also support full ES6 syntax(which is used in the source code).
It will look like hyperHTML/esm.

What is needed for this?

  • Add '*.js' to all imports paths;
  • Replace module field in a package.json with src/index.js(instead of dist version).

List example on redom.js.org incorrect?

Referring to the "Sync lists" part. Shouldn't the resulting HTML be the following?

<body>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</body>

Since this is what happens in the update method:

this.el.textContent = `Item ${i}`;

[Question] Updated elements - diff

Thanks for this great UI library.

One thing I was wondering, lets say you have a component with a lot of props like {title}, {description}, {images} which holds multiple {image} which in turn holds {caption}, {src}, etc. and say one prop in that image changes. Maybe the src of the 2nd image. You do an update on that component.

Is only that specific src attribute being reset or will the whole component be re-rendered?

From the examples I can tell it seems up to the developer to write logic for this in the update function but is there an easy way to only have the specific tags and attributes be targeted?

Unmount call with not yet mounted component returns an exception

Unmounting a component that has not yet been mounted, currently returns DOMException at least on version 3.4.0.

const notYetMounted = new FooComponent();
unmount(document.body, notYetMounted);

raises an exception:

Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

Fragments

Is it possible to create a component in, RE:DOM, that consists of two or more top-level elements?

class AandB {
  constructor() {
    this.el = [el("element-a"), new ComponentB()];

These are called "fragment", "multi-root component", "containerless" etc in other frameworks.

redom loop

Hello,

I was wondering if there was an easy way to deal with loop while creating the DOM with RE:DOM? Because I didn't find any in the doc or here in the issues.

So this is what I came up with if anybody is interested, guess this is improvable :

let presetsList = [
  {
    id:'11111',
    image:'https://redom.js.org/img/logo.svg',
    name:'redom image'
  }
];

let container = el('div.siimple-menu',
  (() => {
    let arr = [];
    for (let i = 0; i < presetsList.length; i++) {
      arr.push(
        el('div.siimple-menu-item',
          el('img', {src:presetsList[i].image})
        )
      );
    }
    return arr;
  })()
);

Cheerz ;)

URL-based routing

First of all, thank you for such an elegant and simple library. I really like the concepts presented here.

Are there any plans to offer a URL-based router using the History API or would it be better to create a Page class that uses the lifecycle methods to accomplish this?

the html cache

heya! im just scrolling over the code for endless time, and noticed one thing.

in the src/html file, when query is string u send it to memoizehtml if not exist in local cache object u just return the result of createElement, but u dont assign it to the cache.

so next time when the query argument is the same string it again will not get it from the cache.

ps: damn, i cant upload screenshot from android? huh..

RedomComponentConstructor type definition bug

I migrating my game engine project that uses ReDOM to use TypeScript. I'm glad you have made type definitions in ReDOM!

But I found a bug.

export function list(parent: RedomQuery, View: RedomComponentConstructor, key?: string, initData?: any): List;

...

export interface RedomComponentConstructor {
    new (): RedomComponent;
}

This means that all RedomComponent classes that I pass to list() must have a constructor without any parameters. However, List has this useful feature of passing initData: new View(initData, item, i, data).

So, I think it would be good if RedomComponentConstructor interface would have those four optional parameters defined. ๐Ÿ™

sample list const is same name as function

Need to update some of the samples, like list function and const have same name

import { el, list, mount } from 'redom';

class Li {
  constructor () {
    this.el = el('li');
  }
  update (data) {
    this.el.textContent = data.name;
  }
}

// const cant be same name as function...
const list = list('ul', Li, '_id');



New question about List.update.

https://gist.github.com/MrSorcus/7f6fc5140360be0903f935173fce70de
and
http://todomvc.com/examples/angularjs/ (Here used Angular 1.X)

Steps to reproduce (for both links):

  1. Add five elements (1, 2, 3, 4, 5)
  2. Tap checkbox on element 3
  3. Remove first element.
  4. Element 4 blinking.

I understand why it's blinking (maybe), but i think that is not normal.
Angular 1.X has similar behavior, but not Angular 2.X (http://todomvc.com/examples/angular2/) or React (http://todomvc.com/examples/react/) or any other.
Is it possible to fix it? Thank you.

SVG lists?

Hi, is it possible to make a list from SVG like this:

<svg width="360" height="170">
  <rect x="0" y="150" width="10" height="20" fill="#2980b9"></rect>
  <rect x="12" y="145" width="10" height="25" fill="#2980b9"></rect>
  <rect x="24" y="140" width="10" height="30" fill="#2980b9"></rect>
  <rect x="36" y="135" width="10" height="35" fill="#2980b9"></rect>
  <rect x="48" y="130" width="10" height="40" fill="#2980b9"></rect>
  <rect x="60" y="125" width="10" height="45" fill="#2980b9"></rect>
  <rect x="72" y="120" width="10" height="50" fill="#2980b9"></rect>
  <rect x="84" y="115" width="10" height="55" fill="#2980b9"></rect>
  <rect x="96" y="110" width="10" height="60" fill="#2980b9"></rect>
  <rect x="108" y="105" width="10" height="65" fill="#2980b9"></rect>
  <rect x="120" y="100" width="10" height="70" fill="#2980b9"></rect>
</svg>

I've tried to create it with:

class Rect {
  constructor() {
    this.el = svg('rect');
  }

  update({
    x,
    y,
    width,
    height,
    fill,
  }) {
    setAttr(this.el, {
      x,
      y,
      width,
      height,
      fill,
    });
  }
}

const svg = list('svg', Rect);
svg.update([/*...*/])

But it does not seem to work as, as far as I understand, list is created with el, not with svg.

router portion of api docs inconsistent

In the api docs, the App update function takes one destructured object ({ section, data }), but the actual instance passes two arguments to the update function ('a', { val: 1}).

class App {
  constructor () {
    this.el = el('.app',
      this.content = router('.content', contentViews)
    );
  }

  update ({ section, data }) {
    this.content.update(section, data);
  }
}

const app = new App();

app.update('a', { val: 1 });

Add no-module example in homepage

Since there's a number of browsers that don't support the JS module via script tag feature (https://caniuse.com/#feat=es6-module) I think it'd be nice if you also add a no-module example in the homepage so that the fact that the library works that way also is declared more explicitly. Something like this:

<div id='root'></div>
<script type="text/javascript" src='https://redom.js.org/redom.min.js'></script>
<script type="text/javascript" 
    redom.mount(document.getElementById('root'), redom.el('h1', 'Hello modules!') )
</script>

TIA

Event handling :>

Hey hey

I like new ways to develop in a modern way with minimal resources and therefore I enjoy the ideas behind RE:DOM

Every app needs some buttons and event handlers for them, I saw you allow to setup those bindings in el('fu',{onclick: myFunc}, 'bar')

Do they work when the fu element is rendered after some async magic? Got frustrated with jQuery lately which didnt allow late bindings on dynamic elements.

And is it possible to use anonymous functions?

JQuery compatibility

Hi,

Is RE:DOM compatible with JQuery? Since I purchased a HTML/CSS/SCSS/JS template which makes use of JQuery and I would like to break this template into components with help of RE:DOM to facilitate my development. Hence my question.

Regards.

The nodom/server side functionality does not seem to work.

I'm trying to setup tests for a project and running into issues with the nodom/server side functionality. To simplify a bit, using the example from this project and nodom fails when I directly run it as well:

const { Document, render } = require('nodom');
const document = new Document();
const { el, mount } = require('redom');

mount(document.body, el('h1', 'Hello world!'));

console.log(render(document.body));

I get the following:

/home/jdoe/Desktop/redom-test/node_modules/redom/dist/redom.js:11
document && (style = document.createElement('p').style);
^

ReferenceError: document is not defined
    at /home/jdoe/Desktop/redom-test/node_modules/redom/dist/redom.js:11:1
    at attached (/home/jdoe/Desktop/redom-test/node_modules/redom/dist/redom.js:2:65)
    at Object.<anonymous> (/home/jdoe/Desktop/redom-test/node_modules/redom/dist/redom.js:5:2)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)

With:

  • node 7.10.0.
  • redom 2.6.1

[BUG] setChildren with text

Hi,

i think i found a bug in the latest version (3.10.2).

In Version 3.8.8 setChildren with a text node worked:

const {mount, el, text, setChildren} = redom;  
const app = document.getElementById('app');  
const myParagraph = el('p', 'text');  
mount(app, myParagraph);  
setChildren(myParagraph, [el('strong', 'title'), text('text')]);  

This results in

<p><strong>title</strong>text</p>

In the latest version the text node will be ignored.

Jsfiddle example to play with: Example.

Cheers

Marc

Ps: Keep up the good work, i love redom ; )

Toggle attributes with setAttr

It would be nice if I could add/remove attributes with ease.
Would you consider modifying setAttr to handle a boolean value like Mithril?

setAttr(el, { checked: true })   // => <input type=checkbox checked>
setAttr(el, { checked: false })  // => <input type=checkbox>

No mount events when mounting into Shadow DOM

Hi!

Love this library. Found a little quirk though today.. I've been using ShadowRoots to create safe containers for styles etc, and have been using Redom to populate the root with elements (which works fine):

const myRootEl = document.createElement("div");
const myRoot = myRootEl.createShadowRoot();

function MyCustomElement() {
  this.el = el("div", "Hello there");
  this.onmount = function() {
    console.log("Mounted..");
  }
}

const myElement = new MyCustomElement();
mount(myRoot, myElement);

In my example ^, "Mounted.." is never logged. If I were to change the mount line to mount(myRootEl, myElement) (so that it mounts to a "real" element), the log comes.

This problem may become more prevalent as the Shadow DOM API is implemented by more browsers, but it has been in Chrome for some time. Are there any plans to fix this? Would you accept a PR if you're too busy?

Idea for setChildren

How about allowing to use it without passing an array but just one component / el? Or do you consider this as an "unclean" approach?

Personally I actually pretty much always try to allow (item) instead of ([item]) for my own API's ๐Ÿ’ƒ.

I know this.el.textContent = this.childComponentInstance.el would work too, but its just not that nice ;)

Feedback

Gonna do it here instead of mail because formatting code and stuff :).

Nice to see this coming up! I'll definitely enjoy participating on this, I like goofing around with implementing things half way, but I'm still not sure if I'd roll it out as is.

Performance

Benchmark numbers on my hardware:

Benching REDOM <div> with multiple child nodes
10692ns per iteration (93529 ops/sec)

This is a regression from my implementation (it was 6500ns btw, not 5200ns, turns out I had a bug that made all tags into <div>s which simplified all the bindings). Passing a function as an argument is powerful, but unless you do it as a reference to a function it also can be costly when you are using curry or other function builders.

I made a PR with my benchmarking tool thing, poor as it may be. It might be a good idea to test things for performance regressions when deciding whether not a particular feature should make it in.

My benchmark was fast because I only used the function call once (to set the class), and it was delegated as the last variant on the if/else branch as to not slow down text and element nodes, which should make up for the bulk of the markup. The trio of String / Node / Function worked pretty well, which brings me to the next point...

Verbosity

    div(
        h1(setClass('doom'), 'Hello ', b('DOOM'), '!'),
        p('Bacon ipsum dolor amet meatloaf meatball shank porchetta \
            picanha bresaola short loin short ribs capicola fatback beef \
            ribs corned beef ham hock.')
    );

Became:

    div(
        children([
            h1(className('redom'), text('Hello '), children([
                b(children([
                    text('RE:DOM')
                ]))
            ]), text('!')),
            p(
                text('Bacon ipsum dolor amet meatloaf meatball shank porchetta \
                    picanha bresaola short loin short ribs capicola fatback beef \
                    ribs corned beef ham hock.')
            )
        ])
    )

That's way more verbose. While I typically prefer things explicit over implicit (I do code in Rust after all), I don't particularly like verbosity that doesn't add much, those things belong in the realms of XML and Java ๐Ÿ˜….

  • The fact that text() is a curry while functions such as b() produce an element got me confused since they both are abstractions of the same type of an object - a Node. It also means I can't use element functions directly as arguments, and I can't use text() calls as children.
  • I had to break things into more lines because the sheer number of brackets and parens made it difficult to keep track of things.

Components

I've been goofing around with how to do components with functions for dbmon, my last attempt was this:

    function cell() {
        var elapsed = span();
        var popover = div(setClass('popover-content'));
        var el = td(
            elapsed,
            div(setClass('popover left'), popover, div(setClass('arrow')))
        );

        function mount(parent) {
            return el;
        }

        mount.update = function (data) {
            el.className = data.elapsedClassName;
            elapsed.textContent = data.formatElapsed;
            popover.textContent = data.query;
        };

        return mount;
    }

Which I'm not very happy with. Having a this to bind elements you create like you'd do in FRZR components is very handy, and the functional alternative isn't very clean since variable declarations are statements and not expressions in JS.

I like your example more:

const login = form(
  children(el => [
    el.email = input(props({ type: 'email' })),
    el.pass = input(props({ type: 'pass' })),
    el.submit = button(text('Sign in'))
  ]),
  events({
    onsubmit (el, e) {
      e.preventDefault();

      console.log(el.email.value, el.pass.value);
    }
  })
);

But it has some problems. I'm not a fan of sticking random members on elements - you might get name conflicts if you are unaware, and the concept is not future proof as the standard can expand and something you've been using as a custom member can become a thing in the future, thus introducing breakage.

Actually using something akin to FRZR components would be an option here, with the views being created a function curry: div(attach(Component)) or div(mount(Component)).

Other things.

  • I've figured that the function passed in could return a child. This made the hasChildren for textContent specialization simpler, and can be used to implement the component mounting.

  • One idea I had for creating a references would involve a curry such as:

    var el = div('Hello ', ref('name', text('Bar')), '!');
    el.refs.name.textContent = 'World!';

    This would not be necessary should we use more FRZR-like components, but it's an idea. It also scopes are custom props to a single object (refs) instead of polluting the member space.


I can roll out a PR with roughly the same implementation I've had before to see how you like it.

List update + clear

first, i like that awesome lib!

my question is, after i do something like

list.update(data1)
list.update(data2)

data1 & data2 are in my list, fine... but how is the proper way to clear that list?

thanks

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.