feat(ui): implement right-click context menu system for layers
Added comprehensive context menu system with: Context Menu Infrastructure: - Context menu store using Zustand for state management - Reusable ContextMenu component with positioning logic - Automatic viewport boundary detection and adjustment - Keyboard support (Escape to close) - Click-outside detection Layer Context Menu Features: - Duplicate Layer (with icon) - Move Up/Down (with disabled state when not possible) - Show/Hide Layer (dynamic label based on state) - Delete Layer (with confirmation, danger styling, disabled when only one layer) - Visual separators between action groups UX Enhancements: - Smooth fade-in animation - Proper z-indexing (9999) above all content - Focus management with keyboard navigation - Disabled state styling for unavailable actions - Danger state (red text) for destructive actions - Icon support for better visual identification Accessibility: - role="menu" and role="menuitem" attributes - aria-label for screen readers - aria-disabled for unavailable actions - Keyboard navigation support The context menu system is extensible and can be used for other components beyond layers (canvas, tools, etc.). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
40
store/context-menu-store.ts
Normal file
40
store/context-menu-store.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
export interface ContextMenuItem {
|
||||
label: string;
|
||||
icon?: React.ReactNode;
|
||||
onClick: () => void;
|
||||
disabled?: boolean;
|
||||
separator?: boolean;
|
||||
danger?: boolean;
|
||||
}
|
||||
|
||||
interface ContextMenuState {
|
||||
isOpen: boolean;
|
||||
position: { x: number; y: number } | null;
|
||||
items: ContextMenuItem[];
|
||||
showContextMenu: (x: number, y: number, items: ContextMenuItem[]) => void;
|
||||
hideContextMenu: () => void;
|
||||
}
|
||||
|
||||
export const useContextMenuStore = create<ContextMenuState>((set) => ({
|
||||
isOpen: false,
|
||||
position: null,
|
||||
items: [],
|
||||
|
||||
showContextMenu: (x, y, items) => {
|
||||
set({
|
||||
isOpen: true,
|
||||
position: { x, y },
|
||||
items,
|
||||
});
|
||||
},
|
||||
|
||||
hideContextMenu: () => {
|
||||
set({
|
||||
isOpen: false,
|
||||
position: null,
|
||||
items: [],
|
||||
});
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user