feat: add collapsible/expandable zones for canvas decluttering
- Add collapsed state to NodeData.custom_colors (type=groupRect only) - Implement toggleNodeCollapsed action in canvasStore (Zustand) - Extend GroupRectNode UI with smooth chevron toggle button - Rotating chevron icon (↓ → when collapsed) - Shows '+N' badge when zone is hidden - Reduces zone opacity to 0.6 when collapsed - All transitions target 60 FPS (ease-out 200ms) - Filter child nodes/edges in CanvasContainer based on parent collapse state - Breadth-first traversal handles multi-level nesting - Connecting edges to hidden nodes are automatically hidden - Add comprehensive test coverage - Store: toggleNodeCollapsed state mutation, unsaved flag - Component: chevron rendering, click handlers, opacity transitions - Persist collapsed state via YAML serialization (part of custom_colors) Benefits: - Declutter large Zigbee meshes, multi-building networks - Preserve layout structure without deleting nodes - Smooth 60 FPS transitions for UX polish CONTRIBUTING.md compliance: - Strict TypeScript types, no 'any' - Zustand store pattern, no prop drilling - Tests for store logic and component behavior - Frontend linting requirements met Co-authored-by: CyberClaw <noreply@openclaw.ai>
This commit is contained in:
@@ -52,6 +52,7 @@ interface CanvasState {
|
||||
setEditingGroupRectId: (id: string | null) => void
|
||||
editingTextId: string | null
|
||||
setEditingTextId: (id: string | null) => void
|
||||
toggleNodeCollapsed: (id: string) => void
|
||||
createGroup: (nodeIds: string[], name: string) => void
|
||||
ungroup: (groupId: string) => void
|
||||
markSaved: () => void
|
||||
@@ -374,6 +375,25 @@ export const useCanvasStore = create<CanvasState>((set) => ({
|
||||
|
||||
setEditingTextId: (id) => set({ editingTextId: id }),
|
||||
|
||||
toggleNodeCollapsed: (id) =>
|
||||
set((state) => ({
|
||||
nodes: state.nodes.map((n) =>
|
||||
n.id === id
|
||||
? {
|
||||
...n,
|
||||
data: {
|
||||
...n.data,
|
||||
custom_colors: {
|
||||
...n.data.custom_colors,
|
||||
collapsed: !n.data.custom_colors?.collapsed,
|
||||
},
|
||||
},
|
||||
}
|
||||
: n
|
||||
),
|
||||
hasUnsavedChanges: true,
|
||||
})),
|
||||
|
||||
createGroup: (nodeIds, name) =>
|
||||
set((state) => {
|
||||
const PADDING_H = 24
|
||||
|
||||
Reference in New Issue
Block a user