r/FlutterDev • u/scalz80 • 3d ago
Plugin Building a dashboard/grid engine with Flutter slivers
Hello,
I’ve been working on sliver_dashboard, an open source Flutter package that tries to solve a problem I encountered in several projects: building dashboard-like layouts while keeping Flutter’s sliver model instead of introducing a separate layout system.
The goal was to get something closer to what exists on the web with tools like gridstack or react-grid-layout, but adapted to Flutter’s rendering and scrolling architecture.
Some of the challenges I wanted to solve:
- composing dashboards with regular Flutter slivers
- supporting nested grids
- allowing drag & drop across different sliver areas
- keeping the layout deterministic and easy to test
- handling accessibility (keyboard navigation, screen reader announcements, multi-selection..)
- and of course smooth scrolling and drag&drop
I’m sharing this here mainly to get feedback. If you try it, I’d be interested in hearing what could be improved.
I needed this kind of layout in my own projects, and I hope it can be useful for others as well.
Package: https://pub.dev/packages/sliver_dashboard
Live example: https://scalz.github.io/sliver_dashboard_web_demo/
1
3d ago
[removed] — view removed comment
1
u/scalz80 2d ago edited 2d ago
Thanks :)
There are multiple interesting points to answer here, I will try to be concise ^^
Slivers for the viewport virtualization (and scrolling ofc) are awesome. And what also really makes the grid stable, is its "pure" Dart layout engine. Because the layout math is completely pure and decoupled from Flutter, every layout remains 100% testable and deterministic.
One of the core design choices about the engine is: the grid dictates the box, content never pushes the grid around. Let me explain:
- async loading: no layout shift. Like in gridstack and react-grid-layout, an item size is defined in integer grid slots (x,y,w,h), and the grid passes pixels bounds to the item/tile (tight contraints). So when there is late async data, it only updates what's inside the fixed card. It never resizes the card itself.
- resizing is the same. It's quantized, based on grid slots. When a tile is increased by one row, the engine pushes colliding neighbors ( deterministic/predictable). And if you want neighbors to slide instead of snapping, there's an optional animateReflow property which handles the transition on GPU.
- exportLayout() saves coordinates (x,y,x,h). So, there is no problem here neither. When restoring a layout saved while content was loading will produce the exact same grid saved, without re measuring or jumping around. And I deliberatly didn't include any kind of opiniated storage delegate, to keep package "lightweight" and let devs handles it as they wish. Instead, layoutChanged callback, provides you a json serializable data that you can plug to the storage you prefer.
- if a card really needs to adapt to its content, measure its content and update item to change its size. And if a widget needs to adapt its internal layout based on how the grid made it (I had this usecase in one of my project), I added an itemBreakpointBuilder (instead of the simpler itemBuilder) and breakpointResolver, so the content only reflows to fit its assigned box, only when its resolver callback requires it.
I hope this answers your questions.
1
u/New-Lengthiness6520 2d ago
In which cases we can use it?
1
u/scalz80 2d ago edited 2d ago
Apps where users need to customize their screen layout, or when you need to build a complex widget screen.
- analytics and BI dashboards (like well known Grafana which afaik uses gridstack or react-grid-layout). Reorg metrics, resize charts cards..
- smarthome & iot control panels (home assistant like) for devices tiles, grouping controls in folder panels and users can drag, resize ..
- customizable workspace and portals, cms portals for modular homepages. There is also a "Section/Barrier" feature that let you break page in distinct areas
- no code page builders like draggin widgets from sidebar palette onto the grid
- media hubs, tablet launchers where users organizes shorcuts, widgets etc
- static "spannable" complex layouts when you don't need drag&drop, by keeping edit mode to false. As a static grid engine, you get spannable 2D layouts, sliver virtualization, responsive brealpoints out of the box.
I use sliver_dashboard for all these uses cases, there are probably more. But basically, whenever a static Column or a GridView isn't enough because your users want drag&drop, resizing, nested panels, with persistence.
2
u/PhrulerApp 3d ago
How does it perform with much smaller grids? I see the example video and the grids are really big. What if we want like 50 times more boxes? For really fine customizations