Having assumed maintenance of this project earlier this year, I always wondered how plugins were used in this library.
In fact, while adding/refactoring this library, I removed the plugin section from the README as I didn't want to officially support a feature that I didn't understand.
However, I know that some users still use this feature (specifically @ Ilaiwi). I would like to better understand how this feature is being used, while also moving towards refactoring/adding a more declarative way of achieving these use cases. It'd be great if ya'll could provide the following:
Well, for our use case plugins are among the most important feature of this library. For me, I think of the calendar part as layers
<Timeline>
<Headers/>
<Calendar>
<HorizontalLinesLayer/>
<VerticalLinesLayer/>
<ItemsLayer/>
</Calendar>
</Timeline>
Recently, you added markers to these layers and I think the whole feature could be implemented using plugins only which is EXTREMLLY POWERFUL in my opntion.
The app I use this library in has very customized use cases for this library. This includes, for example, display a layer of unavailable slots in the calendar. I could, of course, pass the unavailable slots as items on the timeline but this will need so much customization and add so much complication to the code. So in order to solve this and keep my code declarative, I created UnavailableLayer plugin to only handle the unavailable slots.
Example: https://codesandbox.io/s/wknzrlz557
A second use case for me and is a very critical one is drag and drop from outside the calendar. Using a DroppableLayer. I created a custom div and used it as a target for my droppables. This enabled me to do SO MUCH with this library in a very declarative way which I absolutely love.
For me to do all the previous, I had to dig deep into the library code and understand a lot on how the layers work. So I think a good documentation is very very important.
As for enhancements, in my opinion, need to include:
TimelineContext like getLeftOffsetFromDate and getDateFromLeftOffsetPositionThanks for your response @Ilaiwi .
I have a few problems with the plugin API:
groupHeights, groupTops) of the timeline that make refactoring risky and will likely result in breaking changes and major releases if any internal refactoring is doneplugin I believe is inaccurate and confusing as it's really just a render prop approach. (this is nitpicky, I know)Your mentioning of Layers is interesting but I don't want the timeline internally to treat these items as such. There is very complicated code related to row height and item positioning that I would like to eliminate to bring elements more "in flow" instead of using top and left everywhere. I know this is idealistic and might never happen but thinking in Layers in regards to Rows, Columns and Items is wrong IMO.
What I can understand is Layers in regards to positioning overlays on Timelines. @Ilaiwi for your use cases:
I think that exposing a way to customize Rows and Columns will go a long way towards eliminating the need for this "plugins" feature. Important to achieve this though is having the timeline expose helper methods to convert time to pixels and vice versa (as @Ilaiwi mentioned above). The latter will allow the user to make any calculations they need in regards to positioning while preventing the timeline from exposing internal implementation details.
Thoughts?
Very interesting thoughts.
I agree, a lot of the props that are exposed in the plugin expose internal details and utilizing plugins needed a huge effort from me to use. On the other hand, I think most of these internal implementations could be eliminated by utilizing helpers to use the internal state to calculate styles and positioning which will limit users use of the internal state.
As for declarativity, Yes plugins in perspective of this lib is not declarative but my usage of the system makes my component wrapper way more declarative which is a huge deal for me since I might have 5-6 plugins active at the same time soon.
As for your question about DroppableLayer I place droppable targets per row and passed on what row the item was dropped the I add the item to the items list.
For your suggested to achieve my use cases using row and column render props, I think both of DroppableLayer and UnavailableLayer can be achieved using row render prop. Although managing the added features will be a nightmare since I would have 5-6 layers soon. On the other hand, managing the code eventually is my problem and the lib shouldn't focus on that
I also, would like to know more about the approach you mentioned on using "in flow" instead of hight and left for items?
I really would like to hear from other users of the plugin system and how do they use the system to achieve their custom behaviors. I think the plugins give this library so much power and capabilities where I could implement theoretically any custom behavior my product manager could through at me. But if no one shares my viewpoint, I think this should be replaced by row and column renderers.
As for your question about
DroppableLayerI place droppable targets per row and passed on what row the item was dropped the I add the item to the items list.
Hello @Ilaiwi, is it possible to give an example on how to use your idea of DroppableLayer? Or has another solution been implemented in the meantime?
Thanks in advance :)
@jarnovanrhijn I use it currently to drag shifts from outside the timeline to the timeline. I use react-beautiful-dnd (which is an overkill for now). I created droppable areas using plugins the same way I did in https://codesandbox.io/s/wknzrlz557 and dragging draggable shifts from an outside area to those dropabbles.
BUT I NEED TO WARN YOU.
We are removing plugins and converting to the row renderer solution some time at the beginning of next year and this solution will break
@Ilaiwi, Thanks for the quick response. Will implement it for now as i need it asap but will be aware of breaking changes next year!! Keep up the good work :)
@jarnovanrhijn I would really appreciate it if you create a codesandbox with your code. This way you give also back to the community.
@Ilaiwi, I'm trying to create a codesandbox but need some help. I'm a bit stuck at trying to calculate the start time when dropping an item from outside the timeline area. If you could point me in the right direction that would be great. I've build upon your example and added react-dnd for dragging and dropping. code can be found here: https://codesandbox.io/s/o5w280jzn5
@jarnovanrhijn not sure if you still need that but there is a private function inside the library called getTimeFromRowClickEvent you can search for it to see what's it's doing exactly.
Most helpful comment
Well, for our use case plugins are among the most important feature of this library. For me, I think of the calendar part as layers
Recently, you added markers to these layers and I think the whole feature could be implemented using plugins only which is EXTREMLLY POWERFUL in my opntion.
The app I use this library in has very customized use cases for this library. This includes, for example, display a layer of unavailable slots in the calendar. I could, of course, pass the unavailable slots as items on the timeline but this will need so much customization and add so much complication to the code. So in order to solve this and keep my code declarative, I created
UnavailableLayerplugin to only handle the unavailable slots.Example: https://codesandbox.io/s/wknzrlz557
A second use case for me and is a very critical one is drag and drop from outside the calendar. Using a
DroppableLayer. I created a customdivand used it as a target for my droppables. This enabled me to do SO MUCH with this library in a very declarative way which I absolutely love.For me to do all the previous, I had to dig deep into the library code and understand a lot on how the layers work. So I think a good documentation is very very important.
As for enhancements, in my opinion, need to include:
TimelineContextlikegetLeftOffsetFromDateandgetDateFromLeftOffsetPosition