Where do I even begin with this one… between the awesome pull requests and the massive refactor, this is by far one of the most exciting updates. Whats more? This is thanks almost entirely to the community who provided some insanely good PR’s that made my head explode. Across the board, there are massive changes and improvements as well as entirely new features that really step up the game of this library.
Flow UX Support
This was one of the first big changes that came in, and it essentially provides a ton of hooks, new UX and usability improvements that bolster this libraries ability to model processes. Typically when creating processes using diagrams, the most important aspect is model integrity. This means removing dangling links, ensuring that the integrity of the model is valid and also making it super easy to create such flows with confidence. In the new update, you have full programatic control over links and whether or not they can be connected to other specific ports. You can control the types of link models that get created on drag, can ensure that there are no loose links, disallow them completely and make use of new UX that allows easy flow mutations. Existing connections can be dragged to other nodes, which will place the new connected node into the existing flow along with other awesome improvements. For a full rundown checkout the PR.
Epic shoutout to: Andrew Young
Automatic Path Routing
This was an epic addition the library, and in a nutshell the existing links can now automatically route their path to other nodes while avoiding existing nodes on the canvas. This ability works by calculating a bounding box around the node and using really complex matrix math to perform shortest path calculations in a fast and highly optimised manner. This now allows react diagrams to be used for purposes better suited to UML and entity relationship graphs that are not process/flow based. For more info checkout the PR.
Epic shoutout to: Klaus Paiva
This has been on my roadmap for a very long time, and it entailed making the defaults links more generic so that they can be easily extended without having to rewrite the path logic each time. Up until this point, while you could completely swap out the links with your own links, or style them using CSS, it was not possible to easily expand on the existing path logic in pretty common ways. Things we wanted to be able to do, is animate links, give links gradients, give links custom arrows and even handle things like custom visuals for intersections of the paths. Now with the new version, you can extend the DefaultLinkFactory and hook into the custom segment logic to provide your own DOM for the path without having to copy the default link code, or rewrite it from scratch. To see this new feature in action, checkout the updated demo!
There was also an awesome PR (also by Klaus Paiva) that added initial support for labels on links, and while it worked perfectly, I figured we could extend it further to use the same Model/View/Factory architecture that powers the rest of the system. After merging it in and a bit of refactoring, you can now add multiple labels on any link and provide custom widgets to represent them. The labels are now also model based and thus form part of the link models. Go checkout the demo!
End 2 End testing framework!
While version 4 added snapshot testing and laid out the ground work for end to end unit tests, we were not properly making using of the e2e tests to make guarantees on the system functionality. This was mostly due to the difficulty and code required to physically test every demo. I spent a lot of time (RIP Weekends) setting up proper end to end tests for the very basic functionality, and did so by writing a good testing layer that simplifies the puppeteer testing procedure. Using simplified models, you can instruct the headless browser to connect links via mouse drag, assert the existence of the various widgets, and achieve other hard to interactions such as selecting links and dragging nodes etc..
My hope is that this layer will lower the barrier into end to end testing with the rest of the community so that new features can require end to end tests as well, without having to feel like an impossible feat, or requiring complex code and a plethora of time.
Advanced, pluggable BEM support
Something that has been lacking for a while now, is a better sass structure. Thats why starting in version 5, we now make use of a BaseWidget which provides a fantastic was of using BEM throughout the source code in a very predictable, scalable and super pluggable way. All the sass styles were refactored into different files, all widgets were given proper base class names with consistent structure, and all the styles were flattened. Furthermore, the BaseWidget allows you to attach class names onto any widget, you can add additional properties onto the base DOM node of any widget using the ‘extras’ field. Finally, you can completely swap out the “Block” class name entirely by providing a baseClass property. This is super powerful and allows you to retain the BEM Structure of the class but you can provide your own BEM declaration in SASS/LESS to override the default styles. Take a look at this file for example!
I fired up my refactor tractor
Apart from the new features, and standard bug fixes etc.. the library went through an additional major refactor to further abstract various sub systems and pave the way for more complex features in the future. You will notice significantly more classes, more files and more generics used across the entire project right down to the tests. A lot of logic was made more deterministic, and there were a great deal of areas where I tried to install more immutability and functional programming concepts.
Working on this library has given me a lot to think about when it comes to architecture and software engineering design principles, and it has been a great outlet to try out new ideas. I am also constantly astonished at how many PR’s are created that are of a very high quality, but that more importantly embrace the design of this library. I constantly ask myself if the approach I took with this library was the right one, and while it will never be perfect, I have only this awesome community to thank for instilling confidence in my decisions through good debate and really good conversation on the Gitter channel.
I would like to once again thank all the contributors for their amazing work, and for such high quality additions to the source code. Thanks for trusting me with your work and thanks for allowing me to shift into a more integration role rather than feature implementer. I have learnt a plethora of things about open source thanks to this community and I cant wait to see what you all come up with next.
And with that, I would like to officially welcome version 5.0.0 (Codename AllMight 😉 )