Search code examples
javascripthtmldomecmascript-6hyperhtml

Using an external library with HyperHTML


We are looking to integrate HyperHTML into a chat application.

Currently, we use moment.js and timeago for the human-readable timestamps of last time chat was posted. Also the last msg preview in chat list updates frequently but not as frequently as timestamp. All these components are individual but also each together wrapped in an li per chat.

So using hyperHTML with external libraries (like TimeAgo) that attach a time tag to the DOM, and render from the DOM, we are wondering best practice? How can I use timeago() function in hyperHTML template literal?

 hyperHTML.bind(document.querySelector('#txtra_chatMessages'))
   <li class="chatEl their-msg" id="i_${results.addedon}">${results.searchResults}${results.sidebar}<\/li>
   //$('#txtra_chatMessages').append(results);
   //$('time.t-ago').timeago();

Solution

  • sorry for the wait. Before I answer your question, I'd like to underline a fundamental issue with your example: the partial id attribute:

    id="i_${results.addedon}"
    // should be (with or without quotes)
    id=${'i_' + results.addedon}
    

    There is no partial attributes support in current hyperHTML for the simple reasons these are just an unnecessary logic overhead.

    Now that I've clarified this important point, I can answer your question.

    External libraries and hyperHTML

    You can easily integrate hyperHTML with any project you want, as long as you understand "who owns what".

    This means once you create content via hyperHTML, either via bind or wire, such content should not be manipulated by obtrusive 3rd parts libraries.

    As example, the jQuery slider() is an obtrusive plugin because it trashes, replaces, and pollute with extra content the node, interfering with hyperHTML logic.

    In order to make it work without issues, you can create a container node to target instead of changing directly nodes used as interpolated values.

    You can see a live example here.

    The timeago plugin

    In this case the plugin is not necessarily obtrusive and you could use it this way:

    const chat = hyperHTML.bind(
      document.querySelector('#txtra_chatMessages')
    )`
      <li
        class="chatEl their-msg"
        id="${'i_' + results.addedon}"
      >
        ${results.searchResults}
        ${results.sidebar}
      <\/li>`;
    
    $('time.t-ago', chat).timeago();
    

    However, the ideal usage of this plugin would be creating text info directly within results.

    const {bind, wire} = hyperHTML;
    const chat = bind(
      document.querySelector('#txtra_chatMessages')
    )`
      <li
        class="chatEl their-msg"
        id="${'i_' + results.addedon}"
      >
        ${results.searchResults.map(result => wire(result)`
          <span>
            ${result.text}
            (${$.timeago(result.date)})
          </span>`)}
        ${results.sidebar}
      <\/li>`;
    

    In this case you are sure that the whole content is handled by hyperHTML and it's done right away, without needing each time to traverse the chat and update the text of each node.

    This, as summary, is the ideal scenario because ownership of the content is still hyperHTML, and plugin features are seamlessly integrated

    Another way to integrate plugins as content generator via bind or wire could be the following one:

    hyperHTML(document.body)`
      <div>${
        $.magicContent(happen)
      }</div>`;
    

    I hope this answer was somehow useful.

    Best Regards