Pure and simple virtual DOM library

Overview

NpmLicense npmBundleSize build

Maquette

Maquette is a Javascript utility which makes it easy to synchronize the DOM tree in the browser with your data. It uses a technique called 'Virtual DOM'. Compared to other virtual DOM implementations, maquette has the following advantages:

  • It is very lightweight (3.6Kb gzipped)
  • It allows changes to be animated
  • It makes your frontend easy to unit-test

Visit the website for more information.

Comments
  • Diff algorithm turns reorderings into removals and additions

    Diff algorithm turns reorderings into removals and additions

    How am I supposed to do sensible animations when moving children actually doesn't move the DOM nodes around but instead triggers a series of creations and removals?

    opened by paldepind 32
  • createDom produces intermediate DOM states

    createDom produces intermediate DOM states

    I am trying to combine Maquette and A-Frame to render a WebVR scene and am running into an issue with intermediate DOM states.

    When Maquette creates a new DOM node it attaches the new DOM node to the parent node before adding attributes and properties: https://github.com/AFASSoftware/maquette/blob/master/src/maquette.ts#L789-L795. This causes an issue with A-Frame which uses Custom Elements that watch for and react to changes in the DOM. When Maquette attaches the new DOM node to the parent, it is incomplete and thus creates an intermediate and invalid DOM.

    These intermediate DOM states are problematic because they're not rendering what the developer expects and they prematurely trigger observers and proxies.

    As a comparison, A-Frame resolves these issues w/ React by explicitly updating attributes in componentDidUpdate(): https://github.com/aframevr/aframe-react/blob/master/src/index.js#L91. But I don't think Maquette offers a similar mechanism to update the DOM before it's attached.

    I think the most straight-forward solution would be to call initPropertiesAndChildren() on domNode right before it's added to the DOM.

    opened by devpaul 14
  • Use eventHandlerInterceptor provided in projectionOptions if defined

    Use eventHandlerInterceptor provided in projectionOptions if defined

    Includes a change to maquette.ts and two unit tests that fail without the change. The change makes it possible for an application to supply an eventHandlerInterceptor or set it to null if event handling interception is not desired.

    See this comment for more details on the motivation for this change: https://github.com/AFASSoftware/maquette/issues/35#issuecomment-195805477

    While I think this pull request is a substantial improvement in configurability to experiment with different ways to dispatch events (like supporting a "bind" property), I'm still not 100% satisfied with the change in relation to the meaning of setting eventHandlerInterceptor to "null".

    It might be argued that a null eventHandlerInterceptor should mean event handlers are still set in the DOM using the user-supplied functions but they just are not wrapped by an interceptor -- rather than the current behavior for null that event handlers are not set at all. But I expect that is not a big use case and I did not want to modify more of the code code which might have more of a performance impact.

    Here is where such a bigger change would need to be made though if it was desired in the future: https://github.com/AFASSoftware/maquette/blob/8849e235445cb7b24cfa40a91974cddcb5c8e68a/src/maquette.ts#L444

    The possibility of larger change, however, probably should not stand in the way of a smaller improvement in the current pull request.

    opened by pdfernhout 14
  • Using TypeScript instance methods as event handlers?

    Using TypeScript instance methods as event handlers?

    What is the best way to use methods of TypeScript class instances as Maquette event handlers?

    === More details

    Maquette requires event handlers to always be the same exact function for performance reasons, prohibiting code in a render method in a TypeScript object like:

    h("input", { value: this.myData, onchange: this.setMyData.bind(this) ] }) // won't work

    Trying to do that will produce this warning:

    Error: Functions may not be updated on subsequent renders (property: onclick). Hint: declare event handler functions outside the render() function.

    The Maquette todoComponent example shows a certain style of defining objects where the object itself has methods are specialized for the specific object and its fields as a closure held onto by the object.

    That approach works, but it requires every component to have a closure for each of the callback functions, which clashes with a more object-oriented style of programming using classes with methods. It is also potentially inefficient, because if you had a thousand editable items to display, they each would need a closure for each of their event handling methods (rather than sharing methods on a common prototype).

    If the Maquette ToDo example was rewritten using TypeScript classes, a challenge would become obvious. How do you easily connect methods of a typical TypeScript object to event handlers when "this" in an event handler is defined by default as the DOM node receiving the event?

    That is a very common case which in Mithril is typically handled just by using bind as in the first non-working example (admittedly, at a performance penalty).

    Working within the current restriction on event handlers, it could make application development easier if Maquette supported specifying what "this" should be in an event handler, as "this" is otherwise apparently the DOM node getting the event. I don't know the best way to do that, but here are some possibilities.

    One way is perhaps passing an array (or other object) as an event handler that could be used internally in Maquette with apply for event handlers, like so:

    h("input", { value: this.myData, onchange: [ this, this.setMyData, "Extra1", "Extra2" ] })

    But that would be creating a new array on every render.

    Another approach could be to pass a value in for "this" as a field for the properties which Maquette could use in apply like so:

    h("input", { value: this.myData, onchange: this.setMyData, _this: this })

    That way might be the most efficient. It is a bit limiting, but in practice I doubt that limit would be a big issue. A generalization of that approach could be to pass in an array of arguments to be applied to any event handler. Because event handling is unlikely to be performance critical, doing a check to see if there was data to apply on a function would probably not slow things down -- although it would add a small bit of library code complexity at a huge savings for application code complexity.

    There are other approaches I can think of, like functions that lazily cache bound references to methods in the object somehow in a _cachedMethods field, or perhaps managing a global WeakMap of bound functions associated with instances and their methods. Those have their own drawbacks. And they have overhead at rendering to do lookups. Still, it is common to refer to "event.target.value" in handlers (or similar for "checked" and other attributes), and it could be useful to have a wrapper function for that such as Mithril's "withAttr" function. So, I could imagine creating a global event handler tracker that also resolved events to their values which might be worth using especially for that side benefit.

    Perhaps there is some other clever way to handle setting up Maquette event handlers with TypeScript class instances?

    Converting the TODO example to idiomatic TypeScript using a class for todoComponent would be a way for Maquette designers to wrestle with this design issue.

    opened by pdfernhout 14
  • Ability to manage Events and Schedule Rendering

    Ability to manage Events and Schedule Rendering

    Context: We have been prototype using Maquette with dgrid considering using it for the next major version. We have found a few things that we see as challenges for us in adopting it. @kfranqueiro, @maier49, and @edhager have been working on the prototyping.

    Problem Description

    In certain cases, the application is aware that certain DOM Events of which it has listeners for do not equate to any mutations of the DOM, but currently Maquette will always schedule a render on any listener provided via the VDOM.

    Also, we are unsure if the intent of Maquette to potentially manage these events. While the code documents the projector option of eventHandlerInterceptor the actual code will always overwrites this option with one that always schedules a render. (We suspect this is a defect)

    @pdfernhout brought this up in #31, but we have had some further experience with this.

    Impact

    We noticed in our prototypes a significant amount of "jank" when the list was scrolled. Part of that "jank" we us actually some coding issues in our implementation and we were able to get the performance to improve to a great degree, but we highly suspect that in certain situations under certain environments, a schedule render for every scroll event would make the performance unacceptable.

    Discussion

    We suspect the eventHandlerInterceptor is potentially a defect.

    On the wider topic though which was discussed in #31. The application "knows" that only an aggregate scroll movement of X actual would cause the DOM to need to be updated and that often takes 10x the DOM events to equal something the application actually cares about, so for 9 of those events, we have recalculated the whole of the VDOM which results in a noop for actual DOM mutations. The feeling I get from the discussion in #31 was "let's discuss real problems, versus potential ones" which, to me, makes a lot of sense. I think we have come up with a use case though that can cause real problems. Implementing a custom eventHandlerInterceptor could resolve this issue (or as suggested in the other ticket, a custom Projector). In both those cases though, it would mean we would have to become the "experts" at VDOM versus and something we are reticent to do.

    We hope given a compelling use case, we can find a way to improve Maquette to be able to manage DOM events bubbled up to the application more efficiently.

    opened by kitsonk 11
  • Optionally allow function updates

    Optionally allow function updates

    Before all, I'm not aware of all performance issues, so take the associated PR as an example of what can be done, not the way to do it. Also, it needs an option in the maquette.createProjection factory to be effective.

    So I've made it possible to change the event handlers. It seems that this modification does not have a lot of consequences on performances, it adds a property on the DOM Node to store the original handler, so eventHandlerInterceptor is called only once.

    In case of the PR associated with this issue is accepted, I'll sign the CLA.

    opened by cybrown 9
  • Maquette Tutorial error

    Maquette Tutorial error

    The Maquette tutorial in your website is not working. There are errors in the gutter of HTML frame, in http://maquettejs.org/tutorial/01-intro.html:

     Expected an identifier and instead saw '<'.
     ...
    

    This is a fragment of error in Chrome console:

      MutationObserver fired          workbench.js:120
      http://maquettejs.org/tutorial/bower_components/ace-builds/src-noconflict/mode-html.js  Failed to load resource: the server responded with a status of 404 (Not Found)
    

    thanks.

    opened by aMarCruz 9
  • First-class support for progressive enhancement?

    First-class support for progressive enhancement?

    I have been using virtual-dom for several months, before discovering maquette. As mentioned in your blog post, this module appears to use similar hypersrcipt implementation, while giving first-class support for PE?

    But looking at the introduction: http://maquettejs.org/2015/02/28/Progressive-enhancement.html

    and source code at: http://maquettejs.org/tutorial/01-intro.html

    I still haven't fully understand what happens when you do a mergeDom.

    To put it in simpler context, let's say, we have this render template:

    h('body', [
      h('h1', 'welcome')
    ]);
    

    which server-rendered and output as:

    <body>
      <h1>welcome</h1>
    <body>
    

    What does it take to swap it with a maquette-rendered dom using the same template? What happen when you trying to replace them, do nothing happen, or do everything get replaced like replaceChild.


    As a side-note: just how similar are maquette and virtual-dom in terms of their hypersrcipt implementation?

    https://github.com/Matt-Esch/virtual-dom/tree/master/virtual-hyperscript

    I am wondering if I had to rewrite https://github.com/nthtran/vdom-to-html to support maquette.

    opened by bitinn 7
  • Feature request: support undefined values for the class attribute

    Feature request: support undefined values for the class attribute

    Hello,

    I'm using webpack and CSS modules in my maquette.js application and I am a little bit annoyed because maquette.js does not accept undefined values for the class attribute.

    For example, I often do that in my code:

    var styles = require('./component.css');
    
    function renderMaquette() {
      return h('div', { class: styles.root }, 'blah blah');
    }
    

    When we use CSS modules but we don't have the corresponding .root rule in the CSS, styles.root returns undefined which causes maquette.js to throw an error because the class value is not a string.

    I often do this mistake when refactoring my components and their CSS files and it's quite hard to find where the mistake is once you've done it. So, can I suggest supporting undefined values for the class attribute as a synonym for the empty string?

    Side note: I would also like to pass an array of classes to the class or classes attributes but it's not supported either. In those cases, I use the classnames library to format the class attribute, and I think it would probably be a good idea to delegate the class handling to this library in maquette.js.

    opened by sprat 6
  • Updating properties.classes not being reflected in the DOM

    Updating properties.classes not being reflected in the DOM

    Given the following:

    import { createProjector, h, VNode } from 'maquette/maquette';
    
    const node = h('dojo-panel-tabbed', {
        id: 'tabbed-panel'
    }, [
        h('ul', {}, [
            h('li', { classes: { active: false }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ]),
            h('li', { classes: { active: true }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ]),
            h('li', { classes: { active: false }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ]),
            h('li', { classes: { active: false }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ])
        ])
    ]);
    
    function render(): VNode {
        return node;
    }
    
    const projector = createProjector({});
    
    projector.append(document.body, render);
    
    const next = document.getElementById('next');
    
    next.addEventListener('click', (event) => {
        console.log('before', node.children[0].children[1].properties.classes, node.children[0].children[2].properties.classes);
        node.children[0].children[1].properties.classes['active'] = false;
        node.children[0].children[2].properties.classes['active'] = true;
        console.log('after', node.children[0].children[1].properties.classes, node.children[0].children[2].properties.classes);
        projector.scheduleRender();
    });
    

    Maquette does not appear to notice changes to changes to already rendered VNodes. The classes do not change if a VNode is updated. I maybe missing something, but is it not possible to reuse VNodes?

    To explain a bit, where I ran into an issue trying to create a tabbed component, where the VNodes for the tab bar were always regenerated, but the tab's contents would only be calculated for the tab coming into view, but then updating the classes of any tab contents already rendered. That way, if the tab were to come back into view, but its content had not changed, it would be as simple as adding a class back.

    I have noticed though if I dropped a VNode out of one render and then return it later, the VNode will be full parsed.

    I even tried to "reuse" just VNodeProperties, but that also appeared to exhibit the same behaviour, that if it was present from one render to the next, changes to its properties were not deeply noticed.

    I can get it to work, only if I do something like this:

    import { createProjector, h, VNode } from 'maquette/maquette';
    
    let clicked = false;
    
    function render(): VNode {
        return h('dojo-panel-tabbed', {
            id: 'tabbed-panel'
        }, [
            h('ul', {}, [
                h('li', { classes: { active: false }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ]),
                h('li', { classes: { active: !clicked }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ]),
                h('li', { classes: { active: clicked }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ]),
                h('li', { classes: { active: false }, key: {} }, [ h('div.tab-label', [ 'tab 1' ]), h('div.tab-close', [ 'X' ]) ])
            ])
        ]);
    }
    
    const projector = createProjector({});
    
    projector.append(document.body, render);
    
    const next = document.getElementById('next');
    
    next.addEventListener('click', (event) => {
        clicked = true;
        projector.scheduleRender();
    });
    

    In my opinion, this is rather surprising behaviour and means that it is difficult to not fully recalculate the whole of the virtual DOM on every render, which doesn't properly represent the application state, as from render to render, only small changes are made to the VDOM.

    opened by kitsonk 6
  • Support for CSS variables in `styles` property

    Support for CSS variables in `styles` property

    Expected behavior

    When providing a CSS variable through the styles property. It is added to the style attribute of the tag.

    h('div', {
      styles: {
        '--background-color': 'blue',
      }
    }, [])
    

    Should result in:

    <div style="--background-color:blue;"></div>
    

    Current behavior

    CSS variables get ignored and are not rendered.

    Demo

    https://stackblitz.com/edit/maquette-starter-j1rjrw?file=main.ts

    opened by Dyljyn 5
  • Bump json5 from 2.2.1 to 2.2.3

    Bump json5 from 2.2.1 to 2.2.3

    Bumps json5 from 2.2.1 to 2.2.3.

    Release notes

    Sourced from json5's releases.

    v2.2.3

    v2.2.2

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).
    Changelog

    Sourced from json5's changelog.

    v2.2.3 [code, diff]

    v2.2.2 [code, diff]

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).
    Commits
    • c3a7524 2.2.3
    • 94fd06d docs: update CHANGELOG for v2.2.3
    • 3b8cebf docs(security): use GitHub security advisories
    • f0fd9e1 docs: publish a security policy
    • 6a91a05 docs(template): bug -> bug report
    • 14f8cb1 2.2.2
    • 10cc7ca docs: update CHANGELOG for v2.2.2
    • 7774c10 fix: add proto to objects and arrays
    • edde30a Readme: slight tweak to intro
    • 97286f8 Improve example in readme
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump glob-parent from 5.1.1 to 5.1.2

    Bump glob-parent from 5.1.1 to 5.1.2

    Bumps glob-parent from 5.1.1 to 5.1.2.

    Release notes

    Sourced from glob-parent's releases.

    v5.1.2

    Bug Fixes

    Changelog

    Sourced from glob-parent's changelog.

    5.1.2 (2021-03-06)

    Bug Fixes

    6.0.0 (2021-05-03)

    ⚠ BREAKING CHANGES

    • Correct mishandled escaped path separators (#34)
    • upgrade scaffold, dropping node <10 support

    Bug Fixes

    • Correct mishandled escaped path separators (#34) (32f6d52), closes #32

    Miscellaneous Chores

    • upgrade scaffold, dropping node <10 support (e83d0c5)
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Discussion: consider moving from event handler properties to events

    Discussion: consider moving from event handler properties to events

    Maquette's eventing has been working great for us, but we've come across two use cases that have issues with the existing implementation:

    1. custom elements – from what I've seen, there are some web component libraries that don't promote event handler properties for custom events (e.g., hybrids, lit-element, Stencil), so it won't be guaranteed that a custom element will have these properties that maquette's eventing system heavily relies on.
    2. onfocusin/onfocusout – Some browsers (Chrome, Firefox, Edge) no longer seem to have event handler properties for these events (test case). For these particular events, we can't use blur/focus as they don't bubble. Note that these are the ones that have come up in our development, but there could be others.

    Changing maquette's event interceptor to use events instead of event handler properties should help with these cases.

    I look forward to your thoughts on this and if you think it's something worth doing, I'd be more than happy to help out in any way that I can.

    opened by jcfranco 11
  • Extend Projector.append so it can handle Classes as well

    Extend Projector.append so it can handle Classes as well

    Right now, when I want to append a Class based Maquette component, I have to do this: let dateInput = new DateInput(); projector.initialize(dateInput.renderMaquette.bind(dateInput));

    It would be nice if projector.initialize would be able to do the binding for me, so I would only have to pass in a Class: projector.initialize(new DateInput()). This would also require a change in MaquetteQuery on the initialize method.

    enhancement 
    opened by peterwestendorp 0
  • handleEvent for the win :)

    handleEvent for the win :)

    Hey dear friends!

    Do you know about this? https://www.thecssninja.com/javascript/handleevent

    I think it would be a nice addition if your eventhandling would accept objects like in vanilla js!

    var app = {
      state: { title: 'Example' },
      handleEvent: function(evt) { ....
      render: function() {
         return h('button', { onclick: this })
      }
      ...
    }
    ....
    

    No bind is required when you use vanilla htmlButton.addEventListener('click', app)!

    Thanks for your feedback in advance!

    enhancement help wanted 
    opened by katywings 5
  • Improving the render cycle API

    Improving the render cycle API

    You can write your whole application without doing anything with the render cycle. This is part of our philosophy of keeping things pure and simple. But you do need the render cycle if:

    • You integrate components/widgets that are not written using maquette.
    • Do advanced animations.
    • Interact with the DOM API.
    • Measure nodes.

    Every time a new screen is rendered, the following phases take place:

    • Render render() functions are called
    • Diff and patch The real DOM is updated
    • Measure The phase for callbacks that need to take measurement of the layouted DOM (getBoundingClientRect)
    • WrapUp Phase in which the DOM may be modified again

    It is important to have a separate measure and wrapUp phase, because if multiple components were to measure and change the DOM in the same phase, unneeded reflows take place which would hurt performance.

    Every time a render takes place, a new RenderRun object is created. All callbacks that are called during a render get a reference to the RenderRun object as a parameter. The RenderRun has the following interface:

    Interface RenderRun {
      duringMeasure(callback: () => void): void;
      duringWrapUp(callback: () => void): void;
    }
    

    The RenderRun can then be used as follows:

    h('div', { enterAnimation: growToAutoHeight })
    
    let growToAutoHeight = (element: Element, run: RenderRun) => {
      let autoHeight = 0;
      run.duringMeasure(() => {
        autoHeight = element.getBoundingClientRect().height;
      });
      run.duringWrapUp(() => {
        element.style.height = '0px';
        let grow = element.animate([{height: '0px', height: autoHeight+'px'}]);
        grow.onfinish(() => {element.style.height = ''})
      })
    }
    

    The following phases execute when a render takes place:

    1. render() functions are executed.
    2. Diffing and patching of the real DOM. For each DOM node that is processed, the following happens:
      1. afterFirstRender callback is called if the DOM node is new
      2. afterRender callback is called
      3. enterAnimation is called if the DOM node is new and its parent already existed
      4. updateAnimation is called if DOM node is updated
      5. The DOM node is attached to the parent DOM node if DOM node is new
      6. exitAnimation (from previous render) is called if DOM node is removed and its parent remains
    3. Callbacks on RenderRun.duringMeasure are executed duringMeasure callbacks may be used to measure the DOM (getBoundingClientRect), but may not change the DOM.
    4. Callbacks on RenderRun.duringWrapUp are executed duringWrapUp callbacks may change the DOM, but should not measure the DOM.

    When all code uses the RenderRun object appropriately, all updates to the UI should never cause more than 2 reflows.

    Migration path from afterCreate and afterUpdate:

    AfterCreate can be replaced with afterFirstRender. Note that during afterFirstRender, the DOM Node is not attached to its parent. If the afterCreate code needed this, afterFirstRender can register code to run during measure or wrapUp.

    AfterUpdate can be replaced with afterRender. Note that afterRender also runs when the DOM node is first created and at that time it will not have a parent Node.

    This is one of our ideas for maquette 3

    opened by johan-gorter 4
Releases(v3.4.1)
Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom.

Atomico simplifies learning, workflow and maintenance when creating webcomponents. Scalable and reusable interfaces: with Atomico the code is simpler

Atomico 898 Dec 31, 2022
minimalist virtual dom library

petit-dom A minimalist virtual DOM library. Supports HTML & SVG elements. Supports Render functions and Fragments. Custom components allows to build y

Yassine Elouafi 485 Dec 12, 2022
An app to manage tasks. A user can add, delete and edit a task and mark it as completed, It uses simple GUI and relies on DOM manipulation in pure JS and using local storage.

An app to manage tasks. A user can add, delete and edit a task and mark it as completed, It uses simple GUI and relies on DOM manipulation in pure JS and using local storage.

KHITER Mohamed Achraf 6 Aug 20, 2022
Million is a lightweight (<1kb) Virtual DOM. It's really fast and makes it easy to create user interfaces.

?? Watch Video ?? Read the docs ?? Join our Discord What is Million? Million is a lightweight (<1kb) Virtual DOM. It's really fast and makes it easy t

Derek Jones 5 Aug 24, 2022
A Fast & Light Virtual DOM Alternative

hyper(HTML) ?? Community Announcement Please ask questions in the dedicated discussions repository, to help the community around this project grow ♥ A

Andrea Giammarchi 3k Dec 30, 2022
Component oriented framework with Virtual dom (fast, stable, with tooling)

Bobril Main site bobril.com Changelog of npm version: https://github.com/Bobris/Bobril/blob/master/CHANGELOG.md Component oriented framework inspired

Boris Letocha 359 Dec 4, 2022
An extension of DOM-testing-library to provide hooks into the shadow dom

Why? Currently, DOM-testing-library does not support checking shadow roots for elements. This can be troublesome when you're looking for something wit

Konnor Rogers 28 Dec 13, 2022
Custom Vitest matchers to test the state of the DOM, forked from jest-dom.

vitest-dom Custom Vitest matchers to test the state of the DOM This library is a fork of @testing-library/jest-dom. It shares that library's implement

Chance Strickland 14 Dec 16, 2022
Adds `swiped` events to the DOM in 0.7k of pure JavaScript

swiped-events A 0.7k script that adds swiped-left, swiped-right, swiped-up and swiped-down events to the DOM using CustomEvent and pure JS. Based on t

John Doherty 493 Jan 8, 2023
Adds `long-press` event to the DOM in 1k of pure JavaScript

long-press-event A 1k script that adds a long-press event to the DOM using CustomEvent and pure JavaScript. Works in IE9+, Chrome, Firefox, Safari as

John Doherty 262 Jan 2, 2023
A pure javascript class for paginating through any number of DOM elements

PurePajinate A pure javascript class for paginating through any number of DOM elements. Inspired by Pajinate, a plugin for jQuery. Options Option Type

Olivier Buisard 3 Nov 21, 2022
A regular table library, for async and virtual data models.

A Javascript library for the browser, regular-table exports a custom element named <regular-table>, which renders a regular HTML <table> to a sticky p

J.P. Morgan Chase & Co. 285 Dec 16, 2022
Shizuku Launcher is a simple AWS Virtual Machine helper.

shizuku-launcher-web Shizuku Launcher is a simple AWS Virtual Machine helper. Shizuku Launcher offers multiple solutions to keep your credential secur

Seraphim Lou 16 Oct 11, 2022
JS Cloudimage 360 View - A simple, interactive resource that can be used to provide a virtual tour of your product

JS Cloudimage 360 View - A simple, interactive resource that can be used to provide a virtual tour of your product

Scaleflex 1.9k Jan 7, 2023
Shizuku Launcher is a simple AWS Virtual Machine helper. Now in Next.js

Shizuku Launcher Shizuku Launcher is a simple AWS Virtual Machine helper. Shizuku Launcher offers multiple solutions to keep your credential security

Seraphim Lou 50 Jan 3, 2023
A simple library that I use for web scraping. Uses htmlparser2 to parse dom.

Docpa A simple library that I use for web scraping. Uses htmlparser2 to parse dom. Usage const Docpa = require("docpa") const doc = new Docpa(`<html>

Roshan Acharya 2 Jan 21, 2022
A small javascript DOM manipulation library based on Jquery's syntax. Acts as a small utility library with the most common functions.

Quantdom JS Quantdom is a very small (about 600 bytes when ran through terser & gzipped) dom danipulation library that uuses a Jquery like syntax and

Sean McQuaid 7 Aug 16, 2022
🍦 ✨ Simple multi-select pure vanilla Javascript library.

multiSelect.js ✨ Simple multi-select pure vanilla Javascript library. ?? Live Demo v1.0.8 multiSelect.js is a simple, pure vanilla Javascript library

Jacob Kleiman 5 Mar 15, 2022
A Virtual Interactive Keyboard which replicates every key you press and a Text-Area in which everything is written and can be copied to the clipboard with a click of a button.

A Virtual Interactive Keyboard which replicates every key you press and a Text-Area in which everything is written and can be copied to the clipboard with a click of a button.

Devang Joshi 1 Mar 1, 2021