Giter Club home page Giter Club logo

superfine's People

Contributors

2hu12 avatar acstll avatar andrewiggins avatar c01nd01r avatar chadonihi avatar dancespiele avatar jorgebucaran avatar maxholman avatar mindplay-dk avatar osdevisnot avatar pspeter3 avatar svaterlaus avatar tscholl2 avatar whaaaley avatar zaceno 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

superfine's Issues

Slots?

Vue components have this feature: https://vuejs.org/v2/guide/components.html#Named-Slots Seems like this feature is possible in React as well, albeit by plugging in some third party components

Now I wouldn't say this is a crictical feature exactly, but it makes layout-components a bit more readable. I haven't given it very much thought, but it seems like it's not possible with picodom today to create "slotted" layout components in this way. I think it would require some sort of magic in h to be possible.

Has anyone considered this? Any ideas as to how this could work?

Add test for picodom.d.ts (add working type-declarations)

The d.ts file appears to be full of errors.

The VNode<Data> interface doesn't use the Data type-argument, and references a type Props which doesn't seem to exist.

The rest-param children in Component<Props> isn't valid - rest arguments must have an array-type. Same for h<Props>.

The patch function was declared with a default argument value document.body, which I don't think you can do in interfaces.

Is the d.ts file just a draft or something?

A test for the type-declarations probably ought to be added.

Add tests.

Add tests in test.js.

  • Choose a test framework jest
  • Test h.js
  • Test patch.js
    • Test individual functions.

Add documentation.

  • Tidy up README.
    • Best if there was only one, but good example.
  • Add documentation under /docs.
  • Complete API docs: add lifecycle events, keys, etc.

Avoiding the extra wrapper tag?

I wonder if there's any way to avoid an extra wrapper tag?

What I mean is, let's say I have a page with a div with id=app on the page - I use this as the root, but my JSX is going to start with a root wrapper of its own, so now I'm two levels deep already.

Could this be addressed somehow? Not easily, I guess - since diff is done on VNodes, we can't directly diff against an existing root element.

I'm a bit bothered by the fact that the implementation strategy dictates the HTML structure. What if I'm adding to a project with pre-existing CSS that doesn't fit? What if my CSS/HTML designer guy is opinionated? ;-)

I don't know, maybe it's not worth worrying about?

