WebReflection / hyperHTML

A Fast & Light Virtual DOM Alternative
ISC License
3.07k stars 112 forks source link

Improved documentation. #83

Closed WebReflection closed 7 years ago

WebReflection commented 7 years ago

I'm writing down as raw HTML (static content only, sorry) some documentation: https://github.com/viperHTML/viperhtml.github.io/blob/master/hyperhtml/documentation/index.html

You can read it online directly via this page: https://viperhtml.js.org/hyperhtml/documentation/

I'll try to write down the API too but there are already various examples and explanations of all the things you can do via hyperHTML.

There are also 52 examples: https://viperhtml.js.org/hyperhtml/examples/

Most of them updated to use V1. There are various Code Pen too.

The reason I'm opening this issue is to review, ask more, file bugs or PRs against what will be the official documentation page for this project.

Thanks in advance to anyone willing to help.

marcoscaceres commented 7 years ago

Thanks for the pointer. Will try to do an initial pass.

WebReflection commented 7 years ago

A first pass has been don already and merged few minutes ago.

Thanks for any further suggestion.

WebReflection commented 7 years ago

Heads up: mroe documentation has been written recently, including more examples.

There is also a components section that just landed live.

https://viperhtml.js.org/hyperhtml/documentation/#components

zwz commented 7 years ago

Document is very important to developers. Among many reasons, its document must be one for Vue's fast-growing population. The document of Vue has a very clear structure of how to develop SPA (with or without SSR) in the component-based way. I read the document several times. Hyperhtml is quite simple but versatile. But it is not very clear what is recommended way to organize the code and develop apps in hyperhtml.

WebReflection commented 7 years ago

I'm working on it @zwz :+1:

zwz commented 7 years ago

@WebReflection

And I am not sure about my understanding of the "wire ids" part in the document. I thought

sameLI === hyperHTML.wire(info)   <li></li>

should be true, so that it would be reused otherwhere. But It is not! Consequently, I cannot catch the point in the next example (create view for user).

WebReflection commented 7 years ago

I don't know what that sameLI is or where it comes from, but:

// this is always true
hyperHTML.wire(info)`<li></li>` === hyperHTML.wire(info)`<li></li>`

But you can use info to define one item in the list, and also a user profile

hyperHTML.wire(info, ':profile')
`<div>Name: ${info.name}</div>`;
zwz commented 7 years ago

I tested the code in nodejs (with viperhtml). The result is false. But in browser it is true. So viperhtml is different from hyperhtml?

WebReflection commented 7 years ago

this is hyperHTML repository, hence I provide answers for hyperHTML.

In NodeJS wires are buffers. You don't update dynamically viperHTML because all you produce at the end is a string / buffer as output.

The buffer is always different because interpolations will produce different strings.

If you need to create an empty LI, just pass ["<li></li>"] / {html: '<li></li>'} as array/intent directly, that is always identical to itself.

If you need interpolations, use the wire or bind, in viperHTML, which is not even documented yet, these are the same, it's just a 1:1 API.

If you don't need interpolations, don't use viperHTML 'cause it's overkill.

What viperHTML does on Node is to parse, optimize, sanitize, the static DOM parts once, and produce buffers with new interpolated values each time you reuse same templates.

You have an example in here: https://github.com/WebReflection/viper-news/blob/master/shared/view/index.js

every time a user asks for index.js, it will receive right away the answer with all the interpolated values updated. in that case the whole DOM structure is already known and ready to go, same goes for the header and so on.

Any better?

WebReflection commented 7 years ago

P.S. as you can see in the header file, I don't create wires there because there's nothing to sanitize. Those are just regular template literals, rendered as HTML without any XSS risk (static manual input) and as exmplicit opt-in through Array, instead of string.

If you have other questions about viperHTML, which is still not documented much on the official site, please ask as much as you want in viperHTML repository.

If you have a list of questions for viperHTML, please put all of them in so I can start writing documentation as users expect.

Thank you.

zwz commented 7 years ago

@WebReflection OK, I see. Thanks.

kidwm commented 7 years ago

I wish there would be a change log section in documentation.

WebReflection commented 7 years ago

Hi @kidwm I might try to add a new page for that, thanks for the hint.

kidwm commented 7 years ago

BTW, I didn't see hypermvc is mentioned in the documentation, is it outdated?

WebReflection commented 7 years ago

it's just a demo, why would I mention it ? Anyway, the TodoMVC is an outdated demo.

zwz commented 7 years ago

Nice to see hyper.Component in version 1.6. So I tried it to build an input with "x" button to clear its content, which I think maybe a good example for the document. Here is the code:

class XInput extends hyper.Component {
  constructor (name, type = 'text') {
    super()
    this.setState({name, type, [name]: '', css: 'visibility: hidden;'})
  }
  onfocus(e) {
    this.setState({css: ''})
  }
  onblur(e) {
    this.setState({[this.state.name]: e.target.value})
    let that = this
    setTimeout(function () {
      that.setState({css: 'visibility: hidden;'})
    }, 100)
  }
  clear() {
    this.setState({[this.state.name]: ''})
  }
  render() {
    return this.html`<div>
<input type=${this.state.type} name=${this.state.name} value=${this.state[this.state.name]} onfocus=${this} onblur=${this}>
<button style=${this.state.css} data-call=clear onclick=${this}>x</button></div>
`
  }
}

You may notice there is a setTimeout. Because if we hide "x" button immediately, the function "clear" would not be called ( @WebReflection, this bothers me a little ).

WebReflection commented 7 years ago

I don't know what you are trying to do. A blur is not a good entry point to hide buttons.

There is no Code Pen or similar. The pattern looks odd/weird so unless I understand what are you trying to do, what is your use case, where can I test it, I'm afraid I won't be able to help.

zwz commented 7 years ago

@WebReflection https://codepen.io/anon/pen/prmKdm?editors=0010 It is an input with a button to clear its content.

kidwm commented 7 years ago

@WebReflection @zwz So the main point is how to do DOM reference like ref in React way?

WebReflection commented 7 years ago

@zwz it's a funny pattern that doesn't consider accessibility at all. If you use your keyboard to navigate the input and then the button, you're making it impossible to use.

I do that very often online, so I would never go/promote such example.

However, it's easy to improve it, using delayed transitions, enhancing the visual feedback, and avoiding clicks by accident on the element.

https://codepen.io/WebReflection/pen/MvMwrM?editors=0010

WebReflection commented 7 years ago

@kidwm about this

how to do DOM reference like ref in React way

I am not sure how/why/when you need references "the React way" in hyperHTML, I'd like to see a use case to better answer that.

However, within the render you can do whatever you want after, including accessing nodes.

render() {
  var result = this.html`<div><p ref=whatever></p></div>`;
  var whatever = result.querySelector('[ref=whatever]');
  // do things with whatever
  return result;
}

Great News Everyone

The StackOverflow hyperhtml tag has been edited and approved.

I will no longer answer questions in the wild here so please use the tag in place more suitable for any sort of question so that everyone else can also start learning from examples and patterns.

Thank You!

zwz commented 7 years ago

@WebReflection Yes, you are right. Thanks. @kidwm In fact, everything is under your control in hyperhtml, see @WebReflection's code.