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>
41 lines
793 B
TypeScript
41 lines
793 B
TypeScript
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: [],
|
|
});
|
|
},
|
|
}));
|