It was possible with hyperHTML, which is why I'm noticing the difference - it didn't enforce a single root node, and diffs directly against the DOM. (which is not an approach I'd suggest.)

questions about setElementProp()

I've been studying the source code closely, and have a few questions regarding setElementProp():

  1. How or why is it useful/relevant to set a single prop? Aren't props always a set? If so, shouldn't this be setElementProps() (plural) to avoid the loop and function-call overhead at every call site?

  2. Regarding setting of properties (not attributes), this line:

    try {
      element[name] = null == value ? "" : value
    } catch (_) {}

    Why the null (ish) check and defaulting to empty string? It's not a given that the property being set is even a string property. It's also not a given that I wouldn't want to set a property to null. These are object-properties, but they seem to get treated like attribute-values?

    And why the catch? Capturing a stack-trace is expensive, isn't it? Might be cleaner to check for existence with name in element prior to setting?

  3. Regarding the overall logic:

    try {
      element[name] = null == value ? "" : value
    } catch (_) {}
    
    if (typeof value !== "function") {
      if (null == value || false === value) {
        element.removeAttribute(name)
      } else {
        element.setAttribute(name, value === true ? "" : value)
      }
    }

    Aren't we doing double duty here? First setting as property-value, then setting as attribute-value. If we had the property-check (above) we'd could make these mutually exclusive, so properties take precedence over attributes, and so we don't do double assignments - probably more correct and better for performance?

For example, right now, if I do something like <div innerHTML={content}>, I will end up with the same HTML injected as an attribute-value.

Unexpected reordering after keyed removal

Per this example using current unstable picodom @2.0.0

https://jsfiddle.net/4eunk2um/

Click to remove elements from the list, and note how the removed element always ends up at the bottom of the range - because it doesn't get destroyed until 2 seconds later.

Keyed updates presumably exist, for one, so you can do this sort of thing?

Broken link to the API documentation

Hello!

Thank you for sharing this. Very cool stuff!

I was poking around the documentation and noticed the README.md in the docs directory wasn't correctly routing to the api.md file.

Thought I might help out (albeit in the smallest way possible) while I was browsing around.

Add @next tag

Could we have a dist-tag for picodom@next please?

So we can more easily help beta-test the next major version, updating examples, etc. before release.

Style attribute isn’t set in DOM

Hi! Thank you for the lib!

Ran into an issue with a missing style tag:

const { h } = require('picodom')
const hyperx = require('hyperx')
const html = hyperx(h, {attrToProp: false})

const a = html`<div style="height: 100%; background-color: red;">123</div>`
console.log(a)

console:
screen shot 2017-08-27 at 9 45 02 pm

DOM:

<div>123</div>

Tried in the example pen (thought maybe hyperx is to blame), same thing:

https://codepen.io/anon/pen/jLvjOQ?editors=0110

Indistinguishable properties and attributes

Currently, the patch() function treats every JSX attribute simultaneously as a property and an attribute - it initializes both, which means you have no ability to update them individually.

Blindly treating every JSX attribute as both a property and an attribute means that most updates are unnecessarily being done twice - one of them generating either a meaningless property or a meaningless DOM attribute. The DOM accumulates a lot of garbage this way.

For example, <div innerHTML={content}> will inject literal HTML via the innerHTML property, but will also create a useless innerHTML attribute - or in some cases, such as <input value={value}>, will initialize the value twice, first using the value property, then again using setAttribute('value', ...).

I don't have a lot of references, but snabbdom for one separates properties from attributes - which seems sort of inevitable, at the VDOM level, if we want to solve this problem?

Remove container default

Just an opinion based on my personal learning experience with this library.

I'd like to suggest removing the default value for container in the patch function.

I found it quite surprising that there was any default at all - but since the default is document.body, your first experience, if you're following the example, will be that of your own document getting wiped out, which was pretty surprising to me.

Also, when looking at the example in the README for the first time, my first thought was, "if both of the arguments are virtual DOM nodes, how does it figure out which real DOM element to updated?"

Of course, you learn these things quickly if you start poking through the source-code, but most people will likely jump in without reading documentation, or copy/pasting the example - making this argument non-optional might remove any confusion about how a target element is established and/or what happened to your existing body-content.

Defaults don't always curb the learning curve - sometimes they increase it.

Event handlers have no context?

Looks like event-handlers have no this context?

For example:

<button onclick={ () => console.log(this) }>Hello</button>

It looks like this is the number 0?

I was expected maybe this would reference the event target - the button element?

(If we address this, it likely needs to be addressed separately for the life-cycle events.)

Where are tests? :/

First, thank you and congratulations for this amazing library.

We adopted VanilllaJS and it can solve a lot of problems like: bind events in literal dom strings, child replacement right way etc.

BUT

No tests are made and we're afraid to use it. I was seeing the code, and it's really simple. I imagine that tests will be easy. Has any prevision to do it? If you need help, we can relief you.

Regards,
Fabio Carvalho

Custom Elements Everywhere

This seems like a good initiative:

https://custom-elements-everywhere.com/

Demonstrating support for custom elements would probably be a good move to make sure we're ready for the future - as well as to promote the library.

(hyperHTML is the only other lightweight framework on the list, and one of the only ones passing all the tests.)

Any thoughts for "on" attributes for custom events?

I use Picodom in Switzerland due to its size. Definitely good work!

However lately I've been wondering whether it'd be possible to support custom on attributes. For example: <todo-input onadd={() => ...} /> which would desugar to ~node.addEventListener('add', () => ...) where the todo-input node could dispatch add events using the CustomEvent constructor.

Add JSX support for Typescript

With the right declarations in the d.ts file, we should be able to compile directly to h() calls from Typescript, without an additional Babel transform after compiling - as well as getting type-safety and IDE support for JSX expressions in Typescript.

I found clues here and supposedly Snabbdom has this feature.

I will likely experiment with this myself soon, and will post results here if I make any progress :-)

Broken source-maps in `@next`?

Looks like the source-map has gone bonkers in the 2.0 beta?

source-maps

It thinks node is undefined, and somehow node.type is a VNode, in the same expression??

And this is a trivial example like patch(root, null, <div>LALALA</div>), which doesn't work anymore...

patch.js:117 Uncaught TypeError: Cannot read property 'type' of null
    at l (patch.js:117)
    at Object.n [as patch] (patch.js:4)
    at window.setTimeout (media.tsx:61)

I mean, all the tests were passing, so what the....?

