Our product, Webviz, often finds itself short of real estate when users attempt to use an increasing number of panels. We also run into performance constraints when rendering so many panels, so we decided to implement tabbed panels to reduce both the visual and compute headaches!
Check out our release PR here to see the feature!
The tiling library we rely on, react-mosaic
, does not support tabs out of the box, but it does allow nested layouts! So we created a special kind of tile that would render nested layouts, and wrote a tab-like interface on top of it.
Managing the internal state of this layout worked like any other react-mosaic
layout. However, things got tricky when we needed to drag a panel from the Tab panel layout over to the main layout (or vice versa). Since react-mosaic
relies on mosaicId
in its drag handlers to render drop target spaces, these 2 layouts had completely different ids, making any dragging panels between them incompatible.
Furthermore, the information passed to drag handlers is limited - i.e. the handler only receives 2 pieces of information, path
and position
. path
refers to the mosaic layout path to which we would like create the new tile, and position
refers to where we would like to render that tile ("top", "bottom", "left", "right"). This info is sufficient for a single layout, but when you don't know which layout you happen to be dragging into or from, you need more information.
The first tweak we made to our fork of react-mosaic
was creating a mosaicId
prop to pass down to a root MosaicDumbWindow
component. This newly created MosaicDumbWindow
was not wrapped in any kind of drop target logic. That handled the issue of react-mosaic
not properly rendering drop target spaces.
To solve the problem of allowing drag handlers to know which layouts we were dragging from and into, we created a new prop, tabId
, to pass into the drag handlers. From this prop, the drag handlers could infer whether the drag source was coming from a Tab panel layout, and/or being dragged into a Tab panel layout. For the full nitty-gritty details about this drag and drop logic, check out the links below.
Thanks for the writeup! FYI, I found some workarounds for these issues that allows us to stop using the forked repo: https://github.com/foxglove/studio/pull/410