Repository navigation
feat: Support Drag-and-Drop Reordering in SidebarItems #590
Description
Is your feature request related to a problem? Please describe.
When building complex macOS applications using macos_ui, it's convenient to allow users to manually reorder items in the Sidebar (e.g., reordering a list of projects, favorites, or folders) via drag-and-drop. This is a core macOS HIG pattern seen in Finder, Mail, and Messages.
Currently, the SidebarItems widget strictly requires a List<SidebarItem>. Because of this strict typing, developers cannot wrap a SidebarItem in standard Flutter drag-and-drop widgets like DragTarget, LongPressDraggable, or use ReorderableListView.
The rigid typing is explicitly defined in sidebar_items.dart line 59:
final List<SidebarItem> items;
If a developer attempts to wrap a SidebarItem to add reordering logic, the Dart analyzer throws:
The argument type 'Widget' can't be assigned to the parameter type 'SidebarItem'.
Describe the solution you'd like
There are two potential ways to solve this natively within the library:
Option 1: Relax the Type Signature (The Flexible Approach)
Change final List<SidebarItem> items; to final List<Widget> items; within SidebarItems.
This would allow developers to seamlessly wrap SidebarItem instances in whatever interaction detectors or DragTargets they need without breaking the visual styling of the internal _SidebarItem renderer.
Option 2: Native Reorderable Support (The "Batteries Included" Approach)
Implement a built-in callback inside SidebarItems (e.g., onReorder: (int oldIndex, int newIndex)) that automatically handles the internal Draggable and DragTarget logic, rendering the native macOS blue horizontal insertion line during the drag state.
Describe alternatives you've considered
- Option 3: Developers can completely abandon
SidebarItemsand build a customReorderableListViewinside theSidebar, but this sacrifices the pixel-perfect HIG typography, spacing, and accent color states provided bymacos_ui. - Option 4: Adding a
Widget? wrapperbuilder parameter to theSidebarItemclass itself so developers can inject interaction logic without changing the root list type.
Update: Internal Implementation Discovery
While attempting to implement Option 2 within a local fork, we discovered that wrapping a _SidebarItem inside a ReorderableDragStartListener accidentally triggers the internal FocusableActionDetector inside _SidebarItem.build. This causes the macOS layout engine to interpret the dragging state as a permanent "hover/focus" state, resulting in a solid unselectedColor (or selectedColor) block being drawn across the entire width of the sidebar (masking the transparent MacosWindow background).
If Option 2 is implemented natively, the _SidebarItem will need to be refactored to ensure its FocusableActionDetector gracefully ignores or yields to the outer Drag state so it doesn't draw phantom bounding boxes during a drag.
Activity