Update Redux example codepen

Picodom is real nice, thank you for your work!

Due to 1.0.0 API change:

you don't need to keep track of the patched element since we are able to infer it based on the supplied container

the createRenderer method in the Redux example Codepen should be changed, if I’m not mistaken, to:

function createRenderer(view, store) {
  let element
  return () => {
    patch(element, (element = view(store)))
  }
}

use patch nested

Hi,
i would like to use the command patch nested, so patch did not render the complete website dom.

Example:

const messages = ['hello', 'spam'];
function renderMsg (msg) {
  return V.h('div', {'class': 'ui floating message',
    'onclick': () => {
      if (messages.indexOf(msg) !== -1) {
        messages.splice(messages.indexOf(msg), 1);
        renderNotifications();
      }
  }},msg);
}
function renderNotifications(main) {
  V.patch(el, el = V.h('div', {'class': 'notifications'}, messages.map(renderMsg)), main);
}

let notifyEL = V.h('div');
renderNotifications(notifyEL);
V.patch(body, body=V.h('div',null,notifyEL),document.body);

Is this on any way possible?

TypeScript Conversion

This looks really great. How would you feel about converting to TypeScript? (happy to help)

RFC: Should we drop built-in core JSX support?

Should we drop built-in JSX support? Yes or No?

This involves modifying (simplifying really) how hyperapp.h works, by making it monomorphic (single signature) instead of the current implementation that supports multiple varargs (arguments are slow!).

Pros

  • Better performance.
  • More liberty in how components are used / instantiated.

Cons

Ref

Keyed DOM-nodes get rerendered when they shouldn't?

Take a look at these runnable examples, one written with petit-dom and the other with picodom:

Picodom

<body>
<script src="https://unpkg.com/picodom"></script>
<script>
var { h, patch } = picodom

list = ["text0", "text1", "text2", "text3", "text4", "text5", "text6"];
oldnode = null;

function render() {
  node = h("div", {}, listElements());
  patch(oldnode, node, document.body);
  oldnode = node;
}

const listElements = () =>
  list.map((txt,idx) => {
    return h(
      "div",
      {
        onclick: () => {
          list.splice(idx, 1);
          render();
        },
        onupdate(e){
        	console.log(e)
        },
        key: txt
      },
      [txt]
    )});

render();
</script>
</body>

Petit-dom

<body>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/petit-dom.min.js"></script>
<script>
var { h, mount, patch } = petitDom

list = ["text0", "text1", "text2", "text3", "text4", "text5", "text6"];
oldnode = h('div', {}, ['first']);
document.body.appendChild(mount(oldnode));

function render() {
  node = h("div", {}, listElements());
  patch(node, oldnode);
  oldnode = node;
}

const listElements = () =>
  list.map((txt,idx) => {
    return h(
      "div",
      {
        onclick: (e) => {
          var i = idx
          list.splice(idx, 1);
          render();
        },
        key: txt
      },
      [txt]
    )});

render();
</script>
</body>

Open Chrome devtools, inspect elements and click on any text label do remove it, notice that the algorithm in picodom applies dom-changes to all the text-labels after the actual label (see animated gif below). They are also logged with the onupdate hook. But with petit-dom they are not. Is this expected behavior?

out

Documentation for routing.

Picodom is a great VDom library, but it still needs routing. I was hoping to remedy this by using a 3rd party router, but I haven't had any luck with this. Can someone demonstrate how to achieve routing in this library?

Add types for VDOM events.

We have 3 VDOM events at the moment:

  • oncreate(element)
  • onupdate(element, oldProps)
  • onremove(element): remove

But they are not typed in the type declarations.

Change `data` to `props`

In order for vdom decorators like hyperapp-transitions to remain compatible with both hyperapp and picodom

I plan on making a PR myself if no one beats me to it. Just leaving myself a reminder here :)

Transactional/scheduled DOM updates

I completely understand if this is out of scope for this library - I'm mostly asking to make sure it's been considered and deliberately omitted.

If you're familiar with fastdom, scheduled/transactional DOM updates eliminate DOM thrashing, as do most modern libraries/frameworks. I'm not proposing we use this library, I'm merely wondering if this is common enough that you'd want the library to cover that.

I understand that there's nothing preventing you from implementing this library or the technique in your own application or framework - but unless it's something you plan for and design around, you're more likely than not to end up creating something that does thrash the DOM, and maybe that's not a desirable "default", if we can design a simple/solid solution around it?

I think it's worth considering, though as said, I completely understand if this is out of scope.

Keys

The current implementation of picodom supports keyed elements.

This was an important feature in HyperApp, but is it just as important in picodom and can we avoid it?

/cc @zaceno

Setting opacity to 0

I set opacity to 0 as follows:

h( "div", { class: "", style: { width: 15, height: 15, opacity: 0 }, oninsert: function(el) { checkEl = el; } }, "✔" )

Picodom is not outputting an opacity css style prop on the element. If I set it to 0.1 or higher it does.

Add type declarations

@andrewiggins I figured I'd create a separate issue for this one, since your work is already enough to get projects up and going without it.

It would be great if we could also get some type-checking for elements and attributes - standard DOM as well as pico's oncreate etc., and possibly SVG elements. (does pico support SVG?)

I tried something like [elemName in keyof ElementTagNameMap]?: any; in the IntrinsicElements declaration - I think I've seen others doing something similar, but I couldn't make it work.

Snabbdom redeclares the whole kit'n'kaboodle, I guess maybe that's a necessary evil if we want type-checking for elements/attributes?

Either way, we can leave this for a future version, once the overall type-declarations are fully in place.

(feature) Something like `context` in React

Would it be possible to have something like context in React?

An object that you could set once on initialisation (in a custom render function at the top of your app) and then somehow access it later down in the component tree?

It'd be mostly for convenience, since I'm already passing an object (I think you call it data) down, and get my state from it.

I'd like to build something similar to react-router to be used with this library.

What do you think? is this even possible? a stupid idea?

Add support for JSX fragments

JSX fragments are a thing now - we should add support for this.

Note @jorgebucaran: since you're planning to rewrite the diff algo, I'd suggest writing it with fragments in mind - that is, work from the assumption that everything is a set. It's generally simpler/easier to work from the assumption of zero-or-more sets of (V)Nodes than dealing conditionally with nulls. (I tried to work from that assumption in my own rewrite, where, internally, the patch operation works with sets, and the public patch-function starts by dealing with null by turning it into an empty set, so that the internal algo doesn't need to deal with nulls at all.)

Add performance suite

I'd like to propose the additon of a basic performance suite.

While micro-performance is not my primary concern, having the ability to benchmark branches against each other could be useful when making changes or optimizations, to ensure performance doesn't degrade going forward.

I'd also be curious to include a competitive benchmark against at least one of the competing frameworks - likely the best way to do that, would be a contribution to js-framework-benchmark. I'm particularly interested in learning whether frameworks such as hyperHTML are really substantially faster because they avoid a virtual DOM intermediary. (I suspect the difference isn't at all watershed, and/or possibly using VDOM is even faster, on account of it being so much simpler overall.)

(Perhaps js-framework-benchmark could also provide the building blocks for a benchmark suite in-project?)

If you'd like me to contribute, let me know if you have a benchmark framework preference.

Using styles as strings doesn't work

So this h('div', {style:'background:red;etc..'}) doesn't work styles are assumed to be an object.. Is it supposed to be like that or should we accept strings as well? Line 56 in patch.js

Also the NPM is pointing to an old version compared to the docs

const element = patch(
  parent,  // parent HTMLElement to be patched
  oldNode, // the old VNode
  newNode  // the new VNode
)

does't work, call signature has changed.

Typescript: add default type-argument to VNode

Having to explicitly type-hint node arguments as Node<{}> gets tedious doesn't read well.

Can we make it the default?

export interface VNode<Props = {}> {
  type: string
  props?: Props
  children: Array<VNode<{}> | string>
}

This way you can type-hint as just Node.

We can then clean up all the other VNode<{}> type-hints in the declarations file as well.

Redux support

Would be nice to include components for use with redux. Though I'm unsure if there's a concept of a context, which would be required as a prerequisite.

npm install doesn't work

npm install turbodom yields a folder node_modules/turbodom containing nothing but a package.json file.

Installing through: npm install turbodom/turbodom (from github repo), creates the node_modules/turbodom folder containing only: package.json, LICENSE.md and README.md

In either case require('turbodom') can't work

what's the cb argument to patch() ?

The patch() function accepts a fourth argument, cb, which appears to be unused and gets immediately overwritten in a while-loop inside the function.

This argument also doesn't figure in documentation or in the Typescript declaration file.

What's it for?

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.